* Copyright (C) 2022-2024 Huawei Device Co., Ltd.
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
#include "ethernet_exec.h"
#include <cstdint>
#include <new>
#include <numeric>
#include <string>
#include "mac_address_info.h"
#include "ethernet_client.h"
#include "napi_utils.h"
#include "net_manager_constants.h"
#include "netmanager_ext_log.h"
namespace OHOS {
namespace NetManagerStandard {
namespace EthernetExec {
namespace {
constexpr const char *MODE = "mode";
constexpr const char *IP_ADDR = "ipAddr";
constexpr const char *ROUTE = "route";
constexpr const char *NET_MASK = "netMask";
constexpr const char *GATEWAY = "gateway";
constexpr const char *DNS_SERVERS = "dnsServers";
constexpr const char *DOMAIN = "domain";
constexpr const char *HTTP_PROXY = "httpProxy";
constexpr const char *HOST = "host";
constexpr const char *PORT = "port";
constexpr const char *EXCLUSION_LIST = "exclusionList";
constexpr const char *DEFAULT_SEPARATOR = ",";
constexpr const char *MAC_ADDR = "macAddress";
constexpr const char *IFACE = "iface";
constexpr const char *IFACE_NAME = "ifaceName";
constexpr const char *DEVICE_NAME = "deviceName";
constexpr const char *CONNECTION_MODE = "connectionMode";
constexpr const char *SUPPLIER_NAME = "supplierName";
constexpr const char *SUPPLIER_ID = "supplierId";
constexpr const char *PRODUCT_NAME = "productName";
constexpr const char *MAX_RATE = "maximumRate";
std::string AccumulateNetAddress(const std::vector<INetAddr> &netAddrList)
{
return std::accumulate(
netAddrList.begin(), netAddrList.end(), std::string(), [](const std::string &addr, const INetAddr &iter) {
return addr.empty() ? (addr + iter.address_) : (addr + DEFAULT_SEPARATOR + iter.address_);
});
}
}
#ifdef NETMANAGER_EXT_ETHERNET_ENABLE_DISABLE
constexpr int32_t NETMANAGER_EXT_ERR_PERMISSION_DENIED = 201;
constexpr int32_t NETMANAGER_EXT_ERR_NOT_SYSTEM_CALL = 202;
constexpr int32_t NETMANAGER_EXT_ERR_IPC_CONNECT_STUB_FAIL = 2200002;
constexpr int32_t NETMANAGER_EXT_ERR_INTERNAL = 2200003;
#endif
#ifdef NETMANAGER_EXT_ETHERNET_ENABLE_DISABLE
int32_t MapToNapiErrorCode(int32_t internalCode)
{
switch (internalCode) {
case NETMANAGER_EXT_ERR_PERMISSION_DENIED:
return NETMANAGER_EXT_ERR_PERMISSION_DENIED;
case NETMANAGER_EXT_ERR_NOT_SYSTEM_CALL:
return NETMANAGER_EXT_ERR_NOT_SYSTEM_CALL;
case NETMANAGER_EXT_ERR_IPC_CONNECT_STUB_FAIL:
return NETMANAGER_EXT_ERR_IPC_CONNECT_STUB_FAIL;
default:
return NETMANAGER_EXT_ERR_INTERNAL;
}
}
std::string GetNapiErrorMessage(int32_t napiCode)
{
switch (napiCode) {
case NETMANAGER_EXT_ERR_PERMISSION_DENIED:
return "Permission denied.";
case NETMANAGER_EXT_ERR_NOT_SYSTEM_CALL:
return "Non-system applications use system APIs.";
case NETMANAGER_EXT_ERR_IPC_CONNECT_STUB_FAIL:
return "Failed to connect to the service.";
case NETMANAGER_EXT_ERR_INTERNAL:
return "System internal error.";
default:
return "Unknown error.";
}
}
#endif
bool ExecGetMacAddress(GetMacAddressContext *context)
{
int32_t result = DelayedSingleton<EthernetClient>::GetInstance()->GetMacAddress(context->macAddrInfo_);
if (result != NETMANAGER_EXT_SUCCESS) {
NETMANAGER_EXT_LOGE("ExecGetMacAddress error, errorCode: %{public}d", result);
context->SetErrorCode(result);
return false;
}
return true;
}
napi_value GetMacAddressCallback(GetMacAddressContext *context)
{
napi_value macAddressList = NapiUtils::CreateArray(context->GetEnv(), context->macAddrInfo_.size());
uint32_t index = 0;
for (auto &eachInfo : context->macAddrInfo_) {
napi_value macAddrInfo = NapiUtils::CreateObject(context->GetEnv());
NapiUtils::SetStringPropertyUtf8(
context->GetEnv(), macAddrInfo, IFACE, eachInfo.iface_);
NapiUtils::SetStringPropertyUtf8(
context->GetEnv(), macAddrInfo, MAC_ADDR, eachInfo.macAddress_);
NapiUtils::SetArrayElement(context->GetEnv(), macAddressList, index++, macAddrInfo);
}
return macAddressList;
}
bool ExecGetIfaceConfig(GetIfaceConfigContext *context)
{
int32_t result = DelayedSingleton<EthernetClient>::GetInstance()->GetIfaceConfig(context->iface_, context->config_);
if (context->config_ == nullptr || result != NETMANAGER_EXT_SUCCESS) {
NETMANAGER_EXT_LOGE("ExecGetIfaceConfig error, errorCode: %{public}d", result);
context->SetErrorCode(result);
return false;
}
return true;
}
napi_value GetIfaceConfigCallback(GetIfaceConfigContext *context)
{
napi_value interfaceConfiguration = NapiUtils::CreateObject(context->GetEnv());
NapiUtils::SetInt32Property(context->GetEnv(), interfaceConfiguration, MODE, context->config_->mode_);
std::string ipAddresses = AccumulateNetAddress(context->config_->ipStatic_.ipAddrList_);
NapiUtils::SetStringPropertyUtf8(context->GetEnv(), interfaceConfiguration, IP_ADDR, ipAddresses);
std::string routeAddresses = AccumulateNetAddress(context->config_->ipStatic_.routeList_);
NapiUtils::SetStringPropertyUtf8(context->GetEnv(), interfaceConfiguration, ROUTE, routeAddresses);
std::string gatewayAddresses = AccumulateNetAddress(context->config_->ipStatic_.gatewayList_);
NapiUtils::SetStringPropertyUtf8(context->GetEnv(), interfaceConfiguration, GATEWAY, gatewayAddresses);
std::string maskAddresses = AccumulateNetAddress(context->config_->ipStatic_.netMaskList_);
NapiUtils::SetStringPropertyUtf8(context->GetEnv(), interfaceConfiguration, NET_MASK, maskAddresses);
std::string dnsServers = AccumulateNetAddress(context->config_->ipStatic_.dnsServers_);
NapiUtils::SetStringPropertyUtf8(context->GetEnv(), interfaceConfiguration, DNS_SERVERS, dnsServers);
NapiUtils::SetStringPropertyUtf8(context->GetEnv(), interfaceConfiguration, DOMAIN,
context->config_->ipStatic_.domain_);
std::string host = context->config_->httpProxy_.GetHost();
if (!host.empty()) {
napi_value httpProxy = NapiUtils::CreateObject(context->GetEnv());
NapiUtils::SetStringPropertyUtf8(context->GetEnv(), httpProxy, HOST, host);
NapiUtils::SetInt32Property(context->GetEnv(), httpProxy, PORT,
context->config_->httpProxy_.GetPort());
auto lists = context->config_->httpProxy_.GetExclusionList();
napi_value exclusionList = NapiUtils::CreateArray(context->GetEnv(), lists.size());
size_t index = 0;
for (auto list : lists) {
napi_value jsList = NapiUtils::CreateStringUtf8(context->GetEnv(), list);
NapiUtils::SetArrayElement(context->GetEnv(), exclusionList, index++, jsList);
}
NapiUtils::SetNamedProperty(context->GetEnv(), httpProxy, EXCLUSION_LIST, exclusionList);
NapiUtils::SetNamedProperty(context->GetEnv(), interfaceConfiguration, HTTP_PROXY, httpProxy);
}
return interfaceConfiguration;
}
bool ExecSetIfaceConfig(SetIfaceConfigContext *context)
{
int32_t result = DelayedSingleton<EthernetClient>::GetInstance()->SetIfaceConfig(context->iface_, context->config_);
if (result != NETMANAGER_EXT_SUCCESS) {
NETMANAGER_EXT_LOGE("ExecSetIfaceConfig error, errorCode: %{public}d", result);
context->SetErrorCode(result);
return false;
}
return true;
}
napi_value SetIfaceConfigCallback(SetIfaceConfigContext *context)
{
return NapiUtils::GetUndefined(context->GetEnv());
}
bool ExecIsIfaceActive(IsIfaceActiveContext *context)
{
int32_t result =
DelayedSingleton<EthernetClient>::GetInstance()->IsIfaceActive(context->iface_, context->ifActivate_);
if (result != NETMANAGER_EXT_SUCCESS) {
context->SetErrorCode(result);
NETMANAGER_EXT_LOGE("ExecIsIfaceActive error, errorCode: %{public}d", result);
return false;
}
return true;
}
napi_value IsIfaceActiveCallback(IsIfaceActiveContext *context)
{
return NapiUtils::CreateInt32(context->GetEnv(), context->ifActivate_);
}
bool ExecGetAllActiveIfaces(GetAllActiveIfacesContext *context)
{
int32_t result = DelayedSingleton<EthernetClient>::GetInstance()->GetAllActiveIfaces(context->ethernetNameList_);
if (result != NETMANAGER_EXT_SUCCESS) {
context->SetErrorCode(result);
NETMANAGER_EXT_LOGE("ExecIsIfaceActive error, errorCode: %{public}d", result);
return false;
}
return true;
}
napi_value GetAllActiveIfacesCallback(GetAllActiveIfacesContext *context)
{
napi_value ifaces = NapiUtils::CreateArray(context->GetEnv(), context->ethernetNameList_.size());
uint32_t index = 0;
for (const auto &iface : context->ethernetNameList_) {
napi_value ifaceStr = NapiUtils::CreateStringUtf8(context->GetEnv(), iface);
NapiUtils::SetArrayElement(context->GetEnv(), ifaces, index++, ifaceStr);
}
return ifaces;
}
bool ExecGetDeviceInformation(GetDeviceInformationContext *context)
{
int32_t result = DelayedSingleton<EthernetClient>::GetInstance()->GetDeviceInformation(context->deviceInfo_);
if (result != NETMANAGER_EXT_SUCCESS) {
NETMANAGER_EXT_LOGE("ExecGetDeviceInformation, err: %{public}d", result);
context->SetErrorCode(result);
return false;
}
return true;
}
napi_value GetDeviceInformationCallback(GetDeviceInformationContext *context)
{
napi_value deviceInfoList = NapiUtils::CreateArray(context->GetEnv(), context->deviceInfo_.size());
uint32_t index = 0;
for (auto &eachInfo : context->deviceInfo_) {
napi_value deviceInfo = NapiUtils::CreateObject(context->GetEnv());
NapiUtils::SetStringPropertyUtf8(context->GetEnv(), deviceInfo, IFACE_NAME, eachInfo.ifaceName_);
NapiUtils::SetStringPropertyUtf8(context->GetEnv(), deviceInfo, DEVICE_NAME, eachInfo.deviceName_);
NapiUtils::SetInt32Property(context->GetEnv(), deviceInfo, CONNECTION_MODE, eachInfo.connectionMode_);
NapiUtils::SetStringPropertyUtf8(context->GetEnv(), deviceInfo, SUPPLIER_NAME, eachInfo.supplierName_);
NapiUtils::SetStringPropertyUtf8(context->GetEnv(), deviceInfo, SUPPLIER_ID, eachInfo.supplierId_);
NapiUtils::SetStringPropertyUtf8(context->GetEnv(), deviceInfo, PRODUCT_NAME, eachInfo.productName_);
NapiUtils::SetStringPropertyUtf8(context->GetEnv(), deviceInfo, MAX_RATE, eachInfo.maximumRate_);
NapiUtils::SetArrayElement(context->GetEnv(), deviceInfoList, index++, deviceInfo);
}
return deviceInfoList;
}
#ifdef NETMANAGER_EXT_ETHERNET_ENABLE_DISABLE
bool ExecEnableEthernet(EnableEthernetContext *context)
{
int32_t result = DelayedSingleton<EthernetClient>::GetInstance()->EnableEthernetInterface();
if (result != NETMANAGER_EXT_SUCCESS) {
NETMANAGER_EXT_LOGE("ExecEnableEthernet error, errorCode: %{public}d", result);
int32_t napiCode = MapToNapiErrorCode(result);
context->SetErrorCode(napiCode);
return false;
}
return true;
}
napi_value EnableEthernetCallback(EnableEthernetContext *context)
{
return NapiUtils::GetUndefined(context->GetEnv());
}
bool ExecDisableEthernet(DisableEthernetContext *context)
{
int32_t result = DelayedSingleton<EthernetClient>::GetInstance()->DisableEthernetInterface();
if (result != NETMANAGER_EXT_SUCCESS) {
NETMANAGER_EXT_LOGE("ExecDisableEthernet error, errorCode: %{public}d", result);
int32_t napiCode = MapToNapiErrorCode(result);
context->SetErrorCode(napiCode);
return false;
}
return true;
}
napi_value DisableEthernetCallback(DisableEthernetContext *context)
{
return NapiUtils::GetUndefined(context->GetEnv());
}
#endif
}
}
}