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 42static const int32_t WAIT_UDC_MAX_LOOP = 3; 43static const uint32_t WAIT_UDC_TIME = 100000; 44static int32_t g_inFifo = 0; 45/* Usb Serial Related Functions */ 46 47static int32_t UsbSerialInit(struct UsbAcmDevice *acm); 48static int32_t UsbSerialRelease(struct UsbAcmDevice *acm); 49static 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 92static 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 122static 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 165static 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 179static bool g_isStartRead = false; 180static bool g_isReadDone = false; 181static uint64_t g_readCnt = 0; 182struct timeval g_readTimeStart, g_readTimeEnd; 183static float g_readSpeed = 0; 184static bool g_isGetReadTimeStart = false; 185static 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 201static 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 233struct OsalThread g_threadRead; 234static 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 262static 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 272static 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 283static 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 292static int32_t UsbSerialReadSpeedStart(struct UsbSerial *port) 293{ 294 g_inFifo = 0; 295 g_isStartRead = true; 296 return StartThreadReadSpeed(port); 297} 298 299static 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 321static 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 342static 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 363static void UsbSerialFreeFifo(struct DataFifo *fifo) 364{ 365 void *buf = fifo->data; 366 OsalMemFree(buf); 367 DataFifoInit(fifo, 0, NULL); 368} 369 370static 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 406static 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 418static 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 431static 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 469OUT: 470 OsalMutexUnlock(&port->lock); 471 return HDF_SUCCESS; 472} 473 474static 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 501struct UsbFnRequest *g_req[WRITE_SPEED_REQ_NUM] = {NULL}; 502static bool g_isWriteDone = false; 503static uint64_t g_writeCnt = 0; 504struct timeval g_timeStart, g_timeEnd; 505static float g_speed = 0; 506static bool g_isGetWriteTimeStart = false; 507static 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 536static 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 585struct OsalThread g_thread; 586static 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 612static 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 622static 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 633static 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 641static int32_t UsbSerialSpeed(struct UsbSerial *port) 642{ 643 StartThreadSpeed(port); 644 return HDF_SUCCESS; 645} 646 647static 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 } 684OUT: 685 if (port->acm) { 686 UsbSerialStartRx(port); 687 } 688 OsalMemFree(buf); 689 OsalMutexUnlock(&port->lock); 690 return ret; 691} 692 693static 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 731static 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 741static 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 757static 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 779static 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 806static 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 815static 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 824static 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 850static 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 894static 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 929static void AcmDeviceDestroy(struct UsbAcmDevice *acm) 930{ 931 if (acm == NULL) { 932 return; 933 } 934 OsalMemFree(acm); 935} 936 937static 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 963OUT: 964 DListInsertTail(&req->list, &acm->ctrlPool); 965} 966 967static 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 996OUT: 997 return DListIsEmpty(head) ? HDF_FAILURE : HDF_SUCCESS; 998} 999 1000static 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 1014static int32_t AcmNotifySerialState(struct UsbAcmDevice *acm); 1015static 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 1037static 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 1052static 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 1065static 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 1073static 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 1089static 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 1101static 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 1143OUT: 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 1153static 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 1167static 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 1193static 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 1238static 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 1275static 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 1291static 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 1301static 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 1311static 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 1330static struct AcmNotifyMethod g_acmNotifyMethod = { 1331 .Connect = AcmConnect, 1332 .Disconnect = AcmDisconnect, 1333 .SendBreak = AcmSendBreak, 1334}; 1335 1336static 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 1378static 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 1396static 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 1424static 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 1450static 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 1465static 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 1494static 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 */ 1507static 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 1542static 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 1591ERR: 1592 UsbSerialFree(acm); 1593 (void)AcmReleaseFuncDevice(acm); 1594 return ret; 1595} 1596 1597static 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 1611static int32_t AcmDriverInit(struct HdfDeviceObject *device) 1612{ 1613 (void)device; 1614 HDF_LOGI("%{public}s: do nothing", __func__); 1615 return 0; 1616} 1617 1618static 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 1636struct HdfDriverEntry g_acmDriverEntry = { 1637 .moduleVersion = 1, 1638 .moduleName = "usbfn_cdcacm", 1639 .Bind = AcmDriverBind, 1640 .Init = AcmDriverInit, 1641 .Release = AcmDriverRelease, 1642}; 1643 1644HDF_INIT(g_acmDriverEntry); 1645