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