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