/* * Copyright (c) 2021 Huawei Device Co., Ltd. * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ #include "osal_thread.h" #include "signal.h" #include "usbhost_ddk_test.h" #define HDF_LOG_TAG USB_HOST_DDK_TEST #define STR_LEN 256 #define STRTOL_BASE 10 #define PARAM_CMD_LENGTH 3 #define PARAM_SET_CMD_LEN 3 #define PARAM_GET_CMD_LEN 2 #define ARGV_CMD_API_TYPE 1 #define ARGV_CMD_TYPE (PARAM_GET_CMD_LEN - ARGV_CMD_API_TYPE) #define ARGV_CMD_PARAM (PARAM_SET_CMD_LEN - ARGV_CMD_API_TYPE) #define READ_SLEEP_TIME 500 int32_t run; #ifdef __LITEOS_USB_HOST_DDK_TEST__ static struct OsalThread g_Getchar; #endif static void TestHelp(void) { printf("usage: usbhost_ddk_test [options]\n"); printf("\n"); printf("options include:\n"); printf(" -h, --help : help info\n"); printf(" -A, --DDK : test host ddk api function for acm\n"); printf(" -a, --RAW : test host raw api function for acm\n"); printf(" -E, --ECM : test host ddk api function for ecm\n"); printf(" -R, --syncRead : test sync read for acm\n"); printf(" -W, --syncWrite : test sync write for acm\n"); printf(" -r, --asyncRead : test async read for acm\n"); printf(" -w, --asyncWrite : test async write for acm\n"); printf(" -c, --ctrlClassSync : test class ctrl cmd for acm\n"); printf(" -s, --ctrlGetStatus : test get status ctrl cmd for acm\n"); printf(" -C, --ctrlSyncDescriptor : test sync get descriptor ctrl cmd for acm\n"); printf(" -d, --ctrlAsyncDescriptor : test async get descriptor ctrl cmd for acm\n"); printf(" -g, --ctrlGetConfiguration : test get configuration ctrl cmd for acm\n"); printf(" -i, --ctrlGetInterface : test get interface ctrl cmd for acm\n"); printf(" -S, --speedTest : test speed for acm\n"); printf(" -B, --setBaudrate : test set baudrate for acm\n"); printf(" -b, --getBaudrate : test get baudrate for acm\n"); printf(" -I, --addInterface [index} : test add interface for acm(not raw api function) and ecm\n"); printf(" -D, --removeInterface [index] : test remove interface for acm(not raw api function) and ecm\n"); printf("\n"); printf("Examples:\n"); printf(" usbhost_ddk_test -AR : test sync read for acm by host ddk api function\n"); printf(" usbhost_ddk_test -aw 123 : test async write 123 for acm by host raw api function\n"); } static int32_t TestParaseCommand(int32_t paramNum, const char *cmdParam, int32_t *cmdType, char *apiType) { if ((cmdParam == NULL) || (cmdType == NULL) || (apiType == NULL) || (strlen(cmdParam) < PARAM_CMD_LENGTH)) { HDF_LOGE("%{public}s:%{public}d command or cmdType is NULL or cmdParam length is error", __func__, __LINE__); return HDF_ERR_INVALID_PARAM; } uint32_t len = strlen(cmdParam); for (uint32_t i = 0; i < len; i++) { switch (cmdParam[i]) { case 'A': strcpy_s(apiType, DATA_MAX_LEN, "-SDK"); break; case 'a': strcpy_s(apiType, DATA_MAX_LEN, "-RAW"); break; case 'E': strcpy_s(apiType, DATA_MAX_LEN, "-ECM"); break; case 'R': if (paramNum != PARAM_GET_CMD_LEN) { return HDF_FAILURE; } *cmdType = HOST_ACM_SYNC_READ; break; case 'W': if (paramNum != PARAM_SET_CMD_LEN) { return HDF_FAILURE; } *cmdType = HOST_ACM_SYNC_WRITE; break; case 'r': if (paramNum != PARAM_GET_CMD_LEN) { return HDF_FAILURE; } *cmdType = HOST_ACM_ASYNC_READ; break; case 'w': if (paramNum != PARAM_SET_CMD_LEN) { return HDF_FAILURE; } *cmdType = HOST_ACM_ASYNC_WRITE; break; case 'c': if (paramNum != PARAM_GET_CMD_LEN) { return HDF_FAILURE; } *cmdType = HOST_ACM_CTRL_CLASS_SYNC; break; case 's': if (paramNum != PARAM_GET_CMD_LEN) { return HDF_FAILURE; } *cmdType = HOST_ACM_CTRL_GET_STATUS; break; case 'C': if (paramNum != PARAM_GET_CMD_LEN) { return HDF_FAILURE; } *cmdType = HOST_ACM_CTRL_SYNC_DESCRIPTOR; break; case 'd': if (paramNum != PARAM_GET_CMD_LEN) { return HDF_FAILURE; } *cmdType = HOST_ACM_CTRL_ASYNC_DESCRIPTOR; break; case 'g': if (paramNum != PARAM_GET_CMD_LEN) { return HDF_FAILURE; } *cmdType = HOST_ACM_CTRL_GET_CONFIGURATION; break; case 'i': if (paramNum != PARAM_GET_CMD_LEN) { return HDF_FAILURE; } *cmdType = HOST_ACM_CTRL_GET_INTERFACE; break; case 'S': if (paramNum != PARAM_GET_CMD_LEN) { return HDF_FAILURE; } *cmdType = HOST_ACM_SPEED_TEST; break; case 'B': if (paramNum != PARAM_SET_CMD_LEN) { return HDF_FAILURE; } *cmdType = HOST_ACM_SET_BAUDRATE; break; case 'b': if (paramNum != PARAM_GET_CMD_LEN) { return HDF_FAILURE; } *cmdType = HOST_ACM_GET_BAUDRATE; break; case 'I': if (paramNum != PARAM_SET_CMD_LEN) { return HDF_FAILURE; } *cmdType = HOST_ACM_ADD_INTERFACE; break; case 'D': if (paramNum != PARAM_SET_CMD_LEN) { return HDF_FAILURE; } *cmdType = HOST_ACM_REMOVE_INTERFACE; break; case '-': break; default: return HDF_FAILURE; } } return HDF_SUCCESS; } static void TestCmdLoopOther(int32_t cmdType, const char *param) { switch (cmdType) { case HOST_ACM_CTRL_CLASS_SYNC: UsbHostDdkTestCtrlClass(NULL); break; case HOST_ACM_CTRL_GET_STATUS: UsbHostDdkTestStdGetStatus(NULL); break; case HOST_ACM_CTRL_SYNC_DESCRIPTOR: UsbHostDdkTestStdGetDes(NULL); break; case HOST_ACM_CTRL_ASYNC_DESCRIPTOR: UsbHostDdkTestStdGetDesAsync(NULL); usleep(READ_SLEEP_TIME); break; case HOST_ACM_CTRL_GET_CONFIGURATION: TestStdGetConf(); break; case HOST_ACM_CTRL_GET_INTERFACE: TestStdGetInterface(); break; case HOST_ACM_SET_BAUDRATE: UsbHostDdkTestSetBaudrate((uint32_t)(strtoul(param, NULL, STRTOL_BASE))); break; case HOST_ACM_GET_BAUDRATE: UsbHostDdkTestGetBaudrate(NULL); break; case HOST_ACM_ADD_INTERFACE: UsbHostDdkTestAddInterface((uint32_t)(strtoul(param, NULL, STRTOL_BASE))); break; case HOST_ACM_REMOVE_INTERFACE: UsbHostDdkTestRemoveInterface((uint32_t)(strtoul(param, NULL, STRTOL_BASE))); break; default: break; } } static int32_t TestCmdLoop(int32_t cmdType, const char *param) { bool loopFlag = true; bool asyncFlag = false; int32_t cnt = 0; if (TestGetExitFlag() == true) { HDF_LOGD("%{public}s:%{public}d g_exitFlag is true!", __func__, __LINE__); return HDF_FAILURE; } while ((loopFlag) && (!run)) { switch (cmdType) { case HOST_ACM_SYNC_READ: UsbHostDdkTestSyncRead(NULL); break; case HOST_ACM_SYNC_WRITE: UsbHostDdkTestSyncWrite(param); break; case HOST_ACM_ASYNC_READ: if (UsbHostDdkTestAsyncRead(NULL) != HDF_SUCCESS) { #ifdef __LITEOS_USB_HOST_DDK_TEST__ if (cnt++ > 10) { asyncFlag = false; return HDF_DEV_ERR_NO_DEVICE_SERVICE; } #else asyncFlag = false; #endif } else { cnt = 0; asyncFlag = true; usleep(READ_SLEEP_TIME); } break; case HOST_ACM_ASYNC_WRITE: UsbHostDdkTestAsyncWrite(param); break; default: TestCmdLoopOther(cmdType, param); break; } if (!asyncFlag) { loopFlag = false; } } return HDF_SUCCESS; } #ifdef __LITEOS_USB_HOST_DDK_TEST__ static void *SigHandle(void *arg) { (void)arg; run = 0; return NULL; } static int32_t GetCharThread(void *arg) { char str[STR_LEN] = {0}; while (run) { str[0] = (char)getchar(); } return 0; } #endif #define HDF_PROCESS_STACK_SIZE 100000 static int32_t StartThreadGetChar() { #ifdef __LITEOS_USB_HOST_DDK_TEST__ int32_t ret; struct OsalThreadParam threadCfg; memset_s(&threadCfg, sizeof(threadCfg), 0, sizeof(threadCfg)); threadCfg.name = "get char process"; threadCfg.priority = OSAL_THREAD_PRI_DEFAULT; threadCfg.stackSize = HDF_PROCESS_STACK_SIZE; ret = OsalThreadCreate(&g_Getchar, (OsalThreadEntry)GetCharThread, NULL); if (HDF_SUCCESS != ret) { HDF_LOGE("%{public}s:%{public}d OsalThreadCreate failed, ret=%{public}d ", __func__, __LINE__, ret); return HDF_ERR_DEVICE_BUSY; } ret = OsalThreadStart(&g_Getchar, &threadCfg); if (HDF_SUCCESS != ret) { HDF_LOGE("%{public}s:%{public}d OsalThreadStart failed, ret=%{public}d ", __func__, __LINE__, ret); return HDF_ERR_DEVICE_BUSY; } #endif return 0; } int32_t main(int32_t argc, char *argv[]) { int32_t status; int32_t cmdType; char apiType[DATA_MAX_LEN]; if ((argc < ARGV_CMD_TYPE) || (argc < PARAM_GET_CMD_LEN) || (argv[ARGV_CMD_TYPE] == NULL)) { HDF_LOGE("%{public}s:%{public}d invalid parma, argc=%{public}d", __func__, __LINE__, argc); return HDF_FAILURE; } if ((argc == PARAM_GET_CMD_LEN) && ((!strcmp(argv[ARGV_CMD_TYPE], "-h")) || (!strcmp(argv[ARGV_CMD_TYPE], "--help")))) { TestHelp(); return HDF_SUCCESS; } run = 1; StartThreadGetChar(); status = TestParaseCommand(argc, argv[ARGV_CMD_TYPE], &cmdType, apiType); if (status != HDF_SUCCESS) { run = 0; HDF_LOGE("%{public}s:%{public}d TestParaseCommand status=%{public}d err", __func__, __LINE__, status); TestHelp(); return status; } status = UsbHostDdkTestInit(apiType); if (status != HDF_SUCCESS) { run = 0; HDF_LOGE("%{public}s:%{public}d UsbHostDdkTestInit status=%{public}d err", __func__, __LINE__, status); return status; } if (UsbHostDdkTestOpen(cmdType) != HDF_SUCCESS) { goto OUT; } #ifdef __LITEOS_USB_HOST_DDK_TEST__ (void)signal(SIGINT, SigHandle); #endif status = TestCmdLoop(cmdType, argv[ARGV_CMD_PARAM]); if (status == HDF_DEV_ERR_NO_DEVICE_SERVICE) { goto OUT; } if ((cmdType != HOST_ACM_ADD_INTERFACE) && (cmdType != HOST_ACM_REMOVE_INTERFACE)) { if (UsbHostDdkTestClose(cmdType) != HDF_SUCCESS) { goto OUT; } } OUT: run = 0; TestExit(); return HDF_SUCCESS; }