Skip to content

Commit a6d6b4f

Browse files
hai007copybara-github
authored andcommitted
Wi-Fi Direct Service Implementation(10)
PiperOrigin-RevId: 846506392
1 parent 96f1a87 commit a6d6b4f

File tree

7 files changed

+171
-11
lines changed

7 files changed

+171
-11
lines changed

connections/implementation/mediums/wifi_direct.cc

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -60,7 +60,7 @@ bool WifiDirect::IsGOAvailable() const {
6060
}
6161

6262
bool WifiDirect::IsGOAvailableLocked() const {
63-
if (medium_.IsValid()) return medium_.IsInterfaceValid();
63+
if (medium_.IsValid()) return medium_.IsGOInterfaceValid();
6464
return false;
6565
}
6666

internal/platform/implementation/g3/wifi_direct.h

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -158,6 +158,9 @@ class WifiDirectMedium : public api::WifiDirectMedium {
158158
// If the WiFi Adaptor supports to start a WifiDirect interface.
159159
bool IsInterfaceValid() const override { return true; }
160160

161+
// If the WiFi Adaptor supports to start a WifiDirect GO interface.
162+
bool IsGOInterfaceValid() const override { return true; }
163+
161164
// Discoverer connects to server socket
162165
std::unique_ptr<api::WifiDirectSocket> ConnectToService(
163166
absl::string_view ip_address, int port,

internal/platform/implementation/wifi_direct.h

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -90,6 +90,9 @@ class WifiDirectMedium {
9090
// If the WiFi Adaptor supports to start a WifiDirect interface.
9191
virtual bool IsInterfaceValid() const = 0;
9292

93+
// If the WiFi Adaptor supports to start a WifiDirect interface GO.
94+
virtual bool IsGOInterfaceValid() const = 0;
95+
9396
// Connects to a WifiDirect service by port.
9497
// On success, returns a new WifiDirectSocket.
9598
// On error, returns nullptr.

internal/platform/implementation/windows/BUILD

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -28,6 +28,7 @@ cc_library(
2828
compatible_with = ["//buildenv/target:non_prod"],
2929
linkopts = [
3030
"ole32.lib",
31+
"oleaut32.lib",
3132
"shell32.lib",
3233
],
3334
tags = ["windows"],

internal/platform/implementation/windows/wifi_direct.h

Lines changed: 12 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -185,9 +185,15 @@ class WifiDirectMedium : public api::WifiDirectMedium {
185185
WifiDirectMedium(const WifiDirectMedium&) = delete;
186186
WifiDirectMedium& operator=(const WifiDirectMedium&) = delete;
187187

188-
// If the WiFi Adaptor supports to start WifiDirect Service GO.
188+
// If the WiFi Adaptor supports to start WifiDirect Service.
189189
bool IsInterfaceValid() const override;
190190

191+
// If the WiFi Adaptor supports to start WifiDirect Service GO.
192+
// This is used to check if the Windows Firewall rule "WFD ASP Coordination
193+
// Protocol (UDP-In)" is enabled. GO interface is not valid if the rule is
194+
// disabled.
195+
bool IsGOInterfaceValid() const override;
196+
191197
// Discoverer connects to server socket
192198
std::unique_ptr<api::WifiDirectSocket> ConnectToService(
193199
absl::string_view ip_address, int port,
@@ -227,7 +233,6 @@ class WifiDirectMedium : public api::WifiDirectMedium {
227233
// Medium Status
228234
int medium_status_ = kMediumStatusIdle;
229235

230-
bool IsWifiDirectServiceSupported();
231236
bool IsIdle() { return medium_status_ == kMediumStatusIdle; }
232237
// Advertiser is accepting connection on server socket
233238
bool IsAccepting() { return (medium_status_ & kMediumStatusAccepting) != 0; }
@@ -241,7 +246,11 @@ class WifiDirectMedium : public api::WifiDirectMedium {
241246
}
242247
// Discoverer is connected with the WifiDirect
243248
bool IsConnected() { return (medium_status_ & kMediumStatusConnected) != 0; }
244-
249+
// Returns true if the WiFi Direct service is supported.
250+
static bool IsWifiDirectServiceSupported();
251+
// Returns true if the Windows Firewall rule "WFD ASP Coordination Protocol
252+
// (UDP-In)" is enabled.
253+
static bool IsFirewallWfdAspProtoEnabled();
245254
// Converts WiFiDirectServiceConfigurationMethod enum to a string.
246255
static std::string ConfigMethodToString(
247256
WiFiDirectServiceConfigurationMethod config_method);
@@ -285,7 +294,6 @@ class WifiDirectMedium : public api::WifiDirectMedium {
285294
fire_and_forget Watcher_DeviceStopped(DeviceWatcher sender,
286295
IInspectable inspectable);
287296

288-
bool is_interface_valid_ = false;
289297
WifiDirectCredentials* credentials_go_ = nullptr;
290298
WifiDirectCredentials credentials_gc_;
291299
std::string ip_address_local_;

internal/platform/implementation/windows/wifi_direct_medium.cc

Lines changed: 142 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,12 @@
1212
// See the License for the specific language governing permissions and
1313
// limitations under the License.
1414

15+
#include "internal/platform/implementation/windows/wifi_direct.h"
16+
17+
#include <comutil.h>
18+
#include <winrt/base.h>
19+
20+
#include <netfw.h>
1521
#include <cstdint>
1622
#include <exception>
1723
#include <memory>
@@ -31,8 +37,8 @@
3137
#include "internal/platform/flags/nearby_platform_feature_flags.h"
3238
#include "internal/platform/implementation/wifi_direct.h"
3339
#include "internal/platform/implementation/windows/socket_address.h"
40+
#include "internal/platform/implementation/windows/string_utils.h"
3441
#include "internal/platform/implementation/windows/utils.h"
35-
#include "internal/platform/implementation/windows/wifi_direct.h"
3642
#include "internal/platform/logging.h"
3743
#include "internal/platform/prng.h"
3844
#include "internal/platform/wifi_credential.h"
@@ -53,11 +59,9 @@ WifiDirectMedium::WifiDirectMedium() {
5359
LOG(WARNING) << "Failed to get DispatcherQueue for current thread. "
5460
"ConnectAsync might fail if not called from UI thread.";
5561
}
56-
is_interface_valid_ = IsWifiDirectServiceSupported();
5762
}
5863

5964
WifiDirectMedium::~WifiDirectMedium() {
60-
is_interface_valid_ = false;
6165
listener_executor_.Shutdown();
6266
StopWifiDirect();
6367
DisconnectWifiDirect();
@@ -73,6 +77,133 @@ WifiDirectMedium::~WifiDirectMedium() {
7377
}
7478
}
7579

80+
// If Windows Firewall rule "WFD ASP Coordination Protocol (UDP-In)" is not
81+
// enabled, WifiDirectService GO will fail to create WiFiDirectServiceSession.
82+
bool WifiDirectMedium::IsFirewallWfdAspProtoEnabled() {
83+
LOG(INFO)
84+
<< "Check Windows Firewall rule WFD ASP Coordination Protocol (UDP-In)";
85+
bool com_initialized = false;
86+
winrt::com_ptr<INetFwPolicy2> p_net_fw_policy2;
87+
winrt::com_ptr<INetFwRules> p_fw_rules;
88+
winrt::com_ptr<INetFwRule> p_fw_rule;
89+
// Default to true if the firewall rule is not found or enabled.
90+
bool is_firewall_wfd_asp_proto_enabled = true;
91+
92+
// Initialize COM.
93+
HRESULT hr = CoInitializeEx(nullptr, COINIT_MULTITHREADED);
94+
if (FAILED(hr)) {
95+
if (hr == RPC_E_CHANGED_MODE) {
96+
LOG(INFO) << "COM already initialized with a different mode. Proceeding.";
97+
} else {
98+
LOG(ERROR) << absl::StrFormat("CoInitializeEx failed: 0x%08lx", hr);
99+
return is_firewall_wfd_asp_proto_enabled;
100+
}
101+
} else {
102+
com_initialized = true;
103+
}
104+
105+
// Create an instance of the firewall policy object.
106+
hr = CoCreateInstance(__uuidof(NetFwPolicy2), nullptr, CLSCTX_INPROC_SERVER,
107+
__uuidof(INetFwPolicy2), p_net_fw_policy2.put_void());
108+
if (FAILED(hr)) {
109+
LOG(ERROR) << "CoCreateInstance for INetFwPolicy2 failed";
110+
if (com_initialized) CoUninitialize();
111+
return is_firewall_wfd_asp_proto_enabled;
112+
}
113+
114+
if (p_net_fw_policy2 == nullptr) {
115+
LOG(ERROR) << "p_net_fw_policy2 is null";
116+
if (com_initialized) CoUninitialize();
117+
return is_firewall_wfd_asp_proto_enabled;
118+
}
119+
120+
// Retrieve the Rules collection.
121+
hr = p_net_fw_policy2->get_Rules(p_fw_rules.put());
122+
if (FAILED(hr)) {
123+
LOG(ERROR) << "Failed to retrieve firewall rules collection";
124+
if (com_initialized) CoUninitialize();
125+
return is_firewall_wfd_asp_proto_enabled;
126+
}
127+
128+
if (p_fw_rules == nullptr) {
129+
LOG(ERROR) << "p_fw_rules is null";
130+
if (com_initialized) CoUninitialize();
131+
return is_firewall_wfd_asp_proto_enabled;
132+
}
133+
134+
winrt::com_ptr<IUnknown> p_unk;
135+
winrt::com_ptr<IEnumVARIANT> p_enum;
136+
hr = p_fw_rules->get__NewEnum(p_unk.put());
137+
if (FAILED(hr) || !p_unk) {
138+
LOG(ERROR) << "Failed to get rule enumerator.";
139+
if (com_initialized) CoUninitialize();
140+
return is_firewall_wfd_asp_proto_enabled;
141+
}
142+
143+
hr = p_unk->QueryInterface(__uuidof(IEnumVARIANT), p_enum.put_void());
144+
if (FAILED(hr) || !p_enum) {
145+
LOG(ERROR) << "Failed to query IEnumVARIANT.";
146+
if (com_initialized) CoUninitialize();
147+
return is_firewall_wfd_asp_proto_enabled;
148+
}
149+
150+
VARIANT var{};
151+
while (p_enum->Next(1, &var, nullptr) == S_OK) {
152+
if (var.vt == VT_DISPATCH && var.pdispVal != nullptr) {
153+
winrt::com_ptr<INetFwRule> rule;
154+
hr = var.pdispVal->QueryInterface(__uuidof(INetFwRule), rule.put_void());
155+
if (SUCCEEDED(hr) && rule) {
156+
LONG protocol = 0;
157+
rule->get_Protocol(&protocol);
158+
NET_FW_RULE_DIRECTION direction;
159+
rule->get_Direction(&direction);
160+
BSTR bstr_svc = nullptr;
161+
rule->get_ServiceName(&bstr_svc);
162+
_bstr_t service_name(bstr_svc, false);
163+
BSTR bstr_name = nullptr;
164+
rule->get_Name(&bstr_name);
165+
_bstr_t rule_name(bstr_name, false);
166+
167+
if (direction == NET_FW_RULE_DIR_IN &&
168+
protocol == NET_FW_IP_PROTOCOL_UDP &&
169+
service_name == _bstr_t(L"WlanSvc")) {
170+
LOG(INFO) << "Firewall rule name="
171+
<< (bstr_name ? string_utils::WideStringToString(bstr_name)
172+
: "null");
173+
p_fw_rule = rule;
174+
VariantClear(&var);
175+
break;
176+
}
177+
}
178+
}
179+
VariantClear(&var);
180+
}
181+
182+
if (p_fw_rule == nullptr) {
183+
LOG(ERROR)
184+
<< "Failed to find the rule 'WFD ASP Coordination Protocol (UDP-In)'.";
185+
if (com_initialized) CoUninitialize();
186+
return is_firewall_wfd_asp_proto_enabled;
187+
}
188+
189+
// Check if it is currently enabled.
190+
VARIANT_BOOL b_enabled;
191+
hr = p_fw_rule->get_Enabled(&b_enabled);
192+
if (SUCCEEDED(hr)) {
193+
if (b_enabled == VARIANT_TRUE) {
194+
LOG(INFO) << "Rule is enabled.";
195+
} else {
196+
is_firewall_wfd_asp_proto_enabled = false;
197+
LOG(INFO) << "Rule is disabled.";
198+
}
199+
}
200+
201+
if (com_initialized) {
202+
CoUninitialize();
203+
}
204+
return is_firewall_wfd_asp_proto_enabled;
205+
}
206+
76207
bool WifiDirectMedium::IsWifiDirectServiceSupported() {
77208
if (!IsIntelWifiAdapter()) {
78209
LOG(INFO) << "Intel Wifi adapter is not found, WifiDirectService is not "
@@ -96,7 +227,14 @@ bool WifiDirectMedium::IsWifiDirectServiceSupported() {
96227
}
97228

98229
bool WifiDirectMedium::IsInterfaceValid() const {
99-
return is_interface_valid_;
230+
static const bool kIsInterfaceValid = IsWifiDirectServiceSupported();
231+
return kIsInterfaceValid;
232+
}
233+
234+
bool WifiDirectMedium::IsGOInterfaceValid() const {
235+
static const bool kIsFirewallWfdAspProtoEnabled =
236+
IsFirewallWfdAspProtoEnabled();
237+
return kIsFirewallWfdAspProtoEnabled && IsInterfaceValid();
100238
}
101239

102240
// Discoverer connects to server socket

internal/platform/wifi_direct.h

Lines changed: 9 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -198,13 +198,20 @@ class WifiDirectMedium {
198198
WifiDirectCredentials* GetCredential() { return &wifi_direct_credentials_; }
199199

200200
bool IsInterfaceValid() const {
201-
CHECK(impl_);
201+
if (impl_ == nullptr) return false;
202202
return impl_->IsInterfaceValid();
203203
}
204204

205+
// This is used to check if the Windows Firewall rule "WFD ASP Coordination
206+
// Protocol (UDP-In)" is enabled. GO interface is not valid if the rule is
207+
// disabled.
208+
bool IsGOInterfaceValid() const {
209+
if (impl_ == nullptr) return false;
210+
return impl_->IsGOInterfaceValid();
211+
}
212+
205213
bool IsValid() const { return impl_ != nullptr; }
206214
api::WifiDirectMedium& GetImpl() {
207-
CHECK(impl_);
208215
return *impl_;
209216
}
210217

0 commit comments

Comments
 (0)