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 #ifdef FEATURE_AP_SUPPORT
17 #include "wifi_hotspot_manager.h"
18 #include "wifi_manager.h"
19 #include "wifi_service_manager.h"
20 #include "wifi_config_center.h"
21 #include "wifi_logger.h"
22 #include "wifi_common_event_helper.h"
23 #include "wifi_system_timer.h"
24 #ifdef OHOS_ARCH_LITE
25 #include "wifi_internal_event_dispatcher_lite.h"
26 #else
27 #include "wifi_internal_event_dispatcher.h"
28 #include "wifi_sa_manager.h"
29 #endif
30 
31 DEFINE_WIFILOG_LABEL("WifiHotspotManager");
32 
33 namespace OHOS {
34 namespace Wifi {
WifiHotspotManager()35 WifiHotspotManager::WifiHotspotManager()
36 {
37     WIFI_LOGI("create WifiHotspotManager");
38     InitApCallback();
39 }
40 
GetApCallback()41 IApServiceCallbacks& WifiHotspotManager::GetApCallback()
42 {
43     return mApCallback;
44 }
45 
46 #ifndef OHOS_ARCH_LITE
UnloadHotspotSaTimerCallback()47 static void UnloadHotspotSaTimerCallback()
48 {
49     WifiSaLoadManager::GetInstance().UnloadWifiSa(WIFI_HOTSPOT_ABILITY_ID);
50     WifiManager::GetInstance().GetWifiHotspotManager()->StopUnloadApSaTimer();
51 }
52 
StopUnloadApSaTimer(void)53 void WifiHotspotManager::StopUnloadApSaTimer(void)
54 {
55     WIFI_LOGI("StopUnloadApSaTimer! unloadHotspotSaTimerId:%{public}u", unloadHotspotSaTimerId);
56     std::unique_lock<std::mutex> lock(unloadHotspotSaTimerMutex);
57     if (unloadHotspotSaTimerId == 0) {
58         return;
59     }
60     MiscServices::TimeServiceClient::GetInstance()->StopTimer(unloadHotspotSaTimerId);
61     MiscServices::TimeServiceClient::GetInstance()->DestroyTimer(unloadHotspotSaTimerId);
62     unloadHotspotSaTimerId = 0;
63     return;
64 }
65 
StartUnloadApSaTimer(void)66 void WifiHotspotManager::StartUnloadApSaTimer(void)
67 {
68     WIFI_LOGI("StartUnloadApSaTimer! unloadHotspotSaTimerId:%{public}u", unloadHotspotSaTimerId);
69     std::unique_lock<std::mutex> lock(unloadHotspotSaTimerMutex);
70     if (unloadHotspotSaTimerId == 0) {
71         std::shared_ptr<WifiSysTimer> wifiSysTimer = std::make_shared<WifiSysTimer>(false, 0, true, false);
72         wifiSysTimer->SetCallbackInfo(UnloadHotspotSaTimerCallback);
73         unloadHotspotSaTimerId = MiscServices::TimeServiceClient::GetInstance()->CreateTimer(wifiSysTimer);
74         int64_t currentTime = MiscServices::TimeServiceClient::GetInstance()->GetBootTimeMs();
75         MiscServices::TimeServiceClient::GetInstance()->StartTimer(unloadHotspotSaTimerId,
76             currentTime + TIMEOUT_UNLOAD_WIFI_SA);
77         WIFI_LOGI("RegisterUnloadHotspotSaTimer success! unloadHotspotSaTimerId:%{public}u", unloadHotspotSaTimerId);
78     }
79     return;
80 }
81 #endif
82 
CloseApService(int id)83 void WifiHotspotManager::CloseApService(int id)
84 {
85     WIFI_LOGI("close %{public}d ap service", id);
86     WifiServiceManager::GetInstance().UnloadService(WIFI_SERVICE_AP, id);
87     WifiConfigCenter::GetInstance().SetApMidState(WifiOprMidState::CLOSED, id);
88     WifiConfigCenter::GetInstance().SetHotspotState(static_cast<int>(ApState::AP_STATE_CLOSED), id);
89     auto &ins =  WifiManager::GetInstance().GetWifiTogglerManager()->GetControllerMachine();
90     ins->SendMessage(CMD_AP_STOPPED, id);
91     WifiEventCallbackMsg cbMsg;
92     cbMsg.msgCode = WIFI_CBK_MSG_HOTSPOT_STATE_CHANGE;
93     cbMsg.msgData = static_cast<int>(ApState::AP_STATE_CLOSED);
94     cbMsg.id = id;
95     WifiInternalEventDispatcher::GetInstance().AddBroadCastMsg(cbMsg);
96     std::string msg = std::string("OnHotspotStateChanged") + std::string("id = ") + std::to_string(id);
97     WifiCommonEventHelper::PublishHotspotStateChangedEvent(static_cast<int>(ApState::AP_STATE_CLOSED), msg);
98 #ifndef OHOS_ARCH_LITE
99     if (WifiConfigCenter::GetInstance().GetAirplaneModeState() == MODE_STATE_OPEN) {
100         WIFI_LOGI("airplaneMode not close ap SA!");
101         return;
102     }
103     StartUnloadApSaTimer();
104 #endif
105     return;
106 }
107 
InitApCallback(void)108 void WifiHotspotManager::InitApCallback(void)
109 {
110     using namespace std::placeholders;
111     mApCallback.callbackModuleName = "WifiHotspotManager";
112     mApCallback.OnApStateChangedEvent = std::bind(&WifiHotspotManager::DealApStateChanged, this, _1, _2);
113     mApCallback.OnHotspotStaJoinEvent = std::bind(&WifiHotspotManager::DealApGetStaJoin, this, _1, _2);
114     mApCallback.OnHotspotStaLeaveEvent = std::bind(&WifiHotspotManager::DealApGetStaLeave, this, _1, _2);
115     return;
116 }
117 
DealApStateChanged(ApState state,int id)118 void WifiHotspotManager::DealApStateChanged(ApState state, int id)
119 {
120     WIFI_LOGE("%{public}s, state: %{public}d!", __func__, state);
121     WifiEventCallbackMsg cbMsg;
122     cbMsg.msgCode = WIFI_CBK_MSG_HOTSPOT_STATE_CHANGE;
123     cbMsg.msgData = static_cast<int>(state);
124     cbMsg.id = id;
125     WifiInternalEventDispatcher::GetInstance().AddBroadCastMsg(cbMsg);
126     if (state == ApState::AP_STATE_IDLE) {
127         WifiConfigCenter::GetInstance().SetApMidState(WifiOprMidState::CLOSING, id);
128         WifiManager::GetInstance().PushServiceCloseMsg(WifiCloseServiceCode::AP_SERVICE_CLOSE);
129     }
130     if (state == ApState::AP_STATE_STARTED) {
131         WifiConfigCenter::GetInstance().SetApMidState(WifiOprMidState::OPENING, WifiOprMidState::RUNNING, id);
132         auto &ins =  WifiManager::GetInstance().GetWifiTogglerManager()->GetControllerMachine();
133         ins->SendMessage(CMD_AP_START, id);
134     }
135 
136     std::string msg = std::string("OnHotspotStateChanged") + std::string("id = ") + std::to_string(id);
137     WifiCommonEventHelper::PublishHotspotStateChangedEvent((int)state, msg);
138     return;
139 }
140 
DealApGetStaJoin(const StationInfo & info,int id)141 void WifiHotspotManager::DealApGetStaJoin(const StationInfo &info, int id)
142 {
143     WifiEventCallbackMsg cbMsg;
144     cbMsg.msgCode = WIFI_CBK_MSG_HOTSPOT_STATE_JOIN;
145     cbMsg.staInfo = info;
146     cbMsg.id = id;
147     WifiInternalEventDispatcher::GetInstance().AddBroadCastMsg(cbMsg);
148     std::string msg = std::string("ApStaJoined") + std::string("id = ") + std::to_string(id);
149     WifiCommonEventHelper::PublishApStaJoinEvent(0, msg);
150     WifiManager::GetInstance().GetWifiTogglerManager()->GetControllerMachine()->StopSoftapCloseTimer();
151     return;
152 }
153 
DealApGetStaLeave(const StationInfo & info,int id)154 void WifiHotspotManager::DealApGetStaLeave(const StationInfo &info, int id)
155 {
156     WifiEventCallbackMsg cbMsg;
157     cbMsg.msgCode = WIFI_CBK_MSG_HOTSPOT_STATE_LEAVE;
158     cbMsg.staInfo = info;
159     cbMsg.id = id;
160     WifiInternalEventDispatcher::GetInstance().AddBroadCastMsg(cbMsg);
161     std::string msg = std::string("ApStaLeaved") + std::string("id = ") + std::to_string(id);
162     WifiCommonEventHelper::PublishApStaLeaveEvent(0, msg);
163     std::vector<StationInfo> result;
164     IApService *pService = WifiServiceManager::GetInstance().GetApServiceInst(id);
165     if (pService == nullptr) {
166         WIFI_LOGE("Instance %{public}d get hotspot service is null!", id);
167         return;
168     }
169     ErrCode errCode = pService->GetStationList(result);
170     if (errCode != ErrCode::WIFI_OPT_SUCCESS) {
171         return;
172     }
173     if (result.empty()) {
174         WifiManager::GetInstance().GetWifiTogglerManager()->GetControllerMachine()->StartSoftapCloseTimer();
175     }
176     return;
177 }
178 
179 }  // namespace Wifi
180 }  // namespace OHOS
181 #endif