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