1 /*
2  * Copyright (c) 2021-2023 Huawei Device Co., Ltd.
3  * Licensed under the Apache License, Version 2.0 (the "License");
4  * you may not use this file except in compliance with the License.
5  * You may obtain a copy of the License at
6  *
7  * http://www.apache.org/licenses/LICENSE-2.0
8  *
9  * Unless required by applicable law or agreed to in writing, software
10  * distributed under the License is distributed on an "AS IS" BASIS,
11  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12  * See the License for the specific language governing permissions and
13  * limitations under the License.
14  */
15 
16 #include <unistd.h>
17 
18 #include <sys/time.h>
19 
20 #include <cstdio>
21 #include <cstdlib>
22 #include <iostream>
23 #include <sstream>
24 #include <string>
25 
26 #include "hilog_wrapper.h"
27 #include "napi/native_api.h"
28 #include "napi/native_node_api.h"
29 #include "napi_common.h"
30 #include "napi_util.h"
31 #include "securec.h"
32 #include "usb_async_context.h"
33 #include "usb_device_pipe.h"
34 #include "usb_endpoint.h"
35 #include "usb_errors.h"
36 #include "usb_napi_errors.h"
37 #include "usb_srv_client.h"
38 #include "usb_accessory.h"
39 using namespace OHOS;
40 using namespace OHOS::USB;
41 using namespace OHOS::HDI::Usb::V1_0;
42 using namespace OHOS::HDI::Usb::V1_1;
43 
44 static constexpr int32_t INDEX_0 = 0;
45 static constexpr int32_t INDEX_1 = 1;
46 static constexpr int32_t INDEX_2 = 2;
47 static constexpr int32_t INDEX_3 = 3;
48 static constexpr int32_t PARAM_COUNT_0 = 0;
49 static constexpr int32_t PARAM_COUNT_1 = 1;
50 static constexpr int32_t PARAM_COUNT_2 = 2;
51 static constexpr int32_t PARAM_COUNT_3 = 3;
52 static constexpr int32_t PARAM_COUNT_4 = 4;
53 static constexpr int32_t STR_DEFAULT_SIZE = 256;
54 static constexpr int32_t DEFAULT_DESCRIPTION_SIZE = 32;
55 static constexpr int32_t DEFAULT_ACCESSORY_DESCRIPTION_SIZE = 256;
56 static int32_t g_accFd = 0;
ParseUsbDevicePipe(const napi_env env,const napi_value & obj,USBDevicePipe & pipe)57 static void ParseUsbDevicePipe(const napi_env env, const napi_value &obj, USBDevicePipe &pipe)
58 {
59     napi_valuetype valueType;
60     napi_typeof(env, obj, &valueType);
61     USB_ASSERT_RETURN_VOID(
62         env, valueType == napi_object, OHEC_COMMON_PARAM_ERROR, "The type of pipe must be USBDevicePipe.");
63 
64     int32_t busNum = 0;
65     NapiUtil::JsObjectToInt(env, obj, "busNum", busNum);
66     pipe.SetBusNum(static_cast<uint8_t>(busNum));
67     int32_t devAddr = 0;
68     NapiUtil::JsObjectToInt(env, obj, "devAddress", devAddr);
69     pipe.SetDevAddr(static_cast<uint8_t>(devAddr));
70 }
71 
ProcessPromise(const napi_env env,const USBAsyncContext & asyncContext,napi_value & result)72 static void ProcessPromise(const napi_env env, const USBAsyncContext &asyncContext, napi_value &result)
73 {
74     if (asyncContext.deferred) {
75         if (asyncContext.status == napi_ok) {
76             napi_resolve_deferred(env, asyncContext.deferred, result);
77         } else {
78             napi_reject_deferred(env, asyncContext.deferred, result);
79         }
80     }
81 }
82 
CreateUsbDevicePipe(const napi_env env,napi_value & obj,const USBDevicePipe & pipe)83 static void CreateUsbDevicePipe(const napi_env env, napi_value &obj, const USBDevicePipe &pipe)
84 {
85     napi_create_object(env, &obj);
86     NapiUtil::SetValueInt32(env, "busNum", pipe.GetBusNum(), obj);
87     NapiUtil::SetValueInt32(env, "devAddress", pipe.GetDevAddr(), obj);
88 }
89 
CreatAccessoryHandle(const napi_env env,napi_value & obj,int32_t fd)90 static void CreatAccessoryHandle(const napi_env env, napi_value &obj, int32_t fd)
91 {
92     napi_create_object(env, &obj);
93     NapiUtil::SetValueInt32(env, "accessoryFd", fd, obj);
94 }
95 
CtoJSUsbEndpoint(const napi_env & env,napi_value & obj,const USBEndpoint & usbEndpoint)96 static void CtoJSUsbEndpoint(const napi_env &env, napi_value &obj, const USBEndpoint &usbEndpoint)
97 {
98     napi_create_object(env, &obj);
99     NapiUtil::SetValueUint32(env, "address", usbEndpoint.GetAddress(), obj);
100     NapiUtil::SetValueUint32(env, "attributes", usbEndpoint.GetAttributes(), obj);
101     NapiUtil::SetValueInt32(env, "interval", usbEndpoint.GetInterval(), obj);
102     NapiUtil::SetValueInt32(env, "maxPacketSize", usbEndpoint.GetMaxPacketSize(), obj);
103     NapiUtil::SetValueUint32(env, "direction", usbEndpoint.GetDirection(), obj);
104     NapiUtil::SetValueUint32(env, "number", usbEndpoint.GetEndpointNumber(), obj);
105     NapiUtil::SetValueUint32(env, "type", usbEndpoint.GetType(), obj);
106     NapiUtil::SetValueInt32(env, "interfaceId", usbEndpoint.GetInterfaceId(), obj);
107 }
108 
CtoJSUsbInterface(const napi_env & env,napi_value & obj,const UsbInterface & usbInterface)109 static void CtoJSUsbInterface(const napi_env &env, napi_value &obj, const UsbInterface &usbInterface)
110 {
111     napi_create_object(env, &obj);
112     NapiUtil::SetValueInt32(env, "id", usbInterface.GetId(), obj);
113     NapiUtil::SetValueInt32(env, "protocol", usbInterface.GetProtocol(), obj);
114     NapiUtil::SetValueInt32(env, "clazz", usbInterface.GetClass(), obj);
115     NapiUtil::SetValueInt32(env, "subClass", usbInterface.GetSubClass(), obj);
116     NapiUtil::SetValueInt32(env, "alternateSetting", usbInterface.GetAlternateSetting(), obj);
117     NapiUtil::SetValueUtf8String(env, "name", usbInterface.GetName(), obj);
118 
119     napi_value arr;
120     napi_create_array(env, &arr);
121     for (int32_t i = 0; i < usbInterface.GetEndpointCount(); ++i) {
122         auto usbEndpoint = usbInterface.GetEndpoint(i);
123         if (!usbEndpoint.has_value()) {
124             USB_HILOGE(MODULE_JS_NAPI, "GetEndpoint failed i=%{public}d", i);
125             return;
126         }
127 
128         napi_value objTmp;
129         CtoJSUsbEndpoint(env, objTmp, usbEndpoint.value());
130         napi_set_element(env, arr, i, objTmp);
131     }
132     napi_set_named_property(env, obj, "endpoints", arr);
133 }
134 
CtoJSUsbConfig(const napi_env & env,napi_value & obj,const USBConfig & usbConfig)135 static void CtoJSUsbConfig(const napi_env &env, napi_value &obj, const USBConfig &usbConfig)
136 {
137     napi_create_object(env, &obj);
138     NapiUtil::SetValueInt32(env, "id", usbConfig.GetId(), obj);
139     NapiUtil::SetValueUint32(env, "attributes", usbConfig.GetAttributes(), obj);
140     NapiUtil::SetValueBool(env, "isRemoteWakeup", usbConfig.IsRemoteWakeup(), obj);
141     NapiUtil::SetValueBool(env, "isSelfPowered", usbConfig.IsSelfPowered(), obj);
142     NapiUtil::SetValueInt32(env, "maxPower", usbConfig.GetMaxPower(), obj);
143     NapiUtil::SetValueUtf8String(env, "name", usbConfig.GetName(), obj);
144     napi_value arr;
145     napi_create_array(env, &arr);
146     for (uint32_t i = 0; i < usbConfig.GetInterfaceCount(); ++i) {
147         UsbInterface usbInterface;
148         usbConfig.GetInterface(i, usbInterface);
149         napi_value objTmp;
150         CtoJSUsbInterface(env, objTmp, usbInterface);
151         napi_set_element(env, arr, i, objTmp);
152     }
153     napi_set_named_property(env, obj, "interfaces", arr);
154 }
155 
CtoJSUsbDevice(const napi_env & env,napi_value & obj,const UsbDevice & usbDevice)156 static void CtoJSUsbDevice(const napi_env &env, napi_value &obj, const UsbDevice &usbDevice)
157 {
158     napi_create_object(env, &obj);
159     NapiUtil::SetValueUtf8String(env, "name", usbDevice.GetName(), obj);
160     NapiUtil::SetValueUtf8String(env, "serial", usbDevice.GetmSerial(), obj);
161     NapiUtil::SetValueUtf8String(env, "manufacturerName", usbDevice.GetManufacturerName(), obj);
162     NapiUtil::SetValueUtf8String(env, "productName", usbDevice.GetProductName(), obj);
163     NapiUtil::SetValueUtf8String(env, "version", usbDevice.GetVersion(), obj);
164     NapiUtil::SetValueInt32(env, "vendorId", usbDevice.GetVendorId(), obj);
165     NapiUtil::SetValueInt32(env, "productId", usbDevice.GetProductId(), obj);
166     NapiUtil::SetValueInt32(env, "clazz", usbDevice.GetClass(), obj);
167     NapiUtil::SetValueInt32(env, "subClass", usbDevice.GetSubclass(), obj);
168     NapiUtil::SetValueInt32(env, "protocol", usbDevice.GetProtocol(), obj);
169     NapiUtil::SetValueInt32(env, "devAddress", usbDevice.GetDevAddr(), obj);
170     NapiUtil::SetValueInt32(env, "busNum", usbDevice.GetBusNum(), obj);
171     napi_value arr;
172     napi_create_array(env, &arr);
173     for (int32_t i = 0; i < usbDevice.GetConfigCount(); ++i) {
174         USBConfig usbConfig;
175         usbDevice.GetConfig(i, usbConfig);
176         napi_value objTmp;
177         CtoJSUsbConfig(env, objTmp, usbConfig);
178         napi_set_element(env, arr, i, objTmp);
179     }
180     napi_set_named_property(env, obj, "configs", arr);
181 }
182 
CtoJSUSBAccessory(const napi_env & env,napi_value & obj,const USBAccessory & accessory)183 static void CtoJSUSBAccessory(const napi_env &env, napi_value &obj, const USBAccessory &accessory)
184 {
185     napi_create_object(env, &obj);
186     NapiUtil::SetValueUtf8String(env, "manufacturer", accessory.GetManufacturer(), obj);
187     NapiUtil::SetValueUtf8String(env, "product", accessory.GetProduct(), obj);
188     NapiUtil::SetValueUtf8String(env, "description", accessory.GetDescription(), obj);
189     NapiUtil::SetValueUtf8String(env, "version", accessory.GetVersion(), obj);
190     NapiUtil::SetValueUtf8String(env, "serialNumber", accessory.GetSerialNumber(), obj);
191 }
192 
193 static UsbSrvClient &g_usbClient = UsbSrvClient::GetInstance();
194 
195 /* ============================================= Parsers ============================================= */
196 // js to c
ParseEndpointObj(const napi_env env,const napi_value endpointObj,USBEndpoint & ep)197 static void ParseEndpointObj(const napi_env env, const napi_value endpointObj, USBEndpoint &ep)
198 {
199     int32_t address = 0;
200     NapiUtil::JsObjectToInt(env, endpointObj, "address", address);
201     int32_t attributes = 0;
202     NapiUtil::JsObjectToInt(env, endpointObj, "attributes", attributes);
203     int32_t interval = 0;
204     NapiUtil::JsObjectToInt(env, endpointObj, "interval", interval);
205     int32_t maxPacketSize = 0;
206     NapiUtil::JsObjectToInt(env, endpointObj, "maxPacketSize", maxPacketSize);
207     int32_t direction = 0;
208     NapiUtil::JsObjectToInt(env, endpointObj, "direction", direction);
209     USB_ASSERT_RETURN_VOID(env, (direction == USB_ENDPOINT_DIR_IN || direction == USB_ENDPOINT_DIR_OUT),
210         OHEC_COMMON_PARAM_ERROR, "The interface should have the endpoints property.");
211     int32_t number = 0;
212     NapiUtil::JsObjectToInt(env, endpointObj, "number", number);
213     int32_t type = 0;
214     NapiUtil::JsObjectToInt(env, endpointObj, "type", type);
215     int32_t interfaceId = 0;
216     NapiUtil::JsObjectToInt(env, endpointObj, "interfaceId", interfaceId);
217     ep = USBEndpoint(address, attributes, interval, maxPacketSize);
218     ep.SetInterfaceId(interfaceId);
219 }
220 
ParseEndpointsObjs(const napi_env env,const napi_value interfaceObj,std::vector<USBEndpoint> & eps)221 static bool ParseEndpointsObjs(const napi_env env, const napi_value interfaceObj, std::vector<USBEndpoint> &eps)
222 {
223     napi_value endpointsObjs;
224     bool isGetObjSuccess = NapiUtil::JsObjectGetProperty(env, interfaceObj, "endpoints", endpointsObjs);
225     USB_ASSERT_RETURN_FALSE(
226         env, isGetObjSuccess == true, OHEC_COMMON_PARAM_ERROR, "The interface should have the endpoints property.");
227 
228     bool result = false;
229     NAPI_CHECK_RETURN_FALSE(napi_is_array(env, endpointsObjs, &result), "Get endpoints type failed");
230     USB_ASSERT_RETURN_FALSE(env, result == true, OHEC_COMMON_PARAM_ERROR, "The type of endpoints must be array.");
231 
232     uint32_t endpointCount = 0;
233     NAPI_CHECK_RETURN_FALSE(napi_get_array_length(env, endpointsObjs, &endpointCount), "Get array length failed");
234 
235     for (uint32_t k = 0; k < endpointCount; ++k) {
236         napi_value endpointObj;
237         NAPI_CHECK_RETURN_FALSE(napi_get_element(env, endpointsObjs, k, &endpointObj), "Get endpoints element failed");
238         USBEndpoint ep;
239         ParseEndpointObj(env, endpointObj, ep);
240         eps.push_back(ep);
241     }
242 
243     return true;
244 }
245 
246 struct PipeControlParam {
247     int32_t request;
248     int32_t target;
249     uint32_t reqType;
250     int32_t value;
251     int32_t index;
252     uint8_t *data;
253     size_t dataLength;
254 };
255 
ParsePipeControlParam(const napi_env env,const napi_value jsObj,PipeControlParam & controlParam)256 static bool ParsePipeControlParam(const napi_env env, const napi_value jsObj, PipeControlParam &controlParam)
257 {
258     int32_t request = 0;
259     NapiUtil::JsObjectToInt(env, jsObj, "request", request);
260     int32_t target = 0;
261     NapiUtil::JsObjectToInt(env, jsObj, "target", target);
262     uint32_t reqType = 0;
263     NapiUtil::JsObjectToUint(env, jsObj, "reqType", reqType);
264     int32_t value = 0;
265     NapiUtil::JsObjectToInt(env, jsObj, "value", value);
266     int32_t index = 0;
267     NapiUtil::JsObjectToInt(env, jsObj, "index", index);
268 
269     napi_value dataValue;
270     bool hasProperty = NapiUtil::JsObjectGetProperty(env, jsObj, "data", dataValue);
271     USB_ASSERT_RETURN_FALSE(
272         env, hasProperty == true, OHEC_COMMON_PARAM_ERROR, "The controlParam should have the data property.");
273 
274     uint8_t *data = nullptr;
275     size_t dataLength = 0;
276     size_t offset = 0;
277     NapiUtil::JsUint8ArrayParse(env, dataValue, &data, dataLength, offset);
278     controlParam.request = request;
279     controlParam.target = target;
280     controlParam.reqType = reqType;
281     controlParam.value = value;
282     controlParam.index = index;
283     controlParam.data = data;
284     controlParam.dataLength = dataLength;
285     return true;
286 }
287 
288 struct UsbPipeControlParam {
289     uint32_t reqType;
290     int32_t request;
291     int32_t value;
292     int32_t index;
293     int32_t length;
294     uint8_t *data;
295     size_t dataLength;
296 };
297 
ParseUsbPipeControlParam(const napi_env env,const napi_value jsObj,UsbPipeControlParam & controlParam)298 static void ParseUsbPipeControlParam(const napi_env env, const napi_value jsObj, UsbPipeControlParam &controlParam)
299 {
300     uint32_t reqType = 0;
301     NapiUtil::JsObjectToUint(env, jsObj, "bmRequestType", reqType);
302     int32_t request = 0;
303     NapiUtil::JsObjectToInt(env, jsObj, "bRequest", request);
304     int32_t value = 0;
305     NapiUtil::JsObjectToInt(env, jsObj, "wValue", value);
306     int32_t index = 0;
307     NapiUtil::JsObjectToInt(env, jsObj, "wIndex", index);
308     int32_t length = 0;
309     NapiUtil::JsObjectToInt(env, jsObj, "wLength", length);
310 
311     napi_value dataValue;
312     bool hasProperty = NapiUtil::JsObjectGetProperty(env, jsObj, "data", dataValue);
313     USB_ASSERT_RETURN_VOID(
314         env, hasProperty == true, OHEC_COMMON_PARAM_ERROR, "The controlParam should have the data property.");
315 
316     uint8_t *data = nullptr;
317     size_t dataLength = 0;
318     size_t offset = 0;
319     NapiUtil::JsUint8ArrayParse(env, dataValue, &data, dataLength, offset);
320     controlParam.reqType = reqType;
321     controlParam.request = request;
322     controlParam.value = value;
323     controlParam.index = index;
324     controlParam.length = length;
325     controlParam.data = data;
326     controlParam.dataLength = dataLength;
327 }
328 
ParseInterfaceObj(const napi_env env,const napi_value interfaceObj,UsbInterface & interface)329 static void ParseInterfaceObj(const napi_env env, const napi_value interfaceObj, UsbInterface &interface)
330 {
331     int32_t id = 0;
332     NapiUtil::JsObjectToInt(env, interfaceObj, "id", id);
333     int32_t protocol = 0;
334     NapiUtil::JsObjectToInt(env, interfaceObj, "protocol", protocol);
335     int32_t clzz = 0;
336     NapiUtil::JsObjectToInt(env, interfaceObj, "clazz", clzz);
337     int32_t subClass = 0;
338     NapiUtil::JsObjectToInt(env, interfaceObj, "subClass", subClass);
339     int32_t alternateSetting = 0;
340     NapiUtil::JsObjectToInt(env, interfaceObj, "alternateSetting", alternateSetting);
341     std::string name;
342     NapiUtil::JsObjectToString(env, interfaceObj, "name", DEFAULT_DESCRIPTION_SIZE, name);
343     std::vector<USBEndpoint> eps;
344 
345     bool ret = ParseEndpointsObjs(env, interfaceObj, eps);
346     if (!ret) {
347         USB_HILOGE(MODULE_JS_NAPI, "Parse endpointers error.");
348         return;
349     }
350 
351     interface = UsbInterface(id, protocol, clzz, subClass, alternateSetting, name, eps);
352 }
353 
ParseInterfacesObjs(const napi_env env,const napi_value configObj,std::vector<UsbInterface> & interfaces)354 static bool ParseInterfacesObjs(const napi_env env, const napi_value configObj, std::vector<UsbInterface> &interfaces)
355 {
356     napi_value interfacesObjs;
357     bool isGetObjSuccess = NapiUtil::JsObjectGetProperty(env, configObj, "interfaces", interfacesObjs);
358     USB_ASSERT_RETURN_FALSE(
359         env, isGetObjSuccess == true, OHEC_COMMON_PARAM_ERROR, "The config should have the interfaces property.");
360 
361     bool result = false;
362     NAPI_CHECK_RETURN_FALSE(napi_is_array(env, interfacesObjs, &result), "Get interfaces type failed");
363     USB_ASSERT_RETURN_FALSE(env, result == true, OHEC_COMMON_PARAM_ERROR, "The type of interfaces must be array.");
364 
365     uint32_t interfaceCount = 0;
366     NAPI_CHECK_RETURN_FALSE(napi_get_array_length(env, interfacesObjs, &interfaceCount), "Get array length failed");
367 
368     for (uint32_t i = 0; i < interfaceCount; ++i) {
369         napi_value interfaceObj;
370         NAPI_CHECK_RETURN_FALSE(
371             napi_get_element(env, interfacesObjs, i, &interfaceObj), "Get interfaces element failed");
372 
373         UsbInterface interface;
374         ParseInterfaceObj(env, interfaceObj, interface);
375         interfaces.push_back(interface);
376     }
377 
378     return true;
379 }
380 
ParseConfigObj(const napi_env env,const napi_value configObj,USBConfig & config)381 static void ParseConfigObj(const napi_env env, const napi_value configObj, USBConfig &config)
382 {
383     int32_t id = 0;
384     NapiUtil::JsObjectToInt(env, configObj, "id", id);
385     int32_t attributes = 0;
386     NapiUtil::JsObjectToInt(env, configObj, "attributes", attributes);
387     int32_t maxPower = 0;
388     NapiUtil::JsObjectToInt(env, configObj, "maxPower", maxPower);
389     std::string name;
390     NapiUtil::JsObjectToString(env, configObj, "name", DEFAULT_DESCRIPTION_SIZE, name);
391     bool isRemoteWakeup = false;
392     NapiUtil::JsObjectToBool(env, configObj, "isRemoteWakeup", isRemoteWakeup);
393     bool isSelfPowered = false;
394     NapiUtil::JsObjectToBool(env, configObj, "isSelfPowered", isSelfPowered);
395 
396     std::vector<UsbInterface> interfaces;
397     bool ret = ParseInterfacesObjs(env, configObj, interfaces);
398     if (!ret) {
399         USB_HILOGE(MODULE_JS_NAPI, "Parse interfaces error.");
400         return;
401     }
402 
403     config = USBConfig(id, attributes, name, maxPower, interfaces);
404 }
405 
ParseConfigsObjs(const napi_env env,const napi_value deviceObj,std::vector<USBConfig> & configs)406 static void ParseConfigsObjs(const napi_env env, const napi_value deviceObj, std::vector<USBConfig> &configs)
407 {
408     napi_value configsObj;
409     bool hasProperty = NapiUtil::JsObjectGetProperty(env, deviceObj, "configs", configsObj);
410     USB_ASSERT_RETURN_VOID(
411         env, hasProperty == true, OHEC_COMMON_PARAM_ERROR, "The device should have the configs property.");
412     napi_valuetype valueType;
413     napi_typeof(env, configsObj, &valueType);
414     USB_ASSERT_RETURN_VOID(
415         env, valueType == napi_object, OHEC_COMMON_PARAM_ERROR, "The type of configs must be object.");
416 
417     uint32_t configCount = 0;
418     napi_get_array_length(env, configsObj, &configCount);
419     for (uint32_t i = 0; i < configCount; ++i) {
420         napi_value configObj;
421         napi_get_element(env, configsObj, i, &configObj);
422         USBConfig config;
423         ParseConfigObj(env, configObj, config);
424         configs.push_back(config);
425     }
426 }
427 
ParseDeviceObj(const napi_env env,const napi_value deviceObj,UsbDevice & dev)428 static void ParseDeviceObj(const napi_env env, const napi_value deviceObj, UsbDevice &dev)
429 {
430     std::string name;
431     NapiUtil::JsObjectToString(env, deviceObj, "name", DEFAULT_DESCRIPTION_SIZE, name);
432     std::string manufacturerName;
433     NapiUtil::JsObjectToString(env, deviceObj, "manufacturerName", DEFAULT_DESCRIPTION_SIZE, manufacturerName);
434     std::string productName;
435     NapiUtil::JsObjectToString(env, deviceObj, "productName", DEFAULT_DESCRIPTION_SIZE, productName);
436     std::string version;
437     NapiUtil::JsObjectToString(env, deviceObj, "version", DEFAULT_DESCRIPTION_SIZE, version);
438     std::string serial;
439     NapiUtil::JsObjectToString(env, deviceObj, "serial", DEFAULT_DESCRIPTION_SIZE, serial);
440     int32_t devAddr = 0;
441     NapiUtil::JsObjectToInt(env, deviceObj, "devAddress", devAddr);
442     int32_t busNum = 0;
443     NapiUtil::JsObjectToInt(env, deviceObj, "busNum", busNum);
444     int32_t vendorId = 0;
445     NapiUtil::JsObjectToInt(env, deviceObj, "vendorId", vendorId);
446     int32_t productId = 0;
447     NapiUtil::JsObjectToInt(env, deviceObj, "productId", productId);
448     int32_t clazz = 0;
449     NapiUtil::JsObjectToInt(env, deviceObj, "clazz", clazz);
450     int32_t subClass = 0;
451     NapiUtil::JsObjectToInt(env, deviceObj, "subClass", subClass);
452     int32_t protocol = 0;
453     NapiUtil::JsObjectToInt(env, deviceObj, "protocol", protocol);
454     std::vector<USBConfig> configs;
455     ParseConfigsObjs(env, deviceObj, configs);
456     dev = UsbDevice(name, manufacturerName, productName, version, devAddr, busNum, vendorId, productId, clazz, subClass,
457         protocol, configs);
458 }
459 
ParseAccessoryObj(const napi_env env,const napi_value accessoryObj,USBAccessory & accessory)460 static void ParseAccessoryObj(const napi_env env, const napi_value accessoryObj, USBAccessory &accessory)
461 {
462     std::string manufacturer;
463     NapiUtil::JsObjectToString(env, accessoryObj, "manufacturer", DEFAULT_ACCESSORY_DESCRIPTION_SIZE, manufacturer);
464     std::string product;
465     NapiUtil::JsObjectToString(env, accessoryObj, "product", DEFAULT_ACCESSORY_DESCRIPTION_SIZE, product);
466     std::string description;
467     NapiUtil::JsObjectToString(env, accessoryObj, "description", DEFAULT_ACCESSORY_DESCRIPTION_SIZE, description);
468     std::string version;
469     NapiUtil::JsObjectToString(env, accessoryObj, "version", DEFAULT_ACCESSORY_DESCRIPTION_SIZE, version);
470     std::string serialNumber;
471     NapiUtil::JsObjectToString(env, accessoryObj, "serialNumber", DEFAULT_ACCESSORY_DESCRIPTION_SIZE, serialNumber);
472     accessory = USBAccessory(manufacturer, product, description, version, serialNumber);
473 }
474 
475 /* ============================================= Usb Core ============================================= */
476 
CoreGetDevices(napi_env env,napi_callback_info info)477 static napi_value CoreGetDevices(napi_env env, napi_callback_info info)
478 {
479     size_t argc = PARAM_COUNT_1;
480     napi_value argv[PARAM_COUNT_1] = {nullptr};
481     napi_get_cb_info(env, info, &argc, argv, nullptr, nullptr);
482     USB_ASSERT(env, (argc == PARAM_COUNT_0), OHEC_COMMON_PARAM_ERROR, "The function takes no arguments.");
483 
484     std::vector<UsbDevice> deviceList;
485     int32_t ret = g_usbClient.GetDevices(deviceList);
486     napi_value result;
487     if (ret != UEC_OK) {
488         napi_get_undefined(env, &result);
489         USB_HILOGE(MODULE_JS_NAPI, "end call get device failed ret : %{public}d", ret);
490         return result;
491     }
492 
493     napi_create_array(env, &result);
494     int32_t i = 0;
495     for (const auto &ent1 : deviceList) {
496         napi_value element;
497         napi_create_object(env, &element);
498         napi_value device;
499         CtoJSUsbDevice(env, device, ent1);
500         napi_set_element(env, result, i, device);
501         ++i;
502     }
503 
504     return result;
505 }
506 
DeviceGetAccessoryList(napi_env env,napi_callback_info info)507 static napi_value DeviceGetAccessoryList(napi_env env, napi_callback_info info)
508 {
509     size_t argc = PARAM_COUNT_1;
510     napi_value argv[PARAM_COUNT_1] = {nullptr};
511     napi_get_cb_info(env, info, &argc, argv, nullptr, nullptr);
512     USB_ASSERT(env, (argc == PARAM_COUNT_0), OHEC_COMMON_PARAM_ERROR, "The function takes no arguments.");
513 
514     std::vector<USBAccessory> accessoryList;
515     int32_t ret = g_usbClient.GetAccessoryList(accessoryList);
516     if (ret == UEC_OK) {
517         napi_value result;
518         napi_create_array(env, &result);
519         int32_t i = 0;
520         for (const auto &ent1 : accessoryList) {
521             napi_value element;
522             napi_create_object(env, &element);
523             napi_value device;
524             CtoJSUSBAccessory(env, device, ent1);
525             napi_set_element(env, result, i, device);
526             ++i;
527         }
528         return result;
529     } else {
530         ThrowBusinessError(env, UEC_COMMON_SERVICE_EXCEPTION,
531             "Service exception");
532     }
533     return nullptr;
534 }
535 
CoreConnectDevice(napi_env env,napi_callback_info info)536 static napi_value CoreConnectDevice(napi_env env, napi_callback_info info)
537 {
538     size_t argc = PARAM_COUNT_1;
539     napi_value argv[PARAM_COUNT_1] = {nullptr};
540     NAPI_CHECK(env, napi_get_cb_info(env, info, &argc, argv, nullptr, nullptr), "Get call back info failed");
541     USB_ASSERT(env, (argc >= PARAM_COUNT_1), OHEC_COMMON_PARAM_ERROR, "The function at least takes one argument.");
542 
543     napi_value deviceObj = argv[INDEX_0];
544     napi_valuetype type;
545     NAPI_CHECK(env, napi_typeof(env, deviceObj, &type), "Get deviceObj type failed");
546     USB_ASSERT(env, type == napi_object, OHEC_COMMON_PARAM_ERROR, "The type of device must be USBDevice.");
547     UsbDevice dev;
548     ParseDeviceObj(env, deviceObj, dev);
549 
550     USBDevicePipe pipe;
551     int32_t ret = g_usbClient.OpenDevice(dev, pipe);
552     napi_value pipObj = nullptr;
553     if (ret == UEC_OK) {
554         CreateUsbDevicePipe(env, pipObj, pipe);
555     } else if (ret == UEC_SERVICE_PERMISSION_DENIED || ret == UEC_INTERFACE_PERMISSION_DENIED) {
556         ThrowBusinessError(env, UEC_COMMON_HAS_NO_RIGHT, "Call requestRight to get the permission first");
557     } else {
558         napi_get_undefined(env, &pipObj);
559     }
560 
561     return pipObj;
562 }
563 
DeviceOpenAccessory(napi_env env,napi_callback_info info)564 static napi_value DeviceOpenAccessory(napi_env env, napi_callback_info info)
565 {
566     size_t argc = PARAM_COUNT_1;
567     napi_value argv[PARAM_COUNT_1] = {nullptr};
568     NAPI_CHECK(env, napi_get_cb_info(env, info, &argc, argv, nullptr, nullptr), "Get call back info failed");
569     USB_ASSERT(env, (argc >= PARAM_COUNT_1), OHEC_COMMON_PARAM_ERROR, "The function at least takes one argument.");
570 
571     napi_value accessoryObj = argv[INDEX_0];
572     napi_valuetype type;
573     NAPI_CHECK(env, napi_typeof(env, accessoryObj, &type), "Get accessoryObj type failed");
574     USB_ASSERT(env, type == napi_object, OHEC_COMMON_PARAM_ERROR, "The type of device must be USBAccessory.");
575     USBAccessory accessory;
576     ParseAccessoryObj(env, accessoryObj, accessory);
577 
578     int32_t fd = -1;
579     int32_t ret = g_usbClient.OpenAccessory(accessory, fd);
580 
581     napi_value handleObj = nullptr;
582     if (ret == UEC_OK) {
583         g_accFd = fd;
584         CreatAccessoryHandle(env, handleObj, fd);
585     } else if (ret == UEC_SERVICE_PERMISSION_DENIED || ret == UEC_INTERFACE_PERMISSION_DENIED) {
586         ThrowBusinessError(env, UEC_COMMON_HAS_NO_RIGHT,
587             "Call requestAccessoryRight to get the permission first");
588     } else if (ret == UEC_SERVICE_ACCESSORY_NOT_MATCH) {
589         ThrowBusinessError(env, UEC_ACCESSORY_NOT_MATCH,
590             "Get accessory through getAccessoryList");
591     } else if (ret == UEC_SERVICE_ACCESSORY_OPEN_NATIVE_NODE_FAILED) {
592         ThrowBusinessError(env, UEC_ACCESSORY_OPEN_FAILED,
593             "Failed to open the native accessory node");
594     } else if (ret == UEC_SERVICE_ACCESSORY_REOPEN) {
595         ThrowBusinessError(env, UEC_ACCESSORY_CAN_NOT_REOPEN,
596             "Cannot reopen accessory");
597     } else {
598         ThrowBusinessError(env, UEC_COMMON_SERVICE_EXCEPTION,
599             "Service exception");
600     }
601     return handleObj;
602 }
603 
DeviceCloseAccessory(napi_env env,napi_callback_info info)604 static napi_value DeviceCloseAccessory(napi_env env, napi_callback_info info)
605 {
606     size_t argc = PARAM_COUNT_1;
607     napi_value argv[PARAM_COUNT_1] = {nullptr};
608     NAPI_CHECK(env, napi_get_cb_info(env, info, &argc, argv, nullptr, nullptr), "Get call back info failed");
609     USB_ASSERT(env, (argc >= PARAM_COUNT_1), OHEC_COMMON_PARAM_ERROR, "The function at least takes one argument.");
610 
611     napi_value accessoryFdObj = argv[INDEX_0];
612     napi_valuetype type;
613     NAPI_CHECK(env, napi_typeof(env, accessoryFdObj, &type), "Get accessoryObj type failed");
614     USB_ASSERT(env, type == napi_object, OHEC_COMMON_PARAM_ERROR, "The type of device must be USBAccessoryHandle.");
615     int32_t accessoryFd;
616     NapiUtil::JsObjectToInt(env, argv[INDEX_0], "accessoryFd", accessoryFd);
617     if (accessoryFd == 0 || accessoryFd != g_accFd || g_accFd == 0) {
618         ThrowBusinessError(env, OHEC_COMMON_PARAM_ERROR,
619             "Parameter accessoryHandle error, need openAccessory first.");
620     }
621     close(accessoryFd);
622     accessoryFd = 0;
623     int32_t ret = g_usbClient.CloseAccessory(g_accFd);
624     g_accFd = 0;
625     if (ret != UEC_OK) {
626         ThrowBusinessError(env, UEC_COMMON_SERVICE_EXCEPTION,
627             "Service exception");
628     }
629     return nullptr;
630 }
631 
DeviceAddRight(napi_env env,napi_callback_info info)632 static napi_value DeviceAddRight(napi_env env, napi_callback_info info)
633 {
634     size_t argc = PARAM_COUNT_2;
635     napi_value argv[PARAM_COUNT_2] = {nullptr};
636     NAPI_CHECK(env, napi_get_cb_info(env, info, &argc, argv, nullptr, nullptr), "Get call back info failed");
637     USB_ASSERT(env, (argc >= PARAM_COUNT_2), OHEC_COMMON_PARAM_ERROR, "The function at least takes two argument.");
638 
639     napi_valuetype type;
640     NAPI_CHECK(env, napi_typeof(env, argv[INDEX_0], &type), "Get args 1 type failed");
641     USB_ASSERT(env, type == napi_string, OHEC_COMMON_PARAM_ERROR, "The type of bundleName must be string.");
642     std::string bundleName;
643     NapiUtil::JsValueToString(env, argv[INDEX_0], STR_DEFAULT_SIZE, bundleName);
644 
645     NAPI_CHECK(env, napi_typeof(env, argv[INDEX_1], &type), "Get args 2 type failed");
646     USB_ASSERT(env, type == napi_string, OHEC_COMMON_PARAM_ERROR, "The type of deviceName must be string.");
647     std::string deviceName;
648     NapiUtil::JsValueToString(env, argv[INDEX_1], STR_DEFAULT_SIZE, deviceName);
649 
650     napi_value result;
651     int32_t ret = g_usbClient.AddRight(bundleName, deviceName);
652     USB_HILOGD(MODULE_JS_NAPI, "Device call AddRight ret: %{public}d", ret);
653     if (ret == UEC_OK) {
654         napi_get_boolean(env, true, &result);
655     } else {
656         USB_ASSERT_RETURN_UNDEF(env, (ret != UEC_SERVICE_PERMISSION_DENIED_SYSAPI),
657             OHEC_COMMON_NORMAL_APP_NOT_ALLOWED, "");
658         napi_get_boolean(env, false, &result);
659     }
660     return result;
661 }
662 
DeviceAddAccessoryRight(napi_env env,napi_callback_info info)663 static napi_value DeviceAddAccessoryRight(napi_env env, napi_callback_info info)
664 {
665     size_t argc = PARAM_COUNT_2;
666     napi_value argv[PARAM_COUNT_2] = {nullptr};
667     NAPI_CHECK(env, napi_get_cb_info(env, info, &argc, argv, nullptr, nullptr), "Get call back info failed");
668     USB_ASSERT(env, (argc >= PARAM_COUNT_2), OHEC_COMMON_PARAM_ERROR, "The function at least takes two argument.");
669 
670     napi_valuetype type;
671     NAPI_CHECK(env, napi_typeof(env, argv[INDEX_0], &type), "Get args 1 type failed");
672     USB_ASSERT(env, type == napi_number, OHEC_COMMON_PARAM_ERROR, "The type of tokenId must be number.");
673     uint32_t tokenId;
674     napi_get_value_uint32(env, argv[INDEX_0], &tokenId);
675 
676     napi_value accessoryObj = argv[INDEX_1];
677     napi_valuetype type1;
678     NAPI_CHECK(env, napi_typeof(env, accessoryObj, &type1), "Get accessoryObj type failed");
679     USB_ASSERT(env, type1 == napi_object, OHEC_COMMON_PARAM_ERROR, "The type of device must be USBAccessory.");
680     USBAccessory accessory;
681     ParseAccessoryObj(env, accessoryObj, accessory);
682 
683     int32_t ret = g_usbClient.AddAccessoryRight(tokenId, accessory);
684     if (ret == UEC_OK) {
685         return nullptr;
686     } else if (ret == UEC_SERVICE_GET_TOKEN_INFO_FAILED) {
687         ThrowBusinessError(env, OHEC_COMMON_PARAM_ERROR, "");
688     } else if (ret == UEC_SERVICE_ACCESSORY_NOT_MATCH) {
689         ThrowBusinessError(env, OHEC_COMMON_PARAM_ERROR,
690             "Get accessory through getAccessoryList");
691     } else if (ret == UEC_SERVICE_DATABASE_OPERATION_FAILED) {
692         ThrowBusinessError(env, UEC_COMMON_RIGHT_DATABASE_ERROR,
693             "Database request operation exception");
694     } else {
695         ThrowBusinessError(env, UEC_COMMON_SERVICE_EXCEPTION,
696             "Service exception");
697     }
698     USB_HILOGD(MODULE_JS_NAPI, "Device call AddAccessoryRight ret: %{public}d", ret);
699     return nullptr;
700 }
701 
DeviceAddAccessRight(napi_env env,napi_callback_info info)702 static napi_value DeviceAddAccessRight(napi_env env, napi_callback_info info)
703 {
704     size_t argc = PARAM_COUNT_2;
705     napi_value argv[PARAM_COUNT_2] = {nullptr};
706     NAPI_CHECK(env, napi_get_cb_info(env, info, &argc, argv, nullptr, nullptr), "Get call back info failed");
707     USB_ASSERT(env, (argc >= PARAM_COUNT_2), OHEC_COMMON_PARAM_ERROR, "The function at least takes two argument.");
708 
709     napi_valuetype type;
710     NAPI_CHECK(env, napi_typeof(env, argv[INDEX_0], &type), "Get args 1 type failed");
711     USB_ASSERT(env, type == napi_string, OHEC_COMMON_PARAM_ERROR, "The type of tokenId must be string.");
712     std::string tokenId;
713     NapiUtil::JsValueToString(env, argv[INDEX_0], STR_DEFAULT_SIZE, tokenId);
714 
715     NAPI_CHECK(env, napi_typeof(env, argv[INDEX_1], &type), "Get args 2 type failed");
716     USB_ASSERT(env, type == napi_string, OHEC_COMMON_PARAM_ERROR, "The type of deviceName must be string.");
717     std::string deviceName;
718     NapiUtil::JsValueToString(env, argv[INDEX_1], STR_DEFAULT_SIZE, deviceName);
719 
720     napi_value result;
721     int32_t ret = g_usbClient.AddAccessRight(tokenId, deviceName);
722     USB_HILOGD(MODULE_JS_NAPI, "Device call AddRight ret: %{public}d", ret);
723     if (ret == UEC_OK) {
724         napi_get_boolean(env, true, &result);
725     } else {
726         USB_ASSERT_RETURN_UNDEF(env, (ret != UEC_SERVICE_PERMISSION_DENIED_SYSAPI),
727             OHEC_COMMON_NORMAL_APP_NOT_ALLOWED, "");
728         napi_get_boolean(env, false, &result);
729     }
730     return result;
731 }
732 
DeviceRemoveRight(napi_env env,napi_callback_info info)733 static napi_value DeviceRemoveRight(napi_env env, napi_callback_info info)
734 {
735     size_t argc = PARAM_COUNT_1;
736     napi_value argv[PARAM_COUNT_1] = {nullptr};
737     NAPI_CHECK(env, napi_get_cb_info(env, info, &argc, argv, nullptr, nullptr), "Get call back info failed");
738     USB_ASSERT(env, (argc >= PARAM_COUNT_1), OHEC_COMMON_PARAM_ERROR, "The function at least takes two argument.");
739 
740     napi_valuetype type;
741     NAPI_CHECK(env, napi_typeof(env, argv[INDEX_0], &type), "Get args 1 type failed");
742     USB_ASSERT(env, type == napi_string, OHEC_COMMON_PARAM_ERROR, "The type of deviceName must be string.");
743     std::string deviceName;
744     NapiUtil::JsValueToString(env, argv[INDEX_0], STR_DEFAULT_SIZE, deviceName);
745 
746     napi_value result;
747     int32_t ret = g_usbClient.RemoveRight(deviceName);
748     USB_HILOGD(MODULE_JS_NAPI, "Device call RemoveRight ret: %{public}d", ret);
749     if (ret == UEC_OK) {
750         napi_get_boolean(env, true, &result);
751     } else {
752         napi_get_boolean(env, false, &result);
753     }
754 
755     return result;
756 }
757 
DeviceCancelAccessoryRight(napi_env env,napi_callback_info info)758 static napi_value DeviceCancelAccessoryRight(napi_env env, napi_callback_info info)
759 {
760     size_t argc = PARAM_COUNT_1;
761     napi_value argv[PARAM_COUNT_1] = {nullptr};
762     NAPI_CHECK(env, napi_get_cb_info(env, info, &argc, argv, nullptr, nullptr), "Get call back info failed");
763     USB_ASSERT(env, (argc >= PARAM_COUNT_1), OHEC_COMMON_PARAM_ERROR, "The function at least takes one argument.");
764 
765     napi_value accessoryObj = argv[INDEX_0];
766     napi_valuetype type;
767     NAPI_CHECK(env, napi_typeof(env, accessoryObj, &type), "Get accessoryObj type failed");
768     USB_ASSERT(env, type == napi_object, OHEC_COMMON_PARAM_ERROR, "The type of device must be USBAccessory.");
769     USBAccessory accessory;
770     ParseAccessoryObj(env, accessoryObj, accessory);
771 
772     if (g_accFd != 0) {
773         close(g_accFd);
774         g_accFd = 0;
775         g_usbClient.CloseAccessory(g_accFd);
776     }
777 
778     int32_t ret = g_usbClient.CancelAccessoryRight(accessory);
779     if (ret == UEC_OK) {
780         return nullptr;
781     } else if (ret == UEC_SERVICE_ACCESSORY_NOT_MATCH) {
782         ThrowBusinessError(env, UEC_ACCESSORY_NOT_MATCH,
783             "Get accessory through getAccessoryList");
784     } else if (ret == UEC_SERVICE_DATABASE_OPERATION_FAILED) {
785         ThrowBusinessError(env, UEC_COMMON_RIGHT_DATABASE_ERROR,
786             "Database request operation exception");
787     } else {
788         ThrowBusinessError(env, UEC_COMMON_SERVICE_EXCEPTION,
789             "Service exception");
790     }
791     USB_HILOGD(MODULE_JS_NAPI, "Device call RemoveRight ret: %{public}d", ret);
792     return nullptr;
793 }
794 
CoreHasRight(napi_env env,napi_callback_info info)795 static napi_value CoreHasRight(napi_env env, napi_callback_info info)
796 {
797     size_t argc = PARAM_COUNT_1;
798     napi_value args[PARAM_COUNT_1] = {nullptr};
799     NAPI_CHECK(env, napi_get_cb_info(env, info, &argc, args, nullptr, nullptr), "Get call back info failed");
800     USB_ASSERT(env, (argc >= PARAM_COUNT_1), OHEC_COMMON_PARAM_ERROR, "The function at least takes one argument.");
801 
802     napi_valuetype type;
803     NAPI_CHECK(env, napi_typeof(env, args[INDEX_0], &type), "Get args 1 type failed");
804     USB_ASSERT(env, type == napi_string, OHEC_COMMON_PARAM_ERROR, "The type of deviceName must be string");
805     std::string deviceName;
806     NapiUtil::JsValueToString(env, args[INDEX_0], STR_DEFAULT_SIZE, deviceName);
807 
808     bool result = g_usbClient.HasRight(deviceName);
809     USB_HILOGD(MODULE_JS_NAPI, "client called result %{public}d", result);
810 
811     napi_value napiValue = nullptr;
812     napi_get_boolean(env, result, &napiValue);
813 
814     return napiValue;
815 }
816 
DeviceHasAccessoryRight(napi_env env,napi_callback_info info)817 static napi_value DeviceHasAccessoryRight(napi_env env, napi_callback_info info)
818 {
819     size_t argc = PARAM_COUNT_1;
820     napi_value args[PARAM_COUNT_1] = {nullptr};
821     NAPI_CHECK(env, napi_get_cb_info(env, info, &argc, args, nullptr, nullptr), "Get call back info failed");
822     USB_ASSERT(env, (argc >= PARAM_COUNT_1), OHEC_COMMON_PARAM_ERROR, "The function at least takes one argument.");
823 
824     napi_value accessoryObj = args[INDEX_0];
825     napi_valuetype type;
826     NAPI_CHECK(env, napi_typeof(env, accessoryObj, &type), "Get accessoryObj type failed");
827     USB_ASSERT(env, type == napi_object, OHEC_COMMON_PARAM_ERROR, "The type of device must be USBAccessory.");
828     USBAccessory accessory;
829     ParseAccessoryObj(env, accessoryObj, accessory);
830     bool result = false;
831     int32_t ret = g_usbClient.HasAccessoryRight(accessory, result);
832     if (ret == UEC_OK) {
833         napi_value napiValue = nullptr;
834         napi_get_boolean(env, result, &napiValue);
835         return napiValue;
836     } else if (ret == UEC_SERVICE_ACCESSORY_NOT_MATCH) {
837         ThrowBusinessError(env, UEC_ACCESSORY_NOT_MATCH,
838             "Get accessory through getAccessoryList");
839     } else if (ret == UEC_SERVICE_DATABASE_OPERATION_FAILED) {
840         ThrowBusinessError(env, UEC_COMMON_RIGHT_DATABASE_ERROR,
841             "Database request operation exception");
842     } else {
843         ThrowBusinessError(env, UEC_COMMON_SERVICE_EXCEPTION,
844             "Service exception");
845     }
846 
847     return nullptr;
848 }
849 
__anon2b6789b40102(napi_env env, void *data) 850 static auto g_requestRightExecute = [](napi_env env, void *data) {
851     USBRightAsyncContext *asyncContext = reinterpret_cast<USBRightAsyncContext *>(data);
852     int32_t ret = g_usbClient.RequestRight(asyncContext->deviceName);
853     if (ret == UEC_OK) {
854         asyncContext->status = napi_ok;
855     } else {
856         asyncContext->status = napi_generic_failure;
857     }
858 };
859 
__anon2b6789b40202(napi_env env, napi_status status, void *data) 860 static auto g_requestRightComplete = [](napi_env env, napi_status status, void *data) {
861     USBRightAsyncContext *asyncContext = reinterpret_cast<USBRightAsyncContext *>(data);
862     napi_value queryResult = nullptr;
863     napi_get_boolean(env, asyncContext->status == napi_ok, &queryResult);
864 
865     if (asyncContext->deferred) {
866         napi_resolve_deferred(env, asyncContext->deferred, queryResult);
867     }
868     napi_delete_async_work(env, asyncContext->work);
869     delete asyncContext;
870 };
871 
CoreRequestRight(napi_env env,napi_callback_info info)872 static napi_value CoreRequestRight(napi_env env, napi_callback_info info)
873 {
874     size_t argc = PARAM_COUNT_1;
875     napi_value args[PARAM_COUNT_1] = {nullptr};
876     NAPI_CHECK(env, napi_get_cb_info(env, info, &argc, args, nullptr, nullptr), "Get call back info failed");
877     USB_ASSERT(env, (argc >= PARAM_COUNT_1), OHEC_COMMON_PARAM_ERROR, "The function at least takes one argument.");
878 
879     napi_valuetype type;
880     NAPI_CHECK(env, napi_typeof(env, args[INDEX_0], &type), "Get args 1 type failed");
881     USB_ASSERT(env, type == napi_string, OHEC_COMMON_PARAM_ERROR, "The type of deviceName must be string.");
882     std::string deviceName;
883     NapiUtil::JsValueToString(env, args[INDEX_0], STR_DEFAULT_SIZE, deviceName);
884 
885     auto asyncContext = new (std::nothrow) USBRightAsyncContext();
886     if (asyncContext == nullptr) {
887         USB_HILOGE(MODULE_JS_NAPI, "Create USBRightAsyncContext failed.");
888         return nullptr;
889     }
890 
891     asyncContext->env = env;
892     asyncContext->deviceName = deviceName;
893 
894     napi_value result = nullptr;
895     napi_create_promise(env, &asyncContext->deferred, &result);
896 
897     napi_value resource = nullptr;
898     napi_create_string_utf8(env, "RequestRight", NAPI_AUTO_LENGTH, &resource);
899 
900     napi_create_async_work(env, nullptr, resource, g_requestRightExecute, g_requestRightComplete,
901         reinterpret_cast<void *>(asyncContext), &asyncContext->work);
902     napi_queue_async_work(env, asyncContext->work);
903 
904     return result;
905 }
906 
__anon2b6789b40302(napi_env env, void *data) 907 static auto g_requestAccessoryRightExecute = [](napi_env env, void *data) {
908     if (data == nullptr) {
909         USB_HILOGE(MODULE_JS_NAPI, "Failed to create async work, data is nullptr");
910         return;
911     }
912     USBAccessoryRightAsyncContext *asyncContext = reinterpret_cast<USBAccessoryRightAsyncContext *>(data);
913     bool result = false;
914     asyncContext->errCode = g_usbClient.RequestAccessoryRight(asyncContext->accessory, result);
915     asyncContext->hasRight = result;
916 };
917 
__anon2b6789b40402(napi_env env, napi_status status, void *data) 918 static auto g_requestAccessoryRightComplete = [](napi_env env, napi_status status, void *data) {
919     if (data == nullptr) {
920         USB_HILOGE(MODULE_JS_NAPI, "Failed to create async work, data is nullptr");
921         return;
922     }
923     USBAccessoryRightAsyncContext *asyncContext = reinterpret_cast<USBAccessoryRightAsyncContext *>(data);
924     napi_value queryResult = nullptr;
925 
926     if (asyncContext->errCode == UEC_OK) {
927         asyncContext->status = napi_ok;
928         napi_get_boolean(env, asyncContext->hasRight, &queryResult);
929     } else if (asyncContext->errCode == UEC_SERVICE_ACCESSORY_NOT_MATCH) {
930         asyncContext->status = napi_generic_failure;
931         queryResult = CreateBusinessError(env, UEC_ACCESSORY_NOT_MATCH, "");
932     } else if (asyncContext->errCode == UEC_SERVICE_DATABASE_OPERATION_FAILED) {
933         asyncContext->status = napi_generic_failure;
934         queryResult = CreateBusinessError(env, UEC_COMMON_RIGHT_DATABASE_ERROR, "");
935     } else {
936         asyncContext->status = napi_generic_failure;
937         queryResult = CreateBusinessError(env, UEC_COMMON_SERVICE_EXCEPTION, "");
938     }
939     ProcessPromise(env, *asyncContext, queryResult);
940     napi_delete_async_work(env, asyncContext->work);
941     delete asyncContext;
942     asyncContext = nullptr;
943 };
944 
DeviceRequestAccessoryRight(napi_env env,napi_callback_info info)945 static napi_value DeviceRequestAccessoryRight(napi_env env, napi_callback_info info)
946 {
947     size_t argc = PARAM_COUNT_1;
948     napi_value args[PARAM_COUNT_1] = {nullptr};
949     NAPI_CHECK(env, napi_get_cb_info(env, info, &argc, args, nullptr, nullptr), "Get call back info failed");
950     USB_ASSERT(env, (argc >= PARAM_COUNT_1), OHEC_COMMON_PARAM_ERROR, "The function at least takes one argument.");
951 
952     napi_value accessoryObj = args[INDEX_0];
953     napi_valuetype type;
954     NAPI_CHECK(env, napi_typeof(env, accessoryObj, &type), "Get accessoryObj type failed");
955     USB_ASSERT(env, type == napi_object, OHEC_COMMON_PARAM_ERROR, "The type of device must be USBAccessory.");
956     USBAccessory accessory;
957     ParseAccessoryObj(env, accessoryObj, accessory);
958 
959     auto asyncContext = new (std::nothrow) USBAccessoryRightAsyncContext();
960     if (asyncContext == nullptr) {
961         USB_HILOGE(MODULE_JS_NAPI, "Create USBAccessoryRightAsyncContext failed.");
962         return nullptr;
963     }
964 
965     asyncContext->env = env;
966     asyncContext->accessory = accessory;
967 
968     napi_value result = nullptr;
969     napi_create_promise(env, &asyncContext->deferred, &result);
970 
971     napi_value resource = nullptr;
972     napi_create_string_utf8(env, "RequestRight", NAPI_AUTO_LENGTH, &resource);
973 
974     napi_create_async_work(env, nullptr, resource, g_requestAccessoryRightExecute, g_requestAccessoryRightComplete,
975         reinterpret_cast<void *>(asyncContext), &asyncContext->work);
976     napi_queue_async_work(env, asyncContext->work);
977 
978     return result;
979 }
980 
CoreUsbFunctionsFromString(napi_env env,napi_callback_info info)981 static napi_value CoreUsbFunctionsFromString(napi_env env, napi_callback_info info)
982 {
983     size_t argc = PARAM_COUNT_1;
984     napi_value argv[PARAM_COUNT_1] = {nullptr};
985 
986     NAPI_CHECK(env, napi_get_cb_info(env, info, &argc, argv, nullptr, nullptr), "Get call back info failed");
987     USB_ASSERT(env, (argc >= PARAM_COUNT_1), OHEC_COMMON_PARAM_ERROR, "The function at least takes one argument.");
988 
989     napi_valuetype type;
990     NAPI_CHECK(env, napi_typeof(env, argv[INDEX_0], &type), "Get args 1 type failed");
991     USB_ASSERT(env, type == napi_string, OHEC_COMMON_PARAM_ERROR, "The type of funcs must be string.");
992 
993     // get value string argument of napi converted.
994     std::string funcs;
995     NapiUtil::JsValueToString(env, argv[INDEX_0], STR_DEFAULT_SIZE, funcs);
996 
997     int32_t numFuncs = g_usbClient.UsbFunctionsFromString(funcs);
998     USB_HILOGI(MODULE_JS_NAPI, "usb functions from string failed ret = %{public}d", numFuncs);
999     USB_ASSERT_RETURN_UNDEF(env, (numFuncs != UEC_SERVICE_PERMISSION_DENIED_SYSAPI),
1000         OHEC_COMMON_NORMAL_APP_NOT_ALLOWED, "");
1001 
1002     napi_value result;
1003     napi_create_int32(env, numFuncs, &result);
1004 
1005     return result;
1006 }
1007 
CoreUsbFunctionsToString(napi_env env,napi_callback_info info)1008 static napi_value CoreUsbFunctionsToString(napi_env env, napi_callback_info info)
1009 {
1010     size_t argc = PARAM_COUNT_1;
1011     napi_value argv[PARAM_COUNT_1] = {nullptr};
1012 
1013     NAPI_CHECK(env, napi_get_cb_info(env, info, &argc, argv, nullptr, nullptr), "Get call back info failed");
1014     USB_ASSERT(env, (argc >= PARAM_COUNT_1), OHEC_COMMON_PARAM_ERROR, "The function at least takes one argument.");
1015 
1016     napi_valuetype type;
1017     NAPI_CHECK(env, napi_typeof(env, argv[INDEX_0], &type), "Get args 1 type failed");
1018     USB_ASSERT(env, type == napi_number, OHEC_COMMON_PARAM_ERROR, "The type of funcs must be number.");
1019 
1020     int32_t funcs;
1021     napi_get_value_int32(env, argv[INDEX_0], &funcs);
1022     std::string strFuncs = g_usbClient.UsbFunctionsToString(funcs);
1023     USB_ASSERT_RETURN_UNDEF(env, (strFuncs != PERMISSION_DENIED_SYSAPI), OHEC_COMMON_NORMAL_APP_NOT_ALLOWED, "");
1024     napi_value result;
1025     napi_create_string_utf8(env, strFuncs.c_str(), NAPI_AUTO_LENGTH, &result);
1026 
1027     return result;
1028 }
1029 
__anon2b6789b40502(napi_env env, void *data) 1030 static auto g_setCurrentFunctionExecute = [](napi_env env, void *data) {
1031     USBFunctionAsyncContext *asyncContext = reinterpret_cast<USBFunctionAsyncContext *>(data);
1032     int32_t ret = g_usbClient.SetCurrentFunctions(asyncContext->functions);
1033     asyncContext->errCode = ret;
1034 };
1035 
__anon2b6789b40602(napi_env env, napi_status status, void *data) 1036 static auto g_setCurrentFunctionComplete = [](napi_env env, napi_status status, void *data) {
1037     USBFunctionAsyncContext *asyncContext = reinterpret_cast<USBFunctionAsyncContext *>(data);
1038     napi_value queryResult = nullptr;
1039 
1040     if (asyncContext->errCode == UEC_OK) {
1041         asyncContext->status = napi_ok;
1042         napi_get_boolean(env, true, &queryResult);
1043     } else if (asyncContext->errCode == UEC_SERVICE_PERMISSION_DENIED_SYSAPI) {
1044         asyncContext->status = napi_generic_failure;
1045         queryResult = CreateBusinessError((env), OHEC_COMMON_NORMAL_APP_NOT_ALLOWED, "");
1046     } else if (asyncContext->errCode == UEC_SERVICE_PERMISSION_CHECK_HDC) {
1047         asyncContext->status = napi_generic_failure;
1048         queryResult = CreateBusinessError((env), UEC_COMMON_HDC_NOT_ALLOWED, "");
1049     } else if (asyncContext->errCode == UEC_SERVICE_FUNCTION_NOT_SUPPORT) {
1050         asyncContext->status = napi_generic_failure;
1051         queryResult = CreateBusinessError((env), UEC_COMMON_FUNCTION_NOT_SUPPORT, "");
1052     } else {
1053         asyncContext->status = napi_generic_failure;
1054         napi_get_boolean(env, false, &queryResult);
1055     }
1056     ProcessPromise(env, *asyncContext, queryResult);
1057     napi_delete_async_work(env, asyncContext->work);
1058     delete asyncContext;
1059 };
1060 
CoreSetCurrentFunctions(napi_env env,napi_callback_info info)1061 static napi_value CoreSetCurrentFunctions(napi_env env, napi_callback_info info)
1062 {
1063     size_t argc = PARAM_COUNT_1;
1064     napi_value argv[PARAM_COUNT_1] = {nullptr};
1065 
1066     NAPI_CHECK(env, napi_get_cb_info(env, info, &argc, argv, nullptr, nullptr), "Get call back info failed");
1067     USB_ASSERT(env, (argc >= PARAM_COUNT_1), OHEC_COMMON_PARAM_ERROR, "The function at least takes one argument.");
1068 
1069     napi_valuetype type;
1070     NAPI_CHECK(env, napi_typeof(env, argv[INDEX_0], &type), "Get args 1 type failed");
1071     USB_ASSERT(env, type == napi_number, OHEC_COMMON_PARAM_ERROR, "The type of funcs must be number.");
1072 
1073     int32_t funcs = 0;
1074     napi_get_value_int32(env, argv[INDEX_0], &funcs);
1075 
1076     auto asyncContext = new (std::nothrow) USBFunctionAsyncContext();
1077     if (asyncContext == nullptr) {
1078         USB_HILOGE(MODULE_JS_NAPI, "Create USBFunctionAsyncContext failed");
1079         return nullptr;
1080     }
1081 
1082     asyncContext->env = env;
1083     asyncContext->functions = funcs;
1084     napi_value result = nullptr;
1085     napi_create_promise(env, &asyncContext->deferred, &result);
1086 
1087     napi_value resource = nullptr;
1088     napi_create_string_utf8(env, "SetCurrentFunctions", NAPI_AUTO_LENGTH, &resource);
1089 
1090     napi_create_async_work(env, nullptr, resource, g_setCurrentFunctionExecute, g_setCurrentFunctionComplete,
1091         reinterpret_cast<void *>(asyncContext), &asyncContext->work);
1092     napi_queue_async_work(env, asyncContext->work);
1093 
1094     return result;
1095 }
1096 
CoreGetCurrentFunctions(napi_env env,napi_callback_info info)1097 static napi_value CoreGetCurrentFunctions(napi_env env, napi_callback_info info)
1098 {
1099     size_t argc = PARAM_COUNT_1;
1100     napi_value argv[PARAM_COUNT_1] = {nullptr};
1101     NAPI_CHECK(env, napi_get_cb_info(env, info, &argc, argv, nullptr, nullptr), "Get call back info failed");
1102     USB_ASSERT(env, (argc == PARAM_COUNT_0), OHEC_COMMON_PARAM_ERROR, "The function takes no arguments.");
1103 
1104     int32_t cfuncs;
1105     int32_t ret = g_usbClient.GetCurrentFunctions(cfuncs);
1106     napi_value result;
1107     USB_HILOGI(MODULE_JS_NAPI, "get current functions failed ret = %{public}d", ret);
1108     USB_ASSERT_RETURN_UNDEF(env, (ret != UEC_SERVICE_PERMISSION_DENIED_SYSAPI), OHEC_COMMON_NORMAL_APP_NOT_ALLOWED, "");
1109 
1110     if (ret != UEC_OK) {
1111         napi_get_undefined(env, &result);
1112         USB_HILOGE(MODULE_JS_NAPI, "end call get ports failed ret : %{public}d", ret);
1113         return result;
1114     }
1115     napi_create_int32(env, cfuncs, &result);
1116 
1117     return result;
1118 }
1119 
CoreGetPorts(napi_env env,napi_callback_info info)1120 static napi_value CoreGetPorts(napi_env env, napi_callback_info info)
1121 {
1122     size_t argc = PARAM_COUNT_1;
1123     napi_value argv[PARAM_COUNT_1] = {nullptr};
1124     NAPI_CHECK(env, napi_get_cb_info(env, info, &argc, argv, nullptr, nullptr), "Get call back info failed");
1125     USB_ASSERT(env, (argc == PARAM_COUNT_0), OHEC_COMMON_PARAM_ERROR, "The function takes no arguments.");
1126 
1127     std::vector<UsbPort> ports;
1128     int32_t ret = g_usbClient.GetPorts(ports);
1129     napi_value result;
1130     USB_HILOGI(MODULE_JS_NAPI, "get ports failed ret : %{public}d", ret);
1131     USB_ASSERT_RETURN_UNDEF(env, (ret != UEC_SERVICE_PERMISSION_DENIED_SYSAPI), OHEC_COMMON_NORMAL_APP_NOT_ALLOWED, "");
1132 
1133     if (ret != UEC_OK) {
1134         napi_get_undefined(env, &result);
1135         USB_HILOGE(MODULE_JS_NAPI, "end call get ports failed ret : %{public}d", ret);
1136         return result;
1137     }
1138 
1139     napi_create_array(env, &result);
1140     for (uint32_t i = 0; i < ports.size(); ++i) {
1141         napi_value port;
1142         napi_create_object(env, &port);
1143         NapiUtil::SetValueInt32(env, "id", ports[i].id, port);
1144         NapiUtil::SetValueInt32(env, "supportedModes", ports[i].supportedModes, port);
1145         napi_value usbPortStatus;
1146         napi_create_object(env, &usbPortStatus);
1147         NapiUtil::SetValueInt32(env, "currentMode", ports[i].usbPortStatus.currentMode, usbPortStatus);
1148         NapiUtil::SetValueInt32(env, "currentPowerRole", ports[i].usbPortStatus.currentPowerRole, usbPortStatus);
1149         NapiUtil::SetValueInt32(env, "currentDataRole", ports[i].usbPortStatus.currentDataRole, usbPortStatus);
1150         napi_set_named_property(env, port, "status", usbPortStatus);
1151         napi_set_element(env, result, i, port);
1152     }
1153 
1154     return result;
1155 }
1156 
1157 /* ============================================= Usb Port ============================================= */
1158 
PortGetSupportedModes(napi_env env,napi_callback_info info)1159 static napi_value PortGetSupportedModes(napi_env env, napi_callback_info info)
1160 {
1161     size_t argc = PARAM_COUNT_1;
1162     napi_value args[PARAM_COUNT_1] = {nullptr};
1163 
1164     NAPI_CHECK(env, napi_get_cb_info(env, info, &argc, args, nullptr, nullptr), "Get call back info failed");
1165     USB_ASSERT(env, (argc >= PARAM_COUNT_1), OHEC_COMMON_PARAM_ERROR, "The function at least takes one argument.");
1166 
1167     napi_valuetype type;
1168     NAPI_CHECK(env, napi_typeof(env, args[INDEX_0], &type), "Get args 1 type failed");
1169     USB_ASSERT(env, type == napi_number, OHEC_COMMON_PARAM_ERROR, "The type of portId must be number.");
1170 
1171     int32_t id = 0;
1172     int32_t result = 0;
1173     napi_get_value_int32(env, args[INDEX_0], &id);
1174     int32_t ret = g_usbClient.GetSupportedModes(id, result);
1175     USB_HILOGI(MODULE_JS_NAPI, "get supported modes failed ret = %{public}d", ret);
1176     USB_ASSERT_RETURN_UNDEF(env, (ret != UEC_SERVICE_PERMISSION_DENIED_SYSAPI), OHEC_COMMON_NORMAL_APP_NOT_ALLOWED, "");
1177 
1178     if (ret) {
1179         USB_HILOGD(MODULE_JS_NAPI, "false ret = %{public}d", ret);
1180     }
1181     napi_value napiValue = nullptr;
1182     NAPI_CHECK(env, napi_create_int32(env, result, &napiValue), "Create int32 failed");
1183 
1184     return napiValue;
1185 }
1186 
__anon2b6789b40702(napi_env env, void *data) 1187 static auto g_setPortRoleExecute = [](napi_env env, void *data) {
1188     USBPortRoleAsyncContext *asyncContext = reinterpret_cast<USBPortRoleAsyncContext *>(data);
1189     int32_t ret = g_usbClient.SetPortRole(asyncContext->portId, asyncContext->powerRole, asyncContext->dataRole);
1190     asyncContext->errCode = ret;
1191 };
1192 
__anon2b6789b40802(napi_env env, napi_status status, void *data) 1193 static auto g_setPortRoleComplete = [](napi_env env, napi_status status, void *data) {
1194     USBPortRoleAsyncContext *asyncContext = reinterpret_cast<USBPortRoleAsyncContext *>(data);
1195     napi_value queryResult = nullptr;
1196 
1197     if (asyncContext->errCode == UEC_OK) {
1198         asyncContext->status = napi_ok;
1199         napi_get_boolean(env, true, &queryResult);
1200     } else if (asyncContext->errCode == UEC_SERVICE_PERMISSION_DENIED_SYSAPI) {
1201         asyncContext->status = napi_generic_failure;
1202         queryResult = CreateBusinessError((env), OHEC_COMMON_NORMAL_APP_NOT_ALLOWED, "");
1203     } else if (asyncContext->errCode == UEC_SERVICE_NOT_SUPPORT_SWITCH_PORT) {
1204         asyncContext->status = napi_generic_failure;
1205         queryResult = CreateBusinessError((env), UEC_COMMON_PORTROLE_SWITCH_NOT_ALLOWED, "");
1206     } else {
1207         asyncContext->status = napi_generic_failure;
1208         napi_get_boolean(env, false, &queryResult);
1209     }
1210     ProcessPromise(env, *asyncContext, queryResult);
1211     napi_delete_async_work(env, asyncContext->work);
1212     delete asyncContext;
1213 };
1214 
PortSetPortRole(napi_env env,napi_callback_info info)1215 static napi_value PortSetPortRole(napi_env env, napi_callback_info info)
1216 {
1217     size_t argc = PARAM_COUNT_3;
1218     napi_value args[PARAM_COUNT_3] = {nullptr};
1219 
1220     NAPI_CHECK(env, napi_get_cb_info(env, info, &argc, args, nullptr, nullptr), "Get call back info failed");
1221     USB_ASSERT(env, (argc >= PARAM_COUNT_3), OHEC_COMMON_PARAM_ERROR, "The function at least takes three arguments.");
1222 
1223     napi_valuetype type;
1224     NAPI_CHECK(env, napi_typeof(env, args[INDEX_0], &type), "Get args 1 type failed");
1225     USB_ASSERT(env, type == napi_number, OHEC_COMMON_PARAM_ERROR, "The type of portId must be number.");
1226     NAPI_CHECK(env, napi_typeof(env, args[INDEX_1], &type), "Get args 2 type failed");
1227     USB_ASSERT(env, type == napi_number, OHEC_COMMON_PARAM_ERROR, "The type of powerRole must be number.");
1228     NAPI_CHECK(env, napi_typeof(env, args[INDEX_2], &type), "Get args 3 type failed");
1229     USB_ASSERT(env, type == napi_number, OHEC_COMMON_PARAM_ERROR, "The type of dataRole must be number.");
1230 
1231     int32_t id = 0;
1232     napi_get_value_int32(env, args[INDEX_0], &id);
1233     int32_t powerRole = 0;
1234     napi_get_value_int32(env, args[INDEX_1], &powerRole);
1235     int32_t dataRole = 0;
1236     napi_get_value_int32(env, args[INDEX_2], &dataRole);
1237 
1238     auto asyncContext = new (std::nothrow) USBPortRoleAsyncContext();
1239     if (asyncContext == nullptr) {
1240         USB_HILOGE(MODULE_JS_NAPI, "Create USBPortRoleAsyncContext failed");
1241         return nullptr;
1242     }
1243 
1244     asyncContext->env = env;
1245     asyncContext->portId = id;
1246     asyncContext->dataRole = dataRole;
1247     asyncContext->powerRole = powerRole;
1248 
1249     napi_value result = nullptr;
1250     napi_create_promise(env, &asyncContext->deferred, &result);
1251 
1252     napi_value resource = nullptr;
1253     napi_create_string_utf8(env, "PortSetPortRole", NAPI_AUTO_LENGTH, &resource);
1254 
1255     napi_create_async_work(env, nullptr, resource, g_setPortRoleExecute, g_setPortRoleComplete,
1256         reinterpret_cast<void *>(asyncContext), &asyncContext->work);
1257     napi_queue_async_work(env, asyncContext->work);
1258 
1259     return result;
1260 }
1261 
PipeClaimInterface(napi_env env,napi_callback_info info)1262 static napi_value PipeClaimInterface(napi_env env, napi_callback_info info)
1263 {
1264     size_t argc = PARAM_COUNT_3;
1265     napi_value argv[PARAM_COUNT_3] = {nullptr};
1266 
1267     NAPI_CHECK(env, napi_get_cb_info(env, info, &argc, argv, nullptr, nullptr), "Get call back info failed");
1268     USB_ASSERT(env, (argc >= PARAM_COUNT_2), OHEC_COMMON_PARAM_ERROR,
1269         "The function at least takes two arguments.");
1270 
1271     napi_value obj = argv[INDEX_0];
1272     napi_valuetype type;
1273     napi_typeof(env, obj, &type);
1274     USB_ASSERT(env, type == napi_object, OHEC_COMMON_PARAM_ERROR, "The type of pipe must be USBDevicePipe.");
1275 
1276     USBDevicePipe pipe;
1277     ParseUsbDevicePipe(env, obj, pipe);
1278 
1279     UsbInterface interface;
1280     napi_value obj2 = argv[INDEX_1];
1281     napi_typeof(env, obj2, &type);
1282     USB_ASSERT(env, type == napi_object, OHEC_COMMON_PARAM_ERROR, "The type of iface must be USBInterface.");
1283     ParseInterfaceObj(env, obj2, interface);
1284 
1285     bool isForce = false;
1286     if (argc >= PARAM_COUNT_3) {
1287         napi_typeof(env, argv[INDEX_2], &type);
1288         if (type == napi_boolean) {
1289             napi_get_value_bool(env, argv[INDEX_2], &isForce);
1290         } else {
1291             USB_HILOGW(MODULE_JS_NAPI, "The type of force must be boolean.");
1292         }
1293     }
1294 
1295     int32_t ret = pipe.ClaimInterface(interface, isForce);
1296     USB_HILOGD(MODULE_JS_NAPI, "pipe call ClaimInterface ret: %{public}d", ret);
1297     napi_value result;
1298     napi_create_int32(env, ret, &result);
1299 
1300     return result;
1301 }
1302 
PipeReleaseInterface(napi_env env,napi_callback_info info)1303 static napi_value PipeReleaseInterface(napi_env env, napi_callback_info info)
1304 {
1305     size_t argc = PARAM_COUNT_2;
1306     napi_value argv[PARAM_COUNT_2] = {nullptr};
1307 
1308     NAPI_CHECK(env, napi_get_cb_info(env, info, &argc, argv, nullptr, nullptr), "Get call back info failed");
1309     USB_ASSERT(env, (argc >= PARAM_COUNT_2), OHEC_COMMON_PARAM_ERROR, "The function at least takes two argument.");
1310 
1311     napi_value obj = argv[INDEX_0];
1312     napi_valuetype type;
1313     napi_typeof(env, obj, &type);
1314     USB_ASSERT(env, type == napi_object, OHEC_COMMON_PARAM_ERROR, "The type of pipe must be USBDevicePipe.");
1315 
1316     USBDevicePipe pipe;
1317     ParseUsbDevicePipe(env, obj, pipe);
1318 
1319     UsbInterface interface;
1320     napi_value obj2 = argv[INDEX_1];
1321     napi_typeof(env, obj2, &type);
1322     USB_ASSERT(env, type == napi_object, OHEC_COMMON_PARAM_ERROR, "The type of iface must be USBInterface.");
1323     ParseInterfaceObj(env, obj2, interface);
1324     int32_t ret = pipe.ReleaseInterface(interface);
1325     USB_HILOGD(MODULE_JS_NAPI, "pipe call PipeReleaseInterface ret: %{public}d", ret);
1326     napi_value result;
1327     napi_create_int32(env, ret, &result);
1328 
1329     return result;
1330 }
1331 
PipeSetInterface(napi_env env,napi_callback_info info)1332 static napi_value PipeSetInterface(napi_env env, napi_callback_info info)
1333 {
1334     size_t argc = PARAM_COUNT_2;
1335     napi_value argv[PARAM_COUNT_2] = {nullptr};
1336     NAPI_CHECK(env, napi_get_cb_info(env, info, &argc, argv, nullptr, nullptr), "Get call back info failed");
1337     USB_ASSERT(env, (argc >= PARAM_COUNT_2), OHEC_COMMON_PARAM_ERROR, "The function at least takes two argument.");
1338 
1339     napi_value pipeObj = argv[INDEX_0];
1340     napi_valuetype type;
1341     napi_typeof(env, pipeObj, &type);
1342     USB_ASSERT(env, type == napi_object, OHEC_COMMON_PARAM_ERROR, "The type of pipe must be USBDevicePipe.");
1343 
1344     USBDevicePipe pipe;
1345     ParseUsbDevicePipe(env, pipeObj, pipe);
1346 
1347     napi_value interfaceObj = argv[INDEX_1];
1348     napi_typeof(env, interfaceObj, &type);
1349     USB_ASSERT(env, type == napi_object, OHEC_COMMON_PARAM_ERROR, "The type of iface must be USBInterface.");
1350 
1351     UsbInterface interface;
1352     ParseInterfaceObj(env, interfaceObj, interface);
1353     int32_t ret = g_usbClient.SetInterface(pipe, interface);
1354     napi_value result;
1355     napi_create_int32(env, ret, &result);
1356 
1357     return result;
1358 }
1359 
PipeSetConfiguration(napi_env env,napi_callback_info info)1360 static napi_value PipeSetConfiguration(napi_env env, napi_callback_info info)
1361 {
1362     size_t argc = PARAM_COUNT_2;
1363     napi_value argv[PARAM_COUNT_2] = {nullptr};
1364     NAPI_CHECK(env, napi_get_cb_info(env, info, &argc, argv, nullptr, nullptr), "Get call back info failed");
1365     USB_ASSERT(env, (argc >= PARAM_COUNT_2), OHEC_COMMON_PARAM_ERROR, "The function at least takes two argument.");
1366 
1367     napi_valuetype type;
1368     napi_value pipeObj = argv[INDEX_0];
1369 
1370     napi_typeof(env, pipeObj, &type);
1371     USB_ASSERT(env, type == napi_object, OHEC_COMMON_PARAM_ERROR, "The type of pipe must be USBDevicePipe.");
1372     USBDevicePipe pipe;
1373     ParseUsbDevicePipe(env, pipeObj, pipe);
1374 
1375     napi_value configObj = argv[INDEX_1];
1376     napi_typeof(env, configObj, &type);
1377     USB_ASSERT(env, type == napi_object, OHEC_COMMON_PARAM_ERROR, "The type of config must be USBConfig.");
1378     USBConfig config;
1379     ParseConfigObj(env, configObj, config);
1380 
1381     int32_t ret = g_usbClient.SetConfiguration(pipe, config);
1382     napi_value result;
1383     napi_create_int32(env, ret, &result);
1384 
1385     return result;
1386 }
1387 
PipeGetRawDescriptors(napi_env env,napi_callback_info info)1388 static napi_value PipeGetRawDescriptors(napi_env env, napi_callback_info info)
1389 {
1390     size_t argc = PARAM_COUNT_1;
1391     napi_value argv[PARAM_COUNT_1] = {nullptr};
1392 
1393     NAPI_CHECK(env, napi_get_cb_info(env, info, &argc, argv, nullptr, nullptr), "Get call back info failed");
1394     USB_ASSERT(env, (argc >= PARAM_COUNT_1), OHEC_COMMON_PARAM_ERROR, "The function at least takes one argument.");
1395     napi_value obj = argv[INDEX_0];
1396     napi_valuetype type;
1397     napi_typeof(env, obj, &type);
1398     USB_ASSERT(env, type == napi_object, OHEC_COMMON_PARAM_ERROR, "The type of pipe must be USBDevicePipe.");
1399 
1400     USBDevicePipe pipe;
1401     ParseUsbDevicePipe(env, obj, pipe);
1402 
1403     napi_value result;
1404     std::vector<uint8_t> bufferData;
1405     int32_t ret = g_usbClient.GetRawDescriptors(pipe, bufferData);
1406     if (ret == UEC_OK) {
1407         NapiUtil::Uint8ArrayToJsValue(env, bufferData, bufferData.size(), result);
1408     } else {
1409         napi_get_undefined(env, &result);
1410     }
1411 
1412     return result;
1413 }
1414 
PipeGetFileDescriptor(napi_env env,napi_callback_info info)1415 static napi_value PipeGetFileDescriptor(napi_env env, napi_callback_info info)
1416 {
1417     size_t argc = PARAM_COUNT_1;
1418     napi_value argv[PARAM_COUNT_1] = {nullptr};
1419 
1420     NAPI_CHECK(env, napi_get_cb_info(env, info, &argc, argv, nullptr, nullptr), "Get call back info failed");
1421     USB_ASSERT(env, (argc >= PARAM_COUNT_1), OHEC_COMMON_PARAM_ERROR, "The function at least takes one argument.");
1422     napi_value obj = argv[INDEX_0];
1423     napi_valuetype type;
1424     napi_typeof(env, obj, &type);
1425     USB_ASSERT(env, type == napi_object, OHEC_COMMON_PARAM_ERROR, "The type of pipe must be USBDevicePipe.");
1426 
1427     USBDevicePipe pipe;
1428     ParseUsbDevicePipe(env, obj, pipe);
1429 
1430     int32_t fd = -1;
1431     napi_value result;
1432     g_usbClient.GetFileDescriptor(pipe, fd);
1433     napi_create_int32(env, fd, &result);
1434 
1435     return result;
1436 }
1437 
__anon2b6789b40902(napi_env env, void *data) 1438 static auto g_controlTransferExecute = [](napi_env env, void *data) {
1439     USBControlTransferAsyncContext *asyncContext = (USBControlTransferAsyncContext *)data;
1440     std::vector<uint8_t> bufferData(asyncContext->buffer, asyncContext->buffer + asyncContext->bufferLength);
1441     if ((asyncContext->reqType & USB_ENDPOINT_DIR_MASK) == USB_ENDPOINT_DIR_OUT) {
1442         delete[] asyncContext->buffer;
1443         asyncContext->buffer = nullptr;
1444     }
1445 
1446     const UsbCtrlTransfer tctrl = {
1447         asyncContext->reqType, asyncContext->request, asyncContext->value, asyncContext->index, asyncContext->timeOut};
1448     int32_t ret;
1449     do {
1450         ret = asyncContext->pipe.ControlTransfer(tctrl, bufferData);
1451         if (ret != UEC_OK) {
1452             USB_HILOGE(MODULE_JS_NAPI, "ControlTransferExecute failed");
1453             break;
1454         }
1455 
1456         if ((asyncContext->reqType & USB_ENDPOINT_DIR_MASK) == USB_ENDPOINT_DIR_IN) {
1457             ret = memcpy_s(asyncContext->buffer, asyncContext->bufferLength, bufferData.data(), bufferData.size());
1458         }
1459     } while (0);
1460 
1461     if (ret == UEC_OK) {
1462         asyncContext->status = napi_ok;
1463         asyncContext->dataSize = bufferData.size();
1464     } else {
1465         asyncContext->status = napi_generic_failure;
1466         asyncContext->dataSize = 0;
1467     }
1468 };
1469 
__anon2b6789b40a02(napi_env env, napi_status status, void *data) 1470 static auto g_controlTransferComplete = [](napi_env env, napi_status status, void *data) {
1471     USBControlTransferAsyncContext *asyncContext = reinterpret_cast<USBControlTransferAsyncContext *>(data);
1472     napi_value queryResult = nullptr;
1473 
1474     if (asyncContext->status == napi_ok) {
1475         napi_create_int32(env, asyncContext->dataSize, &queryResult);
1476     } else {
1477         USB_HILOGD(MODULE_JS_NAPI, "ControlTransfer failed");
1478         napi_create_int32(env, -1, &queryResult);
1479     }
1480     if (asyncContext->deferred) {
1481         napi_resolve_deferred(env, asyncContext->deferred, queryResult);
1482     }
1483     napi_delete_async_work(env, asyncContext->work);
1484     delete asyncContext;
1485 };
1486 
GetControlTransferParam(napi_env env,napi_callback_info info)1487 static std::tuple<bool, USBDevicePipe, PipeControlParam, int32_t> GetControlTransferParam(
1488     napi_env env, napi_callback_info info)
1489 {
1490     size_t argc = PARAM_COUNT_3;
1491     napi_value argv[PARAM_COUNT_3] = {nullptr};
1492     napi_status status = napi_get_cb_info(env, info, &argc, argv, nullptr, nullptr);
1493     if (status != napi_ok) {
1494         USB_HILOGE(MODULE_JS_NAPI, "ControlTransfer failed to get cb info");
1495         return {false, {}, {}, {}};
1496     }
1497 
1498     if (argc < PARAM_COUNT_2) {
1499         USB_HILOGE(MODULE_JS_NAPI, "The function at least takes two arguments.");
1500         ThrowBusinessError(env, OHEC_COMMON_PARAM_ERROR, "The function at least takes two arguments.");
1501         return {false, {}, {}, {}};
1502     }
1503 
1504     // pipe param
1505     napi_valuetype type;
1506     napi_typeof(env, argv[INDEX_0], &type);
1507     if (type != napi_object) {
1508         USB_HILOGE(MODULE_JS_NAPI, "index 0 wrong argument type, object expected.");
1509         ThrowBusinessError(env, OHEC_COMMON_PARAM_ERROR, "The type of pipe must be USBDevicePipe.");
1510         return {false, {}, {}, {}};
1511     }
1512 
1513     USBDevicePipe pipe;
1514     ParseUsbDevicePipe(env, argv[INDEX_0], pipe);
1515 
1516     // control params
1517     PipeControlParam controlParam = {0};
1518     bool ret = ParsePipeControlParam(env, argv[INDEX_1], controlParam);
1519     if (!ret) {
1520         USB_HILOGE(MODULE_JS_NAPI, "index 1 wrong argument type, object expected.");
1521         return {false, {}, {}, {}};
1522     }
1523 
1524     // timeOut param
1525     int32_t timeOut = 0;
1526     if (argc > PARAM_COUNT_2) {
1527         napi_typeof(env, argv[INDEX_2], &type);
1528         if (type == napi_number) {
1529             napi_get_value_int32(env, argv[INDEX_2], &timeOut);
1530         } else {
1531             USB_HILOGW(MODULE_JS_NAPI, "index 2 wrong argument type, number expected.");
1532         }
1533     }
1534 
1535     return {true, pipe, controlParam, timeOut};
1536 }
1537 
PipeControlTransfer(napi_env env,napi_callback_info info)1538 static napi_value PipeControlTransfer(napi_env env, napi_callback_info info)
1539 {
1540     auto [res, pipe, controlParam, timeOut] = GetControlTransferParam(env, info);
1541     if (!res) {
1542         USB_HILOGE(MODULE_JS_NAPI, "GetControlTransferParam failed.");
1543         return nullptr;
1544     }
1545 
1546     auto asyncContext = new (std::nothrow) USBControlTransferAsyncContext();
1547     if (asyncContext == nullptr) {
1548         USB_HILOGE(MODULE_JS_NAPI, "New USBControlTransferAsyncContext failed.");
1549         return nullptr;
1550     }
1551 
1552     asyncContext->env = env;
1553     asyncContext->pipe = pipe;
1554     asyncContext->request = controlParam.request;
1555     asyncContext->target = controlParam.target;
1556     asyncContext->reqType = controlParam.reqType;
1557     asyncContext->value = controlParam.value;
1558     asyncContext->index = controlParam.index;
1559 
1560     if ((asyncContext->reqType & USB_ENDPOINT_DIR_MASK) == USB_ENDPOINT_DIR_OUT) {
1561         uint8_t *nativeArrayBuffer = new (std::nothrow) uint8_t[controlParam.dataLength];
1562         if (nativeArrayBuffer == nullptr) {
1563             USB_HILOGE(MODULE_JS_NAPI, "new failed");
1564             delete asyncContext;
1565             return nullptr;
1566         }
1567 
1568         errno_t ret = memcpy_s(nativeArrayBuffer, controlParam.dataLength, controlParam.data, controlParam.dataLength);
1569         if (ret != EOK) {
1570             USB_HILOGE(MODULE_JS_NAPI, "memcpy_s failed");
1571             delete asyncContext;
1572             delete[] nativeArrayBuffer;
1573             return nullptr;
1574         }
1575         asyncContext->buffer = nativeArrayBuffer;
1576     } else {
1577         asyncContext->buffer = controlParam.data;
1578     }
1579 
1580     asyncContext->bufferLength = controlParam.dataLength;
1581     asyncContext->timeOut = timeOut;
1582     napi_value result = nullptr;
1583     napi_create_promise(env, &asyncContext->deferred, &result);
1584 
1585     napi_value resource = nullptr;
1586     napi_create_string_utf8(env, "PipeControlTransfer", NAPI_AUTO_LENGTH, &resource);
1587 
1588     napi_create_async_work(env, nullptr, resource, g_controlTransferExecute, g_controlTransferComplete,
1589         reinterpret_cast<void *>(asyncContext), &asyncContext->work);
1590     napi_queue_async_work(env, asyncContext->work);
1591 
1592     return result;
1593 }
1594 
__anon2b6789b40b02(napi_env env, void *data) 1595 static auto g_usbControlTransferExecute = [](napi_env env, void *data) {
1596     USBDeviceControlTransferAsyncContext *asyncContext = (USBDeviceControlTransferAsyncContext *)data;
1597     std::vector<uint8_t> bufferData(asyncContext->buffer, asyncContext->buffer + asyncContext->bufferLength);
1598     if ((asyncContext->reqType & USB_ENDPOINT_DIR_MASK) == USB_ENDPOINT_DIR_OUT && asyncContext->buffer != nullptr) {
1599         delete[] asyncContext->buffer;
1600         asyncContext->buffer = nullptr;
1601     }
1602 
1603     const UsbCtrlTransferParams tctrl = {asyncContext->reqType, asyncContext->request,
1604         asyncContext->value, asyncContext->index, asyncContext->length, asyncContext->timeOut};
1605     int32_t ret;
1606     do {
1607         ret = asyncContext->pipe.UsbControlTransfer(tctrl, bufferData);
1608         if (ret != UEC_OK) {
1609             USB_HILOGE(MODULE_JS_NAPI, "ControlTransferExecute failed");
1610             break;
1611         }
1612 
1613         if ((asyncContext->reqType & USB_ENDPOINT_DIR_MASK) == USB_ENDPOINT_DIR_IN) {
1614             ret = memcpy_s(asyncContext->buffer, asyncContext->bufferLength, bufferData.data(), bufferData.size());
1615         }
1616     } while (0);
1617 
1618     if (ret == UEC_OK) {
1619         asyncContext->status = napi_ok;
1620         asyncContext->dataSize = bufferData.size();
1621     } else {
1622         asyncContext->status = napi_generic_failure;
1623         asyncContext->dataSize = 0;
1624     }
1625 };
1626 
__anon2b6789b40c02(napi_env env, napi_status status, void *data) 1627 static auto g_usbControlTransferComplete = [](napi_env env, napi_status status, void *data) {
1628     USBDeviceControlTransferAsyncContext *asyncContext = reinterpret_cast<USBDeviceControlTransferAsyncContext *>(data);
1629     napi_value queryResult = nullptr;
1630 
1631     if (asyncContext->status == napi_ok) {
1632         napi_create_int32(env, asyncContext->dataSize, &queryResult);
1633     } else {
1634         USB_HILOGD(MODULE_JS_NAPI, "usbControlTransfer failed");
1635         napi_create_int32(env, -1, &queryResult);
1636     }
1637     if (asyncContext->deferred) {
1638         napi_resolve_deferred(env, asyncContext->deferred, queryResult);
1639     }
1640     napi_delete_async_work(env, asyncContext->work);
1641     delete asyncContext;
1642 };
1643 
GetUsbControlTransferParam(napi_env env,napi_callback_info info)1644 static std::tuple<bool, USBDevicePipe, UsbPipeControlParam, int32_t> GetUsbControlTransferParam(
1645     napi_env env, napi_callback_info info)
1646 {
1647     size_t argc = PARAM_COUNT_3;
1648     napi_value argv[PARAM_COUNT_3] = {nullptr};
1649     napi_status status = napi_get_cb_info(env, info, &argc, argv, nullptr, nullptr);
1650     if (status != napi_ok) {
1651         USB_HILOGE(MODULE_JS_NAPI, "ControlTransfer failed to get cb info");
1652         return {false, {}, {}, {}};
1653     }
1654 
1655     if (argc < PARAM_COUNT_2) {
1656         USB_HILOGE(MODULE_JS_NAPI, "The function at least takes two arguments.");
1657         ThrowBusinessError(env, OHEC_COMMON_PARAM_ERROR, "The function at least takes two arguments.");
1658         return {false, {}, {}, {}};
1659     }
1660 
1661     // pipe param
1662     napi_valuetype type;
1663     napi_typeof(env, argv[INDEX_0], &type);
1664     if (type != napi_object) {
1665         USB_HILOGE(MODULE_JS_NAPI, "index 0 wrong argument type, object expected.");
1666         ThrowBusinessError(env, OHEC_COMMON_PARAM_ERROR, "The type of pipe must be USBDevicePipe.");
1667         return {false, {}, {}, {}};
1668     }
1669 
1670     USBDevicePipe pipe;
1671     ParseUsbDevicePipe(env, argv[INDEX_0], pipe);
1672 
1673     // control params
1674     napi_typeof(env, argv[INDEX_1], &type);
1675     if (type != napi_object) {
1676         USB_HILOGE(MODULE_JS_NAPI, "index 1 wrong argument type, object expected.");
1677         ThrowBusinessError(env, OHEC_COMMON_PARAM_ERROR, "The type of requestparam must be USBDeviceRequestParams.");
1678         return {false, {}, {}, {}};
1679     }
1680 
1681     UsbPipeControlParam controlParam = {0};
1682     ParseUsbPipeControlParam(env, argv[INDEX_1], controlParam);
1683 
1684     // timeOut param
1685     int32_t timeOut = 0;
1686     if (argc > PARAM_COUNT_2) {
1687         napi_typeof(env, argv[INDEX_2], &type);
1688         if (type == napi_number) {
1689             napi_get_value_int32(env, argv[INDEX_2], &timeOut);
1690         } else {
1691             USB_HILOGW(MODULE_JS_NAPI, "index 2 wrong argument type, number expected.");
1692         }
1693     }
1694 
1695     return {true, pipe, controlParam, timeOut};
1696 }
1697 
PipeUsbControlTransfer(napi_env env,napi_callback_info info)1698 static napi_value PipeUsbControlTransfer(napi_env env, napi_callback_info info)
1699 {
1700     auto [res, pipe, controlParam, timeOut] = GetUsbControlTransferParam(env, info);
1701     if (!res) {
1702         USB_HILOGE(MODULE_JS_NAPI, "GetUsbControlTransferParam failed.");
1703         return nullptr;
1704     }
1705 
1706     auto asyncContext = new (std::nothrow) USBDeviceControlTransferAsyncContext();
1707     if (asyncContext == nullptr) {
1708         USB_HILOGE(MODULE_JS_NAPI, "New USBDeviceControlTransferAsyncContext failed.");
1709         return nullptr;
1710     }
1711 
1712     asyncContext->env = env;
1713     asyncContext->pipe = pipe;
1714     asyncContext->reqType = controlParam.reqType;
1715     asyncContext->request = controlParam.request;
1716     asyncContext->value = controlParam.value;
1717     asyncContext->index = controlParam.index;
1718     asyncContext->length = controlParam.length;
1719 
1720     if ((asyncContext->reqType & USB_ENDPOINT_DIR_MASK) == USB_ENDPOINT_DIR_OUT) {
1721         uint8_t *nativeArrayBuffer = new (std::nothrow) uint8_t[controlParam.dataLength];
1722         if (nativeArrayBuffer == nullptr) {
1723             USB_HILOGE(MODULE_JS_NAPI, "new failed");
1724             delete asyncContext;
1725             return nullptr;
1726         }
1727 
1728         errno_t ret = memcpy_s(nativeArrayBuffer, controlParam.dataLength, controlParam.data, controlParam.dataLength);
1729         if (ret != EOK) {
1730             USB_HILOGE(MODULE_JS_NAPI, "memcpy_s failed");
1731             delete asyncContext;
1732             delete[] nativeArrayBuffer;
1733             return nullptr;
1734         }
1735         asyncContext->buffer = nativeArrayBuffer;
1736     } else {
1737         asyncContext->buffer = controlParam.data;
1738     }
1739 
1740     asyncContext->bufferLength = controlParam.dataLength;
1741     asyncContext->timeOut = timeOut;
1742     napi_value result = nullptr;
1743     napi_create_promise(env, &asyncContext->deferred, &result);
1744 
1745     napi_value resource = nullptr;
1746     napi_create_string_utf8(env, "PipeUsbControlTransfer", NAPI_AUTO_LENGTH, &resource);
1747 
1748     napi_create_async_work(env, nullptr, resource, g_usbControlTransferExecute, g_usbControlTransferComplete,
1749         reinterpret_cast<void *>(asyncContext), &asyncContext->work);
1750     napi_queue_async_work(env, asyncContext->work);
1751 
1752     return result;
1753 }
1754 
__anon2b6789b40d02(napi_env env, void *data) 1755 static auto g_bulkTransferExecute = [](napi_env env, void *data) {
1756     USBBulkTransferAsyncContext *asyncContext = reinterpret_cast<USBBulkTransferAsyncContext *>(data);
1757     std::vector<uint8_t> bufferData(asyncContext->buffer, asyncContext->buffer + asyncContext->bufferLength);
1758     if (asyncContext->endpoint.GetDirection() == USB_ENDPOINT_DIR_OUT) {
1759         delete[] asyncContext->buffer;
1760         asyncContext->buffer = nullptr;
1761     }
1762 
1763     int32_t ret;
1764     do {
1765         ret = asyncContext->pipe.BulkTransfer(asyncContext->endpoint, bufferData, asyncContext->timeOut);
1766         if (ret != UEC_OK) {
1767             USB_HILOGE(MODULE_JS_NAPI, "ControlTransferExecute failed");
1768             break;
1769         }
1770 
1771         if (asyncContext->endpoint.GetDirection() == USB_ENDPOINT_DIR_IN) {
1772             ret = memcpy_s(asyncContext->buffer, asyncContext->bufferLength, bufferData.data(), bufferData.size());
1773         }
1774     } while (0);
1775 
1776     USB_HILOGD(MODULE_JS_NAPI, "call pipe result %{public}d", ret);
1777     if (ret == UEC_OK) {
1778         asyncContext->status = napi_ok;
1779         asyncContext->dataSize = bufferData.size();
1780     } else {
1781         asyncContext->status = napi_generic_failure;
1782         asyncContext->dataSize = 0;
1783     }
1784 };
1785 
__anon2b6789b40e02(napi_env env, napi_status status, void *data) 1786 static auto g_bulkTransferComplete = [](napi_env env, napi_status status, void *data) {
1787     USBBulkTransferAsyncContext *asyncContext = reinterpret_cast<USBBulkTransferAsyncContext *>(data);
1788     napi_value queryResult = nullptr;
1789     if (asyncContext->status == napi_ok) {
1790         napi_create_int32(env, asyncContext->dataSize, &queryResult);
1791     } else {
1792         USB_HILOGE(MODULE_JS_NAPI, "BulkTransfer failed");
1793         napi_create_int32(env, -1, &queryResult);
1794     }
1795     if (asyncContext->deferred) {
1796         napi_resolve_deferred(env, asyncContext->deferred, queryResult);
1797     }
1798     napi_delete_async_work(env, asyncContext->work);
1799     delete asyncContext;
1800 };
1801 
GetDescriptorOnBulkTransferParam(napi_env env,napi_value data,USBBulkTransferAsyncContext & asyncContext,const USBEndpoint & ep)1802 static bool GetDescriptorOnBulkTransferParam(napi_env env, napi_value data,
1803     USBBulkTransferAsyncContext &asyncContext, const USBEndpoint &ep)
1804 {
1805     uint8_t *buffer = nullptr;
1806     size_t offset = 0;
1807     size_t bufferSize = 0;
1808     bool hasBuffer = NapiUtil::JsUint8ArrayParse(env, data, &buffer, bufferSize, offset);
1809     if (!hasBuffer) {
1810         USB_HILOGE(MODULE_JS_NAPI, "BulkTransfer wrong argument, buffer is null");
1811         return false;
1812     }
1813     asyncContext.env = env;
1814     asyncContext.endpoint = ep;
1815 
1816     if (ep.GetDirection() == USB_ENDPOINT_DIR_OUT) {
1817         uint8_t *nativeArrayBuffer = new (std::nothrow) uint8_t[bufferSize];
1818         RETURN_IF_WITH_RET(nativeArrayBuffer == nullptr, false);
1819 
1820         errno_t ret = memcpy_s(nativeArrayBuffer, bufferSize, buffer, bufferSize);
1821         if (ret != EOK) {
1822             USB_HILOGE(MODULE_JS_NAPI, "memcpy_s failed");
1823             delete[] nativeArrayBuffer;
1824             return false;
1825         }
1826 
1827         asyncContext.buffer = nativeArrayBuffer;
1828     } else {
1829         asyncContext.buffer = buffer;
1830     }
1831     asyncContext.bufferLength = bufferSize;
1832     return true;
1833 }
1834 
GetBulkTransferParams(napi_env env,napi_callback_info info,USBBulkTransferAsyncContext & asyncContext)1835 static bool GetBulkTransferParams(napi_env env, napi_callback_info info, USBBulkTransferAsyncContext &asyncContext)
1836 {
1837     size_t argc = PARAM_COUNT_4;
1838     napi_value argv[PARAM_COUNT_4] = {nullptr};
1839     NAPI_CHECK(env, napi_get_cb_info(env, info, &argc, argv, nullptr, nullptr), "Get call back info failed");
1840     USB_ASSERT_RETURN_FALSE(
1841         env, (argc >= PARAM_COUNT_3), OHEC_COMMON_PARAM_ERROR,
1842         "The function at least takes three arguments.");
1843 
1844     napi_valuetype type;
1845     USBDevicePipe pipe;
1846     napi_typeof(env, argv[INDEX_0], &type);
1847     USB_ASSERT_RETURN_FALSE(
1848         env, type == napi_object, OHEC_COMMON_PARAM_ERROR, "The type of pipe must be USBDevicePipe.");
1849     ParseUsbDevicePipe(env, argv[INDEX_0], pipe);
1850     asyncContext.pipe = pipe;
1851 
1852     USBEndpoint ep;
1853     napi_typeof(env, argv[INDEX_1], &type);
1854     USB_ASSERT_RETURN_FALSE(
1855         env, type == napi_object, OHEC_COMMON_PARAM_ERROR, "The type of endpoint must be USBEndpoint.");
1856     ParseEndpointObj(env, argv[INDEX_1], ep);
1857 
1858     int32_t timeOut = 0;
1859     if (argc > PARAM_COUNT_3) {
1860         napi_typeof(env, argv[INDEX_3], &type);
1861         if (type == napi_number) {
1862             napi_get_value_int32(env, argv[INDEX_3], &timeOut);
1863         } else {
1864             USB_HILOGW(MODULE_JS_NAPI, "The type of timeOut must be number.");
1865         }
1866     }
1867 
1868     if (!GetDescriptorOnBulkTransferParam(env, argv[INDEX_2], asyncContext, ep)) {
1869         USB_HILOGE(MODULE_JS_NAPI, "get asyncContext failed.");
1870         return false;
1871     }
1872     asyncContext.timeOut = timeOut;
1873     return true;
1874 }
1875 
PipeBulkTransfer(napi_env env,napi_callback_info info)1876 static napi_value PipeBulkTransfer(napi_env env, napi_callback_info info)
1877 {
1878     auto asyncContext = new (std::nothrow) USBBulkTransferAsyncContext();
1879     if (asyncContext == nullptr) {
1880         USB_HILOGE(MODULE_JS_NAPI, "Create USBBulkTransferAsyncContext failed.");
1881         return nullptr;
1882     }
1883 
1884     napi_value result = nullptr;
1885     napi_create_promise(env, &asyncContext->deferred, &result);
1886     if (!GetBulkTransferParams(env, info, *asyncContext)) {
1887         USB_HILOGE(MODULE_JS_NAPI, "end call invalid arg");
1888         asyncContext->status = napi_invalid_arg;
1889         napi_value queryResult = nullptr;
1890         napi_create_int32(env, -1, &queryResult);
1891         if (asyncContext->deferred) {
1892             napi_resolve_deferred(env, asyncContext->deferred, queryResult);
1893         }
1894         delete asyncContext;
1895         return result;
1896     }
1897 
1898     napi_value resource = nullptr;
1899     napi_create_string_utf8(env, "PipeBulkTransfer", NAPI_AUTO_LENGTH, &resource);
1900 
1901     napi_status status = napi_create_async_work(env, nullptr, resource, g_bulkTransferExecute, g_bulkTransferComplete,
1902         reinterpret_cast<void *>(asyncContext), &asyncContext->work);
1903     if (status != napi_ok) {
1904         USB_HILOGE(MODULE_JS_NAPI, "create async work failed");
1905         return result;
1906     }
1907     napi_queue_async_work(env, asyncContext->work);
1908 
1909     return result;
1910 }
1911 
PipeClose(napi_env env,napi_callback_info info)1912 static napi_value PipeClose(napi_env env, napi_callback_info info)
1913 {
1914     size_t argc = PARAM_COUNT_1;
1915     napi_value argv[PARAM_COUNT_1] = {nullptr};
1916 
1917     NAPI_CHECK(env, napi_get_cb_info(env, info, &argc, argv, nullptr, nullptr), "Get call back info failed");
1918     USB_ASSERT(env, (argc >= PARAM_COUNT_1), OHEC_COMMON_PARAM_ERROR, "The function at least takes one argument.");
1919 
1920     napi_value obj = argv[INDEX_0];
1921     napi_valuetype type;
1922     napi_typeof(env, obj, &type);
1923     USB_ASSERT(env, type == napi_object, OHEC_COMMON_PARAM_ERROR, "The type of pipe must be USBDevicePipe.");
1924 
1925     USBDevicePipe pipe;
1926     ParseUsbDevicePipe(env, obj, pipe);
1927     int32_t ret = pipe.Close();
1928     napi_value result;
1929     napi_create_int32(env, ret, &result);
1930 
1931     return result;
1932 }
1933 
GetVersion(napi_env env,napi_callback_info info)1934 static napi_value GetVersion(napi_env env, napi_callback_info info)
1935 {
1936     auto version = g_usbClient.GetVersion();
1937     USB_HILOGD(MODULE_JS_NAPI, "version is %{public}s", version.c_str());
1938     napi_value result;
1939     napi_create_string_utf8(env, version.c_str(), NAPI_AUTO_LENGTH, &result);
1940     return result;
1941 }
1942 
ToInt32Value(napi_env env,int32_t value)1943 static napi_value ToInt32Value(napi_env env, int32_t value)
1944 {
1945     napi_value staticValue = nullptr;
1946     napi_create_int32(env, value, &staticValue);
1947     return staticValue;
1948 }
1949 
DeclareEnum(napi_env env,napi_value exports)1950 static napi_value DeclareEnum(napi_env env, napi_value exports)
1951 {
1952     napi_property_descriptor desc[] = {
1953         /* Declare Enum PowerRoleType */
1954         DECLARE_NAPI_STATIC_PROPERTY("NONE", ToInt32Value(env, NONE)),
1955         DECLARE_NAPI_STATIC_PROPERTY("SOURCE", ToInt32Value(env, SOURCE)),
1956         DECLARE_NAPI_STATIC_PROPERTY("SINK", ToInt32Value(env, SINK)),
1957 
1958         /* Declare Enum DataRoleType */
1959         DECLARE_NAPI_STATIC_PROPERTY("HOST", ToInt32Value(env, HOST)),
1960         DECLARE_NAPI_STATIC_PROPERTY("DEVICE", ToInt32Value(env, DEVICE)),
1961 
1962         /* Declare Enum PortModeType */
1963         DECLARE_NAPI_STATIC_PROPERTY("UFP", ToInt32Value(env, UFP)),
1964         DECLARE_NAPI_STATIC_PROPERTY("DFP", ToInt32Value(env, DFP)),
1965         DECLARE_NAPI_STATIC_PROPERTY("DRP", ToInt32Value(env, DRP)),
1966         DECLARE_NAPI_STATIC_PROPERTY("NUM_MODES", ToInt32Value(env, NUM_MODES)),
1967 
1968         /* Declare Enum USBRequestTargetType */
1969         DECLARE_NAPI_STATIC_PROPERTY("USB_REQUEST_TARGET_DEVICE", ToInt32Value(env, USB_REQUEST_TARGET_DEVICE)),
1970         DECLARE_NAPI_STATIC_PROPERTY("USB_REQUEST_TARGET_INTERFACE", ToInt32Value(env, USB_REQUEST_TARGET_INTERFACE)),
1971         DECLARE_NAPI_STATIC_PROPERTY("USB_REQUEST_TARGET_ENDPOINT", ToInt32Value(env, USB_REQUEST_TARGET_ENDPOINT)),
1972         DECLARE_NAPI_STATIC_PROPERTY("USB_REQUEST_TARGET_OTHER", ToInt32Value(env, USB_REQUEST_TARGET_OTHER)),
1973 
1974         /* Declare Enum USBControlRequestType */
1975         DECLARE_NAPI_STATIC_PROPERTY("USB_REQUEST_TYPE_STANDARD", ToInt32Value(env, USB_REQUEST_TYPE_STANDARD)),
1976         DECLARE_NAPI_STATIC_PROPERTY("USB_REQUEST_TYPE_CLASS", ToInt32Value(env, USB_REQUEST_TYPE_CLASS)),
1977         DECLARE_NAPI_STATIC_PROPERTY("USB_REQUEST_TYPE_VENDOR", ToInt32Value(env, USB_REQUEST_TYPE_VENDOR)),
1978 
1979         /* Declare Enum USBRequestDirection */
1980         DECLARE_NAPI_STATIC_PROPERTY("USB_REQUEST_DIR_TO_DEVICE", ToInt32Value(env, USB_REQUEST_DIR_TO_DEVICE)),
1981         DECLARE_NAPI_STATIC_PROPERTY("USB_REQUEST_DIR_FROM_DEVICE", ToInt32Value(env, USB_REQUEST_DIR_FROM_DEVICE)),
1982 
1983         /* Declare Enum FunctionType */
1984         DECLARE_NAPI_STATIC_PROPERTY("ACM", ToInt32Value(env, ACM)),
1985         DECLARE_NAPI_STATIC_PROPERTY("ECM", ToInt32Value(env, ECM)),
1986         DECLARE_NAPI_STATIC_PROPERTY("HDC", ToInt32Value(env, HDC)),
1987         DECLARE_NAPI_STATIC_PROPERTY("MTP", ToInt32Value(env, MTP)),
1988         DECLARE_NAPI_STATIC_PROPERTY("PTP", ToInt32Value(env, PTP)),
1989         DECLARE_NAPI_STATIC_PROPERTY("RNDIS", ToInt32Value(env, RNDIS)),
1990         DECLARE_NAPI_STATIC_PROPERTY("MIDI", ToInt32Value(env, MIDI)),
1991         DECLARE_NAPI_STATIC_PROPERTY("AUDIO_SOURCE", ToInt32Value(env, AUDIO_SOURCE)),
1992         DECLARE_NAPI_STATIC_PROPERTY("NCM", ToInt32Value(env, NCM)),
1993         DECLARE_NAPI_STATIC_PROPERTY("STORAGE", ToInt32Value(env, STORAGE)),
1994     };
1995     NAPI_CALL(env, napi_define_properties(env, exports, sizeof(desc) / sizeof(desc[0]), desc));
1996     return exports;
1997 }
1998 
1999 EXTERN_C_START
2000 /*
2001  * function for module exports
2002  */
UsbInit(napi_env env,napi_value exports)2003 napi_value UsbInit(napi_env env, napi_value exports)
2004 {
2005     USB_HILOGD(MODULE_JS_NAPI, "enter");
2006 
2007     napi_property_descriptor desc[] = {
2008         /* usb core */
2009         DECLARE_NAPI_FUNCTION("getDevices", CoreGetDevices),
2010         DECLARE_NAPI_FUNCTION("connectDevice", CoreConnectDevice),
2011         DECLARE_NAPI_FUNCTION("hasRight", CoreHasRight),
2012         DECLARE_NAPI_FUNCTION("requestRight", CoreRequestRight),
2013         DECLARE_NAPI_FUNCTION("usbFunctionsFromString", CoreUsbFunctionsFromString),
2014         DECLARE_NAPI_FUNCTION("getFunctionsFromString", CoreUsbFunctionsFromString),
2015         DECLARE_NAPI_FUNCTION("usbFunctionsToString", CoreUsbFunctionsToString),
2016         DECLARE_NAPI_FUNCTION("getStringFromFunctions", CoreUsbFunctionsToString),
2017         DECLARE_NAPI_FUNCTION("setCurrentFunctions", CoreSetCurrentFunctions),
2018         DECLARE_NAPI_FUNCTION("setDeviceFunctions", CoreSetCurrentFunctions),
2019         DECLARE_NAPI_FUNCTION("getCurrentFunctions", CoreGetCurrentFunctions),
2020         DECLARE_NAPI_FUNCTION("getDeviceFunctions", CoreGetCurrentFunctions),
2021         DECLARE_NAPI_FUNCTION("getPorts", CoreGetPorts),
2022         DECLARE_NAPI_FUNCTION("getPortList", CoreGetPorts),
2023 
2024         /* usb port */
2025         DECLARE_NAPI_FUNCTION("getSupportedModes", PortGetSupportedModes),
2026         DECLARE_NAPI_FUNCTION("getPortSupportModes", PortGetSupportedModes),
2027         DECLARE_NAPI_FUNCTION("setPortRoles", PortSetPortRole),
2028         DECLARE_NAPI_FUNCTION("setPortRoleTypes", PortSetPortRole),
2029 
2030         /* usb device pipe */
2031         DECLARE_NAPI_FUNCTION("claimInterface", PipeClaimInterface),
2032         DECLARE_NAPI_FUNCTION("releaseInterface", PipeReleaseInterface),
2033         DECLARE_NAPI_FUNCTION("bulkTransfer", PipeBulkTransfer),
2034         DECLARE_NAPI_FUNCTION("controlTransfer", PipeControlTransfer),
2035         DECLARE_NAPI_FUNCTION("usbControlTransfer", PipeUsbControlTransfer),
2036         DECLARE_NAPI_FUNCTION("setInterface", PipeSetInterface),
2037         DECLARE_NAPI_FUNCTION("setConfiguration", PipeSetConfiguration),
2038         DECLARE_NAPI_FUNCTION("getRawDescriptor", PipeGetRawDescriptors),
2039         DECLARE_NAPI_FUNCTION("getFileDescriptor", PipeGetFileDescriptor),
2040         DECLARE_NAPI_FUNCTION("closePipe", PipeClose),
2041 
2042         /* fort test get usb service version */
2043         DECLARE_NAPI_FUNCTION("getVersion", GetVersion),
2044         DECLARE_NAPI_FUNCTION("addRight", DeviceAddRight),
2045         DECLARE_NAPI_FUNCTION("addDeviceAccessRight", DeviceAddAccessRight),
2046         DECLARE_NAPI_FUNCTION("removeRight", DeviceRemoveRight),
2047         DECLARE_NAPI_FUNCTION("getAccessoryList", DeviceGetAccessoryList),
2048         DECLARE_NAPI_FUNCTION("openAccessory", DeviceOpenAccessory),
2049         DECLARE_NAPI_FUNCTION("closeAccessory", DeviceCloseAccessory),
2050         DECLARE_NAPI_FUNCTION("addAccessoryRight", DeviceAddAccessoryRight),
2051         DECLARE_NAPI_FUNCTION("hasAccessoryRight", DeviceHasAccessoryRight),
2052         DECLARE_NAPI_FUNCTION("requestAccessoryRight", DeviceRequestAccessoryRight),
2053         DECLARE_NAPI_FUNCTION("cancelAccessoryRight", DeviceCancelAccessoryRight),
2054     };
2055     NAPI_CALL(env, napi_define_properties(env, exports, sizeof(desc) / sizeof(desc[0]), desc));
2056 
2057     DeclareEnum(env, exports);
2058 
2059     USB_HILOGD(MODULE_JS_NAPI, "return");
2060 
2061     return exports;
2062 }
2063 EXTERN_C_END
2064