1/*
2 * Copyright (c) 2021 Huawei Device Co., Ltd.
3 * Licensed under the Apache License, Version 2.0 (the "License");
4 * you may not use this file except in compliance with the License.
5 * You may obtain a copy of the License at
6 *
7 *     http://www.apache.org/licenses/LICENSE-2.0
8 *
9 * Unless required by applicable law or agreed to in writing, software
10 * distributed under the License is distributed on an "AS IS" BASIS,
11 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12 * See the License for the specific language governing permissions and
13 * limitations under the License.
14 */
15
16#include "adapter_if.h"
17
18#include <dirent.h>
19#include <endian.h>
20#include <fcntl.h>
21#include <poll.h>
22#include <stdarg.h>
23#include <stdio.h>
24#include <stdlib.h>
25#include <string.h>
26#include <sys/eventfd.h>
27#include <sys/ioctl.h>
28#include <sys/stat.h>
29#include <sys/types.h>
30#include <unistd.h>
31
32#include "osal_time.h"
33#include "usbd_wrapper.h"
34
35#define HDF_LOG_TAG adapter_if
36#define SLEEP_DELAY 100000
37#define OPEN_CNT    30
38
39static bool IsDirExist(const char *path)
40{
41    DIR *dir = NULL;
42
43    if (path == NULL) {
44        HDF_LOGE("%{public}s:%{public}d invalid param path.", __func__, __LINE__);
45        return false;
46    }
47
48    dir = opendir(path);
49    if (dir == NULL) {
50        HDF_LOGE("%{public}s: %{public}d: opendir failed!, path is %{public}s, errno is %{public}d", __func__, __LINE__,
51            path, errno);
52        return false;
53    }
54    closedir(dir);
55    return true;
56}
57
58static bool IsDir(const char *path)
59{
60    struct stat statBuf;
61    if (lstat(path, &statBuf) == 0) {
62        return S_ISDIR(statBuf.st_mode) != 0;
63    }
64    return false;
65}
66
67static void GetFilePath(const char *path, const char *fileName, char *filePath)
68{
69    int32_t ret = strcpy_s(filePath, MAX_PATHLEN - 1, path);
70    if (ret != EOK) {
71        HDF_LOGE("%{public}s: strcpy_s failed", __func__);
72        return;
73    }
74
75    if (strlen(path) > 0 && filePath[strlen(path) - 1] != '/') {
76        if (strlen(path) + 1 >= MAX_PATHLEN - strlen(fileName)) {
77            HDF_LOGE("%{public}s: file path too long", __func__);
78            return;
79        }
80        ret = strcat_s(filePath, MAX_PATHLEN - 1, "/");
81        if (ret != EOK) {
82            HDF_LOGE("%{public}s: strcat_s failed", __func__);
83            return;
84        }
85    }
86
87    ret = strcat_s(filePath, MAX_PATHLEN - 1, fileName);
88    if (ret != EOK) {
89        HDF_LOGE("%{public}s: strcat_s failed", __func__);
90    }
91}
92
93static bool IsSpecialDir(const char *path)
94{
95    return (strcmp(path, ".") == 0) || strcmp(path, "..") == 0;
96}
97
98static void DeleteFile(const char *path)
99{
100    DIR *dir = NULL;
101    struct dirent *dirInfo = NULL;
102
103    if (IsDir(path)) {
104        if ((dir = opendir(path)) == NULL) {
105            return;
106        }
107        char filePath[PATH_MAX];
108        while ((dirInfo = readdir(dir)) != NULL) {
109            GetFilePath(path, dirInfo->d_name, filePath);
110            if (IsSpecialDir(dirInfo->d_name)) {
111                continue;
112            }
113            DeleteFile(filePath);
114            (void)remove(filePath);
115        }
116        closedir(dir);
117    }
118}
119
120static bool IsDeviceDirExist(const char *deviceName)
121{
122    char tmp[MAX_PATHLEN] = {0};
123    int32_t ret = snprintf_s(tmp, MAX_PATHLEN, MAX_PATHLEN - 1, "%s/%s", CONFIGFS_DIR, deviceName);
124    if (ret < 0) {
125        HDF_LOGE("%{public}s: snprintf_s failed", __func__);
126        return false;
127    }
128
129    return IsDirExist(tmp);
130}
131
132static int32_t UsbFnWriteFile(const char *path, const char *str)
133{
134    size_t ret;
135    if (strlen(str) == 0) {
136        return 0;
137    }
138
139    FILE *fp = fopen(path, "w");
140    if (fp == NULL) {
141        HDF_LOGE("%{public}s: UsbFnWriteFile failed", __func__);
142        return HDF_ERR_BAD_FD;
143    }
144
145    ret = fwrite(str, strlen(str), 1, fp);
146    if (ret != 1) {
147        (void)fclose(fp);
148        return HDF_FAILURE;
149    }
150    (void)fclose(fp);
151    return 0;
152}
153
154static int32_t UsbFnWriteProp(const char *deviceName, const char *propName, uint32_t propValue)
155{
156    char tmp[MAX_PATHLEN] = {0};
157    char tmpVal[MAX_NAMELEN] = {0};
158    int32_t ret;
159    if (deviceName == NULL || propName == NULL) {
160        HDF_LOGE("%{public}s: INVALID PARAM", __func__);
161        return HDF_ERR_INVALID_PARAM;
162    }
163    ret = snprintf_s(tmp, MAX_PATHLEN, MAX_PATHLEN - 1, "%s/%s/%s", CONFIGFS_DIR, deviceName, propName);
164    if (ret < 0) {
165        HDF_LOGE("%{public}s: snprintf_s failed", __func__);
166        return HDF_ERR_IO;
167    }
168
169    ret = snprintf_s(tmpVal, MAX_NAMELEN, MAX_NAMELEN - 1, "0x%x", propValue);
170    if (ret < 0) {
171        HDF_LOGE("%{public}s: snprintf_s failed", __func__);
172        return HDF_ERR_IO;
173    }
174
175    return UsbFnWriteFile(tmp, tmpVal);
176}
177
178static int32_t UsbFnWriteConfString(const char *deviceName, int32_t configVal, uint16_t lang, const char *stringValue)
179{
180    int32_t ret;
181    char tmp[MAX_PATHLEN] = {0};
182    char tmpPath[MAX_PATHLEN] = {0};
183    ret = snprintf_s(tmp, MAX_PATHLEN, MAX_PATHLEN - 1, "%s/%s/configs/b.%d/strings/0x%x", CONFIGFS_DIR, deviceName,
184        configVal, lang);
185    if (ret < 0) {
186        HDF_LOGE("%{public}s: snprintf_s failed", __func__);
187        return HDF_ERR_IO;
188    }
189
190    if (!IsDirExist(tmp)) {
191        ret = mkdir(tmp, S_IREAD | S_IWRITE);
192        if (ret != 0) {
193            HDF_LOGE("%{public}s: mkdir failed", __func__);
194            return HDF_ERR_IO;
195        }
196    }
197
198    ret = snprintf_s(tmpPath, MAX_PATHLEN, MAX_PATHLEN - 1, "%s/configuration", tmp);
199    if (ret < 0) {
200        HDF_LOGE("%{public}s: snprintf_s failed", __func__);
201        return HDF_ERR_IO;
202    }
203
204    ret = UsbFnWriteFile(tmpPath, stringValue);
205    return ret;
206}
207
208static int32_t UsbFnWriteDesString(
209    const char *deviceName, uint16_t lang, const char *stringName, const char *stringValue)
210{
211    int32_t ret;
212    char tmp[MAX_PATHLEN] = {0};
213    char tmpPath[MAX_PATHLEN] = {0};
214    ret = snprintf_s(tmp, MAX_PATHLEN, MAX_PATHLEN - 1, "%s/%s/strings/0x%x", CONFIGFS_DIR, deviceName, lang);
215    if (ret < 0) {
216        HDF_LOGE("%{public}s: snprintf_s failed", __func__);
217        return HDF_ERR_IO;
218    }
219    if (!IsDirExist(tmp)) {
220        ret = mkdir(tmp, S_IREAD | S_IWRITE);
221        if (ret != 0) {
222            HDF_LOGE("%{public}s: mkdir failed", __func__);
223            return HDF_ERR_IO;
224        }
225    }
226
227    ret = snprintf_s(tmpPath, MAX_PATHLEN, MAX_PATHLEN - 1, "%s/%s", tmp, stringName);
228    if (ret < 0) {
229        HDF_LOGE("%{public}s: snprintf_s failed", __func__);
230        return HDF_ERR_IO;
231    }
232
233    ret = UsbFnWriteFile(tmpPath, stringValue);
234    return ret;
235}
236
237static int32_t UsbFnAdapterCreateFunc(const char *configPath, const char *funcPath)
238{
239    int32_t ret;
240
241    ret = mkdir(funcPath, S_IREAD | S_IWRITE);
242    if (ret != 0) {
243        HDF_LOGE("%{public}s: mkdir failed", __func__);
244        return HDF_ERR_IO;
245    }
246
247    ret = symlink(funcPath, configPath);
248    if (ret != 0) {
249        HDF_LOGE("%{public}s: symlink failed", __func__);
250        return HDF_ERR_IO;
251    }
252    usleep(SLEEP_DELAY);
253    return 0;
254}
255
256static int32_t UsbFnReadFile(const char *path, char *str, uint16_t len)
257{
258    FILE *fp = fopen(path, "r");
259    if (fp == NULL) {
260        HDF_LOGE("%{public}s: fopen failed", __func__);
261        return HDF_ERR_BAD_FD;
262    }
263    if (fread(str, len, 1, fp) != 1) {
264        HDF_LOGE("%{public}s: fread failed", __func__);
265        (void)fclose(fp);
266        return HDF_ERR_IO;
267    }
268    (void)fclose(fp);
269    return 0;
270}
271
272static int32_t UsbFnAdapterWriteUDC(const char *deviceName, const char *udcName, int32_t enable)
273{
274    char tmp[MAX_PATHLEN] = {0};
275    if (deviceName == NULL || udcName == NULL || IsDeviceDirExist(deviceName) == false) {
276        return HDF_ERR_INVALID_PARAM;
277    }
278
279    int32_t ret = snprintf_s(tmp, MAX_PATHLEN, MAX_PATHLEN - 1, "%s/%s/UDC", CONFIGFS_DIR, deviceName);
280    if (ret < 0) {
281        HDF_LOGE("%{public}s: snprintf_s failed", __func__);
282        return HDF_ERR_IO;
283    }
284    if (enable != 0) {
285        (void)UsbFnWriteFile(tmp, udcName);
286        char udcTmp[MAX_NAMELEN] = {0};
287        for (int32_t i = 0; i < OPEN_CNT; i++) {
288            (void)UsbFnReadFile(tmp, udcTmp, strlen(udcName));
289            if (!strcmp(udcName, udcTmp)) {
290                return 0;
291            }
292            usleep(SLEEP_DELAY);
293        }
294        if (strcmp(udcName, udcTmp)) {
295            return HDF_ERR_IO;
296        }
297    } else {
298        (void)UsbFnWriteFile(tmp, "\n");
299    }
300    return 0;
301}
302
303static int32_t UsbFnAdapterOpenFn(void)
304{
305    int32_t i;
306    int32_t ep = -1;
307    for (i = 0; i < OPEN_CNT; i++) {
308        ep = open(USBFN_DEV, O_RDWR);
309        if (ep > 0) {
310            break;
311        }
312        usleep(SLEEP_DELAY);
313    }
314    if (ep < 0) {
315        HDF_LOGE("func not alloc");
316    }
317    return ep;
318}
319
320static int32_t UsbFnAdapterClosefn(int32_t fd)
321{
322    if (fd <= 0) {
323        return HDF_ERR_INVALID_PARAM;
324    }
325    return close(fd);
326}
327
328static int32_t UsbFnAdapterCreatInterface(const char *interfaceName, int32_t nameLen)
329{
330    int32_t ret;
331    int32_t fd;
332    struct FuncNew fnnew;
333    if (interfaceName == NULL || nameLen <= 0) {
334        return HDF_ERR_INVALID_PARAM;
335    }
336    fd = UsbFnAdapterOpenFn();
337    if (fd <= 0) {
338        HDF_LOGE("%{public}s: UsbFnAdapterOpenFn failed", __func__);
339        return HDF_ERR_IO;
340    }
341
342    fnnew.nameLen = (uint32_t)nameLen;
343    ret = snprintf_s(fnnew.name, MAX_NAMELEN, MAX_NAMELEN - 1, "%s", interfaceName);
344    if (ret < 0) {
345        HDF_LOGE("%{public}s: snprintf_s failed", __func__);
346        UsbFnAdapterClosefn(fd);
347        return HDF_ERR_IO;
348    }
349    ret = ioctl(fd, FUNCTIONFS_NEWFN, &fnnew);
350    if (ret != 0) {
351        HDF_LOGE("%{public}s: FUNCTIONFS_NEWFN failed", __func__);
352        UsbFnAdapterClosefn(fd);
353        return HDF_ERR_IO;
354    }
355    ret = UsbFnAdapterClosefn(fd);
356    usleep(SLEEP_DELAY);
357    return ret;
358}
359
360static int32_t UsbFnAdapterDelInterface(const char *interfaceName, int32_t nameLen)
361{
362    int32_t ret;
363    struct FuncNew fnnew;
364    if (interfaceName == NULL || nameLen <= 0) {
365        return HDF_ERR_INVALID_PARAM;
366    }
367
368    int32_t fd = UsbFnAdapterOpenFn();
369    if (fd <= 0) {
370        return HDF_ERR_IO;
371    }
372
373    fnnew.nameLen = (uint32_t)nameLen;
374    ret = snprintf_s(fnnew.name, MAX_NAMELEN, MAX_NAMELEN - 1, "%s", interfaceName);
375    if (ret < 0) {
376        HDF_LOGE("%{public}s: snprintf_s failed", __func__);
377        UsbFnAdapterClosefn(fd);
378        return HDF_ERR_IO;
379    }
380    ret = ioctl(fd, FUNCTIONFS_DELFN, &fnnew);
381    if (ret != 0) {
382        HDF_LOGE("%{public}s: FUNCTIONFS_DELFN failed", __func__);
383        UsbFnAdapterClosefn(fd);
384        return HDF_ERR_IO;
385    }
386    ret = UsbFnAdapterClosefn(fd);
387    return ret;
388}
389
390static int32_t UsbFnAdapterOpenPipe(const char *interfaceName, int32_t epIndex)
391{
392    if (interfaceName == NULL || epIndex < 0) {
393        return HDF_ERR_INVALID_PARAM;
394    }
395
396    char epName[MAX_NAMELEN];
397    int32_t ret = snprintf_s(epName, MAX_NAMELEN, MAX_NAMELEN - 1, "/dev/functionfs/%s.ep%d", interfaceName, epIndex);
398    if (ret < 0) {
399        HDF_LOGE("%{public}s: snprintf_s failed", __func__);
400        return HDF_ERR_IO;
401    }
402
403    int32_t ep = -1;
404    for (int32_t i = 0; i < OPEN_CNT; i++) {
405        ep = open(epName, O_RDWR);
406        if (ep > 0) {
407            break;
408        }
409        usleep(SLEEP_DELAY);
410    }
411    if (ep < 0) {
412        HDF_LOGE("unable to open %{public}s", epName);
413        return HDF_DEV_ERR_NO_DEVICE;
414    }
415    return ep;
416}
417
418static int32_t UsbFnAdapterClosePipe(int32_t ep)
419{
420    if (ep <= 0) {
421        return HDF_ERR_INVALID_PARAM;
422    }
423
424    return close(ep);
425}
426
427static void GetHeaderStr(struct UsbFnStrings ** const strings, struct UsbFunctionfsStringsHead *headerStr)
428{
429    uint32_t i, j;
430    uint32_t langCount = 0;
431    uint32_t strCount = 0;
432    uint32_t len = 0;
433    for (i = 0; strings[i] != NULL; i++) {
434        langCount++;
435        for (j = 0; strings[i]->strings[j].s; j++) {
436            len += strlen(strings[i]->strings[j].s) + sizeof(char);
437        }
438        strCount = j;
439    }
440    headerStr->magic = htole32(FUNCTIONFS_STRINGS_MAGIC);
441    headerStr->length = htole32(sizeof(struct UsbFunctionfsStringsHead) + langCount * sizeof(uint16_t) + len);
442    headerStr->strCount = strCount;
443    headerStr->langCount = langCount;
444}
445
446static int32_t UsbFnWriteStrings(int32_t ep0, struct UsbFnStrings ** const strings)
447{
448    uint8_t *str = NULL;
449    uint8_t *whereDec = NULL;
450    uint32_t i, j;
451    int32_t ret;
452    struct UsbFunctionfsStringsHead headerStr = {0};
453
454    GetHeaderStr(strings, &headerStr);
455    str = UsbFnMemCalloc(headerStr.length);
456    if (str == NULL) {
457        return HDF_ERR_MALLOC_FAIL;
458    }
459
460    whereDec = str;
461    ret = memcpy_s(whereDec, headerStr.length, &headerStr, sizeof(struct UsbFunctionfsStringsHead));
462    if (ret != EOK) {
463        goto ERR;
464    }
465    whereDec += sizeof(struct UsbFunctionfsStringsHead);
466
467    for (i = 0; i < headerStr.langCount; i++) {
468        ret = memcpy_s(whereDec, headerStr.length - (whereDec - str), &strings[i]->language, sizeof(uint16_t));
469        if (ret != EOK) {
470            goto ERR;
471        }
472        whereDec += sizeof(uint16_t);
473        for (j = 0; j < headerStr.strCount; j++) {
474            if (strlen(strings[i]->strings[j].s)) {
475                ret = memcpy_s(whereDec, headerStr.length - (whereDec - str), strings[i]->strings[j].s,
476                    strlen(strings[i]->strings[j].s));
477                whereDec += strlen(strings[i]->strings[j].s) + sizeof(char);
478            } else {
479                break;
480            }
481            if (ret != EOK) {
482                goto ERR;
483            }
484        }
485    }
486
487    if (write(ep0, str, headerStr.length) < 0) {
488        goto ERR;
489    }
490    UsbFnMemFree(str);
491    return 0;
492ERR:
493    UsbFnMemFree(str);
494    return HDF_FAILURE;
495}
496
497static int32_t CopyCount(uint8_t **whereDec, uint32_t fsCount, uint32_t hsCount, uint32_t ssCount)
498{
499    int32_t ret;
500    if (fsCount != 0) {
501        ret = memcpy_s(*whereDec, sizeof(uint32_t), &fsCount, sizeof(uint32_t));
502        if (ret != EOK) {
503            return HDF_FAILURE;
504        }
505        *whereDec += sizeof(uint32_t);
506    }
507    if (hsCount != 0) {
508        ret = memcpy_s(*whereDec, sizeof(uint32_t), &hsCount, sizeof(uint32_t));
509        if (ret != EOK) {
510            return HDF_FAILURE;
511        }
512        *whereDec += sizeof(uint32_t);
513    }
514    if (ssCount != 0) {
515        ret = memcpy_s(*whereDec, sizeof(uint32_t), &ssCount, sizeof(uint32_t));
516        if (ret != EOK) {
517            return HDF_FAILURE;
518        }
519        *whereDec += sizeof(uint32_t);
520    }
521
522    return 0;
523}
524
525static int32_t WriteFuncDescriptors(uint8_t ** const whereDec, struct UsbDescriptorHeader ** const headDes)
526{
527    for (uint32_t i = 0; headDes[i] != NULL; i++) {
528        if (memcpy_s(*whereDec, headDes[i]->bLength, headDes[i], headDes[i]->bLength) != EOK) {
529            HDF_LOGE("%{public}s: memcpy_s failed", __func__);
530            return HDF_FAILURE;
531        }
532        *whereDec += headDes[i]->bLength;
533    }
534    return 0;
535}
536
537static void GetCountAndHead(struct UsbFunctionfsDescsHeadV2 *header, uint32_t *fsCount, uint32_t *hsCount,
538    uint32_t *ssCount, const struct UsbFnFunction *func)
539{
540    int32_t i;
541    uint32_t lenCount = 0;
542    uint32_t lenDes = 0;
543    *fsCount = 0;
544    *hsCount = 0;
545    *ssCount = 0;
546
547    for (i = 0; func->fsDescriptors[i] != NULL; i++) {
548        (*fsCount)++;
549        lenDes += func->fsDescriptors[i]->bLength;
550    }
551    for (i = 0; func->hsDescriptors[i] != NULL; i++) {
552        (*hsCount)++;
553        lenDes += func->hsDescriptors[i]->bLength;
554    }
555    for (i = 0; func->ssDescriptors[i] != NULL; i++) {
556        (*ssCount)++;
557        lenDes += func->ssDescriptors[i]->bLength;
558    }
559
560    if (*fsCount != 0) {
561        lenCount += sizeof(uint32_t);
562        header->flags |= htole32(FUNCTIONFS_HAS_FS_DESC);
563    }
564    if (*hsCount != 0) {
565        lenCount += sizeof(uint32_t);
566        header->flags |= htole32(FUNCTIONFS_HAS_HS_DESC);
567    }
568    if (*ssCount != 0) {
569        lenCount += sizeof(uint32_t);
570        header->flags |= htole32(FUNCTIONFS_HAS_SS_DESC);
571    }
572
573    header->magic = htole32(FUNCTIONFS_DESCRIPTORS_MAGIC_V2);
574    header->length = htole32(sizeof(struct UsbFunctionfsDescsHeadV2) + lenCount + lenDes);
575}
576
577static int32_t UsbFnAdapterCreatPipes(int32_t ep0, const struct UsbFnFunction *func)
578{
579    uint8_t *dec = NULL;
580    uint8_t *whereDec = NULL;
581    uint32_t fsCount;
582    uint32_t hsCount;
583    uint32_t ssCount;
584    struct UsbFunctionfsDescsHeadV2 header = {0};
585
586    GetCountAndHead(&header, &fsCount, &hsCount, &ssCount, func);
587
588    dec = UsbFnMemCalloc(header.length);
589    if (dec == NULL) {
590        HDF_LOGE("%{public}s: UsbFnMemCalloc failed", __func__);
591        return HDF_ERR_MALLOC_FAIL;
592    }
593    whereDec = dec;
594
595    int32_t ret = memcpy_s(whereDec, header.length, &header, sizeof(struct UsbFunctionfsDescsHeadV2));
596    if (ret != EOK) {
597        UsbFnMemFree(dec);
598        return HDF_FAILURE;
599    }
600    whereDec += sizeof(struct UsbFunctionfsDescsHeadV2);
601
602    ret = CopyCount(&whereDec, fsCount, hsCount, ssCount);
603    if (ret != EOK) {
604        UsbFnMemFree(dec);
605        return HDF_FAILURE;
606    }
607
608    ret = WriteFuncDescriptors(&whereDec, func->fsDescriptors);
609    if (ret != EOK) {
610        UsbFnMemFree(dec);
611        return HDF_FAILURE;
612    }
613
614    ret = WriteFuncDescriptors(&whereDec, func->hsDescriptors);
615    if (ret != EOK) {
616        UsbFnMemFree(dec);
617        return HDF_FAILURE;
618    }
619
620    ret = WriteFuncDescriptors(&whereDec, func->ssDescriptors);
621    if (ret != EOK) {
622        UsbFnMemFree(dec);
623        return HDF_FAILURE;
624    }
625
626    if (write(ep0, dec, header.length) < 0) {
627        HDF_LOGE("unable do write descriptors");
628        UsbFnMemFree(dec);
629        return HDF_ERR_IO;
630    }
631
632    UsbFnMemFree(dec);
633    ret = UsbFnWriteStrings(ep0, func->strings);
634
635    usleep(SLEEP_DELAY);
636    return ret;
637}
638
639static int32_t WriteDeviceId(const char *devName, const struct UsbDeviceDescriptor *desc)
640{
641    int32_t ret;
642    ret = UsbFnWriteProp(devName, "idVendor", desc->idVendor);
643    if (ret != HDF_SUCCESS) {
644        return HDF_ERR_INVALID_PARAM;
645    }
646    ret = UsbFnWriteProp(devName, "idProduct", desc->idProduct);
647    if (ret != HDF_SUCCESS) {
648        return HDF_ERR_INVALID_PARAM;
649    }
650    ret = UsbFnWriteProp(devName, "bcdUSB", desc->bcdUSB);
651    if (ret != HDF_SUCCESS) {
652        return HDF_ERR_INVALID_PARAM;
653    }
654    ret = UsbFnWriteProp(devName, "bcdDevice", desc->bcdDevice);
655    if (ret != HDF_SUCCESS) {
656        return HDF_ERR_INVALID_PARAM;
657    }
658    ret = UsbFnWriteProp(devName, "bDeviceClass", desc->bDeviceClass);
659    if (ret != HDF_SUCCESS) {
660        return HDF_ERR_INVALID_PARAM;
661    }
662    ret = UsbFnWriteProp(devName, "bDeviceSubClass", desc->bDeviceSubClass);
663    if (ret != HDF_SUCCESS) {
664        return HDF_ERR_INVALID_PARAM;
665    }
666    ret = UsbFnWriteProp(devName, "bDeviceProtocol", desc->bDeviceProtocol);
667    if (ret != HDF_SUCCESS) {
668        return HDF_ERR_INVALID_PARAM;
669    }
670    ret = UsbFnWriteProp(devName, "bMaxPacketSize0", desc->bMaxPacketSize0);
671    if (ret != HDF_SUCCESS) {
672        return HDF_ERR_INVALID_PARAM;
673    }
674    return 0;
675}
676
677static int32_t WriteDeviceDescriptor(
678    const char *devName, const struct UsbDeviceDescriptor *desc, struct UsbFnStrings **strings)
679{
680    int32_t i, ret;
681    ret = WriteDeviceId(devName, desc);
682    if (ret != HDF_SUCCESS) {
683        return HDF_ERR_INVALID_PARAM;
684    }
685
686    for (i = 0; strings[i] != NULL; i++) {
687        ret = UsbFnWriteDesString(
688            devName, strings[i]->language, "manufacturer", strings[i]->strings[desc->iManufacturer].s);
689        if (ret != HDF_SUCCESS) {
690            return HDF_ERR_INVALID_PARAM;
691        }
692        ret = UsbFnWriteDesString(devName, strings[i]->language, "product", strings[i]->strings[desc->iProduct].s);
693        if (ret != HDF_SUCCESS) {
694            return HDF_ERR_INVALID_PARAM;
695        }
696    }
697    return 0;
698}
699
700static int32_t CreatDeviceDir(const char *devName)
701{
702    int32_t ret;
703    char tmp[MAX_PATHLEN];
704    (void)memset_s(tmp, MAX_PATHLEN, 0, MAX_PATHLEN);
705    ret = snprintf_s(tmp, MAX_PATHLEN, MAX_PATHLEN - 1, "%s/%s", CONFIGFS_DIR, devName);
706    if (ret < 0) {
707        return HDF_ERR_IO;
708    }
709    if (!IsDirExist(tmp)) {
710        ret = mkdir(tmp, S_IREAD | S_IWRITE);
711        if (ret != 0) {
712            HDF_LOGE("%{public}s: mkdir failed", __func__);
713            return HDF_ERR_IO;
714        }
715    }
716    return 0;
717}
718
719static int32_t WriteConfPowerAttributes(const char *devName, struct UsbFnConfiguration *config, uint8_t confVal)
720{
721    int32_t ret;
722    char configName[MAX_PATHLEN];
723    char tmp[MAX_PATHLEN], val[MAX_NAMELEN];
724    (void)memset_s(configName, MAX_PATHLEN, 0, MAX_PATHLEN);
725    ret = snprintf_s(configName, MAX_PATHLEN, MAX_PATHLEN - 1, "%s/%s/configs/b.%u", CONFIGFS_DIR, devName, confVal);
726    if (ret < 0) {
727        return HDF_ERR_IO;
728    }
729    if (!IsDirExist(configName)) {
730        ret = mkdir(configName, S_IREAD | S_IWRITE);
731        if (ret != 0) {
732            return HDF_ERR_IO;
733        }
734    }
735    (void)memset_s(tmp, MAX_PATHLEN, 0, MAX_PATHLEN);
736    ret = snprintf_s(tmp, MAX_PATHLEN, MAX_PATHLEN - 1, "%s/MaxPower", configName);
737    if (ret < 0) {
738        return HDF_ERR_IO;
739    }
740    (void)memset_s(val, MAX_NAMELEN, 0, MAX_NAMELEN);
741    ret = snprintf_s(val, MAX_NAMELEN, MAX_NAMELEN - 1, "%u", config->maxPower);
742    if (ret < 0) {
743        return HDF_ERR_IO;
744    }
745    ret = UsbFnWriteFile(tmp, val);
746    if (ret < 0) {
747        return HDF_ERR_INVALID_PARAM;
748    }
749
750    (void)memset_s(tmp, MAX_PATHLEN, 0, MAX_PATHLEN);
751    ret = snprintf_s(tmp, MAX_PATHLEN, MAX_PATHLEN - 1, "%s/bmAttributes", configName);
752    if (ret < 0) {
753        return HDF_ERR_IO;
754    }
755    (void)memset_s(val, MAX_NAMELEN, 0, MAX_NAMELEN);
756    ret = snprintf_s(val, MAX_NAMELEN, MAX_NAMELEN - 1, "0x%x", config->attributes);
757    if (ret < 0) {
758        return HDF_ERR_IO;
759    }
760    ret = UsbFnWriteFile(tmp, val);
761    if (ret < 0) {
762        return HDF_ERR_INVALID_PARAM;
763    }
764    return 0;
765}
766
767static int32_t CreatKernelFunc(const char *devName, const struct UsbFnFunction *functions, uint8_t confVal)
768{
769    int32_t ret;
770    char configPath[MAX_PATHLEN];
771    char funcPath[MAX_PATHLEN];
772
773    (void)memset_s(funcPath, MAX_PATHLEN, 0, MAX_PATHLEN);
774    ret = snprintf_s(
775        funcPath, MAX_PATHLEN, MAX_PATHLEN - 1, "%s/%s/functions/%s", CONFIGFS_DIR, devName, functions->funcName);
776    if (ret < 0) {
777        return HDF_ERR_IO;
778    }
779
780    (void)memset_s(configPath, MAX_PATHLEN, 0, MAX_PATHLEN);
781    ret = snprintf_s(configPath, MAX_PATHLEN, MAX_PATHLEN - 1, "%s/%s/configs/b.%u/%s", CONFIGFS_DIR, devName, confVal,
782        functions->funcName);
783    if (ret < 0) {
784        return HDF_ERR_IO;
785    }
786    ret = UsbFnAdapterCreateFunc(configPath, funcPath);
787    if (ret != HDF_SUCCESS) {
788        HDF_LOGE("%{public}s: UsbFnAdapterCreateFunc failed", __func__);
789        return HDF_ERR_IO;
790    }
791    return ret;
792}
793
794static void CleanConfigFs(const char *devName, const char *funcName);
795static int32_t CreatFunc(const char *devName, const struct UsbFnFunction *functions, uint8_t confVal)
796{
797    int32_t fd, ret;
798    char interfaceName[MAX_NAMELEN];
799
800    ret = CreatKernelFunc(devName, functions, confVal);
801    if (ret < 0) {
802        return HDF_ERR_IO;
803    }
804
805    (void)memset_s(interfaceName, MAX_NAMELEN, 0, MAX_NAMELEN);
806    ret = snprintf_s(interfaceName, MAX_NAMELEN, MAX_NAMELEN - 1, "%s", functions->funcName);
807    if (ret < 0) {
808        return HDF_ERR_IO;
809    }
810    ret = UsbFnAdapterCreatInterface(interfaceName, strlen(interfaceName));
811    if (ret != HDF_SUCCESS) {
812        HDF_LOGE("%{public}s: UsbFnAdapterCreatInterface failed", __func__);
813        CleanConfigFs(devName, interfaceName);
814        return HDF_ERR_IO;
815    }
816
817    fd = UsbFnAdapterOpenPipe(interfaceName, 0);
818    if (fd <= 0) {
819        HDF_LOGE("%{public}s: UsbFnAdapterOpenPipe failed", __func__);
820        CleanConfigFs(devName, interfaceName);
821        return HDF_ERR_IO;
822    }
823    ret = UsbFnAdapterCreatPipes(fd, functions);
824    if (ret != HDF_SUCCESS) {
825        HDF_LOGE("%{public}s: UsbFnAdapterCreatPipes failed", __func__);
826        UsbFnAdapterClosePipe(fd);
827        return HDF_ERR_IO;
828    }
829    ret = UsbFnAdapterClosePipe(fd);
830    if (ret != HDF_SUCCESS) {
831        HDF_LOGE("%{public}s: UsbFnAdapterClosePipe failed", __func__);
832        return HDF_ERR_IO;
833    }
834    return 0;
835}
836
837static void DelConfigDevice(const char *deviceName)
838{
839    int32_t ret;
840    char tmp[MAX_PATHLEN];
841    (void)memset_s(tmp, MAX_PATHLEN, 0, MAX_PATHLEN);
842    ret = snprintf_s(tmp, MAX_PATHLEN, MAX_PATHLEN - 1, "%s/%s/configs", CONFIGFS_DIR, deviceName);
843    if (ret < 0) {
844        return;
845    }
846    DeleteFile(tmp);
847
848    (void)memset_s(tmp, MAX_PATHLEN, 0, MAX_PATHLEN);
849    ret = snprintf_s(tmp, MAX_PATHLEN, MAX_PATHLEN - 1, "%s/%s/functions", CONFIGFS_DIR, deviceName);
850    if (ret < 0) {
851        return;
852    }
853    DeleteFile(tmp);
854
855    (void)memset_s(tmp, MAX_PATHLEN, 0, MAX_PATHLEN);
856    ret = snprintf_s(tmp, MAX_PATHLEN, MAX_PATHLEN - 1, "%s/%s/strings", CONFIGFS_DIR, deviceName);
857    if (ret < 0) {
858        return;
859    }
860    DeleteFile(tmp);
861
862    (void)memset_s(tmp, MAX_PATHLEN, 0, MAX_PATHLEN);
863    ret = snprintf_s(tmp, MAX_PATHLEN, MAX_PATHLEN - 1, "%s/%s", CONFIGFS_DIR, deviceName);
864    if (ret < 0) {
865        return;
866    }
867    rmdir(tmp);
868}
869
870static void CleanConfigFs(const char *devName, const char *funcName)
871{
872    int32_t ret;
873    char tmp[MAX_PATHLEN];
874
875    (void)memset_s(tmp, MAX_PATHLEN, 0, MAX_PATHLEN);
876    ret = snprintf_s(tmp, MAX_PATHLEN, MAX_PATHLEN - 1, "%s/%s/configs/b.1/%s", CONFIGFS_DIR, devName, funcName);
877    if (ret < 0) {
878        return;
879    }
880    (void)remove(tmp);
881
882    (void)memset_s(tmp, MAX_PATHLEN, 0, MAX_PATHLEN);
883    ret = snprintf_s(tmp, MAX_PATHLEN, MAX_PATHLEN - 1, "%s/%s/functions/%s", CONFIGFS_DIR, devName, funcName);
884    if (ret < 0) {
885        return;
886    }
887    (void)remove(tmp);
888}
889
890static void CleanFunction(const char *devName, const char *funcName)
891{
892    int32_t ret;
893    int32_t nameLength = (int32_t)strlen(funcName);
894    ret = UsbFnAdapterDelInterface(funcName, nameLength);
895    if (ret != HDF_SUCCESS) {
896        HDF_LOGE("%{public}s: UsbFnAdapterDelInterface failed", __func__);
897        return;
898    }
899    CleanConfigFs(devName, funcName);
900}
901
902static void UsbFnAdapterCleanDevice(const char *devName)
903{
904    int32_t ret;
905    char tmp[MAX_PATHLEN];
906    DIR *dir = NULL;
907    struct dirent *ptr = NULL;
908
909    (void)memset_s(tmp, MAX_PATHLEN, 0, MAX_PATHLEN);
910    ret = snprintf_s(tmp, MAX_PATHLEN, MAX_PATHLEN - 1, "%s/%s/functions/", CONFIGFS_DIR, devName);
911    if (ret < 0) {
912        HDF_LOGE("%{public}s: snprintf_s failed", __func__);
913        return;
914    }
915    if ((dir = opendir(tmp)) == NULL) {
916        return;
917    }
918    while ((ptr = readdir(dir)) != NULL) {
919        if (strncmp(ptr->d_name, FUNCTION_GENERIC, strlen(FUNCTION_GENERIC))) {
920            continue;
921        }
922        CleanFunction(devName, ptr->d_name);
923    }
924    closedir(dir);
925}
926
927static int32_t UsbFnAdapterDelDevice(const char *deviceName, const char *udcName, struct UsbFnDeviceDesc *des)
928{
929    uint32_t i, j;
930    int32_t ret;
931    if (deviceName == NULL) {
932        return HDF_ERR_INVALID_PARAM;
933    }
934    ret = UsbFnAdapterWriteUDC(deviceName, udcName, 0);
935    if (ret < 0) {
936        return ret;
937    }
938    for (i = 0; des->configs[i] != NULL; i++) {
939        for (j = 0; des->configs[i]->functions[j] != NULL; j++) {
940            if (des->configs[i]->functions[j]->enable == false) {
941                continue;
942            }
943            if (strncmp(des->configs[i]->functions[j]->funcName, FUNCTION_GENERIC, strlen(FUNCTION_GENERIC)) != 0) {
944                CleanConfigFs(deviceName, des->configs[i]->functions[j]->funcName);
945                continue;
946            }
947            CleanFunction(deviceName, des->configs[i]->functions[j]->funcName);
948        }
949    }
950
951    if (strcmp("g1", deviceName) != 0) {
952        DelConfigDevice(deviceName);
953    }
954    return 0;
955}
956
957static bool CreateFun(struct UsbFnFunction *function, const char *devName, uint8_t *confVal, int32_t *ret)
958{
959    if (function == NULL || devName == NULL || confVal == NULL || ret == NULL) {
960        return false;
961    }
962
963    if (function->enable == false) {
964        return false;
965    }
966    if (strncmp(function->funcName, FUNCTION_GENERIC, strlen(FUNCTION_GENERIC)) != 0) {
967        *ret = CreatKernelFunc(devName, function, *confVal);
968    } else {
969        *ret = CreatFunc(devName, function, *confVal);
970    }
971    return true;
972}
973
974static int32_t UsbFnAdapterCreateDevice(const char *udcName, const char *devName, struct UsbFnDeviceDesc *descriptor)
975{
976    uint32_t i, j;
977    int32_t ret;
978    uint8_t confVal;
979
980    UsbFnAdapterCleanDevice(devName);
981
982    ret = CreatDeviceDir(devName);
983    if (ret != HDF_SUCCESS) {
984        return HDF_ERR_IO;
985    }
986
987    ret = WriteDeviceDescriptor(devName, descriptor->deviceDesc, descriptor->deviceStrings);
988    if (ret != HDF_SUCCESS) {
989        HDF_LOGE("%{public}s: WriteDeviceDescriptor failed", __func__);
990        return HDF_ERR_IO;
991    }
992
993    for (i = 0; descriptor->configs[i] != NULL; i++) {
994        confVal = descriptor->configs[i]->configurationValue;
995        ret = WriteConfPowerAttributes(devName, descriptor->configs[i], confVal);
996        if (ret != HDF_SUCCESS) {
997            HDF_LOGE("%{public}s: WriteConfPowerAttributes failed", __func__);
998            return HDF_ERR_IO;
999        }
1000
1001        for (j = 0; descriptor->deviceStrings[j] != NULL; j++) {
1002            ret = UsbFnWriteConfString(devName, confVal, descriptor->deviceStrings[j]->language,
1003                descriptor->deviceStrings[j]->strings[descriptor->configs[i]->iConfiguration].s);
1004            if (ret < 0) {
1005                HDF_LOGE("%{public}s: UsbFnWriteConfString failed", __func__);
1006                return HDF_ERR_INVALID_PARAM;
1007            }
1008        }
1009
1010        for (j = 0; descriptor->configs[i]->functions[j] != NULL; j++) {
1011            if (!CreateFun(descriptor->configs[i]->functions[j], devName, &confVal, &ret)) {
1012                continue;
1013            }
1014            if (ret < 0) {
1015                HDF_LOGE("%{public}s: CreatFunc failed", __func__);
1016                (void)UsbFnAdapterWriteUDC(devName, "none", 0);
1017                (void)UsbFnAdapterWriteUDC(devName, udcName, 1);
1018                return HDF_ERR_INVALID_PARAM;
1019            }
1020        }
1021    }
1022
1023    return HDF_SUCCESS;
1024}
1025
1026static int32_t UsbFnAdapterGetPipeInfo(int32_t ep, struct UsbFnPipeInfo * const pipeInfo)
1027{
1028    int32_t ret;
1029    if (ep <= 0 || pipeInfo == NULL) {
1030        return HDF_ERR_INVALID_PARAM;
1031    }
1032
1033    struct UsbEndpointDescriptor desc;
1034    ret = ioctl(ep, FUNCTIONFS_ENDPOINT_DESC, &desc);
1035    if (ret != 0) {
1036        HDF_LOGE("%{public}s: FUNCTIONFS_ENDPOINT_DESC failed", __func__);
1037        return HDF_ERR_IO;
1038    }
1039
1040    pipeInfo->type = desc.bmAttributes;
1041    pipeInfo->dir = USB_PIPE_DIRECTION_OUT;
1042    if (desc.bEndpointAddress & 0x80) {
1043        pipeInfo->dir = USB_PIPE_DIRECTION_IN;
1044    }
1045
1046    pipeInfo->maxPacketSize = desc.wMaxPacketSize;
1047    pipeInfo->interval = desc.bInterval;
1048
1049    return ret;
1050}
1051
1052static int32_t UsbFnAdapterQueueInit(int32_t ep)
1053{
1054    if (ep <= 0) {
1055        return HDF_ERR_INVALID_PARAM;
1056    }
1057    return ioctl(ep, FUNCTIONFS_ENDPOINT_QUEUE_INIT, 0);
1058}
1059
1060static int32_t UsbFnAdapterQueueDel(int32_t ep)
1061{
1062    if (ep <= 0) {
1063        return HDF_ERR_INVALID_PARAM;
1064    }
1065
1066    return ioctl(ep, FUNCTIONFS_ENDPOINT_QUEUE_DEL, 0);
1067}
1068
1069static int32_t UsbFnAdapterReleaseBuf(int32_t ep, const struct GenericMemory *mem)
1070{
1071    if (ep <= 0 || mem == NULL) {
1072        return HDF_ERR_INVALID_PARAM;
1073    }
1074
1075    return ioctl(ep, FUNCTIONFS_ENDPOINT_RELEASE_BUF, mem);
1076}
1077
1078static int32_t UsbFnAdapterPipeIo(int32_t ep, struct IoData *ioData)
1079{
1080    int32_t ret;
1081    if (ep <= 0 || ioData == NULL) {
1082        HDF_LOGE("%{public}s: invalid param", __func__);
1083        return HDF_ERR_INVALID_PARAM;
1084    }
1085
1086    if (ioData->read) {
1087        ret = ioctl(ep, FUNCTIONFS_ENDPOINT_READ, ioData);
1088    } else {
1089        ret = ioctl(ep, FUNCTIONFS_ENDPOINT_WRITE, ioData);
1090    }
1091
1092    if (ret < 0) {
1093        HDF_LOGE("%{public}s: handle endpoint failed errno:%{public}d", __func__, errno);
1094    }
1095
1096    return ret;
1097}
1098
1099static int32_t UsbFnAdapterCancelIo(int32_t ep, const struct IoData * const ioData)
1100{
1101    if (ep <= 0 || ioData == NULL) {
1102        return HDF_ERR_INVALID_PARAM;
1103    }
1104    return ioctl(ep, FUNCTIONFS_ENDPOINT_RW_CANCEL, ioData);
1105}
1106
1107static uint8_t *UsbFnAdapterMapAddr(int32_t ep, uint32_t len)
1108{
1109    if (ep <= 0) {
1110        return NULL;
1111    }
1112
1113    return mmap(NULL, len, PROT_READ | PROT_WRITE, MAP_SHARED, ep, 0);
1114}
1115
1116static int32_t UsbFnAdapterUnmapAddr(uint8_t * const mapAddr, uint32_t len)
1117{
1118    if (mapAddr == NULL) {
1119        return HDF_ERR_INVALID_PARAM;
1120    }
1121
1122    return munmap(mapAddr, len);
1123}
1124
1125static void Ep0Event(struct UsbFnEventAll *event, struct pollfd *pfds)
1126{
1127    int32_t ret;
1128    uint8_t i;
1129    for (i = 0; i < event->ep0Num; i++) {
1130        if ((uint32_t)pfds[i].revents & POLLIN) {
1131            ret = read(event->ep0[i], &event->ep0Event[i].ctrlEvent, sizeof(struct UsbFnCtrlEvent));
1132            if (!ret) {
1133                HDF_LOGE("unable to read event from ep0");
1134            }
1135            event->ep0Event[i].type = USB_EP0_CTRL_EVENT;
1136        } else if ((uint32_t)pfds[i].revents & POLLOUT) {
1137            ret = ioctl(event->ep0[i], FUNCTIONFS_ENDPOINT_GET_EP0_EVENT, &event->ep0Event[i].reqEvent);
1138            if (!ret) {
1139                HDF_LOGE("unable to read reqEvent from ep0");
1140            }
1141            event->ep0Event[i].type = USB_EP0_IO_COMPLETED;
1142        }
1143    }
1144}
1145
1146static void EpEvent(struct UsbFnEventAll *event, struct pollfd *pfds)
1147{
1148    uint8_t i;
1149    for (i = 0; i < event->epNum; i++) {
1150        if ((pfds[i + event->ep0Num].revents & POLLIN)) {
1151            event->numEvent[i] = read(event->epx[i], event->reqEvent[i], MAX_REQUEST * sizeof(struct UsbFnReqEvent)) /
1152                sizeof(struct UsbFnReqEvent);
1153            if (!event->numEvent[i]) {
1154                HDF_LOGE("unable to read indexBuf from ep#");
1155            }
1156        }
1157    }
1158}
1159
1160static int32_t UsbFnAdapterPollEvent(struct UsbFnEventAll *event, int32_t timeout)
1161{
1162    int32_t ret;
1163    uint8_t i;
1164    struct pollfd *pfds = NULL;
1165
1166    if (event == NULL) {
1167        return HDF_ERR_INVALID_PARAM;
1168    }
1169    if (event->ep0Num + event->epNum == 0) {
1170        return HDF_ERR_INVALID_PARAM;
1171    }
1172    pfds = UsbFnMemCalloc((event->ep0Num + event->epNum) * sizeof(struct pollfd));
1173    if (pfds == NULL) {
1174        return HDF_ERR_MALLOC_FAIL;
1175    }
1176    for (i = 0; i < event->ep0Num; i++) {
1177        if (event->ep0[i] <= 0) {
1178            UsbFnMemFree(pfds);
1179            HDF_LOGE("%{public}s: ep[%{public}d] = %{public}d", __func__, i, event->ep0[i]);
1180            return HDF_ERR_INVALID_PARAM;
1181        }
1182        pfds[i].fd = event->ep0[i];
1183        pfds[i].events = POLLIN | POLLOUT;
1184    }
1185    for (i = 0; i < event->epNum; i++) {
1186        if (event->epx[i] <= 0) {
1187            UsbFnMemFree(pfds);
1188            HDF_LOGE("%{public}s: ep[%{public}d] = %{public}d", __func__, i, event->epx[i]);
1189            return HDF_ERR_INVALID_PARAM;
1190        }
1191        pfds[i + event->ep0Num].fd = event->epx[i];
1192        pfds[i + event->ep0Num].events = POLLIN;
1193    }
1194    ret = poll(pfds, event->ep0Num + event->epNum, timeout);
1195    if (ret == 0) {
1196        UsbFnMemFree(pfds);
1197        return HDF_ERR_TIMEOUT;
1198    } else if (ret < 0) {
1199        HDF_LOGE("%{public}s: interrupt", __func__);
1200        UsbFnMemFree(pfds);
1201        return HDF_ERR_IO;
1202    }
1203    Ep0Event(event, pfds);
1204    EpEvent(event, pfds);
1205    UsbFnMemFree(pfds);
1206    return 0;
1207}
1208
1209static int32_t UsbFnAdapterRequestGetStatus(int32_t ep, const struct IoData *ioData)
1210{
1211    if (ep <= 0 || ioData == NULL) {
1212        return HDF_ERR_INVALID_PARAM;
1213    }
1214    return ioctl(ep, FUNCTIONFS_ENDPOINT_GET_REQ_STATUS, ioData);
1215}
1216
1217void *UsbFnMemAlloc(size_t size)
1218{
1219    return UsbFnMemCalloc(size);
1220}
1221
1222void *UsbFnMemCalloc(size_t size)
1223{
1224    void *buf = OsalMemCalloc(size);
1225    if (buf == NULL) {
1226        HDF_LOGE("%{public}s: %{public}d, OsalMemCalloc failed", __func__, __LINE__);
1227        return NULL;
1228    }
1229    return buf;
1230}
1231
1232void UsbFnMemFree(const void *mem)
1233{
1234    if (mem == NULL) {
1235        HDF_LOGE("%{public}s:%{public}d invalid param mem.", __func__, __LINE__);
1236        return;
1237    }
1238    OsalMemFree((void *)mem);
1239    mem = NULL;
1240}
1241
1242static struct UsbFnAdapterOps g_usbFnAdapter = {
1243    .createDevice = UsbFnAdapterCreateDevice,
1244    .delDevice = UsbFnAdapterDelDevice,
1245
1246    .openPipe = UsbFnAdapterOpenPipe,
1247    .closePipe = UsbFnAdapterClosePipe,
1248    .getPipeInfo = UsbFnAdapterGetPipeInfo,
1249
1250    .queueInit = UsbFnAdapterQueueInit,
1251    .queueDel = UsbFnAdapterQueueDel,
1252    .releaseBuf = UsbFnAdapterReleaseBuf,
1253    .pipeIo = UsbFnAdapterPipeIo,
1254    .cancelIo = UsbFnAdapterCancelIo,
1255    .getReqStatus = UsbFnAdapterRequestGetStatus,
1256    .mapAddr = UsbFnAdapterMapAddr,
1257    .unmapAddr = UsbFnAdapterUnmapAddr,
1258    .pollEvent = UsbFnAdapterPollEvent,
1259    .writeUDC = UsbFnAdapterWriteUDC,
1260    .writeProp = UsbFnWriteProp,
1261    .writeDesString = UsbFnWriteDesString,
1262};
1263
1264struct UsbFnAdapterOps *UsbFnAdapterGetOps(void)
1265{
1266    return &g_usbFnAdapter;
1267}
1268