• 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         fdsan_close_with_tag(g_fd, fdsan_create_owner_tag(FDSAN_OWNER_TYPE_FILE, LOG_DOMAIN));
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     fdsan_exchange_owner_tag(g_fd, 0, fdsan_create_owner_tag(FDSAN_OWNER_TYPE_FILE, LOG_DOMAIN));
93 
94     return g_fd;
95 }
96 
ClaimInterface(unsigned int iface)97 static int32_t ClaimInterface(unsigned int iface)
98 {
99     if (g_fd < 0 || iface == 0) {
100         HDF_LOGE("%{public}s: parameter error", __func__);
101         return -1;
102     }
103 
104     int32_t ret = ioctl(g_fd, USBDEVFS_CLAIMINTERFACE, &iface);
105     if (ret < 0) {
106         HDF_LOGE("%{public}s: sprintf_s path failed claim failed: iface = %{public}u errno = %{public}d %{public}s",
107             __func__, iface, errno, strerror(errno));
108         return HDF_FAILURE;
109     }
110     HDF_LOGI("%{public}s: claim success: iface = %{public}u", __func__, 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     if (urb == NULL) {
117         HDF_LOGE("%{public}s: urb is null", __func__);
118         return;
119     }
120     urb->userContext = (void *)(urb);
121     urb->type = USB_ADAPTER_URB_TYPE_BULK;
122     urb->streamId = 0;
123     urb->endPoint = g_endNum;
124     if ((g_endNum >> ENDPOINT_IN_OFFSET) == 0) {
125         int32_t ret = memset_s(urb->buffer, len, 'c', len);
126         if (ret != EOK) {
127             HDF_LOGE("%{public}s: memset_s failed: ret = %{public}d", __func__, ret);
128         }
129     }
130 }
131 
SignalHandler(int32_t signo)132 static void SignalHandler(int32_t signo)
133 {
134     static uint32_t sigCnt = 0;
135     struct itimerval new_value, old_value;
136     switch (signo) {
137         case SIGALRM:
138             sigCnt++;
139             if (sigCnt * TEST_PRINT_TIME >= TEST_TIME) {
140                 g_speedFlag = 1;
141                 break;
142             }
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 
SendProcess(void * argurb)157 static int32_t SendProcess(void *argurb)
158 {
159     (void)argurb;
160     int32_t i;
161     while (!g_speedFlag) {
162         OsalSemWait(&sem, HDF_WAIT_FOREVER);
163         for (i = 0; i < TEST_CYCLE; i++) {
164             if (urb[i].inUse == 0) {
165                 urb[i].inUse = 1;
166                 urb[i].urb->userContext = (void *)(&urb[i]);
167                 break;
168             }
169         }
170 
171         if (i == TEST_CYCLE) {
172             i = TEST_CYCLE - 1;
173         }
174         g_sendUrb = urb[i].urb;
175         FillUrb(g_sendUrb, TEST_LENGTH);
176         int32_t ret = ioctl(g_fd, USBDEVFS_SUBMITURB, g_sendUrb);
177         if (ret < 0) {
178             HDF_LOGE("%{public}s: ret:%{public}d errno = %{public}d", __func__, ret, errno);
179             urb[i].inUse = 0;
180             continue;
181         }
182         g_send_count++;
183     }
184     return 0;
185 }
186 
ReapProcess(void * const argurb)187 static int32_t ReapProcess(void * const argurb)
188 {
189     (void)argurb;
190     struct UsbAdapterUrb *urbrecv = NULL;
191     struct itimerval new_value, old_value;
192     if (signal(SIGUSR1, SignalHandler) == SIG_ERR) {
193         HDF_LOGE("%{public}s: signal SIGUSR1 failed", __func__);
194         return HDF_ERR_IO;
195     }
196     g_tid = (pid_t)syscall(SYS_gettid);
197 
198     while (!g_speedFlag) {
199         int32_t r = ioctl(g_fd, USBDEVFS_REAPURB, &urbrecv);
200         if (r < 0) {
201             continue;
202         }
203         if (urbrecv == NULL) {
204             continue;
205         }
206         if (urbrecv->status == 0) {
207             if (g_byteTotal == 0) {
208                 new_value.it_value.tv_sec = TEST_PRINT_TIME;
209                 new_value.it_value.tv_usec = 0;
210                 new_value.it_interval.tv_sec = TEST_PRINT_TIME;
211                 new_value.it_interval.tv_usec = 0;
212                 setitimer(ITIMER_REAL, &new_value, &old_value);
213             }
214             g_recv_count++;
215             g_byteTotal += urbrecv->actualLength;
216         }
217         unsigned char *recvBuf = (unsigned char *)urbrecv->buffer;
218 
219         if (g_printData) {
220             for (int32_t i = 0; i < urbrecv->actualLength; i++) {
221                 HDF_LOGI("%{public}s: recvbuf %{public}c", __func__, recvBuf[i]);
222             }
223             fflush(stdout);
224         } else if (g_recv_count % 10000 == 0) {
225             HDF_LOGI("%{public}s: #", __func__);
226             fflush(stdout);
227         }
228 
229         struct UsbAdapterUrbs *urbs = urbrecv->userContext;
230         urbs->inUse = 0;
231         OsalSemPost(&sem);
232     }
233     g_exitOk = true;
234     return 0;
235 }
236 
FillUrbData(unsigned char endPoint)237 static int32_t FillUrbData(unsigned char endPoint)
238 {
239     int32_t i;
240     char *data = NULL;
241     for (i = 0; i < TEST_CYCLE; i++) {
242         urb[i].urb = calloc(1, sizeof(struct UsbAdapterUrb));
243         if (urb[i].urb == NULL) {
244             return -1;
245         }
246         urb[i].inUse = 0;
247         urb[i].urb->userContext = (void *)(&urb[i]);
248         urb[i].urb->type = USB_ADAPTER_URB_TYPE_BULK;
249         urb[i].urb->streamId = 0;
250         urb[i].urb->endPoint = endPoint;
251 
252         data = OsalMemCalloc(TEST_LENGTH); // AllocMemTest(TEST_LENGTH)
253         if (data == NULL) {
254             return -1;
255         }
256         (void)memset_s(data, TEST_LENGTH, 'c', TEST_LENGTH);
257         data[TEST_LENGTH - 1] = '\0';
258         urb[i].urb->buffer = (void *)data;
259         urb[i].urb->bufferLength = TEST_LENGTH;
260     }
261     return HDF_SUCCESS;
262 }
263 
BeginProcess(unsigned char endPoint)264 static int32_t BeginProcess(unsigned char endPoint)
265 {
266     int32_t ret;
267     struct timeval time;
268     int32_t transNum = 0;
269     int32_t i;
270 
271     if ((g_fd < 0) || (endPoint == 0)) {
272         HDF_LOGE("%{public}s: g_fd or endPoint is invalied", __func__);
273         return -1;
274     }
275 
276     ret = FillUrbData(endPoint);
277     if (ret != HDF_SUCCESS) {
278         HDF_LOGE("%{public}s: Fill urb data failed", __func__);
279         return ret;
280     }
281     gettimeofday(&time, NULL);
282     (void)signal(SIGINT, SignalHandler);
283     (void)signal(SIGALRM, SignalHandler);
284 
285     for (i = 0; i < TEST_CYCLE; i++) {
286         urb[i].inUse = 1;
287         urb[i].urbNum = transNum;
288         urb[i].urb->userContext = (void *)(&urb[i]);
289         g_sendUrb = urb[i].urb;
290         ret = ioctl(g_fd, USBDEVFS_SUBMITURB, g_sendUrb);
291         if (ret < 0) {
292             urb[i].inUse = 0;
293             continue;
294         }
295         g_send_count++;
296     }
297 
298     while (!g_speedFlag) {
299         OsalMSleep(10);
300     }
301 
302     kill(g_tid, SIGUSR1);
303     while (!g_exitOk) {
304         OsalMSleep(10);
305     }
306     for (i = 0; i < TEST_CYCLE; i++) {
307         munmap(urb[i].urb->buffer, TEST_LENGTH);
308         free(urb[i].urb);
309     }
310     return HDF_SUCCESS;
311 }
312 
ShowHelp(char * name)313 static void ShowHelp(char *name)
314 {
315     HDF_LOGI("%{public}s: usage:", __func__);
316     HDF_LOGI("%{public}s: name is %{public}s [<busNum> <devAddr>]  <g_ifaceNum> <endpoint> [<printdata>]",
317         __func__, name);
318 }
319 
FillParamData(int32_t argc,char * argv[])320 static void FillParamData(int32_t argc, char *argv[])
321 {
322     if (argc == TEST_SIX_TYPE) {
323         g_busNum = (unsigned int)strtoul(argv[TEST_ONE_TYPE], NULL, STRTOL_BASE);
324         g_devAddr = (unsigned int)strtoul(argv[TEST_TWO_TYPE], NULL, STRTOL_BASE); // 2 means get second char of argv
325         g_ifaceNum = (unsigned int)strtoul(argv[TEST_THREE_TYPE], NULL, STRTOL_BASE);  // 3 means get third char of argv
326         g_endNum = (unsigned char)strtoul(argv[TEST_FOUR_TYPE], NULL, STRTOL_BASE);   // 4 means get fourth char of argv
327         if ((g_endNum >> ENDPOINT_IN_OFFSET) != 0) {                // the offset value is 7
328             g_printData = (strncmp(argv[TEST_FIVE_TYPE], "printdata", TEST_ONE_TYPE)) ? false : true;
329         }
330     } else if (argc == TEST_FIVE_TYPE) {
331         g_busNum = (unsigned int)strtoul(argv[TEST_ONE_TYPE], NULL, STRTOL_BASE);
332         g_devAddr = (unsigned int)strtoul(argv[TEST_TWO_TYPE], NULL, STRTOL_BASE); // 2 means get second char of argv
333         g_ifaceNum = (unsigned int)strtoul(argv[TEST_THREE_TYPE], NULL, STRTOL_BASE);  // 3 means get third char of argv
334         g_endNum = (unsigned char)strtoul(argv[TEST_FOUR_TYPE], NULL, STRTOL_BASE);   // 4 means get fourth char of argv
335     } else if (argc == TEST_THREE_TYPE) {
336         g_ifaceNum = (unsigned int)strtoul(argv[TEST_ONE_TYPE], NULL, STRTOL_BASE);
337         g_endNum = (unsigned char)strtoul(argv[TEST_TWO_TYPE], NULL, STRTOL_BASE); // 2 means get second char of argv
338     } else {
339         HDF_LOGE("%{public}s: parameter error!", __func__);
340         ShowHelp(argv[TEST_ZERO_TYPE]);
341         return HDF_FAILURE;
342     }
343 }
344 
PrintErrorLog(int32_t ret)345 static void PrintErrorLog(int32_t ret)
346 {
347     if (ret != HDF_SUCCESS) {
348         HDF_LOGE("%{public}s: please check whether usb drv so is existing or not,like acm, ecm, if not, \
349             remove it and test again! ret=%{public}d", __func__, ret);
350     }
351 }
352 
main(int32_t argc,char * argv[])353 int32_t main(int32_t argc, char *argv[])
354 {
355     int32_t ret;
356     FillParamData(argc, argv[]);
357     OsalSemInit(&sem, 0);
358     g_fd = OpenDevice();
359     if (g_fd < 0) {
360         ret = -1;
361         PrintErrorLog(ret);
362     }
363 
364     ret = ClaimInterface(g_ifaceNum);
365     if (ret != HDF_SUCCESS) {
366         PrintErrorLog(ret);
367     }
368 
369     struct OsalThread urbReapProcess;
370     struct OsalThread urbSendProcess;
371     struct OsalThreadParam threadCfg;
372 
373     (void)memset_s(&threadCfg, sizeof(threadCfg), 0, sizeof(threadCfg));
374     threadCfg.name = "urb reap process";
375     threadCfg.priority = OSAL_THREAD_PRI_DEFAULT;
376     threadCfg.stackSize = URB_COMPLETE_PROCESS_STACK_SIZE;
377 
378     ret = OsalThreadCreate(&urbReapProcess, (OsalThreadEntry)ReapProcess, NULL);
379     if (ret != HDF_SUCCESS) {
380         HDF_LOGE("%{public}s: OsalThreadCreate failed, ret=%{public}d", __func__, ret);
381         PrintErrorLog(ret);
382     }
383 
384     ret = OsalThreadStart(&urbReapProcess, &threadCfg);
385     if (ret != HDF_SUCCESS) {
386         HDF_LOGE("%{public}s: OsalThreadStart failed, ret=%{public}d", __func__, ret);
387     }
388 
389     threadCfg.name = "urb send process";
390     threadCfg.priority = OSAL_THREAD_PRI_DEFAULT;
391     threadCfg.stackSize = URB_COMPLETE_PROCESS_STACK_SIZE;
392 
393     ret = OsalThreadCreate(&urbSendProcess, (OsalThreadEntry)SendProcess, NULL);
394     if (ret != HDF_SUCCESS) {
395         HDF_LOGE("%{public}s: OsalThreadCreate failed, ret=%{public}d", __func__, ret);
396         PrintErrorLog(ret);
397     }
398 
399     ret = OsalThreadStart(&urbSendProcess, &threadCfg);
400     if (ret != HDF_SUCCESS) {
401         HDF_LOGE("%{public}s: OsalThreadStart failed, ret=%{public}d", __func__, ret);
402     }
403 
404     ret = BeginProcess(g_endNum);
405     if (ret != HDF_SUCCESS) {
406         PrintErrorLog(ret);
407     }
408     CloseDevice();
409     return ret;
410 }
411