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