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_channel_helper.h"
17 #include "wifi_config_center.h"
18 #include "wifi_logger.h"
19 #include "wifi_settings.h"
20 #ifdef HDI_CHIP_INTERFACE_SUPPORT
21 #include "hal_device_manage.h"
22 #endif
23 #include "wifi_country_code_manager.h"
24
25 namespace OHOS {
26 namespace Wifi {
27 DEFINE_WIFILOG_LABEL("WifiChannelHelper");
28
29 constexpr int FREQ_2G_MIN = 2412;
30 constexpr int FREQ_2G_MAX = 2472;
31 constexpr int FREQ_5G_MIN = 5170;
32 constexpr int FREQ_5G_MAX = 5825;
33 constexpr int CHANNEL_14_FREQ = 2484;
34 constexpr int CHANNEL_14 = 14;
35 constexpr int CENTER_FREQ_DIFF = 5;
36 constexpr int CHANNEL_2G_MIN = 1;
37 constexpr int CHANNEL_2G_MAX = 14; // 2484
38 constexpr int CHANNEL_5G_MIN = 34;
39 constexpr int CHANNEL_5G_MAX = 165; // 5825
40 constexpr int FREQ_CHANNEL_1 = 2412;
41 constexpr int FREQ_CHANNEL_34 = 5170;
42 constexpr int FREQ_2G_MIN_RANGE = 2400;
43 constexpr int FREQ_2G_MAX_RANGE = 2500;
44 constexpr int FREQ_5G_MIN_RANGE = 4900;
45 constexpr int FREQ_5G_MAX_RANGE = 5900;
46 #ifndef OHOS_ARCH_LITE
47 const std::vector<std::string> g_countryCodeNotSupport5G = {"jp", "JP", "ru", "RU", "in", "IN", "qa", "QA", "il", "IL"};
48 #endif
49
WifiChannelHelper()50 WifiChannelHelper::WifiChannelHelper()
51 {
52 UpdateValidFreqs();
53 }
54
GetInstance()55 WifiChannelHelper &WifiChannelHelper::GetInstance()
56 {
57 static WifiChannelHelper gWifiChannelHelper;
58 return gWifiChannelHelper;
59 }
60
GetValidBands(std::vector<BandType> & bands)61 int WifiChannelHelper::GetValidBands(std::vector<BandType> &bands)
62 {
63 std::unique_lock<std::mutex> lock(mMutex);
64 auto it = mValidChannels.find(BandType::BAND_2GHZ);
65 if (it != mValidChannels.end() && it->second.size() > 0) {
66 bands.push_back(BandType::BAND_2GHZ);
67 }
68 it = mValidChannels.find(BandType::BAND_5GHZ);
69 if (it != mValidChannels.end() && it->second.size() > 0) {
70 #ifndef OHOS_ARCH_LITE
71 std::string countryCode;
72 WifiCountryCodeManager::GetInstance().GetWifiCountryCode(countryCode);
73 WIFI_LOGD("GetValidBands: country code is %{public}s", countryCode.c_str());
74 auto iter = std::find(g_countryCodeNotSupport5G.begin(), g_countryCodeNotSupport5G.end(), countryCode);
75 if (iter != g_countryCodeNotSupport5G.end()) {
76 return 0;
77 }
78 #endif
79 bands.push_back(BandType::BAND_5GHZ);
80 }
81 return 0;
82 }
83
SetValidChannels(const ChannelsTable & channelsInfo)84 int WifiChannelHelper::SetValidChannels(const ChannelsTable &channelsInfo)
85 {
86 std::unique_lock<std::mutex> lock(mMutex);
87 mValidChannels = channelsInfo;
88 return 0;
89 }
90
GetValidChannels(ChannelsTable & channelsInfo)91 int WifiChannelHelper::GetValidChannels(ChannelsTable &channelsInfo)
92 {
93 std::unique_lock<std::mutex> lock(mMutex);
94 channelsInfo = mValidChannels;
95 return 0;
96 }
97
UpdateValidChannels(std::string ifaceName,int instId)98 void WifiChannelHelper::UpdateValidChannels(std::string ifaceName, int instId)
99 {
100 WIFI_LOGI("enter UpdateValidChannels");
101 ChannelsTable chanTbs;
102 std::vector<int> freqs2G;
103 std::vector<int> freqs5G;
104 int band = static_cast<int>(BandType::BAND_2GHZ);
105 #ifdef HDI_CHIP_INTERFACE_SUPPORT
106 if (!HalDeviceManager::GetInstance().GetFrequenciesByBand(ifaceName, band, freqs2G)) {
107 WIFI_LOGE("get 2g frequencies failed.");
108 WifiSettings::GetInstance().SetDefaultFrequenciesByCountryBand(BandType::BAND_2GHZ, freqs2G, instId);
109 }
110 #endif
111 band = static_cast<int>(BandType::BAND_5GHZ);
112 #ifdef HDI_CHIP_INTERFACE_SUPPORT
113 if (!HalDeviceManager::GetInstance().GetFrequenciesByBand(ifaceName, band, freqs5G)) {
114 WIFI_LOGE("get 5g frequencies failed.");
115 }
116 #endif
117 std::vector<int32_t> supp2Gfreqs(freqs2G.begin(), freqs2G.end());
118 std::vector<int32_t> supp5Gfreqs(freqs5G.begin(), freqs5G.end());
119 for (auto iter = supp2Gfreqs.begin(); iter != supp2Gfreqs.end(); iter++) {
120 int32_t channel = TransformFrequencyIntoChannel(*iter);
121 if (channel == INVALID_FREQ_OR_CHANNEL) {
122 continue;
123 }
124 chanTbs[BandType::BAND_2GHZ].push_back(channel);
125 }
126 for (auto iter = supp5Gfreqs.begin(); iter != supp5Gfreqs.end(); iter++) {
127 int32_t channel = TransformFrequencyIntoChannel(*iter);
128 if (channel == INVALID_FREQ_OR_CHANNEL) {
129 continue;
130 }
131 chanTbs[BandType::BAND_5GHZ].push_back(channel);
132 }
133 if (SetValidChannels(chanTbs)) {
134 WIFI_LOGE("%{public}s, fail to SetValidChannels", __func__);
135 }
136 }
137
UpdateValidFreqs()138 void WifiChannelHelper::UpdateValidFreqs()
139 {
140 std::vector<int> freqs2G;
141 std::vector<int> freqs5G;
142 std::vector<int> freqsDfs;
143 std::string ifaceName = WifiConfigCenter::GetInstance().GetStaIfaceName();
144 int band = static_cast<int>(ScanBandType::SCAN_BAND_24_GHZ);
145 #ifdef HDI_CHIP_INTERFACE_SUPPORT
146 if (!HalDeviceManager::GetInstance().GetFrequenciesByBand(ifaceName, band, freqs2G)) {
147 WIFI_LOGE("get 2g frequencies failed.");
148 }
149 #endif
150 band = static_cast<int>(ScanBandType::SCAN_BAND_5_GHZ);
151 #ifdef HDI_CHIP_INTERFACE_SUPPORT
152 if (!HalDeviceManager::GetInstance().GetFrequenciesByBand(ifaceName, band, freqs5G)) {
153 WIFI_LOGE("get 5g frequencies failed.");
154 }
155 #endif
156 band = static_cast<int>(ScanBandType::SCAN_BAND_5_GHZ_DFS_ONLY);
157 #ifdef HDI_CHIP_INTERFACE_SUPPORT
158 if (!HalDeviceManager::GetInstance().GetFrequenciesByBand(ifaceName, band, freqsDfs)) {
159 WIFI_LOGE("get 5g frequencies failed.");
160 }
161 #endif
162 mValidFreqs[ScanBandType::SCAN_BAND_24_GHZ] = freqs2G;
163 mValidFreqs[ScanBandType::SCAN_BAND_5_GHZ] = freqs5G;
164 mValidFreqs[ScanBandType::SCAN_BAND_5_GHZ_DFS_ONLY] = freqsDfs;
165 }
166
GetAvailableScanFreqs(ScanBandType band,std::vector<int32_t> & freqs)167 bool WifiChannelHelper::GetAvailableScanFreqs(ScanBandType band, std::vector<int32_t>& freqs)
168 {
169 switch (band) {
170 case ScanBandType::SCAN_BAND_24_GHZ: {
171 freqs.assign(mValidFreqs[ScanBandType::SCAN_BAND_24_GHZ].begin(),
172 mValidFreqs[ScanBandType::SCAN_BAND_24_GHZ].end());
173 return true;
174 }
175 case ScanBandType::SCAN_BAND_5_GHZ: {
176 freqs.assign(mValidFreqs[ScanBandType::SCAN_BAND_5_GHZ].begin(),
177 mValidFreqs[ScanBandType::SCAN_BAND_5_GHZ].end());
178 return true;
179 }
180 case ScanBandType::SCAN_BAND_BOTH: {
181 freqs.insert(freqs.end(), mValidFreqs[ScanBandType::SCAN_BAND_24_GHZ].begin(),
182 mValidFreqs[ScanBandType::SCAN_BAND_24_GHZ].end());
183 freqs.insert(freqs.end(), mValidFreqs[ScanBandType::SCAN_BAND_5_GHZ].begin(),
184 mValidFreqs[ScanBandType::SCAN_BAND_5_GHZ].end());
185 return true;
186 }
187 case ScanBandType::SCAN_BAND_5_GHZ_DFS_ONLY: {
188 freqs.assign(mValidFreqs[ScanBandType::SCAN_BAND_5_GHZ_DFS_ONLY].begin(),
189 mValidFreqs[ScanBandType::SCAN_BAND_5_GHZ_DFS_ONLY].end());
190 return true;
191 }
192 case ScanBandType::SCAN_BAND_5_GHZ_WITH_DFS: {
193 freqs.insert(freqs.end(), mValidFreqs[ScanBandType::SCAN_BAND_5_GHZ].begin(),
194 mValidFreqs[ScanBandType::SCAN_BAND_5_GHZ].end());
195 freqs.insert(freqs.end(), mValidFreqs[ScanBandType::SCAN_BAND_5_GHZ_DFS_ONLY].begin(),
196 mValidFreqs[ScanBandType::SCAN_BAND_5_GHZ_DFS_ONLY].end());
197 return true;
198 }
199 case ScanBandType::SCAN_BAND_BOTH_WITH_DFS: {
200 freqs.insert(freqs.end(), mValidFreqs[ScanBandType::SCAN_BAND_24_GHZ].begin(),
201 mValidFreqs[ScanBandType::SCAN_BAND_24_GHZ].end());
202 freqs.insert(freqs.end(), mValidFreqs[ScanBandType::SCAN_BAND_5_GHZ].begin(),
203 mValidFreqs[ScanBandType::SCAN_BAND_5_GHZ].end());
204 freqs.insert(freqs.end(), mValidFreqs[ScanBandType::SCAN_BAND_5_GHZ_DFS_ONLY].begin(),
205 mValidFreqs[ScanBandType::SCAN_BAND_5_GHZ_DFS_ONLY].end());
206 return true;
207 }
208 default:
209 WIFI_LOGE("bandType(%{public}d) is error.\n", band);
210 return false;
211 }
212 }
213
IsFreqDbac(int freqA,int freqB)214 bool WifiChannelHelper::IsFreqDbac(int freqA, int freqB)
215 {
216 if (freqA == freqB) {
217 return false;
218 }
219 if (IsValid5GHz(freqA) && IsValid5GHz(freqB)) {
220 return true;
221 }
222 if (IsValid24GHz(freqA) && IsValid24GHz(freqB)) {
223 return true;
224 }
225 return false;
226 }
227
IsChannelDbac(int channelA,int channelB)228 bool WifiChannelHelper::IsChannelDbac(int channelA, int channelB)
229 {
230 if (channelA == channelB) {
231 return false;
232 }
233 if (IsValid5GChannel(channelA) && IsValid5GChannel(channelB)) {
234 return true;
235 }
236 if (IsValid24GChannel(channelA) && IsValid24GChannel(channelB)) {
237 return true;
238 }
239 return false;
240 }
241
TransformFrequencyIntoChannel(const std::vector<int> & freqVector,std::vector<int> & chanVector)242 void WifiChannelHelper::TransformFrequencyIntoChannel(const std::vector<int> &freqVector, std::vector<int> &chanVector)
243 {
244 int channel;
245 for (size_t i = 0; i < freqVector.size(); ++i) {
246 channel = TransformFrequencyIntoChannel(freqVector[i]);
247 if (channel == -1) {
248 LOGW("Invalid Freq:%d", freqVector[i]);
249 continue;
250 }
251 chanVector.push_back(channel);
252 }
253 }
254
TransformFrequencyIntoChannel(int freq)255 int WifiChannelHelper::TransformFrequencyIntoChannel(int freq)
256 {
257 if (freq >= FREQ_2G_MIN && freq <= FREQ_2G_MAX) {
258 return (freq - FREQ_2G_MIN) / CENTER_FREQ_DIFF + CHANNEL_2G_MIN;
259 } else if (freq == CHANNEL_14_FREQ) {
260 return CHANNEL_14;
261 } else if (freq >= FREQ_5G_MIN && freq <= FREQ_5G_MAX) {
262 return (freq - FREQ_5G_MIN) / CENTER_FREQ_DIFF + CHANNEL_5G_MIN;
263 }
264 return -1;
265 }
266
TransformChannelToFrequency(int channel)267 int WifiChannelHelper::TransformChannelToFrequency(int channel)
268 {
269 WIFI_LOGI("ChannelToFrequency: %{public}d", channel);
270 if (channel >= CHANNEL_2G_MIN && channel <= CHANNEL_2G_MAX) {
271 return ((channel - CHANNEL_2G_MIN) * CENTER_FREQ_DIFF + FREQ_CHANNEL_1);
272 }
273 if (CHANNEL_5G_MIN <= channel && channel <= CHANNEL_5G_MAX) {
274 return ((channel - CHANNEL_5G_MIN) * CENTER_FREQ_DIFF + FREQ_CHANNEL_34);
275 }
276 return INVALID_FREQ_OR_CHANNEL;
277 }
278
TransformFreqToBand(int freq)279 BandType WifiChannelHelper::TransformFreqToBand(int freq)
280 {
281 if (freq <= CHANNEL_14_FREQ) {
282 return BandType::BAND_2GHZ;
283 } else if (freq <= FREQ_5G_MAX) {
284 return BandType::BAND_5GHZ;
285 }
286 return BandType::BAND_NONE; // not supported currently 6/60GHZ
287 }
288
TransformChannelToBand(int channel)289 BandType WifiChannelHelper::TransformChannelToBand(int channel)
290 {
291 if (channel <= CHANNEL_2G_MAX) {
292 return BandType::BAND_2GHZ;
293 } else if (channel <= CHANNEL_5G_MAX) {
294 return BandType::BAND_5GHZ;
295 }
296 return BandType::BAND_NONE; // not supported currently 6/60GHZ
297 }
298
IsValidFreq(int freq)299 bool WifiChannelHelper::IsValidFreq(int freq)
300 {
301 return IsValid24GHz(freq) || IsValid5GHz(freq);
302 }
303
IsValid24GHz(int freq)304 bool WifiChannelHelper::IsValid24GHz(int freq)
305 {
306 return freq > FREQ_2G_MIN_RANGE && freq < FREQ_2G_MAX_RANGE;
307 }
308
IsValid5GHz(int freq)309 bool WifiChannelHelper::IsValid5GHz(int freq)
310 {
311 return freq > FREQ_5G_MIN_RANGE && freq < FREQ_5G_MAX_RANGE;
312 }
313
IsValid24GChannel(int channel)314 bool WifiChannelHelper::IsValid24GChannel(int channel)
315 {
316 return channel >= CHANNEL_2G_MIN && channel <= CHANNEL_2G_MAX;
317 }
318
IsValid5GChannel(int channel)319 bool WifiChannelHelper::IsValid5GChannel(int channel)
320 {
321 return channel >= CHANNEL_5G_MIN && channel <= CHANNEL_5G_MAX;
322 }
323
324 } // namespace Wifi
325 } // namespace OHOS
326