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