• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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 "hdf_io_service_if.h"
17 #include <stdio.h>
18 #include <unistd.h>
19 
20 #include <sys/time.h>
21 
22 #include "hdf_log.h"
23 #include "osal_mem.h"
24 #include "osal_mutex.h"
25 #include "securec.h"
26 #include "signal.h"
27 
28 #define TEST_WRITE         true
29 #define TEST_READ          false
30 #define SERVER_NAME_SDKAPI "usb_sdkapispeed_service"
31 #define SERVER_NAME_RAWAPI "usb_rawapispeed_service"
32 #define SERVER_NAME_NOSDK  "usb_nosdkspeed_service"
33 #define STRTOL_BASE  10
34 
35 enum UsbSerialCmd {
36     USB_SERIAL_OPEN = 0,
37     USB_SERIAL_CLOSE,
38     USB_SERIAL_SPEED,
39 };
40 struct UsbSpeedTest {
41     int32_t busNum;
42     int32_t devAddr;
43     int32_t ifaceNum;
44     int32_t writeOrRead;
45     bool printData;
46     int32_t paramNum;
47 };
48 enum speedServer {
49     SDKAPI_SERVER = 0,
50     RAWAPI_SERVER,
51     NOSDK_SERVER,
52 };
53 
54 static struct HdfIoService *g_service = NULL;
55 static struct HdfSBuf *g_data = NULL;
56 static struct HdfSBuf *g_reply = NULL;
57 static struct OsalMutex g_lock;
58 static enum speedServer g_spdServer = SDKAPI_SERVER;
59 
60 static sigset_t g_mask;
61 pid_t g_stopHandlerTid;
62 
SpeedTest(struct UsbSpeedTest test)63 static void SpeedTest(struct UsbSpeedTest test)
64 {
65     OsalMutexLock(&g_lock);
66     HdfSbufFlush(g_data);
67     bool bufok = HdfSbufWriteBuffer(g_data, (const void *)&test, sizeof(test));
68     if (!bufok) {
69         printf("HdfSbufWriteBuffer err");
70         goto RET;
71     }
72     int32_t status = g_service->dispatcher->Dispatch(&g_service->object, USB_SERIAL_SPEED, g_data, g_reply);
73     if (status < 0) {
74         printf("%s: Dispatch USB_SERIAL_SPEED failed status = %d\n", __func__, status);
75     }
76 RET:
77     OsalMutexUnlock(&g_lock);
78 }
79 
SpeedInit(void)80 static void SpeedInit(void)
81 {
82     int32_t status;
83 
84     switch (g_spdServer) {
85         case SDKAPI_SERVER:
86             g_service = HdfIoServiceBind(SERVER_NAME_SDKAPI);
87             break;
88         case RAWAPI_SERVER:
89             g_service = HdfIoServiceBind(SERVER_NAME_RAWAPI);
90             break;
91         case NOSDK_SERVER:
92             g_service = HdfIoServiceBind(SERVER_NAME_NOSDK);
93             break;
94         default:
95             break;
96     }
97     if (g_service == NULL || g_service->dispatcher == NULL || g_service->dispatcher->Dispatch == NULL) {
98         printf("%s: GetService g_spdServer=%d err \n", __func__, g_spdServer);
99         return;
100     }
101 
102     // usb info max size is 2000
103     uint32_t usbInfoMaxSize = 2000;
104     g_data = HdfSbufObtain(usbInfoMaxSize);
105     g_reply = HdfSbufObtain(usbInfoMaxSize);
106     if (g_data == NULL || g_reply == NULL) {
107         printf("%s: HdfSbufTypedObtain err", __func__);
108         return;
109     }
110 
111     status = g_service->dispatcher->Dispatch(&g_service->object, USB_SERIAL_OPEN, g_data, g_reply);
112     if (status) {
113         printf("%s: Dispatch USB_SERIAL_OPEN err status = %d\n", __func__, status);
114         return;
115     }
116 
117     if (OsalMutexInit(&g_lock) != HDF_SUCCESS) {
118         printf("%s: init lock fail!", __func__);
119         return;
120     }
121 }
122 
SpeedExit(void)123 static void SpeedExit(void)
124 {
125     if (g_service == NULL) {
126         printf("%s: g_service is null", __func__);
127         return;
128     }
129     int32_t status = g_service->dispatcher->Dispatch(&g_service->object, USB_SERIAL_CLOSE, g_data, g_reply);
130     if (status) {
131         printf("%s: Dispatch USB_SERIAL_CLOSE err status = %d\n", __func__, status);
132     }
133 
134     HdfIoServiceRecycle(g_service);
135     g_service = NULL;
136     HdfSbufRecycle(g_data);
137     HdfSbufRecycle(g_reply);
138 }
139 
ShowHelp(const char * name)140 static void ShowHelp(const char *name)
141 {
142     printf(">> usage:\n");
143     printf(">> %s <-SDK>/<-RAW>/<-NOSDK> [<busNum> <devAddr>]  <ifaceNum> <w>/<r>/<endpoint> [printdata]> \n", name);
144     printf("\n");
145 }
146 
StopHandler(void)147 static void *StopHandler(void)
148 {
149     int32_t signo;
150     g_stopHandlerTid = getpid();
151 
152     while (true) {
153         int32_t err = sigwait(&g_mask, &signo);
154         if (err != 0) {
155             printf("Sigwait failed: %d\n", err);
156         }
157 
158         if ((signo == SIGINT) || (signo == SIGQUIT)) {
159             printf("normal exit\n");
160             SpeedExit();
161             return 0;
162         } else {
163             printf("Unexpected signal %d\n", signo);
164         }
165     }
166 }
167 
checkServer(const char * input)168 static enum speedServer checkServer(const char *input)
169 {
170     char middle[10] = {0};
171     if (input == NULL) {
172         HDF_LOGE("%s:%d input is NULL", __func__, __LINE__);
173         return SDKAPI_SERVER;
174     }
175 
176     int32_t ret = strncpy_s(middle, sizeof(middle), input, (uint32_t)strlen(input));
177     if (ret != EOK) {
178         HDF_LOGE("%s:%d strncpy_s failed", __func__, __LINE__);
179         return SDKAPI_SERVER;
180     }
181 
182     if (strcmp(middle, "-SDK") == 0) {
183         return SDKAPI_SERVER;
184     }
185     if (strcmp(middle, "-RAW") == 0) {
186         return RAWAPI_SERVER;
187     }
188     if (strcmp(middle, "-NOSDK") == 0) {
189         return NOSDK_SERVER;
190     }
191     return SDKAPI_SERVER;
192 }
193 
GetWriteOrReadFlag(const char * buffer)194 static int32_t GetWriteOrReadFlag(const char *buffer)
195 {
196     int32_t writeOrRead;
197 
198     if (!strncmp(buffer, "r", 1)) {
199         writeOrRead = TEST_READ;
200     } else if (!strncmp(buffer, "w", 1)) {
201         writeOrRead = TEST_WRITE;
202     } else {
203         writeOrRead = (int32_t)strtol(buffer, NULL, STRTOL_BASE);
204     }
205 
206     return writeOrRead;
207 }
208 
CheckParam(int32_t argc,const char * argv[],struct UsbSpeedTest * speedTest)209 static int32_t CheckParam(int32_t argc, const char *argv[], struct UsbSpeedTest *speedTest)
210 {
211     int32_t ret = HDF_SUCCESS;
212     bool printData = false;
213 
214     if ((argv == NULL) || (speedTest == NULL) || (argc <= 0)) {
215         return HDF_ERR_INVALID_PARAM;
216     }
217     switch (argc) {
218         case 7:                                  // 7 is number of arguments supplied to the main function
219         case 6:                                  // 6 is number of arguments supplied to the main function
220             g_spdServer = checkServer(argv[1]);  // 1 is argv second element
221             speedTest->busNum = (int32_t)strtol(argv[2], NULL, STRTOL_BASE);   // 2 is argv third element
222             speedTest->devAddr = (int32_t)strtol(argv[3], NULL, STRTOL_BASE);  // 3 is argv fourth element
223             speedTest->ifaceNum = (int32_t)strtol(argv[4], NULL, STRTOL_BASE); // 4 is argv fifth element
224             speedTest->writeOrRead = GetWriteOrReadFlag(argv[5]); // 5 is argv sixth element
225             // 7 is number of arguments supplied to the main function
226             if ((argc == 7) && (speedTest->writeOrRead == TEST_READ)) {
227                 printData = (strncmp(argv[6], "printdata", 1)) ? false : true; // 6 is argv seventh element
228             }
229             break;
230         case 4:                                 // 4 number of arguments supplied to the main function
231             g_spdServer = checkServer(argv[1]); // 1 is argv second element
232             speedTest->busNum = 1;
233             speedTest->devAddr = 2;                               // 2 is device address
234             speedTest->ifaceNum = (int32_t)strtol(argv[2], NULL, STRTOL_BASE);         // 2 is argv third element
235             speedTest->writeOrRead = GetWriteOrReadFlag(argv[3]); // 3 is argv fourth element
236             break;
237         default:
238             printf("Error: parameter error!\n");
239             ShowHelp(argv[0]); // 0 is argv first element
240             ret = HDF_FAILURE;
241             break;
242     }
243     if (ret == HDF_SUCCESS) {
244         speedTest->printData = printData;
245         speedTest->paramNum = argc - 1;
246     }
247 
248     return ret;
249 }
250 
main(int32_t argc,char * argv[])251 int32_t main(int32_t argc, char *argv[])
252 {
253     int32_t ret;
254     struct UsbSpeedTest test;
255 
256     ret = CheckParam(argc, argv, &test);
257     if (ret != HDF_SUCCESS) {
258         goto END;
259     }
260 
261     pthread_t threads;
262     sigemptyset(&g_mask);
263     sigaddset(&g_mask, SIGINT);
264     sigaddset(&g_mask, SIGQUIT);
265     if (pthread_sigmask(SIG_BLOCK, &g_mask, NULL) != 0) {
266         printf("SIG_BLOCK error\n");
267         ret = HDF_FAILURE;
268         goto END;
269     }
270     if (pthread_create(&threads, NULL, StopHandler, NULL) != 0) {
271         printf("Could not create core thread\n");
272         ret = HDF_FAILURE;
273         goto END;
274     }
275 
276     SpeedInit();
277     SpeedTest(test);
278     kill(g_stopHandlerTid, SIGINT);
279     pthread_join(threads, NULL);
280 END:
281     return ret;
282 }
283