• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright (c) 2021-2023 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 <cstdint>
23 #include <iostream>
24 #include <sstream>
25 #include <string>
26 #include <uv.h>
27 
28 #include "v1_2/usb_types.h"
29 #include "ashmem.h"
30 #include "hilog_wrapper.h"
31 #include "napi/native_api.h"
32 #include "napi/native_node_api.h"
33 #include "napi_common.h"
34 #include "napi_util.h"
35 #include "securec.h"
36 #include "usb_async_context.h"
37 #include "usb_device_pipe.h"
38 #include "usb_endpoint.h"
39 #include "usb_errors.h"
40 #include "usb_napi_errors.h"
41 #include "usb_srv_client.h"
42 #include "usb_accessory.h"
43 #include "hitrace_meter.h"
44 #include "hdf_base.h"
45 
46 using namespace OHOS;
47 using namespace OHOS::USB;
48 using namespace OHOS::HDI::Usb::V1_0;
49 using namespace OHOS::HDI::Usb::V1_2;
50 
51 static constexpr int32_t INDEX_0 = 0;
52 static constexpr int32_t INDEX_1 = 1;
53 static constexpr int32_t INDEX_2 = 2;
54 static constexpr int32_t INDEX_3 = 3;
55 static constexpr int32_t PARAM_COUNT_0 = 0;
56 static constexpr int32_t PARAM_COUNT_1 = 1;
57 static constexpr int32_t PARAM_COUNT_2 = 2;
58 static constexpr int32_t PARAM_COUNT_3 = 3;
59 static constexpr int32_t PARAM_COUNT_4 = 4;
60 static constexpr int32_t STR_DEFAULT_SIZE = 256;
61 static constexpr int32_t DEFAULT_DESCRIPTION_SIZE = 32;
62 static constexpr int32_t DEFAULT_ACCESSORY_DESCRIPTION_SIZE = 256;
63 static int32_t g_accFd = 0;
64 
65 const int32_t USB_TRANSFER_SHORT_NOT_OK = 0;
66 const int32_t USB_TRANSFER_FREE_BUFFER = 1;
67 const int32_t USB_TRANSFER_FREE_TRANSFER = 2;
68 const int32_t USB_TRANSFER_ADD_ZERO_PACKET = 3;
69 const int32_t TRANSFER_TYPE_ISOCHRONOUS = 1;
70 const int32_t TRANSFER_TYPE_BULK = 2;
71 const int32_t TRANSFER_TYPE_INTERRUPT = 3;
72 const int32_t TRANSFER_COMPLETED = 0;
73 const int32_t TRANSFER_ERROR = 1;
74 const int32_t TRANSFER_TIMED_OUT = 2;
75 const int32_t TRANSFER_CANCELED = 3;
76 const int32_t TRANSFER_STALL = 4;
77 const int32_t TRANSFER_NO_DEVICE = 5;
78 const int32_t TRANSFER_OVERFLOW = 6;
79 const int32_t IO_ERROR = -1;
80 const int32_t INVALID_PARAM = -2;
81 const int32_t NO_DEVICE = -4;
82 const int32_t NOT_FOUND = -5;
83 const int32_t ERROR_BUSY = -6;
84 const int32_t NO_MEM = -11;
85 
86 enum UsbManagerFeature {
87     FEATURE_HOST = 0,
88     FEATURE_DEVICE = 1,
89     FEATURE_PORT = 2,
90 };
91 
HasFeature(UsbManagerFeature feature)92 static bool HasFeature(UsbManagerFeature feature)
93 {
94     switch (feature) {
95         case FEATURE_HOST:
96 #ifndef USB_MANAGER_FEATURE_HOST
97             return false;
98 #else
99             return true;
100 #endif // USB_MANAGER_FEATURE_HOST
101         case FEATURE_DEVICE:
102 #ifndef USB_MANAGER_FEATURE_DEVICE
103             return false;
104 #else
105             return true;
106 #endif // USB_MANAGER_FEATURE_DEVICE
107         case FEATURE_PORT:
108 #ifndef USB_MANAGER_FEATURE_PORT
109             return false;
110 #else
111             return true;
112 #endif // USB_MANAGER_FEATURE_PORT
113         default:;
114     }
115     return false;
116 }
117 
ParseUsbDevicePipe(const napi_env env,const napi_value & obj,USBDevicePipe & pipe)118 static void ParseUsbDevicePipe(const napi_env env, const napi_value &obj, USBDevicePipe &pipe)
119 {
120     napi_valuetype valueType;
121     napi_typeof(env, obj, &valueType);
122     USB_ASSERT_RETURN_VOID(
123         env, valueType == napi_object, OHEC_COMMON_PARAM_ERROR, "The type of pipe must be USBDevicePipe.");
124 
125     int32_t busNum = 0;
126     NapiUtil::JsObjectToInt(env, obj, "busNum", busNum);
127     pipe.SetBusNum(static_cast<uint8_t>(busNum));
128     int32_t devAddr = 0;
129     NapiUtil::JsObjectToInt(env, obj, "devAddress", devAddr);
130     pipe.SetDevAddr(static_cast<uint8_t>(devAddr));
131 }
132 
ProcessPromise(const napi_env env,const USBAsyncContext & asyncContext,napi_value & result)133 static void ProcessPromise(const napi_env env, const USBAsyncContext &asyncContext, napi_value &result)
134 {
135     if (asyncContext.deferred) {
136         if (asyncContext.status == napi_ok) {
137             napi_resolve_deferred(env, asyncContext.deferred, result);
138         } else {
139             napi_reject_deferred(env, asyncContext.deferred, result);
140         }
141     }
142 }
143 
CreateUsbDevicePipe(const napi_env env,napi_value & obj,const USBDevicePipe & pipe)144 static void CreateUsbDevicePipe(const napi_env env, napi_value &obj, const USBDevicePipe &pipe)
145 {
146     napi_create_object(env, &obj);
147     NapiUtil::SetValueInt32(env, "busNum", pipe.GetBusNum(), obj);
148     NapiUtil::SetValueInt32(env, "devAddress", pipe.GetDevAddr(), obj);
149 }
150 
CreatAccessoryHandle(const napi_env env,napi_value & obj,int32_t fd)151 static void CreatAccessoryHandle(const napi_env env, napi_value &obj, int32_t fd)
152 {
153     napi_create_object(env, &obj);
154     NapiUtil::SetValueInt32(env, "accessoryFd", fd, obj);
155 }
156 
CtoJSUsbEndpoint(const napi_env & env,napi_value & obj,const USBEndpoint & usbEndpoint)157 static void CtoJSUsbEndpoint(const napi_env &env, napi_value &obj, const USBEndpoint &usbEndpoint)
158 {
159     napi_create_object(env, &obj);
160     NapiUtil::SetValueUint32(env, "address", usbEndpoint.GetAddress(), obj);
161     NapiUtil::SetValueUint32(env, "attributes", usbEndpoint.GetAttributes(), obj);
162     NapiUtil::SetValueInt32(env, "interval", usbEndpoint.GetInterval(), obj);
163     NapiUtil::SetValueInt32(env, "maxPacketSize", usbEndpoint.GetMaxPacketSize(), obj);
164     NapiUtil::SetValueUint32(env, "direction", usbEndpoint.GetDirection(), obj);
165     NapiUtil::SetValueUint32(env, "number", usbEndpoint.GetEndpointNumber(), obj);
166     NapiUtil::SetValueUint32(env, "type", usbEndpoint.GetType(), obj);
167     NapiUtil::SetValueInt32(env, "interfaceId", usbEndpoint.GetInterfaceId(), obj);
168 }
169 
CtoJSUsbInterface(const napi_env & env,napi_value & obj,const UsbInterface & usbInterface)170 static void CtoJSUsbInterface(const napi_env &env, napi_value &obj, const UsbInterface &usbInterface)
171 {
172     napi_create_object(env, &obj);
173     NapiUtil::SetValueInt32(env, "id", usbInterface.GetId(), obj);
174     NapiUtil::SetValueInt32(env, "protocol", usbInterface.GetProtocol(), obj);
175     NapiUtil::SetValueInt32(env, "clazz", usbInterface.GetClass(), obj);
176     NapiUtil::SetValueInt32(env, "subClass", usbInterface.GetSubClass(), obj);
177     NapiUtil::SetValueInt32(env, "alternateSetting", usbInterface.GetAlternateSetting(), obj);
178     NapiUtil::SetValueUtf8String(env, "name", usbInterface.GetName(), obj);
179 
180     napi_value arr;
181     napi_create_array(env, &arr);
182     for (int32_t i = 0; i < usbInterface.GetEndpointCount(); ++i) {
183         auto usbEndpoint = usbInterface.GetEndpoint(i);
184         if (!usbEndpoint.has_value()) {
185             USB_HILOGE(MODULE_JS_NAPI, "GetEndpoint failed i=%{public}d", i);
186             return;
187         }
188 
189         napi_value objTmp;
190         CtoJSUsbEndpoint(env, objTmp, usbEndpoint.value());
191         napi_set_element(env, arr, i, objTmp);
192     }
193     napi_set_named_property(env, obj, "endpoints", arr);
194 }
195 
CtoJSUsbConfig(const napi_env & env,napi_value & obj,const USBConfig & usbConfig)196 static void CtoJSUsbConfig(const napi_env &env, napi_value &obj, const USBConfig &usbConfig)
197 {
198     napi_create_object(env, &obj);
199     NapiUtil::SetValueInt32(env, "id", usbConfig.GetId(), obj);
200     NapiUtil::SetValueUint32(env, "attributes", usbConfig.GetAttributes(), obj);
201     NapiUtil::SetValueBool(env, "isRemoteWakeup", usbConfig.IsRemoteWakeup(), obj);
202     NapiUtil::SetValueBool(env, "isSelfPowered", usbConfig.IsSelfPowered(), obj);
203     NapiUtil::SetValueInt32(env, "maxPower", usbConfig.GetMaxPower(), obj);
204     NapiUtil::SetValueUtf8String(env, "name", usbConfig.GetName(), obj);
205     napi_value arr;
206     napi_create_array(env, &arr);
207     for (uint32_t i = 0; i < usbConfig.GetInterfaceCount(); ++i) {
208         UsbInterface usbInterface;
209         usbConfig.GetInterface(i, usbInterface);
210         napi_value objTmp;
211         CtoJSUsbInterface(env, objTmp, usbInterface);
212         napi_set_element(env, arr, i, objTmp);
213     }
214     napi_set_named_property(env, obj, "interfaces", arr);
215 }
216 
CtoJSUsbDevice(const napi_env & env,napi_value & obj,const UsbDevice & usbDevice)217 static void CtoJSUsbDevice(const napi_env &env, napi_value &obj, const UsbDevice &usbDevice)
218 {
219     napi_create_object(env, &obj);
220     NapiUtil::SetValueUtf8String(env, "name", usbDevice.GetName(), obj);
221     NapiUtil::SetValueUtf8String(env, "serial", usbDevice.GetmSerial(), obj);
222     NapiUtil::SetValueUtf8String(env, "manufacturerName", usbDevice.GetManufacturerName(), obj);
223     NapiUtil::SetValueUtf8String(env, "productName", usbDevice.GetProductName(), obj);
224     NapiUtil::SetValueUtf8String(env, "version", usbDevice.GetVersion(), obj);
225     NapiUtil::SetValueInt32(env, "vendorId", usbDevice.GetVendorId(), obj);
226     NapiUtil::SetValueInt32(env, "productId", usbDevice.GetProductId(), obj);
227     NapiUtil::SetValueInt32(env, "clazz", usbDevice.GetClass(), obj);
228     NapiUtil::SetValueInt32(env, "subClass", usbDevice.GetSubclass(), obj);
229     NapiUtil::SetValueInt32(env, "protocol", usbDevice.GetProtocol(), obj);
230     NapiUtil::SetValueInt32(env, "devAddress", usbDevice.GetDevAddr(), obj);
231     NapiUtil::SetValueInt32(env, "busNum", usbDevice.GetBusNum(), obj);
232     napi_value arr;
233     napi_create_array(env, &arr);
234     for (int32_t i = 0; i < usbDevice.GetConfigCount(); ++i) {
235         USBConfig usbConfig;
236         usbDevice.GetConfig(i, usbConfig);
237         napi_value objTmp;
238         CtoJSUsbConfig(env, objTmp, usbConfig);
239         napi_set_element(env, arr, i, objTmp);
240     }
241     napi_set_named_property(env, obj, "configs", arr);
242 }
243 
CtoJSUSBAccessory(const napi_env & env,napi_value & obj,const USBAccessory & accessory)244 static void CtoJSUSBAccessory(const napi_env &env, napi_value &obj, const USBAccessory &accessory)
245 {
246     napi_create_object(env, &obj);
247     NapiUtil::SetValueUtf8String(env, "manufacturer", accessory.GetManufacturer(), obj);
248     NapiUtil::SetValueUtf8String(env, "product", accessory.GetProduct(), obj);
249     NapiUtil::SetValueUtf8String(env, "description", accessory.GetDescription(), obj);
250     NapiUtil::SetValueUtf8String(env, "version", accessory.GetVersion(), obj);
251     NapiUtil::SetValueUtf8String(env, "serialNumber", accessory.GetSerialNumber(), obj);
252 }
253 
254 static UsbSrvClient &g_usbClient = UsbSrvClient::GetInstance();
255 
256 /* ============================================= Parsers ============================================= */
257 // js to c
ParseEndpointObj(const napi_env env,const napi_value endpointObj,USBEndpoint & ep)258 static void ParseEndpointObj(const napi_env env, const napi_value endpointObj, USBEndpoint &ep)
259 {
260     int32_t address = 0;
261     NapiUtil::JsObjectToInt(env, endpointObj, "address", address);
262     int32_t attributes = 0;
263     NapiUtil::JsObjectToInt(env, endpointObj, "attributes", attributes);
264     int32_t interval = 0;
265     NapiUtil::JsObjectToInt(env, endpointObj, "interval", interval);
266     int32_t maxPacketSize = 0;
267     NapiUtil::JsObjectToInt(env, endpointObj, "maxPacketSize", maxPacketSize);
268     int32_t direction = 0;
269     NapiUtil::JsObjectToInt(env, endpointObj, "direction", direction);
270     USB_ASSERT_RETURN_VOID(env, (direction == USB_ENDPOINT_DIR_IN || direction == USB_ENDPOINT_DIR_OUT),
271         OHEC_COMMON_PARAM_ERROR, "The interface should have the endpoints property.");
272     int32_t number = 0;
273     NapiUtil::JsObjectToInt(env, endpointObj, "number", number);
274     int32_t type = 0;
275     NapiUtil::JsObjectToInt(env, endpointObj, "type", type);
276     int32_t interfaceId = 0;
277     NapiUtil::JsObjectToInt(env, endpointObj, "interfaceId", interfaceId);
278     ep = USBEndpoint(address, attributes, interval, maxPacketSize);
279     ep.SetInterfaceId(interfaceId);
280 }
281 
ParseEndpointsObjs(const napi_env env,const napi_value interfaceObj,std::vector<USBEndpoint> & eps)282 static bool ParseEndpointsObjs(const napi_env env, const napi_value interfaceObj, std::vector<USBEndpoint> &eps)
283 {
284     napi_value endpointsObjs;
285     bool isGetObjSuccess = NapiUtil::JsObjectGetProperty(env, interfaceObj, "endpoints", endpointsObjs);
286     USB_ASSERT_RETURN_FALSE(
287         env, isGetObjSuccess == true, OHEC_COMMON_PARAM_ERROR, "The interface should have the endpoints property.");
288 
289     bool result = false;
290     NAPI_CHECK_RETURN_FALSE(napi_is_array(env, endpointsObjs, &result), "Get endpoints type failed");
291     USB_ASSERT_RETURN_FALSE(env, result == true, OHEC_COMMON_PARAM_ERROR, "The type of endpoints must be array.");
292 
293     uint32_t endpointCount = 0;
294     NAPI_CHECK_RETURN_FALSE(napi_get_array_length(env, endpointsObjs, &endpointCount), "Get array length failed");
295 
296     for (uint32_t k = 0; k < endpointCount; ++k) {
297         napi_value endpointObj;
298         NAPI_CHECK_RETURN_FALSE(napi_get_element(env, endpointsObjs, k, &endpointObj), "Get endpoints element failed");
299         USBEndpoint ep;
300         ParseEndpointObj(env, endpointObj, ep);
301         eps.push_back(ep);
302     }
303 
304     return true;
305 }
306 
307 struct PipeControlParam {
308     int32_t request;
309     int32_t target;
310     uint32_t reqType;
311     int32_t value;
312     int32_t index;
313     uint8_t *data;
314     size_t dataLength;
315 };
316 
ParsePipeControlParam(const napi_env env,const napi_value jsObj,PipeControlParam & controlParam)317 static bool ParsePipeControlParam(const napi_env env, const napi_value jsObj, PipeControlParam &controlParam)
318 {
319     int32_t request = 0;
320     NapiUtil::JsObjectToInt(env, jsObj, "request", request);
321     int32_t target = 0;
322     NapiUtil::JsObjectToInt(env, jsObj, "target", target);
323     uint32_t reqType = 0;
324     NapiUtil::JsObjectToUint(env, jsObj, "reqType", reqType);
325     int32_t value = 0;
326     NapiUtil::JsObjectToInt(env, jsObj, "value", value);
327     int32_t index = 0;
328     NapiUtil::JsObjectToInt(env, jsObj, "index", index);
329 
330     napi_value dataValue;
331     bool hasProperty = NapiUtil::JsObjectGetProperty(env, jsObj, "data", dataValue);
332     USB_ASSERT_RETURN_FALSE(
333         env, hasProperty == true, OHEC_COMMON_PARAM_ERROR, "The controlParam should have the data property.");
334 
335     uint8_t *data = nullptr;
336     size_t dataLength = 0;
337     size_t offset = 0;
338     NapiUtil::JsUint8ArrayParse(env, dataValue, &data, dataLength, offset);
339     controlParam.request = request;
340     controlParam.target = target;
341     controlParam.reqType = reqType;
342     controlParam.value = value;
343     controlParam.index = index;
344     controlParam.data = data;
345     controlParam.dataLength = dataLength;
346     return true;
347 }
348 
349 struct UsbPipeControlParam {
350     uint32_t reqType;
351     int32_t request;
352     int32_t value;
353     int32_t index;
354     int32_t length;
355     uint8_t *data;
356     size_t dataLength;
357 };
358 
ParseUsbPipeControlParam(const napi_env env,const napi_value jsObj,UsbPipeControlParam & controlParam)359 static void ParseUsbPipeControlParam(const napi_env env, const napi_value jsObj, UsbPipeControlParam &controlParam)
360 {
361     uint32_t reqType = 0;
362     NapiUtil::JsObjectToUint(env, jsObj, "bmRequestType", reqType);
363     int32_t request = 0;
364     NapiUtil::JsObjectToInt(env, jsObj, "bRequest", request);
365     int32_t value = 0;
366     NapiUtil::JsObjectToInt(env, jsObj, "wValue", value);
367     int32_t index = 0;
368     NapiUtil::JsObjectToInt(env, jsObj, "wIndex", index);
369     int32_t length = 0;
370     NapiUtil::JsObjectToInt(env, jsObj, "wLength", length);
371 
372     napi_value dataValue;
373     bool hasProperty = NapiUtil::JsObjectGetProperty(env, jsObj, "data", dataValue);
374     USB_ASSERT_RETURN_VOID(
375         env, hasProperty == true, OHEC_COMMON_PARAM_ERROR, "The controlParam should have the data property.");
376 
377     uint8_t *data = nullptr;
378     size_t dataLength = 0;
379     size_t offset = 0;
380     NapiUtil::JsUint8ArrayParse(env, dataValue, &data, dataLength, offset);
381     controlParam.reqType = reqType;
382     controlParam.request = request;
383     controlParam.value = value;
384     controlParam.index = index;
385     controlParam.length = length;
386     controlParam.data = data;
387     controlParam.dataLength = dataLength;
388 }
389 
ParseInterfaceObj(const napi_env env,const napi_value interfaceObj,UsbInterface & interface)390 static void ParseInterfaceObj(const napi_env env, const napi_value interfaceObj, UsbInterface &interface)
391 {
392     int32_t id = 0;
393     NapiUtil::JsObjectToInt(env, interfaceObj, "id", id);
394     int32_t protocol = 0;
395     NapiUtil::JsObjectToInt(env, interfaceObj, "protocol", protocol);
396     int32_t clzz = 0;
397     NapiUtil::JsObjectToInt(env, interfaceObj, "clazz", clzz);
398     int32_t subClass = 0;
399     NapiUtil::JsObjectToInt(env, interfaceObj, "subClass", subClass);
400     int32_t alternateSetting = 0;
401     NapiUtil::JsObjectToInt(env, interfaceObj, "alternateSetting", alternateSetting);
402     std::string name;
403     NapiUtil::JsObjectToString(env, interfaceObj, "name", DEFAULT_DESCRIPTION_SIZE, name);
404     std::vector<USBEndpoint> eps;
405 
406     bool ret = ParseEndpointsObjs(env, interfaceObj, eps);
407     if (!ret) {
408         USB_HILOGE(MODULE_JS_NAPI, "Parse endpointers error.");
409         return;
410     }
411 
412     interface = UsbInterface(id, protocol, clzz, subClass, alternateSetting, name, eps);
413 }
414 
ParseInterfacesObjs(const napi_env env,const napi_value configObj,std::vector<UsbInterface> & interfaces)415 static bool ParseInterfacesObjs(const napi_env env, const napi_value configObj, std::vector<UsbInterface> &interfaces)
416 {
417     napi_value interfacesObjs;
418     bool isGetObjSuccess = NapiUtil::JsObjectGetProperty(env, configObj, "interfaces", interfacesObjs);
419     USB_ASSERT_RETURN_FALSE(
420         env, isGetObjSuccess == true, OHEC_COMMON_PARAM_ERROR, "The config should have the interfaces property.");
421 
422     bool result = false;
423     NAPI_CHECK_RETURN_FALSE(napi_is_array(env, interfacesObjs, &result), "Get interfaces type failed");
424     USB_ASSERT_RETURN_FALSE(env, result == true, OHEC_COMMON_PARAM_ERROR, "The type of interfaces must be array.");
425 
426     uint32_t interfaceCount = 0;
427     NAPI_CHECK_RETURN_FALSE(napi_get_array_length(env, interfacesObjs, &interfaceCount), "Get array length failed");
428 
429     for (uint32_t i = 0; i < interfaceCount; ++i) {
430         napi_value interfaceObj;
431         NAPI_CHECK_RETURN_FALSE(
432             napi_get_element(env, interfacesObjs, i, &interfaceObj), "Get interfaces element failed");
433 
434         UsbInterface interface;
435         ParseInterfaceObj(env, interfaceObj, interface);
436         interfaces.push_back(interface);
437     }
438 
439     return true;
440 }
441 
ParseConfigObj(const napi_env env,const napi_value configObj,USBConfig & config)442 static void ParseConfigObj(const napi_env env, const napi_value configObj, USBConfig &config)
443 {
444     int32_t id = 0;
445     NapiUtil::JsObjectToInt(env, configObj, "id", id);
446     int32_t attributes = 0;
447     NapiUtil::JsObjectToInt(env, configObj, "attributes", attributes);
448     int32_t maxPower = 0;
449     NapiUtil::JsObjectToInt(env, configObj, "maxPower", maxPower);
450     std::string name;
451     NapiUtil::JsObjectToString(env, configObj, "name", DEFAULT_DESCRIPTION_SIZE, name);
452     bool isRemoteWakeup = false;
453     NapiUtil::JsObjectToBool(env, configObj, "isRemoteWakeup", isRemoteWakeup);
454     bool isSelfPowered = false;
455     NapiUtil::JsObjectToBool(env, configObj, "isSelfPowered", isSelfPowered);
456 
457     std::vector<UsbInterface> interfaces;
458     bool ret = ParseInterfacesObjs(env, configObj, interfaces);
459     if (!ret) {
460         USB_HILOGE(MODULE_JS_NAPI, "Parse interfaces error.");
461         return;
462     }
463 
464     config = USBConfig(id, attributes, name, maxPower, interfaces);
465 }
466 
ParseConfigsObjs(const napi_env env,const napi_value deviceObj,std::vector<USBConfig> & configs)467 static void ParseConfigsObjs(const napi_env env, const napi_value deviceObj, std::vector<USBConfig> &configs)
468 {
469     napi_value configsObj;
470     bool hasProperty = NapiUtil::JsObjectGetProperty(env, deviceObj, "configs", configsObj);
471     USB_ASSERT_RETURN_VOID(
472         env, hasProperty == true, OHEC_COMMON_PARAM_ERROR, "The device should have the configs property.");
473     napi_valuetype valueType;
474     napi_typeof(env, configsObj, &valueType);
475     USB_ASSERT_RETURN_VOID(
476         env, valueType == napi_object, OHEC_COMMON_PARAM_ERROR, "The type of configs must be object.");
477 
478     uint32_t configCount = 0;
479     napi_get_array_length(env, configsObj, &configCount);
480     for (uint32_t i = 0; i < configCount; ++i) {
481         napi_value configObj;
482         napi_get_element(env, configsObj, i, &configObj);
483         USBConfig config;
484         ParseConfigObj(env, configObj, config);
485         configs.push_back(config);
486     }
487 }
488 
ParseDeviceObj(const napi_env env,const napi_value deviceObj,UsbDevice & dev)489 static void ParseDeviceObj(const napi_env env, const napi_value deviceObj, UsbDevice &dev)
490 {
491     std::string name;
492     NapiUtil::JsObjectToString(env, deviceObj, "name", DEFAULT_DESCRIPTION_SIZE, name);
493     std::string manufacturerName;
494     NapiUtil::JsObjectToString(env, deviceObj, "manufacturerName", DEFAULT_DESCRIPTION_SIZE, manufacturerName);
495     std::string productName;
496     NapiUtil::JsObjectToString(env, deviceObj, "productName", DEFAULT_DESCRIPTION_SIZE, productName);
497     std::string version;
498     NapiUtil::JsObjectToString(env, deviceObj, "version", DEFAULT_DESCRIPTION_SIZE, version);
499     std::string serial;
500     NapiUtil::JsObjectToString(env, deviceObj, "serial", DEFAULT_DESCRIPTION_SIZE, serial);
501     int32_t devAddr = 0;
502     NapiUtil::JsObjectToInt(env, deviceObj, "devAddress", devAddr);
503     int32_t busNum = 0;
504     NapiUtil::JsObjectToInt(env, deviceObj, "busNum", busNum);
505     int32_t vendorId = 0;
506     NapiUtil::JsObjectToInt(env, deviceObj, "vendorId", vendorId);
507     int32_t productId = 0;
508     NapiUtil::JsObjectToInt(env, deviceObj, "productId", productId);
509     int32_t clazz = 0;
510     NapiUtil::JsObjectToInt(env, deviceObj, "clazz", clazz);
511     int32_t subClass = 0;
512     NapiUtil::JsObjectToInt(env, deviceObj, "subClass", subClass);
513     int32_t protocol = 0;
514     NapiUtil::JsObjectToInt(env, deviceObj, "protocol", protocol);
515     std::vector<USBConfig> configs;
516     ParseConfigsObjs(env, deviceObj, configs);
517     dev = UsbDevice(name, manufacturerName, productName, version, devAddr, busNum, vendorId, productId, clazz, subClass,
518         protocol, configs);
519 }
520 
ParseAccessoryObj(const napi_env env,const napi_value accessoryObj,USBAccessory & accessory)521 static void ParseAccessoryObj(const napi_env env, const napi_value accessoryObj, USBAccessory &accessory)
522 {
523     std::string manufacturer;
524     NapiUtil::JsObjectToString(env, accessoryObj, "manufacturer", DEFAULT_ACCESSORY_DESCRIPTION_SIZE, manufacturer);
525     std::string product;
526     NapiUtil::JsObjectToString(env, accessoryObj, "product", DEFAULT_ACCESSORY_DESCRIPTION_SIZE, product);
527     std::string description;
528     NapiUtil::JsObjectToString(env, accessoryObj, "description", DEFAULT_ACCESSORY_DESCRIPTION_SIZE, description);
529     std::string version;
530     NapiUtil::JsObjectToString(env, accessoryObj, "version", DEFAULT_ACCESSORY_DESCRIPTION_SIZE, version);
531     std::string serialNumber;
532     NapiUtil::JsObjectToString(env, accessoryObj, "serialNumber", DEFAULT_ACCESSORY_DESCRIPTION_SIZE, serialNumber);
533     accessory = USBAccessory(manufacturer, product, description, version, serialNumber);
534 }
535 
536 /* ============================================= Usb Core ============================================= */
537 
CoreGetDevices(napi_env env,napi_callback_info info)538 static napi_value CoreGetDevices(napi_env env, napi_callback_info info)
539 {
540     if (!HasFeature(FEATURE_HOST)) {
541         ThrowBusinessError(env, CAPABILITY_NOT_SUPPORT, "");
542         return nullptr;
543     }
544     size_t argc = PARAM_COUNT_1;
545     napi_value argv[PARAM_COUNT_1] = {nullptr};
546     napi_get_cb_info(env, info, &argc, argv, nullptr, nullptr);
547     USB_ASSERT(env, (argc == PARAM_COUNT_0), OHEC_COMMON_PARAM_ERROR, "The function takes no arguments.");
548 
549     std::vector<UsbDevice> deviceList;
550     int32_t ret = g_usbClient.GetDevices(deviceList);
551     napi_value result;
552     if (ret != UEC_OK) {
553         napi_get_undefined(env, &result);
554         USB_HILOGE(MODULE_JS_NAPI, "end call get device failed ret : %{public}d", ret);
555         return result;
556     }
557 
558     napi_create_array(env, &result);
559     int32_t i = 0;
560     for (const auto &ent1 : deviceList) {
561         napi_value element;
562         napi_create_object(env, &element);
563         napi_value device;
564         CtoJSUsbDevice(env, device, ent1);
565         napi_set_element(env, result, i, device);
566         ++i;
567     }
568 
569     return result;
570 }
571 
DeviceGetAccessoryList(napi_env env,napi_callback_info info)572 static napi_value DeviceGetAccessoryList(napi_env env, napi_callback_info info)
573 {
574     if (!HasFeature(FEATURE_DEVICE)) {
575         ThrowBusinessError(env, CAPABILITY_NOT_SUPPORT, "");
576         return nullptr;
577     }
578     size_t argc = PARAM_COUNT_1;
579     napi_value argv[PARAM_COUNT_1] = {nullptr};
580     napi_get_cb_info(env, info, &argc, argv, nullptr, nullptr);
581     USB_ASSERT(env, (argc == PARAM_COUNT_0), OHEC_COMMON_PARAM_ERROR, "The function takes no arguments.");
582 
583     std::vector<USBAccessory> accessoryList;
584     int32_t ret = g_usbClient.GetAccessoryList(accessoryList);
585     if (ret == UEC_OK) {
586         napi_value result;
587         napi_create_array(env, &result);
588         int32_t i = 0;
589         for (const auto &ent1 : accessoryList) {
590             napi_value element;
591             napi_create_object(env, &element);
592             napi_value device;
593             CtoJSUSBAccessory(env, device, ent1);
594             napi_set_element(env, result, i, device);
595             ++i;
596         }
597         return result;
598     } else {
599         ThrowBusinessError(env, UEC_COMMON_SERVICE_EXCEPTION,
600             "Service exception");
601     }
602     return nullptr;
603 }
604 
CoreConnectDevice(napi_env env,napi_callback_info info)605 static napi_value CoreConnectDevice(napi_env env, napi_callback_info info)
606 {
607     if (!HasFeature(FEATURE_HOST)) {
608         ThrowBusinessError(env, CAPABILITY_NOT_SUPPORT, "");
609         return nullptr;
610     }
611     size_t argc = PARAM_COUNT_1;
612     napi_value argv[PARAM_COUNT_1] = {nullptr};
613     NAPI_CHECK(env, napi_get_cb_info(env, info, &argc, argv, nullptr, nullptr), "Get call back info failed");
614     USB_ASSERT(env, (argc >= PARAM_COUNT_1), OHEC_COMMON_PARAM_ERROR, "The function at least takes one argument.");
615 
616     napi_value deviceObj = argv[INDEX_0];
617     napi_valuetype type;
618     NAPI_CHECK(env, napi_typeof(env, deviceObj, &type), "Get deviceObj type failed");
619     USB_ASSERT(env, type == napi_object, OHEC_COMMON_PARAM_ERROR, "The type of device must be USBDevice.");
620     UsbDevice dev;
621     ParseDeviceObj(env, deviceObj, dev);
622 
623     USBDevicePipe pipe;
624     int32_t ret = g_usbClient.OpenDevice(dev, pipe);
625     napi_value pipObj = nullptr;
626     if (ret == UEC_OK) {
627         CreateUsbDevicePipe(env, pipObj, pipe);
628     } else if (ret == UEC_SERVICE_PERMISSION_DENIED || ret == UEC_INTERFACE_PERMISSION_DENIED) {
629         ThrowBusinessError(env, UEC_COMMON_HAS_NO_RIGHT,
630             "need call requestRight to get the permission");
631     } else {
632         napi_get_undefined(env, &pipObj);
633     }
634 
635     return pipObj;
636 }
637 
DeviceOpenAccessory(napi_env env,napi_callback_info info)638 static napi_value DeviceOpenAccessory(napi_env env, napi_callback_info info)
639 {
640     if (!HasFeature(FEATURE_DEVICE)) {
641         ThrowBusinessError(env, CAPABILITY_NOT_SUPPORT, "");
642         return nullptr;
643     }
644     size_t argc = PARAM_COUNT_1;
645     napi_value argv[PARAM_COUNT_1] = {nullptr};
646     NAPI_CHECK(env, napi_get_cb_info(env, info, &argc, argv, nullptr, nullptr), "Get call back info failed");
647     USB_ASSERT(env, (argc >= PARAM_COUNT_1), OHEC_COMMON_PARAM_ERROR, "The function at least takes one argument.");
648 
649     napi_value accessoryObj = argv[INDEX_0];
650     napi_valuetype type;
651     NAPI_CHECK(env, napi_typeof(env, accessoryObj, &type), "Get accessoryObj type failed");
652     USB_ASSERT(env, type == napi_object, OHEC_COMMON_PARAM_ERROR, "The type of device must be USBAccessory.");
653     USBAccessory accessory;
654     ParseAccessoryObj(env, accessoryObj, accessory);
655 
656     int32_t fd = -1;
657     int32_t ret = g_usbClient.OpenAccessory(accessory, fd);
658 
659     napi_value handleObj = nullptr;
660     if (ret == UEC_OK) {
661         g_accFd = fd;
662         CreatAccessoryHandle(env, handleObj, fd);
663     } else if (ret == UEC_SERVICE_PERMISSION_DENIED || ret == UEC_INTERFACE_PERMISSION_DENIED) {
664         ThrowBusinessError(env, UEC_COMMON_HAS_NO_RIGHT,
665             "Call requestAccessoryRight to get the permission first");
666     } else if (ret == UEC_SERVICE_ACCESSORY_NOT_MATCH) {
667         ThrowBusinessError(env, UEC_ACCESSORY_NOT_MATCH,
668             "Get accessory through getAccessoryList");
669     } else if (ret == UEC_SERVICE_ACCESSORY_OPEN_NATIVE_NODE_FAILED) {
670         ThrowBusinessError(env, UEC_ACCESSORY_OPEN_FAILED,
671             "Failed to open the native accessory node");
672     } else if (ret == UEC_SERVICE_ACCESSORY_REOPEN) {
673         ThrowBusinessError(env, UEC_ACCESSORY_CAN_NOT_REOPEN,
674             "Cannot reopen accessory");
675     } else {
676         ThrowBusinessError(env, UEC_COMMON_SERVICE_EXCEPTION,
677             "Service exception");
678     }
679     return handleObj;
680 }
681 
DeviceCloseAccessory(napi_env env,napi_callback_info info)682 static napi_value DeviceCloseAccessory(napi_env env, napi_callback_info info)
683 {
684     if (!HasFeature(FEATURE_DEVICE)) {
685         ThrowBusinessError(env, CAPABILITY_NOT_SUPPORT, "");
686         return nullptr;
687     }
688     size_t argc = PARAM_COUNT_1;
689     napi_value argv[PARAM_COUNT_1] = {nullptr};
690     NAPI_CHECK(env, napi_get_cb_info(env, info, &argc, argv, nullptr, nullptr), "Get call back info failed");
691     USB_ASSERT(env, (argc >= PARAM_COUNT_1), OHEC_COMMON_PARAM_ERROR, "The function at least takes one argument.");
692 
693     napi_value accessoryFdObj = argv[INDEX_0];
694     napi_valuetype type;
695     NAPI_CHECK(env, napi_typeof(env, accessoryFdObj, &type), "Get accessoryObj type failed");
696     USB_ASSERT(env, type == napi_object, OHEC_COMMON_PARAM_ERROR, "The type of device must be USBAccessoryHandle.");
697     int32_t accessoryFd;
698     NapiUtil::JsObjectToInt(env, argv[INDEX_0], "accessoryFd", accessoryFd);
699     if (accessoryFd == 0 || accessoryFd != g_accFd || g_accFd == 0) {
700         ThrowBusinessError(env, OHEC_COMMON_PARAM_ERROR,
701             "Parameter accessoryHandle error, need openAccessory first.");
702     }
703     close(accessoryFd);
704     accessoryFd = 0;
705     int32_t ret = g_usbClient.CloseAccessory(g_accFd);
706     g_accFd = 0;
707     if (ret != UEC_OK) {
708         ThrowBusinessError(env, UEC_COMMON_SERVICE_EXCEPTION,
709             "Service exception");
710     }
711     return nullptr;
712 }
713 
DeviceAddRight(napi_env env,napi_callback_info info)714 static napi_value DeviceAddRight(napi_env env, napi_callback_info info)
715 {
716     if (!HasFeature(FEATURE_HOST)) {
717         ThrowBusinessError(env, CAPABILITY_NOT_SUPPORT, "");
718         return nullptr;
719     }
720     size_t argc = PARAM_COUNT_2;
721     napi_value argv[PARAM_COUNT_2] = {nullptr};
722     NAPI_CHECK(env, napi_get_cb_info(env, info, &argc, argv, nullptr, nullptr), "Get call back info failed");
723     USB_ASSERT(env, (argc >= PARAM_COUNT_2), OHEC_COMMON_PARAM_ERROR, "The function at least takes two argument.");
724 
725     napi_valuetype type;
726     NAPI_CHECK(env, napi_typeof(env, argv[INDEX_0], &type), "Get args 1 type failed");
727     USB_ASSERT(env, type == napi_string, OHEC_COMMON_PARAM_ERROR, "The type of bundleName must be string.");
728     std::string bundleName;
729     NapiUtil::JsValueToString(env, argv[INDEX_0], STR_DEFAULT_SIZE, bundleName);
730 
731     NAPI_CHECK(env, napi_typeof(env, argv[INDEX_1], &type), "Get args 2 type failed");
732     USB_ASSERT(env, type == napi_string, OHEC_COMMON_PARAM_ERROR, "The type of deviceName must be string.");
733     std::string deviceName;
734     NapiUtil::JsValueToString(env, argv[INDEX_1], STR_DEFAULT_SIZE, deviceName);
735 
736     napi_value result;
737     int32_t ret = g_usbClient.AddRight(bundleName, deviceName);
738     USB_HILOGD(MODULE_JS_NAPI, "Device call AddRight ret: %{public}d", ret);
739     if (ret == UEC_OK) {
740         napi_get_boolean(env, true, &result);
741     } else {
742         USB_ASSERT_RETURN_UNDEF(env, (ret != UEC_SERVICE_PERMISSION_DENIED_SYSAPI),
743             OHEC_COMMON_NORMAL_APP_NOT_ALLOWED, "");
744         USB_ASSERT_RETURN_UNDEF(env, (ret != UEC_SERVICE_PERMISSION_DENIED_SYSAPI_FAILED),
745             OHEC_COMMON_PERMISSION_NOT_ALLOWED, "");
746         napi_get_boolean(env, false, &result);
747     }
748     return result;
749 }
750 
DeviceAddAccessoryRight(napi_env env,napi_callback_info info)751 static napi_value DeviceAddAccessoryRight(napi_env env, napi_callback_info info)
752 {
753     if (!HasFeature(FEATURE_DEVICE)) {
754         ThrowBusinessError(env, CAPABILITY_NOT_SUPPORT, "");
755         return nullptr;
756     }
757     size_t argc = PARAM_COUNT_2;
758     napi_value argv[PARAM_COUNT_2] = {nullptr};
759     NAPI_CHECK(env, napi_get_cb_info(env, info, &argc, argv, nullptr, nullptr), "Get call back info failed");
760     USB_ASSERT(env, (argc >= PARAM_COUNT_2), OHEC_COMMON_PARAM_ERROR, "The function at least takes two argument.");
761 
762     napi_valuetype type;
763     NAPI_CHECK(env, napi_typeof(env, argv[INDEX_0], &type), "Get args 1 type failed");
764     USB_ASSERT(env, type == napi_number, OHEC_COMMON_PARAM_ERROR, "The type of tokenId must be number.");
765     uint32_t tokenId;
766     napi_get_value_uint32(env, argv[INDEX_0], &tokenId);
767 
768     napi_value accessoryObj = argv[INDEX_1];
769     napi_valuetype type1;
770     NAPI_CHECK(env, napi_typeof(env, accessoryObj, &type1), "Get accessoryObj type failed");
771     USB_ASSERT(env, type1 == napi_object, OHEC_COMMON_PARAM_ERROR, "The type of device must be USBAccessory.");
772     USBAccessory accessory;
773     ParseAccessoryObj(env, accessoryObj, accessory);
774 
775     int32_t ret = g_usbClient.AddAccessoryRight(tokenId, accessory);
776     if (ret == UEC_OK) {
777         return nullptr;
778     } else if (ret == UEC_SERVICE_GET_TOKEN_INFO_FAILED) {
779         ThrowBusinessError(env, OHEC_COMMON_PARAM_ERROR, "");
780     } else if (ret == UEC_SERVICE_ACCESSORY_NOT_MATCH) {
781         ThrowBusinessError(env, OHEC_COMMON_PARAM_ERROR,
782             "Get accessory through getAccessoryList");
783     } else if (ret == UEC_SERVICE_DATABASE_OPERATION_FAILED) {
784         ThrowBusinessError(env, UEC_COMMON_RIGHT_DATABASE_ERROR,
785             "Database request operation exception");
786     } else {
787         USB_ASSERT_RETURN_UNDEF(env, (ret != UEC_SERVICE_PERMISSION_DENIED_SYSAPI),
788             OHEC_COMMON_NORMAL_APP_NOT_ALLOWED, "");
789         USB_ASSERT_RETURN_UNDEF(env, (ret != UEC_SERVICE_PERMISSION_DENIED_SYSAPI_FAILED),
790             OHEC_COMMON_PERMISSION_NOT_ALLOWED, "");
791         ThrowBusinessError(env, UEC_COMMON_SERVICE_EXCEPTION,
792             "Service exception");
793     }
794     USB_HILOGD(MODULE_JS_NAPI, "Device call AddAccessoryRight ret: %{public}d", ret);
795     return nullptr;
796 }
797 
DeviceAddAccessRight(napi_env env,napi_callback_info info)798 static napi_value DeviceAddAccessRight(napi_env env, napi_callback_info info)
799 {
800     if (!HasFeature(FEATURE_HOST)) {
801         ThrowBusinessError(env, CAPABILITY_NOT_SUPPORT, "");
802         return nullptr;
803     }
804     size_t argc = PARAM_COUNT_2;
805     napi_value argv[PARAM_COUNT_2] = {nullptr};
806     NAPI_CHECK(env, napi_get_cb_info(env, info, &argc, argv, nullptr, nullptr), "Get call back info failed");
807     USB_ASSERT(env, (argc >= PARAM_COUNT_2), OHEC_COMMON_PARAM_ERROR, "The function at least takes two argument.");
808 
809     napi_valuetype type;
810     NAPI_CHECK(env, napi_typeof(env, argv[INDEX_0], &type), "Get args 1 type failed");
811     USB_ASSERT(env, type == napi_string, OHEC_COMMON_PARAM_ERROR, "The type of tokenId must be string.");
812     std::string tokenId;
813     NapiUtil::JsValueToString(env, argv[INDEX_0], STR_DEFAULT_SIZE, tokenId);
814 
815     NAPI_CHECK(env, napi_typeof(env, argv[INDEX_1], &type), "Get args 2 type failed");
816     USB_ASSERT(env, type == napi_string, OHEC_COMMON_PARAM_ERROR, "The type of deviceName must be string.");
817     std::string deviceName;
818     NapiUtil::JsValueToString(env, argv[INDEX_1], STR_DEFAULT_SIZE, deviceName);
819 
820     napi_value result;
821     int32_t ret = g_usbClient.AddAccessRight(tokenId, deviceName);
822     USB_HILOGD(MODULE_JS_NAPI, "Device call AddRight ret: %{public}d", ret);
823     if (ret == UEC_OK) {
824         napi_get_boolean(env, true, &result);
825     } else {
826         USB_ASSERT_RETURN_UNDEF(env, (ret != UEC_SERVICE_PERMISSION_DENIED_SYSAPI),
827             OHEC_COMMON_NORMAL_APP_NOT_ALLOWED, "");
828         USB_ASSERT_RETURN_UNDEF(env, (ret != UEC_SERVICE_PERMISSION_DENIED_SYSAPI_FAILED),
829             OHEC_COMMON_PERMISSION_NOT_ALLOWED, "");
830         napi_get_boolean(env, false, &result);
831     }
832     return result;
833 }
834 
DeviceRemoveRight(napi_env env,napi_callback_info info)835 static napi_value DeviceRemoveRight(napi_env env, napi_callback_info info)
836 {
837     if (!HasFeature(FEATURE_HOST)) {
838         ThrowBusinessError(env, CAPABILITY_NOT_SUPPORT, "");
839         return nullptr;
840     }
841     size_t argc = PARAM_COUNT_1;
842     napi_value argv[PARAM_COUNT_1] = {nullptr};
843     NAPI_CHECK(env, napi_get_cb_info(env, info, &argc, argv, nullptr, nullptr), "Get call back info failed");
844     USB_ASSERT(env, (argc >= PARAM_COUNT_1), OHEC_COMMON_PARAM_ERROR, "The function at least takes one argument.");
845 
846     napi_valuetype type;
847     NAPI_CHECK(env, napi_typeof(env, argv[INDEX_0], &type), "Get args 1 type failed");
848     USB_ASSERT(env, type == napi_string, OHEC_COMMON_PARAM_ERROR, "The type of deviceName must be string.");
849     std::string deviceName;
850     NapiUtil::JsValueToString(env, argv[INDEX_0], STR_DEFAULT_SIZE, deviceName);
851 
852     napi_value result;
853     int32_t ret = g_usbClient.RemoveRight(deviceName);
854     USB_HILOGD(MODULE_JS_NAPI, "Device call RemoveRight ret: %{public}d", ret);
855     if (ret == UEC_OK) {
856         napi_get_boolean(env, true, &result);
857     } else {
858         napi_get_boolean(env, false, &result);
859     }
860 
861     return result;
862 }
863 
DeviceCancelAccessoryRight(napi_env env,napi_callback_info info)864 static napi_value DeviceCancelAccessoryRight(napi_env env, napi_callback_info info)
865 {
866     if (!HasFeature(FEATURE_DEVICE)) {
867         ThrowBusinessError(env, CAPABILITY_NOT_SUPPORT, "");
868         return nullptr;
869     }
870     size_t argc = PARAM_COUNT_1;
871     napi_value argv[PARAM_COUNT_1] = {nullptr};
872     NAPI_CHECK(env, napi_get_cb_info(env, info, &argc, argv, nullptr, nullptr), "Get call back info failed");
873     USB_ASSERT(env, (argc >= PARAM_COUNT_1), OHEC_COMMON_PARAM_ERROR, "The function at least takes one argument.");
874 
875     napi_value accessoryObj = argv[INDEX_0];
876     napi_valuetype type;
877     NAPI_CHECK(env, napi_typeof(env, accessoryObj, &type), "Get accessoryObj type failed");
878     USB_ASSERT(env, type == napi_object, OHEC_COMMON_PARAM_ERROR, "The type of device must be USBAccessory.");
879     USBAccessory accessory;
880     ParseAccessoryObj(env, accessoryObj, accessory);
881 
882     if (g_accFd != 0) {
883         close(g_accFd);
884         g_accFd = 0;
885         g_usbClient.CloseAccessory(g_accFd);
886     }
887 
888     int32_t ret = g_usbClient.CancelAccessoryRight(accessory);
889     if (ret == UEC_OK) {
890         return nullptr;
891     } else if (ret == UEC_SERVICE_ACCESSORY_NOT_MATCH) {
892         ThrowBusinessError(env, UEC_ACCESSORY_NOT_MATCH,
893             "Get accessory through getAccessoryList");
894     } else if (ret == UEC_SERVICE_DATABASE_OPERATION_FAILED) {
895         ThrowBusinessError(env, UEC_COMMON_RIGHT_DATABASE_ERROR,
896             "Database request operation exception");
897     } else {
898         ThrowBusinessError(env, UEC_COMMON_SERVICE_EXCEPTION,
899             "Service exception");
900     }
901     USB_HILOGD(MODULE_JS_NAPI, "Device call RemoveRight ret: %{public}d", ret);
902     return nullptr;
903 }
904 
CoreHasRight(napi_env env,napi_callback_info info)905 static napi_value CoreHasRight(napi_env env, napi_callback_info info)
906 {
907     if (!HasFeature(FEATURE_HOST)) {
908         ThrowBusinessError(env, CAPABILITY_NOT_SUPPORT, "");
909         return nullptr;
910     }
911     size_t argc = PARAM_COUNT_1;
912     napi_value args[PARAM_COUNT_1] = {nullptr};
913     NAPI_CHECK(env, napi_get_cb_info(env, info, &argc, args, nullptr, nullptr), "Get call back info failed");
914     USB_ASSERT(env, (argc >= PARAM_COUNT_1), OHEC_COMMON_PARAM_ERROR, "The function at least takes one argument.");
915 
916     napi_valuetype type;
917     NAPI_CHECK(env, napi_typeof(env, args[INDEX_0], &type), "Get args 1 type failed");
918     USB_ASSERT(env, type == napi_string, OHEC_COMMON_PARAM_ERROR, "The type of deviceName must be string");
919     std::string deviceName;
920     NapiUtil::JsValueToString(env, args[INDEX_0], STR_DEFAULT_SIZE, deviceName);
921 
922     bool result = g_usbClient.HasRight(deviceName);
923     USB_HILOGD(MODULE_JS_NAPI, "client called result %{public}d", result);
924 
925     napi_value napiValue = nullptr;
926     napi_get_boolean(env, result, &napiValue);
927 
928     return napiValue;
929 }
930 
DeviceHasAccessoryRight(napi_env env,napi_callback_info info)931 static napi_value DeviceHasAccessoryRight(napi_env env, napi_callback_info info)
932 {
933     if (!HasFeature(FEATURE_DEVICE)) {
934         ThrowBusinessError(env, CAPABILITY_NOT_SUPPORT, "");
935         return nullptr;
936     }
937     size_t argc = PARAM_COUNT_1;
938     napi_value args[PARAM_COUNT_1] = {nullptr};
939     NAPI_CHECK(env, napi_get_cb_info(env, info, &argc, args, nullptr, nullptr), "Get call back info failed");
940     USB_ASSERT(env, (argc >= PARAM_COUNT_1), OHEC_COMMON_PARAM_ERROR, "The function at least takes one argument.");
941 
942     napi_value accessoryObj = args[INDEX_0];
943     napi_valuetype type;
944     NAPI_CHECK(env, napi_typeof(env, accessoryObj, &type), "Get accessoryObj type failed");
945     USB_ASSERT(env, type == napi_object, OHEC_COMMON_PARAM_ERROR, "The type of device must be USBAccessory.");
946     USBAccessory accessory;
947     ParseAccessoryObj(env, accessoryObj, accessory);
948     bool result = false;
949     int32_t ret = g_usbClient.HasAccessoryRight(accessory, result);
950     if (ret == UEC_OK) {
951         napi_value napiValue = nullptr;
952         napi_get_boolean(env, result, &napiValue);
953         return napiValue;
954     } else if (ret == UEC_SERVICE_ACCESSORY_NOT_MATCH) {
955         ThrowBusinessError(env, UEC_ACCESSORY_NOT_MATCH,
956             "Get accessory through getAccessoryList");
957     } else if (ret == UEC_SERVICE_DATABASE_OPERATION_FAILED) {
958         ThrowBusinessError(env, UEC_COMMON_RIGHT_DATABASE_ERROR,
959             "Database request operation exception");
960     } else {
961         ThrowBusinessError(env, UEC_COMMON_SERVICE_EXCEPTION,
962             "Service exception");
963     }
964 
965     return nullptr;
966 }
967 
__anon1e011ede0102(napi_env env, void *data) 968 static auto g_requestRightExecute = [](napi_env env, void *data) {
969     USBRightAsyncContext *asyncContext = reinterpret_cast<USBRightAsyncContext *>(data);
970     int32_t ret = g_usbClient.RequestRight(asyncContext->deviceName);
971     if (ret == UEC_OK) {
972         asyncContext->status = napi_ok;
973     } else {
974         asyncContext->status = napi_generic_failure;
975     }
976 };
977 
__anon1e011ede0202(napi_env env, napi_status status, void *data) 978 static auto g_requestRightComplete = [](napi_env env, napi_status status, void *data) {
979     USBRightAsyncContext *asyncContext = reinterpret_cast<USBRightAsyncContext *>(data);
980     napi_value queryResult = nullptr;
981     napi_get_boolean(env, asyncContext->status == napi_ok, &queryResult);
982 
983     if (asyncContext->deferred) {
984         napi_resolve_deferred(env, asyncContext->deferred, queryResult);
985     }
986     napi_delete_async_work(env, asyncContext->work);
987     delete asyncContext;
988 };
989 
CoreRequestRight(napi_env env,napi_callback_info info)990 static napi_value CoreRequestRight(napi_env env, napi_callback_info info)
991 {
992     if (!HasFeature(FEATURE_HOST)) {
993         ThrowBusinessError(env, CAPABILITY_NOT_SUPPORT, "");
994         return nullptr;
995     }
996     size_t argc = PARAM_COUNT_1;
997     napi_value args[PARAM_COUNT_1] = {nullptr};
998     NAPI_CHECK(env, napi_get_cb_info(env, info, &argc, args, nullptr, nullptr), "Get call back info failed");
999     USB_ASSERT(env, (argc >= PARAM_COUNT_1), OHEC_COMMON_PARAM_ERROR, "The function at least takes one argument.");
1000 
1001     napi_valuetype type;
1002     NAPI_CHECK(env, napi_typeof(env, args[INDEX_0], &type), "Get args 1 type failed");
1003     USB_ASSERT(env, type == napi_string, OHEC_COMMON_PARAM_ERROR, "The type of deviceName must be string.");
1004     std::string deviceName;
1005     NapiUtil::JsValueToString(env, args[INDEX_0], STR_DEFAULT_SIZE, deviceName);
1006 
1007     auto asyncContext = new (std::nothrow) USBRightAsyncContext();
1008     if (asyncContext == nullptr) {
1009         USB_HILOGE(MODULE_JS_NAPI, "Create USBRightAsyncContext failed.");
1010         return nullptr;
1011     }
1012 
1013     asyncContext->env = env;
1014     asyncContext->deviceName = deviceName;
1015 
1016     napi_value result = nullptr;
1017     napi_create_promise(env, &asyncContext->deferred, &result);
1018 
1019     napi_value resource = nullptr;
1020     napi_create_string_utf8(env, "RequestRight", NAPI_AUTO_LENGTH, &resource);
1021 
1022     napi_create_async_work(env, nullptr, resource, g_requestRightExecute, g_requestRightComplete,
1023         reinterpret_cast<void *>(asyncContext), &asyncContext->work);
1024     napi_queue_async_work(env, asyncContext->work);
1025 
1026     return result;
1027 }
1028 
__anon1e011ede0302(napi_env env, void *data) 1029 static auto g_requestAccessoryRightExecute = [](napi_env env, void *data) {
1030     if (data == nullptr) {
1031         USB_HILOGE(MODULE_JS_NAPI, "Failed to create async work, data is nullptr");
1032         return;
1033     }
1034     USBAccessoryRightAsyncContext *asyncContext = reinterpret_cast<USBAccessoryRightAsyncContext *>(data);
1035     bool result = false;
1036     asyncContext->errCode = g_usbClient.RequestAccessoryRight(asyncContext->accessory, result);
1037     asyncContext->hasRight = result;
1038 };
1039 
__anon1e011ede0402(napi_env env, napi_status status, void *data) 1040 static auto g_requestAccessoryRightComplete = [](napi_env env, napi_status status, void *data) {
1041     if (data == nullptr) {
1042         USB_HILOGE(MODULE_JS_NAPI, "Failed to create async work, data is nullptr");
1043         return;
1044     }
1045     USBAccessoryRightAsyncContext *asyncContext = reinterpret_cast<USBAccessoryRightAsyncContext *>(data);
1046     napi_value queryResult = nullptr;
1047 
1048     if (asyncContext->errCode == UEC_OK) {
1049         asyncContext->status = napi_ok;
1050         napi_get_boolean(env, asyncContext->hasRight, &queryResult);
1051     } else if (asyncContext->errCode == UEC_SERVICE_ACCESSORY_NOT_MATCH) {
1052         asyncContext->status = napi_generic_failure;
1053         queryResult = CreateBusinessError(env, UEC_ACCESSORY_NOT_MATCH, "");
1054     } else if (asyncContext->errCode == UEC_SERVICE_DATABASE_OPERATION_FAILED) {
1055         asyncContext->status = napi_generic_failure;
1056         queryResult = CreateBusinessError(env, UEC_COMMON_RIGHT_DATABASE_ERROR, "");
1057     } else {
1058         asyncContext->status = napi_generic_failure;
1059         queryResult = CreateBusinessError(env, UEC_COMMON_SERVICE_EXCEPTION, "");
1060     }
1061     ProcessPromise(env, *asyncContext, queryResult);
1062     napi_delete_async_work(env, asyncContext->work);
1063     delete asyncContext;
1064     asyncContext = nullptr;
1065 };
1066 
DeviceRequestAccessoryRight(napi_env env,napi_callback_info info)1067 static napi_value DeviceRequestAccessoryRight(napi_env env, napi_callback_info info)
1068 {
1069     if (!HasFeature(FEATURE_DEVICE)) {
1070         ThrowBusinessError(env, CAPABILITY_NOT_SUPPORT, "");
1071         return nullptr;
1072     }
1073     size_t argc = PARAM_COUNT_1;
1074     napi_value args[PARAM_COUNT_1] = {nullptr};
1075     NAPI_CHECK(env, napi_get_cb_info(env, info, &argc, args, nullptr, nullptr), "Get call back info failed");
1076     USB_ASSERT(env, (argc >= PARAM_COUNT_1), OHEC_COMMON_PARAM_ERROR, "The function at least takes one argument.");
1077 
1078     napi_value accessoryObj = args[INDEX_0];
1079     napi_valuetype type;
1080     NAPI_CHECK(env, napi_typeof(env, accessoryObj, &type), "Get accessoryObj type failed");
1081     USB_ASSERT(env, type == napi_object, OHEC_COMMON_PARAM_ERROR, "The type of device must be USBAccessory.");
1082     USBAccessory accessory;
1083     ParseAccessoryObj(env, accessoryObj, accessory);
1084 
1085     auto asyncContext = new (std::nothrow) USBAccessoryRightAsyncContext();
1086     if (asyncContext == nullptr) {
1087         USB_HILOGE(MODULE_JS_NAPI, "Create USBAccessoryRightAsyncContext failed.");
1088         return nullptr;
1089     }
1090 
1091     asyncContext->env = env;
1092     asyncContext->accessory = accessory;
1093 
1094     napi_value result = nullptr;
1095     napi_create_promise(env, &asyncContext->deferred, &result);
1096 
1097     napi_value resource = nullptr;
1098     napi_create_string_utf8(env, "RequestRight", NAPI_AUTO_LENGTH, &resource);
1099 
1100     napi_create_async_work(env, nullptr, resource, g_requestAccessoryRightExecute, g_requestAccessoryRightComplete,
1101         reinterpret_cast<void *>(asyncContext), &asyncContext->work);
1102     napi_queue_async_work(env, asyncContext->work);
1103 
1104     return result;
1105 }
1106 
CoreUsbFunctionsFromString(napi_env env,napi_callback_info info)1107 static napi_value CoreUsbFunctionsFromString(napi_env env, napi_callback_info info)
1108 {
1109     if (!HasFeature(FEATURE_DEVICE)) {
1110         ThrowBusinessError(env, CAPABILITY_NOT_SUPPORT, "");
1111         return nullptr;
1112     }
1113     size_t argc = PARAM_COUNT_1;
1114     napi_value argv[PARAM_COUNT_1] = {nullptr};
1115 
1116     NAPI_CHECK(env, napi_get_cb_info(env, info, &argc, argv, nullptr, nullptr), "Get call back info failed");
1117     USB_ASSERT(env, (argc >= PARAM_COUNT_1), OHEC_COMMON_PARAM_ERROR, "The function at least takes one argument.");
1118 
1119     napi_valuetype type;
1120     NAPI_CHECK(env, napi_typeof(env, argv[INDEX_0], &type), "Get args 1 type failed");
1121     USB_ASSERT(env, type == napi_string, OHEC_COMMON_PARAM_ERROR, "The type of funcs must be string.");
1122 
1123     // get value string argument of napi converted.
1124     std::string funcs;
1125     NapiUtil::JsValueToString(env, argv[INDEX_0], STR_DEFAULT_SIZE, funcs);
1126 
1127     int32_t numFuncs = g_usbClient.UsbFunctionsFromString(funcs);
1128     USB_HILOGI(MODULE_JS_NAPI, "usb functions from string failed ret = %{public}d", numFuncs);
1129     USB_ASSERT_RETURN_UNDEF(env, (numFuncs != UEC_SERVICE_PERMISSION_DENIED_SYSAPI),
1130         OHEC_COMMON_NORMAL_APP_NOT_ALLOWED, "");
1131     USB_ASSERT_RETURN_UNDEF(env, (numFuncs != UEC_SERVICE_PERMISSION_DENIED_SYSAPI_FAILED),
1132         OHEC_COMMON_PERMISSION_NOT_ALLOWED, "");
1133     napi_value result;
1134     napi_create_int32(env, numFuncs, &result);
1135 
1136     return result;
1137 }
1138 
CoreUsbFunctionsToString(napi_env env,napi_callback_info info)1139 static napi_value CoreUsbFunctionsToString(napi_env env, napi_callback_info info)
1140 {
1141     if (!HasFeature(FEATURE_DEVICE)) {
1142         ThrowBusinessError(env, CAPABILITY_NOT_SUPPORT, "");
1143         return nullptr;
1144     }
1145     size_t argc = PARAM_COUNT_1;
1146     napi_value argv[PARAM_COUNT_1] = {nullptr};
1147 
1148     NAPI_CHECK(env, napi_get_cb_info(env, info, &argc, argv, nullptr, nullptr), "Get call back info failed");
1149     USB_ASSERT(env, (argc >= PARAM_COUNT_1), OHEC_COMMON_PARAM_ERROR, "The function at least takes one argument.");
1150 
1151     napi_valuetype type;
1152     NAPI_CHECK(env, napi_typeof(env, argv[INDEX_0], &type), "Get args 1 type failed");
1153     USB_ASSERT(env, type == napi_number, OHEC_COMMON_PARAM_ERROR, "The type of funcs must be number.");
1154 
1155     int32_t funcs;
1156     napi_get_value_int32(env, argv[INDEX_0], &funcs);
1157     std::string strFuncs = g_usbClient.UsbFunctionsToString(funcs);
1158     USB_ASSERT_RETURN_UNDEF(env, (strFuncs != PERMISSION_DENIED_SYSAPI), OHEC_COMMON_NORMAL_APP_NOT_ALLOWED, "");
1159     USB_ASSERT_RETURN_UNDEF(env, (strFuncs != SYS_APP_PERMISSION_DENIED_SYSAPI),
1160         OHEC_COMMON_PERMISSION_NOT_ALLOWED, "");
1161     napi_value result;
1162     napi_create_string_utf8(env, strFuncs.c_str(), NAPI_AUTO_LENGTH, &result);
1163 
1164     return result;
1165 }
1166 
__anon1e011ede0502(napi_env env, void *data) 1167 static auto g_setCurrentFunctionExecute = [](napi_env env, void *data) {
1168     USBFunctionAsyncContext *asyncContext = reinterpret_cast<USBFunctionAsyncContext *>(data);
1169     int32_t ret = g_usbClient.SetCurrentFunctions(asyncContext->functions);
1170     asyncContext->errCode = ret;
1171 };
1172 
__anon1e011ede0602(napi_env env, napi_status status, void *data) 1173 static auto g_setCurrentFunctionComplete = [](napi_env env, napi_status status, void *data) {
1174     USBFunctionAsyncContext *asyncContext = reinterpret_cast<USBFunctionAsyncContext *>(data);
1175     napi_value queryResult = nullptr;
1176 
1177     if (asyncContext->errCode == UEC_OK) {
1178         asyncContext->status = napi_ok;
1179         napi_get_boolean(env, true, &queryResult);
1180     } else if (asyncContext->errCode == UEC_SERVICE_PERMISSION_DENIED_SYSAPI) {
1181         asyncContext->status = napi_generic_failure;
1182         queryResult = CreateBusinessError((env), OHEC_COMMON_NORMAL_APP_NOT_ALLOWED, "");
1183     } else if (asyncContext->errCode == UEC_SERVICE_PERMISSION_DENIED_SYSAPI_FAILED) {
1184         asyncContext->status = napi_generic_failure;
1185         queryResult = CreateBusinessError((env), OHEC_COMMON_PERMISSION_NOT_ALLOWED, "");
1186     } else if (asyncContext->errCode == UEC_SERVICE_PERMISSION_CHECK_HDC) {
1187         asyncContext->status = napi_generic_failure;
1188         queryResult = CreateBusinessError((env), UEC_COMMON_HDC_NOT_ALLOWED, "");
1189     } else if (asyncContext->errCode == UEC_SERVICE_FUNCTION_NOT_SUPPORT) {
1190         asyncContext->status = napi_generic_failure;
1191         queryResult = CreateBusinessError((env), UEC_COMMON_FUNCTION_NOT_SUPPORT, "");
1192     } else {
1193         asyncContext->status = napi_generic_failure;
1194         napi_get_boolean(env, false, &queryResult);
1195     }
1196     ProcessPromise(env, *asyncContext, queryResult);
1197     napi_delete_async_work(env, asyncContext->work);
1198     delete asyncContext;
1199 };
1200 
CoreSetCurrentFunctions(napi_env env,napi_callback_info info)1201 static napi_value CoreSetCurrentFunctions(napi_env env, napi_callback_info info)
1202 {
1203     if (!HasFeature(FEATURE_DEVICE)) {
1204         ThrowBusinessError(env, CAPABILITY_NOT_SUPPORT, "");
1205         return nullptr;
1206     }
1207     size_t argc = PARAM_COUNT_1;
1208     napi_value argv[PARAM_COUNT_1] = {nullptr};
1209 
1210     NAPI_CHECK(env, napi_get_cb_info(env, info, &argc, argv, nullptr, nullptr), "Get call back info failed");
1211     USB_ASSERT(env, (argc >= PARAM_COUNT_1), OHEC_COMMON_PARAM_ERROR, "The function at least takes one argument.");
1212 
1213     napi_valuetype type;
1214     NAPI_CHECK(env, napi_typeof(env, argv[INDEX_0], &type), "Get args 1 type failed");
1215     USB_ASSERT(env, type == napi_number, OHEC_COMMON_PARAM_ERROR, "The type of funcs must be number.");
1216 
1217     int32_t funcs = 0;
1218     napi_get_value_int32(env, argv[INDEX_0], &funcs);
1219 
1220     auto asyncContext = new (std::nothrow) USBFunctionAsyncContext();
1221     if (asyncContext == nullptr) {
1222         USB_HILOGE(MODULE_JS_NAPI, "Create USBFunctionAsyncContext failed");
1223         return nullptr;
1224     }
1225 
1226     asyncContext->env = env;
1227     asyncContext->functions = funcs;
1228     napi_value result = nullptr;
1229     napi_create_promise(env, &asyncContext->deferred, &result);
1230 
1231     napi_value resource = nullptr;
1232     napi_create_string_utf8(env, "SetCurrentFunctions", NAPI_AUTO_LENGTH, &resource);
1233 
1234     napi_create_async_work(env, nullptr, resource, g_setCurrentFunctionExecute, g_setCurrentFunctionComplete,
1235         reinterpret_cast<void *>(asyncContext), &asyncContext->work);
1236     napi_queue_async_work(env, asyncContext->work);
1237 
1238     return result;
1239 }
1240 
CoreGetCurrentFunctions(napi_env env,napi_callback_info info)1241 static napi_value CoreGetCurrentFunctions(napi_env env, napi_callback_info info)
1242 {
1243     if (!HasFeature(FEATURE_DEVICE)) {
1244         ThrowBusinessError(env, CAPABILITY_NOT_SUPPORT, "");
1245         return nullptr;
1246     }
1247     size_t argc = PARAM_COUNT_1;
1248     napi_value argv[PARAM_COUNT_1] = {nullptr};
1249     NAPI_CHECK(env, napi_get_cb_info(env, info, &argc, argv, nullptr, nullptr), "Get call back info failed");
1250     USB_ASSERT(env, (argc == PARAM_COUNT_0), OHEC_COMMON_PARAM_ERROR, "The function takes no arguments.");
1251 
1252     int32_t cfuncs;
1253     int32_t ret = g_usbClient.GetCurrentFunctions(cfuncs);
1254     napi_value result;
1255     USB_HILOGI(MODULE_JS_NAPI, "get current functions failed ret = %{public}d", ret);
1256     USB_ASSERT_RETURN_UNDEF(env, (ret != UEC_SERVICE_PERMISSION_DENIED_SYSAPI), OHEC_COMMON_NORMAL_APP_NOT_ALLOWED, "");
1257     USB_ASSERT_RETURN_UNDEF(env, (ret != UEC_SERVICE_PERMISSION_DENIED_SYSAPI_FAILED),
1258         OHEC_COMMON_PERMISSION_NOT_ALLOWED, "");
1259     if (ret != UEC_OK) {
1260         napi_get_undefined(env, &result);
1261         USB_HILOGE(MODULE_JS_NAPI, "end call get ports failed ret : %{public}d", ret);
1262         return result;
1263     }
1264     napi_create_int32(env, cfuncs, &result);
1265 
1266     return result;
1267 }
1268 
CoreGetPorts(napi_env env,napi_callback_info info)1269 static napi_value CoreGetPorts(napi_env env, napi_callback_info info)
1270 {
1271     if (!HasFeature(FEATURE_PORT)) {
1272         ThrowBusinessError(env, CAPABILITY_NOT_SUPPORT, "");
1273         return nullptr;
1274     }
1275     size_t argc = PARAM_COUNT_1;
1276     napi_value argv[PARAM_COUNT_1] = {nullptr};
1277     NAPI_CHECK(env, napi_get_cb_info(env, info, &argc, argv, nullptr, nullptr), "Get call back info failed");
1278     USB_ASSERT(env, (argc == PARAM_COUNT_0), OHEC_COMMON_PARAM_ERROR, "The function takes no arguments.");
1279 
1280     std::vector<UsbPort> ports;
1281     int32_t ret = g_usbClient.GetPorts(ports);
1282     napi_value result;
1283     USB_ASSERT_RETURN_UNDEF(env, (ret != UEC_SERVICE_PERMISSION_DENIED_SYSAPI), OHEC_COMMON_NORMAL_APP_NOT_ALLOWED, "");
1284     USB_ASSERT_RETURN_UNDEF(env, (ret != UEC_SERVICE_PERMISSION_DENIED_SYSAPI_FAILED),
1285         OHEC_COMMON_PERMISSION_NOT_ALLOWED, "");
1286     if (ret != UEC_OK) {
1287         napi_get_undefined(env, &result);
1288         USB_HILOGE(MODULE_JS_NAPI, "end call get ports failed ret : %{public}d", ret);
1289         return result;
1290     }
1291 
1292     napi_create_array(env, &result);
1293     for (uint32_t i = 0; i < ports.size(); ++i) {
1294         napi_value port;
1295         napi_create_object(env, &port);
1296         NapiUtil::SetValueInt32(env, "id", ports[i].id, port);
1297         NapiUtil::SetValueInt32(env, "supportedModes", ports[i].supportedModes, port);
1298         napi_value usbPortStatus;
1299         napi_create_object(env, &usbPortStatus);
1300         NapiUtil::SetValueInt32(env, "currentMode", ports[i].usbPortStatus.currentMode, usbPortStatus);
1301         NapiUtil::SetValueInt32(env, "currentPowerRole", ports[i].usbPortStatus.currentPowerRole, usbPortStatus);
1302         NapiUtil::SetValueInt32(env, "currentDataRole", ports[i].usbPortStatus.currentDataRole, usbPortStatus);
1303         napi_set_named_property(env, port, "status", usbPortStatus);
1304         napi_set_element(env, result, i, port);
1305     }
1306 
1307     return result;
1308 }
1309 
1310 /* ============================================= Usb Port ============================================= */
1311 
PortGetSupportedModes(napi_env env,napi_callback_info info)1312 static napi_value PortGetSupportedModes(napi_env env, napi_callback_info info)
1313 {
1314     if (!HasFeature(FEATURE_PORT)) {
1315         ThrowBusinessError(env, CAPABILITY_NOT_SUPPORT, "");
1316         return nullptr;
1317     }
1318     size_t argc = PARAM_COUNT_1;
1319     napi_value args[PARAM_COUNT_1] = {nullptr};
1320 
1321     NAPI_CHECK(env, napi_get_cb_info(env, info, &argc, args, nullptr, nullptr), "Get call back info failed");
1322     USB_ASSERT(env, (argc >= PARAM_COUNT_1), OHEC_COMMON_PARAM_ERROR, "The function at least takes one argument.");
1323 
1324     napi_valuetype type;
1325     NAPI_CHECK(env, napi_typeof(env, args[INDEX_0], &type), "Get args 1 type failed");
1326     USB_ASSERT(env, type == napi_number, OHEC_COMMON_PARAM_ERROR, "The type of portId must be number.");
1327 
1328     int32_t id = 0;
1329     int32_t result = 0;
1330     napi_get_value_int32(env, args[INDEX_0], &id);
1331     int32_t ret = g_usbClient.GetSupportedModes(id, result);
1332     USB_ASSERT_RETURN_UNDEF(env, (ret != UEC_SERVICE_PERMISSION_DENIED_SYSAPI), OHEC_COMMON_NORMAL_APP_NOT_ALLOWED, "");
1333     USB_ASSERT_RETURN_UNDEF(env, (ret != UEC_SERVICE_PERMISSION_DENIED_SYSAPI_FAILED),
1334         OHEC_COMMON_PERMISSION_NOT_ALLOWED, "");
1335 
1336     if (ret) {
1337         USB_HILOGD(MODULE_JS_NAPI, "false ret = %{public}d", ret);
1338     }
1339     napi_value napiValue = nullptr;
1340     NAPI_CHECK(env, napi_create_int32(env, result, &napiValue), "Create int32 failed");
1341 
1342     return napiValue;
1343 }
1344 
__anon1e011ede0702(napi_env env, void *data) 1345 static auto g_setPortRoleExecute = [](napi_env env, void *data) {
1346     USBPortRoleAsyncContext *asyncContext = reinterpret_cast<USBPortRoleAsyncContext *>(data);
1347     int32_t ret = g_usbClient.SetPortRole(asyncContext->portId, asyncContext->powerRole, asyncContext->dataRole);
1348     asyncContext->errCode = ret;
1349 };
1350 
__anon1e011ede0802(napi_env env, napi_status status, void *data) 1351 static auto g_setPortRoleComplete = [](napi_env env, napi_status status, void *data) {
1352     USBPortRoleAsyncContext *asyncContext = reinterpret_cast<USBPortRoleAsyncContext *>(data);
1353     napi_value queryResult = nullptr;
1354 
1355     if (asyncContext->errCode == UEC_OK) {
1356         asyncContext->status = napi_ok;
1357         napi_get_boolean(env, true, &queryResult);
1358     } else if (asyncContext->errCode == UEC_SERVICE_PERMISSION_DENIED_SYSAPI) {
1359         asyncContext->status = napi_generic_failure;
1360         queryResult = CreateBusinessError((env), OHEC_COMMON_NORMAL_APP_NOT_ALLOWED, "");
1361     } else if (asyncContext->errCode == UEC_SERVICE_PERMISSION_DENIED_SYSAPI_FAILED) {
1362         asyncContext->status = napi_generic_failure;
1363         queryResult = CreateBusinessError((env), OHEC_COMMON_PERMISSION_NOT_ALLOWED, "");
1364     } else if (asyncContext->errCode == UEC_SERVICE_NOT_SUPPORT_SWITCH_PORT) {
1365         asyncContext->status = napi_generic_failure;
1366         queryResult = CreateBusinessError((env), UEC_COMMON_PORTROLE_SWITCH_NOT_ALLOWED, "");
1367     } else {
1368         asyncContext->status = napi_generic_failure;
1369         napi_get_boolean(env, false, &queryResult);
1370     }
1371     ProcessPromise(env, *asyncContext, queryResult);
1372     napi_delete_async_work(env, asyncContext->work);
1373     delete asyncContext;
1374 };
1375 
PortSetPortRole(napi_env env,napi_callback_info info)1376 static napi_value PortSetPortRole(napi_env env, napi_callback_info info)
1377 {
1378     if (!HasFeature(FEATURE_PORT)) {
1379         ThrowBusinessError(env, CAPABILITY_NOT_SUPPORT, "");
1380         return nullptr;
1381     }
1382     size_t argc = PARAM_COUNT_3;
1383     napi_value args[PARAM_COUNT_3] = {nullptr};
1384 
1385     NAPI_CHECK(env, napi_get_cb_info(env, info, &argc, args, nullptr, nullptr), "Get call back info failed");
1386     USB_ASSERT(env, (argc >= PARAM_COUNT_3), OHEC_COMMON_PARAM_ERROR, "The function at least takes three arguments.");
1387 
1388     napi_valuetype type;
1389     NAPI_CHECK(env, napi_typeof(env, args[INDEX_0], &type), "Get args 1 type failed");
1390     USB_ASSERT(env, type == napi_number, OHEC_COMMON_PARAM_ERROR, "The type of portId must be number.");
1391     NAPI_CHECK(env, napi_typeof(env, args[INDEX_1], &type), "Get args 2 type failed");
1392     USB_ASSERT(env, type == napi_number, OHEC_COMMON_PARAM_ERROR, "The type of powerRole must be number.");
1393     NAPI_CHECK(env, napi_typeof(env, args[INDEX_2], &type), "Get args 3 type failed");
1394     USB_ASSERT(env, type == napi_number, OHEC_COMMON_PARAM_ERROR, "The type of dataRole must be number.");
1395 
1396     int32_t id = 0;
1397     napi_get_value_int32(env, args[INDEX_0], &id);
1398     int32_t powerRole = 0;
1399     napi_get_value_int32(env, args[INDEX_1], &powerRole);
1400     int32_t dataRole = 0;
1401     napi_get_value_int32(env, args[INDEX_2], &dataRole);
1402 
1403     auto asyncContext = new (std::nothrow) USBPortRoleAsyncContext();
1404     if (asyncContext == nullptr) {
1405         USB_HILOGE(MODULE_JS_NAPI, "Create USBPortRoleAsyncContext failed");
1406         return nullptr;
1407     }
1408 
1409     asyncContext->env = env;
1410     asyncContext->portId = id;
1411     asyncContext->dataRole = dataRole;
1412     asyncContext->powerRole = powerRole;
1413 
1414     napi_value result = nullptr;
1415     napi_create_promise(env, &asyncContext->deferred, &result);
1416 
1417     napi_value resource = nullptr;
1418     napi_create_string_utf8(env, "PortSetPortRole", NAPI_AUTO_LENGTH, &resource);
1419 
1420     napi_create_async_work(env, nullptr, resource, g_setPortRoleExecute, g_setPortRoleComplete,
1421         reinterpret_cast<void *>(asyncContext), &asyncContext->work);
1422     napi_queue_async_work(env, asyncContext->work);
1423 
1424     return result;
1425 }
1426 
PipeClaimInterface(napi_env env,napi_callback_info info)1427 static napi_value PipeClaimInterface(napi_env env, napi_callback_info info)
1428 {
1429     if (!HasFeature(FEATURE_HOST)) {
1430         ThrowBusinessError(env, CAPABILITY_NOT_SUPPORT, "");
1431         return nullptr;
1432     }
1433     size_t argc = PARAM_COUNT_3;
1434     napi_value argv[PARAM_COUNT_3] = {nullptr};
1435 
1436     NAPI_CHECK(env, napi_get_cb_info(env, info, &argc, argv, nullptr, nullptr), "Get call back info failed");
1437     USB_ASSERT(env, (argc >= PARAM_COUNT_2), OHEC_COMMON_PARAM_ERROR,
1438         "The function at least takes two arguments.");
1439 
1440     napi_value obj = argv[INDEX_0];
1441     napi_valuetype type;
1442     napi_typeof(env, obj, &type);
1443     USB_ASSERT(env, type == napi_object, OHEC_COMMON_PARAM_ERROR, "The type of pipe must be USBDevicePipe.");
1444 
1445     USBDevicePipe pipe;
1446     ParseUsbDevicePipe(env, obj, pipe);
1447 
1448     UsbInterface interface;
1449     napi_value obj2 = argv[INDEX_1];
1450     napi_typeof(env, obj2, &type);
1451     USB_ASSERT(env, type == napi_object, OHEC_COMMON_PARAM_ERROR, "The type of iface must be USBInterface.");
1452     ParseInterfaceObj(env, obj2, interface);
1453 
1454     bool isForce = false;
1455     if (argc >= PARAM_COUNT_3) {
1456         napi_typeof(env, argv[INDEX_2], &type);
1457         if (type == napi_boolean) {
1458             napi_get_value_bool(env, argv[INDEX_2], &isForce);
1459         } else {
1460             USB_HILOGW(MODULE_JS_NAPI, "The type of force must be boolean.");
1461         }
1462     }
1463 
1464     int32_t ret = pipe.ClaimInterface(interface, isForce);
1465     USB_HILOGD(MODULE_JS_NAPI, "pipe call ClaimInterface ret: %{public}d", ret);
1466     napi_value result;
1467     napi_create_int32(env, ret, &result);
1468 
1469     return result;
1470 }
1471 
PipeReleaseInterface(napi_env env,napi_callback_info info)1472 static napi_value PipeReleaseInterface(napi_env env, napi_callback_info info)
1473 {
1474     if (!HasFeature(FEATURE_HOST)) {
1475         ThrowBusinessError(env, CAPABILITY_NOT_SUPPORT, "");
1476         return nullptr;
1477     }
1478     size_t argc = PARAM_COUNT_2;
1479     napi_value argv[PARAM_COUNT_2] = {nullptr};
1480 
1481     NAPI_CHECK(env, napi_get_cb_info(env, info, &argc, argv, nullptr, nullptr), "Get call back info failed");
1482     USB_ASSERT(env, (argc >= PARAM_COUNT_2), OHEC_COMMON_PARAM_ERROR, "The function at least takes two arguments.");
1483 
1484     napi_value obj = argv[INDEX_0];
1485     napi_valuetype type;
1486     napi_typeof(env, obj, &type);
1487     USB_ASSERT(env, type == napi_object, OHEC_COMMON_PARAM_ERROR, "The type of pipe must be USBDevicePipe.");
1488 
1489     USBDevicePipe pipe;
1490     ParseUsbDevicePipe(env, obj, pipe);
1491 
1492     UsbInterface interface;
1493     napi_value obj2 = argv[INDEX_1];
1494     napi_typeof(env, obj2, &type);
1495     USB_ASSERT(env, type == napi_object, OHEC_COMMON_PARAM_ERROR, "The type of iface must be USBInterface.");
1496     ParseInterfaceObj(env, obj2, interface);
1497     int32_t ret = pipe.ReleaseInterface(interface);
1498     USB_HILOGD(MODULE_JS_NAPI, "pipe call PipeReleaseInterface ret: %{public}d", ret);
1499     napi_value result;
1500     napi_create_int32(env, ret, &result);
1501 
1502     return result;
1503 }
1504 
PipeSetInterface(napi_env env,napi_callback_info info)1505 static napi_value PipeSetInterface(napi_env env, napi_callback_info info)
1506 {
1507     if (!HasFeature(FEATURE_HOST)) {
1508         ThrowBusinessError(env, CAPABILITY_NOT_SUPPORT, "");
1509         return nullptr;
1510     }
1511     size_t argc = PARAM_COUNT_2;
1512     napi_value argv[PARAM_COUNT_2] = {nullptr};
1513     NAPI_CHECK(env, napi_get_cb_info(env, info, &argc, argv, nullptr, nullptr), "Get call back info failed");
1514     USB_ASSERT(env, (argc >= PARAM_COUNT_2), OHEC_COMMON_PARAM_ERROR, "The function at least takes two arguments.");
1515 
1516     napi_value pipeObj = argv[INDEX_0];
1517     napi_valuetype type;
1518     napi_typeof(env, pipeObj, &type);
1519     USB_ASSERT(env, type == napi_object, OHEC_COMMON_PARAM_ERROR, "The type of pipe must be USBDevicePipe.");
1520 
1521     USBDevicePipe pipe;
1522     ParseUsbDevicePipe(env, pipeObj, pipe);
1523 
1524     napi_value interfaceObj = argv[INDEX_1];
1525     napi_typeof(env, interfaceObj, &type);
1526     USB_ASSERT(env, type == napi_object, OHEC_COMMON_PARAM_ERROR, "The type of iface must be USBInterface.");
1527 
1528     UsbInterface interface;
1529     ParseInterfaceObj(env, interfaceObj, interface);
1530     int32_t ret = g_usbClient.SetInterface(pipe, interface);
1531     napi_value result;
1532     napi_create_int32(env, ret, &result);
1533 
1534     return result;
1535 }
1536 
PipeSetConfiguration(napi_env env,napi_callback_info info)1537 static napi_value PipeSetConfiguration(napi_env env, napi_callback_info info)
1538 {
1539     if (!HasFeature(FEATURE_HOST)) {
1540         ThrowBusinessError(env, CAPABILITY_NOT_SUPPORT, "");
1541         return nullptr;
1542     }
1543     size_t argc = PARAM_COUNT_2;
1544     napi_value argv[PARAM_COUNT_2] = {nullptr};
1545     NAPI_CHECK(env, napi_get_cb_info(env, info, &argc, argv, nullptr, nullptr), "Get call back info failed");
1546     USB_ASSERT(env, (argc >= PARAM_COUNT_2), OHEC_COMMON_PARAM_ERROR, "The function at least takes two arguments.");
1547 
1548     napi_valuetype type;
1549     napi_value pipeObj = argv[INDEX_0];
1550 
1551     napi_typeof(env, pipeObj, &type);
1552     USB_ASSERT(env, type == napi_object, OHEC_COMMON_PARAM_ERROR, "The type of pipe must be USBDevicePipe.");
1553     USBDevicePipe pipe;
1554     ParseUsbDevicePipe(env, pipeObj, pipe);
1555 
1556     napi_value configObj = argv[INDEX_1];
1557     napi_typeof(env, configObj, &type);
1558     USB_ASSERT(env, type == napi_object, OHEC_COMMON_PARAM_ERROR, "The type of config must be USBConfig.");
1559     USBConfig config;
1560     ParseConfigObj(env, configObj, config);
1561 
1562     int32_t ret = g_usbClient.SetConfiguration(pipe, config);
1563     napi_value result;
1564     napi_create_int32(env, ret, &result);
1565 
1566     return result;
1567 }
1568 
PipeGetRawDescriptors(napi_env env,napi_callback_info info)1569 static napi_value PipeGetRawDescriptors(napi_env env, napi_callback_info info)
1570 {
1571     if (!HasFeature(FEATURE_HOST)) {
1572         ThrowBusinessError(env, CAPABILITY_NOT_SUPPORT, "");
1573         return nullptr;
1574     }
1575     size_t argc = PARAM_COUNT_1;
1576     napi_value argv[PARAM_COUNT_1] = {nullptr};
1577 
1578     NAPI_CHECK(env, napi_get_cb_info(env, info, &argc, argv, nullptr, nullptr), "Get call back info failed");
1579     USB_ASSERT(env, (argc >= PARAM_COUNT_1), OHEC_COMMON_PARAM_ERROR, "The function at least takes one argument.");
1580     napi_value obj = argv[INDEX_0];
1581     napi_valuetype type;
1582     napi_typeof(env, obj, &type);
1583     USB_ASSERT(env, type == napi_object, OHEC_COMMON_PARAM_ERROR, "The type of pipe must be USBDevicePipe.");
1584 
1585     USBDevicePipe pipe;
1586     ParseUsbDevicePipe(env, obj, pipe);
1587 
1588     napi_value result;
1589     std::vector<uint8_t> bufferData;
1590     int32_t ret = g_usbClient.GetRawDescriptors(pipe, bufferData);
1591     if (ret == UEC_OK) {
1592         NapiUtil::Uint8ArrayToJsValue(env, bufferData, bufferData.size(), result);
1593     } else {
1594         napi_get_undefined(env, &result);
1595     }
1596 
1597     return result;
1598 }
1599 
PipeGetFileDescriptor(napi_env env,napi_callback_info info)1600 static napi_value PipeGetFileDescriptor(napi_env env, napi_callback_info info)
1601 {
1602     if (!HasFeature(FEATURE_HOST)) {
1603         ThrowBusinessError(env, CAPABILITY_NOT_SUPPORT, "");
1604         return nullptr;
1605     }
1606     size_t argc = PARAM_COUNT_1;
1607     napi_value argv[PARAM_COUNT_1] = {nullptr};
1608 
1609     NAPI_CHECK(env, napi_get_cb_info(env, info, &argc, argv, nullptr, nullptr), "Get call back info failed");
1610     USB_ASSERT(env, (argc >= PARAM_COUNT_1), OHEC_COMMON_PARAM_ERROR, "The function at least takes one argument.");
1611     napi_value obj = argv[INDEX_0];
1612     napi_valuetype type;
1613     napi_typeof(env, obj, &type);
1614     USB_ASSERT(env, type == napi_object, OHEC_COMMON_PARAM_ERROR, "The type of pipe must be USBDevicePipe.");
1615 
1616     USBDevicePipe pipe;
1617     ParseUsbDevicePipe(env, obj, pipe);
1618 
1619     int32_t fd = -1;
1620     napi_value result;
1621     g_usbClient.GetFileDescriptor(pipe, fd);
1622     napi_create_int32(env, fd, &result);
1623 
1624     return result;
1625 }
1626 
__anon1e011ede0902(napi_env env, void *data) 1627 static auto g_controlTransferExecute = [](napi_env env, void *data) {
1628     USBControlTransferAsyncContext *asyncContext = (USBControlTransferAsyncContext *)data;
1629     std::vector<uint8_t> bufferData(asyncContext->buffer, asyncContext->buffer + asyncContext->bufferLength);
1630     if ((asyncContext->reqType & USB_ENDPOINT_DIR_MASK) == USB_ENDPOINT_DIR_OUT) {
1631         delete[] asyncContext->buffer;
1632         asyncContext->buffer = nullptr;
1633     }
1634 
1635     const UsbCtrlTransfer tctrl = {
1636         asyncContext->reqType, asyncContext->request, asyncContext->value, asyncContext->index, asyncContext->timeOut};
1637     int32_t ret;
1638     do {
1639         ret = asyncContext->pipe.ControlTransfer(tctrl, bufferData);
1640         if (ret != UEC_OK) {
1641             USB_HILOGE(MODULE_JS_NAPI, "ControlTransferExecute failed");
1642             break;
1643         }
1644 
1645         if ((asyncContext->reqType & USB_ENDPOINT_DIR_MASK) == USB_ENDPOINT_DIR_IN) {
1646             ret = memcpy_s(asyncContext->buffer, asyncContext->bufferLength, bufferData.data(), bufferData.size());
1647         }
1648     } while (0);
1649 
1650     if (ret == UEC_OK) {
1651         asyncContext->status = napi_ok;
1652         asyncContext->dataSize = bufferData.size();
1653     } else {
1654         asyncContext->status = napi_generic_failure;
1655         asyncContext->dataSize = 0;
1656     }
1657 };
1658 
__anon1e011ede0a02(napi_env env, napi_status status, void *data) 1659 static auto g_controlTransferComplete = [](napi_env env, napi_status status, void *data) {
1660     USBControlTransferAsyncContext *asyncContext = reinterpret_cast<USBControlTransferAsyncContext *>(data);
1661     napi_value queryResult = nullptr;
1662 
1663     if (asyncContext->status == napi_ok) {
1664         napi_create_int32(env, asyncContext->dataSize, &queryResult);
1665     } else {
1666         USB_HILOGD(MODULE_JS_NAPI, "ControlTransfer failed");
1667         napi_create_int32(env, -1, &queryResult);
1668     }
1669     if (asyncContext->deferred) {
1670         napi_resolve_deferred(env, asyncContext->deferred, queryResult);
1671     }
1672     napi_delete_async_work(env, asyncContext->work);
1673     delete asyncContext;
1674 };
1675 
GetControlTransferParam(napi_env env,napi_callback_info info)1676 static std::tuple<bool, USBDevicePipe, PipeControlParam, int32_t> GetControlTransferParam(
1677     napi_env env, napi_callback_info info)
1678 {
1679     size_t argc = PARAM_COUNT_3;
1680     napi_value argv[PARAM_COUNT_3] = {nullptr};
1681     napi_status status = napi_get_cb_info(env, info, &argc, argv, nullptr, nullptr);
1682     if (status != napi_ok) {
1683         USB_HILOGE(MODULE_JS_NAPI, "ControlTransfer failed to get cb info");
1684         return {false, {}, {}, {}};
1685     }
1686 
1687     if (argc < PARAM_COUNT_2) {
1688         USB_HILOGE(MODULE_JS_NAPI, "The function at least takes two arguments.");
1689         ThrowBusinessError(env, OHEC_COMMON_PARAM_ERROR, "The function at least takes two arguments.");
1690         return {false, {}, {}, {}};
1691     }
1692 
1693     // pipe param
1694     napi_valuetype type;
1695     napi_typeof(env, argv[INDEX_0], &type);
1696     if (type != napi_object) {
1697         USB_HILOGE(MODULE_JS_NAPI, "index 0 wrong argument type, object expected.");
1698         ThrowBusinessError(env, OHEC_COMMON_PARAM_ERROR, "The type of pipe must be USBDevicePipe.");
1699         return {false, {}, {}, {}};
1700     }
1701 
1702     USBDevicePipe pipe;
1703     ParseUsbDevicePipe(env, argv[INDEX_0], pipe);
1704 
1705     // control params
1706     PipeControlParam controlParam = {0};
1707     bool ret = ParsePipeControlParam(env, argv[INDEX_1], controlParam);
1708     if (!ret) {
1709         USB_HILOGE(MODULE_JS_NAPI, "index 1 wrong argument type, object expected.");
1710         return {false, {}, {}, {}};
1711     }
1712 
1713     // timeOut param
1714     int32_t timeOut = 0;
1715     if (argc > PARAM_COUNT_2) {
1716         napi_typeof(env, argv[INDEX_2], &type);
1717         if (type == napi_number) {
1718             napi_get_value_int32(env, argv[INDEX_2], &timeOut);
1719         } else {
1720             USB_HILOGW(MODULE_JS_NAPI, "index 2 wrong argument type, number expected.");
1721         }
1722     }
1723 
1724     return {true, pipe, controlParam, timeOut};
1725 }
1726 
PipeControlTransfer(napi_env env,napi_callback_info info)1727 static napi_value PipeControlTransfer(napi_env env, napi_callback_info info)
1728 {
1729     if (!HasFeature(FEATURE_HOST)) {
1730         ThrowBusinessError(env, CAPABILITY_NOT_SUPPORT, "");
1731         return nullptr;
1732     }
1733     auto [res, pipe, controlParam, timeOut] = GetControlTransferParam(env, info);
1734     if (!res) {
1735         USB_HILOGE(MODULE_JS_NAPI, "GetControlTransferParam failed.");
1736         return nullptr;
1737     }
1738 
1739     auto asyncContext = new (std::nothrow) USBControlTransferAsyncContext();
1740     if (asyncContext == nullptr) {
1741         USB_HILOGE(MODULE_JS_NAPI, "New USBControlTransferAsyncContext failed.");
1742         return nullptr;
1743     }
1744 
1745     asyncContext->env = env;
1746     asyncContext->pipe = pipe;
1747     asyncContext->request = controlParam.request;
1748     asyncContext->target = controlParam.target;
1749     asyncContext->reqType = controlParam.reqType;
1750     asyncContext->value = controlParam.value;
1751     asyncContext->index = controlParam.index;
1752 
1753     if ((asyncContext->reqType & USB_ENDPOINT_DIR_MASK) == USB_ENDPOINT_DIR_OUT) {
1754         uint8_t *nativeArrayBuffer = new (std::nothrow) uint8_t[controlParam.dataLength];
1755         if (nativeArrayBuffer == nullptr) {
1756             delete asyncContext;
1757             return nullptr;
1758         }
1759 
1760         errno_t ret = memcpy_s(nativeArrayBuffer, controlParam.dataLength, controlParam.data, controlParam.dataLength);
1761         if (ret != EOK) {
1762             USB_HILOGE(MODULE_JS_NAPI, "memcpy_s failed");
1763             delete asyncContext;
1764             delete[] nativeArrayBuffer;
1765             return nullptr;
1766         }
1767         asyncContext->buffer = nativeArrayBuffer;
1768     } else {
1769         asyncContext->buffer = controlParam.data;
1770     }
1771 
1772     asyncContext->bufferLength = controlParam.dataLength;
1773     asyncContext->timeOut = timeOut;
1774     napi_value result = nullptr;
1775     napi_create_promise(env, &asyncContext->deferred, &result);
1776 
1777     napi_value resource = nullptr;
1778     napi_create_string_utf8(env, "PipeControlTransfer", NAPI_AUTO_LENGTH, &resource);
1779 
1780     napi_create_async_work(env, nullptr, resource, g_controlTransferExecute, g_controlTransferComplete,
1781         reinterpret_cast<void *>(asyncContext), &asyncContext->work);
1782     napi_queue_async_work(env, asyncContext->work);
1783 
1784     return result;
1785 }
1786 
__anon1e011ede0b02(napi_env env, void *data) 1787 static auto g_usbControlTransferExecute = [](napi_env env, void *data) {
1788     USBDeviceControlTransferAsyncContext *asyncContext = (USBDeviceControlTransferAsyncContext *)data;
1789     std::vector<uint8_t> bufferData(asyncContext->buffer, asyncContext->buffer + asyncContext->bufferLength);
1790     if ((asyncContext->reqType & USB_ENDPOINT_DIR_MASK) == USB_ENDPOINT_DIR_OUT && asyncContext->buffer != nullptr) {
1791         delete[] asyncContext->buffer;
1792         asyncContext->buffer = nullptr;
1793     }
1794 
1795     const UsbCtrlTransferParams tctrl = {asyncContext->reqType, asyncContext->request,
1796         asyncContext->value, asyncContext->index, asyncContext->length, asyncContext->timeOut};
1797     int32_t ret;
1798     do {
1799         ret = asyncContext->pipe.UsbControlTransfer(tctrl, bufferData);
1800         if (ret != UEC_OK) {
1801             USB_HILOGE(MODULE_JS_NAPI, "ControlTransferExecute failed");
1802             break;
1803         }
1804 
1805         if ((asyncContext->reqType & USB_ENDPOINT_DIR_MASK) == USB_ENDPOINT_DIR_IN) {
1806             ret = memcpy_s(asyncContext->buffer, asyncContext->bufferLength, bufferData.data(), bufferData.size());
1807         }
1808     } while (0);
1809 
1810     if (ret == UEC_OK) {
1811         asyncContext->status = napi_ok;
1812         asyncContext->dataSize = bufferData.size();
1813     } else {
1814         asyncContext->status = napi_generic_failure;
1815         asyncContext->dataSize = 0;
1816     }
1817 };
1818 
__anon1e011ede0c02(napi_env env, napi_status status, void *data) 1819 static auto g_usbControlTransferComplete = [](napi_env env, napi_status status, void *data) {
1820     USBDeviceControlTransferAsyncContext *asyncContext = reinterpret_cast<USBDeviceControlTransferAsyncContext *>(data);
1821     napi_value queryResult = nullptr;
1822 
1823     if (asyncContext->status == napi_ok) {
1824         napi_create_int32(env, asyncContext->dataSize, &queryResult);
1825     } else {
1826         USB_HILOGD(MODULE_JS_NAPI, "usbControlTransfer failed");
1827         napi_create_int32(env, -1, &queryResult);
1828     }
1829     if (asyncContext->deferred) {
1830         napi_resolve_deferred(env, asyncContext->deferred, queryResult);
1831     }
1832     napi_delete_async_work(env, asyncContext->work);
1833     delete asyncContext;
1834 };
1835 
GetUsbControlTransferParam(napi_env env,napi_callback_info info)1836 static std::tuple<bool, USBDevicePipe, UsbPipeControlParam, int32_t> GetUsbControlTransferParam(
1837     napi_env env, napi_callback_info info)
1838 {
1839     size_t argc = PARAM_COUNT_3;
1840     napi_value argv[PARAM_COUNT_3] = {nullptr};
1841     napi_status status = napi_get_cb_info(env, info, &argc, argv, nullptr, nullptr);
1842     if (status != napi_ok) {
1843         USB_HILOGE(MODULE_JS_NAPI, "ControlTransfer failed to get cb info");
1844         return {false, {}, {}, {}};
1845     }
1846 
1847     if (argc < PARAM_COUNT_2) {
1848         USB_HILOGE(MODULE_JS_NAPI, "The function at least takes two arguments.");
1849         ThrowBusinessError(env, OHEC_COMMON_PARAM_ERROR, "The function at least takes two arguments.");
1850         return {false, {}, {}, {}};
1851     }
1852 
1853     // pipe param
1854     napi_valuetype type;
1855     napi_typeof(env, argv[INDEX_0], &type);
1856     if (type != napi_object) {
1857         USB_HILOGE(MODULE_JS_NAPI, "index 0 wrong argument type, object expected.");
1858         ThrowBusinessError(env, OHEC_COMMON_PARAM_ERROR, "The type of pipe must be USBDevicePipe.");
1859         return {false, {}, {}, {}};
1860     }
1861 
1862     USBDevicePipe pipe;
1863     ParseUsbDevicePipe(env, argv[INDEX_0], pipe);
1864 
1865     // control params
1866     napi_typeof(env, argv[INDEX_1], &type);
1867     if (type != napi_object) {
1868         USB_HILOGE(MODULE_JS_NAPI, "index 1 wrong argument type, object expected.");
1869         ThrowBusinessError(env, OHEC_COMMON_PARAM_ERROR, "The type of pipe must be USBDeviceRequestParams.");
1870         return {false, {}, {}, {}};
1871     }
1872 
1873     UsbPipeControlParam controlParam = {0};
1874     ParseUsbPipeControlParam(env, argv[INDEX_1], controlParam);
1875 
1876     // timeOut param
1877     int32_t timeOut = 0;
1878     if (argc > PARAM_COUNT_2) {
1879         napi_typeof(env, argv[INDEX_2], &type);
1880         if (type == napi_number) {
1881             napi_get_value_int32(env, argv[INDEX_2], &timeOut);
1882         } else {
1883             USB_HILOGW(MODULE_JS_NAPI, "index 2 wrong argument type, number expected.");
1884         }
1885     }
1886 
1887     return {true, pipe, controlParam, timeOut};
1888 }
1889 
PipeUsbControlTransfer(napi_env env,napi_callback_info info)1890 static napi_value PipeUsbControlTransfer(napi_env env, napi_callback_info info)
1891 {
1892     if (!HasFeature(FEATURE_HOST)) {
1893         ThrowBusinessError(env, CAPABILITY_NOT_SUPPORT, "");
1894         return nullptr;
1895     }
1896     auto [res, pipe, controlParam, timeOut] = GetUsbControlTransferParam(env, info);
1897     if (!res) {
1898         USB_HILOGE(MODULE_JS_NAPI, "GetUsbControlTransferParam failed.");
1899         return nullptr;
1900     }
1901 
1902     auto asyncContext = new (std::nothrow) USBDeviceControlTransferAsyncContext();
1903     if (asyncContext == nullptr) {
1904         USB_HILOGE(MODULE_JS_NAPI, "New USBDeviceControlTransferAsyncContext failed.");
1905         return nullptr;
1906     }
1907 
1908     asyncContext->env = env;
1909     asyncContext->pipe = pipe;
1910     asyncContext->reqType = controlParam.reqType;
1911     asyncContext->request = controlParam.request;
1912     asyncContext->value = controlParam.value;
1913     asyncContext->index = controlParam.index;
1914     asyncContext->length = controlParam.length;
1915 
1916     if ((asyncContext->reqType & USB_ENDPOINT_DIR_MASK) == USB_ENDPOINT_DIR_OUT) {
1917         uint8_t *nativeArrayBuffer = new (std::nothrow) uint8_t[controlParam.dataLength];
1918         if (nativeArrayBuffer == nullptr) {
1919             delete asyncContext;
1920             return nullptr;
1921         }
1922 
1923         errno_t ret = memcpy_s(nativeArrayBuffer, controlParam.dataLength, controlParam.data, controlParam.dataLength);
1924         if (ret != EOK) {
1925             USB_HILOGE(MODULE_JS_NAPI, "memcpy_s failed");
1926             delete asyncContext;
1927             delete[] nativeArrayBuffer;
1928             return nullptr;
1929         }
1930         asyncContext->buffer = nativeArrayBuffer;
1931     } else {
1932         asyncContext->buffer = controlParam.data;
1933     }
1934 
1935     asyncContext->bufferLength = controlParam.dataLength;
1936     asyncContext->timeOut = timeOut;
1937     napi_value result = nullptr;
1938     napi_create_promise(env, &asyncContext->deferred, &result);
1939 
1940     napi_value resource = nullptr;
1941     napi_create_string_utf8(env, "PipeUsbControlTransfer", NAPI_AUTO_LENGTH, &resource);
1942 
1943     napi_create_async_work(env, nullptr, resource, g_usbControlTransferExecute, g_usbControlTransferComplete,
1944         reinterpret_cast<void *>(asyncContext), &asyncContext->work);
1945     napi_queue_async_work(env, asyncContext->work);
1946 
1947     return result;
1948 }
1949 
__anon1e011ede0d02(napi_env env, void *data) 1950 static auto g_bulkTransferExecute = [](napi_env env, void *data) {
1951     USBBulkTransferAsyncContext *asyncContext = reinterpret_cast<USBBulkTransferAsyncContext *>(data);
1952     std::vector<uint8_t> bufferData(asyncContext->buffer, asyncContext->buffer + asyncContext->bufferLength);
1953     if (asyncContext->endpoint.GetDirection() == USB_ENDPOINT_DIR_OUT) {
1954         delete[] asyncContext->buffer;
1955         asyncContext->buffer = nullptr;
1956     }
1957 
1958     int32_t ret;
1959     do {
1960         ret = asyncContext->pipe.BulkTransfer(asyncContext->endpoint, bufferData, asyncContext->timeOut);
1961         if (ret != UEC_OK) {
1962             USB_HILOGE(MODULE_JS_NAPI, "ControlTransferExecute failed");
1963             break;
1964         }
1965 
1966         if (asyncContext->endpoint.GetDirection() == USB_ENDPOINT_DIR_IN) {
1967             ret = memcpy_s(asyncContext->buffer, asyncContext->bufferLength, bufferData.data(), bufferData.size());
1968         }
1969     } while (0);
1970 
1971     USB_HILOGD(MODULE_JS_NAPI, "call pipe result %{public}d", ret);
1972     if (ret == UEC_OK) {
1973         asyncContext->status = napi_ok;
1974         asyncContext->dataSize = bufferData.size();
1975     } else {
1976         asyncContext->status = napi_generic_failure;
1977         asyncContext->dataSize = 0;
1978     }
1979 };
1980 
__anon1e011ede0e02(napi_env env, napi_status status, void *data) 1981 static auto g_bulkTransferComplete = [](napi_env env, napi_status status, void *data) {
1982     USBBulkTransferAsyncContext *asyncContext = reinterpret_cast<USBBulkTransferAsyncContext *>(data);
1983     napi_value queryResult = nullptr;
1984     if (asyncContext->status == napi_ok) {
1985         napi_create_int32(env, asyncContext->dataSize, &queryResult);
1986     } else {
1987         USB_HILOGE(MODULE_JS_NAPI, "BulkTransfer failed");
1988         napi_create_int32(env, -1, &queryResult);
1989     }
1990     if (asyncContext->deferred) {
1991         napi_resolve_deferred(env, asyncContext->deferred, queryResult);
1992     }
1993     napi_delete_async_work(env, asyncContext->work);
1994     delete asyncContext;
1995 };
1996 
GetDescriptorOnBulkTransferParam(napi_env env,napi_value data,USBBulkTransferAsyncContext & asyncContext,const USBEndpoint & ep)1997 static bool GetDescriptorOnBulkTransferParam(napi_env env, napi_value data,
1998     USBBulkTransferAsyncContext &asyncContext, const USBEndpoint &ep)
1999 {
2000     uint8_t *buffer = nullptr;
2001     size_t offset = 0;
2002     size_t bufferSize = 0;
2003     bool hasBuffer = NapiUtil::JsUint8ArrayParse(env, data, &buffer, bufferSize, offset);
2004     if (!hasBuffer) {
2005         USB_HILOGE(MODULE_JS_NAPI, "BulkTransfer wrong argument, buffer is null");
2006         return false;
2007     }
2008     asyncContext.env = env;
2009     asyncContext.endpoint = ep;
2010 
2011     if (ep.GetDirection() == USB_ENDPOINT_DIR_OUT) {
2012         uint8_t *nativeArrayBuffer = new (std::nothrow) uint8_t[bufferSize];
2013         RETURN_IF_WITH_RET(nativeArrayBuffer == nullptr, false);
2014 
2015         errno_t ret = memcpy_s(nativeArrayBuffer, bufferSize, buffer, bufferSize);
2016         if (ret != EOK) {
2017             USB_HILOGE(MODULE_JS_NAPI, "memcpy_s failed");
2018             delete[] nativeArrayBuffer;
2019             nativeArrayBuffer = nullptr;
2020             return false;
2021         }
2022 
2023         asyncContext.buffer = nativeArrayBuffer;
2024     } else {
2025         asyncContext.buffer = buffer;
2026     }
2027     asyncContext.bufferLength = bufferSize;
2028     return true;
2029 }
2030 
GetBulkTransferParams(napi_env env,napi_callback_info info,USBBulkTransferAsyncContext & asyncContext)2031 static bool GetBulkTransferParams(napi_env env, napi_callback_info info, USBBulkTransferAsyncContext &asyncContext)
2032 {
2033     size_t argc = PARAM_COUNT_4;
2034     napi_value argv[PARAM_COUNT_4] = {nullptr};
2035     NAPI_CHECK(env, napi_get_cb_info(env, info, &argc, argv, nullptr, nullptr), "Get call back info failed");
2036     USB_ASSERT_RETURN_FALSE(
2037         env, (argc >= PARAM_COUNT_3), OHEC_COMMON_PARAM_ERROR,
2038         "The function at least takes three arguments.");
2039 
2040     napi_valuetype type;
2041     USBDevicePipe pipe;
2042     napi_typeof(env, argv[INDEX_0], &type);
2043     USB_ASSERT_RETURN_FALSE(
2044         env, type == napi_object, OHEC_COMMON_PARAM_ERROR, "The type of pipe must be USBDevicePipe.");
2045     ParseUsbDevicePipe(env, argv[INDEX_0], pipe);
2046     asyncContext.pipe = pipe;
2047 
2048     USBEndpoint ep;
2049     napi_typeof(env, argv[INDEX_1], &type);
2050     USB_ASSERT_RETURN_FALSE(
2051         env, type == napi_object, OHEC_COMMON_PARAM_ERROR, "The type of endpoint must be USBEndpoint.");
2052     ParseEndpointObj(env, argv[INDEX_1], ep);
2053 
2054     int32_t timeOut = 0;
2055     if (argc > PARAM_COUNT_3) {
2056         napi_typeof(env, argv[INDEX_3], &type);
2057         if (type == napi_number) {
2058             napi_get_value_int32(env, argv[INDEX_3], &timeOut);
2059         } else {
2060             USB_HILOGW(MODULE_JS_NAPI, "The type of timeOut must be number.");
2061         }
2062     }
2063 
2064     if (!GetDescriptorOnBulkTransferParam(env, argv[INDEX_2], asyncContext, ep)) {
2065         USB_HILOGE(MODULE_JS_NAPI, "get asyncContext failed.");
2066         return false;
2067     }
2068     asyncContext.timeOut = timeOut;
2069     return true;
2070 }
2071 
PipeBulkTransfer(napi_env env,napi_callback_info info)2072 static napi_value PipeBulkTransfer(napi_env env, napi_callback_info info)
2073 {
2074     if (!HasFeature(FEATURE_HOST)) {
2075         ThrowBusinessError(env, CAPABILITY_NOT_SUPPORT, "");
2076         return nullptr;
2077     }
2078     auto asyncContext = new (std::nothrow) USBBulkTransferAsyncContext();
2079     if (asyncContext == nullptr) {
2080         USB_HILOGE(MODULE_JS_NAPI, "Create USBBulkTransferAsyncContext failed.");
2081         return nullptr;
2082     }
2083 
2084     napi_value result = nullptr;
2085     napi_create_promise(env, &asyncContext->deferred, &result);
2086     if (!GetBulkTransferParams(env, info, *asyncContext)) {
2087         USB_HILOGE(MODULE_JS_NAPI, "end call invalid arg");
2088         asyncContext->status = napi_invalid_arg;
2089         napi_value queryResult = nullptr;
2090         napi_create_int32(env, -1, &queryResult);
2091         if (asyncContext->deferred) {
2092             napi_resolve_deferred(env, asyncContext->deferred, queryResult);
2093         }
2094         delete asyncContext;
2095         asyncContext = nullptr;
2096         return result;
2097     }
2098 
2099     napi_value resource = nullptr;
2100     napi_create_string_utf8(env, "PipeBulkTransfer", NAPI_AUTO_LENGTH, &resource);
2101 
2102     napi_status status = napi_create_async_work(env, nullptr, resource, g_bulkTransferExecute, g_bulkTransferComplete,
2103         reinterpret_cast<void *>(asyncContext), &asyncContext->work);
2104     if (status != napi_ok) {
2105         USB_HILOGE(MODULE_JS_NAPI, "create async work failed");
2106         return result;
2107     }
2108     napi_queue_async_work(env, asyncContext->work);
2109 
2110     return result;
2111 }
2112 
ParseTransferParams(const napi_env & env,const napi_value & object,USBTransferAsyncContext * asyncContext)2113 static bool ParseTransferParams(const napi_env &env, const napi_value &object,
2114     USBTransferAsyncContext *asyncContext)
2115 {
2116     napi_value valuePipe = nullptr;
2117     USBDevicePipe pipe;
2118     napi_valuetype valueType;
2119     napi_get_named_property(env, object, "devPipe", &valuePipe);
2120     napi_typeof(env, valuePipe, &valueType);
2121     USB_ASSERT_RETURN_FALSE(env, valueType == napi_object, false, "The valueType of pipe must be USBDevicePipe.");
2122     ParseUsbDevicePipe(env, valuePipe, pipe);
2123     asyncContext->pipe = pipe;
2124 
2125     int32_t flags = static_cast<int32_t>(TransferFlagsJs::TRANSFER_FLAGS_UNKNOWN);
2126     NapiUtil::JsObjectToInt(env, object, "flags", flags);
2127     if (flags == static_cast<int32_t>(TransferFlagsJs::TRANSFER_FLAGS_UNKNOWN)) {
2128         USB_HILOGE(MODULE_JS_NAPI, "TRANSFER_FLAGS_UNKNOWN, flags: %{public}d", flags);
2129         return false;
2130     }
2131     asyncContext->flags = flags;
2132     NapiUtil::JsObjectToInt(env, object, "endpoint", asyncContext->endpoint);
2133     int32_t tranferType = static_cast<int32_t>(EndpointTransferTypeJs::TRANSFER_TYPE_UNKNOWN);
2134     NapiUtil::JsObjectToInt(env, object, "type", tranferType);
2135     if (tranferType == static_cast<int32_t>(EndpointTransferTypeJs::TRANSFER_TYPE_UNKNOWN)) {
2136         USB_HILOGE(MODULE_JS_NAPI, "TRANSFER_TYPE_UNKNOWN, tranferType: %{public}d", tranferType);
2137         return false;
2138     }
2139     asyncContext->type = tranferType;
2140     NapiUtil::JsObjectToInt(env, object, "timeout", asyncContext->timeOut);
2141     NapiUtil::JsObjectToInt(env, object, "length", asyncContext->length);
2142     napi_value valueCallBack;
2143     NapiUtil::JsObjectGetProperty(env, object, "callback", valueCallBack);
2144     napi_typeof(env, valueCallBack, &valueType);
2145     USB_ASSERT_RETURN_FALSE(env, valueType == napi_function, false, "The type of endpoint must be function.");
2146     napi_create_reference(env, valueCallBack, 1, &asyncContext->callbackRef);
2147 
2148     napi_value valueUint8Array;
2149     NapiUtil::JsObjectGetProperty(env, object, "buffer", valueUint8Array);
2150 
2151     size_t offset = 0;
2152     bool hasBuffer = NapiUtil::JsUint8ArrayParse(env, valueUint8Array, &asyncContext->buffer,
2153         asyncContext->bufferLength, offset);
2154     if (!hasBuffer) {
2155         USB_HILOGE(MODULE_JS_NAPI, "Transfer wrong argument, buffer is null");
2156         return false;
2157     }
2158     NapiUtil::JsObjectToUint(env, object, "isoPacketCount", asyncContext->numIsoPackets);
2159     return true;
2160 }
2161 
GetTransferParamsFromJsObj(const napi_env & env,const napi_callback_info & info,USBTransferAsyncContext * asyncContext)2162 static bool GetTransferParamsFromJsObj(const napi_env &env, const napi_callback_info &info,
2163     USBTransferAsyncContext *asyncContext)
2164 {
2165     size_t argc = PARAM_COUNT_1;
2166     napi_value argv[PARAM_COUNT_1] = {nullptr};
2167     NAPI_CHECK(env, napi_get_cb_info(env, info, &argc, argv, nullptr, nullptr), "Get call back info failed");
2168     USB_ASSERT_RETURN_FALSE(env, (argc >= PARAM_COUNT_1), OHEC_COMMON_PARAM_ERROR,
2169         "The function at least takes one arguments.");
2170 
2171     napi_valuetype valueType = napi_undefined;
2172     napi_typeof(env, argv[INDEX_0], &valueType);
2173     USB_ASSERT_RETURN_FALSE(
2174         env, valueType == napi_object, OHEC_COMMON_PARAM_ERROR, "The type of pipe must be USBDataTransfer type.");
2175 
2176     bool parseResult = ParseTransferParams(env, argv[INDEX_0], asyncContext);
2177     if (!parseResult) {
2178         USB_HILOGE(MODULE_JS_NAPI, "Transfer wrong params, ParseTransferParams faied");
2179         return false;
2180     }
2181 
2182     return true;
2183 }
2184 
ParmsInput(napi_env env,AsyncCallBackContext & asyncCBWork)2185 static napi_value ParmsInput(napi_env env, AsyncCallBackContext &asyncCBWork)
2186 {
2187     napi_value res = nullptr;
2188     napi_create_object(env, &res);
2189 
2190     napi_value target = nullptr;
2191     napi_create_object(env, &target);
2192     napi_value status = nullptr;
2193     napi_create_int32(env, asyncCBWork.status, &status);
2194 
2195     napi_value actualLength = nullptr;
2196     napi_create_int32(env, asyncCBWork.actualLength, &actualLength);
2197 
2198     napi_set_named_property(env, res, "status", status);
2199     napi_set_named_property(env, res, "actualLength", actualLength);
2200 
2201     if (asyncCBWork.isoInfo.empty()) {
2202         return res;
2203     }
2204     napi_value isoObjArray = nullptr;
2205     napi_create_array(env, &isoObjArray);
2206     const uint32_t isoCount = asyncCBWork.isoInfo.size();
2207     for (uint32_t i = 0; i < isoCount; i++) {
2208         napi_value iso = nullptr;
2209         napi_create_object(env, &iso);
2210         napi_value isoLength = nullptr;
2211         napi_value isoActualLength = nullptr;
2212         napi_value isoStatus = nullptr;
2213         napi_create_int32(env, asyncCBWork.isoInfo[i].isoLength, &isoLength);
2214         napi_create_int32(env, asyncCBWork.isoInfo[i].isoActualLength, &isoActualLength);
2215         napi_create_int32(env, asyncCBWork.isoInfo[i].isoStatus, &isoStatus);
2216         napi_set_named_property(env, iso, "length", isoLength);
2217         napi_set_named_property(env, iso, "actualLength", isoActualLength);
2218         napi_set_named_property(env, iso, "status", isoStatus);
2219         napi_set_element(env, isoObjArray, i, iso);
2220     }
2221     napi_set_named_property(env, res, "isoPacketDescs", isoObjArray);
2222     return res;
2223 }
2224 
ReadDataToBuffer(USBTransferAsyncContext * asyncContext,const TransferCallbackInfo & info)2225 static void ReadDataToBuffer(USBTransferAsyncContext *asyncContext, const TransferCallbackInfo &info)
2226 {
2227     uint8_t endpointId = static_cast<uint8_t>(asyncContext->endpoint) & USB_ENDPOINT_DIR_MASK;
2228     if (endpointId == USB_ENDPOINT_DIR_IN) {
2229         asyncContext->ashmem->MapReadAndWriteAshmem();
2230         auto ashmemBuffer = asyncContext->ashmem->ReadFromAshmem(info.actualLength, 0);
2231         if (ashmemBuffer == nullptr) {
2232             asyncContext->ashmem->UnmapAshmem();
2233             asyncContext->ashmem->CloseAshmem();
2234             return;
2235         }
2236         int32_t ret = memcpy_s(asyncContext->buffer, asyncContext->bufferLength, ashmemBuffer, info.actualLength);
2237         if (ret != EOK) {
2238             USB_HILOGE(MODULE_JS_NAPI, "memcpy_s fatal failed error: %{public}d", ret);
2239         }
2240     }
2241     asyncContext->ashmem->UnmapAshmem();
2242     asyncContext->ashmem->CloseAshmem();
2243 }
2244 
JsCallBack(USBTransferAsyncContext * asyncContext,const TransferCallbackInfo & info,const std::vector<HDI::Usb::V1_2::UsbIsoPacketDescriptor> & isoInfo)2245 static void JsCallBack(USBTransferAsyncContext *asyncContext, const TransferCallbackInfo &info,
2246     const std::vector<HDI::Usb::V1_2::UsbIsoPacketDescriptor> &isoInfo)
2247 {
2248     USB_HILOGI(MODULE_JS_NAPI, "JsCallBack enter.");
2249     ReadDataToBuffer(asyncContext, info);
2250     AsyncCallBackContext *asyncCBWork = new (std::nothrow) AsyncCallBackContext;
2251     if (asyncCBWork == nullptr) {
2252         delete asyncContext;
2253         asyncContext = nullptr;
2254         return;
2255     }
2256     asyncCBWork->env = asyncContext->env;
2257     asyncCBWork->actualLength = info.actualLength;
2258     asyncCBWork->status = info.status;
2259     asyncCBWork->isoInfo = isoInfo;
2260     asyncCBWork->callbackRef = asyncContext->callbackRef;
2261     auto task = [asyncCBWork, asyncContext]() {
2262         std::shared_ptr<AsyncCallBackContext> context(
2263             static_cast<AsyncCallBackContext*>(asyncCBWork),
2264             [asyncContext](AsyncCallBackContext* ptr) {
2265                 delete ptr;
2266                 delete asyncContext;
2267             });
2268         napi_handle_scope scope;
2269         napi_open_handle_scope(asyncCBWork->env, &scope);
2270         napi_status res = napi_ok;
2271         napi_value resultJsCb;
2272         napi_get_reference_value(asyncCBWork->env, asyncCBWork->callbackRef, &resultJsCb);
2273         napi_value argv[2] = {nullptr};
2274         argv[1] = ParmsInput(asyncCBWork->env, *asyncCBWork);
2275         napi_value result;
2276         res = napi_call_function(asyncCBWork->env, nullptr, resultJsCb, PARAM_COUNT_2, argv, &result);
2277         if (res != napi_ok) {
2278             USB_HILOGE(MODULE_JS_NAPI, "napi_call_function failed, res: %{public}d", res);
2279         }
2280         napi_close_handle_scope(asyncCBWork->env, scope);
2281     };
2282     if (napi_status::napi_ok != napi_send_event(asyncCBWork->env, task, napi_eprio_immediate)) {
2283         USB_HILOGE(MODULE_JS_NAPI, "OnJsCallbackVolumeEvent: Failed to SendEvent");
2284         delete asyncCBWork;
2285         asyncCBWork = nullptr;
2286     }
2287 }
2288 
GetUSBTransferInfo(USBTransferInfo & obj,USBTransferAsyncContext * asyncContext)2289 static void GetUSBTransferInfo(USBTransferInfo &obj, USBTransferAsyncContext *asyncContext)
2290 {
2291     obj.endpoint = asyncContext->endpoint;
2292     obj.type = asyncContext->type;
2293     obj.timeOut = asyncContext->timeOut;
2294     obj.length = asyncContext->length;
2295     obj.numIsoPackets = asyncContext->numIsoPackets;
2296     std::uintptr_t ptrValue = reinterpret_cast<std::uintptr_t>(asyncContext);
2297     obj.userData = static_cast<uint64_t>(ptrValue);
2298 }
2299 
CreateAndWriteAshmem(USBTransferAsyncContext * asyncContext,HDI::Usb::V1_2::USBTransferInfo & obj)2300 static bool CreateAndWriteAshmem(USBTransferAsyncContext *asyncContext, HDI::Usb::V1_2::USBTransferInfo &obj)
2301 {
2302     StartTraceEx(HITRACE_LEVEL_INFO, HITRACE_TAG_USB, "NAPI:Ashmem::CreateAshmem");
2303     asyncContext->ashmem = Ashmem::CreateAshmem(asyncContext->name.c_str(), asyncContext->length);
2304     FinishTraceEx(HITRACE_LEVEL_INFO, HITRACE_TAG_USB);
2305     if (asyncContext->ashmem == nullptr) {
2306         USB_HILOGE(MODULE_JS_NAPI, "Ashmem::CreateAshmem failed");
2307         return false;
2308     }
2309     uint8_t endpointId = static_cast<uint8_t>(asyncContext->endpoint) & USB_ENDPOINT_DIR_MASK;
2310     if (endpointId == USB_ENDPOINT_DIR_OUT) {
2311         std::vector<uint8_t> bufferData(asyncContext->buffer, asyncContext->buffer + asyncContext->bufferLength);
2312         obj.length = static_cast<int32_t>(bufferData.size());
2313         asyncContext->ashmem->MapReadAndWriteAshmem();
2314         StartTraceEx(HITRACE_LEVEL_INFO, HITRACE_TAG_USB, "NAPI:WriteToAshmem");
2315         if (!asyncContext->ashmem->WriteToAshmem(asyncContext->buffer, bufferData.size(), 0)) {
2316             FinishTraceEx(HITRACE_LEVEL_INFO, HITRACE_TAG_USB);
2317             asyncContext->ashmem->CloseAshmem();
2318             USB_HILOGE(MODULE_JS_NAPI, "napi UsbSubmitTransfer Failed to UsbSubmitTransfer to ashmem.");
2319             return false;
2320         }
2321         FinishTraceEx(HITRACE_LEVEL_INFO, HITRACE_TAG_USB);
2322     }
2323     return true;
2324 }
2325 
UsbSubmitTransferErrorCode(int32_t & error)2326 static int32_t UsbSubmitTransferErrorCode(int32_t &error)
2327 {
2328     switch (error) {
2329         case IO_ERROR:
2330             return USB_SUBMIT_TRANSFER_IO_ERROR;
2331         case INVALID_PARAM:
2332             return OHEC_COMMON_PARAM_ERROR;
2333         case NO_DEVICE:
2334             return USB_SUBMIT_TRANSFER_NO_DEVICE_ERROR;
2335         case NOT_FOUND:
2336             return USB_SUBMIT_TRANSFER_NOT_FOUND_ERROR;
2337         case ERROR_BUSY:
2338             return USB_SUBMIT_TRANSFER_RESOURCE_BUSY_ERROR;
2339         case NO_MEM:
2340             return USB_SUBMIT_TRANSFER_NO_MEM_ERROR;
2341         case UEC_SERVICE_PERMISSION_DENIED:
2342             return UEC_COMMON_HAS_NO_RIGHT;
2343         default:
2344             return USB_SUBMIT_TRANSFER_OTHER_ERROR;
2345     }
2346 }
2347 
UsbSubmitTransfer(napi_env env,napi_callback_info info)2348 static napi_value UsbSubmitTransfer(napi_env env, napi_callback_info info)
2349 {
2350     HITRACE_METER_NAME(HITRACE_TAG_USB, "NAPI:UsbSubmitTransfer");
2351     if (!HasFeature(FEATURE_HOST)) {
2352         ThrowBusinessError(env, CAPABILITY_NOT_SUPPORT, "");
2353         return nullptr;
2354     }
2355     auto timesUse = std::make_shared<TimesUse>();
2356     timesUse->beginTime = std::chrono::steady_clock::now();
2357     auto asyncContext = new (std::nothrow) USBTransferAsyncContext();
2358     if (asyncContext == nullptr) {
2359         return nullptr;
2360     }
2361     if (!GetTransferParamsFromJsObj(env, info, asyncContext)) {
2362         ThrowBusinessError(env, OHEC_COMMON_PARAM_ERROR, "BusinessError 401:Parameter error.");
2363         delete asyncContext;
2364         asyncContext = nullptr;
2365         return nullptr;
2366     }
2367     asyncContext->env = env;
2368     HDI::Usb::V1_2::USBTransferInfo obj;
2369     GetUSBTransferInfo(obj, asyncContext);
2370     if (!CreateAndWriteAshmem(asyncContext, obj)) {
2371         delete asyncContext;
2372         return nullptr;
2373     }
2374     static auto func = [] (const TransferCallbackInfo &info,
2375         const std::vector<HDI::Usb::V1_2::UsbIsoPacketDescriptor> &isoInfo, uint64_t userData) -> void {
2376         USBTransferAsyncContext *asyncContext = reinterpret_cast<USBTransferAsyncContext *>(userData);
2377         return JsCallBack(asyncContext, info, isoInfo);
2378     };
2379     StartTraceEx(HITRACE_LEVEL_INFO, HITRACE_TAG_USB, "NAPI:UsbSubmitTransfer");
2380     int32_t ret = asyncContext->pipe.UsbSubmitTransfer(obj, func, asyncContext->ashmem);
2381     FinishTraceEx(HITRACE_LEVEL_INFO, HITRACE_TAG_USB);
2382     if (ret != napi_ok) {
2383         asyncContext->ashmem->CloseAshmem();
2384         delete asyncContext;
2385         asyncContext = nullptr;
2386         ret = UsbSubmitTransferErrorCode(ret);
2387         ThrowBusinessError(env, ret, "");
2388         return nullptr;
2389     }
2390     timesUse->endTime = std::chrono::steady_clock::now();
2391     auto duration = std::chrono::duration_cast<std::chrono::milliseconds>(timesUse->endTime - timesUse->beginTime);
2392     USB_HILOGE(MODULE_JS_NAPI, "UsbSubmitTransfer usedTime:%{public}lld ms", duration.count());
2393     return nullptr;
2394 }
2395 
ParseCancelParams(const napi_env & env,const napi_value & object,std::shared_ptr<USBTransferAsyncContext> asyncContext)2396 static bool ParseCancelParams(const napi_env &env, const napi_value &object,
2397     std::shared_ptr<USBTransferAsyncContext> asyncContext)
2398 {
2399     auto timesUse = std::make_shared<TimesUse>();
2400     timesUse->beginTime = std::chrono::steady_clock::now();
2401     napi_value valuePipe = nullptr;
2402     USBDevicePipe pipe;
2403     napi_valuetype valueType;
2404     napi_get_named_property(env, object, "devPipe", &valuePipe);
2405     napi_typeof(env, valuePipe, &valueType);
2406     USB_ASSERT_RETURN_FALSE(env, valueType == napi_object, false, "The valueType of pipe must be USBDevicePipe.");
2407     ParseUsbDevicePipe(env, valuePipe, pipe);
2408     asyncContext->pipe = pipe;
2409 
2410     NapiUtil::JsObjectToInt(env, object, "endpoint", asyncContext->endpoint);
2411     timesUse->endTime = std::chrono::steady_clock::now();
2412     auto duration = std::chrono::duration_cast<std::chrono::milliseconds>(timesUse->endTime - timesUse->beginTime);
2413     USB_HILOGE(MODULE_JS_NAPI, "UsbCancelTransfer usedTime:%{public}lld ms", duration.count());
2414     return true;
2415 }
2416 
GetCancelParamsFromJsObj(const napi_env & env,const napi_callback_info & info,std::shared_ptr<USBTransferAsyncContext> asyncContext)2417 static bool GetCancelParamsFromJsObj(const napi_env &env, const napi_callback_info &info,
2418     std::shared_ptr<USBTransferAsyncContext> asyncContext)
2419 {
2420     size_t argc = PARAM_COUNT_1;
2421     napi_value argv[PARAM_COUNT_1] = {nullptr};
2422     NAPI_CHECK(env, napi_get_cb_info(env, info, &argc, argv, nullptr, nullptr), "Get call back info failed");
2423     USB_ASSERT_RETURN_FALSE(env, (argc >= PARAM_COUNT_1), OHEC_COMMON_PARAM_ERROR,
2424         "The function at least takes one arguments.");
2425 
2426     napi_valuetype valueType = napi_undefined;
2427     napi_typeof(env, argv[INDEX_0], &valueType);
2428     USB_ASSERT_RETURN_FALSE(
2429         env, valueType == napi_object, OHEC_COMMON_PARAM_ERROR, "The type of pipe must be USBDataTransfer type.");
2430 
2431     bool parseResult = ParseCancelParams(env, argv[INDEX_0], asyncContext);
2432     if (!parseResult) {
2433         USB_HILOGE(MODULE_JS_NAPI, "Transfer wrong params, ParseCancelParams faied");
2434         return false;
2435     }
2436 
2437     return true;
2438 }
2439 
UsbCancelTransfer(napi_env env,napi_callback_info info)2440 static napi_value UsbCancelTransfer(napi_env env, napi_callback_info info)
2441 {
2442     HITRACE_METER_NAME(HITRACE_TAG_USB, "NAPI:UsbCancelTransfer");
2443     if (!HasFeature(FEATURE_HOST)) {
2444         ThrowBusinessError(env, CAPABILITY_NOT_SUPPORT, "");
2445         return nullptr;
2446     }
2447     auto asyncContext = std::make_shared<USBTransferAsyncContext>();
2448     if (asyncContext == nullptr) {
2449         USB_HILOGE(MODULE_JS_NAPI, "Create USBTransferAsyncContext failed.");
2450         return nullptr;
2451     }
2452     if (!GetCancelParamsFromJsObj(env, info, asyncContext)) {
2453         USB_HILOGE(MODULE_JS_NAPI, "end call invalid arg");
2454         ThrowBusinessError(env, OHEC_COMMON_PARAM_ERROR, "BusinessError 401:Parameter error.");
2455         return nullptr;
2456     }
2457 
2458     StartTraceEx(HITRACE_LEVEL_INFO, HITRACE_TAG_USB, "NAPI:pipe.UsbCancelTransfer");
2459     int32_t ret = asyncContext->pipe.UsbCancelTransfer(asyncContext->endpoint);
2460     FinishTraceEx(HITRACE_LEVEL_INFO, HITRACE_TAG_USB);
2461     if (ret != napi_ok) {
2462         ret = UsbSubmitTransferErrorCode(ret);
2463         ThrowBusinessError(env, ret, "");
2464         return nullptr;
2465     }
2466     return nullptr;
2467 }
2468 
PipeResetDevice(napi_env env,napi_callback_info info)2469 static napi_value PipeResetDevice(napi_env env, napi_callback_info info)
2470 {
2471     if (!HasFeature(FEATURE_HOST)) {
2472         ThrowBusinessError(env, CAPABILITY_NOT_SUPPORT, "");
2473         return nullptr;
2474     }
2475     size_t argc = PARAM_COUNT_1;
2476     napi_value argv[PARAM_COUNT_1] = {nullptr};
2477 
2478     NAPI_CHECK(env, napi_get_cb_info(env, info, &argc, argv, nullptr, nullptr), "Get call back info failed");
2479     USB_ASSERT(env, (argc >= PARAM_COUNT_1), OHEC_COMMON_PARAM_ERROR, "The function at least takes one argument.");
2480     napi_value deciveObj = argv[INDEX_0];
2481     napi_valuetype type;
2482     napi_typeof(env, deciveObj, &type);
2483     USB_ASSERT(env, type == napi_object, OHEC_COMMON_PARAM_ERROR, "The type of pipe must be USBDevicePipe.");
2484 
2485     USBDevicePipe pipe;
2486     ParseUsbDevicePipe(env, deciveObj, pipe);
2487 
2488     napi_value napiValue;
2489     int32_t ret = g_usbClient.ResetDevice(pipe);
2490     if (ret == UEC_OK) {
2491         napi_get_boolean(env, true, &napiValue);
2492     } else if (ret == HDF_DEV_ERR_NO_DEVICE || ret == UEC_INTERFACE_NAME_NOT_FOUND) {
2493         ThrowBusinessError(env, USB_SUBMIT_TRANSFER_NO_DEVICE_ERROR,
2494             "Submit transfer no device.");
2495         napi_get_boolean(env, false, &napiValue);
2496     } else if (ret == UEC_SERVICE_PERMISSION_DENIED) {
2497         ThrowBusinessError(env, UEC_COMMON_HAS_NO_RIGHT,
2498             "No permission.");
2499         napi_get_boolean(env, false, &napiValue);
2500     } else if (ret == HDF_FAILURE) {
2501         ThrowBusinessError(env, USB_DEVICE_PIPE_CHECK_ERROR,
2502             "Check devicePipe failed.");
2503         napi_get_boolean(env, false, &napiValue);
2504     } else if (ret == UEC_SERVICE_INVALID_VALUE) {
2505         ThrowBusinessError(env, UEC_COMMON_SERVICE_EXCEPTION,
2506             "Service exception");
2507         napi_get_boolean(env, false, &napiValue);
2508     } else {
2509         ThrowBusinessError(env, USB_SUBMIT_TRANSFER_OTHER_ERROR,
2510             "Other USB error");
2511         napi_get_boolean(env, false, &napiValue);
2512     }
2513     return napiValue;
2514 }
2515 
SetEnumProperty(napi_env env,napi_value object,const std::string & name,int32_t value)2516 static void SetEnumProperty(napi_env env, napi_value object, const std::string &name, int32_t value)
2517 {
2518     if (name.empty()) {
2519         USB_HILOGE(MODULE_JS_NAPI, "Property name cannot be an empty string");
2520         return;
2521     }
2522 
2523     napi_value tempValue = nullptr;
2524     napi_status status = napi_create_int32(env, value, &tempValue);
2525     if (status != napi_ok) {
2526         USB_HILOGE(MODULE_JS_NAPI, "Failed to create int32 value for enum %{public}s", name.c_str());
2527         return;
2528     }
2529     status = napi_set_named_property(env, object, name.c_str(), tempValue);
2530     if (status != napi_ok) {
2531         USB_HILOGE(MODULE_JS_NAPI, "Failed to set property %{public}s", name.c_str());
2532         return;
2533     }
2534 }
2535 
NapiCreateFlagsEnum(napi_env env)2536 static napi_value NapiCreateFlagsEnum(napi_env env)
2537 {
2538     napi_value object = nullptr;
2539     napi_status status = napi_create_object(env, &object);
2540     if (status != napi_ok) {
2541         USB_HILOGE(MODULE_JS_NAPI, "Failed to create object");
2542         return nullptr;
2543     }
2544     SetEnumProperty(env, object, "USB_TRANSFER_SHORT_NOT_OK", USB_TRANSFER_SHORT_NOT_OK);
2545     SetEnumProperty(env, object, "USB_TRANSFER_FREE_BUFFER", USB_TRANSFER_FREE_BUFFER);
2546     SetEnumProperty(env, object, "USB_TRANSFER_FREE_TRANSFER", USB_TRANSFER_FREE_TRANSFER);
2547     SetEnumProperty(env, object, "USB_TRANSFER_ADD_ZERO_PACKET", USB_TRANSFER_ADD_ZERO_PACKET);
2548     return object;
2549 }
2550 
NapiCreateTypeEnum(napi_env env)2551 static napi_value NapiCreateTypeEnum(napi_env env)
2552 {
2553     napi_value object = nullptr;
2554     napi_status status = napi_create_object(env, &object);
2555     if (status != napi_ok) {
2556         USB_HILOGE(MODULE_JS_NAPI, "Failed to create object");
2557         return nullptr;
2558     }
2559     SetEnumProperty(env, object, "TRANSFER_TYPE_ISOCHRONOUS", TRANSFER_TYPE_ISOCHRONOUS);
2560     SetEnumProperty(env, object, "TRANSFER_TYPE_BULK", TRANSFER_TYPE_BULK);
2561     SetEnumProperty(env, object, "TRANSFER_TYPE_INTERRUPT", TRANSFER_TYPE_INTERRUPT);
2562     return object;
2563 }
2564 
NapiCreateStatusEnum(napi_env env)2565 static napi_value NapiCreateStatusEnum(napi_env env)
2566 {
2567     napi_value object = nullptr;
2568     napi_status status = napi_create_object(env, &object);
2569     if (status != napi_ok) {
2570         USB_HILOGE(MODULE_JS_NAPI, "Failed to create object");
2571         return nullptr;
2572     }
2573     SetEnumProperty(env, object, "TRANSFER_COMPLETED", TRANSFER_COMPLETED);
2574     SetEnumProperty(env, object, "TRANSFER_ERROR", TRANSFER_ERROR);
2575     SetEnumProperty(env, object, "TRANSFER_TIMED_OUT", TRANSFER_TIMED_OUT);
2576     SetEnumProperty(env, object, "TRANSFER_CANCELED", TRANSFER_CANCELED);
2577     SetEnumProperty(env, object, "TRANSFER_STALL", TRANSFER_STALL);
2578     SetEnumProperty(env, object, "TRANSFER_NO_DEVICE", TRANSFER_NO_DEVICE);
2579     SetEnumProperty(env, object, "TRANSFER_OVERFLOW", TRANSFER_OVERFLOW);
2580     return object;
2581 }
2582 
PipeClose(napi_env env,napi_callback_info info)2583 static napi_value PipeClose(napi_env env, napi_callback_info info)
2584 {
2585     if (!HasFeature(FEATURE_HOST)) {
2586         ThrowBusinessError(env, CAPABILITY_NOT_SUPPORT, "");
2587         return nullptr;
2588     }
2589     size_t argc = PARAM_COUNT_1;
2590     napi_value argv[PARAM_COUNT_1] = {nullptr};
2591 
2592     NAPI_CHECK(env, napi_get_cb_info(env, info, &argc, argv, nullptr, nullptr), "Get call back info failed");
2593     USB_ASSERT(env, (argc >= PARAM_COUNT_1), OHEC_COMMON_PARAM_ERROR, "The function takes one argument.");
2594 
2595     napi_value obj = argv[INDEX_0];
2596     napi_valuetype type;
2597     napi_typeof(env, obj, &type);
2598     USB_ASSERT(env, type == napi_object, OHEC_COMMON_PARAM_ERROR, "The type of pipe must be USBDevicePipe.");
2599 
2600     USBDevicePipe pipe;
2601     ParseUsbDevicePipe(env, obj, pipe);
2602     int32_t ret = pipe.Close();
2603     napi_value result;
2604     napi_create_int32(env, ret, &result);
2605 
2606     return result;
2607 }
2608 
GetVersion(napi_env env,napi_callback_info info)2609 static napi_value GetVersion(napi_env env, napi_callback_info info)
2610 {
2611     auto version = g_usbClient.GetVersion();
2612     USB_HILOGD(MODULE_JS_NAPI, "version is %{public}s", version.c_str());
2613     napi_value result;
2614     napi_create_string_utf8(env, version.c_str(), NAPI_AUTO_LENGTH, &result);
2615     return result;
2616 }
2617 
ToInt32Value(napi_env env,int32_t value)2618 static napi_value ToInt32Value(napi_env env, int32_t value)
2619 {
2620     napi_value staticValue = nullptr;
2621     napi_create_int32(env, value, &staticValue);
2622     return staticValue;
2623 }
2624 
PowerRoleTypeEnum(napi_env env)2625 static napi_value PowerRoleTypeEnum(napi_env env)
2626 {
2627     napi_value object = nullptr;
2628     napi_status status = napi_create_object(env, &object);
2629     if (status != napi_ok) {
2630         USB_HILOGE(MODULE_JS_NAPI, "Failed to create object");
2631         return nullptr;
2632     }
2633     SetEnumProperty(env, object, "NONE", NONE);
2634     SetEnumProperty(env, object, "SOURCE", SOURCE);
2635     SetEnumProperty(env, object, "SINK", SINK);
2636     return object;
2637 }
2638 
DataRoleTypeEnum(napi_env env)2639 static napi_value DataRoleTypeEnum(napi_env env)
2640 {
2641     napi_value object = nullptr;
2642     napi_status status = napi_create_object(env, &object);
2643     if (status != napi_ok) {
2644         USB_HILOGE(MODULE_JS_NAPI, "Failed to create object");
2645         return nullptr;
2646     }
2647     SetEnumProperty(env, object, "HOST", HOST);
2648     SetEnumProperty(env, object, "DEVICE", DEVICE);
2649     return object;
2650 }
2651 
PortModeTypeEnum(napi_env env)2652 static napi_value PortModeTypeEnum(napi_env env)
2653 {
2654     napi_value object = nullptr;
2655     napi_status status = napi_create_object(env, &object);
2656     if (status != napi_ok) {
2657         USB_HILOGE(MODULE_JS_NAPI, "Failed to create object");
2658         return nullptr;
2659     }
2660     SetEnumProperty(env, object, "UFP", UFP);
2661     SetEnumProperty(env, object, "DFP", DFP);
2662     SetEnumProperty(env, object, "DRP", DRP);
2663     SetEnumProperty(env, object, "NUM_MODES", NUM_MODES);
2664     return object;
2665 }
2666 
USBRequestTargetTypeEnum(napi_env env)2667 static napi_value USBRequestTargetTypeEnum(napi_env env)
2668 {
2669     napi_value object = nullptr;
2670     napi_status status = napi_create_object(env, &object);
2671     if (status != napi_ok) {
2672         USB_HILOGE(MODULE_JS_NAPI, "Failed to create object");
2673         return nullptr;
2674     }
2675     SetEnumProperty(env, object, "USB_REQUEST_TARGET_DEVICE", USB_REQUEST_TARGET_DEVICE);
2676     SetEnumProperty(env, object, "USB_REQUEST_TARGET_INTERFACE", USB_REQUEST_TARGET_INTERFACE);
2677     SetEnumProperty(env, object, "USB_REQUEST_TARGET_ENDPOINT", USB_REQUEST_TARGET_ENDPOINT);
2678     SetEnumProperty(env, object, "USB_REQUEST_TARGET_OTHER", USB_REQUEST_TARGET_OTHER);
2679     return object;
2680 }
2681 
USBControlRequestTypeEnum(napi_env env)2682 static napi_value USBControlRequestTypeEnum(napi_env env)
2683 {
2684     napi_value object = nullptr;
2685     napi_status status = napi_create_object(env, &object);
2686     if (status != napi_ok) {
2687         USB_HILOGE(MODULE_JS_NAPI, "Failed to create object");
2688         return nullptr;
2689     }
2690     SetEnumProperty(env, object, "USB_REQUEST_TYPE_STANDARD", USB_REQUEST_TYPE_STANDARD);
2691     SetEnumProperty(env, object, "USB_REQUEST_TYPE_CLASS", USB_REQUEST_TYPE_CLASS);
2692     SetEnumProperty(env, object, "USB_REQUEST_TYPE_VENDOR", USB_REQUEST_TYPE_VENDOR);
2693     return object;
2694 }
2695 
USBRequestDirectionEnum(napi_env env)2696 static napi_value USBRequestDirectionEnum(napi_env env)
2697 {
2698     napi_value object = nullptr;
2699     napi_status status = napi_create_object(env, &object);
2700     if (status != napi_ok) {
2701         USB_HILOGE(MODULE_JS_NAPI, "Failed to create object");
2702         return nullptr;
2703     }
2704     SetEnumProperty(env, object, "USB_REQUEST_DIR_TO_DEVICE", USB_REQUEST_DIR_TO_DEVICE);
2705     SetEnumProperty(env, object, "USB_REQUEST_DIR_FROM_DEVICE", USB_REQUEST_DIR_FROM_DEVICE);
2706     return object;
2707 }
2708 
FunctionTypeEnum(napi_env env)2709 static napi_value FunctionTypeEnum(napi_env env)
2710 {
2711     napi_value object = nullptr;
2712     napi_status status = napi_create_object(env, &object);
2713     if (status != napi_ok) {
2714         USB_HILOGE(MODULE_JS_NAPI, "Failed to create object");
2715         return nullptr;
2716     }
2717     SetEnumProperty(env, object, "ACM", ACM);
2718     SetEnumProperty(env, object, "ECM", ECM);
2719     SetEnumProperty(env, object, "HDC", HDC);
2720     SetEnumProperty(env, object, "MTP", MTP);
2721     SetEnumProperty(env, object, "PTP", PTP);
2722     SetEnumProperty(env, object, "RNDIS", RNDIS);
2723     SetEnumProperty(env, object, "MIDI", MIDI);
2724     SetEnumProperty(env, object, "AUDIO_SOURCE", AUDIO_SOURCE);
2725     SetEnumProperty(env, object, "NCM", NCM);
2726     SetEnumProperty(env, object, "STORAGE", STORAGE);
2727     return object;
2728 }
2729 
DeclareEnum(napi_env env,napi_value exports)2730 static napi_value DeclareEnum(napi_env env, napi_value exports)
2731 {
2732     napi_property_descriptor desc[] = {
2733         /* Declare Enum PowerRoleType */
2734         DECLARE_NAPI_STATIC_PROPERTY("NONE", ToInt32Value(env, NONE)),
2735         DECLARE_NAPI_STATIC_PROPERTY("SOURCE", ToInt32Value(env, SOURCE)),
2736         DECLARE_NAPI_STATIC_PROPERTY("SINK", ToInt32Value(env, SINK)),
2737         DECLARE_NAPI_STATIC_PROPERTY("PowerRoleType", PowerRoleTypeEnum(env)),
2738 
2739         /* Declare Enum DataRoleType */
2740         DECLARE_NAPI_STATIC_PROPERTY("HOST", ToInt32Value(env, HOST)),
2741         DECLARE_NAPI_STATIC_PROPERTY("DEVICE", ToInt32Value(env, DEVICE)),
2742         DECLARE_NAPI_STATIC_PROPERTY("DataRoleType", DataRoleTypeEnum(env)),
2743 
2744         /* Declare Enum PortModeType */
2745         DECLARE_NAPI_STATIC_PROPERTY("UFP", ToInt32Value(env, UFP)),
2746         DECLARE_NAPI_STATIC_PROPERTY("DFP", ToInt32Value(env, DFP)),
2747         DECLARE_NAPI_STATIC_PROPERTY("DRP", ToInt32Value(env, DRP)),
2748         DECLARE_NAPI_STATIC_PROPERTY("NUM_MODES", ToInt32Value(env, NUM_MODES)),
2749         DECLARE_NAPI_STATIC_PROPERTY("PortModeType", PortModeTypeEnum(env)),
2750 
2751         /* Declare Enum USBRequestTargetType */
2752         DECLARE_NAPI_STATIC_PROPERTY("USB_REQUEST_TARGET_DEVICE", ToInt32Value(env, USB_REQUEST_TARGET_DEVICE)),
2753         DECLARE_NAPI_STATIC_PROPERTY("USB_REQUEST_TARGET_INTERFACE", ToInt32Value(env, USB_REQUEST_TARGET_INTERFACE)),
2754         DECLARE_NAPI_STATIC_PROPERTY("USB_REQUEST_TARGET_ENDPOINT", ToInt32Value(env, USB_REQUEST_TARGET_ENDPOINT)),
2755         DECLARE_NAPI_STATIC_PROPERTY("USB_REQUEST_TARGET_OTHER", ToInt32Value(env, USB_REQUEST_TARGET_OTHER)),
2756         DECLARE_NAPI_STATIC_PROPERTY("USBRequestTargetType", USBRequestTargetTypeEnum(env)),
2757 
2758         /* Declare Enum USBControlRequestType */
2759         DECLARE_NAPI_STATIC_PROPERTY("USB_REQUEST_TYPE_STANDARD", ToInt32Value(env, USB_REQUEST_TYPE_STANDARD)),
2760         DECLARE_NAPI_STATIC_PROPERTY("USB_REQUEST_TYPE_CLASS", ToInt32Value(env, USB_REQUEST_TYPE_CLASS)),
2761         DECLARE_NAPI_STATIC_PROPERTY("USB_REQUEST_TYPE_VENDOR", ToInt32Value(env, USB_REQUEST_TYPE_VENDOR)),
2762         DECLARE_NAPI_STATIC_PROPERTY("USBControlRequestType", USBControlRequestTypeEnum(env)),
2763 
2764         /* Declare Enum USBRequestDirection */
2765         DECLARE_NAPI_STATIC_PROPERTY("USB_REQUEST_DIR_TO_DEVICE", ToInt32Value(env, USB_REQUEST_DIR_TO_DEVICE)),
2766         DECLARE_NAPI_STATIC_PROPERTY("USB_REQUEST_DIR_FROM_DEVICE", ToInt32Value(env, USB_REQUEST_DIR_FROM_DEVICE)),
2767         DECLARE_NAPI_STATIC_PROPERTY("USBRequestDirection", USBRequestDirectionEnum(env)),
2768 
2769         /* Declare Enum FunctionType */
2770         DECLARE_NAPI_STATIC_PROPERTY("ACM", ToInt32Value(env, ACM)),
2771         DECLARE_NAPI_STATIC_PROPERTY("ECM", ToInt32Value(env, ECM)),
2772         DECLARE_NAPI_STATIC_PROPERTY("HDC", ToInt32Value(env, HDC)),
2773         DECLARE_NAPI_STATIC_PROPERTY("MTP", ToInt32Value(env, MTP)),
2774         DECLARE_NAPI_STATIC_PROPERTY("PTP", ToInt32Value(env, PTP)),
2775         DECLARE_NAPI_STATIC_PROPERTY("RNDIS", ToInt32Value(env, RNDIS)),
2776         DECLARE_NAPI_STATIC_PROPERTY("MIDI", ToInt32Value(env, MIDI)),
2777         DECLARE_NAPI_STATIC_PROPERTY("AUDIO_SOURCE", ToInt32Value(env, AUDIO_SOURCE)),
2778         DECLARE_NAPI_STATIC_PROPERTY("NCM", ToInt32Value(env, NCM)),
2779         DECLARE_NAPI_STATIC_PROPERTY("STORAGE", ToInt32Value(env, STORAGE)),
2780         DECLARE_NAPI_STATIC_PROPERTY("FunctionType", FunctionTypeEnum(env)),
2781         DECLARE_NAPI_STATIC_PROPERTY("UsbTransferFlags", NapiCreateFlagsEnum(env)),
2782         DECLARE_NAPI_STATIC_PROPERTY("UsbEndpointTransferType", NapiCreateTypeEnum(env)),
2783         DECLARE_NAPI_STATIC_PROPERTY("UsbTransferStatus", NapiCreateStatusEnum(env)),
2784     };
2785     NAPI_CALL(env, napi_define_properties(env, exports, sizeof(desc) / sizeof(desc[0]), desc));
2786     return exports;
2787 }
2788 
2789 EXTERN_C_START
2790 /*
2791  * function for module exports
2792  */
UsbInit(napi_env env,napi_value exports)2793 napi_value UsbInit(napi_env env, napi_value exports)
2794 {
2795     USB_HILOGD(MODULE_JS_NAPI, "enter");
2796 
2797     napi_property_descriptor desc[] = {
2798         /* usb core */
2799         DECLARE_NAPI_FUNCTION("getDevices", CoreGetDevices),
2800         DECLARE_NAPI_FUNCTION("connectDevice", CoreConnectDevice),
2801         DECLARE_NAPI_FUNCTION("hasRight", CoreHasRight),
2802         DECLARE_NAPI_FUNCTION("requestRight", CoreRequestRight),
2803         DECLARE_NAPI_FUNCTION("usbFunctionsFromString", CoreUsbFunctionsFromString),
2804         DECLARE_NAPI_FUNCTION("getFunctionsFromString", CoreUsbFunctionsFromString),
2805         DECLARE_NAPI_FUNCTION("usbFunctionsToString", CoreUsbFunctionsToString),
2806         DECLARE_NAPI_FUNCTION("getStringFromFunctions", CoreUsbFunctionsToString),
2807         DECLARE_NAPI_FUNCTION("setCurrentFunctions", CoreSetCurrentFunctions),
2808         DECLARE_NAPI_FUNCTION("setDeviceFunctions", CoreSetCurrentFunctions),
2809         DECLARE_NAPI_FUNCTION("getCurrentFunctions", CoreGetCurrentFunctions),
2810         DECLARE_NAPI_FUNCTION("getDeviceFunctions", CoreGetCurrentFunctions),
2811         DECLARE_NAPI_FUNCTION("getPorts", CoreGetPorts),
2812         DECLARE_NAPI_FUNCTION("getPortList", CoreGetPorts),
2813 
2814         /* usb port */
2815         DECLARE_NAPI_FUNCTION("getSupportedModes", PortGetSupportedModes),
2816         DECLARE_NAPI_FUNCTION("getPortSupportModes", PortGetSupportedModes),
2817         DECLARE_NAPI_FUNCTION("setPortRoles", PortSetPortRole),
2818         DECLARE_NAPI_FUNCTION("setPortRoleTypes", PortSetPortRole),
2819 
2820         /* usb device pipe */
2821         DECLARE_NAPI_FUNCTION("claimInterface", PipeClaimInterface),
2822         DECLARE_NAPI_FUNCTION("releaseInterface", PipeReleaseInterface),
2823         DECLARE_NAPI_FUNCTION("bulkTransfer", PipeBulkTransfer),
2824         DECLARE_NAPI_FUNCTION("controlTransfer", PipeControlTransfer),
2825         DECLARE_NAPI_FUNCTION("usbControlTransfer", PipeUsbControlTransfer),
2826         DECLARE_NAPI_FUNCTION("setInterface", PipeSetInterface),
2827         DECLARE_NAPI_FUNCTION("setConfiguration", PipeSetConfiguration),
2828         DECLARE_NAPI_FUNCTION("getRawDescriptor", PipeGetRawDescriptors),
2829         DECLARE_NAPI_FUNCTION("getFileDescriptor", PipeGetFileDescriptor),
2830         DECLARE_NAPI_FUNCTION("closePipe", PipeClose),
2831         DECLARE_NAPI_FUNCTION("resetUsbDevice", PipeResetDevice),
2832         DECLARE_NAPI_FUNCTION("usbCancelTransfer", UsbCancelTransfer),
2833         DECLARE_NAPI_FUNCTION("usbSubmitTransfer", UsbSubmitTransfer),
2834 
2835         /* fort test get usb service version */
2836         DECLARE_NAPI_FUNCTION("getVersion", GetVersion),
2837         DECLARE_NAPI_FUNCTION("addRight", DeviceAddRight),
2838         DECLARE_NAPI_FUNCTION("addDeviceAccessRight", DeviceAddAccessRight),
2839         DECLARE_NAPI_FUNCTION("removeRight", DeviceRemoveRight),
2840         DECLARE_NAPI_FUNCTION("getAccessoryList", DeviceGetAccessoryList),
2841         DECLARE_NAPI_FUNCTION("openAccessory", DeviceOpenAccessory),
2842         DECLARE_NAPI_FUNCTION("closeAccessory", DeviceCloseAccessory),
2843         DECLARE_NAPI_FUNCTION("addAccessoryRight", DeviceAddAccessoryRight),
2844         DECLARE_NAPI_FUNCTION("hasAccessoryRight", DeviceHasAccessoryRight),
2845         DECLARE_NAPI_FUNCTION("requestAccessoryRight", DeviceRequestAccessoryRight),
2846         DECLARE_NAPI_FUNCTION("cancelAccessoryRight", DeviceCancelAccessoryRight),
2847     };
2848     NAPI_CALL(env, napi_define_properties(env, exports, sizeof(desc) / sizeof(desc[0]), desc));
2849 
2850     DeclareEnum(env, exports);
2851 
2852     USB_HILOGD(MODULE_JS_NAPI, "return");
2853 
2854     return exports;
2855 }
2856 EXTERN_C_END
2857