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