Files
hai007 e0e428b00b Wi-Fi Direct security implementation
PiperOrigin-RevId: 939931482
2026-06-29 11:18:55 -07:00

803 lines
27 KiB
C++

// Copyright 2020 Google LLC
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// https://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
#include "connections/implementation/offline_frames.h"
#include <array>
#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/strings/string_view.h"
#include "connections/connection_options.h"
#include "connections/implementation/flags/nearby_connections_feature_flags.h"
#include "connections/implementation/proto/offline_wire_formats.pb.h"
#include "internal/flags/nearby_flags.h"
#include "internal/platform/byte_array.h"
#include "internal/platform/mac_address.h"
#include "internal/platform/service_address.h"
namespace nearby::connections::parser {
namespace {
using ::location::nearby::connections::BandwidthUpgradeNegotiationFrame;
using ::location::nearby::connections::OfflineFrame;
using ::location::nearby::connections::OsInfo;
using ::location::nearby::connections::PayloadTransferFrame;
using ::location::nearby::connections::V1Frame;
using Medium = ::location::nearby::proto::connections::Medium;
using WifiDirectAuthType =
::location::nearby::proto::connections::WifiDirectAuthType;
using MediumMetadata = ::location::nearby::connections::MediumMetadata;
using ::location::nearby::connections::MediumRole;
using ::protobuf_matchers::EqualsProto;
using ::testing::Pointwise;
constexpr absl::string_view kEndpointId{"ABC"};
constexpr absl::string_view kEndpointName{"XYZ"};
constexpr int kNonce = 1234;
constexpr bool kSupports5ghz = true;
constexpr absl::string_view kBssid{"FF:FF:FF:FF:FF:FF"};
constexpr int kApFrequency = 2412;
constexpr std::array<Medium, 11> kMediums = {
Medium::MDNS, Medium::BLUETOOTH, Medium::WIFI_HOTSPOT,
Medium::BLE, Medium::WIFI_LAN, Medium::WIFI_AWARE,
Medium::NFC, Medium::WIFI_DIRECT, Medium::WEB_RTC,
Medium::USB, Medium::AWDL,
};
constexpr int kKeepAliveIntervalMillis = 1000;
constexpr int kKeepAliveTimeoutMillis = 5000;
TEST(OfflineFramesTest, CanParseMessageFromBytes) {
OfflineFrame tx_message;
{
tx_message.set_version(OfflineFrame::V1);
auto* v1_frame = tx_message.mutable_v1();
auto* sub_frame = v1_frame->mutable_connection_request();
v1_frame->set_type(V1Frame::CONNECTION_REQUEST);
// OSS matchers don't like implicitly comparing string_views to strings.
sub_frame->set_endpoint_id(kEndpointId);
sub_frame->set_endpoint_name(kEndpointName);
sub_frame->set_endpoint_info(kEndpointName);
sub_frame->set_nonce(kNonce);
sub_frame->set_keep_alive_interval_millis(kKeepAliveIntervalMillis);
sub_frame->set_keep_alive_timeout_millis(kKeepAliveTimeoutMillis);
auto* medium_metadata = sub_frame->mutable_medium_metadata();
medium_metadata->set_supports_5_ghz(kSupports5ghz);
medium_metadata->set_bssid(kBssid);
for (auto& medium : kMediums) {
sub_frame->add_mediums(MediumToConnectionRequestMedium(medium));
}
}
auto ret_value = FromBytes(tx_message.SerializeAsString());
ASSERT_TRUE(ret_value.ok());
const auto& rx_message = ret_value.result();
EXPECT_THAT(rx_message, EqualsProto(tx_message));
EXPECT_EQ(GetFrameType(rx_message), V1Frame::CONNECTION_REQUEST);
EXPECT_EQ(
ConnectionRequestMediumsToMediums(rx_message.v1().connection_request()),
std::vector(kMediums.begin(), kMediums.end()));
}
TEST(OfflineFramesTest, CanGenerateLegacyConnectionRequest) {
constexpr absl::string_view kExpected =
R"pb(
version: V1
v1: <
type: CONNECTION_REQUEST
connection_request: <
endpoint_id: "ABC"
endpoint_name: "XYZ"
endpoint_info: "XYZ"
nonce: 1234
medium_metadata: <
supports_5_ghz: true
bssid: "FF:FF:FF:FF:FF:FF"
ap_frequency: 2412
>
mediums: MDNS
mediums: BLUETOOTH
mediums: WIFI_HOTSPOT
mediums: BLE
mediums: WIFI_LAN
mediums: WIFI_AWARE
mediums: NFC
mediums: WIFI_DIRECT
mediums: WEB_RTC
mediums: USB
mediums: AWDL
keep_alive_interval_millis: 1000
keep_alive_timeout_millis: 5000
>
>)pb";
ConnectionInfo connection_info{std::string(kEndpointId),
ByteArray{std::string(kEndpointName)},
kNonce,
kSupports5ghz,
std::string(kBssid),
kApFrequency,
std::vector<Medium, std::allocator<Medium>>(
kMediums.begin(), kMediums.end()),
kKeepAliveIntervalMillis,
kKeepAliveTimeoutMillis};
auto response =
FromBytes(ForConnectionRequestConnections({}, connection_info));
ASSERT_TRUE(response.ok());
OfflineFrame message = response.result();
EXPECT_THAT(message, EqualsProto(kExpected));
}
TEST(OfflineFramesTest, CanGenerateConnectionsConnectionRequest) {
NearbyFlags::GetInstance().OverrideBoolFlagValue(
config_package_nearby::nearby_connections_feature::
kEnableDynamicRoleSwitch,
true);
constexpr absl::string_view kExpected =
R"pb(
version: V1
v1: <
type: CONNECTION_REQUEST
connection_request: <
endpoint_id: "ABC"
endpoint_name: "XYZ"
endpoint_info: "XYZ"
nonce: 1234
medium_metadata: <
supports_5_ghz: true
bssid: "FF:FF:FF:FF:FF:FF"
ap_frequency: 2412
medium_role: < support_wifi_hotspot_client: true >
>
mediums: MDNS
mediums: BLUETOOTH
mediums: WIFI_HOTSPOT
mediums: BLE
mediums: WIFI_LAN
mediums: WIFI_AWARE
mediums: NFC
mediums: WIFI_DIRECT
mediums: WEB_RTC
mediums: USB
mediums: AWDL
keep_alive_interval_millis: 1000
keep_alive_timeout_millis: 5000
connections_device {
endpoint_id: "ABC"
endpoint_type: CONNECTIONS_ENDPOINT
endpoint_info: "XYZ"
}
>
>)pb";
location::nearby::connections::ConnectionsDevice connections_device;
connections_device.set_endpoint_id("ABC");
connections_device.set_endpoint_type(
location::nearby::connections::CONNECTIONS_ENDPOINT);
connections_device.set_endpoint_info("XYZ");
MediumRole medium_role;
medium_role.set_support_wifi_hotspot_client(true);
ConnectionInfo connection_info{std::string(kEndpointId),
ByteArray{std::string(kEndpointName)},
kNonce,
kSupports5ghz,
std::string(kBssid),
kApFrequency,
std::vector<Medium, std::allocator<Medium>>(
kMediums.begin(), kMediums.end()),
kKeepAliveIntervalMillis,
kKeepAliveTimeoutMillis,
medium_role};
auto response = FromBytes(
ForConnectionRequestConnections(connections_device, connection_info));
ASSERT_TRUE(response.ok());
OfflineFrame message = response.result();
EXPECT_THAT(message, EqualsProto(kExpected));
}
TEST(OfflineFramesTest, CanGeneratePresenceConnectionRequest) {
constexpr absl::string_view kExpected =
R"pb(
version: V1
v1: <
type: CONNECTION_REQUEST
connection_request: <
endpoint_id: "ABC"
endpoint_name: "XYZ"
endpoint_info: "XYZ"
nonce: 1234
medium_metadata: <
supports_5_ghz: true
bssid: "FF:FF:FF:FF:FF:FF"
ap_frequency: 2412
>
mediums: MDNS
mediums: BLUETOOTH
mediums: WIFI_HOTSPOT
mediums: BLE
mediums: WIFI_LAN
mediums: WIFI_AWARE
mediums: NFC
mediums: WIFI_DIRECT
mediums: WEB_RTC
mediums: USB
mediums: AWDL
keep_alive_interval_millis: 1000
keep_alive_timeout_millis: 5000
presence_device {
endpoint_id: "ABC"
endpoint_type: PRESENCE_ENDPOINT
device_name: "TEST DEVICE"
}
>
>)pb";
ConnectionInfo connection_info{std::string(kEndpointId),
ByteArray{std::string(kEndpointName)},
kNonce,
kSupports5ghz,
std::string(kBssid),
kApFrequency,
std::vector<Medium, std::allocator<Medium>>(
kMediums.begin(), kMediums.end()),
kKeepAliveIntervalMillis,
kKeepAliveTimeoutMillis};
location::nearby::connections::PresenceDevice presence_device;
presence_device.set_endpoint_id("ABC");
presence_device.set_endpoint_type(
location::nearby::connections::PRESENCE_ENDPOINT);
presence_device.set_device_name("TEST DEVICE");
auto response =
FromBytes(ForConnectionRequestPresence(presence_device, connection_info));
ASSERT_TRUE(response.ok());
OfflineFrame message = response.result();
EXPECT_THAT(message, EqualsProto(kExpected));
}
TEST(OfflineFramesTest,
ForConnectionRequestConnectionsPopulatesWifiDirectAuthTypes) {
constexpr absl::string_view kExpected =
R"pb(
version: V1
v1: <
type: CONNECTION_REQUEST
connection_request: <
endpoint_id: "ABC"
endpoint_name: "XYZ"
endpoint_info: "XYZ"
nonce: 1234
medium_metadata: <
supports_5_ghz: true
bssid: "FF:FF:FF:FF:FF:FF"
ap_frequency: 2412
supported_wifi_direct_auth_types: WIFI_DIRECT_WITH_DEVICE_NAME
supported_wifi_direct_auth_types: WIFI_DIRECT_WITH_PASSWORD
>
mediums: MDNS
mediums: BLUETOOTH
mediums: WIFI_HOTSPOT
mediums: BLE
mediums: WIFI_LAN
mediums: WIFI_AWARE
mediums: NFC
mediums: WIFI_DIRECT
mediums: WEB_RTC
mediums: USB
mediums: AWDL
keep_alive_interval_millis: 1000
keep_alive_timeout_millis: 5000
connections_device {
endpoint_id: "ABC"
endpoint_type: CONNECTIONS_ENDPOINT
endpoint_info: "XYZ"
}
>
>)pb";
ConnectionInfo connection_info{std::string(kEndpointId),
ByteArray{std::string(kEndpointName)},
kNonce,
kSupports5ghz,
std::string(kBssid),
kApFrequency,
std::vector<Medium, std::allocator<Medium>>(
kMediums.begin(), kMediums.end()),
kKeepAliveIntervalMillis,
kKeepAliveTimeoutMillis};
connection_info.supported_wifi_direct_auth_types = {
WifiDirectAuthType::WIFI_DIRECT_WITH_DEVICE_NAME,
WifiDirectAuthType::WIFI_DIRECT_WITH_PASSWORD};
location::nearby::connections::ConnectionsDevice connections_device;
connections_device.set_endpoint_id("ABC");
connections_device.set_endpoint_type(
location::nearby::connections::CONNECTIONS_ENDPOINT);
connections_device.set_endpoint_info("XYZ");
auto response = FromBytes(
ForConnectionRequestConnections(connections_device, connection_info));
ASSERT_TRUE(response.ok());
OfflineFrame message = response.result();
EXPECT_THAT(message, EqualsProto(kExpected));
}
TEST(OfflineFramesTest, CanGenerateConnectionResponse) {
constexpr absl::string_view kExpected =
R"pb(
version: V1
v1: <
type: CONNECTION_RESPONSE
connection_response: <
status: 1
response: REJECT
os_info { type: LINUX }
multiplex_socket_bitmask: 0
safe_to_disconnect_version: 5
wifi_direct_device_name: "device_name"
>
>)pb";
OsInfo os_info;
os_info.set_type(OsInfo::LINUX);
NearbyFlags::GetInstance().OverrideInt64FlagValue(
config_package_nearby::nearby_connections_feature::
kSafeToDisconnectVersion,
5);
auto response = FromBytes(
ForConnectionResponse(1, os_info, "device_name"));
ASSERT_TRUE(response.ok());
OfflineFrame message = response.result();
EXPECT_THAT(message, EqualsProto(kExpected));
}
TEST(OfflineFramesTest, CanGenerateControlPayloadTransfer) {
PayloadTransferFrame::PayloadHeader header;
PayloadTransferFrame::ControlMessage control;
header.set_id(12345);
header.set_type(PayloadTransferFrame::PayloadHeader::BYTES);
header.set_total_size(1024);
control.set_event(PayloadTransferFrame::ControlMessage::PAYLOAD_CANCELED);
control.set_offset(150);
constexpr absl::string_view kExpected =
R"pb(
version: V1
v1: <
type: PAYLOAD_TRANSFER
payload_transfer: <
packet_type: CONTROL,
payload_header: < type: BYTES id: 12345 total_size: 1024 >
control_message: < event: PAYLOAD_CANCELED offset: 150 >
>
>)pb";
auto response = FromBytes(ForControlPayloadTransfer(header, control));
ASSERT_TRUE(response.ok());
OfflineFrame message = response.result();
EXPECT_THAT(message, EqualsProto(kExpected));
}
TEST(OfflineFramesTest, CanGenerateDataPayloadTransfer) {
PayloadTransferFrame::PayloadHeader header;
PayloadTransferFrame::PayloadChunk chunk;
header.set_id(12345);
header.set_type(PayloadTransferFrame::PayloadHeader::BYTES);
header.set_total_size(1024);
chunk.set_body("payload data");
chunk.set_offset(150);
chunk.set_flags(1);
constexpr absl::string_view kExpected =
R"pb(
version: V1
v1: <
type: PAYLOAD_TRANSFER
payload_transfer: <
packet_type: DATA,
payload_header: < type: BYTES id: 12345 total_size: 1024 >
payload_chunk: < flags: 1 offset: 150 body: "payload data" >
>
>)pb";
auto response = FromBytes(ForDataPayloadTransfer(header, chunk));
ASSERT_TRUE(response.ok());
OfflineFrame message = response.result();
EXPECT_THAT(message, EqualsProto(kExpected));
}
TEST(OfflineFramesTest, CanGeneratePayloadAckPayloadTransfer) {
constexpr absl::string_view kExpected =
R"pb(
version: V1
v1: <
type: PAYLOAD_TRANSFER
payload_transfer: <
packet_type: PAYLOAD_ACK,
payload_header: < id: 12345 total_size: -1 >
>
>)pb";
auto response = FromBytes(ForPayloadAckPayloadTransfer(12345));
ASSERT_TRUE(response.ok());
OfflineFrame message = response.result();
EXPECT_THAT(message, EqualsProto(kExpected));
}
TEST(OfflineFramesTest, CanGenerateBwuWifiHotspotPathAvailable) {
constexpr absl::string_view kExpected =
R"pb(
version: V1
v1: <
type: BANDWIDTH_UPGRADE_NEGOTIATION
bandwidth_upgrade_negotiation: <
event_type: UPGRADE_PATH_AVAILABLE
upgrade_path_info: <
medium: WIFI_HOTSPOT
wifi_hotspot_credentials: <
ssid: "ssid"
password: "password"
port: 1234
gateway: "0.0.0.0"
frequency: 2412
address_candidates: <
ip_address: "\xfe\x80\x00\x00\x00\x00\x00\x00\x4d\xb2\xb3\x5c\x22\x03\x98\xa1"
port: 1234
>
address_candidates: < ip_address: "\xc0\xa8\x00\x01" port: 5678 >
>
supports_disabling_encryption: false
supports_client_introduction_ack: true
>
>
>)pb";
BandwidthUpgradeNegotiationFrame::UpgradePathInfo::WifiHotspotCredentials
credentials;
credentials.set_ssid("ssid");
credentials.set_password("password");
credentials.set_port(1234);
credentials.set_frequency(2412);
credentials.set_gateway("0.0.0.0");
auto* address_candidate = credentials.add_address_candidates();
address_candidate->set_ip_address(std::string(
"\xfe\x80\x00\x00\x00\x00\x00\x00\x4d\xb2\xb3\x5c\x22\x03\x98\xa1", 16));
address_candidate->set_port(1234);
address_candidate = credentials.add_address_candidates();
address_candidate->set_ip_address(std::string("\xc0\xa8\x00\x01", 4));
address_candidate->set_port(5678);
auto response =
FromBytes(ForBwuWifiHotspotPathAvailable(std::move(credentials), false));
ASSERT_TRUE(response.ok());
OfflineFrame message = response.result();
EXPECT_THAT(message, EqualsProto(kExpected));
}
TEST(OfflineFramesTest, CanGenerateBwuWifiLanPathAvailable) {
constexpr absl::string_view kExpected =
R"pb(
version: V1
v1: <
type: BANDWIDTH_UPGRADE_NEGOTIATION
bandwidth_upgrade_negotiation: <
event_type: UPGRADE_PATH_AVAILABLE
upgrade_path_info: <
medium: WIFI_LAN
wifi_lan_socket: <
ip_address: "\x01\x02\x03\x04"
wifi_port: 1234
address_candidates: <
ip_address: "\x2a\x00\x79\xe0\x2e\x87\x00\x06\xb7\x28\x67\x45\x7a\xdd\x01\x53"
port: 1234
>
address_candidates: < ip_address: "\001\002\003\004" port: 1234 >
>
supports_client_introduction_ack: true
>
>
>)pb";
std::string bytes = ForBwuWifiLanPathAvailable(
{ServiceAddress{
.address = {'\x2a', '\x00', '\x79', '\xe0', '\x2e', '\x87', '\x00',
'\x06', '\xb7', '\x28', '\x67', '\x45', '\x7a', '\xdd',
'\x01', '\x53'},
.port = 1234},
ServiceAddress{.address = {'\x01', '\x02', '\x03', '\x04'},
.port = 1234}});
auto response = FromBytes(bytes);
ASSERT_TRUE(response.ok());
OfflineFrame message = response.result();
EXPECT_THAT(message, EqualsProto(kExpected));
}
TEST(OfflineFramesTest, CanGenerateBwuAwdlPathAvailable) {
constexpr absl::string_view kExpected =
R"pb(
version: V1
v1: <
type: BANDWIDTH_UPGRADE_NEGOTIATION
bandwidth_upgrade_negotiation: <
event_type: UPGRADE_PATH_AVAILABLE
upgrade_path_info: <
medium: AWDL
supports_client_introduction_ack: true
awdl_credentials: <
service_name: "service_name"
service_type: "nearby_upgrade"
password: "password"
>
supports_disabling_encryption: true
>
>
>)pb";
auto response = FromBytes(ForBwuAwdlPathAvailable(
"service_name", "nearby_upgrade", "password", true));
ASSERT_TRUE(response.ok());
OfflineFrame message = response.result();
EXPECT_THAT(message, EqualsProto(kExpected));
}
TEST(OfflineFramesTest, CanGenerateBwuWifiAwarePathAvailable) {
constexpr absl::string_view kExpected =
R"pb(
version: V1
v1: <
type: BANDWIDTH_UPGRADE_NEGOTIATION
bandwidth_upgrade_negotiation: <
event_type: UPGRADE_PATH_AVAILABLE
upgrade_path_info: <
medium: WIFI_AWARE
wifi_aware_credentials: <
service_id: "service_id"
service_info: "service_info"
password: "password"
>
supports_disabling_encryption: false
supports_client_introduction_ack: true
>
>
>)pb";
auto response = FromBytes(
ForBwuWifiAwarePathAvailable("service_id", "service_info", "password",
/*supports_disabling_encryption=*/false));
ASSERT_TRUE(response.ok());
OfflineFrame message = response.result();
EXPECT_THAT(message, EqualsProto(kExpected));
}
TEST(OfflineFramesTest, CanGenerateBwuWifiDirectPathAvailable) {
constexpr absl::string_view kExpected =
R"pb(
version: V1
v1: <
type: BANDWIDTH_UPGRADE_NEGOTIATION
bandwidth_upgrade_negotiation: <
event_type: UPGRADE_PATH_AVAILABLE
upgrade_path_info: <
medium: WIFI_DIRECT
wifi_direct_credentials: <
ssid: ""
password: ""
port: 1000
frequency: 2412
gateway: "192.168.1.1"
device_name: "NC-WifiDirectTest"
pin: "b592f7d3"
>
supports_disabling_encryption: false
supports_client_introduction_ack: true
>
>
>)pb";
auto response = FromBytes(ForBwuWifiDirectPathAvailable(
/*ssid=*/"", /*password=*/"", /*port=*/1000, /*frequency=*/2412,
/*supports_disabling_encryption=*/false, "192.168.1.1",
"NC-WifiDirectTest", "b592f7d3"));
ASSERT_TRUE(response.ok());
OfflineFrame message = response.result();
EXPECT_THAT(message, EqualsProto(kExpected));
}
TEST(OfflineFramesTest, CanGenerateBwuBluetoothPathAvailable) {
constexpr absl::string_view kExpected =
R"pb(
version: V1
v1: <
type: BANDWIDTH_UPGRADE_NEGOTIATION
bandwidth_upgrade_negotiation: <
event_type: UPGRADE_PATH_AVAILABLE
upgrade_path_info: <
medium: BLUETOOTH
bluetooth_credentials: <
service_name: "service"
mac_address: "11:22:33:44:55:66"
>
supports_client_introduction_ack: true
>
>
>)pb";
MacAddress mac_address;
MacAddress::FromString("11:22:33:44:55:66", mac_address);
auto response =
FromBytes(ForBwuBluetoothPathAvailable("service", mac_address));
ASSERT_TRUE(response.ok());
OfflineFrame message = response.result();
EXPECT_THAT(message, EqualsProto(kExpected));
}
TEST(OfflineFramesTest, CanGenerateBwuLastWrite) {
constexpr absl::string_view kExpected =
R"pb(
version: V1
v1: <
type: BANDWIDTH_UPGRADE_NEGOTIATION
bandwidth_upgrade_negotiation: < event_type: LAST_WRITE_TO_PRIOR_CHANNEL >
>)pb";
auto response = FromBytes(ForBwuLastWrite());
ASSERT_TRUE(response.ok());
OfflineFrame message = response.result();
EXPECT_THAT(message, EqualsProto(kExpected));
}
TEST(OfflineFramesTest, CanGenerateBwuSafeToClose) {
constexpr absl::string_view kExpected =
R"pb(
version: V1
v1: <
type: BANDWIDTH_UPGRADE_NEGOTIATION
bandwidth_upgrade_negotiation: < event_type: SAFE_TO_CLOSE_PRIOR_CHANNEL >
>)pb";
auto response = FromBytes(ForBwuSafeToClose());
ASSERT_TRUE(response.ok());
OfflineFrame message = response.result();
EXPECT_THAT(message, EqualsProto(kExpected));
}
TEST(OfflineFramesTest, CanGenerateBwuIntroduction) {
constexpr absl::string_view kExpected =
R"pb(
version: V1
v1: <
type: BANDWIDTH_UPGRADE_NEGOTIATION
bandwidth_upgrade_negotiation: <
event_type: CLIENT_INTRODUCTION
client_introduction: <
endpoint_id: "ABC"
supports_disabling_encryption: false
last_endpoint_id: "DEF"
>
>
>)pb";
auto response =
FromBytes(ForBwuIntroduction(std::string(kEndpointId), "DEF",
false /* supports_disabling_encryption */));
ASSERT_TRUE(response.ok());
OfflineFrame message = response.result();
EXPECT_THAT(message, EqualsProto(kExpected));
}
TEST(OfflineFramesTest, CanGenerateKeepAlive) {
constexpr absl::string_view kExpected =
R"pb(
version: V1
v1: <
type: KEEP_ALIVE
keep_alive: <>
>)pb";
auto response = FromBytes(ForKeepAlive());
ASSERT_TRUE(response.ok());
OfflineFrame message = response.result();
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";
auto response =
FromBytes(ForDisconnection(/* request_safe_to_disconnect */ true,
/* ack_safe_to_disconnect */ true));
ASSERT_TRUE(response.ok());
OfflineFrame message = response.result();
EXPECT_THAT(message, EqualsProto(kExpected));
}
TEST(OfflineFramesTest, CanGenerateBwuPathRequest) {
constexpr absl::string_view kExpected =
R"pb(
version: V1
v1: <
type: BANDWIDTH_UPGRADE_NEGOTIATION
bandwidth_upgrade_negotiation: <
event_type: UPGRADE_PATH_REQUEST
upgrade_path_info: <
medium: WIFI_HOTSPOT
upgrade_path_request: <
mediums: WIFI_HOTSPOT
medium_meta_data: <
supports_5_ghz: true
medium_role: < support_wifi_hotspot_client: true >
>
>
>
>
>)pb";
std::vector<Medium> mediums;
mediums.push_back(Medium::WIFI_HOTSPOT);
MediumRole medium_role;
medium_role.set_support_wifi_hotspot_client(true);
auto response =
FromBytes(ForBwuPathRequest(Medium::WIFI_HOTSPOT, mediums, medium_role,
/*supports_5_ghz=*/true));
ASSERT_TRUE(response.ok());
OfflineFrame message = response.result();
EXPECT_THAT(message, EqualsProto(kExpected));
}
TEST(OfflineFramesTest, WFDAuthTypeToMediumMetadataWFDAuthType) {
EXPECT_EQ(WFDAuthTypeToMediumMetadataWFDAuthType(
WifiDirectAuthType::WIFI_DIRECT_WITH_PASSWORD),
MediumMetadata::WIFI_DIRECT_WITH_PASSWORD);
EXPECT_EQ(WFDAuthTypeToMediumMetadataWFDAuthType(
WifiDirectAuthType::WIFI_DIRECT_WITH_DEVICE_NAME),
MediumMetadata::WIFI_DIRECT_WITH_DEVICE_NAME);
EXPECT_EQ(WFDAuthTypeToMediumMetadataWFDAuthType(
WifiDirectAuthType::WIFI_DIRECT_TYPE_UNKNOWN),
MediumMetadata::WIFI_DIRECT_TYPE_UNKNOWN);
}
TEST(OfflineFramesTest, MediumMetadataWFDAuthTypeToWFDAuthType) {
EXPECT_EQ(MediumMetadataWFDAuthTypeToWFDAuthType(
MediumMetadata::WIFI_DIRECT_WITH_PASSWORD),
WifiDirectAuthType::WIFI_DIRECT_WITH_PASSWORD);
EXPECT_EQ(MediumMetadataWFDAuthTypeToWFDAuthType(
MediumMetadata::WIFI_DIRECT_WITH_DEVICE_NAME),
WifiDirectAuthType::WIFI_DIRECT_WITH_DEVICE_NAME);
EXPECT_EQ(MediumMetadataWFDAuthTypeToWFDAuthType(
MediumMetadata::WIFI_DIRECT_TYPE_UNKNOWN),
WifiDirectAuthType::WIFI_DIRECT_TYPE_UNKNOWN);
}
TEST(OfflineFramesTest, MediumMetadataWFDAuthTypesToWFDAuthTypes) {
MediumMetadata medium_metadata;
medium_metadata.add_supported_wifi_direct_auth_types(
MediumMetadata::WIFI_DIRECT_WITH_PASSWORD);
medium_metadata.add_supported_wifi_direct_auth_types(
MediumMetadata::WIFI_DIRECT_WITH_DEVICE_NAME);
std::vector<WifiDirectAuthType> expected = {
WifiDirectAuthType::WIFI_DIRECT_WITH_PASSWORD,
WifiDirectAuthType::WIFI_DIRECT_WITH_DEVICE_NAME};
EXPECT_THAT(MediumMetadataWFDAuthTypesToWFDAuthTypes(medium_metadata),
Pointwise(testing::Eq(), expected));
MediumMetadata empty_medium_metadata;
EXPECT_TRUE(
MediumMetadataWFDAuthTypesToWFDAuthTypes(empty_medium_metadata).empty());
}
} // namespace
} // namespace nearby::connections::parser