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