diff --git a/internal/platform/implementation/windows/bluetooth_classic_medium.cc b/internal/platform/implementation/windows/bluetooth_classic_medium.cc index 7dbaf96a..87a80ffd 100644 --- a/internal/platform/implementation/windows/bluetooth_classic_medium.cc +++ b/internal/platform/implementation/windows/bluetooth_classic_medium.cc @@ -16,6 +16,7 @@ #include +#include #include #include #include @@ -39,7 +40,6 @@ #include "internal/platform/implementation/windows/generated/winrt/Windows.Foundation.Collections.h" #include "internal/platform/implementation/windows/generated/winrt/base.h" #include "internal/platform/implementation/windows/utils.h" -#include "internal/platform/implementation/windows/wifi_lan.h" #include "internal/platform/logging.h" #include "internal/platform/mac_address.h" @@ -72,6 +72,16 @@ constexpr wchar_t kBluetoothSelector[] = L"System.Devices.Aep.ProtocolId:=\"{e0cbf06c-cd8b-4647-bb8a-263b43f0f974}" L"\""; +// The Id of the Service Name SDP attribute +constexpr 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. +constexpr char SdpServiceNameAttributeType = (4 << 3) | 5; + void DumpDeviceInformation( const IMapView& properties) { if (!kEnableDumpDeviceInfomation) { @@ -462,17 +472,17 @@ bool BluetoothClassicMedium::CheckSdp(RfcommDeviceService requested_service) { } auto attributes = requested_service.GetSdpRawAttributesAsync().get(); - if (!attributes.HasKey(Constants::SdpServiceNameAttributeId)) { + if (!attributes.HasKey(SdpServiceNameAttributeId)) { LOG(ERROR) << __func__ << ": Missing SdpServiceNameAttributeId."; return false; } - auto attribute_reader = DataReader::FromBuffer( - attributes.Lookup(Constants::SdpServiceNameAttributeId)); + auto attribute_reader = + DataReader::FromBuffer(attributes.Lookup(SdpServiceNameAttributeId)); auto attribute_type = attribute_reader.ReadByte(); - if (attribute_type != Constants::SdpServiceNameAttributeType) { + if (attribute_type != SdpServiceNameAttributeType) { LOG(ERROR) << __func__ << ": Missing SdpServiceNameAttributeType."; return false; } @@ -958,7 +968,7 @@ bool BluetoothClassicMedium::InitializeServiceSdpAttributes( auto sdp_writer = DataWriter(); // Write the Service Name Attribute. - sdp_writer.WriteByte(Constants::SdpServiceNameAttributeType); + sdp_writer.WriteByte(SdpServiceNameAttributeType); // The length of the UTF-8 encoded Service Name SDP Attribute. sdp_writer.WriteByte(service_name.size()); @@ -968,8 +978,8 @@ bool BluetoothClassicMedium::InitializeServiceSdpAttributes( sdp_writer.WriteString(winrt::to_hstring(service_name)); // Set the SDP Attribute on the RFCOMM Service Provider. - rfcomm_provider.SdpRawAttributes().Insert( - Constants::SdpServiceNameAttributeId, sdp_writer.DetachBuffer()); + rfcomm_provider.SdpRawAttributes().Insert(SdpServiceNameAttributeId, + sdp_writer.DetachBuffer()); return true; } catch (...) { diff --git a/internal/platform/implementation/windows/utils.cc b/internal/platform/implementation/windows/utils.cc index 62fa4562..ff166f7d 100644 --- a/internal/platform/implementation/windows/utils.cc +++ b/internal/platform/implementation/windows/utils.cc @@ -16,9 +16,6 @@ // clang-format off #include -#include -#include -#include #include #include // clang-format on @@ -33,9 +30,6 @@ #include // Nearby connections headers -#include "absl/strings/string_view.h" -#include "internal/platform/byte_array.h" -#include "internal/platform/implementation/crypto.h" #include "internal/platform/implementation/windows/string_utils.h" #include "internal/platform/logging.h" #include "internal/platform/uuid.h" @@ -44,127 +38,8 @@ #include "winrt/base.h" namespace nearby::windows { -namespace { -void AddIpUnicastAddresses(IP_ADAPTER_UNICAST_ADDRESS* unicast_addresses, - std::vector& addresses) { - std::string address; - while (unicast_addresses != nullptr) { - DWORD size = INET6_ADDRSTRLEN; // Max IP address length. - address.resize(size); - if (WSAAddressToStringA(unicast_addresses->Address.lpSockaddr, - unicast_addresses->Address.iSockaddrLength, - /*lpProtocolInfo=*/nullptr, address.data(), - &size) != 0) { - LOG(ERROR) << __func__ << ": Cannot convert address to string."; - continue; - } - address.resize(size); - addresses.push_back(address); - unicast_addresses = unicast_addresses->Next; - } -} - -void GetIpAddresses(int family, std::vector& wifi_addresses, - std::vector& ethernet_addresses, - std::vector& other_addresses) { - static constexpr int kDefaultBufferSize = 15 * 1024; // default to 15K buffer - static constexpr int kMaxBufferSize = - 45 * 1024; // Try to increase buffer 2 times. - static constexpr ULONG kDefaultFlags = - GAA_FLAG_SKIP_ANYCAST | GAA_FLAG_SKIP_MULTICAST | - GAA_FLAG_SKIP_DNS_SERVER | GAA_FLAG_SKIP_FRIENDLY_NAME; - ULONG buffer_size = 0; - // A string to own the memory for IP_ADAPTER_ADDRESSES. - std::string address_buffer; - ULONG error_code = ERROR_NO_DATA; - IP_ADAPTER_ADDRESSES* addresses = nullptr; - do { - buffer_size += kDefaultBufferSize; - address_buffer.reserve(buffer_size); - addresses = reinterpret_cast(address_buffer.data()); - error_code = GetAdaptersAddresses( - family, kDefaultFlags, /*reserved=*/nullptr, addresses, &buffer_size); - } while (error_code == ERROR_BUFFER_OVERFLOW && - buffer_size <= kMaxBufferSize); - if (error_code != ERROR_NO_DATA && error_code != NO_ERROR) { - LOG(ERROR) << __func__ - << ": Cannot get adapter addresses. Error code: " << error_code; - return; - } - if (error_code == ERROR_NO_DATA) { - LOG(INFO) << __func__ << ": No IPv4 addresses found."; - return; - } - IP_ADAPTER_ADDRESSES* next_address = addresses; - while (next_address != nullptr) { - if (next_address->OperStatus == IfOperStatusUp) { - if (next_address->IfType == IF_TYPE_ETHERNET_CSMACD) { - VLOG(1) << "Found ethernet adater: " << next_address->AdapterName - << " index: " << next_address->IfIndex - << " v6 index: " << next_address->Ipv6IfIndex; - AddIpUnicastAddresses(next_address->FirstUnicastAddress, - ethernet_addresses); - } else if (next_address->IfType == IF_TYPE_IEEE80211) { - VLOG(1) << "Found wifi adapter: " << next_address->AdapterName - << " index: " << next_address->IfIndex - << " v6 index: " << next_address->Ipv6IfIndex; - AddIpUnicastAddresses(next_address->FirstUnicastAddress, - wifi_addresses); - } else if (next_address->IfType != IF_TYPE_SOFTWARE_LOOPBACK) { - // Skip loopback interfaces. - VLOG(1) << "Found other adapter: " << next_address->AdapterName; - AddIpUnicastAddresses(next_address->FirstUnicastAddress, - other_addresses); - } - } - next_address = next_address->Next; - } -} - -} // namespace - -std::string ipaddr_4bytes_to_dotdecimal_string( - absl::string_view ipaddr_4bytes) { - if (ipaddr_4bytes.size() != 4) { - return {}; - } - - in_addr address; - address.S_un.S_un_b.s_b1 = ipaddr_4bytes[0]; - address.S_un.S_un_b.s_b2 = ipaddr_4bytes[1]; - address.S_un.S_un_b.s_b3 = ipaddr_4bytes[2]; - address.S_un.S_un_b.s_b4 = ipaddr_4bytes[3]; - char* ipv4_address = inet_ntoa(address); - 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 {}; - } - - in_addr address; - address.S_un.S_addr = inet_addr(ipv4_s.c_str()); - char ipv4_b[5]; - ipv4_b[0] = address.S_un.S_un_b.s_b1; - ipv4_b[1] = address.S_un.S_un_b.s_b2; - ipv4_b[2] = address.S_un.S_un_b.s_b3; - ipv4_b[3] = address.S_un.S_un_b.s_b4; - ipv4_b[4] = 0; - - return std::string(ipv4_b, 4); -} - -std::vector GetIpv4Addresses() { - std::vector result; - GetIpAddresses(AF_INET, result, result, result); - return result; -} +using winrt::Windows::Foundation::IInspectable; Uuid winrt_guid_to_nearby_uuid(const ::winrt::guid& guid) { int64_t data1 = guid.Data1; @@ -209,11 +84,6 @@ bool is_nearby_uuid_equal_to_winrt_guid(const Uuid& uuid, 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; diff --git a/internal/platform/implementation/windows/utils.h b/internal/platform/implementation/windows/utils.h index 52483dd9..b3910c6a 100644 --- a/internal/platform/implementation/windows/utils.h +++ b/internal/platform/implementation/windows/utils.h @@ -23,8 +23,6 @@ #include #include -#include "absl/strings/string_view.h" -#include "internal/platform/byte_array.h" #include "internal/platform/uuid.h" #include "winrt/Windows.Foundation.h" #include "winrt/base.h" @@ -32,17 +30,6 @@ namespace nearby { namespace windows { -using winrt::Windows::Foundation::IInspectable; - -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 windows platform -ByteArray Sha256(absl::string_view input, size_t size); - -// Reads the IPv4 addresses -std::vector GetIpv4Addresses(); - // 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); @@ -57,31 +44,18 @@ std::optional GetDnsHostName(); // Returns true if the system has an Intel Wi-Fi adapter. bool IsIntelWifiAdapter(); -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 ReadStringArray(IInspectable inspectable); - static GUID ReadGuid(IInspectable inspectable); + static bool ReadBoolean(winrt::Windows::Foundation::IInspectable inspectable); + static uint16_t ReadUint16( + winrt::Windows::Foundation::IInspectable inspectable); + static uint32_t ReadUint32( + winrt::Windows::Foundation::IInspectable inspectable); + static std::string ReadString( + winrt::Windows::Foundation::IInspectable inspectable); + static std::vector ReadStringArray( + winrt::Windows::Foundation::IInspectable inspectable); + static GUID ReadGuid(winrt::Windows::Foundation::IInspectable inspectable); }; } // namespace windows diff --git a/internal/platform/implementation/windows/utils_test.cc b/internal/platform/implementation/windows/utils_test.cc index 54bb7bea..5ee19153 100644 --- a/internal/platform/implementation/windows/utils_test.cc +++ b/internal/platform/implementation/windows/utils_test.cc @@ -24,8 +24,6 @@ #include #include "gtest/gtest.h" -#include "absl/strings/string_view.h" -#include "internal/platform/byte_array.h" #include "internal/platform/implementation/windows/string_utils.h" #include "internal/platform/logging.h" #include "internal/platform/uuid.h" @@ -38,62 +36,8 @@ namespace { using ::winrt::Windows::Foundation::IInspectable; using ::winrt::Windows::Foundation::PropertyValue; -constexpr absl::string_view kIpDotdecimal{"192.168.1.37"}; -constexpr char kIp4Bytes[] = {(char)192, (char)168, (char)1, (char)37}; - } // namespace -TEST(UtilsTests, Ip4BytesToDotdecimal) { - std::string result = - ipaddr_4bytes_to_dotdecimal_string(absl::string_view(kIp4Bytes, 4)); - - EXPECT_EQ(result, kIpDotdecimal); -} - -TEST(UtilsTests, Ip4BytesToDotdecimalInvalid) { - std::string result = ipaddr_4bytes_to_dotdecimal_string(absl::string_view()); - EXPECT_TRUE(result.empty()); -} - -TEST(UtilsTests, IpDotdecimalTo4Bytes) { - std::string result = - ipaddr_dotdecimal_to_4bytes_string(std::string(kIpDotdecimal)); - - EXPECT_EQ(result, std::string(kIp4Bytes, 4)); -} - -TEST(UtilsTests, IpDotdecimalTo4BytesEmpty) { - std::string result = ipaddr_dotdecimal_to_4bytes_string(""); - EXPECT_TRUE(result.empty()); -} - -TEST(UtilsTests, IpDotdecimalTo4BytesInvalid) { - std::string result = ipaddr_dotdecimal_to_4bytes_string("192.168.1.256"); - // inet_addr returns INADDR_NONE for invalid address. - char expected[] = {(char)255, (char)255, (char)255, (char)255}; - EXPECT_EQ(result, std::string(expected, 4)); -} - -TEST(UtilsTests, Sha256) { - std::string input = "Hello World"; - // sha256("Hello World") - const char expected_sha256[] = { - (char)0xa5, (char)0x91, (char)0xa6, (char)0xd4, (char)0x0b, (char)0xf4, - (char)0x20, (char)0x40, (char)0x4a, (char)0x01, (char)0x17, (char)0x33, - (char)0xcf, (char)0xb7, (char)0xb1, (char)0x90, (char)0xd6, (char)0x2c, - (char)0x65, (char)0xbf, (char)0x0b, (char)0xcd, (char)0xa3, (char)0x2b, - (char)0x57, (char)0xb2, (char)0x77, (char)0xd9, (char)0xad, (char)0x9f, - (char)0x14, (char)0x6e}; - - ByteArray result = Sha256(input, 32); - EXPECT_EQ(result.size(), 32); - EXPECT_EQ(memcmp(result.data(), expected_sha256, 32), 0); - - result = Sha256(input, 16); - EXPECT_EQ(result.size(), 16); - EXPECT_EQ(memcmp(result.data(), expected_sha256, 16), 0); -} - TEST(UtilsTests, ConvertBetweenWinrtGuidAndNearbyUuidSuccessfully) { Uuid uuid(0x123e4567e89b12d3, 0xa456426614174000); winrt::guid guid("{123e4567-e89b-12d3-a456-426614174000}"); @@ -157,16 +101,6 @@ TEST(UtilsTests, InspectableReader_ReadStringArray) { std::invalid_argument); } -TEST(UtilsTests, GetIpv4Addresses) { - LOG(ERROR) << "GetIpv4Addresses"; - std::vector addresses = GetIpv4Addresses(); - EXPECT_FALSE(addresses.empty()); - for (const auto& address : addresses) { - LOG(ERROR) << "address: " << address; - } - LOG(ERROR) << "GetIpv4Addresses done"; -} - TEST(UtilsTests, GetDnsHostName) { std::optional host_name = GetDnsHostName(); ASSERT_TRUE(host_name.has_value()); diff --git a/internal/platform/implementation/windows/wifi_lan_medium.cc b/internal/platform/implementation/windows/wifi_lan_medium.cc index f7ab9504..01200bef 100644 --- a/internal/platform/implementation/windows/wifi_lan_medium.cc +++ b/internal/platform/implementation/windows/wifi_lan_medium.cc @@ -64,6 +64,7 @@ using ::winrt::Windows::Devices::Enumeration::DeviceInformationKind; using ::winrt::Windows::Devices::Enumeration::DeviceInformationUpdate; using ::winrt::Windows::Devices::Enumeration::DeviceWatcher; using ::winrt::Windows::Foundation::Collections::IMapView; +using ::winrt::Windows::Foundation::IInspectable; using ::winrt::Windows::Networking::Connectivity::NetworkInformation; // mDNS text attributes diff --git a/internal/platform/implementation/windows/wifi_lan_server_socket.cc b/internal/platform/implementation/windows/wifi_lan_server_socket.cc index 81a39950..ea09e691 100644 --- a/internal/platform/implementation/windows/wifi_lan_server_socket.cc +++ b/internal/platform/implementation/windows/wifi_lan_server_socket.cc @@ -24,22 +24,35 @@ #include "internal/platform/exception.h" #include "internal/platform/implementation/wifi_lan.h" #include "internal/platform/implementation/windows/nearby_server_socket.h" +#include "internal/platform/implementation/windows/network_info.h" #include "internal/platform/implementation/windows/socket_address.h" -#include "internal/platform/implementation/windows/utils.h" #include "internal/platform/implementation/windows/wifi_lan.h" #include "internal/platform/logging.h" +#include "internal/platform/service_address.h" namespace nearby::windows { -// Returns the first IP address. +// Returns the first IPv4 address. std::string WifiLanServerSocket::GetIPAddress() const { // Just pick an IP address from the list of available addresses. - std::vector ip_addresses = GetIpv4Addresses(); - if (ip_addresses.empty()) { - LOG(ERROR) << "No IP addresses found."; - return ""; + const NetworkInfo& network_info = NetworkInfo::GetNetworkInfo(); + for (const NetworkInfo::InterfaceInfo& net_interface : + network_info.GetInterfaces()) { + if (net_interface.type != InterfaceType::kWifi && + net_interface.type != InterfaceType::kEthernet) { + continue; + } + for (const SocketAddress& v4_address : net_interface.ipv4_addresses) { + // Ignore link local addresses. + if (v4_address.IsV4LinkLocal()) { + continue; + } + ServiceAddress service_address = v4_address.ToServiceAddress(0); + return std::string(service_address.address.begin(), + service_address.address.end()); + } } - return ipaddr_dotdecimal_to_4bytes_string(ip_addresses.front()); + return ""; } // Blocks until either: