1 /*
2 * Copyright (C) 2022 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_net_agent.h"
17 #include <cinttypes>
18 #include <algorithm>
19 #include "inet_addr.h"
20 #include "ip_tools.h"
21 #include "iservice_registry.h"
22 #include "netsys_native_service_proxy.h"
23 #include "net_conn_client.h"
24 #include "system_ability_definition.h"
25 #include "wifi_common_util.h"
26 #include "wifi_logger.h"
27 #include "wifi_settings.h"
28 #include "ipv6_address.h"
29
30 DEFINE_WIFILOG_LABEL("WifiNetAgent");
31
32 namespace OHOS {
33 namespace Wifi {
34 constexpr const char *WIFI_NET_CONN_MGR_WORK_THREAD = "WIFI_NET_CONN_MGR_WORK_THREAD";
35 using namespace NetManagerStandard;
36
WifiNetAgent()37 WifiNetAgent::WifiNetAgent()
38 {
39 netConnEventRunner_ = AppExecFwk::EventRunner::Create(WIFI_NET_CONN_MGR_WORK_THREAD);
40 if (netConnEventRunner_) {
41 netConnEventHandler_ = std::make_shared<WifiNetConnEventHandler>(netConnEventRunner_);
42 } else {
43 WIFI_LOGE("Create event runner failed.");
44 }
45 }
~WifiNetAgent()46 WifiNetAgent::~WifiNetAgent()
47 {
48 if (netConnEventRunner_) {
49 netConnEventRunner_->Stop();
50 netConnEventRunner_.reset();
51 }
52
53 if (netConnEventHandler_) {
54 netConnEventHandler_.reset();
55 }
56 }
57
RegisterNetSupplier()58 bool WifiNetAgent::RegisterNetSupplier()
59 {
60 TimeStats timeStats(__func__);
61 WIFI_LOGI("Enter RegisterNetSupplier.");
62
63 std::string ident = "wifi";
64 using NetManagerStandard::NetBearType;
65 using NetManagerStandard::NetCap;
66 std::set<NetCap> netCaps {NetCap::NET_CAPABILITY_INTERNET};
67 int32_t result = NetConnClient::GetInstance().RegisterNetSupplier(NetBearType::BEARER_WIFI,
68 ident, netCaps, supplierId);
69 if (result == NETMANAGER_SUCCESS) {
70 WIFI_LOGI("Register NetSupplier successful");
71 return true;
72 }
73 WIFI_LOGI("Register NetSupplier failed");
74 return false;
75 }
76
RegisterNetSupplierCallback()77 bool WifiNetAgent::RegisterNetSupplierCallback()
78 {
79 TimeStats timeStats(__func__);
80 WIFI_LOGI("Enter RegisterNetSupplierCallback.");
81 sptr<NetConnCallback> pNetConnCallback = (std::make_unique<NetConnCallback>()).release();
82 if (pNetConnCallback == nullptr) {
83 WIFI_LOGE("pNetConnCallback is null\n");
84 return false;
85 }
86
87 int32_t result = NetConnClient::GetInstance().RegisterNetSupplierCallback(supplierId, pNetConnCallback);
88 if (result == NETMANAGER_SUCCESS) {
89 WIFI_LOGI("Register NetSupplierCallback successful");
90 return true;
91 }
92 WIFI_LOGE("Register NetSupplierCallback failed [%{public}d]", result);
93 return false;
94 }
95
UnregisterNetSupplier()96 void WifiNetAgent::UnregisterNetSupplier()
97 {
98 TimeStats timeStats(__func__);
99 WIFI_LOGI("Enter UnregisterNetSupplier.");
100 int32_t result = NetConnClient::GetInstance().UnregisterNetSupplier(supplierId);
101 WIFI_LOGI("Unregister network result:%{public}d", result);
102 }
103
UpdateNetSupplierInfo(const sptr<NetManagerStandard::NetSupplierInfo> & netSupplierInfo)104 void WifiNetAgent::UpdateNetSupplierInfo(const sptr<NetManagerStandard::NetSupplierInfo> &netSupplierInfo)
105 {
106 TimeStats timeStats(__func__);
107 WIFI_LOGI("Enter UpdateNetSupplierInfo.");
108 int32_t result = NetConnClient::GetInstance().UpdateNetSupplierInfo(supplierId, netSupplierInfo);
109 WIFI_LOGI("Update network result:%{public}d", result);
110 }
111
UpdateNetLinkInfo(IpInfo & wifiIpInfo,IpV6Info & wifiIpV6Info,WifiProxyConfig & wifiProxyConfig)112 void WifiNetAgent::UpdateNetLinkInfo(IpInfo &wifiIpInfo, IpV6Info &wifiIpV6Info, WifiProxyConfig &wifiProxyConfig)
113 {
114 TimeStats timeStats(__func__);
115 WIFI_LOGI("Enter UpdateNetLinkInfo.");
116
117 sptr<NetManagerStandard::NetLinkInfo> netLinkInfo = (std::make_unique<NetManagerStandard::NetLinkInfo>()).release();
118 CreateNetLinkInfo(netLinkInfo, wifiIpInfo, wifiIpV6Info, wifiProxyConfig);
119 int32_t result = NetConnClient::GetInstance().UpdateNetLinkInfo(supplierId, netLinkInfo);
120 WIFI_LOGI("UpdateNetLinkInfo result:%{public}d", result);
121 }
122
AddRoute(const std::string interface,const std::string ipAddress,int prefixLength)123 bool WifiNetAgent::AddRoute(const std::string interface, const std::string ipAddress, int prefixLength)
124 {
125 TimeStats timeStats(__func__);
126 LOGI("NetAgent add route");
127 unsigned int ipInt = IpTools::ConvertIpv4Address(ipAddress);
128 std::string mask = IpTools::ConvertIpv4Mask(prefixLength);
129 unsigned int maskInt = IpTools::ConvertIpv4Address(mask);
130 std::string strLocalRoute = IpTools::ConvertIpv4Address(ipInt & maskInt);
131 std::string destAddress = strLocalRoute + "/" + std::to_string(prefixLength);
132
133 auto samgr = SystemAbilityManagerClient::GetInstance().GetSystemAbilityManager();
134 if (samgr == nullptr) {
135 LOGE("GetSystemAbilityManager failed!");
136 return false;
137 }
138 auto remote = samgr->GetSystemAbility(COMM_NETSYS_NATIVE_SYS_ABILITY_ID);
139 if (remote == nullptr) {
140 LOGE("GetSystemAbility failed!");
141 return false;
142 }
143 OHOS::sptr<OHOS::NetsysNative::INetsysService> netsysService = iface_cast<NetsysNative::INetsysService>(remote);
144 if (netsysService == nullptr) {
145 LOGE("NetdService is nullptr!");
146 return false;
147 }
148 LOGI("Add route, interface: %{public}s, destAddress: %{public}s, ipAddress: %{public}s, prefixLength: %{public}d",
149 interface.c_str(), IpAnonymize(destAddress).c_str(), IpAnonymize(ipAddress).c_str(), prefixLength);
150 netsysService->NetworkAddRoute(OHOS::nmd::LOCAL_NETWORK_NETID, interface, destAddress, ipAddress);
151 LOGI("NetAgent add route finish");
152 return true;
153 }
154
OnStaMachineUpdateNetLinkInfo(IpInfo & wifiIpInfo,IpV6Info & wifiIpV6Info,WifiProxyConfig & wifiProxyConfig)155 void WifiNetAgent::OnStaMachineUpdateNetLinkInfo(IpInfo &wifiIpInfo, IpV6Info &wifiIpV6Info,
156 WifiProxyConfig &wifiProxyConfig)
157 {
158 if (netConnEventHandler_) {
159 netConnEventHandler_->PostSyncTask(
160 [this, &wifiIpInfo, &wifiIpV6Info, &wifiProxyConfig]() {
161 this->UpdateNetLinkInfo(wifiIpInfo, wifiIpV6Info, wifiProxyConfig);
162 });
163 }
164 }
165
OnStaMachineUpdateNetSupplierInfo(const sptr<NetManagerStandard::NetSupplierInfo> & netSupplierInfo)166 void WifiNetAgent::OnStaMachineUpdateNetSupplierInfo(const sptr<NetManagerStandard::NetSupplierInfo> &netSupplierInfo)
167 {
168 if (netConnEventHandler_) {
169 netConnEventHandler_->PostSyncTask([this, netInfo = netSupplierInfo]() {
170 this->UpdateNetSupplierInfo(netInfo);
171 });
172 }
173 }
174
OnStaMachineWifiStart()175 void WifiNetAgent::OnStaMachineWifiStart()
176 {
177 if (netConnEventHandler_) {
178 netConnEventHandler_->PostSyncTask([this]() {
179 this->RegisterNetSupplier();
180 this->RegisterNetSupplierCallback();
181 });
182 }
183 }
184
OnStaMachineNetManagerRestart(const sptr<NetManagerStandard::NetSupplierInfo> & netSupplierInfo)185 void WifiNetAgent::OnStaMachineNetManagerRestart(const sptr<NetManagerStandard::NetSupplierInfo> &netSupplierInfo)
186 {
187 if (netConnEventHandler_) {
188 netConnEventHandler_->PostSyncTask([this, supplierInfo = netSupplierInfo]() {
189 this->RegisterNetSupplier();
190 this->RegisterNetSupplierCallback();
191 WifiLinkedInfo linkedInfo;
192 WifiSettings::GetInstance().GetLinkedInfo(linkedInfo);
193 if ((linkedInfo.detailedState == DetailedState::NOTWORKING)
194 && (linkedInfo.connState == ConnState::CONNECTED)) {
195 #ifndef OHOS_ARCH_LITE
196 if (supplierInfo != nullptr) {
197 TimeStats timeStats("Call UpdateNetSupplierInfo");
198 this->UpdateNetSupplierInfo(supplierInfo);
199 }
200 #endif
201 IpInfo wifiIpInfo;
202 WifiSettings::GetInstance().GetIpInfo(wifiIpInfo);
203 IpV6Info wifiIpV6Info;
204 WifiSettings::GetInstance().GetIpv6Info(wifiIpV6Info);
205 WifiDeviceConfig config;
206 WifiSettings::GetInstance().GetDeviceConfig(linkedInfo.networkId, config);
207 this->UpdateNetLinkInfo(wifiIpInfo, wifiIpV6Info, config.wifiProxyconfig);
208 }
209 });
210 }
211 }
212
CreateNetLinkInfo(sptr<NetManagerStandard::NetLinkInfo> & netLinkInfo,IpInfo & wifiIpInfo,IpV6Info & wifiIpV6Info,WifiProxyConfig & wifiProxyConfig)213 void WifiNetAgent::CreateNetLinkInfo(sptr<NetManagerStandard::NetLinkInfo> &netLinkInfo, IpInfo &wifiIpInfo,
214 IpV6Info &wifiIpV6Info, WifiProxyConfig &wifiProxyConfig)
215 {
216 netLinkInfo->ifaceName_ = "wlan0";
217
218 SetNetLinkIPInfo(netLinkInfo, wifiIpInfo, wifiIpV6Info);
219 SetNetLinkRouteInfo(netLinkInfo, wifiIpInfo, wifiIpV6Info);
220 SetNetLinkDnsInfo(netLinkInfo, wifiIpInfo, wifiIpV6Info);
221 SetNetLinkLocalRouteInfo(netLinkInfo, wifiIpInfo, wifiIpV6Info);
222 if (wifiProxyConfig.configureMethod == ConfigureProxyMethod::AUTOCONFIGUE) {
223 /* Automatic proxy is not supported */
224 } else if (wifiProxyConfig.configureMethod == ConfigureProxyMethod::MANUALCONFIGUE) {
225 std::vector<std::string> exclusionList;
226 wifiProxyConfig.manualProxyConfig.GetExclusionObjectList(exclusionList);
227 std::list<std::string> tmpExclusionList;
228 std::copy_if(exclusionList.begin(), exclusionList.end(), std::back_inserter(tmpExclusionList),
229 [](const std::string &str) { return !str.empty(); } );
230 netLinkInfo->httpProxy_.SetHost(std::move(wifiProxyConfig.manualProxyConfig.serverHostName));
231 netLinkInfo->httpProxy_.SetPort(wifiProxyConfig.manualProxyConfig.serverPort);
232 netLinkInfo->httpProxy_.SetExclusionList(tmpExclusionList);
233 } else {
234 netLinkInfo->httpProxy_.SetHost("");
235 netLinkInfo->httpProxy_.SetPort(0);
236 }
237
238 return;
239 }
240
SetNetLinkIPInfo(sptr<NetManagerStandard::NetLinkInfo> & netLinkInfo,IpInfo & wifiIpInfo,IpV6Info & wifiIpV6Info)241 void WifiNetAgent::SetNetLinkIPInfo(sptr<NetManagerStandard::NetLinkInfo> &netLinkInfo, IpInfo &wifiIpInfo,
242 IpV6Info &wifiIpV6Info)
243 {
244 unsigned int prefixLength = IpTools::GetMaskLength(IpTools::ConvertIpv4Address(wifiIpInfo.netmask));
245 sptr<NetManagerStandard::INetAddr> netAddr = (std::make_unique<NetManagerStandard::INetAddr>()).release();
246 netAddr->type_ = NetManagerStandard::INetAddr::IPV4;
247 netAddr->family_ = NetManagerStandard::INetAddr::IPV4;
248 netAddr->address_ = IpTools::ConvertIpv4Address(wifiIpInfo.ipAddress);
249 netAddr->netMask_ = IpTools::ConvertIpv4Address(wifiIpInfo.netmask);
250 netAddr->prefixlen_ = prefixLength;
251 netLinkInfo->netAddrList_.push_back(*netAddr);
252
253 LOGD("SetNetLinkIPInfo %{public}s", wifiIpV6Info.globalIpV6Address.c_str());
254 if (!wifiIpV6Info.globalIpV6Address.empty()) {
255 sptr<NetManagerStandard::INetAddr> netIpv6Addr = (std::make_unique<NetManagerStandard::INetAddr>()).release();
256 netIpv6Addr->type_ = NetManagerStandard::INetAddr::IPV6;
257 netIpv6Addr->family_ = NetManagerStandard::INetAddr::IPV6;
258 netIpv6Addr->address_ = wifiIpV6Info.globalIpV6Address;
259 netIpv6Addr->netMask_ = wifiIpV6Info.netmask;
260 netIpv6Addr->prefixlen_ = 0;
261 netLinkInfo->netAddrList_.push_back(*netIpv6Addr);
262 }
263 }
264
SetNetLinkDnsInfo(sptr<NetManagerStandard::NetLinkInfo> & netLinkInfo,IpInfo & wifiIpInfo,IpV6Info & wifiIpV6Info)265 void WifiNetAgent::SetNetLinkDnsInfo(sptr<NetManagerStandard::NetLinkInfo> &netLinkInfo, IpInfo &wifiIpInfo,
266 IpV6Info &wifiIpV6Info)
267 {
268 sptr<NetManagerStandard::INetAddr> dns = (std::make_unique<NetManagerStandard::INetAddr>()).release();
269 dns->type_ = NetManagerStandard::INetAddr::IPV4;
270 dns->family_ = NetManagerStandard::INetAddr::IPV4;
271 dns->address_ = IpTools::ConvertIpv4Address(wifiIpInfo.primaryDns);
272 netLinkInfo->dnsList_.push_back(*dns);
273 dns->address_ = IpTools::ConvertIpv4Address(wifiIpInfo.secondDns);
274 netLinkInfo->dnsList_.push_back(*dns);
275 LOGD("SetNetLinkDnsInfo %{public}s", wifiIpV6Info.primaryDns.c_str());
276 if (!wifiIpV6Info.primaryDns.empty()) {
277 sptr<NetManagerStandard::INetAddr> ipv6dns = (std::make_unique<NetManagerStandard::INetAddr>()).release();
278 ipv6dns->type_ = NetManagerStandard::INetAddr::IPV6;
279 ipv6dns->family_ = NetManagerStandard::INetAddr::IPV6;
280 ipv6dns->address_ = wifiIpV6Info.primaryDns;
281 netLinkInfo->dnsList_.push_back(*ipv6dns);
282 ipv6dns->address_ = wifiIpV6Info.secondDns;
283 netLinkInfo->dnsList_.push_back(*ipv6dns);
284 }
285 }
286
SetNetLinkRouteInfo(sptr<NetManagerStandard::NetLinkInfo> & netLinkInfo,IpInfo & wifiIpInfo,IpV6Info & wifiIpV6Info)287 void WifiNetAgent::SetNetLinkRouteInfo(sptr<NetManagerStandard::NetLinkInfo> &netLinkInfo, IpInfo &wifiIpInfo,
288 IpV6Info &wifiIpV6Info)
289 {
290 sptr<NetManagerStandard::Route> route = (std::make_unique<NetManagerStandard::Route>()).release();
291 route->iface_ = "wlan0";
292 route->destination_.type_ = NetManagerStandard::INetAddr::IPV4;
293 route->destination_.address_ = "0.0.0.0";
294 route->gateway_.address_ = IpTools::ConvertIpv4Address(wifiIpInfo.gateway);
295 netLinkInfo->routeList_.push_back(*route);
296 LOGD("SetNetLinkRouteInfo %{public}s", wifiIpV6Info.gateway.c_str());
297 if (!wifiIpV6Info.gateway.empty()) {
298 sptr<NetManagerStandard::Route> ipv6route = (std::make_unique<NetManagerStandard::Route>()).release();
299 ipv6route->iface_ = "wlan0";
300 ipv6route->destination_.type_ = NetManagerStandard::INetAddr::IPV6;
301 ipv6route->destination_.address_ = "::";
302 ipv6route->destination_.prefixlen_ = 0;
303 ipv6route->gateway_.address_ = wifiIpV6Info.gateway;
304 netLinkInfo->routeList_.push_back(*ipv6route);
305 }
306 }
307
SetNetLinkLocalRouteInfo(sptr<NetManagerStandard::NetLinkInfo> & netLinkInfo,IpInfo & wifiIpInfo,IpV6Info & wifiIpV6Info)308 void WifiNetAgent::SetNetLinkLocalRouteInfo(sptr<NetManagerStandard::NetLinkInfo> &netLinkInfo, IpInfo &wifiIpInfo,
309 IpV6Info &wifiIpV6Info)
310 {
311 unsigned int prefixLength = IpTools::GetMaskLength(IpTools::ConvertIpv4Address(wifiIpInfo.netmask));
312 sptr<NetManagerStandard::Route> localRoute = (std::make_unique<NetManagerStandard::Route>()).release();
313 std::string strLocalRoute = IpTools::ConvertIpv4Address(wifiIpInfo.ipAddress & wifiIpInfo.netmask);
314 localRoute->iface_ = "wlan0";
315 localRoute->destination_.type_ = NetManagerStandard::INetAddr::IPV4;
316 localRoute->destination_.address_ = strLocalRoute;
317 localRoute->destination_.prefixlen_ = prefixLength;
318 localRoute->gateway_.address_ = "0.0.0.0";
319 netLinkInfo->routeList_.push_back(*localRoute);
320 if (!wifiIpV6Info.netmask.empty()) {
321 unsigned int ipv6PrefixLength = IpTools::GetIPV6MaskLength(wifiIpV6Info.netmask);
322 sptr<NetManagerStandard::Route> ipv6route = (std::make_unique<NetManagerStandard::Route>()).release();
323 ipv6route->iface_ = "wlan0";
324 ipv6route->destination_.type_ = NetManagerStandard::INetAddr::IPV6;
325 ipv6route->destination_.address_ =
326 Ipv6Address::GetPrefixByAddr(wifiIpV6Info.globalIpV6Address, ipv6PrefixLength);
327 ipv6route->destination_.prefixlen_ = ipv6PrefixLength;
328 ipv6route->gateway_.address_ = "";
329 netLinkInfo->routeList_.push_back(*ipv6route);
330 }
331 }
332
NetConnCallback()333 WifiNetAgent::NetConnCallback::NetConnCallback()
334 {
335 }
336
~NetConnCallback()337 WifiNetAgent::NetConnCallback::~NetConnCallback()
338 {}
339
RequestNetwork(const std::string & ident,const std::set<NetManagerStandard::NetCap> & netCaps)340 int32_t WifiNetAgent::NetConnCallback::RequestNetwork(
341 const std::string &ident, const std::set<NetManagerStandard::NetCap> &netCaps)
342 {
343 WIFI_LOGD("Enter NetConnCallback::RequestNetwork");
344 LogNetCaps(ident, netCaps);
345 return 0;
346 }
347
ReleaseNetwork(const std::string & ident,const std::set<NetManagerStandard::NetCap> & netCaps)348 int32_t WifiNetAgent::NetConnCallback::ReleaseNetwork(
349 const std::string &ident, const std::set<NetManagerStandard::NetCap> &netCaps)
350 {
351 WIFI_LOGD("Enter NetConnCallback::ReleaseNetwork");
352 LogNetCaps(ident, netCaps);
353 return 0;
354 }
355
LogNetCaps(const std::string & ident,const std::set<NetManagerStandard::NetCap> & netCaps) const356 void WifiNetAgent::NetConnCallback::LogNetCaps(
357 const std::string &ident, const std::set<NetManagerStandard::NetCap> &netCaps) const
358 {
359 WIFI_LOGD("ident=[%s]", ident.c_str());
360 std::string logStr;
361 const std::string logStrEnd("]");
362 logStr = "netCaps[";
363 for (auto netCap : netCaps) {
364 logStr += std::to_string(static_cast<uint32_t>(netCap));
365 logStr += " ";
366 }
367 logStr += logStrEnd;
368 WIFI_LOGD("%{public}s", logStr.c_str());
369 }
370 }
371 }
372