• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright (c) 2023-2025 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 #include "wifi_manager_addon.h"
16 
17 #include "edm_constants.h"
18 #include "edm_log.h"
19 #include "message_parcel_utils.h"
20 #include "securec.h"
21 
22 #include "napi_edm_adapter.h"
23 using namespace OHOS::EDM;
24 
CreateWifiSecurityTypeObject(napi_env env,napi_value value)25 void WifiManagerAddon::CreateWifiSecurityTypeObject(napi_env env, napi_value value)
26 {
27     napi_value nInvalid;
28     NAPI_CALL_RETURN_VOID(env, napi_create_int32(env, static_cast<int32_t>(SecurityType::SEC_TYPE_INVALID), &nInvalid));
29     NAPI_CALL_RETURN_VOID(env, napi_set_named_property(env, value, "WIFI_SEC_TYPE_INVALID", nInvalid));
30     napi_value nOpen;
31     NAPI_CALL_RETURN_VOID(env, napi_create_int32(env, static_cast<int32_t>(SecurityType::SEC_TYPE_OPEN), &nOpen));
32     NAPI_CALL_RETURN_VOID(env, napi_set_named_property(env, value, "WIFI_SEC_TYPE_OPEN", nOpen));
33     napi_value nWep;
34     NAPI_CALL_RETURN_VOID(env, napi_create_int32(env, static_cast<int32_t>(SecurityType::SEC_TYPE_WEP), &nWep));
35     NAPI_CALL_RETURN_VOID(env, napi_set_named_property(env, value, "WIFI_SEC_TYPE_WEP", nWep));
36     napi_value nPsk;
37     NAPI_CALL_RETURN_VOID(env, napi_create_int32(env, static_cast<int32_t>(SecurityType::SEC_TYPE_PSK), &nPsk));
38     NAPI_CALL_RETURN_VOID(env, napi_set_named_property(env, value, "WIFI_SEC_TYPE_PSK", nPsk));
39     napi_value nSae;
40     NAPI_CALL_RETURN_VOID(env, napi_create_int32(env, static_cast<int32_t>(SecurityType::SEC_TYPE_SAE), &nSae));
41     NAPI_CALL_RETURN_VOID(env, napi_set_named_property(env, value, "WIFI_SEC_TYPE_SAE", nSae));
42     napi_value nEap;
43     NAPI_CALL_RETURN_VOID(env, napi_create_int32(env, static_cast<int32_t>(SecurityType::SEC_TYPE_EAP), &nEap));
44     NAPI_CALL_RETURN_VOID(env, napi_set_named_property(env, value, "WIFI_SEC_TYPE_EAP", nEap));
45     napi_value nEapSuiteB;
46     NAPI_CALL_RETURN_VOID(env, napi_create_int32(env,
47         static_cast<int32_t>(SecurityType::SEC_TYPE_EAP_SUITE_B), &nEapSuiteB));
48     NAPI_CALL_RETURN_VOID(env, napi_set_named_property(env, value, "WIFI_SEC_TYPE_EAP_SUITE_B", nEapSuiteB));
49     napi_value nOwe;
50     NAPI_CALL_RETURN_VOID(env, napi_create_int32(env, static_cast<int32_t>(SecurityType::SEC_TYPE_OWE), &nOwe));
51     NAPI_CALL_RETURN_VOID(env, napi_set_named_property(env, value, "WIFI_SEC_TYPE_OWE", nOwe));
52     napi_value nWapiCert;
53     NAPI_CALL_RETURN_VOID(env, napi_create_int32(env,
54         static_cast<int32_t>(SecurityType::SEC_TYPE_WAPI_CERT), &nWapiCert));
55     NAPI_CALL_RETURN_VOID(env, napi_set_named_property(env, value, "WIFI_SEC_TYPE_WAPI_CERT", nWapiCert));
56     napi_value nWapiPsk;
57     NAPI_CALL_RETURN_VOID(env, napi_create_int32(env,
58         static_cast<int32_t>(SecurityType::SEC_TYPE_WAPI_PSK), &nWapiPsk));
59     NAPI_CALL_RETURN_VOID(env, napi_set_named_property(env, value, "WIFI_SEC_TYPE_WAPI_PSK", nWapiPsk));
60 }
61 
CreateIpTypeObject(napi_env env,napi_value value)62 void WifiManagerAddon::CreateIpTypeObject(napi_env env, napi_value value)
63 {
64     napi_value nStatic;
65     NAPI_CALL_RETURN_VOID(env, napi_create_int32(env, static_cast<int32_t>(IpType::STATIC), &nStatic));
66     NAPI_CALL_RETURN_VOID(env, napi_set_named_property(env, value, "STATIC", nStatic));
67     napi_value nDhcp;
68     NAPI_CALL_RETURN_VOID(env, napi_create_int32(env, static_cast<int32_t>(IpType::DHCP), &nDhcp));
69     NAPI_CALL_RETURN_VOID(env, napi_set_named_property(env, value, "DHCP", nDhcp));
70     napi_value nUnknown;
71     NAPI_CALL_RETURN_VOID(env, napi_create_int32(env,
72         static_cast<int32_t>(IpType::UNKNOWN), &nUnknown));
73     NAPI_CALL_RETURN_VOID(env, napi_set_named_property(env, value, "UNKNOWN", nUnknown));
74 }
75 
CreateEapMethodObject(napi_env env,napi_value value)76 void WifiManagerAddon::CreateEapMethodObject(napi_env env, napi_value value)
77 {
78     napi_value nNone;
79     NAPI_CALL_RETURN_VOID(env, napi_create_int32(env, static_cast<int32_t>(EapMethod::EAP_NONE), &nNone));
80     NAPI_CALL_RETURN_VOID(env, napi_set_named_property(env, value, "EAP_NONE", nNone));
81     napi_value nPeap;
82     NAPI_CALL_RETURN_VOID(env, napi_create_int32(env, static_cast<int32_t>(EapMethod::EAP_PEAP), &nPeap));
83     NAPI_CALL_RETURN_VOID(env, napi_set_named_property(env, value, "EAP_PEAP", nPeap));
84     napi_value nTls;
85     NAPI_CALL_RETURN_VOID(env, napi_create_int32(env, static_cast<int32_t>(EapMethod::EAP_TLS), &nTls));
86     NAPI_CALL_RETURN_VOID(env, napi_set_named_property(env, value, "EAP_TLS", nTls));
87     napi_value nTtls;
88     NAPI_CALL_RETURN_VOID(env, napi_create_int32(env, static_cast<int32_t>(EapMethod::EAP_TTLS), &nTtls));
89     NAPI_CALL_RETURN_VOID(env, napi_set_named_property(env, value, "EAP_TTLS", nTtls));
90     napi_value nPwd;
91     NAPI_CALL_RETURN_VOID(env, napi_create_int32(env, static_cast<int32_t>(EapMethod::EAP_PWD), &nPwd));
92     NAPI_CALL_RETURN_VOID(env, napi_set_named_property(env, value, "EAP_PWD", nPwd));
93     napi_value nSim;
94     NAPI_CALL_RETURN_VOID(env, napi_create_int32(env, static_cast<int32_t>(EapMethod::EAP_SIM), &nSim));
95     NAPI_CALL_RETURN_VOID(env, napi_set_named_property(env, value, "EAP_SIM", nSim));
96     napi_value nAka;
97     NAPI_CALL_RETURN_VOID(env, napi_create_int32(env, static_cast<int32_t>(EapMethod::EAP_AKA), &nAka));
98     NAPI_CALL_RETURN_VOID(env, napi_set_named_property(env, value, "EAP_AKA", nAka));
99     napi_value nAkaPrime;
100     NAPI_CALL_RETURN_VOID(env, napi_create_int32(env, static_cast<int32_t>(EapMethod::EAP_AKA_PRIME), &nAkaPrime));
101     NAPI_CALL_RETURN_VOID(env, napi_set_named_property(env, value, "EAP_AKA_PRIME", nAkaPrime));
102     napi_value nUnauthTls;
103     NAPI_CALL_RETURN_VOID(env, napi_create_int32(env, static_cast<int32_t>(EapMethod::EAP_UNAUTH_TLS), &nUnauthTls));
104     NAPI_CALL_RETURN_VOID(env, napi_set_named_property(env, value, "EAP_UNAUTH_TLS", nUnauthTls));
105 }
106 
CreatePhase2MethodObject(napi_env env,napi_value value)107 void WifiManagerAddon::CreatePhase2MethodObject(napi_env env, napi_value value)
108 {
109 #ifdef WIFI_EDM_ENABLE
110     napi_value nNone;
111     NAPI_CALL_RETURN_VOID(env, napi_create_int32(env, static_cast<int32_t>(Wifi::Phase2Method::NONE), &nNone));
112     NAPI_CALL_RETURN_VOID(env, napi_set_named_property(env, value, "PHASE2_NONE", nNone));
113     napi_value nPap;
114     NAPI_CALL_RETURN_VOID(env, napi_create_int32(env, static_cast<int32_t>(Wifi::Phase2Method::PAP), &nPap));
115     NAPI_CALL_RETURN_VOID(env, napi_set_named_property(env, value, "PHASE2_PAP", nPap));
116     napi_value nMSChap;
117     NAPI_CALL_RETURN_VOID(env, napi_create_int32(env, static_cast<int32_t>(Wifi::Phase2Method::MSCHAP), &nMSChap));
118     NAPI_CALL_RETURN_VOID(env, napi_set_named_property(env, value, "PHASE2_MSCHAP", nMSChap));
119     napi_value nMSChapV2;
120     NAPI_CALL_RETURN_VOID(env, napi_create_int32(env, static_cast<int32_t>(Wifi::Phase2Method::MSCHAPV2), &nMSChapV2));
121     NAPI_CALL_RETURN_VOID(env, napi_set_named_property(env, value, "PHASE2_MSCHAPV2", nMSChapV2));
122     napi_value nGtc;
123     NAPI_CALL_RETURN_VOID(env, napi_create_int32(env, static_cast<int32_t>(Wifi::Phase2Method::GTC), &nGtc));
124     NAPI_CALL_RETURN_VOID(env, napi_set_named_property(env, value, "PHASE2_GTC", nGtc));
125     napi_value nSim;
126     NAPI_CALL_RETURN_VOID(env, napi_create_int32(env, static_cast<int32_t>(Wifi::Phase2Method::SIM), &nSim));
127     NAPI_CALL_RETURN_VOID(env, napi_set_named_property(env, value, "PHASE2_SIM", nSim));
128     napi_value nAka;
129     NAPI_CALL_RETURN_VOID(env, napi_create_int32(env, static_cast<int32_t>(Wifi::Phase2Method::AKA), &nAka));
130     NAPI_CALL_RETURN_VOID(env, napi_set_named_property(env, value, "PHASE2_AKA", nAka));
131     napi_value nAkaPrime;
132     NAPI_CALL_RETURN_VOID(env, napi_create_int32(env, static_cast<int32_t>(Wifi::Phase2Method::AKA_PRIME), &nAkaPrime));
133     NAPI_CALL_RETURN_VOID(env, napi_set_named_property(env, value, "PHASE2_AKA_PRIME", nAkaPrime));
134 #endif
135 }
136 
Init(napi_env env,napi_value exports)137 napi_value WifiManagerAddon::Init(napi_env env, napi_value exports)
138 {
139     napi_value nWifiSecurityType = nullptr;
140     NAPI_CALL(env, napi_create_object(env, &nWifiSecurityType));
141     CreateWifiSecurityTypeObject(env, nWifiSecurityType);
142 
143     napi_value nIpType = nullptr;
144     NAPI_CALL(env, napi_create_object(env, &nIpType));
145     CreateIpTypeObject(env, nIpType);
146 
147     napi_value nEapMethod = nullptr;
148     NAPI_CALL(env, napi_create_object(env, &nEapMethod));
149     CreateEapMethodObject(env, nEapMethod);
150 
151     napi_value nPhase2Method = nullptr;
152     NAPI_CALL(env, napi_create_object(env, &nPhase2Method));
153     CreatePhase2MethodObject(env, nPhase2Method);
154 
155     napi_property_descriptor property[] = {
156         DECLARE_NAPI_FUNCTION("isWifiActive", IsWifiActive),
157         DECLARE_NAPI_FUNCTION("setWifiProfile", SetWifiProfile),
158         DECLARE_NAPI_FUNCTION("setWifiDisabled", SetWifiDisabled),
159         DECLARE_NAPI_FUNCTION("isWifiDisabled", IsWifiDisabled),
160         DECLARE_NAPI_FUNCTION("isWifiActiveSync", IsWifiActiveSync),
161         DECLARE_NAPI_FUNCTION("setWifiProfileSync", SetWifiProfileSync),
162         DECLARE_NAPI_FUNCTION("addAllowedWifiList", AddAllowedWifiList),
163         DECLARE_NAPI_FUNCTION("removeAllowedWifiList", RemoveAllowedWifiList),
164         DECLARE_NAPI_FUNCTION("getAllowedWifiList", GetAllowedWifiList),
165         DECLARE_NAPI_FUNCTION("addDisallowedWifiList", AddDisallowedWifiList),
166         DECLARE_NAPI_FUNCTION("removeDisallowedWifiList", RemoveDisallowedWifiList),
167         DECLARE_NAPI_FUNCTION("getDisallowedWifiList", GetDisallowedWifiList),
168         DECLARE_NAPI_FUNCTION("turnOnWifi", TurnOnWifi),
169         DECLARE_NAPI_FUNCTION("turnOffWifi", TurnOffWifi),
170 
171         DECLARE_NAPI_PROPERTY("WifiSecurityType", nWifiSecurityType),
172         DECLARE_NAPI_PROPERTY("IpType", nIpType),
173         DECLARE_NAPI_PROPERTY("EapMethod", nEapMethod),
174         DECLARE_NAPI_PROPERTY("Phase2Method", nPhase2Method)
175     };
176     NAPI_CALL(env, napi_define_properties(env, exports, sizeof(property) / sizeof(property[0]), property));
177     return exports;
178 }
179 
IsWifiActive(napi_env env,napi_callback_info info)180 napi_value WifiManagerAddon::IsWifiActive(napi_env env, napi_callback_info info)
181 {
182     return IsWifiActiveHandler(env, info, NativeIsWifiActive);
183 }
184 
SetWifiDisabled(napi_env env,napi_callback_info info)185 napi_value WifiManagerAddon::SetWifiDisabled(napi_env env, napi_callback_info info)
186 {
187     AddonMethodSign addonMethodSign;
188     addonMethodSign.name = "setWifiDisabled";
189     addonMethodSign.argsType = {EdmAddonCommonType::ELEMENT, EdmAddonCommonType::BOOLEAN};
190     addonMethodSign.methodAttribute = MethodAttribute::HANDLE;
191     addonMethodSign.apiVersionTag = EdmConstants::PERMISSION_TAG_VERSION_11;
192     AdapterAddonData adapterAddonData{};
193     napi_value result = JsObjectToData(env, info, addonMethodSign, &adapterAddonData);
194     if (result == nullptr) {
195         return nullptr;
196     }
197     int32_t ret = WifiManagerProxy::GetWifiManagerProxy()->SetWifiDisabled(adapterAddonData.data);
198     if (FAILED(ret)) {
199         napi_throw(env, CreateError(env, ret));
200     }
201     return nullptr;
202 }
203 
IsWifiDisabled(napi_env env,napi_callback_info info)204 napi_value WifiManagerAddon::IsWifiDisabled(napi_env env, napi_callback_info info)
205 {
206     AddonMethodSign addonMethodSign;
207     addonMethodSign.name = "isWifiDisabled";
208     addonMethodSign.methodAttribute = MethodAttribute::GET;
209     addonMethodSign.argsType = {EdmAddonCommonType::ELEMENT_NULL};
210     addonMethodSign.apiVersionTag = EdmConstants::PERMISSION_TAG_VERSION_11;
211     AdapterAddonData adapterAddonData{};
212     napi_value result = JsObjectToData(env, info, addonMethodSign, &adapterAddonData);
213     if (result == nullptr) {
214         return nullptr;
215     }
216     int32_t ret = ERR_OK;
217     bool isDisabled = false;
218     ret = WifiManagerProxy::GetWifiManagerProxy()->IsWifiDisabled(adapterAddonData.data, isDisabled);
219     if (FAILED(ret)) {
220         napi_throw(env, CreateError(env, ret));
221         return nullptr;
222     }
223     result = nullptr;
224     NAPI_CALL(env, napi_get_boolean(env, isDisabled, &result));
225     return result;
226 }
227 
SetWifiProfile(napi_env env,napi_callback_info info)228 napi_value WifiManagerAddon::SetWifiProfile(napi_env env, napi_callback_info info)
229 {
230     return SetWifiProfileHandler(env, info, NativeSetWifiProfile);
231 }
232 
AddAllowedWifiList(napi_env env,napi_callback_info info)233 napi_value WifiManagerAddon::AddAllowedWifiList(napi_env env, napi_callback_info info)
234 {
235     EDMLOGI("WifiManagerAddon::AddAllowedWifiList called");
236     return AddOrRemoveAllowedWifiList(env, info, true);
237 }
238 
RemoveAllowedWifiList(napi_env env,napi_callback_info info)239 napi_value WifiManagerAddon::RemoveAllowedWifiList(napi_env env, napi_callback_info info)
240 {
241     EDMLOGI("WifiManagerAddon::RemoveAllowedWifiList called");
242     return AddOrRemoveAllowedWifiList(env, info, false);
243 }
244 
AddOrRemoveAllowedWifiList(napi_env env,napi_callback_info info,bool isAdd)245 napi_value WifiManagerAddon::AddOrRemoveAllowedWifiList(napi_env env, napi_callback_info info, bool isAdd)
246 {
247 #ifdef WIFI_EDM_ENABLE
248     auto convertWifiList2Data = [](napi_env env, napi_value argv, MessageParcel &data,
249         const AddonMethodSign &methodSign) {
250         std::vector<WifiId> wifiIds;
251         if (!ParseWifiInfoArray(env, wifiIds, argv, true)) {
252             EDMLOGE("parameter type parse error");
253             return false;
254         }
255         data.WriteUint32(wifiIds.size());
256         for (const auto &wifiId : wifiIds) {
257             if (!wifiId.Marshalling(data)) {
258                 EDMLOGE("wifiManagerProxy AddOrRemoveAllowedWifiList: write parcel failed!");
259                 return false;
260             }
261         }
262         return true;
263     };
264     AddonMethodSign addonMethodSign;
265     addonMethodSign.argsType = {EdmAddonCommonType::ELEMENT, EdmAddonCommonType::CUSTOM};
266     addonMethodSign.argsConvert = {nullptr, convertWifiList2Data};
267     addonMethodSign.methodAttribute = MethodAttribute::HANDLE;
268     addonMethodSign.name = (isAdd ? "addAllowedWifiList" : "removeAllowedWifiList");
269     AdapterAddonData adapterAddonData{};
270     napi_value result = JsObjectToData(env, info, addonMethodSign, &adapterAddonData);
271     if (result == nullptr) {
272         return nullptr;
273     }
274     auto wifiManagerProxy = WifiManagerProxy::GetWifiManagerProxy();
275     if (wifiManagerProxy == nullptr) {
276         EDMLOGE("can not get usbManagerProxy");
277         return nullptr;
278     }
279     int32_t ret = ERR_OK;
280     if (isAdd) {
281         ret = wifiManagerProxy->AddOrRemoveWifiList(adapterAddonData.data,
282             FuncOperateType::SET, EdmInterfaceCode::ALLOWED_WIFI_LIST);
283     } else {
284         ret = wifiManagerProxy->AddOrRemoveWifiList(adapterAddonData.data,
285             FuncOperateType::REMOVE, EdmInterfaceCode::ALLOWED_WIFI_LIST);
286     }
287     if (FAILED(ret)) {
288         napi_throw(env, CreateError(env, ret));
289     }
290 #else
291     EDMLOGW("WifiManagerAddon::AddOrRemoveAllowedWifiList Unsupported Capabilities.");
292     napi_throw(env, CreateError(env, EdmReturnErrCode::INTERFACE_UNSUPPORTED));
293 #endif
294     return nullptr;
295 }
296 
ParseWifiInfoArray(napi_env env,std::vector<WifiId> & wifiIds,napi_value object,bool isAllowed)297 bool WifiManagerAddon::ParseWifiInfoArray(napi_env env, std::vector<WifiId> &wifiIds, napi_value object, bool isAllowed)
298 {
299     bool isArray = false;
300     napi_is_array(env, object, &isArray);
301     if (!isArray) {
302         return false;
303     }
304     uint32_t arrayLength = 0;
305     napi_get_array_length(env, object, &arrayLength);
306     for (uint32_t i = 0; i < arrayLength; i++) {
307         napi_value value = nullptr;
308         napi_get_element(env, object, i, &value);
309         napi_valuetype valueType = napi_undefined;
310         napi_typeof(env, value, &valueType);
311         if (valueType != napi_object) {
312             wifiIds.clear();
313             return false;
314         }
315         WifiId wifiId;
316         if (!GetWifiIdFromNAPI(env, value, wifiId, isAllowed)) {
317             wifiIds.clear();
318             return false;
319         }
320         wifiIds.push_back(wifiId);
321     }
322     return true;
323 }
324 
GetWifiIdFromNAPI(napi_env env,napi_value value,WifiId & wifiId,bool isAllowed)325 bool WifiManagerAddon::GetWifiIdFromNAPI(napi_env env, napi_value value, WifiId &wifiId, bool isAllowed)
326 {
327     std::string ssid;
328     if (!JsObjectToString(env, value, "ssid", true, ssid)) {
329         EDMLOGE("AddOrRemoveWifiList ssid parse error!");
330         return false;
331     }
332     if (ssid.empty() || ssid.size() > EdmConstants::WIFI_SSID_MAX_LENGTH) {
333         EDMLOGE("AddOrRemoveWifiList ssid is empty or too large!");
334         return false;
335     }
336     std::string bssid;
337     if (!JsObjectToString(env, value, "bssid", isAllowed, bssid)) {
338         EDMLOGE("AddOrRemoveAllowedWifiList bssid parse error!");
339         return false;
340     }
341     if (isAllowed && bssid.empty()) {
342         EDMLOGE("AddOrRemoveAllowedWifiList bssid parse error!");
343         return false;
344     }
345     if (!bssid.empty() && bssid.size() != EdmConstants::WIFI_BSSID_LENGTH) {
346         EDMLOGE("AddOrRemoveAllowedWifiList bssid parse error!");
347         return false;
348     }
349     wifiId.SetSsid(ssid);
350     wifiId.SetBssid(bssid);
351     return true;
352 }
353 
GetWifiList(napi_env env,napi_callback_info info,EdmInterfaceCode policyCode)354 napi_value WifiManagerAddon::GetWifiList(napi_env env, napi_callback_info info, EdmInterfaceCode policyCode)
355 {
356 #ifdef WIFI_EDM_ENABLE
357     AddonMethodSign addonMethodSign;
358     addonMethodSign.name = "getDisallowedWifiList";
359     if (policyCode == EdmInterfaceCode::ALLOWED_WIFI_LIST) {
360         addonMethodSign.name = "getAllowedWifiList";
361     }
362     addonMethodSign.argsType = {EdmAddonCommonType::ELEMENT};
363     addonMethodSign.methodAttribute = MethodAttribute::GET;
364     AdapterAddonData adapterAddonData{};
365     napi_value result = JsObjectToData(env, info, addonMethodSign, &adapterAddonData);
366     if (result == nullptr) {
367         return nullptr;
368     }
369     auto wifiManagerProxy = WifiManagerProxy::GetWifiManagerProxy();
370     if (wifiManagerProxy == nullptr) {
371         EDMLOGE("can not get wifiManagerProxy");
372         return nullptr;
373     }
374     std::vector<WifiId> wifiIds;
375     int32_t ret = wifiManagerProxy->GetWifiList(adapterAddonData.data, wifiIds, policyCode);
376     EDMLOGI("WifiManagerAddon::GetWifiList wifiIds return size: %{public}zu", wifiIds.size());
377     if (FAILED(ret)) {
378         napi_throw(env, CreateError(env, ret));
379         return nullptr;
380     }
381     napi_value jsList = nullptr;
382     NAPI_CALL(env, napi_create_array_with_length(env, wifiIds.size(), &jsList));
383     for (size_t i = 0; i < wifiIds.size(); i++) {
384         napi_value item = WifiIdToJsObj(env, wifiIds[i]);
385         NAPI_CALL(env, napi_set_element(env, jsList, i, item));
386     }
387     return jsList;
388 #else
389     EDMLOGW("WifiManagerAddon::GetWifiList Unsupported Capabilities.");
390     napi_throw(env, CreateError(env, EdmReturnErrCode::INTERFACE_UNSUPPORTED));
391     return nullptr;
392 #endif
393 }
394 
GetAllowedWifiList(napi_env env,napi_callback_info info)395 napi_value WifiManagerAddon::GetAllowedWifiList(napi_env env, napi_callback_info info)
396 {
397     return GetWifiList(env, info, EdmInterfaceCode::ALLOWED_WIFI_LIST);
398 }
399 
AddDisallowedWifiList(napi_env env,napi_callback_info info)400 napi_value WifiManagerAddon::AddDisallowedWifiList(napi_env env, napi_callback_info info)
401 {
402     EDMLOGI("WifiManagerAddon::AddDisallowedWifiList called");
403     return AddOrRemoveDisallowedWifiList(env, info, true);
404 }
405 
RemoveDisallowedWifiList(napi_env env,napi_callback_info info)406 napi_value WifiManagerAddon::RemoveDisallowedWifiList(napi_env env, napi_callback_info info)
407 {
408     EDMLOGI("WifiManagerAddon::RemoveDisallowedWifiList called");
409     return AddOrRemoveDisallowedWifiList(env, info, false);
410 }
411 
AddOrRemoveDisallowedWifiList(napi_env env,napi_callback_info info,bool isAdd)412 napi_value WifiManagerAddon::AddOrRemoveDisallowedWifiList(napi_env env, napi_callback_info info, bool isAdd)
413 {
414 #ifdef WIFI_EDM_ENABLE
415     auto convertWifiList2Data = [](napi_env env, napi_value argv, MessageParcel &data,
416         const AddonMethodSign &methodSign) {
417         std::vector<WifiId> wifiIds;
418         if (!ParseWifiInfoArray(env, wifiIds, argv, false)) {
419             EDMLOGE("parameter type parse error");
420             return false;
421         }
422         data.WriteUint32(wifiIds.size());
423         for (const auto &wifiId : wifiIds) {
424             if (!wifiId.Marshalling(data)) {
425                 EDMLOGE("wifiManagerProxy AddOrRemoveDisallowedWifiList: write parcel failed!");
426                 return false;
427             }
428         }
429         return true;
430     };
431     AddonMethodSign addonMethodSign;
432     addonMethodSign.argsType = {EdmAddonCommonType::ELEMENT, EdmAddonCommonType::CUSTOM};
433     addonMethodSign.argsConvert = {nullptr, convertWifiList2Data};
434     addonMethodSign.methodAttribute = MethodAttribute::HANDLE;
435     addonMethodSign.name = (isAdd ? "addDisallowedWifiList" : "removeDisallowedWifiList");
436     AdapterAddonData adapterAddonData{};
437     napi_value result = JsObjectToData(env, info, addonMethodSign, &adapterAddonData);
438     if (result == nullptr) {
439         return nullptr;
440     }
441     auto wifiManagerProxy = WifiManagerProxy::GetWifiManagerProxy();
442     if (wifiManagerProxy == nullptr) {
443         EDMLOGE("can not get usbManagerProxy");
444         return nullptr;
445     }
446     int32_t ret = ERR_OK;
447     if (isAdd) {
448         ret = wifiManagerProxy->AddOrRemoveWifiList(adapterAddonData.data,
449             FuncOperateType::SET, EdmInterfaceCode::DISALLOWED_WIFI_LIST);
450     } else {
451         ret = wifiManagerProxy->AddOrRemoveWifiList(adapterAddonData.data,
452             FuncOperateType::REMOVE, EdmInterfaceCode::DISALLOWED_WIFI_LIST);
453     }
454     if (FAILED(ret)) {
455         napi_throw(env, CreateError(env, ret));
456     }
457 #else
458     EDMLOGW("WifiManagerAddon::AddOrRemoveDisallowedWifiList Unsupported Capabilities.");
459     napi_throw(env, CreateError(env, EdmReturnErrCode::INTERFACE_UNSUPPORTED));
460 #endif
461     return nullptr;
462 }
463 
GetDisallowedWifiList(napi_env env,napi_callback_info info)464 napi_value WifiManagerAddon::GetDisallowedWifiList(napi_env env, napi_callback_info info)
465 {
466     return GetWifiList(env, info, EdmInterfaceCode::DISALLOWED_WIFI_LIST);
467 }
468 
WifiIdToJsObj(napi_env env,const WifiId & wifiId)469 napi_value WifiManagerAddon::WifiIdToJsObj(napi_env env, const WifiId &wifiId)
470 {
471     napi_value value = nullptr;
472     NAPI_CALL(env, napi_create_object(env, &value));
473 
474     napi_value ssid = nullptr;
475     NAPI_CALL(env, napi_create_string_utf8(env, wifiId.GetSsid().c_str(), NAPI_AUTO_LENGTH, &ssid));
476     NAPI_CALL(env, napi_set_named_property(env, value, "ssid", ssid));
477 
478     napi_value bssid = nullptr;
479     NAPI_CALL(env, napi_create_string_utf8(env, wifiId.GetBssid().c_str(), NAPI_AUTO_LENGTH, &bssid));
480     NAPI_CALL(env, napi_set_named_property(env, value, "bssid", bssid));
481 
482     return value;
483 }
484 
485 #ifdef WIFI_EDM_ENABLE
NativeSetWifiProfile(napi_env env,void * data)486 void WifiManagerAddon::NativeSetWifiProfile(napi_env env, void *data)
487 {
488     EDMLOGI("NAPI_NativeSetWifiProfile called");
489     if (data == nullptr) {
490         EDMLOGE("data is nullptr");
491         return;
492     }
493     AdapterAddonData *asyncCallbackInfo = static_cast<AdapterAddonData *>(data);
494     auto wifiManagerProxy = WifiManagerProxy::GetWifiManagerProxy();
495     if (wifiManagerProxy == nullptr) {
496         EDMLOGE("can not get WifiManagerProxy");
497         return;
498     }
499     asyncCallbackInfo->ret = wifiManagerProxy->SetWifiProfile(asyncCallbackInfo->data);
500 }
501 #endif
502 
NativeIsWifiActive(napi_env env,void * data)503 void WifiManagerAddon::NativeIsWifiActive(napi_env env, void *data)
504 {
505     EDMLOGI("NAPI_NativeIsWifiActive called");
506     if (data == nullptr) {
507         EDMLOGE("data is nullptr");
508         return;
509     }
510     AdapterAddonData *asyncCallbackInfo = static_cast<AdapterAddonData *>(data);
511     auto wifiManagerProxy = WifiManagerProxy::GetWifiManagerProxy();
512     if (wifiManagerProxy == nullptr) {
513         EDMLOGE("can not get WifiManagerProxy");
514         return;
515     }
516     asyncCallbackInfo->ret = wifiManagerProxy->IsWifiActive(asyncCallbackInfo->data,
517         asyncCallbackInfo->boolRet);
518 }
519 #ifdef WIFI_EDM_ENABLE
JsObjToDeviceConfig(napi_env env,napi_value object,Wifi::WifiDeviceConfig & config,WifiPassword & pwd)520 bool WifiManagerAddon::JsObjToDeviceConfig(napi_env env, napi_value object, Wifi::WifiDeviceConfig &config,
521     WifiPassword &pwd)
522 {
523     int32_t type = static_cast<int32_t>(SecurityType::SEC_TYPE_INVALID);
524     int32_t ipType = static_cast<int32_t>(IpType::UNKNOWN);
525     /* "creatorUid" "disableReason" "randomMacType" "randomMacAddr" is not supported currently */
526     std::tuple<int, bool> charArrayProp = {WIFI_PASSWORD_LEN, true};
527     std::vector<char> ret;
528     if (!JsObjectToString(env, object, "ssid", true, config.ssid) ||
529         !JsObjectToString(env, object, "bssid", false, config.bssid) ||
530         !JsObjectToCharArray(env, object, "preSharedKey", charArrayProp, ret) ||
531         !JsObjectToBool(env, object, "isHiddenSsid", false, config.hiddenSSID) ||
532         !JsObjectToInt(env, object, "securityType", true, type) ||
533         !JsObjectToInt(env, object, "netId", false, config.networkId) ||
534         !JsObjectToInt(env, object, "ipType", false, ipType) ||
535         !ProcessIpType(ipType, env, object, config.wifiIpConfig)) {
536         return false;
537     }
538     if (ret.size() != 0) {
539         pwd.preSharedKey = (char*) malloc(ret.size());
540         if (pwd.preSharedKey == nullptr) {
541             memset_s(ret.data(), ret.size(), '\0', ret.size());
542             return false;
543         }
544         if (strncpy_s(pwd.preSharedKey, ret.size(), ret.data(), ret.size()) != ERR_OK) {
545             memset_s(ret.data(), ret.size(), '\0', ret.size());
546             return false;
547         }
548         memset_s(ret.data(), ret.size(), '\0', ret.size());
549         pwd.preSharedKeySize = ret.size();
550     }
551     if (!ConvertEncryptionMode(type, config, pwd)) {
552         return false;
553     }
554     if (type == static_cast<int32_t>(SecurityType::SEC_TYPE_EAP)) {
555         return ProcessEapConfig(env, object, config.wifiEapConfig, pwd);
556     }
557     return true;
558 }
559 
ConvertEncryptionMode(int32_t securityType,Wifi::WifiDeviceConfig & config,WifiPassword & pwd)560 bool WifiManagerAddon::ConvertEncryptionMode(int32_t securityType, Wifi::WifiDeviceConfig &config, WifiPassword &pwd)
561 {
562     switch (securityType) {
563         case static_cast<int32_t>(SecurityType::SEC_TYPE_OPEN):
564             config.keyMgmt = Wifi::KEY_MGMT_NONE;
565             break;
566         case static_cast<int32_t>(SecurityType::SEC_TYPE_WEP):
567             config.keyMgmt = Wifi::KEY_MGMT_WEP;
568             pwd.wepKey = (char*) malloc((pwd.preSharedKeySize + NAPI_RETURN_ONE) * sizeof(char));
569             if (pwd.wepKey == nullptr) {
570                 return false;
571             }
572             if (strncpy_s(pwd.wepKey, pwd.preSharedKeySize + NAPI_RETURN_ONE,
573                 pwd.preSharedKey, pwd.preSharedKeySize) != ERR_OK) {
574                 return false;
575             }
576             pwd.wepKeySize = pwd.preSharedKeySize;
577             EdmUtils::ClearCharArray(pwd.preSharedKey, pwd.preSharedKeySize);
578             pwd.preSharedKeySize = 0;
579             config.wepTxKeyIndex = 0;
580             break;
581         case static_cast<int32_t>(SecurityType::SEC_TYPE_PSK):
582             config.keyMgmt = Wifi::KEY_MGMT_WPA_PSK;
583             break;
584         case static_cast<int32_t>(SecurityType::SEC_TYPE_SAE):
585             config.keyMgmt = Wifi::KEY_MGMT_SAE;
586             break;
587         case static_cast<int32_t>(SecurityType::SEC_TYPE_EAP):
588             config.keyMgmt = Wifi::KEY_MGMT_EAP;
589             break;
590         default:
591             config.keyMgmt = Wifi::KEY_MGMT_NONE;
592             break;
593     }
594     return true;
595 }
596 
ProcessIpType(int32_t ipType,napi_env env,napi_value object,Wifi::WifiIpConfig & ipConfig)597 bool WifiManagerAddon::ProcessIpType(int32_t ipType, napi_env env, napi_value object, Wifi::WifiIpConfig &ipConfig)
598 {
599     switch (ipType) {
600         case static_cast<int32_t>(IpType::DHCP):
601             ipConfig.assignMethod = Wifi::AssignIpMethod::DHCP;
602             break;
603         case static_cast<int32_t>(IpType::STATIC):
604             ipConfig.assignMethod = Wifi::AssignIpMethod::STATIC;
605             break;
606         default:
607             ipConfig.assignMethod = Wifi::AssignIpMethod::UNASSIGNED;
608             break;
609     }
610     if (ipType == static_cast<int32_t>(IpType::STATIC) && !ConfigStaticIp(env, object, ipConfig)) {
611         return false;
612     }
613     return true;
614 }
615 
ConfigStaticIp(napi_env env,napi_value object,Wifi::WifiIpConfig & ipConfig)616 bool WifiManagerAddon::ConfigStaticIp(napi_env env, napi_value object, Wifi::WifiIpConfig &ipConfig)
617 {
618     napi_value staticIp;
619     napi_value dnsServers;
620     napi_value primaryDns;
621     napi_value secondDns;
622     if (!GetJsProperty(env, object, "staticIp", staticIp) ||
623         !JsObjectToUint(env, staticIp, "ipAddress", true,
624         ipConfig.staticIpAddress.ipAddress.address.addressIpv4) ||
625         !JsObjectToUint(env, staticIp, "gateway", true,
626         ipConfig.staticIpAddress.gateway.addressIpv4) ||
627         !JsObjectToInt(env, staticIp, "prefixLength", true,
628         ipConfig.staticIpAddress.ipAddress.prefixLength) ||
629         !GetJsProperty(env, staticIp, "dnsServers", dnsServers)) {
630         return false;
631     }
632     ipConfig.staticIpAddress.ipAddress.address.family = 0;
633     uint32_t arrayLength = 0;
634     const uint32_t DNS_NUM = 2;
635     napi_get_array_length(env, dnsServers, &arrayLength);
636     if (arrayLength != DNS_NUM) {
637         EDMLOGI("ConfigStaticIp, It needs two dns servers.");
638         return false;
639     }
640     napi_get_element(env, dnsServers, 0, &primaryDns);
641     napi_get_element(env, dnsServers, 1, &secondDns);
642     napi_get_value_uint32(env, primaryDns, &ipConfig.staticIpAddress.dnsServer1.addressIpv4);
643     napi_get_value_uint32(env, secondDns, &ipConfig.staticIpAddress.dnsServer2.addressIpv4);
644     return true;
645 }
646 
ProcessEapConfig(napi_env env,napi_value object,Wifi::WifiEapConfig & eapConfig,WifiPassword & pwd)647 bool WifiManagerAddon::ProcessEapConfig(napi_env env, napi_value object, Wifi::WifiEapConfig &eapConfig,
648     WifiPassword &pwd)
649 {
650     napi_value napiEap;
651     int32_t eapMethod = static_cast<int32_t>(EapMethod::EAP_NONE);
652     if (!GetJsProperty(env, object, "eapProfile", napiEap) ||
653         !JsObjectToInt(env, napiEap, "eapMethod", true, eapMethod)) {
654         return false;
655     }
656     switch (eapMethod) {
657         case static_cast<int32_t>(EapMethod::EAP_PEAP):
658             ProcessEapPeapConfig(env, napiEap, eapConfig, pwd);
659             break;
660         case static_cast<int32_t>(EapMethod::EAP_TLS):
661             ProcessEapTlsConfig(env, napiEap, eapConfig);
662             break;
663         default:
664             EDMLOGI("EapMethod: %{public}d unsupported", eapMethod);
665             return false;
666     }
667     return true;
668 }
669 
ProcessEapPeapConfig(napi_env env,napi_value object,Wifi::WifiEapConfig & eapConfig,WifiPassword & pwd)670 bool WifiManagerAddon::ProcessEapPeapConfig(napi_env env, napi_value object, Wifi::WifiEapConfig &eapConfig,
671     WifiPassword &pwd)
672 {
673     eapConfig.eap = Wifi::EAP_METHOD_PEAP;
674     int32_t phase2 = static_cast<int32_t>(Wifi::Phase2Method::NONE);
675     std::tuple<int, bool> charArrayProp = {WIFI_PASSWORD_LEN, true};
676     std::vector<char> ret;
677     if (!JsObjectToString(env, object, "identity", true, eapConfig.identity) ||
678         !JsObjectToCharArray(env, object, "password", charArrayProp, ret) ||
679         !JsObjectToInt(env, object, "phase2Method", true, phase2)) {
680         return false;
681     }
682     if (ret.size() != 0) {
683         pwd.password = (char*) malloc(ret.size());
684         if (pwd.password == nullptr) {
685             memset_s(ret.data(), ret.size(), '\0', ret.size());
686             return false;
687         }
688         if (strncpy_s(pwd.password, ret.size(), ret.data(), ret.size()) != ERR_OK) {
689             memset_s(ret.data(), ret.size(), '\0', ret.size());
690             return false;
691         }
692         memset_s(ret.data(), ret.size(), '\0', ret.size());
693         pwd.preSharedKeySize = ret.size();
694     }
695     MessageParcelUtils::ProcessPhase2Method(phase2, eapConfig);
696     return true;
697 }
698 
ProcessEapTlsConfig(napi_env env,napi_value object,Wifi::WifiEapConfig & eapConfig)699 bool WifiManagerAddon::ProcessEapTlsConfig(napi_env env, napi_value object, Wifi::WifiEapConfig &eapConfig)
700 {
701     eapConfig.eap = Wifi::EAP_METHOD_TLS;
702     std::tuple<int, bool> charArrayProp = {WIFI_PASSWORD_LEN, true};
703     std::vector<char> ret;
704     if (!JsObjectToString(env, object, "identity", true, eapConfig.identity) ||
705         !JsObjectToCharArray(env, object, "certPassword", charArrayProp, ret) ||
706         !JsObjectToU8Vector(env, object, "certEntry", eapConfig.certEntry)) {
707         return false;
708     }
709     if (ret.size() != 0) {
710         if (strncpy_s(eapConfig.certPassword, ret.size(), ret.data(), ret.size()) != ERR_OK) {
711             memset_s(ret.data(), ret.size(), '\0', ret.size());
712             return false;
713         }
714         memset_s(ret.data(), ret.size(), '\0', ret.size());
715     }
716     return true;
717 }
718 #endif
719 
IsWifiActiveSync(napi_env env,napi_callback_info info)720 napi_value WifiManagerAddon::IsWifiActiveSync(napi_env env, napi_callback_info info)
721 {
722     return IsWifiActiveHandler(env, info, nullptr);
723 }
724 
IsWifiActiveHandler(napi_env env,napi_callback_info info,napi_async_execute_callback execute)725 napi_value WifiManagerAddon::IsWifiActiveHandler(napi_env env,
726     napi_callback_info info, napi_async_execute_callback execute)
727 {
728     AddonMethodSign addonMethodSign;
729     addonMethodSign.name = "isWifiActive";
730     addonMethodSign.argsType = {EdmAddonCommonType::ELEMENT};
731     addonMethodSign.methodAttribute = MethodAttribute::GET;
732     addonMethodSign.apiVersionTag = EdmConstants::PERMISSION_TAG_VERSION_12;
733     if (execute != nullptr) {
734         addonMethodSign.apiVersionTag = EdmConstants::PERMISSION_TAG_VERSION_11;
735         return AddonMethodAdapter(env, info, addonMethodSign, execute, NativeBoolCallbackComplete);
736     }
737     AdapterAddonData adapterAddonData{};
738     napi_value result = JsObjectToData(env, info, addonMethodSign, &adapterAddonData);
739     if (result == nullptr) {
740         return nullptr;
741     }
742     auto wifiManagerProxy = WifiManagerProxy::GetWifiManagerProxy();
743     if (wifiManagerProxy == nullptr) {
744         EDMLOGE("can not get WifiManagerProxy");
745         return nullptr;
746     }
747     bool isActive = false;
748     int32_t ret = wifiManagerProxy->IsWifiActive(adapterAddonData.data, isActive);
749     if (FAILED(ret)) {
750         napi_throw(env, CreateError(env, ret));
751         return nullptr;
752     }
753     result = nullptr;
754     NAPI_CALL(env, napi_get_boolean(env, isActive, &result));
755     return result;
756 }
757 
SetWifiProfileSync(napi_env env,napi_callback_info info)758 napi_value WifiManagerAddon::SetWifiProfileSync(napi_env env, napi_callback_info info)
759 {
760     return SetWifiProfileHandler(env, info, nullptr);
761 }
762 
SetWifiProfileHandler(napi_env env,napi_callback_info info,napi_async_execute_callback execute)763 napi_value WifiManagerAddon::SetWifiProfileHandler(napi_env env,
764     napi_callback_info info, napi_async_execute_callback execute)
765 {
766 #ifdef WIFI_EDM_ENABLE
767     auto convertWifiDeviceConfigAndPwd2Data = [](napi_env env, napi_value argv, MessageParcel &data,
768         const AddonMethodSign &methodSign) {
769         Wifi::WifiDeviceConfig config;
770         WifiPassword pwd;
771         bool parseRet = JsObjToDeviceConfig(env, argv, config, pwd);
772         if (!parseRet) {
773             napi_throw(env, CreateError(env, EdmReturnErrCode::PARAM_ERROR, "parameter profile parse error"));
774             return false;
775         }
776         MessageParcelUtils::WriteWifiDeviceConfig(config, data, pwd);
777         return true;
778     };
779     AddonMethodSign addonMethodSign;
780     addonMethodSign.name = "setWifiProfile";
781     addonMethodSign.argsType = {EdmAddonCommonType::ELEMENT, EdmAddonCommonType::CUSTOM};
782     addonMethodSign.argsConvert = {nullptr, convertWifiDeviceConfigAndPwd2Data};
783     addonMethodSign.methodAttribute = MethodAttribute::HANDLE;
784     addonMethodSign.apiVersionTag = EdmConstants::PERMISSION_TAG_VERSION_12;
785     if (execute != nullptr) {
786         addonMethodSign.apiVersionTag = EdmConstants::PERMISSION_TAG_VERSION_11;
787         return AddonMethodAdapter(env, info, addonMethodSign, execute, NativeVoidCallbackComplete);
788     }
789     AdapterAddonData adapterAddonData{};
790     napi_value result = JsObjectToData(env, info, addonMethodSign, &adapterAddonData);
791     if (result == nullptr) {
792         return nullptr;
793     }
794     auto wifiManagerProxy = WifiManagerProxy::GetWifiManagerProxy();
795     if (wifiManagerProxy == nullptr) {
796         EDMLOGE("can not get WifiManagerProxy");
797         return nullptr;
798     }
799     int32_t ret = wifiManagerProxy->SetWifiProfile(adapterAddonData.data);
800     if (FAILED(ret)) {
801         napi_throw(env, CreateError(env, ret));
802     }
803     return nullptr;
804 #else
805     EDMLOGW("WifiManagerAddon::SetWifiProfileSync Unsupported Capabilities.");
806     napi_throw(env, CreateError(env, EdmReturnErrCode::INTERFACE_UNSUPPORTED));
807     return nullptr;
808 #endif
809 }
810 
TurnOnWifi(napi_env env,napi_callback_info info)811 napi_value WifiManagerAddon::TurnOnWifi(napi_env env, napi_callback_info info)
812 {
813     AddonMethodSign addonMethodSign;
814     addonMethodSign.name = "TurnOnWifi";
815     addonMethodSign.argsType = {EdmAddonCommonType::ELEMENT, EdmAddonCommonType::BOOLEAN};
816     addonMethodSign.methodAttribute = MethodAttribute::HANDLE;
817     AdapterAddonData adapterAddonData{};
818     napi_value result = JsObjectToData(env, info, addonMethodSign, &adapterAddonData);
819     if (result == nullptr) {
820         return nullptr;
821     }
822     int32_t ret = WifiManagerProxy::GetWifiManagerProxy()->TurnOnWifi(adapterAddonData.data);
823     if (FAILED(ret)) {
824         napi_throw(env, CreateError(env, ret));
825     }
826     return nullptr;
827 }
828 
TurnOffWifi(napi_env env,napi_callback_info info)829 napi_value WifiManagerAddon::TurnOffWifi(napi_env env, napi_callback_info info)
830 {
831     AddonMethodSign addonMethodSign;
832     addonMethodSign.name = "TurnOffWifi";
833     addonMethodSign.argsType = {EdmAddonCommonType::ELEMENT};
834     addonMethodSign.methodAttribute = MethodAttribute::HANDLE;
835     AdapterAddonData adapterAddonData{};
836     napi_value result = JsObjectToData(env, info, addonMethodSign, &adapterAddonData);
837     if (result == nullptr) {
838         return nullptr;
839     }
840     int32_t ret = WifiManagerProxy::GetWifiManagerProxy()->TurnOffWifi(adapterAddonData.data);
841     if (FAILED(ret)) {
842         napi_throw(env, CreateError(env, ret));
843     }
844     return nullptr;
845 }
846 
847 static napi_module g_wifiManagerModule = {
848     .nm_version = 1,
849     .nm_flags = 0,
850     .nm_filename = nullptr,
851     .nm_register_func = WifiManagerAddon::Init,
852     .nm_modname = "enterprise.wifiManager",
853     .nm_priv = ((void *)0),
854     .reserved = { 0 },
855 };
856 
WifiManagerRegister()857 extern "C" __attribute__((constructor)) void WifiManagerRegister()
858 {
859     napi_module_register(&g_wifiManagerModule);
860 }