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 "usbhost_sdkraw_speed.h"
17 
18 #include <dirent.h>
19 #include <errno.h>
20 #include <fcntl.h>
21 #include <inttypes.h>
22 #include <osal_thread.h>
23 #include <signal.h>
24 #include <stdio.h>
25 #include <stdlib.h>
26 #include <string.h>
27 #include <sys/ioctl.h>
28 #include <sys/mman.h>
29 #include <sys/time.h>
30 #include <unistd.h>
31 
32 #include "hdf_base.h"
33 #include "hdf_log.h"
34 #include "hdf_usb_pnp_manage.h"
35 #include "osal_mem.h"
36 #include "osal_time.h"
37 #include "securec.h"
38 #include "usb_ddk_interface.h"
39 
40 #define HDF_LOG_TAG USB_HOST_ACM_RAW_API
41 
42 #define USB_CTRL_REQ_SIZE             64
43 #define USB_IO_THREAD_STACK_SIZE      8192
44 #define USB_RAW_IO_SLEEP_MS_TIME      500
45 #define USB_RAW_IO_STOP_WAIT_MAX_TIME 2
46 #define STRTOL_BASE  10
47 
48 static struct AcmDevice *g_acm = NULL;
49 static bool g_stopIoThreadFlag = false;
50 static unsigned int g_speedFlag = 0;
51 static uint64_t g_send_count = 0;
52 static uint64_t g_recv_count = 0;
53 static uint64_t g_byteTotal = 0;
54 static bool g_writeOrRead = TEST_WRITE;
55 static bool g_printData = false;
56 static struct OsalSem sem;
57 
58 static void AcmTestBulkCallback(const void *requestArg);
59 static int32_t SerialBegin(struct AcmDevice *acm);
60 
UsbIoThread(void * data)61 static int32_t UsbIoThread(void *data)
62 {
63     int32_t ret;
64     struct AcmDevice *acm = (struct AcmDevice *)data;
65 
66     for (;;) {
67         if (acm == NULL) {
68             HDF_LOGE("%{public}s:%{public}d acm is NULL", __func__, __LINE__);
69             OsalMSleep(USB_RAW_IO_SLEEP_MS_TIME);
70             continue;
71         }
72 
73         if (acm->devHandle == NULL) {
74             HDF_LOGE("%{public}s:%{public}d acm->devHandle is NULL!", __func__, __LINE__);
75             OsalMSleep(USB_RAW_IO_SLEEP_MS_TIME);
76             continue;
77         }
78 
79         ret = UsbRawHandleRequests(acm->devHandle);
80         if (ret < 0) {
81             HDF_LOGE("%{public}s:%{public}d UsbRawHandleRequests failed, ret=%{public}d ", __func__, __LINE__, ret);
82             if (ret == USB_REQUEST_NO_DEVICE) {
83                 HDF_LOGE("%{public}s:%{public}d, ret=%{public}d", __func__, __LINE__, ret);
84                 OsalMSleep(USB_RAW_IO_SLEEP_MS_TIME);
85             }
86         }
87 
88         if (g_stopIoThreadFlag) {
89             HDF_LOGD("%{public}s:%{public}d", __func__, __LINE__);
90             g_stopIoThreadFlag = false;
91             break;
92         }
93     }
94 
95     HDF_LOGE("%{public}s:%{public}d exit", __func__, __LINE__);
96 
97     return HDF_SUCCESS;
98 }
99 
UsbIoSendThread(void * data)100 static int32_t UsbIoSendThread(void *data)
101 {
102     struct AcmDevice *acm = (struct AcmDevice *)data;
103 
104     for (;;) {
105         OsalSemWait(&sem, HDF_WAIT_FOREVER);
106         if (!g_speedFlag) {
107             if (SerialBegin(acm) != HDF_SUCCESS) {
108                 HDF_LOGW("%{public}s:%{public}d SerialBegin error!", __func__, __LINE__);
109             }
110             g_send_count++;
111         }
112     }
113 }
114 
UsbStartIo(struct AcmDevice * const acm)115 static int32_t UsbStartIo(struct AcmDevice * const acm)
116 {
117     struct OsalThreadParam threadCfg;
118     int32_t ret;
119 
120     HDF_LOGI("%{public}s start", __func__);
121 
122     /* create Io thread */
123     (void)memset_s(&threadCfg, sizeof(threadCfg), 0, sizeof(threadCfg));
124     threadCfg.name = "usb io thread";
125     threadCfg.priority = OSAL_THREAD_PRI_DEFAULT;
126     threadCfg.stackSize = USB_IO_THREAD_STACK_SIZE;
127 
128     ret = OsalThreadCreate(&acm->ioThread, (OsalThreadEntry)UsbIoThread, (void *)acm);
129     if (ret != HDF_SUCCESS) {
130         HDF_LOGE("%{public}s:%{public}d OsalThreadCreate failed, ret=%{public}d ", __func__, __LINE__, ret);
131         return ret;
132     }
133 
134     ret = OsalThreadStart(&acm->ioThread, &threadCfg);
135     if (ret != HDF_SUCCESS) {
136         HDF_LOGE("%{public}s:%{public}d OsalThreadStart failed, ret=%{public}d ", __func__, __LINE__, ret);
137         return ret;
138     }
139 
140     (void)memset_s(&threadCfg, sizeof(threadCfg), 0, sizeof(threadCfg));
141     threadCfg.name = "usb io send thread";
142     threadCfg.priority = OSAL_THREAD_PRI_DEFAULT;
143     threadCfg.stackSize = USB_IO_THREAD_STACK_SIZE;
144     ret = OsalThreadCreate(&acm->ioSendThread, (OsalThreadEntry)UsbIoSendThread, (void *)acm);
145     if (ret != HDF_SUCCESS) {
146         HDF_LOGE("%{public}s:%{public}d OsalThreadCreate failed, ret=%{public}d ", __func__, __LINE__, ret);
147         return ret;
148     }
149 
150     ret = OsalThreadStart(&acm->ioSendThread, &threadCfg);
151     if (ret != HDF_SUCCESS) {
152         HDF_LOGE("%{public}s:%{public}d OsalThreadStart failed, ret=%{public}d ", __func__, __LINE__, ret);
153         return ret;
154     }
155 
156     return HDF_SUCCESS;
157 }
158 
UsbStopIo(struct AcmDevice * const acm)159 static int32_t UsbStopIo(struct AcmDevice * const acm)
160 {
161     int32_t ret;
162     int32_t i = 0;
163 
164     HDF_LOGD("%{public}s:%{public}d", __func__, __LINE__);
165     if (!g_stopIoThreadFlag) {
166         HDF_LOGD("%{public}s:%{public}d", __func__, __LINE__);
167         g_stopIoThreadFlag = true;
168     }
169     HDF_LOGD("%{public}s:%{public}d", __func__, __LINE__);
170 
171     while (g_stopIoThreadFlag) {
172         i++;
173         OsalMSleep(USB_RAW_IO_SLEEP_MS_TIME);
174         if (i > USB_RAW_IO_STOP_WAIT_MAX_TIME) {
175             HDF_LOGD("%{public}s:%{public}d", __func__, __LINE__);
176             g_stopIoThreadFlag = false;
177         }
178     }
179     HDF_LOGD("%{public}s:%{public}d", __func__, __LINE__);
180 
181     ret = OsalThreadDestroy(&acm->ioThread);
182     if (ret != HDF_SUCCESS) {
183         HDF_LOGE("%{public}s:%{public}d OsalThreadDestroy failed, ret=%{public}d ", __func__, __LINE__, ret);
184         return ret;
185     }
186 
187     ret = OsalThreadDestroy(&acm->ioSendThread);
188     if (ret != HDF_SUCCESS) {
189         HDF_LOGE("%{public}s:%{public}d OsalThreadDestroy failed, ret=%{public}d ", __func__, __LINE__, ret);
190         return ret;
191     }
192 
193     return HDF_SUCCESS;
194 }
195 
UsbGetConfigDescriptor(UsbRawHandle * const devHandle,struct UsbRawConfigDescriptor ** const config)196 static int32_t UsbGetConfigDescriptor(UsbRawHandle * const devHandle, struct UsbRawConfigDescriptor ** const config)
197 {
198     UsbRawDevice *dev = NULL;
199     int32_t activeConfig;
200     int32_t ret;
201 
202     if (devHandle == NULL) {
203         HDF_LOGE("%{public}s devHandle is NULL", __func__);
204         return HDF_ERR_INVALID_PARAM;
205     }
206 
207     ret = UsbRawGetConfiguration(devHandle, &activeConfig);
208     if (ret != HDF_SUCCESS) {
209         HDF_LOGE("%{public}s:%{public}d UsbRawGetConfiguration failed, ret=%{public}d", __func__, __LINE__, ret);
210         return HDF_FAILURE;
211     }
212     HDF_LOGE("%{public}s activeConfig=%{public}d", __func__, activeConfig);
213     dev = UsbRawGetDevice(devHandle);
214     if (dev == NULL) {
215         HDF_LOGE("%{public}s UsbRawGetDevice failed", __func__);
216         return HDF_FAILURE;
217     }
218 
219     ret = UsbRawGetConfigDescriptor(dev, activeConfig, config);
220     if (ret != HDF_SUCCESS) {
221         HDF_LOGE("UsbRawGetConfigDescriptor failed, ret=%{public}d", ret);
222         return HDF_FAILURE;
223     }
224 
225     return HDF_SUCCESS;
226 }
227 
UsbGetBulkEndpoint(struct AcmDevice * const acm,const struct UsbRawEndpointDescriptor * endPoint)228 static int32_t UsbGetBulkEndpoint(struct AcmDevice * const acm, const struct UsbRawEndpointDescriptor *endPoint)
229 {
230     if ((endPoint->endpointDescriptor.bEndpointAddress & USB_DDK_ENDPOINT_DIR_MASK) == USB_DDK_DIR_IN) {
231         /* get bulk in endpoint */
232         acm->dataInEp = OsalMemAlloc(sizeof(struct UsbEndpoint));
233         if (acm->dataInEp == NULL) {
234             HDF_LOGE("%{public}s:%{public}d allocate dataInEp failed", __func__, __LINE__);
235             return HDF_FAILURE;
236         }
237         acm->dataInEp->addr = endPoint->endpointDescriptor.bEndpointAddress;
238         acm->dataInEp->interval = endPoint->endpointDescriptor.bInterval;
239         acm->dataInEp->maxPacketSize = endPoint->endpointDescriptor.wMaxPacketSize;
240     } else {
241         /* get bulk out endpoint */
242         acm->dataOutEp = OsalMemAlloc(sizeof(struct UsbEndpoint));
243         if (acm->dataOutEp == NULL) {
244             HDF_LOGE("%{public}s:%{public}d allocate dataOutEp failed", __func__, __LINE__);
245             return HDF_FAILURE;
246         }
247         acm->dataOutEp->addr = endPoint->endpointDescriptor.bEndpointAddress;
248         acm->dataOutEp->interval = endPoint->endpointDescriptor.bInterval;
249         acm->dataOutEp->maxPacketSize = endPoint->endpointDescriptor.wMaxPacketSize;
250     }
251 
252     return HDF_SUCCESS;
253 }
254 
UsbParseConfigDescriptorProcess(struct AcmDevice * const acm,const struct UsbRawInterface * const interface,uint8_t interfaceIndex)255 static void UsbParseConfigDescriptorProcess(
256     struct AcmDevice * const acm, const struct UsbRawInterface * const interface, uint8_t interfaceIndex)
257 {
258     uint8_t ifaceClass = interface->altsetting->interfaceDescriptor.bInterfaceClass;
259     uint8_t numEndpoints = interface->altsetting->interfaceDescriptor.bNumEndpoints;
260 
261     switch (ifaceClass) {
262         case USB_DDK_CLASS_COMM:
263             acm->ctrlIface = interfaceIndex;
264             acm->notifyEp = OsalMemAlloc(sizeof(struct UsbEndpoint));
265             if (acm->notifyEp == NULL) {
266                 HDF_LOGE("%{public}s:%{public}d allocate endpoint failed", __func__, __LINE__);
267                 break;
268             }
269             /* get the first endpoint by default */
270             acm->notifyEp->addr = interface->altsetting->endPoint[0].endpointDescriptor.bEndpointAddress;
271             acm->notifyEp->interval = interface->altsetting->endPoint[0].endpointDescriptor.bInterval;
272             acm->notifyEp->maxPacketSize = interface->altsetting->endPoint[0].endpointDescriptor.wMaxPacketSize;
273             break;
274         case USB_DDK_CLASS_CDC_DATA:
275             acm->dataIface = interfaceIndex;
276             for (uint8_t j = 0; j < numEndpoints; j++) {
277                 const struct UsbRawEndpointDescriptor *endPoint = &interface->altsetting->endPoint[j];
278                 if (UsbGetBulkEndpoint(acm, endPoint) != HDF_SUCCESS) {
279                     break;
280                 }
281             }
282             break;
283         default:
284             HDF_LOGE("%{public}s:%{public}d wrong descriptor type", __func__, __LINE__);
285             break;
286     }
287 }
288 
UsbParseConfigDescriptor(struct AcmDevice * const acm,struct UsbRawConfigDescriptor * const config)289 static int32_t UsbParseConfigDescriptor(struct AcmDevice * const acm, struct UsbRawConfigDescriptor * const config)
290 {
291     if (acm == NULL || config == NULL) {
292         HDF_LOGE("%{public}s:%{public}d acm or config is NULL", __func__, __LINE__);
293         return HDF_ERR_INVALID_PARAM;
294     }
295 
296     for (uint8_t i = 0; i < acm->interfaceCnt; i++) {
297         uint8_t interfaceIndex = acm->interfaceIndex[i];
298         const struct UsbRawInterface *interface = config->interface[interfaceIndex];
299 
300         int32_t ret = UsbRawClaimInterface(acm->devHandle, interfaceIndex);
301         if (ret != HDF_SUCCESS) {
302             HDF_LOGE("%{public}s:%{public}d claim interface %{public}u failed", __func__, __LINE__, i);
303             return ret;
304         }
305 
306         UsbParseConfigDescriptorProcess(acm, interface, interfaceIndex);
307     }
308 
309     return HDF_SUCCESS;
310 }
311 
UsbAllocDataRequests(struct AcmDevice * const acm)312 static int32_t UsbAllocDataRequests(struct AcmDevice * const acm)
313 {
314     for (int32_t i = 0; i < TEST_CYCLE; i++) {
315         struct AcmDb *snd = &acm->db[i];
316         snd->request = UsbRawAllocRequest(acm->devHandle, 0, acm->dataEp->maxPacketSize);
317         snd->instance = acm;
318         if (snd->request == NULL) {
319             HDF_LOGE("%{public}s: UsbRawAllocRequest failed", __func__);
320             return HDF_ERR_MALLOC_FAIL;
321         }
322         struct UsbRawFillRequestData reqData;
323         reqData.endPoint = acm->dataEp->addr;
324         reqData.numIsoPackets = 0;
325         reqData.callback = AcmTestBulkCallback;
326         reqData.userData = (void *)snd;
327         reqData.timeout = USB_CTRL_SET_TIMEOUT;
328         reqData.buffer = snd->buf;
329         reqData.length = acm->dataSize;
330 
331         int32_t ret = UsbRawFillBulkRequest(snd->request, acm->devHandle, &reqData);
332         if (ret != HDF_SUCCESS) {
333             HDF_LOGE("%{public}s: FillInterruptRequest failed, ret=%{public}d", __func__, ret);
334             return HDF_FAILURE;
335         }
336     }
337 
338     return HDF_SUCCESS;
339 }
UsbSerialDeviceAlloc(struct AcmDevice * acm)340 static int32_t UsbSerialDeviceAlloc(struct AcmDevice *acm)
341 {
342     struct SerialDevice *port = NULL;
343 
344     if (acm == NULL) {
345         HDF_LOGE("%{public}s: acm null pointer", __func__);
346         return HDF_FAILURE;
347     }
348 
349     port = (struct SerialDevice *)OsalMemCalloc(sizeof(*port));
350     if (port == NULL) {
351         HDF_LOGE("%{public}s: Alloc usb serial port failed", __func__);
352         return HDF_FAILURE;
353     }
354     if (OsalMutexInit(&port->lock) != HDF_SUCCESS) {
355         HDF_LOGE("%{public}s: init lock fail!", __func__);
356         return HDF_FAILURE;
357     }
358     port->lineCoding.dwDTERate = CPU_TO_LE32(DATARATE);
359     port->lineCoding.bCharFormat = USB_CDC_1_STOP_BITS;
360     port->lineCoding.bParityType = USB_CDC_NO_PARITY;
361     port->lineCoding.bDataBits = DATA_BITS_LENGTH;
362     acm->lineCoding = port->lineCoding;
363     acm->port = port;
364     port->acm = acm;
365 
366     return HDF_SUCCESS;
367 }
368 
AcmDbAlloc(struct AcmDevice * const acm)369 static int32_t AcmDbAlloc(struct AcmDevice * const acm)
370 {
371     struct AcmDb *db = NULL;
372     int32_t i;
373 
374     for (i = 0; i < TEST_CYCLE; i++) {
375         db = &acm->db[i];
376         if (!db->use) {
377             db->use = 1;
378             db->len = 0;
379             return i;
380         }
381     }
382     return -1;
383 }
384 
AcmDbIsAvail(struct AcmDevice * const acm)385 static int32_t AcmDbIsAvail(struct AcmDevice * const acm)
386 {
387     int32_t i;
388     int32_t n = TEST_CYCLE;
389 
390     for (i = 0; i < TEST_CYCLE; i++) {
391         n -= acm->db[i].use;
392     }
393     return n;
394 }
395 
AcmStartdb(struct AcmDevice * acm,struct AcmDb * const db)396 static int32_t AcmStartdb(struct AcmDevice *acm, struct AcmDb * const db)
397 {
398     (void)acm;
399     int32_t ret;
400     ret = UsbRawSubmitRequest(db->request);
401     if (ret != HDF_SUCCESS) {
402         HDF_LOGE("UsbRawSubmitRequest failed, ret=%{public}d", ret);
403         db->use = 0;
404     }
405     return ret;
406 }
407 
AcmDataBufAlloc(struct AcmDevice * const acm)408 static int32_t AcmDataBufAlloc(struct AcmDevice * const acm)
409 {
410     struct AcmDb *db = &acm->db[0];
411     int32_t i;
412 
413     for (i = 0; i < TEST_CYCLE; i++, db++) {
414         db->buf = OsalMemCalloc(acm->dataEp->maxPacketSize);
415         if (!db->buf) {
416             while (i != 0) {
417                 --i;
418                 --db;
419                 OsalMemFree(db->buf);
420                 db->buf = NULL;
421             }
422             return -HDF_ERR_MALLOC_FAIL;
423         } else {
424             memset_s(db->buf, acm->dataSize, 'b', acm->dataSize);
425             db->instance = acm;
426         }
427     }
428     return HDF_SUCCESS;
429 }
430 
AcmTestBulkCallback(const void * requestArg)431 static void AcmTestBulkCallback(const void *requestArg)
432 {
433     struct UsbRawRequest *req = (struct UsbRawRequest *)requestArg;
434     struct itimerval new_value, old_value;
435     if (req == NULL) {
436         HDF_LOGE("%{public}s:%{pulib}d req is NULL!", __func__, __LINE__);
437         return;
438     }
439     struct AcmDb *db = (struct AcmDb *)req->userData;
440     if (db == NULL) {
441         HDF_LOGE("%{public}s:%{pulib}d userData(db) is NULL!", __func__, __LINE__);
442         return;
443     }
444 
445     if (req->status == USB_REQUEST_COMPLETED) {
446         if (g_byteTotal == 0) {
447             new_value.it_value.tv_sec = TEST_PRINT_TIME;
448             new_value.it_value.tv_usec = 0;
449             new_value.it_interval.tv_sec = TEST_PRINT_TIME;
450             new_value.it_interval.tv_usec = 0;
451             setitimer(ITIMER_REAL, &new_value, &old_value);
452         }
453         g_recv_count++;
454         g_byteTotal += req->actualLength;
455     } else {
456         printf("status error\n");
457     }
458 
459     if (g_printData) {
460         for (int32_t i = 0; i < req->actualLength; i++) {
461             printf("%c", req->buffer[i]);
462         }
463         fflush(stdout);
464     } else if (g_recv_count % TEST_RECV_COUNT == 0) {
465         printf("#");
466         fflush(stdout);
467     }
468 
469     db->use = 0;
470     OsalSemPost(&sem);
471 }
472 
SerialBegin(struct AcmDevice * acm)473 static int32_t SerialBegin(struct AcmDevice *acm)
474 {
475     uint32_t size = acm->dataSize;
476     int32_t ret;
477     struct AcmDb *db = NULL;
478     int32_t dbn;
479     if (AcmDbIsAvail(acm) != 0) {
480         dbn = AcmDbAlloc(acm);
481     } else {
482         HDF_LOGE("no buf");
483         return 0;
484     }
485     if (dbn < 0) {
486         HDF_LOGE("AcmDbAlloc failed");
487         return HDF_FAILURE;
488     }
489     db = &acm->db[dbn];
490     db->len = acm->dataSize;
491     if (g_writeOrRead == TEST_READ) {
492         memset_s(db->buf, TEST_LENGTH, '0', TEST_LENGTH);
493     }
494     struct UsbRawFillRequestData reqData;
495     reqData.endPoint = acm->dataEp->addr;
496     reqData.numIsoPackets = 0;
497     reqData.callback = AcmTestBulkCallback;
498     reqData.userData = (void *)db;
499     reqData.timeout = USB_CTRL_SET_TIMEOUT;
500     reqData.buffer = db->buf;
501     reqData.length = acm->dataSize;
502 
503     ret = UsbRawFillBulkRequest(db->request, acm->devHandle, &reqData);
504     if (ret != HDF_SUCCESS) {
505         HDF_LOGE("%{public}s: FillInterruptRequest failed, ret=%{public}d", __func__, ret);
506         return HDF_FAILURE;
507     }
508 
509     ret = AcmStartdb(acm, db);
510     return (int32_t)size;
511 }
512 
SignalHandler(int32_t signo)513 static void SignalHandler(int32_t signo)
514 {
515     static uint32_t sigCnt = 0;
516     struct itimerval new_value, old_value;
517     double speed = 0;
518     switch (signo) {
519         case SIGALRM:
520             sigCnt++;
521             if (sigCnt * TEST_PRINT_TIME >= TEST_TIME) {
522                 g_speedFlag = 1;
523                 break;
524             }
525 
526             speed = (g_byteTotal * TEST_FLOAT_COUNT) / (sigCnt * TEST_PRINT_TIME * TEST_BYTE_COUNT * TEST_BYTE_COUNT);
527             printf("\nSpeed:%f MB/s\n", speed);
528             new_value.it_value.tv_sec = TEST_PRINT_TIME;
529             new_value.it_value.tv_usec = 0;
530             new_value.it_interval.tv_sec = TEST_PRINT_TIME;
531             new_value.it_interval.tv_usec = 0;
532             setitimer(ITIMER_REAL, &new_value, &old_value);
533             break;
534         case SIGINT:
535             g_speedFlag = 1;
536             break;
537         default:
538             break;
539     }
540 }
541 
ShowHelp(const char * name)542 static void ShowHelp(const char *name)
543 {
544     printf(">> usage:\n");
545     printf(">>      %s [<busNum> <devAddr>]  <ifaceNum> <w>/<r> [printdata]> \n", name);
546     printf("\n");
547 }
548 
CheckParam(int32_t argc,const char * argv[])549 static int32_t CheckParam(int32_t argc, const char *argv[])
550 {
551     int32_t busNum = 1;
552     int32_t devAddr = 2;
553     int32_t ifaceNum = 3;
554     int32_t ret = HDF_SUCCESS;
555 
556     if (argc == TEST_SIX_TYPE) {
557         busNum = (int32_t)strtol(argv[TEST_ONE_TYPE], NULL, STRTOL_BASE);
558         devAddr = (int32_t)strtol(argv[TEST_TWO_TYPE], NULL, STRTOL_BASE);
559         ifaceNum = (int32_t)strtol(argv[TEST_THREE_TYPE], NULL, STRTOL_BASE);
560         g_writeOrRead = (strncmp(argv[TEST_FOUR_TYPE], "r", TEST_ONE_TYPE)) ? TEST_WRITE : TEST_READ;
561         if (g_writeOrRead == TEST_READ) {
562             g_printData = (strncmp(argv[TEST_FIVE_TYPE], "printdata", TEST_ONE_TYPE)) ? false : true;
563         }
564     } else if (argc == TEST_FIVE_TYPE) {
565         busNum = (int32_t)strtol(argv[TEST_ONE_TYPE], NULL, STRTOL_BASE);
566         devAddr = (int32_t)strtol(argv[TEST_TWO_TYPE], NULL, STRTOL_BASE);
567         ifaceNum = (int32_t)strtol(argv[TEST_THREE_TYPE], NULL, STRTOL_BASE);
568         g_writeOrRead = (strncmp(argv[TEST_FOUR_TYPE], "r", TEST_ONE_TYPE)) ? TEST_WRITE : TEST_READ;
569     } else if (argc == TEST_THREE_TYPE) {
570         ifaceNum = (int32_t)strtol(argv[TEST_ONE_TYPE], NULL, STRTOL_BASE);
571         g_writeOrRead = (strncmp(argv[TEST_TWO_TYPE], "r", TEST_ONE_TYPE)) ? TEST_WRITE : TEST_READ;
572     } else {
573         printf("Error: parameter error!\n\n");
574         ShowHelp(argv[TEST_ZERO_TYPE]);
575         ret = HDF_FAILURE;
576         goto END;
577     }
578     OsalSemInit(&sem, 0);
579 
580     g_acm = (struct AcmDevice *)OsalMemCalloc(sizeof(*g_acm));
581     if (g_acm == NULL) {
582         HDF_LOGE("%{public}s: Alloc usb serial device failed", __func__);
583         ret = HDF_FAILURE;
584         goto END;
585     }
586 
587     g_acm->busNum = busNum;
588     g_acm->devAddr = devAddr;
589     g_acm->interfaceCnt = 1;
590     g_acm->interfaceIndex[0] = ifaceNum;
591 END:
592     return ret;
593 }
594 
InitUsbDdk(void)595 static int32_t InitUsbDdk(void)
596 {
597     int32_t ret;
598     struct UsbSession *session = NULL;
599     UsbRawHandle *devHandle = NULL;
600 
601     ret = UsbRawInit(&session);
602     if (ret != HDF_SUCCESS) {
603         HDF_LOGE("%{public}s: UsbRawInit failed", __func__);
604         goto END;
605     }
606 
607     ret = UsbSerialDeviceAlloc(g_acm);
608     if (ret != HDF_SUCCESS) {
609         HDF_LOGE("%{public}s: UsbSerialDeviceAlloc failed", __func__);
610         goto END;
611     }
612 
613     devHandle = UsbRawOpenDevice(session, g_acm->busNum, g_acm->devAddr);
614     if (devHandle == NULL) {
615         HDF_LOGE("%{public}s: UsbRawOpenDevice failed", __func__);
616         ret = HDF_FAILURE;
617         goto END;
618     }
619     g_acm->devHandle = devHandle;
620     ret = UsbGetConfigDescriptor(devHandle, &g_acm->config);
621     if (ret != HDF_SUCCESS) {
622         HDF_LOGE("%{public}s: UsbGetConfigDescriptor failed", __func__);
623         goto END;
624     }
625     ret = UsbParseConfigDescriptor(g_acm, g_acm->config);
626     if (ret != HDF_SUCCESS) {
627         HDF_LOGE("%{public}s: UsbParseConfigDescriptor failed", __func__);
628         ret = HDF_FAILURE;
629         goto END;
630     }
631     g_acm->dataSize = TEST_LENGTH;
632     g_acm->dataEp = (g_writeOrRead == TEST_WRITE) ? g_acm->dataOutEp : g_acm->dataInEp;
633 
634     ret = AcmDataBufAlloc(g_acm);
635     if (ret < 0) {
636         HDF_LOGE("%{public}s: AcmDataBufAlloc failed", __func__);
637         goto END;
638     }
639     ret = UsbAllocDataRequests(g_acm);
640     if (ret < 0) {
641         HDF_LOGE("%{public}s: UsbAllocDataRequests failed", __func__);
642         goto END;
643     }
644 
645 END:
646     return ret;
647 }
648 
main(int32_t argc,char * argv[])649 int32_t main(int32_t argc, char *argv[])
650 {
651     int32_t ret;
652     struct timeval time;
653     int32_t i;
654 
655     ret = CheckParam(argc, (const char **)argv);
656     if (ret != HDF_SUCCESS) {
657         goto END;
658     }
659 
660     ret = InitUsbDdk();
661     if (ret != HDF_SUCCESS) {
662         goto END;
663     }
664 
665     ret = UsbStartIo(g_acm);
666     if (ret != HDF_SUCCESS) {
667         HDF_LOGE("%{public}s: UsbAllocReadRequests failed", __func__);
668         goto END;
669     }
670 
671     if (signal(SIGINT, SignalHandler) == SIG_ERR) {
672         HDF_LOGE("signal SIGINT failed");
673         return HDF_FAILURE;
674     }
675     if (signal(SIGALRM, SignalHandler) == SIG_ERR) {
676         HDF_LOGE("signal SIGINT failed");
677         return HDF_FAILURE;
678     }
679     gettimeofday(&time, NULL);
680 
681     printf("test SDK rawAPI [%s]\n", g_writeOrRead ? "write" : "read");
682 
683     for (i = 0; i < TEST_CYCLE; i++) {
684         if (SerialBegin(g_acm) != HDF_SUCCESS) {
685             printf("SerialBegin error!\n");
686         }
687         g_send_count++;
688     }
689 
690     while (!g_speedFlag) {
691         OsalMSleep(TEST_SLEEP_TIME);
692     }
693 
694     if (UsbStopIo(g_acm) != HDF_SUCCESS) {
695         printf("UsbStopIo error!\n");
696     }
697 END:
698     if (ret != HDF_SUCCESS) {
699         printf("please check whether usb drv so is existing or not,like acm,ecm,if not, remove it and test again!\n");
700     }
701     return ret;
702 }
703