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
31 int32_t run;
32 
33 #ifdef __LITEOS_USB_HOST_DDK_TEST__
34 static struct OsalThread g_Getchar;
35 #endif
36 
TestHelp(void)37 static 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 
TestParaseCommand(int32_t paramNum,const char * cmdParam,int32_t * cmdType,char * apiType)67 static 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 
TestCmdLoopOther(int32_t cmdType,const char * param)186 static 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 
TestCmdLoop(int32_t cmdType,const char * param)225 static 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__
SigHandle(void * arg)276 static void *SigHandle(void *arg)
277 {
278     (void)arg;
279     run = 0;
280     return NULL;
281 }
282 
GetCharThread(void * arg)283 static 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
StartThreadGetChar()294 static 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 
main(int32_t argc,char * argv[])319 int32_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 
370 OUT:
371     run = 0;
372     TestExit();
373     return HDF_SUCCESS;
374 }