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