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 "osal_thread.h" 17#include "signal.h" 18#include "usbhost_ddk_test.h" 19 20#define HDF_LOG_TAG USB_HOST_DDK_TEST 21#define STR_LEN 256 22#define STRTOL_BASE 10 23 24#define PARAM_CMD_LENGTH 3 25#define PARAM_SET_CMD_LEN 3 26#define PARAM_GET_CMD_LEN 2 27#define ARGV_CMD_API_TYPE 1 28#define ARGV_CMD_TYPE (PARAM_GET_CMD_LEN - ARGV_CMD_API_TYPE) 29#define ARGV_CMD_PARAM (PARAM_SET_CMD_LEN - ARGV_CMD_API_TYPE) 30#define READ_SLEEP_TIME 500 31int32_t run; 32 33#ifdef __LITEOS_USB_HOST_DDK_TEST__ 34static struct OsalThread g_Getchar; 35#endif 36 37static void TestHelp(void) 38{ 39 printf("usage: usbhost_ddk_test [options]\n"); 40 printf("\n"); 41 printf("options include:\n"); 42 printf(" -h, --help : help info\n"); 43 printf(" -A, --DDK : test host ddk api function for acm\n"); 44 printf(" -a, --RAW : test host raw api function for acm\n"); 45 printf(" -E, --ECM : test host ddk api function for ecm\n"); 46 printf(" -R, --syncRead : test sync read for acm\n"); 47 printf(" -W, --syncWrite : test sync write for acm\n"); 48 printf(" -r, --asyncRead : test async read for acm\n"); 49 printf(" -w, --asyncWrite : test async write for acm\n"); 50 printf(" -c, --ctrlClassSync : test class ctrl cmd for acm\n"); 51 printf(" -s, --ctrlGetStatus : test get status ctrl cmd for acm\n"); 52 printf(" -C, --ctrlSyncDescriptor : test sync get descriptor ctrl cmd for acm\n"); 53 printf(" -d, --ctrlAsyncDescriptor : test async get descriptor ctrl cmd for acm\n"); 54 printf(" -g, --ctrlGetConfiguration : test get configuration ctrl cmd for acm\n"); 55 printf(" -i, --ctrlGetInterface : test get interface ctrl cmd for acm\n"); 56 printf(" -S, --speedTest : test speed for acm\n"); 57 printf(" -B, --setBaudrate : test set baudrate for acm\n"); 58 printf(" -b, --getBaudrate : test get baudrate for acm\n"); 59 printf(" -I, --addInterface [index} : test add interface for acm(not raw api function) and ecm\n"); 60 printf(" -D, --removeInterface [index] : test remove interface for acm(not raw api function) and ecm\n"); 61 printf("\n"); 62 printf("Examples:\n"); 63 printf(" usbhost_ddk_test -AR : test sync read for acm by host ddk api function\n"); 64 printf(" usbhost_ddk_test -aw 123 : test async write 123 for acm by host raw api function\n"); 65} 66 67static int32_t TestParaseCommand(int32_t paramNum, const char *cmdParam, int32_t *cmdType, char *apiType) 68{ 69 if ((cmdParam == NULL) || (cmdType == NULL) || (apiType == NULL) || (strlen(cmdParam) < PARAM_CMD_LENGTH)) { 70 HDF_LOGE("%{public}s:%{public}d command or cmdType is NULL or cmdParam length is error", __func__, __LINE__); 71 return HDF_ERR_INVALID_PARAM; 72 } 73 74 uint32_t len = strlen(cmdParam); 75 for (uint32_t i = 0; i < len; i++) { 76 switch (cmdParam[i]) { 77 case 'A': 78 strcpy_s(apiType, DATA_MAX_LEN, "-SDK"); 79 break; 80 case 'a': 81 strcpy_s(apiType, DATA_MAX_LEN, "-RAW"); 82 break; 83 case 'E': 84 strcpy_s(apiType, DATA_MAX_LEN, "-ECM"); 85 break; 86 case 'R': 87 if (paramNum != PARAM_GET_CMD_LEN) { 88 return HDF_FAILURE; 89 } 90 *cmdType = HOST_ACM_SYNC_READ; 91 break; 92 case 'W': 93 if (paramNum != PARAM_SET_CMD_LEN) { 94 return HDF_FAILURE; 95 } 96 *cmdType = HOST_ACM_SYNC_WRITE; 97 break; 98 case 'r': 99 if (paramNum != PARAM_GET_CMD_LEN) { 100 return HDF_FAILURE; 101 } 102 *cmdType = HOST_ACM_ASYNC_READ; 103 break; 104 case 'w': 105 if (paramNum != PARAM_SET_CMD_LEN) { 106 return HDF_FAILURE; 107 } 108 *cmdType = HOST_ACM_ASYNC_WRITE; 109 break; 110 case 'c': 111 if (paramNum != PARAM_GET_CMD_LEN) { 112 return HDF_FAILURE; 113 } 114 *cmdType = HOST_ACM_CTRL_CLASS_SYNC; 115 break; 116 case 's': 117 if (paramNum != PARAM_GET_CMD_LEN) { 118 return HDF_FAILURE; 119 } 120 *cmdType = HOST_ACM_CTRL_GET_STATUS; 121 break; 122 case 'C': 123 if (paramNum != PARAM_GET_CMD_LEN) { 124 return HDF_FAILURE; 125 } 126 *cmdType = HOST_ACM_CTRL_SYNC_DESCRIPTOR; 127 break; 128 case 'd': 129 if (paramNum != PARAM_GET_CMD_LEN) { 130 return HDF_FAILURE; 131 } 132 *cmdType = HOST_ACM_CTRL_ASYNC_DESCRIPTOR; 133 break; 134 case 'g': 135 if (paramNum != PARAM_GET_CMD_LEN) { 136 return HDF_FAILURE; 137 } 138 *cmdType = HOST_ACM_CTRL_GET_CONFIGURATION; 139 break; 140 case 'i': 141 if (paramNum != PARAM_GET_CMD_LEN) { 142 return HDF_FAILURE; 143 } 144 *cmdType = HOST_ACM_CTRL_GET_INTERFACE; 145 break; 146 case 'S': 147 if (paramNum != PARAM_GET_CMD_LEN) { 148 return HDF_FAILURE; 149 } 150 *cmdType = HOST_ACM_SPEED_TEST; 151 break; 152 case 'B': 153 if (paramNum != PARAM_SET_CMD_LEN) { 154 return HDF_FAILURE; 155 } 156 *cmdType = HOST_ACM_SET_BAUDRATE; 157 break; 158 case 'b': 159 if (paramNum != PARAM_GET_CMD_LEN) { 160 return HDF_FAILURE; 161 } 162 *cmdType = HOST_ACM_GET_BAUDRATE; 163 break; 164 case 'I': 165 if (paramNum != PARAM_SET_CMD_LEN) { 166 return HDF_FAILURE; 167 } 168 *cmdType = HOST_ACM_ADD_INTERFACE; 169 break; 170 case 'D': 171 if (paramNum != PARAM_SET_CMD_LEN) { 172 return HDF_FAILURE; 173 } 174 *cmdType = HOST_ACM_REMOVE_INTERFACE; 175 break; 176 case '-': 177 break; 178 default: 179 return HDF_FAILURE; 180 } 181 } 182 183 return HDF_SUCCESS; 184} 185 186static void TestCmdLoopOther(int32_t cmdType, const char *param) 187{ 188 switch (cmdType) { 189 case HOST_ACM_CTRL_CLASS_SYNC: 190 UsbHostDdkTestCtrlClass(NULL); 191 break; 192 case HOST_ACM_CTRL_GET_STATUS: 193 UsbHostDdkTestStdGetStatus(NULL); 194 break; 195 case HOST_ACM_CTRL_SYNC_DESCRIPTOR: 196 UsbHostDdkTestStdGetDes(NULL); 197 break; 198 case HOST_ACM_CTRL_ASYNC_DESCRIPTOR: 199 UsbHostDdkTestStdGetDesAsync(NULL); 200 usleep(READ_SLEEP_TIME); 201 break; 202 case HOST_ACM_CTRL_GET_CONFIGURATION: 203 TestStdGetConf(); 204 break; 205 case HOST_ACM_CTRL_GET_INTERFACE: 206 TestStdGetInterface(); 207 break; 208 case HOST_ACM_SET_BAUDRATE: 209 UsbHostDdkTestSetBaudrate((uint32_t)(strtoul(param, NULL, STRTOL_BASE))); 210 break; 211 case HOST_ACM_GET_BAUDRATE: 212 UsbHostDdkTestGetBaudrate(NULL); 213 break; 214 case HOST_ACM_ADD_INTERFACE: 215 UsbHostDdkTestAddInterface((uint32_t)(strtoul(param, NULL, STRTOL_BASE))); 216 break; 217 case HOST_ACM_REMOVE_INTERFACE: 218 UsbHostDdkTestRemoveInterface((uint32_t)(strtoul(param, NULL, STRTOL_BASE))); 219 break; 220 default: 221 break; 222 } 223} 224 225static int32_t TestCmdLoop(int32_t cmdType, const char *param) 226{ 227 bool loopFlag = true; 228 bool asyncFlag = false; 229 int32_t cnt = 0; 230 231 if (TestGetExitFlag() == true) { 232 HDF_LOGD("%{public}s:%{public}d g_exitFlag is true!", __func__, __LINE__); 233 return HDF_FAILURE; 234 } 235 236 while ((loopFlag) && (!run)) { 237 switch (cmdType) { 238 case HOST_ACM_SYNC_READ: 239 UsbHostDdkTestSyncRead(NULL); 240 break; 241 case HOST_ACM_SYNC_WRITE: 242 UsbHostDdkTestSyncWrite(param); 243 break; 244 case HOST_ACM_ASYNC_READ: 245 if (UsbHostDdkTestAsyncRead(NULL) != HDF_SUCCESS) { 246#ifdef __LITEOS_USB_HOST_DDK_TEST__ 247 if (cnt++ > 10) { 248 asyncFlag = false; 249 return HDF_DEV_ERR_NO_DEVICE_SERVICE; 250 } 251#else 252 asyncFlag = false; 253#endif 254 } else { 255 cnt = 0; 256 asyncFlag = true; 257 usleep(READ_SLEEP_TIME); 258 } 259 break; 260 case HOST_ACM_ASYNC_WRITE: 261 UsbHostDdkTestAsyncWrite(param); 262 break; 263 default: 264 TestCmdLoopOther(cmdType, param); 265 break; 266 } 267 268 if (!asyncFlag) { 269 loopFlag = false; 270 } 271 } 272 return HDF_SUCCESS; 273} 274 275#ifdef __LITEOS_USB_HOST_DDK_TEST__ 276static void *SigHandle(void *arg) 277{ 278 (void)arg; 279 run = 0; 280 return NULL; 281} 282 283static int32_t GetCharThread(void *arg) 284{ 285 char str[STR_LEN] = {0}; 286 while (run) { 287 str[0] = (char)getchar(); 288 } 289 return 0; 290} 291#endif 292 293#define HDF_PROCESS_STACK_SIZE 100000 294static int32_t StartThreadGetChar() 295{ 296#ifdef __LITEOS_USB_HOST_DDK_TEST__ 297 int32_t ret; 298 struct OsalThreadParam threadCfg; 299 memset_s(&threadCfg, sizeof(threadCfg), 0, sizeof(threadCfg)); 300 threadCfg.name = "get char process"; 301 threadCfg.priority = OSAL_THREAD_PRI_DEFAULT; 302 threadCfg.stackSize = HDF_PROCESS_STACK_SIZE; 303 304 ret = OsalThreadCreate(&g_Getchar, (OsalThreadEntry)GetCharThread, NULL); 305 if (HDF_SUCCESS != ret) { 306 HDF_LOGE("%{public}s:%{public}d OsalThreadCreate failed, ret=%{public}d ", __func__, __LINE__, ret); 307 return HDF_ERR_DEVICE_BUSY; 308 } 309 310 ret = OsalThreadStart(&g_Getchar, &threadCfg); 311 if (HDF_SUCCESS != ret) { 312 HDF_LOGE("%{public}s:%{public}d OsalThreadStart failed, ret=%{public}d ", __func__, __LINE__, ret); 313 return HDF_ERR_DEVICE_BUSY; 314 } 315#endif 316 return 0; 317} 318 319int32_t main(int32_t argc, char *argv[]) 320{ 321 int32_t status; 322 int32_t cmdType; 323 char apiType[DATA_MAX_LEN]; 324 325 if ((argc < ARGV_CMD_TYPE) || (argc < PARAM_GET_CMD_LEN) || (argv[ARGV_CMD_TYPE] == NULL)) { 326 HDF_LOGE("%{public}s:%{public}d invalid parma, argc=%{public}d", __func__, __LINE__, argc); 327 return HDF_FAILURE; 328 } 329 330 if ((argc == PARAM_GET_CMD_LEN) && 331 ((!strcmp(argv[ARGV_CMD_TYPE], "-h")) || (!strcmp(argv[ARGV_CMD_TYPE], "--help")))) { 332 TestHelp(); 333 return HDF_SUCCESS; 334 } 335 run = 1; 336 337 StartThreadGetChar(); 338 status = TestParaseCommand(argc, argv[ARGV_CMD_TYPE], &cmdType, apiType); 339 if (status != HDF_SUCCESS) { 340 run = 0; 341 HDF_LOGE("%{public}s:%{public}d TestParaseCommand status=%{public}d err", __func__, __LINE__, status); 342 TestHelp(); 343 return status; 344 } 345 346 status = UsbHostDdkTestInit(apiType); 347 if (status != HDF_SUCCESS) { 348 run = 0; 349 HDF_LOGE("%{public}s:%{public}d UsbHostDdkTestInit status=%{public}d err", __func__, __LINE__, status); 350 return status; 351 } 352 353 if (UsbHostDdkTestOpen(cmdType) != HDF_SUCCESS) { 354 goto OUT; 355 } 356#ifdef __LITEOS_USB_HOST_DDK_TEST__ 357 (void)signal(SIGINT, SigHandle); 358#endif 359 status = TestCmdLoop(cmdType, argv[ARGV_CMD_PARAM]); 360 if (status == HDF_DEV_ERR_NO_DEVICE_SERVICE) { 361 goto OUT; 362 } 363 364 if ((cmdType != HOST_ACM_ADD_INTERFACE) && (cmdType != HOST_ACM_REMOVE_INTERFACE)) { 365 if (UsbHostDdkTestClose(cmdType) != HDF_SUCCESS) { 366 goto OUT; 367 } 368 } 369 370OUT: 371 run = 0; 372 TestExit(); 373 return HDF_SUCCESS; 374}