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