1 /*
2 * Copyright (C) 2021-2022 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 "ap_service.h"
17 #include <unistd.h>
18 #include "ap_state_machine.h"
19 #include "wifi_logger.h"
20 #include "wifi_channel_helper.h"
21 #include "wifi_config_center.h"
22 #include "wifi_ap_hal_interface.h"
23 #include "wifi_country_code_manager.h"
24
25 DEFINE_WIFILOG_HOTSPOT_LABEL("WifiApService");
26 namespace OHOS {
27 namespace Wifi {
ApService(ApStateMachine & apStateMachine,int id)28 ApService::ApService(ApStateMachine &apStateMachine, int id)
29 : m_ApStateMachine(apStateMachine), m_id(id)
30 {}
31
~ApService()32 ApService::~ApService()
33 {}
34
EnableHotspot()35 ErrCode ApService::EnableHotspot()
36 {
37 WIFI_LOGI("Instance %{public}d %{public}s", m_id, __func__);
38
39 // notification of registration country code change
40 std::string moduleName = "ApService_" + std::to_string(m_id);
41 m_apObserver = std::make_shared<WifiCountryCodeChangeObserver>(moduleName, m_ApStateMachine);
42 WifiCountryCodeManager::GetInstance().RegisterWifiCountryCodeChangeListener(m_apObserver);
43 m_ApStateMachine.SendMessage(static_cast<int>(ApStatemachineEvent::CMD_START_HOTSPOT));
44 return ErrCode::WIFI_OPT_SUCCESS;
45 }
46
DisableHotspot() const47 ErrCode ApService::DisableHotspot() const
48 {
49 WIFI_LOGI("Instance %{public}d %{public}s", m_id, __func__);
50
51 // deregistration country code change notification
52 WifiCountryCodeManager::GetInstance()
53 .UnregisterWifiCountryCodeChangeListener(m_apObserver);
54
55 m_ApStateMachine.SendMessage(static_cast<int>(ApStatemachineEvent::CMD_STOP_HOTSPOT));
56 return ErrCode::WIFI_OPT_SUCCESS;
57 }
58
SetHotspotConfig(const HotspotConfig & cfg) const59 ErrCode ApService::SetHotspotConfig(const HotspotConfig &cfg) const
60 {
61 WIFI_LOGI("Instance %{public}d %{public}s", m_id, __func__);
62 InternalMessagePtr msg = m_ApStateMachine.CreateMessage();
63 if (msg == nullptr) {
64 return ErrCode::WIFI_OPT_FAILED;
65 }
66 msg->SetMessageName(static_cast<int>(ApStatemachineEvent::CMD_SET_HOTSPOT_CONFIG));
67 msg->AddStringMessageBody(cfg.GetSsid());
68 msg->AddStringMessageBody(cfg.GetPreSharedKey());
69 msg->AddIntMessageBody(static_cast<int>(cfg.GetSecurityType()));
70 msg->AddIntMessageBody(static_cast<int>(cfg.GetBand()));
71 msg->AddIntMessageBody(cfg.GetChannel());
72 msg->AddIntMessageBody(cfg.GetBandWidth());
73 msg->AddIntMessageBody(cfg.GetMaxConn());
74 msg->AddStringMessageBody(cfg.GetIpAddress());
75 msg->AddIntMessageBody(cfg.GetLeaseTime());
76 m_ApStateMachine.SendMessage(msg);
77 return ErrCode::WIFI_OPT_SUCCESS;
78 }
79
SetHotspotIdleTimeout(int time) const80 ErrCode ApService::SetHotspotIdleTimeout(int time) const
81 {
82 WIFI_LOGI("SetHotspotIdleTimeout");
83 InternalMessagePtr msg = m_ApStateMachine.CreateMessage();
84 if (msg == nullptr) {
85 return ErrCode::WIFI_OPT_FAILED;
86 }
87 msg->SetMessageName(static_cast<int>(ApStatemachineEvent::CMD_SET_IDLE_TIMEOUT));
88 msg->AddIntMessageBody(time);
89 m_ApStateMachine.SendMessage(msg);
90 return ErrCode::WIFI_OPT_SUCCESS;
91 }
92
AddBlockList(const StationInfo & stationInfo) const93 ErrCode ApService::AddBlockList(const StationInfo &stationInfo) const
94 {
95 WIFI_LOGI("Instance %{public}d %{public}s", m_id, __func__);
96 InternalMessagePtr msg = m_ApStateMachine.CreateMessage();
97 if (msg == nullptr) {
98 return ErrCode::WIFI_OPT_FAILED;
99 }
100 msg->SetMessageName(static_cast<int>(ApStatemachineEvent::CMD_ADD_BLOCK_LIST));
101 msg->AddStringMessageBody(stationInfo.deviceName);
102 msg->AddStringMessageBody(stationInfo.bssid);
103 msg->AddStringMessageBody(stationInfo.ipAddr);
104 m_ApStateMachine.SendMessage(msg);
105 return ErrCode::WIFI_OPT_SUCCESS;
106 }
107
DelBlockList(const StationInfo & stationInfo) const108 ErrCode ApService::DelBlockList(const StationInfo &stationInfo) const
109 {
110 WIFI_LOGI("Instance %{public}d %{public}s", m_id, __func__);
111 InternalMessagePtr msg = m_ApStateMachine.CreateMessage();
112 if (msg == nullptr) {
113 return ErrCode::WIFI_OPT_FAILED;
114 }
115 msg->SetMessageName(static_cast<int>(ApStatemachineEvent::CMD_DEL_BLOCK_LIST));
116 msg->AddStringMessageBody(stationInfo.deviceName);
117 msg->AddStringMessageBody(stationInfo.bssid);
118 msg->AddStringMessageBody(stationInfo.ipAddr);
119 m_ApStateMachine.SendMessage(msg);
120 return ErrCode::WIFI_OPT_SUCCESS;
121 }
122
DisconnetStation(const StationInfo & stationInfo) const123 ErrCode ApService::DisconnetStation(const StationInfo &stationInfo) const
124 {
125 WIFI_LOGI("Instance %{public}d %{public}s", m_id, __func__);
126 InternalMessagePtr msg = m_ApStateMachine.CreateMessage();
127 if (msg == nullptr) {
128 return ErrCode::WIFI_OPT_FAILED;
129 }
130 msg->SetMessageName(static_cast<int>(ApStatemachineEvent::CMD_DISCONNECT_STATION));
131 msg->AddStringMessageBody(stationInfo.deviceName);
132 msg->AddStringMessageBody(stationInfo.bssid);
133 msg->AddStringMessageBody(stationInfo.ipAddr);
134 m_ApStateMachine.SendMessage(msg);
135 return ErrCode::WIFI_OPT_SUCCESS;
136 }
137
GetStationList(std::vector<StationInfo> & result) const138 ErrCode ApService::GetStationList(std::vector<StationInfo> &result) const
139 {
140 WIFI_LOGI("Instance %{public}d %{public}s", m_id, __func__);
141 WifiConfigCenter::GetInstance().GetStationList(result);
142 if (result.empty()) {
143 WIFI_LOGW("GetStationList is empty.");
144 return ErrCode::WIFI_OPT_SUCCESS;
145 }
146 // get dhcp lease info, return full connected station info
147 std::map<std::string, StationInfo> tmp;
148 if (!m_ApStateMachine.GetConnectedStationInfo(tmp)) {
149 WIFI_LOGW("Get connected station info failed!");
150 return ErrCode::WIFI_OPT_FAILED;
151 }
152 for (auto iter = result.begin(); iter != result.end(); ++iter) {
153 auto itMap = tmp.find(iter->bssid);
154 if (itMap == tmp.end()) {
155 continue;
156 }
157 iter->deviceName = itMap->second.deviceName;
158 iter->ipAddr = itMap->second.ipAddr;
159 }
160 return ErrCode::WIFI_OPT_SUCCESS;
161 }
162
GetValidBands(std::vector<BandType> & bands)163 ErrCode ApService::GetValidBands(std::vector<BandType> &bands)
164 {
165 WIFI_LOGI("Instance %{public}d %{public}s", m_id, __func__);
166 std::vector<int> allowed5GFreq;
167 std::vector<int> allowed2GFreq;
168 if (WifiChannelHelper::GetInstance().GetValidBands(bands) != 0) {
169 WIFI_LOGE("%{public}s, GetValidBands failed!", __func__);
170 return ErrCode::WIFI_OPT_FAILED;
171 }
172 if (bands.size() > 0) {
173 return ErrCode::WIFI_OPT_SUCCESS;
174 }
175
176 /* Get freqs from hal */
177 if (WifiApHalInterface::GetInstance().GetFrequenciesByBand(
178 WifiConfigCenter::GetInstance().GetApIfaceName(), static_cast<int>(BandType::BAND_2GHZ), allowed2GFreq)) {
179 WIFI_LOGW("%{public}s, fail to get 2.4G channel", __func__);
180 }
181 if (WifiApHalInterface::GetInstance().GetFrequenciesByBand(
182 WifiConfigCenter::GetInstance().GetApIfaceName(), static_cast<int>(BandType::BAND_5GHZ), allowed5GFreq)) {
183 WIFI_LOGW("%{public}s, fail to get 5G channel", __func__);
184 }
185 if (allowed2GFreq.size() > 0) {
186 bands.push_back(BandType::BAND_2GHZ);
187 }
188 if (allowed5GFreq.size() > 0) {
189 bands.push_back(BandType::BAND_5GHZ);
190 }
191 if (bands.size() == 0) {
192 WIFI_LOGW("%{public}s, GetValidBands failed!", __func__);
193 return ErrCode::WIFI_OPT_FAILED;
194 }
195 return ErrCode::WIFI_OPT_SUCCESS;
196 }
197
GetValidChannels(BandType band,std::vector<int32_t> & validChannel)198 ErrCode ApService::GetValidChannels(BandType band, std::vector<int32_t> &validChannel)
199 {
200 WIFI_LOGI("Instance %{public}d %{public}s", m_id, __func__);
201 ChannelsTable channelsInfo;
202 if (WifiChannelHelper::GetInstance().GetValidChannels(channelsInfo) != 0) {
203 WIFI_LOGE("Failed to obtain channels from the WifiSettings.");
204 return ErrCode::WIFI_OPT_FAILED;
205 }
206
207 if (channelsInfo.size() > 0) {
208 auto it = channelsInfo.find(band);
209 if (it != channelsInfo.end()) {
210 validChannel = channelsInfo[band];
211 WIFI_LOGI("%{public}s, get valid channel size:%{public}d, band:%{public}d from WifiSettings.",
212 __func__, (int)validChannel.size(), band);
213 return ErrCode::WIFI_OPT_SUCCESS;
214 }
215 }
216
217 /* get freqs from hal service */
218 std::vector<int32_t> allowed5GFreq, allowed2GFreq;
219 std::vector<int32_t> allowed5GChan, allowed2GChan;
220 if (WifiApHalInterface::GetInstance().GetFrequenciesByBand(
221 WifiConfigCenter::GetInstance().GetApIfaceName(), static_cast<int>(BandType::BAND_2GHZ), allowed2GFreq)) {
222 WIFI_LOGW("%{public}s, fail to get 2.4G channel", __func__);
223 }
224 if (WifiApHalInterface::GetInstance().GetFrequenciesByBand(
225 WifiConfigCenter::GetInstance().GetApIfaceName(), static_cast<int>(BandType::BAND_5GHZ), allowed5GFreq)) {
226 WIFI_LOGW("%{public}s, fail to get 5G channel", __func__);
227 }
228 if (allowed2GFreq.size() == 0) {
229 WifiSettings::GetInstance().SetDefaultFrequenciesByCountryBand(BandType::BAND_2GHZ, allowed2GFreq);
230 }
231 TransformFrequencyIntoChannel(allowed2GFreq, allowed2GChan);
232 TransformFrequencyIntoChannel(allowed5GFreq, allowed5GChan);
233
234 ChannelsTable ChanTbs;
235 ChanTbs[BandType::BAND_2GHZ] = allowed2GChan;
236 ChanTbs[BandType::BAND_5GHZ] = allowed5GChan;
237 if (WifiChannelHelper::GetInstance().SetValidChannels(ChanTbs)) {
238 WIFI_LOGE("%{public}s, fail to SetValidChannels", __func__);
239 }
240 if (band == BandType::BAND_2GHZ || band == BandType::BAND_5GHZ) {
241 validChannel = ChanTbs[band];
242 } else {
243 WIFI_LOGE("%{public}s, invalid band: %{public}d", __func__, band);
244 return ErrCode::WIFI_OPT_INVALID_PARAM;
245 }
246 WIFI_LOGI("%{public}s, get valid channel size:%{public}d, band:%{public}d from hal service.",
247 __func__, (int)validChannel.size(), band);
248 return ErrCode::WIFI_OPT_SUCCESS;
249 }
250
RegisterApServiceCallbacks(const IApServiceCallbacks & callbacks)251 ErrCode ApService::RegisterApServiceCallbacks(const IApServiceCallbacks &callbacks)
252 {
253 WIFI_LOGI("%{public}s, Instance %{public}d ", __func__, m_id);
254 m_ApStateMachine.RegisterApServiceCallbacks(callbacks);
255 return ErrCode::WIFI_OPT_SUCCESS;
256 }
257
GetSupportedPowerModel(std::set<PowerModel> & setPowerModelList)258 ErrCode ApService::GetSupportedPowerModel(std::set<PowerModel>& setPowerModelList)
259 {
260 WIFI_LOGI("Instance %{public}d %{public}s", m_id, __func__);
261 /* All modes are currently supported */
262 setPowerModelList.insert(PowerModel::SLEEPING);
263 setPowerModelList.insert(PowerModel::GENERAL);
264 setPowerModelList.insert(PowerModel::THROUGH_WALL);
265 return ErrCode::WIFI_OPT_SUCCESS;
266 }
267
GetPowerModel(PowerModel & model)268 ErrCode ApService::GetPowerModel(PowerModel& model)
269 {
270 WIFI_LOGI("Instance %{public}d %{public}s", m_id, __func__);
271 WifiConfigCenter::GetInstance().GetPowerModel(model, m_id);
272 LOGI("ApService::GetPowerModel, model=[%{public}d]", static_cast<int>(model));
273 return ErrCode::WIFI_OPT_SUCCESS;
274 }
275
SetPowerModel(const PowerModel & model)276 ErrCode ApService::SetPowerModel(const PowerModel& model)
277 {
278 WIFI_LOGI("Instance %{public}d %{public}s", m_id, __func__);
279 LOGI("Enter ApService::SetPowerModel, model=[%d]", static_cast<int>(model));
280 if (WifiApHalInterface::GetInstance().SetPowerModel(
281 WifiConfigCenter::GetInstance().GetApIfaceName(), static_cast<int>(model)) != WIFI_HAL_OPT_OK) {
282 LOGE("SetPowerModel() failed!");
283 return WIFI_OPT_FAILED;
284 }
285 LOGI("SetPowerModel() succeed!");
286 WifiConfigCenter::GetInstance().SetPowerModel(model);
287 return ErrCode::WIFI_OPT_SUCCESS;
288 }
289
OnWifiCountryCodeChanged(const std::string & wifiCountryCode)290 ErrCode ApService::WifiCountryCodeChangeObserver::OnWifiCountryCodeChanged(const std::string &wifiCountryCode)
291 {
292 if (strcasecmp(m_lastWifiCountryCode.c_str(), wifiCountryCode.c_str()) == 0) {
293 WIFI_LOGI("wifi country code is same, ap not update, code=%{public}s", wifiCountryCode.c_str());
294 return WIFI_OPT_SUCCESS;
295 }
296 WIFI_LOGI("deal wifi country code changed, code=%{public}s", wifiCountryCode.c_str());
297 InternalMessagePtr msg = m_stateMachineObj.CreateMessage();
298 CHECK_NULL_AND_RETURN(msg, WIFI_OPT_FAILED);
299 msg->SetMessageName(static_cast<int>(ApStatemachineEvent::CMD_UPDATE_COUNTRY_CODE));
300 msg->AddStringMessageBody(wifiCountryCode);
301 m_stateMachineObj.SendMessage(msg);
302 m_lastWifiCountryCode = wifiCountryCode;
303 return WIFI_OPT_SUCCESS;
304 }
305
GetListenerModuleName()306 std::string ApService::WifiCountryCodeChangeObserver::GetListenerModuleName()
307 {
308 return m_listenerModuleName;
309 }
310 } // namespace Wifi
311 } // namespace OHOS