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