1 /*
2  * Copyright (c) 2023 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_sta_manager.h"
17 #include "magic_enum.h"
18 #include "wifi_manager.h"
19 #include "wifi_service_manager.h"
20 #include "wifi_config_center.h"
21 #include "wifi_global_func.h"
22 #include "wifi_logger.h"
23 #include "wifi_hisysevent.h"
24 #include "wifi_protect_manager.h"
25 #include "wifi_system_timer.h"
26 #ifdef FEATURE_STA_SUPPORT
27 #include "wifi_country_code_manager.h"
28 #endif
29 #ifdef OHOS_ARCH_LITE
30 #include "wifi_internal_event_dispatcher_lite.h"
31 #else
32 #include "wifi_internal_event_dispatcher.h"
33 #include "wifi_sa_manager.h"
34 #include "wifi_notification_util.h"
35 #endif
36 
37 DEFINE_WIFILOG_LABEL("WifiStaManager");
38 
39 namespace OHOS {
40 namespace Wifi {
WifiStaManager()41 WifiStaManager::WifiStaManager()
42 {
43     WIFI_LOGI("create WifiStaManager");
44     InitStaCallback();
45 }
46 
GetStaCallback()47 StaServiceCallback& WifiStaManager::GetStaCallback()
48 {
49     return mStaCallback;
50 }
51 
52 #ifndef OHOS_ARCH_LITE
UnloadStaSaTimerCallback()53 static void UnloadStaSaTimerCallback()
54 {
55     WifiSaLoadManager::GetInstance().UnloadWifiSa(WIFI_DEVICE_ABILITY_ID);
56     WifiManager::GetInstance().GetWifiStaManager()->StopUnloadStaSaTimer();
57 }
58 
SatelliteTimerCallback()59 static void SatelliteTimerCallback()
60 {
61     WIFI_LOGI("It's time for satellite timer.");
62     WifiManager::GetInstance().GetWifiTogglerManager()->SetSatelliteStartState(false);
63     WifiManager::GetInstance().GetWifiStaManager()->StopSatelliteTimer();
64 }
65 
StopUnloadStaSaTimer(void)66 void WifiStaManager::StopUnloadStaSaTimer(void)
67 {
68     WIFI_LOGI("StopUnloadStaSaTimer! unloadStaSaTimerId:%{public}u", unloadStaSaTimerId);
69     std::unique_lock<std::mutex> lock(unloadStaSaTimerMutex);
70     if (unloadStaSaTimerId == 0) {
71         return;
72     }
73     MiscServices::TimeServiceClient::GetInstance()->StopTimer(unloadStaSaTimerId);
74     MiscServices::TimeServiceClient::GetInstance()->DestroyTimer(unloadStaSaTimerId);
75     unloadStaSaTimerId = 0;
76     return;
77 }
78 
StartUnloadStaSaTimer(void)79 void WifiStaManager::StartUnloadStaSaTimer(void)
80 {
81     WIFI_LOGI("StartUnloadStaSaTimer! unloadStaSaTimerId:%{public}u", unloadStaSaTimerId);
82     std::unique_lock<std::mutex> lock(unloadStaSaTimerMutex);
83     if (unloadStaSaTimerId == 0) {
84         std::shared_ptr<WifiSysTimer> wifiSysTimer = std::make_shared<WifiSysTimer>(false, 0, true, false);
85         wifiSysTimer->SetCallbackInfo(UnloadStaSaTimerCallback);
86         unloadStaSaTimerId = MiscServices::TimeServiceClient::GetInstance()->CreateTimer(wifiSysTimer);
87         int64_t currentTime = MiscServices::TimeServiceClient::GetInstance()->GetBootTimeMs();
88         MiscServices::TimeServiceClient::GetInstance()->StartTimer(unloadStaSaTimerId,
89             currentTime + TIMEOUT_UNLOAD_WIFI_SA);
90         WIFI_LOGI("StartUnloadStaSaTimer success! unloadStaSaTimerId:%{public}u", unloadStaSaTimerId);
91     }
92     return;
93 }
94 #endif
95 
CloseStaService(int instId)96 void WifiStaManager::CloseStaService(int instId)
97 {
98     WIFI_LOGI("close sta service");
99 #ifndef OHOS_ARCH_LITE
100     if (WifiConfigCenter::GetInstance().GetAirplaneModeState() == MODE_STATE_OPEN) {
101         WIFI_LOGI("airplaneMode not close sta SA!");
102         return;
103     }
104     StartUnloadStaSaTimer();
105 #endif
106     return;
107 }
108 
InitStaCallback(void)109 void WifiStaManager::InitStaCallback(void)
110 {
111     using namespace std::placeholders;
112     mStaCallback.callbackModuleName = "WifiStaManager";
113     mStaCallback.OnStaConnChanged = [this](OperateResState state, const WifiLinkedInfo &info, int instId) {
114         this->DealStaConnChanged(state, info, instId);
115     };
116     mStaCallback.OnWpsChanged = [this](WpsStartState state, const int pinCode, int instId) {
117         this->DealWpsChanged(state, pinCode, instId);
118     };
119     mStaCallback.OnStaStreamChanged = [this](StreamDirection direction, int instId) {
120         this->DealStreamChanged(direction, instId);
121     };
122     mStaCallback.OnStaRssiLevelChanged = [this](int rssi, int instId) { this->DealRssiChanged(rssi, instId); };
123     mStaCallback.OnAutoSelectNetworkRes = [this](int networkId, int instId) {
124         this->DealAutoSelectNetworkChanged(networkId, instId);
125     };
126     return;
127 }
128 
DealStaOpened(int instId)129 void WifiStaManager::DealStaOpened(int instId)
130 {
131 #ifdef FEATURE_STA_SUPPORT
132     WifiCountryCodeManager::GetInstance().DealStaOpened(instId);
133 #endif
134 #ifdef FEATURE_SELF_CURE_SUPPORT
135     ISelfCureService *pSelfCureService = WifiServiceManager::GetInstance().GetSelfCureServiceInst(instId);
136     if (pSelfCureService != nullptr) {
137         pSelfCureService->DealStaOpened(instId);
138     }
139 #endif
140     if (WifiOprMidState::RUNNING == WifiConfigCenter::GetInstance().GetWifiScanOnlyMidState(instId)) {
141         WIFI_LOGI("DealStaOpenRes: wifi scan only state notify scan result!");
142         IScanSerivceCallbacks &scanCallback = WifiManager::GetInstance().GetWifiScanManager()->GetScanCallback();
143         scanCallback.OnScanFinishEvent(static_cast<int>(ScanHandleNotify::SCAN_OK), instId);
144     }
145 }
146 
DealStaStopped(int instId)147 void WifiStaManager::DealStaStopped(int instId)
148 {
149 #ifdef FEATURE_STA_SUPPORT
150     WifiCountryCodeManager::GetInstance().DealStaStopped(instId);
151 #endif
152 }
153 
PublishWifiOperateStateHiSysEvent(OperateResState state)154 void WifiStaManager::PublishWifiOperateStateHiSysEvent(OperateResState state)
155 {
156     switch (state) {
157         case OperateResState::DISCONNECT_DISCONNECTED:
158             WriteWifiOperateStateHiSysEvent(static_cast<int>(WifiOperateType::STA_CONNECT),
159                 static_cast<int>(WifiOperateState::STA_DISCONNECTED));
160             break;
161         case OperateResState::CONNECT_ASSOCIATING:
162             WriteWifiConnectFailedEventHiSysEvent(static_cast<int>(WifiOperateState::STA_ASSOCIATING));
163             break;
164         case OperateResState::CONNECT_ASSOCIATED:
165             WriteWifiConnectFailedEventHiSysEvent(static_cast<int>(WifiOperateState::STA_ASSOCIATED));
166             break;
167         case OperateResState::CONNECT_CONNECTION_FULL:
168             WriteWifiOperateStateHiSysEvent(static_cast<int>(WifiOperateType::STA_ASSOC),
169                 static_cast<int>(WifiOperateState::STA_ASSOC_FULL_REJECT));
170             break;
171         case OperateResState::CONNECT_OBTAINING_IP:
172             WriteWifiOperateStateHiSysEvent(static_cast<int>(WifiOperateType::STA_DHCP),
173                 static_cast<int>(WifiOperateState::STA_DHCP));
174             break;
175         case OperateResState::DISCONNECT_DISCONNECTING:
176         case OperateResState::CONNECT_CONNECTING_TIMEOUT:
177             WriteWifiConnectFailedEventHiSysEvent(static_cast<int>(WifiOperateState::STA_DISCONNECT));
178             break;
179         default:
180             break;
181         }
182     return;
183 }
184 
IgnoreConnStateChange(int instId)185 bool WifiStaManager::IgnoreConnStateChange(int instId)
186 {
187     WIFI_LOGD("enter IgnoreConnStateChange");
188 #ifdef FEATURE_SELF_CURE_SUPPORT
189     ISelfCureService *pSelfCureService = WifiServiceManager::GetInstance().GetSelfCureServiceInst(instId);
190     if (pSelfCureService == nullptr) {
191         WIFI_LOGE("%{public}s: pSelfCureService is null.", __FUNCTION__);
192         return false;
193     }
194     if (WifiConfigCenter::GetInstance().GetWifiSelfcureReset()) {
195         WIFI_LOGI("reset selfcure ignore network state changed");
196         return true;
197     }
198     WifiDeviceConfig config;
199     if (WifiSettings::GetInstance().GetDeviceConfig(WifiConfigCenter::GetInstance().GetLastNetworkId(), config) != 0) {
200         WIFI_LOGE("%{public}s: Get device config failed!", __FUNCTION__);
201         return false;
202     }
203     if (pSelfCureService->IsSelfCureOnGoing() && config.isReassocSelfCureWithFactoryMacAddress != 0) {
204         WIFI_LOGI("random mac reassoc selfcure ignore network state changed");
205         return true;
206     }
207 #endif
208     return false;
209 }
210 
DealStaConnChanged(OperateResState state,const WifiLinkedInfo & info,int instId)211 void WifiStaManager::DealStaConnChanged(OperateResState state, const WifiLinkedInfo &info, int instId)
212 {
213     WIFI_LOGD("Enter, DealStaConnChanged, state: %{public}d!, message:%{public}s\n", static_cast<int>(state),
214         magic_enum::Enum2Name(state).c_str());
215     if (state == OperateResState::CONNECT_AP_CONNECTED) {
216         WifiConfigCenter::GetInstance().UpdateLinkedInfo(instId);
217     }
218     bool isReport = true;
219     int reportStateNum = static_cast<int>(ConvertConnStateInternal(state, isReport));
220     if (isReport && !IgnoreConnStateChange(instId)) {
221         WifiEventCallbackMsg cbMsg;
222         cbMsg.msgCode = WIFI_CBK_MSG_CONNECTION_CHANGE;
223         cbMsg.msgData = reportStateNum;
224         cbMsg.linkInfo = info;
225         cbMsg.id = instId;
226         WifiInternalEventDispatcher::GetInstance().AddBroadCastMsg(cbMsg);
227     }
228     if (state == OperateResState::CONNECT_CONNECTING || state == OperateResState::CONNECT_AP_CONNECTED ||
229         state == OperateResState::DISCONNECT_DISCONNECTING || state == OperateResState::DISCONNECT_DISCONNECTED ||
230         state == OperateResState::CONNECT_OBTAINING_IP || state == OperateResState::CONNECT_ASSOCIATING ||
231         state == OperateResState::CONNECT_ASSOCIATED || state == OperateResState::CONNECT_NETWORK_ENABLED ||
232         state == OperateResState::CONNECT_NETWORK_DISABLED || state == OperateResState::SPECIAL_CONNECTED) {
233         if (WifiConfigCenter::GetInstance().GetScanMidState(instId) == WifiOprMidState::RUNNING) {
234             IScanService *pService = WifiServiceManager::GetInstance().GetScanServiceInst(instId);
235             if (pService != nullptr) {
236                 pService->OnClientModeStatusChanged(static_cast<int>(state));
237             }
238         }
239     }
240     PublishWifiOperateStateHiSysEvent(state);
241     if (info.connState == ConnState::AUTHENTICATING)
242     {
243         WriteWifiOperateStateHiSysEvent(static_cast<int>(WifiOperateType::STA_AUTH),
244             static_cast<int>(WifiOperateState::STA_AUTHING));
245     }
246 #ifdef FEATURE_HPF_SUPPORT
247     if (state == OperateResState::CONNECT_AP_CONNECTED) {
248         int screenState = WifiConfigCenter::GetInstance().GetScreenState();
249         WifiManager::GetInstance().InstallPacketFilterProgram(screenState, instId);
250     }
251 #endif
252 #ifndef OHOS_ARCH_LITE
253     bool isConnected = (info.connState == CONNECTED) ? true : false;
254     WifiProtectManager::GetInstance().UpdateWifiClientConnected(isConnected);
255     if (state == OperateResState::DISCONNECT_DISCONNECTED) {
256         WifiNotificationUtil::GetInstance().CancelWifiNotification(
257             WifiNotificationId::WIFI_PORTAL_NOTIFICATION_ID);
258     }
259 #endif
260     return;
261 }
262 
DealWpsChanged(WpsStartState state,const int pinCode,int instId)263 void WifiStaManager::DealWpsChanged(WpsStartState state, const int pinCode, int instId)
264 {
265     WifiEventCallbackMsg cbMsg;
266     cbMsg.msgCode = WIFI_CBK_MSG_WPS_STATE_CHANGE;
267     cbMsg.msgData = static_cast<int>(state);
268     cbMsg.id = instId;
269     cbMsg.pinCode = std::to_string(pinCode);
270     unsigned int len = cbMsg.pinCode.length();
271     if (len < 8) { /* Fill in 8 digits. */
272         cbMsg.pinCode = std::string(8 - len, '0') + cbMsg.pinCode;
273     }
274     WifiInternalEventDispatcher::GetInstance().AddBroadCastMsg(cbMsg);
275     return;
276 }
277 
DealStreamChanged(StreamDirection direction,int instId)278 void WifiStaManager::DealStreamChanged(StreamDirection direction, int instId)
279 {
280     WifiEventCallbackMsg cbMsg;
281     cbMsg.msgCode = WIFI_CBK_MSG_STREAM_DIRECTION;
282     cbMsg.msgData = static_cast<int>(direction);
283     cbMsg.id = instId;
284     WifiInternalEventDispatcher::GetInstance().AddBroadCastMsg(cbMsg);
285     return;
286 }
287 
DealRssiChanged(int rssi,int instId)288 void WifiStaManager::DealRssiChanged(int rssi, int instId)
289 {
290     WifiEventCallbackMsg cbMsg;
291     cbMsg.msgCode = WIFI_CBK_MSG_RSSI_CHANGE;
292     cbMsg.msgData = rssi;
293     cbMsg.id = instId;
294     WifiInternalEventDispatcher::GetInstance().AddBroadCastMsg(cbMsg);
295     return;
296 }
297 
DealAutoSelectNetworkChanged(int networkId,int instId)298 void WifiStaManager::DealAutoSelectNetworkChanged(int networkId, int instId)
299 {
300     IScanService *pService = WifiServiceManager::GetInstance().GetScanServiceInst(instId);
301     if (pService != nullptr) {
302         pService->OnAutoConnectStateChanged(networkId != -1);
303     }
304     return;
305 }
306 
307 #ifndef OHOS_ARCH_LITE
StopSatelliteTimer(void)308 void WifiStaManager::StopSatelliteTimer(void)
309 {
310     WIFI_LOGI("StopSatelliteTimer! satelliteTimerId:%{public}u", satelliteTimerId);
311     std::unique_lock<std::mutex> lock(satelliteTimerMutex);
312     if (satelliteTimerId == 0) {
313         return;
314     }
315     MiscServices::TimeServiceClient::GetInstance()->StopTimer(satelliteTimerId);
316     MiscServices::TimeServiceClient::GetInstance()->DestroyTimer(satelliteTimerId);
317     satelliteTimerId = 0;
318     return;
319 }
320 
StartSatelliteTimer(void)321 void WifiStaManager::StartSatelliteTimer(void)
322 {
323     std::unique_lock<std::mutex> lock(satelliteTimerMutex);
324     std::shared_ptr<WifiSysTimer> wifiSysTimer = std::make_shared<WifiSysTimer>(false, 0, true, false);
325     wifiSysTimer->SetCallbackInfo(SatelliteTimerCallback);
326     satelliteTimerId = MiscServices::TimeServiceClient::GetInstance()->CreateTimer(wifiSysTimer);
327     int64_t currentTime = MiscServices::TimeServiceClient::GetInstance()->GetBootTimeMs();
328     MiscServices::TimeServiceClient::GetInstance()->StartTimer(satelliteTimerId,
329         currentTime + TIMEOUT_STOP_SATELLITE);
330     WIFI_LOGI("StartSatelliteTimer success! satelliteTimerId:%{public}u", satelliteTimerId);
331     return;
332 }
333 #endif
334 }  // namespace Wifi
335 }  // namespace OHOS
336