mirror of
https://github.com/kidfromjupiter/nearby.git
synced 2026-09-16 15:36:12 -04:00
Merge remote-tracking branch 'upstream/main'
This commit is contained in:
@@ -47,9 +47,11 @@ jobs:
|
||||
submodules: recursive
|
||||
- name: Build FPP
|
||||
run: cargo build --manifest-path presence/fpp/fpp/Cargo.toml
|
||||
- name: Build Bluetooth Module
|
||||
run: cargo test --manifest-path fastpair/rust/bluetooth/Cargo.toml
|
||||
- name: Build Fast Pair
|
||||
run: cargo build --manifest-path fastpair/rust/Cargo.toml
|
||||
|
||||
run: cargo test --manifest-path fastpair/rust/demo/rust/Cargo.toml
|
||||
|
||||
build-rust-windows:
|
||||
name: Build Rust on Windows
|
||||
runs-on: windows-latest
|
||||
@@ -57,6 +59,8 @@ jobs:
|
||||
- uses: actions/checkout@v3
|
||||
with:
|
||||
submodules: recursive
|
||||
- name: Build Bluetooth Module
|
||||
run: cargo test --manifest-path fastpair/rust/bluetooth/Cargo.toml
|
||||
- name: Build Fast Pair
|
||||
run: cargo build --manifest-path fastpair/rust/Cargo.toml
|
||||
run: cargo test --manifest-path fastpair/rust/demo/rust/Cargo.toml
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
@@ -517,6 +517,288 @@ inline const std::string& PowerLevel_Name(T enum_t_value) {
|
||||
}
|
||||
bool PowerLevel_Parse(
|
||||
::PROTOBUF_NAMESPACE_ID::ConstStringParam name, PowerLevel* value);
|
||||
enum OperationResultCategory : int {
|
||||
CATEGORY_UNKNOWN = 0,
|
||||
CATEGORY_SUCCESS = 1,
|
||||
CATEGORY_CLIENT_CANCELLATION = 2,
|
||||
CATEGORY_MEDIUM_UNAVAILABLE = 3,
|
||||
CATEGORY_DEVICE_STATE_ERROR = 4,
|
||||
CATEGORY_CLIENT_ERROR = 5,
|
||||
CATEGORY_NEARBY_ERROR = 6,
|
||||
CATEGORY_CONNECTIVITY_ERROR = 7,
|
||||
CATEGORY_MISCELLANEOUS = 8,
|
||||
CATEGORY_IO_ERROR = 9
|
||||
};
|
||||
bool OperationResultCategory_IsValid(int value);
|
||||
constexpr OperationResultCategory OperationResultCategory_MIN = CATEGORY_UNKNOWN;
|
||||
constexpr OperationResultCategory OperationResultCategory_MAX = CATEGORY_IO_ERROR;
|
||||
constexpr int OperationResultCategory_ARRAYSIZE = OperationResultCategory_MAX + 1;
|
||||
|
||||
const std::string& OperationResultCategory_Name(OperationResultCategory value);
|
||||
template<typename T>
|
||||
inline const std::string& OperationResultCategory_Name(T enum_t_value) {
|
||||
static_assert(::std::is_same<T, OperationResultCategory>::value ||
|
||||
::std::is_integral<T>::value,
|
||||
"Incorrect type passed to function OperationResultCategory_Name.");
|
||||
return OperationResultCategory_Name(static_cast<OperationResultCategory>(enum_t_value));
|
||||
}
|
||||
bool OperationResultCategory_Parse(
|
||||
::PROTOBUF_NAMESPACE_ID::ConstStringParam name, OperationResultCategory* value);
|
||||
enum OperationResultDetail : int {
|
||||
DETAIL_UNKNOWN = 0,
|
||||
DETAIL_SUCCESS = 1,
|
||||
CLIENT_CANCELLATION_REMOTE_IN_CANCELED_STATE = 500,
|
||||
CLIENT_CANCELLATION_LOCAL_CANCEL_PAYLOAD = 501,
|
||||
CLIENT_CANCELLATION_REMOTE_CANCEL_PAYLOAD = 502,
|
||||
CLIENT_CANCELLATION_UPGRADE_CANCELED_BY_REMOTE = 503,
|
||||
CLIENT_CANCELLATION_CANCEL_BLE_OUTGOING_CONNECTION = 504,
|
||||
CLIENT_CANCELLATION_CANCEL_BT_OUTGOING_CONNECTION = 505,
|
||||
CLIENT_CANCELLATION_CANCEL_L2CAP_OUTGOING_CONNECTION = 506,
|
||||
CLIENT_CANCELLATION_CANCEL_LAN_OUTGOING_CONNECTION = 507,
|
||||
CLIENT_CANCELLATION_CANCEL_NFC_OUTGOING_CONNECTION = 508,
|
||||
CLIENT_CANCELLATION_CANCEL_USB_OUTGOING_CONNECTION = 509,
|
||||
CLIENT_CANCELLATION_CANCEL_WIFI_AWARE_OUTGOING_CONNECTION = 510,
|
||||
CLIENT_CANCELLATION_CANCEL_WIFI_DIRECT_OUTGOING_CONNECTION = 511,
|
||||
CLIENT_CANCELLATION_CANCEL_WIFI_HOTSPOT_OUTGOING_CONNECTION = 512,
|
||||
CLIENT_CANCELLATION_CANCEL_WEB_RTC_OUTGOING_CONNECTION = 513,
|
||||
CLIENT_CANCELLATION_CANCEL_OUTGOING_CONNECTION = 514,
|
||||
CLIENT_CANCELLATION_CANCEL_INCOMING_CONNECTION = 515,
|
||||
CLIENT_CANCELLATION_WIFI_AWARE_SERVER_SOCKET_CREATION = 516,
|
||||
CLIENT_CANCELLATION_WIFI_DIRECT_SERVER_SOCKET_CREATION = 517,
|
||||
CLIENT_CANCELLATION_WIFI_HOTSPOT_SERVER_SOCKET_CREATION = 518,
|
||||
CLIENT_CANCELLATION_BT_SERVER_SOCKET_CREATION = 519,
|
||||
CLIENT_CANCELLATION_WEB_RTC_SERVER_SOCKET_CREATION = 520,
|
||||
CLIENT_CANCELLATION_WIFI_LAN_SERVER_SOCKET_CREATION = 521,
|
||||
CLIENT_CANCELLATION_LOCAL_DISCONNECT = 522,
|
||||
CLIENT_CANCELLATION_REMOTE_DISCONNECT = 523,
|
||||
DEVICE_STATE_ERROR_UNFINISHED_UPGRADE_ATTEMPTS = 1000,
|
||||
DEVICE_STATE_ERROR_USER_HOTSPOT_ENABLED = 1001,
|
||||
DEVICE_STATE_LOCATION_DISABLED = 1002,
|
||||
DEVICE_STATE_RADIO_DISABLING_FAILURE = 1003,
|
||||
DEVICE_STATE_RADIO_ENABLING_FAILURE = 1004,
|
||||
MEDIUM_UNAVAILABLE_WIFI_AWARE_RESOURCE_NOT_AVAILABLE = 1500,
|
||||
MEDIUM_UNAVAILABLE_DIRECT_HOTSPOT_NOT_SUPPORT = 1501,
|
||||
MEDIUM_UNAVAILABLE_SOFT_AP_NOT_SUPPORT = 1502,
|
||||
MEDIUM_UNAVAILABLE_LOCAL_ONLY_HOTSPOT_NOT_SUPPORT = 1503,
|
||||
MEDIUM_UNAVAILABLE_LOCAL_ONLY_HOTSPOT_NOT_SUPPORT_5G = 1504,
|
||||
MEDIUM_UNAVAILABLE_BLE_NOT_AVAILABLE = 1505,
|
||||
MEDIUM_UNAVAILABLE_L2CAP_NOT_AVAILABLE = 1506,
|
||||
MEDIUM_UNAVAILABLE_BLUETOOTH_NOT_AVAILABLE = 1507,
|
||||
MEDIUM_UNAVAILABLE_WEB_RTC_NOT_AVAILABLE = 1508,
|
||||
MEDIUM_UNAVAILABLE_WIFI_AWARE_NOT_AVAILABLE = 1509,
|
||||
MEDIUM_UNAVAILABLE_WIFI_HOTSPOT_NOT_AVAILABLE = 1510,
|
||||
MEDIUM_UNAVAILABLE_WIFI_DIRECT_NOT_AVAILABLE = 1511,
|
||||
MEDIUM_UNAVAILABLE_NFC_NOT_AVAILABLE = 1512,
|
||||
MEDIUM_UNAVAILABLE_LAN_NOT_AVAILABLE = 1513,
|
||||
MEDIUM_UNAVAILABLE_USB_NOT_AVAILABLE = 1514,
|
||||
MEDIUM_UNAVAILABLE_BLE_NC_LOGICAL_NOT_AVAILABLE = 1515,
|
||||
MEDIUM_UNAVAILABLE_BT_NC_LOGICAL_NOT_AVAILABLE = 1516,
|
||||
MEDIUM_UNAVAILABLE_LAN_NC_LOGICAL_NOT_AVAILABLE = 1517,
|
||||
MEDIUM_UNAVAILABLE_NFC_NC_LOGICAL_NOT_AVAILABLE = 1518,
|
||||
MEDIUM_UNAVAILABLE_USB_NC_LOGICAL_NOT_AVAILABLE = 1519,
|
||||
MEDIUM_UNAVAILABLE_WEB_RTC_NC_LOGICAL_NOT_AVAILABLE = 1520,
|
||||
MEDIUM_UNAVAILABLE_WIFI_AWARE_NC_LOGICAL_NOT_AVAILABLE = 1521,
|
||||
MEDIUM_UNAVAILABLE_WIFI_HOTSPOT_NC_LOGICAL_NOT_AVAILABLE = 1522,
|
||||
MEDIUM_UNAVAILABLE_WIFI_DIRECT_NC_LOGICAL_NOT_AVAILABLE = 1523,
|
||||
MEDIUM_UNAVAILABLE_WIFI_HOTSPOT_P2P_RESOURCE_NOT_AVAILABLE = 1524,
|
||||
MEDIUM_UNAVAILABLE_WIFI_DIRECT_P2P_RESOURCE_NOT_AVAILABLE = 1525,
|
||||
MEDIUM_UNAVAILABLE_UPGRADE_SKIP_BLE_LOW_QUALITY_MEDIUMS = 1526,
|
||||
MEDIUM_UNAVAILABLE_UPGRADE_SKIP_L2CAP_LOW_QUALITY_MEDIUMS = 1527,
|
||||
MEDIUM_UNAVAILABLE_UPGRADE_SKIP_WEB_RTC_LOW_QUALITY_MEDIUMS = 1528,
|
||||
MEDIUM_UNAVAILABLE_UPGRADE_SKIP_LAN_LOW_QUALITY_MEDIUMS = 1529,
|
||||
MEDIUM_UNAVAILABLE_UPGRADE_SKIP_BT_LOW_QUALITY_MEDIUMS = 1530,
|
||||
MEDIUM_UNAVAILABLE_UPGRADE_SKIP_USB_LOW_QUALITY_MEDIUMS = 1531,
|
||||
MEDIUM_UNAVAILABLE_LOCAL_ONLY_HOTSPOT_DISRUPTIVE_FALSE = 1532,
|
||||
MEDIUM_UNAVAILABLE_SOFT_AP_DISRUPTIVE_FALSE = 1533,
|
||||
MEDIUM_UNAVAILABLE_ALREADY_HAVE_A_WIFI_DIRECT_GROUP = 1534,
|
||||
MEDIUM_UNAVAILABLE_ALREADY_HOSTING_HOTSPOT_FOR_OTHER_CLIENTS = 1535,
|
||||
MEDIUM_UNAVAILABLE_REJECT_L2CAP_ON_GATT_MULTIPLEX_CONNECTION = 1536,
|
||||
MEDIUM_UNAVAILABLE_UPGRADE_ON_SAME_MEDIUM = 1537,
|
||||
MEDIUM_UNAVAILABLE_WEB_RTC_NO_INTERNET = 1538,
|
||||
CLIENT_WIFI_DIRECT_ALREADY_HOSTING_DIRECT_GROUP_FOR_THIS_CLIENT = 2000,
|
||||
CLIENT_WIFI_HOTSPOT_ALREADY_HOSTING_HOTSPOT_FOR_THIS_CLIENT = 2001,
|
||||
CLIENT_DUPLICATE_ACCEPTING_BLE_CONNECTION_REQUEST = 2002,
|
||||
CLIENT_DUPLICATE_ACCEPTING_L2CAP_CONNECTION_REQUEST = 2003,
|
||||
CLIENT_DUPLICATE_ACCEPTING_BT_CONNECTION_REQUEST = 2004,
|
||||
CLIENT_DUPLICATE_ACCEPTING_LAN_CONNECTION_REQUEST = 2005,
|
||||
CLIENT_DUPLICATE_ACCEPTING_NFC_CONNECTION_REQUEST = 2006,
|
||||
CLIENT_DUPLICATE_ACCEPTING_WEB_RTC_CONNECTION_REQUEST = 2007,
|
||||
CLIENT_DUPLICATE_ACCEPTING_WIFI_AWARE_CONNECTION_REQUEST = 2008,
|
||||
CLIENT_DUPLICATE_ACCEPTING_WIFI_HOTSPOT_CONNECTION_REQUEST = 2009,
|
||||
CLIENT_DUPLICATE_ACCEPTING_WIFI_DIRECT_CONNECTION_REQUEST = 2010,
|
||||
CLIENT_DUPLICATE_ACCEPTING_USB_CONNECTION_REQUEST = 2011,
|
||||
CLIENT_DUPLICATE_WIFI_AWARE_CONNECTION_REQUEST = 2012,
|
||||
CLIENT_DUPLICATE_WIFI_DIRECT_CONNECTION_REQUEST = 2013,
|
||||
CLIENT_DUPLICATE_WIFI_HOTSPOT_CONNECTION_REQUEST = 2014,
|
||||
CLIENT_DUPLICATE_WIFI_AWARE_SUBSCRIBING_REQUEST = 2015,
|
||||
CLIENT_UNSUPPORTED_USB_TO_BE_UPGRADE_MEDIUM = 2016,
|
||||
MISCELLEANEOUS_BLUETOOTH_MAC_ADDRESS_NULL = 2500,
|
||||
MISCELLEANEOUS_MOVE_TO_NEW_MEDIUM = 2501,
|
||||
MISCELLEANEOUS_WIFI_HOTSPOT_SOFT_AP_BLOCKED_BY_PROVISION = 2502,
|
||||
MISCELLEANEOUS_BLE_SYSTEM_SERVICE_NULL = 2503,
|
||||
MISCELLEANEOUS_L2CAP_SYSTEM_SERVICE_NULL = 2504,
|
||||
MISCELLEANEOUS_BT_SYSTEM_SERVICE_NULL = 2505,
|
||||
MISCELLEANEOUS_WIFI_AWARE_SYSTEM_SERVICE_NULL = 2506,
|
||||
MISCELLEANEOUS_WIFI_DIRECT_SYSTEM_SERVICE_NULL = 2507,
|
||||
MISCELLEANEOUS_WIFI_LAN_SYSTEM_SERVICE_NULL = 2508,
|
||||
MISCELLEANEOUS_WIFI_HOTSPOT_SYSTEM_SERVICE_NULL = 2509,
|
||||
MISCELLEANEOUS_BT_NOT_ACCEPTING_CONNECTION_FOR_WORK_PROFILE = 2510,
|
||||
MISCELLEANEOUS_WEB_RTC_GET_DROIDGUARD_RESULT_FAILURE = 2511,
|
||||
MISCELLEANEOUS_WEB_RTC_TACHYON_SIGNALING_MESSENGER_NULL = 2512,
|
||||
IO_FILE_OPENING_ERROR = 3000,
|
||||
IO_FILE_READING_ERROR = 3001,
|
||||
IO_FILE_WRITING_ERROR = 3002,
|
||||
IO_FOLDER_CREATION_ERROR = 3003,
|
||||
IO_STREAM_CREATE_PIPE_FAILURE = 3004,
|
||||
IO_ENDPOINT_IO_ERROR_ON_BLE = 3005,
|
||||
IO_ENDPOINT_IO_ERROR_ON_L2CAP = 3006,
|
||||
IO_ENDPOINT_IO_ERROR_ON_BT = 3007,
|
||||
IO_ENDPOINT_IO_ERROR_ON_WEB_RTC = 3008,
|
||||
IO_ENDPOINT_IO_ERROR_ON_LAN = 3009,
|
||||
IO_ENDPOINT_IO_ERROR_ON_WIFI_DIRECT = 3010,
|
||||
IO_ENDPOINT_IO_ERROR_ON_WIFI_HOTSPOT = 3011,
|
||||
IO_ENDPOINT_IO_ERROR_ON_WIFI_AWARE = 3012,
|
||||
IO_ENDPOINT_IO_ERROR_ON_NFC = 3013,
|
||||
IO_ENDPOINT_IO_ERROR_ON_USB = 3014,
|
||||
CONNECTIVITY_WIFI_AWARE_ATTACH_FAILURE = 3500,
|
||||
CONNECTIVITY_BLUETOOTH_DEVICE_OBTAIN_FAILURE = 3501,
|
||||
CONNECTIVITY_BLE_CLIENT_SOCKET_CREATION_FAILURE = 3502,
|
||||
CONNECTIVITY_L2CAP_CLIENT_SOCKET_CREATION_FAILURE = 3503,
|
||||
CONNECTIVITY_BT_CLIENT_SOCKET_CREATION_FAILURE = 3504,
|
||||
CONNECTIVITY_LAN_CLIENT_SOCKET_CREATION_FAILURE = 3505,
|
||||
CONNECTIVITY_NFC_CLIENT_SOCKET_CREATION_FAILURE = 3506,
|
||||
CONNECTIVITY_WEB_RTC_CLIENT_SOCKET_CREATION_FAILURE = 3507,
|
||||
CONNECTIVITY_WIFI_AWARE_CLIENT_SOCKET_CREATION_FAILURE = 3508,
|
||||
CONNECTIVITY_WIFI_HOTSPOT_CLIENT_SOCKET_CREATION_FAILURE = 3509,
|
||||
CONNECTIVITY_WIFI_DIRECT_CLIENT_SOCKET_CREATION_FAILURE = 3510,
|
||||
CONNECTIVITY_USB_CLIENT_SOCKET_CREATION_FAILURE = 3511,
|
||||
CONNECTIVITY_WEB_RTC_CONNECT_TO_TACHYON_FAILURE = 3512,
|
||||
CONNECTIVITY_BLE_CREATE_GATT_CONNECTION_FAILURE = 3513,
|
||||
CONNECTIVITY_WIFI_AWARE_GET_REMOTE_IP_FRAME_FAILURE = 3514,
|
||||
CONNECTIVITY_WIFI_AWARE_GET_REMOTE_IP_ADDRESS_FAILURE = 3515,
|
||||
CONNECTIVITY_WIFI_DIRECT_INCONSISTENT_HOSTED_WIFI_BAND = 3516,
|
||||
CONNECTIVITY_WIFI_HOTSPOT_INCONSISTENT_HOSTED_WIFI_BAND = 3517,
|
||||
CONNECTIVITY_BLUETOOTH_INVALID_CREDENTIAL = 3518,
|
||||
CONNECTIVITY_WIFI_LAN_INVALID_CREDENTIAL = 3519,
|
||||
CONNECTIVITY_WIFI_DIRECT_INVALID_CREDENTIAL = 3520,
|
||||
CONNECTIVITY_WIFI_HOTSPOT_INVALID_CREDENTIAL = 3521,
|
||||
CONNECTIVITY_WIFI_AWARE_INVALID_CREDENTIAL = 3522,
|
||||
CONNECTIVITY_WEB_RTC_INVALID_CREDENTIAL = 3523,
|
||||
CONNECTIVITY_WIFI_LAN_IP_ADDRESS_ERROR = 3524,
|
||||
CONNECTIVITY_L2CAP_CLIENT_OBTAIN_FAIURE = 3525,
|
||||
CONNECTIVITY_L2CAP_DATA_CONNECTION_FAILURE = 3526,
|
||||
CONNECTIVITY_WIFI_AWARE_L2MESSAGE_NETWORK_AVAILABLE_FRAME_NULL = 3527,
|
||||
CONNECTIVITY_WIFI_AWARE_L2MESSAGE_SEND_HOST_NETWORK_FRAME_FAILURE = 3528,
|
||||
CONNECTIVITY_LAN_UNREACHABLE = 3529,
|
||||
CONNECTIVITY_WIFI_HOTSPOT_LOHS_CREATION_FAILURE = 3530,
|
||||
CONNECTIVITY_LAN_GET_NETWORK_INTERFACES_FAILURE = 3531,
|
||||
CONNECTIVITY_WIFI_DIRECT_GET_NETWORK_INTERFACES_FAILURE = 3532,
|
||||
CONNECTIVITY_WIFI_HOTSPOT_GET_NETWORK_INTERFACES_FAILURE = 3533,
|
||||
CONNECTIVITY_WIFI_HOTSPOT_P2P_CHANNEL_INITIALIZE_FAILURE = 3534,
|
||||
CONNECTIVITY_WIFI_DIRECT_P2P_CHANNEL_INITIALIZE_FAILURE = 3535,
|
||||
CONNECTIVITY_WIFI_HOTSPOT_P2P_GROUP_CREATION_FAILURE = 3536,
|
||||
CONNECTIVITY_WIFI_DIRECT_P2P_GROUP_CREATION_FAILURE = 3537,
|
||||
CONNECTIVITY_GATT_SERVER_OPEN_FAILURE = 3538,
|
||||
CONNECTIVITY_BLE_SERVER_SOCKET_CREATION_FAILURE = 3539,
|
||||
CONNECTIVITY_L2CAP_SERVER_SOCKET_CREATION_FAILURE = 3540,
|
||||
CONNECTIVITY_BT_SERVER_SOCKET_CREATION_FAILURE = 3541,
|
||||
CONNECTIVITY_LAN_SERVER_SOCKET_CREATION_FAILURE = 3542,
|
||||
CONNECTIVITY_WEB_RTC_SERVER_SOCKET_CREATION_FAILURE = 3543,
|
||||
CONNECTIVITY_WIFI_AWARE_SERVER_SOCKET_CREATION_FAILURE = 3544,
|
||||
CONNECTIVITY_WIFI_HOTSPOT_SERVER_SOCKET_CREATION_FAILURE = 3545,
|
||||
CONNECTIVITY_WIFI_DIRECT_SERVER_SOCKET_CREATION_FAILURE = 3546,
|
||||
CONNECTIVITY_NFC_SERVER_SOCKET_CREATION_FAILURE = 3547,
|
||||
CONNECTIVITY_WIFI_HOTSPOT_SOFT_AP_CREATION_FAILURE = 3548,
|
||||
CONNECTIVITY_WIFI_AWARE_UPDATE_PUBLISH_FAILURE = 3549,
|
||||
CONNECTIVITY_GENERIC_WRITING_CHANNEL_IO_ERROR = 3550,
|
||||
CONNECTIVITY_GENERIC_WRITE_CLIENT_INTRODUCTION_ACK_IO_ERROR = 3551,
|
||||
CONNECTIVITY_WIFI_AWARE_DISCOVERED_PEER_NULL = 3552,
|
||||
CONNECTIVITY_GENERIC_PAYLOAD_SENT_ERROR = 3553,
|
||||
CONNECTIVITY_L2CAP_SERVER_SOCKET_CREATION_SECURITY_EXCEPTION_FAILURE = 3554,
|
||||
CONNECTIVITY_BT_SERVER_SOCKET_CREATION_SECURITY_EXCEPTION_FAILURE = 3555,
|
||||
NEARBY_BLE_ADVERTISEMENT_MAPPING_TO_MAC_ERROR = 4500,
|
||||
NEARBY_BLUETOOTH_MAC_ADDRESS_INVALID_FOR_CONNECT = 4501,
|
||||
NEARBY_WEB_RTC_CONNECTION_FLOW_NULL = 4502,
|
||||
NEARBY_GENERIC_CONNECTION_CLOSED = 4503,
|
||||
NEARBY_BLE_ENDPOINT_CHANNEL_CREATION_FAILURE = 4504,
|
||||
NEARBY_L2CAP_ENDPOINT_CHANNEL_CREATION_FAILURE = 4505,
|
||||
NEARBY_BT_ENDPOINT_CHANNEL_CREATION_FAILURE = 4506,
|
||||
NEARBY_LAN_ENDPOINT_CHANNEL_CREATION_FAILURE = 4507,
|
||||
NEARBY_NFC_ENDPOINT_CHANNEL_CREATION_FAILURE = 4508,
|
||||
NEARBY_WIFI_AWARE_ENDPOINT_CHANNEL_CREATION_FAILURE = 4509,
|
||||
NEARBY_WIFI_HOTSPOT_ENDPOINT_CHANNEL_CREATION_FAILURE = 4510,
|
||||
NEARBY_WIFI_DIRECT_ENDPOINT_CHANNEL_CREATION_FAILURE = 4511,
|
||||
NEARBY_WEB_RTC_ENDPOINT_CHANNEL_CREATION_FAILURE = 4512,
|
||||
NEARBY_USB_ENDPOINT_CHANNEL_CREATION_FAILURE = 4513,
|
||||
NEARBY_GENERIC_ENDPOINT_UNENCRYPTED = 4514,
|
||||
NEARBY_BLE_GATT_ADVERTISEMENT_NULL_FOR_CONNECTION = 4515,
|
||||
NEARBY_WIFI_DIRECT_HOST_ON_SRD_CHANNELS = 4516,
|
||||
NEARBY_WIFI_HOTSPOT_HOST_ON_SRD_CHANNELS = 4517,
|
||||
NEARBY_BLE_GATT_NULL_CALLBACK = 4518,
|
||||
NEARBY_L2CAP_NULL_CALLBACK = 4519,
|
||||
NEARBY_BT_NULL_CALLBACK = 4520,
|
||||
NEARBY_USB_NULL_CALLBACK = 4521,
|
||||
NEARBY_NFC_NULL_CALLBACK = 4522,
|
||||
NEARBY_WIFI_AWARE_NULL_CALLBACK = 4523,
|
||||
NEARBY_WEB_RTC_NULL_CALLBACK = 4524,
|
||||
NEARBY_LAN_NULL_CALLBACK = 4525,
|
||||
NEARBY_WIFI_HOTSPOT_NULL_CALLBACK = 4526,
|
||||
NEARBY_WIFI_DIRECT_NULL_CALLBACK = 4527,
|
||||
NEARBY_WIFI_DIRECT_NULL_SSID = 4528,
|
||||
NEARBY_WIFI_DIRECT_NULL_PASSWORD = 4529,
|
||||
NEARBY_BT_MULTIPLEX_SOCKET_DISABLED = 4530,
|
||||
NEARBY_LAN_MULTIPLEX_SOCKET_DISABLED = 4531,
|
||||
NEARBY_GENERIC_NEW_ENDPOINT_CHANNEL_NULL = 4532,
|
||||
NEARBY_WIFI_DIRECT_NO_GROUP_FOR_LISTENING = 4533,
|
||||
NEARBY_WIFI_HOTSPOT_NO_HOTSPOT_FOR_LISTENING = 4534,
|
||||
NEARBY_GENERIC_OLD_ENDPOINT_CHANNEL_NULL = 4535,
|
||||
NEARBY_BLE_OPERATION_REGISTERED_FAILED = 4536,
|
||||
NEARBY_L2CAP_OPERATION_REGISTERED_FAILED = 4537,
|
||||
NEARBY_BT_OPERATION_REGISTERED_FAILED = 4538,
|
||||
NEARBY_LAN_OPERATION_REGISTERED_FAILED = 4539,
|
||||
NEARBY_WEB_RTC_OPERATION_REGISTERED_FAILED = 4540,
|
||||
NEARBY_WIFI_AWARE_OPERATION_REGISTERED_FAILED = 4541,
|
||||
NEARBY_WIFI_HOTSPOT_DIRECT_OPERATION_REGISTERED_FAILED = 4542,
|
||||
NEARBY_WIFI_HOTSPOT_SOFT_AP_OPERATION_REGISTERED_FAILED = 4543,
|
||||
NEARBY_WIFI_HOTSPOT_LOHS_OPERATION_REGISTERED_FAILED = 4544,
|
||||
NEARBY_WIFI_HOTSPOT_CLIENT_OPERATION_REGISTERED_FAILED = 4545,
|
||||
NEARBY_WIFI_DIRECT_OPERATION_REGISTERED_FAILED = 4546,
|
||||
NEARBY_GENERIC_OUTGOING_PAYLOAD_CREATION_FAILURE = 4547,
|
||||
NEARBY_WIFI_HOTSPOT_P2P_NON_DBS_WANT_2G_BUT_AP_5G = 4548,
|
||||
NEARBY_WIFI_DIRECT_P2P_NON_DBS_WANT_2G_BUT_AP_5G = 4549,
|
||||
NEARBY_WIFI_HOTSPOT_P2P_NON_DBS_WANT_5G_BUT_AP_2G = 4550,
|
||||
NEARBY_WIFI_DIRECT_P2P_NON_DBS_WANT_5G_BUT_AP_2G = 4551,
|
||||
NEARBY_GENERIC_INCOMING_PAYLOAD_NOT_DATA_TYPE = 4552,
|
||||
NEARBY_GENERIC_READ_CLIENT_INTRODUCTION_EVENT_TYPE_ERROR = 4553,
|
||||
NEARBY_GENERIC_READ_CLIENT_INTRODUCTION_FRAME_TYPE_ERROR = 4554,
|
||||
NEARBY_GENERIC_READ_CLIENT_INTRODUCTION_FORMAT_ERROR = 4555,
|
||||
NEARBY_GENERIC_READ_CLIENT_INTRODUCTION_ACK_EVENT_TYPE_ERROR = 4556,
|
||||
NEARBY_GENERIC_READ_CLIENT_INTRODUCTION_ACK_FRAME_TYPE_ERROR = 4557,
|
||||
NEARBY_GENERIC_READ_CLIENT_INTRODUCTION_ACK_FORMAT_ERROR = 4558,
|
||||
NEARBY_GENERIC_REMOTE_ENDPOINT_STATUS_ERROR = 4559,
|
||||
NEARBY_GENERIC_REMOTE_REPORT_PAYLOADS_ERROR = 4560,
|
||||
NEARBY_GENERIC_REMOTE_UPGRADE_FAILURE = 4561,
|
||||
NEARBY_GENERIC_SEND_PAYLOAD_EXECUTOR_NULL = 4562,
|
||||
NEARBY_BT_VIRTUAL_SOCKET_CREATION_FAILURE = 4563,
|
||||
NEARBY_LAN_VIRTUAL_SOCKET_CREATION_FAILURE = 4564,
|
||||
NEARBY_WIFI_LAN_IP_ADDRESS_ERROR = 4565,
|
||||
NEARBY_L2CAP_PSM_NOT_POSITIVE = 4566
|
||||
};
|
||||
bool OperationResultDetail_IsValid(int value);
|
||||
constexpr OperationResultDetail OperationResultDetail_MIN = DETAIL_UNKNOWN;
|
||||
constexpr OperationResultDetail OperationResultDetail_MAX = NEARBY_L2CAP_PSM_NOT_POSITIVE;
|
||||
constexpr int OperationResultDetail_ARRAYSIZE = OperationResultDetail_MAX + 1;
|
||||
|
||||
const std::string& OperationResultDetail_Name(OperationResultDetail value);
|
||||
template<typename T>
|
||||
inline const std::string& OperationResultDetail_Name(T enum_t_value) {
|
||||
static_assert(::std::is_same<T, OperationResultDetail>::value ||
|
||||
::std::is_integral<T>::value,
|
||||
"Incorrect type passed to function OperationResultDetail_Name.");
|
||||
return OperationResultDetail_Name(static_cast<OperationResultDetail>(enum_t_value));
|
||||
}
|
||||
bool OperationResultDetail_Parse(
|
||||
::PROTOBUF_NAMESPACE_ID::ConstStringParam name, OperationResultDetail* value);
|
||||
// ===================================================================
|
||||
|
||||
|
||||
@@ -560,6 +842,8 @@ template <> struct is_proto_enum< ::location::nearby::proto::connections::Bandwi
|
||||
template <> struct is_proto_enum< ::location::nearby::proto::connections::BandwidthUpgradeErrorStage> : ::std::true_type {};
|
||||
template <> struct is_proto_enum< ::location::nearby::proto::connections::LogSource> : ::std::true_type {};
|
||||
template <> struct is_proto_enum< ::location::nearby::proto::connections::PowerLevel> : ::std::true_type {};
|
||||
template <> struct is_proto_enum< ::location::nearby::proto::connections::OperationResultCategory> : ::std::true_type {};
|
||||
template <> struct is_proto_enum< ::location::nearby::proto::connections::OperationResultDetail> : ::std::true_type {};
|
||||
|
||||
PROTOBUF_NAMESPACE_CLOSE
|
||||
|
||||
|
||||
@@ -35,6 +35,7 @@ PROTOBUF_ATTRIBUTE_NO_DESTROY PROTOBUF_CONSTINIT SocketControlFrameDefaultTypeIn
|
||||
constexpr IntroductionFrame::IntroductionFrame(
|
||||
::PROTOBUF_NAMESPACE_ID::internal::ConstantInitialized)
|
||||
: service_id_hash_(&::PROTOBUF_NAMESPACE_ID::internal::fixed_address_empty_string)
|
||||
, service_id_hash_salt_(&::PROTOBUF_NAMESPACE_ID::internal::fixed_address_empty_string)
|
||||
, socket_version_(0)
|
||||
{}
|
||||
struct IntroductionFrameDefaultTypeInternal {
|
||||
@@ -552,6 +553,9 @@ class IntroductionFrame::_Internal {
|
||||
(*has_bits)[0] |= 1u;
|
||||
}
|
||||
static void set_has_socket_version(HasBits* has_bits) {
|
||||
(*has_bits)[0] |= 4u;
|
||||
}
|
||||
static void set_has_service_id_hash_salt(HasBits* has_bits) {
|
||||
(*has_bits)[0] |= 2u;
|
||||
}
|
||||
};
|
||||
@@ -577,6 +581,14 @@ IntroductionFrame::IntroductionFrame(const IntroductionFrame& from)
|
||||
service_id_hash_.Set(::PROTOBUF_NAMESPACE_ID::internal::ArenaStringPtr::EmptyDefault{}, from._internal_service_id_hash(),
|
||||
GetArenaForAllocation());
|
||||
}
|
||||
service_id_hash_salt_.UnsafeSetDefault(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited());
|
||||
#ifdef PROTOBUF_FORCE_COPY_DEFAULT_STRING
|
||||
service_id_hash_salt_.Set(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited(), "", GetArenaForAllocation());
|
||||
#endif // PROTOBUF_FORCE_COPY_DEFAULT_STRING
|
||||
if (from._internal_has_service_id_hash_salt()) {
|
||||
service_id_hash_salt_.Set(::PROTOBUF_NAMESPACE_ID::internal::ArenaStringPtr::EmptyDefault{}, from._internal_service_id_hash_salt(),
|
||||
GetArenaForAllocation());
|
||||
}
|
||||
socket_version_ = from.socket_version_;
|
||||
// @@protoc_insertion_point(copy_constructor:location.nearby.mediums.IntroductionFrame)
|
||||
}
|
||||
@@ -586,6 +598,10 @@ service_id_hash_.UnsafeSetDefault(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptySt
|
||||
#ifdef PROTOBUF_FORCE_COPY_DEFAULT_STRING
|
||||
service_id_hash_.Set(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited(), "", GetArenaForAllocation());
|
||||
#endif // PROTOBUF_FORCE_COPY_DEFAULT_STRING
|
||||
service_id_hash_salt_.UnsafeSetDefault(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited());
|
||||
#ifdef PROTOBUF_FORCE_COPY_DEFAULT_STRING
|
||||
service_id_hash_salt_.Set(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited(), "", GetArenaForAllocation());
|
||||
#endif // PROTOBUF_FORCE_COPY_DEFAULT_STRING
|
||||
socket_version_ = 0;
|
||||
}
|
||||
|
||||
@@ -599,6 +615,7 @@ IntroductionFrame::~IntroductionFrame() {
|
||||
inline void IntroductionFrame::SharedDtor() {
|
||||
GOOGLE_DCHECK(GetArenaForAllocation() == nullptr);
|
||||
service_id_hash_.DestroyNoArena(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited());
|
||||
service_id_hash_salt_.DestroyNoArena(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited());
|
||||
}
|
||||
|
||||
void IntroductionFrame::ArenaDtor(void* object) {
|
||||
@@ -618,8 +635,13 @@ void IntroductionFrame::Clear() {
|
||||
(void) cached_has_bits;
|
||||
|
||||
cached_has_bits = _has_bits_[0];
|
||||
if (cached_has_bits & 0x00000001u) {
|
||||
service_id_hash_.ClearNonDefaultToEmpty();
|
||||
if (cached_has_bits & 0x00000003u) {
|
||||
if (cached_has_bits & 0x00000001u) {
|
||||
service_id_hash_.ClearNonDefaultToEmpty();
|
||||
}
|
||||
if (cached_has_bits & 0x00000002u) {
|
||||
service_id_hash_salt_.ClearNonDefaultToEmpty();
|
||||
}
|
||||
}
|
||||
socket_version_ = 0;
|
||||
_has_bits_.Clear();
|
||||
@@ -655,6 +677,15 @@ const char* IntroductionFrame::_InternalParse(const char* ptr, ::PROTOBUF_NAMESP
|
||||
} else
|
||||
goto handle_unusual;
|
||||
continue;
|
||||
// optional string service_id_hash_salt = 3;
|
||||
case 3:
|
||||
if (PROTOBUF_PREDICT_TRUE(static_cast<uint8_t>(tag) == 26)) {
|
||||
auto str = _internal_mutable_service_id_hash_salt();
|
||||
ptr = ::PROTOBUF_NAMESPACE_ID::internal::InlineGreedyStringParser(str, ptr, ctx);
|
||||
CHK_(ptr);
|
||||
} else
|
||||
goto handle_unusual;
|
||||
continue;
|
||||
default:
|
||||
goto handle_unusual;
|
||||
} // switch
|
||||
@@ -693,12 +724,18 @@ uint8_t* IntroductionFrame::_InternalSerialize(
|
||||
}
|
||||
|
||||
// optional .location.nearby.mediums.SocketVersion socket_version = 2;
|
||||
if (cached_has_bits & 0x00000002u) {
|
||||
if (cached_has_bits & 0x00000004u) {
|
||||
target = stream->EnsureSpace(target);
|
||||
target = ::PROTOBUF_NAMESPACE_ID::internal::WireFormatLite::WriteEnumToArray(
|
||||
2, this->_internal_socket_version(), target);
|
||||
}
|
||||
|
||||
// optional string service_id_hash_salt = 3;
|
||||
if (cached_has_bits & 0x00000002u) {
|
||||
target = stream->WriteStringMaybeAliased(
|
||||
3, this->_internal_service_id_hash_salt(), target);
|
||||
}
|
||||
|
||||
if (PROTOBUF_PREDICT_FALSE(_internal_metadata_.have_unknown_fields())) {
|
||||
target = stream->WriteRaw(_internal_metadata_.unknown_fields<std::string>(::PROTOBUF_NAMESPACE_ID::internal::GetEmptyString).data(),
|
||||
static_cast<int>(_internal_metadata_.unknown_fields<std::string>(::PROTOBUF_NAMESPACE_ID::internal::GetEmptyString).size()), target);
|
||||
@@ -716,7 +753,7 @@ size_t IntroductionFrame::ByteSizeLong() const {
|
||||
(void) cached_has_bits;
|
||||
|
||||
cached_has_bits = _has_bits_[0];
|
||||
if (cached_has_bits & 0x00000003u) {
|
||||
if (cached_has_bits & 0x00000007u) {
|
||||
// optional bytes service_id_hash = 1;
|
||||
if (cached_has_bits & 0x00000001u) {
|
||||
total_size += 1 +
|
||||
@@ -724,8 +761,15 @@ size_t IntroductionFrame::ByteSizeLong() const {
|
||||
this->_internal_service_id_hash());
|
||||
}
|
||||
|
||||
// optional .location.nearby.mediums.SocketVersion socket_version = 2;
|
||||
// optional string service_id_hash_salt = 3;
|
||||
if (cached_has_bits & 0x00000002u) {
|
||||
total_size += 1 +
|
||||
::PROTOBUF_NAMESPACE_ID::internal::WireFormatLite::StringSize(
|
||||
this->_internal_service_id_hash_salt());
|
||||
}
|
||||
|
||||
// optional .location.nearby.mediums.SocketVersion socket_version = 2;
|
||||
if (cached_has_bits & 0x00000004u) {
|
||||
total_size += 1 +
|
||||
::PROTOBUF_NAMESPACE_ID::internal::WireFormatLite::EnumSize(this->_internal_socket_version());
|
||||
}
|
||||
@@ -752,11 +796,14 @@ void IntroductionFrame::MergeFrom(const IntroductionFrame& from) {
|
||||
(void) cached_has_bits;
|
||||
|
||||
cached_has_bits = from._has_bits_[0];
|
||||
if (cached_has_bits & 0x00000003u) {
|
||||
if (cached_has_bits & 0x00000007u) {
|
||||
if (cached_has_bits & 0x00000001u) {
|
||||
_internal_set_service_id_hash(from._internal_service_id_hash());
|
||||
}
|
||||
if (cached_has_bits & 0x00000002u) {
|
||||
_internal_set_service_id_hash_salt(from._internal_service_id_hash_salt());
|
||||
}
|
||||
if (cached_has_bits & 0x00000004u) {
|
||||
socket_version_ = from.socket_version_;
|
||||
}
|
||||
_has_bits_[0] |= cached_has_bits;
|
||||
@@ -786,6 +833,11 @@ void IntroductionFrame::InternalSwap(IntroductionFrame* other) {
|
||||
&service_id_hash_, lhs_arena,
|
||||
&other->service_id_hash_, rhs_arena
|
||||
);
|
||||
::PROTOBUF_NAMESPACE_ID::internal::ArenaStringPtr::InternalSwap(
|
||||
&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited(),
|
||||
&service_id_hash_salt_, lhs_arena,
|
||||
&other->service_id_hash_salt_, rhs_arena
|
||||
);
|
||||
swap(socket_version_, other->socket_version_);
|
||||
}
|
||||
|
||||
|
||||
@@ -468,6 +468,7 @@ class IntroductionFrame final :
|
||||
|
||||
enum : int {
|
||||
kServiceIdHashFieldNumber = 1,
|
||||
kServiceIdHashSaltFieldNumber = 3,
|
||||
kSocketVersionFieldNumber = 2,
|
||||
};
|
||||
// optional bytes service_id_hash = 1;
|
||||
@@ -488,6 +489,24 @@ class IntroductionFrame final :
|
||||
std::string* _internal_mutable_service_id_hash();
|
||||
public:
|
||||
|
||||
// optional string service_id_hash_salt = 3;
|
||||
bool has_service_id_hash_salt() const;
|
||||
private:
|
||||
bool _internal_has_service_id_hash_salt() const;
|
||||
public:
|
||||
void clear_service_id_hash_salt();
|
||||
const std::string& service_id_hash_salt() const;
|
||||
template <typename ArgT0 = const std::string&, typename... ArgT>
|
||||
void set_service_id_hash_salt(ArgT0&& arg0, ArgT... args);
|
||||
std::string* mutable_service_id_hash_salt();
|
||||
PROTOBUF_NODISCARD std::string* release_service_id_hash_salt();
|
||||
void set_allocated_service_id_hash_salt(std::string* service_id_hash_salt);
|
||||
private:
|
||||
const std::string& _internal_service_id_hash_salt() const;
|
||||
inline PROTOBUF_ALWAYS_INLINE void _internal_set_service_id_hash_salt(const std::string& value);
|
||||
std::string* _internal_mutable_service_id_hash_salt();
|
||||
public:
|
||||
|
||||
// optional .location.nearby.mediums.SocketVersion socket_version = 2;
|
||||
bool has_socket_version() const;
|
||||
private:
|
||||
@@ -511,6 +530,7 @@ class IntroductionFrame final :
|
||||
::PROTOBUF_NAMESPACE_ID::internal::HasBits<1> _has_bits_;
|
||||
mutable ::PROTOBUF_NAMESPACE_ID::internal::CachedSize _cached_size_;
|
||||
::PROTOBUF_NAMESPACE_ID::internal::ArenaStringPtr service_id_hash_;
|
||||
::PROTOBUF_NAMESPACE_ID::internal::ArenaStringPtr service_id_hash_salt_;
|
||||
int socket_version_;
|
||||
friend struct ::TableStruct_proto_2fmediums_2fble_5fframes_2eproto;
|
||||
};
|
||||
@@ -1208,7 +1228,7 @@ inline void IntroductionFrame::set_allocated_service_id_hash(std::string* servic
|
||||
|
||||
// optional .location.nearby.mediums.SocketVersion socket_version = 2;
|
||||
inline bool IntroductionFrame::_internal_has_socket_version() const {
|
||||
bool value = (_has_bits_[0] & 0x00000002u) != 0;
|
||||
bool value = (_has_bits_[0] & 0x00000004u) != 0;
|
||||
return value;
|
||||
}
|
||||
inline bool IntroductionFrame::has_socket_version() const {
|
||||
@@ -1216,7 +1236,7 @@ inline bool IntroductionFrame::has_socket_version() const {
|
||||
}
|
||||
inline void IntroductionFrame::clear_socket_version() {
|
||||
socket_version_ = 0;
|
||||
_has_bits_[0] &= ~0x00000002u;
|
||||
_has_bits_[0] &= ~0x00000004u;
|
||||
}
|
||||
inline ::location::nearby::mediums::SocketVersion IntroductionFrame::_internal_socket_version() const {
|
||||
return static_cast< ::location::nearby::mediums::SocketVersion >(socket_version_);
|
||||
@@ -1227,7 +1247,7 @@ inline ::location::nearby::mediums::SocketVersion IntroductionFrame::socket_vers
|
||||
}
|
||||
inline void IntroductionFrame::_internal_set_socket_version(::location::nearby::mediums::SocketVersion value) {
|
||||
assert(::location::nearby::mediums::SocketVersion_IsValid(value));
|
||||
_has_bits_[0] |= 0x00000002u;
|
||||
_has_bits_[0] |= 0x00000004u;
|
||||
socket_version_ = value;
|
||||
}
|
||||
inline void IntroductionFrame::set_socket_version(::location::nearby::mediums::SocketVersion value) {
|
||||
@@ -1235,6 +1255,75 @@ inline void IntroductionFrame::set_socket_version(::location::nearby::mediums::S
|
||||
// @@protoc_insertion_point(field_set:location.nearby.mediums.IntroductionFrame.socket_version)
|
||||
}
|
||||
|
||||
// optional string service_id_hash_salt = 3;
|
||||
inline bool IntroductionFrame::_internal_has_service_id_hash_salt() const {
|
||||
bool value = (_has_bits_[0] & 0x00000002u) != 0;
|
||||
return value;
|
||||
}
|
||||
inline bool IntroductionFrame::has_service_id_hash_salt() const {
|
||||
return _internal_has_service_id_hash_salt();
|
||||
}
|
||||
inline void IntroductionFrame::clear_service_id_hash_salt() {
|
||||
service_id_hash_salt_.ClearToEmpty();
|
||||
_has_bits_[0] &= ~0x00000002u;
|
||||
}
|
||||
inline const std::string& IntroductionFrame::service_id_hash_salt() const {
|
||||
// @@protoc_insertion_point(field_get:location.nearby.mediums.IntroductionFrame.service_id_hash_salt)
|
||||
return _internal_service_id_hash_salt();
|
||||
}
|
||||
template <typename ArgT0, typename... ArgT>
|
||||
inline PROTOBUF_ALWAYS_INLINE
|
||||
void IntroductionFrame::set_service_id_hash_salt(ArgT0&& arg0, ArgT... args) {
|
||||
_has_bits_[0] |= 0x00000002u;
|
||||
service_id_hash_salt_.Set(::PROTOBUF_NAMESPACE_ID::internal::ArenaStringPtr::EmptyDefault{}, static_cast<ArgT0 &&>(arg0), args..., GetArenaForAllocation());
|
||||
// @@protoc_insertion_point(field_set:location.nearby.mediums.IntroductionFrame.service_id_hash_salt)
|
||||
}
|
||||
inline std::string* IntroductionFrame::mutable_service_id_hash_salt() {
|
||||
std::string* _s = _internal_mutable_service_id_hash_salt();
|
||||
// @@protoc_insertion_point(field_mutable:location.nearby.mediums.IntroductionFrame.service_id_hash_salt)
|
||||
return _s;
|
||||
}
|
||||
inline const std::string& IntroductionFrame::_internal_service_id_hash_salt() const {
|
||||
return service_id_hash_salt_.Get();
|
||||
}
|
||||
inline void IntroductionFrame::_internal_set_service_id_hash_salt(const std::string& value) {
|
||||
_has_bits_[0] |= 0x00000002u;
|
||||
service_id_hash_salt_.Set(::PROTOBUF_NAMESPACE_ID::internal::ArenaStringPtr::EmptyDefault{}, value, GetArenaForAllocation());
|
||||
}
|
||||
inline std::string* IntroductionFrame::_internal_mutable_service_id_hash_salt() {
|
||||
_has_bits_[0] |= 0x00000002u;
|
||||
return service_id_hash_salt_.Mutable(::PROTOBUF_NAMESPACE_ID::internal::ArenaStringPtr::EmptyDefault{}, GetArenaForAllocation());
|
||||
}
|
||||
inline std::string* IntroductionFrame::release_service_id_hash_salt() {
|
||||
// @@protoc_insertion_point(field_release:location.nearby.mediums.IntroductionFrame.service_id_hash_salt)
|
||||
if (!_internal_has_service_id_hash_salt()) {
|
||||
return nullptr;
|
||||
}
|
||||
_has_bits_[0] &= ~0x00000002u;
|
||||
auto* p = service_id_hash_salt_.ReleaseNonDefault(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited(), GetArenaForAllocation());
|
||||
#ifdef PROTOBUF_FORCE_COPY_DEFAULT_STRING
|
||||
if (service_id_hash_salt_.IsDefault(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited())) {
|
||||
service_id_hash_salt_.Set(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited(), "", GetArenaForAllocation());
|
||||
}
|
||||
#endif // PROTOBUF_FORCE_COPY_DEFAULT_STRING
|
||||
return p;
|
||||
}
|
||||
inline void IntroductionFrame::set_allocated_service_id_hash_salt(std::string* service_id_hash_salt) {
|
||||
if (service_id_hash_salt != nullptr) {
|
||||
_has_bits_[0] |= 0x00000002u;
|
||||
} else {
|
||||
_has_bits_[0] &= ~0x00000002u;
|
||||
}
|
||||
service_id_hash_salt_.SetAllocated(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited(), service_id_hash_salt,
|
||||
GetArenaForAllocation());
|
||||
#ifdef PROTOBUF_FORCE_COPY_DEFAULT_STRING
|
||||
if (service_id_hash_salt_.IsDefault(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited())) {
|
||||
service_id_hash_salt_.Set(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited(), "", GetArenaForAllocation());
|
||||
}
|
||||
#endif // PROTOBUF_FORCE_COPY_DEFAULT_STRING
|
||||
// @@protoc_insertion_point(field_set_allocated:location.nearby.mediums.IntroductionFrame.service_id_hash_salt)
|
||||
}
|
||||
|
||||
// -------------------------------------------------------------------
|
||||
|
||||
// DisconnectionFrame
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
@@ -117,11 +117,16 @@ enum EventType : int {
|
||||
DEFAULT_OPT_IN = 56,
|
||||
SETUP_WIZARD = 57,
|
||||
TAP_QR_CODE = 58,
|
||||
QR_CODE_LINK_SHOWN = 59
|
||||
QR_CODE_LINK_SHOWN = 59,
|
||||
PARSING_FAILED_ENDPOINT_ID = 60,
|
||||
FAST_INIT_DISCOVER_DEVICE = 61,
|
||||
SEND_DESKTOP_NOTIFICATION = 62,
|
||||
SET_ACCOUNT = 63,
|
||||
DECRYPT_CERTIFICATE_FAILURE = 64
|
||||
};
|
||||
bool EventType_IsValid(int value);
|
||||
constexpr EventType EventType_MIN = UNKNOWN_EVENT_TYPE;
|
||||
constexpr EventType EventType_MAX = QR_CODE_LINK_SHOWN;
|
||||
constexpr EventType EventType_MAX = DECRYPT_CERTIFICATE_FAILURE;
|
||||
constexpr int EventType_ARRAYSIZE = EventType_MAX + 1;
|
||||
|
||||
const std::string& EventType_Name(EventType value);
|
||||
@@ -258,11 +263,15 @@ enum AttachmentTransmissionStatus : int {
|
||||
FAILED_NULL_CONNECTION = 14,
|
||||
FAILED_NO_PAYLOAD = 15,
|
||||
FAILED_WRITE_INTRODUCTION = 16,
|
||||
FAILED_UNKNOWN_REMOTE_RESPONSE = 17
|
||||
FAILED_UNKNOWN_REMOTE_RESPONSE = 17,
|
||||
FAILED_NULL_CONNECTION_INIT_OUTGOING = 18,
|
||||
FAILED_NULL_CONNECTION_DISCONNECTED = 19,
|
||||
FAILED_NULL_CONNECTION_LOST_CONNECTIVITY = 20,
|
||||
FAILED_NULL_CONNECTION_FAILURE = 21
|
||||
};
|
||||
bool AttachmentTransmissionStatus_IsValid(int value);
|
||||
constexpr AttachmentTransmissionStatus AttachmentTransmissionStatus_MIN = UNKNOWN_ATTACHMENT_TRANSMISSION_STATUS;
|
||||
constexpr AttachmentTransmissionStatus AttachmentTransmissionStatus_MAX = FAILED_UNKNOWN_REMOTE_RESPONSE;
|
||||
constexpr AttachmentTransmissionStatus AttachmentTransmissionStatus_MAX = FAILED_NULL_CONNECTION_FAILURE;
|
||||
constexpr int AttachmentTransmissionStatus_ARRAYSIZE = AttachmentTransmissionStatus_MAX + 1;
|
||||
|
||||
const std::string& AttachmentTransmissionStatus_Name(AttachmentTransmissionStatus value);
|
||||
@@ -275,6 +284,42 @@ inline const std::string& AttachmentTransmissionStatus_Name(T enum_t_value) {
|
||||
}
|
||||
bool AttachmentTransmissionStatus_Parse(
|
||||
::PROTOBUF_NAMESPACE_ID::ConstStringParam name, AttachmentTransmissionStatus* value);
|
||||
enum ConnectionLayerStatus : int {
|
||||
CONNECTION_LAYER_STATUS_UNKNOWN = 0,
|
||||
CONNECTION_LAYER_STATUS_SUCCESS = 1,
|
||||
CONNECTION_LAYER_STATUS_ERROR = 2,
|
||||
CONNECTION_LAYER_STATUS_OUT_OF_ORDER_API_CALL = 3,
|
||||
CONNECTION_LAYER_STATUS_ALREADY_HAVE_ACTIVE_STRATEGY = 4,
|
||||
CONNECTION_LAYER_STATUS_ALREADY_ADVERTISING = 5,
|
||||
CONNECTION_LAYER_STATUS_ALREADY_DISCOVERING = 6,
|
||||
CONNECTION_LAYER_STATUS_ALREADY_LISTENING = 7,
|
||||
CONNECTION_LAYER_STATUS_END_POINT_IO_ERROR = 8,
|
||||
CONNECTION_LAYER_STATUS_END_POINT_UNKNOWN = 9,
|
||||
CONNECTION_LAYER_STATUS_CONNECTION_REJECTED = 10,
|
||||
CONNECTION_LAYER_STATUS_ALREADY_CONNECTED_TO_END_POINT = 11,
|
||||
CONNECTION_LAYER_STATUS_NOT_CONNECTED_TO_END_POINT = 12,
|
||||
CONNECTION_LAYER_STATUS_BLUETOOTH_ERROR = 13,
|
||||
CONNECTION_LAYER_STATUS_BLE_ERROR = 14,
|
||||
CONNECTION_LAYER_STATUS_WIFI_LAN_ERROR = 15,
|
||||
CONNECTION_LAYER_STATUS_PAYLOAD_UNKNOWN = 16,
|
||||
CONNECTION_LAYER_STATUS_RESET = 17,
|
||||
CONNECTION_LAYER_STATUS_TIMEOUT = 18
|
||||
};
|
||||
bool ConnectionLayerStatus_IsValid(int value);
|
||||
constexpr ConnectionLayerStatus ConnectionLayerStatus_MIN = CONNECTION_LAYER_STATUS_UNKNOWN;
|
||||
constexpr ConnectionLayerStatus ConnectionLayerStatus_MAX = CONNECTION_LAYER_STATUS_TIMEOUT;
|
||||
constexpr int ConnectionLayerStatus_ARRAYSIZE = ConnectionLayerStatus_MAX + 1;
|
||||
|
||||
const std::string& ConnectionLayerStatus_Name(ConnectionLayerStatus value);
|
||||
template<typename T>
|
||||
inline const std::string& ConnectionLayerStatus_Name(T enum_t_value) {
|
||||
static_assert(::std::is_same<T, ConnectionLayerStatus>::value ||
|
||||
::std::is_integral<T>::value,
|
||||
"Incorrect type passed to function ConnectionLayerStatus_Name.");
|
||||
return ConnectionLayerStatus_Name(static_cast<ConnectionLayerStatus>(enum_t_value));
|
||||
}
|
||||
bool ConnectionLayerStatus_Parse(
|
||||
::PROTOBUF_NAMESPACE_ID::ConstStringParam name, ConnectionLayerStatus* value);
|
||||
enum ProcessReceivedAttachmentsStatus : int {
|
||||
PROCESSING_STATUS_UNKNOWN = 0,
|
||||
PROCESSING_STATUS_COMPLETE_PROCESSING_ATTACHMENTS = 1,
|
||||
@@ -483,6 +528,59 @@ inline const std::string& ServerResponseState_Name(T enum_t_value) {
|
||||
}
|
||||
bool ServerResponseState_Parse(
|
||||
::PROTOBUF_NAMESPACE_ID::ConstStringParam name, ServerResponseState* value);
|
||||
enum SyncPurpose : int {
|
||||
SYNC_PURPOSE_UNKNOWN = 0,
|
||||
SYNC_PURPOSE_ON_DEMAND_SYNC = 1,
|
||||
SYNC_PURPOSE_CHIME_NOTIFICATION = 2,
|
||||
SYNC_PURPOSE_DAILY_SYNC = 3,
|
||||
SYNC_PURPOSE_OPT_IN_FIRST_SYNC = 4,
|
||||
SYNC_PURPOSE_CHECK_DEFAULT_OPT_IN = 5,
|
||||
SYNC_PURPOSE_NEARBY_SHARE_ENABLED = 6,
|
||||
SYNC_PURPOSE_SYNC_AT_FAST_INIT = 7,
|
||||
SYNC_PURPOSE_SYNC_AT_DISCOVERY = 8,
|
||||
SYNC_PURPOSE_SYNC_AT_LOAD_PRIVATE_CERTIFICATE = 9,
|
||||
SYNC_PURPOSE_SYNC_AT_ADVERTISEMENT = 10,
|
||||
SYNC_PURPOSE_CONTACT_LIST_CHANGE = 11,
|
||||
SYNC_PURPOSE_SHOW_C11N_VIEW = 12,
|
||||
SYNC_PURPOSE_REGULAR_CHECK_CONTACT_REACHABILITY = 13,
|
||||
SYNC_PURPOSE_VISIBILITY_SELECTED_CONTACT_CHANGE = 14,
|
||||
SYNC_PURPOSE_ACCOUNT_CHANGE = 15
|
||||
};
|
||||
bool SyncPurpose_IsValid(int value);
|
||||
constexpr SyncPurpose SyncPurpose_MIN = SYNC_PURPOSE_UNKNOWN;
|
||||
constexpr SyncPurpose SyncPurpose_MAX = SYNC_PURPOSE_ACCOUNT_CHANGE;
|
||||
constexpr int SyncPurpose_ARRAYSIZE = SyncPurpose_MAX + 1;
|
||||
|
||||
const std::string& SyncPurpose_Name(SyncPurpose value);
|
||||
template<typename T>
|
||||
inline const std::string& SyncPurpose_Name(T enum_t_value) {
|
||||
static_assert(::std::is_same<T, SyncPurpose>::value ||
|
||||
::std::is_integral<T>::value,
|
||||
"Incorrect type passed to function SyncPurpose_Name.");
|
||||
return SyncPurpose_Name(static_cast<SyncPurpose>(enum_t_value));
|
||||
}
|
||||
bool SyncPurpose_Parse(
|
||||
::PROTOBUF_NAMESPACE_ID::ConstStringParam name, SyncPurpose* value);
|
||||
enum ClientRole : int {
|
||||
CLIENT_ROLE_UNKNOWN = 0,
|
||||
CLIENT_ROLE_SENDER = 1,
|
||||
CLIENT_ROLE_RECEIVER = 2
|
||||
};
|
||||
bool ClientRole_IsValid(int value);
|
||||
constexpr ClientRole ClientRole_MIN = CLIENT_ROLE_UNKNOWN;
|
||||
constexpr ClientRole ClientRole_MAX = CLIENT_ROLE_RECEIVER;
|
||||
constexpr int ClientRole_ARRAYSIZE = ClientRole_MAX + 1;
|
||||
|
||||
const std::string& ClientRole_Name(ClientRole value);
|
||||
template<typename T>
|
||||
inline const std::string& ClientRole_Name(T enum_t_value) {
|
||||
static_assert(::std::is_same<T, ClientRole>::value ||
|
||||
::std::is_integral<T>::value,
|
||||
"Incorrect type passed to function ClientRole_Name.");
|
||||
return ClientRole_Name(static_cast<ClientRole>(enum_t_value));
|
||||
}
|
||||
bool ClientRole_Parse(
|
||||
::PROTOBUF_NAMESPACE_ID::ConstStringParam name, ClientRole* value);
|
||||
enum ScanType : int {
|
||||
UNKNOWN_SCAN_TYPE = 0,
|
||||
FOREGROUND_SCAN = 1,
|
||||
@@ -505,6 +603,26 @@ inline const std::string& ScanType_Name(T enum_t_value) {
|
||||
}
|
||||
bool ScanType_Parse(
|
||||
::PROTOBUF_NAMESPACE_ID::ConstStringParam name, ScanType* value);
|
||||
enum ParsingFailedType : int {
|
||||
FAILED_UNKNOWN_TYPE = 0,
|
||||
FAILED_PARSE_ADVERTISEMENT = 1,
|
||||
FAILED_CONVERT_SHARE_TARGET = 2
|
||||
};
|
||||
bool ParsingFailedType_IsValid(int value);
|
||||
constexpr ParsingFailedType ParsingFailedType_MIN = FAILED_UNKNOWN_TYPE;
|
||||
constexpr ParsingFailedType ParsingFailedType_MAX = FAILED_CONVERT_SHARE_TARGET;
|
||||
constexpr int ParsingFailedType_ARRAYSIZE = ParsingFailedType_MAX + 1;
|
||||
|
||||
const std::string& ParsingFailedType_Name(ParsingFailedType value);
|
||||
template<typename T>
|
||||
inline const std::string& ParsingFailedType_Name(T enum_t_value) {
|
||||
static_assert(::std::is_same<T, ParsingFailedType>::value ||
|
||||
::std::is_integral<T>::value,
|
||||
"Incorrect type passed to function ParsingFailedType_Name.");
|
||||
return ParsingFailedType_Name(static_cast<ParsingFailedType>(enum_t_value));
|
||||
}
|
||||
bool ParsingFailedType_Parse(
|
||||
::PROTOBUF_NAMESPACE_ID::ConstStringParam name, ParsingFailedType* value);
|
||||
enum AdvertisingMode : int {
|
||||
UNKNOWN_ADVERTISING_MODE = 0,
|
||||
SCREEN_OFF_ADVERTISING_MODE = 1,
|
||||
@@ -838,6 +956,121 @@ inline const std::string& PreferencesActionStatus_Name(T enum_t_value) {
|
||||
}
|
||||
bool PreferencesActionStatus_Parse(
|
||||
::PROTOBUF_NAMESPACE_ID::ConstStringParam name, PreferencesActionStatus* value);
|
||||
enum FastInitState : int {
|
||||
FAST_INIT_UNKNOWN_STATE = 0,
|
||||
FAST_INIT_CLOSE_STATE = 1,
|
||||
FAST_INIT_FAR_STATE = 2,
|
||||
FAST_INIT_LOST_STATE = 3
|
||||
};
|
||||
bool FastInitState_IsValid(int value);
|
||||
constexpr FastInitState FastInitState_MIN = FAST_INIT_UNKNOWN_STATE;
|
||||
constexpr FastInitState FastInitState_MAX = FAST_INIT_LOST_STATE;
|
||||
constexpr int FastInitState_ARRAYSIZE = FastInitState_MAX + 1;
|
||||
|
||||
const std::string& FastInitState_Name(FastInitState value);
|
||||
template<typename T>
|
||||
inline const std::string& FastInitState_Name(T enum_t_value) {
|
||||
static_assert(::std::is_same<T, FastInitState>::value ||
|
||||
::std::is_integral<T>::value,
|
||||
"Incorrect type passed to function FastInitState_Name.");
|
||||
return FastInitState_Name(static_cast<FastInitState>(enum_t_value));
|
||||
}
|
||||
bool FastInitState_Parse(
|
||||
::PROTOBUF_NAMESPACE_ID::ConstStringParam name, FastInitState* value);
|
||||
enum FastInitType : int {
|
||||
FAST_INIT_UNKNOWN_TYPE = 0,
|
||||
FAST_INIT_NOTIFY_TYPE = 1,
|
||||
FAST_INIT_SILENT_TYPE = 2
|
||||
};
|
||||
bool FastInitType_IsValid(int value);
|
||||
constexpr FastInitType FastInitType_MIN = FAST_INIT_UNKNOWN_TYPE;
|
||||
constexpr FastInitType FastInitType_MAX = FAST_INIT_SILENT_TYPE;
|
||||
constexpr int FastInitType_ARRAYSIZE = FastInitType_MAX + 1;
|
||||
|
||||
const std::string& FastInitType_Name(FastInitType value);
|
||||
template<typename T>
|
||||
inline const std::string& FastInitType_Name(T enum_t_value) {
|
||||
static_assert(::std::is_same<T, FastInitType>::value ||
|
||||
::std::is_integral<T>::value,
|
||||
"Incorrect type passed to function FastInitType_Name.");
|
||||
return FastInitType_Name(static_cast<FastInitType>(enum_t_value));
|
||||
}
|
||||
bool FastInitType_Parse(
|
||||
::PROTOBUF_NAMESPACE_ID::ConstStringParam name, FastInitType* value);
|
||||
enum DesktopNotification : int {
|
||||
DESKTOP_NOTIFICATION_UNKNOWN = 0,
|
||||
DESKTOP_NOTIFICATION_CONNECTING = 1,
|
||||
DESKTOP_NOTIFICATION_PROGRESS = 2,
|
||||
DESKTOP_NOTIFICATION_ACCEPT = 3,
|
||||
DESKTOP_NOTIFICATION_RECEIVED = 4,
|
||||
DESKTOP_NOTIFICATION_ERROR = 5
|
||||
};
|
||||
bool DesktopNotification_IsValid(int value);
|
||||
constexpr DesktopNotification DesktopNotification_MIN = DESKTOP_NOTIFICATION_UNKNOWN;
|
||||
constexpr DesktopNotification DesktopNotification_MAX = DESKTOP_NOTIFICATION_ERROR;
|
||||
constexpr int DesktopNotification_ARRAYSIZE = DesktopNotification_MAX + 1;
|
||||
|
||||
const std::string& DesktopNotification_Name(DesktopNotification value);
|
||||
template<typename T>
|
||||
inline const std::string& DesktopNotification_Name(T enum_t_value) {
|
||||
static_assert(::std::is_same<T, DesktopNotification>::value ||
|
||||
::std::is_integral<T>::value,
|
||||
"Incorrect type passed to function DesktopNotification_Name.");
|
||||
return DesktopNotification_Name(static_cast<DesktopNotification>(enum_t_value));
|
||||
}
|
||||
bool DesktopNotification_Parse(
|
||||
::PROTOBUF_NAMESPACE_ID::ConstStringParam name, DesktopNotification* value);
|
||||
enum DesktopTransferEventType : int {
|
||||
DESKTOP_TRANSFER_EVENT_TYPE_UNKNOWN = 0,
|
||||
DESKTOP_TRANSFER_EVENT_RECEIVE_TYPE_ACCEPT = 1,
|
||||
DESKTOP_TRANSFER_EVENT_RECEIVE_TYPE_PROGRESS = 2,
|
||||
DESKTOP_TRANSFER_EVENT_RECEIVE_TYPE_RECEIVED = 3,
|
||||
DESKTOP_TRANSFER_EVENT_RECEIVE_TYPE_ERROR = 4,
|
||||
DESKTOP_TRANSFER_EVENT_SEND_TYPE_START = 5,
|
||||
DESKTOP_TRANSFER_EVENT_SEND_TYPE_SELECT_A_DEVICE = 6,
|
||||
DESKTOP_TRANSFER_EVENT_SEND_TYPE_PROGRESS = 7,
|
||||
DESKTOP_TRANSFER_EVENT_SEND_TYPE_SENT = 8,
|
||||
DESKTOP_TRANSFER_EVENT_SEND_TYPE_ERROR = 9
|
||||
};
|
||||
bool DesktopTransferEventType_IsValid(int value);
|
||||
constexpr DesktopTransferEventType DesktopTransferEventType_MIN = DESKTOP_TRANSFER_EVENT_TYPE_UNKNOWN;
|
||||
constexpr DesktopTransferEventType DesktopTransferEventType_MAX = DESKTOP_TRANSFER_EVENT_SEND_TYPE_ERROR;
|
||||
constexpr int DesktopTransferEventType_ARRAYSIZE = DesktopTransferEventType_MAX + 1;
|
||||
|
||||
const std::string& DesktopTransferEventType_Name(DesktopTransferEventType value);
|
||||
template<typename T>
|
||||
inline const std::string& DesktopTransferEventType_Name(T enum_t_value) {
|
||||
static_assert(::std::is_same<T, DesktopTransferEventType>::value ||
|
||||
::std::is_integral<T>::value,
|
||||
"Incorrect type passed to function DesktopTransferEventType_Name.");
|
||||
return DesktopTransferEventType_Name(static_cast<DesktopTransferEventType>(enum_t_value));
|
||||
}
|
||||
bool DesktopTransferEventType_Parse(
|
||||
::PROTOBUF_NAMESPACE_ID::ConstStringParam name, DesktopTransferEventType* value);
|
||||
enum DecryptCertificateFailureStatus : int {
|
||||
DECRYPT_CERT_UNKNOWN_FAILURE = 0,
|
||||
DECRYPT_CERT_NO_SUCH_ALGORITHM_FAILURE = 1,
|
||||
DECRYPT_CERT_NO_SUCH_PADDING_FAILURE = 2,
|
||||
DECRYPT_CERT_INVALID_KEY_FAILURE = 3,
|
||||
DECRYPT_CERT_INVALID_ALGORITHM_PARAMETER_FAILURE = 4,
|
||||
DECRYPT_CERT_ILLEGAL_BLOCK_SIZE_FAILURE = 5,
|
||||
DECRYPT_CERT_BAD_PADDING_FAILURE = 6
|
||||
};
|
||||
bool DecryptCertificateFailureStatus_IsValid(int value);
|
||||
constexpr DecryptCertificateFailureStatus DecryptCertificateFailureStatus_MIN = DECRYPT_CERT_UNKNOWN_FAILURE;
|
||||
constexpr DecryptCertificateFailureStatus DecryptCertificateFailureStatus_MAX = DECRYPT_CERT_BAD_PADDING_FAILURE;
|
||||
constexpr int DecryptCertificateFailureStatus_ARRAYSIZE = DecryptCertificateFailureStatus_MAX + 1;
|
||||
|
||||
const std::string& DecryptCertificateFailureStatus_Name(DecryptCertificateFailureStatus value);
|
||||
template<typename T>
|
||||
inline const std::string& DecryptCertificateFailureStatus_Name(T enum_t_value) {
|
||||
static_assert(::std::is_same<T, DecryptCertificateFailureStatus>::value ||
|
||||
::std::is_integral<T>::value,
|
||||
"Incorrect type passed to function DecryptCertificateFailureStatus_Name.");
|
||||
return DecryptCertificateFailureStatus_Name(static_cast<DecryptCertificateFailureStatus>(enum_t_value));
|
||||
}
|
||||
bool DecryptCertificateFailureStatus_Parse(
|
||||
::PROTOBUF_NAMESPACE_ID::ConstStringParam name, DecryptCertificateFailureStatus* value);
|
||||
// ===================================================================
|
||||
|
||||
|
||||
@@ -870,6 +1103,7 @@ template <> struct is_proto_enum< ::location::nearby::proto::sharing::Visibility
|
||||
template <> struct is_proto_enum< ::location::nearby::proto::sharing::DataUsage> : ::std::true_type {};
|
||||
template <> struct is_proto_enum< ::location::nearby::proto::sharing::EstablishConnectionStatus> : ::std::true_type {};
|
||||
template <> struct is_proto_enum< ::location::nearby::proto::sharing::AttachmentTransmissionStatus> : ::std::true_type {};
|
||||
template <> struct is_proto_enum< ::location::nearby::proto::sharing::ConnectionLayerStatus> : ::std::true_type {};
|
||||
template <> struct is_proto_enum< ::location::nearby::proto::sharing::ProcessReceivedAttachmentsStatus> : ::std::true_type {};
|
||||
template <> struct is_proto_enum< ::location::nearby::proto::sharing::SessionStatus> : ::std::true_type {};
|
||||
template <> struct is_proto_enum< ::location::nearby::proto::sharing::ResponseToIntroduction> : ::std::true_type {};
|
||||
@@ -879,7 +1113,10 @@ template <> struct is_proto_enum< ::location::nearby::proto::sharing::DeviceRela
|
||||
template <> struct is_proto_enum< ::location::nearby::proto::sharing::LogSource> : ::std::true_type {};
|
||||
template <> struct is_proto_enum< ::location::nearby::proto::sharing::ServerActionName> : ::std::true_type {};
|
||||
template <> struct is_proto_enum< ::location::nearby::proto::sharing::ServerResponseState> : ::std::true_type {};
|
||||
template <> struct is_proto_enum< ::location::nearby::proto::sharing::SyncPurpose> : ::std::true_type {};
|
||||
template <> struct is_proto_enum< ::location::nearby::proto::sharing::ClientRole> : ::std::true_type {};
|
||||
template <> struct is_proto_enum< ::location::nearby::proto::sharing::ScanType> : ::std::true_type {};
|
||||
template <> struct is_proto_enum< ::location::nearby::proto::sharing::ParsingFailedType> : ::std::true_type {};
|
||||
template <> struct is_proto_enum< ::location::nearby::proto::sharing::AdvertisingMode> : ::std::true_type {};
|
||||
template <> struct is_proto_enum< ::location::nearby::proto::sharing::ActivityName> : ::std::true_type {};
|
||||
template <> struct is_proto_enum< ::location::nearby::proto::sharing::ConsentType> : ::std::true_type {};
|
||||
@@ -895,6 +1132,11 @@ template <> struct is_proto_enum< ::location::nearby::proto::sharing::AppCrashRe
|
||||
template <> struct is_proto_enum< ::location::nearby::proto::sharing::AttachmentSourceType> : ::std::true_type {};
|
||||
template <> struct is_proto_enum< ::location::nearby::proto::sharing::PreferencesAction> : ::std::true_type {};
|
||||
template <> struct is_proto_enum< ::location::nearby::proto::sharing::PreferencesActionStatus> : ::std::true_type {};
|
||||
template <> struct is_proto_enum< ::location::nearby::proto::sharing::FastInitState> : ::std::true_type {};
|
||||
template <> struct is_proto_enum< ::location::nearby::proto::sharing::FastInitType> : ::std::true_type {};
|
||||
template <> struct is_proto_enum< ::location::nearby::proto::sharing::DesktopNotification> : ::std::true_type {};
|
||||
template <> struct is_proto_enum< ::location::nearby::proto::sharing::DesktopTransferEventType> : ::std::true_type {};
|
||||
template <> struct is_proto_enum< ::location::nearby::proto::sharing::DecryptCertificateFailureStatus> : ::std::true_type {};
|
||||
|
||||
PROTOBUF_NAMESPACE_CLOSE
|
||||
|
||||
|
||||
@@ -35,7 +35,6 @@ cc_library(
|
||||
"//internal/analytics:event_logger",
|
||||
"//internal/interop:device",
|
||||
"//internal/platform:base",
|
||||
"//internal/platform:logging",
|
||||
"//internal/platform:types",
|
||||
"@com_google_absl//absl/strings",
|
||||
"@com_google_absl//absl/time",
|
||||
@@ -102,7 +101,6 @@ cc_test(
|
||||
"//connections/implementation:internal_test",
|
||||
"//connections/v3:v3_types",
|
||||
"//internal/platform:base",
|
||||
"//internal/platform:logging",
|
||||
"//internal/platform:types",
|
||||
"//internal/platform/implementation/g3", # build_cleaner: keep
|
||||
"@com_github_protobuf_matchers//protobuf-matchers",
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
// Copyright 2021 Google LLC
|
||||
// Copyright 2023 Google LLC
|
||||
//
|
||||
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||
// you may not use this file except in compliance with the License.
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
// Copyright 2021 Google LLC
|
||||
// Copyright 2023 Google LLC
|
||||
//
|
||||
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||
// you may not use this file except in compliance with the License.
|
||||
|
||||
+1
-1
@@ -119,7 +119,7 @@ cc_test(
|
||||
],
|
||||
deps = [
|
||||
"//connections:core",
|
||||
"//internal/platform:logging",
|
||||
"//internal/platform:types",
|
||||
"//internal/platform/implementation/windows",
|
||||
"@com_github_protobuf_matchers//protobuf-matchers",
|
||||
"@com_google_googletest//:gtest_main",
|
||||
|
||||
@@ -117,10 +117,10 @@ TEST(BluetoothClassicServerSocketTest,
|
||||
PerformanceTimer::start();
|
||||
|
||||
core.StartAdvertising(SERVICE_ID, AdvertiseOptions, request_info,
|
||||
{.result_cb = [&](Status status) {
|
||||
[&](Status status) {
|
||||
request_result = status;
|
||||
notification.Notify();
|
||||
}});
|
||||
});
|
||||
|
||||
if (notification.WaitForNotificationWithTimeout(
|
||||
absl::Seconds(TimeoutSeconds))) {
|
||||
@@ -163,10 +163,10 @@ TEST(BluetoothClassicServerSocketTest,
|
||||
PerformanceTimer::start();
|
||||
|
||||
core.StartAdvertising(SERVICE_ID, AdvertiseOptions, request_info,
|
||||
{.result_cb = [&](Status status) {
|
||||
[&](Status status) {
|
||||
request_result = status;
|
||||
notification2.Notify();
|
||||
}});
|
||||
});
|
||||
|
||||
if (notification2.WaitForNotificationWithTimeout(
|
||||
absl::Seconds(TimeoutSeconds))) {
|
||||
@@ -209,10 +209,10 @@ TEST(BluetoothClassicServerSocketTest,
|
||||
|
||||
PerformanceTimer::start();
|
||||
|
||||
core.StopAdvertising({.result_cb = [&](Status status) {
|
||||
core.StopAdvertising([&](Status status) {
|
||||
request_result = status;
|
||||
notification3.Notify();
|
||||
}});
|
||||
});
|
||||
|
||||
if (notification3.WaitForNotificationWithTimeout(
|
||||
absl::Seconds(TimeoutSeconds))) {
|
||||
@@ -273,10 +273,10 @@ TEST(BluetoothClassicServerSocketTest, DISABLED_MultiRunWithTimeoutReproStuck) {
|
||||
PerformanceTimer::start();
|
||||
|
||||
core.StartAdvertising(SERVICE_ID, AdvertiseOptions, request_info,
|
||||
{.result_cb = [&](Status status) {
|
||||
[&](Status status) {
|
||||
request_result = status;
|
||||
notification.Notify();
|
||||
}});
|
||||
});
|
||||
|
||||
if (notification.WaitForNotificationWithTimeout(
|
||||
absl::Seconds(TimeoutSeconds))) {
|
||||
@@ -319,10 +319,10 @@ TEST(BluetoothClassicServerSocketTest, DISABLED_MultiRunWithTimeoutReproStuck) {
|
||||
PerformanceTimer::start();
|
||||
|
||||
core.StartAdvertising(SERVICE_ID, AdvertiseOptions, request_info,
|
||||
{.result_cb = [&](Status status) {
|
||||
[&](Status status) {
|
||||
request_result = status;
|
||||
notification2.Notify();
|
||||
}});
|
||||
});
|
||||
|
||||
if (notification2.WaitForNotificationWithTimeout(
|
||||
absl::Seconds(TimeoutSeconds))) {
|
||||
@@ -361,10 +361,10 @@ TEST(BluetoothClassicServerSocketTest, DISABLED_MultiRunWithTimeoutReproStuck) {
|
||||
|
||||
PerformanceTimer::start();
|
||||
|
||||
core.StopAdvertising({.result_cb = [&](Status status) {
|
||||
core.StopAdvertising([&](Status status) {
|
||||
request_result = status;
|
||||
notification3.Notify();
|
||||
}});
|
||||
});
|
||||
|
||||
if (notification3.WaitForNotificationWithTimeout(
|
||||
absl::Seconds(TimeoutSeconds))) {
|
||||
@@ -424,10 +424,10 @@ TEST(BluetoothClassicServerSocketTest, DISABLED_SingleRunNoTimeoutReproStuck) {
|
||||
PerformanceTimer::start();
|
||||
|
||||
core.StartAdvertising(SERVICE_ID, AdvertiseOptions, request_info,
|
||||
{.result_cb = [&](Status status) {
|
||||
[&](Status status) {
|
||||
request_result = status;
|
||||
notification.Notify();
|
||||
}});
|
||||
});
|
||||
|
||||
notification.WaitForNotification();
|
||||
PerformanceTimer::stop();
|
||||
@@ -451,10 +451,10 @@ TEST(BluetoothClassicServerSocketTest, DISABLED_SingleRunNoTimeoutReproStuck) {
|
||||
PerformanceTimer::start();
|
||||
|
||||
core.StartAdvertising(SERVICE_ID, AdvertiseOptions, request_info,
|
||||
{.result_cb = [&](Status status) {
|
||||
[&](Status status) {
|
||||
request_result = status;
|
||||
notification2.Notify();
|
||||
}});
|
||||
});
|
||||
|
||||
notification2.WaitForNotification();
|
||||
PerformanceTimer::stop();
|
||||
@@ -477,10 +477,10 @@ TEST(BluetoothClassicServerSocketTest, DISABLED_SingleRunNoTimeoutReproStuck) {
|
||||
|
||||
PerformanceTimer::start();
|
||||
|
||||
core.StopAdvertising({.result_cb = [&](Status status) {
|
||||
core.StopAdvertising([&](Status status) {
|
||||
request_result = status;
|
||||
notification3.Notify();
|
||||
}});
|
||||
});
|
||||
|
||||
notification3.WaitForNotification();
|
||||
PerformanceTimer::stop();
|
||||
@@ -521,10 +521,10 @@ TEST(BluetoothClassicServerSocketTest, DISABLED_MultiRunNoTimeoutReproStuck) {
|
||||
PerformanceTimer::start();
|
||||
|
||||
core.StartAdvertising(SERVICE_ID, AdvertiseOptions, request_info,
|
||||
{.result_cb = [&](Status status) {
|
||||
[&](Status status) {
|
||||
request_result = status;
|
||||
notification.Notify();
|
||||
}});
|
||||
});
|
||||
|
||||
notification.WaitForNotification();
|
||||
|
||||
@@ -551,10 +551,10 @@ TEST(BluetoothClassicServerSocketTest, DISABLED_MultiRunNoTimeoutReproStuck) {
|
||||
PerformanceTimer::start();
|
||||
|
||||
core.StartAdvertising(SERVICE_ID, AdvertiseOptions, request_info,
|
||||
{.result_cb = [&](Status status) {
|
||||
[&](Status status) {
|
||||
request_result = status;
|
||||
notification2.Notify();
|
||||
}});
|
||||
});
|
||||
|
||||
notification2.WaitForNotification();
|
||||
PerformanceTimer::stop();
|
||||
@@ -580,10 +580,10 @@ TEST(BluetoothClassicServerSocketTest, DISABLED_MultiRunNoTimeoutReproStuck) {
|
||||
|
||||
PerformanceTimer::start();
|
||||
|
||||
core.StopAdvertising({.result_cb = [&](Status status) {
|
||||
core.StopAdvertising([&](Status status) {
|
||||
request_result = status;
|
||||
notification3.Notify();
|
||||
}});
|
||||
});
|
||||
|
||||
notification3.WaitForNotification();
|
||||
PerformanceTimer::stop();
|
||||
|
||||
@@ -32,8 +32,7 @@ void CloseCore(Core *pCore) {
|
||||
if (pCore == nullptr) {
|
||||
return;
|
||||
}
|
||||
pCore->StopAllEndpoints(
|
||||
{.result_cb = std::function<void(Status)>{[](Status) {}}});
|
||||
pCore->StopAllEndpoints([](Status) {});
|
||||
delete pCore;
|
||||
}
|
||||
|
||||
@@ -80,14 +79,14 @@ void StartAdvertising(Core *pCore, const char *service_id,
|
||||
advertising_options.strategy = connections::Strategy::kP2pStar;
|
||||
|
||||
pCore->StartAdvertising(service_id, advertising_options, crInfo,
|
||||
*callback.GetImpl());
|
||||
std::move(*callback.GetImpl()));
|
||||
}
|
||||
|
||||
void StopAdvertising(connections::Core *pCore, ResultCallbackW callback) {
|
||||
if (pCore == nullptr) {
|
||||
return;
|
||||
}
|
||||
pCore->StopAdvertising(*callback.GetImpl());
|
||||
pCore->StopAdvertising(std::move(*callback.GetImpl()));
|
||||
}
|
||||
|
||||
void StartDiscovery(connections::Core *pCore, const char *service_id,
|
||||
@@ -134,7 +133,7 @@ void StopDiscovery(connections::Core *pCore, ResultCallbackW callback) {
|
||||
if (pCore == nullptr) {
|
||||
return;
|
||||
}
|
||||
pCore->StopDiscovery(*callback.GetImpl());
|
||||
pCore->StopDiscovery(std::move(*callback.GetImpl()));
|
||||
}
|
||||
|
||||
void InjectEndpoint(connections::Core *pCore, char *service_id,
|
||||
@@ -153,7 +152,7 @@ void InjectEndpoint(connections::Core *pCore, char *service_id,
|
||||
metadata.remote_bluetooth_mac_address_size};
|
||||
|
||||
pCore->InjectEndpoint(service_id, outOfBandConnectionMetadata,
|
||||
*callback.GetImpl());
|
||||
std::move(*callback.GetImpl()));
|
||||
}
|
||||
|
||||
void RequestConnection(connections::Core *pCore, const char *endpoint_id,
|
||||
@@ -203,7 +202,7 @@ void RequestConnection(connections::Core *pCore, const char *endpoint_id,
|
||||
connection_options.strategy = connections::Strategy::kP2pStar;
|
||||
|
||||
pCore->RequestConnection(endpoint_id, connectionRequestInfo,
|
||||
connection_options, *callback.GetImpl());
|
||||
connection_options, std::move(*callback.GetImpl()));
|
||||
}
|
||||
|
||||
void AcceptConnection(connections::Core *pCore, const char *endpoint_id,
|
||||
@@ -214,7 +213,7 @@ void AcceptConnection(connections::Core *pCore, const char *endpoint_id,
|
||||
connections::PayloadListener payload_listener =
|
||||
std::move(*listener.GetImpl());
|
||||
pCore->AcceptConnection(endpoint_id, std::move(payload_listener),
|
||||
*callback.GetImpl());
|
||||
std::move(*callback.GetImpl()));
|
||||
}
|
||||
|
||||
void RejectConnection(connections::Core *pCore, const char *endpoint_id,
|
||||
@@ -222,7 +221,7 @@ void RejectConnection(connections::Core *pCore, const char *endpoint_id,
|
||||
if (pCore == nullptr) {
|
||||
return;
|
||||
}
|
||||
pCore->RejectConnection(endpoint_id, *callback.GetImpl());
|
||||
pCore->RejectConnection(endpoint_id, std::move(*callback.GetImpl()));
|
||||
}
|
||||
|
||||
void SendPayload(connections::Core *pCore,
|
||||
@@ -235,7 +234,8 @@ void SendPayload(connections::Core *pCore,
|
||||
}
|
||||
std::string payloadData = std::string(*endpoint_ids);
|
||||
absl::Span<const std::string> span{&payloadData, 1};
|
||||
pCore->SendPayload(span, std::move(*payloadw.GetImpl()), *callback.GetImpl());
|
||||
pCore->SendPayload(span, std::move(*payloadw.GetImpl()),
|
||||
std::move(*callback.GetImpl()));
|
||||
}
|
||||
|
||||
void CancelPayload(connections::Core *pCore, std::int64_t payload_id,
|
||||
@@ -243,7 +243,7 @@ void CancelPayload(connections::Core *pCore, std::int64_t payload_id,
|
||||
if (pCore == nullptr) {
|
||||
return;
|
||||
}
|
||||
pCore->CancelPayload(payload_id, *callback.GetImpl());
|
||||
pCore->CancelPayload(payload_id, std::move(*callback.GetImpl()));
|
||||
}
|
||||
|
||||
void DisconnectFromEndpoint(connections::Core *pCore, const char *endpoint_id,
|
||||
@@ -251,14 +251,14 @@ void DisconnectFromEndpoint(connections::Core *pCore, const char *endpoint_id,
|
||||
if (pCore == nullptr) {
|
||||
return;
|
||||
}
|
||||
pCore->DisconnectFromEndpoint(endpoint_id, *callback.GetImpl());
|
||||
pCore->DisconnectFromEndpoint(endpoint_id, std::move(*callback.GetImpl()));
|
||||
}
|
||||
|
||||
void StopAllEndpoints(connections::Core *pCore, ResultCallbackW callback) {
|
||||
if (pCore == nullptr) {
|
||||
return;
|
||||
}
|
||||
pCore->StopAllEndpoints(*callback.GetImpl());
|
||||
pCore->StopAllEndpoints(std::move(*callback.GetImpl()));
|
||||
}
|
||||
|
||||
void InitiateBandwidthUpgrade(connections::Core *pCore, char *endpoint_id,
|
||||
@@ -266,7 +266,7 @@ void InitiateBandwidthUpgrade(connections::Core *pCore, char *endpoint_id,
|
||||
if (pCore == nullptr) {
|
||||
return;
|
||||
}
|
||||
pCore->InitiateBandwidthUpgrade(endpoint_id, *callback.GetImpl());
|
||||
pCore->InitiateBandwidthUpgrade(endpoint_id, std::move(*callback.GetImpl()));
|
||||
}
|
||||
|
||||
const char *GetLocalEndpointId(connections::Core *pCore) {
|
||||
|
||||
@@ -12,6 +12,9 @@
|
||||
// See the License for the specific language governing permissions and
|
||||
// limitations under the License.
|
||||
|
||||
#include <memory>
|
||||
#include <utility>
|
||||
|
||||
#include "connections/c/listeners_w.h"
|
||||
|
||||
#include "connections/listeners.h"
|
||||
@@ -20,9 +23,6 @@ namespace nearby {
|
||||
// Must implement Deleters, since the connections classes weren't
|
||||
// fully defined in the header
|
||||
namespace connections {
|
||||
void ResultCallbackDeleter::operator()(connections::ResultCallback *p) {
|
||||
delete p;
|
||||
}
|
||||
void ConnectionListenerDeleter::operator()(connections::ConnectionListener *p) {
|
||||
delete p;
|
||||
}
|
||||
@@ -41,21 +41,18 @@ static ResultCallbackW *ResultCallbackImpl;
|
||||
void ResultCB(Status status) { ResultCallbackImpl->result_cb(status); }
|
||||
|
||||
ResultCallbackW::ResultCallbackW()
|
||||
: impl_(std::unique_ptr<connections::ResultCallback,
|
||||
connections::ResultCallbackDeleter>(
|
||||
new connections::ResultCallback())) {
|
||||
: impl(std::make_unique<connections::ResultCallback>(ResultCB)) {
|
||||
ResultCallbackImpl = this;
|
||||
impl_->result_cb = ResultCB;
|
||||
}
|
||||
|
||||
ResultCallbackW::~ResultCallbackW() {}
|
||||
|
||||
ResultCallbackW::ResultCallbackW(ResultCallbackW &other) {
|
||||
impl_ = std::move(other.impl_);
|
||||
impl = std::move(other.impl);
|
||||
}
|
||||
|
||||
ResultCallbackW::ResultCallbackW(ResultCallbackW &&other) noexcept {
|
||||
impl_ = std::move(other.impl_);
|
||||
impl = std::move(other.impl);
|
||||
}
|
||||
|
||||
ConnectionListenerW::ConnectionListenerW(InitiatedCB initiatedCB,
|
||||
|
||||
@@ -15,10 +15,8 @@
|
||||
#ifndef THIRD_PARTY_NEARBY_CONNECTIONS_C_LISTENERS_W_H_
|
||||
#define THIRD_PARTY_NEARBY_CONNECTIONS_C_LISTENERS_W_H_
|
||||
|
||||
#include <cstdint>
|
||||
#include <functional>
|
||||
#include <memory>
|
||||
#include <string>
|
||||
#include <utility>
|
||||
|
||||
// This file defines all the protocol listeners and their parameter structures.
|
||||
// Listeners are defined as collections of std::function<T> instances, which is
|
||||
@@ -50,10 +48,7 @@ struct DLL_API PayloadListenerDeleter {
|
||||
void operator()(connections::PayloadListener* p);
|
||||
};
|
||||
|
||||
struct ResultCallback;
|
||||
struct ResultCallbackDeleter {
|
||||
void operator()(connections::ResultCallback* p);
|
||||
};
|
||||
using ResultCallback = absl::AnyInvocable<void(Status)>;
|
||||
|
||||
struct ConnectionResponseInfo;
|
||||
struct PayloadProgressInfo;
|
||||
@@ -92,16 +87,12 @@ struct DLL_API ResultCallbackW {
|
||||
|
||||
void (*result_cb)(Status status) = DefaultConstructor;
|
||||
|
||||
std::unique_ptr<connections::ResultCallback,
|
||||
connections::ResultCallbackDeleter>
|
||||
GetImpl() {
|
||||
return std::move(impl_);
|
||||
std::unique_ptr<connections::ResultCallback> GetImpl() {
|
||||
return std::move(impl);
|
||||
}
|
||||
|
||||
private:
|
||||
std::unique_ptr<connections::ResultCallback,
|
||||
connections::ResultCallbackDeleter>
|
||||
impl_;
|
||||
std::unique_ptr<connections::ResultCallback> impl;
|
||||
};
|
||||
|
||||
struct DLL_API ConnectionResponseInfoW {
|
||||
|
||||
@@ -13,9 +13,16 @@
|
||||
// limitations under the License.
|
||||
#include "connections/c/payload_w.h"
|
||||
|
||||
#include <cstddef>
|
||||
#include <cstdint>
|
||||
#include <memory>
|
||||
#include <utility>
|
||||
|
||||
#include "connections/c/file_w.h"
|
||||
#include "connections/payload.h"
|
||||
#include "connections/payload_type.h"
|
||||
#include "internal/platform/byte_array.h"
|
||||
#include "internal/platform/input_stream.h"
|
||||
#include "internal/platform/payload_id.h"
|
||||
|
||||
namespace nearby {
|
||||
@@ -32,7 +39,7 @@ PayloadW::PayloadW()
|
||||
: impl_(std::unique_ptr<connections::Payload, connections::PayloadDeleter>(
|
||||
new connections::Payload())) {}
|
||||
|
||||
PayloadW::~PayloadW() {}
|
||||
PayloadW::~PayloadW() = default;
|
||||
PayloadW::PayloadW(PayloadW &&other) noexcept : impl_(std::move(other.impl_)) {}
|
||||
|
||||
PayloadW &PayloadW::operator=(PayloadW &&other) noexcept {
|
||||
@@ -49,10 +56,9 @@ PayloadW::PayloadW(InputFileW &file)
|
||||
: impl_(std::unique_ptr<connections::Payload, connections::PayloadDeleter>(
|
||||
new connections::Payload(InputFile(std::move(*file.GetImpl()))))) {}
|
||||
|
||||
// TODO(jfcarroll): Convert std::function to function pointer
|
||||
PayloadW::PayloadW(std::function<InputStream &()> stream)
|
||||
PayloadW::PayloadW(std::unique_ptr<InputStream> stream)
|
||||
: impl_(std::unique_ptr<connections::Payload, connections::PayloadDeleter>(
|
||||
new connections::Payload(stream))) {}
|
||||
new connections::Payload(std::move(stream)))) {}
|
||||
|
||||
// Constructors for incoming payloads.
|
||||
PayloadW::PayloadW(PayloadId id, const char *bytes, const size_t bytes_size)
|
||||
@@ -69,9 +75,9 @@ PayloadW::PayloadW(const char *parent_folder, const char *file_name,
|
||||
new connections::Payload(parent_folder, file_name,
|
||||
std::move(*file.GetImpl())))) {}
|
||||
|
||||
PayloadW::PayloadW(PayloadId id, std::function<InputStream &()> stream)
|
||||
PayloadW::PayloadW(PayloadId id, std::unique_ptr<InputStream> stream)
|
||||
: impl_(std::unique_ptr<connections::Payload, connections::PayloadDeleter>(
|
||||
new connections::Payload(id, stream))) {}
|
||||
new connections::Payload(id, std::move(stream)))) {}
|
||||
|
||||
// Returns ByteArray payload, if it has been defined, or empty ByteArray.
|
||||
bool PayloadW::AsBytes(const char *&bytes, size_t &bytes_size) const & {
|
||||
|
||||
@@ -60,19 +60,18 @@ class DLL_API PayloadW {
|
||||
~PayloadW();
|
||||
|
||||
// Constructors for outgoing payloads.
|
||||
explicit PayloadW(const char* bytes, const size_t size);
|
||||
explicit PayloadW(const char* bytes, size_t size);
|
||||
|
||||
explicit PayloadW(InputFileW& file);
|
||||
explicit PayloadW(std::function<InputStream&()> stream);
|
||||
explicit PayloadW(std::unique_ptr<InputStream> stream);
|
||||
|
||||
// Constructors for incoming payloads.
|
||||
PayloadW(PayloadId id, const char* bytes, const size_t size);
|
||||
PayloadW(PayloadId id, const char* bytes, size_t size);
|
||||
PayloadW(PayloadId id, InputFileW file);
|
||||
explicit PayloadW(const char* parent_folder, const char* file_name,
|
||||
InputFileW file);
|
||||
|
||||
// TODO(jfcarroll): Convert std::function to function pointer
|
||||
PayloadW(PayloadId id, std::function<InputStream&()> stream);
|
||||
PayloadW(PayloadId id, std::unique_ptr<InputStream> stream);
|
||||
// Returns ByteArray payload, if it has
|
||||
// been defined, or empty ByteArray.
|
||||
bool AsBytes(const char*& bytes, size_t& bytes_size) const&;
|
||||
|
||||
+123
-91
@@ -19,15 +19,32 @@
|
||||
#include <vector>
|
||||
|
||||
#include "absl/strings/string_view.h"
|
||||
#include "absl/time/clock.h"
|
||||
#include "absl/time/time.h"
|
||||
#include "absl/types/span.h"
|
||||
#include "connections/advertising_options.h"
|
||||
#include "connections/connection_options.h"
|
||||
#include "connections/discovery_options.h"
|
||||
#include "connections/implementation/service_controller_router.h"
|
||||
#include "connections/implementation/service_id_constants.h"
|
||||
#include "connections/listeners.h"
|
||||
#include "connections/medium_selector.h"
|
||||
#include "connections/out_of_band_connection_metadata.h"
|
||||
#include "connections/params.h"
|
||||
#include "connections/payload.h"
|
||||
#include "connections/payload_type.h"
|
||||
#include "connections/power_level.h"
|
||||
#include "connections/status.h"
|
||||
#include "connections/v3/advertising_options.h"
|
||||
#include "connections/v3/bandwidth_info.h"
|
||||
#include "connections/v3/connection_listening_options.h"
|
||||
#include "connections/v3/connection_result.h"
|
||||
#include "connections/v3/connections_device.h"
|
||||
#include "connections/v3/discovery_options.h"
|
||||
#include "connections/v3/listeners.h"
|
||||
#include "connections/v3/listening_result.h"
|
||||
#include "connections/v3/params.h"
|
||||
#include "internal/interop/device.h"
|
||||
#include "internal/platform/byte_array.h"
|
||||
#include "internal/platform/count_down_latch.h"
|
||||
#include "internal/platform/feature_flags.h"
|
||||
#include "internal/platform/logging.h"
|
||||
@@ -54,10 +71,7 @@ Core::Core(ServiceControllerRouter* router) : router_(router) {}
|
||||
|
||||
Core::~Core() {
|
||||
CountDownLatch latch(1);
|
||||
router_->StopAllEndpoints(
|
||||
&client_, {
|
||||
.result_cb = [&latch](Status) { latch.CountDown(); },
|
||||
});
|
||||
router_->StopAllEndpoints(&client_, [&latch](Status) { latch.CountDown(); });
|
||||
if (!latch.Await(kWaitForDisconnect).result()) {
|
||||
NEARBY_LOG(FATAL, "Unable to shutdown");
|
||||
}
|
||||
@@ -75,11 +89,11 @@ void Core::StartAdvertising(absl::string_view service_id,
|
||||
CHECK(advertising_options.strategy.IsValid());
|
||||
|
||||
router_->StartAdvertising(&client_, service_id, advertising_options, info,
|
||||
callback);
|
||||
std::move(callback));
|
||||
}
|
||||
|
||||
void Core::StopAdvertising(const ResultCallback callback) {
|
||||
router_->StopAdvertising(&client_, callback);
|
||||
void Core::StopAdvertising(ResultCallback callback) {
|
||||
router_->StopAdvertising(&client_, std::move(callback));
|
||||
}
|
||||
|
||||
void Core::StartDiscovery(absl::string_view service_id,
|
||||
@@ -89,18 +103,18 @@ void Core::StartDiscovery(absl::string_view service_id,
|
||||
CHECK(discovery_options.strategy.IsValid());
|
||||
|
||||
router_->StartDiscovery(&client_, service_id, discovery_options, listener,
|
||||
callback);
|
||||
std::move(callback));
|
||||
}
|
||||
|
||||
void Core::InjectEndpoint(absl::string_view service_id,
|
||||
OutOfBandConnectionMetadata metadata,
|
||||
ResultCallback callback) {
|
||||
CheckServiceId(service_id);
|
||||
router_->InjectEndpoint(&client_, service_id, metadata, callback);
|
||||
router_->InjectEndpoint(&client_, service_id, metadata, std::move(callback));
|
||||
}
|
||||
|
||||
void Core::StopDiscovery(ResultCallback callback) {
|
||||
router_->StopDiscovery(&client_, callback);
|
||||
router_->StopDiscovery(&client_, std::move(callback));
|
||||
}
|
||||
|
||||
void Core::RequestConnection(absl::string_view endpoint_id,
|
||||
@@ -128,7 +142,7 @@ void Core::RequestConnection(absl::string_view endpoint_id,
|
||||
}
|
||||
|
||||
router_->RequestConnection(&client_, endpoint_id, info, connection_options,
|
||||
callback);
|
||||
std::move(callback));
|
||||
}
|
||||
|
||||
void Core::AcceptConnection(absl::string_view endpoint_id,
|
||||
@@ -136,19 +150,19 @@ void Core::AcceptConnection(absl::string_view endpoint_id,
|
||||
CHECK(!endpoint_id.empty());
|
||||
|
||||
router_->AcceptConnection(&client_, endpoint_id, std::move(listener),
|
||||
callback);
|
||||
std::move(callback));
|
||||
}
|
||||
|
||||
void Core::RejectConnection(absl::string_view endpoint_id,
|
||||
ResultCallback callback) {
|
||||
CHECK(!endpoint_id.empty());
|
||||
|
||||
router_->RejectConnection(&client_, endpoint_id, callback);
|
||||
router_->RejectConnection(&client_, endpoint_id, std::move(callback));
|
||||
}
|
||||
|
||||
void Core::InitiateBandwidthUpgrade(absl::string_view endpoint_id,
|
||||
ResultCallback callback) {
|
||||
router_->InitiateBandwidthUpgrade(&client_, endpoint_id, callback);
|
||||
router_->InitiateBandwidthUpgrade(&client_, endpoint_id, std::move(callback));
|
||||
}
|
||||
|
||||
void Core::SendPayload(absl::Span<const std::string> endpoint_ids,
|
||||
@@ -156,35 +170,36 @@ void Core::SendPayload(absl::Span<const std::string> endpoint_ids,
|
||||
CHECK(payload.GetType() != PayloadType::kUnknown);
|
||||
CHECK(!endpoint_ids.empty());
|
||||
|
||||
router_->SendPayload(&client_, endpoint_ids, std::move(payload), callback);
|
||||
router_->SendPayload(&client_, endpoint_ids, std::move(payload),
|
||||
std::move(callback));
|
||||
}
|
||||
|
||||
void Core::CancelPayload(std::int64_t payload_id, ResultCallback callback) {
|
||||
CHECK_NE(payload_id, 0);
|
||||
|
||||
router_->CancelPayload(&client_, payload_id, callback);
|
||||
router_->CancelPayload(&client_, payload_id, std::move(callback));
|
||||
}
|
||||
|
||||
void Core::DisconnectFromEndpoint(absl::string_view endpoint_id,
|
||||
ResultCallback callback) {
|
||||
CHECK(!endpoint_id.empty());
|
||||
|
||||
router_->DisconnectFromEndpoint(&client_, endpoint_id, callback);
|
||||
router_->DisconnectFromEndpoint(&client_, endpoint_id, std::move(callback));
|
||||
}
|
||||
|
||||
void Core::StopAllEndpoints(ResultCallback callback) {
|
||||
router_->StopAllEndpoints(&client_, callback);
|
||||
router_->StopAllEndpoints(&client_, std::move(callback));
|
||||
}
|
||||
|
||||
void Core::SetCustomSavePath(absl::string_view path, ResultCallback callback) {
|
||||
router_->SetCustomSavePath(&client_, path, callback);
|
||||
router_->SetCustomSavePath(&client_, path, std::move(callback));
|
||||
}
|
||||
|
||||
std::string Core::Dump() { return client_.Dump(); }
|
||||
|
||||
// V3
|
||||
void Core::StartAdvertisingV3(absl::string_view service_id,
|
||||
const AdvertisingOptions& advertising_options,
|
||||
const v3::AdvertisingOptions& advertising_options,
|
||||
const NearbyDevice& local_device,
|
||||
v3::ConnectionListener listener,
|
||||
ResultCallback callback) {
|
||||
@@ -240,55 +255,32 @@ void Core::StartAdvertisingV3(absl::string_view service_id,
|
||||
.endpoint_info = local_endpoint_info,
|
||||
.listener = old_listener,
|
||||
};
|
||||
StartAdvertising(service_id, advertising_options, old_info, callback);
|
||||
|
||||
CheckServiceId(service_id);
|
||||
CHECK(advertising_options.strategy.IsValid());
|
||||
AdvertisingOptions old_advertising_options = {
|
||||
{
|
||||
advertising_options.strategy,
|
||||
advertising_options.advertising_mediums,
|
||||
},
|
||||
advertising_options.auto_upgrade_bandwidth,
|
||||
advertising_options.enforce_topology_constraints,
|
||||
advertising_options.power_level == PowerLevel::kLowPower, // low_power
|
||||
advertising_options.enable_bluetooth_listening,
|
||||
advertising_options.advertising_mediums.web_rtc,
|
||||
false, // is_out_of_band_connection
|
||||
advertising_options.fast_advertisement_service_uuid,
|
||||
"" // device_info
|
||||
};
|
||||
// TODO(b/291295755): Refactor deeper to use v3 options throughout.
|
||||
router_->StartAdvertising(&client_, service_id, old_advertising_options,
|
||||
old_info, std::move(callback));
|
||||
}
|
||||
|
||||
void Core::StartAdvertisingV3(absl::string_view service_id,
|
||||
const AdvertisingOptions& advertising_options,
|
||||
const v3::AdvertisingOptions& advertising_options,
|
||||
v3::ConnectionListener listener,
|
||||
ResultCallback callback) {
|
||||
ConnectionListener old_listener = {
|
||||
.initiated_cb =
|
||||
[&listener](const std::string& endpoint_id,
|
||||
const ConnectionResponseInfo& info) {
|
||||
auto remote_device = v3::ConnectionsDevice(
|
||||
endpoint_id, info.remote_endpoint_info.AsStringView(), {});
|
||||
listener.initiated_cb(
|
||||
remote_device,
|
||||
v3::InitialConnectionInfo{
|
||||
.authentication_digits = info.authentication_token,
|
||||
.raw_authentication_token =
|
||||
info.raw_authentication_token.string_data(),
|
||||
.is_incoming_connection = info.is_incoming_connection,
|
||||
});
|
||||
},
|
||||
.accepted_cb =
|
||||
[v3_cb = listener.result_cb](const std::string& endpoint_id) {
|
||||
auto remote_device = v3::ConnectionsDevice(endpoint_id, "", {});
|
||||
v3_cb(remote_device,
|
||||
v3::ConnectionResult{.status = Status{
|
||||
.value = Status::kSuccess,
|
||||
}});
|
||||
},
|
||||
.rejected_cb =
|
||||
[v3_cb = listener.result_cb](const std::string& endpoint_id,
|
||||
Status status) {
|
||||
auto remote_device = v3::ConnectionsDevice(endpoint_id, "", {});
|
||||
v3_cb(remote_device, v3::ConnectionResult{
|
||||
.status = status,
|
||||
});
|
||||
},
|
||||
.disconnected_cb =
|
||||
[&listener](const std::string& endpoint_id) {
|
||||
auto remote_device = v3::ConnectionsDevice(endpoint_id, "", {});
|
||||
listener.disconnected_cb(remote_device);
|
||||
},
|
||||
.bandwidth_changed_cb =
|
||||
[&listener](const std::string& endpoint_id, Medium medium) {
|
||||
auto remote_device = v3::ConnectionsDevice(endpoint_id, "", {});
|
||||
listener.bandwidth_changed_cb(remote_device,
|
||||
v3::BandwidthInfo{.medium = medium});
|
||||
}};
|
||||
ByteArray local_endpoint_info;
|
||||
const NearbyDevice* local_device = client_.GetLocalDevice();
|
||||
if (local_device->GetType() == NearbyDevice::kConnectionsDevice) {
|
||||
@@ -296,19 +288,16 @@ void Core::StartAdvertisingV3(absl::string_view service_id,
|
||||
ByteArray(reinterpret_cast<const v3::ConnectionsDevice*>(local_device)
|
||||
->GetEndpointInfo());
|
||||
}
|
||||
ConnectionRequestInfo old_info = {
|
||||
.endpoint_info = local_endpoint_info,
|
||||
.listener = old_listener,
|
||||
};
|
||||
StartAdvertising(service_id, advertising_options, old_info, callback);
|
||||
StartAdvertisingV3(service_id, advertising_options, *local_device,
|
||||
std::move(listener), std::move(callback));
|
||||
}
|
||||
|
||||
void Core::StopAdvertisingV3(ResultCallback result_cb) {
|
||||
StopAdvertising(result_cb);
|
||||
StopAdvertising(std::move(result_cb));
|
||||
}
|
||||
|
||||
void Core::StartDiscoveryV3(absl::string_view service_id,
|
||||
const DiscoveryOptions& discovery_options,
|
||||
const v3::DiscoveryOptions& discovery_options,
|
||||
v3::DiscoveryListener listener,
|
||||
ResultCallback callback) {
|
||||
DiscoveryListener old_listener = {
|
||||
@@ -332,11 +321,24 @@ void Core::StartDiscoveryV3(absl::string_view service_id,
|
||||
listener.endpoint_distance_changed_cb(remote, distance_info);
|
||||
},
|
||||
};
|
||||
StartDiscovery(service_id, discovery_options, old_listener, callback);
|
||||
DiscoveryOptions old_discovery_options = {
|
||||
{
|
||||
discovery_options.strategy,
|
||||
discovery_options.discovery_mediums,
|
||||
},
|
||||
true, // auto_upgrade_bandwidth
|
||||
true, // enforce_topology_constraints
|
||||
false, // is_out_of_band_connection
|
||||
discovery_options.fast_advertisement_service_uuid,
|
||||
discovery_options.power_level == PowerLevel::kLowPower,
|
||||
};
|
||||
// TODO(b/291295755): Deeper refactor to use v3 options throughout.
|
||||
StartDiscovery(service_id, old_discovery_options, old_listener,
|
||||
std::move(callback));
|
||||
}
|
||||
|
||||
void Core::StopDiscoveryV3(ResultCallback result_cb) {
|
||||
router_->StopDiscovery(&client_, result_cb);
|
||||
router_->StopDiscovery(&client_, std::move(result_cb));
|
||||
}
|
||||
|
||||
void Core::StartListeningForIncomingConnectionsV3(
|
||||
@@ -383,7 +385,7 @@ void Core::RequestConnectionV3(const NearbyDevice& local_device,
|
||||
FeatureFlags::GetInstance().GetFlags().keep_alive_timeout_millis;
|
||||
}
|
||||
router_->RequestConnectionV3(&client_, remote_device, std::move(info),
|
||||
connection_options, result_cb);
|
||||
connection_options, std::move(result_cb));
|
||||
}
|
||||
|
||||
void Core::RequestConnectionV3(const NearbyDevice& remote_device,
|
||||
@@ -414,7 +416,7 @@ void Core::RequestConnectionV3(const NearbyDevice& remote_device,
|
||||
FeatureFlags::GetInstance().GetFlags().keep_alive_timeout_millis;
|
||||
}
|
||||
router_->RequestConnectionV3(&client_, remote_device, std::move(info),
|
||||
connection_options, result_cb);
|
||||
connection_options, std::move(result_cb));
|
||||
}
|
||||
|
||||
void Core::AcceptConnectionV3(const NearbyDevice& remote_device,
|
||||
@@ -423,14 +425,14 @@ void Core::AcceptConnectionV3(const NearbyDevice& remote_device,
|
||||
CHECK(!remote_device.GetEndpointId().empty());
|
||||
|
||||
router_->AcceptConnectionV3(&client_, remote_device, std::move(listener_cb),
|
||||
result_cb);
|
||||
std::move(result_cb));
|
||||
}
|
||||
|
||||
void Core::RejectConnectionV3(const NearbyDevice& remote_device,
|
||||
ResultCallback result_cb) {
|
||||
CHECK(!remote_device.GetEndpointId().empty());
|
||||
|
||||
router_->RejectConnectionV3(&client_, remote_device, result_cb);
|
||||
router_->RejectConnectionV3(&client_, remote_device, std::move(result_cb));
|
||||
}
|
||||
|
||||
void Core::SendPayloadV3(const NearbyDevice& remote_device, Payload payload,
|
||||
@@ -439,44 +441,74 @@ void Core::SendPayloadV3(const NearbyDevice& remote_device, Payload payload,
|
||||
CHECK(!remote_device.GetEndpointId().empty());
|
||||
|
||||
router_->SendPayloadV3(&client_, remote_device, std::move(payload),
|
||||
result_cb);
|
||||
std::move(result_cb));
|
||||
}
|
||||
|
||||
void Core::CancelPayloadV3(const NearbyDevice& remote_device,
|
||||
int64_t payload_id, ResultCallback result_cb) {
|
||||
CHECK_NE(payload_id, 0);
|
||||
|
||||
router_->CancelPayloadV3(&client_, remote_device, payload_id, result_cb);
|
||||
router_->CancelPayloadV3(&client_, remote_device, payload_id,
|
||||
std::move(result_cb));
|
||||
}
|
||||
|
||||
void Core::DisconnectFromDeviceV3(const NearbyDevice& remote_device,
|
||||
ResultCallback result_cb) {
|
||||
CHECK(!remote_device.GetEndpointId().empty());
|
||||
|
||||
router_->DisconnectFromDeviceV3(&client_, remote_device, result_cb);
|
||||
router_->DisconnectFromDeviceV3(&client_, remote_device,
|
||||
std::move(result_cb));
|
||||
}
|
||||
|
||||
void Core::StopAllDevicesV3(ResultCallback result_cb) {
|
||||
router_->StopAllEndpoints(&client_, result_cb);
|
||||
router_->StopAllEndpoints(&client_, std::move(result_cb));
|
||||
}
|
||||
|
||||
void Core::InitiateBandwidthUpgradeV3(const NearbyDevice& remote_device,
|
||||
ResultCallback result_cb) {
|
||||
router_->InitiateBandwidthUpgradeV3(&client_, remote_device, result_cb);
|
||||
router_->InitiateBandwidthUpgradeV3(&client_, remote_device,
|
||||
std::move(result_cb));
|
||||
}
|
||||
|
||||
void Core::UpdateAdvertisingOptionsV3(absl::string_view service_id,
|
||||
AdvertisingOptions advertising_options,
|
||||
ResultCallback result_cb) {
|
||||
router_->UpdateAdvertisingOptionsV3(&client_, service_id, advertising_options,
|
||||
result_cb);
|
||||
void Core::UpdateAdvertisingOptionsV3(
|
||||
absl::string_view service_id, v3::AdvertisingOptions advertising_options,
|
||||
ResultCallback result_cb) {
|
||||
// TODO(b/291295755): Deeper refactor to use new advertising options.
|
||||
AdvertisingOptions old_advertising_options = {
|
||||
{
|
||||
advertising_options.strategy,
|
||||
advertising_options.advertising_mediums,
|
||||
},
|
||||
advertising_options.auto_upgrade_bandwidth,
|
||||
advertising_options.enforce_topology_constraints,
|
||||
advertising_options.power_level == PowerLevel::kLowPower, // low_power
|
||||
advertising_options.enable_bluetooth_listening,
|
||||
advertising_options.advertising_mediums.web_rtc,
|
||||
false, // is_out_of_band_connection
|
||||
advertising_options.fast_advertisement_service_uuid,
|
||||
"" // device_info
|
||||
};
|
||||
router_->UpdateAdvertisingOptionsV3(
|
||||
&client_, service_id, old_advertising_options, std::move(result_cb));
|
||||
}
|
||||
|
||||
void Core::UpdateDiscoveryOptionsV3(absl::string_view service_id,
|
||||
DiscoveryOptions discovery_options,
|
||||
v3::DiscoveryOptions discovery_options,
|
||||
ResultCallback result_cb) {
|
||||
router_->UpdateDiscoveryOptionsV3(&client_, service_id, discovery_options,
|
||||
result_cb);
|
||||
// TODO(b/291295755): Deeper refactor to use new discovery options.
|
||||
DiscoveryOptions old_discovery_options = {
|
||||
{
|
||||
discovery_options.strategy,
|
||||
discovery_options.discovery_mediums,
|
||||
},
|
||||
true, // auto_upgrade_bandwidth
|
||||
true, // enforce_topology_constraints
|
||||
false, // is_out_of_band_connection
|
||||
discovery_options.fast_advertisement_service_uuid,
|
||||
discovery_options.power_level == PowerLevel::kLowPower,
|
||||
};
|
||||
router_->UpdateDiscoveryOptionsV3(&client_, service_id, old_discovery_options,
|
||||
std::move(result_cb));
|
||||
}
|
||||
|
||||
} // namespace connections
|
||||
|
||||
+7
-5
@@ -28,7 +28,9 @@
|
||||
#include "connections/listeners.h"
|
||||
#include "connections/params.h"
|
||||
#include "connections/payload.h"
|
||||
#include "connections/v3/advertising_options.h"
|
||||
#include "connections/v3/connection_listening_options.h"
|
||||
#include "connections/v3/discovery_options.h"
|
||||
#include "connections/v3/listeners.h"
|
||||
#include "connections/v3/listening_result.h"
|
||||
#include "internal/analytics/event_logger.h"
|
||||
@@ -273,7 +275,7 @@ class Core {
|
||||
// Status::STATUS_OUT_OF_ORDER_API_CALL if the app is currently
|
||||
// connected to remote endpoints; call StopAllEndpoints first.
|
||||
void StartAdvertisingV3(absl::string_view service_id,
|
||||
const AdvertisingOptions& advertising_options,
|
||||
const v3::AdvertisingOptions& advertising_options,
|
||||
const NearbyDevice& local_device,
|
||||
v3::ConnectionListener listener,
|
||||
ResultCallback callback);
|
||||
@@ -296,7 +298,7 @@ class Core {
|
||||
// Status::STATUS_OUT_OF_ORDER_API_CALL if the app is currently
|
||||
// connected to remote endpoints; call StopAllEndpoints first.
|
||||
void StartAdvertisingV3(absl::string_view service_id,
|
||||
const AdvertisingOptions& advertising_options,
|
||||
const v3::AdvertisingOptions& advertising_options,
|
||||
v3::ConnectionListener listener,
|
||||
ResultCallback callback);
|
||||
|
||||
@@ -322,7 +324,7 @@ class Core {
|
||||
// Status::STATUS_OUT_OF_ORDER_API_CALL if the app is currently
|
||||
// connected to remote endpoints; call StopAllEndpoints first.
|
||||
void StartDiscoveryV3(absl::string_view service_id,
|
||||
const DiscoveryOptions& discovery_options,
|
||||
const v3::DiscoveryOptions& discovery_options,
|
||||
v3::DiscoveryListener listener_cb,
|
||||
ResultCallback callback);
|
||||
|
||||
@@ -504,7 +506,7 @@ class Core {
|
||||
// advertising_options - The new advertising options a client wishes to use.
|
||||
// result_cb - to access the status of the operation when available.
|
||||
void UpdateAdvertisingOptionsV3(absl::string_view service_id,
|
||||
AdvertisingOptions advertising_options,
|
||||
v3::AdvertisingOptions advertising_options,
|
||||
ResultCallback result_cb);
|
||||
|
||||
// Updates DiscoveryOptions. It compares the old DiscoveryOptions and the new
|
||||
@@ -513,7 +515,7 @@ class Core {
|
||||
// discovery_options - The new discovery options a client wishes to use.
|
||||
// result_cb - to access the status of the operation when available.
|
||||
void UpdateDiscoveryOptionsV3(absl::string_view service_id,
|
||||
DiscoveryOptions discovery_options,
|
||||
v3::DiscoveryOptions discovery_options,
|
||||
ResultCallback result_cb);
|
||||
|
||||
// Registers a DeviceProvider to provide functionality for Nearby Connections
|
||||
|
||||
+124
-20
@@ -14,16 +14,29 @@
|
||||
|
||||
#include "connections/core.h"
|
||||
|
||||
#include <memory>
|
||||
#include <string>
|
||||
#include <vector>
|
||||
|
||||
#include "gmock/gmock.h"
|
||||
#include "protobuf-matchers/protocol-buffer-matchers.h"
|
||||
#include "gtest/gtest.h"
|
||||
#include "absl/strings/string_view.h"
|
||||
#include "absl/time/clock.h"
|
||||
#include "connections/advertising_options.h"
|
||||
#include "connections/discovery_options.h"
|
||||
#include "connections/implementation/mock_service_controller_router.h"
|
||||
#include "connections/listeners.h"
|
||||
#include "connections/medium_selector.h"
|
||||
#include "connections/params.h"
|
||||
#include "connections/payload.h"
|
||||
#include "connections/power_level.h"
|
||||
#include "connections/status.h"
|
||||
#include "connections/strategy.h"
|
||||
#include "connections/v3/advertising_options.h"
|
||||
#include "connections/v3/bandwidth_info.h"
|
||||
#include "connections/v3/connection_result.h"
|
||||
#include "connections/v3/connections_device.h"
|
||||
#include "connections/v3/discovery_options.h"
|
||||
#include "internal/platform/byte_array.h"
|
||||
#include "internal/platform/count_down_latch.h"
|
||||
#include "internal/platform/logging.h"
|
||||
|
||||
@@ -54,8 +67,8 @@ TEST(CoreTest, ConstructorDestructorWorks) {
|
||||
MockServiceControllerRouter mock;
|
||||
// Called when Core is destroyed.
|
||||
EXPECT_CALL(mock, StopAllEndpoints)
|
||||
.WillOnce([&](ClientProxy* client, const ResultCallback& callback) {
|
||||
callback.result_cb({Status::kSuccess});
|
||||
.WillOnce([&](ClientProxy* client, ResultCallback callback) {
|
||||
callback({Status::kSuccess});
|
||||
});
|
||||
Core core{&mock};
|
||||
}
|
||||
@@ -71,6 +84,97 @@ TEST(CoreTest, DestructorReportsFatalFailure) {
|
||||
"Unable to shutdown");
|
||||
}
|
||||
|
||||
TEST(CoreTest, RequestConnectionCallsScRouter) {
|
||||
MockServiceControllerRouter mock;
|
||||
// Called when Core is destroyed.
|
||||
EXPECT_CALL(mock, StopAllEndpoints)
|
||||
.WillOnce([&](ClientProxy* client, ResultCallback callback) {
|
||||
callback({Status::kSuccess});
|
||||
});
|
||||
EXPECT_CALL(mock, RequestConnection);
|
||||
Core core{&mock};
|
||||
core.RequestConnection("TEST", {}, {}, {});
|
||||
}
|
||||
|
||||
TEST(CoreTest, AcceptConnectionCallsScRouter) {
|
||||
MockServiceControllerRouter mock;
|
||||
// Called when Core is destroyed.
|
||||
EXPECT_CALL(mock, StopAllEndpoints)
|
||||
.WillOnce([&](ClientProxy* client, ResultCallback callback) {
|
||||
callback({Status::kSuccess});
|
||||
});
|
||||
EXPECT_CALL(mock, AcceptConnection);
|
||||
Core core{&mock};
|
||||
core.AcceptConnection("TEST", {}, {});
|
||||
}
|
||||
|
||||
TEST(CoreTest, SendPayloadCallsScRouter) {
|
||||
MockServiceControllerRouter mock;
|
||||
// Called when Core is destroyed.
|
||||
EXPECT_CALL(mock, StopAllEndpoints)
|
||||
.WillOnce([&](ClientProxy* client, ResultCallback callback) {
|
||||
callback({Status::kSuccess});
|
||||
});
|
||||
EXPECT_CALL(mock, SendPayload);
|
||||
Core core{&mock};
|
||||
core.SendPayload({"TEST"}, Payload(ByteArray("Hello world")), {});
|
||||
}
|
||||
|
||||
TEST(CoreV3Test, TestAdvertisingOptionsConversionWorks) {
|
||||
MockServiceControllerRouter mock;
|
||||
// Called when Core is destroyed.
|
||||
EXPECT_CALL(mock, StopAllEndpoints)
|
||||
.WillOnce([&](ClientProxy* client, ResultCallback callback) {
|
||||
callback({Status::kSuccess});
|
||||
});
|
||||
EXPECT_CALL(mock, StartAdvertising)
|
||||
.WillOnce([](ClientProxy*, absl::string_view,
|
||||
const AdvertisingOptions& options,
|
||||
const ConnectionRequestInfo& info, ResultCallback) {
|
||||
EXPECT_EQ(options.strategy, Strategy::kP2pCluster);
|
||||
EXPECT_FALSE(options.low_power);
|
||||
EXPECT_TRUE(options.enable_bluetooth_listening);
|
||||
EXPECT_FALSE(options.auto_upgrade_bandwidth);
|
||||
EXPECT_EQ(options.fast_advertisement_service_uuid, "NearbyConnections");
|
||||
});
|
||||
Core core{&mock};
|
||||
v3::AdvertisingOptions advertising_options = {
|
||||
.strategy = Strategy::kP2pCluster,
|
||||
.power_level = PowerLevel::kHighPower,
|
||||
.enable_bluetooth_listening = true,
|
||||
.auto_upgrade_bandwidth = false,
|
||||
.fast_advertisement_service_uuid = "NearbyConnections",
|
||||
};
|
||||
core.StartAdvertisingV3("service", advertising_options, {}, {});
|
||||
core.StopDiscoveryV3({});
|
||||
}
|
||||
|
||||
TEST(CoreV3Test, TestDiscoveryOptionsConversionWorks) {
|
||||
MockServiceControllerRouter mock;
|
||||
// Called when Core is destroyed.
|
||||
EXPECT_CALL(mock, StopAllEndpoints)
|
||||
.WillOnce([&](ClientProxy* client, ResultCallback callback) {
|
||||
callback({Status::kSuccess});
|
||||
});
|
||||
EXPECT_CALL(mock, StartDiscovery)
|
||||
.WillOnce([](ClientProxy*, absl::string_view,
|
||||
const DiscoveryOptions& options,
|
||||
const DiscoveryListener& info, ResultCallback) {
|
||||
EXPECT_EQ(options.strategy, Strategy::kP2pCluster);
|
||||
EXPECT_FALSE(options.low_power);
|
||||
EXPECT_TRUE(options.auto_upgrade_bandwidth);
|
||||
EXPECT_EQ(options.fast_advertisement_service_uuid, "NearbyConnections");
|
||||
});
|
||||
Core core{&mock};
|
||||
v3::DiscoveryOptions discovery_options = {
|
||||
.strategy = Strategy::kP2pCluster,
|
||||
.power_level = PowerLevel::kHighPower,
|
||||
.fast_advertisement_service_uuid = "NearbyConnections",
|
||||
};
|
||||
core.StartDiscoveryV3("service", discovery_options, {}, {});
|
||||
core.StopDiscoveryV3({});
|
||||
}
|
||||
|
||||
TEST(CoreV3Test, TestCallbackWrapWorksStartAdvertisingV3FourArgs) {
|
||||
MockServiceControllerRouter mock;
|
||||
EXPECT_CALL(mock, StartAdvertising)
|
||||
@@ -86,16 +190,16 @@ TEST(CoreV3Test, TestCallbackWrapWorksStartAdvertisingV3FourArgs) {
|
||||
info.listener.disconnected_cb("FAKE");
|
||||
});
|
||||
EXPECT_CALL(mock, StopAllEndpoints)
|
||||
.WillOnce([&](ClientProxy* client, const ResultCallback& callback) {
|
||||
.WillOnce([&](ClientProxy* client, ResultCallback callback) {
|
||||
NEARBY_LOGS(INFO) << "StopAllEndpoints called";
|
||||
callback.result_cb({Status::kSuccess});
|
||||
callback({Status::kSuccess});
|
||||
});
|
||||
Core core{&mock};
|
||||
CountDownLatch result_latch(2);
|
||||
CountDownLatch bandwidth_changed_latch(1);
|
||||
CountDownLatch disconnected_latch(1);
|
||||
CountDownLatch initiated_latch(1);
|
||||
AdvertisingOptions advertising_options;
|
||||
v3::AdvertisingOptions advertising_options;
|
||||
advertising_options.strategy = Strategy::kP2pCluster;
|
||||
core.StartAdvertisingV3(
|
||||
"service", advertising_options,
|
||||
@@ -132,7 +236,7 @@ TEST(CoreV3Test, TestStartAdvertisingV3NonConnectionsDeviceProvider) {
|
||||
MockServiceControllerRouter mock;
|
||||
EXPECT_CALL(mock, StartAdvertising)
|
||||
.WillOnce([&](ClientProxy*, absl::string_view, const AdvertisingOptions&,
|
||||
const ConnectionRequestInfo& info, const ResultCallback&) {
|
||||
const ConnectionRequestInfo& info, ResultCallback) {
|
||||
NEARBY_LOGS(INFO) << "StartAdvertising called";
|
||||
ASSERT_TRUE(info.endpoint_info.Empty());
|
||||
// call all callbacks to make sure it all gets called correctly.
|
||||
@@ -143,16 +247,16 @@ TEST(CoreV3Test, TestStartAdvertisingV3NonConnectionsDeviceProvider) {
|
||||
info.listener.disconnected_cb("FAKE");
|
||||
});
|
||||
EXPECT_CALL(mock, StopAllEndpoints)
|
||||
.WillOnce([&](ClientProxy* client, const ResultCallback& callback) {
|
||||
.WillOnce([&](ClientProxy* client, ResultCallback callback) {
|
||||
NEARBY_LOGS(INFO) << "StopAllEndpoints called";
|
||||
callback.result_cb({Status::kSuccess});
|
||||
callback({Status::kSuccess});
|
||||
});
|
||||
Core core{&mock};
|
||||
CountDownLatch result_latch(2);
|
||||
CountDownLatch bandwidth_changed_latch(1);
|
||||
CountDownLatch disconnected_latch(1);
|
||||
CountDownLatch initiated_latch(1);
|
||||
AdvertisingOptions advertising_options;
|
||||
v3::AdvertisingOptions advertising_options;
|
||||
advertising_options.strategy = Strategy::kP2pCluster;
|
||||
FakeNearbyDeviceProvider device_provider;
|
||||
core.RegisterDeviceProvider(&device_provider);
|
||||
@@ -202,16 +306,16 @@ TEST(CoreV3Test, TestStartAdvertisingV3NonConnectionsDevice) {
|
||||
info.listener.disconnected_cb("FAKE");
|
||||
});
|
||||
EXPECT_CALL(mock, StopAllEndpoints)
|
||||
.WillOnce([&](ClientProxy* client, const ResultCallback& callback) {
|
||||
.WillOnce([&](ClientProxy* client, ResultCallback callback) {
|
||||
NEARBY_LOGS(INFO) << "StopAllEndpoints called";
|
||||
callback.result_cb({Status::kSuccess});
|
||||
callback({Status::kSuccess});
|
||||
});
|
||||
Core core{&mock};
|
||||
CountDownLatch result_latch(2);
|
||||
CountDownLatch bandwidth_changed_latch(1);
|
||||
CountDownLatch disconnected_latch(1);
|
||||
CountDownLatch initiated_latch(1);
|
||||
AdvertisingOptions advertising_options;
|
||||
v3::AdvertisingOptions advertising_options;
|
||||
advertising_options.strategy = Strategy::kP2pCluster;
|
||||
auto local_device = FakeNearbyDevice();
|
||||
core.StartAdvertisingV3(
|
||||
@@ -260,16 +364,16 @@ TEST(CoreV3Test, TestCallbackWrapWorksStartAdvertisingV3FiveArgs) {
|
||||
info.listener.disconnected_cb("FAKE");
|
||||
});
|
||||
EXPECT_CALL(mock, StopAllEndpoints)
|
||||
.WillOnce([&](ClientProxy* client, const ResultCallback& callback) {
|
||||
.WillOnce([&](ClientProxy* client, ResultCallback callback) {
|
||||
NEARBY_LOGS(INFO) << "StopAllEndpoints called";
|
||||
callback.result_cb({Status::kSuccess});
|
||||
callback({Status::kSuccess});
|
||||
});
|
||||
Core core{&mock};
|
||||
CountDownLatch result_latch(2);
|
||||
CountDownLatch bandwidth_changed_latch(1);
|
||||
CountDownLatch disconnected_latch(1);
|
||||
CountDownLatch initiated_latch(1);
|
||||
AdvertisingOptions advertising_options;
|
||||
v3::AdvertisingOptions advertising_options;
|
||||
advertising_options.strategy = Strategy::kP2pCluster;
|
||||
auto local_device = v3::ConnectionsDevice("FAKE", "endpoint_info", {});
|
||||
core.StartAdvertisingV3(
|
||||
@@ -315,11 +419,11 @@ TEST(CoreV3Test, TestCallbackWrapWorksStartDiscoveryV3) {
|
||||
info.endpoint_lost_cb("FAKE");
|
||||
});
|
||||
EXPECT_CALL(mock, StopAllEndpoints)
|
||||
.WillOnce([&](ClientProxy* client, const ResultCallback& callback) {
|
||||
.WillOnce([&](ClientProxy* client, ResultCallback callback) {
|
||||
NEARBY_LOGS(INFO) << "StopAllEndpoints called";
|
||||
callback.result_cb({Status::kSuccess});
|
||||
callback({Status::kSuccess});
|
||||
});
|
||||
DiscoveryOptions options;
|
||||
v3::DiscoveryOptions options;
|
||||
options.strategy = Strategy::kP2pCluster;
|
||||
Core core{&mock};
|
||||
CountDownLatch endpoint_distance_latch(1);
|
||||
|
||||
@@ -126,18 +126,20 @@ cc_library(
|
||||
"//internal/platform:comm",
|
||||
"//internal/platform:connection_info",
|
||||
"//internal/platform:error_code_recorder",
|
||||
"//internal/platform:logging",
|
||||
"//internal/platform:types",
|
||||
"//internal/platform:util",
|
||||
"//internal/platform/implementation:comm",
|
||||
"//internal/platform/implementation:platform",
|
||||
"//internal/platform/implementation/shared:file",
|
||||
"//internal/proto/analytics:connections_log_cc_proto",
|
||||
"//proto:connections_enums_cc_proto",
|
||||
"@com_google_absl//absl/base:core_headers",
|
||||
"@com_google_absl//absl/container:btree",
|
||||
"@com_google_absl//absl/container:flat_hash_map",
|
||||
"@com_google_absl//absl/container:flat_hash_set",
|
||||
"@com_google_absl//absl/functional:any_invocable",
|
||||
"@com_google_absl//absl/functional:bind_front",
|
||||
"@com_google_absl//absl/log:check",
|
||||
"@com_google_absl//absl/memory",
|
||||
"@com_google_absl//absl/strings",
|
||||
"@com_google_absl//absl/strings:str_format",
|
||||
@@ -181,10 +183,13 @@ cc_library(
|
||||
deps = [
|
||||
":internal",
|
||||
"//connections:core_types",
|
||||
"//connections/implementation/flags:connections_flags",
|
||||
"//connections/v3:v3_types",
|
||||
"//internal/flags:nearby_flags",
|
||||
"//internal/platform:base",
|
||||
"//internal/platform:test_util",
|
||||
"//internal/platform:types",
|
||||
"@com_google_absl//absl/functional:any_invocable",
|
||||
"@com_google_absl//absl/functional:bind_front",
|
||||
"@com_google_absl//absl/strings",
|
||||
"@com_google_googletest//:gtest_for_library_testonly",
|
||||
@@ -225,6 +230,7 @@ cc_test(
|
||||
":internal",
|
||||
":internal_test",
|
||||
"//connections:core_types",
|
||||
"//connections/implementation/analytics",
|
||||
"//connections/implementation/flags:connections_flags",
|
||||
"//connections/implementation/mediums",
|
||||
"//connections/implementation/proto:offline_wire_formats_cc_proto",
|
||||
@@ -234,13 +240,14 @@ cc_test(
|
||||
"//internal/interop:device",
|
||||
"//internal/platform:base",
|
||||
"//internal/platform:comm",
|
||||
"//internal/platform:logging",
|
||||
"//internal/platform:test_util",
|
||||
"//internal/platform:types",
|
||||
"//internal/platform/implementation/g3", # build_cleaner: keep
|
||||
"//internal/proto/analytics:connections_log_cc_proto",
|
||||
"//internal/test",
|
||||
"//proto:connections_enums_cc_proto",
|
||||
"@com_github_protobuf_matchers//protobuf-matchers",
|
||||
"@com_google_absl//absl/base:core_headers",
|
||||
"@com_google_absl//absl/container:flat_hash_set",
|
||||
"@com_google_absl//absl/strings",
|
||||
"@com_google_absl//absl/strings:str_format",
|
||||
|
||||
@@ -31,7 +31,6 @@ cc_library(
|
||||
"//connections:core_types",
|
||||
"//internal/analytics:event_logger",
|
||||
"//internal/platform:error_code_recorder",
|
||||
"//internal/platform:logging",
|
||||
"//internal/platform:types",
|
||||
"//internal/platform/implementation:types",
|
||||
"//internal/proto/analytics:connections_log_cc_proto",
|
||||
@@ -61,7 +60,6 @@ cc_test(
|
||||
"//internal/platform:base",
|
||||
"//internal/platform:comm",
|
||||
"//internal/platform:error_code_recorder",
|
||||
"//internal/platform:logging",
|
||||
"//internal/platform:types",
|
||||
"//internal/platform/implementation/g3", # build_cleaner: keep
|
||||
"//internal/proto/analytics:connections_log_cc_proto",
|
||||
|
||||
@@ -220,7 +220,7 @@ void AnalyticsRecorder::OnStartedIncomingConnectionListening(
|
||||
return;
|
||||
}
|
||||
UpdateStrategySessionLocked(strategy, ADVERTISER);
|
||||
if (started_advertising_phase_time_ == absl::Now()) {
|
||||
if (started_advertising_phase_time_ == absl::InfinitePast()) {
|
||||
started_advertising_phase_time_ = SystemClock::ElapsedRealtime();
|
||||
}
|
||||
}
|
||||
@@ -250,6 +250,19 @@ void AnalyticsRecorder::OnEndpointFound(Medium medium) {
|
||||
SystemClock::ElapsedRealtime() - started_discovery_phase_time_));
|
||||
}
|
||||
|
||||
void AnalyticsRecorder::OnRequestConnection(
|
||||
const connections::Strategy &strategy, const std::string &endpoint_id) {
|
||||
MutexLock lock(&mutex_);
|
||||
if (!CanRecordAnalyticsLocked("onRequestConnection")) {
|
||||
return;
|
||||
}
|
||||
|
||||
UpdateStrategySessionLocked(strategy, DISCOVERER);
|
||||
if (started_discovery_phase_time_ == absl::InfinitePast()) {
|
||||
started_discovery_phase_time_ = SystemClock::ElapsedRealtime();
|
||||
}
|
||||
}
|
||||
|
||||
void AnalyticsRecorder::OnConnectionRequestReceived(
|
||||
const std::string &remote_endpoint_id) {
|
||||
MutexLock lock(&mutex_);
|
||||
@@ -1034,10 +1047,15 @@ void AnalyticsRecorder::FinishStrategySessionLocked() {
|
||||
bandwidth_upgrade_attempts_.clear();
|
||||
|
||||
// Add the StrategySession in ClientSession
|
||||
current_strategy_session_->set_duration_millis(absl::ToInt64Milliseconds(
|
||||
started_strategy_session_time_ - SystemClock::ElapsedRealtime()));
|
||||
*client_session_->add_strategy_session() =
|
||||
*std::move(current_strategy_session_);
|
||||
if (current_strategy_session_ != nullptr) {
|
||||
current_strategy_session_->set_duration_millis(absl::ToInt64Milliseconds(
|
||||
SystemClock::ElapsedRealtime() - started_strategy_session_time_));
|
||||
*client_session_->add_strategy_session() =
|
||||
*std::move(current_strategy_session_);
|
||||
}
|
||||
|
||||
current_strategy_session_ = nullptr;
|
||||
current_strategy_ = connections::Strategy::kNone;
|
||||
LogEvent(STOP_STRATEGY_SESSION);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -74,6 +74,10 @@ class AnalyticsRecorder {
|
||||
ABSL_LOCKS_EXCLUDED(mutex_);
|
||||
|
||||
// Connection request
|
||||
void OnRequestConnection(const connections::Strategy &strategy,
|
||||
const std::string &endpoint_id)
|
||||
ABSL_LOCKS_EXCLUDED(mutex_);
|
||||
|
||||
void OnConnectionRequestReceived(const std::string &remote_endpoint_id)
|
||||
ABSL_LOCKS_EXCLUDED(mutex_);
|
||||
void OnConnectionRequestSent(const std::string &remote_endpoint_id)
|
||||
@@ -374,13 +378,13 @@ class AnalyticsRecorder {
|
||||
std::unique_ptr<
|
||||
location::nearby::analytics::proto::ConnectionsLog::AdvertisingPhase>
|
||||
current_advertising_phase_;
|
||||
absl::Time started_advertising_phase_time_;
|
||||
absl::Time started_advertising_phase_time_ = absl::InfinitePast();
|
||||
|
||||
// Current DiscoveryPhase
|
||||
std::unique_ptr<
|
||||
location::nearby::analytics::proto::ConnectionsLog::DiscoveryPhase>
|
||||
current_discovery_phase_;
|
||||
absl::Time started_discovery_phase_time_;
|
||||
absl::Time started_discovery_phase_time_ = absl::InfinitePast();
|
||||
|
||||
absl::btree_map<std::string,
|
||||
std::unique_ptr<location::nearby::analytics::proto::
|
||||
|
||||
@@ -138,6 +138,11 @@ bool ThroughputRecorder::Stop() {
|
||||
return true;
|
||||
}
|
||||
|
||||
void ThroughputRecorder::MarkAsSuccess() {
|
||||
MutexLock lock(&mutex_);
|
||||
success_ = true;
|
||||
}
|
||||
|
||||
int ThroughputRecorder::CalculateThroughputKBps(int64_t total_byte_size,
|
||||
int64_t total_millis) {
|
||||
if (total_millis > 0) {
|
||||
|
||||
@@ -87,7 +87,7 @@ class ThroughputRecorder {
|
||||
int64_t GetDurationMillis();
|
||||
void OnFrameSent(Medium medium, PacketMetaData& packetMetaData);
|
||||
void OnFrameReceived(Medium medium, PacketMetaData& packetMetaData);
|
||||
void MarkAsSuccess() { success_ = true; }
|
||||
void MarkAsSuccess();
|
||||
|
||||
private:
|
||||
void CalculateDurationTimes(PacketMetaData packetMetaData);
|
||||
|
||||
@@ -23,8 +23,9 @@
|
||||
namespace nearby {
|
||||
namespace connections {
|
||||
|
||||
BaseBwuHandler::BaseBwuHandler(BwuNotifications bwu_notifications)
|
||||
: bwu_notifications_(std::move(bwu_notifications)) {}
|
||||
BaseBwuHandler::BaseBwuHandler(
|
||||
IncomingConnectionCallback incoming_connection_callback)
|
||||
: incoming_connection_callback_(std::move(incoming_connection_callback)) {}
|
||||
|
||||
ByteArray BaseBwuHandler::InitializeUpgradedMediumForEndpoint(
|
||||
ClientProxy* client, const std::string& service_id,
|
||||
@@ -78,5 +79,14 @@ void BaseBwuHandler::RevertResponderState(const std::string& service_id) {
|
||||
HandleRevertInitiatorStateForService(service_id);
|
||||
}
|
||||
|
||||
void BaseBwuHandler::NotifyOnIncomingConnection(
|
||||
ClientProxy* client, std::unique_ptr<IncomingSocketConnection> connection) {
|
||||
if (!incoming_connection_callback_) {
|
||||
NEARBY_LOGS(WARNING)
|
||||
<< "Ignoring incoming connection, no callback registered";
|
||||
return;
|
||||
}
|
||||
incoming_connection_callback_(client, std::move(connection));
|
||||
}
|
||||
} // namespace connections
|
||||
} // namespace nearby
|
||||
|
||||
@@ -30,7 +30,8 @@ namespace connections {
|
||||
// of the service IDs and endpoint IDs that initiated a bandwidth upgrade.
|
||||
class BaseBwuHandler : public BwuHandler {
|
||||
public:
|
||||
explicit BaseBwuHandler(BwuNotifications bwu_notifications);
|
||||
explicit BaseBwuHandler(
|
||||
IncomingConnectionCallback incoming_connection_callback);
|
||||
|
||||
// BwuHandler implementation:
|
||||
ByteArray InitializeUpgradedMediumForEndpoint(
|
||||
@@ -55,9 +56,13 @@ class BaseBwuHandler : public BwuHandler {
|
||||
virtual void HandleRevertInitiatorStateForService(
|
||||
const std::string& upgrade_service_id) = 0;
|
||||
|
||||
BwuNotifications bwu_notifications_;
|
||||
// Notifies the caller about incoming connection.
|
||||
void NotifyOnIncomingConnection(
|
||||
ClientProxy* client,
|
||||
std::unique_ptr<IncomingSocketConnection> connection);
|
||||
|
||||
private:
|
||||
IncomingConnectionCallback incoming_connection_callback_;
|
||||
// Map from the (wrapped) service ID to endpoint IDs that are initiating a
|
||||
// bandwidth upgrade. Not used for endpoints that respond to bandwidth upgrade
|
||||
// requests from another device.
|
||||
|
||||
@@ -38,7 +38,7 @@ class BwuHandlerImpl : public BaseBwuHandler {
|
||||
absl::optional<std::string> endpoint_id;
|
||||
};
|
||||
|
||||
BwuHandlerImpl() : BaseBwuHandler(BwuNotifications{}) {}
|
||||
BwuHandlerImpl() : BaseBwuHandler(nullptr) {}
|
||||
|
||||
const std::vector<InputData>& handle_initialize_calls() const {
|
||||
return handle_initialize_calls_;
|
||||
|
||||
@@ -21,9 +21,10 @@
|
||||
|
||||
#include "absl/base/thread_annotations.h"
|
||||
#include "connections/implementation/analytics/analytics_recorder.h"
|
||||
#include "connections/implementation/analytics/packet_meta_data.h"
|
||||
#include "connections/implementation/endpoint_channel.h"
|
||||
#include "internal/platform/byte_array.h"
|
||||
#include "internal/platform/condition_variable.h"
|
||||
#include "internal/platform/exception.h"
|
||||
#include "internal/platform/input_stream.h"
|
||||
#include "internal/platform/mutex.h"
|
||||
#include "internal/platform/output_stream.h"
|
||||
|
||||
@@ -14,7 +14,9 @@
|
||||
|
||||
#include "connections/implementation/base_endpoint_channel.h"
|
||||
|
||||
#include <cstddef>
|
||||
#include <functional>
|
||||
#include <memory>
|
||||
#include <string>
|
||||
#include <utility>
|
||||
|
||||
@@ -22,9 +24,13 @@
|
||||
#include "gmock/gmock.h"
|
||||
#include "protobuf-matchers/protocol-buffer-matchers.h"
|
||||
#include "gtest/gtest.h"
|
||||
#include "absl/strings/string_view.h"
|
||||
#include "absl/synchronization/mutex.h"
|
||||
#include "absl/time/clock.h"
|
||||
#include "absl/time/time.h"
|
||||
#include "connections/implementation/client_proxy.h"
|
||||
#include "connections/implementation/encryption_runner.h"
|
||||
#include "connections/implementation/endpoint_channel.h"
|
||||
#include "connections/implementation/offline_frames.h"
|
||||
#include "internal/platform/byte_array.h"
|
||||
#include "internal/platform/count_down_latch.h"
|
||||
@@ -34,7 +40,6 @@
|
||||
#include "internal/platform/multi_thread_executor.h"
|
||||
#include "internal/platform/output_stream.h"
|
||||
#include "internal/platform/pipe.h"
|
||||
#include "internal/platform/single_thread_executor.h"
|
||||
#include "proto/connections_enums.pb.h"
|
||||
|
||||
namespace nearby {
|
||||
@@ -44,6 +49,7 @@ namespace {
|
||||
using ::location::nearby::proto::connections::DisconnectionReason;
|
||||
using ::location::nearby::proto::connections::Medium;
|
||||
using EncryptionContext = BaseEndpointChannel::EncryptionContext;
|
||||
constexpr size_t kChunkSize = 64 * 1024;
|
||||
|
||||
class TestEndpointChannel : public BaseEndpointChannel {
|
||||
public:
|
||||
@@ -62,7 +68,7 @@ std::function<void()> MakeDataPump(
|
||||
return [label, input, output, monitor]() {
|
||||
NEARBY_LOGS(INFO) << "streaming data through '" << label << "'";
|
||||
while (true) {
|
||||
auto read_response = input->Read(Pipe::kChunkSize);
|
||||
auto read_response = input->Read(kChunkSize);
|
||||
if (!read_response.ok()) {
|
||||
NEARBY_LOGS(INFO) << "Peer reader closed on '" << label << "'";
|
||||
output->Close();
|
||||
@@ -158,21 +164,17 @@ DoDhKeyExchange(BaseEndpointChannel* channel_a,
|
||||
}
|
||||
|
||||
TEST(BaseEndpointChannelTest, ConstructorDestructorWorks) {
|
||||
Pipe pipe;
|
||||
InputStream& input_stream = pipe.GetInputStream();
|
||||
OutputStream& output_stream = pipe.GetOutputStream();
|
||||
auto [input, output] = CreatePipe();
|
||||
|
||||
TestEndpointChannel test_channel(&input_stream, &output_stream);
|
||||
TestEndpointChannel test_channel(input.get(), output.get());
|
||||
}
|
||||
|
||||
TEST(BaseEndpointChannelTest, ReadWrite) {
|
||||
// Direct not-encrypted IO.
|
||||
Pipe pipe_a; // channel_a writes to pipe_a, reads from pipe_b.
|
||||
Pipe pipe_b; // channel_b writes to pipe_b, reads from pipe_a.
|
||||
TestEndpointChannel channel_a(&pipe_b.GetInputStream(),
|
||||
&pipe_a.GetOutputStream());
|
||||
TestEndpointChannel channel_b(&pipe_a.GetInputStream(),
|
||||
&pipe_b.GetOutputStream());
|
||||
auto pipe_a = CreatePipe(); // channel_a writes to pipe_a, reads from pipe_b.
|
||||
auto pipe_b = CreatePipe(); // channel_b writes to pipe_b, reads from pipe_a.
|
||||
TestEndpointChannel channel_a(pipe_b.first.get(), pipe_a.second.get());
|
||||
TestEndpointChannel channel_b(pipe_a.first.get(), pipe_b.second.get());
|
||||
ByteArray tx_message{"data message"};
|
||||
channel_a.Write(tx_message);
|
||||
ByteArray rx_message = std::move(channel_b.Read().result());
|
||||
@@ -180,8 +182,8 @@ TEST(BaseEndpointChannelTest, ReadWrite) {
|
||||
}
|
||||
|
||||
TEST(BaseEndpointChannelTest, ChannelUnencryptedByDefault) {
|
||||
Pipe pipe;
|
||||
TestEndpointChannel channel(&pipe.GetInputStream(), &pipe.GetOutputStream());
|
||||
auto pipe = CreatePipe();
|
||||
TestEndpointChannel channel(pipe.first.get(), pipe.second.get());
|
||||
|
||||
ExceptionOr<ByteArray> result = channel.TryDecrypt(ByteArray("message"));
|
||||
|
||||
@@ -192,12 +194,10 @@ TEST(BaseEndpointChannelTest, ChannelUnencryptedByDefault) {
|
||||
|
||||
TEST(BaseEndpointChannelTest, TryDecrypt) {
|
||||
absl::string_view kMessage = "message";
|
||||
Pipe pipe_a; // channel_a writes to pipe_a, reads from pipe_b.
|
||||
Pipe pipe_b; // channel_b writes to pipe_b, reads from pipe_a.
|
||||
TestEndpointChannel channel_a(&pipe_b.GetInputStream(),
|
||||
&pipe_a.GetOutputStream());
|
||||
TestEndpointChannel channel_b(&pipe_a.GetInputStream(),
|
||||
&pipe_b.GetOutputStream());
|
||||
auto pipe_a = CreatePipe(); // channel_a writes to pipe_a, reads from pipe_b.
|
||||
auto pipe_b = CreatePipe(); // channel_b writes to pipe_b, reads from pipe_a.
|
||||
TestEndpointChannel channel_a(pipe_b.first.get(), pipe_a.second.get());
|
||||
TestEndpointChannel channel_b(pipe_a.first.get(), pipe_b.second.get());
|
||||
auto [context_a, context_b] = DoDhKeyExchange(&channel_a, &channel_b);
|
||||
ASSERT_NE(context_a, nullptr);
|
||||
ASSERT_NE(context_b, nullptr);
|
||||
@@ -215,12 +215,10 @@ TEST(BaseEndpointChannelTest, TryDecrypt) {
|
||||
}
|
||||
|
||||
TEST(BaseEndpointChannelTest, TryDecryptFailsWhenDecryptionFails) {
|
||||
Pipe pipe_a; // channel_a writes to pipe_a, reads from pipe_b.
|
||||
Pipe pipe_b; // channel_b writes to pipe_b, reads from pipe_a.
|
||||
TestEndpointChannel channel_a(&pipe_b.GetInputStream(),
|
||||
&pipe_a.GetOutputStream());
|
||||
TestEndpointChannel channel_b(&pipe_a.GetInputStream(),
|
||||
&pipe_b.GetOutputStream());
|
||||
auto pipe_a = CreatePipe(); // channel_a writes to pipe_a, reads from pipe_b.
|
||||
auto pipe_b = CreatePipe(); // channel_b writes to pipe_b, reads from pipe_a.
|
||||
TestEndpointChannel channel_a(pipe_b.first.get(), pipe_a.second.get());
|
||||
TestEndpointChannel channel_b(pipe_a.first.get(), pipe_b.second.get());
|
||||
auto [context_a, context_b] = DoDhKeyExchange(&channel_a, &channel_b);
|
||||
ASSERT_NE(context_a, nullptr);
|
||||
channel_a.EnableEncryption(context_a);
|
||||
@@ -240,25 +238,27 @@ TEST(BaseEndpointChannelTest, NotEncryptedReadWriteCanBeIntercepted) {
|
||||
absl::Mutex mutex;
|
||||
std::string capture_a;
|
||||
std::string capture_b;
|
||||
Pipe client_a; // Channel "a" writes to client "a", reads from server "a".
|
||||
Pipe client_b; // Channel "b" writes to client "b", reads from server "b".
|
||||
Pipe server_a; // Data pump "a" reads from client "a", writes to server "b".
|
||||
Pipe server_b; // Data pump "b" reads from client "b", writes to server "a".
|
||||
TestEndpointChannel channel_a(&server_a.GetInputStream(),
|
||||
&client_a.GetOutputStream());
|
||||
TestEndpointChannel channel_b(&server_b.GetInputStream(),
|
||||
&client_b.GetOutputStream());
|
||||
auto client_a =
|
||||
CreatePipe(); // Channel "a" writes to client "a", reads from server "a".
|
||||
auto client_b =
|
||||
CreatePipe(); // Channel "b" writes to client "b", reads from server "b".
|
||||
auto server_a = CreatePipe(); // Data pump "a" reads from client "a", writes
|
||||
// to server "b".
|
||||
auto server_b = CreatePipe(); // Data pump "b" reads from client "b", writes
|
||||
// to server "a".
|
||||
TestEndpointChannel channel_a(server_a.first.get(), client_a.second.get());
|
||||
TestEndpointChannel channel_b(server_b.first.get(), client_b.second.get());
|
||||
|
||||
ON_CALL(channel_a, GetMedium).WillByDefault([]() { return Medium::BLE; });
|
||||
ON_CALL(channel_b, GetMedium).WillByDefault([]() { return Medium::BLE; });
|
||||
|
||||
MultiThreadExecutor executor(2);
|
||||
executor.Execute(MakeDataPump(
|
||||
"pump_a", &client_a.GetInputStream(), &server_b.GetOutputStream(),
|
||||
MakeDataMonitor("monitor_a", &capture_a, &mutex)));
|
||||
executor.Execute(MakeDataPump(
|
||||
"pump_b", &client_b.GetInputStream(), &server_a.GetOutputStream(),
|
||||
MakeDataMonitor("monitor_b", &capture_b, &mutex)));
|
||||
executor.Execute(
|
||||
MakeDataPump("pump_a", client_a.first.get(), server_b.second.get(),
|
||||
MakeDataMonitor("monitor_a", &capture_a, &mutex)));
|
||||
executor.Execute(
|
||||
MakeDataPump("pump_b", client_b.first.get(), server_a.second.get(),
|
||||
MakeDataMonitor("monitor_b", &capture_b, &mutex)));
|
||||
|
||||
EXPECT_EQ(channel_a.GetType(), "BLE");
|
||||
EXPECT_EQ(channel_b.GetType(), "BLE");
|
||||
@@ -289,14 +289,16 @@ TEST(BaseEndpointChannelTest, EncryptedReadWriteCanNotBeIntercepted) {
|
||||
absl::Mutex mutex;
|
||||
std::string capture_a;
|
||||
std::string capture_b;
|
||||
Pipe client_a; // Channel "a" writes to client "a", reads from server "a".
|
||||
Pipe client_b; // Channel "b" writes to client "b", reads from server "b".
|
||||
Pipe server_a; // Data pump "a" reads from client "a", writes to server "b".
|
||||
Pipe server_b; // Data pump "b" reads from client "b", writes to server "a".
|
||||
TestEndpointChannel channel_a(&server_a.GetInputStream(),
|
||||
&client_a.GetOutputStream());
|
||||
TestEndpointChannel channel_b(&server_b.GetInputStream(),
|
||||
&client_b.GetOutputStream());
|
||||
auto client_a =
|
||||
CreatePipe(); // Channel "a" writes to client "a", reads from server "a".
|
||||
auto client_b =
|
||||
CreatePipe(); // Channel "b" writes to client "b", reads from server "b".
|
||||
auto server_a = CreatePipe(); // Data pump "a" reads from client "a", writes
|
||||
// to server "b".
|
||||
auto server_b = CreatePipe(); // Data pump "b" reads from client "b", writes
|
||||
// to server "a".
|
||||
TestEndpointChannel channel_a(server_a.first.get(), client_a.second.get());
|
||||
TestEndpointChannel channel_b(server_b.first.get(), client_b.second.get());
|
||||
|
||||
ON_CALL(channel_a, GetMedium).WillByDefault([]() {
|
||||
return Medium::BLUETOOTH;
|
||||
@@ -306,12 +308,12 @@ TEST(BaseEndpointChannelTest, EncryptedReadWriteCanNotBeIntercepted) {
|
||||
});
|
||||
|
||||
MultiThreadExecutor executor(2);
|
||||
executor.Execute(MakeDataPump(
|
||||
"pump_a", &client_a.GetInputStream(), &server_b.GetOutputStream(),
|
||||
MakeDataMonitor("monitor_a", &capture_a, &mutex)));
|
||||
executor.Execute(MakeDataPump(
|
||||
"pump_b", &client_b.GetInputStream(), &server_a.GetOutputStream(),
|
||||
MakeDataMonitor("monitor_b", &capture_b, &mutex)));
|
||||
executor.Execute(
|
||||
MakeDataPump("pump_a", client_a.first.get(), server_b.second.get(),
|
||||
MakeDataMonitor("monitor_a", &capture_a, &mutex)));
|
||||
executor.Execute(
|
||||
MakeDataPump("pump_b", client_b.first.get(), server_a.second.get(),
|
||||
MakeDataMonitor("monitor_b", &capture_b, &mutex)));
|
||||
|
||||
// Run DH key exchange; setup encryption contexts for channels.
|
||||
auto [context_a, context_b] = DoDhKeyExchange(&channel_a, &channel_b);
|
||||
@@ -346,12 +348,10 @@ TEST(BaseEndpointChannelTest, EncryptedReadWriteCanNotBeIntercepted) {
|
||||
|
||||
TEST(BaseEndpointChannelTest, CanBesuspendedAndResumed) {
|
||||
// Setup test communication environment.
|
||||
Pipe pipe_a; // channel_a writes to pipe_a, reads from pipe_b.
|
||||
Pipe pipe_b; // channel_b writes to pipe_b, reads from pipe_a.
|
||||
TestEndpointChannel channel_a(&pipe_b.GetInputStream(),
|
||||
&pipe_a.GetOutputStream());
|
||||
TestEndpointChannel channel_b(&pipe_a.GetInputStream(),
|
||||
&pipe_b.GetOutputStream());
|
||||
auto pipe_a = CreatePipe(); // channel_a writes to pipe_a, reads from pipe_b.
|
||||
auto pipe_b = CreatePipe(); // channel_b writes to pipe_b, reads from pipe_a.
|
||||
TestEndpointChannel channel_a(pipe_b.first.get(), pipe_a.second.get());
|
||||
TestEndpointChannel channel_b(pipe_a.first.get(), pipe_b.second.get());
|
||||
|
||||
ON_CALL(channel_a, GetMedium).WillByDefault([]() {
|
||||
return Medium::WIFI_LAN;
|
||||
@@ -399,14 +399,12 @@ TEST(BaseEndpointChannelTest, CanBesuspendedAndResumed) {
|
||||
}
|
||||
|
||||
TEST(BaseEndpointChannelTest, ReadAfterInputStreamClosed) {
|
||||
Pipe pipe;
|
||||
InputStream& input_stream = pipe.GetInputStream();
|
||||
OutputStream& output_stream = pipe.GetOutputStream();
|
||||
auto [input, output] = CreatePipe();
|
||||
|
||||
TestEndpointChannel test_channel(&input_stream, &output_stream);
|
||||
TestEndpointChannel test_channel(input.get(), output.get());
|
||||
|
||||
// Close the output stream before trying to read from the input.
|
||||
output_stream.Close();
|
||||
output->Close();
|
||||
|
||||
// Trying to read should fail gracefully with an IO error.
|
||||
ExceptionOr<ByteArray> read_data = test_channel.Read();
|
||||
@@ -417,12 +415,10 @@ TEST(BaseEndpointChannelTest, ReadAfterInputStreamClosed) {
|
||||
|
||||
TEST(BaseEndpointChannelTest, ReadUnencryptedFrameOnEncryptedChannel) {
|
||||
// Setup test communication environment.
|
||||
Pipe pipe_a; // channel_a writes to pipe_a, reads from pipe_b.
|
||||
Pipe pipe_b; // channel_b writes to pipe_b, reads from pipe_a.
|
||||
TestEndpointChannel channel_a(&pipe_b.GetInputStream(),
|
||||
&pipe_a.GetOutputStream());
|
||||
TestEndpointChannel channel_b(&pipe_a.GetInputStream(),
|
||||
&pipe_b.GetOutputStream());
|
||||
auto pipe_a = CreatePipe(); // channel_a writes to pipe_a, reads from pipe_b.
|
||||
auto pipe_b = CreatePipe(); // channel_b writes to pipe_b, reads from pipe_a.
|
||||
TestEndpointChannel channel_a(pipe_b.first.get(), pipe_a.second.get());
|
||||
TestEndpointChannel channel_b(pipe_a.first.get(), pipe_b.second.get());
|
||||
|
||||
ON_CALL(channel_a, GetMedium).WillByDefault([]() {
|
||||
return Medium::BLUETOOTH;
|
||||
|
||||
@@ -28,6 +28,8 @@
|
||||
#include "absl/types/span.h"
|
||||
#include "connections/advertising_options.h"
|
||||
#include "connections/connection_options.h"
|
||||
#include "connections/implementation/endpoint_channel_manager.h"
|
||||
#include "connections/implementation/client_proxy.h"
|
||||
#include "connections/implementation/flags/nearby_connections_feature_flags.h"
|
||||
#include "connections/implementation/mediums/utils.h"
|
||||
#include "connections/implementation/offline_frames.h"
|
||||
@@ -84,7 +86,7 @@ BasePcpHandler::~BasePcpHandler() {
|
||||
}
|
||||
|
||||
void BasePcpHandler::Shutdown() {
|
||||
if (stop_) return;
|
||||
if (closed_.Set(true)) return;
|
||||
NEARBY_LOGS(INFO) << "Initiating shutdown of BasePcpHandler("
|
||||
<< strategy_.GetName() << ")";
|
||||
DisconnectFromEndpointManager();
|
||||
@@ -694,6 +696,9 @@ Status BasePcpHandler::RequestConnection(
|
||||
"to endpoint_id="
|
||||
<< endpoint_id;
|
||||
|
||||
client->OnRequestConnection(GetStrategy(), endpoint_id,
|
||||
connection_options);
|
||||
|
||||
ConnectionInfo connection_info =
|
||||
FillConnectionInfo(client, info, connection_options);
|
||||
|
||||
@@ -1009,9 +1014,12 @@ void BasePcpHandler::ProcessPreConnectionInitiationFailure(
|
||||
}
|
||||
|
||||
void BasePcpHandler::ProcessPreConnectionResultFailure(
|
||||
ClientProxy* client, const std::string& endpoint_id) {
|
||||
ClientProxy* client, const std::string& endpoint_id,
|
||||
bool should_call_disconnect_endpoint, const DisconnectionReason& reason) {
|
||||
auto item = pending_connections_.extract(endpoint_id);
|
||||
endpoint_manager_->DiscardEndpoint(client, endpoint_id);
|
||||
if (should_call_disconnect_endpoint) {
|
||||
endpoint_manager_->DiscardEndpoint(client, endpoint_id, reason);
|
||||
}
|
||||
client->OnConnectionRejected(endpoint_id, {Status::kError});
|
||||
}
|
||||
|
||||
@@ -1045,7 +1053,9 @@ Status BasePcpHandler::AcceptConnection(ClientProxy* client,
|
||||
NEARBY_LOGS(ERROR) << "Channel destroyed before Accept; bring down "
|
||||
"connection: endpoint_id="
|
||||
<< endpoint_id;
|
||||
ProcessPreConnectionResultFailure(client, endpoint_id);
|
||||
ProcessPreConnectionResultFailure(
|
||||
client, endpoint_id, /* should_call_disconnect_endpoint= */ true,
|
||||
DisconnectionReason::IO_ERROR);
|
||||
response.Set({Status::kEndpointUnknown});
|
||||
return;
|
||||
}
|
||||
@@ -1057,7 +1067,9 @@ Status BasePcpHandler::AcceptConnection(ClientProxy* client,
|
||||
NEARBY_LOGS(INFO)
|
||||
<< "AcceptConnection: failed to send response: endpoint_id="
|
||||
<< endpoint_id;
|
||||
ProcessPreConnectionResultFailure(client, endpoint_id);
|
||||
ProcessPreConnectionResultFailure(
|
||||
client, endpoint_id, /* should_call_disconnect_endpoint= */ true,
|
||||
DisconnectionReason::IO_ERROR);
|
||||
response.Set({Status::kEndpointIoError});
|
||||
return;
|
||||
}
|
||||
@@ -1103,7 +1115,9 @@ Status BasePcpHandler::RejectConnection(ClientProxy* client,
|
||||
<< "Channel destroyed before Reject; bring down connection: "
|
||||
"endpoint_id="
|
||||
<< endpoint_id;
|
||||
ProcessPreConnectionResultFailure(client, endpoint_id);
|
||||
ProcessPreConnectionResultFailure(
|
||||
client, endpoint_id, /* should_call_disconnect_endpoint= */ true,
|
||||
DisconnectionReason::IO_ERROR);
|
||||
response.Set({Status::kEndpointUnknown});
|
||||
return;
|
||||
}
|
||||
@@ -1115,7 +1129,9 @@ Status BasePcpHandler::RejectConnection(ClientProxy* client,
|
||||
NEARBY_LOGS(INFO)
|
||||
<< "RejectConnection: failed to send response: endpoint_id="
|
||||
<< endpoint_id;
|
||||
ProcessPreConnectionResultFailure(client, endpoint_id);
|
||||
ProcessPreConnectionResultFailure(
|
||||
client, endpoint_id, /* should_call_disconnect_endpoint= */ true,
|
||||
DisconnectionReason::IO_ERROR);
|
||||
response.Set({Status::kEndpointIoError});
|
||||
return;
|
||||
}
|
||||
@@ -1179,6 +1195,16 @@ void BasePcpHandler::OnIncomingFrame(
|
||||
client->SetRemoteOsInfo(endpoint_id, connection_response.os_info());
|
||||
}
|
||||
|
||||
if (connection_response.has_safe_to_disconnect_version()) {
|
||||
NEARBY_LOGS(INFO)
|
||||
<< "[safe-to-disconnect]: endpoint_id=" << endpoint_id
|
||||
<< "; Version = "
|
||||
<< connection_response.safe_to_disconnect_version();
|
||||
client->SetRemoteSafeToDisconnectVersion(
|
||||
endpoint_id, connection_response.safe_to_disconnect_version());
|
||||
}
|
||||
channel_manager_->UpdateSafeToDisconnectForEndpoint(endpoint_id,
|
||||
client->IsSafeToDisconnectEnabled(endpoint_id));
|
||||
EvaluateConnectionResult(client, endpoint_id,
|
||||
/* can_close_immediately= */ true);
|
||||
|
||||
@@ -1190,13 +1216,14 @@ void BasePcpHandler::OnIncomingFrame(
|
||||
void BasePcpHandler::OnEndpointDisconnect(ClientProxy* client,
|
||||
const std::string& service_id,
|
||||
const std::string& endpoint_id,
|
||||
CountDownLatch barrier) {
|
||||
CountDownLatch barrier,
|
||||
DisconnectionReason reason) {
|
||||
if (stop_.Get()) {
|
||||
barrier.CountDown();
|
||||
return;
|
||||
}
|
||||
RunOnPcpHandlerThread("on-endpoint-disconnect",
|
||||
[this, client, endpoint_id, barrier]()
|
||||
[this, client, endpoint_id, barrier, reason]()
|
||||
RUN_ON_PCP_HANDLER_THREAD() mutable {
|
||||
auto item = pending_alarms_.find(endpoint_id);
|
||||
if (item != pending_alarms_.end()) {
|
||||
@@ -1204,8 +1231,10 @@ void BasePcpHandler::OnEndpointDisconnect(ClientProxy* client,
|
||||
alarm->Cancel();
|
||||
pending_alarms_.erase(item);
|
||||
}
|
||||
ProcessPreConnectionResultFailure(client,
|
||||
endpoint_id);
|
||||
ProcessPreConnectionResultFailure(
|
||||
client, endpoint_id,
|
||||
/* should_call_disconnect_endpoint= */ false,
|
||||
reason);
|
||||
barrier.CountDown();
|
||||
});
|
||||
}
|
||||
@@ -1648,7 +1677,9 @@ void BasePcpHandler::ProcessTieBreakLoss(
|
||||
client, info->channel->GetMedium(), endpoint_id, info->channel.get(),
|
||||
info->is_incoming, info->start_time, {Status::kEndpointIoError},
|
||||
info->result.lock().get());
|
||||
ProcessPreConnectionResultFailure(client, endpoint_id);
|
||||
ProcessPreConnectionResultFailure(client, endpoint_id,
|
||||
/* should_call_disconnect_endpoint= */ true,
|
||||
DisconnectionReason::IO_ERROR);
|
||||
}
|
||||
|
||||
bool BasePcpHandler::AppendRemoteBluetoothMacAddressEndpoint(
|
||||
@@ -1795,14 +1826,16 @@ void BasePcpHandler::EvaluateConnectionResult(ClientProxy* client,
|
||||
|
||||
// Clean up the channel in EndpointManager if it's no longer required.
|
||||
if (can_close_immediately) {
|
||||
endpoint_manager_->DiscardEndpoint(client, endpoint_id);
|
||||
endpoint_manager_->DiscardEndpoint(client, endpoint_id,
|
||||
DisconnectionReason::UNFINISHED);
|
||||
} else {
|
||||
pending_alarms_.emplace(
|
||||
endpoint_id,
|
||||
std::make_unique<CancelableAlarm>(
|
||||
"BasePcpHandler.evaluateConnectionResult() delayed close",
|
||||
[this, client, endpoint_id]() {
|
||||
endpoint_manager_->DiscardEndpoint(client, endpoint_id);
|
||||
endpoint_manager_->DiscardEndpoint(
|
||||
client, endpoint_id, DisconnectionReason::UNFINISHED);
|
||||
},
|
||||
kRejectedConnectionCloseDelay, &alarm_executor_));
|
||||
}
|
||||
|
||||
@@ -22,6 +22,7 @@
|
||||
#include <vector>
|
||||
|
||||
#include "securegcm/ukey2_handshake.h"
|
||||
#include "absl/base/thread_annotations.h"
|
||||
#include "absl/container/btree_map.h"
|
||||
#include "absl/container/flat_hash_map.h"
|
||||
#include "absl/time/time.h"
|
||||
@@ -148,7 +149,8 @@ class BasePcpHandler : public PcpHandler,
|
||||
// @EndpointManagerThread
|
||||
void OnEndpointDisconnect(ClientProxy* client, const std::string& service_id,
|
||||
const std::string& endpoint_id,
|
||||
CountDownLatch barrier) override;
|
||||
CountDownLatch barrier,
|
||||
DisconnectionReason reason) override;
|
||||
|
||||
Status UpdateAdvertisingOptions(
|
||||
ClientProxy* client, absl::string_view service_id,
|
||||
@@ -359,11 +361,13 @@ class BasePcpHandler : public PcpHandler,
|
||||
// Start alarms for endpoints lost by their mediums. Used when updating
|
||||
// discovery options.
|
||||
void StartEndpointLostByMediumAlarms(
|
||||
ClientProxy* client, location::nearby::proto::connections::Medium medium);
|
||||
ClientProxy* client, location::nearby::proto::connections::Medium medium)
|
||||
RUN_ON_PCP_HANDLER_THREAD();
|
||||
|
||||
void StopEndpointLostByMediumAlarm(
|
||||
absl::string_view endpoint_id,
|
||||
location::nearby::proto::connections::Medium medium);
|
||||
location::nearby::proto::connections::Medium medium)
|
||||
RUN_ON_PCP_HANDLER_THREAD();
|
||||
|
||||
// Returns a vector of ConnectionInfos generated from a StartOperationResult.
|
||||
std::vector<ConnectionInfoVariant> GetConnectionInfoFromResult(
|
||||
@@ -379,9 +383,8 @@ class BasePcpHandler : public PcpHandler,
|
||||
}
|
||||
|
||||
// Test only.
|
||||
absl::flat_hash_map<std::string, std::unique_ptr<CancelableAlarm>>&
|
||||
GetEndpointLostByMediumAlarms() {
|
||||
return endpoint_lost_by_medium_alarms_;
|
||||
int GetEndpointLostByMediumAlarmsCount() RUN_ON_PCP_HANDLER_THREAD() {
|
||||
return endpoint_lost_by_medium_alarms_.size();
|
||||
}
|
||||
|
||||
Mediums* mediums_;
|
||||
@@ -505,7 +508,9 @@ class BasePcpHandler : public PcpHandler,
|
||||
EndpointChannel* channel, bool is_incoming, absl::Time start_time,
|
||||
Status status, Future<Status>* result);
|
||||
void ProcessPreConnectionResultFailure(ClientProxy* client,
|
||||
const std::string& endpoint_id);
|
||||
const std::string& endpoint_id,
|
||||
bool should_call_disconnect_endpoint,
|
||||
const DisconnectionReason& reason);
|
||||
|
||||
// Called when either side accepts/rejects the connection, but only takes
|
||||
// effect after both have accepted or one side has rejected.
|
||||
@@ -603,12 +608,13 @@ class BasePcpHandler : public PcpHandler,
|
||||
// Mapping from endpoint_id -> CancelableAlarm for triggering endpoint loss
|
||||
// while discovery options are updated.
|
||||
absl::flat_hash_map<std::string, std::unique_ptr<CancelableAlarm>>
|
||||
endpoint_lost_by_medium_alarms_;
|
||||
endpoint_lost_by_medium_alarms_ ABSL_GUARDED_BY(GetPcpHandlerThread());
|
||||
|
||||
Pcp pcp_;
|
||||
Strategy strategy_{PcpToStrategy(pcp_)};
|
||||
EncryptionRunner encryption_runner_;
|
||||
BwuManager* bwu_manager_;
|
||||
AtomicBoolean closed_{false};
|
||||
};
|
||||
|
||||
} // namespace connections
|
||||
|
||||
@@ -18,33 +18,48 @@
|
||||
#include <atomic>
|
||||
#include <memory>
|
||||
#include <string>
|
||||
#include <utility>
|
||||
#include <vector>
|
||||
|
||||
#include "gmock/gmock.h"
|
||||
#include "protobuf-matchers/protocol-buffer-matchers.h"
|
||||
#include "gtest/gtest.h"
|
||||
#include "absl/base/thread_annotations.h"
|
||||
#include "absl/strings/string_view.h"
|
||||
#include "absl/time/clock.h"
|
||||
#include "absl/time/time.h"
|
||||
#include "connections/advertising_options.h"
|
||||
#include "connections/connection_options.h"
|
||||
#include "connections/discovery_options.h"
|
||||
#include "connections/implementation/analytics/packet_meta_data.h"
|
||||
#include "connections/implementation/base_endpoint_channel.h"
|
||||
#include "connections/implementation/bwu_manager.h"
|
||||
#include "connections/implementation/client_proxy.h"
|
||||
#include "connections/implementation/encryption_runner.h"
|
||||
#include "connections/implementation/endpoint_manager.h"
|
||||
#include "connections/implementation/flags/nearby_connections_feature_flags.h"
|
||||
#include "connections/implementation/mediums/mediums.h"
|
||||
#include "connections/implementation/offline_frames.h"
|
||||
#include "connections/implementation/pcp.h"
|
||||
#include "connections/implementation/proto/offline_wire_formats.pb.h"
|
||||
#include "connections/listeners.h"
|
||||
#include "connections/medium_selector.h"
|
||||
#include "connections/out_of_band_connection_metadata.h"
|
||||
#include "connections/params.h"
|
||||
#include "connections/status.h"
|
||||
#include "connections/strategy.h"
|
||||
#include "connections/v3/connection_listening_options.h"
|
||||
#include "internal/flags/nearby_flags.h"
|
||||
#include "internal/interop/device.h"
|
||||
#include "internal/interop/device_provider.h"
|
||||
#include "internal/platform/byte_array.h"
|
||||
#include "internal/platform/exception.h"
|
||||
#include "internal/platform/feature_flags.h"
|
||||
#include "internal/platform/logging.h"
|
||||
#include "internal/platform/medium_environment.h"
|
||||
#include "internal/platform/output_stream.h"
|
||||
#include "internal/platform/pipe.h"
|
||||
#include "proto/connections_enums.pb.h"
|
||||
#include "proto/connections_enums.proto.h"
|
||||
|
||||
namespace nearby {
|
||||
namespace connections {
|
||||
@@ -108,9 +123,12 @@ class FakePresenceDeviceProvider : public NearbyDeviceProvider {
|
||||
|
||||
class MockEndpointChannel : public BaseEndpointChannel {
|
||||
public:
|
||||
explicit MockEndpointChannel(Pipe* reader, Pipe* writer)
|
||||
: BaseEndpointChannel("service_id", "channel", &reader->GetInputStream(),
|
||||
&writer->GetOutputStream()) {}
|
||||
explicit MockEndpointChannel(std::unique_ptr<InputStream> reader,
|
||||
std::unique_ptr<OutputStream> writer)
|
||||
: BaseEndpointChannel("service_id", "channel", reader.get(),
|
||||
writer.get()),
|
||||
input_stream_(std::move(reader)),
|
||||
output_stream_(std::move(writer)) {}
|
||||
|
||||
ExceptionOr<ByteArray> DoRead() { return BaseEndpointChannel::Read(); }
|
||||
Exception DoWrite(const ByteArray& data) {
|
||||
@@ -136,6 +154,10 @@ class MockEndpointChannel : public BaseEndpointChannel {
|
||||
MOCK_METHOD(absl::Time, GetLastReadTimestamp, (), (const override));
|
||||
|
||||
bool broken_write_{false};
|
||||
|
||||
private:
|
||||
std::unique_ptr<InputStream> input_stream_;
|
||||
std::unique_ptr<OutputStream> output_stream_;
|
||||
};
|
||||
|
||||
class MockPcpHandler : public BasePcpHandler {
|
||||
@@ -233,19 +255,36 @@ class MockPcpHandler : public BasePcpHandler {
|
||||
return BasePcpHandler::GetDiscoveredEndpoints(medium);
|
||||
}
|
||||
|
||||
absl::flat_hash_map<std::string, std::unique_ptr<CancelableAlarm>>&
|
||||
GetEndpointLostByMediumAlarms() {
|
||||
return BasePcpHandler::GetEndpointLostByMediumAlarms();
|
||||
int GetEndpointLostByMediumAlarmsCount() {
|
||||
Future<int> alarms_count;
|
||||
RunOnPcpHandlerThread(
|
||||
"GetEndpointLostByMediumAlarmsCount",
|
||||
[this, alarms_count]() RUN_ON_PCP_HANDLER_THREAD() mutable {
|
||||
alarms_count.Set(
|
||||
BasePcpHandler::GetEndpointLostByMediumAlarmsCount());
|
||||
});
|
||||
return alarms_count.Get().result();
|
||||
}
|
||||
|
||||
void StartEndpointLostByMediumAlarms(
|
||||
ClientProxy* client, location::nearby::proto::connections::Medium medium) {
|
||||
BasePcpHandler::StartEndpointLostByMediumAlarms(client, medium);
|
||||
ClientProxy* client,
|
||||
location::nearby::proto::connections::Medium medium) {
|
||||
RunOnPcpHandlerThread("StartEndpointLostByMediumAlarms",
|
||||
[this, client, medium]() RUN_ON_PCP_HANDLER_THREAD() {
|
||||
BasePcpHandler::StartEndpointLostByMediumAlarms(
|
||||
client, medium);
|
||||
});
|
||||
}
|
||||
|
||||
void StopEndpointLostByMediumAlarm(absl::string_view endpoint_id,
|
||||
location::nearby::proto::connections::Medium medium) {
|
||||
BasePcpHandler::StopEndpointLostByMediumAlarm(endpoint_id, medium);
|
||||
void StopEndpointLostByMediumAlarm(
|
||||
absl::string_view endpoint_id,
|
||||
location::nearby::proto::connections::Medium medium) {
|
||||
RunOnPcpHandlerThread("StopEndpointLostByMediumAlarm",
|
||||
[this, endpoint_id = std::string(endpoint_id),
|
||||
medium]() RUN_ON_PCP_HANDLER_THREAD() {
|
||||
BasePcpHandler::StopEndpointLostByMediumAlarm(
|
||||
endpoint_id, medium);
|
||||
});
|
||||
}
|
||||
|
||||
std::vector<location::nearby::proto::connections::Medium> GetDiscoveryMediums(
|
||||
@@ -318,6 +357,16 @@ struct MockDiscoveredEndpoint : public MockPcpHandler::DiscoveredEndpoint {
|
||||
MockContext context;
|
||||
};
|
||||
|
||||
class SetSafeToDisconnect {
|
||||
public:
|
||||
explicit SetSafeToDisconnect(bool safe_to_disconnect) {
|
||||
NearbyFlags::GetInstance().OverrideBoolFlagValue(
|
||||
config_package_nearby::nearby_connections_feature::
|
||||
kEnableSafeToDisconnect,
|
||||
safe_to_disconnect);
|
||||
}
|
||||
};
|
||||
|
||||
class BasePcpHandlerTest
|
||||
: public ::testing::TestWithParam<BooleanMediumSelector> {
|
||||
protected:
|
||||
@@ -442,10 +491,13 @@ class BasePcpHandlerTest
|
||||
std::pair<std::unique_ptr<MockEndpointChannel>,
|
||||
std::unique_ptr<MockEndpointChannel>>
|
||||
SetupConnection(
|
||||
Pipe& pipe_a, Pipe& pipe_b,
|
||||
location::nearby::proto::connections::Medium medium) { // NOLINT
|
||||
auto channel_a = std::make_unique<MockEndpointChannel>(&pipe_b, &pipe_a);
|
||||
auto channel_b = std::make_unique<MockEndpointChannel>(&pipe_a, &pipe_b);
|
||||
auto [input_a, output_a] = CreatePipe();
|
||||
auto [input_b, output_b] = CreatePipe();
|
||||
auto channel_a = std::make_unique<MockEndpointChannel>(std::move(input_a),
|
||||
std::move(output_b));
|
||||
auto channel_b = std::make_unique<MockEndpointChannel>(std::move(input_b),
|
||||
std::move(output_a));
|
||||
// On initiator (A) side, we drop the first write, since this is a
|
||||
// connection establishment packet, and we don't have the peer entity, just
|
||||
// the peer channel. The rest of the exchange must happen for the benefit of
|
||||
@@ -553,8 +605,7 @@ class BasePcpHandlerTest
|
||||
const std::string& endpoint_id,
|
||||
std::unique_ptr<MockEndpointChannel> channel_a,
|
||||
MockEndpointChannel* channel_b, ClientProxy* client,
|
||||
MockPcpHandler* pcp_handler,
|
||||
std::atomic_int* flag = nullptr,
|
||||
MockPcpHandler* pcp_handler, std::atomic_int* flag = nullptr,
|
||||
Status expected_result = {Status::kSuccess}) {
|
||||
ConnectionRequestInfo info{
|
||||
.endpoint_info = ByteArray{"ABCD"},
|
||||
@@ -581,29 +632,29 @@ class BasePcpHandlerTest
|
||||
auto allowed_mediums = pcp_handler->GetDiscoveryMediums(client);
|
||||
|
||||
EXPECT_CALL(*pcp_handler, ConnectImpl)
|
||||
.WillRepeatedly(Invoke([&channel_a](
|
||||
ClientProxy* client,
|
||||
MockPcpHandler::DiscoveredEndpoint* endpoint) {
|
||||
if (endpoint->medium ==
|
||||
location::nearby::proto::connections::WIFI_LAN) {
|
||||
NEARBY_LOGS(INFO) << "Connect with Medium WIFI_LAN failed.";
|
||||
return MockPcpHandler::ConnectImplResult{
|
||||
.medium = endpoint->medium,
|
||||
.status = {Status::kError},
|
||||
.endpoint_channel = nullptr,
|
||||
};
|
||||
} else {
|
||||
NEARBY_LOGS(INFO)
|
||||
<< "Connect with Medium: "
|
||||
<< location::nearby::proto::connections::Medium_Name(
|
||||
endpoint->medium);
|
||||
return MockPcpHandler::ConnectImplResult{
|
||||
.medium = endpoint->medium,
|
||||
.status = {Status::kSuccess},
|
||||
.endpoint_channel = std::move(channel_a),
|
||||
};
|
||||
}
|
||||
}));
|
||||
.WillRepeatedly(
|
||||
Invoke([&channel_a](ClientProxy* client,
|
||||
MockPcpHandler::DiscoveredEndpoint* endpoint) {
|
||||
if (endpoint->medium ==
|
||||
location::nearby::proto::connections::WIFI_LAN) {
|
||||
NEARBY_LOGS(INFO) << "Connect with Medium WIFI_LAN failed.";
|
||||
return MockPcpHandler::ConnectImplResult{
|
||||
.medium = endpoint->medium,
|
||||
.status = {Status::kError},
|
||||
.endpoint_channel = nullptr,
|
||||
};
|
||||
} else {
|
||||
NEARBY_LOGS(INFO)
|
||||
<< "Connect with Medium: "
|
||||
<< location::nearby::proto::connections::Medium_Name(
|
||||
endpoint->medium);
|
||||
return MockPcpHandler::ConnectImplResult{
|
||||
.medium = endpoint->medium,
|
||||
.status = {Status::kSuccess},
|
||||
.endpoint_channel = std::move(channel_a),
|
||||
};
|
||||
}
|
||||
}));
|
||||
|
||||
for (const auto& discovered_medium : allowed_mediums) {
|
||||
pcp_handler->OnEndpointFound(
|
||||
@@ -632,9 +683,6 @@ class BasePcpHandlerTest
|
||||
expected_result);
|
||||
NEARBY_LOG(INFO, "Stopping Encryption Runner");
|
||||
}
|
||||
|
||||
Pipe pipe_a_;
|
||||
Pipe pipe_b_;
|
||||
MockConnectionListener mock_connection_listener_;
|
||||
MockDiscoveryListener mock_discovery_listener_;
|
||||
ConnectionListener connection_listener_{
|
||||
@@ -654,6 +702,7 @@ class BasePcpHandlerTest
|
||||
.endpoint_distance_changed_cb =
|
||||
mock_discovery_listener_.endpoint_distance_changed_cb.AsStdFunction(),
|
||||
};
|
||||
SetSafeToDisconnect set_safe_to_disconnect_{true};
|
||||
MediumEnvironment& env_ = MediumEnvironment::Instance();
|
||||
};
|
||||
|
||||
@@ -823,7 +872,7 @@ TEST_F(BasePcpHandlerTest, WifiMediumFailFallBackToBT) {
|
||||
|
||||
auto mediums = pcp_handler.GetDiscoveryMediums(&client);
|
||||
auto connect_medium = mediums[mediums.size() - 1];
|
||||
auto channel_pair = SetupConnection(pipe_a_, pipe_b_, connect_medium);
|
||||
auto channel_pair = SetupConnection(connect_medium);
|
||||
auto& channel_a = channel_pair.first;
|
||||
auto& channel_b = channel_pair.second;
|
||||
EXPECT_CALL(*channel_a, CloseImpl).Times(1);
|
||||
@@ -849,7 +898,7 @@ TEST_P(BasePcpHandlerTest, RequestConnectionChangesState) {
|
||||
StartDiscovery(&client, &pcp_handler);
|
||||
auto mediums = pcp_handler.GetDiscoveryMediums(&client);
|
||||
auto connect_medium = mediums[mediums.size() - 1];
|
||||
auto channel_pair = SetupConnection(pipe_a_, pipe_b_, connect_medium);
|
||||
auto channel_pair = SetupConnection(connect_medium);
|
||||
auto& channel_a = channel_pair.first;
|
||||
auto& channel_b = channel_pair.second;
|
||||
EXPECT_CALL(*channel_a, CloseImpl).Times(1);
|
||||
@@ -894,7 +943,7 @@ TEST_P(BasePcpHandlerTest, CanRequestConnectionPresence) {
|
||||
StartDiscovery(&client, &pcp_handler);
|
||||
auto mediums = pcp_handler.GetDiscoveryMediums(&client);
|
||||
auto connect_medium = mediums[mediums.size() - 1];
|
||||
auto channel_pair = SetupConnection(pipe_a_, pipe_b_, connect_medium);
|
||||
auto channel_pair = SetupConnection(connect_medium);
|
||||
auto& channel_a = channel_pair.first;
|
||||
auto& channel_b = channel_pair.second;
|
||||
EXPECT_CALL(*channel_a, CloseImpl).Times(1);
|
||||
@@ -925,7 +974,7 @@ TEST_P(BasePcpHandlerTest, CanRequestConnectionLegacy) {
|
||||
StartDiscovery(&client, &pcp_handler);
|
||||
auto mediums = pcp_handler.GetDiscoveryMediums(&client);
|
||||
auto connect_medium = mediums[mediums.size() - 1];
|
||||
auto channel_pair = SetupConnection(pipe_a_, pipe_b_, connect_medium);
|
||||
auto channel_pair = SetupConnection(connect_medium);
|
||||
auto& channel_a = channel_pair.first;
|
||||
auto& channel_b = channel_pair.second;
|
||||
EXPECT_CALL(*channel_a, CloseImpl).Times(1);
|
||||
@@ -952,7 +1001,7 @@ TEST_P(BasePcpHandlerTest, IoError_RequestConnectionFails) {
|
||||
StartDiscovery(&client, &pcp_handler);
|
||||
auto mediums = pcp_handler.GetDiscoveryMediums(&client);
|
||||
auto connect_medium = mediums[mediums.size() - 1];
|
||||
auto channel_pair = SetupConnection(pipe_a_, pipe_b_, connect_medium);
|
||||
auto channel_pair = SetupConnection(connect_medium);
|
||||
auto& channel_a = channel_pair.first;
|
||||
auto& channel_b = channel_pair.second;
|
||||
EXPECT_CALL(*channel_a, CloseImpl).Times(AtLeast(1));
|
||||
@@ -981,7 +1030,7 @@ TEST_P(BasePcpHandlerTest, AcceptConnectionChangesState) {
|
||||
StartDiscovery(&client, &pcp_handler);
|
||||
auto mediums = pcp_handler.GetDiscoveryMediums(&client);
|
||||
auto connect_medium = mediums[mediums.size() - 1];
|
||||
auto channel_pair = SetupConnection(pipe_a_, pipe_b_, connect_medium);
|
||||
auto channel_pair = SetupConnection(connect_medium);
|
||||
auto& channel_a = channel_pair.first;
|
||||
auto& channel_b = channel_pair.second;
|
||||
EXPECT_CALL(*channel_a, CloseImpl).Times(1);
|
||||
@@ -1012,7 +1061,7 @@ TEST_P(BasePcpHandlerTest, RejectConnectionChangesState) {
|
||||
StartDiscovery(&client, &pcp_handler);
|
||||
auto mediums = pcp_handler.GetDiscoveryMediums(&client);
|
||||
auto connect_medium = mediums[mediums.size() - 1];
|
||||
auto channel_pair = SetupConnection(pipe_a_, pipe_b_, connect_medium);
|
||||
auto channel_pair = SetupConnection(connect_medium);
|
||||
auto& channel_b = channel_pair.second;
|
||||
EXPECT_CALL(mock_connection_listener_.rejected_cb, Call).Times(1);
|
||||
RequestConnection(endpoint_id, std::move(channel_pair.first), channel_b.get(),
|
||||
@@ -1040,7 +1089,7 @@ TEST_P(BasePcpHandlerTest, OnIncomingFrameChangesState) {
|
||||
StartDiscovery(&client, &pcp_handler);
|
||||
auto mediums = pcp_handler.GetDiscoveryMediums(&client);
|
||||
auto connect_medium = mediums[mediums.size() - 1];
|
||||
auto channel_pair = SetupConnection(pipe_a_, pipe_b_, connect_medium);
|
||||
auto channel_pair = SetupConnection(connect_medium);
|
||||
auto& channel_a = channel_pair.first;
|
||||
auto& channel_b = channel_pair.second;
|
||||
EXPECT_CALL(*channel_a, CloseImpl).Times(1);
|
||||
@@ -1082,7 +1131,7 @@ TEST_P(BasePcpHandlerTest, DestructorIsCalledOnProtocolEndpoint) {
|
||||
StartDiscovery(&client, &pcp_handler);
|
||||
auto mediums = pcp_handler.GetDiscoveryMediums(&client);
|
||||
auto connect_medium = mediums[mediums.size() - 1];
|
||||
auto channel_pair = SetupConnection(pipe_a_, pipe_b_, connect_medium);
|
||||
auto channel_pair = SetupConnection(connect_medium);
|
||||
auto& channel_a = channel_pair.first;
|
||||
auto& channel_b = channel_pair.second;
|
||||
EXPECT_CALL(*channel_a, CloseImpl).Times(1);
|
||||
@@ -1125,7 +1174,7 @@ TEST_P(BasePcpHandlerTest, MultipleMediumsProduceSingleEndpointLostEvent) {
|
||||
StartDiscovery(&client, &pcp_handler);
|
||||
auto mediums = pcp_handler.GetDiscoveryMediums(&client);
|
||||
auto connect_medium = mediums[mediums.size() - 1];
|
||||
auto channel_pair = SetupConnection(pipe_a_, pipe_b_, connect_medium);
|
||||
auto channel_pair = SetupConnection(connect_medium);
|
||||
auto& channel_a = channel_pair.first;
|
||||
auto& channel_b = channel_pair.second;
|
||||
EXPECT_CALL(*channel_a, CloseImpl).Times(1);
|
||||
@@ -1247,9 +1296,9 @@ TEST_F(BasePcpHandlerTest, TestStartStopEndpointLostAlarm) {
|
||||
.status = {Status::kSuccess},
|
||||
.mediums = allowed.GetMediums(true),
|
||||
}));
|
||||
EXPECT_EQ(pcp_handler.StartDiscovery(&client, service_id, discovery_options,
|
||||
{}),
|
||||
Status{Status::kSuccess});
|
||||
EXPECT_EQ(
|
||||
pcp_handler.StartDiscovery(&client, service_id, discovery_options, {}),
|
||||
Status{Status::kSuccess});
|
||||
EXPECT_TRUE(client.IsDiscovering());
|
||||
|
||||
EXPECT_CALL(pcp_handler, InjectEndpointImpl)
|
||||
@@ -1277,11 +1326,11 @@ TEST_F(BasePcpHandlerTest, TestStartStopEndpointLostAlarm) {
|
||||
.remote_bluetooth_mac_address = ByteArray(kFakeMacAddress),
|
||||
});
|
||||
EXPECT_EQ(pcp_handler.GetDiscoveredEndpoints(Medium::BLUETOOTH).size(), 1);
|
||||
EXPECT_EQ(pcp_handler.GetEndpointLostByMediumAlarms().size(), 0);
|
||||
EXPECT_EQ(pcp_handler.GetEndpointLostByMediumAlarmsCount(), 0);
|
||||
pcp_handler.StartEndpointLostByMediumAlarms(&client, Medium::BLUETOOTH);
|
||||
EXPECT_EQ(pcp_handler.GetEndpointLostByMediumAlarms().size(), 1);
|
||||
EXPECT_EQ(pcp_handler.GetEndpointLostByMediumAlarmsCount(), 1);
|
||||
pcp_handler.StopEndpointLostByMediumAlarm(endpoint_id, Medium::BLUETOOTH);
|
||||
EXPECT_EQ(pcp_handler.GetEndpointLostByMediumAlarms().size(), 0);
|
||||
EXPECT_EQ(pcp_handler.GetEndpointLostByMediumAlarmsCount(), 0);
|
||||
env_.Stop();
|
||||
}
|
||||
|
||||
@@ -1311,9 +1360,9 @@ TEST_F(BasePcpHandlerTest, TestStartEndpointLostByMediumAlarms) {
|
||||
.status = {Status::kSuccess},
|
||||
.mediums = allowed.GetMediums(true),
|
||||
}));
|
||||
EXPECT_EQ(pcp_handler.StartDiscovery(&client, service_id, discovery_options,
|
||||
{}),
|
||||
Status{Status::kSuccess});
|
||||
EXPECT_EQ(
|
||||
pcp_handler.StartDiscovery(&client, service_id, discovery_options, {}),
|
||||
Status{Status::kSuccess});
|
||||
EXPECT_TRUE(client.IsDiscovering());
|
||||
|
||||
EXPECT_CALL(pcp_handler, InjectEndpointImpl)
|
||||
@@ -1341,12 +1390,12 @@ TEST_F(BasePcpHandlerTest, TestStartEndpointLostByMediumAlarms) {
|
||||
.remote_bluetooth_mac_address = ByteArray(kFakeMacAddress),
|
||||
});
|
||||
EXPECT_EQ(pcp_handler.GetDiscoveredEndpoints(Medium::BLUETOOTH).size(), 1);
|
||||
EXPECT_EQ(pcp_handler.GetEndpointLostByMediumAlarms().size(), 0);
|
||||
EXPECT_EQ(pcp_handler.GetEndpointLostByMediumAlarmsCount(), 0);
|
||||
pcp_handler.StartEndpointLostByMediumAlarms(&client, Medium::BLUETOOTH);
|
||||
EXPECT_EQ(pcp_handler.GetEndpointLostByMediumAlarms().size(), 1);
|
||||
EXPECT_EQ(pcp_handler.GetEndpointLostByMediumAlarmsCount(), 1);
|
||||
absl::SleepFor(absl::Seconds(11));
|
||||
EXPECT_EQ(pcp_handler.GetDiscoveredEndpoints(Medium::BLUETOOTH).size(), 0);
|
||||
EXPECT_EQ(pcp_handler.GetEndpointLostByMediumAlarms().size(), 0);
|
||||
EXPECT_EQ(pcp_handler.GetEndpointLostByMediumAlarmsCount(), 0);
|
||||
env_.Stop();
|
||||
}
|
||||
|
||||
@@ -1376,37 +1425,39 @@ TEST_F(BasePcpHandlerTest, TestEndpointFoundStopsAlarm) {
|
||||
.status = {Status::kSuccess},
|
||||
.mediums = allowed.GetMediums(true),
|
||||
}));
|
||||
EXPECT_EQ(pcp_handler.StartDiscovery(&client, service_id, discovery_options,
|
||||
{}),
|
||||
Status{Status::kSuccess});
|
||||
EXPECT_EQ(
|
||||
pcp_handler.StartDiscovery(&client, service_id, discovery_options, {}),
|
||||
Status{Status::kSuccess});
|
||||
EXPECT_TRUE(client.IsDiscovering());
|
||||
|
||||
bool first_call = true;
|
||||
EXPECT_CALL(pcp_handler, InjectEndpointImpl).Times(2)
|
||||
.WillRepeatedly(Invoke([&pcp_handler, &endpoint_id, &first_call](
|
||||
ClientProxy* client, const std::string& service_id,
|
||||
const OutOfBandConnectionMetadata& metadata) {
|
||||
ByteArray endpoint_info;
|
||||
if (first_call) {
|
||||
endpoint_info = ByteArray("ABCD");
|
||||
} else {
|
||||
endpoint_info = ByteArray("ABCDE");
|
||||
}
|
||||
first_call = false;
|
||||
pcp_handler.OnEndpointFound(
|
||||
client,
|
||||
std::make_shared<MockDiscoveredEndpoint>(MockDiscoveredEndpoint{
|
||||
{
|
||||
endpoint_id,
|
||||
endpoint_info,
|
||||
service_id,
|
||||
Medium::BLUETOOTH,
|
||||
WebRtcState::kUndefined,
|
||||
},
|
||||
MockContext{nullptr},
|
||||
}));
|
||||
return Status{Status::kSuccess};
|
||||
}));
|
||||
EXPECT_CALL(pcp_handler, InjectEndpointImpl)
|
||||
.Times(2)
|
||||
.WillRepeatedly(
|
||||
Invoke([&pcp_handler, &endpoint_id, &first_call](
|
||||
ClientProxy* client, const std::string& service_id,
|
||||
const OutOfBandConnectionMetadata& metadata) {
|
||||
ByteArray endpoint_info;
|
||||
if (first_call) {
|
||||
endpoint_info = ByteArray("ABCD");
|
||||
} else {
|
||||
endpoint_info = ByteArray("ABCDE");
|
||||
}
|
||||
first_call = false;
|
||||
pcp_handler.OnEndpointFound(
|
||||
client,
|
||||
std::make_shared<MockDiscoveredEndpoint>(MockDiscoveredEndpoint{
|
||||
{
|
||||
endpoint_id,
|
||||
endpoint_info,
|
||||
service_id,
|
||||
Medium::BLUETOOTH,
|
||||
WebRtcState::kUndefined,
|
||||
},
|
||||
MockContext{nullptr},
|
||||
}));
|
||||
return Status{Status::kSuccess};
|
||||
}));
|
||||
pcp_handler.InjectEndpoint(
|
||||
&client, service_id,
|
||||
OutOfBandConnectionMetadata{
|
||||
@@ -1414,16 +1465,16 @@ TEST_F(BasePcpHandlerTest, TestEndpointFoundStopsAlarm) {
|
||||
.remote_bluetooth_mac_address = ByteArray(kFakeMacAddress),
|
||||
});
|
||||
EXPECT_EQ(pcp_handler.GetDiscoveredEndpoints(Medium::BLUETOOTH).size(), 1);
|
||||
EXPECT_EQ(pcp_handler.GetEndpointLostByMediumAlarms().size(), 0);
|
||||
EXPECT_EQ(pcp_handler.GetEndpointLostByMediumAlarmsCount(), 0);
|
||||
pcp_handler.StartEndpointLostByMediumAlarms(&client, Medium::BLUETOOTH);
|
||||
EXPECT_EQ(pcp_handler.GetEndpointLostByMediumAlarms().size(), 1);
|
||||
EXPECT_EQ(pcp_handler.GetEndpointLostByMediumAlarmsCount(), 1);
|
||||
pcp_handler.InjectEndpoint(
|
||||
&client, service_id,
|
||||
OutOfBandConnectionMetadata{
|
||||
.medium = Medium::BLUETOOTH,
|
||||
.remote_bluetooth_mac_address = ByteArray(kFakeMacAddress),
|
||||
});
|
||||
EXPECT_EQ(pcp_handler.GetEndpointLostByMediumAlarms().size(), 0);
|
||||
EXPECT_EQ(pcp_handler.GetEndpointLostByMediumAlarmsCount(), 0);
|
||||
env_.Stop();
|
||||
}
|
||||
|
||||
@@ -1564,7 +1615,7 @@ TEST_F(BasePcpHandlerTest, TestDeviceFilterForConnectionsWithUnknown) {
|
||||
.first.Ok());
|
||||
ASSERT_TRUE(client.IsListeningForIncomingConnections());
|
||||
ASSERT_TRUE(pcp_handler.CanReceiveIncomingConnection(&client));
|
||||
auto channel_pair = SetupConnection(pipe_a_, pipe_b_, Medium::BLUETOOTH);
|
||||
auto channel_pair = SetupConnection(Medium::BLUETOOTH);
|
||||
ByteArray serialized_frame = parser::ForConnectionRequestConnections(
|
||||
{}, {
|
||||
.local_endpoint_id = "ABCD",
|
||||
@@ -1613,7 +1664,7 @@ TEST_F(BasePcpHandlerTest, TestDeviceFilterForPresenceWithUnknown) {
|
||||
.first.Ok());
|
||||
ASSERT_TRUE(client.IsListeningForIncomingConnections());
|
||||
ASSERT_TRUE(pcp_handler.CanReceiveIncomingConnection(&client));
|
||||
auto channel_pair = SetupConnection(pipe_a_, pipe_b_, Medium::BLUETOOTH);
|
||||
auto channel_pair = SetupConnection(Medium::BLUETOOTH);
|
||||
ByteArray serialized_frame = parser::ForConnectionRequestConnections(
|
||||
{}, {
|
||||
.local_endpoint_id = "ABCD",
|
||||
@@ -1663,7 +1714,7 @@ TEST_F(BasePcpHandlerTest, TestDeviceFilterForPresenceWithConnections) {
|
||||
.first.Ok());
|
||||
ASSERT_TRUE(client.IsListeningForIncomingConnections());
|
||||
ASSERT_TRUE(pcp_handler.CanReceiveIncomingConnection(&client));
|
||||
auto channel_pair = SetupConnection(pipe_a_, pipe_b_, Medium::BLUETOOTH);
|
||||
auto channel_pair = SetupConnection(Medium::BLUETOOTH);
|
||||
ByteArray serialized_frame = parser::ForConnectionRequestConnections(
|
||||
{}, {
|
||||
.local_endpoint_id = "ABCD",
|
||||
@@ -1714,7 +1765,7 @@ TEST_F(BasePcpHandlerTest, TestDeviceFilterForPresenceWithPresence) {
|
||||
.first.Ok());
|
||||
ASSERT_TRUE(client.IsListeningForIncomingConnections());
|
||||
ASSERT_TRUE(pcp_handler.CanReceiveIncomingConnection(&client));
|
||||
auto channel_pair = SetupConnection(pipe_a_, pipe_b_, Medium::BLUETOOTH);
|
||||
auto channel_pair = SetupConnection(Medium::BLUETOOTH);
|
||||
ByteArray serialized_frame = parser::ForConnectionRequestConnections(
|
||||
{}, {
|
||||
.local_endpoint_id = "ABCD",
|
||||
@@ -1764,7 +1815,7 @@ TEST_F(BasePcpHandlerTest, TestDeviceFilterForConnectionsWithConnections) {
|
||||
.first.Ok());
|
||||
ASSERT_TRUE(client.IsListeningForIncomingConnections());
|
||||
ASSERT_TRUE(pcp_handler.CanReceiveIncomingConnection(&client));
|
||||
auto channel_pair = SetupConnection(pipe_a_, pipe_b_, Medium::BLUETOOTH);
|
||||
auto channel_pair = SetupConnection(Medium::BLUETOOTH);
|
||||
ByteArray serialized_frame = parser::ForConnectionRequestConnections(
|
||||
{}, {
|
||||
.local_endpoint_id = "ABCD",
|
||||
@@ -1814,7 +1865,7 @@ TEST_F(BasePcpHandlerTest, TestDeviceFilterForConnectionsWithPresence) {
|
||||
.first.Ok());
|
||||
ASSERT_TRUE(client.IsListeningForIncomingConnections());
|
||||
ASSERT_TRUE(pcp_handler.CanReceiveIncomingConnection(&client));
|
||||
auto channel_pair = SetupConnection(pipe_a_, pipe_b_, Medium::BLUETOOTH);
|
||||
auto channel_pair = SetupConnection(Medium::BLUETOOTH);
|
||||
ByteArray serialized_frame = parser::ForConnectionRequestConnections(
|
||||
{}, {
|
||||
.local_endpoint_id = "ABCD",
|
||||
|
||||
@@ -28,9 +28,10 @@
|
||||
namespace nearby {
|
||||
namespace connections {
|
||||
|
||||
BluetoothBwuHandler::BluetoothBwuHandler(Mediums& mediums,
|
||||
BwuNotifications notifications)
|
||||
: BaseBwuHandler(std::move(notifications)), mediums_(mediums) {}
|
||||
BluetoothBwuHandler::BluetoothBwuHandler(
|
||||
Mediums& mediums, IncomingConnectionCallback incoming_connection_callback)
|
||||
: BaseBwuHandler(std::move(incoming_connection_callback)),
|
||||
mediums_(mediums) {}
|
||||
|
||||
// Called by BWU target. Retrieves a new medium info from incoming message,
|
||||
// and establishes connection over BT using this info.
|
||||
@@ -110,11 +111,9 @@ ByteArray BluetoothBwuHandler::HandleInitializeUpgradedMediumForEndpoint(
|
||||
if (!bluetooth_medium_.IsAcceptingConnections(upgrade_service_id)) {
|
||||
if (!bluetooth_medium_.StartAcceptingConnections(
|
||||
upgrade_service_id,
|
||||
{
|
||||
.accepted_cb = absl::bind_front(
|
||||
&BluetoothBwuHandler::OnIncomingBluetoothConnection, this,
|
||||
client),
|
||||
})) {
|
||||
absl::bind_front(
|
||||
&BluetoothBwuHandler::OnIncomingBluetoothConnection, this,
|
||||
client))) {
|
||||
NEARBY_LOGS(ERROR) << "BluetoothBwuHandler couldn't initiate the "
|
||||
"BLUETOOTH upgrade for endpoint "
|
||||
<< endpoint_id
|
||||
@@ -153,7 +152,7 @@ void BluetoothBwuHandler::OnIncomingBluetoothConnection(
|
||||
upgrade_service_id, socket),
|
||||
.channel = std::move(channel),
|
||||
}};
|
||||
bwu_notifications_.incoming_connection_cb(client, std::move(connection));
|
||||
NotifyOnIncomingConnection(client, std::move(connection));
|
||||
}
|
||||
|
||||
} // namespace connections
|
||||
|
||||
@@ -31,8 +31,9 @@ namespace connections {
|
||||
// per-Medium-specific operations needed to upgrade an EndpointChannel.
|
||||
class BluetoothBwuHandler : public BaseBwuHandler {
|
||||
public:
|
||||
explicit BluetoothBwuHandler(Mediums& mediums,
|
||||
BwuNotifications notifications);
|
||||
explicit BluetoothBwuHandler(
|
||||
Mediums& mediums,
|
||||
IncomingConnectionCallback incoming_connection_callback);
|
||||
|
||||
private:
|
||||
class BluetoothIncomingSocket : public IncomingSocket {
|
||||
|
||||
@@ -18,6 +18,7 @@
|
||||
#include <functional>
|
||||
#include <string>
|
||||
|
||||
#include "absl/functional/any_invocable.h"
|
||||
#include "connections/implementation/client_proxy.h"
|
||||
#include "connections/implementation/endpoint_channel.h"
|
||||
#include "connections/implementation/offline_frames.h"
|
||||
@@ -47,12 +48,9 @@ class BwuHandler {
|
||||
std::unique_ptr<IncomingSocket> socket;
|
||||
std::unique_ptr<EndpointChannel> channel;
|
||||
};
|
||||
|
||||
struct BwuNotifications {
|
||||
std::function<void(ClientProxy* client,
|
||||
std::unique_ptr<IncomingSocketConnection> connection)>
|
||||
incoming_connection_cb;
|
||||
};
|
||||
using IncomingConnectionCallback = absl::AnyInvocable<void(
|
||||
ClientProxy* client,
|
||||
std::unique_ptr<IncomingSocketConnection> connection)>;
|
||||
|
||||
virtual ~BwuHandler() = default;
|
||||
|
||||
|
||||
@@ -24,6 +24,8 @@
|
||||
#include "absl/time/time.h"
|
||||
#include "connections/implementation/bluetooth_bwu_handler.h"
|
||||
#include "connections/implementation/bwu_handler.h"
|
||||
#include "connections/implementation/client_proxy.h"
|
||||
#include "connections/implementation/endpoint_channel_manager.h"
|
||||
#include "connections/implementation/offline_frames.h"
|
||||
#include "connections/implementation/service_id_constants.h"
|
||||
#ifdef NO_WEBRTC
|
||||
@@ -103,31 +105,40 @@ BwuManager::~BwuManager() {
|
||||
|
||||
void BwuManager::InitBwuHandlers() {
|
||||
// Register the supported concrete BwuMedium implementations.
|
||||
BwuHandler::BwuNotifications notifications{
|
||||
.incoming_connection_cb =
|
||||
absl::bind_front(&BwuManager::OnIncomingConnection, this),
|
||||
};
|
||||
if (config_.allow_upgrade_to.wifi_hotspot) {
|
||||
handlers_.emplace(
|
||||
Medium::WIFI_HOTSPOT,
|
||||
std::make_unique<WifiHotspotBwuHandler>(*mediums_, notifications));
|
||||
std::make_unique<WifiHotspotBwuHandler>(
|
||||
*mediums_,
|
||||
absl::bind_front(&BwuManager::OnIncomingConnection, this)));
|
||||
}
|
||||
if (config_.allow_upgrade_to.wifi_direct) {
|
||||
handlers_.emplace(
|
||||
Medium::WIFI_DIRECT,
|
||||
std::make_unique<WifiDirectBwuHandler>(*mediums_, notifications));
|
||||
std::make_unique<WifiDirectBwuHandler>(
|
||||
*mediums_,
|
||||
absl::bind_front(&BwuManager::OnIncomingConnection, this)));
|
||||
}
|
||||
if (config_.allow_upgrade_to.wifi_lan) {
|
||||
handlers_.emplace(Medium::WIFI_LAN, std::make_unique<WifiLanBwuHandler>(
|
||||
*mediums_, notifications));
|
||||
handlers_.emplace(
|
||||
Medium::WIFI_LAN,
|
||||
std::make_unique<WifiLanBwuHandler>(
|
||||
*mediums_,
|
||||
absl::bind_front(&BwuManager::OnIncomingConnection, this)));
|
||||
}
|
||||
if (config_.allow_upgrade_to.web_rtc) {
|
||||
handlers_.emplace(Medium::WEB_RTC, std::make_unique<WebrtcBwuHandler>(
|
||||
*mediums_, notifications));
|
||||
handlers_.emplace(
|
||||
Medium::WEB_RTC,
|
||||
std::make_unique<WebrtcBwuHandler>(
|
||||
*mediums_,
|
||||
absl::bind_front(&BwuManager::OnIncomingConnection, this)));
|
||||
}
|
||||
if (config_.allow_upgrade_to.bluetooth) {
|
||||
handlers_.emplace(Medium::BLUETOOTH, std::make_unique<BluetoothBwuHandler>(
|
||||
*mediums_, notifications));
|
||||
handlers_.emplace(
|
||||
Medium::BLUETOOTH,
|
||||
std::make_unique<BluetoothBwuHandler>(
|
||||
*mediums_,
|
||||
absl::bind_front(&BwuManager::OnIncomingConnection, this)));
|
||||
}
|
||||
}
|
||||
|
||||
@@ -334,7 +345,8 @@ void BwuManager::OnIncomingFrame(OfflineFrame& frame,
|
||||
void BwuManager::OnEndpointDisconnect(ClientProxy* client,
|
||||
const std::string& service_id,
|
||||
const std::string& endpoint_id,
|
||||
CountDownLatch barrier) {
|
||||
CountDownLatch barrier,
|
||||
DisconnectionReason reason) {
|
||||
NEARBY_LOGS(INFO)
|
||||
<< "BwuManager has processed endpoint disconnection for endpoint "
|
||||
<< endpoint_id;
|
||||
@@ -700,8 +712,8 @@ void BwuManager::ProcessBwuPathAvailableEvent(
|
||||
|
||||
return;
|
||||
}
|
||||
Medium current_medium = GetBwuMediumForEndpoint(endpoint_id);
|
||||
if (current_medium == Medium::UNKNOWN_MEDIUM) {
|
||||
Medium current_bwu_medium = GetBwuMediumForEndpoint(endpoint_id);
|
||||
if (current_bwu_medium == Medium::UNKNOWN_MEDIUM) {
|
||||
SetBwuMediumForEndpoint(endpoint_id, upgrade_medium);
|
||||
}
|
||||
// Check for the correct medium so we don't process an incorrect OfflineFrame.
|
||||
@@ -711,6 +723,9 @@ void BwuManager::ProcessBwuPathAvailableEvent(
|
||||
return;
|
||||
}
|
||||
|
||||
auto current_channel = channel_manager_->GetChannelForEndpoint(endpoint_id);
|
||||
Medium current_medium =
|
||||
current_channel ? current_channel->GetMedium() : Medium::UNKNOWN_MEDIUM;
|
||||
client->GetAnalyticsRecorder().OnBandwidthUpgradeStarted(
|
||||
endpoint_id, current_medium, upgrade_medium,
|
||||
location::nearby::proto::connections::OUTGOING,
|
||||
@@ -1100,7 +1115,11 @@ void BwuManager::ProcessSafeToClosePriorChannelEvent(
|
||||
// circumstances so it is necessary to send it unencrypted. This way the
|
||||
// serial crypto context does not increment here.
|
||||
previous_endpoint_channel->DisableEncryption();
|
||||
previous_endpoint_channel->Write(parser::ForDisconnection());
|
||||
NEARBY_LOGS(INFO) << "[safe-to-disconnect] Sending "
|
||||
"DISCONNECTION frame with request 0, ack 0";
|
||||
previous_endpoint_channel->Write(
|
||||
parser::ForDisconnection(/* request_safe_to_disconnect */ false,
|
||||
/* ack_safe_to_disconnect */ false));
|
||||
|
||||
// Attempt to read the disconnect message from the previous channel. We don't
|
||||
// care whether we successfully read it or whether we get an exception here.
|
||||
|
||||
@@ -94,7 +94,8 @@ class BwuManager : public EndpointManager::FrameProcessor {
|
||||
void OnEndpointDisconnect(ClientProxy* client_proxy,
|
||||
const std::string& service_id,
|
||||
const std::string& endpoint_id,
|
||||
CountDownLatch barrier) override;
|
||||
CountDownLatch barrier,
|
||||
DisconnectionReason reason) override;
|
||||
|
||||
void Shutdown();
|
||||
|
||||
|
||||
@@ -30,15 +30,19 @@
|
||||
#include "connections/implementation/offline_frames.h"
|
||||
#include "connections/implementation/service_id_constants.h"
|
||||
#include "internal/platform/exception.h"
|
||||
#include "internal/proto/analytics/connections_log.pb.h"
|
||||
#include "proto/connections_enums.pb.h"
|
||||
|
||||
namespace nearby {
|
||||
namespace connections {
|
||||
namespace {
|
||||
using ::location::nearby::analytics::proto::ConnectionsLog;
|
||||
using ::location::nearby::connections::BandwidthUpgradeNegotiationFrame;
|
||||
using ::location::nearby::connections::
|
||||
BandwidthUpgradeNegotiationFrame_UpgradePathInfo;
|
||||
using ::location::nearby::connections::OfflineFrame;
|
||||
using ::location::nearby::connections::V1Frame;
|
||||
using ::location::nearby::proto::connections::DisconnectionReason;
|
||||
|
||||
constexpr absl::string_view kServiceIdA = "ServiceA";
|
||||
constexpr absl::string_view kServiceIdB = "ServiceB";
|
||||
@@ -95,6 +99,11 @@ class BwuManagerTest : public ::testing::Test {
|
||||
std::move(channel));
|
||||
return channel_raw;
|
||||
}
|
||||
void UnRegisterChannelForEndpoint(absl::string_view endpoint_id) {
|
||||
ecm_.UnregisterChannelForEndpoint(
|
||||
std::string(endpoint_id), DisconnectionReason::LOCAL_DISCONNECTION,
|
||||
ConnectionsLog::EstablishedConnection::SAFE_DISCONNECTION);
|
||||
}
|
||||
|
||||
// Upgrade from |initial_medium| to |upgrade_medium|, close down the BLUETOOTH
|
||||
// channel, return the upgraded endpoint channel. This logic is tested in
|
||||
@@ -175,6 +184,9 @@ TEST(BwuManagerBaseTest, AllowToUpgradeMedium) {
|
||||
bwu_manager->InitiateBwuForEndpoint(&client, std::string(kEndpointId1),
|
||||
Medium::WIFI_LAN);
|
||||
EXPECT_TRUE(bwu_manager->IsUpgradeOngoing(std::string(kEndpointId1)));
|
||||
ecm.UnregisterChannelForEndpoint(
|
||||
std::string(kEndpointId1), DisconnectionReason::LOCAL_DISCONNECTION,
|
||||
ConnectionsLog::EstablishedConnection::SAFE_DISCONNECTION);
|
||||
|
||||
auto channel2 = std::make_unique<FakeEndpointChannel>(
|
||||
Medium::BLUETOOTH, std::string(kServiceIdA));
|
||||
@@ -183,6 +195,9 @@ TEST(BwuManagerBaseTest, AllowToUpgradeMedium) {
|
||||
bwu_manager->InitiateBwuForEndpoint(&client, std::string(kEndpointId2),
|
||||
Medium::WIFI_HOTSPOT);
|
||||
EXPECT_TRUE(bwu_manager->IsUpgradeOngoing(std::string(kEndpointId2)));
|
||||
ecm.UnregisterChannelForEndpoint(
|
||||
std::string(kEndpointId2), DisconnectionReason::LOCAL_DISCONNECTION,
|
||||
ConnectionsLog::EstablishedConnection::SAFE_DISCONNECTION);
|
||||
|
||||
auto channel3 = std::make_unique<FakeEndpointChannel>(
|
||||
Medium::BLUETOOTH, std::string(kServiceIdA));
|
||||
@@ -191,6 +206,9 @@ TEST(BwuManagerBaseTest, AllowToUpgradeMedium) {
|
||||
bwu_manager->InitiateBwuForEndpoint(&client, std::string(kEndpointId3),
|
||||
Medium::WIFI_DIRECT);
|
||||
EXPECT_TRUE(bwu_manager->IsUpgradeOngoing(std::string(kEndpointId3)));
|
||||
ecm.UnregisterChannelForEndpoint(
|
||||
std::string(kEndpointId3), DisconnectionReason::LOCAL_DISCONNECTION,
|
||||
ConnectionsLog::EstablishedConnection::SAFE_DISCONNECTION);
|
||||
|
||||
auto channel4 = std::make_unique<FakeEndpointChannel>(
|
||||
Medium::WEB_RTC, std::string(kServiceIdA));
|
||||
@@ -199,6 +217,9 @@ TEST(BwuManagerBaseTest, AllowToUpgradeMedium) {
|
||||
bwu_manager->InitiateBwuForEndpoint(&client, std::string(kEndpointId4),
|
||||
Medium::BLUETOOTH);
|
||||
EXPECT_FALSE(bwu_manager->IsUpgradeOngoing(std::string(kEndpointId4)));
|
||||
ecm.UnregisterChannelForEndpoint(
|
||||
std::string(kEndpointId4), DisconnectionReason::LOCAL_DISCONNECTION,
|
||||
ConnectionsLog::EstablishedConnection::SAFE_DISCONNECTION);
|
||||
|
||||
bwu_manager->Shutdown();
|
||||
}
|
||||
@@ -272,6 +293,7 @@ TEST_P(BwuManagerTestParam, InitiateBwu_Success) {
|
||||
EXPECT_TRUE(old_channel->is_closed());
|
||||
EXPECT_EQ(location::nearby::proto::connections::DisconnectionReason::UPGRADED,
|
||||
old_channel->disconnection_reason());
|
||||
UnRegisterChannelForEndpoint(kEndpointId1);
|
||||
}
|
||||
|
||||
TEST_P(BwuManagerTestParam,
|
||||
@@ -285,6 +307,7 @@ TEST_P(BwuManagerTestParam,
|
||||
bwu_manager_->InitiateBwuForEndpoint(&client_, std::string(kEndpointId1),
|
||||
Medium::WEB_RTC);
|
||||
EXPECT_EQ(1u, fake_web_rtc_bwu_handler_->handle_initialize_calls().size());
|
||||
UnRegisterChannelForEndpoint(kEndpointId1);
|
||||
}
|
||||
|
||||
TEST_P(BwuManagerTestParam,
|
||||
@@ -296,6 +319,7 @@ TEST_P(BwuManagerTestParam,
|
||||
Medium::WIFI_HOTSPOT);
|
||||
EXPECT_TRUE(
|
||||
fake_wifi_hotspot_bwu_handler_->handle_initialize_calls().empty());
|
||||
UnRegisterChannelForEndpoint(kEndpointId1);
|
||||
}
|
||||
|
||||
TEST_P(BwuManagerTestParam, InitiateBwu_Error_NoInitialMedium) {
|
||||
@@ -327,6 +351,7 @@ TEST_P(BwuManagerTestParam, InitiateBwu_Error_UpgradeAlreadyInProgress) {
|
||||
EXPECT_TRUE(
|
||||
fake_wifi_hotspot_bwu_handler_->handle_initialize_calls().empty());
|
||||
EXPECT_TRUE(fake_wifi_direct_bwu_handler_->handle_initialize_calls().empty());
|
||||
UnRegisterChannelForEndpoint(kEndpointId1);
|
||||
}
|
||||
|
||||
TEST_P(BwuManagerTestParam,
|
||||
@@ -358,6 +383,7 @@ TEST_P(BwuManagerTestParam,
|
||||
ecm_.GetChannelForEndpoint(std::string(kEndpointId1)).get());
|
||||
EXPECT_EQ(initial_channel,
|
||||
ecm_.GetChannelForEndpoint(std::string(kEndpointId1)).get());
|
||||
UnRegisterChannelForEndpoint(kEndpointId1);
|
||||
}
|
||||
|
||||
TEST_F(BwuManagerTest,
|
||||
@@ -380,9 +406,12 @@ TEST_F(BwuManagerTest,
|
||||
// Disconnect the first WebRTC endpoint. We don't expect a revert until the
|
||||
// last WebRTC endpoint for the service is disconnected.
|
||||
CountDownLatch latch(1);
|
||||
ecm_.UnregisterChannelForEndpoint(std::string(kEndpointId1));
|
||||
bwu_manager_->OnEndpointDisconnect(&client_, upgrade_service_id,
|
||||
std::string(kEndpointId1), latch);
|
||||
ecm_.UnregisterChannelForEndpoint(
|
||||
std::string(kEndpointId1), DisconnectionReason::LOCAL_DISCONNECTION,
|
||||
ConnectionsLog::EstablishedConnection::UNSAFE_DISCONNECTION);
|
||||
bwu_manager_->OnEndpointDisconnect(
|
||||
&client_, upgrade_service_id, std::string(kEndpointId1), latch,
|
||||
DisconnectionReason::LOCAL_DISCONNECTION);
|
||||
ASSERT_EQ(1u, fake_web_rtc_bwu_handler_->disconnect_calls().size());
|
||||
EXPECT_EQ(kEndpointId1,
|
||||
fake_web_rtc_bwu_handler_->disconnect_calls()[0].endpoint_id);
|
||||
@@ -391,9 +420,12 @@ TEST_F(BwuManagerTest,
|
||||
{
|
||||
// Disconnect the second WebRTC endpoint. We expect a revert.
|
||||
CountDownLatch latch(1);
|
||||
ecm_.UnregisterChannelForEndpoint(std::string(kEndpointId2));
|
||||
bwu_manager_->OnEndpointDisconnect(&client_, upgrade_service_id,
|
||||
std::string(kEndpointId2), latch);
|
||||
ecm_.UnregisterChannelForEndpoint(
|
||||
std::string(kEndpointId2), DisconnectionReason::LOCAL_DISCONNECTION,
|
||||
ConnectionsLog::EstablishedConnection::UNSAFE_DISCONNECTION);
|
||||
bwu_manager_->OnEndpointDisconnect(
|
||||
&client_, upgrade_service_id, std::string(kEndpointId2), latch,
|
||||
DisconnectionReason::LOCAL_DISCONNECTION);
|
||||
ASSERT_EQ(2u, fake_web_rtc_bwu_handler_->disconnect_calls().size());
|
||||
EXPECT_EQ(kEndpointId2,
|
||||
fake_web_rtc_bwu_handler_->disconnect_calls()[1].endpoint_id);
|
||||
@@ -423,9 +455,12 @@ TEST_F(BwuManagerTest,
|
||||
{
|
||||
// Disconnect the first WebRTC endpoint.
|
||||
CountDownLatch latch(1);
|
||||
ecm_.UnregisterChannelForEndpoint(std::string(kEndpointId1));
|
||||
bwu_manager_->OnEndpointDisconnect(&client_, upgrade_service_id,
|
||||
std::string(kEndpointId1), latch);
|
||||
ecm_.UnregisterChannelForEndpoint(
|
||||
std::string(kEndpointId1), DisconnectionReason::LOCAL_DISCONNECTION,
|
||||
ConnectionsLog::EstablishedConnection::UNSAFE_DISCONNECTION);
|
||||
bwu_manager_->OnEndpointDisconnect(
|
||||
&client_, upgrade_service_id, std::string(kEndpointId1), latch,
|
||||
DisconnectionReason::LOCAL_DISCONNECTION);
|
||||
ASSERT_EQ(1u, fake_web_rtc_bwu_handler_->disconnect_calls().size());
|
||||
EXPECT_EQ(kEndpointId1,
|
||||
fake_web_rtc_bwu_handler_->disconnect_calls()[0].endpoint_id);
|
||||
@@ -440,9 +475,12 @@ TEST_F(BwuManagerTest,
|
||||
{
|
||||
// Disconnect the second WebRTC endpoint.
|
||||
CountDownLatch latch(1);
|
||||
ecm_.UnregisterChannelForEndpoint(std::string(kEndpointId2));
|
||||
bwu_manager_->OnEndpointDisconnect(&client_, upgrade_service_id,
|
||||
std::string(kEndpointId2), latch);
|
||||
ecm_.UnregisterChannelForEndpoint(
|
||||
std::string(kEndpointId2), DisconnectionReason::LOCAL_DISCONNECTION,
|
||||
ConnectionsLog::EstablishedConnection::UNSAFE_DISCONNECTION);
|
||||
bwu_manager_->OnEndpointDisconnect(
|
||||
&client_, upgrade_service_id, std::string(kEndpointId2), latch,
|
||||
DisconnectionReason::LOCAL_DISCONNECTION);
|
||||
|
||||
// Note(nohle): There appears to be an off-by-one error in the
|
||||
// existing/flag-disabled code. Revert is called when there are "<= 1"
|
||||
@@ -474,10 +512,13 @@ TEST_F(BwuManagerTest,
|
||||
{
|
||||
CountDownLatch latch(1);
|
||||
EXPECT_EQ(2u, ecm_.GetConnectedEndpointsCount());
|
||||
ecm_.UnregisterChannelForEndpoint(std::string(kEndpointId1));
|
||||
ecm_.UnregisterChannelForEndpoint(
|
||||
std::string(kEndpointId1), DisconnectionReason::LOCAL_DISCONNECTION,
|
||||
ConnectionsLog::EstablishedConnection::UNSAFE_DISCONNECTION);
|
||||
EXPECT_EQ(1u, ecm_.GetConnectedEndpointsCount());
|
||||
bwu_manager_->OnEndpointDisconnect(&client_, upgrade_service_id_A,
|
||||
std::string(kEndpointId1), latch);
|
||||
bwu_manager_->OnEndpointDisconnect(
|
||||
&client_, upgrade_service_id_A, std::string(kEndpointId1), latch,
|
||||
DisconnectionReason::LOCAL_DISCONNECTION);
|
||||
ASSERT_EQ(1u, fake_wifi_lan_bwu_handler_->disconnect_calls().size());
|
||||
EXPECT_EQ(kEndpointId1,
|
||||
fake_wifi_lan_bwu_handler_->disconnect_calls()[0].endpoint_id);
|
||||
@@ -491,10 +532,13 @@ TEST_F(BwuManagerTest,
|
||||
}
|
||||
{
|
||||
CountDownLatch latch(1);
|
||||
ecm_.UnregisterChannelForEndpoint(std::string(kEndpointId2));
|
||||
ecm_.UnregisterChannelForEndpoint(
|
||||
std::string(kEndpointId2), DisconnectionReason::LOCAL_DISCONNECTION,
|
||||
ConnectionsLog::EstablishedConnection::UNSAFE_DISCONNECTION);
|
||||
EXPECT_EQ(0u, ecm_.GetConnectedEndpointsCount());
|
||||
bwu_manager_->OnEndpointDisconnect(&client_, upgrade_service_id_B,
|
||||
std::string(kEndpointId2), latch);
|
||||
bwu_manager_->OnEndpointDisconnect(
|
||||
&client_, upgrade_service_id_B, std::string(kEndpointId2), latch,
|
||||
DisconnectionReason::LOCAL_DISCONNECTION);
|
||||
ASSERT_EQ(2u, fake_wifi_lan_bwu_handler_->disconnect_calls().size());
|
||||
EXPECT_EQ(kEndpointId2,
|
||||
fake_wifi_lan_bwu_handler_->disconnect_calls()[1].endpoint_id);
|
||||
@@ -523,10 +567,13 @@ TEST_F(BwuManagerTest,
|
||||
{
|
||||
CountDownLatch latch(1);
|
||||
EXPECT_EQ(2u, ecm_.GetConnectedEndpointsCount());
|
||||
ecm_.UnregisterChannelForEndpoint(std::string(kEndpointId1));
|
||||
ecm_.UnregisterChannelForEndpoint(
|
||||
std::string(kEndpointId1), DisconnectionReason::LOCAL_DISCONNECTION,
|
||||
ConnectionsLog::EstablishedConnection::UNSAFE_DISCONNECTION);
|
||||
EXPECT_EQ(1u, ecm_.GetConnectedEndpointsCount());
|
||||
bwu_manager_->OnEndpointDisconnect(&client_, upgrade_service_id_A,
|
||||
std::string(kEndpointId1), latch);
|
||||
bwu_manager_->OnEndpointDisconnect(
|
||||
&client_, upgrade_service_id_A, std::string(kEndpointId1), latch,
|
||||
DisconnectionReason::LOCAL_DISCONNECTION);
|
||||
ASSERT_EQ(1u, fake_wifi_lan_bwu_handler_->disconnect_calls().size());
|
||||
EXPECT_EQ(kEndpointId1,
|
||||
fake_wifi_lan_bwu_handler_->disconnect_calls()[0].endpoint_id);
|
||||
@@ -540,10 +587,13 @@ TEST_F(BwuManagerTest,
|
||||
}
|
||||
{
|
||||
CountDownLatch latch(1);
|
||||
ecm_.UnregisterChannelForEndpoint(std::string(kEndpointId2));
|
||||
ecm_.UnregisterChannelForEndpoint(
|
||||
std::string(kEndpointId2), DisconnectionReason::LOCAL_DISCONNECTION,
|
||||
ConnectionsLog::EstablishedConnection::UNSAFE_DISCONNECTION);
|
||||
EXPECT_EQ(0u, ecm_.GetConnectedEndpointsCount());
|
||||
bwu_manager_->OnEndpointDisconnect(&client_, upgrade_service_id_B,
|
||||
std::string(kEndpointId2), latch);
|
||||
bwu_manager_->OnEndpointDisconnect(
|
||||
&client_, upgrade_service_id_B, std::string(kEndpointId2), latch,
|
||||
DisconnectionReason::LOCAL_DISCONNECTION);
|
||||
// Note(nohle): There appears to be an off-by-one error in the
|
||||
// existing/flag-disabled code. Revert is called when there are "<= 1"
|
||||
// (instead of "== 0") connected endpoints.
|
||||
@@ -593,9 +643,12 @@ TEST_F(
|
||||
EXPECT_TRUE(fake_wifi_direct_bwu_handler_->handle_revert_calls().empty());
|
||||
{
|
||||
CountDownLatch latch(1);
|
||||
ecm_.UnregisterChannelForEndpoint(std::string(kEndpointId1));
|
||||
bwu_manager_->OnEndpointDisconnect(&client_, upgrade_service_id_A,
|
||||
std::string(kEndpointId1), latch);
|
||||
ecm_.UnregisterChannelForEndpoint(
|
||||
std::string(kEndpointId1), DisconnectionReason::LOCAL_DISCONNECTION,
|
||||
ConnectionsLog::EstablishedConnection::UNSAFE_DISCONNECTION);
|
||||
bwu_manager_->OnEndpointDisconnect(
|
||||
&client_, upgrade_service_id_A, std::string(kEndpointId1), latch,
|
||||
DisconnectionReason::LOCAL_DISCONNECTION);
|
||||
|
||||
// No more WebRTC channels for service A; expect revert call.
|
||||
ASSERT_EQ(1u, fake_web_rtc_bwu_handler_->disconnect_calls().size());
|
||||
@@ -615,9 +668,12 @@ TEST_F(
|
||||
}
|
||||
{
|
||||
CountDownLatch latch(1);
|
||||
ecm_.UnregisterChannelForEndpoint(std::string(kEndpointId2));
|
||||
bwu_manager_->OnEndpointDisconnect(&client_, upgrade_service_id_A,
|
||||
std::string(kEndpointId2), latch);
|
||||
ecm_.UnregisterChannelForEndpoint(
|
||||
std::string(kEndpointId2), DisconnectionReason::LOCAL_DISCONNECTION,
|
||||
ConnectionsLog::EstablishedConnection::UNSAFE_DISCONNECTION);
|
||||
bwu_manager_->OnEndpointDisconnect(
|
||||
&client_, upgrade_service_id_A, std::string(kEndpointId2), latch,
|
||||
DisconnectionReason::LOCAL_DISCONNECTION);
|
||||
|
||||
// We reverted a WLAN channel; no additional WebRTC calls expected.
|
||||
EXPECT_EQ(1u, fake_web_rtc_bwu_handler_->disconnect_calls().size());
|
||||
@@ -633,9 +689,12 @@ TEST_F(
|
||||
}
|
||||
{
|
||||
CountDownLatch latch(1);
|
||||
ecm_.UnregisterChannelForEndpoint(std::string(kEndpointId3));
|
||||
bwu_manager_->OnEndpointDisconnect(&client_, upgrade_service_id_B,
|
||||
std::string(kEndpointId3), latch);
|
||||
ecm_.UnregisterChannelForEndpoint(
|
||||
std::string(kEndpointId3), DisconnectionReason::LOCAL_DISCONNECTION,
|
||||
ConnectionsLog::EstablishedConnection::UNSAFE_DISCONNECTION);
|
||||
bwu_manager_->OnEndpointDisconnect(
|
||||
&client_, upgrade_service_id_B, std::string(kEndpointId3), latch,
|
||||
DisconnectionReason::LOCAL_DISCONNECTION);
|
||||
|
||||
// We reverted a WLAN channel; no additional WebRTC calls expected.
|
||||
EXPECT_EQ(1u, fake_web_rtc_bwu_handler_->disconnect_calls().size());
|
||||
@@ -651,9 +710,12 @@ TEST_F(
|
||||
}
|
||||
{
|
||||
CountDownLatch latch(1);
|
||||
ecm_.UnregisterChannelForEndpoint(std::string(kEndpointId4));
|
||||
bwu_manager_->OnEndpointDisconnect(&client_, upgrade_service_id_B,
|
||||
std::string(kEndpointId4), latch);
|
||||
ecm_.UnregisterChannelForEndpoint(
|
||||
std::string(kEndpointId4), DisconnectionReason::LOCAL_DISCONNECTION,
|
||||
ConnectionsLog::EstablishedConnection::UNSAFE_DISCONNECTION);
|
||||
bwu_manager_->OnEndpointDisconnect(
|
||||
&client_, upgrade_service_id_B, std::string(kEndpointId4), latch,
|
||||
DisconnectionReason::LOCAL_DISCONNECTION);
|
||||
|
||||
// We reverted a Hotspot channel; no additional WebRTC calls expected.
|
||||
EXPECT_EQ(1u, fake_web_rtc_bwu_handler_->disconnect_calls().size());
|
||||
@@ -671,9 +733,12 @@ TEST_F(
|
||||
}
|
||||
{
|
||||
CountDownLatch latch(1);
|
||||
ecm_.UnregisterChannelForEndpoint(std::string(kEndpointId5));
|
||||
bwu_manager_->OnEndpointDisconnect(&client_, upgrade_service_id_B,
|
||||
std::string(kEndpointId5), latch);
|
||||
ecm_.UnregisterChannelForEndpoint(
|
||||
std::string(kEndpointId5), DisconnectionReason::LOCAL_DISCONNECTION,
|
||||
ConnectionsLog::EstablishedConnection::UNSAFE_DISCONNECTION);
|
||||
bwu_manager_->OnEndpointDisconnect(
|
||||
&client_, upgrade_service_id_B, std::string(kEndpointId5), latch,
|
||||
DisconnectionReason::LOCAL_DISCONNECTION);
|
||||
|
||||
// We reverted a WifiDirect channel; no additional WebRTC calls expected.
|
||||
EXPECT_EQ(1u, fake_web_rtc_bwu_handler_->disconnect_calls().size());
|
||||
@@ -722,6 +787,9 @@ TEST_F(BwuManagerTest, InitiateBwu_Revert_OnUpgradeFailure_FlagEnabled) {
|
||||
ASSERT_EQ(1u, fake_web_rtc_bwu_handler_->handle_revert_calls().size());
|
||||
EXPECT_EQ(WrapInitiatorUpgradeServiceId(kServiceIdB),
|
||||
fake_web_rtc_bwu_handler_->handle_revert_calls()[0].service_id);
|
||||
UnRegisterChannelForEndpoint(kEndpointId1);
|
||||
UnRegisterChannelForEndpoint(kEndpointId2);
|
||||
UnRegisterChannelForEndpoint(kEndpointId3);
|
||||
}
|
||||
|
||||
TEST_F(BwuManagerTest, InitiateBwu_Revert_OnUpgradeFailure_FlagDisabled) {
|
||||
@@ -756,6 +824,9 @@ TEST_F(BwuManagerTest, InitiateBwu_Revert_OnUpgradeFailure_FlagDisabled) {
|
||||
// endpoints for _any_ service. We don't have service-level bookkeeping; we
|
||||
// only know that there is some active WebRTC endpoint.
|
||||
EXPECT_TRUE(fake_web_rtc_bwu_handler_->handle_revert_calls().empty());
|
||||
UnRegisterChannelForEndpoint(kEndpointId1);
|
||||
UnRegisterChannelForEndpoint(kEndpointId2);
|
||||
UnRegisterChannelForEndpoint(kEndpointId3);
|
||||
}
|
||||
|
||||
TEST_F(BwuManagerTest, InitiateBwu_Revert_OnDisconnect_WifiDirect) {
|
||||
@@ -779,7 +850,8 @@ TEST_F(BwuManagerTest, InitiateBwu_Revert_OnDisconnect_WifiDirect) {
|
||||
Medium::BLUETOOTH, packet_meta_data_);
|
||||
CountDownLatch latch(1);
|
||||
bwu_manager_->OnEndpointDisconnect(&client_, (std::string)kServiceIdA,
|
||||
std::string(kEndpointId1), latch);
|
||||
std::string(kEndpointId1), latch,
|
||||
DisconnectionReason::LOCAL_DISCONNECTION);
|
||||
|
||||
ASSERT_EQ(fake_wifi_direct_bwu_handler_->disconnect_calls().size(), 1u);
|
||||
EXPECT_EQ(kEndpointId1,
|
||||
@@ -787,6 +859,7 @@ TEST_F(BwuManagerTest, InitiateBwu_Revert_OnDisconnect_WifiDirect) {
|
||||
// This is called by the RESPONDER--call RevertInitiatorState only when
|
||||
// BWU Medium is Hotspot or WifiDirect.
|
||||
ASSERT_EQ(fake_wifi_direct_bwu_handler_->handle_revert_calls().size(), 1u);
|
||||
UnRegisterChannelForEndpoint(kEndpointId1);
|
||||
}
|
||||
|
||||
TEST_F(BwuManagerTest, InitiateBwu_Revert_OnDisconnect_Hotspot) {
|
||||
@@ -811,9 +884,11 @@ TEST_F(BwuManagerTest, InitiateBwu_Revert_OnDisconnect_Hotspot) {
|
||||
Medium::BLUETOOTH, packet_meta_data_);
|
||||
CountDownLatch latch(1);
|
||||
bwu_manager_->OnEndpointDisconnect(&client_, (std::string)kServiceIdA,
|
||||
std::string(kEndpointId1), latch);
|
||||
std::string(kEndpointId1), latch,
|
||||
DisconnectionReason::LOCAL_DISCONNECTION);
|
||||
|
||||
ASSERT_EQ(fake_wifi_hotspot_bwu_handler_->handle_revert_calls().size(), 1u);
|
||||
UnRegisterChannelForEndpoint(kEndpointId1);
|
||||
}
|
||||
|
||||
TEST_F(BwuManagerTest, InitiateBwu_Revert_OnDisconnect_Wlan) {
|
||||
@@ -837,9 +912,11 @@ TEST_F(BwuManagerTest, InitiateBwu_Revert_OnDisconnect_Wlan) {
|
||||
Medium::BLUETOOTH, packet_meta_data_);
|
||||
CountDownLatch latch(1);
|
||||
bwu_manager_->OnEndpointDisconnect(&client_, (std::string)kServiceIdA,
|
||||
std::string(kEndpointId1), latch);
|
||||
std::string(kEndpointId1), latch,
|
||||
DisconnectionReason::LOCAL_DISCONNECTION);
|
||||
|
||||
ASSERT_EQ(fake_wifi_lan_bwu_handler_->handle_revert_calls().size(), 0u);
|
||||
UnRegisterChannelForEndpoint(kEndpointId1);
|
||||
}
|
||||
|
||||
TEST_F(BwuManagerTest, OnReceiveBwuEvent) {
|
||||
|
||||
@@ -14,6 +14,7 @@
|
||||
|
||||
#include "connections/implementation/client_proxy.h"
|
||||
|
||||
#include <cstdint>
|
||||
#include <cstdlib>
|
||||
#include <functional>
|
||||
#include <ios>
|
||||
@@ -26,12 +27,15 @@
|
||||
|
||||
#include "absl/container/flat_hash_map.h"
|
||||
#include "absl/container/flat_hash_set.h"
|
||||
#include "absl/functional/any_invocable.h"
|
||||
#include "absl/strings/escaping.h"
|
||||
#include "absl/strings/str_format.h"
|
||||
#include "absl/strings/string_view.h"
|
||||
#include "connections/implementation/flags/nearby_connections_feature_flags.h"
|
||||
#include "connections/v3/bandwidth_info.h"
|
||||
#include "connections/v3/connection_listening_options.h"
|
||||
#include "connections/v3/connections_device_provider.h"
|
||||
#include "internal/analytics/event_logger.h"
|
||||
#include "internal/flags/nearby_flags.h"
|
||||
#include "internal/platform/error_code_recorder.h"
|
||||
#include "internal/platform/feature_flags.h"
|
||||
#include "internal/platform/implementation/platform.h"
|
||||
@@ -66,6 +70,12 @@ ClientProxy::ClientProxy(::nearby::analytics::EventLogger* event_logger)
|
||||
});
|
||||
local_os_info_.set_type(
|
||||
OSNameToOsInfoType(api::ImplementationPlatform::GetCurrentOS()));
|
||||
supports_safe_to_disconnect_ = NearbyFlags::GetInstance().GetBoolFlag(
|
||||
config_package_nearby::nearby_connections_feature::
|
||||
kEnableSafeToDisconnect);
|
||||
local_safe_to_disconnect_version_ = NearbyFlags::GetInstance().GetInt64Flag(
|
||||
config_package_nearby::nearby_connections_feature::
|
||||
kSafeToDisconnectVersion);
|
||||
}
|
||||
|
||||
ClientProxy::~ClientProxy() { Reset(); }
|
||||
@@ -318,8 +328,11 @@ void ClientProxy::OnEndpointFound(
|
||||
MutexLock lock(&mutex_);
|
||||
|
||||
NEARBY_LOGS(INFO) << "ClientProxy [Endpoint Found]: [enter] id="
|
||||
<< endpoint_id << "; service=" << service_id << "; info="
|
||||
<< absl::BytesToHexString(endpoint_info.data());
|
||||
<< endpoint_id << "; service=" << service_id
|
||||
<< "; info=" << absl::BytesToHexString(endpoint_info.data())
|
||||
<< "; medium="
|
||||
<< location::nearby::proto::connections::Medium_Name(
|
||||
medium);
|
||||
if (!IsDiscoveringServiceId(service_id)) {
|
||||
NEARBY_LOGS(INFO) << "ClientProxy [Endpoint Found]: Ignoring event for id="
|
||||
<< endpoint_id
|
||||
@@ -366,6 +379,12 @@ void ClientProxy::OnEndpointLost(const std::string& service_id,
|
||||
discovery_info_.listener.endpoint_lost_cb(endpoint_id);
|
||||
}
|
||||
|
||||
void ClientProxy::OnRequestConnection(
|
||||
const Strategy& strategy, const std::string& endpoint_id,
|
||||
const ConnectionOptions& connection_options) {
|
||||
analytics_recorder_->OnRequestConnection(strategy, endpoint_id);
|
||||
}
|
||||
|
||||
void ClientProxy::OnConnectionInitiated(
|
||||
const std::string& endpoint_id, const ConnectionResponseInfo& info,
|
||||
const ConnectionOptions& connection_options,
|
||||
@@ -545,7 +564,7 @@ bool ClientProxy::IsConnectedToEndpoint(const std::string& endpoint_id) const {
|
||||
}
|
||||
|
||||
std::vector<std::string> ClientProxy::GetMatchingEndpoints(
|
||||
std::function<bool(const Connection&)> pred) const {
|
||||
absl::AnyInvocable<bool(const Connection&)> pred) const {
|
||||
MutexLock lock(&mutex_);
|
||||
|
||||
std::vector<std::string> connected_endpoints;
|
||||
@@ -779,9 +798,7 @@ void ClientProxy::CancelEndpoint(const std::string& endpoint_id) {
|
||||
}
|
||||
}
|
||||
|
||||
const OsInfo& ClientProxy::GetLocalOsInfo() const {
|
||||
return local_os_info_;
|
||||
}
|
||||
const OsInfo& ClientProxy::GetLocalOsInfo() const { return local_os_info_; }
|
||||
|
||||
std::optional<OsInfo> ClientProxy::GetRemoteOsInfo(
|
||||
absl::string_view endpoint_id) const {
|
||||
@@ -799,6 +816,44 @@ void ClientProxy::SetRemoteOsInfo(absl::string_view endpoint_id,
|
||||
item->first.os_info.emplace(remote_os_info);
|
||||
}
|
||||
}
|
||||
|
||||
std::optional<std::int32_t> ClientProxy::GetRemoteSafeToDisconnectVersion(
|
||||
absl::string_view endpoint_id) const {
|
||||
const ConnectionPair* item = LookupConnection(endpoint_id);
|
||||
if (item != nullptr) {
|
||||
return item->first.safe_to_disconnect_version;
|
||||
}
|
||||
return std::nullopt;
|
||||
}
|
||||
|
||||
void ClientProxy::SetRemoteSafeToDisconnectVersion(
|
||||
absl::string_view endpoint_id,
|
||||
const std::int32_t& safe_to_disconnect_version) {
|
||||
ConnectionPair* item = LookupConnection(endpoint_id);
|
||||
if (item != nullptr) {
|
||||
item->first.safe_to_disconnect_version = safe_to_disconnect_version;
|
||||
}
|
||||
}
|
||||
|
||||
bool ClientProxy::IsSafeToDisconnectEnabled(absl::string_view endpoint_id) {
|
||||
return IsSupportSafeToDisconnect() &&
|
||||
GetRemoteSafeToDisconnectVersion(endpoint_id).has_value() &&
|
||||
(GetRemoteSafeToDisconnectVersion(endpoint_id) >=
|
||||
FeatureFlags::GetInstance()
|
||||
.GetFlags()
|
||||
.min_nc_version_supports_safe_to_disconnect);
|
||||
}
|
||||
|
||||
bool ClientProxy::IsPayloadReceivedAckEnabled(absl::string_view endpoint_id) {
|
||||
return IsSupportSafeToDisconnect() &&
|
||||
GetRemoteSafeToDisconnectVersion(endpoint_id).has_value() &&
|
||||
(GetRemoteSafeToDisconnectVersion(endpoint_id) >=
|
||||
FeatureFlags::GetInstance()
|
||||
.GetFlags()
|
||||
.min_nc_version_supports_payload_received_ack);
|
||||
}
|
||||
|
||||
|
||||
void ClientProxy::CancelAllEndpoints() {
|
||||
for (const auto& item : cancellation_flags_) {
|
||||
CancellationFlag* cancellation_flag = item.second.get();
|
||||
|
||||
@@ -16,13 +16,13 @@
|
||||
#define CORE_INTERNAL_CLIENT_PROXY_H_
|
||||
|
||||
#include <cstdint>
|
||||
#include <functional>
|
||||
#include <memory>
|
||||
#include <optional>
|
||||
#include <string>
|
||||
#include <utility>
|
||||
#include <vector>
|
||||
|
||||
#include "absl/functional/any_invocable.h"
|
||||
#include "connections/advertising_options.h"
|
||||
#include "connections/discovery_options.h"
|
||||
#include "connections/implementation/analytics/analytics_recorder.h"
|
||||
@@ -143,11 +143,17 @@ class ClientProxy final {
|
||||
void OnEndpointLost(const std::string& service_id,
|
||||
const std::string& endpoint_id);
|
||||
|
||||
// Triggered when client request connection to remote device.
|
||||
void OnRequestConnection(const Strategy& strategy,
|
||||
const std::string& endpoint_id,
|
||||
const ConnectionOptions& connection_options);
|
||||
|
||||
// Proxies to the client's ConnectionListener::OnInitiated() callback.
|
||||
void OnConnectionInitiated(
|
||||
const std::string& endpoint_id, const ConnectionResponseInfo& info,
|
||||
const ConnectionOptions& connection_options,
|
||||
const ConnectionListener& listener, const std::string& connection_token);
|
||||
void OnConnectionInitiated(const std::string& endpoint_id,
|
||||
const ConnectionResponseInfo& info,
|
||||
const ConnectionOptions& connection_options,
|
||||
const ConnectionListener& listener,
|
||||
const std::string& connection_token);
|
||||
|
||||
// Proxies to the client's ConnectionListener::OnAccepted() callback.
|
||||
void OnConnectionAccepted(const std::string& endpoint_id);
|
||||
@@ -261,6 +267,20 @@ class ClientProxy final {
|
||||
connections_device_provider_ = std::move(provider);
|
||||
}
|
||||
|
||||
const bool& IsSupportSafeToDisconnect() const {
|
||||
return supports_safe_to_disconnect_;
|
||||
}
|
||||
const std::int32_t& GetLocalSafeToDisconnectVersion() const {
|
||||
return local_safe_to_disconnect_version_;
|
||||
}
|
||||
std::optional<std::int32_t> GetRemoteSafeToDisconnectVersion(
|
||||
absl::string_view endpoint_id) const;
|
||||
void SetRemoteSafeToDisconnectVersion(
|
||||
absl::string_view endpoint_id,
|
||||
const std::int32_t& safe_to_disconnect_version);
|
||||
bool IsSafeToDisconnectEnabled(absl::string_view endpoint_id);
|
||||
bool IsPayloadReceivedAckEnabled(absl::string_view endpoint_id);
|
||||
|
||||
private:
|
||||
struct Connection {
|
||||
// Status: may be either:
|
||||
@@ -290,6 +310,7 @@ class ClientProxy final {
|
||||
AdvertisingOptions advertising_options;
|
||||
std::string connection_token;
|
||||
std::optional<location::nearby::connections::OsInfo> os_info;
|
||||
std::int32_t safe_to_disconnect_version;
|
||||
};
|
||||
using ConnectionPair = std::pair<Connection, PayloadListener>;
|
||||
|
||||
@@ -332,7 +353,7 @@ class ClientProxy final {
|
||||
bool ConnectionStatusMatches(const std::string& endpoint_id,
|
||||
Connection::Status status) const;
|
||||
std::vector<std::string> GetMatchingEndpoints(
|
||||
std::function<bool(const Connection&)> pred) const;
|
||||
absl::AnyInvocable<bool(const Connection&)> pred) const;
|
||||
std::string GenerateLocalEndpointId();
|
||||
|
||||
void ScheduleClearLocalHighVisModeCacheEndpointIdAlarm();
|
||||
@@ -421,6 +442,8 @@ class ClientProxy final {
|
||||
NearbyDeviceProvider* external_device_provider_ = nullptr;
|
||||
// For Nearby Connections' own device provider.
|
||||
std::unique_ptr<v3::ConnectionsDeviceProvider> connections_device_provider_;
|
||||
bool supports_safe_to_disconnect_;
|
||||
std::int32_t local_safe_to_disconnect_version_;
|
||||
};
|
||||
|
||||
} // namespace connections
|
||||
|
||||
@@ -14,6 +14,7 @@
|
||||
|
||||
#include "connections/implementation/client_proxy.h"
|
||||
|
||||
#include <cstdint>
|
||||
#include <cstdio>
|
||||
#include <memory>
|
||||
#include <optional>
|
||||
@@ -40,7 +41,7 @@
|
||||
#include "internal/platform/count_down_latch.h"
|
||||
#include "internal/platform/feature_flags.h"
|
||||
#include "internal/platform/medium_environment.h"
|
||||
#include "proto/connections_enums.proto.h"
|
||||
#include "proto/connections_enums.pb.h"
|
||||
|
||||
namespace nearby {
|
||||
namespace connections {
|
||||
@@ -1023,6 +1024,9 @@ TEST_F(ClientProxyTest, GetRemoteInfoNullWithoutConnections) {
|
||||
StartAdvertising(&client1_, advertising_connection_listener_);
|
||||
|
||||
EXPECT_FALSE(client1_.GetRemoteOsInfo(advertising_endpoint.id).has_value());
|
||||
EXPECT_FALSE(
|
||||
client1_.GetRemoteSafeToDisconnectVersion(advertising_endpoint.id)
|
||||
.has_value());
|
||||
}
|
||||
|
||||
TEST_F(ClientProxyTest, SetRemoteInfoCorrect) {
|
||||
@@ -1032,11 +1036,16 @@ TEST_F(ClientProxyTest, SetRemoteInfoCorrect) {
|
||||
|
||||
OsInfo os_info;
|
||||
os_info.set_type(OsInfo::ANDROID);
|
||||
std::int32_t nearby_connections_version = 2;
|
||||
client1_.SetRemoteOsInfo(advertising_endpoint.id, os_info);
|
||||
client1_.SetRemoteSafeToDisconnectVersion(advertising_endpoint.id,
|
||||
nearby_connections_version);
|
||||
|
||||
ASSERT_TRUE(client1_.GetRemoteOsInfo(advertising_endpoint.id).has_value());
|
||||
EXPECT_EQ(client1_.GetRemoteOsInfo(advertising_endpoint.id).value().type(),
|
||||
OsInfo::ANDROID);
|
||||
EXPECT_EQ(client1_.GetRemoteSafeToDisconnectVersion(advertising_endpoint.id),
|
||||
nearby_connections_version);
|
||||
}
|
||||
|
||||
// Test ClientProxy::AddCancellationFlag, where if a flag is already in the map,
|
||||
|
||||
@@ -17,15 +17,19 @@
|
||||
#include <cinttypes>
|
||||
#include <cstdint>
|
||||
#include <memory>
|
||||
#include <string>
|
||||
#include <utility>
|
||||
|
||||
#include "securegcm/ukey2_handshake.h"
|
||||
#include "absl/strings/ascii.h"
|
||||
#include "absl/time/clock.h"
|
||||
#include "absl/time/time.h"
|
||||
#include "connections/implementation/client_proxy.h"
|
||||
#include "connections/implementation/endpoint_channel.h"
|
||||
#include "internal/platform/base64_utils.h"
|
||||
#include "internal/platform/byte_array.h"
|
||||
#include "internal/platform/exception.h"
|
||||
#include "internal/platform/cancelable_alarm.h"
|
||||
#include "internal/platform/exception.h"
|
||||
#include "internal/platform/logging.h"
|
||||
|
||||
namespace nearby {
|
||||
@@ -49,7 +53,7 @@ std::string ToHumanReadableString(const ByteArray& token) {
|
||||
|
||||
bool HandleEncryptionSuccess(const std::string& endpoint_id,
|
||||
std::unique_ptr<securegcm::UKey2Handshake> ukey2,
|
||||
const EncryptionRunner::ResultListener& listener) {
|
||||
EncryptionRunner::ResultListener& listener) {
|
||||
std::unique_ptr<std::string> verification_string =
|
||||
ukey2->GetVerificationString(kMaxUkey2VerificationStringLength);
|
||||
if (verification_string == nullptr) {
|
||||
@@ -58,9 +62,9 @@ bool HandleEncryptionSuccess(const std::string& endpoint_id,
|
||||
|
||||
ByteArray raw_authentication_token(*verification_string);
|
||||
|
||||
listener.on_success_cb(endpoint_id, std::move(ukey2),
|
||||
ToHumanReadableString(raw_authentication_token),
|
||||
raw_authentication_token);
|
||||
listener.CallSuccessCallback(endpoint_id, std::move(ukey2),
|
||||
ToHumanReadableString(raw_authentication_token),
|
||||
raw_authentication_token);
|
||||
|
||||
return true;
|
||||
}
|
||||
@@ -79,14 +83,14 @@ class ServerRunnable final {
|
||||
public:
|
||||
ServerRunnable(ClientProxy* client, ScheduledExecutor* alarm_executor,
|
||||
const std::string& endpoint_id, EndpointChannel* channel,
|
||||
EncryptionRunner::ResultListener&& listener)
|
||||
EncryptionRunner::ResultListener listener)
|
||||
: client_(client),
|
||||
alarm_executor_(alarm_executor),
|
||||
endpoint_id_(endpoint_id),
|
||||
channel_(channel),
|
||||
listener_(std::move(listener)) {}
|
||||
|
||||
void operator()() const {
|
||||
void operator()() {
|
||||
CancelableAlarm timeout_alarm(
|
||||
"EncryptionRunner.StartServer() timeout",
|
||||
[this]() { CancelableAlarmRunnable(client_, endpoint_id_, channel_); },
|
||||
@@ -189,9 +193,9 @@ class ServerRunnable final {
|
||||
<< endpoint_id_ << ").";
|
||||
}
|
||||
|
||||
void HandleHandshakeOrIoException(CancelableAlarm* timeout_alarm) const {
|
||||
void HandleHandshakeOrIoException(CancelableAlarm* timeout_alarm) {
|
||||
timeout_alarm->Cancel();
|
||||
listener_.on_failure_cb(endpoint_id_, channel_);
|
||||
listener_.CallFailureCallback(endpoint_id_, channel_);
|
||||
}
|
||||
|
||||
void HandleAlertException(
|
||||
@@ -217,14 +221,14 @@ class ClientRunnable final {
|
||||
public:
|
||||
ClientRunnable(ClientProxy* client, ScheduledExecutor* alarm_executor,
|
||||
const std::string& endpoint_id, EndpointChannel* channel,
|
||||
EncryptionRunner::ResultListener&& listener)
|
||||
EncryptionRunner::ResultListener listener)
|
||||
: client_(client),
|
||||
alarm_executor_(alarm_executor),
|
||||
endpoint_id_(endpoint_id),
|
||||
channel_(channel),
|
||||
listener_(std::move(listener)) {}
|
||||
|
||||
void operator()() const {
|
||||
void operator()() {
|
||||
CancelableAlarm timeout_alarm(
|
||||
"EncryptionRunner.StartClient() timeout",
|
||||
[this]() { CancelableAlarmRunnable(client_, endpoint_id_, channel_); },
|
||||
@@ -326,9 +330,9 @@ class ClientRunnable final {
|
||||
<< endpoint_id_ << ").";
|
||||
}
|
||||
|
||||
void HandleHandshakeOrIoException(CancelableAlarm* timeout_alarm) const {
|
||||
void HandleHandshakeOrIoException(CancelableAlarm* timeout_alarm) {
|
||||
timeout_alarm->Cancel();
|
||||
listener_.on_failure_cb(endpoint_id_, channel_);
|
||||
listener_.CallFailureCallback(endpoint_id_, channel_);
|
||||
}
|
||||
|
||||
void HandleAlertException(
|
||||
@@ -359,28 +363,46 @@ EncryptionRunner::~EncryptionRunner() {
|
||||
alarm_executor_.Shutdown();
|
||||
}
|
||||
|
||||
void EncryptionRunner::StartServer(
|
||||
ClientProxy* client, const std::string& endpoint_id,
|
||||
EndpointChannel* endpoint_channel,
|
||||
EncryptionRunner::ResultListener&& listener) {
|
||||
server_executor_.Execute(
|
||||
"encryption-server",
|
||||
[runnable{ServerRunnable(client, &alarm_executor_, endpoint_id,
|
||||
endpoint_channel, std::move(listener))}]() {
|
||||
runnable();
|
||||
});
|
||||
void EncryptionRunner::StartServer(ClientProxy* client,
|
||||
const std::string& endpoint_id,
|
||||
EndpointChannel* endpoint_channel,
|
||||
EncryptionRunner::ResultListener listener) {
|
||||
ServerRunnable runnable(client, &alarm_executor_, endpoint_id,
|
||||
endpoint_channel, std::move(listener));
|
||||
server_executor_.Execute("encryption-server", std::move(runnable));
|
||||
}
|
||||
|
||||
void EncryptionRunner::StartClient(
|
||||
ClientProxy* client, const std::string& endpoint_id,
|
||||
EndpointChannel* endpoint_channel,
|
||||
EncryptionRunner::ResultListener&& listener) {
|
||||
client_executor_.Execute(
|
||||
"encryption-client",
|
||||
[runnable{ClientRunnable(client, &alarm_executor_, endpoint_id,
|
||||
endpoint_channel, std::move(listener))}]() {
|
||||
runnable();
|
||||
});
|
||||
void EncryptionRunner::StartClient(ClientProxy* client,
|
||||
const std::string& endpoint_id,
|
||||
EndpointChannel* endpoint_channel,
|
||||
EncryptionRunner::ResultListener listener) {
|
||||
ClientRunnable runnable(client, &alarm_executor_, endpoint_id,
|
||||
endpoint_channel, std::move(listener));
|
||||
client_executor_.Execute("encryption-client", std::move(runnable));
|
||||
}
|
||||
|
||||
void EncryptionRunner::ResultListener::CallSuccessCallback(
|
||||
const std::string& endpoint_id,
|
||||
std::unique_ptr<securegcm::UKey2Handshake> ukey2,
|
||||
const std::string& auth_token, const ByteArray& raw_auth_token) {
|
||||
if (on_success_cb) {
|
||||
std::move(on_success_cb)(endpoint_id, std::move(ukey2), auth_token,
|
||||
raw_auth_token);
|
||||
}
|
||||
Reset();
|
||||
}
|
||||
|
||||
void EncryptionRunner::ResultListener::CallFailureCallback(
|
||||
const std::string& endpoint_id, EndpointChannel* channel) {
|
||||
if (on_failure_cb) {
|
||||
std::move(on_failure_cb)(endpoint_id, channel);
|
||||
}
|
||||
Reset();
|
||||
}
|
||||
|
||||
void EncryptionRunner::ResultListener::Reset() {
|
||||
on_success_cb = nullptr;
|
||||
on_failure_cb = nullptr;
|
||||
}
|
||||
|
||||
} // namespace connections
|
||||
|
||||
@@ -18,6 +18,7 @@
|
||||
#include <string>
|
||||
|
||||
#include "securegcm/ukey2_handshake.h"
|
||||
#include "absl/functional/any_invocable.h"
|
||||
#include "connections/implementation/client_proxy.h"
|
||||
#include "connections/implementation/endpoint_channel.h"
|
||||
#include "connections/listeners.h"
|
||||
@@ -39,14 +40,20 @@ class EncryptionRunner {
|
||||
~EncryptionRunner();
|
||||
|
||||
struct ResultListener {
|
||||
void CallSuccessCallback(const std::string& endpoint_id,
|
||||
std::unique_ptr<securegcm::UKey2Handshake> ukey2,
|
||||
const std::string& auth_token,
|
||||
const ByteArray& raw_auth_token);
|
||||
void CallFailureCallback(const std::string& endpoint_id,
|
||||
EndpointChannel* channel);
|
||||
void Reset();
|
||||
|
||||
// @EncryptionRunnerThread
|
||||
std::function<void(const std::string& endpoint_id,
|
||||
std::unique_ptr<securegcm::UKey2Handshake> ukey2,
|
||||
const std::string& auth_token,
|
||||
const ByteArray& raw_auth_token)>
|
||||
on_success_cb = [](const std::string&,
|
||||
std::unique_ptr<securegcm::UKey2Handshake>,
|
||||
const std::string&, const ByteArray&) {};
|
||||
absl::AnyInvocable<void(const std::string& endpoint_id,
|
||||
std::unique_ptr<securegcm::UKey2Handshake> ukey2,
|
||||
const std::string& auth_token,
|
||||
const ByteArray& raw_auth_token) &&>
|
||||
on_success_cb;
|
||||
|
||||
// Encryption has failed. The remote_endpoint_id and channel are given so
|
||||
// that any pending state can be cleaned up.
|
||||
@@ -57,19 +64,19 @@ class EncryptionRunner {
|
||||
// channel to the same endpoint.
|
||||
//
|
||||
// @EncryptionRunnerThread
|
||||
std::function<void(const std::string& endpoint_id,
|
||||
EndpointChannel* channel)>
|
||||
on_failure_cb = [](const std::string&, EndpointChannel*) {};
|
||||
absl::AnyInvocable<void(const std::string& endpoint_id,
|
||||
EndpointChannel* channel) &&>
|
||||
on_failure_cb;
|
||||
};
|
||||
|
||||
// @AnyThread
|
||||
void StartServer(ClientProxy* client, const std::string& endpoint_id,
|
||||
EndpointChannel* endpoint_channel,
|
||||
ResultListener&& result_listener);
|
||||
ResultListener result_listener);
|
||||
// @AnyThread
|
||||
void StartClient(ClientProxy* client, const std::string& endpoint_id,
|
||||
EndpointChannel* endpoint_channel,
|
||||
ResultListener&& result_listener);
|
||||
ResultListener result_listener);
|
||||
|
||||
private:
|
||||
ScheduledExecutor alarm_executor_;
|
||||
|
||||
@@ -14,23 +14,30 @@
|
||||
|
||||
#include "connections/implementation/encryption_runner.h"
|
||||
|
||||
#include "gmock/gmock.h"
|
||||
#include "protobuf-matchers/protocol-buffer-matchers.h"
|
||||
#include <cstddef>
|
||||
#include <string>
|
||||
|
||||
#include "gtest/gtest.h"
|
||||
#include "absl/time/clock.h"
|
||||
#include "absl/time/time.h"
|
||||
#include "connections/implementation/analytics/analytics_recorder.h"
|
||||
#include "connections/implementation/client_proxy.h"
|
||||
#include "connections/implementation/endpoint_channel.h"
|
||||
#include "internal/platform/byte_array.h"
|
||||
#include "internal/platform/count_down_latch.h"
|
||||
#include "internal/platform/exception.h"
|
||||
#include "internal/platform/input_stream.h"
|
||||
#include "internal/platform/output_stream.h"
|
||||
#include "internal/platform/pipe.h"
|
||||
#include "internal/platform/system_clock.h"
|
||||
#include "proto/connections_enums.pb.h"
|
||||
#include "third_party/ukey2/src/main/cpp/include/securegcm/ukey2_handshake.h"
|
||||
|
||||
namespace nearby {
|
||||
namespace connections {
|
||||
namespace {
|
||||
|
||||
using ::location::nearby::proto::connections::Medium;
|
||||
constexpr size_t kChunkSize = 64 * 1024;
|
||||
|
||||
class FakeEndpointChannel : public EndpointChannel {
|
||||
public:
|
||||
@@ -38,13 +45,11 @@ class FakeEndpointChannel : public EndpointChannel {
|
||||
: in_(in), out_(out) {}
|
||||
ExceptionOr<ByteArray> Read() override {
|
||||
read_timestamp_ = SystemClock::ElapsedRealtime();
|
||||
return in_ ? in_->Read(Pipe::kChunkSize)
|
||||
: ExceptionOr<ByteArray>{Exception::kIo};
|
||||
return in_ ? in_->Read(kChunkSize) : ExceptionOr<ByteArray>{Exception::kIo};
|
||||
}
|
||||
ExceptionOr<ByteArray> Read(PacketMetaData& packet_meta_data) override {
|
||||
read_timestamp_ = SystemClock::ElapsedRealtime();
|
||||
return in_ ? in_->Read(Pipe::kChunkSize)
|
||||
: ExceptionOr<ByteArray>{Exception::kIo};
|
||||
return in_ ? in_->Read(kChunkSize) : ExceptionOr<ByteArray>{Exception::kIo};
|
||||
}
|
||||
Exception Write(const ByteArray& data) override {
|
||||
write_timestamp_ = SystemClock::ElapsedRealtime();
|
||||
@@ -103,8 +108,7 @@ class FakeEndpointChannel : public EndpointChannel {
|
||||
};
|
||||
|
||||
struct User {
|
||||
User(Pipe* reader, Pipe* writer)
|
||||
: channel(&reader->GetInputStream(), &writer->GetOutputStream()) {}
|
||||
User(InputStream* reader, OutputStream* writer) : channel(reader, writer) {}
|
||||
|
||||
FakeEndpointChannel channel;
|
||||
EncryptionRunner crypto;
|
||||
@@ -126,10 +130,12 @@ struct Response {
|
||||
TEST(EncryptionRunnerTest, ConstructorDestructorWorks) { EncryptionRunner enc; }
|
||||
|
||||
TEST(EncryptionRunnerTest, ReadWrite) {
|
||||
Pipe from_a_to_b;
|
||||
Pipe from_b_to_a;
|
||||
User user_a(/*reader=*/&from_b_to_a, /*writer=*/&from_a_to_b);
|
||||
User user_b(/*reader=*/&from_a_to_b, /*writer=*/&from_b_to_a);
|
||||
auto from_a_to_b = CreatePipe();
|
||||
auto from_b_to_a = CreatePipe();
|
||||
User user_a(/*reader=*/from_b_to_a.first.get(),
|
||||
/*writer=*/from_a_to_b.second.get());
|
||||
User user_b(/*reader=*/from_a_to_b.first.get(),
|
||||
/*writer=*/from_b_to_a.second.get());
|
||||
Response response;
|
||||
|
||||
user_a.crypto.StartServer(
|
||||
|
||||
@@ -20,12 +20,16 @@
|
||||
|
||||
#include "absl/time/time.h"
|
||||
#include "connections/implementation/offline_frames.h"
|
||||
#include "internal/platform/condition_variable.h"
|
||||
#include "internal/platform/feature_flags.h"
|
||||
#include "internal/platform/logging.h"
|
||||
#include "internal/platform/mutex.h"
|
||||
#include "internal/platform/mutex_lock.h"
|
||||
#include "proto/connections_enums.pb.h"
|
||||
|
||||
namespace nearby {
|
||||
namespace connections {
|
||||
using ::location::nearby::analytics::proto::ConnectionsLog;
|
||||
|
||||
namespace {
|
||||
const absl::Duration kDataTransferDelay = absl::Milliseconds(500);
|
||||
@@ -97,7 +101,8 @@ void EndpointChannelManager::SetActiveEndpointChannel(
|
||||
// crypto context is present.
|
||||
channel->SetAnalyticsRecorder(&client->GetAnalyticsRecorder(), endpoint_id);
|
||||
channel_state_.UpdateChannelForEndpoint(endpoint_id, std::move(channel));
|
||||
|
||||
channel_state_.UpdateSafeToDisconnectForEndpoint(
|
||||
endpoint_id, client->IsSafeToDisconnectEnabled(endpoint_id));
|
||||
auto* endpoint = channel_state_.LookupEndpointData(endpoint_id);
|
||||
if (endpoint->IsEncrypted() && enable_encryption)
|
||||
channel_state_.EncryptChannel(endpoint);
|
||||
@@ -113,6 +118,37 @@ bool EndpointChannelManager::isWifiLanConnected() const {
|
||||
return channel_state_.isWifiLanConnected();
|
||||
}
|
||||
|
||||
void EndpointChannelManager::UpdateSafeToDisconnectForEndpoint(
|
||||
const std::string& endpoint_id,
|
||||
bool safe_to_disconnect_enabled) {
|
||||
MutexLock lock(&mutex_);
|
||||
channel_state_.UpdateSafeToDisconnectForEndpoint(endpoint_id,
|
||||
safe_to_disconnect_enabled);
|
||||
}
|
||||
|
||||
void EndpointChannelManager::MarkEndpointStopWaitToDisconnect(
|
||||
const std::string& endpoint_id, bool is_safe_to_disconnect,
|
||||
bool notify_stop_waiting) {
|
||||
MutexLock lock(&mutex_);
|
||||
channel_state_.MarkEndpointStopWaitToDisconnect(
|
||||
endpoint_id, is_safe_to_disconnect, notify_stop_waiting);
|
||||
}
|
||||
|
||||
bool EndpointChannelManager::CreateNewTimeoutDisconnectedState(
|
||||
const std::string& endpoint_id) {
|
||||
return channel_state_.CreateNewTimeoutDisconnectedState(endpoint_id);
|
||||
}
|
||||
|
||||
bool EndpointChannelManager::IsSafeToDisconnect(
|
||||
const std::string& endpoint_id) {
|
||||
return channel_state_.IsSafeToDisconnect(endpoint_id);
|
||||
}
|
||||
void EndpointChannelManager::RemoveTimeoutDisconnectedState(
|
||||
const std::string& endpoint_id) {
|
||||
MutexLock lock(&mutex_);
|
||||
channel_state_.RemoveTimeoutDisconnectedState(endpoint_id);
|
||||
}
|
||||
|
||||
///////////////////////////////// ChannelState /////////////////////////////////
|
||||
|
||||
// endpoint - channel endpoint to encrypt
|
||||
@@ -133,6 +169,15 @@ EndpointChannelManager::ChannelState::LookupEndpointData(
|
||||
return item != endpoints_.end() ? &item->second : nullptr;
|
||||
}
|
||||
|
||||
void EndpointChannelManager::ChannelState::DestroyAll() {
|
||||
for (auto& item : endpoints_) {
|
||||
RemoveEndpoint(item.first, DisconnectionReason::SHUTDOWN,
|
||||
/* safe_to_disconnect_enabled */ false,
|
||||
ConnectionsLog::EstablishedConnection::SAFE_DISCONNECTION);
|
||||
}
|
||||
endpoints_.clear();
|
||||
}
|
||||
|
||||
void EndpointChannelManager::ChannelState::UpdateChannelForEndpoint(
|
||||
const std::string& endpoint_id, std::unique_ptr<EndpointChannel> channel) {
|
||||
// Create EndpointData instance, if necessary, and populate channel.
|
||||
@@ -146,24 +191,54 @@ void EndpointChannelManager::ChannelState::UpdateEncryptionContextForEndpoint(
|
||||
endpoints_[endpoint_id].context = std::move(context);
|
||||
}
|
||||
|
||||
bool EndpointChannelManager::ChannelState::RemoveEndpoint(
|
||||
void EndpointChannelManager::ChannelState::UpdateSafeToDisconnectForEndpoint(
|
||||
const std::string& endpoint_id,
|
||||
location::nearby::proto::connections::DisconnectionReason reason) {
|
||||
bool safe_to_disconnect_enabled) {
|
||||
NEARBY_LOGS(INFO) << "[safe-to-disconnect] "
|
||||
"UpdateSafeToDisconnectForEndpoint for: "
|
||||
<< endpoint_id << " " << safe_to_disconnect_enabled;
|
||||
|
||||
endpoints_[endpoint_id].safe_to_disconnect_enabled =
|
||||
safe_to_disconnect_enabled;
|
||||
}
|
||||
|
||||
bool EndpointChannelManager::ChannelState::GetSafeToDisconnectForEndpoint(
|
||||
const std::string& endpoint_id) {
|
||||
auto item = endpoints_.find(endpoint_id);
|
||||
if (item == endpoints_.end()) return false;
|
||||
NEARBY_LOGS(INFO) << "[safe-to-disconnect] GetSafeToDisconnectForEndpoint: "
|
||||
<< item->second.safe_to_disconnect_enabled;
|
||||
return item->second.safe_to_disconnect_enabled;
|
||||
}
|
||||
|
||||
bool EndpointChannelManager::ChannelState::RemoveEndpoint(
|
||||
const std::string& endpoint_id, DisconnectionReason reason,
|
||||
bool safe_to_disconnect_enabled, SafeDisconnectionResult result) {
|
||||
auto item = endpoints_.find(endpoint_id);
|
||||
if (item == endpoints_.end()) return false;
|
||||
|
||||
MarkEndpointStopWaitToDisconnect(endpoint_id,
|
||||
/* is_safe_to_disconnect */ true,
|
||||
/* notify_stop_waiting */ true);
|
||||
item->second.disconnect_reason = reason;
|
||||
auto channel = item->second.channel;
|
||||
if (channel) {
|
||||
|
||||
if (channel && !safe_to_disconnect_enabled) {
|
||||
// If the channel was paused (i.e. during a bandwidth upgrade negotiation)
|
||||
// we resume to ensure the thread won't hang when trying to write to it.
|
||||
channel->Resume();
|
||||
|
||||
channel->Write(parser::ForDisconnection());
|
||||
NEARBY_LOGS(INFO) << "[safe-to-disconnect] Sending DISCONNECTION frame"
|
||||
" with request 0, ack 0";
|
||||
channel->Write(
|
||||
parser::ForDisconnection(/* request_safe_to_disconnect */ false,
|
||||
/* ack_safe_to_disconnect */ false));
|
||||
NEARBY_LOGS(INFO)
|
||||
<< "EndpointChannelManager reported the disconnection to endpoint "
|
||||
<< endpoint_id;
|
||||
SystemClock::Sleep(kDataTransferDelay);
|
||||
}
|
||||
NEARBY_LOGS(INFO) << "Remove Endpoint: " << endpoint_id;
|
||||
endpoints_.erase(item);
|
||||
return true;
|
||||
}
|
||||
@@ -183,20 +258,93 @@ bool EndpointChannelManager::ChannelState::isWifiLanConnected() const {
|
||||
return false;
|
||||
}
|
||||
|
||||
bool EndpointChannelManager::UnregisterChannelForEndpoint(
|
||||
void EndpointChannelManager::ChannelState::MarkEndpointStopWaitToDisconnect(
|
||||
const std::string& endpoint_id, bool is_safe_to_disconnect,
|
||||
bool notify_stop_waiting) {
|
||||
auto item = endpoints_.find(endpoint_id);
|
||||
if (item == endpoints_.end()) return;
|
||||
NEARBY_LOGS(INFO) << "[safe-to-disconnect] is_safe_to_disconnect= "
|
||||
<< is_safe_to_disconnect
|
||||
<< ", notify_stop_waiting= " << notify_stop_waiting
|
||||
<< " for endpoint: " << endpoint_id;
|
||||
{
|
||||
MutexLock lock(&item->second.timeout_to_disconnected_mutex);
|
||||
item->second.is_safe_to_disconnect = is_safe_to_disconnect;
|
||||
if (!item->second.timeout_to_disconnected_enabled) return;
|
||||
if (notify_stop_waiting) {
|
||||
NEARBY_LOGS(INFO) << "[safe-to-disconnect] Notify stop "
|
||||
"waiting before timeout.";
|
||||
item->second.timeout_to_disconnected.Notify();
|
||||
item->second.timeout_to_disconnected_notified = true;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
bool EndpointChannelManager::ChannelState::CreateNewTimeoutDisconnectedState(
|
||||
const std::string& endpoint_id) {
|
||||
auto item = endpoints_.find(endpoint_id);
|
||||
if (item == endpoints_.end()) return false;
|
||||
NEARBY_LOGS(INFO) << "[safe-to-disconnect] "
|
||||
"Create TimeoutDisconnectedState for endpoint: "
|
||||
<< endpoint_id;
|
||||
{
|
||||
MutexLock lock(&item->second.timeout_to_disconnected_mutex);
|
||||
item->second.timeout_to_disconnected_enabled = true;
|
||||
item->second.timeout_to_disconnected_notified = false;
|
||||
item->second.timeout_to_disconnected.Wait(FeatureFlags::GetInstance()
|
||||
.GetFlags()
|
||||
.safe_to_disconnect_ack_delay_millis);
|
||||
NEARBY_LOGS(INFO) << "[safe-to-disconnect] Wait is done with "
|
||||
<< (item->second.timeout_to_disconnected_notified
|
||||
? "notification"
|
||||
: "timeout");
|
||||
if (!item->second.timeout_to_disconnected_notified)
|
||||
item->second.is_safe_to_disconnect = true;
|
||||
item->second.timeout_to_disconnected_notified = false;
|
||||
item->second.timeout_to_disconnected_enabled = false;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
bool EndpointChannelManager::ChannelState::IsSafeToDisconnect(
|
||||
const std::string& endpoint_id) {
|
||||
|
||||
auto item = endpoints_.find(endpoint_id);
|
||||
if (item == endpoints_.end()) return true;
|
||||
{
|
||||
MutexLock lock(&item->second.timeout_to_disconnected_mutex);
|
||||
NEARBY_LOGS(INFO)
|
||||
<< "[safe-to-disconnect] Get SafeToDisconnect status for endpoint: "
|
||||
<< endpoint_id << ": " << item->second.is_safe_to_disconnect;
|
||||
return (item->second.is_safe_to_disconnect);
|
||||
}
|
||||
}
|
||||
|
||||
void EndpointChannelManager::ChannelState::RemoveTimeoutDisconnectedState(
|
||||
const std::string& endpoint_id) {
|
||||
auto item = endpoints_.find(endpoint_id);
|
||||
if (item == endpoints_.end()) return;
|
||||
{
|
||||
MutexLock lock(&item->second.timeout_to_disconnected_mutex);
|
||||
item->second.timeout_to_disconnected_notified = false;
|
||||
item->second.timeout_to_disconnected_enabled = false;
|
||||
}
|
||||
}
|
||||
|
||||
bool EndpointChannelManager::UnregisterChannelForEndpoint(
|
||||
const std::string& endpoint_id, DisconnectionReason reason,
|
||||
SafeDisconnectionResult result) {
|
||||
MutexLock lock(&mutex_);
|
||||
|
||||
if (!channel_state_.RemoveEndpoint(
|
||||
endpoint_id, location::nearby::proto::connections::
|
||||
DisconnectionReason::LOCAL_DISCONNECTION)) {
|
||||
auto safe_to_disconnect_enabled =
|
||||
channel_state_.GetSafeToDisconnectForEndpoint(endpoint_id);
|
||||
if (!channel_state_.RemoveEndpoint(endpoint_id, reason,
|
||||
safe_to_disconnect_enabled, result)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
NEARBY_LOGS(INFO)
|
||||
<< "EndpointChannelManager unregistered channel for endpoint "
|
||||
<< endpoint_id;
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
@@ -17,15 +17,23 @@
|
||||
|
||||
#include <memory>
|
||||
#include <string>
|
||||
#include <utility>
|
||||
|
||||
#include "securegcm/d2d_connection_context_v1.h"
|
||||
#include "absl/base/thread_annotations.h"
|
||||
#include "absl/container/flat_hash_map.h"
|
||||
#include "connections/implementation/client_proxy.h"
|
||||
#include "connections/implementation/endpoint_channel.h"
|
||||
#include "internal/platform/feature_flags.h"
|
||||
#include "internal/platform/mutex.h"
|
||||
#include "internal/proto/analytics/connections_log.pb.h"
|
||||
|
||||
namespace nearby {
|
||||
namespace connections {
|
||||
using DisconnectionReason =
|
||||
::location::nearby::proto::connections::DisconnectionReason;
|
||||
using SafeDisconnectionResult = ::location::nearby::analytics::proto::
|
||||
ConnectionsLog::EstablishedConnection::SafeDisconnectionResult;
|
||||
|
||||
// NOTE(std::string):
|
||||
// All the strings in internal class public interfaces should be exchanged as
|
||||
@@ -90,13 +98,28 @@ class EndpointChannelManager final {
|
||||
|
||||
// Returns true if 'endpoint_id' actually had a registered EndpointChannel.
|
||||
// IOW, a return of false signifies a no-op.
|
||||
bool UnregisterChannelForEndpoint(const std::string& endpoint_id)
|
||||
bool UnregisterChannelForEndpoint(const std::string& endpoint_id,
|
||||
DisconnectionReason reason,
|
||||
SafeDisconnectionResult result)
|
||||
ABSL_LOCKS_EXCLUDED(mutex_);
|
||||
|
||||
int GetConnectedEndpointsCount() const ABSL_LOCKS_EXCLUDED(mutex_);
|
||||
|
||||
// Check if any endpoint uses WLAN Medium
|
||||
bool isWifiLanConnected() const ABSL_LOCKS_EXCLUDED(mutex_);
|
||||
void UpdateSafeToDisconnectForEndpoint(const std::string& endpoint_id,
|
||||
bool safe_to_disconnect_enabled)
|
||||
ABSL_LOCKS_EXCLUDED(mutex_);
|
||||
void MarkEndpointStopWaitToDisconnect(const std::string& endpoint_id,
|
||||
bool is_safe_to_disconnect,
|
||||
bool notify_stop_waiting)
|
||||
ABSL_LOCKS_EXCLUDED(mutex_);
|
||||
bool CreateNewTimeoutDisconnectedState(const std::string& endpoint_id)
|
||||
ABSL_LOCKS_EXCLUDED(mutex_);
|
||||
bool IsSafeToDisconnect(const std::string& endpoint_id)
|
||||
ABSL_LOCKS_EXCLUDED(mutex_);
|
||||
void RemoveTimeoutDisconnectedState(const std::string& endpoint_id)
|
||||
ABSL_LOCKS_EXCLUDED(mutex_);
|
||||
|
||||
private:
|
||||
// Tracks channel state for all endpoints. This includes what EndpointChannel
|
||||
@@ -119,9 +142,17 @@ class EndpointChannelManager final {
|
||||
|
||||
std::shared_ptr<EndpointChannel> channel;
|
||||
std::shared_ptr<EncryptionContext> context;
|
||||
location::nearby::proto::connections::DisconnectionReason
|
||||
disconnect_reason = location::nearby::proto::connections::
|
||||
DisconnectionReason::UNKNOWN_DISCONNECTION_REASON;
|
||||
DisconnectionReason disconnect_reason =
|
||||
DisconnectionReason::UNKNOWN_DISCONNECTION_REASON;
|
||||
bool safe_to_disconnect_enabled = false;
|
||||
mutable Mutex timeout_to_disconnected_mutex;
|
||||
ConditionVariable timeout_to_disconnected{&timeout_to_disconnected_mutex};
|
||||
bool timeout_to_disconnected_enabled
|
||||
ABSL_GUARDED_BY(timeout_to_disconnected_mutex) = false;
|
||||
bool timeout_to_disconnected_notified
|
||||
ABSL_GUARDED_BY(timeout_to_disconnected_mutex) = false;
|
||||
bool is_safe_to_disconnect
|
||||
ABSL_GUARDED_BY(timeout_to_disconnected_mutex) = false;
|
||||
};
|
||||
|
||||
ChannelState() = default;
|
||||
@@ -130,7 +161,7 @@ class EndpointChannelManager final {
|
||||
ChannelState& operator=(ChannelState&&) = default;
|
||||
|
||||
// Provides a way to destroy contents of a container, while holding a lock.
|
||||
void DestroyAll() { endpoints_.clear(); }
|
||||
void DestroyAll();
|
||||
// Return pointer to endpoint data, or nullptr, it not found.
|
||||
EndpointData* LookupEndpointData(const std::string& endpoint_id);
|
||||
|
||||
@@ -145,15 +176,26 @@ class EndpointChannelManager final {
|
||||
const std::string& endpoint_id,
|
||||
std::unique_ptr<EncryptionContext> context);
|
||||
|
||||
void UpdateSafeToDisconnectForEndpoint(const std::string& endpoint_id,
|
||||
bool safe_to_disconnect_enabled);
|
||||
bool GetSafeToDisconnectForEndpoint(const std::string& endpoint_id);
|
||||
|
||||
// Removes all knowledge of this endpoint, cleaning up as necessary.
|
||||
// Returns false if the endpoint was not found.
|
||||
bool RemoveEndpoint(
|
||||
const std::string& endpoint_id,
|
||||
location::nearby::proto::connections::DisconnectionReason reason);
|
||||
bool RemoveEndpoint(const std::string& endpoint_id,
|
||||
DisconnectionReason reason,
|
||||
bool safe_to_disconnect_enabled,
|
||||
SafeDisconnectionResult result);
|
||||
|
||||
bool EncryptChannel(EndpointData* endpoint);
|
||||
int GetConnectedEndpointsCount() const { return endpoints_.size(); }
|
||||
bool isWifiLanConnected() const;
|
||||
void MarkEndpointStopWaitToDisconnect(const std::string& endpoint_id,
|
||||
bool is_safe_to_disconnect,
|
||||
bool notify_stop_waiting);
|
||||
bool CreateNewTimeoutDisconnectedState(const std::string& endpoint_id);
|
||||
bool IsSafeToDisconnect(const std::string& endpoint_id);
|
||||
void RemoveTimeoutDisconnectedState(const std::string& endpoint_id);
|
||||
|
||||
private:
|
||||
// Endpoint ID -> EndpointData. Contains everything we know about the
|
||||
@@ -168,7 +210,7 @@ class EndpointChannelManager final {
|
||||
ABSL_EXCLUSIVE_LOCKS_REQUIRED(mutex_);
|
||||
|
||||
mutable Mutex mutex_;
|
||||
ChannelState channel_state_ ABSL_GUARDED_BY(mutex_);
|
||||
ChannelState channel_state_;
|
||||
};
|
||||
|
||||
} // namespace connections
|
||||
|
||||
@@ -14,20 +14,24 @@
|
||||
|
||||
#include "connections/implementation/endpoint_channel_manager.h"
|
||||
|
||||
#include <cstddef>
|
||||
#include <functional>
|
||||
#include <memory>
|
||||
#include <string>
|
||||
#include <utility>
|
||||
|
||||
#include "securegcm/d2d_connection_context_v1.h"
|
||||
#include "securegcm/ukey2_handshake.h"
|
||||
#include "gmock/gmock.h"
|
||||
#include "protobuf-matchers/protocol-buffer-matchers.h"
|
||||
#include "gtest/gtest.h"
|
||||
#include "absl/strings/string_view.h"
|
||||
#include "absl/synchronization/mutex.h"
|
||||
#include "absl/time/time.h"
|
||||
#include "connections/implementation/base_endpoint_channel.h"
|
||||
#include "connections/implementation/client_proxy.h"
|
||||
#include "connections/implementation/encryption_runner.h"
|
||||
#include "connections/implementation/endpoint_channel.h"
|
||||
#include "internal/platform/byte_array.h"
|
||||
#include "internal/platform/count_down_latch.h"
|
||||
#include "internal/platform/exception.h"
|
||||
#include "internal/platform/input_stream.h"
|
||||
@@ -35,16 +39,19 @@
|
||||
#include "internal/platform/multi_thread_executor.h"
|
||||
#include "internal/platform/output_stream.h"
|
||||
#include "internal/platform/pipe.h"
|
||||
#include "internal/proto/analytics/connections_log.pb.h"
|
||||
#include "proto/connections_enums.pb.h"
|
||||
|
||||
namespace nearby {
|
||||
namespace connections {
|
||||
namespace {
|
||||
|
||||
using ::location::nearby::analytics::proto::ConnectionsLog;
|
||||
using ::location::nearby::proto::connections::DisconnectionReason;
|
||||
using ::location::nearby::proto::connections::Medium;
|
||||
using EncryptionContext = BaseEndpointChannel::EncryptionContext;
|
||||
|
||||
constexpr size_t kChunkSize = 64 * 1024;
|
||||
constexpr absl::string_view kEndpointId = "EndpointId";
|
||||
constexpr absl::string_view kMonitorA = "MonitorA";
|
||||
constexpr absl::string_view kMonitorB = "MonitorB";
|
||||
@@ -66,7 +73,7 @@ std::function<void()> MakeDataPump(
|
||||
return [label, input, output, monitor]() {
|
||||
NEARBY_LOGS(INFO) << "streaming data through '" << label << "'";
|
||||
while (true) {
|
||||
auto read_response = input->Read(Pipe::kChunkSize);
|
||||
auto read_response = input->Read(kChunkSize);
|
||||
if (!read_response.ok()) {
|
||||
NEARBY_LOGS(INFO) << "Peer reader closed on '" << label << "'";
|
||||
output->Close();
|
||||
@@ -169,14 +176,18 @@ TEST(BaseEndpointChannelManagerTest, RegisterChannelEncryptedReadwrite) {
|
||||
std::string capture_b;
|
||||
ClientProxy proxy_a;
|
||||
ClientProxy proxy_b;
|
||||
Pipe client_a; // Channel "a" writes to client "a", reads from server "a".
|
||||
Pipe client_b; // Channel "b" writes to client "b", reads from server "b".
|
||||
Pipe server_a; // Data pump "a" reads from client "a", writes to server "b".
|
||||
Pipe server_b; // Data pump "b" reads from client "b", writes to server "a".
|
||||
auto channel_a = std::make_unique<MockEndpointChannel>(
|
||||
&server_a.GetInputStream(), &client_a.GetOutputStream());
|
||||
auto channel_b = std::make_unique<MockEndpointChannel>(
|
||||
&server_b.GetInputStream(), &client_b.GetOutputStream());
|
||||
auto client_a =
|
||||
CreatePipe(); // Channel "a" writes to client "a", reads from server "a".
|
||||
auto client_b =
|
||||
CreatePipe(); // Channel "b" writes to client "b", reads from server "b".
|
||||
auto server_a = CreatePipe(); // Data pump "a" reads from client "a", writes
|
||||
// to server "b".
|
||||
auto server_b = CreatePipe(); // Data pump "b" reads from client "b", writes
|
||||
// to server "a".
|
||||
auto channel_a = std::make_unique<MockEndpointChannel>(server_a.first.get(),
|
||||
client_a.second.get());
|
||||
auto channel_b = std::make_unique<MockEndpointChannel>(server_b.first.get(),
|
||||
client_b.second.get());
|
||||
auto channel_a_raw = channel_a.get();
|
||||
auto channel_b_raw = channel_b.get();
|
||||
|
||||
@@ -188,12 +199,12 @@ TEST(BaseEndpointChannelManagerTest, RegisterChannelEncryptedReadwrite) {
|
||||
});
|
||||
|
||||
MultiThreadExecutor executor(2);
|
||||
executor.Execute(MakeDataPump(
|
||||
kPumpA, &client_a.GetInputStream(), &server_b.GetOutputStream(),
|
||||
MakeDataMonitor(kMonitorA, &capture_a, &mutex)));
|
||||
executor.Execute(MakeDataPump(
|
||||
kPumpB, &client_b.GetInputStream(), &server_a.GetOutputStream(),
|
||||
MakeDataMonitor(kMonitorB, &capture_b, &mutex)));
|
||||
executor.Execute(
|
||||
MakeDataPump(kPumpA, client_a.first.get(), server_b.second.get(),
|
||||
MakeDataMonitor(kMonitorA, &capture_a, &mutex)));
|
||||
executor.Execute(
|
||||
MakeDataPump(kPumpB, client_b.first.get(), server_a.second.get(),
|
||||
MakeDataMonitor(kMonitorB, &capture_b, &mutex)));
|
||||
|
||||
// Run DH key exchange; setup encryption contexts for channels.
|
||||
auto context = DoDhKeyExchange(channel_a.get(), channel_b.get());
|
||||
@@ -231,6 +242,12 @@ TEST(BaseEndpointChannelManagerTest, RegisterChannelEncryptedReadwrite) {
|
||||
// Shutdown test environment.
|
||||
channel_a_raw->Close(DisconnectionReason::LOCAL_DISCONNECTION);
|
||||
channel_b_raw->Close(DisconnectionReason::REMOTE_DISCONNECTION);
|
||||
ecm_a.UnregisterChannelForEndpoint(
|
||||
std::string(kEndpointId), DisconnectionReason::LOCAL_DISCONNECTION,
|
||||
ConnectionsLog::EstablishedConnection::SAFE_DISCONNECTION);
|
||||
ecm_b.UnregisterChannelForEndpoint(
|
||||
std::string(kEndpointId), DisconnectionReason::REMOTE_DISCONNECTION,
|
||||
ConnectionsLog::EstablishedConnection::SAFE_DISCONNECTION);
|
||||
}
|
||||
|
||||
TEST(BaseEndpointChannelManagerTest, ReplaceChannelNoEncrypted) {
|
||||
@@ -240,14 +257,18 @@ TEST(BaseEndpointChannelManagerTest, ReplaceChannelNoEncrypted) {
|
||||
std::string capture_b;
|
||||
ClientProxy proxy_a;
|
||||
ClientProxy proxy_b;
|
||||
Pipe client_a; // Channel "a" writes to client "a", reads from server "a".
|
||||
Pipe client_b; // Channel "b" writes to client "b", reads from server "b".
|
||||
Pipe server_a; // Data pump "a" reads from client "a", writes to server "b".
|
||||
Pipe server_b; // Data pump "b" reads from client "b", writes to server "a".
|
||||
auto channel_a = std::make_unique<MockEndpointChannel>(
|
||||
&server_a.GetInputStream(), &client_a.GetOutputStream());
|
||||
auto channel_b = std::make_unique<MockEndpointChannel>(
|
||||
&server_b.GetInputStream(), &client_b.GetOutputStream());
|
||||
auto client_a =
|
||||
CreatePipe(); // Channel "a" writes to client "a", reads from server "a".
|
||||
auto client_b =
|
||||
CreatePipe(); // Channel "b" writes to client "b", reads from server "b".
|
||||
auto server_a = CreatePipe(); // Data pump "a" reads from client "a", writes
|
||||
// to server "b".
|
||||
auto server_b = CreatePipe(); // Data pump "b" reads from client "b", writes
|
||||
// to server "a".
|
||||
auto channel_a = std::make_unique<MockEndpointChannel>(server_a.first.get(),
|
||||
client_a.second.get());
|
||||
auto channel_b = std::make_unique<MockEndpointChannel>(server_b.first.get(),
|
||||
client_b.second.get());
|
||||
auto channel_a_raw = channel_a.get();
|
||||
auto channel_b_raw = channel_b.get();
|
||||
|
||||
@@ -259,12 +280,12 @@ TEST(BaseEndpointChannelManagerTest, ReplaceChannelNoEncrypted) {
|
||||
});
|
||||
|
||||
MultiThreadExecutor executor(2);
|
||||
executor.Execute(MakeDataPump(
|
||||
kPumpA, &client_a.GetInputStream(), &server_b.GetOutputStream(),
|
||||
MakeDataMonitor(kMonitorA, &capture_a, &mutex)));
|
||||
executor.Execute(MakeDataPump(
|
||||
kPumpB, &client_b.GetInputStream(), &server_a.GetOutputStream(),
|
||||
MakeDataMonitor(kMonitorB, &capture_b, &mutex)));
|
||||
executor.Execute(
|
||||
MakeDataPump(kPumpA, client_a.first.get(), server_b.second.get(),
|
||||
MakeDataMonitor(kMonitorA, &capture_a, &mutex)));
|
||||
executor.Execute(
|
||||
MakeDataPump(kPumpB, client_b.first.get(), server_a.second.get(),
|
||||
MakeDataMonitor(kMonitorB, &capture_b, &mutex)));
|
||||
|
||||
// Run DH key exchange; setup encryption contexts for channels.
|
||||
auto context = DoDhKeyExchange(channel_a.get(), channel_b.get());
|
||||
@@ -289,7 +310,12 @@ TEST(BaseEndpointChannelManagerTest, ReplaceChannelNoEncrypted) {
|
||||
// Shutdown test environment.
|
||||
channel_a_raw->Close(DisconnectionReason::LOCAL_DISCONNECTION);
|
||||
channel_b_raw->Close(DisconnectionReason::REMOTE_DISCONNECTION);
|
||||
}
|
||||
ecm_a.UnregisterChannelForEndpoint(
|
||||
std::string(kEndpointId), DisconnectionReason::LOCAL_DISCONNECTION,
|
||||
ConnectionsLog::EstablishedConnection::SAFE_DISCONNECTION);
|
||||
ecm_b.UnregisterChannelForEndpoint(
|
||||
std::string(kEndpointId), DisconnectionReason::REMOTE_DISCONNECTION,
|
||||
ConnectionsLog::EstablishedConnection::SAFE_DISCONNECTION);}
|
||||
|
||||
} // namespace
|
||||
} // namespace connections
|
||||
|
||||
@@ -21,8 +21,11 @@
|
||||
#include <utility>
|
||||
#include <vector>
|
||||
|
||||
#include "absl/time/time.h"
|
||||
#include "connections/implementation/analytics/throughput_recorder.h"
|
||||
#include "connections/implementation/client_proxy.h"
|
||||
#include "connections/implementation/endpoint_channel.h"
|
||||
#include "connections/implementation/endpoint_channel_manager.h"
|
||||
#include "connections/implementation/offline_frames.h"
|
||||
#include "connections/implementation/payload_manager.h"
|
||||
#include "connections/implementation/proto/offline_wire_formats.pb.h"
|
||||
@@ -30,12 +33,16 @@
|
||||
#include "internal/platform/count_down_latch.h"
|
||||
#include "internal/platform/exception.h"
|
||||
#include "internal/platform/logging.h"
|
||||
#include "internal/platform/mutex.h"
|
||||
#include "internal/platform/mutex_lock.h"
|
||||
#include "internal/proto/analytics/connections_log.pb.h"
|
||||
#include "proto/connections_enums.pb.h"
|
||||
|
||||
namespace nearby {
|
||||
namespace connections {
|
||||
|
||||
namespace {
|
||||
using ::location::nearby::analytics::proto::ConnectionsLog;
|
||||
using ::location::nearby::connections::OfflineFrame;
|
||||
using ::location::nearby::connections::V1Frame;
|
||||
using ::nearby::analytics::PacketMetaData;
|
||||
@@ -97,7 +104,7 @@ class EndpointManager::LockedFrameProcessor {
|
||||
void EndpointManager::EndpointChannelLoopRunnable(
|
||||
const std::string& runnable_name, ClientProxy* client,
|
||||
const std::string& endpoint_id,
|
||||
std::function<ExceptionOr<bool>(EndpointChannel*)> handler) {
|
||||
absl::AnyInvocable<ExceptionOr<bool>(EndpointChannel*)> handler) {
|
||||
// EndpointChannelManager will not let multiple channels exist simultaneously
|
||||
// for the same endpoint_id; it will be closing "old" channels as new ones
|
||||
// come.
|
||||
@@ -162,6 +169,11 @@ void EndpointManager::EndpointChannelLoopRunnable(
|
||||
NEARBY_LOGS(INFO) << "Dropping current channel: last medium="
|
||||
<< location::nearby::proto::connections::Medium_Name(
|
||||
last_failed_medium);
|
||||
if (client->IsSafeToDisconnectEnabled(endpoint_id)) {
|
||||
channel_manager_->MarkEndpointStopWaitToDisconnect(
|
||||
endpoint_id, /* is_safe_to_disconnect */ false,
|
||||
/* notify_stop_waiting */ true);
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
@@ -171,7 +183,7 @@ void EndpointManager::EndpointChannelLoopRunnable(
|
||||
<< "; endpoint_id=" << endpoint_id;
|
||||
// Always clear out all state related to this endpoint before terminating
|
||||
// this thread.
|
||||
DiscardEndpoint(client, endpoint_id);
|
||||
DiscardEndpoint(client, endpoint_id, DisconnectionReason::IO_ERROR);
|
||||
NEARBY_LOGS(INFO) << "Worker done; worker name=" << runnable_name
|
||||
<< "; endpoint_id=" << endpoint_id;
|
||||
}
|
||||
@@ -260,7 +272,7 @@ ExceptionOr<bool> EndpointManager::HandleData(
|
||||
} else if (frame_type == V1Frame::DISCONNECTION) {
|
||||
NEARBY_LOG(INFO, "Disconnect message for endpoint %s",
|
||||
endpoint_id.c_str());
|
||||
endpoint_channel->Close();
|
||||
ProcessDisconnectionFrame(client, endpoint_id, endpoint_channel, frame);
|
||||
} else {
|
||||
NEARBY_LOGS(ERROR) << "Unhandled message: endpoint_id=" << endpoint_id
|
||||
<< ", frame type="
|
||||
@@ -275,6 +287,62 @@ ExceptionOr<bool> EndpointManager::HandleData(
|
||||
}
|
||||
}
|
||||
|
||||
void EndpointManager::ProcessDisconnectionFrame(
|
||||
ClientProxy* client, const std::string& endpoint_id,
|
||||
EndpointChannel* endpoint_channel, OfflineFrame& frame) {
|
||||
if (!client->IsSafeToDisconnectEnabled(endpoint_id)) {
|
||||
NEARBY_LOGS(INFO)
|
||||
<< "EndpointManager received a DISCONNECTION frame from endpoint "
|
||||
<< endpoint_id << " on channel " << endpoint_channel->GetType()
|
||||
<< ", disconnecting...";
|
||||
endpoint_channel->Close(DisconnectionReason::REMOTE_DISCONNECTION);
|
||||
return;
|
||||
}
|
||||
|
||||
if (!frame.v1().has_disconnection() ||
|
||||
!frame.v1().disconnection().has_request_safe_to_disconnect() ||
|
||||
!frame.v1().disconnection().request_safe_to_disconnect()) {
|
||||
NEARBY_LOGS(INFO) << "[safe-to-disconnect] no need to apply "
|
||||
"safe-to-disconnect protocol for endpoint "
|
||||
<< endpoint_id << " on channel "
|
||||
<< endpoint_channel->GetType() << ", disconnecting...";
|
||||
endpoint_channel->Close(DisconnectionReason::REMOTE_DISCONNECTION);
|
||||
return;
|
||||
}
|
||||
NEARBY_LOGS(INFO)
|
||||
<< "[safe-to-disconnect] received a "
|
||||
"DISCONNECTION frame with request safe to disconnect = true and ack = "
|
||||
<< frame.v1().disconnection().ack_safe_to_disconnect()
|
||||
<< " from endpoint " << endpoint_id << " on channel "
|
||||
<< endpoint_channel->GetType()
|
||||
<< ", disconnecting with safe-to-disconnect protocol ...";
|
||||
if (frame.v1().disconnection().ack_safe_to_disconnect()) {
|
||||
channel_manager_->MarkEndpointStopWaitToDisconnect(
|
||||
endpoint_id, /* is_safe_to_disconnect */ true,
|
||||
/* notify_stop_waiting */ true);
|
||||
} else {
|
||||
channel_manager_->MarkEndpointStopWaitToDisconnect(
|
||||
endpoint_id, /* is_safe_to_disconnect */ true,
|
||||
/* notify_stop_waiting */ false);
|
||||
RunOnEndpointManagerThread(
|
||||
"safe-to-disconnect", [this, client, &endpoint_id]() {
|
||||
RemoveEndpoint(client, endpoint_id, /*notify=*/true,
|
||||
DisconnectionReason::REMOTE_DISCONNECTION);
|
||||
});
|
||||
endpoint_channel->Resume();
|
||||
NEARBY_LOGS(INFO) << "[safe-to-disconnect] Sending "
|
||||
"DISCONNECTION frame with request 1, ack 1";
|
||||
Exception write_exception = endpoint_channel->Write(
|
||||
parser::ForDisconnection(/* request_safe_to_disconnect= */ true,
|
||||
/* ack_safe_to_disconnect= */ true));
|
||||
if (!write_exception.Ok()) {
|
||||
NEARBY_LOGS(INFO) << "[safe-to-disconnect] Failed to send "
|
||||
"DISCONNECTION frame with ack to endpoint"
|
||||
<< endpoint_id;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
ExceptionOr<bool> EndpointManager::HandleKeepAlive(
|
||||
EndpointChannel* endpoint_channel, absl::Duration keep_alive_interval,
|
||||
absl::Duration keep_alive_timeout, Mutex* keep_alive_waiter_mutex,
|
||||
@@ -290,10 +358,10 @@ ExceptionOr<bool> EndpointManager::HandleKeepAlive(
|
||||
return ExceptionOr<bool>(false);
|
||||
}
|
||||
|
||||
// If we haven't written anything to the endpoint for a while, attempt to send
|
||||
// the KeepAlive frame over the endpoint channel. If the write fails, our
|
||||
// super class will loop back around and try our luck again in case there's
|
||||
// been a replacement for this endpoint.
|
||||
// If we haven't written anything to the endpoint for a while, attempt to
|
||||
// send the KeepAlive frame over the endpoint channel. If the write fails,
|
||||
// our super class will loop back around and try our luck again in case
|
||||
// there's been a replacement for this endpoint.
|
||||
absl::Time last_write_time = endpoint_channel->GetLastWriteTimestamp();
|
||||
absl::Duration duration_until_write_keep_alive =
|
||||
last_write_time == kInvalidTimestamp
|
||||
@@ -323,15 +391,15 @@ ExceptionOr<bool> EndpointManager::HandleKeepAlive(
|
||||
|
||||
bool operator==(const EndpointManager::FrameProcessor& lhs,
|
||||
const EndpointManager::FrameProcessor& rhs) {
|
||||
// We're comparing addresses because these objects are callbacks which need to
|
||||
// be matched by exact instances.
|
||||
// We're comparing addresses because these objects are callbacks which need
|
||||
// to be matched by exact instances.
|
||||
return &lhs == &rhs;
|
||||
}
|
||||
|
||||
bool operator<(const EndpointManager::FrameProcessor& lhs,
|
||||
const EndpointManager::FrameProcessor& rhs) {
|
||||
// We're comparing addresses because these objects are callbacks which need to
|
||||
// be matched by exact instances.
|
||||
// We're comparing addresses because these objects are callbacks which need
|
||||
// to be matched by exact instances.
|
||||
return &lhs < &rhs;
|
||||
}
|
||||
|
||||
@@ -444,10 +512,11 @@ void EndpointManager::RegisterEndpoint(
|
||||
|
||||
// NOTE (unique_ptr<> capture):
|
||||
// std::unique_ptr<> is not copyable, so we can not pass it to
|
||||
// lambda capture, because lambda eventually is converted to std::function<>.
|
||||
// Instead, we release() a pointer, and pass a raw pointer, which is copyalbe.
|
||||
// We ignore the risk of job not scheduled (and an associated risk of memory
|
||||
// leak), because this may only happen during service shutdown.
|
||||
// lambda capture, because lambda eventually is converted to
|
||||
// std::function<>. Instead, we release() a pointer, and pass a raw pointer,
|
||||
// which is copyalbe. We ignore the risk of job not scheduled (and an
|
||||
// associated risk of memory leak), because this may only happen during
|
||||
// service shutdown.
|
||||
RunOnEndpointManagerThread("register-endpoint", [this, client,
|
||||
channel = channel.release(),
|
||||
&endpoint_id, &info,
|
||||
@@ -456,8 +525,8 @@ void EndpointManager::RegisterEndpoint(
|
||||
&latch]() {
|
||||
if (endpoints_.contains(endpoint_id)) {
|
||||
NEARBY_LOGS(WARNING) << "Registering duplicate endpoint " << endpoint_id;
|
||||
// We must remove old endpoint state before registering a new one for the
|
||||
// same endpoint_id.
|
||||
// We must remove old endpoint state before registering a new one
|
||||
// for the same endpoint_id.
|
||||
RemoveEndpointState(endpoint_id);
|
||||
}
|
||||
|
||||
@@ -487,8 +556,8 @@ void EndpointManager::RegisterEndpoint(
|
||||
// For every endpoint, there's normally only one Read handler instance
|
||||
// running on a dedicated thread. This instance reads data from the
|
||||
// endpoint and delegates incoming frames to various FrameProcessors.
|
||||
// Once the frame has been properly handled, it starts reading again for
|
||||
// the next frame. If the handler fails its read and no other
|
||||
// Once the frame has been properly handled, it starts reading again
|
||||
// for the next frame. If the handler fails its read and no other
|
||||
// EndpointChannels are available for this endpoint, a disconnection
|
||||
// will be initiated.
|
||||
endpoint_state.StartEndpointReader([this, client, endpoint_id]() {
|
||||
@@ -499,17 +568,18 @@ void EndpointManager::RegisterEndpoint(
|
||||
});
|
||||
});
|
||||
|
||||
// For every endpoint, there's only one KeepAliveManager instance running on
|
||||
// a dedicated thread. This instance will periodically send out a ping* to
|
||||
// the endpoint while listening for an incoming pong**. If it fails to send
|
||||
// the ping, or if no pong is heard within keep_alive_timeout, it initiates
|
||||
// a disconnection.
|
||||
// For every endpoint, there's only one KeepAliveManager instance
|
||||
// running on a dedicated thread. This instance will periodically send
|
||||
// out a ping* to the endpoint while listening for an incoming pong**.
|
||||
// If it fails to send the ping, or if no pong is heard within
|
||||
// keep_alive_timeout, it initiates a disconnection.
|
||||
//
|
||||
// (*) Bluetooth requires a constant outgoing stream of messages. If
|
||||
// there's silence, Android will break the socket. This is why we ping.
|
||||
// (**) Wifi Hotspots can fail to notice a connection has been lost, and
|
||||
// they will happily keep writing to /dev/null. This is why we listen
|
||||
// for the pong.
|
||||
// there's silence, Android will break the socket. This is why we
|
||||
// ping.
|
||||
// (**) Wifi Hotspots can fail to notice a connection has been lost,
|
||||
// and they will happily keep writing to /dev/null. This is why we
|
||||
// listen for the pong.
|
||||
NEARBY_LOGS(VERBOSE) << "EndpointManager enabling KeepAlive for endpoint "
|
||||
<< endpoint_id;
|
||||
endpoint_state.StartEndpointKeepAliveManager(
|
||||
@@ -545,7 +615,8 @@ void EndpointManager::UnregisterEndpoint(ClientProxy* client,
|
||||
RunOnEndpointManagerThread(
|
||||
"unregister-endpoint", [this, client, endpoint_id, &latch]() {
|
||||
RemoveEndpoint(client, endpoint_id,
|
||||
/*notify=*/client->IsConnectedToEndpoint(endpoint_id));
|
||||
/*notify=*/client->IsConnectedToEndpoint(endpoint_id),
|
||||
DisconnectionReason::LOCAL_DISCONNECTION);
|
||||
latch.CountDown();
|
||||
});
|
||||
latch.Await();
|
||||
@@ -578,12 +649,19 @@ std::vector<std::string> EndpointManager::SendPayloadChunk(
|
||||
}
|
||||
|
||||
// Designed to run asynchronously. It is called from IO thread pools, and
|
||||
// jobs in these pools may be waited for from the EndpointManager thread. If we
|
||||
// allow synchronous behavior here it will cause a live lock.
|
||||
// jobs in these pools may be waited for from the EndpointManager thread. If
|
||||
// we allow synchronous behavior here it will cause a live lock.
|
||||
void EndpointManager::DiscardEndpoint(ClientProxy* client,
|
||||
const std::string& endpoint_id) {
|
||||
NEARBY_LOGS(VERBOSE) << "DiscardEndpoint for endpoint " << endpoint_id;
|
||||
RunOnEndpointManagerThread("discard-endpoint", [this, client, endpoint_id]() {
|
||||
const std::string& endpoint_id,
|
||||
DisconnectionReason reason) {
|
||||
NEARBY_LOGS(INFO) << "DiscardEndpoint for endpoint " << endpoint_id;
|
||||
if (reason == DisconnectionReason::IO_ERROR) {
|
||||
channel_manager_->MarkEndpointStopWaitToDisconnect(
|
||||
endpoint_id, /* is_safe_to_disconnect */ false,
|
||||
/* notify_stop_waiting */ true);
|
||||
}
|
||||
RunOnEndpointManagerThread("discard-endpoint", [this, client, endpoint_id,
|
||||
reason]() {
|
||||
// `ClientProxy` is destroyed before `EndpointManager` in
|
||||
// `~NearbyConnections`, which means "discard-endpoint" needs to check
|
||||
// if this task is being executing during `~EndpointManager` to
|
||||
@@ -625,7 +703,8 @@ void EndpointManager::DiscardEndpoint(ClientProxy* client,
|
||||
}
|
||||
|
||||
RemoveEndpoint(client, endpoint_id,
|
||||
/*notify=*/client->IsConnectedToEndpoint(endpoint_id));
|
||||
/* notify */client->IsConnectedToEndpoint(endpoint_id),
|
||||
reason);
|
||||
});
|
||||
}
|
||||
|
||||
@@ -647,8 +726,12 @@ std::vector<std::string> EndpointManager::SendControlMessage(
|
||||
// @EndpointManagerThread
|
||||
void EndpointManager::RemoveEndpoint(ClientProxy* client,
|
||||
const std::string& endpoint_id,
|
||||
bool notify) {
|
||||
NEARBY_LOGS(INFO) << "RemoveEndpoint for endpoint " << endpoint_id;
|
||||
bool notify, DisconnectionReason reason) {
|
||||
NEARBY_LOGS(INFO) << "RemoveEndpoint for endpoint: " << endpoint_id
|
||||
<< ", reason: " << reason;
|
||||
|
||||
SafeDisconnectionResult safe_disconnect_result =
|
||||
ConnectionsLog::EstablishedConnection::SAFE_DISCONNECTION;
|
||||
|
||||
// Grab the service ID before we destroy the channel.
|
||||
EndpointChannel* channel =
|
||||
@@ -656,16 +739,35 @@ void EndpointManager::RemoveEndpoint(ClientProxy* client,
|
||||
std::string service_id =
|
||||
channel ? channel->GetServiceId() : std::string(kUnknownServiceId);
|
||||
|
||||
if (client->IsSafeToDisconnectEnabled(endpoint_id)) {
|
||||
if (channel != nullptr) {
|
||||
bool is_safe_disconnection =
|
||||
ApplySafeToDisconnect(endpoint_id, channel, reason);
|
||||
safe_disconnect_result =
|
||||
is_safe_disconnection
|
||||
? ConnectionsLog::EstablishedConnection::SAFE_DISCONNECTION
|
||||
: ConnectionsLog::EstablishedConnection::UNSAFE_DISCONNECTION;
|
||||
NEARBY_LOGS(INFO) << "[safe-to-disconnect] safe_disconnect_result:"
|
||||
<< (safe_disconnect_result? "true" : "false");
|
||||
}
|
||||
}
|
||||
if (safe_disconnect_result ==
|
||||
ConnectionsLog::EstablishedConnection::UNSAFE_DISCONNECTION) {
|
||||
// TODO(b/297259496): Autoreconnect
|
||||
}
|
||||
|
||||
// Unregistering from channel_manager_ will also serve to terminate
|
||||
// the dedicated handler and KeepAlive threads we started when we registered
|
||||
// this endpoint.
|
||||
if (channel_manager_->UnregisterChannelForEndpoint(endpoint_id)) {
|
||||
if (channel_manager_->UnregisterChannelForEndpoint(endpoint_id, reason,
|
||||
safe_disconnect_result)) {
|
||||
// Notify all frame processors of the disconnection immediately and wait
|
||||
// for them to clean up state. Only once all processors are done cleaning
|
||||
// up, we can remove the endpoint from ClientProxy after which there
|
||||
// should be no further interactions with the endpoint.
|
||||
// (See b/37352254 for history)
|
||||
WaitForEndpointDisconnectionProcessing(client, service_id, endpoint_id);
|
||||
WaitForEndpointDisconnectionProcessing(client, service_id, endpoint_id,
|
||||
reason);
|
||||
|
||||
client->OnDisconnected(endpoint_id, notify);
|
||||
NEARBY_LOGS(INFO) << "Removed endpoint for endpoint " << endpoint_id;
|
||||
@@ -673,15 +775,68 @@ void EndpointManager::RemoveEndpoint(ClientProxy* client,
|
||||
RemoveEndpointState(endpoint_id);
|
||||
}
|
||||
|
||||
bool EndpointManager::ApplySafeToDisconnect(const std::string& endpoint_id,
|
||||
EndpointChannel* endpoint_channel,
|
||||
DisconnectionReason reason) {
|
||||
NEARBY_LOGS(INFO) << "[safe-to-disconnect] ApplySafeToDisconnect reason: "
|
||||
<< reason;
|
||||
bool is_safe_disconnection = false;
|
||||
bool send_disconnection_frame = true;
|
||||
switch (reason) {
|
||||
case DisconnectionReason::UPGRADED:
|
||||
case DisconnectionReason::SHUTDOWN:
|
||||
case DisconnectionReason::UNFINISHED:
|
||||
return true; // safe disconnection
|
||||
case DisconnectionReason::IO_ERROR:
|
||||
return false; // unsafe disconnection
|
||||
case DisconnectionReason::LOCAL_DISCONNECTION:
|
||||
is_safe_disconnection = true;
|
||||
send_disconnection_frame = true;
|
||||
break;
|
||||
case DisconnectionReason::REMOTE_DISCONNECTION:
|
||||
is_safe_disconnection = true;
|
||||
send_disconnection_frame = false;
|
||||
break;
|
||||
default:
|
||||
is_safe_disconnection = false;
|
||||
send_disconnection_frame = true;
|
||||
}
|
||||
|
||||
if (send_disconnection_frame) {
|
||||
// If the channel was paused (i.e. during a bandwidth upgrade negotiation)
|
||||
// we resume to ensure the thread won't hang when trying to write to it.
|
||||
endpoint_channel->Resume();
|
||||
NEARBY_LOGS(INFO) << "[safe-to-disconnect] Sending "
|
||||
"DISCONNECTION frame with request 1, ack 0";
|
||||
Exception write_exception = endpoint_channel->Write(
|
||||
parser::ForDisconnection(/* request_safe_to_disconnect= */ true,
|
||||
/* ack_safe_to_disconnect= */ false));
|
||||
|
||||
if (!write_exception.Ok()) {
|
||||
NEARBY_LOGS(WARNING) << "[safe-to-disconnect] Failed to send "
|
||||
"DISCONNECTION frame to endpoint"
|
||||
<< endpoint_id << " for reason: " << reason;
|
||||
return is_safe_disconnection;
|
||||
}
|
||||
}
|
||||
|
||||
bool state =
|
||||
channel_manager_->CreateNewTimeoutDisconnectedState(endpoint_id);
|
||||
if (!state) return is_safe_disconnection;
|
||||
|
||||
return is_safe_disconnection ||
|
||||
channel_manager_->IsSafeToDisconnect(endpoint_id);
|
||||
}
|
||||
|
||||
// @EndpointManagerThread
|
||||
void EndpointManager::WaitForEndpointDisconnectionProcessing(
|
||||
ClientProxy* client, const std::string& service_id,
|
||||
const std::string& endpoint_id) {
|
||||
const std::string& endpoint_id, DisconnectionReason reason) {
|
||||
NEARBY_LOGS(INFO) << "Wait: client=" << client
|
||||
<< "; service_id=" << service_id
|
||||
<< "; endpoint_id=" << endpoint_id;
|
||||
CountDownLatch barrier = NotifyFrameProcessorsOnEndpointDisconnect(
|
||||
client, service_id, endpoint_id);
|
||||
client, service_id, endpoint_id, reason);
|
||||
|
||||
NEARBY_LOGS(INFO)
|
||||
<< "Waiting for frame processors to disconnect from endpoint "
|
||||
@@ -690,15 +845,15 @@ void EndpointManager::WaitForEndpointDisconnectionProcessing(
|
||||
NEARBY_LOGS(INFO) << "Failed to disconnect frame processors from endpoint "
|
||||
<< endpoint_id;
|
||||
} else {
|
||||
NEARBY_LOGS(INFO)
|
||||
<< "Finished waiting for frame processors to disconnect from endpoint "
|
||||
<< endpoint_id;
|
||||
NEARBY_LOGS(INFO) << "Finished waiting for frame processors to "
|
||||
"disconnect from endpoint "
|
||||
<< endpoint_id;
|
||||
}
|
||||
}
|
||||
|
||||
CountDownLatch EndpointManager::NotifyFrameProcessorsOnEndpointDisconnect(
|
||||
ClientProxy* client, const std::string& service_id,
|
||||
const std::string& endpoint_id) {
|
||||
const std::string& endpoint_id, DisconnectionReason reason) {
|
||||
NEARBY_LOGS(INFO) << "NotifyFrameProcessorsOnEndpointDisconnect: client="
|
||||
<< client << "; service_id=" << service_id
|
||||
<< "; endpoint_id=" << endpoint_id;
|
||||
@@ -714,7 +869,8 @@ CountDownLatch EndpointManager::NotifyFrameProcessorsOnEndpointDisconnect(
|
||||
<< "; frame type=" << V1Frame::FrameType_Name(item.first);
|
||||
if (processor) {
|
||||
valid++;
|
||||
processor->OnEndpointDisconnect(client, service_id, endpoint_id, barrier);
|
||||
processor->OnEndpointDisconnect(client, service_id, endpoint_id, barrier,
|
||||
reason);
|
||||
} else {
|
||||
barrier.CountDown();
|
||||
}
|
||||
@@ -739,7 +895,8 @@ std::vector<std::string> EndpointManager::SendTransferFrameBytes(
|
||||
|
||||
if (channel == nullptr) {
|
||||
// We no longer know about this endpoint (it was either explicitly
|
||||
// unregistered, or a read/write error made us unregister it internally).
|
||||
// unregistered, or a read/write error made us unregister it
|
||||
// internally).
|
||||
NEARBY_LOGS(ERROR) << "EndpointManager failed to find EndpointChannel "
|
||||
"over which to write "
|
||||
<< packet_type << " at offset " << offset
|
||||
@@ -766,12 +923,15 @@ std::vector<std::string> EndpointManager::SendTransferFrameBytes(
|
||||
|
||||
EndpointManager::EndpointState::~EndpointState() {
|
||||
// We must unregister the endpoint first to signal the runnables that they
|
||||
// should exit their loops. SingleThreadExecutor destructors will wait for the
|
||||
// workers to finish. |channel_manager_| is null after moved from this object
|
||||
// (in move constructor) which prevents unregistering the channel prematurely.
|
||||
// should exit their loops. SingleThreadExecutor destructors will wait for
|
||||
// the workers to finish. |channel_manager_| is null after moved from this
|
||||
// object (in move constructor) which prevents unregistering the channel
|
||||
// prematurely.
|
||||
if (channel_manager_) {
|
||||
NEARBY_LOG(VERBOSE, "EndpointState destructor %s", endpoint_id_.c_str());
|
||||
channel_manager_->UnregisterChannelForEndpoint(endpoint_id_);
|
||||
channel_manager_->UnregisterChannelForEndpoint(
|
||||
endpoint_id_, DisconnectionReason::SHUTDOWN,
|
||||
ConnectionsLog::EstablishedConnection::SAFE_DISCONNECTION);
|
||||
}
|
||||
|
||||
// Make sure the KeepAlive thread isn't blocking shutdown.
|
||||
@@ -786,11 +946,11 @@ void EndpointManager::EndpointState::StartEndpointReader(Runnable&& runnable) {
|
||||
}
|
||||
|
||||
void EndpointManager::EndpointState::StartEndpointKeepAliveManager(
|
||||
std::function<void(Mutex*, ConditionVariable*)> runnable) {
|
||||
absl::AnyInvocable<void(Mutex*, ConditionVariable*)> runnable) {
|
||||
keep_alive_thread_.Execute(
|
||||
"keep-alive",
|
||||
[runnable, keep_alive_waiter_mutex = keep_alive_waiter_mutex_.get(),
|
||||
keep_alive_waiter = keep_alive_waiter_.get()]() {
|
||||
"keep-alive", [runnable = std::move(runnable),
|
||||
keep_alive_waiter_mutex = keep_alive_waiter_mutex_.get(),
|
||||
keep_alive_waiter = keep_alive_waiter_.get()]() mutable {
|
||||
runnable(keep_alive_waiter_mutex, keep_alive_waiter);
|
||||
});
|
||||
}
|
||||
|
||||
@@ -25,6 +25,7 @@
|
||||
#include "absl/base/thread_annotations.h"
|
||||
#include "absl/container/flat_hash_map.h"
|
||||
#include "absl/container/flat_hash_set.h"
|
||||
#include "absl/functional/any_invocable.h"
|
||||
#include "absl/time/time.h"
|
||||
#include "connections/implementation/analytics/packet_meta_data.h"
|
||||
#include "connections/implementation/client_proxy.h"
|
||||
@@ -89,7 +90,8 @@ class EndpointManager {
|
||||
virtual void OnEndpointDisconnect(ClientProxy* client,
|
||||
const std::string& service_id,
|
||||
const std::string& endpoint_id,
|
||||
CountDownLatch barrier) = 0;
|
||||
CountDownLatch barrier,
|
||||
DisconnectionReason reason) = 0;
|
||||
};
|
||||
|
||||
explicit EndpointManager(EndpointChannelManager* manager);
|
||||
@@ -153,7 +155,8 @@ class EndpointManager {
|
||||
// ask everyone who's registered an FrameProcessor to
|
||||
// processEndpointDisconnection() while the caller of DiscardEndpoint() is
|
||||
// blocked here.
|
||||
void DiscardEndpoint(ClientProxy* client, const std::string& endpoint_id);
|
||||
void DiscardEndpoint(ClientProxy* client, const std::string& endpoint_id,
|
||||
DisconnectionReason reason);
|
||||
|
||||
protected:
|
||||
// For unit tests only to control executing tasks on the executor.
|
||||
@@ -189,7 +192,7 @@ class EndpointManager {
|
||||
|
||||
void StartEndpointReader(Runnable&& runnable);
|
||||
void StartEndpointKeepAliveManager(
|
||||
std::function<void(Mutex*, ConditionVariable*)> runnable);
|
||||
absl::AnyInvocable<void(Mutex*, ConditionVariable*)> runnable);
|
||||
|
||||
private:
|
||||
const std::string endpoint_id_;
|
||||
@@ -245,7 +248,7 @@ class EndpointManager {
|
||||
void EndpointChannelLoopRunnable(
|
||||
const std::string& runnable_name, ClientProxy* client_proxy,
|
||||
const std::string& endpoint_id,
|
||||
std::function<ExceptionOr<bool>(EndpointChannel*)> handler);
|
||||
absl::AnyInvocable<ExceptionOr<bool>(EndpointChannel*)> handler);
|
||||
|
||||
static void WaitForLatch(const std::string& method_name,
|
||||
CountDownLatch* latch);
|
||||
@@ -259,15 +262,21 @@ class EndpointManager {
|
||||
// this method is idempotent.
|
||||
// @EndpointManagerThread
|
||||
void RemoveEndpoint(ClientProxy* client, const std::string& endpoint_id,
|
||||
bool notify);
|
||||
|
||||
bool notify, DisconnectionReason reason);
|
||||
bool ApplySafeToDisconnect(const std::string& endpoint_id,
|
||||
EndpointChannel* endpoint_channel,
|
||||
DisconnectionReason reason);
|
||||
void WaitForEndpointDisconnectionProcessing(ClientProxy* client,
|
||||
const std::string& service_id,
|
||||
const std::string& endpoint_id);
|
||||
|
||||
const std::string& endpoint_id,
|
||||
DisconnectionReason reason);
|
||||
void ProcessDisconnectionFrame(
|
||||
ClientProxy* client, const std::string& endpoint_id,
|
||||
EndpointChannel* endpoint_channel,
|
||||
location::nearby::connections::OfflineFrame& frame);
|
||||
CountDownLatch NotifyFrameProcessorsOnEndpointDisconnect(
|
||||
ClientProxy* client, const std::string& service_id,
|
||||
const std::string& endpoint_id);
|
||||
const std::string& endpoint_id, DisconnectionReason reason);
|
||||
|
||||
std::vector<std::string> SendTransferFrameBytes(
|
||||
const std::vector<std::string>& endpoint_ids,
|
||||
|
||||
@@ -29,10 +29,13 @@
|
||||
#include "connections/connection_options.h"
|
||||
#include "connections/implementation/client_proxy.h"
|
||||
#include "connections/implementation/endpoint_channel_manager.h"
|
||||
#include "connections/implementation/flags/nearby_connections_feature_flags.h"
|
||||
#include "connections/implementation/offline_frames.h"
|
||||
#include "internal/flags/nearby_flags.h"
|
||||
#include "internal/platform/byte_array.h"
|
||||
#include "internal/platform/count_down_latch.h"
|
||||
#include "internal/platform/exception.h"
|
||||
// #include "internal/platform/feature_flags.h"
|
||||
#include "internal/platform/logging.h"
|
||||
#include "internal/test/fake_single_thread_executor.h"
|
||||
#include "proto/connections_enums.pb.h"
|
||||
@@ -112,10 +115,21 @@ class MockFrameProcessor : public EndpointManager::FrameProcessor {
|
||||
|
||||
MOCK_METHOD(void, OnEndpointDisconnect,
|
||||
(ClientProxy * client, const std::string& service_id,
|
||||
const std::string& endpoint_id, CountDownLatch barrier),
|
||||
const std::string& endpoint_id, CountDownLatch barrier,
|
||||
DisconnectionReason reason),
|
||||
(override));
|
||||
};
|
||||
|
||||
class SetSafeToDisconnect {
|
||||
public:
|
||||
explicit SetSafeToDisconnect(bool safe_to_disconnect) {
|
||||
NearbyFlags::GetInstance().OverrideBoolFlagValue(
|
||||
config_package_nearby::nearby_connections_feature::
|
||||
kEnableSafeToDisconnect,
|
||||
safe_to_disconnect);
|
||||
}
|
||||
};
|
||||
|
||||
class TestEndpointManager : public EndpointManager {
|
||||
public:
|
||||
TestEndpointManager(EndpointChannelManager* manager,
|
||||
@@ -146,7 +160,7 @@ class EndpointManagerTest : public ::testing::Test {
|
||||
EXPECT_TRUE(done.Await(absl::Milliseconds(1000)).result());
|
||||
}
|
||||
}
|
||||
|
||||
SetSafeToDisconnect set_safe_to_disconnect_{true};
|
||||
std::unique_ptr<ClientProxy> client_ = std::make_unique<ClientProxy>();
|
||||
ConnectionOptions connection_options_{
|
||||
.keep_alive_interval_millis = 5000,
|
||||
@@ -199,9 +213,9 @@ TEST_F(EndpointManagerTest, RegisterEndpointCallsOnConnectionInitiated) {
|
||||
}
|
||||
|
||||
TEST_F(EndpointManagerTest, UnregisterEndpointCallsOnDisconnected) {
|
||||
auto endpoint_channel = std::make_unique<MockEndpointChannel>();
|
||||
EXPECT_CALL(*endpoint_channel, Read())
|
||||
.WillRepeatedly(Return(ExceptionOr<ByteArray>(Exception::kIo)));
|
||||
// auto endpoint_channel = std::make_unique<MockEndpointChannel>();
|
||||
// EXPECT_CALL(*endpoint_channel, Read())
|
||||
// .WillRepeatedly(Return(ExceptionOr<ByteArray>(Exception::kIo)));
|
||||
RegisterEndpoint(std::make_unique<MockEndpointChannel>());
|
||||
// NOTE: disconnect_cb is not called, because we did not reach fully connected
|
||||
// state. On top of that, UnregisterEndpoint is suppressing this notification.
|
||||
@@ -211,6 +225,19 @@ TEST_F(EndpointManagerTest, UnregisterEndpointCallsOnDisconnected) {
|
||||
em_.UnregisterEndpoint(client_.get(), endpoint_id_);
|
||||
}
|
||||
|
||||
TEST_F(EndpointManagerTest,
|
||||
UnregisterEndpointCallsOnDisconnectedSafeToDisconnect) {
|
||||
RegisterEndpoint(std::make_unique<MockEndpointChannel>());
|
||||
// NOTE: disconnect_cb is not called, because we did not reach fully connected
|
||||
// state. On top of that, UnregisterEndpoint is suppressing this notification.
|
||||
// (IMO, it should be called as long as any connection callback was called
|
||||
// before. (in this case initiated_cb is called)).
|
||||
// Test captures current protocol behavior.
|
||||
client_->SetRemoteSafeToDisconnectVersion(endpoint_id_, 2);
|
||||
ecm_.UpdateSafeToDisconnectForEndpoint(endpoint_id_, true);
|
||||
em_.UnregisterEndpoint(client_.get(), endpoint_id_);
|
||||
}
|
||||
|
||||
TEST_F(EndpointManagerTest, RegisterFrameProcessorWorks) {
|
||||
auto endpoint_channel = std::make_unique<MockEndpointChannel>();
|
||||
auto connect_request = std::make_unique<MockFrameProcessor>();
|
||||
@@ -434,7 +461,8 @@ TEST_F(EndpointManagerTest, DisconnectEndpointDuringDestruction) {
|
||||
// immediately.
|
||||
fake_serial_executor->SetRunExecutablesImmediately(
|
||||
/*run_executables_immediately=*/false);
|
||||
endpoint_manager->DiscardEndpoint(client_.get(), endpoint_id_);
|
||||
endpoint_manager->DiscardEndpoint(client_.get(), endpoint_id_,
|
||||
DisconnectionReason::IO_ERROR);
|
||||
|
||||
// Simulate Core destruction of ClientProxy by destroying `client_`.
|
||||
client_.reset();
|
||||
|
||||
@@ -47,7 +47,7 @@ class FakeBwuHandler : public BaseBwuHandler {
|
||||
};
|
||||
|
||||
explicit FakeBwuHandler(Medium medium)
|
||||
: BaseBwuHandler(BwuNotifications{}), medium_(medium) {}
|
||||
: BaseBwuHandler(nullptr), medium_(medium) {}
|
||||
~FakeBwuHandler() override = default;
|
||||
|
||||
const std::vector<InputData>& create_calls() const { return create_calls_; }
|
||||
|
||||
@@ -15,6 +15,7 @@
|
||||
#ifndef THIRD_PARTY_NEARBY_CONNECTIONS_IMPLEMENTATION_FLAGS_NEARBY_CONNECTIONS_FEATURE_FLAGS_H_
|
||||
#define THIRD_PARTY_NEARBY_CONNECTIONS_IMPLEMENTATION_FLAGS_NEARBY_CONNECTIONS_FEATURE_FLAGS_H_
|
||||
|
||||
#include <cstdint>
|
||||
#include "absl/strings/string_view.h"
|
||||
#include "internal/flags/flag.h"
|
||||
|
||||
@@ -27,7 +28,6 @@ constexpr absl::string_view kConfigPackage = "nearby";
|
||||
// The Nearby Connections features.
|
||||
namespace nearby_connections_feature {
|
||||
|
||||
// LINT.IfChanged
|
||||
// Disable/Enable BLE v2 in Nearby Connections SDK.
|
||||
constexpr auto kEnableBleV2 =
|
||||
flags::Flag<bool>(kConfigPackage, "45401515", false);
|
||||
@@ -44,11 +44,18 @@ constexpr auto kEnableGattQueryInThread =
|
||||
constexpr auto kEnablePayloadManagerToSkipChunkUpdate =
|
||||
flags::Flag<bool>(kConfigPackage, "45415729", false);
|
||||
|
||||
// LINT.ThenChange(
|
||||
// //depot/google3/location/nearby/cpp/sharing/clients/cpp/nearby_sharing_service_adapter_dart.h,
|
||||
// //depot/google3/location/nearby/cpp/sharing/clients/cpp/nearby_sharing_service_adapter_dart.cc,
|
||||
// //depot/google3/location/nearby/cpp/sharing/clients/dart/platform/lib/types/models.dart
|
||||
// )
|
||||
// Enable/Disable safe-to-disconnect feature.
|
||||
constexpr auto kEnableSafeToDisconnect =
|
||||
flags::Flag<bool>(kConfigPackage, "45425789", false);
|
||||
|
||||
// When true, allows to enable payload-received-ack protocol.
|
||||
constexpr auto kEnablePayloadReceivedAck =
|
||||
flags::Flag<bool>(kConfigPackage, "45425840", false);
|
||||
|
||||
// Support 1. safe-to-disconnect 2. reserved 3. auto-reconnect
|
||||
// 4. auto-resume for dev device 5. payload_ack
|
||||
constexpr auto kSafeToDisconnectVersion =
|
||||
flags::Flag<int64_t>(kConfigPackage, "45425841", 2);
|
||||
|
||||
} // namespace nearby_connections_feature
|
||||
} // namespace config_package_nearby
|
||||
|
||||
@@ -23,6 +23,7 @@ cc_fuzz_target(
|
||||
deps = [
|
||||
"//connections/implementation:internal",
|
||||
"//internal/platform:base",
|
||||
"//internal/platform/implementation/g3",
|
||||
"//security/fuzzing/blaze:default_init_google_for_cc_fuzz_target",
|
||||
],
|
||||
)
|
||||
|
||||
@@ -14,24 +14,25 @@
|
||||
|
||||
#include "connections/implementation/internal_payload_factory.h"
|
||||
|
||||
#include <cstddef>
|
||||
#include <cstdint>
|
||||
#include <memory>
|
||||
#include <string>
|
||||
#include <utility>
|
||||
|
||||
#include "absl/memory/memory.h"
|
||||
#include "connections/implementation/offline_frames_validator.h"
|
||||
#include "absl/strings/str_cat.h"
|
||||
#include "connections/implementation/internal_payload.h"
|
||||
#include "connections/implementation/proto/offline_wire_formats.pb.h"
|
||||
#include "connections/payload.h"
|
||||
#include "connections/payload_type.h"
|
||||
#include "internal/platform/byte_array.h"
|
||||
#include "internal/platform/condition_variable.h"
|
||||
#include "internal/platform/exception.h"
|
||||
#include "internal/platform/feature_flags.h"
|
||||
#include "internal/platform/file.h"
|
||||
#include "internal/platform/implementation/platform.h"
|
||||
#include "internal/platform/implementation/shared/file.h"
|
||||
#include "internal/platform/input_stream.h"
|
||||
#include "internal/platform/logging.h"
|
||||
#include "internal/platform/mutex.h"
|
||||
#include "internal/platform/os_name.h"
|
||||
#include "internal/platform/output_stream.h"
|
||||
#include "internal/platform/pipe.h"
|
||||
|
||||
namespace nearby {
|
||||
@@ -155,8 +156,9 @@ class OutgoingStreamInternalPayload : public InternalPayload {
|
||||
|
||||
class IncomingStreamInternalPayload : public InternalPayload {
|
||||
public:
|
||||
IncomingStreamInternalPayload(Payload payload, std::shared_ptr<Pipe> pipe)
|
||||
: InternalPayload(std::move(payload)), pipe_(pipe) {}
|
||||
IncomingStreamInternalPayload(Payload payload,
|
||||
std::unique_ptr<OutputStream> output)
|
||||
: InternalPayload(std::move(payload)), output_(std::move(output)) {}
|
||||
|
||||
PayloadTransferFrame::PayloadHeader::PayloadType GetType() const override {
|
||||
return PayloadTransferFrame::PayloadHeader::STREAM;
|
||||
@@ -174,7 +176,7 @@ class IncomingStreamInternalPayload : public InternalPayload {
|
||||
return {Exception::kSuccess};
|
||||
}
|
||||
|
||||
return pipe_->GetOutputStream().Write(chunk);
|
||||
return output_->Write(chunk);
|
||||
}
|
||||
|
||||
ExceptionOr<size_t> SkipToOffset(size_t offset) override {
|
||||
@@ -183,10 +185,10 @@ class IncomingStreamInternalPayload : public InternalPayload {
|
||||
return {Exception::kIo};
|
||||
}
|
||||
|
||||
void Close() override { pipe_->GetOutputStream().Close(); }
|
||||
void Close() override { output_->Close(); }
|
||||
|
||||
private:
|
||||
std::shared_ptr<Pipe> pipe_;
|
||||
std::unique_ptr<OutputStream> output_;
|
||||
};
|
||||
|
||||
class OutgoingFileInternalPayload : public InternalPayload {
|
||||
@@ -311,14 +313,14 @@ std::unique_ptr<InternalPayload> CreateOutgoingInternalPayload(
|
||||
Payload payload) {
|
||||
switch (payload.GetType()) {
|
||||
case PayloadType::kBytes:
|
||||
return absl::make_unique<BytesInternalPayload>(std::move(payload));
|
||||
return std::make_unique<BytesInternalPayload>(std::move(payload));
|
||||
|
||||
case PayloadType::kFile: {
|
||||
return absl::make_unique<OutgoingFileInternalPayload>(std::move(payload));
|
||||
return std::make_unique<OutgoingFileInternalPayload>(std::move(payload));
|
||||
}
|
||||
|
||||
case PayloadType::kStream:
|
||||
return absl::make_unique<OutgoingStreamInternalPayload>(
|
||||
return std::make_unique<OutgoingStreamInternalPayload>(
|
||||
std::move(payload));
|
||||
|
||||
default:
|
||||
@@ -359,19 +361,15 @@ std::unique_ptr<InternalPayload> CreateIncomingInternalPayload(
|
||||
const Payload::Id payload_id = frame.payload_header().id();
|
||||
switch (frame.payload_header().type()) {
|
||||
case PayloadTransferFrame::PayloadHeader::BYTES: {
|
||||
return absl::make_unique<BytesInternalPayload>(
|
||||
return std::make_unique<BytesInternalPayload>(
|
||||
Payload(payload_id, ByteArray(frame.payload_chunk().body())));
|
||||
}
|
||||
|
||||
case PayloadTransferFrame::PayloadHeader::STREAM: {
|
||||
auto pipe = std::make_shared<Pipe>();
|
||||
auto [input, output] = CreatePipe();
|
||||
|
||||
return absl::make_unique<IncomingStreamInternalPayload>(
|
||||
Payload(payload_id,
|
||||
[pipe]() -> InputStream& {
|
||||
return pipe->GetInputStream(); // NOLINT
|
||||
}),
|
||||
pipe);
|
||||
return std::make_unique<IncomingStreamInternalPayload>(
|
||||
Payload(payload_id, std::move(input)), std::move(output));
|
||||
}
|
||||
|
||||
case PayloadTransferFrame::PayloadHeader::FILE: {
|
||||
@@ -411,11 +409,11 @@ std::unique_ptr<InternalPayload> CreateIncomingInternalPayload(
|
||||
// there will be no input file to open.
|
||||
// On Chrome the file path should be empty, so use the payload id.
|
||||
if (ImplementationPlatform::GetCurrentOS() == OSName::kChromeOS) {
|
||||
return absl::make_unique<IncomingFileInternalPayload>(
|
||||
return std::make_unique<IncomingFileInternalPayload>(
|
||||
Payload(payload_id, InputFile(payload_id, total_size)),
|
||||
OutputFile(payload_id), total_size);
|
||||
} else {
|
||||
return absl::make_unique<IncomingFileInternalPayload>(
|
||||
return std::make_unique<IncomingFileInternalPayload>(
|
||||
Payload(payload_id, parent_folder, file_name,
|
||||
InputFile(file_path, total_size)),
|
||||
OutputFile(file_path), total_size);
|
||||
|
||||
@@ -14,15 +14,19 @@
|
||||
|
||||
#include "connections/implementation/internal_payload_factory.h"
|
||||
|
||||
#include <cstdint>
|
||||
#include <memory>
|
||||
#include <string>
|
||||
#include <utility>
|
||||
|
||||
#include "gmock/gmock.h"
|
||||
#include "protobuf-matchers/protocol-buffer-matchers.h"
|
||||
#include "gtest/gtest.h"
|
||||
#include "connections/implementation/offline_frames.h"
|
||||
#include "connections/implementation/internal_payload.h"
|
||||
#include "connections/implementation/proto/offline_wire_formats.pb.h"
|
||||
#include "connections/payload.h"
|
||||
#include "connections/payload_type.h"
|
||||
#include "internal/platform/byte_array.h"
|
||||
#include "internal/platform/exception.h"
|
||||
#include "internal/platform/file.h"
|
||||
#include "internal/platform/pipe.h"
|
||||
|
||||
namespace nearby {
|
||||
@@ -44,11 +48,9 @@ TEST(InternalPayloadFactoryTest, CanCreateInternalPayloadFromBytePayload) {
|
||||
}
|
||||
|
||||
TEST(InternalPayloadFactoryTest, CanCreateInternalPayloadFromStreamPayload) {
|
||||
auto pipe = std::make_shared<Pipe>();
|
||||
auto [input, output] = CreatePipe();
|
||||
std::unique_ptr<InternalPayload> internal_payload =
|
||||
CreateOutgoingInternalPayload(Payload{[pipe]() -> InputStream& {
|
||||
return pipe->GetInputStream(); // NOLINT
|
||||
}});
|
||||
CreateOutgoingInternalPayload(Payload(std::move(input)));
|
||||
EXPECT_NE(internal_payload, nullptr);
|
||||
Payload payload = internal_payload->ReleasePayload();
|
||||
EXPECT_EQ(payload.AsFile(), nullptr);
|
||||
@@ -212,13 +214,11 @@ TEST(InternalPayloadFactoryTest,
|
||||
SkipToOffset_StreamPayloadValidOffset_SkipsOffset) {
|
||||
ByteArray contents("0123456789");
|
||||
constexpr size_t kOffset = 6;
|
||||
auto pipe = std::make_shared<Pipe>();
|
||||
auto [input, output] = CreatePipe();
|
||||
std::unique_ptr<InternalPayload> internal_payload =
|
||||
CreateOutgoingInternalPayload(Payload{[pipe]() -> InputStream& {
|
||||
return pipe->GetInputStream(); // NOLINT
|
||||
}});
|
||||
CreateOutgoingInternalPayload(Payload(std::move(input)));
|
||||
EXPECT_NE(internal_payload, nullptr);
|
||||
pipe->GetOutputStream().Write(contents);
|
||||
output->Write(contents);
|
||||
|
||||
ExceptionOr<size_t> result = internal_payload->SkipToOffset(kOffset);
|
||||
|
||||
|
||||
@@ -55,7 +55,6 @@ cc_library(
|
||||
"//internal/platform:base",
|
||||
"//internal/platform:cancellation_flag",
|
||||
"//internal/platform:comm",
|
||||
"//internal/platform:logging",
|
||||
"//internal/platform:types",
|
||||
"//internal/platform:uuid",
|
||||
"//proto/mediums:web_rtc_signaling_frames_cc_proto",
|
||||
@@ -63,6 +62,7 @@ cc_library(
|
||||
"@com_google_absl//absl/container:btree",
|
||||
"@com_google_absl//absl/container:flat_hash_map",
|
||||
"@com_google_absl//absl/container:flat_hash_set",
|
||||
"@com_google_absl//absl/functional:any_invocable",
|
||||
"@com_google_absl//absl/functional:bind_front",
|
||||
"@com_google_absl//absl/strings",
|
||||
"@com_google_absl//absl/strings:str_format",
|
||||
|
||||
@@ -72,11 +72,7 @@ TEST_P(BleTest, CanStartAcceptingConnectionsAndConnect) {
|
||||
fast_advertisement_service_uuid);
|
||||
ble_a.StartAcceptingConnections(
|
||||
service_id,
|
||||
{
|
||||
.accepted_cb = [&accept_latch](
|
||||
BleSocket socket,
|
||||
const std::string&) { accept_latch.CountDown(); },
|
||||
});
|
||||
[&](BleSocket socket, const std::string&) { accept_latch.CountDown(); });
|
||||
BlePeripheral discovered_peripheral;
|
||||
ble_b.StartScanning(
|
||||
service_id, fast_advertisement_service_uuid,
|
||||
@@ -126,11 +122,7 @@ TEST_P(BleTest, CanCancelConnect) {
|
||||
fast_advertisement_service_uuid);
|
||||
ble_a.StartAcceptingConnections(
|
||||
service_id,
|
||||
{
|
||||
.accepted_cb = [&accept_latch](
|
||||
BleSocket socket,
|
||||
const std::string&) { accept_latch.CountDown(); },
|
||||
});
|
||||
[&](BleSocket socket, const std::string&) { accept_latch.CountDown(); });
|
||||
BlePeripheral discovered_peripheral;
|
||||
ble_b.StartScanning(
|
||||
service_id, fast_advertisement_service_uuid,
|
||||
|
||||
@@ -417,7 +417,9 @@ bool BleV2::StartAcceptingConnections(const std::string& service_id,
|
||||
});
|
||||
incoming_sockets_.insert({service_id, client_socket});
|
||||
}
|
||||
callback.accepted_cb(std::move(client_socket), service_id);
|
||||
if (callback) {
|
||||
callback(std::move(client_socket), service_id);
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
|
||||
@@ -48,10 +48,8 @@ class BleV2 final {
|
||||
using DiscoveredPeripheralCallback = mediums::DiscoveredPeripheralCallback;
|
||||
|
||||
// Callback that is invoked when a new connection is accepted.
|
||||
struct AcceptedConnectionCallback {
|
||||
absl::AnyInvocable<void(BleV2Socket socket, const std::string& service_id)>
|
||||
accepted_cb = DefaultCallback<BleV2Socket, const std::string&>();
|
||||
};
|
||||
using AcceptedConnectionCallback = absl::AnyInvocable<void(
|
||||
BleV2Socket socket, const std::string& service_id)>;
|
||||
|
||||
explicit BleV2(BluetoothRadio& bluetooth_radio);
|
||||
~BleV2();
|
||||
|
||||
@@ -45,12 +45,12 @@ cc_library(
|
||||
"//internal/flags:nearby_flags",
|
||||
"//internal/platform:base",
|
||||
"//internal/platform:comm",
|
||||
"//internal/platform:logging",
|
||||
"//internal/platform:types",
|
||||
"//internal/platform:util",
|
||||
"//internal/platform:uuid",
|
||||
"//proto/mediums:ble_frames_cc_proto",
|
||||
"@aappleby_smhasher//:libmurmur3",
|
||||
"@com_google_absl//absl/base:core_headers",
|
||||
"@com_google_absl//absl/container:flat_hash_map",
|
||||
"@com_google_absl//absl/container:flat_hash_set",
|
||||
"@com_google_absl//absl/numeric:int128",
|
||||
|
||||
@@ -30,6 +30,7 @@
|
||||
#include "connections/implementation/mediums/ble_v2/bloom_filter.h"
|
||||
#include "internal/flags/nearby_flags.h"
|
||||
#include "internal/platform/ble_v2.h"
|
||||
#include "internal/platform/byte_array.h"
|
||||
#include "internal/platform/logging.h"
|
||||
#include "internal/platform/multi_thread_executor.h"
|
||||
#include "internal/platform/mutex_lock.h"
|
||||
@@ -521,13 +522,35 @@ void DiscoveredPeripheralTracker::HandleAdvertisementHeader(
|
||||
<< absl::BytesToHexString(
|
||||
ByteArray(advertisement_header).data())
|
||||
<< " in thread";
|
||||
ByteArray advertisement_data{advertisement_header};
|
||||
if (fetching_advertisements_.contains(advertisement_data)) {
|
||||
NEARBY_LOGS(VERBOSE) << ": Ignore the advertisement header due to it "
|
||||
"is already in fetcing.";
|
||||
return;
|
||||
}
|
||||
|
||||
fetching_advertisements_.insert(advertisement_data);
|
||||
|
||||
if (executor_ == nullptr) {
|
||||
// The situation happens when flag value changed
|
||||
executor_ = std::make_unique<MultiThreadExecutor>(kGattThreadCount);
|
||||
}
|
||||
executor_->Execute([this, peripheral, advertisement_header,
|
||||
advertisement_fetcher =
|
||||
std::move(advertisement_fetcher)]() {
|
||||
std::move(advertisement_fetcher),
|
||||
advertisement_data =
|
||||
std::move(advertisement_data)]() {
|
||||
{
|
||||
MutexLock lock(&mutex_);
|
||||
if (!IsInterestingAdvertisementHeader(advertisement_header)) {
|
||||
NEARBY_LOGS(INFO)
|
||||
<< ": Ignore to read raw advertisement from server due to it "
|
||||
"is not interesting header now.";
|
||||
fetching_advertisements_.erase(advertisement_data);
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
std::vector<const ByteArray*> gatt_advertisement_bytes_list =
|
||||
FetchRawAdvertisementsInThread(peripheral, advertisement_header,
|
||||
std::move(advertisement_fetcher));
|
||||
@@ -537,6 +560,7 @@ void DiscoveredPeripheralTracker::HandleAdvertisementHeader(
|
||||
gatt_advertisement_bytes_list,
|
||||
/*service_uuid=*/{});
|
||||
UpdateCommonStateForFoundBleAdvertisement(advertisement_header);
|
||||
fetching_advertisements_.erase(advertisement_data);
|
||||
NEARBY_LOGS(VERBOSE)
|
||||
<< ": Completed to handle GATT advertisement "
|
||||
<< absl::BytesToHexString(ByteArray(advertisement_header).data())
|
||||
|
||||
@@ -20,6 +20,9 @@
|
||||
#include <string>
|
||||
#include <vector>
|
||||
|
||||
#include "absl/base/thread_annotations.h"
|
||||
#include "absl/container/flat_hash_map.h"
|
||||
#include "absl/container/flat_hash_set.h"
|
||||
#include "connections/implementation/mediums//lost_entity_tracker.h"
|
||||
#include "connections/implementation/mediums/ble_v2/advertisement_read_result.h"
|
||||
#include "connections/implementation/mediums/ble_v2/ble_advertisement.h"
|
||||
@@ -289,6 +292,10 @@ class DiscoveredPeripheralTracker {
|
||||
absl::flat_hash_map<BleAdvertisement, GattAdvertisementInfo>
|
||||
gatt_advertisement_infos_ ABSL_GUARDED_BY(mutex_);
|
||||
|
||||
// Tracks the advertisements in GATT fetching.
|
||||
absl::flat_hash_set<ByteArray> fetching_advertisements_
|
||||
ABSL_GUARDED_BY(mutex_);
|
||||
|
||||
std::unique_ptr<MultiThreadExecutor> executor_ ABSL_GUARDED_BY(mutex_) =
|
||||
nullptr;
|
||||
};
|
||||
|
||||
@@ -77,14 +77,10 @@ TEST_P(BleV2Test, CanConnect) {
|
||||
|
||||
BleV2Socket socket_for_server;
|
||||
EXPECT_TRUE(ble_server.StartAcceptingConnections(
|
||||
service_id, {
|
||||
.accepted_cb =
|
||||
[&socket_for_server, &accept_latch](
|
||||
BleV2Socket socket, const std::string&) {
|
||||
socket_for_server = std::move(socket);
|
||||
accept_latch.CountDown();
|
||||
},
|
||||
}));
|
||||
service_id, [&](BleV2Socket socket, const std::string&) {
|
||||
socket_for_server = std::move(socket);
|
||||
accept_latch.CountDown();
|
||||
}));
|
||||
|
||||
ble_server.StartAdvertising(service_id, advertisement_bytes,
|
||||
PowerLevel::kHighPower,
|
||||
@@ -139,14 +135,10 @@ TEST_P(BleV2Test, CanCancelConnect) {
|
||||
|
||||
BleV2Socket socket_for_server;
|
||||
EXPECT_TRUE(ble_server.StartAcceptingConnections(
|
||||
service_id, {
|
||||
.accepted_cb =
|
||||
[&socket_for_server, &accept_latch](
|
||||
BleV2Socket socket, const std::string&) {
|
||||
socket_for_server = std::move(socket);
|
||||
accept_latch.CountDown();
|
||||
},
|
||||
}));
|
||||
service_id, [&](BleV2Socket socket, const std::string&) {
|
||||
socket_for_server = std::move(socket);
|
||||
accept_latch.CountDown();
|
||||
}));
|
||||
|
||||
ble_server.StartAdvertising(service_id, advertisement_bytes,
|
||||
PowerLevel::kHighPower,
|
||||
|
||||
@@ -298,8 +298,9 @@ bool BluetoothClassic::StartAcceptingConnections(
|
||||
server_socket.Close();
|
||||
break;
|
||||
}
|
||||
|
||||
callback.accepted_cb(service_id, std::move(client_socket));
|
||||
if (callback) {
|
||||
callback(service_id, std::move(client_socket));
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
|
||||
@@ -17,9 +17,9 @@
|
||||
|
||||
#include <cstdint>
|
||||
#include <functional>
|
||||
#include <string>
|
||||
#include <memory>
|
||||
#include <map>
|
||||
#include <memory>
|
||||
#include <string>
|
||||
|
||||
#include "absl/container/flat_hash_map.h"
|
||||
#include "connections/implementation/mediums/bluetooth_radio.h"
|
||||
@@ -40,10 +40,8 @@ class BluetoothClassic {
|
||||
using ScanMode = BluetoothAdapter::ScanMode;
|
||||
|
||||
// Callback that is invoked when a new connection is accepted.
|
||||
struct AcceptedConnectionCallback {
|
||||
std::function<void(const std::string& service_id, BluetoothSocket socket)>
|
||||
accepted_cb = [](const std::string&, BluetoothSocket) {};
|
||||
};
|
||||
using AcceptedConnectionCallback = absl::AnyInvocable<void(
|
||||
const std::string& service_id, BluetoothSocket socket)>;
|
||||
|
||||
explicit BluetoothClassic(BluetoothRadio& radio);
|
||||
~BluetoothClassic();
|
||||
|
||||
@@ -162,13 +162,9 @@ TEST_P(BluetoothClassicTest, CanConnect) {
|
||||
CountDownLatch accept_latch(1);
|
||||
EXPECT_TRUE(bt_server.StartAcceptingConnections(
|
||||
std::string(kServiceName1),
|
||||
{
|
||||
.accepted_cb =
|
||||
[&socket_for_server, &accept_latch](const std::string& service_id,
|
||||
BluetoothSocket socket) {
|
||||
socket_for_server = std::move(socket);
|
||||
accept_latch.CountDown();
|
||||
},
|
||||
[&](const std::string& service_id, BluetoothSocket socket) {
|
||||
socket_for_server = std::move(socket);
|
||||
accept_latch.CountDown();
|
||||
}));
|
||||
CancellationFlag flag;
|
||||
BluetoothSocket socket_for_client =
|
||||
@@ -217,13 +213,9 @@ TEST_P(BluetoothClassicTest, CanCancelBeforeConnect) {
|
||||
CountDownLatch accept_latch(1);
|
||||
EXPECT_TRUE(bt_server.StartAcceptingConnections(
|
||||
std::string(kServiceName1),
|
||||
{
|
||||
.accepted_cb =
|
||||
[&socket_for_server, &accept_latch](const std::string& service_id,
|
||||
BluetoothSocket socket) {
|
||||
socket_for_server = std::move(socket);
|
||||
accept_latch.CountDown();
|
||||
},
|
||||
[&](const std::string& service_id, BluetoothSocket socket) {
|
||||
socket_for_server = std::move(socket);
|
||||
accept_latch.CountDown();
|
||||
}));
|
||||
CancellationFlag flag(true);
|
||||
BluetoothSocket socket_for_client =
|
||||
@@ -288,13 +280,9 @@ TEST_P(BluetoothClassicTest, CanCancelDuringConnect) {
|
||||
CountDownLatch accept_latch(1);
|
||||
EXPECT_TRUE(bt_server.StartAcceptingConnections(
|
||||
std::string(kServiceName1),
|
||||
{
|
||||
.accepted_cb =
|
||||
[&socket_for_server, &accept_latch](const std::string& service_id,
|
||||
BluetoothSocket socket) {
|
||||
socket_for_server = std::move(socket);
|
||||
accept_latch.CountDown();
|
||||
},
|
||||
[&](const std::string& service_id, BluetoothSocket socket) {
|
||||
socket_for_server = std::move(socket);
|
||||
accept_latch.CountDown();
|
||||
}));
|
||||
CancellationFlag flag;
|
||||
BluetoothSocket socket_for_client =
|
||||
@@ -361,13 +349,9 @@ TEST_P(BluetoothClassicTest, CanCancelDuringConnect_MultipleEndpoints) {
|
||||
|
||||
EXPECT_TRUE(bt_server.StartAcceptingConnections(
|
||||
std::string(kServiceName1),
|
||||
{
|
||||
.accepted_cb =
|
||||
[&socket_for_server1, &accept_latch](
|
||||
const std::string& service_id, BluetoothSocket socket) {
|
||||
socket_for_server1 = std::move(socket);
|
||||
accept_latch.CountDown();
|
||||
},
|
||||
[&](const std::string& service_id, BluetoothSocket socket) {
|
||||
socket_for_server1 = std::move(socket);
|
||||
accept_latch.CountDown();
|
||||
}));
|
||||
CancellationFlag flag;
|
||||
BluetoothSocket socket_for_client1 =
|
||||
@@ -378,13 +362,9 @@ TEST_P(BluetoothClassicTest, CanCancelDuringConnect_MultipleEndpoints) {
|
||||
medium_a_->CancelDuringConnectToService();
|
||||
EXPECT_TRUE(bt_server.StartAcceptingConnections(
|
||||
std::string(kServiceName2),
|
||||
{
|
||||
.accepted_cb =
|
||||
[&socket_for_server2, &accept_latch](
|
||||
const std::string& service_id, BluetoothSocket socket) {
|
||||
socket_for_server2 = std::move(socket);
|
||||
accept_latch.CountDown();
|
||||
},
|
||||
[&](const std::string& service_id, BluetoothSocket socket) {
|
||||
socket_for_server2 = std::move(socket);
|
||||
accept_latch.CountDown();
|
||||
}));
|
||||
|
||||
BluetoothSocket socket_for_client2 =
|
||||
|
||||
@@ -107,7 +107,7 @@ bool WebRtc::StartAcceptingConnections(const std::string& service_id,
|
||||
// who may be also using WebRTC.
|
||||
AcceptingConnectionsInfo info = AcceptingConnectionsInfo();
|
||||
info.self_peer_id = self_peer_id;
|
||||
info.accepted_connection_callback = callback;
|
||||
info.accepted_connection_callback = std::move(callback);
|
||||
|
||||
// Create a new SignalingMessenger so that we can communicate w/ Tachyon.
|
||||
info.signaling_messenger =
|
||||
@@ -688,8 +688,9 @@ void WebRtc::ProcessDataChannelOpen(const std::string& service_id,
|
||||
|
||||
const auto& accepting_connection_entry =
|
||||
accepting_connections_info_.find(service_id);
|
||||
if (accepting_connection_entry != accepting_connections_info_.end()) {
|
||||
accepting_connection_entry->second.accepted_connection_callback.accepted_cb(
|
||||
if (accepting_connection_entry != accepting_connections_info_.end() &&
|
||||
accepting_connection_entry->second.accepted_connection_callback) {
|
||||
accepting_connection_entry->second.accepted_connection_callback(
|
||||
service_id, socket_wrapper);
|
||||
return;
|
||||
}
|
||||
|
||||
@@ -17,13 +17,12 @@
|
||||
|
||||
#ifndef NO_WEBRTC
|
||||
|
||||
#include <cstddef>
|
||||
#include <functional>
|
||||
#include <map>
|
||||
#include <memory>
|
||||
#include <string>
|
||||
|
||||
#include "absl/container/flat_hash_map.h"
|
||||
#include "absl/functional/any_invocable.h"
|
||||
#include "connections/implementation/mediums/webrtc/connection_flow.h"
|
||||
#include "connections/implementation/mediums/webrtc_peer_id.h"
|
||||
#include "connections/implementation/mediums/webrtc_socket.h"
|
||||
@@ -42,15 +41,13 @@ namespace nearby {
|
||||
namespace connections {
|
||||
namespace mediums {
|
||||
|
||||
// Callback that is invoked when a new connection is accepted.
|
||||
struct AcceptedConnectionCallback {
|
||||
std::function<void(const std::string& service_id, WebRtcSocketWrapper socket)>
|
||||
accepted_cb = [](const std::string&, WebRtcSocketWrapper) {};
|
||||
};
|
||||
|
||||
// Entry point for connecting a data channel between two devices via WebRtc.
|
||||
class WebRtc {
|
||||
public:
|
||||
// Callback that is invoked when a new connection is accepted.
|
||||
using AcceptedConnectionCallback = absl::AnyInvocable<void(
|
||||
const std::string& service_id, WebRtcSocketWrapper socket)>;
|
||||
|
||||
WebRtc();
|
||||
~WebRtc();
|
||||
|
||||
|
||||
@@ -39,7 +39,6 @@ cc_library(
|
||||
"//connections/implementation/mediums:utils",
|
||||
"//internal/platform:base",
|
||||
"//internal/platform:comm",
|
||||
"//internal/platform:logging",
|
||||
"//internal/platform:types",
|
||||
"//proto/mediums:web_rtc_signaling_frames_cc_proto",
|
||||
# TODO: Support WebRTC
|
||||
|
||||
@@ -12,10 +12,18 @@
|
||||
// See the License for the specific language governing permissions and
|
||||
// limitations under the License.
|
||||
|
||||
#include <cstdint>
|
||||
#include <string>
|
||||
#include <tuple>
|
||||
#include <utility>
|
||||
|
||||
#include "internal/platform/byte_array.h"
|
||||
#include "internal/platform/exception.h"
|
||||
#include "internal/platform/input_stream.h"
|
||||
#include "internal/platform/pipe.h"
|
||||
#ifndef NO_WEBRTC
|
||||
|
||||
#include "connections/implementation/mediums/webrtc/webrtc_socket_impl.h"
|
||||
|
||||
#include "internal/platform/logging.h"
|
||||
#include "internal/platform/mutex_lock.h"
|
||||
|
||||
@@ -61,6 +69,7 @@ WebRtcSocket::WebRtcSocket(
|
||||
: name_(name), data_channel_(std::move(data_channel)) {
|
||||
NEARBY_LOGS(INFO) << "WebRtcSocket::WebRtcSocket(" << name_
|
||||
<< ") this: " << this;
|
||||
std::tie(pipe_input_, pipe_output_) = CreatePipe();
|
||||
data_channel_->RegisterObserver(this);
|
||||
}
|
||||
|
||||
@@ -77,7 +86,7 @@ WebRtcSocket::~WebRtcSocket() {
|
||||
<< ") this: " << this << " done";
|
||||
}
|
||||
|
||||
InputStream& WebRtcSocket::GetInputStream() { return pipe_.GetInputStream(); }
|
||||
InputStream& WebRtcSocket::GetInputStream() { return *pipe_input_; }
|
||||
|
||||
OutputStream& WebRtcSocket::GetOutputStream() { return output_stream_; }
|
||||
|
||||
@@ -129,12 +138,12 @@ void WebRtcSocket::OnMessage(const webrtc::DataBuffer& buffer) {
|
||||
// we don't block signaling.
|
||||
OffloadFromSignalingThread(
|
||||
[this, buffer = ByteArray(buffer.data.data<char>(), buffer.size())] {
|
||||
if (!pipe_.GetOutputStream().Write(buffer).Ok()) {
|
||||
if (!pipe_output_->Write(buffer).Ok()) {
|
||||
Close();
|
||||
return;
|
||||
}
|
||||
|
||||
if (!pipe_.GetOutputStream().Flush().Ok()) {
|
||||
if (!pipe_output_->Flush().Ok()) {
|
||||
Close();
|
||||
}
|
||||
});
|
||||
@@ -159,8 +168,8 @@ void WebRtcSocket::ClosePipe() {
|
||||
// This is thread-safe to close these sockets even if a read or write is in
|
||||
// process on another thread, Close will wait for the exclusive mutex before
|
||||
// setting state.
|
||||
pipe_.GetInputStream().Close();
|
||||
pipe_.GetOutputStream().Close();
|
||||
pipe_input_->Close();
|
||||
pipe_output_->Close();
|
||||
WakeUpWriter();
|
||||
NEARBY_LOGS(INFO) << "WebRtcSocket::ClosePipe(" << name_ << ") this: " << this
|
||||
<< " done";
|
||||
|
||||
@@ -100,8 +100,8 @@ class WebRtcSocket : public Socket, public webrtc::DataChannelObserver {
|
||||
std::string name_;
|
||||
rtc::scoped_refptr<webrtc::DataChannelInterface> data_channel_;
|
||||
|
||||
Pipe pipe_;
|
||||
|
||||
std::unique_ptr<InputStream> pipe_input_;
|
||||
std::unique_ptr<OutputStream> pipe_output_;
|
||||
OutputStreamImpl output_stream_{this};
|
||||
|
||||
AtomicBoolean closed_{false};
|
||||
|
||||
@@ -31,14 +31,13 @@
|
||||
namespace nearby {
|
||||
namespace connections {
|
||||
namespace mediums {
|
||||
// Callback that is invoked when a new connection is accepted.
|
||||
struct AcceptedConnectionCallback {
|
||||
std::function<void(WebRtcSocketWrapper socket)> accepted_cb =
|
||||
[](WebRtcSocketWrapper) {};
|
||||
};
|
||||
|
||||
// Entry point for connecting a data channel between two devices via WebRtc.
|
||||
class WebRtc {
|
||||
public:
|
||||
// Callback that is invoked when a new connection is accepted.
|
||||
using AcceptedConnectionCallback =
|
||||
absl::AnyInvocable<void(WebRtcSocketWrapper socket)>;
|
||||
WebRtc();
|
||||
~WebRtc();
|
||||
|
||||
|
||||
@@ -80,11 +80,11 @@ TEST_P(WebRtcTest, ConnectBothDevices_ShutdownSignaling_SendData) {
|
||||
|
||||
receiver.StartAcceptingConnections(
|
||||
service_id, self_id, location_hint,
|
||||
{[&receiver_socket, connected](const std::string& service_id,
|
||||
WebRtcSocketWrapper wrapper) mutable {
|
||||
[&receiver_socket, connected](const std::string& service_id,
|
||||
WebRtcSocketWrapper wrapper) mutable {
|
||||
receiver_socket = wrapper;
|
||||
connected.Set(receiver_socket.IsValid());
|
||||
}});
|
||||
});
|
||||
|
||||
CancellationFlag flag;
|
||||
sender_socket = sender.Connect(service_id, self_id, location_hint, &flag);
|
||||
@@ -119,11 +119,11 @@ TEST_P(WebRtcTest, CanCancelConnect) {
|
||||
|
||||
receiver.StartAcceptingConnections(
|
||||
service_id, self_id, location_hint,
|
||||
{[&receiver_socket, connected](const std::string& service_id,
|
||||
WebRtcSocketWrapper wrapper) mutable {
|
||||
[&receiver_socket, connected](const std::string& service_id,
|
||||
WebRtcSocketWrapper wrapper) mutable {
|
||||
receiver_socket = wrapper;
|
||||
connected.Set(receiver_socket.IsValid());
|
||||
}});
|
||||
});
|
||||
|
||||
CancellationFlag flag(true);
|
||||
sender_socket = sender.Connect(service_id, self_id, location_hint, &flag);
|
||||
@@ -173,10 +173,10 @@ TEST_F(WebRtcTest, StartAcceptingConnectionTwice) {
|
||||
ASSERT_TRUE(webrtc.IsAvailable());
|
||||
ASSERT_TRUE(webrtc.StartAcceptingConnections(
|
||||
service_id, self_id, location_hint,
|
||||
{mock_accepted_callback_.AsStdFunction()}));
|
||||
mock_accepted_callback_.AsStdFunction()));
|
||||
EXPECT_FALSE(webrtc.StartAcceptingConnections(
|
||||
service_id, self_id, location_hint,
|
||||
{mock_accepted_callback_.AsStdFunction()}));
|
||||
mock_accepted_callback_.AsStdFunction()));
|
||||
EXPECT_TRUE(webrtc.IsAcceptingConnections(service_id));
|
||||
EXPECT_FALSE(webrtc.IsAcceptingConnections(std::string{}));
|
||||
env_.Stop();
|
||||
@@ -197,8 +197,8 @@ TEST_F(WebRtcTest, Connect_NoPeer) {
|
||||
webrtc.Connect(service_id, peer_id, location_hint, &flag);
|
||||
EXPECT_FALSE(wrapper_1.IsValid());
|
||||
|
||||
EXPECT_TRUE(webrtc.StartAcceptingConnections(
|
||||
service_id, peer_id, location_hint, AcceptedConnectionCallback()));
|
||||
EXPECT_TRUE(webrtc.StartAcceptingConnections(service_id, peer_id,
|
||||
location_hint, nullptr));
|
||||
env_.Stop();
|
||||
}
|
||||
|
||||
@@ -215,7 +215,7 @@ TEST_F(WebRtcTest, StartAcceptingConnection_ThenConnect) {
|
||||
ASSERT_TRUE(webrtc.IsAvailable());
|
||||
ASSERT_TRUE(webrtc.StartAcceptingConnections(
|
||||
service_id, self_id, location_hint,
|
||||
{mock_accepted_callback_.AsStdFunction()}));
|
||||
mock_accepted_callback_.AsStdFunction()));
|
||||
CancellationFlag flag;
|
||||
WebRtcSocketWrapper wrapper = webrtc.Connect(
|
||||
service_id, WebrtcPeerId("random_peer_id"), location_hint, &flag);
|
||||
@@ -223,7 +223,7 @@ TEST_F(WebRtcTest, StartAcceptingConnection_ThenConnect) {
|
||||
EXPECT_FALSE(wrapper.IsValid());
|
||||
EXPECT_FALSE(webrtc.StartAcceptingConnections(
|
||||
service_id, self_id, location_hint,
|
||||
{mock_accepted_callback_.AsStdFunction()}));
|
||||
mock_accepted_callback_.AsStdFunction()));
|
||||
env_.Stop();
|
||||
}
|
||||
|
||||
@@ -240,7 +240,7 @@ TEST_F(WebRtcTest, StartAndStopAcceptingConnections) {
|
||||
ASSERT_TRUE(webrtc.IsAvailable());
|
||||
ASSERT_TRUE(webrtc.StartAcceptingConnections(
|
||||
service_id, self_id, location_hint,
|
||||
{mock_accepted_callback_.AsStdFunction()}));
|
||||
mock_accepted_callback_.AsStdFunction()));
|
||||
EXPECT_TRUE(webrtc.IsAcceptingConnections(service_id));
|
||||
webrtc.StopAcceptingConnections(service_id);
|
||||
EXPECT_FALSE(webrtc.IsAcceptingConnections(service_id));
|
||||
@@ -261,15 +261,15 @@ TEST_F(WebRtcTest, ConnectTwice) {
|
||||
|
||||
receiver.StartAcceptingConnections(
|
||||
service_id, self_id, location_hint,
|
||||
{[&receiver_socket, connected](const std::string& service_id,
|
||||
WebRtcSocketWrapper wrapper) mutable {
|
||||
[&receiver_socket, connected](const std::string& service_id,
|
||||
WebRtcSocketWrapper wrapper) mutable {
|
||||
receiver_socket = wrapper;
|
||||
connected.Set(receiver_socket.IsValid());
|
||||
}});
|
||||
});
|
||||
|
||||
device_c.StartAcceptingConnections(
|
||||
service_id, other_id, location_hint,
|
||||
{[](const std::string& service_id, WebRtcSocketWrapper wrapper) {}});
|
||||
[](const std::string& service_id, WebRtcSocketWrapper wrapper) {});
|
||||
|
||||
CancellationFlag flag;
|
||||
sender_socket = sender.Connect(service_id, self_id, location_hint, &flag);
|
||||
@@ -311,11 +311,11 @@ TEST_F(WebRtcTest, ConnectBothDevicesAndAbort) {
|
||||
|
||||
receiver.StartAcceptingConnections(
|
||||
service_id, self_id, location_hint,
|
||||
{[&receiver_socket, connected](const std::string& service_id,
|
||||
WebRtcSocketWrapper wrapper) mutable {
|
||||
[&receiver_socket, connected](const std::string& service_id,
|
||||
WebRtcSocketWrapper wrapper) mutable {
|
||||
receiver_socket = wrapper;
|
||||
connected.Set(receiver_socket.IsValid());
|
||||
}});
|
||||
});
|
||||
|
||||
CancellationFlag flag;
|
||||
sender_socket = sender.Connect(service_id, self_id, location_hint, &flag);
|
||||
@@ -343,11 +343,11 @@ TEST_F(WebRtcTest, ConnectBothDevicesAndSendData) {
|
||||
|
||||
receiver.StartAcceptingConnections(
|
||||
service_id, self_id, location_hint,
|
||||
{[&receiver_socket, connected](const std::string& service_id,
|
||||
WebRtcSocketWrapper wrapper) mutable {
|
||||
[&receiver_socket, connected](const std::string& service_id,
|
||||
WebRtcSocketWrapper wrapper) mutable {
|
||||
receiver_socket = wrapper;
|
||||
connected.Set(receiver_socket.IsValid());
|
||||
}});
|
||||
});
|
||||
|
||||
CancellationFlag flag;
|
||||
sender_socket = sender.Connect(service_id, self_id, location_hint, &flag);
|
||||
@@ -399,7 +399,7 @@ TEST_F(WebRtcTest, ContinueAcceptingConnectionsOnComplete) {
|
||||
ASSERT_TRUE(webrtc.IsAvailable());
|
||||
ASSERT_TRUE(webrtc.StartAcceptingConnections(
|
||||
service_id, self_id, location_hint,
|
||||
{mock_accepted_callback_.AsStdFunction()}));
|
||||
mock_accepted_callback_.AsStdFunction()));
|
||||
EXPECT_TRUE(webrtc.IsAcceptingConnections(service_id));
|
||||
|
||||
// Simulate a failure in receiving messages stream, WebRtc should restart
|
||||
@@ -450,11 +450,11 @@ TEST_F(WebRtcTest, CancelDuringConnect) {
|
||||
|
||||
receiver->StartAcceptingConnections(
|
||||
service_id, self_id, location_hint,
|
||||
{[&receiver_socket, connected](const std::string& service_id,
|
||||
WebRtcSocketWrapper wrapper) mutable {
|
||||
[&receiver_socket, connected](const std::string& service_id,
|
||||
WebRtcSocketWrapper wrapper) mutable {
|
||||
receiver_socket = wrapper;
|
||||
connected.Set(receiver_socket.IsValid());
|
||||
}});
|
||||
});
|
||||
|
||||
sender_socket =
|
||||
sender->Connect(service_id, self_id, location_hint, &sender_flag);
|
||||
@@ -496,11 +496,11 @@ TEST_F(WebRtcTest, CancelBeforeConnect) {
|
||||
|
||||
receiver->StartAcceptingConnections(
|
||||
service_id, self_id, location_hint,
|
||||
{[&receiver_socket, connected](const std::string& service_id,
|
||||
WebRtcSocketWrapper wrapper) mutable {
|
||||
[&receiver_socket, connected](const std::string& service_id,
|
||||
WebRtcSocketWrapper wrapper) mutable {
|
||||
receiver_socket = wrapper;
|
||||
connected.Set(receiver_socket.IsValid());
|
||||
}});
|
||||
});
|
||||
|
||||
sender_socket =
|
||||
sender->Connect(service_id, self_id, location_hint, &sender_flag);
|
||||
@@ -541,11 +541,11 @@ TEST_F(WebRtcTest, CancelDuringConnect_MultipleConnect) {
|
||||
|
||||
receiver->StartAcceptingConnections(
|
||||
ns_service_id, self_id, location_hint,
|
||||
{[&receiver_socket, connected](const std::string& ns_service_id,
|
||||
WebRtcSocketWrapper wrapper) mutable {
|
||||
[&receiver_socket, connected](const std::string& ns_service_id,
|
||||
WebRtcSocketWrapper wrapper) mutable {
|
||||
receiver_socket = wrapper;
|
||||
connected.Set(receiver_socket.IsValid());
|
||||
}});
|
||||
});
|
||||
|
||||
// Simulate a successful connect for the endpoint of NearbySharing.
|
||||
sender_socket = sender->Connect(ns_service_id, self_id, location_hint, &flag);
|
||||
|
||||
@@ -185,7 +185,9 @@ bool WifiDirect::StartAcceptingConnections(
|
||||
server_socket.Close();
|
||||
break;
|
||||
}
|
||||
callback.accepted_cb(service_id, std::move(client_socket));
|
||||
if (callback) {
|
||||
callback(service_id, std::move(client_socket));
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
|
||||
@@ -29,10 +29,8 @@ namespace connections {
|
||||
class WifiDirect {
|
||||
public:
|
||||
// Callback that is invoked when a new connection is accepted.
|
||||
struct AcceptedConnectionCallback {
|
||||
std::function<void(const std::string& service_id, WifiDirectSocket socket)>
|
||||
accepted_cb = [](const std::string&, WifiDirectSocket) {};
|
||||
};
|
||||
using AcceptedConnectionCallback = absl::AnyInvocable<void(
|
||||
const std::string& service_id, WifiDirectSocket socket)>;
|
||||
|
||||
WifiDirect() : is_go_started_(false), is_connected_to_go_(false) {}
|
||||
~WifiDirect();
|
||||
|
||||
@@ -14,8 +14,8 @@
|
||||
|
||||
#include "connections/implementation/mediums/wifi_hotspot.h"
|
||||
|
||||
#include <utility>
|
||||
#include <string>
|
||||
#include <utility>
|
||||
|
||||
#include "absl/strings/str_format.h"
|
||||
#include "absl/strings/string_view.h"
|
||||
@@ -188,7 +188,9 @@ bool WifiHotspot::StartAcceptingConnections(
|
||||
server_socket.Close();
|
||||
break;
|
||||
}
|
||||
callback.accepted_cb(service_id, std::move(client_socket));
|
||||
if (callback) {
|
||||
callback(service_id, std::move(client_socket));
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
|
||||
@@ -29,10 +29,8 @@ namespace connections {
|
||||
class WifiHotspot {
|
||||
public:
|
||||
// Callback that is invoked when a new connection is accepted.
|
||||
struct AcceptedConnectionCallback {
|
||||
std::function<void(const std::string& service_id, WifiHotspotSocket socket)>
|
||||
accepted_cb = [](const std::string&, WifiHotspotSocket) {};
|
||||
};
|
||||
using AcceptedConnectionCallback = absl::AnyInvocable<void(
|
||||
const std::string& service_id, WifiHotspotSocket socket)>;
|
||||
|
||||
WifiHotspot() : is_hotspot_started_(false), is_connected_to_hotspot_(false) {}
|
||||
~WifiHotspot();
|
||||
|
||||
@@ -264,7 +264,9 @@ bool WifiLan::StartAcceptingConnections(const std::string& service_id,
|
||||
server_socket.Close();
|
||||
break;
|
||||
}
|
||||
callback.accepted_cb(service_id, std::move(client_socket));
|
||||
if (callback) {
|
||||
callback(service_id, std::move(client_socket));
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
|
||||
@@ -36,10 +36,8 @@ class WifiLan {
|
||||
using DiscoveredServiceCallback = WifiLanMedium::DiscoveredServiceCallback;
|
||||
|
||||
// Callback that is invoked when a new connection is accepted.
|
||||
struct AcceptedConnectionCallback {
|
||||
std::function<void(const std::string& service_id, WifiLanSocket socket)>
|
||||
accepted_cb = [](const std::string&, WifiLanSocket) {};
|
||||
};
|
||||
using AcceptedConnectionCallback = absl::AnyInvocable<void(
|
||||
const std::string& service_id, WifiLanSocket socket)>;
|
||||
|
||||
WifiLan() = default;
|
||||
~WifiLan();
|
||||
|
||||
@@ -68,14 +68,9 @@ TEST_P(WifiLanTest, CanConnect) {
|
||||
|
||||
WifiLanSocket socket_for_server;
|
||||
EXPECT_TRUE(wifi_lan_server.StartAcceptingConnections(
|
||||
service_id,
|
||||
{
|
||||
.accepted_cb =
|
||||
[&socket_for_server, &accept_latch](const std::string& service_id,
|
||||
WifiLanSocket socket) {
|
||||
socket_for_server = std::move(socket);
|
||||
accept_latch.CountDown();
|
||||
},
|
||||
service_id, [&](const std::string& service_id, WifiLanSocket socket) {
|
||||
socket_for_server = std::move(socket);
|
||||
accept_latch.CountDown();
|
||||
}));
|
||||
|
||||
NsdServiceInfo nsd_service_info;
|
||||
@@ -125,14 +120,9 @@ TEST_P(WifiLanTest, CanCancelConnect) {
|
||||
|
||||
WifiLanSocket socket_for_server;
|
||||
EXPECT_TRUE(wifi_lan_server.StartAcceptingConnections(
|
||||
service_id,
|
||||
{
|
||||
.accepted_cb =
|
||||
[&socket_for_server, &accept_latch](const std::string& service_id,
|
||||
WifiLanSocket socket) {
|
||||
socket_for_server = std::move(socket);
|
||||
accept_latch.CountDown();
|
||||
},
|
||||
service_id, [&](const std::string& service_id, WifiLanSocket socket) {
|
||||
socket_for_server = std::move(socket);
|
||||
accept_latch.CountDown();
|
||||
}));
|
||||
|
||||
NsdServiceInfo nsd_service_info;
|
||||
|
||||
@@ -26,118 +26,113 @@ class MockServiceControllerRouter : public ServiceControllerRouter {
|
||||
MOCK_METHOD(void, StartAdvertising,
|
||||
(ClientProxy * client, absl::string_view service_id,
|
||||
const AdvertisingOptions& advertising_options,
|
||||
const ConnectionRequestInfo& info,
|
||||
const ResultCallback& callback),
|
||||
const ConnectionRequestInfo& info, ResultCallback callback),
|
||||
(override));
|
||||
|
||||
MOCK_METHOD(void, StopAdvertising,
|
||||
(ClientProxy * client, const ResultCallback& callback),
|
||||
(override));
|
||||
(ClientProxy * client, ResultCallback callback), (override));
|
||||
|
||||
MOCK_METHOD(void, StartDiscovery,
|
||||
(ClientProxy * client, absl::string_view service_id,
|
||||
const DiscoveryOptions& discovery_options,
|
||||
const DiscoveryListener& listener,
|
||||
const ResultCallback& callback),
|
||||
const DiscoveryListener& listener, ResultCallback callback),
|
||||
(override));
|
||||
|
||||
MOCK_METHOD(void, StopDiscovery,
|
||||
(ClientProxy * client, const ResultCallback& callback),
|
||||
(override));
|
||||
(ClientProxy * client, ResultCallback callback), (override));
|
||||
|
||||
MOCK_METHOD(void, InjectEndpoint,
|
||||
(ClientProxy * client, absl::string_view service_id,
|
||||
const OutOfBandConnectionMetadata& metadata,
|
||||
const ResultCallback& callback),
|
||||
ResultCallback callback),
|
||||
(override));
|
||||
|
||||
MOCK_METHOD(void, RequestConnection,
|
||||
(ClientProxy * client, absl::string_view endpoint_id,
|
||||
const ConnectionRequestInfo& info,
|
||||
const ConnectionOptions& connection_options,
|
||||
const ResultCallback& callback),
|
||||
ResultCallback callback),
|
||||
(override));
|
||||
|
||||
MOCK_METHOD(void, AcceptConnection,
|
||||
(ClientProxy * client, absl::string_view endpoint_id,
|
||||
PayloadListener listener, const ResultCallback& callback),
|
||||
PayloadListener listener, ResultCallback callback),
|
||||
(override));
|
||||
|
||||
MOCK_METHOD(void, RejectConnection,
|
||||
(ClientProxy * client, absl::string_view endpoint_id,
|
||||
const ResultCallback& callback),
|
||||
ResultCallback callback),
|
||||
(override));
|
||||
|
||||
MOCK_METHOD(void, InitiateBandwidthUpgrade,
|
||||
(ClientProxy * client, absl::string_view endpoint_id,
|
||||
const ResultCallback& callback),
|
||||
ResultCallback callback),
|
||||
(override));
|
||||
|
||||
MOCK_METHOD(void, SendPayload,
|
||||
(ClientProxy * client, absl::Span<const std::string> endpoint_ids,
|
||||
Payload payload, const ResultCallback& callback),
|
||||
Payload payload, ResultCallback callback),
|
||||
(override));
|
||||
|
||||
MOCK_METHOD(void, CancelPayload,
|
||||
(ClientProxy * client, std::uint64_t payload_id,
|
||||
const ResultCallback& callback),
|
||||
ResultCallback callback),
|
||||
(override));
|
||||
|
||||
MOCK_METHOD(void, DisconnectFromEndpoint,
|
||||
(ClientProxy * client, absl::string_view endpoint_id,
|
||||
const ResultCallback& callback),
|
||||
ResultCallback callback),
|
||||
(override));
|
||||
|
||||
MOCK_METHOD(void, StopAllEndpoints,
|
||||
(ClientProxy * client, const ResultCallback& callback),
|
||||
(override));
|
||||
(ClientProxy * client, ResultCallback callback), (override));
|
||||
|
||||
MOCK_METHOD(void, SetCustomSavePath,
|
||||
(ClientProxy * client, absl::string_view path,
|
||||
const ResultCallback& callback),
|
||||
ResultCallback callback),
|
||||
(override));
|
||||
|
||||
MOCK_METHOD(void, RequestConnectionV3,
|
||||
(ClientProxy * client, const NearbyDevice&,
|
||||
v3::ConnectionRequestInfo, const ConnectionOptions&,
|
||||
const ResultCallback& callback),
|
||||
ResultCallback callback),
|
||||
(override));
|
||||
|
||||
MOCK_METHOD(void, AcceptConnectionV3,
|
||||
(ClientProxy * client, const NearbyDevice&, v3::PayloadListener,
|
||||
const ResultCallback& callback),
|
||||
ResultCallback callback),
|
||||
(override));
|
||||
|
||||
MOCK_METHOD(void, RejectConnectionV3,
|
||||
(ClientProxy * client, const NearbyDevice&,
|
||||
const ResultCallback& callback),
|
||||
ResultCallback callback),
|
||||
(override));
|
||||
|
||||
MOCK_METHOD(void, InitiateBandwidthUpgradeV3,
|
||||
(ClientProxy * client, const NearbyDevice&,
|
||||
const ResultCallback& callback),
|
||||
ResultCallback callback),
|
||||
(override));
|
||||
|
||||
MOCK_METHOD(void, SendPayloadV3,
|
||||
(ClientProxy * client, const NearbyDevice&, Payload,
|
||||
const ResultCallback& callback),
|
||||
ResultCallback callback),
|
||||
(override));
|
||||
|
||||
MOCK_METHOD(void, DisconnectFromDeviceV3,
|
||||
(ClientProxy * client, const NearbyDevice&,
|
||||
const ResultCallback& callback),
|
||||
ResultCallback callback),
|
||||
(override));
|
||||
|
||||
MOCK_METHOD(void, UpdateAdvertisingOptionsV3,
|
||||
(ClientProxy * client, absl::string_view service_id,
|
||||
const AdvertisingOptions& advertising_options,
|
||||
const ResultCallback& callback),
|
||||
ResultCallback callback),
|
||||
(override));
|
||||
|
||||
MOCK_METHOD(void, UpdateDiscoveryOptionsV3,
|
||||
(ClientProxy * client, absl::string_view service_id,
|
||||
const DiscoveryOptions& discovery_options,
|
||||
const ResultCallback& callback),
|
||||
ResultCallback callback),
|
||||
(override));
|
||||
};
|
||||
|
||||
|
||||
@@ -14,14 +14,17 @@
|
||||
|
||||
#include "connections/implementation/offline_frames.h"
|
||||
|
||||
#include <cstdint>
|
||||
#include <memory>
|
||||
#include <string>
|
||||
#include <utility>
|
||||
#include <vector>
|
||||
|
||||
#include "connections/implementation/flags/nearby_connections_feature_flags.h"
|
||||
#include "connections/implementation/offline_frames_validator.h"
|
||||
#include "connections/implementation/proto/offline_wire_formats.pb.h"
|
||||
#include "connections/status.h"
|
||||
#include "internal/flags/nearby_flags.h"
|
||||
#include "internal/platform/byte_array.h"
|
||||
|
||||
namespace nearby {
|
||||
@@ -165,7 +168,8 @@ ByteArray ForConnectionRequestPresence(
|
||||
return ToBytes(std::move(frame));
|
||||
}
|
||||
|
||||
ByteArray ForConnectionResponse(std::int32_t status, const OsInfo& os_info) {
|
||||
ByteArray ForConnectionResponse(
|
||||
std::int32_t status, const OsInfo& os_info) {
|
||||
OfflineFrame frame;
|
||||
|
||||
frame.set_version(OfflineFrame::V1);
|
||||
@@ -181,6 +185,10 @@ ByteArray ForConnectionResponse(std::int32_t status, const OsInfo& os_info) {
|
||||
? ConnectionResponseFrame::ACCEPT
|
||||
: ConnectionResponseFrame::REJECT);
|
||||
*sub_frame->mutable_os_info() = os_info;
|
||||
sub_frame->set_safe_to_disconnect_version(
|
||||
NearbyFlags::GetInstance().GetInt64Flag(
|
||||
config_package_nearby::nearby_connections_feature::
|
||||
kSafeToDisconnectVersion));
|
||||
|
||||
return ToBytes(std::move(frame));
|
||||
}
|
||||
@@ -445,13 +453,16 @@ ByteArray ForKeepAlive() {
|
||||
return ToBytes(std::move(frame));
|
||||
}
|
||||
|
||||
ByteArray ForDisconnection() {
|
||||
ByteArray ForDisconnection(bool request_safe_to_disconnect,
|
||||
bool ack_safe_to_disconnect) {
|
||||
OfflineFrame frame;
|
||||
|
||||
frame.set_version(OfflineFrame::V1);
|
||||
auto* v1_frame = frame.mutable_v1();
|
||||
v1_frame->set_type(V1Frame::DISCONNECTION);
|
||||
v1_frame->mutable_disconnection();
|
||||
auto* disconnection = v1_frame->mutable_disconnection();
|
||||
disconnection->set_request_safe_to_disconnect(request_safe_to_disconnect);
|
||||
disconnection->set_ack_safe_to_disconnect(ack_safe_to_disconnect);
|
||||
|
||||
return ToBytes(std::move(frame));
|
||||
}
|
||||
|
||||
@@ -98,8 +98,8 @@ ByteArray ForBwuLastWrite();
|
||||
ByteArray ForBwuSafeToClose();
|
||||
|
||||
ByteArray ForKeepAlive();
|
||||
ByteArray ForDisconnection();
|
||||
|
||||
ByteArray ForDisconnection(bool request_safe_to_disconnect,
|
||||
bool ack_safe_to_disconnect);
|
||||
UpgradePathInfo::Medium MediumToUpgradePathInfoMedium(Medium medium);
|
||||
Medium UpgradePathInfoMediumToMedium(UpgradePathInfo::Medium medium);
|
||||
|
||||
|
||||
@@ -269,6 +269,7 @@ TEST(OfflineFramesTest, CanGenerateConnectionResponse) {
|
||||
status: 1
|
||||
response: REJECT
|
||||
os_info { type: LINUX }
|
||||
safe_to_disconnect_version: 2
|
||||
>
|
||||
>)pb";
|
||||
|
||||
@@ -538,6 +539,25 @@ TEST(OfflineFramesTest, CanGenerateKeepAlive) {
|
||||
EXPECT_THAT(message, EqualsProto(kExpected));
|
||||
}
|
||||
|
||||
TEST(OfflineFramesTest, CanGenerateDisconnection) {
|
||||
constexpr absl::string_view kExpected =
|
||||
R"pb(
|
||||
version: V1
|
||||
v1: <
|
||||
type: DISCONNECTION
|
||||
disconnection: <
|
||||
request_safe_to_disconnect: true
|
||||
ack_safe_to_disconnect: true
|
||||
>
|
||||
>)pb";
|
||||
ByteArray bytes = ForDisconnection(/* request_safe_to_disconnect */ true,
|
||||
/* ack_safe_to_disconnect */ true);
|
||||
auto response = FromBytes(bytes);
|
||||
ASSERT_TRUE(response.ok());
|
||||
OfflineFrame message = response.result();
|
||||
EXPECT_THAT(message, EqualsProto(kExpected));
|
||||
}
|
||||
|
||||
} // namespace
|
||||
} // namespace parser
|
||||
} // namespace connections
|
||||
|
||||
@@ -12,31 +12,42 @@
|
||||
// See the License for the specific language governing permissions and
|
||||
// limitations under the License.
|
||||
|
||||
#include "connections/implementation/offline_service_controller.h"
|
||||
|
||||
#include <array>
|
||||
#include <cstddef>
|
||||
#include <string>
|
||||
#include <utility>
|
||||
|
||||
#include "gmock/gmock.h"
|
||||
#include "protobuf-matchers/protocol-buffer-matchers.h"
|
||||
#include "gtest/gtest.h"
|
||||
#include "absl/strings/string_view.h"
|
||||
#include "absl/time/time.h"
|
||||
#include "connections/advertising_options.h"
|
||||
#include "connections/discovery_options.h"
|
||||
#include "connections/implementation/flags/nearby_connections_feature_flags.h"
|
||||
#include "connections/implementation/offline_simulation_user.h"
|
||||
#include "connections/listeners.h"
|
||||
#include "connections/medium_selector.h"
|
||||
#include "connections/out_of_band_connection_metadata.h"
|
||||
#include "connections/payload.h"
|
||||
#include "connections/status.h"
|
||||
#include "connections/strategy.h"
|
||||
#include "internal/flags/nearby_flags.h"
|
||||
#include "internal/platform/byte_array.h"
|
||||
#include "internal/platform/count_down_latch.h"
|
||||
#include "internal/platform/input_stream.h"
|
||||
#include "internal/platform/logging.h"
|
||||
#include "internal/platform/medium_environment.h"
|
||||
#include "internal/platform/output_stream.h"
|
||||
#include "internal/platform/pipe.h"
|
||||
#include "internal/platform/system_clock.h"
|
||||
#include "proto/connections_enums.proto.h"
|
||||
|
||||
namespace nearby {
|
||||
namespace connections {
|
||||
namespace {
|
||||
|
||||
using ::testing::Eq;
|
||||
|
||||
constexpr size_t kChunkSize = 64 * 1024;
|
||||
constexpr std::array<char, 6> kFakeMacAddress = {'a', 'b', 'c', 'd', 'e', 'f'};
|
||||
constexpr absl::string_view kServiceId = "service-id";
|
||||
constexpr absl::string_view kDeviceA = "device-a";
|
||||
@@ -83,6 +94,9 @@ class OfflineServiceControllerTest
|
||||
void SetUp() override {
|
||||
NearbyFlags::GetInstance().OverrideBoolFlagValue(
|
||||
config_package_nearby::nearby_connections_feature::kEnableBleV2, true);
|
||||
NearbyFlags::GetInstance().OverrideBoolFlagValue(
|
||||
config_package_nearby::nearby_connections_feature::
|
||||
kEnableSafeToDisconnect, false);
|
||||
}
|
||||
bool SetupConnection(OfflineSimulationUser& user_a,
|
||||
OfflineSimulationUser& user_b) {
|
||||
@@ -284,10 +298,10 @@ TEST_P(OfflineServiceControllerTest, CanSendBytePayload) {
|
||||
env_.Start();
|
||||
OfflineSimulationUser user_a(kDeviceA, GetParam());
|
||||
OfflineSimulationUser user_b(kDeviceB, GetParam());
|
||||
user_b.ExpectPayload(payload_latch_);
|
||||
ASSERT_TRUE(SetupConnection(user_a, user_b));
|
||||
ByteArray message(std::string{kMessage});
|
||||
user_a.SendPayload(Payload(message));
|
||||
user_b.ExpectPayload(payload_latch_);
|
||||
EXPECT_TRUE(payload_latch_.Await(kLongTimeout));
|
||||
EXPECT_EQ(user_b.GetPayload().AsBytes(), message);
|
||||
user_a.Stop();
|
||||
@@ -299,15 +313,12 @@ TEST_P(OfflineServiceControllerTest, CanSendStreamPayload) {
|
||||
env_.Start();
|
||||
OfflineSimulationUser user_a(kDeviceA, GetParam());
|
||||
OfflineSimulationUser user_b(kDeviceB, GetParam());
|
||||
user_b.ExpectPayload(payload_latch_);
|
||||
ASSERT_TRUE(SetupConnection(user_a, user_b));
|
||||
ByteArray message(std::string{kMessage});
|
||||
auto pipe = std::make_shared<Pipe>();
|
||||
OutputStream& tx = pipe->GetOutputStream();
|
||||
user_a.SendPayload(Payload([pipe]() -> InputStream& {
|
||||
return pipe->GetInputStream(); // NOLINT
|
||||
}));
|
||||
user_b.ExpectPayload(payload_latch_);
|
||||
tx.Write(message);
|
||||
auto [input, tx] = CreatePipe();
|
||||
user_a.SendPayload(Payload(std::move(input)));
|
||||
tx->Write(message);
|
||||
EXPECT_TRUE(payload_latch_.Await(kLongTimeout));
|
||||
ASSERT_NE(user_b.GetPayload().AsStream(), nullptr);
|
||||
InputStream& rx = *user_b.GetPayload().AsStream();
|
||||
@@ -316,7 +327,7 @@ TEST_P(OfflineServiceControllerTest, CanSendStreamPayload) {
|
||||
return info.bytes_transferred >= size;
|
||||
},
|
||||
kLongTimeout));
|
||||
EXPECT_EQ(rx.Read(Pipe::kChunkSize).result(), message);
|
||||
EXPECT_EQ(rx.Read(kChunkSize).result(), message);
|
||||
user_a.Stop();
|
||||
user_b.Stop();
|
||||
env_.Stop();
|
||||
@@ -326,15 +337,12 @@ TEST_P(OfflineServiceControllerTest, CanCancelStreamPayload) {
|
||||
env_.Start();
|
||||
OfflineSimulationUser user_a(kDeviceA, GetParam());
|
||||
OfflineSimulationUser user_b(kDeviceB, GetParam());
|
||||
user_b.ExpectPayload(payload_latch_);
|
||||
ASSERT_TRUE(SetupConnection(user_a, user_b));
|
||||
ByteArray message(std::string{kMessage});
|
||||
auto pipe = std::make_shared<Pipe>();
|
||||
OutputStream& tx = pipe->GetOutputStream();
|
||||
user_a.SendPayload(Payload([pipe]() -> InputStream& {
|
||||
return pipe->GetInputStream(); // NOLINT
|
||||
}));
|
||||
user_b.ExpectPayload(payload_latch_);
|
||||
tx.Write(message);
|
||||
auto [input, tx] = CreatePipe();
|
||||
user_a.SendPayload(Payload(std::move(input)));
|
||||
tx->Write(message);
|
||||
EXPECT_TRUE(payload_latch_.Await(kLongTimeout));
|
||||
ASSERT_NE(user_b.GetPayload().AsStream(), nullptr);
|
||||
InputStream& rx = *user_b.GetPayload().AsStream();
|
||||
@@ -343,11 +351,11 @@ TEST_P(OfflineServiceControllerTest, CanCancelStreamPayload) {
|
||||
return info.bytes_transferred >= size;
|
||||
},
|
||||
kLongTimeout));
|
||||
EXPECT_EQ(rx.Read(Pipe::kChunkSize).result(), message);
|
||||
EXPECT_EQ(rx.Read(kChunkSize).result(), message);
|
||||
user_b.CancelPayload();
|
||||
absl::Time start_time = SystemClock::ElapsedRealtime();
|
||||
while (true) {
|
||||
if (!tx.Write(message).Ok()) break;
|
||||
if (!tx->Write(message).Ok()) break;
|
||||
absl::Duration run_time = SystemClock::ElapsedRealtime() - start_time;
|
||||
if (run_time >= kLongTimeout) {
|
||||
EXPECT_LT(run_time, kLongTimeout);
|
||||
|
||||
@@ -14,6 +14,7 @@
|
||||
|
||||
#include "connections/implementation/offline_simulation_user.h"
|
||||
|
||||
#include "absl/functional/any_invocable.h"
|
||||
#include "absl/functional/bind_front.h"
|
||||
#include "connections/listeners.h"
|
||||
#include "internal/platform/byte_array.h"
|
||||
@@ -86,7 +87,7 @@ void OfflineSimulationUser::OnPayloadProgress(absl::string_view endpoint_id,
|
||||
}
|
||||
|
||||
bool OfflineSimulationUser::WaitForProgress(
|
||||
std::function<bool(const PayloadProgressInfo&)> predicate,
|
||||
absl::AnyInvocable<bool(const PayloadProgressInfo&)> predicate,
|
||||
absl::Duration timeout) {
|
||||
Future<bool> future;
|
||||
{
|
||||
|
||||
@@ -18,6 +18,7 @@
|
||||
#include <string>
|
||||
|
||||
#include "gtest/gtest.h"
|
||||
#include "absl/functional/any_invocable.h"
|
||||
#include "absl/strings/string_view.h"
|
||||
#include "connections/implementation/client_proxy.h"
|
||||
#include "connections/implementation/offline_service_controller.h"
|
||||
@@ -131,8 +132,9 @@ class OfflineSimulationUser {
|
||||
const DiscoveredInfo& GetDiscovered() const { return discovered_; }
|
||||
ByteArray GetInfo() const { return info_; }
|
||||
|
||||
bool WaitForProgress(std::function<bool(const PayloadProgressInfo&)> pred,
|
||||
absl::Duration timeout);
|
||||
bool WaitForProgress(
|
||||
absl::AnyInvocable<bool(const PayloadProgressInfo&)> pred,
|
||||
absl::Duration timeout);
|
||||
|
||||
Payload& GetPayload() { return payload_; }
|
||||
void SendPayload(Payload payload) {
|
||||
@@ -203,7 +205,7 @@ class OfflineSimulationUser {
|
||||
CountDownLatch* payload_latch_ = nullptr;
|
||||
CountDownLatch* disconnect_latch_ = nullptr;
|
||||
Future<bool>* future_ = nullptr;
|
||||
std::function<bool(const PayloadProgressInfo&)> predicate_;
|
||||
absl::AnyInvocable<bool(const PayloadProgressInfo&)> predicate_;
|
||||
ClientProxy client_;
|
||||
OfflineServiceController ctrl_;
|
||||
};
|
||||
|
||||
@@ -298,78 +298,77 @@ void P2pClusterPcpHandler::BluetoothNameChangedHandler(
|
||||
BluetoothDevice device) {
|
||||
RunOnPcpHandlerThread(
|
||||
"p2p-bt-name-changed",
|
||||
[this, client, service_id, device]()
|
||||
RUN_ON_PCP_HANDLER_THREAD() {
|
||||
// Make sure we are still discovering before proceeding.
|
||||
if (!client->IsDiscovering()) {
|
||||
NEARBY_LOGS(WARNING)
|
||||
<< "Ignoring lost BluetoothDevice " << device.GetName()
|
||||
<< " because Connections is no longer discovering.";
|
||||
return;
|
||||
}
|
||||
[this, client, service_id, device]() RUN_ON_PCP_HANDLER_THREAD() {
|
||||
// Make sure we are still discovering before proceeding.
|
||||
if (!client->IsDiscovering()) {
|
||||
NEARBY_LOGS(WARNING)
|
||||
<< "Ignoring lost BluetoothDevice " << device.GetName()
|
||||
<< " because Connections is no longer discovering.";
|
||||
return;
|
||||
}
|
||||
|
||||
// Parse the Bluetooth device name.
|
||||
const std::string device_name_string = device.GetName();
|
||||
BluetoothDeviceName device_name(device_name_string);
|
||||
NEARBY_LOGS(INFO)
|
||||
<< "BT discovery handler (CHANGED) [client_id="
|
||||
<< client->GetClientId() << ", service_id=" << service_id
|
||||
<< "]: processing new name " << device_name_string;
|
||||
// Parse the Bluetooth device name.
|
||||
const std::string device_name_string = device.GetName();
|
||||
BluetoothDeviceName device_name(device_name_string);
|
||||
NEARBY_LOGS(INFO) << "BT discovery handler (CHANGED) [client_id="
|
||||
<< client->GetClientId()
|
||||
<< ", service_id=" << service_id
|
||||
<< "]: processing new name " << device_name_string;
|
||||
|
||||
// By this point, the BluetoothDevice passed to us has a different
|
||||
// name than what we may have discovered before. We need to iterate
|
||||
// over the found BluetoothEndpoints and compare their addresses to
|
||||
// see the devices are the same. We are not guaranteed to discover a
|
||||
// match, since the old name may not have been formatted for Nearby
|
||||
// Connections.
|
||||
for (auto endpoint : GetDiscoveredEndpoints(Medium::BLUETOOTH)) {
|
||||
BluetoothEndpoint* bluetoothEndpoint =
|
||||
static_cast<BluetoothEndpoint*>(endpoint);
|
||||
NEARBY_LOGS(INFO)
|
||||
<< "BT discovery handler (CHANGED) [client_id="
|
||||
<< client->GetClientId() << ", service_id=" << service_id
|
||||
<< "]: comparing MAC addresses with existing endpoint "
|
||||
<< bluetoothEndpoint->bluetooth_device.GetName()
|
||||
<< ". They have MAC address "
|
||||
<< bluetoothEndpoint->bluetooth_device.GetMacAddress()
|
||||
<< " and the new endpoint has MAC address "
|
||||
<< device.GetMacAddress();
|
||||
if (bluetoothEndpoint->bluetooth_device.GetMacAddress() ==
|
||||
device.GetMacAddress()) {
|
||||
// Report the BluetoothEndpoint as lost to the client.
|
||||
NEARBY_LOGS(INFO)
|
||||
<< "Reporting lost BluetoothDevice "
|
||||
<< bluetoothEndpoint->bluetooth_device.GetName()
|
||||
<< ", due to device name change.";
|
||||
OnEndpointLost(client, *endpoint);
|
||||
break;
|
||||
}
|
||||
}
|
||||
// By this point, the BluetoothDevice passed to us has a different
|
||||
// name than what we may have discovered before. We need to iterate
|
||||
// over the found BluetoothEndpoints and compare their addresses to
|
||||
// see the devices are the same. We are not guaranteed to discover a
|
||||
// match, since the old name may not have been formatted for Nearby
|
||||
// Connections.
|
||||
for (auto endpoint : GetDiscoveredEndpoints(Medium::BLUETOOTH)) {
|
||||
BluetoothEndpoint* bluetoothEndpoint =
|
||||
static_cast<BluetoothEndpoint*>(endpoint);
|
||||
NEARBY_LOGS(INFO)
|
||||
<< "BT discovery handler (CHANGED) [client_id="
|
||||
<< client->GetClientId() << ", service_id=" << service_id
|
||||
<< "]: comparing MAC addresses with existing endpoint "
|
||||
<< bluetoothEndpoint->bluetooth_device.GetName()
|
||||
<< ". They have MAC address "
|
||||
<< bluetoothEndpoint->bluetooth_device.GetMacAddress()
|
||||
<< " and the new endpoint has MAC address "
|
||||
<< device.GetMacAddress();
|
||||
if (bluetoothEndpoint->bluetooth_device.GetMacAddress() ==
|
||||
device.GetMacAddress()) {
|
||||
// Report the BluetoothEndpoint as lost to the client.
|
||||
NEARBY_LOGS(INFO) << "Reporting lost BluetoothDevice "
|
||||
<< bluetoothEndpoint->bluetooth_device.GetName()
|
||||
<< ", due to device name change.";
|
||||
OnEndpointLost(client, *endpoint);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
// Make sure the Bluetooth device name points to a valid
|
||||
// endpoint we're discovering.
|
||||
if (!IsRecognizedBluetoothEndpoint(device_name_string, service_id,
|
||||
device_name)) {
|
||||
NEARBY_LOGS(INFO) << "Found unrecognized BluetoothDeviceName "
|
||||
<< device_name_string;
|
||||
return;
|
||||
}
|
||||
// Make sure the Bluetooth device name points to a valid
|
||||
// endpoint we're discovering.
|
||||
if (!IsRecognizedBluetoothEndpoint(device_name_string, service_id,
|
||||
device_name)) {
|
||||
NEARBY_LOGS(INFO) << "Found unrecognized BluetoothDeviceName "
|
||||
<< device_name_string;
|
||||
return;
|
||||
}
|
||||
|
||||
// Report the discovered endpoint to the client.
|
||||
NEARBY_LOGS(INFO)
|
||||
<< "Found BluetoothDeviceName " << device_name_string
|
||||
<< " (with endpoint_id=" << device_name.GetEndpointId()
|
||||
<< " and endpoint_info="
|
||||
<< absl::BytesToHexString(device_name.GetEndpointInfo().data())
|
||||
<< ").";
|
||||
OnEndpointFound(
|
||||
client, std::make_shared<BluetoothEndpoint>(BluetoothEndpoint{
|
||||
{device_name.GetEndpointId(),
|
||||
device_name.GetEndpointInfo(), service_id,
|
||||
Medium::BLUETOOTH, device_name.GetWebRtcState()},
|
||||
device,
|
||||
}));
|
||||
});
|
||||
// Report the discovered endpoint to the client.
|
||||
NEARBY_LOGS(INFO) << "Found BluetoothDeviceName " << device_name_string
|
||||
<< " (with endpoint_id="
|
||||
<< device_name.GetEndpointId()
|
||||
<< " and endpoint_info="
|
||||
<< absl::BytesToHexString(
|
||||
device_name.GetEndpointInfo().data())
|
||||
<< ").";
|
||||
OnEndpointFound(
|
||||
client,
|
||||
std::make_shared<BluetoothEndpoint>(BluetoothEndpoint{
|
||||
{device_name.GetEndpointId(), device_name.GetEndpointInfo(),
|
||||
service_id, Medium::BLUETOOTH, device_name.GetWebRtcState()},
|
||||
device,
|
||||
}));
|
||||
});
|
||||
}
|
||||
|
||||
void P2pClusterPcpHandler::BluetoothDeviceLostHandler(
|
||||
@@ -1088,10 +1087,10 @@ P2pClusterPcpHandler::StartListeningForIncomingConnectionsImpl(
|
||||
!bluetooth_medium_.IsAcceptingConnections(std::string(service_id))) {
|
||||
if (!bluetooth_medium_.StartAcceptingConnections(
|
||||
std::string(service_id),
|
||||
{.accepted_cb = absl::bind_front(
|
||||
&P2pClusterPcpHandler::BluetoothConnectionAcceptedHandler,
|
||||
this, client_proxy, local_endpoint_id,
|
||||
options.listening_endpoint_type)})) {
|
||||
absl::bind_front(
|
||||
&P2pClusterPcpHandler::BluetoothConnectionAcceptedHandler, this,
|
||||
client_proxy, local_endpoint_id,
|
||||
options.listening_endpoint_type))) {
|
||||
NEARBY_LOGS(WARNING)
|
||||
<< "Failed to start listening for incoming connections on Bluetooth";
|
||||
} else {
|
||||
@@ -1107,10 +1106,10 @@ P2pClusterPcpHandler::StartListeningForIncomingConnectionsImpl(
|
||||
!ble_v2_medium_.IsAcceptingConnections(std::string(service_id))) {
|
||||
if (!ble_v2_medium_.StartAcceptingConnections(
|
||||
std::string(service_id),
|
||||
{.accepted_cb = absl::bind_front(
|
||||
&P2pClusterPcpHandler::BleV2ConnectionAcceptedHandler, this,
|
||||
client_proxy, local_endpoint_id,
|
||||
options.listening_endpoint_type)})) {
|
||||
absl::bind_front(
|
||||
&P2pClusterPcpHandler::BleV2ConnectionAcceptedHandler, this,
|
||||
client_proxy, local_endpoint_id,
|
||||
options.listening_endpoint_type))) {
|
||||
NEARBY_LOGS(WARNING)
|
||||
<< "Failed to start listening for incoming connections on ble_v2";
|
||||
} else {
|
||||
@@ -1123,10 +1122,10 @@ P2pClusterPcpHandler::StartListeningForIncomingConnectionsImpl(
|
||||
!ble_medium_.IsAcceptingConnections(std::string(service_id))) {
|
||||
if (!ble_medium_.StartAcceptingConnections(
|
||||
std::string(service_id),
|
||||
{.accepted_cb = absl::bind_front(
|
||||
&P2pClusterPcpHandler::BleConnectionAcceptedHandler, this,
|
||||
client_proxy, local_endpoint_id,
|
||||
options.listening_endpoint_type)})) {
|
||||
absl::bind_front(
|
||||
&P2pClusterPcpHandler::BleConnectionAcceptedHandler, this,
|
||||
client_proxy, local_endpoint_id,
|
||||
options.listening_endpoint_type))) {
|
||||
NEARBY_LOGS(WARNING)
|
||||
<< "Failed to start listening for incoming connections on ble";
|
||||
} else {
|
||||
@@ -1138,10 +1137,10 @@ P2pClusterPcpHandler::StartListeningForIncomingConnectionsImpl(
|
||||
!wifi_lan_medium_.IsAcceptingConnections(std::string(service_id))) {
|
||||
if (!wifi_lan_medium_.StartAcceptingConnections(
|
||||
std::string(service_id),
|
||||
{.accepted_cb = absl::bind_front(
|
||||
&P2pClusterPcpHandler::WifiLanConnectionAcceptedHandler, this,
|
||||
client_proxy, local_endpoint_id, "",
|
||||
options.listening_endpoint_type)})) {
|
||||
absl::bind_front(
|
||||
&P2pClusterPcpHandler::WifiLanConnectionAcceptedHandler, this,
|
||||
client_proxy, local_endpoint_id, "",
|
||||
options.listening_endpoint_type))) {
|
||||
NEARBY_LOGS(WARNING)
|
||||
<< "Failed to start listening for incoming connections on wifi_lan";
|
||||
} else {
|
||||
@@ -1459,10 +1458,10 @@ Medium P2pClusterPcpHandler::StartBluetoothAdvertising(
|
||||
if (!bluetooth_radio_.Enable() ||
|
||||
!bluetooth_medium_.StartAcceptingConnections(
|
||||
service_id,
|
||||
{.accepted_cb = absl::bind_front(
|
||||
&P2pClusterPcpHandler::BluetoothConnectionAcceptedHandler,
|
||||
this, client, local_endpoint_info.AsStringView(),
|
||||
NearbyDevice::Type::kConnectionsDevice)})) {
|
||||
absl::bind_front(
|
||||
&P2pClusterPcpHandler::BluetoothConnectionAcceptedHandler, this,
|
||||
client, local_endpoint_info.AsStringView(),
|
||||
NearbyDevice::Type::kConnectionsDevice))) {
|
||||
NEARBY_LOGS(WARNING)
|
||||
<< "In StartBluetoothAdvertising("
|
||||
<< absl::BytesToHexString(local_endpoint_info.data())
|
||||
@@ -1636,11 +1635,10 @@ Medium P2pClusterPcpHandler::StartBleAdvertising(
|
||||
if (!ble_medium_.IsAcceptingConnections(service_id)) {
|
||||
if (!bluetooth_radio_.Enable() ||
|
||||
!ble_medium_.StartAcceptingConnections(
|
||||
service_id,
|
||||
{.accepted_cb = absl::bind_front(
|
||||
&P2pClusterPcpHandler::BleConnectionAcceptedHandler, this,
|
||||
client, local_endpoint_info.AsStringView(),
|
||||
NearbyDevice::Type::kConnectionsDevice)})) {
|
||||
service_id, absl::bind_front(
|
||||
&P2pClusterPcpHandler::BleConnectionAcceptedHandler,
|
||||
this, client, local_endpoint_info.AsStringView(),
|
||||
NearbyDevice::Type::kConnectionsDevice))) {
|
||||
NEARBY_LOGS(WARNING)
|
||||
<< "In StartBleAdvertising("
|
||||
<< absl::BytesToHexString(local_endpoint_info.data())
|
||||
@@ -1665,10 +1663,10 @@ Medium P2pClusterPcpHandler::StartBleAdvertising(
|
||||
if (!bluetooth_radio_.Enable() ||
|
||||
!bluetooth_medium_.StartAcceptingConnections(
|
||||
service_id,
|
||||
{.accepted_cb = absl::bind_front(
|
||||
&P2pClusterPcpHandler::BluetoothConnectionAcceptedHandler,
|
||||
this, client, local_endpoint_info.AsStringView(),
|
||||
NearbyDevice::Type::kConnectionsDevice)})) {
|
||||
absl::bind_front(
|
||||
&P2pClusterPcpHandler::BluetoothConnectionAcceptedHandler,
|
||||
this, client, local_endpoint_info.AsStringView(),
|
||||
NearbyDevice::Type::kConnectionsDevice))) {
|
||||
NEARBY_LOGS(WARNING)
|
||||
<< "In BT StartBleAdvertising("
|
||||
<< absl::BytesToHexString(local_endpoint_info.data())
|
||||
@@ -1846,10 +1844,10 @@ Medium P2pClusterPcpHandler::StartBleV2Advertising(
|
||||
if (!bluetooth_radio_.Enable() ||
|
||||
!ble_v2_medium_.StartAcceptingConnections(
|
||||
service_id,
|
||||
{.accepted_cb = absl::bind_front(
|
||||
&P2pClusterPcpHandler::BleV2ConnectionAcceptedHandler, this,
|
||||
client, local_endpoint_info.AsStringView(),
|
||||
NearbyDevice::Type::kConnectionsDevice)})) {
|
||||
absl::bind_front(
|
||||
&P2pClusterPcpHandler::BleV2ConnectionAcceptedHandler, this,
|
||||
client, local_endpoint_info.AsStringView(),
|
||||
NearbyDevice::Type::kConnectionsDevice))) {
|
||||
NEARBY_LOGS(WARNING)
|
||||
<< "In StartBleAdvertising("
|
||||
<< absl::BytesToHexString(local_endpoint_info.data())
|
||||
@@ -1877,10 +1875,10 @@ Medium P2pClusterPcpHandler::StartBleV2Advertising(
|
||||
if (!bluetooth_radio_.Enable() ||
|
||||
!bluetooth_medium_.StartAcceptingConnections(
|
||||
service_id,
|
||||
{.accepted_cb = absl::bind_front(
|
||||
&P2pClusterPcpHandler::BluetoothConnectionAcceptedHandler,
|
||||
this, client, local_endpoint_info.AsStringView(),
|
||||
NearbyDevice::Type::kConnectionsDevice)})) {
|
||||
absl::bind_front(
|
||||
&P2pClusterPcpHandler::BluetoothConnectionAcceptedHandler,
|
||||
this, client, local_endpoint_info.AsStringView(),
|
||||
NearbyDevice::Type::kConnectionsDevice))) {
|
||||
NEARBY_LOGS(WARNING)
|
||||
<< "In BT StartBleAdvertising("
|
||||
<< absl::BytesToHexString(local_endpoint_info.data())
|
||||
@@ -2058,10 +2056,10 @@ Medium P2pClusterPcpHandler::StartWifiLanAdvertising(
|
||||
if (!wifi_lan_medium_.IsAcceptingConnections(service_id)) {
|
||||
if (!wifi_lan_medium_.StartAcceptingConnections(
|
||||
service_id,
|
||||
{.accepted_cb = absl::bind_front(
|
||||
&P2pClusterPcpHandler::WifiLanConnectionAcceptedHandler, this,
|
||||
client, local_endpoint_id, local_endpoint_info.AsStringView(),
|
||||
NearbyDevice::Type::kConnectionsDevice)})) {
|
||||
absl::bind_front(
|
||||
&P2pClusterPcpHandler::WifiLanConnectionAcceptedHandler, this,
|
||||
client, local_endpoint_id, local_endpoint_info.AsStringView(),
|
||||
NearbyDevice::Type::kConnectionsDevice))) {
|
||||
NEARBY_LOGS(WARNING)
|
||||
<< "In StartWifiLanAdvertising("
|
||||
<< absl::BytesToHexString(local_endpoint_info.data())
|
||||
@@ -2165,9 +2163,6 @@ BasePcpHandler::ConnectImplResult P2pClusterPcpHandler::WifiLanConnectImpl(
|
||||
WifiLanSocket socket = wifi_lan_medium_.Connect(
|
||||
endpoint->service_id, endpoint->service_info,
|
||||
client->GetCancellationFlag(endpoint->endpoint_id));
|
||||
NEARBY_LOGS(INFO) << "In WifiLanConnectImpl(), connect to service "
|
||||
<< " socket=" << &socket.GetImpl()
|
||||
<< " for endpoint(id=" << endpoint->endpoint_id << ").";
|
||||
if (!socket.IsValid()) {
|
||||
NEARBY_LOGS(ERROR)
|
||||
<< "In WifiLanConnectImpl(), failed to connect to service "
|
||||
@@ -2177,6 +2172,9 @@ BasePcpHandler::ConnectImplResult P2pClusterPcpHandler::WifiLanConnectImpl(
|
||||
.status = {Status::kWifiLanError},
|
||||
};
|
||||
}
|
||||
NEARBY_LOGS(INFO) << "In WifiLanConnectImpl(), connect to service "
|
||||
<< " socket=" << &socket.GetImpl()
|
||||
<< " for endpoint(id=" << endpoint->endpoint_id << ").";
|
||||
|
||||
auto channel = std::make_unique<WifiLanEndpointChannel>(
|
||||
endpoint->service_id, /*channel_name=*/endpoint->endpoint_id, socket);
|
||||
|
||||
@@ -113,7 +113,8 @@ class P2pClusterPcpHandler : public BasePcpHandler {
|
||||
ClientProxy* client, absl::string_view service_id,
|
||||
absl::string_view local_endpoint_id,
|
||||
absl::string_view local_endpoint_info,
|
||||
const DiscoveryOptions& discovery_options) override;
|
||||
const DiscoveryOptions& discovery_options)
|
||||
RUN_ON_PCP_HANDLER_THREAD() override;
|
||||
|
||||
private:
|
||||
// Holds the state required to re-create a BleEndpoint we see on a
|
||||
|
||||
@@ -16,6 +16,7 @@
|
||||
|
||||
#include <memory>
|
||||
#include <string>
|
||||
#include <tuple>
|
||||
|
||||
#include "gmock/gmock.h"
|
||||
#include "protobuf-matchers/protocol-buffer-matchers.h"
|
||||
@@ -690,6 +691,7 @@ TEST_P(P2pClusterPcpHandlerTest, CanConnect) {
|
||||
EXPECT_EQ(client_a_.GetIPAddress(client_b_local_endpoint),
|
||||
mediums_b.GetWifi().GetInformation().ip_address_4_bytes);
|
||||
|
||||
handler_b.StopDiscovery(&client_b_);
|
||||
bwu_a.Shutdown();
|
||||
bwu_b.Shutdown();
|
||||
env_.Stop();
|
||||
|
||||
@@ -15,30 +15,39 @@
|
||||
#include "connections/implementation/payload_manager.h"
|
||||
|
||||
#include <algorithm>
|
||||
#include <functional>
|
||||
#include <cstdint>
|
||||
#include <limits>
|
||||
#include <memory>
|
||||
#include <string>
|
||||
#include <utility>
|
||||
#include <vector>
|
||||
|
||||
#include "absl/memory/memory.h"
|
||||
#include "absl/functional/any_invocable.h"
|
||||
#include "absl/functional/bind_front.h"
|
||||
#include "absl/strings/str_cat.h"
|
||||
#include "absl/strings/str_format.h"
|
||||
#include "absl/time/time.h"
|
||||
#include "connections/implementation/analytics/throughput_recorder.h"
|
||||
#include "connections/implementation/client_proxy.h"
|
||||
#include "connections/implementation/endpoint_channel_manager.h"
|
||||
#include "connections/implementation/flags/nearby_connections_feature_flags.h"
|
||||
#include "connections/implementation/internal_payload_factory.h"
|
||||
#include "connections/payload_type.h"
|
||||
#include "internal/flags/nearby_flags.h"
|
||||
#include "internal/platform/count_down_latch.h"
|
||||
#include "internal/platform/exception.h"
|
||||
#include "internal/platform/feature_flags.h"
|
||||
#include "internal/platform/logging.h"
|
||||
#include "internal/platform/mutex_lock.h"
|
||||
#include "internal/platform/single_thread_executor.h"
|
||||
#include "proto/connections_enums.pb.h"
|
||||
|
||||
namespace nearby {
|
||||
namespace connections {
|
||||
|
||||
using ::location::nearby::connections::OfflineFrame;
|
||||
using ::location::nearby::connections::V1Frame;
|
||||
using ::location::nearby::proto::connections::PayloadStatus;
|
||||
using ::nearby::analytics::PacketMetaData;
|
||||
using ::nearby::analytics::ThroughputRecorderContainer;
|
||||
using ::nearby::connections::PayloadDirection;
|
||||
@@ -155,7 +164,7 @@ bool PayloadManager::SendPayloadLoop(
|
||||
location::nearby::proto::connections::
|
||||
PayloadStatus::ENDPOINT_IO_ERROR);
|
||||
}
|
||||
|
||||
bool is_last_chunk = IsLastChunk(payload_chunk);
|
||||
// Check whether at least one endpoint succeeded -- if they all failed,
|
||||
// we'll just go right back to the top of the loop and break out when
|
||||
// availableEndpointIds is re-synced and found to be empty at that point.
|
||||
@@ -163,6 +172,12 @@ bool PayloadManager::SendPayloadLoop(
|
||||
for (const auto& endpoint_id : available_endpoint_ids) {
|
||||
if (std::find(failed_endpoint_ids.begin(), failed_endpoint_ids.end(),
|
||||
endpoint_id) == failed_endpoint_ids.end()) {
|
||||
if (!WaitForReceivedAck(client, endpoint_id, pending_payload,
|
||||
payload_header, next_chunk_offset,
|
||||
is_last_chunk)) {
|
||||
continue;
|
||||
}
|
||||
|
||||
HandleSuccessfulOutgoingChunk(
|
||||
client, endpoint_id, payload_header, payload_chunk.flags(),
|
||||
payload_chunk.offset(), payload_chunk.body().size());
|
||||
@@ -279,9 +294,11 @@ Payload::Id PayloadManager::CreateOutgoingPayload(
|
||||
NEARBY_LOGS(INFO) << "CreateOutgoingPayload: payload_id=" << payload_id;
|
||||
MutexLock lock(&mutex_);
|
||||
pending_payloads_.StartTrackingPayload(
|
||||
payload_id, absl::make_unique<PendingPayload>(std::move(internal_payload),
|
||||
endpoint_ids,
|
||||
/*is_incoming=*/false));
|
||||
payload_id,
|
||||
std::make_unique<PendingPayload>(
|
||||
std::move(internal_payload), endpoint_ids,
|
||||
/*is_incoming=*/false,
|
||||
absl::bind_front(&PayloadManager::OnPendingPayloadDestroy, this)));
|
||||
|
||||
return payload_id;
|
||||
}
|
||||
@@ -297,18 +314,17 @@ void PayloadManager::CancelAllPayloads() {
|
||||
{
|
||||
MutexLock lock(&mutex_);
|
||||
int pending_outgoing_payloads = 0;
|
||||
for (const auto& pending_id : pending_payloads_.GetAllPayloads()) {
|
||||
auto* pending = pending_payloads_.GetPayload(pending_id);
|
||||
pending_payloads_.ForEachPayload([&](PendingPayload* pending) {
|
||||
if (!pending->IsIncoming()) pending_outgoing_payloads++;
|
||||
pending->MarkLocallyCanceled();
|
||||
pending->Close(); // To unblock the sender thread, if there is no data.
|
||||
}
|
||||
});
|
||||
|
||||
if (pending_outgoing_payloads) {
|
||||
shutdown_barrier_ =
|
||||
absl::make_unique<CountDownLatch>(pending_outgoing_payloads);
|
||||
std::make_unique<CountDownLatch>(pending_outgoing_payloads);
|
||||
}
|
||||
}
|
||||
|
||||
if (shutdown_barrier_) {
|
||||
NEARBY_LOG(INFO,
|
||||
"PayloadManager: waiting for pending outgoing payloads; self=%p",
|
||||
@@ -342,9 +358,7 @@ PayloadManager::~PayloadManager() {
|
||||
NEARBY_LOG(INFO, "PayloadManager: stop tracking payloads; self=%p",
|
||||
this);
|
||||
MutexLock lock(&mutex_);
|
||||
for (const auto& pending_id : pending_payloads_.GetAllPayloads()) {
|
||||
pending_payloads_.StopTrackingPayload(pending_id);
|
||||
}
|
||||
pending_payloads_.StopTrackingAllPayloads();
|
||||
stop_latch.CountDown();
|
||||
});
|
||||
stop_latch.Await();
|
||||
@@ -419,7 +433,7 @@ void PayloadManager::SendPayload(ClientProxy* client,
|
||||
"send-payload", [this, client, endpoint_ids, payload_id, payload_type,
|
||||
resume_offset, payload_total_size]() {
|
||||
if (shutdown_.Get()) return;
|
||||
PendingPayload* pending_payload = GetPayload(payload_id);
|
||||
PendingPayloadHandle pending_payload = GetPayload(payload_id);
|
||||
if (!pending_payload) {
|
||||
RecordInvalidPayloadAnalytics(client, endpoint_ids, payload_id,
|
||||
payload_type, resume_offset,
|
||||
@@ -455,8 +469,6 @@ void PayloadManager::SendPayload(ClientProxy* client,
|
||||
next_chunk_offset, resume_offset);
|
||||
}
|
||||
|
||||
ThroughputRecorderContainer::GetInstance().StopTPRecorder(
|
||||
payload_id, PayloadDirection::OUTGOING_PAYLOAD);
|
||||
RunOnStatusUpdateThread("destroy-payload",
|
||||
[this, payload_id]()
|
||||
RUN_ON_PAYLOAD_STATUS_UPDATE_THREAD() {
|
||||
@@ -468,15 +480,14 @@ void PayloadManager::SendPayload(ClientProxy* client,
|
||||
<< ", payload_type=" << ToString(payload_type);
|
||||
}
|
||||
|
||||
PayloadManager::PendingPayload* PayloadManager::GetPayload(
|
||||
PayloadManager::PendingPayloadHandle PayloadManager::GetPayload(
|
||||
Payload::Id payload_id) const {
|
||||
MutexLock lock(&mutex_);
|
||||
return pending_payloads_.GetPayload(payload_id);
|
||||
}
|
||||
|
||||
Status PayloadManager::CancelPayload(ClientProxy* client,
|
||||
Payload::Id payload_id) {
|
||||
PendingPayload* canceled_payload = GetPayload(payload_id);
|
||||
PendingPayloadHandle canceled_payload = GetPayload(payload_id);
|
||||
if (!canceled_payload) {
|
||||
NEARBY_LOGS(INFO) << "Client requested cancel for unknown payload_id="
|
||||
<< payload_id << ", ignoring.";
|
||||
@@ -525,58 +536,70 @@ void PayloadManager::OnIncomingFrame(
|
||||
void PayloadManager::OnEndpointDisconnect(ClientProxy* client,
|
||||
const std::string& service_id,
|
||||
const std::string& endpoint_id,
|
||||
CountDownLatch barrier) {
|
||||
CountDownLatch barrier,
|
||||
DisconnectionReason reason) {
|
||||
if (shutdown_.Get()) {
|
||||
barrier.CountDown();
|
||||
return;
|
||||
}
|
||||
RunOnStatusUpdateThread(
|
||||
"payload-manager-on-disconnect",
|
||||
[this, client, endpoint_id, barrier]()
|
||||
RUN_ON_PAYLOAD_STATUS_UPDATE_THREAD() mutable {
|
||||
// Iterate through all our payloads and look for payloads associated
|
||||
// with this endpoint.
|
||||
MutexLock lock(&mutex_);
|
||||
for (const auto& payload_id : pending_payloads_.GetAllPayloads()) {
|
||||
auto* pending_payload = pending_payloads_.GetPayload(payload_id);
|
||||
if (!pending_payload) continue;
|
||||
auto endpoint_info = pending_payload->GetEndpoint(endpoint_id);
|
||||
if (!endpoint_info) continue;
|
||||
std::int64_t endpoint_offset = endpoint_info->offset;
|
||||
// Stop tracking the endpoint for this payload.
|
||||
pending_payload->RemoveEndpoints({endpoint_id});
|
||||
// |endpoint_info| is longer valid after calling RemoveEndpoints.
|
||||
endpoint_info = nullptr;
|
||||
[this, client, endpoint_id,
|
||||
barrier, reason]() RUN_ON_PAYLOAD_STATUS_UPDATE_THREAD() mutable {
|
||||
// Iterate through all our payloads and look for payloads associated
|
||||
// with this endpoint.
|
||||
MutexLock lock(&mutex_);
|
||||
pending_payloads_.ForEachPayload([&](PendingPayload* pending_payload) {
|
||||
auto endpoint_info = pending_payload->GetEndpoint(endpoint_id);
|
||||
if (!endpoint_info) return;
|
||||
std::int64_t endpoint_offset = endpoint_info->offset;
|
||||
// Stop tracking the endpoint for this payload.
|
||||
pending_payload->RemoveEndpoints({endpoint_id});
|
||||
// |endpoint_info| is longer valid after calling
|
||||
// RemoveEndpoints.
|
||||
endpoint_info = nullptr;
|
||||
|
||||
std::int64_t payload_total_size =
|
||||
pending_payload->GetInternalPayload()->GetTotalSize();
|
||||
std::int64_t payload_total_size =
|
||||
pending_payload->GetInternalPayload()->GetTotalSize();
|
||||
|
||||
// If no endpoints are left for this payload, close it.
|
||||
if (pending_payload->GetEndpoints().empty()) {
|
||||
pending_payload->Close();
|
||||
// If no endpoints are left for this payload, close it.
|
||||
if (pending_payload->GetEndpoints().empty()) {
|
||||
pending_payload->Close();
|
||||
}
|
||||
// Create the payload transfer update.
|
||||
PayloadProgressInfo update{pending_payload->GetId(),
|
||||
PayloadProgressInfo::Status::kFailure,
|
||||
payload_total_size, endpoint_offset};
|
||||
|
||||
// Send a client notification of a payload transfer failure.
|
||||
client->OnPayloadProgress(endpoint_id, update);
|
||||
|
||||
PayloadStatus payload_status;
|
||||
switch (reason) {
|
||||
case DisconnectionReason::LOCAL_DISCONNECTION:
|
||||
payload_status = PayloadStatus::LOCAL_CLIENT_DISCONNECTION;
|
||||
break;
|
||||
case DisconnectionReason::REMOTE_DISCONNECTION:
|
||||
payload_status = PayloadStatus::REMOTE_CLIENT_DISCONNECTION;
|
||||
break;
|
||||
case DisconnectionReason::IO_ERROR:
|
||||
default:
|
||||
payload_status = PayloadStatus::ENDPOINT_IO_ERROR;
|
||||
break;
|
||||
}
|
||||
|
||||
// Create the payload transfer update.
|
||||
PayloadProgressInfo update{payload_id,
|
||||
PayloadProgressInfo::Status::kFailure,
|
||||
payload_total_size, endpoint_offset};
|
||||
|
||||
// Send a client notification of a payload transfer failure.
|
||||
client->OnPayloadProgress(endpoint_id, update);
|
||||
if (pending_payload->IsIncoming()) {
|
||||
client->GetAnalyticsRecorder().OnIncomingPayloadDone(
|
||||
endpoint_id, pending_payload->GetId(), payload_status);
|
||||
} else {
|
||||
client->GetAnalyticsRecorder().OnOutgoingPayloadDone(
|
||||
endpoint_id, pending_payload->GetId(), payload_status);
|
||||
}
|
||||
});
|
||||
|
||||
if (pending_payload->IsIncoming()) {
|
||||
client->GetAnalyticsRecorder().OnIncomingPayloadDone(
|
||||
endpoint_id, pending_payload->GetId(),
|
||||
location::nearby::proto::connections::ENDPOINT_IO_ERROR);
|
||||
} else {
|
||||
client->GetAnalyticsRecorder().OnOutgoingPayloadDone(
|
||||
endpoint_id, pending_payload->GetId(),
|
||||
location::nearby::proto::connections::ENDPOINT_IO_ERROR);
|
||||
}
|
||||
}
|
||||
|
||||
barrier.CountDown();
|
||||
});
|
||||
barrier.CountDown();
|
||||
});
|
||||
}
|
||||
|
||||
location::nearby::proto::connections::PayloadStatus
|
||||
@@ -686,25 +709,37 @@ PayloadTransferFrame::PayloadChunk PayloadManager::CreatePayloadChunk(
|
||||
return payload_chunk;
|
||||
}
|
||||
|
||||
PayloadManager::PendingPayload* PayloadManager::CreateIncomingPayload(
|
||||
PayloadManager::PendingPayloadHandle PayloadManager::CreateIncomingPayload(
|
||||
const PayloadTransferFrame& frame, const std::string& endpoint_id) {
|
||||
auto internal_payload =
|
||||
CreateIncomingInternalPayload(frame, custom_save_path_);
|
||||
if (!internal_payload) {
|
||||
return nullptr;
|
||||
return PendingPayloadHandle();
|
||||
}
|
||||
|
||||
Payload::Id payload_id = internal_payload->GetId();
|
||||
NEARBY_LOGS(INFO) << "CreateIncomingPayload: payload_id=" << payload_id;
|
||||
MutexLock lock(&mutex_);
|
||||
pending_payloads_.StartTrackingPayload(
|
||||
payload_id,
|
||||
absl::make_unique<PendingPayload>(std::move(internal_payload),
|
||||
EndpointIds{endpoint_id}, true));
|
||||
|
||||
std::make_unique<PendingPayload>(
|
||||
std::move(internal_payload), EndpointIds{endpoint_id}, true,
|
||||
absl::bind_front(&PayloadManager::OnPendingPayloadDestroy, this)));
|
||||
return pending_payloads_.GetPayload(payload_id);
|
||||
}
|
||||
|
||||
void PayloadManager::OnPendingPayloadDestroy(const PendingPayload* payload) {
|
||||
NEARBY_LOGS(INFO) << "PayloadManager: destroying " << payload->ToString()
|
||||
<< " self=" << this;
|
||||
ThroughputRecorderContainer::GetInstance().StopTPRecorder(
|
||||
payload->GetId(), payload->IsIncoming()
|
||||
? PayloadDirection::INCOMING_PAYLOAD
|
||||
: PayloadDirection::OUTGOING_PAYLOAD);
|
||||
if (payload->IsIncoming()) return;
|
||||
RunOnStatusUpdateThread(
|
||||
"~PendingPayload",
|
||||
[this]() RUN_ON_PAYLOAD_STATUS_UPDATE_THREAD() { NotifyShutdown(); });
|
||||
}
|
||||
|
||||
void PayloadManager::SendClientCallbacksForFinishedOutgoingPayload(
|
||||
ClientProxy* client, const EndpointIds& finished_endpoint_ids,
|
||||
const PayloadTransferFrame::PayloadHeader& payload_header,
|
||||
@@ -716,7 +751,7 @@ void PayloadManager::SendClientCallbacksForFinishedOutgoingPayload(
|
||||
num_bytes_successfully_transferred,
|
||||
status]() RUN_ON_PAYLOAD_STATUS_UPDATE_THREAD() {
|
||||
// Make sure we're still tracking this payload.
|
||||
PendingPayload* pending_payload = GetPayload(payload_header.id());
|
||||
PendingPayloadHandle pending_payload = GetPayload(payload_header.id());
|
||||
if (!pending_payload) {
|
||||
return;
|
||||
}
|
||||
@@ -760,13 +795,14 @@ void PayloadManager::SendClientCallbacksForFinishedIncomingPayload(
|
||||
[this, client, endpoint_id, payload_header, offset_bytes,
|
||||
status]() RUN_ON_PAYLOAD_STATUS_UPDATE_THREAD() {
|
||||
// Make sure we're still tracking this payload.
|
||||
PendingPayload* pending_payload = GetPayload(payload_header.id());
|
||||
PendingPayloadHandle pending_payload = GetPayload(payload_header.id());
|
||||
if (!pending_payload) {
|
||||
return;
|
||||
}
|
||||
|
||||
// Unless we never started tracking this payload (meaning we failed to
|
||||
// even create the InternalPayload), notify the client (and close it).
|
||||
// Unless we never started tracking this payload (meaning we
|
||||
// failed to even create the InternalPayload), notify the client
|
||||
// (and close it).
|
||||
PayloadProgressInfo update{
|
||||
payload_header.id(),
|
||||
PayloadManager::PayloadStatusToTransferUpdateStatus(status),
|
||||
@@ -793,6 +829,99 @@ void PayloadManager::SendControlMessage(
|
||||
endpoint_ids);
|
||||
}
|
||||
|
||||
void PayloadManager::SendPayloadReceivedAck(
|
||||
ClientProxy* client, PendingPayload& pending_payload,
|
||||
const std::string& endpoint_id,
|
||||
const PayloadTransferFrame::PayloadHeader& payload_header,
|
||||
std::int64_t chunk_size, bool is_last_chunk) {
|
||||
if (!is_last_chunk ||
|
||||
!IsPayloadReceivedAckEnabled(client, endpoint_id, pending_payload)) {
|
||||
return;
|
||||
}
|
||||
// Send the PAYLOAD_RECEIVED_ACK to the remote endpoint for the sender asap.
|
||||
NEARBY_LOGS(INFO)
|
||||
<< "[PAYLOAD_RECEIVED_ACK] isLastChunk, receiver send ack to "
|
||||
<< endpoint_id;
|
||||
|
||||
SendControlMessage(
|
||||
{endpoint_id}, payload_header, chunk_size,
|
||||
PayloadTransferFrame::ControlMessage::PAYLOAD_RECEIVED_ACK);
|
||||
}
|
||||
|
||||
bool PayloadManager::WaitForReceivedAck(
|
||||
ClientProxy* client, const std::string& endpoint_id,
|
||||
PendingPayload& pending_payload,
|
||||
const PayloadTransferFrame::PayloadHeader& payload_header,
|
||||
std::int64_t payload_chunk_offset, bool is_last_chunk) {
|
||||
if (!is_last_chunk ||
|
||||
!IsPayloadReceivedAckEnabled(client, endpoint_id, pending_payload)) {
|
||||
return true;
|
||||
}
|
||||
|
||||
NEARBY_LOGS(INFO) << "[safe-to-disconnect] Last Chunk, sender wait for "
|
||||
"PAYLOAD_RECEIVED_ACK frame from: "
|
||||
<< endpoint_id;
|
||||
while (true) {
|
||||
PendingPayloadHandle latest_pending_payload =
|
||||
GetPayload(payload_header.id());
|
||||
// Make sure we're still tracking this payload and its associated endpoint.
|
||||
if (!latest_pending_payload) {
|
||||
return false;
|
||||
}
|
||||
|
||||
auto* endpoint_info = latest_pending_payload->GetEndpoint(endpoint_id);
|
||||
if (endpoint_info == nullptr) {
|
||||
return false;
|
||||
}
|
||||
|
||||
// Local payload cancellation
|
||||
if (latest_pending_payload->IsLocallyCanceled()) {
|
||||
HandleFinishedOutgoingPayload(client, {endpoint_id}, payload_header,
|
||||
payload_chunk_offset,
|
||||
location::nearby::proto::connections::
|
||||
PayloadStatus::LOCAL_CANCELLATION);
|
||||
return false;
|
||||
}
|
||||
// Remote payload cancellation, etc
|
||||
if (!endpoint_info->IsEndpointAvailable(client,
|
||||
endpoint_info->status.Get())) {
|
||||
HandleFinishedOutgoingPayload(
|
||||
client, {endpoint_id}, payload_header, payload_chunk_offset,
|
||||
EndpointInfoStatusToPayloadStatus(endpoint_info->status.Get()));
|
||||
return false;
|
||||
}
|
||||
{
|
||||
MutexLock lock(&endpoint_info->payload_received_ack_mutex);
|
||||
if (endpoint_info->is_payload_received_ack) {
|
||||
endpoint_info->is_payload_received_ack = false;
|
||||
return true;
|
||||
}
|
||||
Exception wait_exception = endpoint_info->payload_received_ack_cond.Wait(
|
||||
FeatureFlags::GetInstance()
|
||||
.GetFlags()
|
||||
.wait_payload_received_ack_millis);
|
||||
endpoint_info->is_payload_received_ack = false;
|
||||
if (!wait_exception.Ok()) {
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
bool PayloadManager::IsPayloadReceivedAckEnabled(
|
||||
ClientProxy* client, const std::string& endpoint_id,
|
||||
PendingPayload& pending_payload) {
|
||||
return NearbyFlags::GetInstance().GetBoolFlag(
|
||||
config_package_nearby::nearby_connections_feature::
|
||||
kEnablePayloadReceivedAck) &&
|
||||
client->IsPayloadReceivedAckEnabled(endpoint_id) &&
|
||||
(pending_payload.GetInternalPayload()->GetType() !=
|
||||
nearby::connections::PayloadTransferFrame::PayloadTransferFrame::
|
||||
PayloadHeader::BYTES);
|
||||
}
|
||||
|
||||
void PayloadManager::HandleFinishedOutgoingPayload(
|
||||
ClientProxy* client, const EndpointIds& finished_endpoint_ids,
|
||||
const PayloadTransferFrame::PayloadHeader& payload_header,
|
||||
@@ -823,7 +952,8 @@ void PayloadManager::HandleFinishedOutgoingPayload(
|
||||
// Unregister these endpoints, since we had an IO error on the physical
|
||||
// connection.
|
||||
for (const auto& endpoint_id : finished_endpoint_ids) {
|
||||
endpoint_manager_->DiscardEndpoint(client, endpoint_id);
|
||||
endpoint_manager_->DiscardEndpoint(client, endpoint_id,
|
||||
DisconnectionReason::IO_ERROR);
|
||||
}
|
||||
break;
|
||||
case location::nearby::proto::connections::PayloadStatus::REMOTE_ERROR:
|
||||
@@ -845,8 +975,6 @@ void PayloadManager::HandleFinishedIncomingPayload(
|
||||
const PayloadTransferFrame::PayloadHeader& payload_header,
|
||||
std::int64_t offset_bytes,
|
||||
location::nearby::proto::connections::PayloadStatus status) {
|
||||
ThroughputRecorderContainer::GetInstance().StopTPRecorder(
|
||||
payload_header.id(), PayloadDirection::INCOMING_PAYLOAD);
|
||||
SendClientCallbacksForFinishedIncomingPayload(
|
||||
client, endpoint_id, payload_header, offset_bytes, status);
|
||||
|
||||
@@ -903,12 +1031,14 @@ void PayloadManager::HandleSuccessfulOutgoingChunk(
|
||||
if (!is_last_chunk && payload_chunk_offset != 0) {
|
||||
NEARBY_LOGS(INFO) << "Skip the outgoing chunk update with offset="
|
||||
<< payload_chunk_offset;
|
||||
client->GetAnalyticsRecorder().OnPayloadChunkSent(
|
||||
endpoint_id, payload_header.id(), payload_chunk_body_size);
|
||||
return;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
PendingPayload* pending_payload = GetPayload(payload_header.id());
|
||||
PendingPayloadHandle pending_payload = GetPayload(payload_header.id());
|
||||
if (!pending_payload || !pending_payload->GetEndpoint(endpoint_id)) {
|
||||
NEARBY_LOGS(INFO)
|
||||
<< "HandleSuccessfulOutgoingChunk: endpoint not found: "
|
||||
@@ -949,20 +1079,7 @@ void PayloadManager::HandleSuccessfulOutgoingChunk(
|
||||
|
||||
// @PayloadManagerStatusUpdateThread
|
||||
void PayloadManager::DestroyPendingPayload(Payload::Id payload_id) {
|
||||
bool is_incoming = false;
|
||||
{
|
||||
MutexLock lock(&mutex_);
|
||||
auto pending = pending_payloads_.StopTrackingPayload(payload_id);
|
||||
if (!pending) return;
|
||||
is_incoming = pending->IsIncoming();
|
||||
const char* direction = is_incoming ? "incoming" : "outgoing";
|
||||
NEARBY_LOGS(INFO) << "PayloadManager: destroying " << direction
|
||||
<< " pending payload: self=" << this
|
||||
<< "; payload_id=" << payload_id;
|
||||
pending->Close();
|
||||
pending.reset();
|
||||
}
|
||||
if (!is_incoming) NotifyShutdown();
|
||||
pending_payloads_.StopTrackingPayload(payload_id);
|
||||
}
|
||||
|
||||
void PayloadManager::HandleSuccessfulIncomingChunk(
|
||||
@@ -998,12 +1115,14 @@ void PayloadManager::HandleSuccessfulIncomingChunk(
|
||||
if (!is_last_chunk && payload_chunk_offset != 0) {
|
||||
NEARBY_LOGS(INFO) << "Skip the incoming chunk update with offset="
|
||||
<< payload_chunk_offset;
|
||||
client->GetAnalyticsRecorder().OnPayloadChunkReceived(
|
||||
endpoint_id, payload_header.id(), payload_chunk_body_size);
|
||||
return;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
PendingPayload* pending_payload = GetPayload(payload_header.id());
|
||||
PendingPayloadHandle pending_payload = GetPayload(payload_header.id());
|
||||
if (!pending_payload) {
|
||||
return;
|
||||
}
|
||||
@@ -1044,11 +1163,11 @@ void PayloadManager::ProcessDataPacket(
|
||||
<< payload_header.id()
|
||||
<< " from endpoint_id=" << from_endpoint_id
|
||||
<< " at offset " << payload_chunk.offset();
|
||||
|
||||
PendingPayload* pending_payload;
|
||||
Payload::Id payload_id = payload_header.id();
|
||||
PendingPayloadHandle pending_payload;
|
||||
if (payload_chunk.offset() == 0) {
|
||||
ThroughputRecorderContainer::GetInstance()
|
||||
.GetTPRecorder(payload_header.id(), PayloadDirection::INCOMING_PAYLOAD)
|
||||
.GetTPRecorder(payload_id, PayloadDirection::INCOMING_PAYLOAD)
|
||||
->Start((PayloadType)payload_header.type(),
|
||||
PayloadDirection::INCOMING_PAYLOAD);
|
||||
packet_meta_data.Reset();
|
||||
@@ -1077,12 +1196,13 @@ void PayloadManager::ProcessDataPacket(
|
||||
PayloadTransferFrame::ControlMessage::PAYLOAD_ERROR);
|
||||
return;
|
||||
}
|
||||
|
||||
// Also, let the client know of this new incoming payload.
|
||||
RunOnStatusUpdateThread(
|
||||
"process-data-packet",
|
||||
[to_client, from_endpoint_id, pending_payload]()
|
||||
[to_client, from_endpoint_id,
|
||||
pending_payload = GetPayload(payload_id)]()
|
||||
RUN_ON_PAYLOAD_STATUS_UPDATE_THREAD() {
|
||||
if (!pending_payload) return;
|
||||
NEARBY_LOGS(INFO)
|
||||
<< "PayloadManager received new payload_id="
|
||||
<< pending_payload->GetInternalPayload()->GetId()
|
||||
@@ -1093,17 +1213,17 @@ void PayloadManager::ProcessDataPacket(
|
||||
});
|
||||
} else {
|
||||
pending_payload = GetPayload(payload_header.id());
|
||||
if (!pending_payload) {
|
||||
NEARBY_LOGS(WARNING) << "ProcessDataPacket: [missing] endpoint_id="
|
||||
<< from_endpoint_id
|
||||
<< "; payload_id=" << payload_header.id();
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
if (!pending_payload) {
|
||||
NEARBY_LOGS(WARNING) << "ProcessDataPacket: [missing] endpoint_id="
|
||||
<< from_endpoint_id
|
||||
<< "; payload_id=" << payload_header.id();
|
||||
return;
|
||||
}
|
||||
if (pending_payload->IsLocallyCanceled()) {
|
||||
// This incoming payload was canceled by the client. Drop this frame and do
|
||||
// all the cleanup. See go/nc-cancel-payload
|
||||
// This incoming payload was canceled by the client. Drop this frame and
|
||||
// do all the cleanup. See go/nc-cancel-payload
|
||||
NEARBY_LOGS(INFO) << "ProcessDataPacket: [cancel] endpoint_id="
|
||||
<< from_endpoint_id
|
||||
<< "; payload_id=" << pending_payload->GetId();
|
||||
@@ -1115,15 +1235,16 @@ void PayloadManager::ProcessDataPacket(
|
||||
}
|
||||
|
||||
// Update the offset for this payload. An endpoint disconnection might occur
|
||||
// from another thread and we would need to know the current offset to report
|
||||
// back to the client. For the sake of accuracy, we update the pending payload
|
||||
// here because it's after all payload terminating events are handled, but
|
||||
// right before we actually start attaching the next chunk.
|
||||
// from another thread and we would need to know the current offset to
|
||||
// report back to the client. For the sake of accuracy, we update the
|
||||
// pending payload here because it's after all payload terminating events
|
||||
// are handled, but right before we actually start attaching the next chunk.
|
||||
pending_payload->SetOffsetForEndpoint(from_endpoint_id,
|
||||
payload_chunk.offset());
|
||||
|
||||
// Save size of packet before we move it.
|
||||
std::int64_t payload_body_size = payload_chunk.body().size();
|
||||
|
||||
packet_meta_data.StartFileIo();
|
||||
if (pending_payload->GetInternalPayload()
|
||||
->AttachNextChunk(ByteArray(std::move(*payload_chunk.mutable_body())))
|
||||
@@ -1137,6 +1258,11 @@ void PayloadManager::ProcessDataPacket(
|
||||
return;
|
||||
}
|
||||
packet_meta_data.StopFileIo();
|
||||
bool is_last_chunk = (payload_chunk.flags() &
|
||||
PayloadTransferFrame::PayloadChunk::LAST_CHUNK) != 0;
|
||||
SendPayloadReceivedAck(
|
||||
to_client, *pending_payload, from_endpoint_id, payload_header,
|
||||
payload_chunk.offset() + payload_body_size, is_last_chunk);
|
||||
|
||||
HandleSuccessfulIncomingChunk(to_client, from_endpoint_id, payload_header,
|
||||
payload_chunk.flags(), payload_chunk.offset(),
|
||||
@@ -1145,15 +1271,10 @@ void PayloadManager::ProcessDataPacket(
|
||||
ThroughputRecorderContainer::GetInstance()
|
||||
.GetTPRecorder(payload_header.id(), PayloadDirection::INCOMING_PAYLOAD)
|
||||
->OnFrameReceived(medium, packet_meta_data);
|
||||
bool is_last_chunk = (payload_chunk.flags() &
|
||||
PayloadTransferFrame::PayloadChunk::LAST_CHUNK) != 0;
|
||||
if (is_last_chunk) {
|
||||
ThroughputRecorderContainer::GetInstance()
|
||||
.GetTPRecorder(payload_header.id(), PayloadDirection::INCOMING_PAYLOAD)
|
||||
->MarkAsSuccess();
|
||||
|
||||
ThroughputRecorderContainer::GetInstance().StopTPRecorder(
|
||||
payload_header.id(), PayloadDirection::INCOMING_PAYLOAD);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1165,7 +1286,7 @@ void PayloadManager::ProcessControlPacket(
|
||||
payload_transfer_frame.payload_header();
|
||||
const PayloadTransferFrame::ControlMessage& control_message =
|
||||
payload_transfer_frame.control_message();
|
||||
PendingPayload* pending_payload = GetPayload(payload_header.id());
|
||||
PendingPayloadHandle pending_payload = GetPayload(payload_header.id());
|
||||
if (!pending_payload) {
|
||||
NEARBY_LOGS(INFO) << "Got ControlMessage for unknown payload_id="
|
||||
<< payload_header.id()
|
||||
@@ -1209,6 +1330,17 @@ void PayloadManager::ProcessControlPacket(
|
||||
control_message);
|
||||
}
|
||||
break;
|
||||
case PayloadTransferFrame::ControlMessage::PAYLOAD_RECEIVED_ACK:
|
||||
if (!pending_payload->IsIncoming() &&
|
||||
IsPayloadReceivedAckEnabled(to_client, from_endpoint_id,
|
||||
*pending_payload)) {
|
||||
NEARBY_LOGS(INFO) << "[safe-to-disconnect]Sender received "
|
||||
"PAYLOAD_RECEIVED_ACK frame with id:"
|
||||
<< pending_payload->GetInternalPayload()->GetId()
|
||||
<< " from endpoint_id=" << from_endpoint_id;
|
||||
pending_payload->MarkReceivedAckFromEndpoint(from_endpoint_id);
|
||||
}
|
||||
break;
|
||||
default:
|
||||
NEARBY_LOGS(INFO) << "Unhandled control message "
|
||||
<< control_message.event() << " for payload_id="
|
||||
@@ -1266,7 +1398,8 @@ void PayloadManager::SetCustomSavePath(ClientProxy* client,
|
||||
custom_save_path_ = path;
|
||||
}
|
||||
|
||||
///////////////////////////////// EndpointInfo /////////////////////////////////
|
||||
///////////////////////////////// EndpointInfo
|
||||
////////////////////////////////////
|
||||
|
||||
PayloadManager::EndpointInfo::Status
|
||||
PayloadManager::EndpointInfo::ControlMessageEventToEndpointInfoStatus(
|
||||
@@ -1292,19 +1425,40 @@ void PayloadManager::EndpointInfo::SetStatusFromControlMessage(
|
||||
<< " based on OOB ControlMessage";
|
||||
}
|
||||
|
||||
void PayloadManager::EndpointInfo::MarkReceivedAckFromEndpoint() {
|
||||
MutexLock lock(&payload_received_ack_mutex);
|
||||
is_payload_received_ack = true;
|
||||
payload_received_ack_cond.Notify();
|
||||
}
|
||||
|
||||
bool PayloadManager::EndpointInfo::IsEndpointAvailable(
|
||||
ClientProxy* clientProxy, EndpointInfo::Status status) {
|
||||
// Pending endpointIds would be removed from the payload after
|
||||
// onPayloadTransferUpdate, but there is the racing problem that gets the
|
||||
// available endpoints before update. Here force to remove those endpoints
|
||||
// (b/227419433).
|
||||
bool is_pending_endpoint = false;
|
||||
if (clientProxy->HasPendingConnectionToEndpoint(id)) {
|
||||
is_pending_endpoint = true;
|
||||
}
|
||||
return (status == EndpointInfo::Status::kAvailable) && !is_pending_endpoint;
|
||||
}
|
||||
|
||||
//////////////////////////////// PendingPayload ////////////////////////////////
|
||||
|
||||
PayloadManager::PendingPayload::PendingPayload(
|
||||
std::unique_ptr<InternalPayload> internal_payload,
|
||||
const EndpointIds& endpoint_ids, bool is_incoming)
|
||||
const EndpointIds& endpoint_ids, bool is_incoming,
|
||||
DestroyCallback destroy_callback)
|
||||
: is_incoming_(is_incoming),
|
||||
internal_payload_(std::move(internal_payload)) {
|
||||
internal_payload_(std::move(internal_payload)),
|
||||
destroy_callback_(std::move(destroy_callback)) {
|
||||
// Initially we mark all endpoints as available.
|
||||
// Later on some may become canceled, some may experience data transfer
|
||||
// failures. Any of these situations will cause endpoint to be marked as
|
||||
// unavailable.
|
||||
for (const auto& id : endpoint_ids) {
|
||||
EndpointInfo endpoint_info{};
|
||||
EndpointInfo endpoint_info;
|
||||
endpoint_info.id = id;
|
||||
endpoint_info.status.Set(EndpointInfo::Status::kAvailable);
|
||||
|
||||
@@ -1328,6 +1482,13 @@ void PayloadManager::PendingPayload::MarkLocallyCanceled() {
|
||||
is_locally_canceled_.Set(true);
|
||||
}
|
||||
|
||||
void PayloadManager::PendingPayload::MarkReceivedAckFromEndpoint(
|
||||
const std::string& from_endpoint_id) {
|
||||
auto info = GetEndpoint(from_endpoint_id);
|
||||
if (!info) return;
|
||||
info->MarkReceivedAckFromEndpoint();
|
||||
}
|
||||
|
||||
bool PayloadManager::PendingPayload::IsIncoming() const { return is_incoming_; }
|
||||
|
||||
std::vector<const PayloadManager::EndpointInfo*>
|
||||
@@ -1384,66 +1545,123 @@ void PayloadManager::PendingPayload::SetOffsetForEndpoint(
|
||||
}
|
||||
|
||||
void PayloadManager::PendingPayload::Close() {
|
||||
bool was_closed = is_closed_.Set(true);
|
||||
if (was_closed) return;
|
||||
if (internal_payload_) internal_payload_->Close();
|
||||
close_event_.CountDown();
|
||||
}
|
||||
|
||||
bool PayloadManager::PendingPayload::WaitForClose() {
|
||||
return close_event_.Await(kWaitCloseTimeout).result();
|
||||
}
|
||||
|
||||
bool PayloadManager::PendingPayload::IsClosed() {
|
||||
return close_event_.Await(absl::ZeroDuration()).result();
|
||||
}
|
||||
|
||||
void PayloadManager::RunOnStatusUpdateThread(const std::string& name,
|
||||
std::function<void()> runnable) {
|
||||
void PayloadManager::RunOnStatusUpdateThread(
|
||||
const std::string& name, absl::AnyInvocable<void()> runnable) {
|
||||
payload_status_update_executor_.Execute(name, std::move(runnable));
|
||||
}
|
||||
|
||||
/////////////////////////////// PendingPayloads ///////////////////////////////
|
||||
/////////////////////////////// PendingPayloads
|
||||
//////////////////////////////////
|
||||
|
||||
void PayloadManager::PendingPayloads::StartTrackingPayload(
|
||||
Payload::Id payload_id, std::unique_ptr<PendingPayload> pending_payload) {
|
||||
MutexLock lock(&mutex_);
|
||||
|
||||
// If the |payload_id| is being re-used, always prefer the newer payload.
|
||||
auto it = pending_payloads_.find(payload_id);
|
||||
if (it != pending_payloads_.end()) {
|
||||
pending_payloads_.erase(payload_id);
|
||||
}
|
||||
auto pair = pending_payloads_.emplace(payload_id, std::move(pending_payload));
|
||||
NEARBY_LOGS(INFO) << "StartTrackingPayload: payload_id=" << payload_id
|
||||
<< "; inserted=" << pair.second;
|
||||
Remove(pending_payloads_.find(payload_id));
|
||||
NEARBY_LOGS(INFO) << "StartTrackingPayload: " << pending_payload->ToString();
|
||||
pending_payload->IncRefCount();
|
||||
pending_payloads_[payload_id] = std::move(pending_payload);
|
||||
}
|
||||
|
||||
std::unique_ptr<PayloadManager::PendingPayload>
|
||||
PayloadManager::PendingPayloads::StopTrackingPayload(Payload::Id payload_id) {
|
||||
void PayloadManager::PendingPayloads::StopTrackingPayload(
|
||||
Payload::Id payload_id) {
|
||||
MutexLock lock(&mutex_);
|
||||
|
||||
auto it = pending_payloads_.find(payload_id);
|
||||
if (it == pending_payloads_.end()) return {};
|
||||
|
||||
auto item = pending_payloads_.extract(it);
|
||||
return std::move(item.mapped());
|
||||
NEARBY_LOGS(INFO) << "StopTrackingPayload " << payload_id;
|
||||
Remove(pending_payloads_.find(payload_id));
|
||||
}
|
||||
|
||||
PayloadManager::PendingPayload* PayloadManager::PendingPayloads::GetPayload(
|
||||
Payload::Id payload_id) const {
|
||||
void PayloadManager::PendingPayloads::Remove(
|
||||
absl::flat_hash_map<Payload::Id, std::unique_ptr<PendingPayload>>::iterator
|
||||
it) {
|
||||
if (it != pending_payloads_.end()) {
|
||||
int refcount = it->second->DecRefCount();
|
||||
if (refcount == 0) {
|
||||
// Nobody is using the payload, we can remove it.
|
||||
NEARBY_LOGS(VERBOSE) << "Erase payload " << it->second->ToString();
|
||||
pending_payloads_.erase(it);
|
||||
} else {
|
||||
// Someone is still using the payload. Move it to the garbage bin. The
|
||||
// payload will be removed when they release it.
|
||||
NEARBY_LOGS(VERBOSE) << "Bin payload " << it->second->ToString();
|
||||
payload_garbage_bin_.push_back(
|
||||
std::move(pending_payloads_.extract(it).mapped()));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
PayloadManager::PendingPayloadHandle
|
||||
PayloadManager::PendingPayloads::GetPayload(Payload::Id payload_id) const {
|
||||
MutexLock lock(&mutex_);
|
||||
|
||||
auto item = pending_payloads_.find(payload_id);
|
||||
return item != pending_payloads_.end() ? item->second.get() : nullptr;
|
||||
if (item == pending_payloads_.end()) {
|
||||
return PendingPayloadHandle();
|
||||
}
|
||||
PendingPayload* payload = item->second.get();
|
||||
payload->IncRefCount();
|
||||
return PendingPayloadHandle(
|
||||
payload, absl::bind_front(&PendingPayloads::Release,
|
||||
const_cast<PendingPayloads*>(this)));
|
||||
}
|
||||
|
||||
std::vector<Payload::Id> PayloadManager::PendingPayloads::GetAllPayloads() {
|
||||
void PayloadManager::PendingPayloads::StopTrackingAllPayloads() {
|
||||
MutexLock lock(&mutex_);
|
||||
|
||||
std::vector<Payload::Id> result;
|
||||
for (const auto& item : pending_payloads_) {
|
||||
result.push_back(item.first);
|
||||
for (auto it = pending_payloads_.begin(); it != pending_payloads_.end();) {
|
||||
Remove(it++);
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
void PayloadManager::PendingPayloads::ForEachPayload(
|
||||
absl::AnyInvocable<void(PendingPayload*)> callback) {
|
||||
MutexLock lock(&mutex_);
|
||||
|
||||
for (const auto& item : pending_payloads_) {
|
||||
callback(item.second.get());
|
||||
}
|
||||
}
|
||||
|
||||
void PayloadManager::PendingPayloads::Release(PendingPayload* payload) {
|
||||
// Called when `PendingPayloadHandle` is destroyed.
|
||||
MutexLock lock(&mutex_);
|
||||
NEARBY_LOGS(VERBOSE) << __func__ << " " << payload->ToString();
|
||||
auto it = pending_payloads_.find(payload->GetId());
|
||||
if (it != pending_payloads_.end() && it->second.get() == payload) {
|
||||
// The payload is still tracked.
|
||||
payload->DecRefCount();
|
||||
return;
|
||||
}
|
||||
auto bin_it =
|
||||
std::find_if(payload_garbage_bin_.begin(), payload_garbage_bin_.end(),
|
||||
[payload](auto& item) { return item.get() == payload; });
|
||||
if (bin_it != payload_garbage_bin_.end()) {
|
||||
int refcount = payload->DecRefCount();
|
||||
if (refcount == 0) {
|
||||
// The payload is not tracked and it was the last reference.
|
||||
payload_garbage_bin_.erase(bin_it);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
PayloadManager::PendingPayloadHandle::PendingPayloadHandle(
|
||||
PendingPayload* payload, DestroyCallback destroy_callback)
|
||||
: payload_(payload), destroy_callback_(std::move(destroy_callback)) {}
|
||||
|
||||
PayloadManager::PendingPayloadHandle::~PendingPayloadHandle() {
|
||||
if (destroy_callback_) {
|
||||
std::move(destroy_callback_)(payload_);
|
||||
}
|
||||
}
|
||||
|
||||
std::string PayloadManager::PendingPayload::ToString() const {
|
||||
return absl::StrFormat("Payload(%s, %d)",
|
||||
IsIncoming() ? "incoming" : "outgoing", GetId());
|
||||
}
|
||||
|
||||
} // namespace connections
|
||||
|
||||
@@ -15,6 +15,7 @@
|
||||
#ifndef CORE_INTERNAL_PAYLOAD_MANAGER_H_
|
||||
#define CORE_INTERNAL_PAYLOAD_MANAGER_H_
|
||||
|
||||
#include <cstddef>
|
||||
#include <cstdint>
|
||||
#include <functional>
|
||||
#include <memory>
|
||||
@@ -23,6 +24,7 @@
|
||||
#include <vector>
|
||||
|
||||
#include "absl/container/flat_hash_map.h"
|
||||
#include "absl/functional/any_invocable.h"
|
||||
#include "connections/implementation/analytics/packet_meta_data.h"
|
||||
#include "connections/implementation/client_proxy.h"
|
||||
#include "connections/implementation/endpoint_manager.h"
|
||||
@@ -33,6 +35,7 @@
|
||||
#include "internal/platform/atomic_boolean.h"
|
||||
#include "internal/platform/atomic_reference.h"
|
||||
#include "internal/platform/byte_array.h"
|
||||
#include "internal/platform/condition_variable.h"
|
||||
#include "internal/platform/count_down_latch.h"
|
||||
#include "internal/platform/mutex.h"
|
||||
|
||||
@@ -68,7 +71,8 @@ class PayloadManager : public EndpointManager::FrameProcessor {
|
||||
// @EndpointManagerThread
|
||||
void OnEndpointDisconnect(ClientProxy* client, const std::string& service_id,
|
||||
const std::string& endpoint_id,
|
||||
CountDownLatch barrier) override;
|
||||
CountDownLatch barrier,
|
||||
DisconnectionReason reason) override;
|
||||
|
||||
void DisconnectFromEndpointManager();
|
||||
|
||||
@@ -90,21 +94,35 @@ class PayloadManager : public EndpointManager::FrameProcessor {
|
||||
|
||||
static Status ControlMessageEventToEndpointInfoStatus(
|
||||
PayloadTransferFrame::ControlMessage::EventType event);
|
||||
void MarkReceivedAckFromEndpoint();
|
||||
bool IsEndpointAvailable(ClientProxy* clientProxy,
|
||||
EndpointInfo::Status status);
|
||||
|
||||
std::string id;
|
||||
AtomicReference<Status> status{Status::kUnknown};
|
||||
std::int64_t offset = 0;
|
||||
mutable Mutex payload_received_ack_mutex;
|
||||
ConditionVariable payload_received_ack_cond{&payload_received_ack_mutex};
|
||||
bool is_payload_received_ack ABSL_GUARDED_BY(payload_received_ack_mutex) =
|
||||
false;
|
||||
};
|
||||
|
||||
// Tracks state for an InternalPayload and the endpoints associated with it.
|
||||
class PendingPayload {
|
||||
public:
|
||||
using DestroyCallback = absl::AnyInvocable<void(PendingPayload*) &&>;
|
||||
PendingPayload(std::unique_ptr<InternalPayload> internal_payload,
|
||||
const EndpointIds& endpoint_ids, bool is_incoming);
|
||||
const EndpointIds& endpoint_ids, bool is_incoming,
|
||||
DestroyCallback destroy_callback);
|
||||
PendingPayload(PendingPayload&&) = default;
|
||||
PendingPayload& operator=(PendingPayload&&) = default;
|
||||
|
||||
~PendingPayload() { Close(); }
|
||||
~PendingPayload() {
|
||||
Close();
|
||||
if (destroy_callback_) {
|
||||
std::move(destroy_callback_)(this);
|
||||
}
|
||||
}
|
||||
|
||||
Payload::Id GetId() const;
|
||||
|
||||
@@ -112,6 +130,7 @@ class PayloadManager : public EndpointManager::FrameProcessor {
|
||||
|
||||
bool IsLocallyCanceled() const;
|
||||
void MarkLocallyCanceled();
|
||||
void MarkReceivedAckFromEndpoint(const std::string& from_endpoint_id);
|
||||
bool IsIncoming() const;
|
||||
|
||||
// Gets the EndpointInfo objects for the endpoints (still) associated with
|
||||
@@ -137,24 +156,65 @@ class PayloadManager : public EndpointManager::FrameProcessor {
|
||||
void SetOffsetForEndpoint(const std::string& endpoint_id,
|
||||
std::int64_t offset) ABSL_LOCKS_EXCLUDED(mutex_);
|
||||
|
||||
// Closes internal_payload_ and triggers close_event_.
|
||||
// Closes internal_payload_.
|
||||
// Close is called when a pending peyload does not have associated
|
||||
// endpoints.
|
||||
void Close();
|
||||
|
||||
// Waits for close_event_ or for timeout to happen.
|
||||
// Returns true, if event happened, false otherwise.
|
||||
bool WaitForClose();
|
||||
bool IsClosed();
|
||||
std::string ToString() const;
|
||||
|
||||
// Ref counting for `PendingPayloads` use only. `PendingPayloads` class owns
|
||||
// all instances of `PendingPayload`.
|
||||
int IncRefCount() { return ++refcount_; }
|
||||
int DecRefCount() { return --refcount_; }
|
||||
|
||||
private:
|
||||
mutable Mutex mutex_;
|
||||
bool is_incoming_;
|
||||
AtomicBoolean is_locally_canceled_{false};
|
||||
CountDownLatch close_event_{1};
|
||||
AtomicBoolean is_closed_;
|
||||
std::unique_ptr<InternalPayload> internal_payload_;
|
||||
DestroyCallback destroy_callback_;
|
||||
absl::flat_hash_map<std::string, EndpointInfo> endpoints_
|
||||
ABSL_GUARDED_BY(mutex_);
|
||||
int refcount_ = 0;
|
||||
};
|
||||
|
||||
// A RAII handle to `PendingPayload`. Holding a `PendingPayloadHandle`
|
||||
// guarantees that `PendingPaylaod` won't be destroyed while in use.
|
||||
// Create instances with `GetPayload(Payload::Id)`.
|
||||
class PendingPayloadHandle {
|
||||
public:
|
||||
using DestroyCallback = absl::AnyInvocable<void(PendingPayload*) &&>;
|
||||
PendingPayloadHandle() = default;
|
||||
PendingPayloadHandle(PendingPayload* payload,
|
||||
DestroyCallback destroy_callback);
|
||||
PendingPayloadHandle(const PendingPayloadHandle&) = delete;
|
||||
PendingPayloadHandle(PendingPayloadHandle&& other) {
|
||||
payload_ = other.payload_;
|
||||
other.payload_ = nullptr;
|
||||
destroy_callback_ = std::move(other.destroy_callback_);
|
||||
}
|
||||
~PendingPayloadHandle();
|
||||
PendingPayloadHandle& operator=(const PendingPayloadHandle&) = delete;
|
||||
PendingPayloadHandle& operator=(PendingPayloadHandle&& other) {
|
||||
if (payload_ != nullptr && destroy_callback_) {
|
||||
std::move(destroy_callback_)(payload_);
|
||||
}
|
||||
payload_ = other.payload_;
|
||||
other.payload_ = nullptr;
|
||||
destroy_callback_ = std::move(other.destroy_callback_);
|
||||
return *this;
|
||||
}
|
||||
explicit operator bool() const { return payload_ != nullptr; }
|
||||
|
||||
PendingPayload* operator->() const { return payload_; }
|
||||
|
||||
PendingPayload& operator*() const { return *payload_; }
|
||||
|
||||
private:
|
||||
PendingPayload* payload_ = nullptr;
|
||||
DestroyCallback destroy_callback_;
|
||||
};
|
||||
|
||||
// Tracks and manages PendingPayload objects in a synchronized manner.
|
||||
@@ -166,16 +226,30 @@ class PayloadManager : public EndpointManager::FrameProcessor {
|
||||
void StartTrackingPayload(Payload::Id payload_id,
|
||||
std::unique_ptr<PendingPayload> pending_payload)
|
||||
ABSL_LOCKS_EXCLUDED(mutex_);
|
||||
std::unique_ptr<PendingPayload> StopTrackingPayload(Payload::Id payload_id)
|
||||
void StopTrackingPayload(Payload::Id payload_id)
|
||||
ABSL_LOCKS_EXCLUDED(mutex_);
|
||||
PendingPayload* GetPayload(Payload::Id payload_id) const
|
||||
void StopTrackingAllPayloads() ABSL_LOCKS_EXCLUDED(mutex_);
|
||||
PendingPayloadHandle GetPayload(Payload::Id payload_id) const
|
||||
ABSL_LOCKS_EXCLUDED(mutex_);
|
||||
// Calls `callback` for each tracked payload. The callback must not call
|
||||
// other `PendingPayloads` methods.
|
||||
void ForEachPayload(absl::AnyInvocable<void(PendingPayload*)> callback)
|
||||
ABSL_LOCKS_EXCLUDED(mutex_);
|
||||
std::vector<Payload::Id> GetAllPayloads() ABSL_LOCKS_EXCLUDED(mutex_);
|
||||
|
||||
private:
|
||||
void Release(PendingPayload* payload) ABSL_LOCKS_EXCLUDED(mutex_);
|
||||
void Remove(absl::flat_hash_map<
|
||||
Payload::Id, std::unique_ptr<PendingPayload>>::iterator it)
|
||||
ABSL_EXCLUSIVE_LOCKS_REQUIRED(mutex_);
|
||||
mutable Mutex mutex_;
|
||||
absl::flat_hash_map<Payload::Id, std::unique_ptr<PendingPayload>>
|
||||
pending_payloads_ ABSL_GUARDED_BY(mutex_);
|
||||
// When we stop tracking a payload but someone is still holding a handle to
|
||||
// the payload, we can't delete it just yet. Instead, we move it to the
|
||||
// garbage bin. When the `PendingPayloadHandle` is released, the payload
|
||||
// will be removed from the bin.
|
||||
std::vector<std::unique_ptr<PendingPayload>> payload_garbage_bin_
|
||||
ABSL_GUARDED_BY(mutex_);
|
||||
};
|
||||
|
||||
using Endpoints = std::vector<const EndpointInfo*>;
|
||||
@@ -185,8 +259,8 @@ class PayloadManager : public EndpointManager::FrameProcessor {
|
||||
static std::string ToString(EndpointInfo::Status status);
|
||||
|
||||
// Splits the endpoints for this payload by availability.
|
||||
// Returns a pair of lists of EndpointInfo*, with the first being the list of
|
||||
// still-available endpoints, and the second for unavailable endpoints.
|
||||
// Returns a pair of lists of EndpointInfo*, with the first being the list
|
||||
// of still-available endpoints, and the second for unavailable endpoints.
|
||||
static std::pair<Endpoints, Endpoints> GetAvailableAndUnavailableEndpoints(
|
||||
const PendingPayload& pending_payload);
|
||||
|
||||
@@ -203,14 +277,14 @@ class PayloadManager : public EndpointManager::FrameProcessor {
|
||||
std::int64_t offset_bytes,
|
||||
location::nearby::proto::connections::PayloadStatus status);
|
||||
|
||||
// Converts the status of an endpoint that's been set out-of-band via a remote
|
||||
// ControlMessage to the PayloadStatus for handling of that endpoint-payload
|
||||
// pair.
|
||||
// Converts the status of an endpoint that's been set out-of-band via a
|
||||
// remote ControlMessage to the PayloadStatus for handling of that
|
||||
// endpoint-payload pair.
|
||||
static location::nearby::proto::connections::PayloadStatus
|
||||
EndpointInfoStatusToPayloadStatus(EndpointInfo::Status status);
|
||||
// Converts a ControlMessage::EventType for a particular payload to a
|
||||
// PayloadStatus. Called when we've received a ControlMessage with this event
|
||||
// from a remote endpoint; thus the PayloadStatuses are REMOTE_*.
|
||||
// PayloadStatus. Called when we've received a ControlMessage with this
|
||||
// event from a remote endpoint; thus the PayloadStatuses are REMOTE_*.
|
||||
static location::nearby::proto::connections::PayloadStatus
|
||||
ControlMessageEventToPayloadStatus(
|
||||
PayloadTransferFrame::ControlMessage::EventType event);
|
||||
@@ -225,9 +299,13 @@ class PayloadManager : public EndpointManager::FrameProcessor {
|
||||
|
||||
PayloadTransferFrame::PayloadChunk CreatePayloadChunk(std::int64_t offset,
|
||||
ByteArray body);
|
||||
bool IsLastChunk(PayloadTransferFrame::PayloadChunk payload_chunk) {
|
||||
return ((payload_chunk.flags() &
|
||||
PayloadTransferFrame::PayloadChunk::LAST_CHUNK) != 0);
|
||||
}
|
||||
|
||||
PendingPayload* CreateIncomingPayload(const PayloadTransferFrame& frame,
|
||||
const std::string& endpoint_id)
|
||||
PendingPayloadHandle CreateIncomingPayload(const PayloadTransferFrame& frame,
|
||||
const std::string& endpoint_id)
|
||||
ABSL_LOCKS_EXCLUDED(mutex_);
|
||||
|
||||
Payload::Id CreateOutgoingPayload(Payload payload,
|
||||
@@ -251,8 +329,23 @@ class PayloadManager : public EndpointManager::FrameProcessor {
|
||||
std::int64_t num_bytes_successfully_transferred,
|
||||
PayloadTransferFrame::ControlMessage::EventType event_type);
|
||||
|
||||
// Handles a finished outgoing payload for the given endpointIds. All statuses
|
||||
// except for SUCCESS are handled here.
|
||||
void SendPayloadReceivedAck(
|
||||
ClientProxy* client, PendingPayload& pending_payload,
|
||||
const std::string& endpoint_id,
|
||||
const PayloadTransferFrame::PayloadHeader& payload_header,
|
||||
std::int64_t chunk_size, bool is_last_chunk);
|
||||
|
||||
bool WaitForReceivedAck(
|
||||
ClientProxy* client, const std::string& endpoint_id,
|
||||
PendingPayload& pending_payload,
|
||||
const PayloadTransferFrame::PayloadHeader& payload_header,
|
||||
std::int64_t payload_chunk_offset, bool is_last_chunk);
|
||||
bool IsPayloadReceivedAckEnabled(ClientProxy* client,
|
||||
const std::string& endpoint_id,
|
||||
PendingPayload& pending_payload);
|
||||
|
||||
// Handles a finished outgoing payload for the given endpointIds. All
|
||||
// statuses except for SUCCESS are handled here.
|
||||
void HandleFinishedOutgoingPayload(
|
||||
ClientProxy* client, const EndpointIds& finished_endpoint_ids,
|
||||
const PayloadTransferFrame::PayloadHeader& payload_header,
|
||||
@@ -293,11 +386,11 @@ class PayloadManager : public EndpointManager::FrameProcessor {
|
||||
SingleThreadExecutor* GetOutgoingPayloadExecutor(PayloadType payload_type);
|
||||
|
||||
void RunOnStatusUpdateThread(const std::string& name,
|
||||
std::function<void()> runnable);
|
||||
absl::AnyInvocable<void()> runnable);
|
||||
bool NotifyShutdown() ABSL_LOCKS_EXCLUDED(mutex_);
|
||||
void DestroyPendingPayload(Payload::Id payload_id)
|
||||
ABSL_LOCKS_EXCLUDED(mutex_);
|
||||
PendingPayload* GetPayload(Payload::Id payload_id) const
|
||||
PendingPayloadHandle GetPayload(Payload::Id payload_id) const
|
||||
ABSL_LOCKS_EXCLUDED(mutex_);
|
||||
void CancelAllPayloads() ABSL_LOCKS_EXCLUDED(mutex_);
|
||||
|
||||
@@ -317,23 +410,23 @@ class PayloadManager : public EndpointManager::FrameProcessor {
|
||||
PayloadType FramePayloadTypeToPayloadType(
|
||||
PayloadTransferFrame::PayloadHeader::PayloadType type);
|
||||
|
||||
void OnPendingPayloadDestroy(const PendingPayload* payload);
|
||||
mutable Mutex mutex_;
|
||||
std::string custom_save_path_;
|
||||
AtomicBoolean shutdown_{false};
|
||||
std::unique_ptr<CountDownLatch> shutdown_barrier_;
|
||||
int send_payload_count_ = 0;
|
||||
PendingPayloads pending_payloads_ ABSL_GUARDED_BY(mutex_);
|
||||
SingleThreadExecutor bytes_payload_executor_;
|
||||
SingleThreadExecutor file_payload_executor_;
|
||||
SingleThreadExecutor stream_payload_executor_;
|
||||
SingleThreadExecutor payload_status_update_executor_;
|
||||
|
||||
PendingPayloads pending_payloads_;
|
||||
EndpointManager* endpoint_manager_;
|
||||
|
||||
// When callback processing cannot keep the speed of callback update, the
|
||||
// callback thread will be lag to the real transfer. In order to keep sync
|
||||
// between callback and sending/receiving threads, we will skip non-important
|
||||
// callbacks during file transfer.
|
||||
// between callback and sending/receiving threads, we will skip
|
||||
// non-important callbacks during file transfer.
|
||||
mutable Mutex chunk_update_mutex_;
|
||||
int outgoing_chunk_update_count_ ABSL_GUARDED_BY(chunk_update_mutex_) = 0;
|
||||
int incoming_chunk_update_count_ ABSL_GUARDED_BY(chunk_update_mutex_) = 0;
|
||||
|
||||
@@ -14,19 +14,29 @@
|
||||
|
||||
#include "connections/implementation/payload_manager.h"
|
||||
|
||||
#include "gmock/gmock.h"
|
||||
#include "protobuf-matchers/protocol-buffer-matchers.h"
|
||||
#include <cstddef>
|
||||
#include <string>
|
||||
#include <utility>
|
||||
|
||||
#include "gtest/gtest.h"
|
||||
#include "absl/strings/string_view.h"
|
||||
#include "absl/time/time.h"
|
||||
#include "connections/implementation/simulation_user.h"
|
||||
#include "connections/listeners.h"
|
||||
#include "connections/medium_selector.h"
|
||||
#include "connections/payload.h"
|
||||
#include "connections/status.h"
|
||||
#include "internal/platform/byte_array.h"
|
||||
#include "internal/platform/count_down_latch.h"
|
||||
#include "internal/platform/logging.h"
|
||||
#include "internal/platform/medium_environment.h"
|
||||
#include "internal/platform/pipe.h"
|
||||
#include "internal/platform/system_clock.h"
|
||||
|
||||
namespace nearby {
|
||||
namespace connections {
|
||||
namespace {
|
||||
|
||||
constexpr size_t kChunkSize = 64 * 1024;
|
||||
constexpr absl::string_view kServiceId = "service-id";
|
||||
constexpr absl::string_view kDeviceA = "device-a";
|
||||
constexpr absl::string_view kDeviceB = "device-b";
|
||||
@@ -165,18 +175,14 @@ TEST_P(PayloadManagerTest, CanSendStreamPayload) {
|
||||
PayloadSimulationUser user_b(kDeviceB, GetParam());
|
||||
ASSERT_TRUE(SetupConnection(user_a, user_b));
|
||||
|
||||
auto pipe = std::make_shared<Pipe>();
|
||||
OutputStream& tx = pipe->GetOutputStream();
|
||||
|
||||
auto [input, tx] = CreatePipe();
|
||||
user_a.ExpectPayload(payload_latch_);
|
||||
const ByteArray message{std::string(kMessage)};
|
||||
// The first write to the output stream will send the first PAYLOAD_TRANSFER
|
||||
// packet with payload info and message data.
|
||||
tx.Write(message);
|
||||
tx->Write(message);
|
||||
|
||||
user_b.SendPayload(Payload([pipe]() -> InputStream& {
|
||||
return pipe->GetInputStream(); // NOLINT
|
||||
}));
|
||||
user_b.SendPayload(Payload(std::move(input)));
|
||||
ASSERT_TRUE(payload_latch_.Await(kDefaultTimeout).result());
|
||||
ASSERT_NE(user_a.GetPayload().AsStream(), nullptr);
|
||||
InputStream& rx = *user_a.GetPayload().AsStream();
|
||||
@@ -187,22 +193,22 @@ TEST_P(PayloadManagerTest, CanSendStreamPayload) {
|
||||
return info.bytes_transferred >= message.size();
|
||||
},
|
||||
kProgressTimeout));
|
||||
ByteArray result = rx.Read(Pipe::kChunkSize).result();
|
||||
ByteArray result = rx.Read(kChunkSize).result();
|
||||
EXPECT_EQ(result, message);
|
||||
NEARBY_LOG(INFO, "Packet 1 handled.");
|
||||
|
||||
tx.Write(message);
|
||||
tx->Write(message);
|
||||
EXPECT_TRUE(user_a.WaitForProgress(
|
||||
[&message](const PayloadProgressInfo& info) {
|
||||
return info.bytes_transferred >= 2 * message.size();
|
||||
},
|
||||
kProgressTimeout));
|
||||
ByteArray result2 = rx.Read(Pipe::kChunkSize).result();
|
||||
ByteArray result2 = rx.Read(kChunkSize).result();
|
||||
EXPECT_EQ(result2, message);
|
||||
NEARBY_LOG(INFO, "Packet 2 handled.");
|
||||
|
||||
rx.Close();
|
||||
tx.Close();
|
||||
tx->Close();
|
||||
NEARBY_LOG(INFO, "Test completed.");
|
||||
user_a.Stop();
|
||||
user_b.Stop();
|
||||
@@ -214,17 +220,12 @@ TEST_P(PayloadManagerTest, CanCancelPayloadOnReceiverSide) {
|
||||
PayloadSimulationUser user_a(kDeviceA, GetParam());
|
||||
PayloadSimulationUser user_b(kDeviceB, GetParam());
|
||||
ASSERT_TRUE(SetupConnection(user_a, user_b));
|
||||
|
||||
auto pipe = std::make_shared<Pipe>();
|
||||
OutputStream& tx = pipe->GetOutputStream();
|
||||
|
||||
auto [input, tx] = CreatePipe();
|
||||
user_a.ExpectPayload(payload_latch_);
|
||||
const ByteArray message{std::string(kMessage)};
|
||||
tx.Write(message);
|
||||
tx->Write(message);
|
||||
|
||||
user_b.SendPayload(Payload([pipe]() -> InputStream& {
|
||||
return pipe->GetInputStream(); // NOLINT
|
||||
}));
|
||||
user_b.SendPayload(Payload(std::move(input)));
|
||||
ASSERT_TRUE(payload_latch_.Await(kDefaultTimeout).result());
|
||||
ASSERT_NE(user_a.GetPayload().AsStream(), nullptr);
|
||||
InputStream& rx = *user_a.GetPayload().AsStream();
|
||||
@@ -235,7 +236,7 @@ TEST_P(PayloadManagerTest, CanCancelPayloadOnReceiverSide) {
|
||||
return info.bytes_transferred >= message.size();
|
||||
},
|
||||
kProgressTimeout));
|
||||
ByteArray result = rx.Read(Pipe::kChunkSize).result();
|
||||
ByteArray result = rx.Read(kChunkSize).result();
|
||||
EXPECT_EQ(result, message);
|
||||
NEARBY_LOG(INFO, "Packet 1 handled.");
|
||||
|
||||
@@ -246,7 +247,7 @@ TEST_P(PayloadManagerTest, CanCancelPayloadOnReceiverSide) {
|
||||
// Once cancel is handled, write will fail.
|
||||
int count = 0;
|
||||
while (true) {
|
||||
if (!tx.Write(message).Ok()) break;
|
||||
if (!tx->Write(message).Ok()) break;
|
||||
SystemClock::Sleep(kDefaultTimeout);
|
||||
count++;
|
||||
}
|
||||
@@ -258,7 +259,7 @@ TEST_P(PayloadManagerTest, CanCancelPayloadOnReceiverSide) {
|
||||
kProgressTimeout));
|
||||
NEARBY_LOG(INFO, "Stream cancelation received.");
|
||||
|
||||
tx.Close();
|
||||
tx->Close();
|
||||
rx.Close();
|
||||
|
||||
NEARBY_LOG(INFO, "Test completed.");
|
||||
@@ -272,17 +273,12 @@ TEST_P(PayloadManagerTest, CanCancelPayloadOnSenderSide) {
|
||||
PayloadSimulationUser user_a(kDeviceA, GetParam());
|
||||
PayloadSimulationUser user_b(kDeviceB, GetParam());
|
||||
ASSERT_TRUE(SetupConnection(user_a, user_b));
|
||||
|
||||
auto pipe = std::make_shared<Pipe>();
|
||||
OutputStream& tx = pipe->GetOutputStream();
|
||||
|
||||
auto [input, tx] = CreatePipe();
|
||||
user_a.ExpectPayload(payload_latch_);
|
||||
const ByteArray message{std::string(kMessage)};
|
||||
tx.Write(message);
|
||||
tx->Write(message);
|
||||
|
||||
user_b.SendPayload(Payload([pipe]() -> InputStream& {
|
||||
return pipe->GetInputStream(); // NOLINT
|
||||
}));
|
||||
user_b.SendPayload(Payload(std::move(input)));
|
||||
ASSERT_TRUE(payload_latch_.Await(kDefaultTimeout).result());
|
||||
ASSERT_NE(user_a.GetPayload().AsStream(), nullptr);
|
||||
InputStream& rx = *user_a.GetPayload().AsStream();
|
||||
@@ -293,7 +289,7 @@ TEST_P(PayloadManagerTest, CanCancelPayloadOnSenderSide) {
|
||||
return info.bytes_transferred >= message.size();
|
||||
},
|
||||
kProgressTimeout));
|
||||
ByteArray result = rx.Read(Pipe::kChunkSize).result();
|
||||
ByteArray result = rx.Read(kChunkSize).result();
|
||||
EXPECT_EQ(result, message);
|
||||
NEARBY_LOG(INFO, "Packet 1 handled.");
|
||||
|
||||
@@ -304,7 +300,7 @@ TEST_P(PayloadManagerTest, CanCancelPayloadOnSenderSide) {
|
||||
// Once cancel is handled, write will fail.
|
||||
int count = 0;
|
||||
while (true) {
|
||||
if (!tx.Write(message).Ok()) break;
|
||||
if (!tx->Write(message).Ok()) break;
|
||||
SystemClock::Sleep(kDefaultTimeout);
|
||||
count++;
|
||||
}
|
||||
@@ -316,7 +312,7 @@ TEST_P(PayloadManagerTest, CanCancelPayloadOnSenderSide) {
|
||||
kProgressTimeout));
|
||||
NEARBY_LOG(INFO, "Stream cancelation received.");
|
||||
|
||||
tx.Close();
|
||||
tx->Close();
|
||||
rx.Close();
|
||||
|
||||
NEARBY_LOG(INFO, "Test completed.");
|
||||
@@ -331,19 +327,14 @@ TEST_P(PayloadManagerTest, SendPayloadWithSkip_StreamPayload) {
|
||||
PayloadSimulationUser user_a(kDeviceA, GetParam());
|
||||
PayloadSimulationUser user_b(kDeviceB, GetParam());
|
||||
ASSERT_TRUE(SetupConnection(user_a, user_b));
|
||||
|
||||
auto pipe = std::make_shared<Pipe>();
|
||||
OutputStream& tx = pipe->GetOutputStream();
|
||||
|
||||
auto [input, tx] = CreatePipe();
|
||||
user_a.ExpectPayload(payload_latch_);
|
||||
const ByteArray message{std::string(kMessage)};
|
||||
// The first write to the output stream will send the first PAYLOAD_TRANSFER
|
||||
// packet with payload info and message data.
|
||||
tx.Write(message);
|
||||
tx->Write(message);
|
||||
|
||||
Payload payload([pipe]() -> InputStream& {
|
||||
return pipe->GetInputStream(); // NOLINT
|
||||
});
|
||||
Payload payload(std::move(input));
|
||||
payload.SetOffset(kOffset);
|
||||
user_b.SendPayload(std::move(payload));
|
||||
ASSERT_TRUE(payload_latch_.Await(kDefaultTimeout).result());
|
||||
@@ -356,22 +347,22 @@ TEST_P(PayloadManagerTest, SendPayloadWithSkip_StreamPayload) {
|
||||
return info.bytes_transferred >= message.size() - kOffset;
|
||||
},
|
||||
kProgressTimeout));
|
||||
ByteArray result = rx.Read(Pipe::kChunkSize).result();
|
||||
ByteArray result = rx.Read(kChunkSize).result();
|
||||
EXPECT_EQ(result, ByteArray("sage"));
|
||||
NEARBY_LOG(INFO, "Packet 1 handled.");
|
||||
|
||||
tx.Write(message);
|
||||
tx->Write(message);
|
||||
EXPECT_TRUE(user_a.WaitForProgress(
|
||||
[&message](const PayloadProgressInfo& info) {
|
||||
return info.bytes_transferred >= 2 * message.size() - kOffset;
|
||||
},
|
||||
kProgressTimeout));
|
||||
ByteArray result2 = rx.Read(Pipe::kChunkSize).result();
|
||||
ByteArray result2 = rx.Read(kChunkSize).result();
|
||||
EXPECT_EQ(result2, message);
|
||||
NEARBY_LOG(INFO, "Packet 2 handled.");
|
||||
|
||||
rx.Close();
|
||||
tx.Close();
|
||||
tx->Close();
|
||||
NEARBY_LOG(INFO, "Test completed.");
|
||||
user_a.Stop();
|
||||
user_b.Stop();
|
||||
|
||||
@@ -47,6 +47,7 @@ message V1Frame {
|
||||
AUTHENTICATION_RESULT = 9;
|
||||
AUTO_RESUME = 10;
|
||||
AUTO_RECONNECT = 11;
|
||||
BANDWIDTH_UPGRADE_RETRY = 12;
|
||||
}
|
||||
optional FrameType type = 1;
|
||||
|
||||
@@ -62,6 +63,7 @@ message V1Frame {
|
||||
optional AuthenticationResultFrame authentication_result = 10;
|
||||
optional AutoResumeFrame auto_resume = 11;
|
||||
optional AutoReconnectFrame auto_reconnect = 12;
|
||||
optional BandwidthUpgradeRetryFrame bandwidth_upgrade_retry = 13;
|
||||
}
|
||||
|
||||
message ConnectionRequestFrame {
|
||||
@@ -307,9 +309,39 @@ message BandwidthUpgradeNegotiationFrame {
|
||||
optional ClientIntroductionAck client_introduction_ack = 4;
|
||||
}
|
||||
|
||||
message BandwidthUpgradeRetryFrame {
|
||||
// Should always match cs/symbol:location.nearby.proto.connections.Medium
|
||||
// LINT.IfChange
|
||||
enum Medium {
|
||||
UNKNOWN_MEDIUM = 0;
|
||||
// 1 is reserved.
|
||||
BLUETOOTH = 2;
|
||||
WIFI_HOTSPOT = 3;
|
||||
BLE = 4;
|
||||
WIFI_LAN = 5;
|
||||
WIFI_AWARE = 6;
|
||||
NFC = 7;
|
||||
WIFI_DIRECT = 8;
|
||||
WEB_RTC = 9;
|
||||
BLE_L2CAP = 10;
|
||||
USB = 11;
|
||||
}
|
||||
// LINT.ThenChange(//depot/google3/third_party/nearby/proto/connections_enums.proto)
|
||||
|
||||
// The mediums this device supports upgrading to. This list should be filtered
|
||||
// by both the strategy and this device's individual limitations.
|
||||
repeated Medium supported_medium = 1;
|
||||
|
||||
// If true, expect the remote endpoint to send back the latest
|
||||
// supported_medium.
|
||||
optional bool is_request = 2;
|
||||
}
|
||||
|
||||
message KeepAliveFrame {
|
||||
// And ack will be sent after receiving KEEP_ALIVE frame.
|
||||
optional bool ack = 1;
|
||||
// The sequence number
|
||||
optional uint32 seq_num = 2;
|
||||
}
|
||||
|
||||
// Informs the remote side to immediately severe the socket connection.
|
||||
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user