1 /*
2 * Copyright (c) Huawei Technologies Co., Ltd. 2024. All rights reserved.
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 <cctype>
17 #include <cerrno>
18 #include <cstdint>
19 #include <fcntl.h>
20 #include <sys/socket.h>
21 #include <netlink/genl/genl.h>
22 #include <netlink/genl/family.h>
23 #include <netlink/genl/ctrl.h>
24 #include <linux/rtnetlink.h>
25 #include <netpacket/packet.h>
26 #include <linux/filter.h>
27 #include <linux/errqueue.h>
28 #include <linux/nl80211.h>
29 #include <linux/pkt_sched.h>
30 #include <netlink/object-api.h>
31 #include <netlink/netlink.h>
32 #include <netlink/socket.h>
33 #include <netlink/handlers.h>
34 #include "common.h"
35 #include "cpp_bindings.h"
36 #include "gscan.h"
37
38 typedef enum {
39 GSCAN_ATTRIBUTE_NUM_BUCKETS = 10,
40 GSCAN_ATTRIBUTE_BASE_PERIOD,
41 GSCAN_ATTRIBUTE_BUCKETS_BAND,
42 GSCAN_ATTRIBUTE_BUCKET_ID,
43 GSCAN_ATTRIBUTE_BUCKET_PERIOD,
44 GSCAN_ATTRIBUTE_BUCKET_NUM_CHANNELS,
45 GSCAN_ATTRIBUTE_BUCKET_CHANNELS,
46 GSCAN_ATTRIBUTE_NUM_AP_PER_SCAN,
47 GSCAN_ATTRIBUTE_REPORT_THRESHOLD,
48 GSCAN_ATTRIBUTE_NUM_SCANS_TO_CACHE,
49 GSCAN_ATTRIBUTE_BAND = GSCAN_ATTRIBUTE_BUCKETS_BAND,
50
51 GSCAN_ATTRIBUTE_ENABLE_FEATURE = 20,
52 GSCAN_ATTRIBUTE_SCAN_RESULTS_COMPLETE, /* indicates_no_more_results */
53 GSCAN_ATTRIBUTE_FLUSH_FEATURE, /* Flush all the configs */
54 GSCAN_ENABLE_FULL_SCAN_RESULTS,
55 GSCAN_ATTRIBUTE_REPORT_EVENTS,
56
57 /* remaining reserved for additional attributes */
58 GSCAN_ATTRIBUTE_NUM_OF_RESULTS = 30,
59 GSCAN_ATTRIBUTE_FLUSH_RESULTS,
60 GSCAN_ATTRIBUTE_SCAN_RESULTS, /* flat array of wifi_scan_result */
61 GSCAN_ATTRIBUTE_SCAN_ID, /* indicates scan number */
62 GSCAN_ATTRIBUTE_SCAN_FLAGS, /* indicates if scan was aborted */
63 GSCAN_ATTRIBUTE_AP_FLAGS, /* flags on significant change event*/
64 GSCAN_ATTRIBUTE_NUM_CHANNELS,
65 GSCAN_ATTRIBUTE_CHANNEL_LIST,
66 GSCAN_ATTRIBUTE_CH_BUCKET_BITMASK,
67 /* remaining reserved for additional attributes */
68
69 GSCAN_ATTRIBUTE_SSID = 40,
70 GSCAN_ATTRIBUTE_BSSID,
71 GSCAN_ATTRIBUTE_CHANNEL,
72 GSCAN_ATTRIBUTE_RSSI,
73 GSCAN_ATTRIBUTE_TIMESTAMP,
74 GSCAN_ATTRIBUTE_RTT,
75 GSCAN_ATTRIBUTE_RTTSD,
76
77 /* remaining reserved for additional attributes */
78
79 GSCAN_ATTRIBUTE_HOTLIST_BSSIDS = 50,
80 GSCAN_ATTRIBUTE_RSSI_LOW,
81 GSCAN_ATTRIBUTE_RSSI_HIGH,
82 GSCAN_ATTRIBUTE_HOTLIST_ELEM,
83 GSCAN_ATTRIBUTE_HOTLIST_FLUSH,
84 GSCAN_ATTRIBUTE_HOTLIST_BSSID_COUNT,
85
86 /* remaining reserved for additional attributes */
87 GSCAN_ATTRIBUTE_RSSI_SAMPLE_SIZE = 60,
88 GSCAN_ATTRIBUTE_LOST_AP_SAMPLE_SIZE,
89 GSCAN_ATTRIBUTE_MIN_BREACHING,
90 GSCAN_ATTRIBUTE_SIGNIFICANT_CHANGE_BSSIDS,
91 GSCAN_ATTRIBUTE_SIGNIFICANT_CHANGE_FLUSH,
92
93 /* EPNO */
94 GSCAN_ATTRIBUTE_EPNO_SSID_LIST = 70,
95 GSCAN_ATTRIBUTE_EPNO_SSID,
96 GSCAN_ATTRIBUTE_EPNO_SSID_LEN,
97 GSCAN_ATTRIBUTE_EPNO_RSSI,
98 GSCAN_ATTRIBUTE_EPNO_FLAGS,
99 GSCAN_ATTRIBUTE_EPNO_AUTH,
100 GSCAN_ATTRIBUTE_EPNO_SSID_NUM,
101 GSCAN_ATTRIBUTE_EPNO_FLUSH,
102
103 /* remaining reserved for additional attributes */
104
105 GSCAN_ATTRIBUTE_WHITELIST_SSID = 80,
106 GSCAN_ATTRIBUTE_NUM_WL_SSID,
107 GSCAN_ATTRIBUTE_WL_SSID_LEN,
108 GSCAN_ATTRIBUTE_WL_SSID_FLUSH,
109 GSCAN_ATTRIBUTE_WHITELIST_SSID_ELEM,
110 GSCAN_ATTRIBUTE_NUM_BSSID,
111 GSCAN_ATTRIBUTE_BSSID_PREF_LIST,
112 GSCAN_ATTRIBUTE_BSSID_PREF_FLUSH,
113 GSCAN_ATTRIBUTE_BSSID_PREF,
114 GSCAN_ATTRIBUTE_RSSI_MODIFIER,
115
116 /* remaining reserved for additional attributes */
117
118 GSCAN_ATTRIBUTE_A_BAND_BOOST_THRESHOLD = 90,
119 GSCAN_ATTRIBUTE_A_BAND_PENALTY_THRESHOLD,
120 GSCAN_ATTRIBUTE_A_BAND_BOOST_FACTOR,
121 GSCAN_ATTRIBUTE_A_BAND_PENALTY_FACTOR,
122 GSCAN_ATTRIBUTE_A_BAND_MAX_BOOST,
123 GSCAN_ATTRIBUTE_LAZY_ROAM_HYSTERESIS,
124 GSCAN_ATTRIBUTE_ALERT_ROAM_RSSI_TRIGGER,
125 GSCAN_ATTRIBUTE_LAZY_ROAM_ENABLE,
126
127 /* BSSID AVOID */
128 GSCAN_ATTRIBUTE_BSSID_AVOID_FLUSH = 100,
129 GSCAN_ATTRIBUTE_AVOID_BSSID,
130
131 /* ANQPO */
132 GSCAN_ATTRIBUTE_ANQPO_HS_LIST = 110,
133 GSCAN_ATTRIBUTE_ANQPO_HS_LIST_SIZE,
134 GSCAN_ATTRIBUTE_ANQPO_HS_NETWORK_ID,
135 GSCAN_ATTRIBUTE_ANQPO_HS_NAI_REALM,
136 GSCAN_ATTRIBUTE_ANQPO_HS_ROAM_CONSORTIUM_ID,
137 GSCAN_ATTRIBUTE_ANQPO_HS_PLMN,
138
139 /* Adaptive scan attributes */
140 GSCAN_ATTRIBUTE_BUCKET_STEP_COUNT = 120,
141 GSCAN_ATTRIBUTE_BUCKET_MAX_PERIOD,
142
143 /* ePNO cfg */
144 GSCAN_ATTRIBUTE_EPNO_5G_RSSI_THR = 130,
145 GSCAN_ATTRIBUTE_EPNO_2G_RSSI_THR,
146 GSCAN_ATTRIBUTE_EPNO_INIT_SCORE_MAX,
147 GSCAN_ATTRIBUTE_EPNO_CUR_CONN_BONUS,
148 GSCAN_ATTRIBUTE_EPNO_SAME_NETWORK_BONUS,
149 GSCAN_ATTRIBUTE_EPNO_SECURE_BONUS,
150 GSCAN_ATTRIBUTE_EPNO_5G_BONUS,
151
152 /* Roaming features */
153 GSCAN_ATTRIBUTE_ROAM_STATE_SET = 140,
154 GSCAN_ATTRIBUTE_MAX
155 } GSCAN_ATTRIBUTE;
156
157 class GetChannelListCommand : public WifiCommand {
158 std::vector<uint32_t> mFreqs;
159 int mBand;
160 public:
GetChannelListCommand(wifiInterfaceHandle iface,int band)161 GetChannelListCommand(wifiInterfaceHandle iface, int band)
162 : WifiCommand("GetChannelListCommand", iface, 0), mBand(band)
163 {}
Create()164 int Create() override
165 {
166 int ret = mMsg.Create(FamilyId(), NL80211_CMD_GET_WIPHY, NLM_F_DUMP, 0);
167 if (ret < 0) {
168 HDF_LOGE("Can't create message to send to driver - %{public}d", ret);
169 return ret;
170 }
171 mMsg.PutFlag(NL80211_ATTR_SPLIT_WIPHY_DUMP);
172 ret = mMsg.PutU32(NL80211_ATTR_IFINDEX, IfaceId());
173 if (ret < 0) {
174 HDF_LOGE("put ifaceid fail %{public}d", IfaceId());
175 }
176 return ret;
177 }
178
GetCenterFreq(struct nlattr * bands)179 void GetCenterFreq(struct nlattr *bands)
180 {
181 struct nlattr *attrFreq[NL80211_FREQUENCY_ATTR_MAX + 1];
182 struct nlattr *nlFreq = nullptr;
183 void *data = nullptr;
184 int32_t len;
185 int32_t i;
186 uint32_t freq;
187 static struct nla_policy freqPolicy[NL80211_FREQUENCY_ATTR_MAX + 1];
188 freqPolicy[NL80211_FREQUENCY_ATTR_FREQ].type = NLA_U32;
189 freqPolicy[NL80211_FREQUENCY_ATTR_MAX_TX_POWER].type = NLA_U32;
190
191 nla_for_each_nested(nlFreq, bands, i) {
192 data = nla_data(nlFreq);
193 len = nla_len(nlFreq);
194 nla_parse(attrFreq, NL80211_FREQUENCY_ATTR_MAX, (struct nlattr *)data, len, freqPolicy);
195 if (attrFreq[NL80211_FREQUENCY_ATTR_FREQ] == nullptr) {
196 continue;
197 }
198 if (attrFreq[NL80211_FREQUENCY_ATTR_DISABLED] != nullptr) {
199 continue;
200 }
201 freq = nla_get_u32(attrFreq[NL80211_FREQUENCY_ATTR_FREQ]);
202 switch (mBand) {
203 case NL80211_BAND_2GHZ:
204 if (freq > LOW_LITMIT_FREQ_2_4G && freq < HIGH_LIMIT_FREQ_2_4G) {
205 mFreqs.push_back(freq);
206 }
207 break;
208 case NL80211_BAND_5GHZ:
209 if (freq > LOW_LIMIT_FREQ_5G && freq < HIGH_LIMIT_FREQ_5G) {
210 mFreqs.push_back(freq);
211 }
212 break;
213 default:
214 break;
215 }
216 }
217 }
218
GetFreqs()219 std::vector<uint32_t> &GetFreqs()
220 {
221 return mFreqs;
222 }
223 protected:
HandleResponse(WifiEvent & reply)224 int HandleResponse(WifiEvent& reply) override
225 {
226 struct nlattr *attrBand[NL80211_BAND_ATTR_MAX + 1];
227 struct nlattr *nlBand = nullptr;
228 struct nlattr **attr = reply.Attributes();
229 int32_t i;
230 void *data = nullptr;
231 int32_t len;
232
233 if (!attr[NL80211_ATTR_WIPHY_BANDS]) {
234 return NL_SKIP;
235 }
236 struct nlattr *attrWiphyBands = attr[NL80211_ATTR_WIPHY_BANDS];
237 if (attrWiphyBands == nullptr) {
238 return NL_SKIP;
239 }
240 nla_for_each_nested(nlBand, attrWiphyBands, i) {
241 data = nla_data(nlBand);
242 len = nla_len(nlBand);
243 nla_parse(attrBand, NL80211_BAND_ATTR_MAX, (struct nlattr *)data, len, NULL);
244 if (attrBand[NL80211_BAND_ATTR_FREQS] == nullptr) {
245 continue;
246 }
247 GetCenterFreq(attrBand[NL80211_BAND_ATTR_FREQS]);
248 }
249
250 return NL_OK;
251 }
252 };
253
VendorHalGetChannelsInBand(wifiInterfaceHandle handle,int band,std::vector<uint32_t> & freqs)254 WifiError VendorHalGetChannelsInBand(wifiInterfaceHandle handle,
255 int band, std::vector<uint32_t>& freqs)
256 {
257 HDF_LOGI("VendorHalGetChannelsInBand band = %{public}d", band);
258 if (!handle) {
259 HDF_LOGE("Handle is null");
260 return HAL_INVALID_ARGS;
261 }
262 if (band > 0 && band <= IEEE80211_NUM_BANDS) {
263 band = band - 1;
264 }
265 if (band >= IEEE80211_NUM_BANDS) {
266 HDF_LOGE("Invalid input parameter, band = %{public}d", band);
267 return HAL_INVALID_ARGS;
268 }
269 GetChannelListCommand command(handle, band);
270 auto lock = ReadLockData();
271 int ret = command.RequestResponse();
272 if (ret < 0) {
273 return HAL_NONE;
274 }
275 freqs = command.GetFreqs();
276 return HAL_SUCCESS;
277 }
278