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 }