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