1From 0b5ba8bb5f6b559b913aab638018bb6e5a709032 Mon Sep 17 00:00:00 2001
2From: zhaoshenghua <zhaoshenghua1@huawei.com>
3Date: Wed, 14 Aug 2024 14:11:10 +0800
4Subject: [PATCH 1/4] wifi
5
6Signed-off-by: zhaoshenghua <zhaoshenghua1@huawei.com>
7Change-Id: I91c87de6b8933e8ff11e3929f60536d8e0d8360e
8---
9 wifi/frameworks/BUILD.gn                 |   1 +
10 wifi/frameworks/cj/BUILD.gn              |  69 +++
11 wifi/frameworks/cj/include/ffi_structs.h | 199 ++++++
12 wifi/frameworks/cj/include/wifi_ffi.h    |  79 +++
13 wifi/frameworks/cj/src/wifi_ffi.cpp      | 735 +++++++++++++++++++++++
14 5 files changed, 1083 insertions(+)
15 create mode 100644 wifi/frameworks/cj/BUILD.gn
16 create mode 100644 wifi/frameworks/cj/include/ffi_structs.h
17 create mode 100644 wifi/frameworks/cj/include/wifi_ffi.h
18 create mode 100644 wifi/frameworks/cj/src/wifi_ffi.cpp
19
20diff --git a/wifi/frameworks/BUILD.gn b/wifi/frameworks/BUILD.gn
21index b79abfbb6..e856dd96a 100644
22--- a/wifi/frameworks/BUILD.gn
23+++ b/wifi/frameworks/BUILD.gn
24@@ -28,6 +28,7 @@ group("wifi_kits") {
25       "$WIFI_ROOT_DIR/frameworks/js/napi:wifiext",
26       "$WIFI_ROOT_DIR/frameworks/js/napi:wifimanager",
27       "$WIFI_ROOT_DIR/frameworks/js/napi:wifimanagerext",
28+      "$WIFI_ROOT_DIR/frameworks/cj:cj_wifi_ffi",
29     ]
30   }
31 }
32diff --git a/wifi/frameworks/cj/BUILD.gn b/wifi/frameworks/cj/BUILD.gn
33new file mode 100644
34index 000000000..71fed17cc
35--- /dev/null
36+++ b/wifi/frameworks/cj/BUILD.gn
37@@ -0,0 +1,69 @@
38+# Copyright (C) 2024 Huawei Device Co., Ltd.
39+# Licensed under the Apache License, Version 2.0 (the "License");
40+# you may not use this file except in compliance with the License.
41+# You may obtain a copy of the License at
42+#
43+#     http://www.apache.org/licenses/LICENSE-2.0
44+#
45+# Unless required by applicable law or agreed to in writing, software
46+# distributed under the License is distributed on an "AS IS" BASIS,
47+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
48+# See the License for the specific language governing permissions and
49+# limitations under the License.
50+
51+import("//build/ohos.gni")
52+import("//foundation/communication/wifi/wifi/wifi.gni")
53+
54+ohos_shared_library("cj_wifi_ffi") {
55+  branch_protector_ret = "pac_ret"
56+
57+  sanitize = {
58+    cfi = true  # Enable/disable control flow integrity detection
59+    boundary_sanitize = true  # Enable boundary san detection
60+    cfi_cross_dso = true  # Cross-SO CFI Checks
61+    integer_overflow = true  # Enable integer overflow detection
62+    ubsan = true  # Enable some Ubsan options
63+    debug = false
64+  }
65+  install_enable = true
66+  include_dirs = [
67+    "$WIFI_ROOT_DIR/services/wifi_standard/wifi_framework/wifi_toolkit/log",
68+    "$WIFI_ROOT_DIR/frameworks/native/interfaces",
69+    "$WIFI_ROOT_DIR/interfaces/inner_api",
70+    "$WIFI_ROOT_DIR/frameworks/native/include",
71+    "$WIFI_ROOT_DIR/frameworks/native/src",
72+    "$WIFI_ROOT_DIR/services/wifi_standard/wifi_framework/wifi_toolkit/net_helper",
73+    "$WIFI_ROOT_DIR/utils/inc",
74+    "./include"
75+  ]
76+
77+  sources = [
78+    "src/wifi_ffi.cpp",
79+  ]
80+
81+  deps = [ "$WIFI_ROOT_DIR/frameworks/native:wifi_sdk" ]
82+
83+  defines = []
84+  if (wifi_feature_with_random_mac_addr) {
85+    defines += [ "SUPPORT_RANDOM_MAC_ADDR" ]
86+  }
87+
88+  external_deps = [
89+    "ability_runtime:app_context",
90+    "access_token:libaccesstoken_sdk",
91+    "bundle_framework:appexecfwk_base",
92+    "c_utils:utils",
93+    "hilog:libhilog",
94+    "ipc:ipc_single",
95+    "napi:cj_bind_ffi",
96+    "napi:cj_bind_native",
97+    "samgr:samgr_proxy",
98+  ]
99+  cflags = memory_optimization_cflags
100+  cflags_cc = memory_optimization_cflags_cc
101+  ldflags = memory_optimization_ldflags
102+
103+  innerapi_tags = [ "platformsdk" ]
104+  part_name = "wifi"
105+  subsystem_name = "communication"
106+}
107\ No newline at end of file
108diff --git a/wifi/frameworks/cj/include/ffi_structs.h b/wifi/frameworks/cj/include/ffi_structs.h
109new file mode 100644
110index 000000000..ca174fecf
111--- /dev/null
112+++ b/wifi/frameworks/cj/include/ffi_structs.h
113@@ -0,0 +1,199 @@
114+/*
115+ * Copyright (c) 2024 Huawei Device Co., Ltd.
116+ * Licensed under the Apache License, Version 2.0 (the "License");
117+ * you may not use this file except in compliance with the License.
118+ * You may obtain a copy of the License at
119+ *
120+ *     http://www.apache.org/licenses/LICENSE-2.0
121+ *
122+ * Unless required by applicable law or agreed to in writing, software
123+ * distributed under the License is distributed on an "AS IS" BASIS,
124+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
125+ * See the License for the specific language governing permissions and
126+ * limitations under the License.
127+ */
128+
129+#ifndef CJ_WIFI_FFI_STRUCTS_H
130+#define CJ_WIFI_FFI_STRUCTS_H
131+
132+#include <cstdint>
133+#include "cj_ffi/cj_common_ffi.h"
134+
135+extern "C" {
136+    struct CWifiInfoElem
137+    {
138+        uint32_t eid;
139+        CArrUI8 content;
140+    };
141+
142+    struct CWifiScanInfo
143+    {
144+        char *ssid;
145+        char *bssid;
146+        int32_t bssidType;
147+        char *capabilities;
148+        int32_t securityType;
149+        int32_t rssi;
150+        int32_t band;
151+        int32_t frequency;
152+        int32_t channelWidth;
153+        int32_t centerFrequency0;
154+        int32_t centerFrequency1;
155+        CWifiInfoElem *infoElems;
156+        int64_t elemsSize;
157+        int64_t timestamp;
158+        int32_t supportedWifiCategory;
159+        bool isHiLinkNetwork;
160+    };
161+    
162+    struct WifiScanInfoArr
163+    {
164+        CWifiScanInfo *head;
165+        int64_t size;
166+    };
167+
168+    // TODO figure out clientCert
169+    struct CWifiEapConfig
170+    {
171+        int32_t eapMethod;                        /* EAP authentication mode:PEAP/TLS/TTLS/PWD/SIM/AKA/AKA' */
172+        int32_t phase2Method;              /* Second stage authentication method */
173+        char *identity;                   /* Identity information */
174+        char *anonymousIdentity;          /* Anonymous identity information */
175+        char *password;                   /* EAP mode password */
176+        char *caCertAlias;                /* CA certificate alias */
177+        char *caPath;                 /* CA certificate path */
178+        char *clientCertAlias;
179+        CArrUI8 certEntry;         /* CA certificate entry */
180+        char *certPassword;   /* Certificate password */
181+        char *altSubjectMatch;                  /* Alternative topic matching */
182+        char *domainSuffixMatch;                /* Domain suffix matching */
183+        char *realm;                            /* The field of passport credentials */
184+        char *plmn;                             /* PLMN */
185+        int32_t eapSubId;                       /* Sub ID of SIM card */
186+        bool isNone;
187+    };
188+
189+    struct CWifiWapiConfig
190+    {
191+        int32_t wapiPskType;
192+        char *wapiAsCert;
193+        char *wapiUserCert;
194+        bool isNone;
195+    };
196+
197+    struct CIpInfo
198+    {
199+        uint32_t ipAddress;
200+        uint32_t gateway;
201+        uint32_t netmask;
202+        uint32_t primaryDns;
203+        uint32_t secondDns;
204+        uint32_t serverIp;
205+        uint32_t leaseDuration;
206+    };
207+
208+    struct CIpv6Info
209+    {
210+        char *linkIpV6Address;
211+        char *globalIpV6Address;
212+        char *randomGlobalIpV6Address;
213+        char *uniqueIpv6Address;
214+        char *randomUniqueIpv6Address;
215+        char *gateway;
216+        char *netmask;
217+        char *primaryDns;
218+        char *secondDNS;
219+    };
220+
221+    struct CWifiP2PConfig
222+    {
223+        char *deviceAddress;
224+        char *passphrase;
225+        char *groupName;
226+        int32_t netId;
227+        int32_t goBand;
228+        int32_t deviceAddressType;        
229+    };
230+
231+    struct CWifiP2PLinkedInfo
232+    {
233+        int32_t connectState;
234+        bool isGroupOwner;
235+        char *groupOwnerAddr;
236+    };
237+
238+    struct CWifiP2pDevice
239+    {
240+        char *deviceName;
241+        char *deviceAddress;
242+        char *primaryDeviceType;
243+        int32_t deviceStatus;
244+        int32_t groupCapabilities;
245+        int32_t deviceAddressType;
246+    };
247+
248+    struct WifiP2pDeviceArr
249+    {
250+        CWifiP2pDevice *head;
251+        int64_t size;
252+    };
253+
254+    struct CWifiP2PGroupInfo
255+    {
256+        bool isP2pGo;
257+        CWifiP2pDevice ownerInfo;
258+        char *passphrase;
259+        char *interfaceName;
260+        char *groupName;
261+        int32_t networkId;
262+        int32_t frequency;
263+        CWifiP2pDevice *clientDevices;
264+        int64_t clientSize;
265+        char *goIpAddress;
266+    };
267+
268+    struct CWifiLinkedInfo
269+    {
270+        char *ssid;
271+        char *bssid;
272+        int32_t rssi;
273+        int32_t band;
274+        int32_t linkSpeed;
275+        int32_t rxLinkSpeed;
276+        int32_t maxSupportedTxLinkSpeed;
277+        int32_t maxSupportedRxLinkSpeed;
278+        int32_t frequency;
279+        bool isHidden;
280+        bool isRestricted;
281+        int32_t macType;
282+        char *macAddress;
283+        uint32_t ipAddress;
284+        int32_t connState;
285+        int32_t channelWidth;
286+        int32_t wifiStandard;
287+        int32_t supportedWifiCategory;
288+        bool isHiLinkNetwork;
289+    };
290+
291+    struct CWifiDeviceConfig
292+    {
293+        int32_t securityType;
294+        int32_t bssidType;
295+        bool isHiddenSsid;
296+        char *bssid;
297+        char *ssid;
298+        char *preSharedKey;
299+        CWifiEapConfig eapConfig;
300+        CWifiWapiConfig wapiConfig;
301+    };
302+
303+    struct WifiDeviceConfigArr
304+    {
305+        CWifiDeviceConfig *head;
306+        int64_t size;
307+    };
308+}
309+
310+
311+
312+#endif // CJ_WIFI_FFI_STRUCTS_H
313\ No newline at end of file
314diff --git a/wifi/frameworks/cj/include/wifi_ffi.h b/wifi/frameworks/cj/include/wifi_ffi.h
315new file mode 100644
316index 000000000..5525813ed
317--- /dev/null
318+++ b/wifi/frameworks/cj/include/wifi_ffi.h
319@@ -0,0 +1,79 @@
320+/*
321+ * Copyright (c) 2024 Huawei Device Co., Ltd.
322+ * Licensed under the Apache License, Version 2.0 (the "License");
323+ * you may not use this file except in compliance with the License.
324+ * You may obtain a copy of the License at
325+ *
326+ *     http://www.apache.org/licenses/LICENSE-2.0
327+ *
328+ * Unless required by applicable law or agreed to in writing, software
329+ * distributed under the License is distributed on an "AS IS" BASIS,
330+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
331+ * See the License for the specific language governing permissions and
332+ * limitations under the License.
333+ */
334+
335+#ifndef CJ_WIFI_FFI_H
336+#define CJ_WIFI_FFI_H
337+
338+#include "cj_ffi/cj_common_ffi.h"
339+#include "ffi_structs.h"
340+
341+char *MallocCString(const std::string &origin);
342+
343+enum class SecTypeCj {
344+    /** Invalid security type */
345+    SEC_TYPE_INVALID = 0,
346+    /** Open */
347+    SEC_TYPE_OPEN = 1,
348+    /** Wired Equivalent Privacy (WEP) */
349+    SEC_TYPE_WEP = 2,
350+    /** Pre-shared key (PSK) */
351+    SEC_TYPE_PSK = 3,
352+    /** Simultaneous Authentication of Equals (SAE) */
353+    SEC_TYPE_SAE = 4,
354+    /** EAP authentication. */
355+    SEC_TYPE_EAP = 5,
356+    /** SUITE_B_192 192 bit level. */
357+    SEC_TYPE_EAP_SUITE_B = 6,
358+#ifdef ENABLE_NAPI_WIFI_MANAGER
359+    /** Opportunistic Wireless Encryption. */
360+    SEC_TYPE_OWE = 7,
361+#endif
362+    /** WAPI certificate to be specified. */
363+    SEC_TYPE_WAPI_CERT = 8,
364+    /** WAPI pre-shared key to be specified. */
365+    SEC_TYPE_WAPI_PSK = 9,
366+};
367+
368+extern "C" {
369+FFI_EXPORT int32_t CJ_IsWifiActive(bool &ret);
370+FFI_EXPORT WifiScanInfoArr CJ_GetScanInfoList(int32_t &ret);
371+FFI_EXPORT int32_t CJ_RemoveCandidateConfig(int32_t id);
372+FFI_EXPORT int32_t CJ_ConnectToCandidateConfig(int32_t id);
373+FFI_EXPORT int32_t CJ_GetSignalLevel(int32_t rssi, int32_t band, uint32_t &ret);
374+FFI_EXPORT int32_t CJ_IsConnected(bool &ret);
375+FFI_EXPORT int32_t CJ_IsFeatureSupported(int64_t featureId, bool &ret);
376+FFI_EXPORT int32_t CJ_GetIpInfo(CIpInfo &ret);
377+FFI_EXPORT int32_t CJ_GetIpv6Info(CIpv6Info &ret);
378+FFI_EXPORT char *CJ_GetCountryCode(int32_t &code);
379+FFI_EXPORT int32_t CJ_IsBandTypeSupported(int32_t bandType, bool &ret);
380+FFI_EXPORT int32_t CJ_IsMeteredHotspot(bool &ret);
381+FFI_EXPORT int32_t CJ_RemoveGroup();
382+FFI_EXPORT int32_t CJ_P2pConnect(CWifiP2PConfig &cfg);
383+FFI_EXPORT int32_t CJ_P2pCancelConnect();
384+FFI_EXPORT int32_t CJ_StartDiscoverDevices();
385+FFI_EXPORT int32_t CJ_StopDiscoverDevices();
386+FFI_EXPORT int32_t CJ_GetP2pLinkedInfo(CWifiP2PLinkedInfo &info);
387+FFI_EXPORT int32_t CJ_GetCurrentGroup(CWifiP2PGroupInfo &info);
388+FFI_EXPORT WifiP2pDeviceArr CJ_GetP2pPeerDevices(int32_t &ret);
389+FFI_EXPORT int32_t CJ_GetP2pLocalDevice(CWifiP2pDevice &info);
390+FFI_EXPORT int32_t CJ_CreateGroup(CWifiP2PConfig &cfg);
391+FFI_EXPORT int32_t CJ_GetLinkedInfo(CWifiLinkedInfo &info);
392+FFI_EXPORT int32_t CJ_AddCandidateConfig(CWifiDeviceConfig cfg, int32_t &ret);
393+FFI_EXPORT WifiDeviceConfigArr CJ_GetCandidateConfigs(int32_t &code);
394+FFI_EXPORT int32_t CJ_WifiOn(char *type, int64_t id);
395+FFI_EXPORT int32_t CJ_WifiOff(char* type);
396+}
397+
398+#endif // CJ_WIFI_FFI_H
399\ No newline at end of file
400diff --git a/wifi/frameworks/cj/src/wifi_ffi.cpp b/wifi/frameworks/cj/src/wifi_ffi.cpp
401new file mode 100644
402index 000000000..2673fee55
403--- /dev/null
404+++ b/wifi/frameworks/cj/src/wifi_ffi.cpp
405@@ -0,0 +1,735 @@
406+/*
407+ * Copyright (c) 2024 Huawei Device Co., Ltd.
408+ * Licensed under the Apache License, Version 2.0 (the "License");
409+ * you may not use this file except in compliance with the License.
410+ * You may obtain a copy of the License at
411+ *
412+ *     http://www.apache.org/licenses/LICENSE-2.0
413+ *
414+ * Unless required by applicable law or agreed to in writing, software
415+ * distributed under the License is distributed on an "AS IS" BASIS,
416+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
417+ * See the License for the specific language governing permissions and
418+ * limitations under the License.
419+ */
420+
421+#include "wifi_ffi.h"
422+
423+#include <vector>
424+#include <functional>
425+#include "wifi_device.h"
426+#include "wifi_scan.h"
427+#include "wifi_p2p.h"
428+#include "wifi_common_util.h"
429+#include "wifi_logger.h"
430+
431+DEFINE_WIFILOG_LABEL("CJ_WIFI_FFI");
432+
433+namespace OHOS::Wifi {
434+
435+std::shared_ptr<WifiDevice> cjWifiDevicePtr = WifiDevice::GetInstance(WIFI_DEVICE_ABILITY_ID);
436+std::shared_ptr<WifiScan> cjWifiScanPtr = WifiScan::GetInstance(WIFI_SCAN_ABILITY_ID);
437+std::shared_ptr<WifiP2p> cjWifiP2pPtr = WifiP2p::GetInstance(WIFI_P2P_ABILITY_ID);
438+static const std::string EAP_METHOD[] = { "NONE", "PEAP", "TLS", "TTLS", "PWD", "SIM", "AKA", "AKA'" };
439+
440+static std::string EapMethod2Str(const int& method)
441+{
442+    if (method < 0 || method >= static_cast<int>(sizeof(EAP_METHOD) / sizeof(EAP_METHOD[0]))) {
443+        return "NONE";
444+    }
445+    return EAP_METHOD[method];
446+}
447+
448+static char *MallocCString(const std::string &origin)
449+{
450+    if (origin.empty()) {
451+        return nullptr;
452+    }
453+    auto len = origin.length() + 1;
454+    char *res = static_cast<char *>(malloc(sizeof(char) * len));
455+    if (res == nullptr) {
456+        return nullptr;
457+    }
458+    return std::char_traits<char>::copy(res, origin.c_str(), len);
459+}
460+
461+static SecTypeCj SecurityTypeNativeToCj(const WifiSecurity& cppSecurityType)
462+{
463+    SecTypeCj cjSecurityType = SecTypeCj::SEC_TYPE_INVALID;
464+    switch (cppSecurityType) {
465+        case WifiSecurity::OPEN:
466+            cjSecurityType = SecTypeCj::SEC_TYPE_OPEN;
467+            break;
468+        case WifiSecurity::WEP:
469+            cjSecurityType = SecTypeCj::SEC_TYPE_WEP;
470+            break;
471+        case WifiSecurity::PSK:
472+            cjSecurityType = SecTypeCj::SEC_TYPE_PSK;
473+            break;
474+        case WifiSecurity::SAE:
475+        case WifiSecurity::PSK_SAE:
476+            cjSecurityType = SecTypeCj::SEC_TYPE_SAE;
477+            break;
478+        case WifiSecurity::EAP:
479+            cjSecurityType = SecTypeCj::SEC_TYPE_EAP;
480+            break;
481+        case WifiSecurity::EAP_SUITE_B:
482+            cjSecurityType = SecTypeCj::SEC_TYPE_EAP_SUITE_B;
483+            break;
484+        case WifiSecurity::WAPI_CERT:
485+            cjSecurityType = SecTypeCj::SEC_TYPE_WAPI_CERT;
486+            break;
487+        case WifiSecurity::WAPI_PSK:
488+            cjSecurityType = SecTypeCj::SEC_TYPE_WAPI_PSK;
489+            break;
490+        default:
491+            cjSecurityType = SecTypeCj::SEC_TYPE_INVALID;
492+            break;
493+    }
494+    return cjSecurityType;
495+}
496+
497+static void ConvertEncryptionMode(const SecTypeCj& securityType, std::string& keyMgmt)
498+{
499+    switch (securityType) {
500+        case SecTypeCj::SEC_TYPE_OPEN:
501+            keyMgmt = KEY_MGMT_NONE;
502+            break;
503+        case SecTypeCj::SEC_TYPE_WEP:
504+            keyMgmt = KEY_MGMT_WEP;
505+            break;
506+        case SecTypeCj::SEC_TYPE_PSK:
507+            keyMgmt = KEY_MGMT_WPA_PSK;
508+            break;
509+        case SecTypeCj::SEC_TYPE_SAE:
510+            keyMgmt = KEY_MGMT_SAE;
511+            break;
512+        case SecTypeCj::SEC_TYPE_EAP:
513+            keyMgmt = KEY_MGMT_EAP;
514+            break;
515+        case SecTypeCj::SEC_TYPE_EAP_SUITE_B:
516+            keyMgmt = KEY_MGMT_SUITE_B_192;
517+            break;
518+        case SecTypeCj::SEC_TYPE_WAPI_CERT:
519+            keyMgmt = KEY_MGMT_WAPI_CERT;
520+            break;
521+        case SecTypeCj::SEC_TYPE_WAPI_PSK:
522+            keyMgmt = KEY_MGMT_WAPI_PSK;
523+            break;
524+        default:
525+            keyMgmt = KEY_MGMT_NONE;
526+            break;
527+    }
528+}
529+
530+static void ProcessPassphrase(const SecTypeCj& securityType, WifiDeviceConfig& cppConfig)
531+{
532+    if (securityType == SecTypeCj::SEC_TYPE_WEP) {
533+        cppConfig.wepKeys[0] = cppConfig.preSharedKey;
534+        cppConfig.wepTxKeyIndex = 0;
535+        cppConfig.preSharedKey = "";
536+        std::string().swap(cppConfig.preSharedKey);
537+    }
538+}
539+
540+static void NativeInfoElems2Cj(const std::vector<WifiInfoElem>& infoElems, CWifiScanInfo &info)
541+{
542+    int valueStep = 2;
543+    int64_t size = static_cast<int64_t>(infoElems.size());
544+    if (size > 0) {
545+        info.infoElems = static_cast<CWifiInfoElem *>(malloc(sizeof(CWifiInfoElem) * size));
546+        if (info.infoElems == nullptr) {
547+            info.elemsSize = 0;
548+            return;
549+        }
550+        info.elemsSize = size;
551+        for (int64_t i = 0; i < size; i++) {
552+            CWifiInfoElem elem;
553+            elem.eid = infoElems[i].id;
554+
555+            const char *uStr = &infoElems[i].content[0];
556+            size_t len = infoElems[i].content.size();
557+            size_t inLen = static_cast<size_t>(infoElems[i].content.size() * valueStep + 1);
558+            char *buf = (char *)calloc(inLen + 1, sizeof(char));
559+            if (buf == nullptr) {
560+                elem.content = CArrUI8{.head = nullptr, .size = 0};
561+                info.infoElems[i] = elem;
562+                continue;
563+            }
564+            int pos = 0;
565+            for (size_t k = 0; k < len; ++k) {
566+                pos = (k << 1);
567+                if (snprintf_s(buf + pos, inLen - pos, inLen - pos - 1, "%02x", uStr[k]) < 0) {
568+                    free(buf);
569+                    buf = NULL;
570+                    elem.content = CArrUI8{.head = nullptr, .size = 0};
571+                    info.infoElems[i] = elem;
572+                    continue;
573+                }
574+            }
575+            elem.content = CArrUI8{.head = reinterpret_cast<uint8_t *>(buf), .size = inLen - 1}; // TODO check size
576+            info.infoElems[i] = elem;
577+        }
578+    }
579+}
580+
581+static int32_t ScanInfo2Cj(const std::vector<WifiScanInfo>& scanInfos, WifiScanInfoArr &infos)
582+{
583+    int64_t size = static_cast<int64_t>(scanInfos.size());
584+    WIFI_LOGI("GetScanInfoList, size: %{public}zu", scanInfos.size());
585+
586+    if (size > 0) {
587+        infos.head = static_cast<CWifiScanInfo *>(malloc(sizeof(CWifiScanInfo) * size));
588+        if (infos.head == nullptr) {
589+            return WIFI_OPT_FAILED;
590+        }
591+        infos.size = size;
592+
593+        uint32_t idx = 0;
594+        for(auto& each : scanInfos) {
595+            CWifiScanInfo info;
596+            info.ssid = MallocCString(each.ssid);
597+            info.bssid = MallocCString(each.bssid);
598+            info.bssidType = each.bssidType;
599+            info.capabilities = MallocCString(each.capabilities);
600+            info.securityType = static_cast<int32_t>(SecurityTypeNativeToCj(each.securityType));
601+            info.rssi = each.rssi;
602+            info.band = each.band;
603+            info.frequency = each.frequency;
604+            info.channelWidth = static_cast<int32_t>(each.channelWidth);
605+            info.centerFrequency0 = each.centerFrequency0;
606+            info.centerFrequency1 = each.centerFrequency1;
607+            NativeInfoElems2Cj(each.infoElems, info);
608+            info.channelWidth = static_cast<int32_t>(each.channelWidth);
609+            info.timestamp = each.timestamp;
610+            info.supportedWifiCategory = static_cast<int32_t>(each.supportedWifiCategory);
611+            info.isHiLinkNetwork = each.isHiLinkNetwork;
612+            infos.head[idx] = info;
613+            idx++;
614+        }
615+    }
616+    return WIFI_OPT_SUCCESS;
617+}
618+
619+static void DeviceInfo2Cj(const WifiP2pDevice &device, CWifiP2pDevice &info)
620+{
621+    info.deviceName = MallocCString(device.GetDeviceName());
622+    info.deviceAddress = MallocCString(device.GetDeviceAddress());
623+    info.primaryDeviceType = MallocCString(device.GetPrimaryDeviceType());
624+    info.deviceStatus = static_cast<int32_t>(device.GetP2pDeviceStatus());
625+    info.groupCapabilities = device.GetGroupCapabilitys();
626+    info.deviceAddressType = device.GetDeviceAddressType();
627+}
628+
629+static void CjWifiP2PConfig2C(const CWifiP2PConfig &cfg, WifiP2pConfig &config)
630+{
631+    config.SetDeviceAddress(std::string(cfg.deviceAddress));
632+    config.SetDeviceAddressType(cfg.deviceAddressType);
633+    config.SetNetId(cfg.netId);
634+    config.SetPassphrase(std::string(cfg.passphrase));
635+    config.SetGroupName(std::string(cfg.groupName));
636+    config.SetGoBand(static_cast<GroupOwnerBand>(cfg.goBand));
637+}
638+
639+static void UpdateSecurityTypeAndPreSharedKey(WifiDeviceConfig &cppConfig)
640+{
641+    if (cppConfig.keyMgmt != KEY_MGMT_NONE) {
642+        return;
643+    }
644+    for (int i = 0; i != WEPKEYS_SIZE; ++i) {
645+        if (!cppConfig.wepKeys[i].empty() && cppConfig.wepTxKeyIndex == i) {
646+            cppConfig.keyMgmt = KEY_MGMT_WEP;
647+            cppConfig.preSharedKey = cppConfig.wepKeys[i];
648+        }
649+    }
650+}
651+
652+static SecTypeCj ConvertKeyMgmtToSecType(const std::string &keyMgmt)
653+{
654+    std::map<std::string, SecTypeCj> mapKeyMgmtToSecType = {
655+        {KEY_MGMT_NONE, SecTypeCj::SEC_TYPE_OPEN},
656+        {KEY_MGMT_WEP, SecTypeCj::SEC_TYPE_WEP},
657+        {KEY_MGMT_WPA_PSK, SecTypeCj::SEC_TYPE_PSK},
658+        {KEY_MGMT_SAE, SecTypeCj::SEC_TYPE_SAE},
659+        {KEY_MGMT_EAP, SecTypeCj::SEC_TYPE_EAP},
660+        {KEY_MGMT_SUITE_B_192, SecTypeCj::SEC_TYPE_EAP_SUITE_B},
661+        {KEY_MGMT_WAPI_CERT, SecTypeCj::SEC_TYPE_WAPI_CERT},
662+        {KEY_MGMT_WAPI_PSK, SecTypeCj::SEC_TYPE_WAPI_PSK},
663+    };
664+
665+    std::map<std::string, SecTypeCj>::iterator iter = mapKeyMgmtToSecType.find(keyMgmt);
666+    return iter == mapKeyMgmtToSecType.end() ? SecTypeCj::SEC_TYPE_OPEN : iter->second;
667+}
668+
669+static int Str2EapMethod(const std::string &str)
670+{
671+    WIFI_LOGD("%{public}s: eapMethod is %{public}s", __func__, str.c_str());
672+    int len = sizeof(EAP_METHOD) / sizeof(EAP_METHOD[0]);
673+    for (int i = 0; i < len; i++) {
674+        if (EAP_METHOD[i] == str) {
675+            WIFI_LOGD("%{public}s: index is %{public}d", __func__, i);
676+            return i;
677+        }
678+    }
679+    return 0;
680+}
681+
682+static void DeviceConfig2C(WifiDeviceConfig &config, CWifiDeviceConfig &cfg)
683+{
684+    UpdateSecurityTypeAndPreSharedKey(config);
685+    cfg.ssid = MallocCString(config.ssid);
686+    cfg.bssid = MallocCString(config.bssid);
687+    cfg.bssidType = config.bssidType;
688+    cfg.preSharedKey = MallocCString(config.preSharedKey);
689+    cfg.isHiddenSsid = config.hiddenSSID;
690+    cfg.eapConfig.isNone = true;
691+    cfg.wapiConfig.isNone = true;
692+    SecTypeCj type = ConvertKeyMgmtToSecType(config.keyMgmt);
693+    cfg.securityType = static_cast<int32_t>(type);
694+    if (type == SecTypeCj::SEC_TYPE_EAP || type == SecTypeCj::SEC_TYPE_EAP_SUITE_B) {
695+        cfg.eapConfig.eapMethod = Str2EapMethod(config.wifiEapConfig.eap);
696+        cfg.eapConfig.phase2Method = static_cast<int>(config.wifiEapConfig.phase2Method);
697+        cfg.eapConfig.identity = MallocCString(config.wifiEapConfig.identity);
698+        cfg.eapConfig.anonymousIdentity = MallocCString(config.wifiEapConfig.anonymousIdentity);
699+        cfg.eapConfig.password = MallocCString(config.wifiEapConfig.password);
700+        cfg.eapConfig.caCertAlias = MallocCString(config.wifiEapConfig.caCertAlias);
701+        cfg.eapConfig.caPath = MallocCString(config.wifiEapConfig.caCertPath);
702+        cfg.eapConfig.clientCertAlias = MallocCString(config.wifiEapConfig.caCertAlias); // ?
703+        CArrUI8 arr{.head = nullptr, .size = 0};
704+        int64_t size = config.wifiEapConfig.certEntry.size();
705+        arr.head = static_cast<uint8_t *>(malloc(sizeof(uint8_t) * size));
706+        if (arr.head != nullptr) {
707+            uint32_t idx = 0;
708+            for (auto& each : config.wifiEapConfig.certEntry) {
709+                arr.head[idx] = each;
710+                idx++;
711+            }
712+        }
713+        cfg.eapConfig.certEntry = arr;
714+        cfg.eapConfig.certPassword = MallocCString(config.wifiEapConfig.certPassword);
715+        cfg.eapConfig.altSubjectMatch = MallocCString(config.wifiEapConfig.altSubjectMatch);
716+        cfg.eapConfig.domainSuffixMatch = MallocCString(config.wifiEapConfig.domainSuffixMatch);
717+        cfg.eapConfig.realm = MallocCString(config.wifiEapConfig.realm);
718+        cfg.eapConfig.plmn = MallocCString(config.wifiEapConfig.plmn);
719+        cfg.eapConfig.eapSubId = config.wifiEapConfig.eapSubId;
720+        cfg.eapConfig.isNone = false;
721+    }
722+    if (type == SecTypeCj::SEC_TYPE_WAPI_CERT || type == SecTypeCj::SEC_TYPE_WAPI_PSK) {
723+        cfg.wapiConfig.wapiPskType = config.wifiWapiConfig.wapiPskType;
724+        cfg.wapiConfig.wapiAsCert = nullptr;
725+        cfg.wapiConfig.wapiUserCert = nullptr;
726+        cfg.wapiConfig.isNone = false;
727+    }
728+}
729+
730+extern "C" {
731+
732+int32_t CJ_IsWifiActive(bool &ret)
733+{
734+    if (cjWifiDevicePtr == nullptr) {
735+        return WIFI_OPT_FAILED;
736+    }
737+    return cjWifiDevicePtr->IsWifiActive(ret);
738+}
739+
740+WifiScanInfoArr CJ_GetScanInfoList(int32_t &ret)
741+{
742+    WifiScanInfoArr infos{ .head = nullptr, .size = 0 };
743+    if (cjWifiScanPtr == nullptr) {
744+        ret = WIFI_OPT_FAILED;
745+        return infos;
746+    }
747+    std::vector<WifiScanInfo> scanInfos;
748+    ret = cjWifiScanPtr->GetScanInfoList(scanInfos, false);
749+    if (ret == WIFI_OPT_SUCCESS) {
750+        ret = ScanInfo2Cj(scanInfos, infos);
751+    }
752+    return infos;
753+}
754+
755+int32_t CJ_RemoveCandidateConfig(int32_t id)
756+{
757+    if (cjWifiDevicePtr == nullptr) {
758+        return WIFI_OPT_FAILED;
759+    }
760+    return static_cast<int32_t>(cjWifiDevicePtr->RemoveCandidateConfig(id));
761+}
762+
763+int32_t CJ_ConnectToCandidateConfig(int32_t id)
764+{
765+    if (cjWifiDevicePtr == nullptr) {
766+        return WIFI_OPT_FAILED;
767+    }
768+    return static_cast<int32_t>(cjWifiDevicePtr->ConnectToNetwork(id, true));
769+}
770+
771+int32_t CJ_GetSignalLevel(int32_t rssi, int32_t band, uint32_t &ret)
772+{
773+    if (cjWifiDevicePtr == nullptr) {
774+        return WIFI_OPT_FAILED;
775+    }
776+    int level = -1;
777+    ErrCode code = cjWifiDevicePtr->GetSignalLevel(rssi, band, level);
778+    ret = static_cast<uint32_t>(level);
779+    return static_cast<int32_t>(code);
780+}
781+
782+int32_t CJ_IsConnected(bool &ret)
783+{
784+    if (cjWifiDevicePtr == nullptr) {
785+        return WIFI_OPT_FAILED;
786+    }
787+    return static_cast<int32_t>(cjWifiDevicePtr->IsConnected(ret));
788+}
789+
790+int32_t CJ_IsFeatureSupported(int64_t featureId, bool &ret)
791+{
792+    if (cjWifiDevicePtr == nullptr) {
793+        return WIFI_OPT_FAILED;
794+    }
795+    return static_cast<int32_t>(cjWifiDevicePtr->IsFeatureSupported(featureId, ret));
796+}
797+
798+int32_t CJ_GetIpInfo(CIpInfo &ret)
799+{
800+    if (cjWifiDevicePtr == nullptr) {
801+        return WIFI_OPT_FAILED;
802+    }
803+    IpInfo ipInfo;
804+    ErrCode code = cjWifiDevicePtr->GetIpInfo(ipInfo);
805+    if (code == WIFI_OPT_SUCCESS) {
806+        ret.ipAddress = ipInfo.ipAddress;
807+        ret.gateway = ipInfo.gateway;
808+        ret.netmask = ipInfo.netmask;
809+        ret.primaryDns = ipInfo.primaryDns;
810+        ret.secondDns = ipInfo.secondDns;
811+        ret.serverIp = ipInfo.serverIp;
812+        ret.leaseDuration = ipInfo.leaseDuration;
813+    }
814+    return code;
815+}
816+
817+int32_t CJ_GetIpv6Info(CIpv6Info &ret)
818+{
819+    if (cjWifiDevicePtr == nullptr) {
820+        return WIFI_OPT_FAILED;
821+    }
822+    IpV6Info ipInfo;
823+    ErrCode code = cjWifiDevicePtr->GetIpv6Info(ipInfo);
824+    if (code == WIFI_OPT_SUCCESS) {
825+        ret.linkIpV6Address = MallocCString(ipInfo.linkIpV6Address);
826+        ret.globalIpV6Address = MallocCString(ipInfo.globalIpV6Address);
827+        ret.randomGlobalIpV6Address = MallocCString(ipInfo.randGlobalIpV6Address);
828+        ret.uniqueIpv6Address = MallocCString(ipInfo.uniqueLocalAddress1);
829+        ret.randomUniqueIpv6Address = MallocCString(ipInfo.uniqueLocalAddress2);
830+        ret.gateway = MallocCString(ipInfo.gateway);
831+        ret.netmask = MallocCString(ipInfo.netmask);
832+        ret.primaryDns = MallocCString(ipInfo.primaryDns);
833+        ret.secondDNS = MallocCString(ipInfo.secondDns);
834+    }
835+    return code;
836+}
837+
838+char *CJ_GetCountryCode(int32_t &code)
839+{
840+    if (cjWifiDevicePtr == nullptr) {
841+        code = WIFI_OPT_FAILED;
842+        return nullptr;
843+    }
844+    std::string countryCode;
845+    code = cjWifiDevicePtr->GetCountryCode(countryCode);
846+    if (code == WIFI_OPT_SUCCESS) {
847+        return MallocCString(countryCode);
848+    }
849+    return nullptr;
850+}
851+
852+int32_t CJ_IsBandTypeSupported(int32_t bandType, bool &ret)
853+{
854+    if (cjWifiDevicePtr == nullptr) {
855+        return WIFI_OPT_FAILED;
856+    }
857+    return cjWifiDevicePtr->IsBandTypeSupported(bandType, ret);
858+}
859+
860+int32_t CJ_IsMeteredHotspot(bool &ret)
861+{
862+    if (cjWifiDevicePtr == nullptr) {
863+        return WIFI_OPT_FAILED;
864+    }
865+    return cjWifiDevicePtr->IsMeteredHotspot(ret);
866+}
867+
868+int32_t CJ_RemoveGroup()
869+{
870+    if (cjWifiP2pPtr == nullptr) {
871+        return WIFI_OPT_FAILED;
872+    }
873+    return cjWifiP2pPtr->RemoveGroup();
874+}
875+
876+int32_t CJ_P2pConnect(CWifiP2PConfig &cfg)
877+{
878+    if (cjWifiP2pPtr == nullptr) {
879+        return WIFI_OPT_FAILED;
880+    }
881+    WifiP2pConfig config;
882+    CjWifiP2PConfig2C(cfg, config);
883+    return cjWifiP2pPtr->P2pConnect(config);
884+}
885+
886+int32_t CJ_P2pCancelConnect()
887+{
888+    if (cjWifiP2pPtr == nullptr) {
889+        return WIFI_OPT_FAILED;
890+    }
891+    return cjWifiP2pPtr->P2pCancelConnect();
892+}
893+
894+int32_t CJ_StartDiscoverDevices()
895+{
896+    if (cjWifiP2pPtr == nullptr) {
897+        return WIFI_OPT_FAILED;
898+    }
899+    return cjWifiP2pPtr->DiscoverDevices();
900+}
901+
902+int32_t CJ_StopDiscoverDevices()
903+{
904+    if (cjWifiP2pPtr == nullptr) {
905+        return WIFI_OPT_FAILED;
906+    }
907+    return cjWifiP2pPtr->StopDiscoverDevices();
908+}
909+
910+int32_t CJ_GetP2pLinkedInfo(CWifiP2PLinkedInfo &info)
911+{
912+    if (cjWifiP2pPtr == nullptr) {
913+        return WIFI_OPT_FAILED;
914+    }
915+    WifiP2pLinkedInfo linkedInfo;
916+    ErrCode code = cjWifiP2pPtr->QueryP2pLinkedInfo(linkedInfo);
917+    if (code == WIFI_OPT_SUCCESS) {
918+        info.connectState = static_cast<int>(linkedInfo.GetConnectState());
919+        info.isGroupOwner = linkedInfo.IsGroupOwner();
920+        info.groupOwnerAddr = MallocCString(linkedInfo.GetGroupOwnerAddress());
921+    }
922+    return code;
923+}
924+
925+int32_t CJ_GetCurrentGroup(CWifiP2PGroupInfo &info)
926+{
927+    if (cjWifiP2pPtr == nullptr) {
928+        return WIFI_OPT_FAILED;
929+    }
930+    WifiP2pGroupInfo groupInfo;
931+    ErrCode code = cjWifiP2pPtr->GetCurrentGroup(groupInfo);
932+    if (code == WIFI_OPT_SUCCESS) {
933+        info.isP2pGo = groupInfo.IsGroupOwner();
934+        DeviceInfo2Cj(groupInfo.GetOwner(), info.ownerInfo);
935+        info.passphrase = MallocCString(groupInfo.GetPassphrase());
936+        info.interfaceName = MallocCString(groupInfo.GetInterface());
937+        info.groupName = MallocCString(groupInfo.GetGroupName());
938+        info.goIpAddress = MallocCString(groupInfo.GetGoIpAddress());
939+        info.networkId = groupInfo.GetNetworkId();
940+        info.frequency = groupInfo.GetFrequency();
941+        info.clientSize = 0;
942+        if (!groupInfo.IsClientDevicesEmpty()) {
943+            const std::vector<OHOS::Wifi::WifiP2pDevice>& vecDevices = groupInfo.GetClientDevices();
944+            int64_t size = static_cast<int64_t>(vecDevices.size());
945+            info.clientDevices = static_cast<CWifiP2pDevice *>(malloc(sizeof(CWifiP2pDevice) * size));
946+            if (info.clientDevices != nullptr) {
947+                info.clientSize = size;
948+                uint32_t idx = 0;
949+                for (auto& each : vecDevices) {
950+                    CWifiP2pDevice device;
951+                    DeviceInfo2Cj(each, device);
952+                    info.clientDevices[idx] = device;
953+                    idx++;
954+                }
955+            }
956+        }
957+    }
958+    return code;
959+}
960+
961+WifiP2pDeviceArr CJ_GetP2pPeerDevices(int32_t &ret)
962+{
963+    WifiP2pDeviceArr arr{.head = nullptr, .size = 0};
964+    if (cjWifiP2pPtr == nullptr) {
965+        ret = WIFI_OPT_FAILED;
966+        return arr;
967+    }
968+    std::vector<WifiP2pDevice> vecP2pDevices;
969+    ret = cjWifiP2pPtr->QueryP2pDevices(vecP2pDevices);
970+    int64_t size = static_cast<int64_t>(vecP2pDevices.size());
971+    WIFI_LOGI("GetP2pDeviceList, size: %{public}d", static_cast<int>(size));
972+
973+    if (ret == WIFI_OPT_SUCCESS && size > 0) {
974+        arr.head = static_cast<CWifiP2pDevice *>(malloc(sizeof(CWifiP2pDevice) * size));
975+        if (arr.head == nullptr) {
976+            ret = WIFI_OPT_FAILED;
977+            return arr;
978+        }
979+        arr.size = size;
980+
981+        uint32_t idx = 0;
982+        for (auto& each : vecP2pDevices) {
983+            CWifiP2pDevice device;
984+            DeviceInfo2Cj(each, device);
985+            arr.head[idx] = device;
986+            idx++;
987+        }
988+    }
989+    return arr;
990+}
991+
992+int32_t CJ_GetP2pLocalDevice(CWifiP2pDevice &info)
993+{
994+    if (cjWifiP2pPtr == nullptr) {
995+        return WIFI_OPT_FAILED;
996+    }
997+    WifiP2pDevice deviceInfo;
998+    ErrCode code = cjWifiP2pPtr->QueryP2pLocalDevice(deviceInfo);
999+    if (code == WIFI_OPT_SUCCESS) {
1000+        DeviceInfo2Cj(deviceInfo, info);
1001+    }
1002+    return code;
1003+}
1004+
1005+int32_t CJ_CreateGroup(CWifiP2PConfig &cfg)
1006+{
1007+    if (cjWifiP2pPtr == nullptr) {
1008+        return WIFI_OPT_FAILED;
1009+    }
1010+    WifiP2pConfig config;
1011+    CjWifiP2PConfig2C(cfg, config);
1012+    return cjWifiP2pPtr->CreateGroup(config);
1013+}
1014+
1015+int32_t CJ_GetLinkedInfo(CWifiLinkedInfo &info)
1016+{
1017+    if (cjWifiDevicePtr == nullptr) {
1018+        return WIFI_OPT_FAILED;
1019+    }
1020+    WifiLinkedInfo linkedInfo;
1021+    ErrCode code = cjWifiDevicePtr->GetLinkedInfo(linkedInfo);
1022+    if (code == WIFI_OPT_SUCCESS) {
1023+        info.ssid = MallocCString(linkedInfo.ssid);
1024+        info.bssid = MallocCString(linkedInfo.bssid);
1025+        info.rssi = linkedInfo.rssi;
1026+        info.band = linkedInfo.band;
1027+        info.linkSpeed = linkedInfo.linkSpeed;
1028+        info.frequency = linkedInfo.frequency;
1029+        info.isHidden = linkedInfo.ifHiddenSSID;
1030+        info.isRestricted = linkedInfo.isDataRestricted;
1031+        info.macAddress = MallocCString(linkedInfo.macAddress);
1032+        info.macType = linkedInfo.macType;
1033+        info.ipAddress = linkedInfo.ipAddress;
1034+        info.connState = static_cast<int32_t>(linkedInfo.connState);
1035+        info.wifiStandard = linkedInfo.wifiStandard;
1036+        info.maxSupportedRxLinkSpeed = linkedInfo.maxSupportedRxLinkSpeed;
1037+        info.maxSupportedTxLinkSpeed = linkedInfo.maxSupportedTxLinkSpeed;
1038+        info.rxLinkSpeed = linkedInfo.rxLinkSpeed;
1039+        info.channelWidth = static_cast<int32_t>(linkedInfo.channelWidth);
1040+        info.supportedWifiCategory = static_cast<int32_t>(linkedInfo.supportedWifiCategory);
1041+        info.isHiLinkNetwork = linkedInfo.isHiLinkNetwork;
1042+    }
1043+    return code;
1044+}
1045+
1046+int32_t CJ_AddCandidateConfig(CWifiDeviceConfig cfg, int32_t &ret)
1047+{
1048+    if (cjWifiDevicePtr == nullptr) {
1049+        return WIFI_OPT_FAILED;
1050+    }
1051+
1052+    WifiDeviceConfig config;
1053+
1054+    config.ssid = std::string(cfg.ssid);
1055+    config.preSharedKey = std::string(cfg.preSharedKey);
1056+    SecTypeCj type = SecTypeCj(cfg.securityType);
1057+    if (cfg.bssid != nullptr) {
1058+        config.bssid = std::string(cfg.bssid);
1059+    }
1060+    config.bssidType = cfg.bssidType;
1061+    config.hiddenSSID = cfg.isHiddenSsid;
1062+    ConvertEncryptionMode(type, config.keyMgmt);
1063+    ProcessPassphrase(type, config);
1064+    config.wifiPrivacySetting = WifiPrivacyConfig::RANDOMMAC;
1065+
1066+    if (!cfg.eapConfig.isNone && (type == SecTypeCj::SEC_TYPE_EAP || type == SecTypeCj::SEC_TYPE_EAP_SUITE_B)) {
1067+        config.wifiEapConfig.eap = EapMethod2Str(cfg.eapConfig.eapMethod);
1068+        config.wifiEapConfig.phase2Method = Phase2Method(cfg.eapConfig.phase2Method);
1069+        config.wifiEapConfig.identity = std::string(cfg.eapConfig.identity);
1070+        config.wifiEapConfig.anonymousIdentity = std::string(cfg.eapConfig.anonymousIdentity);
1071+        config.wifiEapConfig.password = std::string(cfg.eapConfig.password);
1072+        config.wifiEapConfig.caCertAlias = std::string(cfg.eapConfig.caCertAlias);
1073+        config.wifiEapConfig.caCertPath = std::string(cfg.eapConfig.caPath);
1074+        config.wifiEapConfig.clientCert = std::string(cfg.eapConfig.clientCertAlias);
1075+        config.wifiEapConfig.privateKey = std::string(cfg.eapConfig.clientCertAlias);
1076+        config.wifiEapConfig.certEntry = std::vector<uint8_t>(cfg.eapConfig.certEntry.head, cfg.eapConfig.certEntry.head + cfg.eapConfig.certEntry.size);
1077+        if (strncpy_s(config.wifiEapConfig.certPassword, sizeof(config.wifiEapConfig.certPassword),
1078+            cfg.eapConfig.certPassword, strlen(cfg.eapConfig.certPassword)) != EOK) {
1079+            WIFI_LOGE("%{public}s: failed to copy", __func__);
1080+        }
1081+        config.wifiEapConfig.altSubjectMatch = std::string(cfg.eapConfig.altSubjectMatch);
1082+        config.wifiEapConfig.domainSuffixMatch = std::string(cfg.eapConfig.domainSuffixMatch);
1083+        config.wifiEapConfig.realm = std::string(cfg.eapConfig.realm);
1084+        config.wifiEapConfig.plmn = std::string(cfg.eapConfig.plmn);
1085+        config.wifiEapConfig.eapSubId = cfg.eapConfig.eapSubId;
1086+    }
1087+    if (!cfg.wapiConfig.isNone && (type == SecTypeCj::SEC_TYPE_WAPI_CERT || type == SecTypeCj::SEC_TYPE_WAPI_PSK)) {
1088+        config.wifiWapiConfig.wapiPskType = cfg.wapiConfig.wapiPskType;
1089+        config.wifiWapiConfig.wapiAsCertData = MallocCString(cfg.wapiConfig.wapiAsCert);
1090+        config.wifiWapiConfig.wapiUserCertData = MallocCString(cfg.wapiConfig.wapiUserCert);
1091+    }
1092+
1093+    ErrCode code = cjWifiDevicePtr->AddDeviceConfig(config, ret, true);
1094+    if (ret < 0 || code != WIFI_OPT_SUCCESS) {
1095+        WIFI_LOGE("Add candidate device config failed: %{public}d", static_cast<int>(code));
1096+        ret = -1;
1097+    }
1098+    return code;
1099+}
1100+
1101+WifiDeviceConfigArr CJ_GetCandidateConfigs(int32_t &code)
1102+{
1103+    WifiDeviceConfigArr arr{.head = nullptr, .size = 0};
1104+    if (cjWifiDevicePtr == nullptr) {
1105+        code = WIFI_OPT_FAILED;
1106+        return arr;
1107+    }
1108+    std::vector<WifiDeviceConfig> vecDeviceConfigs;
1109+    code = cjWifiDevicePtr->GetDeviceConfigs(vecDeviceConfigs, true);
1110+    int64_t size = static_cast<int64_t>(vecDeviceConfigs.size());
1111+    if (code == WIFI_OPT_SUCCESS && size > 0) {
1112+        WIFI_LOGI("Get candidate device configs size: %{public}zu", vecDeviceConfigs.size());
1113+        // transform
1114+        arr.head = static_cast<CWifiDeviceConfig *>(malloc(sizeof(CWifiDeviceConfig) * size));
1115+        if (arr.head == nullptr) {
1116+            code = WIFI_OPT_FAILED;
1117+            return arr;
1118+        }
1119+        arr.size = size;
1120+        for(int64_t i = 0; i < size; i++) {
1121+            CWifiDeviceConfig cfg;
1122+            DeviceConfig2C(vecDeviceConfigs[i], cfg);
1123+            arr.head[i] = cfg;
1124+        }
1125+    }
1126+    return arr;
1127+}
1128+
1129+int32_t CJ_WifiOn(char *type, int64_t id)
1130+{
1131+    return 0;
1132+}
1133+
1134+int32_t CJ_WifiOff(char* type)
1135+{
1136+    return 0;
1137+}
1138+
1139+}
1140+}
1141\ No newline at end of file
1142-- 
11432.34.1
1144
1145