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