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
18094332d3Sopenharmony_ci#include <dirent.h>
19094332d3Sopenharmony_ci#include <endian.h>
20094332d3Sopenharmony_ci#include <fcntl.h>
21094332d3Sopenharmony_ci#include <poll.h>
22094332d3Sopenharmony_ci#include <stdarg.h>
23094332d3Sopenharmony_ci#include <stdio.h>
24094332d3Sopenharmony_ci#include <stdlib.h>
25094332d3Sopenharmony_ci#include <string.h>
26094332d3Sopenharmony_ci#include <sys/eventfd.h>
27094332d3Sopenharmony_ci#include <sys/ioctl.h>
28094332d3Sopenharmony_ci#include <sys/stat.h>
29094332d3Sopenharmony_ci#include <sys/types.h>
30094332d3Sopenharmony_ci#include <unistd.h>
31094332d3Sopenharmony_ci
32094332d3Sopenharmony_ci#include "osal_time.h"
33094332d3Sopenharmony_ci#include "usbd_wrapper.h"
34094332d3Sopenharmony_ci
35094332d3Sopenharmony_ci#define HDF_LOG_TAG adapter_if
36094332d3Sopenharmony_ci#define SLEEP_DELAY 100000
37094332d3Sopenharmony_ci#define OPEN_CNT    30
38094332d3Sopenharmony_ci
39094332d3Sopenharmony_cistatic bool IsDirExist(const char *path)
40094332d3Sopenharmony_ci{
41094332d3Sopenharmony_ci    DIR *dir = NULL;
42094332d3Sopenharmony_ci
43094332d3Sopenharmony_ci    if (path == NULL) {
44094332d3Sopenharmony_ci        HDF_LOGE("%{public}s:%{public}d invalid param path.", __func__, __LINE__);
45094332d3Sopenharmony_ci        return false;
46094332d3Sopenharmony_ci    }
47094332d3Sopenharmony_ci
48094332d3Sopenharmony_ci    dir = opendir(path);
49094332d3Sopenharmony_ci    if (dir == NULL) {
50094332d3Sopenharmony_ci        HDF_LOGE("%{public}s: %{public}d: opendir failed!, path is %{public}s, errno is %{public}d", __func__, __LINE__,
51094332d3Sopenharmony_ci            path, errno);
52094332d3Sopenharmony_ci        return false;
53094332d3Sopenharmony_ci    }
54094332d3Sopenharmony_ci    closedir(dir);
55094332d3Sopenharmony_ci    return true;
56094332d3Sopenharmony_ci}
57094332d3Sopenharmony_ci
58094332d3Sopenharmony_cistatic bool IsDir(const char *path)
59094332d3Sopenharmony_ci{
60094332d3Sopenharmony_ci    struct stat statBuf;
61094332d3Sopenharmony_ci    if (lstat(path, &statBuf) == 0) {
62094332d3Sopenharmony_ci        return S_ISDIR(statBuf.st_mode) != 0;
63094332d3Sopenharmony_ci    }
64094332d3Sopenharmony_ci    return false;
65094332d3Sopenharmony_ci}
66094332d3Sopenharmony_ci
67094332d3Sopenharmony_cistatic void GetFilePath(const char *path, const char *fileName, char *filePath)
68094332d3Sopenharmony_ci{
69094332d3Sopenharmony_ci    int32_t ret = strcpy_s(filePath, MAX_PATHLEN - 1, path);
70094332d3Sopenharmony_ci    if (ret != EOK) {
71094332d3Sopenharmony_ci        HDF_LOGE("%{public}s: strcpy_s failed", __func__);
72094332d3Sopenharmony_ci        return;
73094332d3Sopenharmony_ci    }
74094332d3Sopenharmony_ci
75094332d3Sopenharmony_ci    if (strlen(path) > 0 && filePath[strlen(path) - 1] != '/') {
76094332d3Sopenharmony_ci        if (strlen(path) + 1 >= MAX_PATHLEN - strlen(fileName)) {
77094332d3Sopenharmony_ci            HDF_LOGE("%{public}s: file path too long", __func__);
78094332d3Sopenharmony_ci            return;
79094332d3Sopenharmony_ci        }
80094332d3Sopenharmony_ci        ret = strcat_s(filePath, MAX_PATHLEN - 1, "/");
81094332d3Sopenharmony_ci        if (ret != EOK) {
82094332d3Sopenharmony_ci            HDF_LOGE("%{public}s: strcat_s failed", __func__);
83094332d3Sopenharmony_ci            return;
84094332d3Sopenharmony_ci        }
85094332d3Sopenharmony_ci    }
86094332d3Sopenharmony_ci
87094332d3Sopenharmony_ci    ret = strcat_s(filePath, MAX_PATHLEN - 1, fileName);
88094332d3Sopenharmony_ci    if (ret != EOK) {
89094332d3Sopenharmony_ci        HDF_LOGE("%{public}s: strcat_s failed", __func__);
90094332d3Sopenharmony_ci    }
91094332d3Sopenharmony_ci}
92094332d3Sopenharmony_ci
93094332d3Sopenharmony_cistatic bool IsSpecialDir(const char *path)
94094332d3Sopenharmony_ci{
95094332d3Sopenharmony_ci    return (strcmp(path, ".") == 0) || strcmp(path, "..") == 0;
96094332d3Sopenharmony_ci}
97094332d3Sopenharmony_ci
98094332d3Sopenharmony_cistatic void DeleteFile(const char *path)
99094332d3Sopenharmony_ci{
100094332d3Sopenharmony_ci    DIR *dir = NULL;
101094332d3Sopenharmony_ci    struct dirent *dirInfo = NULL;
102094332d3Sopenharmony_ci
103094332d3Sopenharmony_ci    if (IsDir(path)) {
104094332d3Sopenharmony_ci        if ((dir = opendir(path)) == NULL) {
105094332d3Sopenharmony_ci            return;
106094332d3Sopenharmony_ci        }
107094332d3Sopenharmony_ci        char filePath[PATH_MAX];
108094332d3Sopenharmony_ci        while ((dirInfo = readdir(dir)) != NULL) {
109094332d3Sopenharmony_ci            GetFilePath(path, dirInfo->d_name, filePath);
110094332d3Sopenharmony_ci            if (IsSpecialDir(dirInfo->d_name)) {
111094332d3Sopenharmony_ci                continue;
112094332d3Sopenharmony_ci            }
113094332d3Sopenharmony_ci            DeleteFile(filePath);
114094332d3Sopenharmony_ci            (void)remove(filePath);
115094332d3Sopenharmony_ci        }
116094332d3Sopenharmony_ci        closedir(dir);
117094332d3Sopenharmony_ci    }
118094332d3Sopenharmony_ci}
119094332d3Sopenharmony_ci
120094332d3Sopenharmony_cistatic bool IsDeviceDirExist(const char *deviceName)
121094332d3Sopenharmony_ci{
122094332d3Sopenharmony_ci    char tmp[MAX_PATHLEN] = {0};
123094332d3Sopenharmony_ci    int32_t ret = snprintf_s(tmp, MAX_PATHLEN, MAX_PATHLEN - 1, "%s/%s", CONFIGFS_DIR, deviceName);
124094332d3Sopenharmony_ci    if (ret < 0) {
125094332d3Sopenharmony_ci        HDF_LOGE("%{public}s: snprintf_s failed", __func__);
126094332d3Sopenharmony_ci        return false;
127094332d3Sopenharmony_ci    }
128094332d3Sopenharmony_ci
129094332d3Sopenharmony_ci    return IsDirExist(tmp);
130094332d3Sopenharmony_ci}
131094332d3Sopenharmony_ci
132094332d3Sopenharmony_cistatic int32_t UsbFnWriteFile(const char *path, const char *str)
133094332d3Sopenharmony_ci{
134094332d3Sopenharmony_ci    size_t ret;
135094332d3Sopenharmony_ci    if (strlen(str) == 0) {
136094332d3Sopenharmony_ci        return 0;
137094332d3Sopenharmony_ci    }
138094332d3Sopenharmony_ci
139094332d3Sopenharmony_ci    FILE *fp = fopen(path, "w");
140094332d3Sopenharmony_ci    if (fp == NULL) {
141094332d3Sopenharmony_ci        HDF_LOGE("%{public}s: UsbFnWriteFile failed", __func__);
142094332d3Sopenharmony_ci        return HDF_ERR_BAD_FD;
143094332d3Sopenharmony_ci    }
144094332d3Sopenharmony_ci
145094332d3Sopenharmony_ci    ret = fwrite(str, strlen(str), 1, fp);
146094332d3Sopenharmony_ci    if (ret != 1) {
147094332d3Sopenharmony_ci        (void)fclose(fp);
148094332d3Sopenharmony_ci        return HDF_FAILURE;
149094332d3Sopenharmony_ci    }
150094332d3Sopenharmony_ci    (void)fclose(fp);
151094332d3Sopenharmony_ci    return 0;
152094332d3Sopenharmony_ci}
153094332d3Sopenharmony_ci
154094332d3Sopenharmony_cistatic int32_t UsbFnWriteProp(const char *deviceName, const char *propName, uint32_t propValue)
155094332d3Sopenharmony_ci{
156094332d3Sopenharmony_ci    char tmp[MAX_PATHLEN] = {0};
157094332d3Sopenharmony_ci    char tmpVal[MAX_NAMELEN] = {0};
158094332d3Sopenharmony_ci    int32_t ret;
159094332d3Sopenharmony_ci    if (deviceName == NULL || propName == NULL) {
160094332d3Sopenharmony_ci        HDF_LOGE("%{public}s: INVALID PARAM", __func__);
161094332d3Sopenharmony_ci        return HDF_ERR_INVALID_PARAM;
162094332d3Sopenharmony_ci    }
163094332d3Sopenharmony_ci    ret = snprintf_s(tmp, MAX_PATHLEN, MAX_PATHLEN - 1, "%s/%s/%s", CONFIGFS_DIR, deviceName, propName);
164094332d3Sopenharmony_ci    if (ret < 0) {
165094332d3Sopenharmony_ci        HDF_LOGE("%{public}s: snprintf_s failed", __func__);
166094332d3Sopenharmony_ci        return HDF_ERR_IO;
167094332d3Sopenharmony_ci    }
168094332d3Sopenharmony_ci
169094332d3Sopenharmony_ci    ret = snprintf_s(tmpVal, MAX_NAMELEN, MAX_NAMELEN - 1, "0x%x", propValue);
170094332d3Sopenharmony_ci    if (ret < 0) {
171094332d3Sopenharmony_ci        HDF_LOGE("%{public}s: snprintf_s failed", __func__);
172094332d3Sopenharmony_ci        return HDF_ERR_IO;
173094332d3Sopenharmony_ci    }
174094332d3Sopenharmony_ci
175094332d3Sopenharmony_ci    return UsbFnWriteFile(tmp, tmpVal);
176094332d3Sopenharmony_ci}
177094332d3Sopenharmony_ci
178094332d3Sopenharmony_cistatic int32_t UsbFnWriteConfString(const char *deviceName, int32_t configVal, uint16_t lang, const char *stringValue)
179094332d3Sopenharmony_ci{
180094332d3Sopenharmony_ci    int32_t ret;
181094332d3Sopenharmony_ci    char tmp[MAX_PATHLEN] = {0};
182094332d3Sopenharmony_ci    char tmpPath[MAX_PATHLEN] = {0};
183094332d3Sopenharmony_ci    ret = snprintf_s(tmp, MAX_PATHLEN, MAX_PATHLEN - 1, "%s/%s/configs/b.%d/strings/0x%x", CONFIGFS_DIR, deviceName,
184094332d3Sopenharmony_ci        configVal, lang);
185094332d3Sopenharmony_ci    if (ret < 0) {
186094332d3Sopenharmony_ci        HDF_LOGE("%{public}s: snprintf_s failed", __func__);
187094332d3Sopenharmony_ci        return HDF_ERR_IO;
188094332d3Sopenharmony_ci    }
189094332d3Sopenharmony_ci
190094332d3Sopenharmony_ci    if (!IsDirExist(tmp)) {
191094332d3Sopenharmony_ci        ret = mkdir(tmp, S_IREAD | S_IWRITE);
192094332d3Sopenharmony_ci        if (ret != 0) {
193094332d3Sopenharmony_ci            HDF_LOGE("%{public}s: mkdir failed", __func__);
194094332d3Sopenharmony_ci            return HDF_ERR_IO;
195094332d3Sopenharmony_ci        }
196094332d3Sopenharmony_ci    }
197094332d3Sopenharmony_ci
198094332d3Sopenharmony_ci    ret = snprintf_s(tmpPath, MAX_PATHLEN, MAX_PATHLEN - 1, "%s/configuration", tmp);
199094332d3Sopenharmony_ci    if (ret < 0) {
200094332d3Sopenharmony_ci        HDF_LOGE("%{public}s: snprintf_s failed", __func__);
201094332d3Sopenharmony_ci        return HDF_ERR_IO;
202094332d3Sopenharmony_ci    }
203094332d3Sopenharmony_ci
204094332d3Sopenharmony_ci    ret = UsbFnWriteFile(tmpPath, stringValue);
205094332d3Sopenharmony_ci    return ret;
206094332d3Sopenharmony_ci}
207094332d3Sopenharmony_ci
208094332d3Sopenharmony_cistatic int32_t UsbFnWriteDesString(
209094332d3Sopenharmony_ci    const char *deviceName, uint16_t lang, const char *stringName, const char *stringValue)
210094332d3Sopenharmony_ci{
211094332d3Sopenharmony_ci    int32_t ret;
212094332d3Sopenharmony_ci    char tmp[MAX_PATHLEN] = {0};
213094332d3Sopenharmony_ci    char tmpPath[MAX_PATHLEN] = {0};
214094332d3Sopenharmony_ci    ret = snprintf_s(tmp, MAX_PATHLEN, MAX_PATHLEN - 1, "%s/%s/strings/0x%x", CONFIGFS_DIR, deviceName, lang);
215094332d3Sopenharmony_ci    if (ret < 0) {
216094332d3Sopenharmony_ci        HDF_LOGE("%{public}s: snprintf_s failed", __func__);
217094332d3Sopenharmony_ci        return HDF_ERR_IO;
218094332d3Sopenharmony_ci    }
219094332d3Sopenharmony_ci    if (!IsDirExist(tmp)) {
220094332d3Sopenharmony_ci        ret = mkdir(tmp, S_IREAD | S_IWRITE);
221094332d3Sopenharmony_ci        if (ret != 0) {
222094332d3Sopenharmony_ci            HDF_LOGE("%{public}s: mkdir failed", __func__);
223094332d3Sopenharmony_ci            return HDF_ERR_IO;
224094332d3Sopenharmony_ci        }
225094332d3Sopenharmony_ci    }
226094332d3Sopenharmony_ci
227094332d3Sopenharmony_ci    ret = snprintf_s(tmpPath, MAX_PATHLEN, MAX_PATHLEN - 1, "%s/%s", tmp, stringName);
228094332d3Sopenharmony_ci    if (ret < 0) {
229094332d3Sopenharmony_ci        HDF_LOGE("%{public}s: snprintf_s failed", __func__);
230094332d3Sopenharmony_ci        return HDF_ERR_IO;
231094332d3Sopenharmony_ci    }
232094332d3Sopenharmony_ci
233094332d3Sopenharmony_ci    ret = UsbFnWriteFile(tmpPath, stringValue);
234094332d3Sopenharmony_ci    return ret;
235094332d3Sopenharmony_ci}
236094332d3Sopenharmony_ci
237094332d3Sopenharmony_cistatic int32_t UsbFnAdapterCreateFunc(const char *configPath, const char *funcPath)
238094332d3Sopenharmony_ci{
239094332d3Sopenharmony_ci    int32_t ret;
240094332d3Sopenharmony_ci
241094332d3Sopenharmony_ci    ret = mkdir(funcPath, S_IREAD | S_IWRITE);
242094332d3Sopenharmony_ci    if (ret != 0) {
243094332d3Sopenharmony_ci        HDF_LOGE("%{public}s: mkdir failed", __func__);
244094332d3Sopenharmony_ci        return HDF_ERR_IO;
245094332d3Sopenharmony_ci    }
246094332d3Sopenharmony_ci
247094332d3Sopenharmony_ci    ret = symlink(funcPath, configPath);
248094332d3Sopenharmony_ci    if (ret != 0) {
249094332d3Sopenharmony_ci        HDF_LOGE("%{public}s: symlink failed", __func__);
250094332d3Sopenharmony_ci        return HDF_ERR_IO;
251094332d3Sopenharmony_ci    }
252094332d3Sopenharmony_ci    usleep(SLEEP_DELAY);
253094332d3Sopenharmony_ci    return 0;
254094332d3Sopenharmony_ci}
255094332d3Sopenharmony_ci
256094332d3Sopenharmony_cistatic int32_t UsbFnReadFile(const char *path, char *str, uint16_t len)
257094332d3Sopenharmony_ci{
258094332d3Sopenharmony_ci    FILE *fp = fopen(path, "r");
259094332d3Sopenharmony_ci    if (fp == NULL) {
260094332d3Sopenharmony_ci        HDF_LOGE("%{public}s: fopen failed", __func__);
261094332d3Sopenharmony_ci        return HDF_ERR_BAD_FD;
262094332d3Sopenharmony_ci    }
263094332d3Sopenharmony_ci    if (fread(str, len, 1, fp) != 1) {
264094332d3Sopenharmony_ci        HDF_LOGE("%{public}s: fread failed", __func__);
265094332d3Sopenharmony_ci        (void)fclose(fp);
266094332d3Sopenharmony_ci        return HDF_ERR_IO;
267094332d3Sopenharmony_ci    }
268094332d3Sopenharmony_ci    (void)fclose(fp);
269094332d3Sopenharmony_ci    return 0;
270094332d3Sopenharmony_ci}
271094332d3Sopenharmony_ci
272094332d3Sopenharmony_cistatic int32_t UsbFnAdapterWriteUDC(const char *deviceName, const char *udcName, int32_t enable)
273094332d3Sopenharmony_ci{
274094332d3Sopenharmony_ci    char tmp[MAX_PATHLEN] = {0};
275094332d3Sopenharmony_ci    if (deviceName == NULL || udcName == NULL || IsDeviceDirExist(deviceName) == false) {
276094332d3Sopenharmony_ci        return HDF_ERR_INVALID_PARAM;
277094332d3Sopenharmony_ci    }
278094332d3Sopenharmony_ci
279094332d3Sopenharmony_ci    int32_t ret = snprintf_s(tmp, MAX_PATHLEN, MAX_PATHLEN - 1, "%s/%s/UDC", CONFIGFS_DIR, deviceName);
280094332d3Sopenharmony_ci    if (ret < 0) {
281094332d3Sopenharmony_ci        HDF_LOGE("%{public}s: snprintf_s failed", __func__);
282094332d3Sopenharmony_ci        return HDF_ERR_IO;
283094332d3Sopenharmony_ci    }
284094332d3Sopenharmony_ci    if (enable != 0) {
285094332d3Sopenharmony_ci        (void)UsbFnWriteFile(tmp, udcName);
286094332d3Sopenharmony_ci        char udcTmp[MAX_NAMELEN] = {0};
287094332d3Sopenharmony_ci        for (int32_t i = 0; i < OPEN_CNT; i++) {
288094332d3Sopenharmony_ci            (void)UsbFnReadFile(tmp, udcTmp, strlen(udcName));
289094332d3Sopenharmony_ci            if (!strcmp(udcName, udcTmp)) {
290094332d3Sopenharmony_ci                return 0;
291094332d3Sopenharmony_ci            }
292094332d3Sopenharmony_ci            usleep(SLEEP_DELAY);
293094332d3Sopenharmony_ci        }
294094332d3Sopenharmony_ci        if (strcmp(udcName, udcTmp)) {
295094332d3Sopenharmony_ci            return HDF_ERR_IO;
296094332d3Sopenharmony_ci        }
297094332d3Sopenharmony_ci    } else {
298094332d3Sopenharmony_ci        (void)UsbFnWriteFile(tmp, "\n");
299094332d3Sopenharmony_ci    }
300094332d3Sopenharmony_ci    return 0;
301094332d3Sopenharmony_ci}
302094332d3Sopenharmony_ci
303094332d3Sopenharmony_cistatic int32_t UsbFnAdapterOpenFn(void)
304094332d3Sopenharmony_ci{
305094332d3Sopenharmony_ci    int32_t i;
306094332d3Sopenharmony_ci    int32_t ep = -1;
307094332d3Sopenharmony_ci    for (i = 0; i < OPEN_CNT; i++) {
308094332d3Sopenharmony_ci        ep = open(USBFN_DEV, O_RDWR);
309094332d3Sopenharmony_ci        if (ep > 0) {
310094332d3Sopenharmony_ci            break;
311094332d3Sopenharmony_ci        }
312094332d3Sopenharmony_ci        usleep(SLEEP_DELAY);
313094332d3Sopenharmony_ci    }
314094332d3Sopenharmony_ci    if (ep < 0) {
315094332d3Sopenharmony_ci        HDF_LOGE("func not alloc");
316094332d3Sopenharmony_ci    }
317094332d3Sopenharmony_ci    return ep;
318094332d3Sopenharmony_ci}
319094332d3Sopenharmony_ci
320094332d3Sopenharmony_cistatic int32_t UsbFnAdapterClosefn(int32_t fd)
321094332d3Sopenharmony_ci{
322094332d3Sopenharmony_ci    if (fd <= 0) {
323094332d3Sopenharmony_ci        return HDF_ERR_INVALID_PARAM;
324094332d3Sopenharmony_ci    }
325094332d3Sopenharmony_ci    return close(fd);
326094332d3Sopenharmony_ci}
327094332d3Sopenharmony_ci
328094332d3Sopenharmony_cistatic int32_t UsbFnAdapterCreatInterface(const char *interfaceName, int32_t nameLen)
329094332d3Sopenharmony_ci{
330094332d3Sopenharmony_ci    int32_t ret;
331094332d3Sopenharmony_ci    int32_t fd;
332094332d3Sopenharmony_ci    struct FuncNew fnnew;
333094332d3Sopenharmony_ci    if (interfaceName == NULL || nameLen <= 0) {
334094332d3Sopenharmony_ci        return HDF_ERR_INVALID_PARAM;
335094332d3Sopenharmony_ci    }
336094332d3Sopenharmony_ci    fd = UsbFnAdapterOpenFn();
337094332d3Sopenharmony_ci    if (fd <= 0) {
338094332d3Sopenharmony_ci        HDF_LOGE("%{public}s: UsbFnAdapterOpenFn failed", __func__);
339094332d3Sopenharmony_ci        return HDF_ERR_IO;
340094332d3Sopenharmony_ci    }
341094332d3Sopenharmony_ci
342094332d3Sopenharmony_ci    fnnew.nameLen = (uint32_t)nameLen;
343094332d3Sopenharmony_ci    ret = snprintf_s(fnnew.name, MAX_NAMELEN, MAX_NAMELEN - 1, "%s", interfaceName);
344094332d3Sopenharmony_ci    if (ret < 0) {
345094332d3Sopenharmony_ci        HDF_LOGE("%{public}s: snprintf_s failed", __func__);
346094332d3Sopenharmony_ci        UsbFnAdapterClosefn(fd);
347094332d3Sopenharmony_ci        return HDF_ERR_IO;
348094332d3Sopenharmony_ci    }
349094332d3Sopenharmony_ci    ret = ioctl(fd, FUNCTIONFS_NEWFN, &fnnew);
350094332d3Sopenharmony_ci    if (ret != 0) {
351094332d3Sopenharmony_ci        HDF_LOGE("%{public}s: FUNCTIONFS_NEWFN failed", __func__);
352094332d3Sopenharmony_ci        UsbFnAdapterClosefn(fd);
353094332d3Sopenharmony_ci        return HDF_ERR_IO;
354094332d3Sopenharmony_ci    }
355094332d3Sopenharmony_ci    ret = UsbFnAdapterClosefn(fd);
356094332d3Sopenharmony_ci    usleep(SLEEP_DELAY);
357094332d3Sopenharmony_ci    return ret;
358094332d3Sopenharmony_ci}
359094332d3Sopenharmony_ci
360094332d3Sopenharmony_cistatic int32_t UsbFnAdapterDelInterface(const char *interfaceName, int32_t nameLen)
361094332d3Sopenharmony_ci{
362094332d3Sopenharmony_ci    int32_t ret;
363094332d3Sopenharmony_ci    struct FuncNew fnnew;
364094332d3Sopenharmony_ci    if (interfaceName == NULL || nameLen <= 0) {
365094332d3Sopenharmony_ci        return HDF_ERR_INVALID_PARAM;
366094332d3Sopenharmony_ci    }
367094332d3Sopenharmony_ci
368094332d3Sopenharmony_ci    int32_t fd = UsbFnAdapterOpenFn();
369094332d3Sopenharmony_ci    if (fd <= 0) {
370094332d3Sopenharmony_ci        return HDF_ERR_IO;
371094332d3Sopenharmony_ci    }
372094332d3Sopenharmony_ci
373094332d3Sopenharmony_ci    fnnew.nameLen = (uint32_t)nameLen;
374094332d3Sopenharmony_ci    ret = snprintf_s(fnnew.name, MAX_NAMELEN, MAX_NAMELEN - 1, "%s", interfaceName);
375094332d3Sopenharmony_ci    if (ret < 0) {
376094332d3Sopenharmony_ci        HDF_LOGE("%{public}s: snprintf_s failed", __func__);
377094332d3Sopenharmony_ci        UsbFnAdapterClosefn(fd);
378094332d3Sopenharmony_ci        return HDF_ERR_IO;
379094332d3Sopenharmony_ci    }
380094332d3Sopenharmony_ci    ret = ioctl(fd, FUNCTIONFS_DELFN, &fnnew);
381094332d3Sopenharmony_ci    if (ret != 0) {
382094332d3Sopenharmony_ci        HDF_LOGE("%{public}s: FUNCTIONFS_DELFN failed", __func__);
383094332d3Sopenharmony_ci        UsbFnAdapterClosefn(fd);
384094332d3Sopenharmony_ci        return HDF_ERR_IO;
385094332d3Sopenharmony_ci    }
386094332d3Sopenharmony_ci    ret = UsbFnAdapterClosefn(fd);
387094332d3Sopenharmony_ci    return ret;
388094332d3Sopenharmony_ci}
389094332d3Sopenharmony_ci
390094332d3Sopenharmony_cistatic int32_t UsbFnAdapterOpenPipe(const char *interfaceName, int32_t epIndex)
391094332d3Sopenharmony_ci{
392094332d3Sopenharmony_ci    if (interfaceName == NULL || epIndex < 0) {
393094332d3Sopenharmony_ci        return HDF_ERR_INVALID_PARAM;
394094332d3Sopenharmony_ci    }
395094332d3Sopenharmony_ci
396094332d3Sopenharmony_ci    char epName[MAX_NAMELEN];
397094332d3Sopenharmony_ci    int32_t ret = snprintf_s(epName, MAX_NAMELEN, MAX_NAMELEN - 1, "/dev/functionfs/%s.ep%d", interfaceName, epIndex);
398094332d3Sopenharmony_ci    if (ret < 0) {
399094332d3Sopenharmony_ci        HDF_LOGE("%{public}s: snprintf_s failed", __func__);
400094332d3Sopenharmony_ci        return HDF_ERR_IO;
401094332d3Sopenharmony_ci    }
402094332d3Sopenharmony_ci
403094332d3Sopenharmony_ci    int32_t ep = -1;
404094332d3Sopenharmony_ci    for (int32_t i = 0; i < OPEN_CNT; i++) {
405094332d3Sopenharmony_ci        ep = open(epName, O_RDWR);
406094332d3Sopenharmony_ci        if (ep > 0) {
407094332d3Sopenharmony_ci            break;
408094332d3Sopenharmony_ci        }
409094332d3Sopenharmony_ci        usleep(SLEEP_DELAY);
410094332d3Sopenharmony_ci    }
411094332d3Sopenharmony_ci    if (ep < 0) {
412094332d3Sopenharmony_ci        HDF_LOGE("unable to open %{public}s", epName);
413094332d3Sopenharmony_ci        return HDF_DEV_ERR_NO_DEVICE;
414094332d3Sopenharmony_ci    }
415094332d3Sopenharmony_ci    return ep;
416094332d3Sopenharmony_ci}
417094332d3Sopenharmony_ci
418094332d3Sopenharmony_cistatic int32_t UsbFnAdapterClosePipe(int32_t ep)
419094332d3Sopenharmony_ci{
420094332d3Sopenharmony_ci    if (ep <= 0) {
421094332d3Sopenharmony_ci        return HDF_ERR_INVALID_PARAM;
422094332d3Sopenharmony_ci    }
423094332d3Sopenharmony_ci
424094332d3Sopenharmony_ci    return close(ep);
425094332d3Sopenharmony_ci}
426094332d3Sopenharmony_ci
427094332d3Sopenharmony_cistatic void GetHeaderStr(struct UsbFnStrings ** const strings, struct UsbFunctionfsStringsHead *headerStr)
428094332d3Sopenharmony_ci{
429094332d3Sopenharmony_ci    uint32_t i, j;
430094332d3Sopenharmony_ci    uint32_t langCount = 0;
431094332d3Sopenharmony_ci    uint32_t strCount = 0;
432094332d3Sopenharmony_ci    uint32_t len = 0;
433094332d3Sopenharmony_ci    for (i = 0; strings[i] != NULL; i++) {
434094332d3Sopenharmony_ci        langCount++;
435094332d3Sopenharmony_ci        for (j = 0; strings[i]->strings[j].s; j++) {
436094332d3Sopenharmony_ci            len += strlen(strings[i]->strings[j].s) + sizeof(char);
437094332d3Sopenharmony_ci        }
438094332d3Sopenharmony_ci        strCount = j;
439094332d3Sopenharmony_ci    }
440094332d3Sopenharmony_ci    headerStr->magic = htole32(FUNCTIONFS_STRINGS_MAGIC);
441094332d3Sopenharmony_ci    headerStr->length = htole32(sizeof(struct UsbFunctionfsStringsHead) + langCount * sizeof(uint16_t) + len);
442094332d3Sopenharmony_ci    headerStr->strCount = strCount;
443094332d3Sopenharmony_ci    headerStr->langCount = langCount;
444094332d3Sopenharmony_ci}
445094332d3Sopenharmony_ci
446094332d3Sopenharmony_cistatic int32_t UsbFnWriteStrings(int32_t ep0, struct UsbFnStrings ** const strings)
447094332d3Sopenharmony_ci{
448094332d3Sopenharmony_ci    uint8_t *str = NULL;
449094332d3Sopenharmony_ci    uint8_t *whereDec = NULL;
450094332d3Sopenharmony_ci    uint32_t i, j;
451094332d3Sopenharmony_ci    int32_t ret;
452094332d3Sopenharmony_ci    struct UsbFunctionfsStringsHead headerStr = {0};
453094332d3Sopenharmony_ci
454094332d3Sopenharmony_ci    GetHeaderStr(strings, &headerStr);
455094332d3Sopenharmony_ci    str = UsbFnMemCalloc(headerStr.length);
456094332d3Sopenharmony_ci    if (str == NULL) {
457094332d3Sopenharmony_ci        return HDF_ERR_MALLOC_FAIL;
458094332d3Sopenharmony_ci    }
459094332d3Sopenharmony_ci
460094332d3Sopenharmony_ci    whereDec = str;
461094332d3Sopenharmony_ci    ret = memcpy_s(whereDec, headerStr.length, &headerStr, sizeof(struct UsbFunctionfsStringsHead));
462094332d3Sopenharmony_ci    if (ret != EOK) {
463094332d3Sopenharmony_ci        goto ERR;
464094332d3Sopenharmony_ci    }
465094332d3Sopenharmony_ci    whereDec += sizeof(struct UsbFunctionfsStringsHead);
466094332d3Sopenharmony_ci
467094332d3Sopenharmony_ci    for (i = 0; i < headerStr.langCount; i++) {
468094332d3Sopenharmony_ci        ret = memcpy_s(whereDec, headerStr.length - (whereDec - str), &strings[i]->language, sizeof(uint16_t));
469094332d3Sopenharmony_ci        if (ret != EOK) {
470094332d3Sopenharmony_ci            goto ERR;
471094332d3Sopenharmony_ci        }
472094332d3Sopenharmony_ci        whereDec += sizeof(uint16_t);
473094332d3Sopenharmony_ci        for (j = 0; j < headerStr.strCount; j++) {
474094332d3Sopenharmony_ci            if (strlen(strings[i]->strings[j].s)) {
475094332d3Sopenharmony_ci                ret = memcpy_s(whereDec, headerStr.length - (whereDec - str), strings[i]->strings[j].s,
476094332d3Sopenharmony_ci                    strlen(strings[i]->strings[j].s));
477094332d3Sopenharmony_ci                whereDec += strlen(strings[i]->strings[j].s) + sizeof(char);
478094332d3Sopenharmony_ci            } else {
479094332d3Sopenharmony_ci                break;
480094332d3Sopenharmony_ci            }
481094332d3Sopenharmony_ci            if (ret != EOK) {
482094332d3Sopenharmony_ci                goto ERR;
483094332d3Sopenharmony_ci            }
484094332d3Sopenharmony_ci        }
485094332d3Sopenharmony_ci    }
486094332d3Sopenharmony_ci
487094332d3Sopenharmony_ci    if (write(ep0, str, headerStr.length) < 0) {
488094332d3Sopenharmony_ci        goto ERR;
489094332d3Sopenharmony_ci    }
490094332d3Sopenharmony_ci    UsbFnMemFree(str);
491094332d3Sopenharmony_ci    return 0;
492094332d3Sopenharmony_ciERR:
493094332d3Sopenharmony_ci    UsbFnMemFree(str);
494094332d3Sopenharmony_ci    return HDF_FAILURE;
495094332d3Sopenharmony_ci}
496094332d3Sopenharmony_ci
497094332d3Sopenharmony_cistatic int32_t CopyCount(uint8_t **whereDec, uint32_t fsCount, uint32_t hsCount, uint32_t ssCount)
498094332d3Sopenharmony_ci{
499094332d3Sopenharmony_ci    int32_t ret;
500094332d3Sopenharmony_ci    if (fsCount != 0) {
501094332d3Sopenharmony_ci        ret = memcpy_s(*whereDec, sizeof(uint32_t), &fsCount, sizeof(uint32_t));
502094332d3Sopenharmony_ci        if (ret != EOK) {
503094332d3Sopenharmony_ci            return HDF_FAILURE;
504094332d3Sopenharmony_ci        }
505094332d3Sopenharmony_ci        *whereDec += sizeof(uint32_t);
506094332d3Sopenharmony_ci    }
507094332d3Sopenharmony_ci    if (hsCount != 0) {
508094332d3Sopenharmony_ci        ret = memcpy_s(*whereDec, sizeof(uint32_t), &hsCount, sizeof(uint32_t));
509094332d3Sopenharmony_ci        if (ret != EOK) {
510094332d3Sopenharmony_ci            return HDF_FAILURE;
511094332d3Sopenharmony_ci        }
512094332d3Sopenharmony_ci        *whereDec += sizeof(uint32_t);
513094332d3Sopenharmony_ci    }
514094332d3Sopenharmony_ci    if (ssCount != 0) {
515094332d3Sopenharmony_ci        ret = memcpy_s(*whereDec, sizeof(uint32_t), &ssCount, sizeof(uint32_t));
516094332d3Sopenharmony_ci        if (ret != EOK) {
517094332d3Sopenharmony_ci            return HDF_FAILURE;
518094332d3Sopenharmony_ci        }
519094332d3Sopenharmony_ci        *whereDec += sizeof(uint32_t);
520094332d3Sopenharmony_ci    }
521094332d3Sopenharmony_ci
522094332d3Sopenharmony_ci    return 0;
523094332d3Sopenharmony_ci}
524094332d3Sopenharmony_ci
525094332d3Sopenharmony_cistatic int32_t WriteFuncDescriptors(uint8_t ** const whereDec, struct UsbDescriptorHeader ** const headDes)
526094332d3Sopenharmony_ci{
527094332d3Sopenharmony_ci    for (uint32_t i = 0; headDes[i] != NULL; i++) {
528094332d3Sopenharmony_ci        if (memcpy_s(*whereDec, headDes[i]->bLength, headDes[i], headDes[i]->bLength) != EOK) {
529094332d3Sopenharmony_ci            HDF_LOGE("%{public}s: memcpy_s failed", __func__);
530094332d3Sopenharmony_ci            return HDF_FAILURE;
531094332d3Sopenharmony_ci        }
532094332d3Sopenharmony_ci        *whereDec += headDes[i]->bLength;
533094332d3Sopenharmony_ci    }
534094332d3Sopenharmony_ci    return 0;
535094332d3Sopenharmony_ci}
536094332d3Sopenharmony_ci
537094332d3Sopenharmony_cistatic void GetCountAndHead(struct UsbFunctionfsDescsHeadV2 *header, uint32_t *fsCount, uint32_t *hsCount,
538094332d3Sopenharmony_ci    uint32_t *ssCount, const struct UsbFnFunction *func)
539094332d3Sopenharmony_ci{
540094332d3Sopenharmony_ci    int32_t i;
541094332d3Sopenharmony_ci    uint32_t lenCount = 0;
542094332d3Sopenharmony_ci    uint32_t lenDes = 0;
543094332d3Sopenharmony_ci    *fsCount = 0;
544094332d3Sopenharmony_ci    *hsCount = 0;
545094332d3Sopenharmony_ci    *ssCount = 0;
546094332d3Sopenharmony_ci
547094332d3Sopenharmony_ci    for (i = 0; func->fsDescriptors[i] != NULL; i++) {
548094332d3Sopenharmony_ci        (*fsCount)++;
549094332d3Sopenharmony_ci        lenDes += func->fsDescriptors[i]->bLength;
550094332d3Sopenharmony_ci    }
551094332d3Sopenharmony_ci    for (i = 0; func->hsDescriptors[i] != NULL; i++) {
552094332d3Sopenharmony_ci        (*hsCount)++;
553094332d3Sopenharmony_ci        lenDes += func->hsDescriptors[i]->bLength;
554094332d3Sopenharmony_ci    }
555094332d3Sopenharmony_ci    for (i = 0; func->ssDescriptors[i] != NULL; i++) {
556094332d3Sopenharmony_ci        (*ssCount)++;
557094332d3Sopenharmony_ci        lenDes += func->ssDescriptors[i]->bLength;
558094332d3Sopenharmony_ci    }
559094332d3Sopenharmony_ci
560094332d3Sopenharmony_ci    if (*fsCount != 0) {
561094332d3Sopenharmony_ci        lenCount += sizeof(uint32_t);
562094332d3Sopenharmony_ci        header->flags |= htole32(FUNCTIONFS_HAS_FS_DESC);
563094332d3Sopenharmony_ci    }
564094332d3Sopenharmony_ci    if (*hsCount != 0) {
565094332d3Sopenharmony_ci        lenCount += sizeof(uint32_t);
566094332d3Sopenharmony_ci        header->flags |= htole32(FUNCTIONFS_HAS_HS_DESC);
567094332d3Sopenharmony_ci    }
568094332d3Sopenharmony_ci    if (*ssCount != 0) {
569094332d3Sopenharmony_ci        lenCount += sizeof(uint32_t);
570094332d3Sopenharmony_ci        header->flags |= htole32(FUNCTIONFS_HAS_SS_DESC);
571094332d3Sopenharmony_ci    }
572094332d3Sopenharmony_ci
573094332d3Sopenharmony_ci    header->magic = htole32(FUNCTIONFS_DESCRIPTORS_MAGIC_V2);
574094332d3Sopenharmony_ci    header->length = htole32(sizeof(struct UsbFunctionfsDescsHeadV2) + lenCount + lenDes);
575094332d3Sopenharmony_ci}
576094332d3Sopenharmony_ci
577094332d3Sopenharmony_cistatic int32_t UsbFnAdapterCreatPipes(int32_t ep0, const struct UsbFnFunction *func)
578094332d3Sopenharmony_ci{
579094332d3Sopenharmony_ci    uint8_t *dec = NULL;
580094332d3Sopenharmony_ci    uint8_t *whereDec = NULL;
581094332d3Sopenharmony_ci    uint32_t fsCount;
582094332d3Sopenharmony_ci    uint32_t hsCount;
583094332d3Sopenharmony_ci    uint32_t ssCount;
584094332d3Sopenharmony_ci    struct UsbFunctionfsDescsHeadV2 header = {0};
585094332d3Sopenharmony_ci
586094332d3Sopenharmony_ci    GetCountAndHead(&header, &fsCount, &hsCount, &ssCount, func);
587094332d3Sopenharmony_ci
588094332d3Sopenharmony_ci    dec = UsbFnMemCalloc(header.length);
589094332d3Sopenharmony_ci    if (dec == NULL) {
590094332d3Sopenharmony_ci        HDF_LOGE("%{public}s: UsbFnMemCalloc failed", __func__);
591094332d3Sopenharmony_ci        return HDF_ERR_MALLOC_FAIL;
592094332d3Sopenharmony_ci    }
593094332d3Sopenharmony_ci    whereDec = dec;
594094332d3Sopenharmony_ci
595094332d3Sopenharmony_ci    int32_t ret = memcpy_s(whereDec, header.length, &header, sizeof(struct UsbFunctionfsDescsHeadV2));
596094332d3Sopenharmony_ci    if (ret != EOK) {
597094332d3Sopenharmony_ci        UsbFnMemFree(dec);
598094332d3Sopenharmony_ci        return HDF_FAILURE;
599094332d3Sopenharmony_ci    }
600094332d3Sopenharmony_ci    whereDec += sizeof(struct UsbFunctionfsDescsHeadV2);
601094332d3Sopenharmony_ci
602094332d3Sopenharmony_ci    ret = CopyCount(&whereDec, fsCount, hsCount, ssCount);
603094332d3Sopenharmony_ci    if (ret != EOK) {
604094332d3Sopenharmony_ci        UsbFnMemFree(dec);
605094332d3Sopenharmony_ci        return HDF_FAILURE;
606094332d3Sopenharmony_ci    }
607094332d3Sopenharmony_ci
608094332d3Sopenharmony_ci    ret = WriteFuncDescriptors(&whereDec, func->fsDescriptors);
609094332d3Sopenharmony_ci    if (ret != EOK) {
610094332d3Sopenharmony_ci        UsbFnMemFree(dec);
611094332d3Sopenharmony_ci        return HDF_FAILURE;
612094332d3Sopenharmony_ci    }
613094332d3Sopenharmony_ci
614094332d3Sopenharmony_ci    ret = WriteFuncDescriptors(&whereDec, func->hsDescriptors);
615094332d3Sopenharmony_ci    if (ret != EOK) {
616094332d3Sopenharmony_ci        UsbFnMemFree(dec);
617094332d3Sopenharmony_ci        return HDF_FAILURE;
618094332d3Sopenharmony_ci    }
619094332d3Sopenharmony_ci
620094332d3Sopenharmony_ci    ret = WriteFuncDescriptors(&whereDec, func->ssDescriptors);
621094332d3Sopenharmony_ci    if (ret != EOK) {
622094332d3Sopenharmony_ci        UsbFnMemFree(dec);
623094332d3Sopenharmony_ci        return HDF_FAILURE;
624094332d3Sopenharmony_ci    }
625094332d3Sopenharmony_ci
626094332d3Sopenharmony_ci    if (write(ep0, dec, header.length) < 0) {
627094332d3Sopenharmony_ci        HDF_LOGE("unable do write descriptors");
628094332d3Sopenharmony_ci        UsbFnMemFree(dec);
629094332d3Sopenharmony_ci        return HDF_ERR_IO;
630094332d3Sopenharmony_ci    }
631094332d3Sopenharmony_ci
632094332d3Sopenharmony_ci    UsbFnMemFree(dec);
633094332d3Sopenharmony_ci    ret = UsbFnWriteStrings(ep0, func->strings);
634094332d3Sopenharmony_ci
635094332d3Sopenharmony_ci    usleep(SLEEP_DELAY);
636094332d3Sopenharmony_ci    return ret;
637094332d3Sopenharmony_ci}
638094332d3Sopenharmony_ci
639094332d3Sopenharmony_cistatic int32_t WriteDeviceId(const char *devName, const struct UsbDeviceDescriptor *desc)
640094332d3Sopenharmony_ci{
641094332d3Sopenharmony_ci    int32_t ret;
642094332d3Sopenharmony_ci    ret = UsbFnWriteProp(devName, "idVendor", desc->idVendor);
643094332d3Sopenharmony_ci    if (ret != HDF_SUCCESS) {
644094332d3Sopenharmony_ci        return HDF_ERR_INVALID_PARAM;
645094332d3Sopenharmony_ci    }
646094332d3Sopenharmony_ci    ret = UsbFnWriteProp(devName, "idProduct", desc->idProduct);
647094332d3Sopenharmony_ci    if (ret != HDF_SUCCESS) {
648094332d3Sopenharmony_ci        return HDF_ERR_INVALID_PARAM;
649094332d3Sopenharmony_ci    }
650094332d3Sopenharmony_ci    ret = UsbFnWriteProp(devName, "bcdUSB", desc->bcdUSB);
651094332d3Sopenharmony_ci    if (ret != HDF_SUCCESS) {
652094332d3Sopenharmony_ci        return HDF_ERR_INVALID_PARAM;
653094332d3Sopenharmony_ci    }
654094332d3Sopenharmony_ci    ret = UsbFnWriteProp(devName, "bcdDevice", desc->bcdDevice);
655094332d3Sopenharmony_ci    if (ret != HDF_SUCCESS) {
656094332d3Sopenharmony_ci        return HDF_ERR_INVALID_PARAM;
657094332d3Sopenharmony_ci    }
658094332d3Sopenharmony_ci    ret = UsbFnWriteProp(devName, "bDeviceClass", desc->bDeviceClass);
659094332d3Sopenharmony_ci    if (ret != HDF_SUCCESS) {
660094332d3Sopenharmony_ci        return HDF_ERR_INVALID_PARAM;
661094332d3Sopenharmony_ci    }
662094332d3Sopenharmony_ci    ret = UsbFnWriteProp(devName, "bDeviceSubClass", desc->bDeviceSubClass);
663094332d3Sopenharmony_ci    if (ret != HDF_SUCCESS) {
664094332d3Sopenharmony_ci        return HDF_ERR_INVALID_PARAM;
665094332d3Sopenharmony_ci    }
666094332d3Sopenharmony_ci    ret = UsbFnWriteProp(devName, "bDeviceProtocol", desc->bDeviceProtocol);
667094332d3Sopenharmony_ci    if (ret != HDF_SUCCESS) {
668094332d3Sopenharmony_ci        return HDF_ERR_INVALID_PARAM;
669094332d3Sopenharmony_ci    }
670094332d3Sopenharmony_ci    ret = UsbFnWriteProp(devName, "bMaxPacketSize0", desc->bMaxPacketSize0);
671094332d3Sopenharmony_ci    if (ret != HDF_SUCCESS) {
672094332d3Sopenharmony_ci        return HDF_ERR_INVALID_PARAM;
673094332d3Sopenharmony_ci    }
674094332d3Sopenharmony_ci    return 0;
675094332d3Sopenharmony_ci}
676094332d3Sopenharmony_ci
677094332d3Sopenharmony_cistatic int32_t WriteDeviceDescriptor(
678094332d3Sopenharmony_ci    const char *devName, const struct UsbDeviceDescriptor *desc, struct UsbFnStrings **strings)
679094332d3Sopenharmony_ci{
680094332d3Sopenharmony_ci    int32_t i, ret;
681094332d3Sopenharmony_ci    ret = WriteDeviceId(devName, desc);
682094332d3Sopenharmony_ci    if (ret != HDF_SUCCESS) {
683094332d3Sopenharmony_ci        return HDF_ERR_INVALID_PARAM;
684094332d3Sopenharmony_ci    }
685094332d3Sopenharmony_ci
686094332d3Sopenharmony_ci    for (i = 0; strings[i] != NULL; i++) {
687094332d3Sopenharmony_ci        ret = UsbFnWriteDesString(
688094332d3Sopenharmony_ci            devName, strings[i]->language, "manufacturer", strings[i]->strings[desc->iManufacturer].s);
689094332d3Sopenharmony_ci        if (ret != HDF_SUCCESS) {
690094332d3Sopenharmony_ci            return HDF_ERR_INVALID_PARAM;
691094332d3Sopenharmony_ci        }
692094332d3Sopenharmony_ci        ret = UsbFnWriteDesString(devName, strings[i]->language, "product", strings[i]->strings[desc->iProduct].s);
693094332d3Sopenharmony_ci        if (ret != HDF_SUCCESS) {
694094332d3Sopenharmony_ci            return HDF_ERR_INVALID_PARAM;
695094332d3Sopenharmony_ci        }
696094332d3Sopenharmony_ci    }
697094332d3Sopenharmony_ci    return 0;
698094332d3Sopenharmony_ci}
699094332d3Sopenharmony_ci
700094332d3Sopenharmony_cistatic int32_t CreatDeviceDir(const char *devName)
701094332d3Sopenharmony_ci{
702094332d3Sopenharmony_ci    int32_t ret;
703094332d3Sopenharmony_ci    char tmp[MAX_PATHLEN];
704094332d3Sopenharmony_ci    (void)memset_s(tmp, MAX_PATHLEN, 0, MAX_PATHLEN);
705094332d3Sopenharmony_ci    ret = snprintf_s(tmp, MAX_PATHLEN, MAX_PATHLEN - 1, "%s/%s", CONFIGFS_DIR, devName);
706094332d3Sopenharmony_ci    if (ret < 0) {
707094332d3Sopenharmony_ci        return HDF_ERR_IO;
708094332d3Sopenharmony_ci    }
709094332d3Sopenharmony_ci    if (!IsDirExist(tmp)) {
710094332d3Sopenharmony_ci        ret = mkdir(tmp, S_IREAD | S_IWRITE);
711094332d3Sopenharmony_ci        if (ret != 0) {
712094332d3Sopenharmony_ci            HDF_LOGE("%{public}s: mkdir failed", __func__);
713094332d3Sopenharmony_ci            return HDF_ERR_IO;
714094332d3Sopenharmony_ci        }
715094332d3Sopenharmony_ci    }
716094332d3Sopenharmony_ci    return 0;
717094332d3Sopenharmony_ci}
718094332d3Sopenharmony_ci
719094332d3Sopenharmony_cistatic int32_t WriteConfPowerAttributes(const char *devName, struct UsbFnConfiguration *config, uint8_t confVal)
720094332d3Sopenharmony_ci{
721094332d3Sopenharmony_ci    int32_t ret;
722094332d3Sopenharmony_ci    char configName[MAX_PATHLEN];
723094332d3Sopenharmony_ci    char tmp[MAX_PATHLEN], val[MAX_NAMELEN];
724094332d3Sopenharmony_ci    (void)memset_s(configName, MAX_PATHLEN, 0, MAX_PATHLEN);
725094332d3Sopenharmony_ci    ret = snprintf_s(configName, MAX_PATHLEN, MAX_PATHLEN - 1, "%s/%s/configs/b.%u", CONFIGFS_DIR, devName, confVal);
726094332d3Sopenharmony_ci    if (ret < 0) {
727094332d3Sopenharmony_ci        return HDF_ERR_IO;
728094332d3Sopenharmony_ci    }
729094332d3Sopenharmony_ci    if (!IsDirExist(configName)) {
730094332d3Sopenharmony_ci        ret = mkdir(configName, S_IREAD | S_IWRITE);
731094332d3Sopenharmony_ci        if (ret != 0) {
732094332d3Sopenharmony_ci            return HDF_ERR_IO;
733094332d3Sopenharmony_ci        }
734094332d3Sopenharmony_ci    }
735094332d3Sopenharmony_ci    (void)memset_s(tmp, MAX_PATHLEN, 0, MAX_PATHLEN);
736094332d3Sopenharmony_ci    ret = snprintf_s(tmp, MAX_PATHLEN, MAX_PATHLEN - 1, "%s/MaxPower", configName);
737094332d3Sopenharmony_ci    if (ret < 0) {
738094332d3Sopenharmony_ci        return HDF_ERR_IO;
739094332d3Sopenharmony_ci    }
740094332d3Sopenharmony_ci    (void)memset_s(val, MAX_NAMELEN, 0, MAX_NAMELEN);
741094332d3Sopenharmony_ci    ret = snprintf_s(val, MAX_NAMELEN, MAX_NAMELEN - 1, "%u", config->maxPower);
742094332d3Sopenharmony_ci    if (ret < 0) {
743094332d3Sopenharmony_ci        return HDF_ERR_IO;
744094332d3Sopenharmony_ci    }
745094332d3Sopenharmony_ci    ret = UsbFnWriteFile(tmp, val);
746094332d3Sopenharmony_ci    if (ret < 0) {
747094332d3Sopenharmony_ci        return HDF_ERR_INVALID_PARAM;
748094332d3Sopenharmony_ci    }
749094332d3Sopenharmony_ci
750094332d3Sopenharmony_ci    (void)memset_s(tmp, MAX_PATHLEN, 0, MAX_PATHLEN);
751094332d3Sopenharmony_ci    ret = snprintf_s(tmp, MAX_PATHLEN, MAX_PATHLEN - 1, "%s/bmAttributes", configName);
752094332d3Sopenharmony_ci    if (ret < 0) {
753094332d3Sopenharmony_ci        return HDF_ERR_IO;
754094332d3Sopenharmony_ci    }
755094332d3Sopenharmony_ci    (void)memset_s(val, MAX_NAMELEN, 0, MAX_NAMELEN);
756094332d3Sopenharmony_ci    ret = snprintf_s(val, MAX_NAMELEN, MAX_NAMELEN - 1, "0x%x", config->attributes);
757094332d3Sopenharmony_ci    if (ret < 0) {
758094332d3Sopenharmony_ci        return HDF_ERR_IO;
759094332d3Sopenharmony_ci    }
760094332d3Sopenharmony_ci    ret = UsbFnWriteFile(tmp, val);
761094332d3Sopenharmony_ci    if (ret < 0) {
762094332d3Sopenharmony_ci        return HDF_ERR_INVALID_PARAM;
763094332d3Sopenharmony_ci    }
764094332d3Sopenharmony_ci    return 0;
765094332d3Sopenharmony_ci}
766094332d3Sopenharmony_ci
767094332d3Sopenharmony_cistatic int32_t CreatKernelFunc(const char *devName, const struct UsbFnFunction *functions, uint8_t confVal)
768094332d3Sopenharmony_ci{
769094332d3Sopenharmony_ci    int32_t ret;
770094332d3Sopenharmony_ci    char configPath[MAX_PATHLEN];
771094332d3Sopenharmony_ci    char funcPath[MAX_PATHLEN];
772094332d3Sopenharmony_ci
773094332d3Sopenharmony_ci    (void)memset_s(funcPath, MAX_PATHLEN, 0, MAX_PATHLEN);
774094332d3Sopenharmony_ci    ret = snprintf_s(
775094332d3Sopenharmony_ci        funcPath, MAX_PATHLEN, MAX_PATHLEN - 1, "%s/%s/functions/%s", CONFIGFS_DIR, devName, functions->funcName);
776094332d3Sopenharmony_ci    if (ret < 0) {
777094332d3Sopenharmony_ci        return HDF_ERR_IO;
778094332d3Sopenharmony_ci    }
779094332d3Sopenharmony_ci
780094332d3Sopenharmony_ci    (void)memset_s(configPath, MAX_PATHLEN, 0, MAX_PATHLEN);
781094332d3Sopenharmony_ci    ret = snprintf_s(configPath, MAX_PATHLEN, MAX_PATHLEN - 1, "%s/%s/configs/b.%u/%s", CONFIGFS_DIR, devName, confVal,
782094332d3Sopenharmony_ci        functions->funcName);
783094332d3Sopenharmony_ci    if (ret < 0) {
784094332d3Sopenharmony_ci        return HDF_ERR_IO;
785094332d3Sopenharmony_ci    }
786094332d3Sopenharmony_ci    ret = UsbFnAdapterCreateFunc(configPath, funcPath);
787094332d3Sopenharmony_ci    if (ret != HDF_SUCCESS) {
788094332d3Sopenharmony_ci        HDF_LOGE("%{public}s: UsbFnAdapterCreateFunc failed", __func__);
789094332d3Sopenharmony_ci        return HDF_ERR_IO;
790094332d3Sopenharmony_ci    }
791094332d3Sopenharmony_ci    return ret;
792094332d3Sopenharmony_ci}
793094332d3Sopenharmony_ci
794094332d3Sopenharmony_cistatic void CleanConfigFs(const char *devName, const char *funcName);
795094332d3Sopenharmony_cistatic int32_t CreatFunc(const char *devName, const struct UsbFnFunction *functions, uint8_t confVal)
796094332d3Sopenharmony_ci{
797094332d3Sopenharmony_ci    int32_t fd, ret;
798094332d3Sopenharmony_ci    char interfaceName[MAX_NAMELEN];
799094332d3Sopenharmony_ci
800094332d3Sopenharmony_ci    ret = CreatKernelFunc(devName, functions, confVal);
801094332d3Sopenharmony_ci    if (ret < 0) {
802094332d3Sopenharmony_ci        return HDF_ERR_IO;
803094332d3Sopenharmony_ci    }
804094332d3Sopenharmony_ci
805094332d3Sopenharmony_ci    (void)memset_s(interfaceName, MAX_NAMELEN, 0, MAX_NAMELEN);
806094332d3Sopenharmony_ci    ret = snprintf_s(interfaceName, MAX_NAMELEN, MAX_NAMELEN - 1, "%s", functions->funcName);
807094332d3Sopenharmony_ci    if (ret < 0) {
808094332d3Sopenharmony_ci        return HDF_ERR_IO;
809094332d3Sopenharmony_ci    }
810094332d3Sopenharmony_ci    ret = UsbFnAdapterCreatInterface(interfaceName, strlen(interfaceName));
811094332d3Sopenharmony_ci    if (ret != HDF_SUCCESS) {
812094332d3Sopenharmony_ci        HDF_LOGE("%{public}s: UsbFnAdapterCreatInterface failed", __func__);
813094332d3Sopenharmony_ci        CleanConfigFs(devName, interfaceName);
814094332d3Sopenharmony_ci        return HDF_ERR_IO;
815094332d3Sopenharmony_ci    }
816094332d3Sopenharmony_ci
817094332d3Sopenharmony_ci    fd = UsbFnAdapterOpenPipe(interfaceName, 0);
818094332d3Sopenharmony_ci    if (fd <= 0) {
819094332d3Sopenharmony_ci        HDF_LOGE("%{public}s: UsbFnAdapterOpenPipe failed", __func__);
820094332d3Sopenharmony_ci        CleanConfigFs(devName, interfaceName);
821094332d3Sopenharmony_ci        return HDF_ERR_IO;
822094332d3Sopenharmony_ci    }
823094332d3Sopenharmony_ci    ret = UsbFnAdapterCreatPipes(fd, functions);
824094332d3Sopenharmony_ci    if (ret != HDF_SUCCESS) {
825094332d3Sopenharmony_ci        HDF_LOGE("%{public}s: UsbFnAdapterCreatPipes failed", __func__);
826094332d3Sopenharmony_ci        UsbFnAdapterClosePipe(fd);
827094332d3Sopenharmony_ci        return HDF_ERR_IO;
828094332d3Sopenharmony_ci    }
829094332d3Sopenharmony_ci    ret = UsbFnAdapterClosePipe(fd);
830094332d3Sopenharmony_ci    if (ret != HDF_SUCCESS) {
831094332d3Sopenharmony_ci        HDF_LOGE("%{public}s: UsbFnAdapterClosePipe failed", __func__);
832094332d3Sopenharmony_ci        return HDF_ERR_IO;
833094332d3Sopenharmony_ci    }
834094332d3Sopenharmony_ci    return 0;
835094332d3Sopenharmony_ci}
836094332d3Sopenharmony_ci
837094332d3Sopenharmony_cistatic void DelConfigDevice(const char *deviceName)
838094332d3Sopenharmony_ci{
839094332d3Sopenharmony_ci    int32_t ret;
840094332d3Sopenharmony_ci    char tmp[MAX_PATHLEN];
841094332d3Sopenharmony_ci    (void)memset_s(tmp, MAX_PATHLEN, 0, MAX_PATHLEN);
842094332d3Sopenharmony_ci    ret = snprintf_s(tmp, MAX_PATHLEN, MAX_PATHLEN - 1, "%s/%s/configs", CONFIGFS_DIR, deviceName);
843094332d3Sopenharmony_ci    if (ret < 0) {
844094332d3Sopenharmony_ci        return;
845094332d3Sopenharmony_ci    }
846094332d3Sopenharmony_ci    DeleteFile(tmp);
847094332d3Sopenharmony_ci
848094332d3Sopenharmony_ci    (void)memset_s(tmp, MAX_PATHLEN, 0, MAX_PATHLEN);
849094332d3Sopenharmony_ci    ret = snprintf_s(tmp, MAX_PATHLEN, MAX_PATHLEN - 1, "%s/%s/functions", CONFIGFS_DIR, deviceName);
850094332d3Sopenharmony_ci    if (ret < 0) {
851094332d3Sopenharmony_ci        return;
852094332d3Sopenharmony_ci    }
853094332d3Sopenharmony_ci    DeleteFile(tmp);
854094332d3Sopenharmony_ci
855094332d3Sopenharmony_ci    (void)memset_s(tmp, MAX_PATHLEN, 0, MAX_PATHLEN);
856094332d3Sopenharmony_ci    ret = snprintf_s(tmp, MAX_PATHLEN, MAX_PATHLEN - 1, "%s/%s/strings", CONFIGFS_DIR, deviceName);
857094332d3Sopenharmony_ci    if (ret < 0) {
858094332d3Sopenharmony_ci        return;
859094332d3Sopenharmony_ci    }
860094332d3Sopenharmony_ci    DeleteFile(tmp);
861094332d3Sopenharmony_ci
862094332d3Sopenharmony_ci    (void)memset_s(tmp, MAX_PATHLEN, 0, MAX_PATHLEN);
863094332d3Sopenharmony_ci    ret = snprintf_s(tmp, MAX_PATHLEN, MAX_PATHLEN - 1, "%s/%s", CONFIGFS_DIR, deviceName);
864094332d3Sopenharmony_ci    if (ret < 0) {
865094332d3Sopenharmony_ci        return;
866094332d3Sopenharmony_ci    }
867094332d3Sopenharmony_ci    rmdir(tmp);
868094332d3Sopenharmony_ci}
869094332d3Sopenharmony_ci
870094332d3Sopenharmony_cistatic void CleanConfigFs(const char *devName, const char *funcName)
871094332d3Sopenharmony_ci{
872094332d3Sopenharmony_ci    int32_t ret;
873094332d3Sopenharmony_ci    char tmp[MAX_PATHLEN];
874094332d3Sopenharmony_ci
875094332d3Sopenharmony_ci    (void)memset_s(tmp, MAX_PATHLEN, 0, MAX_PATHLEN);
876094332d3Sopenharmony_ci    ret = snprintf_s(tmp, MAX_PATHLEN, MAX_PATHLEN - 1, "%s/%s/configs/b.1/%s", CONFIGFS_DIR, devName, funcName);
877094332d3Sopenharmony_ci    if (ret < 0) {
878094332d3Sopenharmony_ci        return;
879094332d3Sopenharmony_ci    }
880094332d3Sopenharmony_ci    (void)remove(tmp);
881094332d3Sopenharmony_ci
882094332d3Sopenharmony_ci    (void)memset_s(tmp, MAX_PATHLEN, 0, MAX_PATHLEN);
883094332d3Sopenharmony_ci    ret = snprintf_s(tmp, MAX_PATHLEN, MAX_PATHLEN - 1, "%s/%s/functions/%s", CONFIGFS_DIR, devName, funcName);
884094332d3Sopenharmony_ci    if (ret < 0) {
885094332d3Sopenharmony_ci        return;
886094332d3Sopenharmony_ci    }
887094332d3Sopenharmony_ci    (void)remove(tmp);
888094332d3Sopenharmony_ci}
889094332d3Sopenharmony_ci
890094332d3Sopenharmony_cistatic void CleanFunction(const char *devName, const char *funcName)
891094332d3Sopenharmony_ci{
892094332d3Sopenharmony_ci    int32_t ret;
893094332d3Sopenharmony_ci    int32_t nameLength = (int32_t)strlen(funcName);
894094332d3Sopenharmony_ci    ret = UsbFnAdapterDelInterface(funcName, nameLength);
895094332d3Sopenharmony_ci    if (ret != HDF_SUCCESS) {
896094332d3Sopenharmony_ci        HDF_LOGE("%{public}s: UsbFnAdapterDelInterface failed", __func__);
897094332d3Sopenharmony_ci        return;
898094332d3Sopenharmony_ci    }
899094332d3Sopenharmony_ci    CleanConfigFs(devName, funcName);
900094332d3Sopenharmony_ci}
901094332d3Sopenharmony_ci
902094332d3Sopenharmony_cistatic void UsbFnAdapterCleanDevice(const char *devName)
903094332d3Sopenharmony_ci{
904094332d3Sopenharmony_ci    int32_t ret;
905094332d3Sopenharmony_ci    char tmp[MAX_PATHLEN];
906094332d3Sopenharmony_ci    DIR *dir = NULL;
907094332d3Sopenharmony_ci    struct dirent *ptr = NULL;
908094332d3Sopenharmony_ci
909094332d3Sopenharmony_ci    (void)memset_s(tmp, MAX_PATHLEN, 0, MAX_PATHLEN);
910094332d3Sopenharmony_ci    ret = snprintf_s(tmp, MAX_PATHLEN, MAX_PATHLEN - 1, "%s/%s/functions/", CONFIGFS_DIR, devName);
911094332d3Sopenharmony_ci    if (ret < 0) {
912094332d3Sopenharmony_ci        HDF_LOGE("%{public}s: snprintf_s failed", __func__);
913094332d3Sopenharmony_ci        return;
914094332d3Sopenharmony_ci    }
915094332d3Sopenharmony_ci    if ((dir = opendir(tmp)) == NULL) {
916094332d3Sopenharmony_ci        return;
917094332d3Sopenharmony_ci    }
918094332d3Sopenharmony_ci    while ((ptr = readdir(dir)) != NULL) {
919094332d3Sopenharmony_ci        if (strncmp(ptr->d_name, FUNCTION_GENERIC, strlen(FUNCTION_GENERIC))) {
920094332d3Sopenharmony_ci            continue;
921094332d3Sopenharmony_ci        }
922094332d3Sopenharmony_ci        CleanFunction(devName, ptr->d_name);
923094332d3Sopenharmony_ci    }
924094332d3Sopenharmony_ci    closedir(dir);
925094332d3Sopenharmony_ci}
926094332d3Sopenharmony_ci
927094332d3Sopenharmony_cistatic int32_t UsbFnAdapterDelDevice(const char *deviceName, const char *udcName, struct UsbFnDeviceDesc *des)
928094332d3Sopenharmony_ci{
929094332d3Sopenharmony_ci    uint32_t i, j;
930094332d3Sopenharmony_ci    int32_t ret;
931094332d3Sopenharmony_ci    if (deviceName == NULL) {
932094332d3Sopenharmony_ci        return HDF_ERR_INVALID_PARAM;
933094332d3Sopenharmony_ci    }
934094332d3Sopenharmony_ci    ret = UsbFnAdapterWriteUDC(deviceName, udcName, 0);
935094332d3Sopenharmony_ci    if (ret < 0) {
936094332d3Sopenharmony_ci        return ret;
937094332d3Sopenharmony_ci    }
938094332d3Sopenharmony_ci    for (i = 0; des->configs[i] != NULL; i++) {
939094332d3Sopenharmony_ci        for (j = 0; des->configs[i]->functions[j] != NULL; j++) {
940094332d3Sopenharmony_ci            if (des->configs[i]->functions[j]->enable == false) {
941094332d3Sopenharmony_ci                continue;
942094332d3Sopenharmony_ci            }
943094332d3Sopenharmony_ci            if (strncmp(des->configs[i]->functions[j]->funcName, FUNCTION_GENERIC, strlen(FUNCTION_GENERIC)) != 0) {
944094332d3Sopenharmony_ci                CleanConfigFs(deviceName, des->configs[i]->functions[j]->funcName);
945094332d3Sopenharmony_ci                continue;
946094332d3Sopenharmony_ci            }
947094332d3Sopenharmony_ci            CleanFunction(deviceName, des->configs[i]->functions[j]->funcName);
948094332d3Sopenharmony_ci        }
949094332d3Sopenharmony_ci    }
950094332d3Sopenharmony_ci
951094332d3Sopenharmony_ci    if (strcmp("g1", deviceName) != 0) {
952094332d3Sopenharmony_ci        DelConfigDevice(deviceName);
953094332d3Sopenharmony_ci    }
954094332d3Sopenharmony_ci    return 0;
955094332d3Sopenharmony_ci}
956094332d3Sopenharmony_ci
957094332d3Sopenharmony_cistatic bool CreateFun(struct UsbFnFunction *function, const char *devName, uint8_t *confVal, int32_t *ret)
958094332d3Sopenharmony_ci{
959094332d3Sopenharmony_ci    if (function == NULL || devName == NULL || confVal == NULL || ret == NULL) {
960094332d3Sopenharmony_ci        return false;
961094332d3Sopenharmony_ci    }
962094332d3Sopenharmony_ci
963094332d3Sopenharmony_ci    if (function->enable == false) {
964094332d3Sopenharmony_ci        return false;
965094332d3Sopenharmony_ci    }
966094332d3Sopenharmony_ci    if (strncmp(function->funcName, FUNCTION_GENERIC, strlen(FUNCTION_GENERIC)) != 0) {
967094332d3Sopenharmony_ci        *ret = CreatKernelFunc(devName, function, *confVal);
968094332d3Sopenharmony_ci    } else {
969094332d3Sopenharmony_ci        *ret = CreatFunc(devName, function, *confVal);
970094332d3Sopenharmony_ci    }
971094332d3Sopenharmony_ci    return true;
972094332d3Sopenharmony_ci}
973094332d3Sopenharmony_ci
974094332d3Sopenharmony_cistatic int32_t UsbFnAdapterCreateDevice(const char *udcName, const char *devName, struct UsbFnDeviceDesc *descriptor)
975094332d3Sopenharmony_ci{
976094332d3Sopenharmony_ci    uint32_t i, j;
977094332d3Sopenharmony_ci    int32_t ret;
978094332d3Sopenharmony_ci    uint8_t confVal;
979094332d3Sopenharmony_ci
980094332d3Sopenharmony_ci    UsbFnAdapterCleanDevice(devName);
981094332d3Sopenharmony_ci
982094332d3Sopenharmony_ci    ret = CreatDeviceDir(devName);
983094332d3Sopenharmony_ci    if (ret != HDF_SUCCESS) {
984094332d3Sopenharmony_ci        return HDF_ERR_IO;
985094332d3Sopenharmony_ci    }
986094332d3Sopenharmony_ci
987094332d3Sopenharmony_ci    ret = WriteDeviceDescriptor(devName, descriptor->deviceDesc, descriptor->deviceStrings);
988094332d3Sopenharmony_ci    if (ret != HDF_SUCCESS) {
989094332d3Sopenharmony_ci        HDF_LOGE("%{public}s: WriteDeviceDescriptor failed", __func__);
990094332d3Sopenharmony_ci        return HDF_ERR_IO;
991094332d3Sopenharmony_ci    }
992094332d3Sopenharmony_ci
993094332d3Sopenharmony_ci    for (i = 0; descriptor->configs[i] != NULL; i++) {
994094332d3Sopenharmony_ci        confVal = descriptor->configs[i]->configurationValue;
995094332d3Sopenharmony_ci        ret = WriteConfPowerAttributes(devName, descriptor->configs[i], confVal);
996094332d3Sopenharmony_ci        if (ret != HDF_SUCCESS) {
997094332d3Sopenharmony_ci            HDF_LOGE("%{public}s: WriteConfPowerAttributes failed", __func__);
998094332d3Sopenharmony_ci            return HDF_ERR_IO;
999094332d3Sopenharmony_ci        }
1000094332d3Sopenharmony_ci
1001094332d3Sopenharmony_ci        for (j = 0; descriptor->deviceStrings[j] != NULL; j++) {
1002094332d3Sopenharmony_ci            ret = UsbFnWriteConfString(devName, confVal, descriptor->deviceStrings[j]->language,
1003094332d3Sopenharmony_ci                descriptor->deviceStrings[j]->strings[descriptor->configs[i]->iConfiguration].s);
1004094332d3Sopenharmony_ci            if (ret < 0) {
1005094332d3Sopenharmony_ci                HDF_LOGE("%{public}s: UsbFnWriteConfString failed", __func__);
1006094332d3Sopenharmony_ci                return HDF_ERR_INVALID_PARAM;
1007094332d3Sopenharmony_ci            }
1008094332d3Sopenharmony_ci        }
1009094332d3Sopenharmony_ci
1010094332d3Sopenharmony_ci        for (j = 0; descriptor->configs[i]->functions[j] != NULL; j++) {
1011094332d3Sopenharmony_ci            if (!CreateFun(descriptor->configs[i]->functions[j], devName, &confVal, &ret)) {
1012094332d3Sopenharmony_ci                continue;
1013094332d3Sopenharmony_ci            }
1014094332d3Sopenharmony_ci            if (ret < 0) {
1015094332d3Sopenharmony_ci                HDF_LOGE("%{public}s: CreatFunc failed", __func__);
1016094332d3Sopenharmony_ci                (void)UsbFnAdapterWriteUDC(devName, "none", 0);
1017094332d3Sopenharmony_ci                (void)UsbFnAdapterWriteUDC(devName, udcName, 1);
1018094332d3Sopenharmony_ci                return HDF_ERR_INVALID_PARAM;
1019094332d3Sopenharmony_ci            }
1020094332d3Sopenharmony_ci        }
1021094332d3Sopenharmony_ci    }
1022094332d3Sopenharmony_ci
1023094332d3Sopenharmony_ci    return HDF_SUCCESS;
1024094332d3Sopenharmony_ci}
1025094332d3Sopenharmony_ci
1026094332d3Sopenharmony_cistatic int32_t UsbFnAdapterGetPipeInfo(int32_t ep, struct UsbFnPipeInfo * const pipeInfo)
1027094332d3Sopenharmony_ci{
1028094332d3Sopenharmony_ci    int32_t ret;
1029094332d3Sopenharmony_ci    if (ep <= 0 || pipeInfo == NULL) {
1030094332d3Sopenharmony_ci        return HDF_ERR_INVALID_PARAM;
1031094332d3Sopenharmony_ci    }
1032094332d3Sopenharmony_ci
1033094332d3Sopenharmony_ci    struct UsbEndpointDescriptor desc;
1034094332d3Sopenharmony_ci    ret = ioctl(ep, FUNCTIONFS_ENDPOINT_DESC, &desc);
1035094332d3Sopenharmony_ci    if (ret != 0) {
1036094332d3Sopenharmony_ci        HDF_LOGE("%{public}s: FUNCTIONFS_ENDPOINT_DESC failed", __func__);
1037094332d3Sopenharmony_ci        return HDF_ERR_IO;
1038094332d3Sopenharmony_ci    }
1039094332d3Sopenharmony_ci
1040094332d3Sopenharmony_ci    pipeInfo->type = desc.bmAttributes;
1041094332d3Sopenharmony_ci    pipeInfo->dir = USB_PIPE_DIRECTION_OUT;
1042094332d3Sopenharmony_ci    if (desc.bEndpointAddress & 0x80) {
1043094332d3Sopenharmony_ci        pipeInfo->dir = USB_PIPE_DIRECTION_IN;
1044094332d3Sopenharmony_ci    }
1045094332d3Sopenharmony_ci
1046094332d3Sopenharmony_ci    pipeInfo->maxPacketSize = desc.wMaxPacketSize;
1047094332d3Sopenharmony_ci    pipeInfo->interval = desc.bInterval;
1048094332d3Sopenharmony_ci
1049094332d3Sopenharmony_ci    return ret;
1050094332d3Sopenharmony_ci}
1051094332d3Sopenharmony_ci
1052094332d3Sopenharmony_cistatic int32_t UsbFnAdapterQueueInit(int32_t ep)
1053094332d3Sopenharmony_ci{
1054094332d3Sopenharmony_ci    if (ep <= 0) {
1055094332d3Sopenharmony_ci        return HDF_ERR_INVALID_PARAM;
1056094332d3Sopenharmony_ci    }
1057094332d3Sopenharmony_ci    return ioctl(ep, FUNCTIONFS_ENDPOINT_QUEUE_INIT, 0);
1058094332d3Sopenharmony_ci}
1059094332d3Sopenharmony_ci
1060094332d3Sopenharmony_cistatic int32_t UsbFnAdapterQueueDel(int32_t ep)
1061094332d3Sopenharmony_ci{
1062094332d3Sopenharmony_ci    if (ep <= 0) {
1063094332d3Sopenharmony_ci        return HDF_ERR_INVALID_PARAM;
1064094332d3Sopenharmony_ci    }
1065094332d3Sopenharmony_ci
1066094332d3Sopenharmony_ci    return ioctl(ep, FUNCTIONFS_ENDPOINT_QUEUE_DEL, 0);
1067094332d3Sopenharmony_ci}
1068094332d3Sopenharmony_ci
1069094332d3Sopenharmony_cistatic int32_t UsbFnAdapterReleaseBuf(int32_t ep, const struct GenericMemory *mem)
1070094332d3Sopenharmony_ci{
1071094332d3Sopenharmony_ci    if (ep <= 0 || mem == NULL) {
1072094332d3Sopenharmony_ci        return HDF_ERR_INVALID_PARAM;
1073094332d3Sopenharmony_ci    }
1074094332d3Sopenharmony_ci
1075094332d3Sopenharmony_ci    return ioctl(ep, FUNCTIONFS_ENDPOINT_RELEASE_BUF, mem);
1076094332d3Sopenharmony_ci}
1077094332d3Sopenharmony_ci
1078094332d3Sopenharmony_cistatic int32_t UsbFnAdapterPipeIo(int32_t ep, struct IoData *ioData)
1079094332d3Sopenharmony_ci{
1080094332d3Sopenharmony_ci    int32_t ret;
1081094332d3Sopenharmony_ci    if (ep <= 0 || ioData == NULL) {
1082094332d3Sopenharmony_ci        HDF_LOGE("%{public}s: invalid param", __func__);
1083094332d3Sopenharmony_ci        return HDF_ERR_INVALID_PARAM;
1084094332d3Sopenharmony_ci    }
1085094332d3Sopenharmony_ci
1086094332d3Sopenharmony_ci    if (ioData->read) {
1087094332d3Sopenharmony_ci        ret = ioctl(ep, FUNCTIONFS_ENDPOINT_READ, ioData);
1088094332d3Sopenharmony_ci    } else {
1089094332d3Sopenharmony_ci        ret = ioctl(ep, FUNCTIONFS_ENDPOINT_WRITE, ioData);
1090094332d3Sopenharmony_ci    }
1091094332d3Sopenharmony_ci
1092094332d3Sopenharmony_ci    if (ret < 0) {
1093094332d3Sopenharmony_ci        HDF_LOGE("%{public}s: handle endpoint failed errno:%{public}d", __func__, errno);
1094094332d3Sopenharmony_ci    }
1095094332d3Sopenharmony_ci
1096094332d3Sopenharmony_ci    return ret;
1097094332d3Sopenharmony_ci}
1098094332d3Sopenharmony_ci
1099094332d3Sopenharmony_cistatic int32_t UsbFnAdapterCancelIo(int32_t ep, const struct IoData * const ioData)
1100094332d3Sopenharmony_ci{
1101094332d3Sopenharmony_ci    if (ep <= 0 || ioData == NULL) {
1102094332d3Sopenharmony_ci        return HDF_ERR_INVALID_PARAM;
1103094332d3Sopenharmony_ci    }
1104094332d3Sopenharmony_ci    return ioctl(ep, FUNCTIONFS_ENDPOINT_RW_CANCEL, ioData);
1105094332d3Sopenharmony_ci}
1106094332d3Sopenharmony_ci
1107094332d3Sopenharmony_cistatic uint8_t *UsbFnAdapterMapAddr(int32_t ep, uint32_t len)
1108094332d3Sopenharmony_ci{
1109094332d3Sopenharmony_ci    if (ep <= 0) {
1110094332d3Sopenharmony_ci        return NULL;
1111094332d3Sopenharmony_ci    }
1112094332d3Sopenharmony_ci
1113094332d3Sopenharmony_ci    return mmap(NULL, len, PROT_READ | PROT_WRITE, MAP_SHARED, ep, 0);
1114094332d3Sopenharmony_ci}
1115094332d3Sopenharmony_ci
1116094332d3Sopenharmony_cistatic int32_t UsbFnAdapterUnmapAddr(uint8_t * const mapAddr, uint32_t len)
1117094332d3Sopenharmony_ci{
1118094332d3Sopenharmony_ci    if (mapAddr == NULL) {
1119094332d3Sopenharmony_ci        return HDF_ERR_INVALID_PARAM;
1120094332d3Sopenharmony_ci    }
1121094332d3Sopenharmony_ci
1122094332d3Sopenharmony_ci    return munmap(mapAddr, len);
1123094332d3Sopenharmony_ci}
1124094332d3Sopenharmony_ci
1125094332d3Sopenharmony_cistatic void Ep0Event(struct UsbFnEventAll *event, struct pollfd *pfds)
1126094332d3Sopenharmony_ci{
1127094332d3Sopenharmony_ci    int32_t ret;
1128094332d3Sopenharmony_ci    uint8_t i;
1129094332d3Sopenharmony_ci    for (i = 0; i < event->ep0Num; i++) {
1130094332d3Sopenharmony_ci        if ((uint32_t)pfds[i].revents & POLLIN) {
1131094332d3Sopenharmony_ci            ret = read(event->ep0[i], &event->ep0Event[i].ctrlEvent, sizeof(struct UsbFnCtrlEvent));
1132094332d3Sopenharmony_ci            if (!ret) {
1133094332d3Sopenharmony_ci                HDF_LOGE("unable to read event from ep0");
1134094332d3Sopenharmony_ci            }
1135094332d3Sopenharmony_ci            event->ep0Event[i].type = USB_EP0_CTRL_EVENT;
1136094332d3Sopenharmony_ci        } else if ((uint32_t)pfds[i].revents & POLLOUT) {
1137094332d3Sopenharmony_ci            ret = ioctl(event->ep0[i], FUNCTIONFS_ENDPOINT_GET_EP0_EVENT, &event->ep0Event[i].reqEvent);
1138094332d3Sopenharmony_ci            if (!ret) {
1139094332d3Sopenharmony_ci                HDF_LOGE("unable to read reqEvent from ep0");
1140094332d3Sopenharmony_ci            }
1141094332d3Sopenharmony_ci            event->ep0Event[i].type = USB_EP0_IO_COMPLETED;
1142094332d3Sopenharmony_ci        }
1143094332d3Sopenharmony_ci    }
1144094332d3Sopenharmony_ci}
1145094332d3Sopenharmony_ci
1146094332d3Sopenharmony_cistatic void EpEvent(struct UsbFnEventAll *event, struct pollfd *pfds)
1147094332d3Sopenharmony_ci{
1148094332d3Sopenharmony_ci    uint8_t i;
1149094332d3Sopenharmony_ci    for (i = 0; i < event->epNum; i++) {
1150094332d3Sopenharmony_ci        if ((pfds[i + event->ep0Num].revents & POLLIN)) {
1151094332d3Sopenharmony_ci            event->numEvent[i] = read(event->epx[i], event->reqEvent[i], MAX_REQUEST * sizeof(struct UsbFnReqEvent)) /
1152094332d3Sopenharmony_ci                sizeof(struct UsbFnReqEvent);
1153094332d3Sopenharmony_ci            if (!event->numEvent[i]) {
1154094332d3Sopenharmony_ci                HDF_LOGE("unable to read indexBuf from ep#");
1155094332d3Sopenharmony_ci            }
1156094332d3Sopenharmony_ci        }
1157094332d3Sopenharmony_ci    }
1158094332d3Sopenharmony_ci}
1159094332d3Sopenharmony_ci
1160094332d3Sopenharmony_cistatic int32_t UsbFnAdapterPollEvent(struct UsbFnEventAll *event, int32_t timeout)
1161094332d3Sopenharmony_ci{
1162094332d3Sopenharmony_ci    int32_t ret;
1163094332d3Sopenharmony_ci    uint8_t i;
1164094332d3Sopenharmony_ci    struct pollfd *pfds = NULL;
1165094332d3Sopenharmony_ci
1166094332d3Sopenharmony_ci    if (event == NULL) {
1167094332d3Sopenharmony_ci        return HDF_ERR_INVALID_PARAM;
1168094332d3Sopenharmony_ci    }
1169094332d3Sopenharmony_ci    if (event->ep0Num + event->epNum == 0) {
1170094332d3Sopenharmony_ci        return HDF_ERR_INVALID_PARAM;
1171094332d3Sopenharmony_ci    }
1172094332d3Sopenharmony_ci    pfds = UsbFnMemCalloc((event->ep0Num + event->epNum) * sizeof(struct pollfd));
1173094332d3Sopenharmony_ci    if (pfds == NULL) {
1174094332d3Sopenharmony_ci        return HDF_ERR_MALLOC_FAIL;
1175094332d3Sopenharmony_ci    }
1176094332d3Sopenharmony_ci    for (i = 0; i < event->ep0Num; i++) {
1177094332d3Sopenharmony_ci        if (event->ep0[i] <= 0) {
1178094332d3Sopenharmony_ci            UsbFnMemFree(pfds);
1179094332d3Sopenharmony_ci            HDF_LOGE("%{public}s: ep[%{public}d] = %{public}d", __func__, i, event->ep0[i]);
1180094332d3Sopenharmony_ci            return HDF_ERR_INVALID_PARAM;
1181094332d3Sopenharmony_ci        }
1182094332d3Sopenharmony_ci        pfds[i].fd = event->ep0[i];
1183094332d3Sopenharmony_ci        pfds[i].events = POLLIN | POLLOUT;
1184094332d3Sopenharmony_ci    }
1185094332d3Sopenharmony_ci    for (i = 0; i < event->epNum; i++) {
1186094332d3Sopenharmony_ci        if (event->epx[i] <= 0) {
1187094332d3Sopenharmony_ci            UsbFnMemFree(pfds);
1188094332d3Sopenharmony_ci            HDF_LOGE("%{public}s: ep[%{public}d] = %{public}d", __func__, i, event->epx[i]);
1189094332d3Sopenharmony_ci            return HDF_ERR_INVALID_PARAM;
1190094332d3Sopenharmony_ci        }
1191094332d3Sopenharmony_ci        pfds[i + event->ep0Num].fd = event->epx[i];
1192094332d3Sopenharmony_ci        pfds[i + event->ep0Num].events = POLLIN;
1193094332d3Sopenharmony_ci    }
1194094332d3Sopenharmony_ci    ret = poll(pfds, event->ep0Num + event->epNum, timeout);
1195094332d3Sopenharmony_ci    if (ret == 0) {
1196094332d3Sopenharmony_ci        UsbFnMemFree(pfds);
1197094332d3Sopenharmony_ci        return HDF_ERR_TIMEOUT;
1198094332d3Sopenharmony_ci    } else if (ret < 0) {
1199094332d3Sopenharmony_ci        HDF_LOGE("%{public}s: interrupt", __func__);
1200094332d3Sopenharmony_ci        UsbFnMemFree(pfds);
1201094332d3Sopenharmony_ci        return HDF_ERR_IO;
1202094332d3Sopenharmony_ci    }
1203094332d3Sopenharmony_ci    Ep0Event(event, pfds);
1204094332d3Sopenharmony_ci    EpEvent(event, pfds);
1205094332d3Sopenharmony_ci    UsbFnMemFree(pfds);
1206094332d3Sopenharmony_ci    return 0;
1207094332d3Sopenharmony_ci}
1208094332d3Sopenharmony_ci
1209094332d3Sopenharmony_cistatic int32_t UsbFnAdapterRequestGetStatus(int32_t ep, const struct IoData *ioData)
1210094332d3Sopenharmony_ci{
1211094332d3Sopenharmony_ci    if (ep <= 0 || ioData == NULL) {
1212094332d3Sopenharmony_ci        return HDF_ERR_INVALID_PARAM;
1213094332d3Sopenharmony_ci    }
1214094332d3Sopenharmony_ci    return ioctl(ep, FUNCTIONFS_ENDPOINT_GET_REQ_STATUS, ioData);
1215094332d3Sopenharmony_ci}
1216094332d3Sopenharmony_ci
1217094332d3Sopenharmony_civoid *UsbFnMemAlloc(size_t size)
1218094332d3Sopenharmony_ci{
1219094332d3Sopenharmony_ci    return UsbFnMemCalloc(size);
1220094332d3Sopenharmony_ci}
1221094332d3Sopenharmony_ci
1222094332d3Sopenharmony_civoid *UsbFnMemCalloc(size_t size)
1223094332d3Sopenharmony_ci{
1224094332d3Sopenharmony_ci    void *buf = OsalMemCalloc(size);
1225094332d3Sopenharmony_ci    if (buf == NULL) {
1226094332d3Sopenharmony_ci        HDF_LOGE("%{public}s: %{public}d, OsalMemCalloc failed", __func__, __LINE__);
1227094332d3Sopenharmony_ci        return NULL;
1228094332d3Sopenharmony_ci    }
1229094332d3Sopenharmony_ci    return buf;
1230094332d3Sopenharmony_ci}
1231094332d3Sopenharmony_ci
1232094332d3Sopenharmony_civoid UsbFnMemFree(const void *mem)
1233094332d3Sopenharmony_ci{
1234094332d3Sopenharmony_ci    if (mem == NULL) {
1235094332d3Sopenharmony_ci        HDF_LOGE("%{public}s:%{public}d invalid param mem.", __func__, __LINE__);
1236094332d3Sopenharmony_ci        return;
1237094332d3Sopenharmony_ci    }
1238094332d3Sopenharmony_ci    OsalMemFree((void *)mem);
1239094332d3Sopenharmony_ci    mem = NULL;
1240094332d3Sopenharmony_ci}
1241094332d3Sopenharmony_ci
1242094332d3Sopenharmony_cistatic struct UsbFnAdapterOps g_usbFnAdapter = {
1243094332d3Sopenharmony_ci    .createDevice = UsbFnAdapterCreateDevice,
1244094332d3Sopenharmony_ci    .delDevice = UsbFnAdapterDelDevice,
1245094332d3Sopenharmony_ci
1246094332d3Sopenharmony_ci    .openPipe = UsbFnAdapterOpenPipe,
1247094332d3Sopenharmony_ci    .closePipe = UsbFnAdapterClosePipe,
1248094332d3Sopenharmony_ci    .getPipeInfo = UsbFnAdapterGetPipeInfo,
1249094332d3Sopenharmony_ci
1250094332d3Sopenharmony_ci    .queueInit = UsbFnAdapterQueueInit,
1251094332d3Sopenharmony_ci    .queueDel = UsbFnAdapterQueueDel,
1252094332d3Sopenharmony_ci    .releaseBuf = UsbFnAdapterReleaseBuf,
1253094332d3Sopenharmony_ci    .pipeIo = UsbFnAdapterPipeIo,
1254094332d3Sopenharmony_ci    .cancelIo = UsbFnAdapterCancelIo,
1255094332d3Sopenharmony_ci    .getReqStatus = UsbFnAdapterRequestGetStatus,
1256094332d3Sopenharmony_ci    .mapAddr = UsbFnAdapterMapAddr,
1257094332d3Sopenharmony_ci    .unmapAddr = UsbFnAdapterUnmapAddr,
1258094332d3Sopenharmony_ci    .pollEvent = UsbFnAdapterPollEvent,
1259094332d3Sopenharmony_ci    .writeUDC = UsbFnAdapterWriteUDC,
1260094332d3Sopenharmony_ci    .writeProp = UsbFnWriteProp,
1261094332d3Sopenharmony_ci    .writeDesString = UsbFnWriteDesString,
1262094332d3Sopenharmony_ci};
1263094332d3Sopenharmony_ci
1264094332d3Sopenharmony_cistruct UsbFnAdapterOps *UsbFnAdapterGetOps(void)
1265094332d3Sopenharmony_ci{
1266094332d3Sopenharmony_ci    return &g_usbFnAdapter;
1267094332d3Sopenharmony_ci}
1268