mirror of
https://github.com/kidfromjupiter/nearby.git
synced 2026-09-14 22:56:12 -04:00
Remove unneeded functions, add UuidFromString.
This commit is contained in:
@@ -12,342 +12,40 @@
|
||||
// See the License for the specific language governing permissions and
|
||||
// limitations under the License.
|
||||
|
||||
#include <systemd/sd-id128.h>
|
||||
|
||||
#include "internal/platform/implementation/linux/utils.h"
|
||||
|
||||
// Standard C/C++ headers
|
||||
#include <cerrno>
|
||||
#include <codecvt>
|
||||
#include <cstdint>
|
||||
#include <exception>
|
||||
#include <stdexcept>
|
||||
#include <string>
|
||||
#include <vector>
|
||||
|
||||
// Third party headers
|
||||
#include "absl/strings/ascii.h"
|
||||
#include "absl/strings/str_cat.h"
|
||||
#include "absl/strings/str_format.h"
|
||||
|
||||
// Nearby connections headers
|
||||
#include "absl/strings/string_view.h"
|
||||
#include "internal/platform/bluetooth_utils.h"
|
||||
#include "internal/platform/byte_array.h"
|
||||
#include "internal/platform/implementation/crypto.h"
|
||||
#include "internal/platform/logging.h"
|
||||
#include "internal/platform/uuid.h"
|
||||
|
||||
// Linux headers
|
||||
#include <arpa/inet.h>
|
||||
#include <ifaddrs.h>
|
||||
#include <netdb.h>
|
||||
#include <netinet/in.h>
|
||||
|
||||
namespace nearby {
|
||||
namespace linux {
|
||||
namespace {
|
||||
std::optional<Uuid> UuidFromString(const std::string &uuid_str) {
|
||||
sd_id128_t uuid;
|
||||
if (auto ret = sd_id128_from_string(uuid_str.c_str(), &uuid); ret < 0)
|
||||
return std::nullopt;
|
||||
|
||||
std::string uint64_to_mac_address_string(uint64_t bluetoothAddress) {
|
||||
std::string buffer = absl::StrFormat(
|
||||
"%02llx:%02llx:%02llx:%02llx:%02llx:%02llx", bluetoothAddress >> 40,
|
||||
(bluetoothAddress >> 32) & 0xff, (bluetoothAddress >> 24) & 0xff,
|
||||
(bluetoothAddress >> 16) & 0xff, (bluetoothAddress >> 8) & 0xff,
|
||||
bluetoothAddress & 0xff);
|
||||
const int ONE = 1;
|
||||
if (*(reinterpret_cast<const char *>(&ONE)) ==
|
||||
1) { // On a little endian platform
|
||||
uint64_t msb = static_cast<uint64_t>(uuid.bytes[7]) +
|
||||
(static_cast<uint64_t>(uuid.bytes[6]) << 8) +
|
||||
(static_cast<uint64_t>(uuid.bytes[5]) << 16) +
|
||||
(static_cast<uint64_t>(uuid.bytes[4]) << 24) +
|
||||
(static_cast<uint64_t>(uuid.bytes[3]) << 32) +
|
||||
(static_cast<uint64_t>(uuid.bytes[2]) << 40) +
|
||||
(static_cast<uint64_t>(uuid.bytes[1]) << 48) +
|
||||
(static_cast<uint64_t>(uuid.bytes[0]) << 56);
|
||||
uint64_t lsb = static_cast<uint64_t>(uuid.bytes[15]) +
|
||||
(static_cast<uint64_t>(uuid.bytes[14]) << 8) +
|
||||
(static_cast<uint64_t>(uuid.bytes[13]) << 16) +
|
||||
(static_cast<uint64_t>(uuid.bytes[12]) << 24) +
|
||||
(static_cast<uint64_t>(uuid.bytes[11]) << 32) +
|
||||
(static_cast<uint64_t>(uuid.bytes[10]) << 40) +
|
||||
(static_cast<uint64_t>(uuid.bytes[9]) << 48) +
|
||||
(static_cast<uint64_t>(uuid.bytes[8]) << 56);
|
||||
return Uuid(msb, lsb);
|
||||
}
|
||||
|
||||
return absl::AsciiStrToUpper(buffer);
|
||||
return Uuid(uuid.qwords[0], uuid.qwords[1]);
|
||||
}
|
||||
|
||||
uint64_t mac_address_string_to_uint64(absl::string_view mac_address) {
|
||||
ByteArray mac_address_array = BluetoothUtils::FromString(mac_address);
|
||||
uint64_t mac_address_uint64 = 0;
|
||||
for (int i = 0; i < mac_address_array.size(); i++) {
|
||||
mac_address_uint64 <<= 8;
|
||||
mac_address_uint64 |= static_cast<uint8_t>(
|
||||
static_cast<unsigned char>(*(mac_address_array.data() + i)));
|
||||
}
|
||||
return mac_address_uint64;
|
||||
}
|
||||
|
||||
std::string ipaddr_4bytes_to_dotdecimal_string(
|
||||
absl::string_view ipaddr_4bytes) {
|
||||
union addrs {
|
||||
in_addr_t addr;
|
||||
uint8_t bits[4];
|
||||
} address;
|
||||
|
||||
address.bits[0] = ipaddr_4bytes[0];
|
||||
address.bits[1] = ipaddr_4bytes[1];
|
||||
address.bits[2] = ipaddr_4bytes[2];
|
||||
address.bits[3] = ipaddr_4bytes[3];
|
||||
|
||||
struct in_addr addr;
|
||||
|
||||
addr.s_addr = address.addr;
|
||||
char* ipv4_address = inet_ntoa(addr);
|
||||
if (ipv4_address == nullptr) {
|
||||
return {};
|
||||
}
|
||||
|
||||
return std::string(ipv4_address);
|
||||
}
|
||||
|
||||
std::string ipaddr_dotdecimal_to_4bytes_string(std::string ipv4_s) {
|
||||
if (ipv4_s.empty()) {
|
||||
return {};
|
||||
}
|
||||
|
||||
struct in_addr addr;
|
||||
|
||||
if (inet_aton(ipv4_s.c_str(), &addr) != 0) {
|
||||
return {};
|
||||
}
|
||||
|
||||
std::string ipv4_b = std::to_string(addr.s_addr);
|
||||
|
||||
return std::string();
|
||||
}
|
||||
|
||||
std::wstring string_to_wstring(std::string str) {
|
||||
std::wstring_convert<std::codecvt_utf8_utf16<wchar_t>> converter;
|
||||
return converter.from_bytes(str);
|
||||
}
|
||||
|
||||
std::string wstring_to_string(std::wstring wstr) {
|
||||
std::wstring_convert<std::codecvt_utf8_utf16<wchar_t>> converter;
|
||||
return converter.to_bytes(wstr);
|
||||
}
|
||||
|
||||
std::vector<std::string> GetIpv4Addresses() {
|
||||
std::vector<std::string> result;
|
||||
|
||||
struct ifaddrs* interface = nullptr;
|
||||
char host[NI_MAXHOST];
|
||||
|
||||
if (getifaddrs(&interface) != 0) {
|
||||
NEARBY_LOGS(ERROR) << __func__ << ": Failed to get interfaces. Error: "
|
||||
<< strerror(errno);
|
||||
freeifaddrs(interface);
|
||||
return {};
|
||||
}
|
||||
int status = 0;
|
||||
for (struct ifaddrs* ifa = interface; ifa != nullptr; ifa = ifa->ifa_next) {
|
||||
if (ifa->ifa_addr->sa_family == AF_INET) {
|
||||
status = getnameinfo(ifa->ifa_addr, sizeof(struct sockaddr_in), host,
|
||||
NI_MAXHOST, nullptr, 0, NI_NUMERICHOST);
|
||||
}
|
||||
switch (status) {
|
||||
case EAI_AGAIN:
|
||||
NEARBY_LOGS(ERROR) << __func__ << "Failed to get IP for interface: "
|
||||
<< ifa->ifa_name
|
||||
<< " : The name could not be resolved at this time. "
|
||||
<< "Try again later.";
|
||||
break;
|
||||
case EAI_BADFLAGS:
|
||||
NEARBY_LOGS(ERROR) << __func__ << "Failed to get IP for interface: "
|
||||
<< ifa->ifa_name
|
||||
<< " : The flags argument has an invalid value.";
|
||||
break;
|
||||
case EAI_FAIL:
|
||||
NEARBY_LOGS(ERROR) << __func__ << "Failed to get IP for interface: "
|
||||
<< ifa->ifa_name
|
||||
<< " : A nonrecoverable error occured.";
|
||||
break;
|
||||
case EAI_FAMILY:
|
||||
NEARBY_LOGS(ERROR) << __func__ << "Failed to get IP for interface: "
|
||||
<< ifa->ifa_name
|
||||
<< " : The address family was not recognized, "
|
||||
<< "or the address length was invalid for the "
|
||||
<< "specified family.";
|
||||
break;
|
||||
case EAI_MEMORY:
|
||||
NEARBY_LOGS(ERROR) << __func__ << "Failed to get IP for interface: "
|
||||
<< ifa->ifa_name << " : Out of memory.";
|
||||
break;
|
||||
case EAI_NONAME:
|
||||
NEARBY_LOGS(ERROR)
|
||||
<< __func__ << "Failed to get IP for interface: " << ifa->ifa_name
|
||||
<< " : The name does not resolve for the suplied arguments."
|
||||
<< " NI_NAMEREQD is set and the host's name cannot be located, "
|
||||
<< "or neither hostname nor service name were requsted.";
|
||||
break;
|
||||
case EAI_OVERFLOW:
|
||||
NEARBY_LOGS(ERROR)
|
||||
<< __func__ << "Failed to get IP for interface: " << ifa->ifa_name
|
||||
<< " : The bugger pointed to by `host` or `serv` was too small.";
|
||||
break;
|
||||
case EAI_SYSTEM:
|
||||
NEARBY_LOGS(ERROR) << __func__
|
||||
<< "A system error occured. Error code: " << errno
|
||||
<< ": " << strerror(errno);
|
||||
break;
|
||||
}
|
||||
}
|
||||
freeifaddrs(interface);
|
||||
return result;
|
||||
}
|
||||
|
||||
std::vector<std::string> Get4BytesIpv4Addresses() {
|
||||
std::vector<std::string> result;
|
||||
std::vector<std::string> ipv4_addresses = GetIpv4Addresses();
|
||||
for (const auto& ipv4_address : ipv4_addresses) {
|
||||
// Converts IP address from x.x.x.x to 4 bytes format using utils function
|
||||
result.push_back(ipaddr_dotdecimal_to_4bytes_string(ipv4_address));
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
/*
|
||||
Uuid winrt_guid_to_nearby_uuid(const ::winrt::guid& guid) {
|
||||
int64_t data1 = guid.Data1;
|
||||
int64_t data2 = guid.Data2;
|
||||
int64_t data3 = guid.Data3;
|
||||
|
||||
int64_t msb = ((data1 >> 24) & 0xff) << 56 | ((data1 >> 16) & 0xff) << 48 |
|
||||
((data1 >> 8) & 0xff) << 40 | ((data1)&0xff) << 32 |
|
||||
((data2 >> 8) & 0xff) << 24 | ((data2)&0xff) << 16 |
|
||||
((data3 >> 8) & 0xff) << 8 | (data3 & 0xff);
|
||||
|
||||
int64_t lsb =
|
||||
((int64_t)guid.Data4[0]) << 56 | ((int64_t)guid.Data4[1]) << 48 |
|
||||
((int64_t)guid.Data4[2]) << 40 | ((int64_t)guid.Data4[3]) << 32 |
|
||||
((int64_t)guid.Data4[4]) << 24 | ((int64_t)guid.Data4[5]) << 16 |
|
||||
((int64_t)guid.Data4[6]) << 8 | (int64_t)guid.Data4[7];
|
||||
|
||||
return Uuid(msb, lsb);
|
||||
}
|
||||
*/
|
||||
|
||||
/*
|
||||
winrt::guid nearby_uuid_to_winrt_guid(Uuid uuid) {
|
||||
winrt::guid guid;
|
||||
uint64_t msb = uuid.GetMostSigBits();
|
||||
guid.Data1 = ((msb >> 56) & 0xff) << 24 | ((msb >> 48) & 0xff) << 16 |
|
||||
((msb >> 40) & 0xff) << 8 | ((msb >> 32) & 0xff);
|
||||
guid.Data2 = ((msb >> 24) & 0xff) << 8 | ((msb >> 16) & 0xff);
|
||||
guid.Data3 = ((msb >> 8) & 0xff) << 8 | (msb & 0xff);
|
||||
uint64_t lsb = uuid.GetLeastSigBits();
|
||||
guid.Data4[0] = (lsb >> 56) & 0xff;
|
||||
guid.Data4[1] = (lsb >> 48) & 0xff;
|
||||
guid.Data4[2] = (lsb >> 40) & 0xff;
|
||||
guid.Data4[3] = (lsb >> 32) & 0xff;
|
||||
guid.Data4[4] = (lsb >> 24) & 0xff;
|
||||
guid.Data4[5] = (lsb >> 16) & 0xff;
|
||||
guid.Data4[6] = (lsb >> 8) & 0xff;
|
||||
guid.Data4[7] = lsb & 0xff;
|
||||
return guid;
|
||||
}
|
||||
*/
|
||||
|
||||
/*
|
||||
bool is_nearby_uuid_equal_to_winrt_guid(const Uuid& uuid,
|
||||
const ::winrt::guid& guid) {
|
||||
return uuid == winrt_guid_to_nearby_uuid(guid);
|
||||
}
|
||||
*/
|
||||
|
||||
ByteArray Sha256(absl::string_view input, size_t size) {
|
||||
ByteArray hash = nearby::Crypto::Sha256(input);
|
||||
return ByteArray{hash.data(), size};
|
||||
}
|
||||
/*
|
||||
bool InspectableReader::ReadBoolean(IInspectable inspectable) {
|
||||
if (inspectable == nullptr) {
|
||||
return false;
|
||||
}
|
||||
|
||||
auto property_value =
|
||||
inspectable.try_as<winrt::Windows::Foundation::IPropertyValue>();
|
||||
if (property_value == nullptr) {
|
||||
throw std::invalid_argument("no property value interface.");
|
||||
}
|
||||
if (property_value.Type() !=
|
||||
winrt::Windows::Foundation::PropertyType::Boolean) {
|
||||
throw std::invalid_argument("not uin16 data type.");
|
||||
}
|
||||
|
||||
return property_value.GetBoolean();
|
||||
}
|
||||
|
||||
uint16 InspectableReader::ReadUint16(IInspectable inspectable) {
|
||||
if (inspectable == nullptr) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
auto property_value =
|
||||
inspectable.try_as<winrt::Windows::Foundation::IPropertyValue>();
|
||||
if (property_value == nullptr) {
|
||||
throw std::invalid_argument("no property value interface.");
|
||||
}
|
||||
if (property_value.Type() !=
|
||||
winrt::Windows::Foundation::PropertyType::UInt16) {
|
||||
throw std::invalid_argument("not uin16 data type.");
|
||||
}
|
||||
|
||||
return property_value.GetUInt16();
|
||||
}
|
||||
|
||||
uint32 InspectableReader::ReadUint32(IInspectable inspectable) {
|
||||
if (inspectable == nullptr) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
auto property_value =
|
||||
inspectable.try_as<winrt::Windows::Foundation::IPropertyValue>();
|
||||
if (property_value == nullptr) {
|
||||
throw std::invalid_argument("no property value interface.");
|
||||
}
|
||||
if (property_value.Type() !=
|
||||
winrt::Windows::Foundation::PropertyType::UInt32) {
|
||||
throw std::invalid_argument("not uin32 data type.");
|
||||
}
|
||||
|
||||
return property_value.GetUInt32();
|
||||
}
|
||||
|
||||
std::string InspectableReader::ReadString(IInspectable inspectable) {
|
||||
if (inspectable == nullptr) {
|
||||
return "";
|
||||
}
|
||||
|
||||
auto property_value =
|
||||
inspectable.try_as<winrt::Windows::Foundation::IPropertyValue>();
|
||||
if (property_value == nullptr) {
|
||||
throw std::invalid_argument("no property value interface.");
|
||||
}
|
||||
if (property_value.Type() !=
|
||||
winrt::Windows::Foundation::PropertyType::String) {
|
||||
throw std::invalid_argument("not string data type.");
|
||||
}
|
||||
|
||||
return wstring_to_string(property_value.GetString().c_str());
|
||||
}
|
||||
|
||||
std::vector<std::string> InspectableReader::ReadStringArray(
|
||||
IInspectable inspectable) {
|
||||
std::vector<std::string> result;
|
||||
if (inspectable == nullptr) {
|
||||
return result;
|
||||
}
|
||||
|
||||
auto property_value =
|
||||
inspectable.try_as<winrt::Windows::Foundation::IPropertyValue>();
|
||||
if (property_value == nullptr) {
|
||||
throw std::invalid_argument("no property value interface.");
|
||||
}
|
||||
if (property_value.Type() !=
|
||||
winrt::Windows::Foundation::PropertyType::StringArray) {
|
||||
throw std::invalid_argument("not string array data type.");
|
||||
}
|
||||
|
||||
winrt::com_array<winrt::hstring> strings;
|
||||
property_value.GetStringArray(strings);
|
||||
|
||||
for (winrt::hstring str : strings) {
|
||||
result.push_back(winrt::to_string(str));
|
||||
}
|
||||
return result;
|
||||
}
|
||||
*/
|
||||
} // namespace
|
||||
} // namespace linux
|
||||
} // namespace nearby
|
||||
|
||||
@@ -16,68 +16,17 @@
|
||||
#define PLATFORM_IMPL_LINUX_UTILS_H_
|
||||
|
||||
#include <cstdint>
|
||||
#include <optional>
|
||||
#include <string>
|
||||
#include <vector>
|
||||
|
||||
#include "absl/strings/string_view.h"
|
||||
#include "internal/platform/byte_array.h"
|
||||
#include "internal/platform/uuid.h"
|
||||
|
||||
namespace nearby {
|
||||
namespace linux {
|
||||
|
||||
std::string uint64_to_mac_address_string(uint64_t bluetoothAddress);
|
||||
uint64_t mac_address_string_to_uint64(absl::string_view mac_address);
|
||||
|
||||
std::string ipaddr_4bytes_to_dotdecimal_string(absl::string_view ipaddr_4bytes);
|
||||
std::string ipaddr_dotdecimal_to_4bytes_string(std::string ipv4_s);
|
||||
|
||||
// Helpers to linux platform
|
||||
std::wstring string_to_wstring(std::string str);
|
||||
std::string wstring_to_string(std::wstring wstr);
|
||||
ByteArray Sha256(absl::string_view input, size_t size);
|
||||
|
||||
// Reads the IPv4 addresses
|
||||
std::vector<std::string> GetIpv4Addresses();
|
||||
std::vector<std::string> Get4BytesIpv4Addresses();
|
||||
|
||||
/*
|
||||
// Help methods to convert between Uuid and winrt::guid
|
||||
Uuid winrt_guid_to_nearby_uuid(const ::winrt::guid& guid);
|
||||
winrt::guid nearby_uuid_to_winrt_guid(Uuid uuid);
|
||||
|
||||
// Check whether Uuid and guid is the same value.
|
||||
bool is_nearby_uuid_equal_to_winrt_guid(const Uuid& uuid,
|
||||
const ::winrt::guid& guid);
|
||||
*/
|
||||
|
||||
namespace Constants {
|
||||
// The Id of the Service Name SDP attribute
|
||||
const uint16_t SdpServiceNameAttributeId = 0x100;
|
||||
|
||||
// The SDP Type of the Service Name SDP attribute.
|
||||
// The first byte in the SDP Attribute encodes the SDP Attribute Type as
|
||||
// follows:
|
||||
// - the Attribute Type size in the least significant 3 bits,
|
||||
// - the SDP Attribute Type value in the most significant 5 bits.
|
||||
const char SdpServiceNameAttributeType = (4 << 3) | 5;
|
||||
|
||||
// Possible values for the adapter type. Refer to:
|
||||
// https://learn.microsoft.com/en-us/windows/win32/api/iptypes/ns-iptypes-ip_adapter_info
|
||||
const uint16_t kInterfaceTypeEthernet = 6;
|
||||
const uint16_t kInterfaceTypeWifi = 71;
|
||||
} // namespace Constants
|
||||
|
||||
/*
|
||||
class InspectableReader {
|
||||
public:
|
||||
static bool ReadBoolean(IInspectable inspectable);
|
||||
static uint16_t ReadUint16(IInspectable inspectable);
|
||||
static uint32_t ReadUint32(IInspectable inspectable);
|
||||
static std::string ReadString(IInspectable inspectable);
|
||||
static std::vector<std::string> ReadStringArray(IInspectable inspectable);
|
||||
};
|
||||
*/
|
||||
std::optional<Uuid> UuidFromString(const std::string &uuid_str);
|
||||
|
||||
} // namespace linux
|
||||
} // namespace nearby
|
||||
|
||||
@@ -12,74 +12,25 @@
|
||||
// See the License for the specific language governing permissions and
|
||||
// limitations under the License.
|
||||
|
||||
#include "internal/platform/implementation/linux/utils.h"
|
||||
|
||||
#include <string>
|
||||
|
||||
#include "absl/strings/ascii.h"
|
||||
#include "internal/platform/implementation/linux/utils.h"
|
||||
|
||||
#include "gtest/gtest.h"
|
||||
|
||||
namespace nearby {
|
||||
namespace linux {
|
||||
|
||||
TEST(UtilsTests, MacAddressToString) {
|
||||
// Arrange
|
||||
const uint64_t input = 0x000034363bc70c71;
|
||||
std::string expected = "34:36:3B:C7:0C:71";
|
||||
TEST(UtilsTests, UuidFromStringRoundTrip) {
|
||||
std::string input = "b5209043-f493-4b38-8c34-810aa3cd1407";
|
||||
|
||||
// Act
|
||||
std::string result = uint64_to_mac_address_string(input);
|
||||
auto nearby_uuid = UuidFromString(input);
|
||||
EXPECT_TRUE(nearby_uuid.has_value());
|
||||
|
||||
// Assert
|
||||
EXPECT_EQ(result, expected);
|
||||
|
||||
EXPECT_EQ(absl::AsciiStrToLower(std::string{*nearby_uuid}),
|
||||
"b5209043-f493-4b38-8c34-810aa3cd1407");
|
||||
}
|
||||
|
||||
TEST(UtilsTests, StringToMacAddress) {
|
||||
// Arrange
|
||||
std::string input = "34:36:3B:C7:8C:71";
|
||||
const uint64_t expected = 0x000034363bc78c71;
|
||||
|
||||
// Act
|
||||
uint64_t result = mac_address_string_to_uint64(input);
|
||||
|
||||
// Assert
|
||||
EXPECT_EQ(result, expected);
|
||||
}
|
||||
|
||||
constexpr absl::string_view kIpDotdecimal{"192.168.1.37"};
|
||||
|
||||
constexpr char kIp4Bytes[] = {(char)192, (char)168, (char)1, (char)37};
|
||||
|
||||
TEST(UtilsTests, Ip4BytesToDotdecimal) {
|
||||
std::string result =
|
||||
ipaddr_4bytes_to_dotdecimal_string(absl::string_view(kIp4Bytes));
|
||||
|
||||
EXPECT_EQ(result, kIpDotdecimal);
|
||||
}
|
||||
|
||||
TEST(UtilsTests, IpDotdecimalTo4Bytes) {
|
||||
std::string result =
|
||||
ipaddr_dotdecimal_to_4bytes_string(std::string(kIpDotdecimal));
|
||||
|
||||
EXPECT_EQ(result, std::string(kIp4Bytes, 4));
|
||||
}
|
||||
|
||||
/*
|
||||
TEST(UtilsTests, ConvertBetweenWinrtGuidAndNearbyUuidSuccessfully) {
|
||||
Uuid uuid(0x123e4567e89b12d3, 0xa456426614174000);
|
||||
winrt::guid guid("{123e4567-e89b-12d3-a456-426614174000}");
|
||||
|
||||
EXPECT_EQ(uuid, winrt_guid_to_nearby_uuid(guid));
|
||||
EXPECT_EQ(nearby_uuid_to_winrt_guid(uuid), guid);
|
||||
EXPECT_TRUE(is_nearby_uuid_equal_to_winrt_guid(uuid, guid));
|
||||
}
|
||||
|
||||
TEST(UtilsTests, CompareWinrtGuidAndNearbyUuidSuccessfully) {
|
||||
Uuid uuid(0x123e4567e89b12d3, 0xa456426614174000);
|
||||
winrt::guid guid("123e4567-e89b-12d3-a456-426614074000");
|
||||
|
||||
EXPECT_NE(uuid, winrt_guid_to_nearby_uuid(guid));
|
||||
}
|
||||
*/
|
||||
|
||||
} // namespace linux
|
||||
} // namespace nearby
|
||||
|
||||
Reference in New Issue
Block a user