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