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