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 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 delete config_;
155 config_ = nullptr;
156 RemoveMsgFromEvtHandler(NfcCommonEvent::MSG_WIFI_ENABLE_TIMEOUT);
157 RemoveMsgFromEvtHandler(NfcCommonEvent::MSG_WIFI_CONNECT_TIMEOUT);
158 UnsubscribeWifiCommonEvents();
159 }
160
HandleWifiEnableFailed()161 void WifiConnectionManager::HandleWifiEnableFailed()
162 {
163 std::unique_lock<std::shared_mutex> guard(mutex_);
164 ErrorLog("Wifi Enable Failed");
165 OnFinish();
166 }
167
HandleWifiConnectFailed()168 void WifiConnectionManager::HandleWifiConnectFailed()
169 {
170 std::unique_lock<std::shared_mutex> guard(mutex_);
171 ErrorLog("Wifi Connect Failed");
172 OnFinish();
173 }
174
IsWifiEnabled()175 __attribute__((no_sanitize("cfi"))) bool WifiConnectionManager::IsWifiEnabled()
176 {
177 if (GetWifiDevPtr() == nullptr) {
178 ErrorLog("wifi dev is null");
179 return false;
180 }
181 bool isEnabled = false;
182 ErrCode ret = wifiDevPtr_->IsWifiActive(isEnabled);
183 if (ret != Wifi::WIFI_OPT_SUCCESS) {
184 ErrorLog("get wifi active status failed ret = %{public}d", ret);
185 return false;
186 }
187 InfoLog("get wifi active status = %{public}d", isEnabled);
188 return isEnabled;
189 }
190
HandleEnableWifi()191 __attribute__((no_sanitize("cfi"))) bool WifiConnectionManager::HandleEnableWifi()
192 {
193 if (GetWifiDevPtr() == nullptr) {
194 ErrorLog("wifi dev is null");
195 return false;
196 }
197 ErrCode ret = wifiDevPtr_->EnableWifi();
198 if (ret != Wifi::WIFI_OPT_SUCCESS) {
199 ErrorLog("enable wifi failed ret = %{public}d", ret);
200 return false;
201 }
202 g_isWaitingForWifiEnable = true;
203 SendMsgToEvtHandler(NfcCommonEvent::MSG_WIFI_ENABLE_TIMEOUT, ENABLE_WIFI_TIMEOUT);
204 return true;
205 }
206
IsSameSsid()207 __attribute__((no_sanitize("cfi"))) bool WifiConnectionManager::IsSameSsid()
208 {
209 if (GetWifiDevPtr() == nullptr) {
210 ErrorLog("wifi dev is null");
211 return false;
212 }
213 if (config_ == nullptr) {
214 ErrorLog("config_ is null");
215 return false;
216 }
217 Wifi::WifiLinkedInfo info;
218 ErrCode ret = wifiDevPtr_->GetLinkedInfo(info);
219 if (ret != Wifi::WIFI_OPT_SUCCESS) {
220 ErrorLog("get linked info failed ret = %{public}d", ret);
221 return false;
222 }
223 DebugLog("current ssid: %{private}s, target ssid: %{private}s", info.ssid.c_str(), config_->ssid.c_str());
224 if (info.ssid.compare(config_->ssid.c_str()) == 0) {
225 return true;
226 }
227 return false;
228 }
229
TryConnectWifi(std::shared_ptr<WifiData> data)230 void WifiConnectionManager::TryConnectWifi(std::shared_ptr<WifiData> data)
231 {
232 std::unique_lock<std::shared_mutex> guard(mutex_);
233 if (!data || !data->isValid_) {
234 ErrorLog("data invalid");
235 return;
236 }
237 if (!data->config_) {
238 ErrorLog("config is null");
239 return;
240 }
241 RemoveMsgFromEvtHandler(NfcCommonEvent::MSG_WIFI_ENABLE_TIMEOUT);
242 RemoveMsgFromEvtHandler(NfcCommonEvent::MSG_WIFI_CONNECT_TIMEOUT);
243 config_ = data->config_;
244 InfoLog("TryConnectWifi: Publish notification ssid: %{private}s", config_->ssid.c_str());
245 ExternalDepsProxy::GetInstance().PublishNfcNotification(NFC_WIFI_NOTIFICATION_ID, config_->ssid, 0);
246 }
247
HandleConnectWifi()248 __attribute__((no_sanitize("cfi"))) bool WifiConnectionManager::HandleConnectWifi()
249 {
250 if (IsSameSsid()) {
251 InfoLog("already connected to target");
252 OnFinish();
253 return true;
254 }
255
256 InfoLog("HandleConnectWifi");
257 if (GetWifiDevPtr() == nullptr) {
258 ErrorLog("wifi dev is null");
259 OnFinish();
260 return false;
261 }
262 if (config_ == nullptr) {
263 ErrorLog("config_ is null");
264 OnFinish();
265 return false;
266 }
267 // NDEF msg does not include hiddenSSID info, set true to connect all type WiFi.
268 config_->hiddenSSID = true;
269 ErrCode err = wifiDevPtr_->ConnectToDevice(*(config_));
270 InfoLog("ConnectToDevice err: %{public}d", err);
271 if (err != Wifi::WIFI_OPT_SUCCESS) {
272 ErrorLog("ConnectToDevice failed err: %{public}d", err);
273 OnFinish();
274 return false;
275 }
276 SendMsgToEvtHandler(NfcCommonEvent::MSG_WIFI_CONNECT_TIMEOUT, CONNECT_WIFI_TIMEOUT);
277 g_isWaitingForWifiConnect = true;
278 return true;
279 }
280
OnWifiNtfClicked()281 void WifiConnectionManager::OnWifiNtfClicked()
282 {
283 InfoLog("OnWifiNtfClicked");
284 std::unique_lock<std::shared_mutex> guard(mutex_);
285 SubscribeWifiCommonEvents();
286 if (IsWifiEnabled()) {
287 HandleConnectWifi();
288 } else if (!HandleEnableWifi()) {
289 OnFinish();
290 }
291 }
292
OnWifiEnabled()293 void WifiConnectionManager::OnWifiEnabled()
294 {
295 DebugLog("OnWifiEnabled");
296 std::unique_lock<std::shared_mutex> guard(mutex_);
297 if (!g_isWaitingForWifiEnable) {
298 ErrorLog("not waiting for wifi enable, exit");
299 return;
300 }
301 RemoveMsgFromEvtHandler(NfcCommonEvent::MSG_WIFI_ENABLE_TIMEOUT);
302 g_isWaitingForWifiEnable = false;
303 HandleConnectWifi();
304 }
305
OnWifiConnected()306 void WifiConnectionManager::OnWifiConnected()
307 {
308 DebugLog("OnWifiConnected");
309 std::unique_lock<std::shared_mutex> guard(mutex_);
310 if (!g_isWaitingForWifiConnect) {
311 ErrorLog("not waiting for wifi connect, exit");
312 return;
313 }
314 if (!IsSameSsid()) {
315 OnFinish();
316 } else {
317 InfoLog("connected to target config");
318 OnFinish();
319 }
320 }
321
OnReceiveEvent(const EventFwk::CommonEventData & data)322 void WifiConnectionManager::WifiCommonEventReceiver::OnReceiveEvent(const EventFwk::CommonEventData& data)
323 {
324 std::string action = data.GetWant().GetAction();
325 if (action.empty()) {
326 ErrorLog("action is empty");
327 return;
328 }
329 InfoLog("OnReceiveEvent: action: %{public}s, code: %{public}d", action.c_str(), data.GetCode());
330 if (action.compare(EventFwk::CommonEventSupport::COMMON_EVENT_WIFI_POWER_STATE) == 0) {
331 if (data.GetCode() != static_cast<int32_t>(Wifi::WifiState::ENABLED)) {
332 return;
333 }
334 std::unique_lock<std::shared_mutex> guard(nfcWifiConnMgr_.mutex_);
335 nfcWifiConnMgr_.SendMsgToEvtHandler(NfcCommonEvent::MSG_WIFI_ENABLED, 0);
336 } else if (action.compare(EventFwk::CommonEventSupport::COMMON_EVENT_WIFI_CONN_STATE) == 0) {
337 if (data.GetCode() != static_cast<int32_t>(Wifi::ConnState::CONNECTED)) {
338 return;
339 }
340 std::unique_lock<std::shared_mutex> guard(nfcWifiConnMgr_.mutex_);
341 nfcWifiConnMgr_.SendMsgToEvtHandler(NfcCommonEvent::MSG_WIFI_CONNECTED, 0);
342 }
343 }
344 } // namespace TAG
345 } // namespace NFC
346 } // namespace OHOS
347