1/*
2 * Copyright (c) 2021-2023 Huawei Device Co., Ltd.
3 * Licensed under the Apache License, Version 2.0 (the "License");
4 * you may not use this file except in compliance with the License.
5 * You may obtain a copy of the License at
6 *
7 *     http://www.apache.org/licenses/LICENSE-2.0
8 *
9 * Unless required by applicable law or agreed to in writing, software
10 * distributed under the License is distributed on an "AS IS" BASIS,
11 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12 * See the License for the specific language governing permissions and
13 * limitations under the License.
14 */
15
16#include "../include/cdcacm.h"
17#include <unistd.h>
18#include "device_resource_if.h"
19#include "hdf_base.h"
20#include "hdf_device_object.h"
21#include "hdf_log.h"
22#include "osal_mem.h"
23#include "osal_time.h"
24#include "securec.h"
25#include "usbfn_device.h"
26#include "usbfn_interface.h"
27#include "usbfn_request.h"
28
29#define HDF_LOG_TAG hdf_cdc_acm
30#define UDC_NAME "invalid_udc_name"
31
32#define PENDING_FLAG     0
33#define CTRL_REQUEST_NUM 2
34#define QUEUE_SIZE       8
35#define WRITE_BUF_SIZE   8192
36#define READ_BUF_SIZE    8192
37
38#define PORT_RATE 9600
39#define DATA_BIT  8
40#define USBCDC_LEN 2
41#define RECEIVE_ALL_EVENTS 0xff
42static const int32_t WAIT_UDC_MAX_LOOP = 3;
43static const uint32_t WAIT_UDC_TIME = 100000;
44static int32_t g_inFifo = 0;
45/* Usb Serial Related Functions */
46
47static int32_t UsbSerialInit(struct UsbAcmDevice *acm);
48static int32_t UsbSerialRelease(struct UsbAcmDevice *acm);
49static int32_t UsbSerialStartTx(struct UsbSerial *port)
50{
51    if (port == NULL) {
52        return HDF_FAILURE;
53    }
54    struct DListHead *pool = &port->writePool;
55    int32_t ret = HDF_FAILURE;
56    if (port->acm == NULL) {
57        return HDF_SUCCESS;
58    }
59    while (!port->writeBusy && !DListIsEmpty(pool)) {
60        struct UsbFnRequest *req = NULL;
61        uint32_t len;
62        if (port->writeStarted >= QUEUE_SIZE) {
63            break;
64        }
65        req = DLIST_FIRST_ENTRY(pool, struct UsbFnRequest, list);
66        if (req == NULL) {
67            break;
68        }
69        len = DataFifoRead(&port->writeFifo, req->buf, port->acm->dataInPipe.maxPacketSize);
70        if (len == 0) {
71            break;
72        }
73        req->length = len;
74        DListRemove(&req->list);
75        port->writeBusy = true;
76        ret = UsbFnSubmitRequestAsync(req);
77        port->writeBusy = false;
78        if (ret != HDF_SUCCESS) {
79            HDF_LOGE("%{public}s: send request error %{public}d", __func__, ret);
80            DListInsertTail(&req->list, pool);
81            break;
82        }
83        port->writeStarted++;
84        /* if acm is disconnect, abort immediately */
85        if (port->acm == NULL) {
86            break;
87        }
88    }
89    return ret;
90}
91
92static uint32_t UsbSerialStartRx(struct UsbSerial *port)
93{
94    struct DListHead *pool = &port->readPool;
95    struct UsbAcmPipe *out = &port->acm->dataOutPipe;
96    while (!DListIsEmpty(pool)) {
97        struct UsbFnRequest *req = NULL;
98        int32_t ret;
99
100        if (port->readStarted >= QUEUE_SIZE) {
101            break;
102        }
103
104        req = DLIST_FIRST_ENTRY(pool, struct UsbFnRequest, list);
105        DListRemove(&req->list);
106        req->length = out->maxPacketSize;
107        ret = UsbFnSubmitRequestAsync(req);
108        if (ret != HDF_SUCCESS) {
109            HDF_LOGE("%{public}s: send request error %{public}d", __func__, ret);
110            DListInsertTail(&req->list, pool);
111            break;
112        }
113        port->readStarted++;
114        /* if acm is disconnect, abort immediately */
115        if (port->acm == NULL) {
116            break;
117        }
118    }
119    return port->readStarted;
120}
121
122static void UsbSerialRxPush(struct UsbSerial *port)
123{
124    struct DListHead *queue = &port->readQueue;
125    bool disconnect = false;
126    while (!DListIsEmpty(queue)) {
127        struct UsbFnRequest *req;
128
129        req = DLIST_FIRST_ENTRY(queue, struct UsbFnRequest, list);
130        switch (req->status) {
131            case USB_REQUEST_NO_DEVICE:
132                disconnect = true;
133                HDF_LOGV("%{public}s: the device is disconnected", __func__);
134                break;
135            case USB_REQUEST_COMPLETED:
136                break;
137            default:
138                HDF_LOGV("%{public}s: unexpected status %{public}d", __func__, req->status);
139                break;
140        }
141
142        if (g_inFifo && req->actual) {
143            uint32_t size = req->actual;
144            uint8_t *data = req->buf;
145
146            if (DataFifoIsFull(&port->readFifo)) {
147                DataFifoSkip(&port->readFifo, size);
148            }
149            uint32_t count = DataFifoWrite(&port->readFifo, data, size);
150            if (count != size) {
151                HDF_LOGW("%{public}s: write %{public}u less than expected %{public}u", __func__, count, size);
152            }
153        }
154
155        DListRemove(&req->list);
156        DListInsertTail(&req->list, &port->readPool);
157        port->readStarted--;
158    }
159
160    if (!disconnect && port->acm) {
161        UsbSerialStartRx(port);
162    }
163}
164
165static void UsbSerialFreeRequests(struct DListHead * const head, int32_t *allocated)
166{
167    struct UsbFnRequest *req = NULL;
168    while (!DListIsEmpty(head)) {
169        req = DLIST_FIRST_ENTRY(head, struct UsbFnRequest, list);
170        DListRemove(&req->list);
171        (void)UsbFnCancelRequest(req);
172        (void)UsbFnFreeRequest(req);
173        if (allocated) {
174            (*allocated)--;
175        }
176    }
177}
178
179static bool g_isStartRead = false;
180static bool g_isReadDone = false;
181static uint64_t g_readCnt = 0;
182struct timeval g_readTimeStart, g_readTimeEnd;
183static float g_readSpeed = 0;
184static bool g_isGetReadTimeStart = false;
185static void UsbSerialReadComplete(uint8_t pipe, struct UsbFnRequest *req)
186{
187    struct UsbSerial *port = (struct UsbSerial *)req->context;
188    if ((!g_isReadDone) && g_isStartRead && req->status == USB_REQUEST_COMPLETED) {
189        g_readCnt += req->actual;
190        if (!g_isGetReadTimeStart) {
191            g_isGetReadTimeStart = true;
192            gettimeofday(&g_readTimeStart, NULL);
193        }
194    }
195    OsalMutexLock(&port->lock);
196    DListInsertTail(&req->list, &port->readQueue);
197    UsbSerialRxPush(port);
198    OsalMutexUnlock(&port->lock);
199}
200
201static int32_t SpeedReadThread(void *arg)
202{
203    (void)arg;
204    g_readCnt = 0;
205    g_isReadDone = false;
206    g_readSpeed = 0;
207    g_isGetReadTimeStart = false;
208    double timeUse;
209    double usec = 1000000;
210    double k = 1024;
211    struct timeval timeTmp;
212    while (!g_isReadDone) {
213        if (g_readCnt == 0) {
214            OsalSleep(1);
215            continue;
216        } else {
217            OsalSleep(1);
218        }
219        gettimeofday(&timeTmp, NULL);
220        timeUse = (double)(timeTmp.tv_sec - g_readTimeStart.tv_sec) + (double)timeTmp.tv_usec / usec -
221            (double)g_readTimeStart.tv_usec / usec;
222        g_readSpeed = (float)((double)g_readCnt / k / k / timeUse);
223    }
224    timeUse = (double)(g_readTimeEnd.tv_sec - g_readTimeStart.tv_sec) + (double)g_readTimeEnd.tv_usec / usec -
225        (double)g_readTimeStart.tv_usec / usec;
226    HDF_LOGD("timeUse = %{public}lf", timeUse);
227    g_readSpeed = (float)((double)g_readCnt / k / k / timeUse);
228    HDF_LOGD("%{public}s: g_speed = %{public}f MB/s", __func__, g_readSpeed);
229    return HDF_SUCCESS;
230}
231
232#define HDF_PROCESS_STACK_SIZE 100000
233struct OsalThread g_threadRead;
234static int32_t StartThreadReadSpeed(struct UsbSerial *port)
235{
236    int32_t ret;
237    struct OsalThreadParam threadCfg;
238    ret = memset_s(&threadCfg, sizeof(threadCfg), 0, sizeof(threadCfg));
239    if (ret != EOK) {
240        HDF_LOGE("%{public}s:%{public}d memset_s failed", __func__, __LINE__);
241        return ret;
242    }
243
244    threadCfg.name = "speed read process";
245    threadCfg.priority = OSAL_THREAD_PRI_LOW;
246    threadCfg.stackSize = HDF_PROCESS_STACK_SIZE;
247
248    ret = OsalThreadCreate(&g_threadRead, (OsalThreadEntry)SpeedReadThread, port);
249    if (ret != HDF_SUCCESS) {
250        HDF_LOGE("%{public}s:%{public}d OsalThreadCreate failed, ret=%{public}d ", __func__, __LINE__, ret);
251        return HDF_ERR_DEVICE_BUSY;
252    }
253
254    ret = OsalThreadStart(&g_threadRead, &threadCfg);
255    if (ret != HDF_SUCCESS) {
256        HDF_LOGE("%{public}s:%{public}d OsalThreadStart failed, ret=%{public}d ", __func__, __LINE__, ret);
257        return HDF_ERR_DEVICE_BUSY;
258    }
259    return HDF_SUCCESS;
260}
261
262static int32_t UsbSerialGetTempReadSpeed(struct UsbSerial *port, struct HdfSBuf *reply)
263{
264    (void)port;
265    if (!HdfSbufWriteFloat(reply, g_readSpeed)) {
266        HDF_LOGE("%{public}s: HdfSbufWriteFloat failed", __func__);
267        return HDF_FAILURE;
268    }
269    return HDF_SUCCESS;
270}
271
272static int32_t UsbSerialGetTempReadSpeedInt(struct UsbSerial *port, struct HdfSBuf *reply)
273{
274    (void)port;
275    uint32_t calc = 10000;
276    if (!HdfSbufWriteUint32(reply, (uint32_t)(g_readSpeed * calc))) {
277        HDF_LOGE("%{public}s: HdfSbufWriteUint32 failed", __func__);
278        return HDF_FAILURE;
279    }
280    return HDF_SUCCESS;
281}
282
283static int32_t UsbSerialReadSpeedDone(struct UsbSerial *port)
284{
285    (void)port;
286    gettimeofday(&g_readTimeEnd, NULL);
287    g_isReadDone = true;
288    g_isStartRead = false;
289    return HDF_SUCCESS;
290}
291
292static int32_t UsbSerialReadSpeedStart(struct UsbSerial *port)
293{
294    g_inFifo = 0;
295    g_isStartRead = true;
296    return StartThreadReadSpeed(port);
297}
298
299static void UsbSerialWriteComplete(uint8_t pipe, struct UsbFnRequest *req)
300{
301    struct UsbSerial *port = (struct UsbSerial *)req->context;
302
303    OsalMutexLock(&port->lock);
304    DListInsertTail(&req->list, &port->writePool);
305    port->writeStarted--;
306
307    switch (req->status) {
308        case USB_REQUEST_COMPLETED:
309            UsbSerialStartTx(port);
310            break;
311        case USB_REQUEST_NO_DEVICE:
312            HDF_LOGV("%{public}s: acm device was disconnected", __func__);
313            break;
314        default:
315            HDF_LOGV("%{public}s: unexpected status %{public}d", __func__, req->status);
316            break;
317    }
318    OsalMutexUnlock(&port->lock);
319}
320
321static int32_t UsbSerialAllocReadRequests(struct UsbSerial *port, int32_t num)
322{
323    struct UsbAcmDevice *acm = port->acm;
324    struct DListHead *head = &port->readPool;
325    struct UsbFnRequest *req = NULL;
326    int32_t i;
327
328    for (i = 0; i < num; i++) {
329        req = UsbFnAllocRequest(acm->dataIface.handle, acm->dataOutPipe.id, acm->dataOutPipe.maxPacketSize);
330        if (!req) {
331            return DListIsEmpty(head) ? HDF_FAILURE : HDF_SUCCESS;
332        }
333
334        req->complete = UsbSerialReadComplete;
335        req->context = port;
336        DListInsertTail(&req->list, head);
337        port->readAllocated++;
338    }
339    return HDF_SUCCESS;
340}
341
342static int32_t UsbSerialAllocWriteRequests(struct UsbSerial *port, int32_t num)
343{
344    struct UsbAcmDevice *acm = port->acm;
345    struct DListHead *head = &port->writePool;
346    struct UsbFnRequest *req = NULL;
347    int32_t i;
348
349    for (i = 0; i < num; i++) {
350        req = UsbFnAllocRequest(acm->dataIface.handle, acm->dataInPipe.id, acm->dataInPipe.maxPacketSize);
351        if (!req) {
352            return DListIsEmpty(head) ? HDF_FAILURE : HDF_SUCCESS;
353        }
354
355        req->complete = UsbSerialWriteComplete;
356        req->context = port;
357        DListInsertTail(&req->list, head);
358        port->writeAllocated++;
359    }
360    return HDF_SUCCESS;
361}
362
363static void UsbSerialFreeFifo(struct DataFifo *fifo)
364{
365    void *buf = fifo->data;
366    OsalMemFree(buf);
367    DataFifoInit(fifo, 0, NULL);
368}
369
370static int32_t UsbSerialStartIo(struct UsbSerial *port)
371{
372    struct DListHead *head = &port->readPool;
373    int32_t ret = HDF_SUCCESS;
374    uint32_t started;
375
376    /* allocate requests for read/write */
377    if (port->readAllocated == 0) {
378        ret = UsbSerialAllocReadRequests(port, QUEUE_SIZE);
379        if (ret != HDF_SUCCESS) {
380            HDF_LOGE("%{public}s: UsbSerialAllocReadRequests failed:%{public}d", __func__, ret);
381            return ret;
382        }
383    }
384    if (port->writeAllocated == 0) {
385        ret = UsbSerialAllocWriteRequests(port, QUEUE_SIZE);
386        if (ret != HDF_SUCCESS) {
387            UsbSerialFreeRequests(head, &port->readAllocated);
388            HDF_LOGE("%{public}s: UsbSerialAllocWriteRequests failed:%{public}d", __func__, ret);
389            return ret;
390        }
391    }
392
393    started = UsbSerialStartRx(port);
394    if (started) {
395        UsbSerialStartTx(port);
396    } else {
397        UsbSerialFreeRequests(head, &port->readAllocated);
398        UsbSerialFreeRequests(&port->writePool, &port->writeAllocated);
399        HDF_LOGE("%{public}s: UsbSerialStartRx failed", __func__);
400        ret = HDF_ERR_IO;
401    }
402
403    return ret;
404}
405
406static void UsbSerialStopIo(struct UsbSerial *port)
407{
408    if (port == NULL) {
409        HDF_LOGE("%{public}s: port is null", __func__);
410        return;
411    }
412    UsbSerialFreeRequests(&port->readPool, &port->readAllocated);
413    UsbSerialFreeRequests(&port->writePool, &port->writeAllocated);
414    UsbSerialFreeFifo(&port->writeFifo);
415    UsbSerialFreeFifo(&port->readFifo);
416}
417
418static int32_t UsbSerialAllocFifo(struct DataFifo *fifo, uint32_t size)
419{
420    if (!DataFifoIsInitialized(fifo)) {
421        void *data = OsalMemAlloc(size);
422        if (data == NULL) {
423            HDF_LOGE("%{public}s: allocate fifo data buffer failed", __func__);
424            return HDF_ERR_MALLOC_FAIL;
425        }
426        DataFifoInit(fifo, size, data);
427    }
428    return HDF_SUCCESS;
429}
430
431static int32_t UsbSerialOpen(struct UsbSerial *port)
432{
433    int32_t ret;
434
435    if (port == NULL) {
436        return HDF_ERR_INVALID_PARAM;
437    }
438    g_inFifo = 1;
439    OsalMutexLock(&port->lock);
440    ret = UsbSerialAllocFifo(&port->writeFifo, WRITE_BUF_SIZE);
441    if (ret != HDF_SUCCESS) {
442        HDF_LOGE("%{public}s: UsbSerialAllocFifo failed", __func__);
443        goto OUT;
444    }
445    ret = UsbSerialAllocFifo(&port->readFifo, READ_BUF_SIZE);
446    if (ret != HDF_SUCCESS) {
447        HDF_LOGE("%{public}s: UsbSerialAllocFifo failed", __func__);
448        goto OUT;
449    }
450
451    /* the acm is enabled, start the io stream */
452    if (port->acm) {
453        if (!port->suspended) {
454            struct UsbAcmDevice *acm = port->acm;
455            HDF_LOGD("%{public}s: start usb serial", __func__);
456            ret = UsbSerialStartIo(port);
457            if (ret != HDF_SUCCESS) {
458                goto OUT;
459            }
460            if (acm->notify && acm->notify->Connect) {
461                acm->notify->Connect(acm);
462            }
463        } else {
464            HDF_LOGD("%{public}s: delay start usb serial", __func__);
465            port->startDelayed = true;
466        }
467    }
468
469OUT:
470    OsalMutexUnlock(&port->lock);
471    return HDF_SUCCESS;
472}
473
474static int32_t UsbSerialClose(struct UsbSerial *port)
475{
476    struct UsbAcmDevice *acm = NULL;
477
478    if (port == NULL) {
479        return HDF_ERR_INVALID_PARAM;
480    }
481
482    OsalMutexLock(&port->lock);
483
484    HDF_LOGD("%{public}s: close usb serial", __func__);
485    acm = port->acm;
486    if (acm && !port->suspended) {
487        if (acm->notify && acm->notify->Disconnect) {
488            acm->notify->Disconnect(acm);
489        }
490    }
491    DataFifoReset(&port->writeFifo);
492    DataFifoReset(&port->readFifo);
493    UsbSerialStopIo(port);
494    port->startDelayed = false;
495
496    OsalMutexUnlock(&port->lock);
497    return HDF_SUCCESS;
498}
499
500#define WRITE_SPEED_REQ_NUM 8
501struct UsbFnRequest *g_req[WRITE_SPEED_REQ_NUM] = {NULL};
502static bool g_isWriteDone = false;
503static uint64_t g_writeCnt = 0;
504struct timeval g_timeStart, g_timeEnd;
505static float g_speed = 0;
506static bool g_isGetWriteTimeStart = false;
507static void UsbSerialWriteSpeedComplete(uint8_t pipe, struct UsbFnRequest *req)
508{
509    switch (req->status) {
510        case USB_REQUEST_COMPLETED:
511            g_writeCnt += req->actual;
512            if (!g_isGetWriteTimeStart) {
513                g_isGetWriteTimeStart = true;
514                gettimeofday(&g_timeStart, NULL);
515            }
516            if (g_isWriteDone) {
517                UsbFnFreeRequest(req);
518                req = NULL;
519            } else {
520                if (memset_s(req->buf, req->length, 'a', req->length) != EOK) {
521                    HDF_LOGE("%{public}s:%{public}d memset_s failed", __func__, __LINE__);
522                    return;
523                }
524                UsbFnSubmitRequestAsync(req);
525            }
526            break;
527        case USB_REQUEST_NO_DEVICE:
528            HDF_LOGV("%{public}s: acm device was disconnected", __func__);
529            break;
530        default:
531            HDF_LOGD("%{public}s: req->status = %{public}d", __func__, req->status);
532            break;
533    }
534}
535
536static int32_t SpeedThread(void *arg)
537{
538    g_writeCnt = 0;
539    g_isWriteDone = false;
540    g_isGetWriteTimeStart = false;
541    g_speed = 0;
542    double timeUse;
543    double usec = 1000000;
544    double k = 1024;
545    struct timeval timeTmp;
546    struct UsbSerial *port = (struct UsbSerial *)arg;
547
548    for (int32_t i = 0; i < WRITE_SPEED_REQ_NUM; i++) {
549        g_req[i] = UsbFnAllocRequest(
550            port->acm->dataIface.handle, port->acm->dataInPipe.id, port->acm->dataInPipe.maxPacketSize);
551        if (g_req[i] == NULL) {
552            return HDF_FAILURE;
553        }
554        g_req[i]->complete = UsbSerialWriteSpeedComplete;
555        g_req[i]->context = port;
556        g_req[i]->length = port->acm->dataInPipe.maxPacketSize;
557        int32_t ret =
558            memset_s(g_req[i]->buf, port->acm->dataInPipe.maxPacketSize, 'a', port->acm->dataInPipe.maxPacketSize);
559        if (ret != HDF_SUCCESS) {
560            HDF_LOGE("%{public}s:%{public}d memset_s failed", __func__, __LINE__);
561            return ret;
562        }
563        UsbFnSubmitRequestAsync(g_req[i]);
564    }
565    while (!g_isWriteDone) {
566        if (g_writeCnt == 0) {
567            OsalSleep(1);
568            continue;
569        } else {
570            OsalSleep(1);
571        }
572        gettimeofday(&timeTmp, NULL);
573        timeUse = (double)(timeTmp.tv_sec - g_timeStart.tv_sec) + (double)timeTmp.tv_usec / usec -
574            (double)g_timeStart.tv_usec / usec;
575        g_speed = (float)((double)g_writeCnt / k / k / timeUse);
576    }
577    timeUse = (double)(g_timeEnd.tv_sec - g_timeStart.tv_sec) + (double)g_timeEnd.tv_usec / usec -
578        (double)g_timeStart.tv_usec / usec;
579    HDF_LOGE("timeUse = %{public}lf", timeUse);
580    g_speed = (float)((double)g_writeCnt / k / k / timeUse);
581    HDF_LOGD("%{public}s: g_speed = %{public}f MB/s", __func__, g_speed);
582    return HDF_SUCCESS;
583}
584
585struct OsalThread g_thread;
586static int32_t StartThreadSpeed(struct UsbSerial *port)
587{
588    struct OsalThreadParam threadCfg;
589    int32_t ret = memset_s(&threadCfg, sizeof(threadCfg), 0, sizeof(threadCfg));
590    if (ret != EOK) {
591        HDF_LOGE("%{public}s:%{public}d memset_s failed", __func__, __LINE__);
592        return ret;
593    }
594    threadCfg.name = "speed test process";
595    threadCfg.priority = OSAL_THREAD_PRI_LOW;
596    threadCfg.stackSize = HDF_PROCESS_STACK_SIZE;
597
598    ret = OsalThreadCreate(&g_thread, (OsalThreadEntry)SpeedThread, port);
599    if (ret != HDF_SUCCESS) {
600        HDF_LOGE("%{public}s:%{public}d OsalThreadCreate failed, ret=%{public}d ", __func__, __LINE__, ret);
601        return HDF_ERR_DEVICE_BUSY;
602    }
603
604    ret = OsalThreadStart(&g_thread, &threadCfg);
605    if (ret != HDF_SUCCESS) {
606        HDF_LOGE("%{public}s:%{public}d OsalThreadStart failed, ret=%{public}d ", __func__, __LINE__, ret);
607        return HDF_ERR_DEVICE_BUSY;
608    }
609    return 0;
610}
611
612static int32_t UsbSerialGetTempSpeed(struct UsbSerial *port, struct HdfSBuf *reply)
613{
614    (void)port;
615    if (!HdfSbufWriteFloat(reply, g_speed)) {
616        HDF_LOGE("%{public}s: HdfSbufWriteFloat failed", __func__);
617        return HDF_FAILURE;
618    }
619    return HDF_SUCCESS;
620}
621
622static int32_t UsbSerialGetTempSpeedInt(struct UsbSerial *port, struct HdfSBuf *reply)
623{
624    (void)port;
625    uint32_t calc = 10000;
626    if (!HdfSbufWriteUint32(reply, (uint32_t)(g_speed * calc))) {
627        HDF_LOGE("%{public}s: HdfSbufWriteUint32 failed", __func__);
628        return HDF_FAILURE;
629    }
630    return HDF_SUCCESS;
631}
632
633static int32_t UsbSerialSpeedDone(struct UsbSerial *port)
634{
635    (void)port;
636    gettimeofday(&g_timeEnd, NULL);
637    g_isWriteDone = true;
638    return HDF_SUCCESS;
639}
640
641static int32_t UsbSerialSpeed(struct UsbSerial *port)
642{
643    StartThreadSpeed(port);
644    return HDF_SUCCESS;
645}
646
647static int32_t UsbSerialRead(struct UsbSerial *port, struct HdfSBuf *reply)
648{
649    uint32_t len, fifoLen;
650    int32_t ret = HDF_SUCCESS;
651    uint8_t *buf = NULL;
652    uint32_t i;
653    OsalMutexLock(&port->lock);
654    if (DataFifoIsEmpty(&port->readFifo)) {
655        OsalMutexUnlock(&port->lock);
656        return 0;
657    }
658    fifoLen = DataFifoLen(&port->readFifo);
659    buf = (uint8_t *)OsalMemCalloc(fifoLen + 1);
660    if (buf == NULL) {
661        HDF_LOGE("%{public}s: OsalMemCalloc error", __func__);
662        OsalMutexUnlock(&port->lock);
663        return HDF_ERR_MALLOC_FAIL;
664    }
665    for (i = 0; i < fifoLen; i++) {
666        len = DataFifoRead(&port->readFifo, buf + i, 1);
667        if (len == 0) {
668            HDF_LOGE("%{public}s: no data", __func__);
669            ret = HDF_ERR_IO;
670            goto OUT;
671        }
672        if (*(buf + i) == 0) {
673            if (i == 0) {
674                goto OUT;
675            }
676            break;
677        }
678    }
679
680    if (!HdfSbufWriteString(reply, (const char *)buf)) {
681        HDF_LOGE("%{public}s: sbuf write buffer failed", __func__);
682        ret = HDF_ERR_IO;
683    }
684OUT:
685    if (port->acm) {
686        UsbSerialStartRx(port);
687    }
688    OsalMemFree(buf);
689    OsalMutexUnlock(&port->lock);
690    return ret;
691}
692
693static int32_t UsbSerialWrite(struct UsbSerial *port, struct HdfSBuf *data)
694{
695    int32_t size;
696    const char *tmp = NULL;
697
698    OsalMutexLock(&port->lock);
699
700    tmp = HdfSbufReadString(data);
701    if (tmp == NULL) {
702        HDF_LOGE("%{public}s: sbuf read buffer failed", __func__);
703        OsalMutexUnlock(&port->lock);
704        return HDF_ERR_IO;
705    }
706    char *buf = OsalMemCalloc(strlen(tmp) + 1);
707    if (buf == NULL) {
708        HDF_LOGE("%{public}s: OsalMemCalloc failed", __func__);
709        OsalMutexUnlock(&port->lock);
710        return HDF_ERR_IO;
711    }
712
713    int32_t ret = strcpy_s(buf, strlen(tmp) + 1, tmp);
714    if (ret != EOK) {
715        HDF_LOGE("%{public}s: strcpy_s failed", __func__);
716        OsalMutexUnlock(&port->lock);
717        OsalMemFree(buf);
718        return HDF_ERR_IO;
719    }
720
721    size = (int32_t)DataFifoWrite(&port->writeFifo, (uint8_t *)buf, strlen(buf));
722
723    if (port->acm) {
724        UsbSerialStartTx(port);
725    }
726    OsalMutexUnlock(&port->lock);
727    OsalMemFree(buf);
728    return size;
729}
730
731static int32_t UsbSerialGetBaudrate(struct UsbSerial *port, struct HdfSBuf *reply)
732{
733    uint32_t baudRate = LE32_TO_CPU(port->lineCoding.dwDTERate);
734    if (!HdfSbufWriteBuffer(reply, &baudRate, sizeof(baudRate))) {
735        HDF_LOGE("%{public}s: sbuf write buffer failed", __func__);
736        return HDF_ERR_IO;
737    }
738    return HDF_SUCCESS;
739}
740
741static int32_t UsbSerialSetBaudrate(struct UsbSerial *port, struct HdfSBuf *data)
742{
743    uint32_t size;
744    uint32_t *baudRate = NULL;
745
746    if (!HdfSbufReadBuffer(data, (const void **)&baudRate, &size)) {
747        HDF_LOGE("%{public}s: sbuf read buffer failed", __func__);
748        return HDF_ERR_IO;
749    }
750    port->lineCoding.dwDTERate = CPU_TO_LE32(*baudRate);
751    if (port->acm) {
752        port->acm->lineCoding.dwDTERate = CPU_TO_LE32(*baudRate);
753    }
754    return HDF_SUCCESS;
755}
756
757static int32_t UsbSerialGetProp(struct UsbAcmDevice *acmDevice, struct HdfSBuf *data, struct HdfSBuf *reply)
758{
759    struct UsbFnInterface *intf = acmDevice->ctrlIface.fn;
760    const char *propName = NULL;
761    char propValue[USB_MAX_PACKET_SIZE] = {0};
762    int32_t ret;
763
764    propName = HdfSbufReadString(data);
765    if (propName == NULL) {
766        return HDF_ERR_IO;
767    }
768    ret = UsbFnGetInterfaceProp(intf, propName, propValue);
769    if (ret) {
770        return HDF_ERR_IO;
771    }
772    if (!HdfSbufWriteString(reply, propValue)) {
773        HDF_LOGE("%{public}s:failed to write result", __func__);
774        return HDF_ERR_IO;
775    }
776    return HDF_SUCCESS;
777}
778
779static int32_t UsbSerialSetProp(struct UsbAcmDevice *acmDevice, struct HdfSBuf *data)
780{
781    struct UsbFnInterface *intf = acmDevice->ctrlIface.fn;
782    char tmp[USB_MAX_PACKET_SIZE] = {0};
783
784    const char *propName = HdfSbufReadString(data);
785    if (propName == NULL) {
786        return HDF_ERR_IO;
787    }
788    const char *propValue = HdfSbufReadString(data);
789    if (propValue == NULL) {
790        return HDF_ERR_IO;
791    }
792    (void)memset_s(&tmp, sizeof(tmp), 0, sizeof(tmp));
793    int32_t ret = snprintf_s(tmp, USB_MAX_PACKET_SIZE, USB_MAX_PACKET_SIZE - 1, "%s", propValue);
794    if (ret < 0) {
795        HDF_LOGE("%{public}s: snprintf_s failed", __func__);
796        return HDF_FAILURE;
797    }
798    ret = UsbFnSetInterfaceProp(intf, propName, tmp);
799    if (ret) {
800        HDF_LOGE("%{public}s: UsbFnInterfaceSetProp failed", __func__);
801        return HDF_ERR_IO;
802    }
803    return HDF_SUCCESS;
804}
805
806static int32_t UsbSerialRegistPropAGet(const struct UsbFnInterface *intf, const char *name, const char *value)
807{
808    (void)intf;
809    HDF_LOGE("%{public}s: name = %{public}s", __func__, name);
810    HDF_LOGE("%{public}s: value = %{public}s", __func__, value);
811
812    return 0;
813}
814
815static int32_t UsbSerialRegistPropASet(const struct UsbFnInterface *intf, const char *name, const char *value)
816{
817    (void)intf;
818    HDF_LOGE("%{public}s: name = %{public}s", __func__, name);
819    HDF_LOGE("%{public}s: value = %{public}s", __func__, value);
820
821    return 0;
822}
823
824static int32_t UsbSerialRegistProp(struct UsbAcmDevice *acmDevice, struct HdfSBuf *data)
825{
826    struct UsbFnInterface *intf = acmDevice->ctrlIface.fn;
827    struct UsbFnRegistInfo registInfo;
828    int32_t ret;
829
830    const char *propName = HdfSbufReadString(data);
831    if (propName == NULL) {
832        return HDF_ERR_IO;
833    }
834    const char *propValue = HdfSbufReadString(data);
835    if (propValue == NULL) {
836        return HDF_ERR_IO;
837    }
838    registInfo.name = propName;
839    registInfo.value = propValue;
840    registInfo.getProp = UsbSerialRegistPropAGet;
841    registInfo.setProp = UsbSerialRegistPropASet;
842    ret = UsbFnRegistInterfaceProp(intf, &registInfo);
843    if (ret) {
844        HDF_LOGE("%{public}s: UsbFnInterfaceSetProp failed", __func__);
845        return HDF_ERR_IO;
846    }
847    return HDF_SUCCESS;
848}
849
850static int32_t AcmSerialCmd(
851    struct UsbAcmDevice *acm, int32_t cmd, struct UsbSerial *port, struct HdfSBuf *data, struct HdfSBuf *reply)
852{
853    switch (cmd) {
854        case USB_SERIAL_OPEN:
855            return UsbSerialOpen(port);
856        case USB_SERIAL_CLOSE:
857            return UsbSerialClose(port);
858        case USB_SERIAL_READ:
859            return UsbSerialRead(port, reply);
860        case USB_SERIAL_WRITE:
861            return UsbSerialWrite(port, data);
862        case USB_SERIAL_GET_BAUDRATE:
863            return UsbSerialGetBaudrate(port, reply);
864        case USB_SERIAL_SET_BAUDRATE:
865            return UsbSerialSetBaudrate(port, data);
866        case USB_SERIAL_SET_PROP:
867            return UsbSerialSetProp(acm, data);
868        case USB_SERIAL_GET_PROP:
869            return UsbSerialGetProp(acm, data, reply);
870        case USB_SERIAL_REGIST_PROP:
871            return UsbSerialRegistProp(acm, data);
872        case USB_SERIAL_WRITE_SPEED:
873            return UsbSerialSpeed(port);
874        case USB_SERIAL_WRITE_GET_TEMP_SPEED:
875            return UsbSerialGetTempSpeed(port, reply);
876        case USB_SERIAL_WRITE_SPEED_DONE:
877            return UsbSerialSpeedDone(port);
878        case USB_SERIAL_WRITE_GET_TEMP_SPEED_UINT32:
879            return UsbSerialGetTempSpeedInt(port, reply);
880        case USB_SERIAL_READ_SPEED:
881            return UsbSerialReadSpeedStart(port);
882        case USB_SERIAL_READ_GET_TEMP_SPEED:
883            return UsbSerialGetTempReadSpeed(port, reply);
884        case USB_SERIAL_READ_SPEED_DONE:
885            return UsbSerialReadSpeedDone(port);
886        case USB_SERIAL_READ_GET_TEMP_SPEED_UINT32:
887            return UsbSerialGetTempReadSpeedInt(port, reply);
888        default:
889            return HDF_ERR_NOT_SUPPORT;
890    }
891    return HDF_SUCCESS;
892}
893
894static int32_t AcmDeviceDispatch(
895    struct HdfDeviceIoClient *client, int32_t cmd, struct HdfSBuf *data, struct HdfSBuf *reply)
896{
897    if (client == NULL || client->device == NULL || client->device->service == NULL) {
898        HDF_LOGE("%{public}s: client is NULL", __func__);
899        return HDF_ERR_INVALID_OBJECT;
900    }
901
902    struct UsbAcmDevice *acm = (struct UsbAcmDevice *)client->device->service;
903    if (!HdfDeviceObjectCheckInterfaceDesc(client->device, data)) {
904        HDF_LOGE("%{public}s:%{public}d check interface desc fail", __func__, __LINE__);
905        return HDF_ERR_INVALID_PARAM;
906    }
907
908    switch (cmd) {
909        case USB_SERIAL_INIT:
910            return UsbSerialInit(acm);
911        case USB_SERIAL_RELEASE:
912            return UsbSerialRelease(acm);
913        default:
914            HDF_LOGE("%{public}s: unknown cmd %{public}d", __func__, cmd);
915            break;
916    }
917    OsalMutexLock(&acm->lock);
918    struct UsbSerial *port = acm->port;
919    if (port == NULL) {
920        OsalMutexUnlock(&acm->lock);
921        HDF_LOGE("%{public}s: port is NULL", __func__);
922        return HDF_ERR_IO;
923    }
924    int32_t ret = AcmSerialCmd(acm, cmd, port, data, reply);
925    OsalMutexUnlock(&acm->lock);
926    return ret;
927}
928
929static void AcmDeviceDestroy(struct UsbAcmDevice *acm)
930{
931    if (acm == NULL) {
932        return;
933    }
934    OsalMemFree(acm);
935}
936
937static void AcmCtrlComplete(uint8_t pipe, struct UsbFnRequest *req)
938{
939    if (req == NULL) {
940        return;
941    }
942    struct CtrlInfo *ctrlInfo = (struct CtrlInfo *)req->context;
943    if (ctrlInfo == NULL) {
944        return;
945    }
946    struct UsbAcmDevice *acm = ctrlInfo->acm;
947    if (req->status != USB_REQUEST_COMPLETED) {
948        HDF_LOGD("%{public}s: ctrl completion error %{public}d", __func__, req->status);
949        goto OUT;
950    }
951
952    if (ctrlInfo->request == USB_DDK_CDC_REQ_SET_LINE_CODING) {
953        struct UsbCdcLineCoding *value = req->buf;
954        if (req->actual == sizeof(*value)) {
955            acm->lineCoding = *value;
956            HDF_LOGD("dwDTERate =  %{public}d", acm->lineCoding.dwDTERate);
957            HDF_LOGD("bCharFormat =  %{public}d", acm->lineCoding.bCharFormat);
958            HDF_LOGD("bParityType =  %{public}d", acm->lineCoding.bParityType);
959            HDF_LOGD("bDataBits =  %{public}d", acm->lineCoding.bDataBits);
960        }
961    }
962
963OUT:
964    DListInsertTail(&req->list, &acm->ctrlPool);
965}
966
967static int32_t AcmAllocCtrlRequests(struct UsbAcmDevice *acm, int32_t num)
968{
969    struct DListHead *head = &acm->ctrlPool;
970    struct UsbFnRequest *req = NULL;
971    struct CtrlInfo *ctrlInfo = NULL;
972    int32_t i;
973
974    DListHeadInit(&acm->ctrlPool);
975    acm->ctrlReqNum = 0;
976
977    for (i = 0; i < num; i++) {
978        ctrlInfo = (struct CtrlInfo *)OsalMemCalloc(sizeof(*ctrlInfo));
979        if (ctrlInfo == NULL) {
980            HDF_LOGE("%{public}s: Allocate ctrlInfo failed", __func__);
981            goto OUT;
982        }
983        ctrlInfo->acm = acm;
984        req = UsbFnAllocCtrlRequest(
985            acm->ctrlIface.handle, sizeof(struct UsbCdcLineCoding) + sizeof(struct UsbCdcLineCoding));
986        if (req == NULL) {
987            goto OUT;
988        }
989        req->complete = AcmCtrlComplete;
990        req->context = ctrlInfo;
991        DListInsertTail(&req->list, head);
992        acm->ctrlReqNum++;
993    }
994    return HDF_SUCCESS;
995
996OUT:
997    return DListIsEmpty(head) ? HDF_FAILURE : HDF_SUCCESS;
998}
999
1000static void AcmFreeCtrlRequests(struct UsbAcmDevice *acm)
1001{
1002    struct DListHead *head = &acm->ctrlPool;
1003    struct UsbFnRequest *req = NULL;
1004
1005    while (!DListIsEmpty(head)) {
1006        req = DLIST_FIRST_ENTRY(head, struct UsbFnRequest, list);
1007        DListRemove(&req->list);
1008        OsalMemFree(req->context);
1009        (void)UsbFnFreeRequest(req);
1010        acm->ctrlReqNum--;
1011    }
1012}
1013
1014static int32_t AcmNotifySerialState(struct UsbAcmDevice *acm);
1015static void AcmNotifyComplete(uint8_t pipe, struct UsbFnRequest *req)
1016{
1017    struct UsbAcmDevice *acm = (struct UsbAcmDevice *)req->context;
1018    bool pending = false;
1019
1020    if (acm == NULL) {
1021        HDF_LOGE("%{public}s: acm is null", __func__);
1022        return;
1023    }
1024
1025    OsalMutexLock(&acm->lock);
1026    /* estimate pending */
1027    if (req->status == PENDING_FLAG) {
1028        pending = acm->pending;
1029    }
1030    acm->notifyReq = req;
1031    OsalMutexUnlock(&acm->lock);
1032    if (pending) {
1033        AcmNotifySerialState(acm);
1034    }
1035}
1036
1037static int32_t AcmAllocNotifyRequest(struct UsbAcmDevice *acm)
1038{
1039    /* allocate notification request, 2 means compatible liteOS and linux */
1040    acm->notifyReq =
1041        UsbFnAllocRequest(acm->ctrlIface.handle, acm->notifyPipe.id, sizeof(struct UsbCdcNotification) * USBCDC_LEN);
1042    if (acm->notifyReq == NULL) {
1043        HDF_LOGE("%{public}s: allocate notify request failed", __func__);
1044        return HDF_FAILURE;
1045    }
1046    acm->notifyReq->complete = AcmNotifyComplete;
1047    acm->notifyReq->context = acm;
1048
1049    return HDF_SUCCESS;
1050}
1051
1052static void AcmFreeNotifyRequest(struct UsbAcmDevice *acm)
1053{
1054    int32_t ret;
1055
1056    /* free notification request */
1057    ret = UsbFnFreeRequest(acm->notifyReq);
1058    if (ret != HDF_SUCCESS) {
1059        HDF_LOGE("%{public}s: free notify request failed", __func__);
1060        return;
1061    }
1062    acm->notifyReq = NULL;
1063}
1064
1065static uint32_t AcmEnable(struct UsbAcmDevice *acm)
1066{
1067    struct UsbSerial *port = acm->port;
1068    port->acm = acm;
1069    acm->lineCoding = port->lineCoding;
1070    return HDF_SUCCESS;
1071}
1072
1073static uint32_t AcmDisable(struct UsbAcmDevice *acm)
1074{
1075    struct UsbSerial *port = acm->port;
1076
1077    if (port == NULL) {
1078        HDF_LOGE("%{public}s: port is null", __func__);
1079        return HDF_FAILURE;
1080    }
1081
1082    OsalMutexLock(&port->lock);
1083    port->lineCoding = acm->lineCoding;
1084    OsalMutexUnlock(&port->lock);
1085
1086    return HDF_SUCCESS;
1087}
1088
1089static struct UsbFnRequest *AcmGetCtrlReq(struct UsbAcmDevice *acm)
1090{
1091    struct UsbFnRequest *req = NULL;
1092    struct DListHead *pool = &acm->ctrlPool;
1093
1094    if (!DListIsEmpty(pool)) {
1095        req = DLIST_FIRST_ENTRY(pool, struct UsbFnRequest, list);
1096        DListRemove(&req->list);
1097    }
1098    return req;
1099}
1100
1101static void AcmSetup(struct UsbAcmDevice *acm, struct UsbFnCtrlRequest *setup)
1102{
1103    if (acm == NULL || setup == NULL) {
1104        return;
1105    }
1106    struct UsbFnRequest *req = NULL;
1107    struct CtrlInfo *ctrlInfo = NULL;
1108    uint16_t value = LE16_TO_CPU(setup->value);
1109    uint16_t length = LE16_TO_CPU(setup->length);
1110    int32_t ret = 0;
1111
1112    req = AcmGetCtrlReq(acm);
1113    if (req == NULL) {
1114        HDF_LOGE("%{public}s: control request pool is empty", __func__);
1115        return;
1116    }
1117
1118    switch (setup->request) {
1119        case USB_DDK_CDC_REQ_SET_LINE_CODING:
1120            if (length != sizeof(struct UsbCdcLineCoding)) {
1121                goto OUT;
1122            }
1123            ret = (int)length;
1124            break;
1125        case USB_DDK_CDC_REQ_GET_LINE_CODING:
1126            ret = (int)MIN(length, sizeof(struct UsbCdcLineCoding));
1127            if (acm->lineCoding.dwDTERate == 0) {
1128                acm->lineCoding = acm->port->lineCoding;
1129            }
1130            if (memcpy_s(req->buf, ret, &acm->lineCoding, ret) != EOK) {
1131                return;
1132            }
1133            break;
1134        case USB_DDK_CDC_REQ_SET_CONTROL_LINE_STATE:
1135            ret = 0;
1136            acm->handshakeBits = value;
1137            break;
1138        default:
1139            HDF_LOGE("%{public}s: setup request is not supported", __func__);
1140            break;
1141    }
1142
1143OUT:
1144    ctrlInfo = (struct CtrlInfo *)req->context;
1145    ctrlInfo->request = setup->request;
1146    req->length = (uint32_t)ret;
1147    ret = UsbFnSubmitRequestAsync(req);
1148    if (ret != HDF_SUCCESS) {
1149        HDF_LOGE("%{public}s: acm send setup response error", __func__);
1150    }
1151}
1152
1153static void AcmSuspend(struct UsbAcmDevice *acm)
1154{
1155    struct UsbSerial *port = acm->port;
1156
1157    if (port == NULL) {
1158        HDF_LOGE("%{public}s: port is null", __func__);
1159        return;
1160    }
1161
1162    OsalMutexLock(&port->lock);
1163    port->suspended = true;
1164    OsalMutexUnlock(&port->lock);
1165}
1166
1167static void AcmResume(struct UsbAcmDevice *acm)
1168{
1169    int32_t ret;
1170    struct UsbSerial *port = acm->port;
1171    if (port == NULL) {
1172        HDF_LOGE("%{public}s: port is null", __func__);
1173        return;
1174    }
1175
1176    OsalMutexLock(&port->lock);
1177    port->suspended = false;
1178    if (!port->startDelayed) {
1179        OsalMutexUnlock(&port->lock);
1180        return;
1181    }
1182    ret = UsbSerialStartIo(port);
1183    if (ret != HDF_SUCCESS) {
1184        HDF_LOGE("%{public}s: UsbSerialStartIo failed", __func__);
1185    }
1186    if (acm->notify && acm->notify->Connect) {
1187        acm->notify->Connect(acm);
1188    }
1189    port->startDelayed = false;
1190    OsalMutexUnlock(&port->lock);
1191}
1192
1193static void UsbAcmEventCallback(struct UsbFnEvent *event)
1194{
1195    struct UsbAcmDevice *acm = NULL;
1196
1197    if (event == NULL || event->context == NULL) {
1198        HDF_LOGE("%{public}s: event is null", __func__);
1199        return;
1200    }
1201
1202    acm = (struct UsbAcmDevice *)event->context;
1203    switch (event->type) {
1204        case USBFN_STATE_BIND:
1205            HDF_LOGI("%{public}s: receive bind event", __func__);
1206            break;
1207        case USBFN_STATE_UNBIND:
1208            HDF_LOGI("%{public}s: receive unbind event", __func__);
1209            break;
1210        case USBFN_STATE_ENABLE:
1211            HDF_LOGI("%{public}s: receive enable event", __func__);
1212            AcmEnable(acm);
1213            break;
1214        case USBFN_STATE_DISABLE:
1215            HDF_LOGI("%{public}s: receive disable event", __func__);
1216            AcmDisable(acm);
1217            acm->enableEvtCnt = 0;
1218            break;
1219        case USBFN_STATE_SETUP:
1220            HDF_LOGI("%{public}s: receive setup event", __func__);
1221            if (event->setup != NULL) {
1222                AcmSetup(acm, event->setup);
1223            }
1224            break;
1225        case USBFN_STATE_SUSPEND:
1226            HDF_LOGI("%{public}s: receive suspend event", __func__);
1227            AcmSuspend(acm);
1228            break;
1229        case USBFN_STATE_RESUME:
1230            HDF_LOGI("%{public}s: receive resume event", __func__);
1231            AcmResume(acm);
1232            break;
1233        default:
1234            break;
1235    }
1236}
1237
1238static int32_t AcmSendNotifyRequest(
1239    struct UsbAcmDevice *acm, uint8_t type, uint16_t value, const void *data, uint32_t length)
1240{
1241    struct UsbFnRequest *req = acm->notifyReq;
1242    struct UsbCdcNotification *notify = NULL;
1243    int32_t ret;
1244
1245    if (req == NULL || req->buf == NULL) {
1246        HDF_LOGE("%{public}s: req is null", __func__);
1247        return HDF_FAILURE;
1248    }
1249
1250    acm->notifyReq = NULL;
1251    acm->pending = false;
1252    req->length = sizeof(*notify) + length;
1253
1254    notify = (struct UsbCdcNotification *)req->buf;
1255    notify->bmRequestType = USB_DDK_DIR_IN | USB_DDK_TYPE_CLASS | USB_DDK_RECIP_INTERFACE;
1256    notify->bNotificationType = type;
1257    notify->wValue = CPU_TO_LE16(value);
1258    notify->wIndex = CPU_TO_LE16(acm->ctrlIface.fn->info.index);
1259    notify->wLength = CPU_TO_LE16(length);
1260    ret = memcpy_s((void *)(notify + 1), length, data, length);
1261    if (ret != EOK) {
1262        HDF_LOGE("%{public}s: memcpy_s failed", __func__);
1263        return HDF_FAILURE;
1264    }
1265
1266    ret = UsbFnSubmitRequestAsync(req);
1267    if (ret != HDF_SUCCESS) {
1268        HDF_LOGE("%{public}s: send notify request failed", __func__);
1269        acm->notifyReq = req;
1270    }
1271
1272    return ret;
1273}
1274
1275static int32_t AcmNotifySerialState(struct UsbAcmDevice *acm)
1276{
1277    int32_t ret = 0;
1278    uint16_t serialState;
1279
1280    if (acm->notifyReq) {
1281        HDF_LOGI("acm serial state %{public}04x", acm->serialState);
1282        serialState = CPU_TO_LE16(acm->serialState);
1283        ret = AcmSendNotifyRequest(acm, USB_DDK_CDC_NOTIFY_SERIAL_STATE, 0, &serialState, sizeof(acm->serialState));
1284    } else {
1285        acm->pending = true;
1286    }
1287
1288    return ret;
1289}
1290
1291static void AcmConnect(struct UsbAcmDevice *acm)
1292{
1293    if (acm == NULL) {
1294        HDF_LOGE("%{public}s: acm is null", __func__);
1295        return;
1296    }
1297    acm->serialState |= SERIAL_STATE_DSR | SERIAL_STATE_DCD;
1298    AcmNotifySerialState(acm);
1299}
1300
1301static void AcmDisconnect(struct UsbAcmDevice *acm)
1302{
1303    if (acm == NULL) {
1304        HDF_LOGE("%{public}s: acm is null", __func__);
1305        return;
1306    }
1307    acm->serialState &= ~(SERIAL_STATE_DSR | SERIAL_STATE_DCD);
1308    AcmNotifySerialState(acm);
1309}
1310
1311static int32_t AcmSendBreak(struct UsbAcmDevice *acm, int32_t duration)
1312{
1313    uint16_t state;
1314
1315    if (acm == NULL) {
1316        HDF_LOGE("%{public}s: acm is null", __func__);
1317        return HDF_FAILURE;
1318    }
1319
1320    state = acm->serialState;
1321    state &= ~SERIAL_STATE_BREAK;
1322    if (duration != 0) {
1323        state |= SERIAL_STATE_BREAK;
1324    }
1325
1326    acm->serialState = state;
1327    return AcmNotifySerialState(acm);
1328}
1329
1330static struct AcmNotifyMethod g_acmNotifyMethod = {
1331    .Connect = AcmConnect,
1332    .Disconnect = AcmDisconnect,
1333    .SendBreak = AcmSendBreak,
1334};
1335
1336static int32_t AcmParseEachPipe(struct UsbAcmDevice *acm, struct UsbAcmInterface *iface)
1337{
1338    struct UsbFnInterface *fnIface = iface->fn;
1339    uint32_t repetIdx = 0;
1340    for (int32_t i = 0; i < fnIface->info.numPipes; i++) {
1341        struct UsbFnPipeInfo pipeInfo;
1342        (void)memset_s(&pipeInfo, sizeof(pipeInfo), 0, sizeof(pipeInfo));
1343        int32_t ret = UsbFnGetInterfacePipeInfo(fnIface, (uint8_t)i, &pipeInfo);
1344        if (ret != HDF_SUCCESS) {
1345            HDF_LOGE("%{public}s: get pipe info error", __func__);
1346            return ret;
1347        }
1348        switch (pipeInfo.type) {
1349            case USB_PIPE_TYPE_INTERRUPT:
1350                acm->notifyPipe.id = pipeInfo.id;
1351                acm->notifyPipe.maxPacketSize = pipeInfo.maxPacketSize;
1352                acm->ctrlIface = *iface;
1353                break;
1354            case USB_PIPE_TYPE_BULK:
1355                if (pipeInfo.dir == USB_PIPE_DIRECTION_IN) {
1356                    acm->dataInPipe.id = pipeInfo.id;
1357                    acm->dataInPipe.maxPacketSize = pipeInfo.maxPacketSize;
1358                    acm->dataIface = *iface;
1359                } else {
1360                    acm->dataOutPipe.id = pipeInfo.id;
1361                    acm->dataOutPipe.maxPacketSize = pipeInfo.maxPacketSize;
1362                }
1363                break;
1364            default:
1365                if (repetIdx < WAIT_UDC_MAX_LOOP) {
1366                    usleep(WAIT_UDC_TIME);
1367                    i--;
1368                }
1369                repetIdx++;
1370                HDF_LOGE("%{public}s: pipe type %{public}d don't support", __func__, pipeInfo.type);
1371                break;
1372        }
1373    }
1374
1375    return HDF_SUCCESS;
1376}
1377
1378static int32_t AcmParseAcmIface(struct UsbAcmDevice *acm, struct UsbFnInterface *fnIface)
1379{
1380    struct UsbAcmInterface iface;
1381    UsbFnInterfaceHandle handle = UsbFnOpenInterface(fnIface);
1382    if (handle == NULL) {
1383        HDF_LOGE("%{public}s: open interface failed", __func__);
1384        return HDF_FAILURE;
1385    }
1386    iface.fn = fnIface;
1387    iface.handle = handle;
1388
1389    int32_t ret = AcmParseEachPipe(acm, &iface);
1390    if (ret != HDF_SUCCESS) {
1391        return HDF_FAILURE;
1392    }
1393    return HDF_SUCCESS;
1394}
1395
1396static int32_t AcmParseEachIface(struct UsbAcmDevice *acm, struct UsbFnDevice *fnDev)
1397{
1398    struct UsbFnInterface *fnIface = NULL;
1399    uint32_t i;
1400    if (fnDev == NULL) {
1401        return HDF_FAILURE;
1402    }
1403    for (i = 0; i < fnDev->numInterfaces; i++) {
1404        fnIface = (struct UsbFnInterface *)UsbFnGetInterface(fnDev, i);
1405        if (fnIface == NULL) {
1406            HDF_LOGE("%{public}s: get interface failed", __func__);
1407            return HDF_FAILURE;
1408        }
1409
1410        if (fnIface->info.subclass == USB_DDK_CDC_SUBCLASS_ACM) {
1411            (void)AcmParseAcmIface(acm, fnIface);
1412            fnIface = (struct UsbFnInterface *)UsbFnGetInterface(fnDev, i + 1);
1413            if (fnIface == NULL) {
1414                HDF_LOGE("%{public}s: get interface failed", __func__);
1415                return HDF_FAILURE;
1416            }
1417            (void)AcmParseAcmIface(acm, fnIface);
1418            return HDF_SUCCESS;
1419        }
1420    }
1421    return HDF_FAILURE;
1422}
1423
1424static int32_t AcmCreateFuncDevice(struct UsbAcmDevice *acm, struct DeviceResourceIface *iface)
1425{
1426    int32_t ret;
1427    struct UsbFnDevice *fnDev = NULL;
1428
1429    if (iface->GetString(acm->device->property, "udc_name", (const char **)&acm->udcName, UDC_NAME) != HDF_SUCCESS) {
1430        HDF_LOGE("%{public}s: read udc_name failed, use default", __func__);
1431        return HDF_FAILURE;
1432    }
1433
1434    fnDev = (struct UsbFnDevice *)UsbFnGetDevice(acm->udcName);
1435    if (fnDev == NULL) {
1436        HDF_LOGE("%{public}s: create usb function device failed", __func__);
1437        return HDF_FAILURE;
1438    }
1439
1440    ret = AcmParseEachIface(acm, fnDev);
1441    if (ret != HDF_SUCCESS) {
1442        HDF_LOGE("%{public}s: get pipes failed", __func__);
1443        return HDF_FAILURE;
1444    }
1445
1446    acm->fnDev = fnDev;
1447    return HDF_SUCCESS;
1448}
1449
1450static int32_t AcmReleaseFuncDevice(struct UsbAcmDevice *acm)
1451{
1452    int32_t ret = HDF_SUCCESS;
1453    if (acm->fnDev == NULL) {
1454        HDF_LOGE("%{public}s: fnDev is null", __func__);
1455        return HDF_FAILURE;
1456    }
1457    AcmFreeCtrlRequests(acm);
1458    AcmFreeNotifyRequest(acm);
1459    (void)UsbFnCloseInterface(acm->ctrlIface.handle);
1460    (void)UsbFnCloseInterface(acm->dataIface.handle);
1461    (void)UsbFnStopRecvInterfaceEvent(acm->ctrlIface.fn);
1462    return ret;
1463}
1464
1465static int32_t UsbSerialAlloc(struct UsbAcmDevice *acm)
1466{
1467    struct UsbSerial *port = NULL;
1468
1469    port = (struct UsbSerial *)OsalMemCalloc(sizeof(*port));
1470    if (port == NULL) {
1471        HDF_LOGE("%{public}s: Alloc usb serial port failed", __func__);
1472        return HDF_FAILURE;
1473    }
1474
1475    if (OsalMutexInit(&port->lock) != HDF_SUCCESS) {
1476        HDF_LOGE("%{public}s: init lock fail!", __func__);
1477        OsalMemFree(port);
1478        return HDF_FAILURE;
1479    }
1480
1481    DListHeadInit(&port->readPool);
1482    DListHeadInit(&port->readQueue);
1483    DListHeadInit(&port->writePool);
1484
1485    port->lineCoding.dwDTERate = CPU_TO_LE32(PORT_RATE);
1486    port->lineCoding.bCharFormat = USB_CDC_1_STOP_BITS;
1487    port->lineCoding.bParityType = USB_CDC_NO_PARITY;
1488    port->lineCoding.bDataBits = DATA_BIT;
1489
1490    acm->port = port;
1491    return HDF_SUCCESS;
1492}
1493
1494static void UsbSerialFree(struct UsbAcmDevice *acm)
1495{
1496    struct UsbSerial *port = acm->port;
1497
1498    if (port == NULL) {
1499        HDF_LOGE("%{public}s: port is null", __func__);
1500        return;
1501    }
1502    OsalMemFree(port);
1503    acm->port = NULL;
1504}
1505
1506/* HdfDriverEntry implementations */
1507static int32_t AcmDriverBind(struct HdfDeviceObject *device)
1508{
1509    struct UsbAcmDevice *acm = NULL;
1510
1511    if (device == NULL) {
1512        HDF_LOGE("%{public}s: device is null", __func__);
1513        return HDF_ERR_INVALID_OBJECT;
1514    }
1515
1516    acm = (struct UsbAcmDevice *)OsalMemCalloc(sizeof(*acm));
1517    if (acm == NULL) {
1518        HDF_LOGE("%{public}s: Alloc usb acm device failed", __func__);
1519        return HDF_FAILURE;
1520    }
1521
1522    if (OsalMutexInit(&acm->lock) != HDF_SUCCESS) {
1523        HDF_LOGE("%{public}s: init lock fail!", __func__);
1524        OsalMemFree(acm);
1525        return HDF_FAILURE;
1526    }
1527
1528    if (HdfDeviceObjectSetInterfaceDesc(device, "hdf.usb.usbfn") != HDF_SUCCESS) {
1529        HDF_LOGE(" Set Desc fail!");
1530        OsalMemFree(acm);
1531        return HDF_FAILURE;
1532    }
1533
1534    acm->device = device;
1535    device->service = &(acm->service);
1536    acm->device->service->Dispatch = AcmDeviceDispatch;
1537    acm->notify = NULL;
1538    acm->initFlag = false;
1539    return HDF_SUCCESS;
1540}
1541
1542static int32_t UsbSerialInit(struct UsbAcmDevice *acm)
1543{
1544    struct DeviceResourceIface *iface = NULL;
1545    int32_t ret;
1546
1547    if (acm == NULL || acm->initFlag) {
1548        HDF_LOGE("%{public}s: acm is null", __func__);
1549        return HDF_FAILURE;
1550    }
1551    iface = DeviceResourceGetIfaceInstance(HDF_CONFIG_SOURCE);
1552    if (iface == NULL || iface->GetUint32 == NULL) {
1553        HDF_LOGE("%{public}s: face is invalid", __func__);
1554        return HDF_FAILURE;
1555    }
1556
1557    ret = AcmCreateFuncDevice(acm, iface);
1558    if (ret != HDF_SUCCESS) {
1559        HDF_LOGE("%{public}s: AcmCreateFuncDevice failed", __func__);
1560        return HDF_FAILURE;
1561    }
1562
1563    ret = UsbSerialAlloc(acm);
1564    if (ret != HDF_SUCCESS) {
1565        HDF_LOGE("%{public}s: UsbSerialAlloc failed", __func__);
1566        goto ERR;
1567    }
1568
1569    ret = AcmAllocCtrlRequests(acm, CTRL_REQUEST_NUM);
1570    if (ret != HDF_SUCCESS) {
1571        HDF_LOGE("%{public}s: AcmAllocCtrlRequests failed", __func__);
1572        goto ERR;
1573    }
1574
1575    ret = AcmAllocNotifyRequest(acm);
1576    if (ret != HDF_SUCCESS) {
1577        HDF_LOGE("%{public}s: AcmAllocNotifyRequest failed", __func__);
1578        goto ERR;
1579    }
1580
1581    ret = UsbFnStartRecvInterfaceEvent(acm->ctrlIface.fn, RECEIVE_ALL_EVENTS, UsbAcmEventCallback, acm);
1582    if (ret != HDF_SUCCESS) {
1583        HDF_LOGE("%{public}s: register event callback failed", __func__);
1584        goto ERR;
1585    }
1586
1587    acm->notify = &g_acmNotifyMethod;
1588    acm->initFlag = true;
1589    return HDF_SUCCESS;
1590
1591ERR:
1592    UsbSerialFree(acm);
1593    (void)AcmReleaseFuncDevice(acm);
1594    return ret;
1595}
1596
1597static int32_t UsbSerialRelease(struct UsbAcmDevice *acm)
1598{
1599    if (acm == NULL || acm->initFlag == false) {
1600        HDF_LOGE("%{public}s: acm is null", __func__);
1601        return HDF_FAILURE;
1602    }
1603    OsalMutexLock(&acm->lock);
1604    (void)AcmReleaseFuncDevice(acm);
1605    UsbSerialFree(acm);
1606    acm->initFlag = false;
1607    OsalMutexUnlock(&acm->lock);
1608    return 0;
1609}
1610
1611static int32_t AcmDriverInit(struct HdfDeviceObject *device)
1612{
1613    (void)device;
1614    HDF_LOGI("%{public}s: do nothing", __func__);
1615    return 0;
1616}
1617
1618static void AcmDriverRelease(struct HdfDeviceObject *device)
1619{
1620    struct UsbAcmDevice *acm = NULL;
1621    if (device == NULL) {
1622        HDF_LOGE("%{public}s: device is NULL", __func__);
1623        return;
1624    }
1625
1626    acm = (struct UsbAcmDevice *)device->service;
1627    if (acm == NULL) {
1628        HDF_LOGE("%{public}s: acm is null", __func__);
1629        return;
1630    }
1631    (void)OsalMutexDestroy(&acm->lock);
1632    AcmDeviceDestroy(acm);
1633    device->service = NULL;
1634}
1635
1636struct HdfDriverEntry g_acmDriverEntry = {
1637    .moduleVersion = 1,
1638    .moduleName = "usbfn_cdcacm",
1639    .Bind = AcmDriverBind,
1640    .Init = AcmDriverInit,
1641    .Release = AcmDriverRelease,
1642};
1643
1644HDF_INIT(g_acmDriverEntry);
1645