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