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