• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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