• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright (C) 2021-2022 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 
16 #include "wifi_napi_utils.h"
17 #include "securec.h"
18 #include "wifi_logger.h"
19 #include "context.h"
20 #include "wifi_napi_errcode.h"
21 
22 namespace OHOS {
23 namespace Wifi {
24 DEFINE_WIFILOG_LABEL("WifiNAPIUtils");
25 
TraceFuncCall(std::string funcName)26 TraceFuncCall::TraceFuncCall(std::string funcName): m_funcName(funcName)
27 {
28     if (m_isTrace) {
29         m_startTime = std::chrono::steady_clock::now();
30         WIFI_LOGI("Call wifi func: %{public}s (start)", m_funcName.c_str());
31     }
32 }
33 
~TraceFuncCall()34 TraceFuncCall::~TraceFuncCall()
35 {
36     if (m_isTrace) {
37         auto us = std::chrono::duration_cast<std::chrono::microseconds>
38             (std::chrono::steady_clock::now() - m_startTime).count();
39         constexpr int usForPerMs = 1000;
40         WIFI_LOGI("Call wifi func: %{public}s (end), time cost:%{public}lldus, %{public}lldms",
41             m_funcName.c_str(), us, us / usForPerMs);
42     }
43 }
44 
UndefinedNapiValue(const napi_env & env)45 napi_value UndefinedNapiValue(const napi_env& env)
46 {
47     napi_value result;
48     napi_get_undefined(env, &result);
49     return result;
50 }
51 
CreateInt32(const napi_env & env)52 napi_value CreateInt32(const napi_env& env)
53 {
54     int32_t value = 1;
55     napi_value result = nullptr;
56     napi_create_int32(env, value, &result);
57     return result;
58 }
59 
JsObjectToString(const napi_env & env,const napi_value & object,const char * fieldStr,const int bufLen,std::string & fieldRef)60 napi_value JsObjectToString(const napi_env& env, const napi_value& object,
61     const char* fieldStr, const int bufLen, std::string& fieldRef)
62 {
63     bool hasProperty = false;
64     NAPI_CALL(env, napi_has_named_property(env, object, fieldStr, &hasProperty));
65     if (hasProperty) {
66         napi_value field;
67         napi_valuetype valueType;
68 
69         napi_get_named_property(env, object, fieldStr, &field);
70         NAPI_CALL(env, napi_typeof(env, field, &valueType));
71         if (valueType != napi_string) {
72             WIFI_LOGE("Wrong argument type. String expected.");
73             return NULL;
74         }
75         if (bufLen <= 0) {
76             return NULL;
77         }
78         char *buf = (char *)malloc(bufLen);
79         if (buf == nullptr) {
80             WIFI_LOGE("Js object to str malloc failed");
81             return NULL;
82         }
83         (void)memset_s(buf, bufLen, 0, bufLen);
84         size_t result = 0;
85         if (napi_get_value_string_utf8(env, field, buf, bufLen, &result) != napi_ok) {
86             free(buf);
87             buf = nullptr;
88             return NULL;
89         }
90         fieldRef = buf;
91         free(buf);
92         buf = nullptr;
93     } else {
94         WIFI_LOGW("Js obj to str no property: %{public}s", fieldStr);
95         return NULL;
96     }
97     return UndefinedNapiValue(env);
98 }
99 
JsObjectToInt(const napi_env & env,const napi_value & object,const char * fieldStr,int & fieldRef)100 napi_value JsObjectToInt(const napi_env& env, const napi_value& object, const char* fieldStr, int& fieldRef)
101 {
102     bool hasProperty = false;
103     NAPI_CALL(env, napi_has_named_property(env, object, fieldStr, &hasProperty));
104     if (hasProperty) {
105         napi_value field;
106         napi_valuetype valueType;
107 
108         napi_get_named_property(env, object, fieldStr, &field);
109         NAPI_CALL(env, napi_typeof(env, field, &valueType));
110         NAPI_ASSERT(env, valueType == napi_number, "Wrong argument type. Number expected.");
111         napi_get_value_int32(env, field, &fieldRef);
112     } else {
113         WIFI_LOGW("Js to int no property: %{public}s", fieldStr);
114     }
115     return UndefinedNapiValue(env);
116 }
117 
JsObjectToUint(const napi_env & env,const napi_value & object,const char * fieldStr,uint32_t & fieldRef)118 napi_value JsObjectToUint(const napi_env& env, const napi_value& object, const char* fieldStr, uint32_t& fieldRef)
119 {
120     bool hasProperty = false;
121     NAPI_CALL(env, napi_has_named_property(env, object, fieldStr, &hasProperty));
122     if (hasProperty) {
123         napi_value field;
124         napi_valuetype valueType;
125 
126         napi_get_named_property(env, object, fieldStr, &field);
127         NAPI_CALL(env, napi_typeof(env, field, &valueType));
128         NAPI_ASSERT(env, valueType == napi_number, "Wrong argument type. Number expected.");
129         napi_get_value_uint32(env, field, &fieldRef);
130     } else {
131         WIFI_LOGW("Js to int no property: %{public}s", fieldStr);
132     }
133     return UndefinedNapiValue(env);
134 }
135 
JsObjectToBool(const napi_env & env,const napi_value & object,const char * fieldStr,bool & fieldRef)136 napi_value JsObjectToBool(const napi_env& env, const napi_value& object, const char* fieldStr, bool& fieldRef)
137 {
138     bool hasProperty = false;
139     NAPI_CALL(env, napi_has_named_property(env, object, fieldStr, &hasProperty));
140     if (hasProperty) {
141         napi_value field;
142         napi_valuetype valueType;
143 
144         napi_get_named_property(env, object, fieldStr, &field);
145         NAPI_CALL(env, napi_typeof(env, field, &valueType));
146         NAPI_ASSERT(env, valueType == napi_boolean, "Wrong argument type. Bool expected.");
147         napi_get_value_bool(env, field, &fieldRef);
148     } else {
149         WIFI_LOGW("Js to bool no property: %{public}s", fieldStr);
150     }
151     return UndefinedNapiValue(env);
152 }
153 
JsObjectToU8Vector(const napi_env & env,const napi_value & object,const char * fieldStr)154 std::vector<uint8_t> JsObjectToU8Vector(const napi_env& env, const napi_value& object, const char* fieldStr)
155 {
156     bool hasProperty = false;
157     NAPI_CALL_BASE(env, napi_has_named_property(env, object, fieldStr, &hasProperty), {});
158     if (!hasProperty) {
159         WIFI_LOGW("JsObjectToU8Vector, Js to U8Vector no property: %{public}s", fieldStr);
160         return {};
161     }
162 
163     bool isTypedArray = false;
164     if (napi_is_typedarray(env, object, &isTypedArray) != napi_ok || !isTypedArray) {
165         WIFI_LOGW("JsObjectToU8Vector, property is not typedarray: %{public}s", fieldStr);
166         return {};
167     }
168 
169     size_t length = 0;
170     size_t offset = 0;
171     napi_typedarray_type type;
172     napi_value buffer = nullptr;
173     NAPI_CALL_BASE(env, napi_get_typedarray_info(env, object, &type, &length, nullptr, &buffer, &offset), {});
174     if (type != napi_uint8_array || buffer == nullptr) {
175         WIFI_LOGW("JsObjectToU8Vector, %{public}s, buffer is nullptr: %{public}d",
176             fieldStr, (int)(buffer == nullptr));
177         return {};
178     }
179 
180     size_t total = 0;
181     uint8_t *data = nullptr;
182     NAPI_CALL_BASE(env, napi_get_arraybuffer_info(env, buffer, reinterpret_cast<void **>(&data), &total), {});
183     length = std::min<size_t>(length, total - offset);
184     std::vector<uint8_t> result(length);
185     int retCode = memcpy_s(result.data(), result.size(), &data[offset], length);
186     if (retCode != 0) {
187         WIFI_LOGW("JsObjectToU8Vector, memcpy_s return fail: %{public}d", retCode);
188         return {};
189     }
190     return result;
191 }
192 
SetValueUtf8String(const napi_env & env,const char * fieldStr,const char * str,napi_value & result,size_t strLen)193 napi_status SetValueUtf8String(const napi_env& env, const char* fieldStr, const char* str,
194     napi_value& result, size_t strLen)
195 {
196     napi_value value;
197     size_t len = strLen;
198     napi_status status = napi_create_string_utf8(env, str, len, &value);
199     if (status != napi_ok) {
200         WIFI_LOGE("Set value create utf8 string error! field: %{public}s", fieldStr);
201         return status;
202     }
203     status = napi_set_named_property(env, result, fieldStr, value);
204     if (status != napi_ok) {
205         WIFI_LOGE("Set utf8 string named property error! field: %{public}s", fieldStr);
206     }
207     return status;
208 }
209 
SetValueUtf8String(const napi_env & env,const std::string & fieldStr,const std::string & valueStr,napi_value & result)210 napi_status SetValueUtf8String(const napi_env& env, const std::string &fieldStr, const std::string &valueStr,
211     napi_value& result)
212 {
213     WIFI_LOGD("SetValueUtf8String, fieldStr: %{public}s, valueStr: %{public}s",
214         fieldStr.c_str(), valueStr.c_str());
215     napi_value value;
216     size_t len = valueStr.length();
217     napi_status status = napi_create_string_utf8(env, valueStr.c_str(), len, &value);
218     if (status != napi_ok) {
219         WIFI_LOGE("Set value create utf8 string error! field: %{public}s", fieldStr.c_str());
220         return status;
221     }
222     status = napi_set_named_property(env, result, fieldStr.c_str(), value);
223     if (status != napi_ok) {
224         WIFI_LOGE("Set utf8 string named property error! field: %{public}s", fieldStr.c_str());
225     }
226     return status;
227 }
228 
SetValueInt32(const napi_env & env,const char * fieldStr,const int intValue,napi_value & result)229 napi_status SetValueInt32(const napi_env& env, const char* fieldStr, const int intValue, napi_value& result)
230 {
231     napi_value value;
232     napi_status status = napi_create_int32(env, intValue, &value);
233     if (status != napi_ok) {
234         WIFI_LOGE("Set value create int32 error! field: %{public}s", fieldStr);
235         return status;
236     }
237     status = napi_set_named_property(env, result, fieldStr, value);
238     if (status != napi_ok) {
239         WIFI_LOGE("Set int32 named property error! field: %{public}s", fieldStr);
240     }
241     return status;
242 }
243 
SetValueUnsignedInt32(const napi_env & env,const char * fieldStr,const int intValue,napi_value & result)244 napi_status SetValueUnsignedInt32(const napi_env& env, const char* fieldStr, const int intValue, napi_value& result)
245 {
246     napi_value value;
247     napi_status status = napi_create_uint32(env, intValue, &value);
248     if (status != napi_ok) {
249         WIFI_LOGE("Set value create unsigned int32 error! field: %{public}s", fieldStr);
250         return status;
251     }
252     status = napi_set_named_property(env, result, fieldStr, value);
253     if (status != napi_ok) {
254         WIFI_LOGE("Set unsigned int32 named property error! field: %{public}s", fieldStr);
255     }
256     return status;
257 }
258 
SetValueInt64(const napi_env & env,const char * fieldStr,const int64_t intValue,napi_value & result)259 napi_status SetValueInt64(const napi_env& env, const char* fieldStr, const int64_t intValue, napi_value& result)
260 {
261     napi_value value;
262     napi_status status = napi_create_int64(env, intValue, &value);
263     if (status != napi_ok) {
264         WIFI_LOGE("Set value create int64 error! field: %{public}s", fieldStr);
265         return status;
266     }
267     status = napi_set_named_property(env, result, fieldStr, value);
268     if (status != napi_ok) {
269         WIFI_LOGE("Set int64 named property error! field: %{public}s", fieldStr);
270     }
271     return status;
272 }
273 
SetValueBool(const napi_env & env,const char * fieldStr,const bool boolvalue,napi_value & result)274 napi_status SetValueBool(const napi_env& env, const char* fieldStr, const bool boolvalue, napi_value& result)
275 {
276     napi_value value;
277     napi_status status = napi_get_boolean(env, boolvalue, &value);
278     if (status != napi_ok) {
279         WIFI_LOGE("Set value create boolean error! field: %{public}s", fieldStr);
280         return status;
281     }
282     status = napi_set_named_property(env, result, fieldStr, value);
283     if (status != napi_ok) {
284         WIFI_LOGE("Set boolean named property error! field: %{public}s", fieldStr);
285     }
286     return status;
287 }
288 
InitAsyncCallBackEnv(const napi_env & env,AsyncContext * asyncContext,const size_t argc,const napi_value * argv,const size_t nonCallbackArgNum)289 static napi_value InitAsyncCallBackEnv(const napi_env& env, AsyncContext *asyncContext,
290     const size_t argc, const napi_value *argv, const size_t nonCallbackArgNum)
291 {
292     for (size_t i = nonCallbackArgNum; i != argc; ++i) {
293         napi_valuetype valuetype;
294         NAPI_CALL(env, napi_typeof(env, argv[i], &valuetype));
295         NAPI_ASSERT(env, valuetype == napi_function, "Wrong argument type. Function expected.");
296         napi_create_reference(env, argv[i], 1, &asyncContext->callback[i - nonCallbackArgNum]);
297     }
298     return nullptr;
299 }
300 
InitAsyncPromiseEnv(const napi_env & env,AsyncContext * asyncContext,napi_value & promise)301 static napi_value InitAsyncPromiseEnv(const napi_env& env, AsyncContext *asyncContext, napi_value& promise)
302 {
303     napi_deferred deferred;
304     NAPI_CALL(env, napi_create_promise(env, &deferred, &promise));
305     asyncContext->deferred = deferred;
306     return nullptr;
307 }
308 
DoCallBackAsyncWork(const napi_env & env,AsyncContext * asyncContext)309 static napi_value DoCallBackAsyncWork(const napi_env& env, AsyncContext *asyncContext)
310 {
311     napi_create_async_work(
312         env,
313         nullptr,
314         asyncContext->resourceName,
315         [](napi_env env, void* data) {
316             if (data == nullptr) {
317                 WIFI_LOGE("Async data parameter is null");
318                 return;
319             }
320             AsyncContext *context = (AsyncContext *)data;
321             context->executeFunc(context);
322         },
323         [](napi_env env, napi_status status, void* data) {
324             if (data == nullptr) {
325                 WIFI_LOGE("Async data parameter is null");
326                 return;
327             }
328             AsyncContext *context = (AsyncContext *)data;
329             context->completeFunc(data);
330             HandleCallbackErrCode(env, *context);
331             if (context->callback[0] != nullptr) {
332                 napi_delete_reference(env, context->callback[0]);
333             }
334             if (context->callback[1] != nullptr) {
335                 napi_delete_reference(env, context->callback[1]);
336             }
337             napi_delete_async_work(env, context->work);
338             delete context;
339         },
340         (void *)asyncContext,
341         &asyncContext->work);
342     NAPI_CALL(env, napi_queue_async_work(env, asyncContext->work));
343     return UndefinedNapiValue(env);
344 }
345 
DoPromiseAsyncWork(const napi_env & env,AsyncContext * asyncContext)346 static napi_value DoPromiseAsyncWork(const napi_env& env, AsyncContext *asyncContext)
347 {
348     napi_create_async_work(
349         env,
350         nullptr,
351         asyncContext->resourceName,
352         [](napi_env env, void *data) {
353             if (data == nullptr) {
354                 WIFI_LOGE("Async data parameter is null");
355                 return;
356             }
357             AsyncContext *context = (AsyncContext *)data;
358             context->executeFunc(context);
359         },
360         [](napi_env env, napi_status status, void *data) {
361             if (data == nullptr) {
362                 WIFI_LOGE("Async data parameter is null");
363                 return;
364             }
365             AsyncContext *context = (AsyncContext *)data;
366             context->completeFunc(data);
367             HandlePromiseErrCode(env, *context);
368             napi_delete_async_work(env, context->work);
369             delete context;
370         },
371         (void *)asyncContext,
372         &asyncContext->work);
373     napi_queue_async_work(env, asyncContext->work);
374     return UndefinedNapiValue(env);
375 }
376 
DoAsyncWork(const napi_env & env,AsyncContext * asyncContext,const size_t argc,const napi_value * argv,const size_t nonCallbackArgNum)377 napi_value DoAsyncWork(const napi_env& env, AsyncContext *asyncContext,
378     const size_t argc, const napi_value *argv, const size_t nonCallbackArgNum)
379 {
380     if (argc > nonCallbackArgNum) {
381         InitAsyncCallBackEnv(env, asyncContext, argc, argv, nonCallbackArgNum);
382         return DoCallBackAsyncWork(env, asyncContext);
383     } else {
384         napi_value promise;
385         InitAsyncPromiseEnv(env, asyncContext, promise);
386         DoPromiseAsyncWork(env, asyncContext);
387         return promise;
388     }
389 }
SetNamedPropertyByInteger(napi_env env,napi_value dstObj,int32_t objName,const char * propName)390 void SetNamedPropertyByInteger(napi_env env, napi_value dstObj, int32_t objName, const char *propName)
391 {
392     napi_value prop = nullptr;
393     if (napi_create_int32(env, objName, &prop) == napi_ok) {
394         napi_set_named_property(env, dstObj, propName, prop);
395     }
396 }
397 }  // namespace Wifi
398 }  // namespace OHOS
399