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