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