From 0b5ba8bb5f6b559b913aab638018bb6e5a709032 Mon Sep 17 00:00:00 2001 From: zhaoshenghua Date: Wed, 14 Aug 2024 14:11:10 +0800 Subject: [PATCH 1/4] wifi Signed-off-by: zhaoshenghua Change-Id: I91c87de6b8933e8ff11e3929f60536d8e0d8360e --- wifi/frameworks/BUILD.gn | 1 + wifi/frameworks/cj/BUILD.gn | 69 +++ wifi/frameworks/cj/include/ffi_structs.h | 199 ++++++ wifi/frameworks/cj/include/wifi_ffi.h | 79 +++ wifi/frameworks/cj/src/wifi_ffi.cpp | 735 +++++++++++++++++++++++ 5 files changed, 1083 insertions(+) create mode 100644 wifi/frameworks/cj/BUILD.gn create mode 100644 wifi/frameworks/cj/include/ffi_structs.h create mode 100644 wifi/frameworks/cj/include/wifi_ffi.h create mode 100644 wifi/frameworks/cj/src/wifi_ffi.cpp diff --git a/wifi/frameworks/BUILD.gn b/wifi/frameworks/BUILD.gn index b79abfbb6..e856dd96a 100644 --- a/wifi/frameworks/BUILD.gn +++ b/wifi/frameworks/BUILD.gn @@ -28,6 +28,7 @@ group("wifi_kits") { "$WIFI_ROOT_DIR/frameworks/js/napi:wifiext", "$WIFI_ROOT_DIR/frameworks/js/napi:wifimanager", "$WIFI_ROOT_DIR/frameworks/js/napi:wifimanagerext", + "$WIFI_ROOT_DIR/frameworks/cj:cj_wifi_ffi", ] } } diff --git a/wifi/frameworks/cj/BUILD.gn b/wifi/frameworks/cj/BUILD.gn new file mode 100644 index 000000000..71fed17cc --- /dev/null +++ b/wifi/frameworks/cj/BUILD.gn @@ -0,0 +1,69 @@ +# Copyright (C) 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. + +import("//build/ohos.gni") +import("//foundation/communication/wifi/wifi/wifi.gni") + +ohos_shared_library("cj_wifi_ffi") { + branch_protector_ret = "pac_ret" + + sanitize = { + cfi = true # Enable/disable control flow integrity detection + boundary_sanitize = true # Enable boundary san detection + cfi_cross_dso = true # Cross-SO CFI Checks + integer_overflow = true # Enable integer overflow detection + ubsan = true # Enable some Ubsan options + debug = false + } + install_enable = true + include_dirs = [ + "$WIFI_ROOT_DIR/services/wifi_standard/wifi_framework/wifi_toolkit/log", + "$WIFI_ROOT_DIR/frameworks/native/interfaces", + "$WIFI_ROOT_DIR/interfaces/inner_api", + "$WIFI_ROOT_DIR/frameworks/native/include", + "$WIFI_ROOT_DIR/frameworks/native/src", + "$WIFI_ROOT_DIR/services/wifi_standard/wifi_framework/wifi_toolkit/net_helper", + "$WIFI_ROOT_DIR/utils/inc", + "./include" + ] + + sources = [ + "src/wifi_ffi.cpp", + ] + + deps = [ "$WIFI_ROOT_DIR/frameworks/native:wifi_sdk" ] + + defines = [] + if (wifi_feature_with_random_mac_addr) { + defines += [ "SUPPORT_RANDOM_MAC_ADDR" ] + } + + external_deps = [ + "ability_runtime:app_context", + "access_token:libaccesstoken_sdk", + "bundle_framework:appexecfwk_base", + "c_utils:utils", + "hilog:libhilog", + "ipc:ipc_single", + "napi:cj_bind_ffi", + "napi:cj_bind_native", + "samgr:samgr_proxy", + ] + cflags = memory_optimization_cflags + cflags_cc = memory_optimization_cflags_cc + ldflags = memory_optimization_ldflags + + innerapi_tags = [ "platformsdk" ] + part_name = "wifi" + subsystem_name = "communication" +} \ No newline at end of file diff --git a/wifi/frameworks/cj/include/ffi_structs.h b/wifi/frameworks/cj/include/ffi_structs.h new file mode 100644 index 000000000..ca174fecf --- /dev/null +++ b/wifi/frameworks/cj/include/ffi_structs.h @@ -0,0 +1,199 @@ +/* + * Copyright (c) 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. + */ + +#ifndef CJ_WIFI_FFI_STRUCTS_H +#define CJ_WIFI_FFI_STRUCTS_H + +#include +#include "cj_ffi/cj_common_ffi.h" + +extern "C" { + struct CWifiInfoElem + { + uint32_t eid; + CArrUI8 content; + }; + + struct CWifiScanInfo + { + char *ssid; + char *bssid; + int32_t bssidType; + char *capabilities; + int32_t securityType; + int32_t rssi; + int32_t band; + int32_t frequency; + int32_t channelWidth; + int32_t centerFrequency0; + int32_t centerFrequency1; + CWifiInfoElem *infoElems; + int64_t elemsSize; + int64_t timestamp; + int32_t supportedWifiCategory; + bool isHiLinkNetwork; + }; + + struct WifiScanInfoArr + { + CWifiScanInfo *head; + int64_t size; + }; + + // TODO figure out clientCert + struct CWifiEapConfig + { + int32_t eapMethod; /* EAP authentication mode:PEAP/TLS/TTLS/PWD/SIM/AKA/AKA' */ + int32_t phase2Method; /* Second stage authentication method */ + char *identity; /* Identity information */ + char *anonymousIdentity; /* Anonymous identity information */ + char *password; /* EAP mode password */ + char *caCertAlias; /* CA certificate alias */ + char *caPath; /* CA certificate path */ + char *clientCertAlias; + CArrUI8 certEntry; /* CA certificate entry */ + char *certPassword; /* Certificate password */ + char *altSubjectMatch; /* Alternative topic matching */ + char *domainSuffixMatch; /* Domain suffix matching */ + char *realm; /* The field of passport credentials */ + char *plmn; /* PLMN */ + int32_t eapSubId; /* Sub ID of SIM card */ + bool isNone; + }; + + struct CWifiWapiConfig + { + int32_t wapiPskType; + char *wapiAsCert; + char *wapiUserCert; + bool isNone; + }; + + struct CIpInfo + { + uint32_t ipAddress; + uint32_t gateway; + uint32_t netmask; + uint32_t primaryDns; + uint32_t secondDns; + uint32_t serverIp; + uint32_t leaseDuration; + }; + + struct CIpv6Info + { + char *linkIpV6Address; + char *globalIpV6Address; + char *randomGlobalIpV6Address; + char *uniqueIpv6Address; + char *randomUniqueIpv6Address; + char *gateway; + char *netmask; + char *primaryDns; + char *secondDNS; + }; + + struct CWifiP2PConfig + { + char *deviceAddress; + char *passphrase; + char *groupName; + int32_t netId; + int32_t goBand; + int32_t deviceAddressType; + }; + + struct CWifiP2PLinkedInfo + { + int32_t connectState; + bool isGroupOwner; + char *groupOwnerAddr; + }; + + struct CWifiP2pDevice + { + char *deviceName; + char *deviceAddress; + char *primaryDeviceType; + int32_t deviceStatus; + int32_t groupCapabilities; + int32_t deviceAddressType; + }; + + struct WifiP2pDeviceArr + { + CWifiP2pDevice *head; + int64_t size; + }; + + struct CWifiP2PGroupInfo + { + bool isP2pGo; + CWifiP2pDevice ownerInfo; + char *passphrase; + char *interfaceName; + char *groupName; + int32_t networkId; + int32_t frequency; + CWifiP2pDevice *clientDevices; + int64_t clientSize; + char *goIpAddress; + }; + + struct CWifiLinkedInfo + { + char *ssid; + char *bssid; + int32_t rssi; + int32_t band; + int32_t linkSpeed; + int32_t rxLinkSpeed; + int32_t maxSupportedTxLinkSpeed; + int32_t maxSupportedRxLinkSpeed; + int32_t frequency; + bool isHidden; + bool isRestricted; + int32_t macType; + char *macAddress; + uint32_t ipAddress; + int32_t connState; + int32_t channelWidth; + int32_t wifiStandard; + int32_t supportedWifiCategory; + bool isHiLinkNetwork; + }; + + struct CWifiDeviceConfig + { + int32_t securityType; + int32_t bssidType; + bool isHiddenSsid; + char *bssid; + char *ssid; + char *preSharedKey; + CWifiEapConfig eapConfig; + CWifiWapiConfig wapiConfig; + }; + + struct WifiDeviceConfigArr + { + CWifiDeviceConfig *head; + int64_t size; + }; +} + + + +#endif // CJ_WIFI_FFI_STRUCTS_H \ No newline at end of file diff --git a/wifi/frameworks/cj/include/wifi_ffi.h b/wifi/frameworks/cj/include/wifi_ffi.h new file mode 100644 index 000000000..5525813ed --- /dev/null +++ b/wifi/frameworks/cj/include/wifi_ffi.h @@ -0,0 +1,79 @@ +/* + * Copyright (c) 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. + */ + +#ifndef CJ_WIFI_FFI_H +#define CJ_WIFI_FFI_H + +#include "cj_ffi/cj_common_ffi.h" +#include "ffi_structs.h" + +char *MallocCString(const std::string &origin); + +enum class SecTypeCj { + /** Invalid security type */ + SEC_TYPE_INVALID = 0, + /** Open */ + SEC_TYPE_OPEN = 1, + /** Wired Equivalent Privacy (WEP) */ + SEC_TYPE_WEP = 2, + /** Pre-shared key (PSK) */ + SEC_TYPE_PSK = 3, + /** Simultaneous Authentication of Equals (SAE) */ + SEC_TYPE_SAE = 4, + /** EAP authentication. */ + SEC_TYPE_EAP = 5, + /** SUITE_B_192 192 bit level. */ + SEC_TYPE_EAP_SUITE_B = 6, +#ifdef ENABLE_NAPI_WIFI_MANAGER + /** Opportunistic Wireless Encryption. */ + SEC_TYPE_OWE = 7, +#endif + /** WAPI certificate to be specified. */ + SEC_TYPE_WAPI_CERT = 8, + /** WAPI pre-shared key to be specified. */ + SEC_TYPE_WAPI_PSK = 9, +}; + +extern "C" { +FFI_EXPORT int32_t CJ_IsWifiActive(bool &ret); +FFI_EXPORT WifiScanInfoArr CJ_GetScanInfoList(int32_t &ret); +FFI_EXPORT int32_t CJ_RemoveCandidateConfig(int32_t id); +FFI_EXPORT int32_t CJ_ConnectToCandidateConfig(int32_t id); +FFI_EXPORT int32_t CJ_GetSignalLevel(int32_t rssi, int32_t band, uint32_t &ret); +FFI_EXPORT int32_t CJ_IsConnected(bool &ret); +FFI_EXPORT int32_t CJ_IsFeatureSupported(int64_t featureId, bool &ret); +FFI_EXPORT int32_t CJ_GetIpInfo(CIpInfo &ret); +FFI_EXPORT int32_t CJ_GetIpv6Info(CIpv6Info &ret); +FFI_EXPORT char *CJ_GetCountryCode(int32_t &code); +FFI_EXPORT int32_t CJ_IsBandTypeSupported(int32_t bandType, bool &ret); +FFI_EXPORT int32_t CJ_IsMeteredHotspot(bool &ret); +FFI_EXPORT int32_t CJ_RemoveGroup(); +FFI_EXPORT int32_t CJ_P2pConnect(CWifiP2PConfig &cfg); +FFI_EXPORT int32_t CJ_P2pCancelConnect(); +FFI_EXPORT int32_t CJ_StartDiscoverDevices(); +FFI_EXPORT int32_t CJ_StopDiscoverDevices(); +FFI_EXPORT int32_t CJ_GetP2pLinkedInfo(CWifiP2PLinkedInfo &info); +FFI_EXPORT int32_t CJ_GetCurrentGroup(CWifiP2PGroupInfo &info); +FFI_EXPORT WifiP2pDeviceArr CJ_GetP2pPeerDevices(int32_t &ret); +FFI_EXPORT int32_t CJ_GetP2pLocalDevice(CWifiP2pDevice &info); +FFI_EXPORT int32_t CJ_CreateGroup(CWifiP2PConfig &cfg); +FFI_EXPORT int32_t CJ_GetLinkedInfo(CWifiLinkedInfo &info); +FFI_EXPORT int32_t CJ_AddCandidateConfig(CWifiDeviceConfig cfg, int32_t &ret); +FFI_EXPORT WifiDeviceConfigArr CJ_GetCandidateConfigs(int32_t &code); +FFI_EXPORT int32_t CJ_WifiOn(char *type, int64_t id); +FFI_EXPORT int32_t CJ_WifiOff(char* type); +} + +#endif // CJ_WIFI_FFI_H \ No newline at end of file diff --git a/wifi/frameworks/cj/src/wifi_ffi.cpp b/wifi/frameworks/cj/src/wifi_ffi.cpp new file mode 100644 index 000000000..2673fee55 --- /dev/null +++ b/wifi/frameworks/cj/src/wifi_ffi.cpp @@ -0,0 +1,735 @@ +/* + * Copyright (c) 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 "wifi_ffi.h" + +#include +#include +#include "wifi_device.h" +#include "wifi_scan.h" +#include "wifi_p2p.h" +#include "wifi_common_util.h" +#include "wifi_logger.h" + +DEFINE_WIFILOG_LABEL("CJ_WIFI_FFI"); + +namespace OHOS::Wifi { + +std::shared_ptr cjWifiDevicePtr = WifiDevice::GetInstance(WIFI_DEVICE_ABILITY_ID); +std::shared_ptr cjWifiScanPtr = WifiScan::GetInstance(WIFI_SCAN_ABILITY_ID); +std::shared_ptr cjWifiP2pPtr = WifiP2p::GetInstance(WIFI_P2P_ABILITY_ID); +static const std::string EAP_METHOD[] = { "NONE", "PEAP", "TLS", "TTLS", "PWD", "SIM", "AKA", "AKA'" }; + +static std::string EapMethod2Str(const int& method) +{ + if (method < 0 || method >= static_cast(sizeof(EAP_METHOD) / sizeof(EAP_METHOD[0]))) { + return "NONE"; + } + return EAP_METHOD[method]; +} + +static char *MallocCString(const std::string &origin) +{ + if (origin.empty()) { + return nullptr; + } + auto len = origin.length() + 1; + char *res = static_cast(malloc(sizeof(char) * len)); + if (res == nullptr) { + return nullptr; + } + return std::char_traits::copy(res, origin.c_str(), len); +} + +static SecTypeCj SecurityTypeNativeToCj(const WifiSecurity& cppSecurityType) +{ + SecTypeCj cjSecurityType = SecTypeCj::SEC_TYPE_INVALID; + switch (cppSecurityType) { + case WifiSecurity::OPEN: + cjSecurityType = SecTypeCj::SEC_TYPE_OPEN; + break; + case WifiSecurity::WEP: + cjSecurityType = SecTypeCj::SEC_TYPE_WEP; + break; + case WifiSecurity::PSK: + cjSecurityType = SecTypeCj::SEC_TYPE_PSK; + break; + case WifiSecurity::SAE: + case WifiSecurity::PSK_SAE: + cjSecurityType = SecTypeCj::SEC_TYPE_SAE; + break; + case WifiSecurity::EAP: + cjSecurityType = SecTypeCj::SEC_TYPE_EAP; + break; + case WifiSecurity::EAP_SUITE_B: + cjSecurityType = SecTypeCj::SEC_TYPE_EAP_SUITE_B; + break; + case WifiSecurity::WAPI_CERT: + cjSecurityType = SecTypeCj::SEC_TYPE_WAPI_CERT; + break; + case WifiSecurity::WAPI_PSK: + cjSecurityType = SecTypeCj::SEC_TYPE_WAPI_PSK; + break; + default: + cjSecurityType = SecTypeCj::SEC_TYPE_INVALID; + break; + } + return cjSecurityType; +} + +static void ConvertEncryptionMode(const SecTypeCj& securityType, std::string& keyMgmt) +{ + switch (securityType) { + case SecTypeCj::SEC_TYPE_OPEN: + keyMgmt = KEY_MGMT_NONE; + break; + case SecTypeCj::SEC_TYPE_WEP: + keyMgmt = KEY_MGMT_WEP; + break; + case SecTypeCj::SEC_TYPE_PSK: + keyMgmt = KEY_MGMT_WPA_PSK; + break; + case SecTypeCj::SEC_TYPE_SAE: + keyMgmt = KEY_MGMT_SAE; + break; + case SecTypeCj::SEC_TYPE_EAP: + keyMgmt = KEY_MGMT_EAP; + break; + case SecTypeCj::SEC_TYPE_EAP_SUITE_B: + keyMgmt = KEY_MGMT_SUITE_B_192; + break; + case SecTypeCj::SEC_TYPE_WAPI_CERT: + keyMgmt = KEY_MGMT_WAPI_CERT; + break; + case SecTypeCj::SEC_TYPE_WAPI_PSK: + keyMgmt = KEY_MGMT_WAPI_PSK; + break; + default: + keyMgmt = KEY_MGMT_NONE; + break; + } +} + +static void ProcessPassphrase(const SecTypeCj& securityType, WifiDeviceConfig& cppConfig) +{ + if (securityType == SecTypeCj::SEC_TYPE_WEP) { + cppConfig.wepKeys[0] = cppConfig.preSharedKey; + cppConfig.wepTxKeyIndex = 0; + cppConfig.preSharedKey = ""; + std::string().swap(cppConfig.preSharedKey); + } +} + +static void NativeInfoElems2Cj(const std::vector& infoElems, CWifiScanInfo &info) +{ + int valueStep = 2; + int64_t size = static_cast(infoElems.size()); + if (size > 0) { + info.infoElems = static_cast(malloc(sizeof(CWifiInfoElem) * size)); + if (info.infoElems == nullptr) { + info.elemsSize = 0; + return; + } + info.elemsSize = size; + for (int64_t i = 0; i < size; i++) { + CWifiInfoElem elem; + elem.eid = infoElems[i].id; + + const char *uStr = &infoElems[i].content[0]; + size_t len = infoElems[i].content.size(); + size_t inLen = static_cast(infoElems[i].content.size() * valueStep + 1); + char *buf = (char *)calloc(inLen + 1, sizeof(char)); + if (buf == nullptr) { + elem.content = CArrUI8{.head = nullptr, .size = 0}; + info.infoElems[i] = elem; + continue; + } + int pos = 0; + for (size_t k = 0; k < len; ++k) { + pos = (k << 1); + if (snprintf_s(buf + pos, inLen - pos, inLen - pos - 1, "%02x", uStr[k]) < 0) { + free(buf); + buf = NULL; + elem.content = CArrUI8{.head = nullptr, .size = 0}; + info.infoElems[i] = elem; + continue; + } + } + elem.content = CArrUI8{.head = reinterpret_cast(buf), .size = inLen - 1}; // TODO check size + info.infoElems[i] = elem; + } + } +} + +static int32_t ScanInfo2Cj(const std::vector& scanInfos, WifiScanInfoArr &infos) +{ + int64_t size = static_cast(scanInfos.size()); + WIFI_LOGI("GetScanInfoList, size: %{public}zu", scanInfos.size()); + + if (size > 0) { + infos.head = static_cast(malloc(sizeof(CWifiScanInfo) * size)); + if (infos.head == nullptr) { + return WIFI_OPT_FAILED; + } + infos.size = size; + + uint32_t idx = 0; + for(auto& each : scanInfos) { + CWifiScanInfo info; + info.ssid = MallocCString(each.ssid); + info.bssid = MallocCString(each.bssid); + info.bssidType = each.bssidType; + info.capabilities = MallocCString(each.capabilities); + info.securityType = static_cast(SecurityTypeNativeToCj(each.securityType)); + info.rssi = each.rssi; + info.band = each.band; + info.frequency = each.frequency; + info.channelWidth = static_cast(each.channelWidth); + info.centerFrequency0 = each.centerFrequency0; + info.centerFrequency1 = each.centerFrequency1; + NativeInfoElems2Cj(each.infoElems, info); + info.channelWidth = static_cast(each.channelWidth); + info.timestamp = each.timestamp; + info.supportedWifiCategory = static_cast(each.supportedWifiCategory); + info.isHiLinkNetwork = each.isHiLinkNetwork; + infos.head[idx] = info; + idx++; + } + } + return WIFI_OPT_SUCCESS; +} + +static void DeviceInfo2Cj(const WifiP2pDevice &device, CWifiP2pDevice &info) +{ + info.deviceName = MallocCString(device.GetDeviceName()); + info.deviceAddress = MallocCString(device.GetDeviceAddress()); + info.primaryDeviceType = MallocCString(device.GetPrimaryDeviceType()); + info.deviceStatus = static_cast(device.GetP2pDeviceStatus()); + info.groupCapabilities = device.GetGroupCapabilitys(); + info.deviceAddressType = device.GetDeviceAddressType(); +} + +static void CjWifiP2PConfig2C(const CWifiP2PConfig &cfg, WifiP2pConfig &config) +{ + config.SetDeviceAddress(std::string(cfg.deviceAddress)); + config.SetDeviceAddressType(cfg.deviceAddressType); + config.SetNetId(cfg.netId); + config.SetPassphrase(std::string(cfg.passphrase)); + config.SetGroupName(std::string(cfg.groupName)); + config.SetGoBand(static_cast(cfg.goBand)); +} + +static void UpdateSecurityTypeAndPreSharedKey(WifiDeviceConfig &cppConfig) +{ + if (cppConfig.keyMgmt != KEY_MGMT_NONE) { + return; + } + for (int i = 0; i != WEPKEYS_SIZE; ++i) { + if (!cppConfig.wepKeys[i].empty() && cppConfig.wepTxKeyIndex == i) { + cppConfig.keyMgmt = KEY_MGMT_WEP; + cppConfig.preSharedKey = cppConfig.wepKeys[i]; + } + } +} + +static SecTypeCj ConvertKeyMgmtToSecType(const std::string &keyMgmt) +{ + std::map mapKeyMgmtToSecType = { + {KEY_MGMT_NONE, SecTypeCj::SEC_TYPE_OPEN}, + {KEY_MGMT_WEP, SecTypeCj::SEC_TYPE_WEP}, + {KEY_MGMT_WPA_PSK, SecTypeCj::SEC_TYPE_PSK}, + {KEY_MGMT_SAE, SecTypeCj::SEC_TYPE_SAE}, + {KEY_MGMT_EAP, SecTypeCj::SEC_TYPE_EAP}, + {KEY_MGMT_SUITE_B_192, SecTypeCj::SEC_TYPE_EAP_SUITE_B}, + {KEY_MGMT_WAPI_CERT, SecTypeCj::SEC_TYPE_WAPI_CERT}, + {KEY_MGMT_WAPI_PSK, SecTypeCj::SEC_TYPE_WAPI_PSK}, + }; + + std::map::iterator iter = mapKeyMgmtToSecType.find(keyMgmt); + return iter == mapKeyMgmtToSecType.end() ? SecTypeCj::SEC_TYPE_OPEN : iter->second; +} + +static int Str2EapMethod(const std::string &str) +{ + WIFI_LOGD("%{public}s: eapMethod is %{public}s", __func__, str.c_str()); + int len = sizeof(EAP_METHOD) / sizeof(EAP_METHOD[0]); + for (int i = 0; i < len; i++) { + if (EAP_METHOD[i] == str) { + WIFI_LOGD("%{public}s: index is %{public}d", __func__, i); + return i; + } + } + return 0; +} + +static void DeviceConfig2C(WifiDeviceConfig &config, CWifiDeviceConfig &cfg) +{ + UpdateSecurityTypeAndPreSharedKey(config); + cfg.ssid = MallocCString(config.ssid); + cfg.bssid = MallocCString(config.bssid); + cfg.bssidType = config.bssidType; + cfg.preSharedKey = MallocCString(config.preSharedKey); + cfg.isHiddenSsid = config.hiddenSSID; + cfg.eapConfig.isNone = true; + cfg.wapiConfig.isNone = true; + SecTypeCj type = ConvertKeyMgmtToSecType(config.keyMgmt); + cfg.securityType = static_cast(type); + if (type == SecTypeCj::SEC_TYPE_EAP || type == SecTypeCj::SEC_TYPE_EAP_SUITE_B) { + cfg.eapConfig.eapMethod = Str2EapMethod(config.wifiEapConfig.eap); + cfg.eapConfig.phase2Method = static_cast(config.wifiEapConfig.phase2Method); + cfg.eapConfig.identity = MallocCString(config.wifiEapConfig.identity); + cfg.eapConfig.anonymousIdentity = MallocCString(config.wifiEapConfig.anonymousIdentity); + cfg.eapConfig.password = MallocCString(config.wifiEapConfig.password); + cfg.eapConfig.caCertAlias = MallocCString(config.wifiEapConfig.caCertAlias); + cfg.eapConfig.caPath = MallocCString(config.wifiEapConfig.caCertPath); + cfg.eapConfig.clientCertAlias = MallocCString(config.wifiEapConfig.caCertAlias); // ? + CArrUI8 arr{.head = nullptr, .size = 0}; + int64_t size = config.wifiEapConfig.certEntry.size(); + arr.head = static_cast(malloc(sizeof(uint8_t) * size)); + if (arr.head != nullptr) { + uint32_t idx = 0; + for (auto& each : config.wifiEapConfig.certEntry) { + arr.head[idx] = each; + idx++; + } + } + cfg.eapConfig.certEntry = arr; + cfg.eapConfig.certPassword = MallocCString(config.wifiEapConfig.certPassword); + cfg.eapConfig.altSubjectMatch = MallocCString(config.wifiEapConfig.altSubjectMatch); + cfg.eapConfig.domainSuffixMatch = MallocCString(config.wifiEapConfig.domainSuffixMatch); + cfg.eapConfig.realm = MallocCString(config.wifiEapConfig.realm); + cfg.eapConfig.plmn = MallocCString(config.wifiEapConfig.plmn); + cfg.eapConfig.eapSubId = config.wifiEapConfig.eapSubId; + cfg.eapConfig.isNone = false; + } + if (type == SecTypeCj::SEC_TYPE_WAPI_CERT || type == SecTypeCj::SEC_TYPE_WAPI_PSK) { + cfg.wapiConfig.wapiPskType = config.wifiWapiConfig.wapiPskType; + cfg.wapiConfig.wapiAsCert = nullptr; + cfg.wapiConfig.wapiUserCert = nullptr; + cfg.wapiConfig.isNone = false; + } +} + +extern "C" { + +int32_t CJ_IsWifiActive(bool &ret) +{ + if (cjWifiDevicePtr == nullptr) { + return WIFI_OPT_FAILED; + } + return cjWifiDevicePtr->IsWifiActive(ret); +} + +WifiScanInfoArr CJ_GetScanInfoList(int32_t &ret) +{ + WifiScanInfoArr infos{ .head = nullptr, .size = 0 }; + if (cjWifiScanPtr == nullptr) { + ret = WIFI_OPT_FAILED; + return infos; + } + std::vector scanInfos; + ret = cjWifiScanPtr->GetScanInfoList(scanInfos, false); + if (ret == WIFI_OPT_SUCCESS) { + ret = ScanInfo2Cj(scanInfos, infos); + } + return infos; +} + +int32_t CJ_RemoveCandidateConfig(int32_t id) +{ + if (cjWifiDevicePtr == nullptr) { + return WIFI_OPT_FAILED; + } + return static_cast(cjWifiDevicePtr->RemoveCandidateConfig(id)); +} + +int32_t CJ_ConnectToCandidateConfig(int32_t id) +{ + if (cjWifiDevicePtr == nullptr) { + return WIFI_OPT_FAILED; + } + return static_cast(cjWifiDevicePtr->ConnectToNetwork(id, true)); +} + +int32_t CJ_GetSignalLevel(int32_t rssi, int32_t band, uint32_t &ret) +{ + if (cjWifiDevicePtr == nullptr) { + return WIFI_OPT_FAILED; + } + int level = -1; + ErrCode code = cjWifiDevicePtr->GetSignalLevel(rssi, band, level); + ret = static_cast(level); + return static_cast(code); +} + +int32_t CJ_IsConnected(bool &ret) +{ + if (cjWifiDevicePtr == nullptr) { + return WIFI_OPT_FAILED; + } + return static_cast(cjWifiDevicePtr->IsConnected(ret)); +} + +int32_t CJ_IsFeatureSupported(int64_t featureId, bool &ret) +{ + if (cjWifiDevicePtr == nullptr) { + return WIFI_OPT_FAILED; + } + return static_cast(cjWifiDevicePtr->IsFeatureSupported(featureId, ret)); +} + +int32_t CJ_GetIpInfo(CIpInfo &ret) +{ + if (cjWifiDevicePtr == nullptr) { + return WIFI_OPT_FAILED; + } + IpInfo ipInfo; + ErrCode code = cjWifiDevicePtr->GetIpInfo(ipInfo); + if (code == WIFI_OPT_SUCCESS) { + ret.ipAddress = ipInfo.ipAddress; + ret.gateway = ipInfo.gateway; + ret.netmask = ipInfo.netmask; + ret.primaryDns = ipInfo.primaryDns; + ret.secondDns = ipInfo.secondDns; + ret.serverIp = ipInfo.serverIp; + ret.leaseDuration = ipInfo.leaseDuration; + } + return code; +} + +int32_t CJ_GetIpv6Info(CIpv6Info &ret) +{ + if (cjWifiDevicePtr == nullptr) { + return WIFI_OPT_FAILED; + } + IpV6Info ipInfo; + ErrCode code = cjWifiDevicePtr->GetIpv6Info(ipInfo); + if (code == WIFI_OPT_SUCCESS) { + ret.linkIpV6Address = MallocCString(ipInfo.linkIpV6Address); + ret.globalIpV6Address = MallocCString(ipInfo.globalIpV6Address); + ret.randomGlobalIpV6Address = MallocCString(ipInfo.randGlobalIpV6Address); + ret.uniqueIpv6Address = MallocCString(ipInfo.uniqueLocalAddress1); + ret.randomUniqueIpv6Address = MallocCString(ipInfo.uniqueLocalAddress2); + ret.gateway = MallocCString(ipInfo.gateway); + ret.netmask = MallocCString(ipInfo.netmask); + ret.primaryDns = MallocCString(ipInfo.primaryDns); + ret.secondDNS = MallocCString(ipInfo.secondDns); + } + return code; +} + +char *CJ_GetCountryCode(int32_t &code) +{ + if (cjWifiDevicePtr == nullptr) { + code = WIFI_OPT_FAILED; + return nullptr; + } + std::string countryCode; + code = cjWifiDevicePtr->GetCountryCode(countryCode); + if (code == WIFI_OPT_SUCCESS) { + return MallocCString(countryCode); + } + return nullptr; +} + +int32_t CJ_IsBandTypeSupported(int32_t bandType, bool &ret) +{ + if (cjWifiDevicePtr == nullptr) { + return WIFI_OPT_FAILED; + } + return cjWifiDevicePtr->IsBandTypeSupported(bandType, ret); +} + +int32_t CJ_IsMeteredHotspot(bool &ret) +{ + if (cjWifiDevicePtr == nullptr) { + return WIFI_OPT_FAILED; + } + return cjWifiDevicePtr->IsMeteredHotspot(ret); +} + +int32_t CJ_RemoveGroup() +{ + if (cjWifiP2pPtr == nullptr) { + return WIFI_OPT_FAILED; + } + return cjWifiP2pPtr->RemoveGroup(); +} + +int32_t CJ_P2pConnect(CWifiP2PConfig &cfg) +{ + if (cjWifiP2pPtr == nullptr) { + return WIFI_OPT_FAILED; + } + WifiP2pConfig config; + CjWifiP2PConfig2C(cfg, config); + return cjWifiP2pPtr->P2pConnect(config); +} + +int32_t CJ_P2pCancelConnect() +{ + if (cjWifiP2pPtr == nullptr) { + return WIFI_OPT_FAILED; + } + return cjWifiP2pPtr->P2pCancelConnect(); +} + +int32_t CJ_StartDiscoverDevices() +{ + if (cjWifiP2pPtr == nullptr) { + return WIFI_OPT_FAILED; + } + return cjWifiP2pPtr->DiscoverDevices(); +} + +int32_t CJ_StopDiscoverDevices() +{ + if (cjWifiP2pPtr == nullptr) { + return WIFI_OPT_FAILED; + } + return cjWifiP2pPtr->StopDiscoverDevices(); +} + +int32_t CJ_GetP2pLinkedInfo(CWifiP2PLinkedInfo &info) +{ + if (cjWifiP2pPtr == nullptr) { + return WIFI_OPT_FAILED; + } + WifiP2pLinkedInfo linkedInfo; + ErrCode code = cjWifiP2pPtr->QueryP2pLinkedInfo(linkedInfo); + if (code == WIFI_OPT_SUCCESS) { + info.connectState = static_cast(linkedInfo.GetConnectState()); + info.isGroupOwner = linkedInfo.IsGroupOwner(); + info.groupOwnerAddr = MallocCString(linkedInfo.GetGroupOwnerAddress()); + } + return code; +} + +int32_t CJ_GetCurrentGroup(CWifiP2PGroupInfo &info) +{ + if (cjWifiP2pPtr == nullptr) { + return WIFI_OPT_FAILED; + } + WifiP2pGroupInfo groupInfo; + ErrCode code = cjWifiP2pPtr->GetCurrentGroup(groupInfo); + if (code == WIFI_OPT_SUCCESS) { + info.isP2pGo = groupInfo.IsGroupOwner(); + DeviceInfo2Cj(groupInfo.GetOwner(), info.ownerInfo); + info.passphrase = MallocCString(groupInfo.GetPassphrase()); + info.interfaceName = MallocCString(groupInfo.GetInterface()); + info.groupName = MallocCString(groupInfo.GetGroupName()); + info.goIpAddress = MallocCString(groupInfo.GetGoIpAddress()); + info.networkId = groupInfo.GetNetworkId(); + info.frequency = groupInfo.GetFrequency(); + info.clientSize = 0; + if (!groupInfo.IsClientDevicesEmpty()) { + const std::vector& vecDevices = groupInfo.GetClientDevices(); + int64_t size = static_cast(vecDevices.size()); + info.clientDevices = static_cast(malloc(sizeof(CWifiP2pDevice) * size)); + if (info.clientDevices != nullptr) { + info.clientSize = size; + uint32_t idx = 0; + for (auto& each : vecDevices) { + CWifiP2pDevice device; + DeviceInfo2Cj(each, device); + info.clientDevices[idx] = device; + idx++; + } + } + } + } + return code; +} + +WifiP2pDeviceArr CJ_GetP2pPeerDevices(int32_t &ret) +{ + WifiP2pDeviceArr arr{.head = nullptr, .size = 0}; + if (cjWifiP2pPtr == nullptr) { + ret = WIFI_OPT_FAILED; + return arr; + } + std::vector vecP2pDevices; + ret = cjWifiP2pPtr->QueryP2pDevices(vecP2pDevices); + int64_t size = static_cast(vecP2pDevices.size()); + WIFI_LOGI("GetP2pDeviceList, size: %{public}d", static_cast(size)); + + if (ret == WIFI_OPT_SUCCESS && size > 0) { + arr.head = static_cast(malloc(sizeof(CWifiP2pDevice) * size)); + if (arr.head == nullptr) { + ret = WIFI_OPT_FAILED; + return arr; + } + arr.size = size; + + uint32_t idx = 0; + for (auto& each : vecP2pDevices) { + CWifiP2pDevice device; + DeviceInfo2Cj(each, device); + arr.head[idx] = device; + idx++; + } + } + return arr; +} + +int32_t CJ_GetP2pLocalDevice(CWifiP2pDevice &info) +{ + if (cjWifiP2pPtr == nullptr) { + return WIFI_OPT_FAILED; + } + WifiP2pDevice deviceInfo; + ErrCode code = cjWifiP2pPtr->QueryP2pLocalDevice(deviceInfo); + if (code == WIFI_OPT_SUCCESS) { + DeviceInfo2Cj(deviceInfo, info); + } + return code; +} + +int32_t CJ_CreateGroup(CWifiP2PConfig &cfg) +{ + if (cjWifiP2pPtr == nullptr) { + return WIFI_OPT_FAILED; + } + WifiP2pConfig config; + CjWifiP2PConfig2C(cfg, config); + return cjWifiP2pPtr->CreateGroup(config); +} + +int32_t CJ_GetLinkedInfo(CWifiLinkedInfo &info) +{ + if (cjWifiDevicePtr == nullptr) { + return WIFI_OPT_FAILED; + } + WifiLinkedInfo linkedInfo; + ErrCode code = cjWifiDevicePtr->GetLinkedInfo(linkedInfo); + if (code == WIFI_OPT_SUCCESS) { + info.ssid = MallocCString(linkedInfo.ssid); + info.bssid = MallocCString(linkedInfo.bssid); + info.rssi = linkedInfo.rssi; + info.band = linkedInfo.band; + info.linkSpeed = linkedInfo.linkSpeed; + info.frequency = linkedInfo.frequency; + info.isHidden = linkedInfo.ifHiddenSSID; + info.isRestricted = linkedInfo.isDataRestricted; + info.macAddress = MallocCString(linkedInfo.macAddress); + info.macType = linkedInfo.macType; + info.ipAddress = linkedInfo.ipAddress; + info.connState = static_cast(linkedInfo.connState); + info.wifiStandard = linkedInfo.wifiStandard; + info.maxSupportedRxLinkSpeed = linkedInfo.maxSupportedRxLinkSpeed; + info.maxSupportedTxLinkSpeed = linkedInfo.maxSupportedTxLinkSpeed; + info.rxLinkSpeed = linkedInfo.rxLinkSpeed; + info.channelWidth = static_cast(linkedInfo.channelWidth); + info.supportedWifiCategory = static_cast(linkedInfo.supportedWifiCategory); + info.isHiLinkNetwork = linkedInfo.isHiLinkNetwork; + } + return code; +} + +int32_t CJ_AddCandidateConfig(CWifiDeviceConfig cfg, int32_t &ret) +{ + if (cjWifiDevicePtr == nullptr) { + return WIFI_OPT_FAILED; + } + + WifiDeviceConfig config; + + config.ssid = std::string(cfg.ssid); + config.preSharedKey = std::string(cfg.preSharedKey); + SecTypeCj type = SecTypeCj(cfg.securityType); + if (cfg.bssid != nullptr) { + config.bssid = std::string(cfg.bssid); + } + config.bssidType = cfg.bssidType; + config.hiddenSSID = cfg.isHiddenSsid; + ConvertEncryptionMode(type, config.keyMgmt); + ProcessPassphrase(type, config); + config.wifiPrivacySetting = WifiPrivacyConfig::RANDOMMAC; + + if (!cfg.eapConfig.isNone && (type == SecTypeCj::SEC_TYPE_EAP || type == SecTypeCj::SEC_TYPE_EAP_SUITE_B)) { + config.wifiEapConfig.eap = EapMethod2Str(cfg.eapConfig.eapMethod); + config.wifiEapConfig.phase2Method = Phase2Method(cfg.eapConfig.phase2Method); + config.wifiEapConfig.identity = std::string(cfg.eapConfig.identity); + config.wifiEapConfig.anonymousIdentity = std::string(cfg.eapConfig.anonymousIdentity); + config.wifiEapConfig.password = std::string(cfg.eapConfig.password); + config.wifiEapConfig.caCertAlias = std::string(cfg.eapConfig.caCertAlias); + config.wifiEapConfig.caCertPath = std::string(cfg.eapConfig.caPath); + config.wifiEapConfig.clientCert = std::string(cfg.eapConfig.clientCertAlias); + config.wifiEapConfig.privateKey = std::string(cfg.eapConfig.clientCertAlias); + config.wifiEapConfig.certEntry = std::vector(cfg.eapConfig.certEntry.head, cfg.eapConfig.certEntry.head + cfg.eapConfig.certEntry.size); + if (strncpy_s(config.wifiEapConfig.certPassword, sizeof(config.wifiEapConfig.certPassword), + cfg.eapConfig.certPassword, strlen(cfg.eapConfig.certPassword)) != EOK) { + WIFI_LOGE("%{public}s: failed to copy", __func__); + } + config.wifiEapConfig.altSubjectMatch = std::string(cfg.eapConfig.altSubjectMatch); + config.wifiEapConfig.domainSuffixMatch = std::string(cfg.eapConfig.domainSuffixMatch); + config.wifiEapConfig.realm = std::string(cfg.eapConfig.realm); + config.wifiEapConfig.plmn = std::string(cfg.eapConfig.plmn); + config.wifiEapConfig.eapSubId = cfg.eapConfig.eapSubId; + } + if (!cfg.wapiConfig.isNone && (type == SecTypeCj::SEC_TYPE_WAPI_CERT || type == SecTypeCj::SEC_TYPE_WAPI_PSK)) { + config.wifiWapiConfig.wapiPskType = cfg.wapiConfig.wapiPskType; + config.wifiWapiConfig.wapiAsCertData = MallocCString(cfg.wapiConfig.wapiAsCert); + config.wifiWapiConfig.wapiUserCertData = MallocCString(cfg.wapiConfig.wapiUserCert); + } + + ErrCode code = cjWifiDevicePtr->AddDeviceConfig(config, ret, true); + if (ret < 0 || code != WIFI_OPT_SUCCESS) { + WIFI_LOGE("Add candidate device config failed: %{public}d", static_cast(code)); + ret = -1; + } + return code; +} + +WifiDeviceConfigArr CJ_GetCandidateConfigs(int32_t &code) +{ + WifiDeviceConfigArr arr{.head = nullptr, .size = 0}; + if (cjWifiDevicePtr == nullptr) { + code = WIFI_OPT_FAILED; + return arr; + } + std::vector vecDeviceConfigs; + code = cjWifiDevicePtr->GetDeviceConfigs(vecDeviceConfigs, true); + int64_t size = static_cast(vecDeviceConfigs.size()); + if (code == WIFI_OPT_SUCCESS && size > 0) { + WIFI_LOGI("Get candidate device configs size: %{public}zu", vecDeviceConfigs.size()); + // transform + arr.head = static_cast(malloc(sizeof(CWifiDeviceConfig) * size)); + if (arr.head == nullptr) { + code = WIFI_OPT_FAILED; + return arr; + } + arr.size = size; + for(int64_t i = 0; i < size; i++) { + CWifiDeviceConfig cfg; + DeviceConfig2C(vecDeviceConfigs[i], cfg); + arr.head[i] = cfg; + } + } + return arr; +} + +int32_t CJ_WifiOn(char *type, int64_t id) +{ + return 0; +} + +int32_t CJ_WifiOff(char* type) +{ + return 0; +} + +} +} \ No newline at end of file -- 2.34.1