1094332d3Sopenharmony_ci/*
2094332d3Sopenharmony_ci * Copyright (c) 2021 Huawei Device Co., Ltd.
3094332d3Sopenharmony_ci * Licensed under the Apache License, Version 2.0 (the "License");
4094332d3Sopenharmony_ci * you may not use this file except in compliance with the License.
5094332d3Sopenharmony_ci * You may obtain a copy of the License at
6094332d3Sopenharmony_ci *
7094332d3Sopenharmony_ci *     http://www.apache.org/licenses/LICENSE-2.0
8094332d3Sopenharmony_ci *
9094332d3Sopenharmony_ci * Unless required by applicable law or agreed to in writing, software
10094332d3Sopenharmony_ci * distributed under the License is distributed on an "AS IS" BASIS,
11094332d3Sopenharmony_ci * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12094332d3Sopenharmony_ci * See the License for the specific language governing permissions and
13094332d3Sopenharmony_ci * limitations under the License.
14094332d3Sopenharmony_ci */
15094332d3Sopenharmony_ci
16094332d3Sopenharmony_ci#include "adapter_if.h"
17094332d3Sopenharmony_ci#include <dirent.h>
18094332d3Sopenharmony_ci#include <endian.h>
19094332d3Sopenharmony_ci#include <fcntl.h>
20094332d3Sopenharmony_ci#include <poll.h>
21094332d3Sopenharmony_ci#include <stdarg.h>
22094332d3Sopenharmony_ci#include <stdio.h>
23094332d3Sopenharmony_ci#include <stdlib.h>
24094332d3Sopenharmony_ci#include <string.h>
25094332d3Sopenharmony_ci#include <sys/ioctl.h>
26094332d3Sopenharmony_ci#include <sys/stat.h>
27094332d3Sopenharmony_ci#include <sys/types.h>
28094332d3Sopenharmony_ci#include <unistd.h>
29094332d3Sopenharmony_ci
30094332d3Sopenharmony_ci#include "usb_handle.h"
31094332d3Sopenharmony_ci#include "usbd_wrapper.h"
32094332d3Sopenharmony_ci
33094332d3Sopenharmony_ci#define HDF_LOG_TAG adapter_if
34094332d3Sopenharmony_ci#define SLEEP_TIME  100000
35094332d3Sopenharmony_ci#define OPEN_CNT    30
36094332d3Sopenharmony_ci
37094332d3Sopenharmony_cistatic int32_t UsbFnAdapterOpenFn(void)
38094332d3Sopenharmony_ci{
39094332d3Sopenharmony_ci    int32_t i;
40094332d3Sopenharmony_ci    int32_t ep;
41094332d3Sopenharmony_ci    for (i = 0; i < OPEN_CNT; i++) {
42094332d3Sopenharmony_ci        ep = handle_open("/dev/fconfig");
43094332d3Sopenharmony_ci        if (ep > 0) {
44094332d3Sopenharmony_ci            break;
45094332d3Sopenharmony_ci        }
46094332d3Sopenharmony_ci        usleep(SLEEP_TIME);
47094332d3Sopenharmony_ci    }
48094332d3Sopenharmony_ci    if (ep < 0) {
49094332d3Sopenharmony_ci        HDF_LOGE("func not alloc!");
50094332d3Sopenharmony_ci    }
51094332d3Sopenharmony_ci    return ep;
52094332d3Sopenharmony_ci}
53094332d3Sopenharmony_ci
54094332d3Sopenharmony_cistatic int32_t UsbFnAdapterClosefn(int32_t fd)
55094332d3Sopenharmony_ci{
56094332d3Sopenharmony_ci    if (fd < 0) {
57094332d3Sopenharmony_ci        return HDF_ERR_INVALID_PARAM;
58094332d3Sopenharmony_ci    }
59094332d3Sopenharmony_ci    return handle_close(fd);
60094332d3Sopenharmony_ci}
61094332d3Sopenharmony_ci
62094332d3Sopenharmony_cistatic int32_t UsbFnAdapterCreateFconfigString(struct FconfigString * const configString, const char *name)
63094332d3Sopenharmony_ci{
64094332d3Sopenharmony_ci    if (configString == NULL || name == NULL) {
65094332d3Sopenharmony_ci        HDF_LOGE("%{public}s: configName is NULL", __func__);
66094332d3Sopenharmony_ci        return HDF_ERR_IO;
67094332d3Sopenharmony_ci    }
68094332d3Sopenharmony_ci
69094332d3Sopenharmony_ci    size_t strLen = strlen(name);
70094332d3Sopenharmony_ci    if (strLen >= SIZE_MAX) {
71094332d3Sopenharmony_ci        HDF_LOGE("%{public}s: name length is too long", __func__);
72094332d3Sopenharmony_ci        return HDF_ERR_INVALID_PARAM;
73094332d3Sopenharmony_ci    }
74094332d3Sopenharmony_ci    configString->len = (uint32_t)strLen;
75094332d3Sopenharmony_ci    configString->s = UsbFnMemCalloc(strLen + 1);
76094332d3Sopenharmony_ci    if (configString->s == NULL) {
77094332d3Sopenharmony_ci        HDF_LOGE("%{public}s: UsbFnMemCalloc failed!", __func__);
78094332d3Sopenharmony_ci        return HDF_ERR_MALLOC_FAIL;
79094332d3Sopenharmony_ci    }
80094332d3Sopenharmony_ci
81094332d3Sopenharmony_ci    int32_t ret = memcpy_s(configString->s, (strLen + 1), name, strLen);
82094332d3Sopenharmony_ci    if (ret != EOK) {
83094332d3Sopenharmony_ci        HDF_LOGE("%{public}s: memcpy_s failed!", __func__);
84094332d3Sopenharmony_ci        UsbFnMemFree(configString->s);
85094332d3Sopenharmony_ci        configString->s = NULL;
86094332d3Sopenharmony_ci        return HDF_ERR_MALLOC_FAIL;
87094332d3Sopenharmony_ci    }
88094332d3Sopenharmony_ci
89094332d3Sopenharmony_ci    *(configString->s + configString->len) = '\0';
90094332d3Sopenharmony_ci    return 0;
91094332d3Sopenharmony_ci}
92094332d3Sopenharmony_ci
93094332d3Sopenharmony_cistatic int32_t UsbFnAdapterWriteGadget(int32_t fd, int32_t cmd, struct FconfigString *gadgetName)
94094332d3Sopenharmony_ci{
95094332d3Sopenharmony_ci    int32_t ret;
96094332d3Sopenharmony_ci
97094332d3Sopenharmony_ci    if (gadgetName == NULL) {
98094332d3Sopenharmony_ci        HDF_LOGE("%{public}s: udcName is NULL", __func__);
99094332d3Sopenharmony_ci        return HDF_ERR_IO;
100094332d3Sopenharmony_ci    }
101094332d3Sopenharmony_ci    ret = handle_ioctl(fd, cmd, gadgetName);
102094332d3Sopenharmony_ci    if (ret != 0) {
103094332d3Sopenharmony_ci        HDF_LOGE("%{public}s: ioctl failed!", __func__);
104094332d3Sopenharmony_ci        return HDF_ERR_IO;
105094332d3Sopenharmony_ci    }
106094332d3Sopenharmony_ci    return 0;
107094332d3Sopenharmony_ci}
108094332d3Sopenharmony_ci
109094332d3Sopenharmony_cistatic int32_t UsbFnAdapterWriteDevDesc(
110094332d3Sopenharmony_ci    int32_t fd, struct FconfigString * const gadgetName, const struct UsbFnDeviceDesc * const descriptor)
111094332d3Sopenharmony_ci{
112094332d3Sopenharmony_ci    struct FconfigDevDesc devDesc;
113094332d3Sopenharmony_ci
114094332d3Sopenharmony_ci    if (gadgetName == NULL || descriptor == NULL) {
115094332d3Sopenharmony_ci        HDF_LOGE("%{public}s: udcName is NULL", __func__);
116094332d3Sopenharmony_ci        return HDF_ERR_IO;
117094332d3Sopenharmony_ci    }
118094332d3Sopenharmony_ci
119094332d3Sopenharmony_ci    devDesc.gadgetName.len = gadgetName->len;
120094332d3Sopenharmony_ci    devDesc.gadgetName.s = gadgetName->s;
121094332d3Sopenharmony_ci    int32_t ret = memcpy_s(&devDesc.devDesc, sizeof(devDesc.devDesc), descriptor->deviceDesc, sizeof(devDesc.devDesc));
122094332d3Sopenharmony_ci    if (ret != EOK) {
123094332d3Sopenharmony_ci        HDF_LOGE("%{public}s: memcpy_s failed!", __func__);
124094332d3Sopenharmony_ci        return HDF_ERR_MALLOC_FAIL;
125094332d3Sopenharmony_ci    }
126094332d3Sopenharmony_ci
127094332d3Sopenharmony_ci    ret = handle_ioctl(fd, FCONFIG_CMD_WRITE_DEV_DESC, &devDesc);
128094332d3Sopenharmony_ci    if (ret != 0) {
129094332d3Sopenharmony_ci        HDF_LOGE("%{public}s: ioctl failed!", __func__);
130094332d3Sopenharmony_ci        return HDF_ERR_MALLOC_FAIL;
131094332d3Sopenharmony_ci    }
132094332d3Sopenharmony_ci
133094332d3Sopenharmony_ci    return 0;
134094332d3Sopenharmony_ci}
135094332d3Sopenharmony_ci
136094332d3Sopenharmony_cistatic int32_t UsbFnAdapterWriteDevString(
137094332d3Sopenharmony_ci    int32_t fd, struct FconfigDevStrings * const devStrings, const struct UsbFnStrings * const usbFnString)
138094332d3Sopenharmony_ci{
139094332d3Sopenharmony_ci    struct UsbString *usbString = NULL;
140094332d3Sopenharmony_ci    int32_t jCount;
141094332d3Sopenharmony_ci    int32_t ret;
142094332d3Sopenharmony_ci
143094332d3Sopenharmony_ci    devStrings->language = usbFnString->language;
144094332d3Sopenharmony_ci    devStrings->strCount = 0;
145094332d3Sopenharmony_ci    usbString = usbFnString->strings;
146094332d3Sopenharmony_ci    while (usbString->s) {
147094332d3Sopenharmony_ci        devStrings->strCount++;
148094332d3Sopenharmony_ci        usbString++;
149094332d3Sopenharmony_ci    }
150094332d3Sopenharmony_ci    devStrings->strings = UsbFnMemCalloc((devStrings->strCount + 1) * sizeof(struct FconfigUsbString));
151094332d3Sopenharmony_ci    if (devStrings->strings == NULL) {
152094332d3Sopenharmony_ci        HDF_LOGE("%{public}s: UsbFnMemCalloc failed!", __func__);
153094332d3Sopenharmony_ci        return HDF_ERR_MALLOC_FAIL;
154094332d3Sopenharmony_ci    }
155094332d3Sopenharmony_ci    devStrings->strings[devStrings->strCount].str.len = 0;
156094332d3Sopenharmony_ci    devStrings->strings[devStrings->strCount].str.s = NULL;
157094332d3Sopenharmony_ci    usbString = usbFnString->strings;
158094332d3Sopenharmony_ci    for (jCount = 0; jCount < (int)devStrings->strCount; jCount++) {
159094332d3Sopenharmony_ci        devStrings->strings[jCount].id = usbString[jCount].id;
160094332d3Sopenharmony_ci        ret = UsbFnAdapterCreateFconfigString(&devStrings->strings[jCount].str, usbString[jCount].s);
161094332d3Sopenharmony_ci        if (ret != HDF_SUCCESS) {
162094332d3Sopenharmony_ci            HDF_LOGE("%{public}s: create string failed!", __func__);
163094332d3Sopenharmony_ci            UsbFnMemFree(devStrings->strings[jCount].str.s);
164094332d3Sopenharmony_ci            goto FAIL;
165094332d3Sopenharmony_ci        }
166094332d3Sopenharmony_ci    }
167094332d3Sopenharmony_ci    ret = handle_ioctl(fd, FCONFIG_CMD_WRITE_STRINGS, devStrings);
168094332d3Sopenharmony_ci    if (ret != 0) {
169094332d3Sopenharmony_ci        HDF_LOGE("%{public}s: ioctl failed!", __func__);
170094332d3Sopenharmony_ci        goto FAIL;
171094332d3Sopenharmony_ci    }
172094332d3Sopenharmony_ci    for (jCount = 0; jCount < (int)devStrings->strCount; jCount++) {
173094332d3Sopenharmony_ci        UsbFnMemFree(devStrings->strings[jCount].str.s);
174094332d3Sopenharmony_ci    }
175094332d3Sopenharmony_ci    UsbFnMemFree(devStrings->strings);
176094332d3Sopenharmony_ci    return 0;
177094332d3Sopenharmony_ciFAIL:
178094332d3Sopenharmony_ci    while ((--jCount) >= 0) {
179094332d3Sopenharmony_ci        UsbFnMemFree(devStrings->strings[jCount].str.s);
180094332d3Sopenharmony_ci    }
181094332d3Sopenharmony_ci    UsbFnMemFree(devStrings->strings);
182094332d3Sopenharmony_ci    return -1;
183094332d3Sopenharmony_ci}
184094332d3Sopenharmony_ci
185094332d3Sopenharmony_cistatic int32_t UsbFnAdapterWriteDevStrings(
186094332d3Sopenharmony_ci    int32_t fd, struct FconfigString * const gadgetName, const struct UsbFnDeviceDesc *descriptor)
187094332d3Sopenharmony_ci{
188094332d3Sopenharmony_ci    if (gadgetName == NULL || descriptor == NULL) {
189094332d3Sopenharmony_ci        HDF_LOGE("%{public}s: udcName is NULL", __func__);
190094332d3Sopenharmony_ci        return HDF_ERR_IO;
191094332d3Sopenharmony_ci    }
192094332d3Sopenharmony_ci
193094332d3Sopenharmony_ci    struct FconfigDevStrings devStrings;
194094332d3Sopenharmony_ci    devStrings.gadgetName.len = gadgetName->len;
195094332d3Sopenharmony_ci    devStrings.gadgetName.s = gadgetName->s;
196094332d3Sopenharmony_ci    for (uint32_t iCount = 0; descriptor->deviceStrings[iCount]; iCount++) {
197094332d3Sopenharmony_ci        int32_t ret = UsbFnAdapterWriteDevString(fd, &devStrings, descriptor->deviceStrings[iCount]);
198094332d3Sopenharmony_ci        if (ret != 0) {
199094332d3Sopenharmony_ci            HDF_LOGE("%{public}s: UsbFnAdapterWriteDevString failed", __func__);
200094332d3Sopenharmony_ci            return HDF_ERR_IO;
201094332d3Sopenharmony_ci        }
202094332d3Sopenharmony_ci    }
203094332d3Sopenharmony_ci    return 0;
204094332d3Sopenharmony_ci}
205094332d3Sopenharmony_ci
206094332d3Sopenharmony_cistatic int32_t UsbFnAdapterFillConfigDesc(
207094332d3Sopenharmony_ci    struct UsbConfigDescriptor * const cfgDesc, struct UsbFnConfiguration * const usbFnConfig)
208094332d3Sopenharmony_ci{
209094332d3Sopenharmony_ci    if (cfgDesc == NULL || usbFnConfig == NULL) {
210094332d3Sopenharmony_ci        HDF_LOGE("%{public}s: name is NULL", __func__);
211094332d3Sopenharmony_ci        return HDF_ERR_IO;
212094332d3Sopenharmony_ci    }
213094332d3Sopenharmony_ci    cfgDesc->bConfigurationValue = usbFnConfig->configurationValue;
214094332d3Sopenharmony_ci    cfgDesc->bmAttributes = usbFnConfig->attributes;
215094332d3Sopenharmony_ci    cfgDesc->bMaxPower = usbFnConfig->maxPower;
216094332d3Sopenharmony_ci    cfgDesc->iConfiguration = usbFnConfig->iConfiguration;
217094332d3Sopenharmony_ci    return 0;
218094332d3Sopenharmony_ci}
219094332d3Sopenharmony_ci
220094332d3Sopenharmony_cistatic int32_t UsbFnAdapterOpenPipe(const char *funcName, int32_t epIndex)
221094332d3Sopenharmony_ci{
222094332d3Sopenharmony_ci    int32_t ret;
223094332d3Sopenharmony_ci    char epName[MAX_NAMELEN];
224094332d3Sopenharmony_ci    const char *pName = &epName[0];
225094332d3Sopenharmony_ci    int32_t i;
226094332d3Sopenharmony_ci    int32_t ep;
227094332d3Sopenharmony_ci    if (funcName == NULL || epIndex < 0) {
228094332d3Sopenharmony_ci        return HDF_ERR_INVALID_PARAM;
229094332d3Sopenharmony_ci    }
230094332d3Sopenharmony_ci
231094332d3Sopenharmony_ci    ret = snprintf_s(epName, MAX_NAMELEN, MAX_NAMELEN - 1, "/dev/%s/ep%d", funcName, epIndex);
232094332d3Sopenharmony_ci    if (ret < 0) {
233094332d3Sopenharmony_ci        HDF_LOGE("%{public}s: snprintf_s failed", __func__);
234094332d3Sopenharmony_ci        return HDF_ERR_IO;
235094332d3Sopenharmony_ci    }
236094332d3Sopenharmony_ci
237094332d3Sopenharmony_ci    for (i = 0; i < OPEN_CNT; i++) {
238094332d3Sopenharmony_ci        ep = handle_open(pName);
239094332d3Sopenharmony_ci        if (ep > 0) {
240094332d3Sopenharmony_ci            break;
241094332d3Sopenharmony_ci        }
242094332d3Sopenharmony_ci        usleep(SLEEP_TIME);
243094332d3Sopenharmony_ci    }
244094332d3Sopenharmony_ci    if (ep < 0) {
245094332d3Sopenharmony_ci        HDF_LOGE("unable to open %{public}s", epName);
246094332d3Sopenharmony_ci        return HDF_ERR_IO;
247094332d3Sopenharmony_ci    }
248094332d3Sopenharmony_ci    return ep;
249094332d3Sopenharmony_ci}
250094332d3Sopenharmony_ci
251094332d3Sopenharmony_cistatic int32_t UsbFnAdapterClosePipe(int32_t ep)
252094332d3Sopenharmony_ci{
253094332d3Sopenharmony_ci    if (ep < 0) {
254094332d3Sopenharmony_ci        return HDF_ERR_INVALID_PARAM;
255094332d3Sopenharmony_ci    }
256094332d3Sopenharmony_ci
257094332d3Sopenharmony_ci    return handle_close(ep);
258094332d3Sopenharmony_ci}
259094332d3Sopenharmony_ci
260094332d3Sopenharmony_cistatic void GetHeaderStr(struct UsbFnStrings ** const strings, struct UsbFunctionfsStringsHead *headerStr)
261094332d3Sopenharmony_ci{
262094332d3Sopenharmony_ci    uint32_t i, j;
263094332d3Sopenharmony_ci    uint32_t langCount = 0;
264094332d3Sopenharmony_ci    uint32_t strCount = 0;
265094332d3Sopenharmony_ci    uint32_t len = 0;
266094332d3Sopenharmony_ci    for (i = 0; strings[i] != NULL; i++) {
267094332d3Sopenharmony_ci        langCount++;
268094332d3Sopenharmony_ci        for (j = 0; strings[i]->strings[j].s; j++) {
269094332d3Sopenharmony_ci            len += strlen(strings[i]->strings[j].s) + sizeof(char);
270094332d3Sopenharmony_ci        }
271094332d3Sopenharmony_ci        strCount = j;
272094332d3Sopenharmony_ci    }
273094332d3Sopenharmony_ci    headerStr->magic = htole32(FUNCTIONFS_STRINGS_MAGIC);
274094332d3Sopenharmony_ci    headerStr->length = htole32(sizeof(struct UsbFunctionfsStringsHead) + langCount * sizeof(uint16_t) + len);
275094332d3Sopenharmony_ci    headerStr->strCount = strCount;
276094332d3Sopenharmony_ci    headerStr->langCount = langCount;
277094332d3Sopenharmony_ci}
278094332d3Sopenharmony_ci
279094332d3Sopenharmony_cistatic int32_t UsbFnWriteStrings(int32_t ep0, struct UsbFnStrings ** const strings)
280094332d3Sopenharmony_ci{
281094332d3Sopenharmony_ci    uint8_t *str = NULL;
282094332d3Sopenharmony_ci    uint8_t *whereDec = NULL;
283094332d3Sopenharmony_ci    uint32_t i, j;
284094332d3Sopenharmony_ci    int32_t ret;
285094332d3Sopenharmony_ci    struct UsbFunctionfsStringsHead headerStr = {0};
286094332d3Sopenharmony_ci
287094332d3Sopenharmony_ci    GetHeaderStr(strings, &headerStr);
288094332d3Sopenharmony_ci    str = UsbFnMemCalloc(headerStr.length);
289094332d3Sopenharmony_ci    if (str == NULL) {
290094332d3Sopenharmony_ci        return HDF_ERR_MALLOC_FAIL;
291094332d3Sopenharmony_ci    }
292094332d3Sopenharmony_ci
293094332d3Sopenharmony_ci    whereDec = str;
294094332d3Sopenharmony_ci    ret = memcpy_s(whereDec, headerStr.length, &headerStr, sizeof(struct UsbFunctionfsStringsHead));
295094332d3Sopenharmony_ci    if (ret != EOK) {
296094332d3Sopenharmony_ci        goto ERR;
297094332d3Sopenharmony_ci    }
298094332d3Sopenharmony_ci    whereDec += sizeof(struct UsbFunctionfsStringsHead);
299094332d3Sopenharmony_ci
300094332d3Sopenharmony_ci    for (i = 0; i < headerStr.langCount; i++) {
301094332d3Sopenharmony_ci        ret = memcpy_s(whereDec, headerStr.length - (whereDec - str), &strings[i]->language, sizeof(uint16_t));
302094332d3Sopenharmony_ci        if (ret != EOK) {
303094332d3Sopenharmony_ci            goto ERR;
304094332d3Sopenharmony_ci        }
305094332d3Sopenharmony_ci        whereDec += sizeof(uint16_t);
306094332d3Sopenharmony_ci        for (j = 0; j < headerStr.strCount; j++) {
307094332d3Sopenharmony_ci            if (strlen(strings[i]->strings[j].s)) {
308094332d3Sopenharmony_ci                ret = memcpy_s(whereDec, headerStr.length - (whereDec - str), strings[i]->strings[j].s,
309094332d3Sopenharmony_ci                    strlen(strings[i]->strings[j].s));
310094332d3Sopenharmony_ci                whereDec += strlen(strings[i]->strings[j].s) + sizeof(char);
311094332d3Sopenharmony_ci            } else {
312094332d3Sopenharmony_ci                break;
313094332d3Sopenharmony_ci            }
314094332d3Sopenharmony_ci            if (ret != EOK) {
315094332d3Sopenharmony_ci                goto ERR;
316094332d3Sopenharmony_ci            }
317094332d3Sopenharmony_ci        }
318094332d3Sopenharmony_ci    }
319094332d3Sopenharmony_ci
320094332d3Sopenharmony_ci    if (handle_write(ep0, str, headerStr.length) < 0) {
321094332d3Sopenharmony_ci        goto ERR;
322094332d3Sopenharmony_ci    }
323094332d3Sopenharmony_ci    UsbFnMemFree(str);
324094332d3Sopenharmony_ci    return 0;
325094332d3Sopenharmony_ciERR:
326094332d3Sopenharmony_ci    UsbFnMemFree(str);
327094332d3Sopenharmony_ci    return HDF_FAILURE;
328094332d3Sopenharmony_ci}
329094332d3Sopenharmony_ci
330094332d3Sopenharmony_cistatic void GetCountAndHead(struct UsbFunctionfsDescsHeadV2 *header, uint32_t *fsCount, uint32_t *hsCount,
331094332d3Sopenharmony_ci    uint32_t *ssCount, const struct UsbFnFunction *func)
332094332d3Sopenharmony_ci{
333094332d3Sopenharmony_ci    int32_t i;
334094332d3Sopenharmony_ci    uint32_t lenCount = 0;
335094332d3Sopenharmony_ci    uint32_t lenDes = 0;
336094332d3Sopenharmony_ci    *fsCount = 0;
337094332d3Sopenharmony_ci    *hsCount = 0;
338094332d3Sopenharmony_ci    *ssCount = 0;
339094332d3Sopenharmony_ci
340094332d3Sopenharmony_ci    for (i = 0; func->fsDescriptors[i] != NULL; i++) {
341094332d3Sopenharmony_ci        (*fsCount)++;
342094332d3Sopenharmony_ci        lenDes += func->fsDescriptors[i]->bLength;
343094332d3Sopenharmony_ci    }
344094332d3Sopenharmony_ci    for (i = 0; func->hsDescriptors[i] != NULL; i++) {
345094332d3Sopenharmony_ci        (*hsCount)++;
346094332d3Sopenharmony_ci        lenDes += func->hsDescriptors[i]->bLength;
347094332d3Sopenharmony_ci    }
348094332d3Sopenharmony_ci    for (i = 0; func->ssDescriptors[i] != NULL; i++) {
349094332d3Sopenharmony_ci        (*ssCount)++;
350094332d3Sopenharmony_ci        lenDes += func->ssDescriptors[i]->bLength;
351094332d3Sopenharmony_ci    }
352094332d3Sopenharmony_ci
353094332d3Sopenharmony_ci    if (*fsCount) {
354094332d3Sopenharmony_ci        lenCount += sizeof(uint32_t);
355094332d3Sopenharmony_ci        header->flags |= htole32(FUNCTIONFS_HAS_FS_DESC);
356094332d3Sopenharmony_ci    }
357094332d3Sopenharmony_ci    if (*hsCount) {
358094332d3Sopenharmony_ci        lenCount += sizeof(uint32_t);
359094332d3Sopenharmony_ci        header->flags |= htole32(FUNCTIONFS_HAS_HS_DESC);
360094332d3Sopenharmony_ci    }
361094332d3Sopenharmony_ci    if (*ssCount) {
362094332d3Sopenharmony_ci        lenCount += sizeof(uint32_t);
363094332d3Sopenharmony_ci        header->flags |= htole32(FUNCTIONFS_HAS_SS_DESC);
364094332d3Sopenharmony_ci    }
365094332d3Sopenharmony_ci
366094332d3Sopenharmony_ci    header->magic = htole32(FUNCTIONFS_DESCRIPTORS_MAGIC_V2);
367094332d3Sopenharmony_ci    header->length = htole32(sizeof(struct UsbFunctionfsDescsHeadV2) + lenCount + lenDes);
368094332d3Sopenharmony_ci}
369094332d3Sopenharmony_ci
370094332d3Sopenharmony_cistatic int32_t WriteFuncDescriptors(uint8_t ** const whereDec, struct UsbDescriptorHeader ** const headDes)
371094332d3Sopenharmony_ci{
372094332d3Sopenharmony_ci    for (uint32_t i = 0; headDes[i] != NULL; i++) {
373094332d3Sopenharmony_ci        if (memcpy_s(*whereDec, headDes[i]->bLength, headDes[i], headDes[i]->bLength) != EOK) {
374094332d3Sopenharmony_ci            HDF_LOGE("%{public}s: memcpy_s failed!", __func__);
375094332d3Sopenharmony_ci            return HDF_FAILURE;
376094332d3Sopenharmony_ci        }
377094332d3Sopenharmony_ci        *whereDec += headDes[i]->bLength;
378094332d3Sopenharmony_ci    }
379094332d3Sopenharmony_ci    return 0;
380094332d3Sopenharmony_ci}
381094332d3Sopenharmony_ci
382094332d3Sopenharmony_cistatic int32_t CopyCount(uint8_t **whereDec, uint32_t fsCount, uint32_t hsCount, uint32_t ssCount)
383094332d3Sopenharmony_ci{
384094332d3Sopenharmony_ci    int32_t ret;
385094332d3Sopenharmony_ci    if (fsCount) {
386094332d3Sopenharmony_ci        ret = memcpy_s(*whereDec, sizeof(uint32_t), &fsCount, sizeof(uint32_t));
387094332d3Sopenharmony_ci        if (ret != EOK) {
388094332d3Sopenharmony_ci            return HDF_FAILURE;
389094332d3Sopenharmony_ci        }
390094332d3Sopenharmony_ci        *whereDec += sizeof(uint32_t);
391094332d3Sopenharmony_ci    }
392094332d3Sopenharmony_ci    if (hsCount) {
393094332d3Sopenharmony_ci        ret = memcpy_s(*whereDec, sizeof(uint32_t), &hsCount, sizeof(uint32_t));
394094332d3Sopenharmony_ci        if (ret != EOK) {
395094332d3Sopenharmony_ci            return HDF_FAILURE;
396094332d3Sopenharmony_ci        }
397094332d3Sopenharmony_ci        *whereDec += sizeof(uint32_t);
398094332d3Sopenharmony_ci    }
399094332d3Sopenharmony_ci    if (ssCount) {
400094332d3Sopenharmony_ci        ret = memcpy_s(*whereDec, sizeof(uint32_t), &ssCount, sizeof(uint32_t));
401094332d3Sopenharmony_ci        if (ret != EOK) {
402094332d3Sopenharmony_ci            return HDF_FAILURE;
403094332d3Sopenharmony_ci        }
404094332d3Sopenharmony_ci        *whereDec += sizeof(uint32_t);
405094332d3Sopenharmony_ci    }
406094332d3Sopenharmony_ci
407094332d3Sopenharmony_ci    return 0;
408094332d3Sopenharmony_ci}
409094332d3Sopenharmony_ci
410094332d3Sopenharmony_cistatic int32_t UsbFnAdapterCreatPipes(int32_t ep0, const struct UsbFnFunction *func)
411094332d3Sopenharmony_ci{
412094332d3Sopenharmony_ci    uint8_t *dec = NULL;
413094332d3Sopenharmony_ci    uint8_t *whereDec = NULL;
414094332d3Sopenharmony_ci    int32_t ret;
415094332d3Sopenharmony_ci    uint32_t fsCount;
416094332d3Sopenharmony_ci    uint32_t hsCount;
417094332d3Sopenharmony_ci    uint32_t ssCount;
418094332d3Sopenharmony_ci    struct UsbFunctionfsDescsHeadV2 header = {0};
419094332d3Sopenharmony_ci
420094332d3Sopenharmony_ci    GetCountAndHead(&header, &fsCount, &hsCount, &ssCount, func);
421094332d3Sopenharmony_ci
422094332d3Sopenharmony_ci    dec = UsbFnMemCalloc(header.length);
423094332d3Sopenharmony_ci    if (dec == NULL) {
424094332d3Sopenharmony_ci        HDF_LOGE("%{public}s: UsbFnMemCalloc failed!", __func__);
425094332d3Sopenharmony_ci        return HDF_ERR_MALLOC_FAIL;
426094332d3Sopenharmony_ci    }
427094332d3Sopenharmony_ci    whereDec = dec;
428094332d3Sopenharmony_ci
429094332d3Sopenharmony_ci    ret = memcpy_s(whereDec, header.length, &header, sizeof(struct UsbFunctionfsDescsHeadV2));
430094332d3Sopenharmony_ci    if (ret != EOK) {
431094332d3Sopenharmony_ci        UsbFnMemFree(dec);
432094332d3Sopenharmony_ci        return HDF_FAILURE;
433094332d3Sopenharmony_ci    }
434094332d3Sopenharmony_ci    whereDec += sizeof(struct UsbFunctionfsDescsHeadV2);
435094332d3Sopenharmony_ci
436094332d3Sopenharmony_ci    ret = CopyCount(&whereDec, fsCount, hsCount, ssCount);
437094332d3Sopenharmony_ci    if (ret != EOK) {
438094332d3Sopenharmony_ci        UsbFnMemFree(dec);
439094332d3Sopenharmony_ci        return HDF_FAILURE;
440094332d3Sopenharmony_ci    }
441094332d3Sopenharmony_ci
442094332d3Sopenharmony_ci    ret = WriteFuncDescriptors(&whereDec, func->fsDescriptors);
443094332d3Sopenharmony_ci    if (ret != EOK) {
444094332d3Sopenharmony_ci        UsbFnMemFree(dec);
445094332d3Sopenharmony_ci        return HDF_FAILURE;
446094332d3Sopenharmony_ci    }
447094332d3Sopenharmony_ci
448094332d3Sopenharmony_ci    ret = WriteFuncDescriptors(&whereDec, func->hsDescriptors);
449094332d3Sopenharmony_ci    if (ret != EOK) {
450094332d3Sopenharmony_ci        UsbFnMemFree(dec);
451094332d3Sopenharmony_ci        return HDF_FAILURE;
452094332d3Sopenharmony_ci    }
453094332d3Sopenharmony_ci
454094332d3Sopenharmony_ci    ret = WriteFuncDescriptors(&whereDec, func->ssDescriptors);
455094332d3Sopenharmony_ci    if (ret != EOK) {
456094332d3Sopenharmony_ci        UsbFnMemFree(dec);
457094332d3Sopenharmony_ci        return HDF_FAILURE;
458094332d3Sopenharmony_ci    }
459094332d3Sopenharmony_ci
460094332d3Sopenharmony_ci    if (handle_write(ep0, dec, header.length) < 0) {
461094332d3Sopenharmony_ci        HDF_LOGE("unable do write descriptors");
462094332d3Sopenharmony_ci        UsbFnMemFree(dec);
463094332d3Sopenharmony_ci        return HDF_ERR_IO;
464094332d3Sopenharmony_ci    }
465094332d3Sopenharmony_ci
466094332d3Sopenharmony_ci    UsbFnMemFree(dec);
467094332d3Sopenharmony_ci    ret = UsbFnWriteStrings(ep0, func->strings);
468094332d3Sopenharmony_ci    return ret;
469094332d3Sopenharmony_ci}
470094332d3Sopenharmony_ci
471094332d3Sopenharmony_civoid UsbFnAdapterPipeCreateAndClose(int32_t fdEp0, struct UsbFnConfiguration * const usbFnConfig, int32_t iCount)
472094332d3Sopenharmony_ci{
473094332d3Sopenharmony_ci    if (UsbFnAdapterCreatPipes(fdEp0, usbFnConfig->functions[iCount]) != HDF_SUCCESS) {
474094332d3Sopenharmony_ci        goto FAIL2;
475094332d3Sopenharmony_ci    }
476094332d3Sopenharmony_ci
477094332d3Sopenharmony_ci    if (UsbFnAdapterClosePipe(fdEp0) != HDF_SUCCESS) {
478094332d3Sopenharmony_ci        goto FAIL2;
479094332d3Sopenharmony_ci    }
480094332d3Sopenharmony_ciFAIL2:
481094332d3Sopenharmony_ci    UsbFnAdapterClosePipe(fdEp0);
482094332d3Sopenharmony_ci}
483094332d3Sopenharmony_ci
484094332d3Sopenharmony_cistatic int32_t UsbFnAdapterWriteFunctions(int32_t fd, struct UsbFnConfiguration * const usbFnConfig, int32_t cmd,
485094332d3Sopenharmony_ci    struct FconfigString * const gadgetName, struct FconfigString * const configName)
486094332d3Sopenharmony_ci{
487094332d3Sopenharmony_ci    if (usbFnConfig == NULL || gadgetName == NULL || configName == NULL) {
488094332d3Sopenharmony_ci        HDF_LOGE("%{public}s: usbFnConfig is NULL", __func__);
489094332d3Sopenharmony_ci        return HDF_ERR_IO;
490094332d3Sopenharmony_ci    }
491094332d3Sopenharmony_ci
492094332d3Sopenharmony_ci    int32_t fdEp0;
493094332d3Sopenharmony_ci    struct FconfigFuncInfo funcInfo;
494094332d3Sopenharmony_ci    funcInfo.gadgetName.len = gadgetName->len;
495094332d3Sopenharmony_ci    funcInfo.gadgetName.s = gadgetName->s;
496094332d3Sopenharmony_ci    funcInfo.configName.len = configName->len;
497094332d3Sopenharmony_ci    funcInfo.configName.s = configName->s;
498094332d3Sopenharmony_ci    for (uint32_t iCount = 0; usbFnConfig->functions[iCount] != NULL; iCount++) {
499094332d3Sopenharmony_ci        char tmp[MAX_PATHLEN];
500094332d3Sopenharmony_ci        if (memset_s(tmp, MAX_PATHLEN, 0, MAX_PATHLEN) != EOK) {
501094332d3Sopenharmony_ci            HDF_LOGE("%{public}s:%{public}d memset_s failed", __func__, __LINE__);
502094332d3Sopenharmony_ci            return HDF_FAILURE;
503094332d3Sopenharmony_ci        }
504094332d3Sopenharmony_ci        int32_t ret =
505094332d3Sopenharmony_ci            snprintf_s(tmp, MAX_PATHLEN, MAX_PATHLEN - 1, "generic.%s", usbFnConfig->functions[iCount]->funcName);
506094332d3Sopenharmony_ci        if (ret < 0) {
507094332d3Sopenharmony_ci            return HDF_ERR_IO;
508094332d3Sopenharmony_ci        }
509094332d3Sopenharmony_ci        ret = UsbFnAdapterCreateFconfigString(&funcInfo.funcName, tmp);
510094332d3Sopenharmony_ci        if (ret != HDF_SUCCESS) {
511094332d3Sopenharmony_ci            return HDF_ERR_MALLOC_FAIL;
512094332d3Sopenharmony_ci        }
513094332d3Sopenharmony_ci        if (handle_ioctl(fd, cmd, &funcInfo) != 0) {
514094332d3Sopenharmony_ci            goto FAIL;
515094332d3Sopenharmony_ci        }
516094332d3Sopenharmony_ci        UsbFnMemFree(funcInfo.funcName.s);
517094332d3Sopenharmony_ci        if (cmd == FCONFIG_CMD_DROP_FUNCTION) {
518094332d3Sopenharmony_ci            continue;
519094332d3Sopenharmony_ci        }
520094332d3Sopenharmony_ci
521094332d3Sopenharmony_ci        fdEp0 = UsbFnAdapterOpenPipe(usbFnConfig->functions[iCount]->funcName, 0);
522094332d3Sopenharmony_ci        if (fd < 0) {
523094332d3Sopenharmony_ci            goto FAIL;
524094332d3Sopenharmony_ci        }
525094332d3Sopenharmony_ci        UsbFnAdapterPipeCreateAndClose(fdEp0, usbFnConfig, iCount);
526094332d3Sopenharmony_ci    }
527094332d3Sopenharmony_ci    return 0;
528094332d3Sopenharmony_ciFAIL:
529094332d3Sopenharmony_ci    UsbFnMemFree(funcInfo.funcName.s);
530094332d3Sopenharmony_ci    return -1;
531094332d3Sopenharmony_ci}
532094332d3Sopenharmony_ci
533094332d3Sopenharmony_cistatic int32_t UsbFnAdapterWriteConfigs(
534094332d3Sopenharmony_ci    int32_t fd, struct FconfigString * const gadgetName, const struct UsbFnDeviceDesc * const descriptor)
535094332d3Sopenharmony_ci{
536094332d3Sopenharmony_ci    struct FconfigCfgDesc configDesc;
537094332d3Sopenharmony_ci    char tmp[MAX_PATHLEN];
538094332d3Sopenharmony_ci
539094332d3Sopenharmony_ci    if (gadgetName == NULL || descriptor == NULL || descriptor->configs == NULL) {
540094332d3Sopenharmony_ci        HDF_LOGE("%{public}s: name is NULL", __func__);
541094332d3Sopenharmony_ci        return HDF_ERR_IO;
542094332d3Sopenharmony_ci    }
543094332d3Sopenharmony_ci    for (uint32_t iCount = 0; descriptor->configs[iCount]; iCount++) {
544094332d3Sopenharmony_ci        configDesc.gadgetName.len = gadgetName->len;
545094332d3Sopenharmony_ci        configDesc.gadgetName.s = gadgetName->s;
546094332d3Sopenharmony_ci        uint8_t confVal = descriptor->configs[iCount]->configurationValue;
547094332d3Sopenharmony_ci        if (memset_s(tmp, MAX_PATHLEN, 0, MAX_PATHLEN) != EOK) {
548094332d3Sopenharmony_ci            HDF_LOGE("%{public}s:%{public}d memset_s failed", __func__, __LINE__);
549094332d3Sopenharmony_ci            return HDF_FAILURE;
550094332d3Sopenharmony_ci        }
551094332d3Sopenharmony_ci        int32_t ret = snprintf_s(tmp, MAX_PATHLEN, MAX_PATHLEN - 1, "b.%u", confVal);
552094332d3Sopenharmony_ci        if (ret < 0) {
553094332d3Sopenharmony_ci            return HDF_ERR_IO;
554094332d3Sopenharmony_ci        }
555094332d3Sopenharmony_ci        ret = UsbFnAdapterCreateFconfigString(&configDesc.configName, tmp);
556094332d3Sopenharmony_ci        if (ret != HDF_SUCCESS) {
557094332d3Sopenharmony_ci            HDF_LOGE("%{public}s: create config name failed!", __func__);
558094332d3Sopenharmony_ci            return HDF_ERR_MALLOC_FAIL;
559094332d3Sopenharmony_ci        }
560094332d3Sopenharmony_ci        ret = UsbFnAdapterFillConfigDesc(&configDesc.cfgDesc, descriptor->configs[iCount]);
561094332d3Sopenharmony_ci        if (ret != HDF_SUCCESS) {
562094332d3Sopenharmony_ci            HDF_LOGE("%{public}s: UsbFnMemCalloc failed!", __func__);
563094332d3Sopenharmony_ci            return HDF_ERR_MALLOC_FAIL;
564094332d3Sopenharmony_ci        }
565094332d3Sopenharmony_ci        ret = handle_ioctl(fd, FCONFIG_CMD_ADD_CONFIG, &configDesc);
566094332d3Sopenharmony_ci        if (ret != HDF_SUCCESS) {
567094332d3Sopenharmony_ci            HDF_LOGE("%{public}s: ioctl failed!", __func__);
568094332d3Sopenharmony_ci            return HDF_ERR_MALLOC_FAIL;
569094332d3Sopenharmony_ci        }
570094332d3Sopenharmony_ci        ret = UsbFnAdapterWriteFunctions(
571094332d3Sopenharmony_ci            fd, descriptor->configs[iCount], FCONFIG_CMD_MAKE_FUNCTION, gadgetName, &configDesc.configName);
572094332d3Sopenharmony_ci        if (ret != HDF_SUCCESS) {
573094332d3Sopenharmony_ci            HDF_LOGE("%{public}s: write func failed!", __func__);
574094332d3Sopenharmony_ci            return HDF_ERR_MALLOC_FAIL;
575094332d3Sopenharmony_ci        }
576094332d3Sopenharmony_ci        UsbFnMemFree(configDesc.configName.s);
577094332d3Sopenharmony_ci    }
578094332d3Sopenharmony_ci    return 0;
579094332d3Sopenharmony_ci}
580094332d3Sopenharmony_ci
581094332d3Sopenharmony_cistatic int32_t UsbFnAdapterWriteFcofnigUDC(
582094332d3Sopenharmony_ci    int32_t fd, int32_t cmd, struct FconfigString * const gadgetName, const char *udcName)
583094332d3Sopenharmony_ci{
584094332d3Sopenharmony_ci    int32_t ret;
585094332d3Sopenharmony_ci    struct FconfigUdcInfo udcInfo;
586094332d3Sopenharmony_ci
587094332d3Sopenharmony_ci    if (gadgetName == NULL || udcName == NULL) {
588094332d3Sopenharmony_ci        return HDF_ERR_INVALID_PARAM;
589094332d3Sopenharmony_ci    }
590094332d3Sopenharmony_ci    udcInfo.gadgetName.len = gadgetName->len;
591094332d3Sopenharmony_ci    udcInfo.gadgetName.s = gadgetName->s;
592094332d3Sopenharmony_ci    ret = UsbFnAdapterCreateFconfigString(&udcInfo.udcName, udcName);
593094332d3Sopenharmony_ci    if (ret != HDF_SUCCESS) {
594094332d3Sopenharmony_ci        HDF_LOGE("%{public}s: create udc_name failed!", __func__);
595094332d3Sopenharmony_ci        return HDF_ERR_IO;
596094332d3Sopenharmony_ci    }
597094332d3Sopenharmony_ci    ret = handle_ioctl(fd, cmd, &udcInfo);
598094332d3Sopenharmony_ci    if (ret != 0) {
599094332d3Sopenharmony_ci        HDF_LOGE("%{public}s: ioctl failed!", __func__);
600094332d3Sopenharmony_ci    }
601094332d3Sopenharmony_ci    UsbFnMemFree(udcInfo.udcName.s);
602094332d3Sopenharmony_ci
603094332d3Sopenharmony_ci    return ret;
604094332d3Sopenharmony_ci}
605094332d3Sopenharmony_ci
606094332d3Sopenharmony_cistatic int32_t UsbFnAdapterCreateDevice(const char *udcName, const char *devName, struct UsbFnDeviceDesc *descriptor)
607094332d3Sopenharmony_ci{
608094332d3Sopenharmony_ci    int32_t fd;
609094332d3Sopenharmony_ci    int32_t ret;
610094332d3Sopenharmony_ci    struct FconfigString gadgetName;
611094332d3Sopenharmony_ci
612094332d3Sopenharmony_ci    fd = UsbFnAdapterOpenFn();
613094332d3Sopenharmony_ci    if (fd < 0) {
614094332d3Sopenharmony_ci        return HDF_ERR_IO;
615094332d3Sopenharmony_ci    }
616094332d3Sopenharmony_ci    ret = UsbFnAdapterCreateFconfigString(&gadgetName, devName);
617094332d3Sopenharmony_ci    if (ret != HDF_SUCCESS) {
618094332d3Sopenharmony_ci        HDF_LOGE("%{public}s: create gadget name failed!", __func__);
619094332d3Sopenharmony_ci        goto FAIL;
620094332d3Sopenharmony_ci    }
621094332d3Sopenharmony_ci    ret = UsbFnAdapterWriteGadget(fd, FCONFIG_CMD_MAKE_GADGET, &gadgetName);
622094332d3Sopenharmony_ci    if (ret != HDF_SUCCESS) {
623094332d3Sopenharmony_ci        dprintf("%s: UsbFnAdapterWriteGadget failed!", __func__);
624094332d3Sopenharmony_ci        goto EXIT;
625094332d3Sopenharmony_ci    }
626094332d3Sopenharmony_ci    ret = UsbFnAdapterWriteDevDesc(fd, &gadgetName, descriptor);
627094332d3Sopenharmony_ci    if (ret != HDF_SUCCESS) {
628094332d3Sopenharmony_ci        dprintf("%s: UsbFnAdapterWriteDevDesc failed!", __func__);
629094332d3Sopenharmony_ci        goto EXIT;
630094332d3Sopenharmony_ci    }
631094332d3Sopenharmony_ci    ret = UsbFnAdapterWriteDevStrings(fd, &gadgetName, descriptor);
632094332d3Sopenharmony_ci    if (ret != HDF_SUCCESS) {
633094332d3Sopenharmony_ci        dprintf("%s: UsbFnAdapterWriteDevStrings failed!", __func__);
634094332d3Sopenharmony_ci        goto EXIT;
635094332d3Sopenharmony_ci    }
636094332d3Sopenharmony_ci    ret = UsbFnAdapterWriteConfigs(fd, &gadgetName, descriptor);
637094332d3Sopenharmony_ci    if (ret != HDF_SUCCESS) {
638094332d3Sopenharmony_ci        dprintf("%s: UsbFnAdapterWriteConfigs failed!", __func__);
639094332d3Sopenharmony_ci        goto EXIT;
640094332d3Sopenharmony_ci    }
641094332d3Sopenharmony_ci    ret = UsbFnAdapterWriteFcofnigUDC(fd, FCONFIG_CMD_ENABLE_UDC, &gadgetName, udcName);
642094332d3Sopenharmony_ci    if (ret != HDF_SUCCESS) {
643094332d3Sopenharmony_ci        dprintf("%s: UsbFnAdapterWriteFcofnigUDC failed!", __func__);
644094332d3Sopenharmony_ci        goto EXIT;
645094332d3Sopenharmony_ci    }
646094332d3Sopenharmony_ci    dprintf("%s: create device success!\n", __func__);
647094332d3Sopenharmony_ciEXIT:
648094332d3Sopenharmony_ci    UsbFnMemFree(gadgetName.s);
649094332d3Sopenharmony_ciFAIL:
650094332d3Sopenharmony_ci    if (UsbFnAdapterClosefn(fd) != 0) {
651094332d3Sopenharmony_ci        dprintf("%s[%d] close fconfig failed\n", __func__, __LINE__);
652094332d3Sopenharmony_ci    }
653094332d3Sopenharmony_ci
654094332d3Sopenharmony_ci    return ret;
655094332d3Sopenharmony_ci}
656094332d3Sopenharmony_ci
657094332d3Sopenharmony_cistatic int32_t UsbFnAdapterDelConfigs(
658094332d3Sopenharmony_ci    int32_t configFd, struct FconfigString * const gadgetName, struct UsbFnDeviceDesc * const descriptor)
659094332d3Sopenharmony_ci{
660094332d3Sopenharmony_ci    struct FconfigCfgDesc configDesc;
661094332d3Sopenharmony_ci    struct FconfigString configName;
662094332d3Sopenharmony_ci    char tmp[MAX_PATHLEN];
663094332d3Sopenharmony_ci    int32_t ret;
664094332d3Sopenharmony_ci    int32_t iCount;
665094332d3Sopenharmony_ci    uint8_t confVal;
666094332d3Sopenharmony_ci
667094332d3Sopenharmony_ci    if (gadgetName == NULL || descriptor == NULL) {
668094332d3Sopenharmony_ci        HDF_LOGE("%{public}s: name is NULL", __func__);
669094332d3Sopenharmony_ci        return HDF_ERR_INVALID_PARAM;
670094332d3Sopenharmony_ci    }
671094332d3Sopenharmony_ci    for (iCount = 0; descriptor->configs[iCount]; iCount++) {
672094332d3Sopenharmony_ci        configDesc.gadgetName.len = gadgetName->len;
673094332d3Sopenharmony_ci        configDesc.gadgetName.s = gadgetName->s;
674094332d3Sopenharmony_ci        confVal = descriptor->configs[iCount]->configurationValue;
675094332d3Sopenharmony_ci        ret = snprintf_s(tmp, MAX_PATHLEN, MAX_PATHLEN - 1, "b.%u", confVal);
676094332d3Sopenharmony_ci        if (ret < 0) {
677094332d3Sopenharmony_ci            HDF_LOGE("%{public}s: snprintf_s failed", __func__);
678094332d3Sopenharmony_ci            return HDF_ERR_IO;
679094332d3Sopenharmony_ci        }
680094332d3Sopenharmony_ci        ret = UsbFnAdapterCreateFconfigString(&configName, tmp);
681094332d3Sopenharmony_ci        if (ret != HDF_SUCCESS) {
682094332d3Sopenharmony_ci            HDF_LOGE("%{public}s: create config name failed!", __func__);
683094332d3Sopenharmony_ci            return HDF_ERR_MALLOC_FAIL;
684094332d3Sopenharmony_ci        }
685094332d3Sopenharmony_ci        configDesc.configName.len = configName.len;
686094332d3Sopenharmony_ci        configDesc.configName.s = configName.s;
687094332d3Sopenharmony_ci        ret = UsbFnAdapterWriteFunctions(
688094332d3Sopenharmony_ci            configFd, descriptor->configs[iCount], FCONFIG_CMD_DROP_FUNCTION, gadgetName, &configName);
689094332d3Sopenharmony_ci        if (ret != HDF_SUCCESS) {
690094332d3Sopenharmony_ci            HDF_LOGE("%{public}s: write func failed!", __func__);
691094332d3Sopenharmony_ci            goto FAIL;
692094332d3Sopenharmony_ci        }
693094332d3Sopenharmony_ci        ret = UsbFnAdapterFillConfigDesc(&configDesc.cfgDesc, descriptor->configs[iCount]);
694094332d3Sopenharmony_ci        if (ret != HDF_SUCCESS) {
695094332d3Sopenharmony_ci            HDF_LOGE("%{public}s: UsbFnMemCalloc failed!", __func__);
696094332d3Sopenharmony_ci            goto FAIL;
697094332d3Sopenharmony_ci        }
698094332d3Sopenharmony_ci        ret = handle_ioctl(configFd, FCONFIG_CMD_REMOVE_CONFIG, &configDesc);
699094332d3Sopenharmony_ci        if (ret != HDF_SUCCESS) {
700094332d3Sopenharmony_ci            HDF_LOGE("%{public}s: ioctl failed!", __func__);
701094332d3Sopenharmony_ci            goto FAIL;
702094332d3Sopenharmony_ci        }
703094332d3Sopenharmony_ci        UsbFnMemFree(configName.s);
704094332d3Sopenharmony_ci    }
705094332d3Sopenharmony_ci    return 0;
706094332d3Sopenharmony_ciFAIL:
707094332d3Sopenharmony_ci    UsbFnMemFree(configName.s);
708094332d3Sopenharmony_ci    return -1;
709094332d3Sopenharmony_ci}
710094332d3Sopenharmony_ci
711094332d3Sopenharmony_cistatic int32_t UsbFnAdapterDelDevice(const char *devName, const char *udcName, struct UsbFnDeviceDesc *descriptor)
712094332d3Sopenharmony_ci{
713094332d3Sopenharmony_ci    int32_t configFd;
714094332d3Sopenharmony_ci    int32_t ret;
715094332d3Sopenharmony_ci    struct FconfigString gadgetName;
716094332d3Sopenharmony_ci
717094332d3Sopenharmony_ci    if (devName == NULL || udcName == NULL || descriptor == NULL) {
718094332d3Sopenharmony_ci        return HDF_ERR_INVALID_PARAM;
719094332d3Sopenharmony_ci    }
720094332d3Sopenharmony_ci    configFd = UsbFnAdapterOpenFn();
721094332d3Sopenharmony_ci    if (configFd <= 0) {
722094332d3Sopenharmony_ci        return HDF_ERR_IO;
723094332d3Sopenharmony_ci    }
724094332d3Sopenharmony_ci    ret = UsbFnAdapterCreateFconfigString(&gadgetName, devName);
725094332d3Sopenharmony_ci    if (ret != HDF_SUCCESS) {
726094332d3Sopenharmony_ci        HDF_LOGE("%{public}s: create gadget_name failed!", __func__);
727094332d3Sopenharmony_ci        return HDF_ERR_IO;
728094332d3Sopenharmony_ci    }
729094332d3Sopenharmony_ci    ret = UsbFnAdapterWriteFcofnigUDC(configFd, FCONFIG_CMD_DISABLE_UDC, &gadgetName, udcName);
730094332d3Sopenharmony_ci    if (ret != HDF_SUCCESS) {
731094332d3Sopenharmony_ci        goto FAIL;
732094332d3Sopenharmony_ci    }
733094332d3Sopenharmony_ci    ret = UsbFnAdapterDelConfigs(configFd, &gadgetName, descriptor);
734094332d3Sopenharmony_ci    if (ret != HDF_SUCCESS) {
735094332d3Sopenharmony_ci        goto FAIL;
736094332d3Sopenharmony_ci    }
737094332d3Sopenharmony_ci    ret = UsbFnAdapterWriteGadget(configFd, FCONFIG_CMD_DROP_GADGET, &gadgetName);
738094332d3Sopenharmony_ci    if (ret != HDF_SUCCESS) {
739094332d3Sopenharmony_ci        goto FAIL;
740094332d3Sopenharmony_ci    }
741094332d3Sopenharmony_ci    ret = UsbFnAdapterClosefn(configFd);
742094332d3Sopenharmony_ci
743094332d3Sopenharmony_ciFAIL:
744094332d3Sopenharmony_ci    UsbFnMemFree(gadgetName.s);
745094332d3Sopenharmony_ci    return ret;
746094332d3Sopenharmony_ci}
747094332d3Sopenharmony_ci
748094332d3Sopenharmony_cistatic int32_t UsbFnAdapterGetPipeInfo(int32_t ep, struct UsbFnPipeInfo * const pipeInfo)
749094332d3Sopenharmony_ci{
750094332d3Sopenharmony_ci    if (ep <= 0 || pipeInfo == NULL) {
751094332d3Sopenharmony_ci        return HDF_ERR_INVALID_PARAM;
752094332d3Sopenharmony_ci    }
753094332d3Sopenharmony_ci
754094332d3Sopenharmony_ci    struct usb_endpoint_descriptor desc;
755094332d3Sopenharmony_ci    if (memset_s(&desc, sizeof(desc), 0, sizeof(desc)) != EOK) {
756094332d3Sopenharmony_ci        HDF_LOGE("%{public}s:%{public}d memset_s failed", __func__, __LINE__);
757094332d3Sopenharmony_ci        return HDF_FAILURE;
758094332d3Sopenharmony_ci    }
759094332d3Sopenharmony_ci
760094332d3Sopenharmony_ci    int32_t ret = handle_ioctl(ep, GENERIC_CMD_GET_PIPE_INFO, &desc);
761094332d3Sopenharmony_ci    if (ret != HDF_SUCCESS) {
762094332d3Sopenharmony_ci        HDF_LOGE("%{public}s: FUNCTIONFS_ENDPOINT_DESC failed!", __func__);
763094332d3Sopenharmony_ci        return HDF_ERR_IO;
764094332d3Sopenharmony_ci    }
765094332d3Sopenharmony_ci
766094332d3Sopenharmony_ci    pipeInfo->type = desc.bmAttributes;
767094332d3Sopenharmony_ci    pipeInfo->dir = USB_PIPE_DIRECTION_OUT;
768094332d3Sopenharmony_ci    if (desc.bEndpointAddress & 0x80) {
769094332d3Sopenharmony_ci        pipeInfo->dir = USB_PIPE_DIRECTION_IN;
770094332d3Sopenharmony_ci    }
771094332d3Sopenharmony_ci
772094332d3Sopenharmony_ci    pipeInfo->maxPacketSize = (desc.wMaxPacketSize[0] | (desc.wMaxPacketSize[1] << 8));
773094332d3Sopenharmony_ci    pipeInfo->interval = desc.bInterval;
774094332d3Sopenharmony_ci
775094332d3Sopenharmony_ci    return 0;
776094332d3Sopenharmony_ci}
777094332d3Sopenharmony_ci
778094332d3Sopenharmony_cistatic int32_t UsbFnAdapterQueueInit(int32_t ep)
779094332d3Sopenharmony_ci{
780094332d3Sopenharmony_ci    (void)ep;
781094332d3Sopenharmony_ci    return 0;
782094332d3Sopenharmony_ci}
783094332d3Sopenharmony_ci
784094332d3Sopenharmony_cistatic int32_t UsbFnAdapterQueueDel(int32_t ep)
785094332d3Sopenharmony_ci{
786094332d3Sopenharmony_ci    (void)ep;
787094332d3Sopenharmony_ci    return 0;
788094332d3Sopenharmony_ci}
789094332d3Sopenharmony_ci
790094332d3Sopenharmony_cistatic int32_t UsbFnAdapterReleaseBuf(int32_t ep, const struct GenericMemory *mem)
791094332d3Sopenharmony_ci{
792094332d3Sopenharmony_ci    return handle_ioctl(ep, GENERIC_CMD_FREE_MEM, &mem);
793094332d3Sopenharmony_ci}
794094332d3Sopenharmony_ci
795094332d3Sopenharmony_cistatic int32_t UsbFnAdapterPipeIo(int32_t ep, struct IoData * const ioData)
796094332d3Sopenharmony_ci{
797094332d3Sopenharmony_ci    int32_t ret;
798094332d3Sopenharmony_ci    if (ep <= 0 || ioData == NULL) {
799094332d3Sopenharmony_ci        return HDF_ERR_INVALID_PARAM;
800094332d3Sopenharmony_ci    }
801094332d3Sopenharmony_ci    if (ioData->aio) {
802094332d3Sopenharmony_ci        ret = handle_write(ep, (void *)ioData->buf, ioData->len);
803094332d3Sopenharmony_ci    } else {
804094332d3Sopenharmony_ci        ret = handle_ioctl(ep, GENERIC_CMD_ENDPOINT_IO, ioData);
805094332d3Sopenharmony_ci    }
806094332d3Sopenharmony_ci    return ret;
807094332d3Sopenharmony_ci}
808094332d3Sopenharmony_ci
809094332d3Sopenharmony_cistatic int32_t UsbFnAdapterCancelIo(int32_t ep, const struct IoData * const ioData)
810094332d3Sopenharmony_ci{
811094332d3Sopenharmony_ci    struct GenericMemory mem;
812094332d3Sopenharmony_ci
813094332d3Sopenharmony_ci    mem.buf = ioData->buf;
814094332d3Sopenharmony_ci    mem.size = ioData->len;
815094332d3Sopenharmony_ci
816094332d3Sopenharmony_ci    return handle_ioctl(ep, GENERIC_CMD_CANCEL_REQUEST, &mem);
817094332d3Sopenharmony_ci}
818094332d3Sopenharmony_ci
819094332d3Sopenharmony_cistatic int32_t UsbFnAdapterRequestGetStatus(int32_t ep, const struct IoData *ioData)
820094332d3Sopenharmony_ci{
821094332d3Sopenharmony_ci    if (ep <= 0 || ioData == NULL) {
822094332d3Sopenharmony_ci        return HDF_ERR_INVALID_PARAM;
823094332d3Sopenharmony_ci    }
824094332d3Sopenharmony_ci    return handle_ioctl(ep, GENERIC_CMD_GET_REQ_STATUS, (void *)ioData);
825094332d3Sopenharmony_ci}
826094332d3Sopenharmony_ci
827094332d3Sopenharmony_cistatic uint8_t *UsbFnAdapterMapAddr(int32_t ep, uint32_t len)
828094332d3Sopenharmony_ci{
829094332d3Sopenharmony_ci    return handle_mmap(ep, len);
830094332d3Sopenharmony_ci}
831094332d3Sopenharmony_ci
832094332d3Sopenharmony_cistatic int32_t UsbFnAdapterUnmapAddr(uint8_t *mapAddr, uint32_t len)
833094332d3Sopenharmony_ci{
834094332d3Sopenharmony_ci    (void)mapAddr;
835094332d3Sopenharmony_ci    (void)len;
836094332d3Sopenharmony_ci    return 0;
837094332d3Sopenharmony_ci}
838094332d3Sopenharmony_ci
839094332d3Sopenharmony_cistatic int32_t Ep0Event(struct UsbFnEventAll * const event, struct FconfigPollFd * const pfds)
840094332d3Sopenharmony_ci{
841094332d3Sopenharmony_ci    int32_t ret;
842094332d3Sopenharmony_ci    uint8_t i;
843094332d3Sopenharmony_ci    for (i = 0; i < event->ep0Num; i++) {
844094332d3Sopenharmony_ci        if (pfds[i].revents & POLLIN) {
845094332d3Sopenharmony_ci            ret = handle_read(event->ep0[i], &event->ep0Event[i].ctrlEvent, sizeof(struct UsbFnCtrlEvent));
846094332d3Sopenharmony_ci            if (ret < 0) {
847094332d3Sopenharmony_ci                HDF_LOGE("unable to read event from ep0");
848094332d3Sopenharmony_ci                return ret;
849094332d3Sopenharmony_ci            }
850094332d3Sopenharmony_ci            event->ep0Event[i].type = USB_EP0_CTRL_EVENT;
851094332d3Sopenharmony_ci        } else if (pfds[i].revents & POLLOUT) {
852094332d3Sopenharmony_ci            ret = handle_ioctl(event->ep0[i], GENERIC_CMD_GET_EP0_EVENT, &event->ep0Event[i].reqEvent);
853094332d3Sopenharmony_ci            if (ret < 0) {
854094332d3Sopenharmony_ci                HDF_LOGE("unable to read reqEvent from ep0");
855094332d3Sopenharmony_ci                return ret;
856094332d3Sopenharmony_ci            }
857094332d3Sopenharmony_ci            event->ep0Event[i].type = USB_EP0_IO_COMPLETED;
858094332d3Sopenharmony_ci        }
859094332d3Sopenharmony_ci    }
860094332d3Sopenharmony_ci    return 0;
861094332d3Sopenharmony_ci}
862094332d3Sopenharmony_ci
863094332d3Sopenharmony_cistatic int32_t EpEvent(struct UsbFnEventAll * const event, struct FconfigPollFd * const pfds)
864094332d3Sopenharmony_ci{
865094332d3Sopenharmony_ci    uint8_t i;
866094332d3Sopenharmony_ci    int32_t ret;
867094332d3Sopenharmony_ci    for (i = 0; i < event->epNum; i++) {
868094332d3Sopenharmony_ci        if ((pfds[i + event->ep0Num].revents & POLLIN)) {
869094332d3Sopenharmony_ci            ret = handle_read(event->epx[i], event->reqEvent[i], MAX_REQUEST * sizeof(struct UsbFnReqEvent));
870094332d3Sopenharmony_ci            if (ret < 0) {
871094332d3Sopenharmony_ci                HDF_LOGE("unable to read event from eps");
872094332d3Sopenharmony_ci                return ret;
873094332d3Sopenharmony_ci            }
874094332d3Sopenharmony_ci            event->numEvent[i] = (uint8_t)(ret / sizeof(struct UsbFnReqEvent));
875094332d3Sopenharmony_ci        }
876094332d3Sopenharmony_ci    }
877094332d3Sopenharmony_ci    return 0;
878094332d3Sopenharmony_ci}
879094332d3Sopenharmony_ci
880094332d3Sopenharmony_cistatic int32_t UsbFnAdapterPollEvent(struct UsbFnEventAll *event, int32_t timeout)
881094332d3Sopenharmony_ci{
882094332d3Sopenharmony_ci    uint8_t i;
883094332d3Sopenharmony_ci    struct FconfigPollFd pfds[16] = {0};
884094332d3Sopenharmony_ci    struct FconfigPollFd *pfd = &pfds[0];
885094332d3Sopenharmony_ci    if (event == NULL) {
886094332d3Sopenharmony_ci        return HDF_ERR_INVALID_PARAM;
887094332d3Sopenharmony_ci    }
888094332d3Sopenharmony_ci    if ((event->ep0Num + event->epNum) == 0) {
889094332d3Sopenharmony_ci        return HDF_ERR_INVALID_PARAM;
890094332d3Sopenharmony_ci    }
891094332d3Sopenharmony_ci
892094332d3Sopenharmony_ci    if (memset_s(&pfds, sizeof(pfds), 0, sizeof(pfds)) != EOK) {
893094332d3Sopenharmony_ci        HDF_LOGE("%{public}s:%{public}d memset_s failed", __func__, __LINE__);
894094332d3Sopenharmony_ci        return HDF_FAILURE;
895094332d3Sopenharmony_ci    }
896094332d3Sopenharmony_ci
897094332d3Sopenharmony_ci    for (i = 0; i < event->ep0Num; i++) {
898094332d3Sopenharmony_ci        if (event->ep0[i] <= 0) {
899094332d3Sopenharmony_ci            HDF_LOGE("%{public}s: ep[%{public}d] = %{public}d", __func__, i, event->ep0[i]);
900094332d3Sopenharmony_ci            return HDF_ERR_INVALID_PARAM;
901094332d3Sopenharmony_ci        }
902094332d3Sopenharmony_ci        pfds[i].fd = event->ep0[i];
903094332d3Sopenharmony_ci        pfds[i].events = POLLIN | POLLOUT;
904094332d3Sopenharmony_ci    }
905094332d3Sopenharmony_ci    for (i = 0; i < event->epNum; i++) {
906094332d3Sopenharmony_ci        if (event->epx[i] <= 0) {
907094332d3Sopenharmony_ci            HDF_LOGE("%{public}s: ep[%{public}d] = %{public}d", __func__, i, event->epx[i]);
908094332d3Sopenharmony_ci            return HDF_ERR_INVALID_PARAM;
909094332d3Sopenharmony_ci        }
910094332d3Sopenharmony_ci        pfds[i + event->ep0Num].fd = event->epx[i];
911094332d3Sopenharmony_ci        pfds[i + event->ep0Num].events = POLLIN;
912094332d3Sopenharmony_ci    }
913094332d3Sopenharmony_ci    for (i = 0; i < (event->ep0Num + event->epNum); i++) {
914094332d3Sopenharmony_ci        pfds[i].revents = (uint32_t)handle_poll(pfds[i].fd, timeout);
915094332d3Sopenharmony_ci        if (pfds[i].revents < 0) {
916094332d3Sopenharmony_ci            HDF_LOGE("%{public}s: handle_poll failed", __func__);
917094332d3Sopenharmony_ci            return HDF_ERR_INVALID_PARAM;
918094332d3Sopenharmony_ci        }
919094332d3Sopenharmony_ci    }
920094332d3Sopenharmony_ci    if (Ep0Event(event, pfd) < 0) {
921094332d3Sopenharmony_ci        HDF_LOGE("%{public}s: handle_poll failed", __func__);
922094332d3Sopenharmony_ci        return HDF_ERR_IO;
923094332d3Sopenharmony_ci    }
924094332d3Sopenharmony_ci    if (EpEvent(event, pfd) < 0) {
925094332d3Sopenharmony_ci        HDF_LOGE("%{public}s: handle_poll failed", __func__);
926094332d3Sopenharmony_ci        return HDF_ERR_IO;
927094332d3Sopenharmony_ci    }
928094332d3Sopenharmony_ci    return 0;
929094332d3Sopenharmony_ci}
930094332d3Sopenharmony_ci
931094332d3Sopenharmony_cistatic int32_t UsbFnAdapterWriteUDC(const char *deviceName, const char *udcName, int32_t enable)
932094332d3Sopenharmony_ci{
933094332d3Sopenharmony_ci    struct FconfigUdcInfo udcInfo;
934094332d3Sopenharmony_ci
935094332d3Sopenharmony_ci    int32_t configFd = UsbFnAdapterOpenFn();
936094332d3Sopenharmony_ci    if (configFd <= 0) {
937094332d3Sopenharmony_ci        return HDF_ERR_IO;
938094332d3Sopenharmony_ci    }
939094332d3Sopenharmony_ci
940094332d3Sopenharmony_ci    int32_t ret = UsbFnAdapterCreateFconfigString(&udcInfo.gadgetName, deviceName);
941094332d3Sopenharmony_ci    if (ret != HDF_SUCCESS) {
942094332d3Sopenharmony_ci        HDF_LOGE("%{public}s: create gadget_name failed!", __func__);
943094332d3Sopenharmony_ci        return HDF_ERR_IO;
944094332d3Sopenharmony_ci    }
945094332d3Sopenharmony_ci
946094332d3Sopenharmony_ci    int32_t cmd = enable ? FCONFIG_CMD_ENABLE_UDC : FCONFIG_CMD_DISABLE_UDC;
947094332d3Sopenharmony_ci    ret = UsbFnAdapterWriteFcofnigUDC(configFd, cmd, &udcInfo.gadgetName, udcName);
948094332d3Sopenharmony_ci    if (ret != HDF_SUCCESS) {
949094332d3Sopenharmony_ci        return HDF_ERR_IO;
950094332d3Sopenharmony_ci    }
951094332d3Sopenharmony_ci
952094332d3Sopenharmony_ci    ret = UsbFnAdapterClosefn(configFd);
953094332d3Sopenharmony_ci    if (ret != 0) {
954094332d3Sopenharmony_ci        HDF_LOGE("%{public}s: close failed!", __func__);
955094332d3Sopenharmony_ci    }
956094332d3Sopenharmony_ci    return 0;
957094332d3Sopenharmony_ci}
958094332d3Sopenharmony_ci
959094332d3Sopenharmony_cistatic int32_t UsbFnWriteProp(const char *deviceName, const char *propName, uint32_t propValue)
960094332d3Sopenharmony_ci{
961094332d3Sopenharmony_ci    struct FconfigDevdescInfo info;
962094332d3Sopenharmony_ci    if (deviceName == NULL || propName == NULL) {
963094332d3Sopenharmony_ci        HDF_LOGE("%{public}s: param invail!", __func__);
964094332d3Sopenharmony_ci        return HDF_ERR_IO;
965094332d3Sopenharmony_ci    }
966094332d3Sopenharmony_ci    int32_t ret = UsbFnAdapterCreateFconfigString(&info.gadgetName, deviceName);
967094332d3Sopenharmony_ci    if (ret != HDF_SUCCESS) {
968094332d3Sopenharmony_ci        HDF_LOGE("%{public}s: create gadget name failed!", __func__);
969094332d3Sopenharmony_ci        return HDF_ERR_IO;
970094332d3Sopenharmony_ci    }
971094332d3Sopenharmony_ci    info.prop.propName = propName;
972094332d3Sopenharmony_ci    info.prop.propValue = (uint32_t)propValue;
973094332d3Sopenharmony_ci    int32_t configFd = UsbFnAdapterOpenFn();
974094332d3Sopenharmony_ci    if (configFd <= 0) {
975094332d3Sopenharmony_ci        ret = HDF_ERR_IO;
976094332d3Sopenharmony_ci        goto FAIL;
977094332d3Sopenharmony_ci    }
978094332d3Sopenharmony_ci    ret = handle_ioctl(configFd, FCONFIG_CMD_CHAGE_DEVINFO, &info);
979094332d3Sopenharmony_ci    if (ret != 0) {
980094332d3Sopenharmony_ci        HDF_LOGE("%{public}s: ioctl failed!", __func__);
981094332d3Sopenharmony_ci        goto FAIL;
982094332d3Sopenharmony_ci    }
983094332d3Sopenharmony_ci    ret = UsbFnAdapterClosefn(configFd);
984094332d3Sopenharmony_ci    if (ret != 0) {
985094332d3Sopenharmony_ci        HDF_LOGE("%{public}s: close failed!", __func__);
986094332d3Sopenharmony_ci    }
987094332d3Sopenharmony_ciFAIL:
988094332d3Sopenharmony_ci    UsbFnMemFree(info.gadgetName.s);
989094332d3Sopenharmony_ci
990094332d3Sopenharmony_ci    return ret;
991094332d3Sopenharmony_ci}
992094332d3Sopenharmony_ci
993094332d3Sopenharmony_cistatic int32_t UsbFnWriteDesString(
994094332d3Sopenharmony_ci    const char *deviceName, uint16_t lang, const char *stringName, const char *stringValue)
995094332d3Sopenharmony_ci{
996094332d3Sopenharmony_ci    struct FconfigDevDescString info;
997094332d3Sopenharmony_ci    if (deviceName == NULL || stringName == NULL || stringValue == NULL) {
998094332d3Sopenharmony_ci        HDF_LOGE("%{public}s: param invail!", __func__);
999094332d3Sopenharmony_ci        return HDF_ERR_IO;
1000094332d3Sopenharmony_ci    }
1001094332d3Sopenharmony_ci    int32_t ret = UsbFnAdapterCreateFconfigString(&info.gadgetName, deviceName);
1002094332d3Sopenharmony_ci    if (ret != HDF_SUCCESS) {
1003094332d3Sopenharmony_ci        HDF_LOGE("%{public}s: create gadget name failed!", __func__);
1004094332d3Sopenharmony_ci        return HDF_ERR_IO;
1005094332d3Sopenharmony_ci    }
1006094332d3Sopenharmony_ci    info.prop.lang = lang;
1007094332d3Sopenharmony_ci    info.prop.propName = stringName;
1008094332d3Sopenharmony_ci    info.prop.propValue = stringValue;
1009094332d3Sopenharmony_ci    int32_t configFd = UsbFnAdapterOpenFn();
1010094332d3Sopenharmony_ci    if (configFd <= 0) {
1011094332d3Sopenharmony_ci        dprintf("%s, %d\n", __func__, __LINE__);
1012094332d3Sopenharmony_ci        ret = HDF_ERR_IO;
1013094332d3Sopenharmony_ci        goto FAIL;
1014094332d3Sopenharmony_ci    }
1015094332d3Sopenharmony_ci    ret = handle_ioctl(configFd, FCONFIG_CMD_CHAGE_DEVSTRING, &info);
1016094332d3Sopenharmony_ci    if (ret != 0) {
1017094332d3Sopenharmony_ci        HDF_LOGE("%{public}s: ioctl failed!", __func__);
1018094332d3Sopenharmony_ci        goto FAIL;
1019094332d3Sopenharmony_ci    }
1020094332d3Sopenharmony_ci    ret = UsbFnAdapterClosefn(configFd);
1021094332d3Sopenharmony_ci    if (ret != 0) {
1022094332d3Sopenharmony_ci        HDF_LOGE("%{public}s: close failed!", __func__);
1023094332d3Sopenharmony_ci    }
1024094332d3Sopenharmony_ciFAIL:
1025094332d3Sopenharmony_ci    UsbFnMemFree(info.gadgetName.s);
1026094332d3Sopenharmony_ci
1027094332d3Sopenharmony_ci    return ret;
1028094332d3Sopenharmony_ci}
1029094332d3Sopenharmony_ci
1030094332d3Sopenharmony_cistatic void *UsbFnMemAlloc(size_t size)
1031094332d3Sopenharmony_ci{
1032094332d3Sopenharmony_ci    return UsbFnMemCalloc(size);
1033094332d3Sopenharmony_ci}
1034094332d3Sopenharmony_ci
1035094332d3Sopenharmony_cistatic void *UsbFnMemCalloc(size_t size)
1036094332d3Sopenharmony_ci{
1037094332d3Sopenharmony_ci    void *buf = OsalMemCalloc(size);
1038094332d3Sopenharmony_ci    if (buf == NULL) {
1039094332d3Sopenharmony_ci        HDF_LOGE("%{public}s: %{public}d, OsalMemCalloc failed", __func__, __LINE__);
1040094332d3Sopenharmony_ci        return NULL;
1041094332d3Sopenharmony_ci    }
1042094332d3Sopenharmony_ci
1043094332d3Sopenharmony_ci    return buf;
1044094332d3Sopenharmony_ci}
1045094332d3Sopenharmony_ci
1046094332d3Sopenharmony_civoid UsbFnMemFree(const void *mem)
1047094332d3Sopenharmony_ci{
1048094332d3Sopenharmony_ci    if (mem == NULL) {
1049094332d3Sopenharmony_ci        HDF_LOGE("%{public}s:%{public}d invalid param mem.", __func__, __LINE__);
1050094332d3Sopenharmony_ci        return;
1051094332d3Sopenharmony_ci    }
1052094332d3Sopenharmony_ci
1053094332d3Sopenharmony_ci    OsalMemFree((void *)mem);
1054094332d3Sopenharmony_ci    mem = NULL;
1055094332d3Sopenharmony_ci}
1056094332d3Sopenharmony_ci
1057094332d3Sopenharmony_cistatic struct UsbFnAdapterOps g_usbFnAdapter = {
1058094332d3Sopenharmony_ci    .createDevice = UsbFnAdapterCreateDevice,
1059094332d3Sopenharmony_ci    .delDevice = UsbFnAdapterDelDevice,
1060094332d3Sopenharmony_ci
1061094332d3Sopenharmony_ci    .openPipe = UsbFnAdapterOpenPipe,
1062094332d3Sopenharmony_ci    .closePipe = UsbFnAdapterClosePipe,
1063094332d3Sopenharmony_ci    .getPipeInfo = UsbFnAdapterGetPipeInfo,
1064094332d3Sopenharmony_ci
1065094332d3Sopenharmony_ci    .queueInit = UsbFnAdapterQueueInit,
1066094332d3Sopenharmony_ci    .queueDel = UsbFnAdapterQueueDel,
1067094332d3Sopenharmony_ci    .releaseBuf = UsbFnAdapterReleaseBuf,
1068094332d3Sopenharmony_ci    .pipeIo = UsbFnAdapterPipeIo,
1069094332d3Sopenharmony_ci    .cancelIo = UsbFnAdapterCancelIo,
1070094332d3Sopenharmony_ci    .getReqStatus = UsbFnAdapterRequestGetStatus,
1071094332d3Sopenharmony_ci    .mapAddr = UsbFnAdapterMapAddr,
1072094332d3Sopenharmony_ci    .unmapAddr = UsbFnAdapterUnmapAddr,
1073094332d3Sopenharmony_ci    .pollEvent = UsbFnAdapterPollEvent,
1074094332d3Sopenharmony_ci    .writeUDC = UsbFnAdapterWriteUDC,
1075094332d3Sopenharmony_ci    .writeProp = UsbFnWriteProp,
1076094332d3Sopenharmony_ci    .writeDesString = UsbFnWriteDesString,
1077094332d3Sopenharmony_ci};
1078094332d3Sopenharmony_ci
1079094332d3Sopenharmony_cistruct UsbFnAdapterOps *UsbFnAdapterGetOps(void)
1080094332d3Sopenharmony_ci{
1081094332d3Sopenharmony_ci    return &g_usbFnAdapter;
1082094332d3Sopenharmony_ci}
1083