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