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