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
48static struct AcmDevice *g_acm = NULL;
49static bool g_stopIoThreadFlag = false;
50static unsigned int g_speedFlag = 0;
51static uint64_t g_send_count = 0;
52static uint64_t g_recv_count = 0;
53static uint64_t g_byteTotal = 0;
54static bool g_writeOrRead = TEST_WRITE;
55static bool g_printData = false;
56static struct OsalSem sem;
57
58static void AcmTestBulkCallback(const void *requestArg);
59static int32_t SerialBegin(struct AcmDevice *acm);
60
61static 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
100static 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
115static 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
159static 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
196static 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
228static 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
255static 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
289static 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
312static 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}
340static 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
369static 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
385static 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
396static 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
408static 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
431static 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
473static 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
513static 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
542static 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
549static 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;
591END:
592    return ret;
593}
594
595static 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
645END:
646    return ret;
647}
648
649int32_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    }
697END:
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