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