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