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