diff --git a/README.md b/README.md
index 49b11e42..4f8639e5 100644
--- a/README.md
+++ b/README.md
@@ -177,12 +177,14 @@ The `details` value depends on the `type` value.
| Property | Platform | Type | Description |
| ----------------------- | --------------------------------- | --------- | -------------------------------------------------------------------------------------------------------------------------- |
| `isConnectionExpensive` | Android, iOS, macOS, Windows, Web | `boolean` | If the network connection is considered "expensive". This could be in either energy or monetary terms. |
-| `ssid` | Android, iOS (not tvOS) | `string` | The SSID of the network. May not be present, `null`, or an empty string if it cannot be determined. **On iOS, make sure your app meets at least one of the [following requirements](https://developer.apple.com/documentation/systemconfiguration/1614126-cncopycurrentnetworkinfo?language=objc#discussion). On Android, you need to have the `ACCESS_FINE_LOCATION` permission in your `AndroidManifest.xml` and accepted by the user**. |
-| `bssid` | Android, iOS (not tvOS) | `string` | The BSSID of the network. May not be present, `null`, or an empty string if it cannot be determined. **On iOS, make sure your app meets at least one of the [following requirements](https://developer.apple.com/documentation/systemconfiguration/1614126-cncopycurrentnetworkinfo?language=objc#discussion). On Android, you need to have the `ACCESS_FINE_LOCATION` permission in your `AndroidManifest.xml` and accepted by the user**. |
-| `strength` | Android | `number` | An integer number from `0` to `100` for the signal strength. May not be present if the signal strength cannot be determined. |
+| `ssid` | Android, iOS (not tvOS), Windows | `string` | The SSID of the network. May not be present, `null`, or an empty string if it cannot be determined. **On iOS, make sure your app meets at least one of the [following requirements](https://developer.apple.com/documentation/systemconfiguration/1614126-cncopycurrentnetworkinfo?language=objc#discussion). On Android, you need to have the `ACCESS_FINE_LOCATION` permission in your `AndroidManifest.xml` and accepted by the user**. |
+| `bssid` | Android, iOS (not tvOS), Windows* | `string` | The BSSID of the network. May not be present, `null`, or an empty string if it cannot be determined. **On iOS, make sure your app meets at least one of the [following requirements](https://developer.apple.com/documentation/systemconfiguration/1614126-cncopycurrentnetworkinfo?language=objc#discussion). On Android, you need to have the `ACCESS_FINE_LOCATION` permission in your `AndroidManifest.xml` and accepted by the user**. |
+| `strength` | Android, Windows | `number` | An integer number from `0` to `100` for the signal strength. May not be present if the signal strength cannot be determined. |
| `ipAddress` | Android, iOS, macOS | `string` | The external IP address. Can be in IPv4 or IPv6 format. May not be present if it cannot be determined. |
| `subnet` | Android, iOS, macOS | `string` | The subnet mask in IPv4 format. May not be present if it cannot be determined. |
-| `frequency` | Android | `number` | Network frequency. Example: For 2.4 GHz networks, the method will return 2457. May not be present if it cannot be determined. |
+| `frequency` | Android, Windows* | `number` | Network frequency. Example: For 2.4 GHz networks, the method will return 2457. May not be present if it cannot be determined. |
+
+`*` Requires `wiFiControl` capability in appxmanifest. Without it, these values will be null.
##### `type` is `cellular`
diff --git a/example/windows/NetInfoExample/Package.appxmanifest b/example/windows/NetInfoExample/Package.appxmanifest
index 1a4d8763..6143558d 100644
--- a/example/windows/NetInfoExample/Package.appxmanifest
+++ b/example/windows/NetInfoExample/Package.appxmanifest
@@ -45,5 +45,6 @@
+
\ No newline at end of file
diff --git a/windows/RNCNetInfo.sln b/windows/RNCNetInfo.sln
index 37780c14..4d724c9b 100644
--- a/windows/RNCNetInfo.sln
+++ b/windows/RNCNetInfo.sln
@@ -84,6 +84,18 @@ Global
{A990658C-CE31-4BCC-976F-0FC6B1AF693D}.Release|x64.Build.0 = Release|x64
{A990658C-CE31-4BCC-976F-0FC6B1AF693D}.Release|x86.ActiveCfg = Release|Win32
{A990658C-CE31-4BCC-976F-0FC6B1AF693D}.Release|x86.Build.0 = Release|Win32
+ {14B93DC8-FD93-4A6D-81CB-8BC96644501C}.Debug|ARM64.ActiveCfg = Debug|ARM64
+ {14B93DC8-FD93-4A6D-81CB-8BC96644501C}.Debug|ARM64.Build.0 = Debug|ARM64
+ {14B93DC8-FD93-4A6D-81CB-8BC96644501C}.Debug|x64.ActiveCfg = Debug|x64
+ {14B93DC8-FD93-4A6D-81CB-8BC96644501C}.Debug|x64.Build.0 = Debug|x64
+ {14B93DC8-FD93-4A6D-81CB-8BC96644501C}.Debug|x86.ActiveCfg = Debug|Win32
+ {14B93DC8-FD93-4A6D-81CB-8BC96644501C}.Debug|x86.Build.0 = Debug|Win32
+ {14B93DC8-FD93-4A6D-81CB-8BC96644501C}.Release|ARM64.ActiveCfg = Release|ARM64
+ {14B93DC8-FD93-4A6D-81CB-8BC96644501C}.Release|ARM64.Build.0 = Release|ARM64
+ {14B93DC8-FD93-4A6D-81CB-8BC96644501C}.Release|x64.ActiveCfg = Release|x64
+ {14B93DC8-FD93-4A6D-81CB-8BC96644501C}.Release|x64.Build.0 = Release|x64
+ {14B93DC8-FD93-4A6D-81CB-8BC96644501C}.Release|x86.ActiveCfg = Release|Win32
+ {14B93DC8-FD93-4A6D-81CB-8BC96644501C}.Release|x86.Build.0 = Release|Win32
{A9D95A91-4DB7-4F72-BEB6-FE8A5C89BFBD}.Debug|ARM64.ActiveCfg = Debug|ARM64
{A9D95A91-4DB7-4F72-BEB6-FE8A5C89BFBD}.Debug|ARM64.Build.0 = Debug|ARM64
{A9D95A91-4DB7-4F72-BEB6-FE8A5C89BFBD}.Debug|x64.ActiveCfg = Debug|x64
@@ -120,26 +132,13 @@ Global
{FCA38F3C-7C73-4C47-BE4E-32F77FA8538D}.Release|x64.Build.0 = Release|x64
{FCA38F3C-7C73-4C47-BE4E-32F77FA8538D}.Release|x86.ActiveCfg = Release|Win32
{FCA38F3C-7C73-4C47-BE4E-32F77FA8538D}.Release|x86.Build.0 = Release|Win32
- {14B93DC8-FD93-4A6D-81CB-8BC96644501C}.Debug|ARM64.ActiveCfg = Debug|ARM64
- {14B93DC8-FD93-4A6D-81CB-8BC96644501C}.Debug|ARM64.Build.0 = Debug|ARM64
- {14B93DC8-FD93-4A6D-81CB-8BC96644501C}.Debug|x64.ActiveCfg = Debug|x64
- {14B93DC8-FD93-4A6D-81CB-8BC96644501C}.Debug|x64.Build.0 = Debug|x64
- {14B93DC8-FD93-4A6D-81CB-8BC96644501C}.Debug|x86.ActiveCfg = Debug|Win32
- {14B93DC8-FD93-4A6D-81CB-8BC96644501C}.Debug|x86.Build.0 = Debug|Win32
- {14B93DC8-FD93-4A6D-81CB-8BC96644501C}.Debug|x86.Deploy.0 = Debug|Win32
- {14B93DC8-FD93-4A6D-81CB-8BC96644501C}.Release|ARM64.ActiveCfg = Release|ARM64
- {14B93DC8-FD93-4A6D-81CB-8BC96644501C}.Release|ARM64.Build.0 = Release|ARM64
- {14B93DC8-FD93-4A6D-81CB-8BC96644501C}.Release|x64.ActiveCfg = Release|x64
- {14B93DC8-FD93-4A6D-81CB-8BC96644501C}.Release|x64.Build.0 = Release|x64
- {14B93DC8-FD93-4A6D-81CB-8BC96644501C}.Release|x86.ActiveCfg = Release|Win32
- {14B93DC8-FD93-4A6D-81CB-8BC96644501C}.Release|x86.Build.0 = Release|Win32
- {14B93DC8-FD93-4A6D-81CB-8BC96644501C}.Release|x86.Deploy.0 = Release|Win32
EndGlobalSection
GlobalSection(SolutionProperties) = preSolution
HideSolutionNode = FALSE
EndGlobalSection
GlobalSection(NestedProjects) = preSolution
{A990658C-CE31-4BCC-976F-0FC6B1AF693D} = {5EA20F54-880A-49F3-99FA-4B3FE54E8AB1}
+ {14B93DC8-FD93-4A6D-81CB-8BC96644501C} = {5EA20F54-880A-49F3-99FA-4B3FE54E8AB1}
{A9D95A91-4DB7-4F72-BEB6-FE8A5C89BFBD} = {5EA20F54-880A-49F3-99FA-4B3FE54E8AB1}
{C38970C0-5FBF-4D69-90D8-CBAC225AE895} = {5EA20F54-880A-49F3-99FA-4B3FE54E8AB1}
{F7D32BD0-2749-483E-9A0D-1635EF7E3136} = {5EA20F54-880A-49F3-99FA-4B3FE54E8AB1}
@@ -148,7 +147,6 @@ Global
{2049DBE9-8D13-42C9-AE4B-413AE38FFFD0} = {5EA20F54-880A-49F3-99FA-4B3FE54E8AB1}
{84E05BFA-CBAF-4F0D-BFB6-4CE85742A57E} = {5EA20F54-880A-49F3-99FA-4B3FE54E8AB1}
{EF074BA1-2D54-4D49-A28E-5E040B47CD2E} = {5EA20F54-880A-49F3-99FA-4B3FE54E8AB1}
- {14B93DC8-FD93-4A6D-81CB-8BC96644501C} = {5EA20F54-880A-49F3-99FA-4B3FE54E8AB1}
EndGlobalSection
GlobalSection(ExtensibilityGlobals) = postSolution
SolutionGuid = {D43FAD39-F619-437D-BB40-04A3982ACB6A}
diff --git a/windows/RNCNetInfoCPP/NetworkInfo.cpp b/windows/RNCNetInfoCPP/NetworkInfo.cpp
deleted file mode 100644
index 74c51c68..00000000
--- a/windows/RNCNetInfoCPP/NetworkInfo.cpp
+++ /dev/null
@@ -1,109 +0,0 @@
-// Copyright (c) Microsoft Corporation. All rights reserved.
-// Licensed under the MIT License.
-
-#include "pch.h"
-#include "NetworkInfo.h"
-
-namespace winrt{
- using namespace Windows::Foundation;
- using namespace Windows::Networking::Connectivity;
-}
-
-namespace winrt::ReactNativeNetInfo::implementation {
-
- NetworkInfo::NetworkInfo() {
- GetConnectionProfile();
-
- m_networkStatusChangedRevoker = NetworkInformation::NetworkStatusChanged(winrt::auto_revoke, [&](const winrt::IInspectable& sender) {
- GetConnectionProfile();
-
- if (m_statusChangedHandler) {
- m_statusChangedHandler(sender);
- }
- });
- }
-
- void NetworkInfo::StatusChanged(const NetworkStatusChangedEventHandler& handler) {
- m_statusChangedHandler = handler;
- }
-
- bool NetworkInfo::IsConnected() {
- return m_profile && m_profile.GetNetworkConnectivityLevel() != NetworkConnectivityLevel::None;
- }
-
- void NetworkInfo::GetConnectionProfile() {
- try
- {
- m_profile = NetworkInformation::GetInternetConnectionProfile();
- }
- catch (const std::exception&)
- {
- m_profile = { nullptr };
- }
- }
-
- std::string NetworkInfo::ConnectivityType() {
- if (!m_profile) {
- return CONNECTION_TYPE_NONE;
- }
- if (m_profile.IsWlanConnectionProfile()) {
- return CONNECTION_TYPE_WIFI;
- }
- if (m_profile.IsWwanConnectionProfile()) {
- return CONNECTION_TYPE_CELLULAR;
- }
-
- auto networkAdapter = m_profile.NetworkAdapter();
- if (!networkAdapter) {
- return CONNECTION_TYPE_UNKNOWN;
- }
- // Possible values: https://docs.microsoft.com/en-us/uwp/api/windows.networking.connectivity.networkadapter.ianainterfacetype
- if (networkAdapter.IanaInterfaceType() == 6u) {
- return CONNECTION_TYPE_ETHERNET;
- }
- else {
- return CONNECTION_TYPE_OTHER;
- }
- }
-
- std::string NetworkInfo::CellularGeneration() {
- if (!m_profile.IsWwanConnectionProfile()) {
- return CELLULAR_GENERATION_NONE;
- }
-
- auto dataClass = m_profile.WwanConnectionProfileDetails().GetCurrentDataClass();
- switch (dataClass) {
- case WwanDataClass::None:
- return CELLULAR_GENERATION_NONE;
- case WwanDataClass::Edge:
- case WwanDataClass::Gprs:
- return CELLULAR_GENERATION_2G;
- case WwanDataClass::Cdma1xEvdo:
- case WwanDataClass::Cdma1xEvdoRevA:
- case WwanDataClass::Cdma1xEvdoRevB:
- case WwanDataClass::Cdma1xEvdv:
- case WwanDataClass::Cdma1xRtt:
- case WwanDataClass::Cdma3xRtt:
- case WwanDataClass::Hsdpa:
- case WwanDataClass::Hsupa:
- case WwanDataClass::Umts:
- return CELLULAR_GENERATION_3G;
- case WwanDataClass::CdmaUmb:
- case WwanDataClass::LteAdvanced:
- return CELLULAR_GENERATION_4G;
- case WwanDataClass::Custom:
- default:
- return CELLULAR_GENERATION_UNKNOWN;
- }
- }
-
- bool NetworkInfo::IsConnectionExpensive() {
- if (!m_profile) {
- return false;
- }
-
- auto costType = m_profile.GetConnectionCost().NetworkCostType();
- return costType == NetworkCostType::Fixed || costType == NetworkCostType::Variable;
- }
-
-}
diff --git a/windows/RNCNetInfoCPP/NetworkInfo.h b/windows/RNCNetInfoCPP/NetworkInfo.h
deleted file mode 100644
index 0139a9f1..00000000
--- a/windows/RNCNetInfoCPP/NetworkInfo.h
+++ /dev/null
@@ -1,37 +0,0 @@
-// Copyright (c) Microsoft Corporation. All rights reserved.
-// Licensed under the MIT License.
-#pragma once
-#include "NativeModules.h"
-
-namespace winrt::ReactNativeNetInfo::implementation {
-
- class NetworkInfo {
- public:
- NetworkInfo();
- bool IsConnected();
- std::string ConnectivityType();
- std::string CellularGeneration();
- bool IsConnectionExpensive();
- void StatusChanged(const winrt::Windows::Networking::Connectivity::NetworkStatusChangedEventHandler& handler);
-
- static constexpr auto CONNECTION_TYPE_CELLULAR = "cellular";
- static constexpr auto CONNECTION_TYPE_ETHERNET = "ethernet";
- static constexpr auto CONNECTION_TYPE_NONE = "none";
- static constexpr auto CONNECTION_TYPE_UNKNOWN = "unknown";
- static constexpr auto CONNECTION_TYPE_WIFI = "wifi";
- static constexpr auto CONNECTION_TYPE_OTHER = "other";
-
- static constexpr auto CELLULAR_GENERATION_2G = "2g";
- static constexpr auto CELLULAR_GENERATION_3G = "3g";
- static constexpr auto CELLULAR_GENERATION_4G = "4g";
- static constexpr auto CELLULAR_GENERATION_NONE = nullptr;
- static constexpr auto CELLULAR_GENERATION_UNKNOWN = nullptr;
-
- private:
- void GetConnectionProfile();
- winrt::Windows::Networking::Connectivity::NetworkInformation::NetworkStatusChanged_revoker m_networkStatusChangedRevoker{};
- winrt::Windows::Networking::Connectivity::NetworkStatusChangedEventHandler m_statusChangedHandler{};
- winrt::Windows::Networking::Connectivity::ConnectionProfile m_profile{ nullptr };
- };
-
-}
\ No newline at end of file
diff --git a/windows/RNCNetInfoCPP/RNCNetInfo.cpp b/windows/RNCNetInfoCPP/RNCNetInfo.cpp
new file mode 100644
index 00000000..3e4e3057
--- /dev/null
+++ b/windows/RNCNetInfoCPP/RNCNetInfo.cpp
@@ -0,0 +1,195 @@
+// Copyright (c) Microsoft Corporation. All rights reserved.
+// Licensed under the MIT License.
+
+#include "pch.h"
+#include "RNCNetInfo.h"
+
+#include
+
+namespace winrt {
+ using namespace Windows::Foundation;
+ using namespace Windows::Networking::Connectivity;
+ using namespace Windows::Devices::WiFi;
+}
+
+using namespace winrt::Microsoft::ReactNative;
+
+namespace winrt::ReactNativeNetInfo::implementation {
+
+ static constexpr auto CONNECTION_TYPE_CELLULAR = "cellular";
+ static constexpr auto CONNECTION_TYPE_ETHERNET = "ethernet";
+ static constexpr auto CONNECTION_TYPE_NONE = "none";
+ static constexpr auto CONNECTION_TYPE_UNKNOWN = "unknown";
+ static constexpr auto CONNECTION_TYPE_WIFI = "wifi";
+ static constexpr auto CONNECTION_TYPE_OTHER = "other";
+
+ static constexpr auto CELLULAR_GENERATION_2G = "2g";
+ static constexpr auto CELLULAR_GENERATION_3G = "3g";
+ static constexpr auto CELLULAR_GENERATION_4G = "4g";
+ static constexpr auto CELLULAR_GENERATION_NONE = nullptr;
+ static constexpr auto CELLULAR_GENERATION_UNKNOWN = nullptr;
+
+ static constexpr auto WIFI_GENERATION_1 = "WiFi 1";
+ static constexpr auto WIFI_GENERATION_2 = "WiFi 2";
+ static constexpr auto WIFI_GENERATION_3 = "WiFi 3";
+ static constexpr auto WIFI_GENERATION_4 = "WiFi 4";
+ static constexpr auto WIFI_GENERATION_5 = "WiFi 5";
+ static constexpr auto WIFI_GENERATION_6 = "WiFi 6";
+ static constexpr auto WIFI_GENERATION_UNKNOWN = nullptr;
+
+ std::optional GetCellularGeneration(winrt::WwanDataClass dataClass) {
+ switch (dataClass) {
+ case WwanDataClass::None:
+ return CELLULAR_GENERATION_NONE;
+ case WwanDataClass::Edge:
+ case WwanDataClass::Gprs:
+ return CELLULAR_GENERATION_2G;
+ case WwanDataClass::Cdma1xEvdo:
+ case WwanDataClass::Cdma1xEvdoRevA:
+ case WwanDataClass::Cdma1xEvdoRevB:
+ case WwanDataClass::Cdma1xEvdv:
+ case WwanDataClass::Cdma1xRtt:
+ case WwanDataClass::Cdma3xRtt:
+ case WwanDataClass::Hsdpa:
+ case WwanDataClass::Hsupa:
+ case WwanDataClass::Umts:
+ return CELLULAR_GENERATION_3G;
+ case WwanDataClass::CdmaUmb:
+ case WwanDataClass::LteAdvanced:
+ return CELLULAR_GENERATION_4G;
+ case WwanDataClass::Custom:
+ default:
+ return CELLULAR_GENERATION_UNKNOWN;
+ }
+ }
+
+ std::optional GetWifiGeneration(winrt::WiFiPhyKind kind) {
+ switch (kind) {
+ case WiFiPhyKind::Dsss: // 802.11b
+ return WIFI_GENERATION_1;
+ case WiFiPhyKind::Ofdm: // 802.11a
+ return WIFI_GENERATION_2;
+ case WiFiPhyKind::Erp: // 802.11g
+ return WIFI_GENERATION_3;
+ case WiFiPhyKind::HT: // 802.11n
+ return WIFI_GENERATION_4;
+ case WiFiPhyKind::Vht: // 802.11ac
+ return WIFI_GENERATION_5;
+ case WiFiPhyKind::HE: // 802.11ax
+ return WIFI_GENERATION_6;
+ default:
+ return WIFI_GENERATION_UNKNOWN;
+ }
+ }
+
+ winrt::IAsyncOperation GetWiFiNetwork(winrt::NetworkAdapter adapter, winrt::hstring ssid)
+ {
+ // Unfortunately UWP doesn't have any APIs for getting WiFi network info for an existing connection. We have to trigger a scan
+ // of available networks and walk through them to get details.
+ try {
+ // This call only works if the app has the "wiFiControl" capability enabled in its appxmanifest, otherwise it will throw.
+ auto wifiAdapters = co_await WiFiAdapter::FindAllAdaptersAsync();
+ for (const auto& wifiAdapter : wifiAdapters)
+ {
+ if (wifiAdapter.NetworkAdapter().NetworkAdapterId() == adapter.NetworkAdapterId()) {
+ auto networks = wifiAdapter.NetworkReport().AvailableNetworks();
+ for (const auto& network : networks) {
+ if (network.Ssid() == ssid) {
+ co_return network;
+ }
+ }
+ }
+ }
+ }
+ catch (...) {}
+ co_return nullptr;
+ }
+
+ void RNCNetInfo::Initialize(winrt::Microsoft::ReactNative::ReactContext const& /*reactContext*/) noexcept {
+
+ // NetworkStatusChanged callback is captured by value on purpose. The event handler is called asynchronously and thus can fire even
+ // after we've already revoked it in our destructor during module teardown. In such a case, a reference
+ // to "this" or "this->NetworkStatusChanged" would be invalid.
+ m_networkStatusChangedRevoker = NetworkInformation::NetworkStatusChanged(winrt::auto_revoke, [callback = NetworkStatusChanged](const winrt::IInspectable& /*sender*/) -> winrt::fire_and_forget {
+ try {
+ // Copy lambda capture into a local so it still exists after the co_await.
+ auto localCallback = callback;
+ localCallback(co_await GetNetworkStatus());
+ }
+ catch (...) {}
+ });
+ }
+
+ winrt::fire_and_forget RNCNetInfo::getCurrentState(std::string requestedInterface, winrt::Microsoft::ReactNative::ReactPromise promise) noexcept {
+ // Jump to background to avoid blocking the JS thread while we gather the requested data
+ co_await winrt::resume_background();
+
+ promise.Resolve(co_await GetNetworkStatus());
+ }
+
+ /*static*/ std::future RNCNetInfo::GetNetworkStatus() {
+ NetInfoState state{};
+
+ // https://docs.microsoft.com/en-us/uwp/api/windows.networking.connectivity.connectionprofile
+ try {
+ auto profile = NetworkInformation::GetInternetConnectionProfile();
+ if (profile) {
+ auto networkAdapter = profile.NetworkAdapter();
+ auto connectivityLevel = profile.GetNetworkConnectivityLevel();
+ auto signal = profile.GetSignalBars();
+ auto costType = profile.GetConnectionCost().NetworkCostType();
+
+ state.isConnected = connectivityLevel != NetworkConnectivityLevel::None;
+
+ if (state.isConnected) {
+ NetInfoDetails details{};
+
+ state.isInternetReachable = connectivityLevel == NetworkConnectivityLevel::InternetAccess;
+ details.isConnectionExpensive = costType == NetworkCostType::Fixed || costType == NetworkCostType::Variable;
+ if (signal) {
+ details.strength = winrt::unbox_value(signal) * 20; // Signal strength is 0-5 but we want 0-100.
+ }
+
+ if (profile.IsWlanConnectionProfile()) {
+ auto wlanDetails = profile.WlanConnectionProfileDetails();
+ auto ssid = wlanDetails.GetConnectedSsid();
+ auto network = co_await GetWiFiNetwork(networkAdapter, ssid);
+
+ state.type = CONNECTION_TYPE_WIFI;
+ details.ssid = winrt::to_string(ssid);
+ if (network) {
+ details.bssid = winrt::to_string(network.Bssid());
+ details.frequency = network.ChannelCenterFrequencyInKilohertz() / 1000; // Convert to Mhz
+ details.wifiGeneration = GetWifiGeneration(network.PhyKind());
+ }
+ }
+ else if (profile.IsWwanConnectionProfile()) {
+ auto wwanDetails = profile.WwanConnectionProfileDetails();
+ auto dataClass = wwanDetails.GetCurrentDataClass();
+
+ state.type = CONNECTION_TYPE_CELLULAR;
+ details.cellularGeneration = GetCellularGeneration(dataClass);
+ }
+ else if (networkAdapter) {
+ // Possible values: https://docs.microsoft.com/en-us/uwp/api/windows.networking.connectivity.networkadapter.ianainterfacetype
+ if (networkAdapter.IanaInterfaceType() == 6u) {
+ state.type = CONNECTION_TYPE_ETHERNET;
+ }
+ else {
+ state.type = CONNECTION_TYPE_OTHER;
+ }
+ }
+ else {
+ state.type = CONNECTION_TYPE_UNKNOWN;
+ }
+
+ state.details = std::move(details);
+ }
+ }
+ }
+ catch (...) {
+ }
+
+ co_return state;
+ }
+}
\ No newline at end of file
diff --git a/windows/RNCNetInfoCPP/RNCNetInfo.h b/windows/RNCNetInfoCPP/RNCNetInfo.h
index 907fad1b..af504355 100644
--- a/windows/RNCNetInfoCPP/RNCNetInfo.h
+++ b/windows/RNCNetInfoCPP/RNCNetInfo.h
@@ -2,56 +2,81 @@
// Licensed under the MIT License.
#pragma once
-#include "pch.h"
#include
+#include
+#include
+#include
+#include
#include "NativeModules.h"
-#include "NetworkInfo.h"
namespace winrt::ReactNativeNetInfo::implementation {
+ REACT_STRUCT(NetInfoDetails);
+ struct NetInfoDetails {
+ REACT_FIELD(isConnectionExpensive);
+ bool isConnectionExpensive;
+
+ REACT_FIELD(cellularGeneration);
+ std::optional cellularGeneration;
+
+ REACT_FIELD(wifiGeneration);
+ std::optional wifiGeneration;
+
+ REACT_FIELD(ssid);
+ std::optional ssid;
+
+ REACT_FIELD(bssid);
+ std::optional bssid;
+
+ REACT_FIELD(strength);
+ std::optional strength;
+
+ REACT_FIELD(frequency);
+ std::optional frequency;
+ };
+
+ REACT_STRUCT(NetInfoState);
+ struct NetInfoState {
+ ///
+ /// The type of the active network connection
+ ///
+ ///
+ REACT_FIELD(type);
+ std::string type;
+
+ ///
+ /// Is there an active network connection
+ ///
+ ///
+ REACT_FIELD(isConnected);
+ bool isConnected;
+
+ ///
+ /// Is the internet reachable with the active network
+ ///
+ ///
+ REACT_FIELD(isInternetReachable);
+ std::optional isInternetReachable;
+
+ REACT_FIELD(details);
+ std::optional details;
+ };
+
REACT_MODULE(RNCNetInfo);
struct RNCNetInfo {
- NetworkInfo networkInfo;
+ public:
+ REACT_INIT(Initialize);
+ void Initialize(winrt::Microsoft::ReactNative::ReactContext const& reactContext) noexcept;
- RNCNetInfo() {
- networkInfo.StatusChanged([&](const auto& /*sender*/) {
- NetworkStatusChanged(CreateNetInfoStateObject());
- });
- }
+ REACT_METHOD(getCurrentState);
+ winrt::fire_and_forget getCurrentState(std::string requestedInterface, winrt::Microsoft::ReactNative::ReactPromise promise) noexcept;
REACT_EVENT(NetworkStatusChanged, L"netInfo.networkStatusDidChange");
- std::function NetworkStatusChanged;
+ std::function NetworkStatusChanged;
- REACT_METHOD(getCurrentState);
- void getCurrentState(std::string requestedInterface,
- ReactPromise const& promise) noexcept {
- promise.Resolve(CreateNetInfoStateObject());
- }
-
- JSValue CreateNetInfoStateObject()
- {
- auto isConnected = networkInfo.IsConnected();
- auto type = networkInfo.ConnectivityType();
- auto detailsWriter = MakeJSValueTreeWriter();
- if (isConnected) {
- detailsWriter.WriteObjectBegin();
- WriteProperty(detailsWriter, L"isConnectionExpensive", networkInfo.IsConnectionExpensive());
- if (type == NetworkInfo::CONNECTION_TYPE_CELLULAR)
- {
- WriteProperty(detailsWriter, L"cellularGeneration", networkInfo.CellularGeneration());
- }
- detailsWriter.WriteObjectEnd();
- }
-
- auto writer = winrt::Microsoft::ReactNative::MakeJSValueTreeWriter();
- writer.WriteObjectBegin();
- WriteProperty(writer, L"type", type);
- WriteProperty(writer, L"isConnected", isConnected);
- if (isConnected) {
- WriteProperty(writer, L"details", TakeJSValue(detailsWriter));
- }
- writer.WriteObjectEnd();
- return TakeJSValue(writer);
- }
+ static std::future GetNetworkStatus();
+
+ private:
+ winrt::Windows::Networking::Connectivity::NetworkInformation::NetworkStatusChanged_revoker m_networkStatusChangedRevoker{};
};
}
\ No newline at end of file
diff --git a/windows/RNCNetInfoCPP/RNCNetInfoCPP.vcxproj b/windows/RNCNetInfoCPP/RNCNetInfoCPP.vcxproj
index 9587f409..5fecea68 100644
--- a/windows/RNCNetInfoCPP/RNCNetInfoCPP.vcxproj
+++ b/windows/RNCNetInfoCPP/RNCNetInfoCPP.vcxproj
@@ -113,7 +113,6 @@
ReactPackageProvider.idl
-
@@ -124,8 +123,8 @@
ReactPackageProvider.idl
-
+
diff --git a/windows/RNCNetInfoCPP/RNCNetInfoCPP.vcxproj.filters b/windows/RNCNetInfoCPP/RNCNetInfoCPP.vcxproj.filters
index 19ebfadd..5b15c094 100644
--- a/windows/RNCNetInfoCPP/RNCNetInfoCPP.vcxproj.filters
+++ b/windows/RNCNetInfoCPP/RNCNetInfoCPP.vcxproj.filters
@@ -7,12 +7,11 @@
-
+
-
diff --git a/windows/RNCNetInfoCPP/pch.h b/windows/RNCNetInfoCPP/pch.h
index 4ee087d0..8fe0e977 100644
--- a/windows/RNCNetInfoCPP/pch.h
+++ b/windows/RNCNetInfoCPP/pch.h
@@ -12,5 +12,3 @@
#include
#include
#include
-
-using namespace winrt::Windows::Foundation;