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 #include <dirent.h>
18 #include <errno.h>
19 #include <fcntl.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/time.h>
28 #include <unistd.h>
29 
30 #include "hdf_base.h"
31 #include "hdf_log.h"
32 #include "hdf_usb_pnp_manage.h"
33 #include "implementation/global_implementation.h"
34 #include "osal_mem.h"
35 #include "osal_time.h"
36 #include "securec.h"
37 #include "usb_ddk_interface.h"
38 #include "usb_pnp_notify.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 USB_DEVICE_VENDOR_ID          0x12D1
47 #define USB_DEVICE_PRODUCT_ID         0x5000
48 #define USB_RECV_COUNT_TSH            10000
49 
50 static struct AcmDevice *g_acm = NULL;
51 static bool g_stopIoThreadFlag = false;
52 static unsigned int g_speedFlag = 0;
53 static uint64_t g_send_count = 0;
54 static uint64_t g_recv_count = 0;
55 static uint64_t g_byteTotal = 0;
56 static bool g_writeOrRead = TEST_WRITE;
57 static bool g_printData = false;
58 static struct OsalSem sem;
59 static struct OsalSem timeSem;
60 static uint32_t sigCnt = 0;
61 static void AcmTestBulkCallback(const void *requestArg);
62 static int32_t SerialBegin(struct AcmDevice *acm);
63 
UsbIoThread(void * data)64 static int32_t UsbIoThread(void *data)
65 {
66     int32_t ret;
67     struct AcmDevice *acm = (struct AcmDevice *)data;
68 
69     while (true) {
70         if (acm == NULL) {
71             printf("%s:%d acm is NULL", __func__, __LINE__);
72             OsalMSleep(USB_RAW_IO_SLEEP_MS_TIME);
73             continue;
74         }
75 
76         if (acm->devHandle == NULL) {
77             printf("%s:%d acm->devHandle is NULL!", __func__, __LINE__);
78             OsalMSleep(USB_RAW_IO_SLEEP_MS_TIME);
79             continue;
80         }
81 
82         ret = UsbRawHandleRequests(acm->devHandle);
83         if (ret < 0) {
84             printf("%s:%d UsbRawHandleRequests failed, ret=%d ", __func__, __LINE__, ret);
85             if (ret == USB_REQUEST_NO_DEVICE) {
86                 printf("%s:%d, ret=%d", __func__, __LINE__, ret);
87                 OsalMSleep(USB_RAW_IO_SLEEP_MS_TIME);
88             }
89         }
90 
91         if (g_stopIoThreadFlag) {
92             HDF_LOGD("%{public}s:%{public}d", __func__, __LINE__);
93             g_stopIoThreadFlag = false;
94             break;
95         }
96     }
97 
98     HDF_LOGE("%{public}s:%{public}d exit", __func__, __LINE__);
99 
100     return HDF_SUCCESS;
101 }
102 
UsbIoSendThread(void * data)103 static int32_t UsbIoSendThread(void *data)
104 {
105     struct AcmDevice *acm = (struct AcmDevice *)data;
106 
107     while (!g_stopIoThreadFlag) {
108         OsalSemWait(&sem, HDF_WAIT_FOREVER);
109         if (!g_speedFlag) {
110             if (SerialBegin(acm) != HDF_SUCCESS) {
111                 HDF_LOGW("%{public}s:%{public}d SerialBegin error!", __func__, __LINE__);
112             }
113             g_send_count++;
114         }
115     }
116     return 0;
117 }
118 
UsbStartIo(struct AcmDevice * const acm)119 static int32_t UsbStartIo(struct AcmDevice * const acm)
120 {
121     struct OsalThreadParam threadCfg;
122     int32_t ret;
123 
124     HDF_LOGI("%{public}s start", __func__);
125     g_stopIoThreadFlag = false;
126 
127     /* create Io thread */
128     (void)memset_s(&threadCfg, sizeof(threadCfg), 0, sizeof(threadCfg));
129     threadCfg.name = "usb io thread";
130     threadCfg.priority = OSAL_THREAD_PRI_DEFAULT;
131     threadCfg.stackSize = USB_IO_THREAD_STACK_SIZE;
132 
133     ret = OsalThreadCreate(&acm->ioThread, (OsalThreadEntry)UsbIoThread, (void *)acm);
134     if (ret != HDF_SUCCESS) {
135         HDF_LOGE("%{public}s:%{public}d OsalThreadCreate failed, ret=%{public}d ", __func__, __LINE__, ret);
136         return ret;
137     }
138 
139     ret = OsalThreadStart(&acm->ioThread, &threadCfg);
140     if (ret != HDF_SUCCESS) {
141         HDF_LOGE("%{public}s:%{public}d OsalThreadStart failed, ret=%{public}d ", __func__, __LINE__, ret);
142         return ret;
143     }
144 
145     (void)memset_s(&threadCfg, sizeof(threadCfg), 0, sizeof(threadCfg));
146     threadCfg.name = "usb io send thread";
147     threadCfg.priority = OSAL_THREAD_PRI_DEFAULT;
148     threadCfg.stackSize = USB_IO_THREAD_STACK_SIZE;
149     ret = OsalThreadCreate(&acm->ioSendThread, (OsalThreadEntry)UsbIoSendThread, (void *)acm);
150     if (ret != HDF_SUCCESS) {
151         HDF_LOGE("%{public}s:%{public}d OsalThreadCreate failed, ret=%{public}d ", __func__, __LINE__, ret);
152         return ret;
153     }
154 
155     ret = OsalThreadStart(&acm->ioSendThread, &threadCfg);
156     if (ret != HDF_SUCCESS) {
157         HDF_LOGE("%{public}s:%{public}d OsalThreadStart failed, ret=%{public}d ", __func__, __LINE__, ret);
158         return ret;
159     }
160 
161     return HDF_SUCCESS;
162 }
163 
UsbStopIo(struct AcmDevice * const acm)164 static int32_t UsbStopIo(struct AcmDevice * const acm)
165 {
166     int32_t ret;
167     int32_t i = 0;
168 
169     printf("%s:%d", __func__, __LINE__);
170     if (!g_stopIoThreadFlag) {
171         printf("%s:%d", __func__, __LINE__);
172         g_stopIoThreadFlag = true;
173     }
174     printf("%s:%d", __func__, __LINE__);
175 
176     while (g_stopIoThreadFlag) {
177         i++;
178         OsalMSleep(USB_RAW_IO_SLEEP_MS_TIME);
179         if (i > USB_RAW_IO_STOP_WAIT_MAX_TIME) {
180             printf("%s:%d", __func__, __LINE__);
181             g_stopIoThreadFlag = false;
182         }
183     }
184     printf("%s:%d", __func__, __LINE__);
185 
186     ret = OsalThreadDestroy(&acm->ioThread);
187     if (ret != HDF_SUCCESS) {
188         printf("%s:%d OsalThreadDestroy failed, ret=%d", __func__, __LINE__, ret);
189         return ret;
190     }
191 
192     ret = OsalThreadDestroy(&acm->ioSendThread);
193     if (ret != HDF_SUCCESS) {
194         printf("%s:%d OsalThreadDestroy failed, ret=%d ", __func__, __LINE__, ret);
195         return ret;
196     }
197 
198     return HDF_SUCCESS;
199 }
200 
UsbGetConfigDescriptor(UsbRawHandle * devHandle,struct UsbRawConfigDescriptor ** const config)201 static int32_t UsbGetConfigDescriptor(UsbRawHandle *devHandle, struct UsbRawConfigDescriptor ** const config)
202 {
203     UsbRawDevice *dev = NULL;
204     int32_t activeConfig;
205     int32_t ret;
206 
207     if (devHandle == NULL) {
208         printf("%s:%d devHandle is NULL", __func__, __LINE__);
209         return HDF_ERR_INVALID_PARAM;
210     }
211 
212     ret = UsbRawGetConfiguration(devHandle, &activeConfig);
213     if (ret != HDF_SUCCESS) {
214         printf("%s:%d UsbRawGetConfiguration failed, ret=%d", __func__, __LINE__, ret);
215         return HDF_FAILURE;
216     }
217     HDF_LOGE("%{public}s:%{public}d activeConfig=%{public}d", __func__, __LINE__, activeConfig);
218     dev = UsbRawGetDevice(devHandle);
219     if (dev == NULL) {
220         printf("%s:%d UsbRawGetDevice failed", __func__, __LINE__);
221         return HDF_FAILURE;
222     }
223 
224     ret = UsbRawGetConfigDescriptor(dev, activeConfig, config);
225     if (ret != HDF_SUCCESS) {
226         printf("UsbRawGetConfigDescriptor failed, ret=%d\n", ret);
227         return HDF_FAILURE;
228     }
229 
230     return HDF_SUCCESS;
231 }
232 
UsbSpeedGetBulkEndpoint(struct AcmDevice * const acm,const struct UsbRawEndpointDescriptor * endPoint)233 static int32_t UsbSpeedGetBulkEndpoint(struct AcmDevice * const acm, const struct UsbRawEndpointDescriptor *endPoint)
234 {
235     if ((endPoint->endpointDescriptor.bEndpointAddress & USB_DDK_ENDPOINT_DIR_MASK) == USB_DDK_DIR_IN) {
236         /* get bulk in endpoint */
237         acm->dataInEp = OsalMemAlloc(sizeof(struct UsbEndpoint));
238         if (acm->dataInEp == NULL) {
239             HDF_LOGE("%{public}s:%{public}d allocate dataInEp failed", __func__, __LINE__);
240             return HDF_FAILURE;
241         }
242         acm->dataInEp->addr = endPoint->endpointDescriptor.bEndpointAddress;
243         acm->dataInEp->interval = endPoint->endpointDescriptor.bInterval;
244         acm->dataInEp->maxPacketSize = endPoint->endpointDescriptor.wMaxPacketSize;
245     } else {
246         /* get bulk out endpoint */
247         acm->dataOutEp = OsalMemAlloc(sizeof(struct UsbEndpoint));
248         if (acm->dataOutEp == NULL) {
249             HDF_LOGE("%{public}s:%{public}d allocate dataOutEp failed", __func__, __LINE__);
250             return HDF_FAILURE;
251         }
252         acm->dataOutEp->addr = endPoint->endpointDescriptor.bEndpointAddress;
253         acm->dataOutEp->interval = endPoint->endpointDescriptor.bInterval;
254         acm->dataOutEp->maxPacketSize = endPoint->endpointDescriptor.wMaxPacketSize;
255     }
256 
257     return HDF_SUCCESS;
258 }
259 
UsbSpeedParaseInterfaceClass(struct AcmDevice * acm,const struct UsbRawInterface * interface,uint8_t interfaceIndex)260 static void UsbSpeedParaseInterfaceClass(
261     struct AcmDevice *acm, const struct UsbRawInterface *interface, uint8_t interfaceIndex)
262 {
263     uint8_t j;
264     uint8_t ifaceClass = interface->altsetting->interfaceDescriptor.bInterfaceClass;
265     uint8_t numEndpoints = interface->altsetting->interfaceDescriptor.bNumEndpoints;
266 
267     switch (ifaceClass) {
268         case USB_DDK_CLASS_COMM:
269             acm->ctrlIface = interfaceIndex;
270             acm->notifyEp = OsalMemAlloc(sizeof(struct UsbEndpoint));
271             if (acm->notifyEp == NULL) {
272                 printf("%s:%d allocate endpoint failed", __func__, __LINE__);
273                 break;
274             }
275             /* get the first endpoint by default */
276             acm->notifyEp->addr = interface->altsetting->endPoint[0].endpointDescriptor.bEndpointAddress;
277             acm->notifyEp->interval = interface->altsetting->endPoint[0].endpointDescriptor.bInterval;
278             acm->notifyEp->maxPacketSize = interface->altsetting->endPoint[0].endpointDescriptor.wMaxPacketSize;
279             break;
280         case USB_DDK_CLASS_CDC_DATA:
281             acm->dataIface = interfaceIndex;
282             for (j = 0; j < numEndpoints; j++) {
283                 const struct UsbRawEndpointDescriptor *endPoint = &interface->altsetting->endPoint[j];
284 
285                 if (UsbSpeedGetBulkEndpoint(acm, endPoint) != HDF_SUCCESS) {
286                     break;
287                 }
288             }
289             break;
290         default:
291             printf("%s:%d wrong descriptor type", __func__, __LINE__);
292             break;
293     }
294 }
295 
UsbParseConfigDescriptor(struct AcmDevice * const acm,struct UsbRawConfigDescriptor * const config)296 static int32_t UsbParseConfigDescriptor(struct AcmDevice * const acm, struct UsbRawConfigDescriptor * const config)
297 {
298     uint8_t i;
299     int32_t ret;
300 
301     if ((acm == NULL) || (config == NULL)) {
302         printf("%s:%d acm or config is NULL", __func__, __LINE__);
303         return HDF_ERR_INVALID_PARAM;
304     }
305 
306     for (i = 0; i < acm->interfaceCnt; i++) {
307         uint8_t interfaceIndex = acm->interfaceIndex[i];
308         const struct UsbRawInterface *interface = config->interface[interfaceIndex];
309 
310         if (acm->devHandle) {
311             ret = UsbRawClaimInterface(acm->devHandle, interfaceIndex);
312             if (ret != HDF_SUCCESS) {
313                 printf("%s:%d claim interface %d failed", __func__, __LINE__, i);
314                 return ret;
315             }
316         }
317 
318         UsbSpeedParaseInterfaceClass(acm, interface, interfaceIndex);
319     }
320 
321     return HDF_SUCCESS;
322 }
323 
UsbAllocDataRequests(struct AcmDevice * const acm)324 static int32_t UsbAllocDataRequests(struct AcmDevice * const acm)
325 {
326     for (int32_t i = 0; i < TEST_CYCLE; i++) {
327         struct AcmDb *snd = &acm->db[i];
328         snd->request = UsbRawAllocRequest(acm->devHandle, 0, acm->dataEp->maxPacketSize);
329         snd->instance = acm;
330         if (snd->request == NULL) {
331             printf("%s: UsbRawAllocRequest failed", __func__);
332             return HDF_ERR_MALLOC_FAIL;
333         }
334         struct UsbRawFillRequestData reqData;
335         reqData.endPoint = acm->dataEp->addr;
336         reqData.numIsoPackets = 0;
337         reqData.callback = AcmTestBulkCallback;
338         reqData.userData = (void *)snd;
339         reqData.timeout = USB_CTRL_SET_TIMEOUT;
340         reqData.buffer = snd->buf;
341         reqData.length = acm->dataSize;
342 
343         int32_t ret = UsbRawFillBulkRequest(snd->request, acm->devHandle, &reqData);
344         if (ret != HDF_SUCCESS) {
345             printf("%s: FillBulkRequest failed, ret = %d", __func__, ret);
346             return HDF_FAILURE;
347         }
348     }
349 
350     return HDF_SUCCESS;
351 }
352 
UsbFreeDataRequests(struct AcmDevice * acm)353 static int32_t UsbFreeDataRequests(struct AcmDevice *acm)
354 {
355     int32_t i;
356     for (i = 0; i < TEST_CYCLE; i++) {
357         struct AcmDb *snd = &acm->db[i];
358         UsbRawCancelRequest(snd->request);
359         UsbRawFreeRequest(snd->request);
360     }
361     return HDF_SUCCESS;
362 }
363 
AcmDbAlloc(struct AcmDevice * const acm)364 static int32_t AcmDbAlloc(struct AcmDevice * const acm)
365 {
366     struct AcmDb *db = NULL;
367     int32_t i;
368 
369     for (i = 0; i < TEST_CYCLE; i++) {
370         db = &acm->db[i];
371         if (!db->use) {
372             db->use = 1;
373             db->len = 0;
374             return i;
375         }
376     }
377     return -1;
378 }
379 
AcmDbIsAvail(struct AcmDevice * const acm)380 static int32_t AcmDbIsAvail(struct AcmDevice * const acm)
381 {
382     int32_t i;
383     int32_t n = TEST_CYCLE;
384 
385     for (i = 0; i < TEST_CYCLE; i++) {
386         n -= acm->db[i].use;
387     }
388     return n;
389 }
390 
AcmStartdb(struct AcmDevice * acm,struct AcmDb * const db)391 static int32_t AcmStartdb(struct AcmDevice *acm, struct AcmDb * const db)
392 {
393     (void)acm;
394     int32_t ret = UsbRawSubmitRequest(db->request);
395     if (ret != HDF_SUCCESS) {
396         printf("UsbRawSubmitRequest failed, ret=%d", ret);
397         db->use = 0;
398     }
399     return ret;
400 }
401 
AcmDataBufAlloc(struct AcmDevice * const acm)402 static int32_t AcmDataBufAlloc(struct AcmDevice * const acm)
403 {
404     struct AcmDb *db = &acm->db[0];
405     int32_t i;
406 
407     for (i = 0; i < TEST_CYCLE; i++, db++) {
408         db->buf = OsalMemCalloc(acm->dataEp->maxPacketSize);
409         if (!db->buf) {
410             while (i != 0) {
411                 --i;
412                 --db;
413                 OsalMemFree(db->buf);
414                 db->buf = NULL;
415             }
416             return -HDF_ERR_MALLOC_FAIL;
417         } else {
418             memset_s(db->buf, acm->dataSize, 'b', acm->dataSize);
419             db->instance = acm;
420         }
421     }
422     return HDF_SUCCESS;
423 }
AcmDataBufFree(const struct AcmDevice * acm)424 static int32_t AcmDataBufFree(const struct AcmDevice *acm)
425 {
426     struct AcmDb *db = (struct AcmDb *)&acm->db[0];
427     int32_t i;
428     for (i = 0; i < TEST_CYCLE; i++, db++) {
429         if (db->buf) {
430             OsalMemFree(db->buf);
431             db->use = 0;
432         }
433     }
434     return 0;
435 }
436 
AcmTestBulkCallback(const void * requestArg)437 static void AcmTestBulkCallback(const void *requestArg)
438 {
439     struct UsbRawRequest *req = (struct UsbRawRequest *)requestArg;
440     if (req == NULL) {
441         HDF_LOGE("%{public}s:%{pulib}d req is NULL!", __func__, __LINE__);
442         return;
443     }
444     struct AcmDb *db = (struct AcmDb *)req->userData;
445     if (db == NULL) {
446         HDF_LOGE("%{public}s:%{pulib}d userData(db) is NULL!", __func__, __LINE__);
447         return;
448     }
449 
450     if (req->status == USB_REQUEST_COMPLETED) {
451         if (g_byteTotal == 0) {
452             OsalSemPost(&timeSem);
453         }
454         g_recv_count++;
455         g_byteTotal += (uint64_t)req->actualLength;
456     } else {
457         printf("status error\n");
458     }
459 
460     if (g_printData) {
461         for (int32_t i = 0; i < req->actualLength; i++) {
462             printf("%c", req->buffer[i]);
463         }
464         fflush(stdout);
465     } else if (g_recv_count % USB_RECV_COUNT_TSH == 0) {
466         printf("#");
467         fflush(stdout);
468     }
469 
470     db->use = 0;
471     OsalSemPost(&sem);
472 }
473 
SerialBegin(struct AcmDevice * acm)474 static int32_t SerialBegin(struct AcmDevice *acm)
475 {
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         printf("no buf\n");
483         return 0;
484     }
485     if (dbn < 0) {
486         printf("AcmDbAlloc failed\n");
487         return HDF_FAILURE;
488     }
489     db = &acm->db[dbn];
490     db->len = acm->dataSize;
491 
492     ret = AcmStartdb(acm, db);
493     return ret;
494 }
495 
SpeedPrint(void)496 static void SpeedPrint(void)
497 {
498     double speed;
499     uint64_t count;
500 
501     sigCnt++;
502     count = (uint64_t)sigCnt * TEST_PRINT_TIME;
503     if (count >= TEST_TIME) {
504         g_speedFlag = true;
505     }
506     speed = (g_byteTotal * TEST_FLOAT_COUNT) / (sigCnt * TEST_PRINT_TIME * TEST_BYTE_COUNT * TEST_BYTE_COUNT);
507     printf("\nSpeed:%f MB/s\n", speed);
508 }
509 
ShowHelp(const char * name)510 static void ShowHelp(const char *name)
511 {
512     printf(">> usage:\n");
513     printf(">>      %s [<busNum> <devAddr>]  <ifaceNum> <w>/<r> [printdata]> \n", name);
514     printf("\n");
515 }
516 
UsbGetDevInfo(int32_t * const busNum,int32_t * const devNum)517 static void UsbGetDevInfo(int32_t * const busNum, int32_t * const devNum)
518 {
519     struct UsbGetDevicePara paraData;
520     struct usb_device *usbPnpDevice = NULL;
521     paraData.type = USB_PNP_DEVICE_VENDOR_PRODUCT_TYPE;
522     paraData.vendorId = USB_DEVICE_VENDOR_ID;
523     paraData.productId = USB_DEVICE_PRODUCT_ID;
524     usbPnpDevice = UsbPnpNotifyGetUsbDevice(paraData);
525     if (usbPnpDevice == NULL) {
526         printf("%s:%d UsbPnpNotifyGetUsbDevice is NULL!", __func__, __LINE__);
527         return;
528     }
529     *busNum = (int)usbPnpDevice->address;
530     *devNum = (int)usbPnpDevice->port_no;
531     printf("%s:%d busNum=%d devNum=%d!\n", __func__, __LINE__, *busNum, *devNum);
532 }
533 
UsbSerialOpen(void)534 static int32_t UsbSerialOpen(void)
535 {
536     return HDF_SUCCESS;
537 }
UsbSerialClose(void)538 static int32_t UsbSerialClose(void)
539 {
540     if (!g_speedFlag) {
541         g_speedFlag = true;
542     }
543     return HDF_SUCCESS;
544 }
545 
UsbSerialSpeedInit(const struct UsbSpeedTest * input,int32_t * const ifaceNum)546 static int32_t UsbSerialSpeedInit(const struct UsbSpeedTest *input, int32_t * const ifaceNum)
547 {
548     int32_t ret = HDF_SUCCESS;
549     int32_t busNum = 1;
550     int32_t devAddr = 2;
551     if (input == NULL) {
552         return HDF_ERR_INVALID_PARAM;
553     }
554 
555     g_speedFlag = false;
556     g_send_count = 0;
557     g_recv_count = 0;
558     g_byteTotal = 0;
559     g_printData = false;
560     g_writeOrRead = TEST_WRITE;
561     sigCnt = 0;
562 
563     UsbGetDevInfo(&busNum, &devAddr);
564     if (input->paramNum == TEST_SIX_TYPE) {
565         busNum = input->busNum;
566         devAddr = input->devAddr;
567         *ifaceNum = input->ifaceNum;
568         g_writeOrRead = input->writeOrRead;
569         if (g_writeOrRead == TEST_READ) {
570             g_printData = input->printData;
571         }
572     } else if (input->paramNum == TEST_FIVE_TYPE) {
573         busNum = input->busNum;
574         devAddr = input->devAddr;
575         *ifaceNum = input->ifaceNum;
576         g_writeOrRead = input->writeOrRead;
577     } else if (input->paramNum == TEST_THREE_TYPE) {
578         *ifaceNum = input->ifaceNum;
579         g_writeOrRead = input->writeOrRead;
580     } else {
581         printf("Error: parameter error! \n\n");
582         ShowHelp("speedtest");
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     OsalSemInit(&sem, 0);
592     OsalSemInit(&timeSem, 0);
593 
594 END:
595     return ret;
596 }
597 
UsbSpeedDdkInit(const struct UsbSession * session)598 static int32_t UsbSpeedDdkInit(const struct UsbSession *session)
599 {
600     int32_t ret;
601     UsbRawHandle *devHandle = NULL;
602 
603     ret = UsbRawInit((struct UsbSession **)&session);
604     if (ret != HDF_SUCCESS) {
605         HDF_LOGE("%{public}s: UsbRawInit failed", __func__);
606         return HDF_FAILURE;
607     }
608 
609     devHandle = UsbRawOpenDevice(session, g_acm->busNum, g_acm->devAddr);
610     if (devHandle == NULL) {
611         HDF_LOGE("%{public}s: UsbRawOpenDevice failed", __func__);
612         return HDF_FAILURE;
613     }
614     g_acm->devHandle = devHandle;
615     ret = UsbGetConfigDescriptor(devHandle, &g_acm->config);
616     if (ret != HDF_SUCCESS) {
617         HDF_LOGE("%{public}s: UsbGetConfigDescriptor failed", __func__);
618         return HDF_FAILURE;
619     }
620     ret = UsbParseConfigDescriptor(g_acm, g_acm->config);
621     if (ret != HDF_SUCCESS) {
622         HDF_LOGE("%{public}s: UsbParseConfigDescriptor failed", __func__);
623         return HDF_FAILURE;
624     }
625     g_acm->dataSize = TEST_LENGTH;
626     g_acm->dataEp = (g_writeOrRead == TEST_WRITE) ? g_acm->dataOutEp : g_acm->dataInEp;
627 
628     ret = AcmDataBufAlloc(g_acm);
629     if (ret < 0) {
630         HDF_LOGE("%{public}s: AcmDataBufAlloc failed", __func__);
631         AcmDataBufFree(g_acm);
632         return HDF_FAILURE;
633     }
634     ret = UsbAllocDataRequests(g_acm);
635     if (ret < 0) {
636         HDF_LOGE("%{public}s: UsbAllocDataRequests failed", __func__);
637         UsbFreeDataRequests(g_acm);
638         return HDF_FAILURE;
639     }
640 
641     ret = UsbStartIo(g_acm);
642     if (ret != HDF_SUCCESS) {
643         HDF_LOGE("%{public}s: UsbAllocReadRequests failed", __func__);
644         return HDF_FAILURE;
645     }
646 
647     return ret;
648 }
649 
UsbSpeedDdkExit(const struct UsbSession * session)650 static void UsbSpeedDdkExit(const struct UsbSession *session)
651 {
652     int32_t i;
653 
654     if (UsbStopIo(g_acm) != HDF_SUCCESS) {
655         HDF_LOGE("%{public}s UsbStopIo error!", __func__);
656     }
657     if (UsbFreeDataRequests(g_acm) != HDF_SUCCESS) {
658         HDF_LOGE("%{public}s UsbFreeDataRequests error!", __func__);
659     }
660     AcmDataBufFree(g_acm);
661     for (i = 0; i < g_acm->interfaceCnt; i++) {
662         uint8_t interfaceIndex = g_acm->interfaceIndex[i];
663         UsbRawReleaseInterface(g_acm->devHandle, interfaceIndex);
664     }
665     UsbRawCloseDevice(g_acm->devHandle);
666     UsbRawExit(session);
667     OsalSemDestroy(&timeSem);
668     OsalSemDestroy(&sem);
669     g_acm->busy = false;
670 }
671 
UsbSerialSpeed(struct HdfSBuf * data)672 static int32_t UsbSerialSpeed(struct HdfSBuf *data)
673 {
674     struct UsbSession *session = NULL;
675     int32_t ret = HDF_SUCCESS;
676     int32_t ifaceNum = 3;
677     uint32_t size;
678     int32_t i;
679     struct UsbSpeedTest *input = NULL;
680 
681     if (g_acm->busy == true) {
682         printf("%s: speed test busy\n", __func__);
683         ret = HDF_ERR_IO;
684         goto END;
685     } else {
686         g_acm->busy = true;
687     }
688 
689     (void)HdfSbufReadBuffer(data, (const void **)&input, &size);
690     if ((input == NULL) || (size != sizeof(struct UsbSpeedTest))) {
691         printf("%s: sbuf read buffer failed\n", __func__);
692         ret = HDF_ERR_IO;
693         goto END;
694     }
695 
696     ret = UsbSerialSpeedInit(input, &ifaceNum);
697     if (ret != HDF_SUCCESS) {
698         goto END;
699     }
700 
701     ret = UsbSpeedDdkInit(session);
702     if (ret != HDF_SUCCESS) {
703         goto END;
704     }
705 
706     printf("test SDK rawAPI [%s]\n", g_writeOrRead ? "write" : "read");
707 
708     for (i = 0; i < TEST_CYCLE; i++) {
709         if (SerialBegin(g_acm) != HDF_SUCCESS) {
710             printf("SerialBegin error!\n");
711         }
712         g_send_count++;
713     }
714 
715     OsalSemWait(&timeSem, TEST_TIME);
716     while (!g_speedFlag) {
717         OsalSemWait(&timeSem, TEST_PRINT_TIME * TEST_PRINT_TIME_UINT);
718         SpeedPrint();
719     }
720 
721     UsbSpeedDdkExit(session);
722 END:
723     if (ret != HDF_SUCCESS) {
724         printf("please check whether usb drv so is existing or not,like acm,ecm,if not,remove it and test again!\n");
725     }
726     return ret;
727 }
728 
AcmDeviceDispatch(struct HdfDeviceIoClient * const client,int32_t cmd,struct HdfSBuf * data,struct HdfSBuf * reply)729 static int32_t AcmDeviceDispatch(
730     struct HdfDeviceIoClient * const client, int32_t cmd, struct HdfSBuf *data, struct HdfSBuf *reply)
731 {
732     (void)reply;
733     if (client == NULL) {
734         HDF_LOGE("%{public}s: client is NULL", __func__);
735         return HDF_ERR_INVALID_OBJECT;
736     }
737 
738     if (client->device == NULL) {
739         HDF_LOGE("%{public}s: client->device is NULL", __func__);
740         return HDF_ERR_INVALID_OBJECT;
741     }
742 
743     if (client->device->service == NULL) {
744         HDF_LOGE("%{public}s: client->device->service is NULL", __func__);
745         return HDF_ERR_INVALID_OBJECT;
746     }
747 
748     g_acm = (struct AcmDevice *)client->device->service;
749 
750     switch (cmd) {
751         case USB_SERIAL_OPEN:
752             return UsbSerialOpen();
753         case USB_SERIAL_CLOSE:
754             return UsbSerialClose();
755         case USB_SERIAL_SPEED:
756             return UsbSerialSpeed(data);
757         default:
758             return HDF_ERR_NOT_SUPPORT;
759     }
760 
761     return HDF_SUCCESS;
762 }
763 
AcmDriverBind(struct HdfDeviceObject * device)764 static int32_t AcmDriverBind(struct HdfDeviceObject *device)
765 {
766     if (device == NULL) {
767         HDF_LOGE("%{public}s: device is null", __func__);
768         return HDF_ERR_INVALID_OBJECT;
769     }
770 
771     g_acm = (struct AcmDevice *)OsalMemCalloc(sizeof(*g_acm));
772     if (g_acm == NULL) {
773         HDF_LOGE("%{public}s: Alloc usb acm device failed", __func__);
774         return HDF_FAILURE;
775     }
776 
777     g_acm->device = device;
778     device->service = &(g_acm->service);
779     if (g_acm->device && g_acm->device->service) {
780         g_acm->device->service->Dispatch = AcmDeviceDispatch;
781     }
782 
783     return HDF_SUCCESS;
784 }
785 
AcmDriverInit(struct HdfDeviceObject * device)786 static int32_t AcmDriverInit(struct HdfDeviceObject *device)
787 {
788     (void)device;
789     return 0;
790 }
791 
AcmDriverRelease(struct HdfDeviceObject * device)792 static void AcmDriverRelease(struct HdfDeviceObject *device)
793 {
794     (void)device;
795     return;
796 }
797 
798 struct HdfDriverEntry g_usbRawApiSpeedDriverEntry = {
799     .moduleVersion = 1,
800     .moduleName = "usb_rawapispeed",
801     .Bind = AcmDriverBind,
802     .Init = AcmDriverInit,
803     .Release = AcmDriverRelease,
804 };
805 
806 HDF_INIT(g_usbRawApiSpeedDriverEntry);
807