• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright (c) 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 
16 #include <unistd.h>
17 
18 #include <sys/time.h>
19 
20 #include <cstdio>
21 #include <cstdlib>
22 #include <iostream>
23 #include <sstream>
24 #include <string>
25 #include <future>
26 #include <functional>
27 
28 #include "hilog_wrapper.h"
29 #include "securec.h"
30 #include "napi/native_api.h"
31 #include "napi/native_node_api.h"
32 #include "napi_common.h"
33 #include "napi_util.h"
34 #include "serial_async_context.h"
35 #include "serial_napi_errors.h"
36 #include "usb_errors.h"
37 
38 #include "usb_srv_client.h"
39 #include "usb_serial_type.h"
40 
41 using namespace OHOS;
42 using namespace OHOS::USB;
43 
44 const int32_t ARGC_1 = 1;
45 const int32_t ARGC_2 = 2;
46 const int32_t ARGC_3 = 3;
47 
48 static UsbSrvClient &g_usbClient = UsbSrvClient::GetInstance();
49 
ErrorCodeConversion(int32_t value)50 int32_t ErrorCodeConversion(int32_t value)
51 {
52     if (value == UEC_SERVICE_PERMISSION_DENIED_SYSAPI) {
53         return SERIAL_SYSAPI_PERMISSION_DENIED;
54     } else if (value == UEC_SERVICE_PERMISSION_DENIED) {
55         return SERIAL_INTERFACE_PERMISSION_DENIED;
56     } else if (value == UEC_SERVICE_PERMISSION_DENIED_SYSAPI_FAILED) {
57         return SERIAL_SYSAPI_NOPERMISSION_CALL;
58     } else if (value == UEC_SERIAL_PORT_REPEAT_OPEN || value == UEC_SERIAL_PORT_REPEAT_CLOSE
59         || value == UEC_SERIAL_PORT_OCCUPIED) {
60         return SERIAL_PORT_OCCUPIED;
61     } else if (value == UEC_SERIAL_DEVICENOTOPEN || value == UEC_SERIAL_PORT_NOT_OPEN) {
62         return SERIAL_PORT_NOT_OPEN;
63     } else if (value == UEC_INTERFACE_TIMED_OUT) {
64         return SERIAL_TIMED_OUT;
65     } else if (value == UEC_SERIAL_IO_EXCEPTION) {
66         return SERIAL_IO_EXCEPTION;
67     } else if (value == UEC_SERIAL_PORT_NOT_EXIST) {
68         return SERIAL_PORT_NOT_EXIST;
69     } else if (value == UEC_SERIAL_DATEBASE_ERROR) {
70         return UEC_COMMON_RIGHT_DATABASE_ERROR;
71     } else {
72         return SERIAL_SERVICE_ABNORMAL;
73     }
74 }
75 
SerialGetPortListNapi(napi_env env,napi_callback_info info)76 static napi_value SerialGetPortListNapi(napi_env env, napi_callback_info info)
77 {
78     USB_HILOGI(MODULE_JS_NAPI, "SerialGetPortListNapi start");
79     std::vector<OHOS::USB::UsbSerialPort> portIds;
80     int32_t ret = g_usbClient.SerialGetPortList(portIds);
81     napi_value result = nullptr;
82     napi_create_array(env, &result);
83     if (ret < 0) {
84         USB_HILOGE(MODULE_JS_NAPI, "SerialGetPortList failed");
85         return result;
86     }
87     for (uint32_t i = 0; i < portIds.size(); ++i) {
88         napi_value portObj;
89         napi_create_object(env, &portObj);
90         NapiUtil::SetValueInt32(env, "portId", portIds[i].portId_, portObj);
91         std::string deviceName = std::to_string(portIds[i].busNum_) + "-" +
92             std::to_string(portIds[i].devAddr_);
93         NapiUtil::SetValueUtf8String(env, "deviceName", deviceName, portObj);
94         USB_HILOGI(MODULE_JS_NAPI, "portId: %{public}d", portIds[i].portId_);
95         USB_HILOGI(MODULE_JS_NAPI, "deviceName: %{public}s", deviceName.c_str());
96         napi_set_element(env, result, i, portObj);
97     }
98     return result;
99 }
100 
SerialGetAttributeNapi(napi_env env,napi_callback_info info)101 static napi_value SerialGetAttributeNapi(napi_env env, napi_callback_info info)
102 {
103     USB_HILOGI(MODULE_JS_NAPI, "SerialGetAttributeNapi start");
104     size_t argc = ARGC_1;
105     napi_value argv[ARGC_1] = {nullptr};
106     if (!CheckNapiResult(env, napi_get_cb_info(env, info, &argc, argv, nullptr, nullptr),
107         "Get call back info failed")) {
108         CheckAndThrowOnError(env, false, SYSPARAM_INVALID_INPUT, "get arguments failed.");
109         return nullptr;
110     }
111     if (!CheckAndThrowOnError(env, (argc == ARGC_1), SYSPARAM_INVALID_INPUT, "The function takes 1 arguments.")) {
112         return nullptr;
113     }
114     napi_value portId = argv[0];
115     napi_valuetype type;
116     napi_typeof(env, portId, &type);
117     if (!CheckAndThrowOnError(env, type == napi_number, SYSPARAM_INVALID_INPUT, "The type of arg0 must be int32_t.")) {
118         return nullptr;
119     }
120     int32_t portIdValue = -1;
121     napi_get_value_int32(env, portId, &portIdValue);
122     if (!CheckAndThrowOnError(env, (portIdValue != -1), SYSPARAM_INVALID_INPUT, "Failed to get portId.")) {
123         return nullptr;
124     }
125     UsbSerialAttr serialAttribute;
126     int32_t ret = g_usbClient.SerialGetAttribute(portIdValue, serialAttribute);
127     if (!CheckAndThrowOnError(env, (ret == 0), ErrorCodeConversion(ret), "Failed to get attribute.")) {
128         return nullptr;
129     }
130     napi_value result = nullptr;
131     napi_create_object(env, &result);
132     NapiUtil::SetValueUint32(env, "baudRate", serialAttribute.baudRate_, result);
133     NapiUtil::SetValueUint32(env, "dataBits", serialAttribute.dataBits_, result);
134     NapiUtil::SetValueUint32(env, "parity", serialAttribute.parity_, result);
135     NapiUtil::SetValueUint32(env, "stopBits", serialAttribute.stopBits_, result);
136     return result;
137 }
138 
ParseSetAttributeInterfaceParams(napi_env env,napi_callback_info info,int32_t & portIdValue,UsbSerialAttr & serialAttribute)139 bool ParseSetAttributeInterfaceParams(napi_env env, napi_callback_info info,
140     int32_t& portIdValue, UsbSerialAttr& serialAttribute)
141 {
142     USB_HILOGI(MODULE_JS_NAPI, "ParseSetAttributeInterfaceParams start");
143     size_t argc = ARGC_2;
144     napi_value argv[ARGC_2] = { nullptr };
145     if (!CheckNapiResult(env, napi_get_cb_info(env, info, &argc, argv, nullptr, nullptr),
146         "Get call back info failed")) {
147         CheckAndThrowOnError(env, false, SYSPARAM_INVALID_INPUT, "get arguments failed.");
148         return false;
149     }
150     if (!CheckAndThrowOnError(env, (argc == ARGC_2), SYSPARAM_INVALID_INPUT, "The function takes 2 arguments.")) {
151         return false;
152     }
153     napi_value portId = argv[0];
154     napi_valuetype type;
155     napi_typeof(env, portId, &type);
156     if (!CheckAndThrowOnError(env, type == napi_number, SYSPARAM_INVALID_INPUT, "The type of arg0 must be int32_t.")) {
157         return false;
158     }
159     napi_get_value_int32(env, portId, &portIdValue);
160     if (!CheckAndThrowOnError(env, (portIdValue != -1), SYSPARAM_INVALID_INPUT, "Failed to get portId.")) {
161         return false;
162     }
163     napi_value obj = argv[1];
164     napi_typeof(env, obj, &type);
165     if (!CheckAndThrowOnError(env, type == napi_object, SYSPARAM_INVALID_INPUT,
166         "The type of arg1 must be SerialAttribute.")) {
167         return false;
168     }
169     NapiUtil::JsObjectToUint(env, obj, "baudRate", serialAttribute.baudRate_);
170     NapiUtil::JsObjectToUint(env, obj, "dataBits", serialAttribute.dataBits_);
171     NapiUtil::JsObjectToUint(env, obj, "parity", serialAttribute.parity_);
172     NapiUtil::JsObjectToUint(env, obj, "stopBits", serialAttribute.stopBits_);
173     return true;
174 }
175 
SerialSetAttributeNapi(napi_env env,napi_callback_info info)176 static napi_value SerialSetAttributeNapi(napi_env env, napi_callback_info info)
177 {
178     USB_HILOGI(MODULE_JS_NAPI, "SerialSetAttributeNapi start");
179     UsbSerialAttr serialAttribute;
180     int32_t portIdValue = -1;
181     if (!ParseSetAttributeInterfaceParams(env, info, portIdValue, serialAttribute)) {
182         return nullptr;
183     }
184     USB_HILOGI(MODULE_JS_NAPI, "SetAttributeNapi portIdValue: %{public}d", portIdValue);
185     int ret = g_usbClient.SerialSetAttribute(portIdValue, serialAttribute);
186     if (!CheckAndThrowOnError(env, (ret == 0), ErrorCodeConversion(ret), "Failed to set attribute.")) {
187         return nullptr;
188     }
189     return nullptr;
190 }
191 
ParseWriteInterfaceParams(napi_env env,napi_callback_info info,int32_t & portIdValue,napi_value * buffer,uint32_t & timeoutValue)192 bool ParseWriteInterfaceParams(napi_env env, napi_callback_info info,
193     int32_t& portIdValue, napi_value* buffer, uint32_t& timeoutValue)
194 {
195     USB_HILOGI(MODULE_JS_NAPI, "ParseWriteInterfaceParams start");
196     size_t argc = ARGC_3;
197     napi_value argv[ARGC_3] = {nullptr};
198     if (!CheckNapiResult(env, napi_get_cb_info(env, info, &argc, argv, nullptr, nullptr),
199         "Get call back info failed")) {
200         CheckAndThrowOnError(env, false, SYSPARAM_INVALID_INPUT, "get arguments failed.");
201         return false;
202     }
203     if (!CheckAndThrowOnError(env, (argc == ARGC_2 || argc == ARGC_3), SYSPARAM_INVALID_INPUT,
204         "The function takes 2 or 3 arguments.")) {
205         return false;
206     }
207     napi_value portId = argv[0];
208     napi_valuetype type;
209     napi_typeof(env, portId, &type);
210     if (!CheckAndThrowOnError(env, type == napi_number, SYSPARAM_INVALID_INPUT,
211         "The type of portId must be int32_t.")) {
212         return false;
213     }
214     napi_get_value_int32(env, portId, &portIdValue);
215     if (!CheckAndThrowOnError(env, (portIdValue != -1), SYSPARAM_INVALID_INPUT, "Failed to get portId.")) {
216         return false;
217     }
218     *buffer = argv[1];
219     if (argc == ARGC_3) {
220         napi_value timeout = argv[2];
221         napi_typeof(env, timeout, &type);
222         if (!CheckAndThrowOnError(env, type == napi_number, SYSPARAM_INVALID_INPUT,
223             "The type of timeout must be uint32_t.")) {
224             return false;
225         }
226         napi_get_value_uint32(env, timeout, &timeoutValue);
227     }
228     return true;
229 }
230 
SerialWriteSyncNapi(napi_env env,napi_callback_info info)231 static napi_value SerialWriteSyncNapi(napi_env env, napi_callback_info info)
232 {
233     USB_HILOGI(MODULE_JS_NAPI, "SerialWriteSyncNapi start");
234     int32_t portIdValue = -1;
235     napi_value buffer;
236     uint32_t timeoutValue = 0;
237     if (!ParseWriteInterfaceParams(env, info, portIdValue, &buffer, timeoutValue)) {
238         return nullptr;
239     }
240     napi_typedarray_type arrayType;
241     size_t bufferLength;
242     void* bufferValue = nullptr;
243     napi_get_typedarray_info(env, buffer, &arrayType, &bufferLength, &bufferValue, nullptr, nullptr);
244     if (!CheckAndThrowOnError(env, arrayType == napi_uint8_array, SYSPARAM_INVALID_INPUT,
245         "The type of buffer must be an array of uint8_t.")) {
246         return nullptr;
247     }
248     std::vector<uint8_t> bufferVector(static_cast<uint8_t*>(bufferValue),
249         static_cast<uint8_t*>(bufferValue) + bufferLength);
250 
251     uint32_t actualSize = 0;
252     int32_t ret = g_usbClient.SerialWrite(portIdValue, bufferVector, bufferLength, actualSize, timeoutValue);
253     if (!CheckAndThrowOnError(env, (ret == 0), ErrorCodeConversion(ret), "SerialWrite Failed.")) {
254         return nullptr;
255     }
256 
257     napi_value result = nullptr;
258     napi_create_int32(env, actualSize, &result);
259     return result;
260 }
261 
__anoncfca98d20102(napi_env env, void* data) 262 static auto g_serialWriteExecute = [](napi_env env, void* data) {
263     SerialWriteAsyncContext *context = static_cast<SerialWriteAsyncContext *>(data);
264     if (context->contextErrno) {
265         USB_HILOGE(MODULE_JS_NAPI, "ExecuteCallback failed, reason: napi_get_reference_value");
266         return;
267     }
268 
269     void* bufferValue = context->pData;
270     if (context->size == 0) {
271         USB_HILOGE(MODULE_JS_NAPI, "no valid data to write");
272         return;
273     }
274 
275     std::vector<uint8_t> bufferVector(static_cast<uint8_t*>(bufferValue),
276         static_cast<uint8_t*>(bufferValue) + context->size);
277 
278     uint32_t actualSize = 0;
279     int32_t ret = g_usbClient.SerialWrite(context->portId, bufferVector, context->size, actualSize, context->timeout);
280     if (ret != 0) {
281         context->contextErrno = ErrorCodeConversion(ret);
282     }
283 
284     context->ret = actualSize;
285 };
286 
__anoncfca98d20202(napi_env env, napi_status status, void *data) 287 static auto g_serialWriteComplete = [](napi_env env, napi_status status, void *data) {
288     SerialWriteAsyncContext *context = static_cast<SerialWriteAsyncContext *>(data);
289     napi_value result = nullptr;
290     if (context->contextErrno) {
291         napi_create_int32(env, context->contextErrno, &result);
292         napi_reject_deferred(env, context->deferred, result);
293     } else {
294         napi_create_int32(env, context->ret, &result);
295         napi_resolve_deferred(env, context->deferred, result);
296     }
297     napi_delete_async_work(env, context->work);
298     delete context;
299 };
300 
SerialWriteNapi(napi_env env,napi_callback_info info)301 static napi_value SerialWriteNapi(napi_env env, napi_callback_info info)
302 {
303     USB_HILOGI(MODULE_JS_NAPI, "start write Napi");
304     int32_t portIdValue = -1;
305     napi_value buffer;
306     uint32_t timeoutValue = 0;
307     if (!ParseWriteInterfaceParams(env, info, portIdValue, &buffer, timeoutValue)) {
308         return nullptr;
309     }
310     napi_typedarray_type arrayType;
311     size_t bufferLength;
312     void* bufferValue = nullptr;
313     napi_get_typedarray_info(env, buffer, &arrayType, &bufferLength, &bufferValue, nullptr, nullptr);
314     if (!CheckAndThrowOnError(env, arrayType == napi_uint8_array, SYSPARAM_INVALID_INPUT,
315         "The type of buffer must be an array of uint8_t.")) {
316         return nullptr;
317     }
318     SerialWriteAsyncContext *asyncContext = new (std::nothrow) SerialWriteAsyncContext;
319     if (asyncContext == nullptr) {
320         USB_HILOGE(MODULE_JS_NAPI, "new SerialWriteAsyncContext failed!");
321         CheckAndThrowOnError(env, false, SYSPARAM_INVALID_INPUT, "asyncContext is null");
322         return nullptr;
323     }
324     napi_value promise;
325     napi_create_promise(env, &asyncContext->deferred, &promise);
326     asyncContext->portId = portIdValue;
327     asyncContext->timeout = timeoutValue;
328     asyncContext->contextErrno = 0;
329     asyncContext->size = bufferLength;
330     asyncContext->pData = bufferValue;
331     napi_value resourceName;
332     napi_create_string_utf8(env, "SerialWrite", NAPI_AUTO_LENGTH, &resourceName);
333     napi_create_async_work(env, nullptr, resourceName, g_serialWriteExecute, g_serialWriteComplete, asyncContext,
334         &asyncContext->work);
335     napi_queue_async_work(env, asyncContext->work);
336     return promise;
337 }
338 
ParseReadInterfaceParams(napi_env env,napi_callback_info info,int32_t & portIdValue,napi_value * buffer,uint32_t & timeoutValue)339 bool ParseReadInterfaceParams(napi_env env, napi_callback_info info, int32_t& portIdValue,
340     napi_value* buffer, uint32_t& timeoutValue)
341 {
342     size_t argc = ARGC_3;
343     napi_value argv[ARGC_3] = {nullptr};
344     if (!CheckNapiResult(env, napi_get_cb_info(env, info, &argc, argv, nullptr, nullptr),
345         "Get call back info failed")) {
346         CheckAndThrowOnError(env, false, SYSPARAM_INVALID_INPUT, "get arguments failed.");
347         return false;
348     }
349     if (!CheckAndThrowOnError(env, (argc == ARGC_2 || argc == ARGC_3), SYSPARAM_INVALID_INPUT,
350         "The function takes 2 or 3 arguments.")) {
351         return false;
352     }
353     napi_value portId = argv[0];
354     napi_valuetype type;
355     napi_typeof(env, portId, &type);
356     if (!CheckAndThrowOnError(env, type == napi_number, SYSPARAM_INVALID_INPUT,
357         "The type of portId must be int32_t.")) {
358         return false;
359     }
360     napi_get_value_int32(env, portId, &portIdValue);
361     if (!CheckAndThrowOnError(env, (portIdValue != -1), SYSPARAM_INVALID_INPUT, "Failed to get portId.")) {
362         return false;
363     }
364     *buffer = argv[1];
365     if (argc == ARGC_3) {
366         napi_value timeout = argv[2];
367         napi_typeof(env, timeout, &type);
368         if (!CheckAndThrowOnError(env, type == napi_number, SYSPARAM_INVALID_INPUT,
369             "The type of timeout must be uint32_t.")) {
370             return false;
371         }
372         napi_get_value_uint32(env, timeout, &timeoutValue);
373     }
374     return true;
375 }
376 
SerialReadSyncNapi(napi_env env,napi_callback_info info)377 static napi_value SerialReadSyncNapi(napi_env env, napi_callback_info info)
378 {
379     USB_HILOGI(MODULE_JS_NAPI, "SerialReadSyncNapi start");
380     int32_t portIdValue = -1;
381     napi_value buffer;
382     uint32_t timeoutValue = 0;
383     if (!ParseReadInterfaceParams(env, info, portIdValue, &buffer, timeoutValue)) {
384         return nullptr;
385     }
386     napi_typedarray_type arrayType;
387     size_t bufferLength;
388     void* bufferValue = nullptr;
389     napi_get_typedarray_info(env, buffer, &arrayType, &bufferLength, &bufferValue, nullptr, nullptr);
390     if (!CheckAndThrowOnError(env, arrayType == napi_uint8_array, SYSPARAM_INVALID_INPUT,
391         "The type of buffer must be an array of uint8_t.")) {
392         return nullptr;
393     }
394     std::vector<uint8_t> bufferData;
395     uint32_t actualSize = 0;
396     int32_t ret = g_usbClient.SerialRead(portIdValue, bufferData, bufferLength, actualSize,
397         timeoutValue);
398     if (!CheckAndThrowOnError(env, (ret == 0), ErrorCodeConversion(ret), "SerialReadSync Failed.")) {
399         return nullptr;
400     }
401     ret = memcpy_s(bufferValue, bufferLength, bufferData.data(), bufferData.size());
402     if (ret != UEC_OK) {
403         USB_HILOGE(MODULE_JS_NAPI,
404             "serial read sync, memcpy_s failed size: %{public}zu, bufferSize: %{public}zu, ret: %{public}d",
405             bufferLength, bufferData.size(), ret);
406     }
407     napi_value result = nullptr;
408     napi_create_int32(env, actualSize, &result);
409     return result;
410 }
411 
__anoncfca98d20302(napi_env env, void* data) 412 static auto g_serialReadExecute = [](napi_env env, void* data) {
413     SerialReadAsyncContext *context = static_cast<SerialReadAsyncContext *>(data);
414     uint32_t actualSize = 0;
415     std::vector<uint8_t> bufferData;
416     int32_t ret = g_usbClient.SerialRead(context->portId, bufferData,
417         context->size, actualSize, context->timeout);
418     if (ret != 0) {
419         context->contextErrno = ErrorCodeConversion(ret);
420     }
421     ret = memcpy_s(context->pData, context->size, bufferData.data(), bufferData.size());
422     if (ret != UEC_OK) {
423         USB_HILOGE(MODULE_JS_NAPI, "memcpy_s failed size: %{public}u, bufferSize: %{public}zu, ret: %{public}d",
424             context->size, bufferData.size(), ret);
425     }
426     context->ret = actualSize;
427 };
428 
__anoncfca98d20402(napi_env env, napi_status status, void* data) 429 static auto g_serialReadComplete = [](napi_env env, napi_status status, void* data) {
430     SerialReadAsyncContext *context = static_cast<SerialReadAsyncContext *>(data);
431     napi_value result = nullptr;
432     if (context->contextErrno) {
433         napi_create_int32(env, context->contextErrno, &result);
434         napi_reject_deferred(env, context->deferred, result);
435     } else {
436         napi_create_int32(env, context->ret, &result);
437         napi_resolve_deferred(env, context->deferred, result);
438     }
439     napi_delete_async_work(env, context->work);
440     delete context;
441 };
442 
SerialReadNapi(napi_env env,napi_callback_info info)443 static napi_value SerialReadNapi(napi_env env, napi_callback_info info)
444 {
445     USB_HILOGI(MODULE_JS_NAPI, "SerialReadNapi start");
446     int32_t portIdValue = -1;
447     napi_value buffer;
448     uint32_t timeoutValue = 0;
449     if (!ParseReadInterfaceParams(env, info, portIdValue, &buffer, timeoutValue)) {
450         return nullptr;
451     }
452     napi_typedarray_type arrayType;
453     size_t bufferLength;
454     void* bufferValue = nullptr;
455     napi_get_typedarray_info(env, buffer, &arrayType, &bufferLength, &bufferValue, nullptr, nullptr);
456     if (!CheckAndThrowOnError(env, arrayType == napi_uint8_array, SYSPARAM_INVALID_INPUT,
457         "The type of buffer must be an array of uint8_t.")) {
458         return nullptr;
459     }
460     SerialReadAsyncContext *asyncContext = new (std::nothrow) SerialReadAsyncContext;
461     napi_value promise;
462     napi_create_promise(env, &asyncContext->deferred, &promise);
463     asyncContext->portId = portIdValue;
464     asyncContext->timeout = timeoutValue;
465     asyncContext->contextErrno = 0;
466     asyncContext->size = bufferLength;
467     asyncContext->pData = bufferValue;
468     napi_value resourceName;
469     napi_create_string_utf8(env, "SerialRead", NAPI_AUTO_LENGTH, &resourceName);
470     napi_create_async_work(env, nullptr, resourceName, g_serialReadExecute, g_serialReadComplete, asyncContext,
471         &asyncContext->work);
472     napi_queue_async_work(env, asyncContext->work);
473     return promise;
474 }
475 
SerialOpenNapi(napi_env env,napi_callback_info info)476 static napi_value SerialOpenNapi(napi_env env, napi_callback_info info)
477 {
478     USB_HILOGI(MODULE_JS_NAPI, "serialOpenNapi start");
479     size_t argc = ARGC_1;
480     napi_value argv[ARGC_1] = {nullptr};
481     if (!CheckNapiResult(env, napi_get_cb_info(env, info, &argc, argv, nullptr, nullptr),
482         "Get call back info failed")) {
483         CheckAndThrowOnError(env, false, SYSPARAM_INVALID_INPUT, "get arguments failed.");
484         return nullptr;
485     }
486     if (!CheckAndThrowOnError(env, (argc == ARGC_1), SYSPARAM_INVALID_INPUT, "The function takes 1 arguments.")) {
487         return nullptr;
488     }
489     napi_value portId = argv[0];
490     napi_valuetype type;
491     napi_typeof(env, portId, &type);
492     if (!CheckAndThrowOnError(env, type == napi_number, SYSPARAM_INVALID_INPUT,
493         "The type of portId must be int32_t.")) {
494         return nullptr;
495     }
496     int32_t portIdValue = -1;
497     napi_get_value_int32(env, portId, &portIdValue);
498     if (!CheckAndThrowOnError(env, (portIdValue != -1), SYSPARAM_INVALID_INPUT, "Failed to get portId.")) {
499         return nullptr;
500     }
501     USB_HILOGE(MODULE_JS_NAPI, "portIdValue: %{public}d", portIdValue);
502     int ret = g_usbClient.SerialOpen(portIdValue);
503     if (!CheckAndThrowOnError(env, ret == 0, ErrorCodeConversion(ret), "SerialOpen failed.")) {
504         return nullptr;
505     }
506 
507     return nullptr;
508 }
509 
SerialCloseNapi(napi_env env,napi_callback_info info)510 static napi_value SerialCloseNapi(napi_env env, napi_callback_info info)
511 {
512     USB_HILOGI(MODULE_JS_NAPI, "SerialCloseNapi start");
513     size_t argc = ARGC_1;
514     napi_value argv[ARGC_1] = {nullptr};
515     if (!CheckNapiResult(env, napi_get_cb_info(env, info, &argc, argv, nullptr, nullptr),
516         "Get call back info failed")) {
517         CheckAndThrowOnError(env, false, SYSPARAM_INVALID_INPUT, "get arguments failed.");
518         return nullptr;
519     }
520     if (!CheckAndThrowOnError(env, (argc == ARGC_1), SYSPARAM_INVALID_INPUT, "The function takes 1 arguments.")) {
521         return nullptr;
522     }
523     napi_value portId = argv[0];
524     napi_valuetype type;
525     napi_typeof(env, portId, &type);
526     if (!CheckAndThrowOnError(env, type == napi_number, SYSPARAM_INVALID_INPUT,
527         "The type of portId must be int32_t.")) {
528         return nullptr;
529     }
530     int32_t portIdValue = -1;
531     napi_get_value_int32(env, portId, &portIdValue);
532     if (!CheckAndThrowOnError(env, (portIdValue != -1), SYSPARAM_INVALID_INPUT, "Failed to get portId.")) {
533         return nullptr;
534     }
535 
536     int ret = g_usbClient.SerialClose(portIdValue);
537     if (!CheckAndThrowOnError(env, ret == 0, ErrorCodeConversion(ret), "SerialClose failed.")) {
538         return nullptr;
539     }
540     return nullptr;
541 }
542 
SerialHasRightNapi(napi_env env,napi_callback_info info)543 static napi_value SerialHasRightNapi(napi_env env, napi_callback_info info)
544 {
545     USB_HILOGI(MODULE_JS_NAPI, "SerialHasRightNapi start");
546     size_t argc = ARGC_1;
547     napi_value argv[ARGC_1] = {nullptr};
548     if (!CheckNapiResult(env, napi_get_cb_info(env, info, &argc, argv, nullptr, nullptr),
549         "Get call back info failed")) {
550         CheckAndThrowOnError(env, false, SYSPARAM_INVALID_INPUT, "get arguments failed.");
551         return nullptr;
552     }
553     if (!CheckAndThrowOnError(env, (argc == ARGC_1), SYSPARAM_INVALID_INPUT, "The function takes 1 arguments.")) {
554         return nullptr;
555     }
556     napi_value portId = argv[0];
557     napi_valuetype type;
558     napi_typeof(env, portId, &type);
559     if (!CheckAndThrowOnError(env, type == napi_number, SYSPARAM_INVALID_INPUT,
560         "The type of portId must be int32_t.")) {
561         return nullptr;
562     }
563     int32_t portIdValue = -1;
564     napi_get_value_int32(env, portId, &portIdValue);
565     if (!CheckAndThrowOnError(env, (portIdValue != -1), SYSPARAM_INVALID_INPUT, "Failed to get portId.")) {
566         return nullptr;
567     }
568     napi_value result = nullptr;
569     bool hasRight = false;
570     int32_t ret = g_usbClient.HasSerialRight(portIdValue, hasRight);
571     if (!CheckAndThrowOnError(env, (ret == 0), ErrorCodeConversion(ret), "SerialHasRight failed.")) {
572         return nullptr;
573     }
574     napi_get_boolean(env, hasRight, &result);
575     return result;
576 }
577 
CancelSerialRightNapi(napi_env env,napi_callback_info info)578 static napi_value CancelSerialRightNapi(napi_env env, napi_callback_info info)
579 {
580     USB_HILOGI(MODULE_JS_NAPI, "CancelSerialRightNapi start");
581     size_t argc = ARGC_1;
582     napi_value argv[ARGC_1] = {nullptr};
583     if (!CheckNapiResult(env, napi_get_cb_info(env, info, &argc, argv, nullptr, nullptr),
584         "Get call back info failed")) {
585         CheckAndThrowOnError(env, false, SYSPARAM_INVALID_INPUT, "get arguments failed.");
586         return nullptr;
587     }
588     if (!CheckAndThrowOnError(env, (argc == ARGC_1), SYSPARAM_INVALID_INPUT, "The function takes 1 arguments.")) {
589         return nullptr;
590     }
591     napi_value portId = argv[0];
592     napi_valuetype type;
593     napi_typeof(env, portId, &type);
594     if (!CheckAndThrowOnError(env, type == napi_number, SYSPARAM_INVALID_INPUT,
595         "The type of portId must be int32_t.")) {
596         return nullptr;
597     }
598     int32_t portIdValue = -1;
599     napi_get_value_int32(env, portId, &portIdValue);
600     if (!CheckAndThrowOnError(env, (portIdValue != -1), SYSPARAM_INVALID_INPUT, "Failed to get portId.")) {
601         return nullptr;
602     }
603     int32_t ret = g_usbClient.CancelSerialRight(portIdValue);
604     if (!CheckAndThrowOnError(env, ret == 0, ErrorCodeConversion(ret), "SerialRemoveRight failed.")) {
605         return nullptr;
606     }
607     return nullptr;
608 }
609 
SerialAddRightNapi(napi_env env,napi_callback_info info)610 static napi_value SerialAddRightNapi(napi_env env, napi_callback_info info)
611 {
612     USB_HILOGI(MODULE_JS_NAPI, "SerialAddRightNapi start");
613     size_t argc = ARGC_2;
614     napi_value argv[ARGC_2] = {nullptr};
615     if (!CheckNapiResult(env, napi_get_cb_info(env, info, &argc, argv, nullptr, nullptr),
616         "Get call back info failed")) {
617         CheckAndThrowOnError(env, false, SYSPARAM_INVALID_INPUT, "can not get arguments.");
618         return nullptr;
619     }
620     if (!CheckAndThrowOnError(env, (argc == ARGC_2), SYSPARAM_INVALID_INPUT, "The function takes 2 arguments.")) {
621         return nullptr;
622     }
623     napi_value tokenId = argv[0];
624     napi_valuetype type;
625     napi_typeof(env, tokenId, &type);
626     if (!CheckAndThrowOnError(env, type == napi_number, SYSPARAM_INVALID_INPUT,
627         "The type of tokenId must be int32_t.")) {
628         return nullptr;
629     }
630     int32_t tokenIdValue = 0;
631     napi_get_value_int32(env, tokenId, &tokenIdValue);
632     if (!CheckAndThrowOnError(env, (tokenIdValue != 0), SYSPARAM_INVALID_INPUT, "Failed to get tokenId.")) {
633         return nullptr;
634     }
635     napi_value portId = argv[1];
636     napi_typeof(env, portId, &type);
637     if (!CheckAndThrowOnError(env, type == napi_number, SYSPARAM_INVALID_INPUT,
638         "The type of portId must be int32_t.")) {
639         return nullptr;
640     }
641     int32_t portIdValue = -1;
642     napi_get_value_int32(env, portId, &portIdValue);
643     if (!CheckAndThrowOnError(env, (portIdValue != -1), SYSPARAM_INVALID_INPUT, "Failed to get portId.")) {
644         return nullptr;
645     }
646     int32_t ret = g_usbClient.AddSerialRight(tokenIdValue, portIdValue);
647     if (!CheckAndThrowOnError(env, ret == 0, ErrorCodeConversion(ret), "SerialAddRight failed.")) {
648         return nullptr;
649     }
650     return nullptr;
651 }
652 
__anoncfca98d20502(napi_env env, void* data) 653 static auto g_serialRequestRightExecute = [](napi_env env, void* data) {
654     SerialRequestRightAsyncContext *asyncContext = static_cast<SerialRequestRightAsyncContext *>(data);
655     int32_t ret = g_usbClient.RequestSerialRight(asyncContext->portIdValue, asyncContext->hasRight);
656     asyncContext->contextErrno = 0;
657     if (ret != 0) {
658         USB_HILOGE(MODULE_JS_NAPI, "request right has error");
659         asyncContext->contextErrno = ErrorCodeConversion(ret);
660     }
661 };
662 
__anoncfca98d20602(napi_env env, napi_status status, void* data) 663 static auto g_serialRequestRightComplete = [](napi_env env, napi_status status, void* data) {
664     SerialRequestRightAsyncContext *asyncContext = static_cast<SerialRequestRightAsyncContext *>(data);
665     napi_value result = nullptr;
666     if (asyncContext->contextErrno) {
667         USB_HILOGE(MODULE_JS_NAPI, "Failed to request serial right");
668         napi_create_int32(env, asyncContext->contextErrno, &result);
669         napi_reject_deferred(env, asyncContext->deferred, result);
670     } else {
671         napi_get_boolean(env, asyncContext->hasRight, &result);
672         napi_resolve_deferred(env, asyncContext->deferred, result);
673     }
674     napi_delete_async_work(env, asyncContext->work);
675     delete asyncContext;
676 };
677 
SerialRequestRightNapi(napi_env env,napi_callback_info info)678 static napi_value SerialRequestRightNapi(napi_env env, napi_callback_info info)
679 {
680     size_t argc = ARGC_1;
681     napi_value argv[ARGC_1] = {nullptr};
682     if (!CheckNapiResult(env, napi_get_cb_info(env, info, &argc, argv, nullptr, nullptr),
683         "Get call back info failed")) {
684         CheckAndThrowOnError(env, false, SYSPARAM_INVALID_INPUT, "can not get arguments.");
685         return nullptr;
686     }
687     if (!CheckAndThrowOnError(env, (argc == ARGC_1), SYSPARAM_INVALID_INPUT, "The function takes 1 arguments.")) {
688         return nullptr;
689     }
690     napi_value portId = argv[0];
691     napi_valuetype type;
692     napi_typeof(env, portId, &type);
693     if (!CheckAndThrowOnError(env, type == napi_number, SYSPARAM_INVALID_INPUT,
694         "The type of portId must be int32_t.")) {
695         return nullptr;
696     }
697     int32_t portIdValue = -1;
698     napi_get_value_int32(env, portId, &portIdValue);
699     if (!CheckAndThrowOnError(env, (portIdValue != -1), SYSPARAM_INVALID_INPUT, "Failed to get portId.")) {
700         return nullptr;
701     }
702     SerialRequestRightAsyncContext* asyncContext = new (std::nothrow) SerialRequestRightAsyncContext;
703     asyncContext->portIdValue = portIdValue;
704     asyncContext->contextErrno = 0;
705     asyncContext->hasRight = false;
706     napi_value result = nullptr;
707     napi_create_promise(env, &asyncContext->deferred, &result);
708     napi_value resourceName;
709     napi_create_string_utf8(env, "SerialRequestRight", NAPI_AUTO_LENGTH, &resourceName);
710     napi_create_async_work(env, nullptr, resourceName, g_serialRequestRightExecute,
711         g_serialRequestRightComplete, static_cast<void*>(asyncContext), &asyncContext->work);
712     napi_queue_async_work(env, asyncContext->work);
713     return result;
714 }
715 
SetEnumProperty(napi_env env,napi_value object,const std::string & name,int32_t value)716 static void SetEnumProperty(napi_env env, napi_value object, const std::string &name, int32_t value)
717 {
718     if (name.empty()) {
719         USB_HILOGE(MODULE_JS_NAPI, "Property name cannot be an empty string");
720         return;
721     }
722 
723     napi_value tempValue = nullptr;
724     napi_status status = napi_create_int32(env, value, &tempValue);
725     if (status != napi_ok) {
726         USB_HILOGE(MODULE_JS_NAPI, "Failed to create int32 value for enum %{public}s", name.c_str());
727         return;
728     }
729     status = napi_set_named_property(env, object, name.c_str(), tempValue);
730     if (status != napi_ok) {
731         USB_HILOGE(MODULE_JS_NAPI, "Failed to set property %{public}s", name.c_str());
732         return;
733     }
734 }
735 
NapiCreateStopBitsTypeEnum(napi_env env)736 static napi_value NapiCreateStopBitsTypeEnum(napi_env env)
737 {
738     napi_value object = nullptr;
739     napi_status status = napi_create_object(env, &object);
740     if (status != napi_ok) {
741         USB_HILOGE(MODULE_JS_NAPI, "Failed to create object");
742         return nullptr;
743     }
744     SetEnumProperty(env, object, "STOPBIT_1", STOPBIT_1);
745     SetEnumProperty(env, object, "STOPBIT_1P5", STOPBIT_1P5);
746     SetEnumProperty(env, object, "STOPBIT_2", STOPBIT_2);
747     return object;
748 }
749 
NapiCreateParityTypeEnum(napi_env env)750 static napi_value NapiCreateParityTypeEnum(napi_env env)
751 {
752     napi_value object = nullptr;
753     napi_status status = napi_create_object(env, &object);
754     if (status != napi_ok) {
755         USB_HILOGE(MODULE_JS_NAPI, "Failed to create object");
756         return nullptr;
757     }
758     SetEnumProperty(env, object, "PARITY_NONE", PARITY_NONE);
759     SetEnumProperty(env, object, "PARITY_ODD", PARITY_ODD);
760     SetEnumProperty(env, object, "PARITY_EVEN", PARITY_EVEN);
761     SetEnumProperty(env, object, "PARITY_MARK", PARITY_MARK);
762     SetEnumProperty(env, object, "PARITY_SPACE", PARITY_SPACE);
763     return object;
764 }
765 
NapiCreateDataBitsTypeEnum(napi_env env)766 static napi_value NapiCreateDataBitsTypeEnum(napi_env env)
767 {
768     napi_value object = nullptr;
769     napi_status status = napi_create_object(env, &object);
770     if (status != napi_ok) {
771         USB_HILOGE(MODULE_JS_NAPI, "Failed to create object");
772         return nullptr;
773     }
774     SetEnumProperty(env, object, "DATABIT_8", DATABIT_8);
775     SetEnumProperty(env, object, "DATABIT_7", DATABIT_7);
776     SetEnumProperty(env, object, "DATABIT_6", DATABIT_6);
777     SetEnumProperty(env, object, "DATABIT_5", DATABIT_5);
778     SetEnumProperty(env, object, "DATABIT_4", DATABIT_4);
779     return object;
780 }
781 
NapiCreateBaudRatesTypeEnum(napi_env env)782 static napi_value NapiCreateBaudRatesTypeEnum(napi_env env)
783 {
784     napi_value object = nullptr;
785     napi_status status = napi_create_object(env, &object);
786     if (status != napi_ok) {
787         USB_HILOGE(MODULE_JS_NAPI, "Failed to create object");
788         return nullptr;
789     }
790     SetEnumProperty(env, object, "BAUDRATE_50", BAUDRATE_50);
791     SetEnumProperty(env, object, "BAUDRATE_75", BAUDRATE_75);
792     SetEnumProperty(env, object, "BAUDRATE_110", BAUDRATE_110);
793     SetEnumProperty(env, object, "BAUDRATE_134", BAUDRATE_134);
794     SetEnumProperty(env, object, "BAUDRATE_150", BAUDRATE_150);
795     SetEnumProperty(env, object, "BAUDRATE_200", BAUDRATE_200);
796     SetEnumProperty(env, object, "BAUDRATE_300", BAUDRATE_300);
797     SetEnumProperty(env, object, "BAUDRATE_600", BAUDRATE_600);
798     SetEnumProperty(env, object, "BAUDRATE_1200", BAUDRATE_1200);
799     SetEnumProperty(env, object, "BAUDRATE_1800", BAUDRATE_1800);
800     SetEnumProperty(env, object, "BAUDRATE_2400", BAUDRATE_2400);
801     SetEnumProperty(env, object, "BAUDRATE_4800", BAUDRATE_4800);
802     SetEnumProperty(env, object, "BAUDRATE_9600", BAUDRATE_9600);
803     SetEnumProperty(env, object, "BAUDRATE_19200", BAUDRATE_19200);
804     SetEnumProperty(env, object, "BAUDRATE_38400", BAUDRATE_38400);
805     SetEnumProperty(env, object, "BAUDRATE_57600", BAUDRATE_57600);
806     SetEnumProperty(env, object, "BAUDRATE_115200", BAUDRATE_115200);
807     SetEnumProperty(env, object, "BAUDRATE_230400", BAUDRATE_230400);
808     SetEnumProperty(env, object, "BAUDRATE_460800", BAUDRATE_460800);
809     SetEnumProperty(env, object, "BAUDRATE_500000", BAUDRATE_500000);
810     SetEnumProperty(env, object, "BAUDRATE_576000", BAUDRATE_576000);
811     SetEnumProperty(env, object, "BAUDRATE_921600", BAUDRATE_921600);
812     SetEnumProperty(env, object, "BAUDRATE_1000000", BAUDRATE_1000000);
813     SetEnumProperty(env, object, "BAUDRATE_1152000", BAUDRATE_1152000);
814     SetEnumProperty(env, object, "BAUDRATE_1500000", BAUDRATE_1500000);
815     SetEnumProperty(env, object, "BAUDRATE_2000000", BAUDRATE_2000000);
816     SetEnumProperty(env, object, "BAUDRATE_2500000", BAUDRATE_2500000);
817     SetEnumProperty(env, object, "BAUDRATE_3000000", BAUDRATE_3000000);
818     SetEnumProperty(env, object, "BAUDRATE_3500000", BAUDRATE_3500000);
819     SetEnumProperty(env, object, "BAUDRATE_4000000", BAUDRATE_4000000);
820     return object;
821 }
822 
DeclareEnum(napi_env env,napi_value exports)823 static napi_value DeclareEnum(napi_env env, napi_value exports)
824 {
825     napi_property_descriptor desc[] = {
826         DECLARE_NAPI_STATIC_PROPERTY("StopBits", NapiCreateStopBitsTypeEnum(env)),
827         DECLARE_NAPI_STATIC_PROPERTY("Parity", NapiCreateParityTypeEnum(env)),
828         DECLARE_NAPI_STATIC_PROPERTY("DataBits", NapiCreateDataBitsTypeEnum(env)),
829         DECLARE_NAPI_STATIC_PROPERTY("BaudRates", NapiCreateBaudRatesTypeEnum(env)),
830     };
831     NAPI_CALL(env, napi_define_properties(env, exports, sizeof(desc) / sizeof(desc[0]), desc));
832     return exports;
833 }
834 
835 EXTERN_C_START
836 /*
837  * function for module exports
838  */
SerialInit(napi_env env,napi_value exports)839 napi_value SerialInit(napi_env env, napi_value exports)
840 {
841     USB_HILOGD(MODULE_JS_NAPI, "enter");
842     napi_property_descriptor desc[] = {
843         DECLARE_NAPI_FUNCTION("getPortList", SerialGetPortListNapi),
844         DECLARE_NAPI_FUNCTION("open", SerialOpenNapi),
845         DECLARE_NAPI_FUNCTION("close", SerialCloseNapi),
846         DECLARE_NAPI_FUNCTION("read", SerialReadNapi),
847         DECLARE_NAPI_FUNCTION("readSync", SerialReadSyncNapi),
848         DECLARE_NAPI_FUNCTION("write", SerialWriteNapi),
849         DECLARE_NAPI_FUNCTION("writeSync", SerialWriteSyncNapi),
850         DECLARE_NAPI_FUNCTION("getAttribute", SerialGetAttributeNapi),
851         DECLARE_NAPI_FUNCTION("setAttribute", SerialSetAttributeNapi),
852         DECLARE_NAPI_FUNCTION("hasSerialRight", SerialHasRightNapi),
853         DECLARE_NAPI_FUNCTION("requestSerialRight", SerialRequestRightNapi),
854         DECLARE_NAPI_FUNCTION("addSerialRight", SerialAddRightNapi),
855         DECLARE_NAPI_FUNCTION("cancelSerialRight", CancelSerialRightNapi),
856     };
857     NAPI_CALL(env, napi_define_properties(env, exports, sizeof(desc) / sizeof(desc[0]), desc));
858     DeclareEnum(env, exports);
859     USB_HILOGD(MODULE_JS_NAPI, "return");
860     return exports;
861 }
862 EXTERN_C_END
863