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