1 /*
2 * Copyright (C) 2024 Huawei Device Co., Ltd.
3 * Licensed under the Apache License, Version 2.0 (the "License");
4 * you may not use this file except in compliance with the License.
5 * You may obtain a copy of the License at
6 *
7 * http://www.apache.org/licenses/LICENSE-2.0
8 *
9 * Unless required by applicable law or agreed to in writing, software
10 * distributed under the License is distributed on an "AS IS" BASIS,
11 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12 * See the License for the specific language governing permissions and
13 * limitations under the License.
14 */
15
16 #include "wifi_connection_manager.h"
17
18 #include "common_event_manager.h"
19 #include "common_event_support.h"
20 #include "external_deps_proxy.h"
21 #include "infc_service.h"
22 #include "loghelper.h"
23 #include "nfc_service.h"
24 #include "wifi_errcode.h"
25 #include "wifi_msg.h"
26
27 namespace OHOS {
28 namespace NFC {
29 namespace TAG {
30 const int64_t ENABLE_WIFI_TIMEOUT = 5000; // ms
31 const int64_t CONNECT_WIFI_TIMEOUT = 5000; // ms
32 std::shared_ptr<Wifi::WifiDevice> wifiDevPtr_ {};
33 std::shared_ptr<Wifi::WifiDeviceConfig> config_ {};
34 std::shared_ptr<EventFwk::CommonEventSubscriber> wifiSubscriber_ {};
35 bool g_isWaitingForWifiEnable = false;
36 bool g_isWaitingForWifiConnect = false;
37
WifiConnectionManager()38 WifiConnectionManager::WifiConnectionManager()
39 {
40 }
41
GetInstance()42 WifiConnectionManager& WifiConnectionManager::GetInstance()
43 {
44 static WifiConnectionManager instance;
45 return instance;
46 }
47
Initialize(std::weak_ptr<NfcService> nfcService)48 void WifiConnectionManager::Initialize(std::weak_ptr<NfcService> nfcService)
49 {
50 std::unique_lock<std::shared_mutex> guard(mutex_);
51 DebugLog("Init: isInitialized = %{public}d", isInitialized_);
52 if (isInitialized_) {
53 return;
54 }
55 nfcService_ = nfcService;
56 isInitialized_ = true;
57 }
58
59 class WifiConnectionManager::WifiCommonEventReceiver : public EventFwk::CommonEventSubscriber {
60 public:
61 explicit WifiCommonEventReceiver(WifiConnectionManager& nfcWifiConnMgr,
62 const EventFwk::CommonEventSubscribeInfo& subscribeInfo);
~WifiCommonEventReceiver()63 ~WifiCommonEventReceiver()
64 {
65 }
66 void OnReceiveEvent(const EventFwk::CommonEventData& data) override;
67
68 private:
69 WifiConnectionManager& nfcWifiConnMgr_;
70 };
71
WifiCommonEventReceiver(WifiConnectionManager & nfcWifiConnMgr,const EventFwk::CommonEventSubscribeInfo & subscribeInfo)72 WifiConnectionManager::WifiCommonEventReceiver::WifiCommonEventReceiver(WifiConnectionManager& nfcWifiConnMgr,
73 const EventFwk::CommonEventSubscribeInfo& subscribeInfo)
74 : EventFwk::CommonEventSubscriber(subscribeInfo),
75 nfcWifiConnMgr_(nfcWifiConnMgr)
76 {
77 }
78
SubscribeWifiCommonEvents()79 void WifiConnectionManager::SubscribeWifiCommonEvents()
80 {
81 if (wifiSubscriber_ != nullptr) {
82 InfoLog("already subscribed");
83 return;
84 }
85 EventFwk::MatchingSkills matchingSkills;
86 matchingSkills.AddEvent(EventFwk::CommonEventSupport::COMMON_EVENT_WIFI_POWER_STATE);
87 matchingSkills.AddEvent(EventFwk::CommonEventSupport::COMMON_EVENT_WIFI_CONN_STATE);
88 EventFwk::CommonEventSubscribeInfo subscribeInfo(matchingSkills);
89 wifiSubscriber_ = std::make_shared<WifiCommonEventReceiver>(*this, subscribeInfo);
90 if (wifiSubscriber_ == nullptr) {
91 ErrorLog("Create wifi subscriber failed");
92 return;
93 }
94 if (!EventFwk::CommonEventManager::SubscribeCommonEvent(wifiSubscriber_)) {
95 ErrorLog("Subscribe wifi event fail");
96 }
97 }
98
UnsubscribeWifiCommonEvents()99 void WifiConnectionManager::UnsubscribeWifiCommonEvents()
100 {
101 if (!wifiSubscriber_) {
102 InfoLog("already unsubscribed");
103 return;
104 }
105 DebugLog("UnsubscribeWifiCommonEvents");
106 if (!EventFwk::CommonEventManager::UnSubscribeCommonEvent(wifiSubscriber_)) {
107 ErrorLog("Unsubscribe wifi event fail");
108 return;
109 }
110 wifiSubscriber_ = nullptr;
111 }
112
SendMsgToEvtHandler(NfcCommonEvent evt,int64_t delay)113 void WifiConnectionManager::SendMsgToEvtHandler(NfcCommonEvent evt, int64_t delay)
114 {
115 if (nfcService_.expired()) {
116 ErrorLog("nfcService expired");
117 return;
118 }
119 if (nfcService_.lock()->eventHandler_ == nullptr) {
120 ErrorLog("event handler is null");
121 return;
122 }
123 DebugLog("SendMsgToEvtHandler: event:%{public}d, delay:%{public}ld", evt, delay);
124 nfcService_.lock()->eventHandler_->SendEvent(static_cast<uint32_t>(evt), delay);
125 }
126
RemoveMsgFromEvtHandler(NfcCommonEvent evt)127 void WifiConnectionManager::RemoveMsgFromEvtHandler(NfcCommonEvent evt)
128 {
129 if (nfcService_.expired()) {
130 ErrorLog("nfcService expired");
131 return;
132 }
133 if (nfcService_.lock()->eventHandler_ == nullptr) {
134 ErrorLog("event handler is null");
135 return;
136 }
137 DebugLog("RemoveMsgFromEvtHandler: event:%{public}d", evt);
138 nfcService_.lock()->eventHandler_->RemoveEvent(static_cast<uint32_t>(evt), static_cast<int64_t>(0));
139 }
140
GetWifiDevPtr()141 std::shared_ptr<Wifi::WifiDevice> WifiConnectionManager::GetWifiDevPtr()
142 {
143 if (wifiDevPtr_ == nullptr) {
144 wifiDevPtr_ = Wifi::WifiDevice::GetInstance(WIFI_DEVICE_ABILITY_ID);
145 }
146 return wifiDevPtr_;
147 }
148
OnFinish()149 void WifiConnectionManager::OnFinish()
150 {
151 DebugLog("OnFinish");
152 g_isWaitingForWifiEnable = false;
153 g_isWaitingForWifiConnect = false;
154 config_ = nullptr;
155 RemoveMsgFromEvtHandler(NfcCommonEvent::MSG_WIFI_ENABLE_TIMEOUT);
156 RemoveMsgFromEvtHandler(NfcCommonEvent::MSG_WIFI_CONNECT_TIMEOUT);
157 UnsubscribeWifiCommonEvents();
158 }
159
HandleWifiEnableFailed()160 void WifiConnectionManager::HandleWifiEnableFailed()
161 {
162 std::unique_lock<std::shared_mutex> guard(mutex_);
163 ErrorLog("Wifi Enable Failed");
164 OnFinish();
165 }
166
HandleWifiConnectFailed()167 void WifiConnectionManager::HandleWifiConnectFailed()
168 {
169 std::unique_lock<std::shared_mutex> guard(mutex_);
170 ErrorLog("Wifi Connect Failed");
171 OnFinish();
172 }
173
IsWifiEnabled()174 __attribute__((no_sanitize("cfi"))) bool WifiConnectionManager::IsWifiEnabled()
175 {
176 if (GetWifiDevPtr() == nullptr) {
177 ErrorLog("wifi dev is null");
178 return false;
179 }
180 bool isEnabled = false;
181 ErrCode ret = wifiDevPtr_->IsWifiActive(isEnabled);
182 if (ret != Wifi::WIFI_OPT_SUCCESS) {
183 ErrorLog("get wifi active status failed ret = %{public}d", ret);
184 return false;
185 }
186 InfoLog("get wifi active status = %{public}d", isEnabled);
187 return isEnabled;
188 }
189
HandleEnableWifi()190 __attribute__((no_sanitize("cfi"))) bool WifiConnectionManager::HandleEnableWifi()
191 {
192 if (GetWifiDevPtr() == nullptr) {
193 ErrorLog("wifi dev is null");
194 return false;
195 }
196 ErrCode ret = wifiDevPtr_->EnableWifi();
197 if (ret != Wifi::WIFI_OPT_SUCCESS) {
198 ErrorLog("enable wifi failed ret = %{public}d", ret);
199 return false;
200 }
201 g_isWaitingForWifiEnable = true;
202 SendMsgToEvtHandler(NfcCommonEvent::MSG_WIFI_ENABLE_TIMEOUT, ENABLE_WIFI_TIMEOUT);
203 return true;
204 }
205
IsSameSsid()206 __attribute__((no_sanitize("cfi"))) bool WifiConnectionManager::IsSameSsid()
207 {
208 if (GetWifiDevPtr() == nullptr) {
209 ErrorLog("wifi dev is null");
210 return false;
211 }
212 if (config_ == nullptr) {
213 ErrorLog("config_ is null");
214 return false;
215 }
216 Wifi::WifiLinkedInfo info;
217 ErrCode ret = wifiDevPtr_->GetLinkedInfo(info);
218 if (ret != Wifi::WIFI_OPT_SUCCESS) {
219 ErrorLog("get linked info failed ret = %{public}d", ret);
220 return false;
221 }
222 DebugLog("current ssid: %{private}s, target ssid: %{private}s", info.ssid.c_str(), config_->ssid.c_str());
223 if (info.ssid.compare(config_->ssid.c_str()) == 0) {
224 return true;
225 }
226 return false;
227 }
228
TryConnectWifi(std::shared_ptr<WifiData> data)229 void WifiConnectionManager::TryConnectWifi(std::shared_ptr<WifiData> data)
230 {
231 std::unique_lock<std::shared_mutex> guard(mutex_);
232 if (!data || !data->isValid_) {
233 ErrorLog("data invalid");
234 return;
235 }
236 if (!data->config_) {
237 ErrorLog("config is null");
238 return;
239 }
240 RemoveMsgFromEvtHandler(NfcCommonEvent::MSG_WIFI_ENABLE_TIMEOUT);
241 RemoveMsgFromEvtHandler(NfcCommonEvent::MSG_WIFI_CONNECT_TIMEOUT);
242 config_ = data->config_;
243 InfoLog("TryConnectWifi: Publish notification ssid: %{private}s", config_->ssid.c_str());
244 ExternalDepsProxy::GetInstance().PublishNfcNotification(NFC_WIFI_NOTIFICATION_ID, config_->ssid, 0);
245 }
246
HandleConnectWifi()247 __attribute__((no_sanitize("cfi"))) bool WifiConnectionManager::HandleConnectWifi()
248 {
249 if (IsSameSsid()) {
250 InfoLog("already connected to target");
251 OnFinish();
252 return true;
253 }
254
255 InfoLog("HandleConnectWifi");
256 if (GetWifiDevPtr() == nullptr) {
257 ErrorLog("wifi dev is null");
258 OnFinish();
259 return false;
260 }
261 if (config_ == nullptr) {
262 ErrorLog("config_ is null");
263 OnFinish();
264 return false;
265 }
266 // NDEF msg does not include hiddenSSID info, set true to connect all type WiFi.
267 config_->hiddenSSID = true;
268 ErrCode err = wifiDevPtr_->ConnectToDevice(*(config_));
269 InfoLog("ConnectToDevice err: %{public}d", err);
270 if (err != Wifi::WIFI_OPT_SUCCESS) {
271 ErrorLog("ConnectToDevice failed err: %{public}d", err);
272 OnFinish();
273 return false;
274 }
275 SendMsgToEvtHandler(NfcCommonEvent::MSG_WIFI_CONNECT_TIMEOUT, CONNECT_WIFI_TIMEOUT);
276 g_isWaitingForWifiConnect = true;
277 return true;
278 }
279
OnWifiNtfClicked()280 void WifiConnectionManager::OnWifiNtfClicked()
281 {
282 InfoLog("OnWifiNtfClicked");
283 std::unique_lock<std::shared_mutex> guard(mutex_);
284 SubscribeWifiCommonEvents();
285 if (IsWifiEnabled()) {
286 HandleConnectWifi();
287 } else if (!HandleEnableWifi()) {
288 OnFinish();
289 }
290 }
291
OnWifiEnabled()292 void WifiConnectionManager::OnWifiEnabled()
293 {
294 DebugLog("OnWifiEnabled");
295 std::unique_lock<std::shared_mutex> guard(mutex_);
296 if (!g_isWaitingForWifiEnable) {
297 ErrorLog("not waiting for wifi enable, exit");
298 return;
299 }
300 RemoveMsgFromEvtHandler(NfcCommonEvent::MSG_WIFI_ENABLE_TIMEOUT);
301 g_isWaitingForWifiEnable = false;
302 HandleConnectWifi();
303 }
304
OnWifiConnected()305 void WifiConnectionManager::OnWifiConnected()
306 {
307 DebugLog("OnWifiConnected");
308 std::unique_lock<std::shared_mutex> guard(mutex_);
309 if (!g_isWaitingForWifiConnect) {
310 ErrorLog("not waiting for wifi connect, exit");
311 return;
312 }
313 if (!IsSameSsid()) {
314 OnFinish();
315 } else {
316 InfoLog("connected to target config");
317 OnFinish();
318 }
319 }
320
OnReceiveEvent(const EventFwk::CommonEventData & data)321 void WifiConnectionManager::WifiCommonEventReceiver::OnReceiveEvent(const EventFwk::CommonEventData& data)
322 {
323 std::string action = data.GetWant().GetAction();
324 if (action.empty()) {
325 ErrorLog("action is empty");
326 return;
327 }
328 InfoLog("OnReceiveEvent: action: %{public}s, code: %{public}d", action.c_str(), data.GetCode());
329 if (action.compare(EventFwk::CommonEventSupport::COMMON_EVENT_WIFI_POWER_STATE) == 0) {
330 if (data.GetCode() != static_cast<int32_t>(Wifi::WifiState::ENABLED)) {
331 return;
332 }
333 std::unique_lock<std::shared_mutex> guard(nfcWifiConnMgr_.mutex_);
334 nfcWifiConnMgr_.SendMsgToEvtHandler(NfcCommonEvent::MSG_WIFI_ENABLED, 0);
335 } else if (action.compare(EventFwk::CommonEventSupport::COMMON_EVENT_WIFI_CONN_STATE) == 0) {
336 if (data.GetCode() != static_cast<int32_t>(Wifi::ConnState::CONNECTED)) {
337 return;
338 }
339 std::unique_lock<std::shared_mutex> guard(nfcWifiConnMgr_.mutex_);
340 nfcWifiConnMgr_.SendMsgToEvtHandler(NfcCommonEvent::MSG_WIFI_CONNECTED, 0);
341 }
342 }
343 } // namespace TAG
344 } // namespace NFC
345 } // namespace OHOS
346