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