• 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 <stdio.h>
17 #include <stdlib.h>
18 #include <unistd.h>
19 #include <errno.h>
20 #include <string.h>
21 #include <dirent.h>
22 #include <sys/ioctl.h>
23 #include <sys/mman.h>
24 #include <fcntl.h>
25 #include <stdlib.h>
26 #include <sys/time.h>
27 #include <signal.h>
28 #include <sys/mman.h>
29 #include <osal_sem.h>
30 #include <osal_thread.h>
31 #include <errno.h>
32 #include <sys/syscall.h>
33 #include <time.h>
34 #include "usbhost_nosdk_speed.h"
35 #include "osal_time.h"
36 #include "osal_mem.h"
37 #include "securec.h"
38 
39 #define USB_DEV_FS_PATH "/dev/bus/usb"
40 #define URB_COMPLETE_PROCESS_STACK_SIZE 8196
41 
42 #define PATH_SIZE 24
43 #define TIME_SCALE 1024
44 #define RECV_COUNT_SIZE 10000
45 #define SLEEP_TIME 10
46 
47 #define TEST_LENGTH     512
48 #define TEST_CYCLE      30
49 #define TEST_TIME       0xffffffff
50 #define TEST_PRINT_TIME 2
51 #define TEST_PRINT_TIME_UINT    1000
52 #define ENDPOINT_IN_OFFSET 7
53 
54 static pid_t tid;
55 static int exitOk = false;
56 static int g_speedFlag = 0;
57 static unsigned int g_busNum = 1;
58 static unsigned int g_devAddr = 2;
59 static int fd;
60 static struct OsalSem sem;
61 static uint64_t g_send_count = 0;
62 static uint64_t g_recv_count = 0;
63 static uint64_t g_byteTotal = 0;
64 static struct UsbAdapterUrbs urb[TEST_CYCLE];
65 static struct UsbAdapterUrb *sendUrb = NULL;
66 static bool g_printData = false;
67 static unsigned int ifaceNum;
68 static unsigned char endNum;
69 
CloseDevice(void)70 static void CloseDevice(void)
71 {
72     if (fd > 0) {
73         close(fd);
74         fd = 0;
75     }
76     return;
77 }
78 
OpenDevice(void)79 static int OpenDevice(void)
80 {
81     char path[PATH_SIZE];
82     int ret;
83 
84     ret = snprintf_s(path, PATH_SIZE, sizeof(path) - 1, USB_DEV_FS_PATH "/%03u/%03u", g_busNum, g_devAddr);
85     if (ret < 0) {
86         printf("path error\n");
87         return ret;
88     }
89 
90     printf("open: %s\n", path);
91     fd = open(path, O_RDWR);
92     if (fd < 0) {
93         printf("open device failed! errno=%2d(%s)\n", errno, strerror(errno));
94     }
95 
96     return fd;
97 }
98 
ClaimInterface(unsigned int iface)99 static int ClaimInterface(unsigned int iface)
100 {
101     if (fd < 0 || iface < 0) {
102         printf("parameter error\n");
103         return -1;
104     }
105 
106     int ret = ioctl(fd, USBDEVFS_CLAIMINTERFACE, &iface);
107     if (ret < 0) {
108         printf("claim failed: iface=%u, errno=%2d(%s)\n", iface, errno, strerror(errno));
109         return HDF_FAILURE;
110     }
111     printf("claim success: iface=%u\n", iface);
112     return HDF_SUCCESS;
113 }
114 
FillUrb(struct UsbAdapterUrb * urb,int len)115 static void FillUrb(struct UsbAdapterUrb *urb, int len)
116 {
117     if (urb == NULL) {
118         urb = OsalMemCalloc(sizeof(*urb));
119         urb->userContext = (void *)(urb);
120         urb->type = USB_ADAPTER_URB_TYPE_BULK;
121         urb->streamId = 0;
122         urb->endPoint = endNum;
123     }
124     if ((endNum >> ENDPOINT_IN_OFFSET) == 0) {
125         memset_s(urb->buffer, len, 'c', len);
126     }
127 }
128 
SignalHandler(int signo)129 void SignalHandler(int signo)
130 {
131     static uint32_t sigCnt = 0;
132     struct itimerval new_value, old_value;
133     double speed = 0;
134     switch (signo) {
135         case SIGALRM:
136             sigCnt++;
137             if (sigCnt * TEST_PRINT_TIME >= TEST_TIME) {
138                 g_speedFlag = 1;
139                 break;
140             }
141             speed = (g_byteTotal * 1.0) / (sigCnt * TEST_PRINT_TIME  * TIME_SCALE * TIME_SCALE);
142             printf("\nSpeed:%f MB/s\n", speed);
143             new_value.it_value.tv_sec = TEST_PRINT_TIME;
144             new_value.it_value.tv_usec = 0;
145             new_value.it_interval.tv_sec = TEST_PRINT_TIME;
146             new_value.it_interval.tv_usec = 0;
147             setitimer(ITIMER_REAL, &new_value, &old_value);
148             break;
149         case SIGINT:
150             g_speedFlag = 1;
151             break;
152         default:
153             break;
154     }
155 }
156 
SubmitRequest(uint32_t transNum)157 void SubmitRequest(uint32_t transNum)
158 {
159     int i;
160     int ret;
161     for (i = 0; i < TEST_CYCLE; i++) {
162         urb[i].inUse = 1;
163         urb[i].urbNum = transNum;
164         urb[i].urb->userContext = (void*)(&urb[i]);
165         sendUrb = urb[i].urb;
166         ret = ioctl(fd, USBDEVFS_SUBMITURB, sendUrb);
167         if (ret < 0) {
168             printf("SubmitBulkRequest: ret:%d errno=%d\n", ret, errno);
169             urb[i].inUse = 0;
170             continue;
171         }
172         g_send_count++;
173     }
174 }
175 
SendProcess(void * argurb)176 static int SendProcess(void *argurb)
177 {
178     int i;
179     int ret;
180     while (!g_speedFlag) {
181         OsalSemWait(&sem, HDF_WAIT_FOREVER);
182         for (i = 0; i < TEST_CYCLE; i++) {
183             if (urb[i].inUse == 0) {
184                 urb[i].inUse = 1;
185                 urb[i].urb->userContext = (void*)(&urb[i]);
186                 break;
187             }
188         }
189 
190         if (i==TEST_CYCLE) {
191             i=TEST_CYCLE-1;
192         }
193         sendUrb = urb[i].urb;
194         FillUrb(sendUrb, TEST_LENGTH);
195         ret = ioctl(fd, USBDEVFS_SUBMITURB, sendUrb);
196         if (ret < 0) {
197             printf("SubmitBulkRequest: ret:%d errno=%d\n", ret, errno);
198             urb[i].inUse = 0;
199             continue;
200         }
201         g_send_count++;
202     }
203     return 0;
204 }
205 
ReapProcess(void * argurb)206 static int ReapProcess(void *argurb)
207 {
208     int ret;
209     struct UsbAdapterUrb *urbrecv = NULL;
210     struct itimerval new_value, old_value;
211     if (signal(SIGUSR1, SignalHandler) == SIG_ERR) {
212         printf("signal SIGUSR1 failed");
213         return HDF_ERR_IO;
214     }
215     tid = syscall(SYS_gettid);
216 
217     while (!g_speedFlag) {
218         ret = ioctl(fd, USBDEVFS_REAPURB, &urbrecv);
219         if (ret < 0) {
220             continue;
221         }
222         if (urbrecv == NULL) {
223             continue;
224         }
225         if (urbrecv->status == 0) {
226             if (g_byteTotal == 0) {
227                 new_value.it_value.tv_sec = TEST_PRINT_TIME;
228                 new_value.it_value.tv_usec = 0;
229                 new_value.it_interval.tv_sec = TEST_PRINT_TIME;
230                 new_value.it_interval.tv_usec = 0;
231                 setitimer(ITIMER_REAL, &new_value, &old_value);
232             }
233             g_recv_count++;
234             g_byteTotal += urbrecv->actualLength;
235         }
236         unsigned char *recvBuf = (unsigned char*)urbrecv->buffer;
237 
238         if (g_printData == true) {
239             for (int i = 0; i < urbrecv->actualLength; i++)
240                 printf("%c", recvBuf[i]);
241             fflush(stdout);
242         } else if (g_recv_count % RECV_COUNT_SIZE == 0) {
243             printf("#");
244             fflush(stdout);
245         }
246 
247         struct UsbAdapterUrbs *urbs = urbrecv->userContext;
248         urbs->inUse = 0;
249         OsalSemPost(&sem);
250     }
251     exitOk = true;
252     return 0;
253 }
254 
BeginProcess(uint8_t endPoint)255 static int BeginProcess(uint8_t endPoint)
256 {
257     char *data = NULL;
258     struct timeval time;
259     int transNum = 0;
260     int i = 0;
261 
262     if (fd < 0 || endPoint <= 0) {
263         printf("parameter error\n");
264         return -1;
265     }
266     for (i = 0; i < TEST_CYCLE; i++) {
267         urb[i].urb = calloc(1, sizeof(struct UsbAdapterUrb));
268         if (urb[i].urb == NULL) {
269             return -1;
270         }
271         urb[i].inUse = 0;
272         urb[i].urb->userContext = (void *)(&urb[i]);
273         urb[i].urb->type = USB_ADAPTER_URB_TYPE_BULK;
274         urb[i].urb->streamId = 0;
275         urb[i].urb->endPoint = endPoint;
276 
277         data = OsalMemCalloc(TEST_LENGTH);
278         if (data == NULL) {
279             return -1;
280         }
281         memset_s(data, TEST_LENGTH, 'c', TEST_LENGTH);
282         data[TEST_LENGTH - 1] = '\0';
283         urb[i].urb->buffer = (void *)data;
284         urb[i].urb->bufferLength = TEST_LENGTH;
285     }
286 
287     gettimeofday(&time, NULL);
288     if (signal(SIGINT, SignalHandler) == SIG_ERR) {
289         printf("signal SIGINT failed");
290         return HDF_ERR_IO;
291     }
292     signal(SIGALRM, SignalHandler);
293 
294     printf("test NO SDK endpoint:%d\n", endPoint);
295     printf("Start: sec%ld usec%ld\n", time.tv_sec, time.tv_usec);
296 
297     SubmitRequest(transNum);
298 
299     while (!g_speedFlag) {
300         OsalMSleep(SLEEP_TIME);
301     }
302 
303     kill(tid, SIGUSR1);
304     while (exitOk != true) {
305         OsalMSleep(SLEEP_TIME);
306     }
307     for (i = 0; i < TEST_CYCLE; i++) {
308         munmap(urb[i].urb->buffer, TEST_LENGTH);
309         free(urb[i].urb);
310     }
311     return HDF_SUCCESS;
312 }
313 
ShowHelp(char * name)314 static void ShowHelp(char *name)
315 {
316     printf(">> usage:\n");
317     printf(">>      %s [<busNum> <devAddr>]  <ifaceNum> <endpoint> [<printdata>]\n", name);
318     printf("\n");
319 }
320 
OptionParse(int argc,char * argv[])321 static bool OptionParse(int argc, char *argv[])
322 {
323     if (argc == 6) {
324         g_busNum = atoi(argv[1]);
325         g_devAddr = atoi(argv[2]);
326         ifaceNum = atoi(argv[3]);
327         endNum = atoi(argv[4]);
328         if ((endNum >> ENDPOINT_IN_OFFSET) != 0) {
329             g_printData = (strncmp(argv[5], "printdata", 1))?false:true;
330         }
331     } else if (argc == 5) {
332         g_busNum = atoi(argv[1]);
333         g_devAddr = atoi(argv[2]);
334         ifaceNum = atoi(argv[3]);
335         endNum = atoi(argv[4]);
336     } else if (argc == 3) {
337         ifaceNum = atoi(argv[1]);
338         endNum = atoi(argv[2]);
339     } else {
340         printf("Error: parameter error!\n\n");
341         ShowHelp(argv[0]);
342         return false;
343     }
344     return true;
345 }
346 
OsalThreadOperate(void)347 static int OsalThreadOperate(void)
348 {
349     int ret;
350     struct OsalThread urbReapProcess;
351     struct OsalThread urbSendProcess;
352     struct OsalThreadParam threadCfg;
353 
354     (void)memset_s(&threadCfg, sizeof(threadCfg), 0, sizeof(threadCfg));
355     threadCfg.name = "urb reap process";
356     threadCfg.priority = OSAL_THREAD_PRI_DEFAULT;
357     threadCfg.stackSize = URB_COMPLETE_PROCESS_STACK_SIZE;
358 
359     ret = OsalThreadCreate(&urbReapProcess, (OsalThreadEntry)ReapProcess, NULL);
360     if (ret != HDF_SUCCESS) {
361         printf("OsalThreadCreate fail, ret=%d\n", ret);
362         return HDF_FAILURE;
363     }
364 
365     ret = OsalThreadStart(&urbReapProcess, &threadCfg);
366     if (ret != HDF_SUCCESS) {
367         printf("OsalThreadStart fail, ret=%d\n", ret);
368     }
369 
370     threadCfg.name = "urb send process";
371     threadCfg.priority = OSAL_THREAD_PRI_DEFAULT;
372     threadCfg.stackSize = URB_COMPLETE_PROCESS_STACK_SIZE;
373 
374     ret = OsalThreadCreate(&urbSendProcess, (OsalThreadEntry)SendProcess, NULL);
375     if (ret != HDF_SUCCESS) {
376         printf("OsalThreadCreate fail, ret=%d\n", ret);
377         return HDF_FAILURE;
378     }
379 
380     ret = OsalThreadStart(&urbSendProcess, &threadCfg);
381     if (ret != HDF_SUCCESS) {
382         printf("OsalThreadStart fail, ret=%d\n", ret);
383     }
384 
385     ret = BeginProcess(endNum);
386     if (ret != HDF_SUCCESS) {
387         return HDF_FAILURE;
388     }
389     return HDF_SUCCESS;
390 }
391 
main(int argc,char * argv[])392 int main(int argc, char *argv[])
393 {
394     int ret;
395     if (!OptionParse(argc, argv)) {
396         ret = -1;
397         goto ERR;
398     }
399     OsalSemInit(&sem, 0);
400 
401     fd = OpenDevice();
402     if (fd < 0) {
403         ret = -1;
404         goto ERR;
405     }
406 
407     ret = ClaimInterface(ifaceNum);
408     if (ret != HDF_SUCCESS) {
409         goto ERR;
410     }
411 
412     ret = OsalThreadOperate();
413     if (ret != HDF_SUCCESS) {
414         goto ERR;
415     }
416 ERR:
417     if (ret != HDF_SUCCESS) {
418         printf("please check whether usb drv so is existing or not,like acm, ecm, if not, remove it and test again!\n");
419     }
420     CloseDevice();
421     return ret;
422 }
423 
424