1094332d3Sopenharmony_ci/*
2094332d3Sopenharmony_ci * Copyright (c) 2021-2023 Huawei Device Co., Ltd.
3094332d3Sopenharmony_ci * Licensed under the Apache License, Version 2.0 (the "License");
4094332d3Sopenharmony_ci * you may not use this file except in compliance with the License.
5094332d3Sopenharmony_ci * You may obtain a copy of the License at
6094332d3Sopenharmony_ci *
7094332d3Sopenharmony_ci *     http://www.apache.org/licenses/LICENSE-2.0
8094332d3Sopenharmony_ci *
9094332d3Sopenharmony_ci * Unless required by applicable law or agreed to in writing, software
10094332d3Sopenharmony_ci * distributed under the License is distributed on an "AS IS" BASIS,
11094332d3Sopenharmony_ci * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12094332d3Sopenharmony_ci * See the License for the specific language governing permissions and
13094332d3Sopenharmony_ci * limitations under the License.
14094332d3Sopenharmony_ci */
15094332d3Sopenharmony_ci
16094332d3Sopenharmony_ci#include "../include/cdcacm.h"
17094332d3Sopenharmony_ci#include <unistd.h>
18094332d3Sopenharmony_ci#include "device_resource_if.h"
19094332d3Sopenharmony_ci#include "hdf_base.h"
20094332d3Sopenharmony_ci#include "hdf_device_object.h"
21094332d3Sopenharmony_ci#include "hdf_log.h"
22094332d3Sopenharmony_ci#include "osal_mem.h"
23094332d3Sopenharmony_ci#include "osal_time.h"
24094332d3Sopenharmony_ci#include "securec.h"
25094332d3Sopenharmony_ci#include "usbfn_device.h"
26094332d3Sopenharmony_ci#include "usbfn_interface.h"
27094332d3Sopenharmony_ci#include "usbfn_request.h"
28094332d3Sopenharmony_ci
29094332d3Sopenharmony_ci#define HDF_LOG_TAG hdf_cdc_acm
30094332d3Sopenharmony_ci#define UDC_NAME "invalid_udc_name"
31094332d3Sopenharmony_ci
32094332d3Sopenharmony_ci#define PENDING_FLAG     0
33094332d3Sopenharmony_ci#define CTRL_REQUEST_NUM 2
34094332d3Sopenharmony_ci#define QUEUE_SIZE       8
35094332d3Sopenharmony_ci#define WRITE_BUF_SIZE   8192
36094332d3Sopenharmony_ci#define READ_BUF_SIZE    8192
37094332d3Sopenharmony_ci
38094332d3Sopenharmony_ci#define PORT_RATE 9600
39094332d3Sopenharmony_ci#define DATA_BIT  8
40094332d3Sopenharmony_ci#define USBCDC_LEN 2
41094332d3Sopenharmony_ci#define RECEIVE_ALL_EVENTS 0xff
42094332d3Sopenharmony_cistatic const int32_t WAIT_UDC_MAX_LOOP = 3;
43094332d3Sopenharmony_cistatic const uint32_t WAIT_UDC_TIME = 100000;
44094332d3Sopenharmony_cistatic int32_t g_inFifo = 0;
45094332d3Sopenharmony_ci/* Usb Serial Related Functions */
46094332d3Sopenharmony_ci
47094332d3Sopenharmony_cistatic int32_t UsbSerialInit(struct UsbAcmDevice *acm);
48094332d3Sopenharmony_cistatic int32_t UsbSerialRelease(struct UsbAcmDevice *acm);
49094332d3Sopenharmony_cistatic int32_t UsbSerialStartTx(struct UsbSerial *port)
50094332d3Sopenharmony_ci{
51094332d3Sopenharmony_ci    if (port == NULL) {
52094332d3Sopenharmony_ci        return HDF_FAILURE;
53094332d3Sopenharmony_ci    }
54094332d3Sopenharmony_ci    struct DListHead *pool = &port->writePool;
55094332d3Sopenharmony_ci    int32_t ret = HDF_FAILURE;
56094332d3Sopenharmony_ci    if (port->acm == NULL) {
57094332d3Sopenharmony_ci        return HDF_SUCCESS;
58094332d3Sopenharmony_ci    }
59094332d3Sopenharmony_ci    while (!port->writeBusy && !DListIsEmpty(pool)) {
60094332d3Sopenharmony_ci        struct UsbFnRequest *req = NULL;
61094332d3Sopenharmony_ci        uint32_t len;
62094332d3Sopenharmony_ci        if (port->writeStarted >= QUEUE_SIZE) {
63094332d3Sopenharmony_ci            break;
64094332d3Sopenharmony_ci        }
65094332d3Sopenharmony_ci        req = DLIST_FIRST_ENTRY(pool, struct UsbFnRequest, list);
66094332d3Sopenharmony_ci        if (req == NULL) {
67094332d3Sopenharmony_ci            break;
68094332d3Sopenharmony_ci        }
69094332d3Sopenharmony_ci        len = DataFifoRead(&port->writeFifo, req->buf, port->acm->dataInPipe.maxPacketSize);
70094332d3Sopenharmony_ci        if (len == 0) {
71094332d3Sopenharmony_ci            break;
72094332d3Sopenharmony_ci        }
73094332d3Sopenharmony_ci        req->length = len;
74094332d3Sopenharmony_ci        DListRemove(&req->list);
75094332d3Sopenharmony_ci        port->writeBusy = true;
76094332d3Sopenharmony_ci        ret = UsbFnSubmitRequestAsync(req);
77094332d3Sopenharmony_ci        port->writeBusy = false;
78094332d3Sopenharmony_ci        if (ret != HDF_SUCCESS) {
79094332d3Sopenharmony_ci            HDF_LOGE("%{public}s: send request error %{public}d", __func__, ret);
80094332d3Sopenharmony_ci            DListInsertTail(&req->list, pool);
81094332d3Sopenharmony_ci            break;
82094332d3Sopenharmony_ci        }
83094332d3Sopenharmony_ci        port->writeStarted++;
84094332d3Sopenharmony_ci        /* if acm is disconnect, abort immediately */
85094332d3Sopenharmony_ci        if (port->acm == NULL) {
86094332d3Sopenharmony_ci            break;
87094332d3Sopenharmony_ci        }
88094332d3Sopenharmony_ci    }
89094332d3Sopenharmony_ci    return ret;
90094332d3Sopenharmony_ci}
91094332d3Sopenharmony_ci
92094332d3Sopenharmony_cistatic uint32_t UsbSerialStartRx(struct UsbSerial *port)
93094332d3Sopenharmony_ci{
94094332d3Sopenharmony_ci    struct DListHead *pool = &port->readPool;
95094332d3Sopenharmony_ci    struct UsbAcmPipe *out = &port->acm->dataOutPipe;
96094332d3Sopenharmony_ci    while (!DListIsEmpty(pool)) {
97094332d3Sopenharmony_ci        struct UsbFnRequest *req = NULL;
98094332d3Sopenharmony_ci        int32_t ret;
99094332d3Sopenharmony_ci
100094332d3Sopenharmony_ci        if (port->readStarted >= QUEUE_SIZE) {
101094332d3Sopenharmony_ci            break;
102094332d3Sopenharmony_ci        }
103094332d3Sopenharmony_ci
104094332d3Sopenharmony_ci        req = DLIST_FIRST_ENTRY(pool, struct UsbFnRequest, list);
105094332d3Sopenharmony_ci        DListRemove(&req->list);
106094332d3Sopenharmony_ci        req->length = out->maxPacketSize;
107094332d3Sopenharmony_ci        ret = UsbFnSubmitRequestAsync(req);
108094332d3Sopenharmony_ci        if (ret != HDF_SUCCESS) {
109094332d3Sopenharmony_ci            HDF_LOGE("%{public}s: send request error %{public}d", __func__, ret);
110094332d3Sopenharmony_ci            DListInsertTail(&req->list, pool);
111094332d3Sopenharmony_ci            break;
112094332d3Sopenharmony_ci        }
113094332d3Sopenharmony_ci        port->readStarted++;
114094332d3Sopenharmony_ci        /* if acm is disconnect, abort immediately */
115094332d3Sopenharmony_ci        if (port->acm == NULL) {
116094332d3Sopenharmony_ci            break;
117094332d3Sopenharmony_ci        }
118094332d3Sopenharmony_ci    }
119094332d3Sopenharmony_ci    return port->readStarted;
120094332d3Sopenharmony_ci}
121094332d3Sopenharmony_ci
122094332d3Sopenharmony_cistatic void UsbSerialRxPush(struct UsbSerial *port)
123094332d3Sopenharmony_ci{
124094332d3Sopenharmony_ci    struct DListHead *queue = &port->readQueue;
125094332d3Sopenharmony_ci    bool disconnect = false;
126094332d3Sopenharmony_ci    while (!DListIsEmpty(queue)) {
127094332d3Sopenharmony_ci        struct UsbFnRequest *req;
128094332d3Sopenharmony_ci
129094332d3Sopenharmony_ci        req = DLIST_FIRST_ENTRY(queue, struct UsbFnRequest, list);
130094332d3Sopenharmony_ci        switch (req->status) {
131094332d3Sopenharmony_ci            case USB_REQUEST_NO_DEVICE:
132094332d3Sopenharmony_ci                disconnect = true;
133094332d3Sopenharmony_ci                HDF_LOGV("%{public}s: the device is disconnected", __func__);
134094332d3Sopenharmony_ci                break;
135094332d3Sopenharmony_ci            case USB_REQUEST_COMPLETED:
136094332d3Sopenharmony_ci                break;
137094332d3Sopenharmony_ci            default:
138094332d3Sopenharmony_ci                HDF_LOGV("%{public}s: unexpected status %{public}d", __func__, req->status);
139094332d3Sopenharmony_ci                break;
140094332d3Sopenharmony_ci        }
141094332d3Sopenharmony_ci
142094332d3Sopenharmony_ci        if (g_inFifo && req->actual) {
143094332d3Sopenharmony_ci            uint32_t size = req->actual;
144094332d3Sopenharmony_ci            uint8_t *data = req->buf;
145094332d3Sopenharmony_ci
146094332d3Sopenharmony_ci            if (DataFifoIsFull(&port->readFifo)) {
147094332d3Sopenharmony_ci                DataFifoSkip(&port->readFifo, size);
148094332d3Sopenharmony_ci            }
149094332d3Sopenharmony_ci            uint32_t count = DataFifoWrite(&port->readFifo, data, size);
150094332d3Sopenharmony_ci            if (count != size) {
151094332d3Sopenharmony_ci                HDF_LOGW("%{public}s: write %{public}u less than expected %{public}u", __func__, count, size);
152094332d3Sopenharmony_ci            }
153094332d3Sopenharmony_ci        }
154094332d3Sopenharmony_ci
155094332d3Sopenharmony_ci        DListRemove(&req->list);
156094332d3Sopenharmony_ci        DListInsertTail(&req->list, &port->readPool);
157094332d3Sopenharmony_ci        port->readStarted--;
158094332d3Sopenharmony_ci    }
159094332d3Sopenharmony_ci
160094332d3Sopenharmony_ci    if (!disconnect && port->acm) {
161094332d3Sopenharmony_ci        UsbSerialStartRx(port);
162094332d3Sopenharmony_ci    }
163094332d3Sopenharmony_ci}
164094332d3Sopenharmony_ci
165094332d3Sopenharmony_cistatic void UsbSerialFreeRequests(struct DListHead * const head, int32_t *allocated)
166094332d3Sopenharmony_ci{
167094332d3Sopenharmony_ci    struct UsbFnRequest *req = NULL;
168094332d3Sopenharmony_ci    while (!DListIsEmpty(head)) {
169094332d3Sopenharmony_ci        req = DLIST_FIRST_ENTRY(head, struct UsbFnRequest, list);
170094332d3Sopenharmony_ci        DListRemove(&req->list);
171094332d3Sopenharmony_ci        (void)UsbFnCancelRequest(req);
172094332d3Sopenharmony_ci        (void)UsbFnFreeRequest(req);
173094332d3Sopenharmony_ci        if (allocated) {
174094332d3Sopenharmony_ci            (*allocated)--;
175094332d3Sopenharmony_ci        }
176094332d3Sopenharmony_ci    }
177094332d3Sopenharmony_ci}
178094332d3Sopenharmony_ci
179094332d3Sopenharmony_cistatic bool g_isStartRead = false;
180094332d3Sopenharmony_cistatic bool g_isReadDone = false;
181094332d3Sopenharmony_cistatic uint64_t g_readCnt = 0;
182094332d3Sopenharmony_cistruct timeval g_readTimeStart, g_readTimeEnd;
183094332d3Sopenharmony_cistatic float g_readSpeed = 0;
184094332d3Sopenharmony_cistatic bool g_isGetReadTimeStart = false;
185094332d3Sopenharmony_cistatic void UsbSerialReadComplete(uint8_t pipe, struct UsbFnRequest *req)
186094332d3Sopenharmony_ci{
187094332d3Sopenharmony_ci    struct UsbSerial *port = (struct UsbSerial *)req->context;
188094332d3Sopenharmony_ci    if ((!g_isReadDone) && g_isStartRead && req->status == USB_REQUEST_COMPLETED) {
189094332d3Sopenharmony_ci        g_readCnt += req->actual;
190094332d3Sopenharmony_ci        if (!g_isGetReadTimeStart) {
191094332d3Sopenharmony_ci            g_isGetReadTimeStart = true;
192094332d3Sopenharmony_ci            gettimeofday(&g_readTimeStart, NULL);
193094332d3Sopenharmony_ci        }
194094332d3Sopenharmony_ci    }
195094332d3Sopenharmony_ci    OsalMutexLock(&port->lock);
196094332d3Sopenharmony_ci    DListInsertTail(&req->list, &port->readQueue);
197094332d3Sopenharmony_ci    UsbSerialRxPush(port);
198094332d3Sopenharmony_ci    OsalMutexUnlock(&port->lock);
199094332d3Sopenharmony_ci}
200094332d3Sopenharmony_ci
201094332d3Sopenharmony_cistatic int32_t SpeedReadThread(void *arg)
202094332d3Sopenharmony_ci{
203094332d3Sopenharmony_ci    (void)arg;
204094332d3Sopenharmony_ci    g_readCnt = 0;
205094332d3Sopenharmony_ci    g_isReadDone = false;
206094332d3Sopenharmony_ci    g_readSpeed = 0;
207094332d3Sopenharmony_ci    g_isGetReadTimeStart = false;
208094332d3Sopenharmony_ci    double timeUse;
209094332d3Sopenharmony_ci    double usec = 1000000;
210094332d3Sopenharmony_ci    double k = 1024;
211094332d3Sopenharmony_ci    struct timeval timeTmp;
212094332d3Sopenharmony_ci    while (!g_isReadDone) {
213094332d3Sopenharmony_ci        if (g_readCnt == 0) {
214094332d3Sopenharmony_ci            OsalSleep(1);
215094332d3Sopenharmony_ci            continue;
216094332d3Sopenharmony_ci        } else {
217094332d3Sopenharmony_ci            OsalSleep(1);
218094332d3Sopenharmony_ci        }
219094332d3Sopenharmony_ci        gettimeofday(&timeTmp, NULL);
220094332d3Sopenharmony_ci        timeUse = (double)(timeTmp.tv_sec - g_readTimeStart.tv_sec) + (double)timeTmp.tv_usec / usec -
221094332d3Sopenharmony_ci            (double)g_readTimeStart.tv_usec / usec;
222094332d3Sopenharmony_ci        g_readSpeed = (float)((double)g_readCnt / k / k / timeUse);
223094332d3Sopenharmony_ci    }
224094332d3Sopenharmony_ci    timeUse = (double)(g_readTimeEnd.tv_sec - g_readTimeStart.tv_sec) + (double)g_readTimeEnd.tv_usec / usec -
225094332d3Sopenharmony_ci        (double)g_readTimeStart.tv_usec / usec;
226094332d3Sopenharmony_ci    HDF_LOGD("timeUse = %{public}lf", timeUse);
227094332d3Sopenharmony_ci    g_readSpeed = (float)((double)g_readCnt / k / k / timeUse);
228094332d3Sopenharmony_ci    HDF_LOGD("%{public}s: g_speed = %{public}f MB/s", __func__, g_readSpeed);
229094332d3Sopenharmony_ci    return HDF_SUCCESS;
230094332d3Sopenharmony_ci}
231094332d3Sopenharmony_ci
232094332d3Sopenharmony_ci#define HDF_PROCESS_STACK_SIZE 100000
233094332d3Sopenharmony_cistruct OsalThread g_threadRead;
234094332d3Sopenharmony_cistatic int32_t StartThreadReadSpeed(struct UsbSerial *port)
235094332d3Sopenharmony_ci{
236094332d3Sopenharmony_ci    int32_t ret;
237094332d3Sopenharmony_ci    struct OsalThreadParam threadCfg;
238094332d3Sopenharmony_ci    ret = memset_s(&threadCfg, sizeof(threadCfg), 0, sizeof(threadCfg));
239094332d3Sopenharmony_ci    if (ret != EOK) {
240094332d3Sopenharmony_ci        HDF_LOGE("%{public}s:%{public}d memset_s failed", __func__, __LINE__);
241094332d3Sopenharmony_ci        return ret;
242094332d3Sopenharmony_ci    }
243094332d3Sopenharmony_ci
244094332d3Sopenharmony_ci    threadCfg.name = "speed read process";
245094332d3Sopenharmony_ci    threadCfg.priority = OSAL_THREAD_PRI_LOW;
246094332d3Sopenharmony_ci    threadCfg.stackSize = HDF_PROCESS_STACK_SIZE;
247094332d3Sopenharmony_ci
248094332d3Sopenharmony_ci    ret = OsalThreadCreate(&g_threadRead, (OsalThreadEntry)SpeedReadThread, port);
249094332d3Sopenharmony_ci    if (ret != HDF_SUCCESS) {
250094332d3Sopenharmony_ci        HDF_LOGE("%{public}s:%{public}d OsalThreadCreate failed, ret=%{public}d ", __func__, __LINE__, ret);
251094332d3Sopenharmony_ci        return HDF_ERR_DEVICE_BUSY;
252094332d3Sopenharmony_ci    }
253094332d3Sopenharmony_ci
254094332d3Sopenharmony_ci    ret = OsalThreadStart(&g_threadRead, &threadCfg);
255094332d3Sopenharmony_ci    if (ret != HDF_SUCCESS) {
256094332d3Sopenharmony_ci        HDF_LOGE("%{public}s:%{public}d OsalThreadStart failed, ret=%{public}d ", __func__, __LINE__, ret);
257094332d3Sopenharmony_ci        return HDF_ERR_DEVICE_BUSY;
258094332d3Sopenharmony_ci    }
259094332d3Sopenharmony_ci    return HDF_SUCCESS;
260094332d3Sopenharmony_ci}
261094332d3Sopenharmony_ci
262094332d3Sopenharmony_cistatic int32_t UsbSerialGetTempReadSpeed(struct UsbSerial *port, struct HdfSBuf *reply)
263094332d3Sopenharmony_ci{
264094332d3Sopenharmony_ci    (void)port;
265094332d3Sopenharmony_ci    if (!HdfSbufWriteFloat(reply, g_readSpeed)) {
266094332d3Sopenharmony_ci        HDF_LOGE("%{public}s: HdfSbufWriteFloat failed", __func__);
267094332d3Sopenharmony_ci        return HDF_FAILURE;
268094332d3Sopenharmony_ci    }
269094332d3Sopenharmony_ci    return HDF_SUCCESS;
270094332d3Sopenharmony_ci}
271094332d3Sopenharmony_ci
272094332d3Sopenharmony_cistatic int32_t UsbSerialGetTempReadSpeedInt(struct UsbSerial *port, struct HdfSBuf *reply)
273094332d3Sopenharmony_ci{
274094332d3Sopenharmony_ci    (void)port;
275094332d3Sopenharmony_ci    uint32_t calc = 10000;
276094332d3Sopenharmony_ci    if (!HdfSbufWriteUint32(reply, (uint32_t)(g_readSpeed * calc))) {
277094332d3Sopenharmony_ci        HDF_LOGE("%{public}s: HdfSbufWriteUint32 failed", __func__);
278094332d3Sopenharmony_ci        return HDF_FAILURE;
279094332d3Sopenharmony_ci    }
280094332d3Sopenharmony_ci    return HDF_SUCCESS;
281094332d3Sopenharmony_ci}
282094332d3Sopenharmony_ci
283094332d3Sopenharmony_cistatic int32_t UsbSerialReadSpeedDone(struct UsbSerial *port)
284094332d3Sopenharmony_ci{
285094332d3Sopenharmony_ci    (void)port;
286094332d3Sopenharmony_ci    gettimeofday(&g_readTimeEnd, NULL);
287094332d3Sopenharmony_ci    g_isReadDone = true;
288094332d3Sopenharmony_ci    g_isStartRead = false;
289094332d3Sopenharmony_ci    return HDF_SUCCESS;
290094332d3Sopenharmony_ci}
291094332d3Sopenharmony_ci
292094332d3Sopenharmony_cistatic int32_t UsbSerialReadSpeedStart(struct UsbSerial *port)
293094332d3Sopenharmony_ci{
294094332d3Sopenharmony_ci    g_inFifo = 0;
295094332d3Sopenharmony_ci    g_isStartRead = true;
296094332d3Sopenharmony_ci    return StartThreadReadSpeed(port);
297094332d3Sopenharmony_ci}
298094332d3Sopenharmony_ci
299094332d3Sopenharmony_cistatic void UsbSerialWriteComplete(uint8_t pipe, struct UsbFnRequest *req)
300094332d3Sopenharmony_ci{
301094332d3Sopenharmony_ci    struct UsbSerial *port = (struct UsbSerial *)req->context;
302094332d3Sopenharmony_ci
303094332d3Sopenharmony_ci    OsalMutexLock(&port->lock);
304094332d3Sopenharmony_ci    DListInsertTail(&req->list, &port->writePool);
305094332d3Sopenharmony_ci    port->writeStarted--;
306094332d3Sopenharmony_ci
307094332d3Sopenharmony_ci    switch (req->status) {
308094332d3Sopenharmony_ci        case USB_REQUEST_COMPLETED:
309094332d3Sopenharmony_ci            UsbSerialStartTx(port);
310094332d3Sopenharmony_ci            break;
311094332d3Sopenharmony_ci        case USB_REQUEST_NO_DEVICE:
312094332d3Sopenharmony_ci            HDF_LOGV("%{public}s: acm device was disconnected", __func__);
313094332d3Sopenharmony_ci            break;
314094332d3Sopenharmony_ci        default:
315094332d3Sopenharmony_ci            HDF_LOGV("%{public}s: unexpected status %{public}d", __func__, req->status);
316094332d3Sopenharmony_ci            break;
317094332d3Sopenharmony_ci    }
318094332d3Sopenharmony_ci    OsalMutexUnlock(&port->lock);
319094332d3Sopenharmony_ci}
320094332d3Sopenharmony_ci
321094332d3Sopenharmony_cistatic int32_t UsbSerialAllocReadRequests(struct UsbSerial *port, int32_t num)
322094332d3Sopenharmony_ci{
323094332d3Sopenharmony_ci    struct UsbAcmDevice *acm = port->acm;
324094332d3Sopenharmony_ci    struct DListHead *head = &port->readPool;
325094332d3Sopenharmony_ci    struct UsbFnRequest *req = NULL;
326094332d3Sopenharmony_ci    int32_t i;
327094332d3Sopenharmony_ci
328094332d3Sopenharmony_ci    for (i = 0; i < num; i++) {
329094332d3Sopenharmony_ci        req = UsbFnAllocRequest(acm->dataIface.handle, acm->dataOutPipe.id, acm->dataOutPipe.maxPacketSize);
330094332d3Sopenharmony_ci        if (!req) {
331094332d3Sopenharmony_ci            return DListIsEmpty(head) ? HDF_FAILURE : HDF_SUCCESS;
332094332d3Sopenharmony_ci        }
333094332d3Sopenharmony_ci
334094332d3Sopenharmony_ci        req->complete = UsbSerialReadComplete;
335094332d3Sopenharmony_ci        req->context = port;
336094332d3Sopenharmony_ci        DListInsertTail(&req->list, head);
337094332d3Sopenharmony_ci        port->readAllocated++;
338094332d3Sopenharmony_ci    }
339094332d3Sopenharmony_ci    return HDF_SUCCESS;
340094332d3Sopenharmony_ci}
341094332d3Sopenharmony_ci
342094332d3Sopenharmony_cistatic int32_t UsbSerialAllocWriteRequests(struct UsbSerial *port, int32_t num)
343094332d3Sopenharmony_ci{
344094332d3Sopenharmony_ci    struct UsbAcmDevice *acm = port->acm;
345094332d3Sopenharmony_ci    struct DListHead *head = &port->writePool;
346094332d3Sopenharmony_ci    struct UsbFnRequest *req = NULL;
347094332d3Sopenharmony_ci    int32_t i;
348094332d3Sopenharmony_ci
349094332d3Sopenharmony_ci    for (i = 0; i < num; i++) {
350094332d3Sopenharmony_ci        req = UsbFnAllocRequest(acm->dataIface.handle, acm->dataInPipe.id, acm->dataInPipe.maxPacketSize);
351094332d3Sopenharmony_ci        if (!req) {
352094332d3Sopenharmony_ci            return DListIsEmpty(head) ? HDF_FAILURE : HDF_SUCCESS;
353094332d3Sopenharmony_ci        }
354094332d3Sopenharmony_ci
355094332d3Sopenharmony_ci        req->complete = UsbSerialWriteComplete;
356094332d3Sopenharmony_ci        req->context = port;
357094332d3Sopenharmony_ci        DListInsertTail(&req->list, head);
358094332d3Sopenharmony_ci        port->writeAllocated++;
359094332d3Sopenharmony_ci    }
360094332d3Sopenharmony_ci    return HDF_SUCCESS;
361094332d3Sopenharmony_ci}
362094332d3Sopenharmony_ci
363094332d3Sopenharmony_cistatic void UsbSerialFreeFifo(struct DataFifo *fifo)
364094332d3Sopenharmony_ci{
365094332d3Sopenharmony_ci    void *buf = fifo->data;
366094332d3Sopenharmony_ci    OsalMemFree(buf);
367094332d3Sopenharmony_ci    DataFifoInit(fifo, 0, NULL);
368094332d3Sopenharmony_ci}
369094332d3Sopenharmony_ci
370094332d3Sopenharmony_cistatic int32_t UsbSerialStartIo(struct UsbSerial *port)
371094332d3Sopenharmony_ci{
372094332d3Sopenharmony_ci    struct DListHead *head = &port->readPool;
373094332d3Sopenharmony_ci    int32_t ret = HDF_SUCCESS;
374094332d3Sopenharmony_ci    uint32_t started;
375094332d3Sopenharmony_ci
376094332d3Sopenharmony_ci    /* allocate requests for read/write */
377094332d3Sopenharmony_ci    if (port->readAllocated == 0) {
378094332d3Sopenharmony_ci        ret = UsbSerialAllocReadRequests(port, QUEUE_SIZE);
379094332d3Sopenharmony_ci        if (ret != HDF_SUCCESS) {
380094332d3Sopenharmony_ci            HDF_LOGE("%{public}s: UsbSerialAllocReadRequests failed:%{public}d", __func__, ret);
381094332d3Sopenharmony_ci            return ret;
382094332d3Sopenharmony_ci        }
383094332d3Sopenharmony_ci    }
384094332d3Sopenharmony_ci    if (port->writeAllocated == 0) {
385094332d3Sopenharmony_ci        ret = UsbSerialAllocWriteRequests(port, QUEUE_SIZE);
386094332d3Sopenharmony_ci        if (ret != HDF_SUCCESS) {
387094332d3Sopenharmony_ci            UsbSerialFreeRequests(head, &port->readAllocated);
388094332d3Sopenharmony_ci            HDF_LOGE("%{public}s: UsbSerialAllocWriteRequests failed:%{public}d", __func__, ret);
389094332d3Sopenharmony_ci            return ret;
390094332d3Sopenharmony_ci        }
391094332d3Sopenharmony_ci    }
392094332d3Sopenharmony_ci
393094332d3Sopenharmony_ci    started = UsbSerialStartRx(port);
394094332d3Sopenharmony_ci    if (started) {
395094332d3Sopenharmony_ci        UsbSerialStartTx(port);
396094332d3Sopenharmony_ci    } else {
397094332d3Sopenharmony_ci        UsbSerialFreeRequests(head, &port->readAllocated);
398094332d3Sopenharmony_ci        UsbSerialFreeRequests(&port->writePool, &port->writeAllocated);
399094332d3Sopenharmony_ci        HDF_LOGE("%{public}s: UsbSerialStartRx failed", __func__);
400094332d3Sopenharmony_ci        ret = HDF_ERR_IO;
401094332d3Sopenharmony_ci    }
402094332d3Sopenharmony_ci
403094332d3Sopenharmony_ci    return ret;
404094332d3Sopenharmony_ci}
405094332d3Sopenharmony_ci
406094332d3Sopenharmony_cistatic void UsbSerialStopIo(struct UsbSerial *port)
407094332d3Sopenharmony_ci{
408094332d3Sopenharmony_ci    if (port == NULL) {
409094332d3Sopenharmony_ci        HDF_LOGE("%{public}s: port is null", __func__);
410094332d3Sopenharmony_ci        return;
411094332d3Sopenharmony_ci    }
412094332d3Sopenharmony_ci    UsbSerialFreeRequests(&port->readPool, &port->readAllocated);
413094332d3Sopenharmony_ci    UsbSerialFreeRequests(&port->writePool, &port->writeAllocated);
414094332d3Sopenharmony_ci    UsbSerialFreeFifo(&port->writeFifo);
415094332d3Sopenharmony_ci    UsbSerialFreeFifo(&port->readFifo);
416094332d3Sopenharmony_ci}
417094332d3Sopenharmony_ci
418094332d3Sopenharmony_cistatic int32_t UsbSerialAllocFifo(struct DataFifo *fifo, uint32_t size)
419094332d3Sopenharmony_ci{
420094332d3Sopenharmony_ci    if (!DataFifoIsInitialized(fifo)) {
421094332d3Sopenharmony_ci        void *data = OsalMemAlloc(size);
422094332d3Sopenharmony_ci        if (data == NULL) {
423094332d3Sopenharmony_ci            HDF_LOGE("%{public}s: allocate fifo data buffer failed", __func__);
424094332d3Sopenharmony_ci            return HDF_ERR_MALLOC_FAIL;
425094332d3Sopenharmony_ci        }
426094332d3Sopenharmony_ci        DataFifoInit(fifo, size, data);
427094332d3Sopenharmony_ci    }
428094332d3Sopenharmony_ci    return HDF_SUCCESS;
429094332d3Sopenharmony_ci}
430094332d3Sopenharmony_ci
431094332d3Sopenharmony_cistatic int32_t UsbSerialOpen(struct UsbSerial *port)
432094332d3Sopenharmony_ci{
433094332d3Sopenharmony_ci    int32_t ret;
434094332d3Sopenharmony_ci
435094332d3Sopenharmony_ci    if (port == NULL) {
436094332d3Sopenharmony_ci        return HDF_ERR_INVALID_PARAM;
437094332d3Sopenharmony_ci    }
438094332d3Sopenharmony_ci    g_inFifo = 1;
439094332d3Sopenharmony_ci    OsalMutexLock(&port->lock);
440094332d3Sopenharmony_ci    ret = UsbSerialAllocFifo(&port->writeFifo, WRITE_BUF_SIZE);
441094332d3Sopenharmony_ci    if (ret != HDF_SUCCESS) {
442094332d3Sopenharmony_ci        HDF_LOGE("%{public}s: UsbSerialAllocFifo failed", __func__);
443094332d3Sopenharmony_ci        goto OUT;
444094332d3Sopenharmony_ci    }
445094332d3Sopenharmony_ci    ret = UsbSerialAllocFifo(&port->readFifo, READ_BUF_SIZE);
446094332d3Sopenharmony_ci    if (ret != HDF_SUCCESS) {
447094332d3Sopenharmony_ci        HDF_LOGE("%{public}s: UsbSerialAllocFifo failed", __func__);
448094332d3Sopenharmony_ci        goto OUT;
449094332d3Sopenharmony_ci    }
450094332d3Sopenharmony_ci
451094332d3Sopenharmony_ci    /* the acm is enabled, start the io stream */
452094332d3Sopenharmony_ci    if (port->acm) {
453094332d3Sopenharmony_ci        if (!port->suspended) {
454094332d3Sopenharmony_ci            struct UsbAcmDevice *acm = port->acm;
455094332d3Sopenharmony_ci            HDF_LOGD("%{public}s: start usb serial", __func__);
456094332d3Sopenharmony_ci            ret = UsbSerialStartIo(port);
457094332d3Sopenharmony_ci            if (ret != HDF_SUCCESS) {
458094332d3Sopenharmony_ci                goto OUT;
459094332d3Sopenharmony_ci            }
460094332d3Sopenharmony_ci            if (acm->notify && acm->notify->Connect) {
461094332d3Sopenharmony_ci                acm->notify->Connect(acm);
462094332d3Sopenharmony_ci            }
463094332d3Sopenharmony_ci        } else {
464094332d3Sopenharmony_ci            HDF_LOGD("%{public}s: delay start usb serial", __func__);
465094332d3Sopenharmony_ci            port->startDelayed = true;
466094332d3Sopenharmony_ci        }
467094332d3Sopenharmony_ci    }
468094332d3Sopenharmony_ci
469094332d3Sopenharmony_ciOUT:
470094332d3Sopenharmony_ci    OsalMutexUnlock(&port->lock);
471094332d3Sopenharmony_ci    return HDF_SUCCESS;
472094332d3Sopenharmony_ci}
473094332d3Sopenharmony_ci
474094332d3Sopenharmony_cistatic int32_t UsbSerialClose(struct UsbSerial *port)
475094332d3Sopenharmony_ci{
476094332d3Sopenharmony_ci    struct UsbAcmDevice *acm = NULL;
477094332d3Sopenharmony_ci
478094332d3Sopenharmony_ci    if (port == NULL) {
479094332d3Sopenharmony_ci        return HDF_ERR_INVALID_PARAM;
480094332d3Sopenharmony_ci    }
481094332d3Sopenharmony_ci
482094332d3Sopenharmony_ci    OsalMutexLock(&port->lock);
483094332d3Sopenharmony_ci
484094332d3Sopenharmony_ci    HDF_LOGD("%{public}s: close usb serial", __func__);
485094332d3Sopenharmony_ci    acm = port->acm;
486094332d3Sopenharmony_ci    if (acm && !port->suspended) {
487094332d3Sopenharmony_ci        if (acm->notify && acm->notify->Disconnect) {
488094332d3Sopenharmony_ci            acm->notify->Disconnect(acm);
489094332d3Sopenharmony_ci        }
490094332d3Sopenharmony_ci    }
491094332d3Sopenharmony_ci    DataFifoReset(&port->writeFifo);
492094332d3Sopenharmony_ci    DataFifoReset(&port->readFifo);
493094332d3Sopenharmony_ci    UsbSerialStopIo(port);
494094332d3Sopenharmony_ci    port->startDelayed = false;
495094332d3Sopenharmony_ci
496094332d3Sopenharmony_ci    OsalMutexUnlock(&port->lock);
497094332d3Sopenharmony_ci    return HDF_SUCCESS;
498094332d3Sopenharmony_ci}
499094332d3Sopenharmony_ci
500094332d3Sopenharmony_ci#define WRITE_SPEED_REQ_NUM 8
501094332d3Sopenharmony_cistruct UsbFnRequest *g_req[WRITE_SPEED_REQ_NUM] = {NULL};
502094332d3Sopenharmony_cistatic bool g_isWriteDone = false;
503094332d3Sopenharmony_cistatic uint64_t g_writeCnt = 0;
504094332d3Sopenharmony_cistruct timeval g_timeStart, g_timeEnd;
505094332d3Sopenharmony_cistatic float g_speed = 0;
506094332d3Sopenharmony_cistatic bool g_isGetWriteTimeStart = false;
507094332d3Sopenharmony_cistatic void UsbSerialWriteSpeedComplete(uint8_t pipe, struct UsbFnRequest *req)
508094332d3Sopenharmony_ci{
509094332d3Sopenharmony_ci    switch (req->status) {
510094332d3Sopenharmony_ci        case USB_REQUEST_COMPLETED:
511094332d3Sopenharmony_ci            g_writeCnt += req->actual;
512094332d3Sopenharmony_ci            if (!g_isGetWriteTimeStart) {
513094332d3Sopenharmony_ci                g_isGetWriteTimeStart = true;
514094332d3Sopenharmony_ci                gettimeofday(&g_timeStart, NULL);
515094332d3Sopenharmony_ci            }
516094332d3Sopenharmony_ci            if (g_isWriteDone) {
517094332d3Sopenharmony_ci                UsbFnFreeRequest(req);
518094332d3Sopenharmony_ci                req = NULL;
519094332d3Sopenharmony_ci            } else {
520094332d3Sopenharmony_ci                if (memset_s(req->buf, req->length, 'a', req->length) != EOK) {
521094332d3Sopenharmony_ci                    HDF_LOGE("%{public}s:%{public}d memset_s failed", __func__, __LINE__);
522094332d3Sopenharmony_ci                    return;
523094332d3Sopenharmony_ci                }
524094332d3Sopenharmony_ci                UsbFnSubmitRequestAsync(req);
525094332d3Sopenharmony_ci            }
526094332d3Sopenharmony_ci            break;
527094332d3Sopenharmony_ci        case USB_REQUEST_NO_DEVICE:
528094332d3Sopenharmony_ci            HDF_LOGV("%{public}s: acm device was disconnected", __func__);
529094332d3Sopenharmony_ci            break;
530094332d3Sopenharmony_ci        default:
531094332d3Sopenharmony_ci            HDF_LOGD("%{public}s: req->status = %{public}d", __func__, req->status);
532094332d3Sopenharmony_ci            break;
533094332d3Sopenharmony_ci    }
534094332d3Sopenharmony_ci}
535094332d3Sopenharmony_ci
536094332d3Sopenharmony_cistatic int32_t SpeedThread(void *arg)
537094332d3Sopenharmony_ci{
538094332d3Sopenharmony_ci    g_writeCnt = 0;
539094332d3Sopenharmony_ci    g_isWriteDone = false;
540094332d3Sopenharmony_ci    g_isGetWriteTimeStart = false;
541094332d3Sopenharmony_ci    g_speed = 0;
542094332d3Sopenharmony_ci    double timeUse;
543094332d3Sopenharmony_ci    double usec = 1000000;
544094332d3Sopenharmony_ci    double k = 1024;
545094332d3Sopenharmony_ci    struct timeval timeTmp;
546094332d3Sopenharmony_ci    struct UsbSerial *port = (struct UsbSerial *)arg;
547094332d3Sopenharmony_ci
548094332d3Sopenharmony_ci    for (int32_t i = 0; i < WRITE_SPEED_REQ_NUM; i++) {
549094332d3Sopenharmony_ci        g_req[i] = UsbFnAllocRequest(
550094332d3Sopenharmony_ci            port->acm->dataIface.handle, port->acm->dataInPipe.id, port->acm->dataInPipe.maxPacketSize);
551094332d3Sopenharmony_ci        if (g_req[i] == NULL) {
552094332d3Sopenharmony_ci            return HDF_FAILURE;
553094332d3Sopenharmony_ci        }
554094332d3Sopenharmony_ci        g_req[i]->complete = UsbSerialWriteSpeedComplete;
555094332d3Sopenharmony_ci        g_req[i]->context = port;
556094332d3Sopenharmony_ci        g_req[i]->length = port->acm->dataInPipe.maxPacketSize;
557094332d3Sopenharmony_ci        int32_t ret =
558094332d3Sopenharmony_ci            memset_s(g_req[i]->buf, port->acm->dataInPipe.maxPacketSize, 'a', port->acm->dataInPipe.maxPacketSize);
559094332d3Sopenharmony_ci        if (ret != HDF_SUCCESS) {
560094332d3Sopenharmony_ci            HDF_LOGE("%{public}s:%{public}d memset_s failed", __func__, __LINE__);
561094332d3Sopenharmony_ci            return ret;
562094332d3Sopenharmony_ci        }
563094332d3Sopenharmony_ci        UsbFnSubmitRequestAsync(g_req[i]);
564094332d3Sopenharmony_ci    }
565094332d3Sopenharmony_ci    while (!g_isWriteDone) {
566094332d3Sopenharmony_ci        if (g_writeCnt == 0) {
567094332d3Sopenharmony_ci            OsalSleep(1);
568094332d3Sopenharmony_ci            continue;
569094332d3Sopenharmony_ci        } else {
570094332d3Sopenharmony_ci            OsalSleep(1);
571094332d3Sopenharmony_ci        }
572094332d3Sopenharmony_ci        gettimeofday(&timeTmp, NULL);
573094332d3Sopenharmony_ci        timeUse = (double)(timeTmp.tv_sec - g_timeStart.tv_sec) + (double)timeTmp.tv_usec / usec -
574094332d3Sopenharmony_ci            (double)g_timeStart.tv_usec / usec;
575094332d3Sopenharmony_ci        g_speed = (float)((double)g_writeCnt / k / k / timeUse);
576094332d3Sopenharmony_ci    }
577094332d3Sopenharmony_ci    timeUse = (double)(g_timeEnd.tv_sec - g_timeStart.tv_sec) + (double)g_timeEnd.tv_usec / usec -
578094332d3Sopenharmony_ci        (double)g_timeStart.tv_usec / usec;
579094332d3Sopenharmony_ci    HDF_LOGE("timeUse = %{public}lf", timeUse);
580094332d3Sopenharmony_ci    g_speed = (float)((double)g_writeCnt / k / k / timeUse);
581094332d3Sopenharmony_ci    HDF_LOGD("%{public}s: g_speed = %{public}f MB/s", __func__, g_speed);
582094332d3Sopenharmony_ci    return HDF_SUCCESS;
583094332d3Sopenharmony_ci}
584094332d3Sopenharmony_ci
585094332d3Sopenharmony_cistruct OsalThread g_thread;
586094332d3Sopenharmony_cistatic int32_t StartThreadSpeed(struct UsbSerial *port)
587094332d3Sopenharmony_ci{
588094332d3Sopenharmony_ci    struct OsalThreadParam threadCfg;
589094332d3Sopenharmony_ci    int32_t ret = memset_s(&threadCfg, sizeof(threadCfg), 0, sizeof(threadCfg));
590094332d3Sopenharmony_ci    if (ret != EOK) {
591094332d3Sopenharmony_ci        HDF_LOGE("%{public}s:%{public}d memset_s failed", __func__, __LINE__);
592094332d3Sopenharmony_ci        return ret;
593094332d3Sopenharmony_ci    }
594094332d3Sopenharmony_ci    threadCfg.name = "speed test process";
595094332d3Sopenharmony_ci    threadCfg.priority = OSAL_THREAD_PRI_LOW;
596094332d3Sopenharmony_ci    threadCfg.stackSize = HDF_PROCESS_STACK_SIZE;
597094332d3Sopenharmony_ci
598094332d3Sopenharmony_ci    ret = OsalThreadCreate(&g_thread, (OsalThreadEntry)SpeedThread, port);
599094332d3Sopenharmony_ci    if (ret != HDF_SUCCESS) {
600094332d3Sopenharmony_ci        HDF_LOGE("%{public}s:%{public}d OsalThreadCreate failed, ret=%{public}d ", __func__, __LINE__, ret);
601094332d3Sopenharmony_ci        return HDF_ERR_DEVICE_BUSY;
602094332d3Sopenharmony_ci    }
603094332d3Sopenharmony_ci
604094332d3Sopenharmony_ci    ret = OsalThreadStart(&g_thread, &threadCfg);
605094332d3Sopenharmony_ci    if (ret != HDF_SUCCESS) {
606094332d3Sopenharmony_ci        HDF_LOGE("%{public}s:%{public}d OsalThreadStart failed, ret=%{public}d ", __func__, __LINE__, ret);
607094332d3Sopenharmony_ci        return HDF_ERR_DEVICE_BUSY;
608094332d3Sopenharmony_ci    }
609094332d3Sopenharmony_ci    return 0;
610094332d3Sopenharmony_ci}
611094332d3Sopenharmony_ci
612094332d3Sopenharmony_cistatic int32_t UsbSerialGetTempSpeed(struct UsbSerial *port, struct HdfSBuf *reply)
613094332d3Sopenharmony_ci{
614094332d3Sopenharmony_ci    (void)port;
615094332d3Sopenharmony_ci    if (!HdfSbufWriteFloat(reply, g_speed)) {
616094332d3Sopenharmony_ci        HDF_LOGE("%{public}s: HdfSbufWriteFloat failed", __func__);
617094332d3Sopenharmony_ci        return HDF_FAILURE;
618094332d3Sopenharmony_ci    }
619094332d3Sopenharmony_ci    return HDF_SUCCESS;
620094332d3Sopenharmony_ci}
621094332d3Sopenharmony_ci
622094332d3Sopenharmony_cistatic int32_t UsbSerialGetTempSpeedInt(struct UsbSerial *port, struct HdfSBuf *reply)
623094332d3Sopenharmony_ci{
624094332d3Sopenharmony_ci    (void)port;
625094332d3Sopenharmony_ci    uint32_t calc = 10000;
626094332d3Sopenharmony_ci    if (!HdfSbufWriteUint32(reply, (uint32_t)(g_speed * calc))) {
627094332d3Sopenharmony_ci        HDF_LOGE("%{public}s: HdfSbufWriteUint32 failed", __func__);
628094332d3Sopenharmony_ci        return HDF_FAILURE;
629094332d3Sopenharmony_ci    }
630094332d3Sopenharmony_ci    return HDF_SUCCESS;
631094332d3Sopenharmony_ci}
632094332d3Sopenharmony_ci
633094332d3Sopenharmony_cistatic int32_t UsbSerialSpeedDone(struct UsbSerial *port)
634094332d3Sopenharmony_ci{
635094332d3Sopenharmony_ci    (void)port;
636094332d3Sopenharmony_ci    gettimeofday(&g_timeEnd, NULL);
637094332d3Sopenharmony_ci    g_isWriteDone = true;
638094332d3Sopenharmony_ci    return HDF_SUCCESS;
639094332d3Sopenharmony_ci}
640094332d3Sopenharmony_ci
641094332d3Sopenharmony_cistatic int32_t UsbSerialSpeed(struct UsbSerial *port)
642094332d3Sopenharmony_ci{
643094332d3Sopenharmony_ci    StartThreadSpeed(port);
644094332d3Sopenharmony_ci    return HDF_SUCCESS;
645094332d3Sopenharmony_ci}
646094332d3Sopenharmony_ci
647094332d3Sopenharmony_cistatic int32_t UsbSerialRead(struct UsbSerial *port, struct HdfSBuf *reply)
648094332d3Sopenharmony_ci{
649094332d3Sopenharmony_ci    uint32_t len, fifoLen;
650094332d3Sopenharmony_ci    int32_t ret = HDF_SUCCESS;
651094332d3Sopenharmony_ci    uint8_t *buf = NULL;
652094332d3Sopenharmony_ci    uint32_t i;
653094332d3Sopenharmony_ci    OsalMutexLock(&port->lock);
654094332d3Sopenharmony_ci    if (DataFifoIsEmpty(&port->readFifo)) {
655094332d3Sopenharmony_ci        OsalMutexUnlock(&port->lock);
656094332d3Sopenharmony_ci        return 0;
657094332d3Sopenharmony_ci    }
658094332d3Sopenharmony_ci    fifoLen = DataFifoLen(&port->readFifo);
659094332d3Sopenharmony_ci    buf = (uint8_t *)OsalMemCalloc(fifoLen + 1);
660094332d3Sopenharmony_ci    if (buf == NULL) {
661094332d3Sopenharmony_ci        HDF_LOGE("%{public}s: OsalMemCalloc error", __func__);
662094332d3Sopenharmony_ci        OsalMutexUnlock(&port->lock);
663094332d3Sopenharmony_ci        return HDF_ERR_MALLOC_FAIL;
664094332d3Sopenharmony_ci    }
665094332d3Sopenharmony_ci    for (i = 0; i < fifoLen; i++) {
666094332d3Sopenharmony_ci        len = DataFifoRead(&port->readFifo, buf + i, 1);
667094332d3Sopenharmony_ci        if (len == 0) {
668094332d3Sopenharmony_ci            HDF_LOGE("%{public}s: no data", __func__);
669094332d3Sopenharmony_ci            ret = HDF_ERR_IO;
670094332d3Sopenharmony_ci            goto OUT;
671094332d3Sopenharmony_ci        }
672094332d3Sopenharmony_ci        if (*(buf + i) == 0) {
673094332d3Sopenharmony_ci            if (i == 0) {
674094332d3Sopenharmony_ci                goto OUT;
675094332d3Sopenharmony_ci            }
676094332d3Sopenharmony_ci            break;
677094332d3Sopenharmony_ci        }
678094332d3Sopenharmony_ci    }
679094332d3Sopenharmony_ci
680094332d3Sopenharmony_ci    if (!HdfSbufWriteString(reply, (const char *)buf)) {
681094332d3Sopenharmony_ci        HDF_LOGE("%{public}s: sbuf write buffer failed", __func__);
682094332d3Sopenharmony_ci        ret = HDF_ERR_IO;
683094332d3Sopenharmony_ci    }
684094332d3Sopenharmony_ciOUT:
685094332d3Sopenharmony_ci    if (port->acm) {
686094332d3Sopenharmony_ci        UsbSerialStartRx(port);
687094332d3Sopenharmony_ci    }
688094332d3Sopenharmony_ci    OsalMemFree(buf);
689094332d3Sopenharmony_ci    OsalMutexUnlock(&port->lock);
690094332d3Sopenharmony_ci    return ret;
691094332d3Sopenharmony_ci}
692094332d3Sopenharmony_ci
693094332d3Sopenharmony_cistatic int32_t UsbSerialWrite(struct UsbSerial *port, struct HdfSBuf *data)
694094332d3Sopenharmony_ci{
695094332d3Sopenharmony_ci    int32_t size;
696094332d3Sopenharmony_ci    const char *tmp = NULL;
697094332d3Sopenharmony_ci
698094332d3Sopenharmony_ci    OsalMutexLock(&port->lock);
699094332d3Sopenharmony_ci
700094332d3Sopenharmony_ci    tmp = HdfSbufReadString(data);
701094332d3Sopenharmony_ci    if (tmp == NULL) {
702094332d3Sopenharmony_ci        HDF_LOGE("%{public}s: sbuf read buffer failed", __func__);
703094332d3Sopenharmony_ci        OsalMutexUnlock(&port->lock);
704094332d3Sopenharmony_ci        return HDF_ERR_IO;
705094332d3Sopenharmony_ci    }
706094332d3Sopenharmony_ci    char *buf = OsalMemCalloc(strlen(tmp) + 1);
707094332d3Sopenharmony_ci    if (buf == NULL) {
708094332d3Sopenharmony_ci        HDF_LOGE("%{public}s: OsalMemCalloc failed", __func__);
709094332d3Sopenharmony_ci        OsalMutexUnlock(&port->lock);
710094332d3Sopenharmony_ci        return HDF_ERR_IO;
711094332d3Sopenharmony_ci    }
712094332d3Sopenharmony_ci
713094332d3Sopenharmony_ci    int32_t ret = strcpy_s(buf, strlen(tmp) + 1, tmp);
714094332d3Sopenharmony_ci    if (ret != EOK) {
715094332d3Sopenharmony_ci        HDF_LOGE("%{public}s: strcpy_s failed", __func__);
716094332d3Sopenharmony_ci        OsalMutexUnlock(&port->lock);
717094332d3Sopenharmony_ci        OsalMemFree(buf);
718094332d3Sopenharmony_ci        return HDF_ERR_IO;
719094332d3Sopenharmony_ci    }
720094332d3Sopenharmony_ci
721094332d3Sopenharmony_ci    size = (int32_t)DataFifoWrite(&port->writeFifo, (uint8_t *)buf, strlen(buf));
722094332d3Sopenharmony_ci
723094332d3Sopenharmony_ci    if (port->acm) {
724094332d3Sopenharmony_ci        UsbSerialStartTx(port);
725094332d3Sopenharmony_ci    }
726094332d3Sopenharmony_ci    OsalMutexUnlock(&port->lock);
727094332d3Sopenharmony_ci    OsalMemFree(buf);
728094332d3Sopenharmony_ci    return size;
729094332d3Sopenharmony_ci}
730094332d3Sopenharmony_ci
731094332d3Sopenharmony_cistatic int32_t UsbSerialGetBaudrate(struct UsbSerial *port, struct HdfSBuf *reply)
732094332d3Sopenharmony_ci{
733094332d3Sopenharmony_ci    uint32_t baudRate = LE32_TO_CPU(port->lineCoding.dwDTERate);
734094332d3Sopenharmony_ci    if (!HdfSbufWriteBuffer(reply, &baudRate, sizeof(baudRate))) {
735094332d3Sopenharmony_ci        HDF_LOGE("%{public}s: sbuf write buffer failed", __func__);
736094332d3Sopenharmony_ci        return HDF_ERR_IO;
737094332d3Sopenharmony_ci    }
738094332d3Sopenharmony_ci    return HDF_SUCCESS;
739094332d3Sopenharmony_ci}
740094332d3Sopenharmony_ci
741094332d3Sopenharmony_cistatic int32_t UsbSerialSetBaudrate(struct UsbSerial *port, struct HdfSBuf *data)
742094332d3Sopenharmony_ci{
743094332d3Sopenharmony_ci    uint32_t size;
744094332d3Sopenharmony_ci    uint32_t *baudRate = NULL;
745094332d3Sopenharmony_ci
746094332d3Sopenharmony_ci    if (!HdfSbufReadBuffer(data, (const void **)&baudRate, &size)) {
747094332d3Sopenharmony_ci        HDF_LOGE("%{public}s: sbuf read buffer failed", __func__);
748094332d3Sopenharmony_ci        return HDF_ERR_IO;
749094332d3Sopenharmony_ci    }
750094332d3Sopenharmony_ci    port->lineCoding.dwDTERate = CPU_TO_LE32(*baudRate);
751094332d3Sopenharmony_ci    if (port->acm) {
752094332d3Sopenharmony_ci        port->acm->lineCoding.dwDTERate = CPU_TO_LE32(*baudRate);
753094332d3Sopenharmony_ci    }
754094332d3Sopenharmony_ci    return HDF_SUCCESS;
755094332d3Sopenharmony_ci}
756094332d3Sopenharmony_ci
757094332d3Sopenharmony_cistatic int32_t UsbSerialGetProp(struct UsbAcmDevice *acmDevice, struct HdfSBuf *data, struct HdfSBuf *reply)
758094332d3Sopenharmony_ci{
759094332d3Sopenharmony_ci    struct UsbFnInterface *intf = acmDevice->ctrlIface.fn;
760094332d3Sopenharmony_ci    const char *propName = NULL;
761094332d3Sopenharmony_ci    char propValue[USB_MAX_PACKET_SIZE] = {0};
762094332d3Sopenharmony_ci    int32_t ret;
763094332d3Sopenharmony_ci
764094332d3Sopenharmony_ci    propName = HdfSbufReadString(data);
765094332d3Sopenharmony_ci    if (propName == NULL) {
766094332d3Sopenharmony_ci        return HDF_ERR_IO;
767094332d3Sopenharmony_ci    }
768094332d3Sopenharmony_ci    ret = UsbFnGetInterfaceProp(intf, propName, propValue);
769094332d3Sopenharmony_ci    if (ret) {
770094332d3Sopenharmony_ci        return HDF_ERR_IO;
771094332d3Sopenharmony_ci    }
772094332d3Sopenharmony_ci    if (!HdfSbufWriteString(reply, propValue)) {
773094332d3Sopenharmony_ci        HDF_LOGE("%{public}s:failed to write result", __func__);
774094332d3Sopenharmony_ci        return HDF_ERR_IO;
775094332d3Sopenharmony_ci    }
776094332d3Sopenharmony_ci    return HDF_SUCCESS;
777094332d3Sopenharmony_ci}
778094332d3Sopenharmony_ci
779094332d3Sopenharmony_cistatic int32_t UsbSerialSetProp(struct UsbAcmDevice *acmDevice, struct HdfSBuf *data)
780094332d3Sopenharmony_ci{
781094332d3Sopenharmony_ci    struct UsbFnInterface *intf = acmDevice->ctrlIface.fn;
782094332d3Sopenharmony_ci    char tmp[USB_MAX_PACKET_SIZE] = {0};
783094332d3Sopenharmony_ci
784094332d3Sopenharmony_ci    const char *propName = HdfSbufReadString(data);
785094332d3Sopenharmony_ci    if (propName == NULL) {
786094332d3Sopenharmony_ci        return HDF_ERR_IO;
787094332d3Sopenharmony_ci    }
788094332d3Sopenharmony_ci    const char *propValue = HdfSbufReadString(data);
789094332d3Sopenharmony_ci    if (propValue == NULL) {
790094332d3Sopenharmony_ci        return HDF_ERR_IO;
791094332d3Sopenharmony_ci    }
792094332d3Sopenharmony_ci    (void)memset_s(&tmp, sizeof(tmp), 0, sizeof(tmp));
793094332d3Sopenharmony_ci    int32_t ret = snprintf_s(tmp, USB_MAX_PACKET_SIZE, USB_MAX_PACKET_SIZE - 1, "%s", propValue);
794094332d3Sopenharmony_ci    if (ret < 0) {
795094332d3Sopenharmony_ci        HDF_LOGE("%{public}s: snprintf_s failed", __func__);
796094332d3Sopenharmony_ci        return HDF_FAILURE;
797094332d3Sopenharmony_ci    }
798094332d3Sopenharmony_ci    ret = UsbFnSetInterfaceProp(intf, propName, tmp);
799094332d3Sopenharmony_ci    if (ret) {
800094332d3Sopenharmony_ci        HDF_LOGE("%{public}s: UsbFnInterfaceSetProp failed", __func__);
801094332d3Sopenharmony_ci        return HDF_ERR_IO;
802094332d3Sopenharmony_ci    }
803094332d3Sopenharmony_ci    return HDF_SUCCESS;
804094332d3Sopenharmony_ci}
805094332d3Sopenharmony_ci
806094332d3Sopenharmony_cistatic int32_t UsbSerialRegistPropAGet(const struct UsbFnInterface *intf, const char *name, const char *value)
807094332d3Sopenharmony_ci{
808094332d3Sopenharmony_ci    (void)intf;
809094332d3Sopenharmony_ci    HDF_LOGE("%{public}s: name = %{public}s", __func__, name);
810094332d3Sopenharmony_ci    HDF_LOGE("%{public}s: value = %{public}s", __func__, value);
811094332d3Sopenharmony_ci
812094332d3Sopenharmony_ci    return 0;
813094332d3Sopenharmony_ci}
814094332d3Sopenharmony_ci
815094332d3Sopenharmony_cistatic int32_t UsbSerialRegistPropASet(const struct UsbFnInterface *intf, const char *name, const char *value)
816094332d3Sopenharmony_ci{
817094332d3Sopenharmony_ci    (void)intf;
818094332d3Sopenharmony_ci    HDF_LOGE("%{public}s: name = %{public}s", __func__, name);
819094332d3Sopenharmony_ci    HDF_LOGE("%{public}s: value = %{public}s", __func__, value);
820094332d3Sopenharmony_ci
821094332d3Sopenharmony_ci    return 0;
822094332d3Sopenharmony_ci}
823094332d3Sopenharmony_ci
824094332d3Sopenharmony_cistatic int32_t UsbSerialRegistProp(struct UsbAcmDevice *acmDevice, struct HdfSBuf *data)
825094332d3Sopenharmony_ci{
826094332d3Sopenharmony_ci    struct UsbFnInterface *intf = acmDevice->ctrlIface.fn;
827094332d3Sopenharmony_ci    struct UsbFnRegistInfo registInfo;
828094332d3Sopenharmony_ci    int32_t ret;
829094332d3Sopenharmony_ci
830094332d3Sopenharmony_ci    const char *propName = HdfSbufReadString(data);
831094332d3Sopenharmony_ci    if (propName == NULL) {
832094332d3Sopenharmony_ci        return HDF_ERR_IO;
833094332d3Sopenharmony_ci    }
834094332d3Sopenharmony_ci    const char *propValue = HdfSbufReadString(data);
835094332d3Sopenharmony_ci    if (propValue == NULL) {
836094332d3Sopenharmony_ci        return HDF_ERR_IO;
837094332d3Sopenharmony_ci    }
838094332d3Sopenharmony_ci    registInfo.name = propName;
839094332d3Sopenharmony_ci    registInfo.value = propValue;
840094332d3Sopenharmony_ci    registInfo.getProp = UsbSerialRegistPropAGet;
841094332d3Sopenharmony_ci    registInfo.setProp = UsbSerialRegistPropASet;
842094332d3Sopenharmony_ci    ret = UsbFnRegistInterfaceProp(intf, &registInfo);
843094332d3Sopenharmony_ci    if (ret) {
844094332d3Sopenharmony_ci        HDF_LOGE("%{public}s: UsbFnInterfaceSetProp failed", __func__);
845094332d3Sopenharmony_ci        return HDF_ERR_IO;
846094332d3Sopenharmony_ci    }
847094332d3Sopenharmony_ci    return HDF_SUCCESS;
848094332d3Sopenharmony_ci}
849094332d3Sopenharmony_ci
850094332d3Sopenharmony_cistatic int32_t AcmSerialCmd(
851094332d3Sopenharmony_ci    struct UsbAcmDevice *acm, int32_t cmd, struct UsbSerial *port, struct HdfSBuf *data, struct HdfSBuf *reply)
852094332d3Sopenharmony_ci{
853094332d3Sopenharmony_ci    switch (cmd) {
854094332d3Sopenharmony_ci        case USB_SERIAL_OPEN:
855094332d3Sopenharmony_ci            return UsbSerialOpen(port);
856094332d3Sopenharmony_ci        case USB_SERIAL_CLOSE:
857094332d3Sopenharmony_ci            return UsbSerialClose(port);
858094332d3Sopenharmony_ci        case USB_SERIAL_READ:
859094332d3Sopenharmony_ci            return UsbSerialRead(port, reply);
860094332d3Sopenharmony_ci        case USB_SERIAL_WRITE:
861094332d3Sopenharmony_ci            return UsbSerialWrite(port, data);
862094332d3Sopenharmony_ci        case USB_SERIAL_GET_BAUDRATE:
863094332d3Sopenharmony_ci            return UsbSerialGetBaudrate(port, reply);
864094332d3Sopenharmony_ci        case USB_SERIAL_SET_BAUDRATE:
865094332d3Sopenharmony_ci            return UsbSerialSetBaudrate(port, data);
866094332d3Sopenharmony_ci        case USB_SERIAL_SET_PROP:
867094332d3Sopenharmony_ci            return UsbSerialSetProp(acm, data);
868094332d3Sopenharmony_ci        case USB_SERIAL_GET_PROP:
869094332d3Sopenharmony_ci            return UsbSerialGetProp(acm, data, reply);
870094332d3Sopenharmony_ci        case USB_SERIAL_REGIST_PROP:
871094332d3Sopenharmony_ci            return UsbSerialRegistProp(acm, data);
872094332d3Sopenharmony_ci        case USB_SERIAL_WRITE_SPEED:
873094332d3Sopenharmony_ci            return UsbSerialSpeed(port);
874094332d3Sopenharmony_ci        case USB_SERIAL_WRITE_GET_TEMP_SPEED:
875094332d3Sopenharmony_ci            return UsbSerialGetTempSpeed(port, reply);
876094332d3Sopenharmony_ci        case USB_SERIAL_WRITE_SPEED_DONE:
877094332d3Sopenharmony_ci            return UsbSerialSpeedDone(port);
878094332d3Sopenharmony_ci        case USB_SERIAL_WRITE_GET_TEMP_SPEED_UINT32:
879094332d3Sopenharmony_ci            return UsbSerialGetTempSpeedInt(port, reply);
880094332d3Sopenharmony_ci        case USB_SERIAL_READ_SPEED:
881094332d3Sopenharmony_ci            return UsbSerialReadSpeedStart(port);
882094332d3Sopenharmony_ci        case USB_SERIAL_READ_GET_TEMP_SPEED:
883094332d3Sopenharmony_ci            return UsbSerialGetTempReadSpeed(port, reply);
884094332d3Sopenharmony_ci        case USB_SERIAL_READ_SPEED_DONE:
885094332d3Sopenharmony_ci            return UsbSerialReadSpeedDone(port);
886094332d3Sopenharmony_ci        case USB_SERIAL_READ_GET_TEMP_SPEED_UINT32:
887094332d3Sopenharmony_ci            return UsbSerialGetTempReadSpeedInt(port, reply);
888094332d3Sopenharmony_ci        default:
889094332d3Sopenharmony_ci            return HDF_ERR_NOT_SUPPORT;
890094332d3Sopenharmony_ci    }
891094332d3Sopenharmony_ci    return HDF_SUCCESS;
892094332d3Sopenharmony_ci}
893094332d3Sopenharmony_ci
894094332d3Sopenharmony_cistatic int32_t AcmDeviceDispatch(
895094332d3Sopenharmony_ci    struct HdfDeviceIoClient *client, int32_t cmd, struct HdfSBuf *data, struct HdfSBuf *reply)
896094332d3Sopenharmony_ci{
897094332d3Sopenharmony_ci    if (client == NULL || client->device == NULL || client->device->service == NULL) {
898094332d3Sopenharmony_ci        HDF_LOGE("%{public}s: client is NULL", __func__);
899094332d3Sopenharmony_ci        return HDF_ERR_INVALID_OBJECT;
900094332d3Sopenharmony_ci    }
901094332d3Sopenharmony_ci
902094332d3Sopenharmony_ci    struct UsbAcmDevice *acm = (struct UsbAcmDevice *)client->device->service;
903094332d3Sopenharmony_ci    if (!HdfDeviceObjectCheckInterfaceDesc(client->device, data)) {
904094332d3Sopenharmony_ci        HDF_LOGE("%{public}s:%{public}d check interface desc fail", __func__, __LINE__);
905094332d3Sopenharmony_ci        return HDF_ERR_INVALID_PARAM;
906094332d3Sopenharmony_ci    }
907094332d3Sopenharmony_ci
908094332d3Sopenharmony_ci    switch (cmd) {
909094332d3Sopenharmony_ci        case USB_SERIAL_INIT:
910094332d3Sopenharmony_ci            return UsbSerialInit(acm);
911094332d3Sopenharmony_ci        case USB_SERIAL_RELEASE:
912094332d3Sopenharmony_ci            return UsbSerialRelease(acm);
913094332d3Sopenharmony_ci        default:
914094332d3Sopenharmony_ci            HDF_LOGE("%{public}s: unknown cmd %{public}d", __func__, cmd);
915094332d3Sopenharmony_ci            break;
916094332d3Sopenharmony_ci    }
917094332d3Sopenharmony_ci    OsalMutexLock(&acm->lock);
918094332d3Sopenharmony_ci    struct UsbSerial *port = acm->port;
919094332d3Sopenharmony_ci    if (port == NULL) {
920094332d3Sopenharmony_ci        OsalMutexUnlock(&acm->lock);
921094332d3Sopenharmony_ci        HDF_LOGE("%{public}s: port is NULL", __func__);
922094332d3Sopenharmony_ci        return HDF_ERR_IO;
923094332d3Sopenharmony_ci    }
924094332d3Sopenharmony_ci    int32_t ret = AcmSerialCmd(acm, cmd, port, data, reply);
925094332d3Sopenharmony_ci    OsalMutexUnlock(&acm->lock);
926094332d3Sopenharmony_ci    return ret;
927094332d3Sopenharmony_ci}
928094332d3Sopenharmony_ci
929094332d3Sopenharmony_cistatic void AcmDeviceDestroy(struct UsbAcmDevice *acm)
930094332d3Sopenharmony_ci{
931094332d3Sopenharmony_ci    if (acm == NULL) {
932094332d3Sopenharmony_ci        return;
933094332d3Sopenharmony_ci    }
934094332d3Sopenharmony_ci    OsalMemFree(acm);
935094332d3Sopenharmony_ci}
936094332d3Sopenharmony_ci
937094332d3Sopenharmony_cistatic void AcmCtrlComplete(uint8_t pipe, struct UsbFnRequest *req)
938094332d3Sopenharmony_ci{
939094332d3Sopenharmony_ci    if (req == NULL) {
940094332d3Sopenharmony_ci        return;
941094332d3Sopenharmony_ci    }
942094332d3Sopenharmony_ci    struct CtrlInfo *ctrlInfo = (struct CtrlInfo *)req->context;
943094332d3Sopenharmony_ci    if (ctrlInfo == NULL) {
944094332d3Sopenharmony_ci        return;
945094332d3Sopenharmony_ci    }
946094332d3Sopenharmony_ci    struct UsbAcmDevice *acm = ctrlInfo->acm;
947094332d3Sopenharmony_ci    if (req->status != USB_REQUEST_COMPLETED) {
948094332d3Sopenharmony_ci        HDF_LOGD("%{public}s: ctrl completion error %{public}d", __func__, req->status);
949094332d3Sopenharmony_ci        goto OUT;
950094332d3Sopenharmony_ci    }
951094332d3Sopenharmony_ci
952094332d3Sopenharmony_ci    if (ctrlInfo->request == USB_DDK_CDC_REQ_SET_LINE_CODING) {
953094332d3Sopenharmony_ci        struct UsbCdcLineCoding *value = req->buf;
954094332d3Sopenharmony_ci        if (req->actual == sizeof(*value)) {
955094332d3Sopenharmony_ci            acm->lineCoding = *value;
956094332d3Sopenharmony_ci            HDF_LOGD("dwDTERate =  %{public}d", acm->lineCoding.dwDTERate);
957094332d3Sopenharmony_ci            HDF_LOGD("bCharFormat =  %{public}d", acm->lineCoding.bCharFormat);
958094332d3Sopenharmony_ci            HDF_LOGD("bParityType =  %{public}d", acm->lineCoding.bParityType);
959094332d3Sopenharmony_ci            HDF_LOGD("bDataBits =  %{public}d", acm->lineCoding.bDataBits);
960094332d3Sopenharmony_ci        }
961094332d3Sopenharmony_ci    }
962094332d3Sopenharmony_ci
963094332d3Sopenharmony_ciOUT:
964094332d3Sopenharmony_ci    DListInsertTail(&req->list, &acm->ctrlPool);
965094332d3Sopenharmony_ci}
966094332d3Sopenharmony_ci
967094332d3Sopenharmony_cistatic int32_t AcmAllocCtrlRequests(struct UsbAcmDevice *acm, int32_t num)
968094332d3Sopenharmony_ci{
969094332d3Sopenharmony_ci    struct DListHead *head = &acm->ctrlPool;
970094332d3Sopenharmony_ci    struct UsbFnRequest *req = NULL;
971094332d3Sopenharmony_ci    struct CtrlInfo *ctrlInfo = NULL;
972094332d3Sopenharmony_ci    int32_t i;
973094332d3Sopenharmony_ci
974094332d3Sopenharmony_ci    DListHeadInit(&acm->ctrlPool);
975094332d3Sopenharmony_ci    acm->ctrlReqNum = 0;
976094332d3Sopenharmony_ci
977094332d3Sopenharmony_ci    for (i = 0; i < num; i++) {
978094332d3Sopenharmony_ci        ctrlInfo = (struct CtrlInfo *)OsalMemCalloc(sizeof(*ctrlInfo));
979094332d3Sopenharmony_ci        if (ctrlInfo == NULL) {
980094332d3Sopenharmony_ci            HDF_LOGE("%{public}s: Allocate ctrlInfo failed", __func__);
981094332d3Sopenharmony_ci            goto OUT;
982094332d3Sopenharmony_ci        }
983094332d3Sopenharmony_ci        ctrlInfo->acm = acm;
984094332d3Sopenharmony_ci        req = UsbFnAllocCtrlRequest(
985094332d3Sopenharmony_ci            acm->ctrlIface.handle, sizeof(struct UsbCdcLineCoding) + sizeof(struct UsbCdcLineCoding));
986094332d3Sopenharmony_ci        if (req == NULL) {
987094332d3Sopenharmony_ci            goto OUT;
988094332d3Sopenharmony_ci        }
989094332d3Sopenharmony_ci        req->complete = AcmCtrlComplete;
990094332d3Sopenharmony_ci        req->context = ctrlInfo;
991094332d3Sopenharmony_ci        DListInsertTail(&req->list, head);
992094332d3Sopenharmony_ci        acm->ctrlReqNum++;
993094332d3Sopenharmony_ci    }
994094332d3Sopenharmony_ci    return HDF_SUCCESS;
995094332d3Sopenharmony_ci
996094332d3Sopenharmony_ciOUT:
997094332d3Sopenharmony_ci    return DListIsEmpty(head) ? HDF_FAILURE : HDF_SUCCESS;
998094332d3Sopenharmony_ci}
999094332d3Sopenharmony_ci
1000094332d3Sopenharmony_cistatic void AcmFreeCtrlRequests(struct UsbAcmDevice *acm)
1001094332d3Sopenharmony_ci{
1002094332d3Sopenharmony_ci    struct DListHead *head = &acm->ctrlPool;
1003094332d3Sopenharmony_ci    struct UsbFnRequest *req = NULL;
1004094332d3Sopenharmony_ci
1005094332d3Sopenharmony_ci    while (!DListIsEmpty(head)) {
1006094332d3Sopenharmony_ci        req = DLIST_FIRST_ENTRY(head, struct UsbFnRequest, list);
1007094332d3Sopenharmony_ci        DListRemove(&req->list);
1008094332d3Sopenharmony_ci        OsalMemFree(req->context);
1009094332d3Sopenharmony_ci        (void)UsbFnFreeRequest(req);
1010094332d3Sopenharmony_ci        acm->ctrlReqNum--;
1011094332d3Sopenharmony_ci    }
1012094332d3Sopenharmony_ci}
1013094332d3Sopenharmony_ci
1014094332d3Sopenharmony_cistatic int32_t AcmNotifySerialState(struct UsbAcmDevice *acm);
1015094332d3Sopenharmony_cistatic void AcmNotifyComplete(uint8_t pipe, struct UsbFnRequest *req)
1016094332d3Sopenharmony_ci{
1017094332d3Sopenharmony_ci    struct UsbAcmDevice *acm = (struct UsbAcmDevice *)req->context;
1018094332d3Sopenharmony_ci    bool pending = false;
1019094332d3Sopenharmony_ci
1020094332d3Sopenharmony_ci    if (acm == NULL) {
1021094332d3Sopenharmony_ci        HDF_LOGE("%{public}s: acm is null", __func__);
1022094332d3Sopenharmony_ci        return;
1023094332d3Sopenharmony_ci    }
1024094332d3Sopenharmony_ci
1025094332d3Sopenharmony_ci    OsalMutexLock(&acm->lock);
1026094332d3Sopenharmony_ci    /* estimate pending */
1027094332d3Sopenharmony_ci    if (req->status == PENDING_FLAG) {
1028094332d3Sopenharmony_ci        pending = acm->pending;
1029094332d3Sopenharmony_ci    }
1030094332d3Sopenharmony_ci    acm->notifyReq = req;
1031094332d3Sopenharmony_ci    OsalMutexUnlock(&acm->lock);
1032094332d3Sopenharmony_ci    if (pending) {
1033094332d3Sopenharmony_ci        AcmNotifySerialState(acm);
1034094332d3Sopenharmony_ci    }
1035094332d3Sopenharmony_ci}
1036094332d3Sopenharmony_ci
1037094332d3Sopenharmony_cistatic int32_t AcmAllocNotifyRequest(struct UsbAcmDevice *acm)
1038094332d3Sopenharmony_ci{
1039094332d3Sopenharmony_ci    /* allocate notification request, 2 means compatible liteOS and linux */
1040094332d3Sopenharmony_ci    acm->notifyReq =
1041094332d3Sopenharmony_ci        UsbFnAllocRequest(acm->ctrlIface.handle, acm->notifyPipe.id, sizeof(struct UsbCdcNotification) * USBCDC_LEN);
1042094332d3Sopenharmony_ci    if (acm->notifyReq == NULL) {
1043094332d3Sopenharmony_ci        HDF_LOGE("%{public}s: allocate notify request failed", __func__);
1044094332d3Sopenharmony_ci        return HDF_FAILURE;
1045094332d3Sopenharmony_ci    }
1046094332d3Sopenharmony_ci    acm->notifyReq->complete = AcmNotifyComplete;
1047094332d3Sopenharmony_ci    acm->notifyReq->context = acm;
1048094332d3Sopenharmony_ci
1049094332d3Sopenharmony_ci    return HDF_SUCCESS;
1050094332d3Sopenharmony_ci}
1051094332d3Sopenharmony_ci
1052094332d3Sopenharmony_cistatic void AcmFreeNotifyRequest(struct UsbAcmDevice *acm)
1053094332d3Sopenharmony_ci{
1054094332d3Sopenharmony_ci    int32_t ret;
1055094332d3Sopenharmony_ci
1056094332d3Sopenharmony_ci    /* free notification request */
1057094332d3Sopenharmony_ci    ret = UsbFnFreeRequest(acm->notifyReq);
1058094332d3Sopenharmony_ci    if (ret != HDF_SUCCESS) {
1059094332d3Sopenharmony_ci        HDF_LOGE("%{public}s: free notify request failed", __func__);
1060094332d3Sopenharmony_ci        return;
1061094332d3Sopenharmony_ci    }
1062094332d3Sopenharmony_ci    acm->notifyReq = NULL;
1063094332d3Sopenharmony_ci}
1064094332d3Sopenharmony_ci
1065094332d3Sopenharmony_cistatic uint32_t AcmEnable(struct UsbAcmDevice *acm)
1066094332d3Sopenharmony_ci{
1067094332d3Sopenharmony_ci    struct UsbSerial *port = acm->port;
1068094332d3Sopenharmony_ci    port->acm = acm;
1069094332d3Sopenharmony_ci    acm->lineCoding = port->lineCoding;
1070094332d3Sopenharmony_ci    return HDF_SUCCESS;
1071094332d3Sopenharmony_ci}
1072094332d3Sopenharmony_ci
1073094332d3Sopenharmony_cistatic uint32_t AcmDisable(struct UsbAcmDevice *acm)
1074094332d3Sopenharmony_ci{
1075094332d3Sopenharmony_ci    struct UsbSerial *port = acm->port;
1076094332d3Sopenharmony_ci
1077094332d3Sopenharmony_ci    if (port == NULL) {
1078094332d3Sopenharmony_ci        HDF_LOGE("%{public}s: port is null", __func__);
1079094332d3Sopenharmony_ci        return HDF_FAILURE;
1080094332d3Sopenharmony_ci    }
1081094332d3Sopenharmony_ci
1082094332d3Sopenharmony_ci    OsalMutexLock(&port->lock);
1083094332d3Sopenharmony_ci    port->lineCoding = acm->lineCoding;
1084094332d3Sopenharmony_ci    OsalMutexUnlock(&port->lock);
1085094332d3Sopenharmony_ci
1086094332d3Sopenharmony_ci    return HDF_SUCCESS;
1087094332d3Sopenharmony_ci}
1088094332d3Sopenharmony_ci
1089094332d3Sopenharmony_cistatic struct UsbFnRequest *AcmGetCtrlReq(struct UsbAcmDevice *acm)
1090094332d3Sopenharmony_ci{
1091094332d3Sopenharmony_ci    struct UsbFnRequest *req = NULL;
1092094332d3Sopenharmony_ci    struct DListHead *pool = &acm->ctrlPool;
1093094332d3Sopenharmony_ci
1094094332d3Sopenharmony_ci    if (!DListIsEmpty(pool)) {
1095094332d3Sopenharmony_ci        req = DLIST_FIRST_ENTRY(pool, struct UsbFnRequest, list);
1096094332d3Sopenharmony_ci        DListRemove(&req->list);
1097094332d3Sopenharmony_ci    }
1098094332d3Sopenharmony_ci    return req;
1099094332d3Sopenharmony_ci}
1100094332d3Sopenharmony_ci
1101094332d3Sopenharmony_cistatic void AcmSetup(struct UsbAcmDevice *acm, struct UsbFnCtrlRequest *setup)
1102094332d3Sopenharmony_ci{
1103094332d3Sopenharmony_ci    if (acm == NULL || setup == NULL) {
1104094332d3Sopenharmony_ci        return;
1105094332d3Sopenharmony_ci    }
1106094332d3Sopenharmony_ci    struct UsbFnRequest *req = NULL;
1107094332d3Sopenharmony_ci    struct CtrlInfo *ctrlInfo = NULL;
1108094332d3Sopenharmony_ci    uint16_t value = LE16_TO_CPU(setup->value);
1109094332d3Sopenharmony_ci    uint16_t length = LE16_TO_CPU(setup->length);
1110094332d3Sopenharmony_ci    int32_t ret = 0;
1111094332d3Sopenharmony_ci
1112094332d3Sopenharmony_ci    req = AcmGetCtrlReq(acm);
1113094332d3Sopenharmony_ci    if (req == NULL) {
1114094332d3Sopenharmony_ci        HDF_LOGE("%{public}s: control request pool is empty", __func__);
1115094332d3Sopenharmony_ci        return;
1116094332d3Sopenharmony_ci    }
1117094332d3Sopenharmony_ci
1118094332d3Sopenharmony_ci    switch (setup->request) {
1119094332d3Sopenharmony_ci        case USB_DDK_CDC_REQ_SET_LINE_CODING:
1120094332d3Sopenharmony_ci            if (length != sizeof(struct UsbCdcLineCoding)) {
1121094332d3Sopenharmony_ci                goto OUT;
1122094332d3Sopenharmony_ci            }
1123094332d3Sopenharmony_ci            ret = (int)length;
1124094332d3Sopenharmony_ci            break;
1125094332d3Sopenharmony_ci        case USB_DDK_CDC_REQ_GET_LINE_CODING:
1126094332d3Sopenharmony_ci            ret = (int)MIN(length, sizeof(struct UsbCdcLineCoding));
1127094332d3Sopenharmony_ci            if (acm->lineCoding.dwDTERate == 0) {
1128094332d3Sopenharmony_ci                acm->lineCoding = acm->port->lineCoding;
1129094332d3Sopenharmony_ci            }
1130094332d3Sopenharmony_ci            if (memcpy_s(req->buf, ret, &acm->lineCoding, ret) != EOK) {
1131094332d3Sopenharmony_ci                return;
1132094332d3Sopenharmony_ci            }
1133094332d3Sopenharmony_ci            break;
1134094332d3Sopenharmony_ci        case USB_DDK_CDC_REQ_SET_CONTROL_LINE_STATE:
1135094332d3Sopenharmony_ci            ret = 0;
1136094332d3Sopenharmony_ci            acm->handshakeBits = value;
1137094332d3Sopenharmony_ci            break;
1138094332d3Sopenharmony_ci        default:
1139094332d3Sopenharmony_ci            HDF_LOGE("%{public}s: setup request is not supported", __func__);
1140094332d3Sopenharmony_ci            break;
1141094332d3Sopenharmony_ci    }
1142094332d3Sopenharmony_ci
1143094332d3Sopenharmony_ciOUT:
1144094332d3Sopenharmony_ci    ctrlInfo = (struct CtrlInfo *)req->context;
1145094332d3Sopenharmony_ci    ctrlInfo->request = setup->request;
1146094332d3Sopenharmony_ci    req->length = (uint32_t)ret;
1147094332d3Sopenharmony_ci    ret = UsbFnSubmitRequestAsync(req);
1148094332d3Sopenharmony_ci    if (ret != HDF_SUCCESS) {
1149094332d3Sopenharmony_ci        HDF_LOGE("%{public}s: acm send setup response error", __func__);
1150094332d3Sopenharmony_ci    }
1151094332d3Sopenharmony_ci}
1152094332d3Sopenharmony_ci
1153094332d3Sopenharmony_cistatic void AcmSuspend(struct UsbAcmDevice *acm)
1154094332d3Sopenharmony_ci{
1155094332d3Sopenharmony_ci    struct UsbSerial *port = acm->port;
1156094332d3Sopenharmony_ci
1157094332d3Sopenharmony_ci    if (port == NULL) {
1158094332d3Sopenharmony_ci        HDF_LOGE("%{public}s: port is null", __func__);
1159094332d3Sopenharmony_ci        return;
1160094332d3Sopenharmony_ci    }
1161094332d3Sopenharmony_ci
1162094332d3Sopenharmony_ci    OsalMutexLock(&port->lock);
1163094332d3Sopenharmony_ci    port->suspended = true;
1164094332d3Sopenharmony_ci    OsalMutexUnlock(&port->lock);
1165094332d3Sopenharmony_ci}
1166094332d3Sopenharmony_ci
1167094332d3Sopenharmony_cistatic void AcmResume(struct UsbAcmDevice *acm)
1168094332d3Sopenharmony_ci{
1169094332d3Sopenharmony_ci    int32_t ret;
1170094332d3Sopenharmony_ci    struct UsbSerial *port = acm->port;
1171094332d3Sopenharmony_ci    if (port == NULL) {
1172094332d3Sopenharmony_ci        HDF_LOGE("%{public}s: port is null", __func__);
1173094332d3Sopenharmony_ci        return;
1174094332d3Sopenharmony_ci    }
1175094332d3Sopenharmony_ci
1176094332d3Sopenharmony_ci    OsalMutexLock(&port->lock);
1177094332d3Sopenharmony_ci    port->suspended = false;
1178094332d3Sopenharmony_ci    if (!port->startDelayed) {
1179094332d3Sopenharmony_ci        OsalMutexUnlock(&port->lock);
1180094332d3Sopenharmony_ci        return;
1181094332d3Sopenharmony_ci    }
1182094332d3Sopenharmony_ci    ret = UsbSerialStartIo(port);
1183094332d3Sopenharmony_ci    if (ret != HDF_SUCCESS) {
1184094332d3Sopenharmony_ci        HDF_LOGE("%{public}s: UsbSerialStartIo failed", __func__);
1185094332d3Sopenharmony_ci    }
1186094332d3Sopenharmony_ci    if (acm->notify && acm->notify->Connect) {
1187094332d3Sopenharmony_ci        acm->notify->Connect(acm);
1188094332d3Sopenharmony_ci    }
1189094332d3Sopenharmony_ci    port->startDelayed = false;
1190094332d3Sopenharmony_ci    OsalMutexUnlock(&port->lock);
1191094332d3Sopenharmony_ci}
1192094332d3Sopenharmony_ci
1193094332d3Sopenharmony_cistatic void UsbAcmEventCallback(struct UsbFnEvent *event)
1194094332d3Sopenharmony_ci{
1195094332d3Sopenharmony_ci    struct UsbAcmDevice *acm = NULL;
1196094332d3Sopenharmony_ci
1197094332d3Sopenharmony_ci    if (event == NULL || event->context == NULL) {
1198094332d3Sopenharmony_ci        HDF_LOGE("%{public}s: event is null", __func__);
1199094332d3Sopenharmony_ci        return;
1200094332d3Sopenharmony_ci    }
1201094332d3Sopenharmony_ci
1202094332d3Sopenharmony_ci    acm = (struct UsbAcmDevice *)event->context;
1203094332d3Sopenharmony_ci    switch (event->type) {
1204094332d3Sopenharmony_ci        case USBFN_STATE_BIND:
1205094332d3Sopenharmony_ci            HDF_LOGI("%{public}s: receive bind event", __func__);
1206094332d3Sopenharmony_ci            break;
1207094332d3Sopenharmony_ci        case USBFN_STATE_UNBIND:
1208094332d3Sopenharmony_ci            HDF_LOGI("%{public}s: receive unbind event", __func__);
1209094332d3Sopenharmony_ci            break;
1210094332d3Sopenharmony_ci        case USBFN_STATE_ENABLE:
1211094332d3Sopenharmony_ci            HDF_LOGI("%{public}s: receive enable event", __func__);
1212094332d3Sopenharmony_ci            AcmEnable(acm);
1213094332d3Sopenharmony_ci            break;
1214094332d3Sopenharmony_ci        case USBFN_STATE_DISABLE:
1215094332d3Sopenharmony_ci            HDF_LOGI("%{public}s: receive disable event", __func__);
1216094332d3Sopenharmony_ci            AcmDisable(acm);
1217094332d3Sopenharmony_ci            acm->enableEvtCnt = 0;
1218094332d3Sopenharmony_ci            break;
1219094332d3Sopenharmony_ci        case USBFN_STATE_SETUP:
1220094332d3Sopenharmony_ci            HDF_LOGI("%{public}s: receive setup event", __func__);
1221094332d3Sopenharmony_ci            if (event->setup != NULL) {
1222094332d3Sopenharmony_ci                AcmSetup(acm, event->setup);
1223094332d3Sopenharmony_ci            }
1224094332d3Sopenharmony_ci            break;
1225094332d3Sopenharmony_ci        case USBFN_STATE_SUSPEND:
1226094332d3Sopenharmony_ci            HDF_LOGI("%{public}s: receive suspend event", __func__);
1227094332d3Sopenharmony_ci            AcmSuspend(acm);
1228094332d3Sopenharmony_ci            break;
1229094332d3Sopenharmony_ci        case USBFN_STATE_RESUME:
1230094332d3Sopenharmony_ci            HDF_LOGI("%{public}s: receive resume event", __func__);
1231094332d3Sopenharmony_ci            AcmResume(acm);
1232094332d3Sopenharmony_ci            break;
1233094332d3Sopenharmony_ci        default:
1234094332d3Sopenharmony_ci            break;
1235094332d3Sopenharmony_ci    }
1236094332d3Sopenharmony_ci}
1237094332d3Sopenharmony_ci
1238094332d3Sopenharmony_cistatic int32_t AcmSendNotifyRequest(
1239094332d3Sopenharmony_ci    struct UsbAcmDevice *acm, uint8_t type, uint16_t value, const void *data, uint32_t length)
1240094332d3Sopenharmony_ci{
1241094332d3Sopenharmony_ci    struct UsbFnRequest *req = acm->notifyReq;
1242094332d3Sopenharmony_ci    struct UsbCdcNotification *notify = NULL;
1243094332d3Sopenharmony_ci    int32_t ret;
1244094332d3Sopenharmony_ci
1245094332d3Sopenharmony_ci    if (req == NULL || req->buf == NULL) {
1246094332d3Sopenharmony_ci        HDF_LOGE("%{public}s: req is null", __func__);
1247094332d3Sopenharmony_ci        return HDF_FAILURE;
1248094332d3Sopenharmony_ci    }
1249094332d3Sopenharmony_ci
1250094332d3Sopenharmony_ci    acm->notifyReq = NULL;
1251094332d3Sopenharmony_ci    acm->pending = false;
1252094332d3Sopenharmony_ci    req->length = sizeof(*notify) + length;
1253094332d3Sopenharmony_ci
1254094332d3Sopenharmony_ci    notify = (struct UsbCdcNotification *)req->buf;
1255094332d3Sopenharmony_ci    notify->bmRequestType = USB_DDK_DIR_IN | USB_DDK_TYPE_CLASS | USB_DDK_RECIP_INTERFACE;
1256094332d3Sopenharmony_ci    notify->bNotificationType = type;
1257094332d3Sopenharmony_ci    notify->wValue = CPU_TO_LE16(value);
1258094332d3Sopenharmony_ci    notify->wIndex = CPU_TO_LE16(acm->ctrlIface.fn->info.index);
1259094332d3Sopenharmony_ci    notify->wLength = CPU_TO_LE16(length);
1260094332d3Sopenharmony_ci    ret = memcpy_s((void *)(notify + 1), length, data, length);
1261094332d3Sopenharmony_ci    if (ret != EOK) {
1262094332d3Sopenharmony_ci        HDF_LOGE("%{public}s: memcpy_s failed", __func__);
1263094332d3Sopenharmony_ci        return HDF_FAILURE;
1264094332d3Sopenharmony_ci    }
1265094332d3Sopenharmony_ci
1266094332d3Sopenharmony_ci    ret = UsbFnSubmitRequestAsync(req);
1267094332d3Sopenharmony_ci    if (ret != HDF_SUCCESS) {
1268094332d3Sopenharmony_ci        HDF_LOGE("%{public}s: send notify request failed", __func__);
1269094332d3Sopenharmony_ci        acm->notifyReq = req;
1270094332d3Sopenharmony_ci    }
1271094332d3Sopenharmony_ci
1272094332d3Sopenharmony_ci    return ret;
1273094332d3Sopenharmony_ci}
1274094332d3Sopenharmony_ci
1275094332d3Sopenharmony_cistatic int32_t AcmNotifySerialState(struct UsbAcmDevice *acm)
1276094332d3Sopenharmony_ci{
1277094332d3Sopenharmony_ci    int32_t ret = 0;
1278094332d3Sopenharmony_ci    uint16_t serialState;
1279094332d3Sopenharmony_ci
1280094332d3Sopenharmony_ci    if (acm->notifyReq) {
1281094332d3Sopenharmony_ci        HDF_LOGI("acm serial state %{public}04x", acm->serialState);
1282094332d3Sopenharmony_ci        serialState = CPU_TO_LE16(acm->serialState);
1283094332d3Sopenharmony_ci        ret = AcmSendNotifyRequest(acm, USB_DDK_CDC_NOTIFY_SERIAL_STATE, 0, &serialState, sizeof(acm->serialState));
1284094332d3Sopenharmony_ci    } else {
1285094332d3Sopenharmony_ci        acm->pending = true;
1286094332d3Sopenharmony_ci    }
1287094332d3Sopenharmony_ci
1288094332d3Sopenharmony_ci    return ret;
1289094332d3Sopenharmony_ci}
1290094332d3Sopenharmony_ci
1291094332d3Sopenharmony_cistatic void AcmConnect(struct UsbAcmDevice *acm)
1292094332d3Sopenharmony_ci{
1293094332d3Sopenharmony_ci    if (acm == NULL) {
1294094332d3Sopenharmony_ci        HDF_LOGE("%{public}s: acm is null", __func__);
1295094332d3Sopenharmony_ci        return;
1296094332d3Sopenharmony_ci    }
1297094332d3Sopenharmony_ci    acm->serialState |= SERIAL_STATE_DSR | SERIAL_STATE_DCD;
1298094332d3Sopenharmony_ci    AcmNotifySerialState(acm);
1299094332d3Sopenharmony_ci}
1300094332d3Sopenharmony_ci
1301094332d3Sopenharmony_cistatic void AcmDisconnect(struct UsbAcmDevice *acm)
1302094332d3Sopenharmony_ci{
1303094332d3Sopenharmony_ci    if (acm == NULL) {
1304094332d3Sopenharmony_ci        HDF_LOGE("%{public}s: acm is null", __func__);
1305094332d3Sopenharmony_ci        return;
1306094332d3Sopenharmony_ci    }
1307094332d3Sopenharmony_ci    acm->serialState &= ~(SERIAL_STATE_DSR | SERIAL_STATE_DCD);
1308094332d3Sopenharmony_ci    AcmNotifySerialState(acm);
1309094332d3Sopenharmony_ci}
1310094332d3Sopenharmony_ci
1311094332d3Sopenharmony_cistatic int32_t AcmSendBreak(struct UsbAcmDevice *acm, int32_t duration)
1312094332d3Sopenharmony_ci{
1313094332d3Sopenharmony_ci    uint16_t state;
1314094332d3Sopenharmony_ci
1315094332d3Sopenharmony_ci    if (acm == NULL) {
1316094332d3Sopenharmony_ci        HDF_LOGE("%{public}s: acm is null", __func__);
1317094332d3Sopenharmony_ci        return HDF_FAILURE;
1318094332d3Sopenharmony_ci    }
1319094332d3Sopenharmony_ci
1320094332d3Sopenharmony_ci    state = acm->serialState;
1321094332d3Sopenharmony_ci    state &= ~SERIAL_STATE_BREAK;
1322094332d3Sopenharmony_ci    if (duration != 0) {
1323094332d3Sopenharmony_ci        state |= SERIAL_STATE_BREAK;
1324094332d3Sopenharmony_ci    }
1325094332d3Sopenharmony_ci
1326094332d3Sopenharmony_ci    acm->serialState = state;
1327094332d3Sopenharmony_ci    return AcmNotifySerialState(acm);
1328094332d3Sopenharmony_ci}
1329094332d3Sopenharmony_ci
1330094332d3Sopenharmony_cistatic struct AcmNotifyMethod g_acmNotifyMethod = {
1331094332d3Sopenharmony_ci    .Connect = AcmConnect,
1332094332d3Sopenharmony_ci    .Disconnect = AcmDisconnect,
1333094332d3Sopenharmony_ci    .SendBreak = AcmSendBreak,
1334094332d3Sopenharmony_ci};
1335094332d3Sopenharmony_ci
1336094332d3Sopenharmony_cistatic int32_t AcmParseEachPipe(struct UsbAcmDevice *acm, struct UsbAcmInterface *iface)
1337094332d3Sopenharmony_ci{
1338094332d3Sopenharmony_ci    struct UsbFnInterface *fnIface = iface->fn;
1339094332d3Sopenharmony_ci    uint32_t repetIdx = 0;
1340094332d3Sopenharmony_ci    for (int32_t i = 0; i < fnIface->info.numPipes; i++) {
1341094332d3Sopenharmony_ci        struct UsbFnPipeInfo pipeInfo;
1342094332d3Sopenharmony_ci        (void)memset_s(&pipeInfo, sizeof(pipeInfo), 0, sizeof(pipeInfo));
1343094332d3Sopenharmony_ci        int32_t ret = UsbFnGetInterfacePipeInfo(fnIface, (uint8_t)i, &pipeInfo);
1344094332d3Sopenharmony_ci        if (ret != HDF_SUCCESS) {
1345094332d3Sopenharmony_ci            HDF_LOGE("%{public}s: get pipe info error", __func__);
1346094332d3Sopenharmony_ci            return ret;
1347094332d3Sopenharmony_ci        }
1348094332d3Sopenharmony_ci        switch (pipeInfo.type) {
1349094332d3Sopenharmony_ci            case USB_PIPE_TYPE_INTERRUPT:
1350094332d3Sopenharmony_ci                acm->notifyPipe.id = pipeInfo.id;
1351094332d3Sopenharmony_ci                acm->notifyPipe.maxPacketSize = pipeInfo.maxPacketSize;
1352094332d3Sopenharmony_ci                acm->ctrlIface = *iface;
1353094332d3Sopenharmony_ci                break;
1354094332d3Sopenharmony_ci            case USB_PIPE_TYPE_BULK:
1355094332d3Sopenharmony_ci                if (pipeInfo.dir == USB_PIPE_DIRECTION_IN) {
1356094332d3Sopenharmony_ci                    acm->dataInPipe.id = pipeInfo.id;
1357094332d3Sopenharmony_ci                    acm->dataInPipe.maxPacketSize = pipeInfo.maxPacketSize;
1358094332d3Sopenharmony_ci                    acm->dataIface = *iface;
1359094332d3Sopenharmony_ci                } else {
1360094332d3Sopenharmony_ci                    acm->dataOutPipe.id = pipeInfo.id;
1361094332d3Sopenharmony_ci                    acm->dataOutPipe.maxPacketSize = pipeInfo.maxPacketSize;
1362094332d3Sopenharmony_ci                }
1363094332d3Sopenharmony_ci                break;
1364094332d3Sopenharmony_ci            default:
1365094332d3Sopenharmony_ci                if (repetIdx < WAIT_UDC_MAX_LOOP) {
1366094332d3Sopenharmony_ci                    usleep(WAIT_UDC_TIME);
1367094332d3Sopenharmony_ci                    i--;
1368094332d3Sopenharmony_ci                }
1369094332d3Sopenharmony_ci                repetIdx++;
1370094332d3Sopenharmony_ci                HDF_LOGE("%{public}s: pipe type %{public}d don't support", __func__, pipeInfo.type);
1371094332d3Sopenharmony_ci                break;
1372094332d3Sopenharmony_ci        }
1373094332d3Sopenharmony_ci    }
1374094332d3Sopenharmony_ci
1375094332d3Sopenharmony_ci    return HDF_SUCCESS;
1376094332d3Sopenharmony_ci}
1377094332d3Sopenharmony_ci
1378094332d3Sopenharmony_cistatic int32_t AcmParseAcmIface(struct UsbAcmDevice *acm, struct UsbFnInterface *fnIface)
1379094332d3Sopenharmony_ci{
1380094332d3Sopenharmony_ci    struct UsbAcmInterface iface;
1381094332d3Sopenharmony_ci    UsbFnInterfaceHandle handle = UsbFnOpenInterface(fnIface);
1382094332d3Sopenharmony_ci    if (handle == NULL) {
1383094332d3Sopenharmony_ci        HDF_LOGE("%{public}s: open interface failed", __func__);
1384094332d3Sopenharmony_ci        return HDF_FAILURE;
1385094332d3Sopenharmony_ci    }
1386094332d3Sopenharmony_ci    iface.fn = fnIface;
1387094332d3Sopenharmony_ci    iface.handle = handle;
1388094332d3Sopenharmony_ci
1389094332d3Sopenharmony_ci    int32_t ret = AcmParseEachPipe(acm, &iface);
1390094332d3Sopenharmony_ci    if (ret != HDF_SUCCESS) {
1391094332d3Sopenharmony_ci        return HDF_FAILURE;
1392094332d3Sopenharmony_ci    }
1393094332d3Sopenharmony_ci    return HDF_SUCCESS;
1394094332d3Sopenharmony_ci}
1395094332d3Sopenharmony_ci
1396094332d3Sopenharmony_cistatic int32_t AcmParseEachIface(struct UsbAcmDevice *acm, struct UsbFnDevice *fnDev)
1397094332d3Sopenharmony_ci{
1398094332d3Sopenharmony_ci    struct UsbFnInterface *fnIface = NULL;
1399094332d3Sopenharmony_ci    uint32_t i;
1400094332d3Sopenharmony_ci    if (fnDev == NULL) {
1401094332d3Sopenharmony_ci        return HDF_FAILURE;
1402094332d3Sopenharmony_ci    }
1403094332d3Sopenharmony_ci    for (i = 0; i < fnDev->numInterfaces; i++) {
1404094332d3Sopenharmony_ci        fnIface = (struct UsbFnInterface *)UsbFnGetInterface(fnDev, i);
1405094332d3Sopenharmony_ci        if (fnIface == NULL) {
1406094332d3Sopenharmony_ci            HDF_LOGE("%{public}s: get interface failed", __func__);
1407094332d3Sopenharmony_ci            return HDF_FAILURE;
1408094332d3Sopenharmony_ci        }
1409094332d3Sopenharmony_ci
1410094332d3Sopenharmony_ci        if (fnIface->info.subclass == USB_DDK_CDC_SUBCLASS_ACM) {
1411094332d3Sopenharmony_ci            (void)AcmParseAcmIface(acm, fnIface);
1412094332d3Sopenharmony_ci            fnIface = (struct UsbFnInterface *)UsbFnGetInterface(fnDev, i + 1);
1413094332d3Sopenharmony_ci            if (fnIface == NULL) {
1414094332d3Sopenharmony_ci                HDF_LOGE("%{public}s: get interface failed", __func__);
1415094332d3Sopenharmony_ci                return HDF_FAILURE;
1416094332d3Sopenharmony_ci            }
1417094332d3Sopenharmony_ci            (void)AcmParseAcmIface(acm, fnIface);
1418094332d3Sopenharmony_ci            return HDF_SUCCESS;
1419094332d3Sopenharmony_ci        }
1420094332d3Sopenharmony_ci    }
1421094332d3Sopenharmony_ci    return HDF_FAILURE;
1422094332d3Sopenharmony_ci}
1423094332d3Sopenharmony_ci
1424094332d3Sopenharmony_cistatic int32_t AcmCreateFuncDevice(struct UsbAcmDevice *acm, struct DeviceResourceIface *iface)
1425094332d3Sopenharmony_ci{
1426094332d3Sopenharmony_ci    int32_t ret;
1427094332d3Sopenharmony_ci    struct UsbFnDevice *fnDev = NULL;
1428094332d3Sopenharmony_ci
1429094332d3Sopenharmony_ci    if (iface->GetString(acm->device->property, "udc_name", (const char **)&acm->udcName, UDC_NAME) != HDF_SUCCESS) {
1430094332d3Sopenharmony_ci        HDF_LOGE("%{public}s: read udc_name failed, use default", __func__);
1431094332d3Sopenharmony_ci        return HDF_FAILURE;
1432094332d3Sopenharmony_ci    }
1433094332d3Sopenharmony_ci
1434094332d3Sopenharmony_ci    fnDev = (struct UsbFnDevice *)UsbFnGetDevice(acm->udcName);
1435094332d3Sopenharmony_ci    if (fnDev == NULL) {
1436094332d3Sopenharmony_ci        HDF_LOGE("%{public}s: create usb function device failed", __func__);
1437094332d3Sopenharmony_ci        return HDF_FAILURE;
1438094332d3Sopenharmony_ci    }
1439094332d3Sopenharmony_ci
1440094332d3Sopenharmony_ci    ret = AcmParseEachIface(acm, fnDev);
1441094332d3Sopenharmony_ci    if (ret != HDF_SUCCESS) {
1442094332d3Sopenharmony_ci        HDF_LOGE("%{public}s: get pipes failed", __func__);
1443094332d3Sopenharmony_ci        return HDF_FAILURE;
1444094332d3Sopenharmony_ci    }
1445094332d3Sopenharmony_ci
1446094332d3Sopenharmony_ci    acm->fnDev = fnDev;
1447094332d3Sopenharmony_ci    return HDF_SUCCESS;
1448094332d3Sopenharmony_ci}
1449094332d3Sopenharmony_ci
1450094332d3Sopenharmony_cistatic int32_t AcmReleaseFuncDevice(struct UsbAcmDevice *acm)
1451094332d3Sopenharmony_ci{
1452094332d3Sopenharmony_ci    int32_t ret = HDF_SUCCESS;
1453094332d3Sopenharmony_ci    if (acm->fnDev == NULL) {
1454094332d3Sopenharmony_ci        HDF_LOGE("%{public}s: fnDev is null", __func__);
1455094332d3Sopenharmony_ci        return HDF_FAILURE;
1456094332d3Sopenharmony_ci    }
1457094332d3Sopenharmony_ci    AcmFreeCtrlRequests(acm);
1458094332d3Sopenharmony_ci    AcmFreeNotifyRequest(acm);
1459094332d3Sopenharmony_ci    (void)UsbFnCloseInterface(acm->ctrlIface.handle);
1460094332d3Sopenharmony_ci    (void)UsbFnCloseInterface(acm->dataIface.handle);
1461094332d3Sopenharmony_ci    (void)UsbFnStopRecvInterfaceEvent(acm->ctrlIface.fn);
1462094332d3Sopenharmony_ci    return ret;
1463094332d3Sopenharmony_ci}
1464094332d3Sopenharmony_ci
1465094332d3Sopenharmony_cistatic int32_t UsbSerialAlloc(struct UsbAcmDevice *acm)
1466094332d3Sopenharmony_ci{
1467094332d3Sopenharmony_ci    struct UsbSerial *port = NULL;
1468094332d3Sopenharmony_ci
1469094332d3Sopenharmony_ci    port = (struct UsbSerial *)OsalMemCalloc(sizeof(*port));
1470094332d3Sopenharmony_ci    if (port == NULL) {
1471094332d3Sopenharmony_ci        HDF_LOGE("%{public}s: Alloc usb serial port failed", __func__);
1472094332d3Sopenharmony_ci        return HDF_FAILURE;
1473094332d3Sopenharmony_ci    }
1474094332d3Sopenharmony_ci
1475094332d3Sopenharmony_ci    if (OsalMutexInit(&port->lock) != HDF_SUCCESS) {
1476094332d3Sopenharmony_ci        HDF_LOGE("%{public}s: init lock fail!", __func__);
1477094332d3Sopenharmony_ci        OsalMemFree(port);
1478094332d3Sopenharmony_ci        return HDF_FAILURE;
1479094332d3Sopenharmony_ci    }
1480094332d3Sopenharmony_ci
1481094332d3Sopenharmony_ci    DListHeadInit(&port->readPool);
1482094332d3Sopenharmony_ci    DListHeadInit(&port->readQueue);
1483094332d3Sopenharmony_ci    DListHeadInit(&port->writePool);
1484094332d3Sopenharmony_ci
1485094332d3Sopenharmony_ci    port->lineCoding.dwDTERate = CPU_TO_LE32(PORT_RATE);
1486094332d3Sopenharmony_ci    port->lineCoding.bCharFormat = USB_CDC_1_STOP_BITS;
1487094332d3Sopenharmony_ci    port->lineCoding.bParityType = USB_CDC_NO_PARITY;
1488094332d3Sopenharmony_ci    port->lineCoding.bDataBits = DATA_BIT;
1489094332d3Sopenharmony_ci
1490094332d3Sopenharmony_ci    acm->port = port;
1491094332d3Sopenharmony_ci    return HDF_SUCCESS;
1492094332d3Sopenharmony_ci}
1493094332d3Sopenharmony_ci
1494094332d3Sopenharmony_cistatic void UsbSerialFree(struct UsbAcmDevice *acm)
1495094332d3Sopenharmony_ci{
1496094332d3Sopenharmony_ci    struct UsbSerial *port = acm->port;
1497094332d3Sopenharmony_ci
1498094332d3Sopenharmony_ci    if (port == NULL) {
1499094332d3Sopenharmony_ci        HDF_LOGE("%{public}s: port is null", __func__);
1500094332d3Sopenharmony_ci        return;
1501094332d3Sopenharmony_ci    }
1502094332d3Sopenharmony_ci    OsalMemFree(port);
1503094332d3Sopenharmony_ci    acm->port = NULL;
1504094332d3Sopenharmony_ci}
1505094332d3Sopenharmony_ci
1506094332d3Sopenharmony_ci/* HdfDriverEntry implementations */
1507094332d3Sopenharmony_cistatic int32_t AcmDriverBind(struct HdfDeviceObject *device)
1508094332d3Sopenharmony_ci{
1509094332d3Sopenharmony_ci    struct UsbAcmDevice *acm = NULL;
1510094332d3Sopenharmony_ci
1511094332d3Sopenharmony_ci    if (device == NULL) {
1512094332d3Sopenharmony_ci        HDF_LOGE("%{public}s: device is null", __func__);
1513094332d3Sopenharmony_ci        return HDF_ERR_INVALID_OBJECT;
1514094332d3Sopenharmony_ci    }
1515094332d3Sopenharmony_ci
1516094332d3Sopenharmony_ci    acm = (struct UsbAcmDevice *)OsalMemCalloc(sizeof(*acm));
1517094332d3Sopenharmony_ci    if (acm == NULL) {
1518094332d3Sopenharmony_ci        HDF_LOGE("%{public}s: Alloc usb acm device failed", __func__);
1519094332d3Sopenharmony_ci        return HDF_FAILURE;
1520094332d3Sopenharmony_ci    }
1521094332d3Sopenharmony_ci
1522094332d3Sopenharmony_ci    if (OsalMutexInit(&acm->lock) != HDF_SUCCESS) {
1523094332d3Sopenharmony_ci        HDF_LOGE("%{public}s: init lock fail!", __func__);
1524094332d3Sopenharmony_ci        OsalMemFree(acm);
1525094332d3Sopenharmony_ci        return HDF_FAILURE;
1526094332d3Sopenharmony_ci    }
1527094332d3Sopenharmony_ci
1528094332d3Sopenharmony_ci    if (HdfDeviceObjectSetInterfaceDesc(device, "hdf.usb.usbfn") != HDF_SUCCESS) {
1529094332d3Sopenharmony_ci        HDF_LOGE(" Set Desc fail!");
1530094332d3Sopenharmony_ci        OsalMemFree(acm);
1531094332d3Sopenharmony_ci        return HDF_FAILURE;
1532094332d3Sopenharmony_ci    }
1533094332d3Sopenharmony_ci
1534094332d3Sopenharmony_ci    acm->device = device;
1535094332d3Sopenharmony_ci    device->service = &(acm->service);
1536094332d3Sopenharmony_ci    acm->device->service->Dispatch = AcmDeviceDispatch;
1537094332d3Sopenharmony_ci    acm->notify = NULL;
1538094332d3Sopenharmony_ci    acm->initFlag = false;
1539094332d3Sopenharmony_ci    return HDF_SUCCESS;
1540094332d3Sopenharmony_ci}
1541094332d3Sopenharmony_ci
1542094332d3Sopenharmony_cistatic int32_t UsbSerialInit(struct UsbAcmDevice *acm)
1543094332d3Sopenharmony_ci{
1544094332d3Sopenharmony_ci    struct DeviceResourceIface *iface = NULL;
1545094332d3Sopenharmony_ci    int32_t ret;
1546094332d3Sopenharmony_ci
1547094332d3Sopenharmony_ci    if (acm == NULL || acm->initFlag) {
1548094332d3Sopenharmony_ci        HDF_LOGE("%{public}s: acm is null", __func__);
1549094332d3Sopenharmony_ci        return HDF_FAILURE;
1550094332d3Sopenharmony_ci    }
1551094332d3Sopenharmony_ci    iface = DeviceResourceGetIfaceInstance(HDF_CONFIG_SOURCE);
1552094332d3Sopenharmony_ci    if (iface == NULL || iface->GetUint32 == NULL) {
1553094332d3Sopenharmony_ci        HDF_LOGE("%{public}s: face is invalid", __func__);
1554094332d3Sopenharmony_ci        return HDF_FAILURE;
1555094332d3Sopenharmony_ci    }
1556094332d3Sopenharmony_ci
1557094332d3Sopenharmony_ci    ret = AcmCreateFuncDevice(acm, iface);
1558094332d3Sopenharmony_ci    if (ret != HDF_SUCCESS) {
1559094332d3Sopenharmony_ci        HDF_LOGE("%{public}s: AcmCreateFuncDevice failed", __func__);
1560094332d3Sopenharmony_ci        return HDF_FAILURE;
1561094332d3Sopenharmony_ci    }
1562094332d3Sopenharmony_ci
1563094332d3Sopenharmony_ci    ret = UsbSerialAlloc(acm);
1564094332d3Sopenharmony_ci    if (ret != HDF_SUCCESS) {
1565094332d3Sopenharmony_ci        HDF_LOGE("%{public}s: UsbSerialAlloc failed", __func__);
1566094332d3Sopenharmony_ci        goto ERR;
1567094332d3Sopenharmony_ci    }
1568094332d3Sopenharmony_ci
1569094332d3Sopenharmony_ci    ret = AcmAllocCtrlRequests(acm, CTRL_REQUEST_NUM);
1570094332d3Sopenharmony_ci    if (ret != HDF_SUCCESS) {
1571094332d3Sopenharmony_ci        HDF_LOGE("%{public}s: AcmAllocCtrlRequests failed", __func__);
1572094332d3Sopenharmony_ci        goto ERR;
1573094332d3Sopenharmony_ci    }
1574094332d3Sopenharmony_ci
1575094332d3Sopenharmony_ci    ret = AcmAllocNotifyRequest(acm);
1576094332d3Sopenharmony_ci    if (ret != HDF_SUCCESS) {
1577094332d3Sopenharmony_ci        HDF_LOGE("%{public}s: AcmAllocNotifyRequest failed", __func__);
1578094332d3Sopenharmony_ci        goto ERR;
1579094332d3Sopenharmony_ci    }
1580094332d3Sopenharmony_ci
1581094332d3Sopenharmony_ci    ret = UsbFnStartRecvInterfaceEvent(acm->ctrlIface.fn, RECEIVE_ALL_EVENTS, UsbAcmEventCallback, acm);
1582094332d3Sopenharmony_ci    if (ret != HDF_SUCCESS) {
1583094332d3Sopenharmony_ci        HDF_LOGE("%{public}s: register event callback failed", __func__);
1584094332d3Sopenharmony_ci        goto ERR;
1585094332d3Sopenharmony_ci    }
1586094332d3Sopenharmony_ci
1587094332d3Sopenharmony_ci    acm->notify = &g_acmNotifyMethod;
1588094332d3Sopenharmony_ci    acm->initFlag = true;
1589094332d3Sopenharmony_ci    return HDF_SUCCESS;
1590094332d3Sopenharmony_ci
1591094332d3Sopenharmony_ciERR:
1592094332d3Sopenharmony_ci    UsbSerialFree(acm);
1593094332d3Sopenharmony_ci    (void)AcmReleaseFuncDevice(acm);
1594094332d3Sopenharmony_ci    return ret;
1595094332d3Sopenharmony_ci}
1596094332d3Sopenharmony_ci
1597094332d3Sopenharmony_cistatic int32_t UsbSerialRelease(struct UsbAcmDevice *acm)
1598094332d3Sopenharmony_ci{
1599094332d3Sopenharmony_ci    if (acm == NULL || acm->initFlag == false) {
1600094332d3Sopenharmony_ci        HDF_LOGE("%{public}s: acm is null", __func__);
1601094332d3Sopenharmony_ci        return HDF_FAILURE;
1602094332d3Sopenharmony_ci    }
1603094332d3Sopenharmony_ci    OsalMutexLock(&acm->lock);
1604094332d3Sopenharmony_ci    (void)AcmReleaseFuncDevice(acm);
1605094332d3Sopenharmony_ci    UsbSerialFree(acm);
1606094332d3Sopenharmony_ci    acm->initFlag = false;
1607094332d3Sopenharmony_ci    OsalMutexUnlock(&acm->lock);
1608094332d3Sopenharmony_ci    return 0;
1609094332d3Sopenharmony_ci}
1610094332d3Sopenharmony_ci
1611094332d3Sopenharmony_cistatic int32_t AcmDriverInit(struct HdfDeviceObject *device)
1612094332d3Sopenharmony_ci{
1613094332d3Sopenharmony_ci    (void)device;
1614094332d3Sopenharmony_ci    HDF_LOGI("%{public}s: do nothing", __func__);
1615094332d3Sopenharmony_ci    return 0;
1616094332d3Sopenharmony_ci}
1617094332d3Sopenharmony_ci
1618094332d3Sopenharmony_cistatic void AcmDriverRelease(struct HdfDeviceObject *device)
1619094332d3Sopenharmony_ci{
1620094332d3Sopenharmony_ci    struct UsbAcmDevice *acm = NULL;
1621094332d3Sopenharmony_ci    if (device == NULL) {
1622094332d3Sopenharmony_ci        HDF_LOGE("%{public}s: device is NULL", __func__);
1623094332d3Sopenharmony_ci        return;
1624094332d3Sopenharmony_ci    }
1625094332d3Sopenharmony_ci
1626094332d3Sopenharmony_ci    acm = (struct UsbAcmDevice *)device->service;
1627094332d3Sopenharmony_ci    if (acm == NULL) {
1628094332d3Sopenharmony_ci        HDF_LOGE("%{public}s: acm is null", __func__);
1629094332d3Sopenharmony_ci        return;
1630094332d3Sopenharmony_ci    }
1631094332d3Sopenharmony_ci    (void)OsalMutexDestroy(&acm->lock);
1632094332d3Sopenharmony_ci    AcmDeviceDestroy(acm);
1633094332d3Sopenharmony_ci    device->service = NULL;
1634094332d3Sopenharmony_ci}
1635094332d3Sopenharmony_ci
1636094332d3Sopenharmony_cistruct HdfDriverEntry g_acmDriverEntry = {
1637094332d3Sopenharmony_ci    .moduleVersion = 1,
1638094332d3Sopenharmony_ci    .moduleName = "usbfn_cdcacm",
1639094332d3Sopenharmony_ci    .Bind = AcmDriverBind,
1640094332d3Sopenharmony_ci    .Init = AcmDriverInit,
1641094332d3Sopenharmony_ci    .Release = AcmDriverRelease,
1642094332d3Sopenharmony_ci};
1643094332d3Sopenharmony_ci
1644094332d3Sopenharmony_ciHDF_INIT(g_acmDriverEntry);
1645