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 <cstdio>
17 #include <cstring>
18 #include <unistd.h>
19 #include <gtest/gtest.h>
20 extern "C" {
21 #include "usb_host_sdk_if_test.h"
22 #include "hdf_base.h"
23 #include "hdf_log.h"
24 #include "osal_mem.h"
25 #include "osal_time.h"
26 #include "securec.h"
27 #include "usb_ddk_interface.h"
28 }
29 
30 #define USB_PIPE_DIR_OFFSET          7
31 
32 using namespace std;
33 using namespace testing::ext;
34 
35 namespace {
36 class UsbHostSdkIfTestIo : public testing::Test {
37 };
38 
39 static struct AcmDevice g_deviceService;
40 static struct AcmDevice *g_acm = &g_deviceService;
41 
AcmReadBulk(struct UsbRequest * req)42 static void AcmReadBulk(struct UsbRequest *req)
43 {
44     uint32_t size = req->compInfo.actualLength;
45     int32_t status = req->compInfo.status;
46     HDF_LOGI("%{public}s: Bulk status:%{public}d,actualLength:%{public}u", __func__, status, size);
47     return;
48 }
49 
AcmWriteBulk(struct UsbRequest * req)50 static void AcmWriteBulk(struct UsbRequest *req)
51 {
52     int32_t status;
53 
54     if (req == nullptr) {
55         HDF_LOGE("%{public}s:%{public}d req is nullptr!", __func__, __LINE__);
56         return;
57     }
58 
59     status = req->compInfo.status;
60     HDF_LOGI("%{public}s: Bulk Write status:%{public}d", __func__, status);
61     struct AcmWb *wb  = static_cast<struct AcmWb *>(req->compInfo.userData);
62     switch (status) {
63         case 0:
64             wb->use = 0;
65             break;
66         case -ECONNRESET:
67         case -ENOENT:
68         case -ESHUTDOWN:
69             return;
70         default:
71             return;
72     }
73     return;
74 }
75 
AcmWriteBufAlloc(struct AcmDevice * acm)76 static int32_t AcmWriteBufAlloc(struct AcmDevice *acm)
77 {
78     int32_t i;
79     struct AcmWb *wb;
80     for (wb = &acm->wb[0], i = 0; i < ACM_NW; i++, wb++) {
81         wb->buf = (uint8_t *)OsalMemCalloc(acm->writeSize);
82         if (!wb->buf) {
83             while (i != 0) {
84                 --i;
85                 --wb;
86                 OsalMemFree(wb->buf);
87                 wb->buf = NULL;
88             }
89             return -HDF_ERR_MALLOC_FAIL;
90         }
91     }
92     return 0;
93 }
94 
AcmCtrlIrq(struct UsbRequest * req)95 static void AcmCtrlIrq(struct UsbRequest *req)
96 {
97     if (req == nullptr) {
98         HDF_LOGE("%{public}s:%{public}d req is nullptr!", __func__, __LINE__);
99         return;
100     }
101     int32_t status = req->compInfo.status;
102     unsigned int currentSize = req->compInfo.actualLength;
103     HDF_LOGI("%{public}s: Irqstatus:%{public}d, actualLength:%{public}u", __func__, status, currentSize);
104     if (status != 0) {
105         return;
106     }
107     HDF_LOGI("%{public}s:%{public}d exit", __func__, __LINE__);
108 }
109 
UsbControlMsg(struct TestControlMsgData msgData)110 static struct UsbControlRequest UsbControlMsg(struct TestControlMsgData msgData)
111 {
112     struct UsbControlRequest dr;
113     dr.target = (UsbRequestTargetType)(msgData.requestType & TARGET_MASK);
114     dr.reqType = (UsbControlRequestType)((msgData.requestType >> USB_TYPE_OFFSET) & REQUEST_TYPE_MASK);
115     dr.directon = (UsbRequestDirection)((msgData.requestType >> USB_DIR_OFFSET) & DIRECTION_MASK);
116     dr.request = msgData.request;
117     dr.value = CPU_TO_LE16(msgData.value);
118     dr.index = CPU_TO_LE16(msgData.index);
119     dr.buffer = msgData.data;
120     dr.length = CPU_TO_LE16(msgData.size);
121     return dr;
122 }
123 
AcmGetPipe()124 static void AcmGetPipe()
125 {
126     int32_t ret;
127     UsbPipeInfo p;
128     UsbPipeInfo *pi = (UsbPipeInfo *)OsalMemCalloc(sizeof(UsbPipeInfo));
129     if (pi == nullptr) {
130         HDF_LOGE("%{public}s: sosalmemcalloc failed", __func__);
131         return;
132     }
133 
134     for (int32_t i = 0;  i <= g_acm->dataIface->info.pipeNum; i++) {
135         ret = UsbGetPipeInfo(g_acm->data_devHandle, g_acm->dataIface->info.curAltSetting, i, &p);
136         if (ret < 0) {
137             continue;
138         }
139         if ((p.pipeDirection == USB_PIPE_DIRECTION_IN) && (p.pipeType == USB_PIPE_TYPE_BULK)) {
140             EXPECT_NE(nullptr,  pi);
141             p.interfaceId = g_acm->dataIface->info.interfaceIndex;
142             *pi = p;
143             g_acm->dataInPipe = pi;
144         }
145 
146         if ((p.pipeDirection == USB_PIPE_DIRECTION_OUT) && (p.pipeType == USB_PIPE_TYPE_BULK)) {
147             EXPECT_NE(nullptr,  pi);
148             p.interfaceId = g_acm->dataIface->info.interfaceIndex;
149             *pi = p;
150             g_acm->dataOutPipe = pi;
151         }
152     }
153 
154     for (int32_t i = 0;  i <= g_acm->intIface->info.pipeNum; i++) {
155         ret = UsbGetPipeInfo(g_acm->int_devHandle, g_acm->intIface->info.curAltSetting, i, &p);
156         if (ret < 0) {
157             continue;
158         }
159         if ((p.pipeDirection == USB_PIPE_DIRECTION_IN) && (p.pipeType == USB_PIPE_TYPE_INTERRUPT)) {
160             p.interfaceId = g_acm->intIface->info.interfaceIndex;
161             *pi = p;
162             g_acm->intPipe = pi;
163             break;
164         }
165     }
166 
167     g_acm->interfaceIndex = USB_CTRL_INTERFACE_ID;
168     for (int32_t i = 0;  i <= g_acm->ctrIface->info.pipeNum; i++) {
169         ret = UsbGetPipeInfo(g_acm->ctrl_devHandle, g_acm->ctrIface->info.curAltSetting, i, &p);
170         if (ret < 0) {
171             continue;
172         }
173         if ((p.pipeDirection == USB_PIPE_DIRECTION_OUT) && (p.pipeType == USB_PIPE_TYPE_CONTROL)) {
174             p.interfaceId = g_acm->interfaceIndex;
175             *pi = p;
176             g_acm->ctrPipe = pi;
177             break;
178         }
179     }
180 }
181 
AcmGetRequest()182 static void AcmGetRequest()
183 {
184     int32_t ret;
185     int32_t i;
186     g_acm->readSize = g_acm->dataInPipe->maxPacketSize;
187     for (i = 0; i < ACM_NR; i++) {
188         g_acm->readReq[i] = UsbAllocRequest(g_acm->data_devHandle, 0, g_acm->readSize);
189         EXPECT_NE(nullptr,  g_acm->readReq[i]);
190     }
191 
192     g_acm->writeSize = g_acm->dataOutPipe->maxPacketSize;
193     ret = AcmWriteBufAlloc(g_acm);
194     EXPECT_EQ(HDF_SUCCESS, ret);
195 
196     for (i = 0; i < ACM_NW; i++) {
197         g_acm->wb[i].request = UsbAllocRequest(g_acm->data_devHandle, 0, g_acm->writeSize);
198         g_acm->wb[i].instance = g_acm;
199         EXPECT_NE(nullptr,  g_acm->wb[i].request);
200     }
201 
202     g_acm->intSize = g_acm->intPipe->maxPacketSize;
203     g_acm->notifyReq = UsbAllocRequest(g_acm->int_devHandle, 0, g_acm->intSize);
204     EXPECT_NE(nullptr,  g_acm->notifyReq);
205 
206     g_acm->ctrlSize = sizeof (struct UsbCdcLineCoding);
207     g_acm->ctrlReq = UsbAllocRequest(g_acm->ctrl_devHandle, 0, g_acm->ctrlSize);
208     EXPECT_NE(nullptr,  g_acm->ctrlReq);
209 }
210 
AcmFillReadRequest()211 static void AcmFillReadRequest()
212 {
213     int32_t i;
214     struct UsbRequestParams readParmas;
215     int32_t ret;
216     for (i = 0; i < ACM_NR; i++) {
217         readParmas.userData = (void *)g_acm;
218         readParmas.pipeAddress = g_acm->dataInPipe->pipeAddress;
219         readParmas.pipeId = g_acm->dataInPipe->pipeId;
220         readParmas.interfaceId = g_acm->dataInPipe->interfaceId;
221         readParmas.callback = AcmReadBulk;
222         readParmas.requestType = USB_REQUEST_PARAMS_DATA_TYPE;
223         readParmas.timeout = USB_CTRL_SET_TIMEOUT;
224         readParmas.dataReq.numIsoPackets = 0;
225         readParmas.dataReq.directon = (UsbRequestDirection)((g_acm->dataInPipe->pipeDirection >> USB_DIR_OFFSET) \
226             & 0x1);
227         readParmas.dataReq.length = g_acm->readSize;
228         ret = UsbFillRequest(g_acm->readReq[i], g_acm->data_devHandle, &readParmas);
229         EXPECT_EQ(HDF_SUCCESS, ret);
230     }
231 }
232 
AcmFillWriteRequest()233 static void AcmFillWriteRequest()
234 {
235     struct UsbRequestParams parmas;
236     char sendData[] = {"abcde\0"};
237     uint32_t size = strlen(sendData) + 1;
238     int32_t i;
239     int32_t ret;
240 
241     g_acm->writeSize = g_acm->dataOutPipe->maxPacketSize;
242     size = (size > g_acm->writeSize) ? g_acm->writeSize : size;
243 
244     for (i = 0; i < ACM_NW; i++) {
245         g_acm->wb[i].len = size;
246         if ((g_acm->wb[i].buf == nullptr) || (g_acm->writeSize == 0)) {
247             break;
248         }
249         ret = memcpy_s(g_acm->wb[i].buf, g_acm->writeSize, sendData, size);
250         if (ret != EOK) {
251             HDF_LOGE("%{public}s: memcpy_s failed", __func__);
252             break;
253         }
254 
255         parmas.interfaceId = g_acm->dataOutPipe->interfaceId;
256         parmas.pipeAddress = g_acm->dataOutPipe->pipeAddress;
257         parmas.pipeId = g_acm->dataOutPipe->pipeId;
258         parmas.callback = AcmWriteBulk;
259         parmas.requestType = USB_REQUEST_PARAMS_DATA_TYPE;
260         parmas.timeout = USB_CTRL_SET_TIMEOUT;
261         parmas.dataReq.numIsoPackets = 0;
262         parmas.userData = (void *)&g_acm->wb[i];
263         parmas.dataReq.length = g_acm->wb[i].len;
264         parmas.dataReq.buffer = g_acm->wb[i].buf;
265         ret = UsbFillRequest(g_acm->wb[i].request, g_acm->data_devHandle, &parmas);
266         EXPECT_EQ(HDF_SUCCESS, ret);
267     }
268 }
269 
AcmFillIntRequest()270 static void AcmFillIntRequest()
271 {
272     int32_t ret;
273     struct UsbRequestParams intParmas;
274 
275     intParmas.userData = (void *)g_acm;
276     intParmas.pipeAddress = g_acm->intPipe->pipeAddress;
277     intParmas.pipeId = g_acm->intPipe->pipeId;
278     intParmas.interfaceId = g_acm->intPipe->interfaceId;
279     intParmas.callback = AcmCtrlIrq;
280     intParmas.requestType = USB_REQUEST_PARAMS_DATA_TYPE;
281     intParmas.timeout = USB_CTRL_SET_TIMEOUT;
282     intParmas.dataReq.numIsoPackets = 0;
283     intParmas.dataReq.directon = (UsbRequestDirection)((g_acm->intPipe->pipeDirection >> USB_PIPE_DIR_OFFSET) \
284         & DIRECTION_MASK);
285     intParmas.dataReq.length = g_acm->intSize;
286     ret = UsbFillRequest(g_acm->notifyReq, g_acm->int_devHandle, &intParmas);
287     EXPECT_EQ(HDF_SUCCESS, ret);
288 }
289 
AcmFillCtrlRequest()290 static void AcmFillCtrlRequest()
291 {
292     int32_t ret;
293     struct UsbRequestParams parmas;
294     uint16_t index = 2;
295     uint16_t value = 0;
296     struct TestControlMsgData msgData = {0};
297 
298     parmas.interfaceId = USB_CTRL_INTERFACE_ID;
299     parmas.pipeAddress = 0;
300     parmas.pipeId = 0;
301     parmas.callback = AcmCtrlIrq;
302     parmas.requestType = USB_REQUEST_PARAMS_CTRL_TYPE;
303     parmas.timeout = USB_CTRL_SET_TIMEOUT;
304 
305     g_acm->lineCoding.dwDTERate = CPU_TO_LE32(DATARATE);
306     g_acm->lineCoding.bCharFormat = USB_CDC_1_STOP_BITS;
307     g_acm->lineCoding.bParityType = USB_CDC_NO_PARITY;
308     g_acm->lineCoding.bDataBits = DATA_BITS_LENGTH;
309 
310     msgData.request = USB_DDK_CDC_REQ_SET_LINE_CODING;
311     msgData.requestType = USB_DDK_TYPE_CLASS | USB_DDK_RECIP_INTERFACE;
312     msgData.value = value;
313     msgData.index = index;
314     msgData.data = &g_acm->lineCoding;
315     msgData.size = sizeof(struct UsbCdcLineCoding);
316     parmas.ctrlReq = UsbControlMsg(msgData);
317     ret = UsbFillRequest(g_acm->ctrlReq, g_acm->ctrl_devHandle, &parmas);
318     EXPECT_EQ(HDF_SUCCESS, ret);
319 }
320 
AcmInit()321 static void AcmInit()
322 {
323     int32_t ret;
324     struct UsbSession *session = nullptr;
325 
326     ret = UsbInitHostSdk(&session);
327     EXPECT_EQ(HDF_SUCCESS, ret);
328     g_acm->session = session;
329 
330     g_acm->busNum = 1U;
331     g_acm->devAddr = 2U;
332     g_acm->interfaceIndex = 3U;
333     g_acm->dataIface =  UsbClaimInterface(g_acm->session, g_acm->busNum, g_acm->devAddr, g_acm->interfaceIndex);
334     EXPECT_NE(nullptr,  g_acm->dataIface);
335 
336     g_acm->interfaceIndex = 2U;
337     g_acm->intIface =  UsbClaimInterface(g_acm->session, g_acm->busNum, g_acm->devAddr, g_acm->interfaceIndex);
338     EXPECT_NE(nullptr,  g_acm->intIface);
339 
340     g_acm->interfaceIndex = 255U;
341     g_acm->ctrIface =  UsbClaimInterface(g_acm->session, g_acm->busNum, g_acm->devAddr, g_acm->interfaceIndex);
342     EXPECT_NE(nullptr,  g_acm->ctrIface);
343 
344     g_acm->data_devHandle = UsbOpenInterface(g_acm->dataIface);
345     EXPECT_NE(nullptr,  g_acm->data_devHandle);
346     g_acm->int_devHandle = UsbOpenInterface(g_acm->intIface);
347     EXPECT_NE(nullptr,  g_acm->int_devHandle);
348     g_acm->ctrl_devHandle = UsbOpenInterface(g_acm->ctrIface);
349     EXPECT_NE(nullptr,  g_acm->ctrl_devHandle);
350 
351     AcmGetPipe();
352     AcmGetRequest();
353     AcmFillReadRequest();
354     AcmFillWriteRequest();
355     AcmFillIntRequest();
356     AcmFillCtrlRequest();
357 }
358 
359 /**
360  * @tc.number    : CheckHostSdkIfSubmitRequestSync001
361  * @tc.name      :
362  * @tc.type      : PERF
363  * @tc.level     : Level 1
364  */
365 HWTEST_F(UsbHostSdkIfTestIo, CheckHostSdkIfSubmitRequestSync001, TestSize.Level1)
366 {
367     int32_t ret;
368     int32_t i;
369     AcmInit();
370     for (i = 0; i < 1; i++) {
371         HDF_LOGI("%{public}s: ------UsbSubmitRequestSync i = [%{public}d]------", __func__, i);
372         ret = UsbSubmitRequestSync(g_acm->readReq[i]);
373         EXPECT_EQ(HDF_SUCCESS, ret);
374     }
375     OsalMemFree(g_acm->dataInPipe);
376     OsalMemFree(g_acm->dataOutPipe);
377     OsalMemFree(g_acm->intPipe);
378     OsalMemFree(g_acm->ctrPipe);
379 }
380 
381 /**
382  * @tc.number    : CheckHostSdkIfSubmitRequestSync002
383  * @tc.name      :
384  * @tc.type      : PERF
385  * @tc.level     : Level 1
386  */
387 HWTEST_F(UsbHostSdkIfTestIo, CheckHostSdkIfSubmitRequestSync002, TestSize.Level1)
388 {
389     int32_t ret;
390     int32_t i;
391 
392     for (i = 0; i < 1; i++) {
393         HDF_LOGI("%{public}s: ------UsbSubmitRequestSync i = [%{public}d]------", __func__, i);
394         ret = UsbSubmitRequestSync(g_acm->wb[i].request);
395         EXPECT_EQ(HDF_SUCCESS, ret);
396     }
397 }
398 
399 /**
400  * @tc.number    : CheckHostSdkIfSubmitRequestSync003
401  * @tc.name      :
402  * @tc.type      : PERF
403  * @tc.level     : Level 1
404  */
405 HWTEST_F(UsbHostSdkIfTestIo, CheckHostSdkIfSubmitRequestSync003, TestSize.Level1)
406 {
407     int32_t ret;
408 
409     ret = UsbSubmitRequestSync(g_acm->notifyReq);
410     EXPECT_EQ(HDF_SUCCESS, ret);
411 }
412 
413 /**
414  * @tc.number    : CheckHostSdkIfSubmitRequestSync004
415  * @tc.name      :
416  * @tc.type      : PERF
417  * @tc.level     : Level 1
418  */
419 HWTEST_F(UsbHostSdkIfTestIo, CheckHostSdkIfSubmitRequestSync004, TestSize.Level1)
420 {
421     int32_t ret;
422 
423     ret = UsbSubmitRequestSync(g_acm->notifyReq);
424     EXPECT_EQ(HDF_SUCCESS, ret);
425 }
426 
427 /**
428  * @tc.number    : CheckHostSdkIfSubmitRequestAsync001
429  * @tc.name      :
430  * @tc.type      : PERF
431  * @tc.level     : Level 1
432  */
433 HWTEST_F(UsbHostSdkIfTestIo, CheckHostSdkIfSubmitRequestAsync001, TestSize.Level1)
434 {
435     int32_t ret;
436     int32_t i;
437 
438     for (i = 0; i < ACM_NR; i++) {
439         ret = UsbSubmitRequestAsync(g_acm->readReq[i]);
440         EXPECT_EQ(HDF_SUCCESS, ret);
441     }
442 }
443 
444 /**
445  * @tc.number    : CheckHostSdkIfCancelRequest001
446  * @tc.name      :
447  * @tc.type      : PERF
448  * @tc.level     : Level 1
449  */
450 HWTEST_F(UsbHostSdkIfTestIo, CheckHostSdkIfCancelRequest001, TestSize.Level1)
451 {
452     int32_t ret;
453     int32_t i = 0;
454 
455     ret = UsbCancelRequest(g_acm->readReq[i]);
456     EXPECT_EQ(HDF_SUCCESS, ret);
457 }
458 
459 /**
460  * @tc.number    : CheckHostSdkIfSubmitRequestAsync002
461  * @tc.name      :
462  * @tc.type      : PERF
463  * @tc.level     : Level 1
464  */
465 HWTEST_F(UsbHostSdkIfTestIo, CheckHostSdkIfSubmitRequestAsync002, TestSize.Level1)
466 {
467     int32_t ret;
468     int32_t i;
469 
470     for (i = 0; i < ACM_NR; i++) {
471         ret = UsbSubmitRequestAsync(g_acm->wb[i].request);
472         EXPECT_EQ(HDF_SUCCESS, ret);
473     }
474 }
475 
476 /**
477  * @tc.number    : CheckHostSdkIfCancelRequest002
478  * @tc.name      :
479  * @tc.type      : PERF
480  * @tc.level     : Level 1
481  */
482 HWTEST_F(UsbHostSdkIfTestIo, CheckHostSdkIfCancelRequest002, TestSize.Level1)
483 {
484     int32_t ret;
485     int32_t i = 0;
486 
487     i = ACM_NR-1;
488     ret = UsbCancelRequest(g_acm->wb[i].request);
489     EXPECT_EQ(HDF_SUCCESS, ret);
490 }
491 
492 /**
493  * @tc.number    : CheckHostSdkIfSubmitRequestAsync003
494  * @tc.name      :
495  * @tc.type      : PERF
496  * @tc.level     : Level 1
497  */
498 HWTEST_F(UsbHostSdkIfTestIo, CheckHostSdkIfSubmitRequestAsync003, TestSize.Level1)
499 {
500     int32_t ret;
501 
502     ret = UsbSubmitRequestAsync(g_acm->notifyReq);
503     EXPECT_EQ(HDF_SUCCESS, ret);
504 }
505 
506 /**
507  * @tc.number    : CheckHostSdkIfCancelRequest003
508  * @tc.name      :
509  * @tc.type      : PERF
510  * @tc.level     : Level 1
511  */
512 HWTEST_F(UsbHostSdkIfTestIo, CheckHostSdkIfCancelRequest003, TestSize.Level1)
513 {
514     int32_t ret;
515 
516     ret = UsbCancelRequest(g_acm->notifyReq);
517     EXPECT_EQ(HDF_SUCCESS, ret);
518 }
519 
520 /**
521  * @tc.number    : CheckHostSdkIfSubmitRequestAsync004
522  * @tc.name      :
523  * @tc.type      : PERF
524  * @tc.level     : Level 1
525  */
526 HWTEST_F(UsbHostSdkIfTestIo, CheckHostSdkIfSubmitRequestAsync004, TestSize.Level1)
527 {
528     int32_t ret;
529 
530     ret = UsbSubmitRequestAsync(g_acm->readReq[0]);
531 
532     EXPECT_EQ(HDF_SUCCESS, ret);
533 }
534 
535 /**
536  * @tc.number    : CheckHostSdkIfCancelRequest004
537  * @tc.name      :
538  * @tc.type      : PERF
539  * @tc.level     : Level 1
540  */
541 HWTEST_F(UsbHostSdkIfTestIo, CheckHostSdkIfCancelRequest004, TestSize.Level1)
542 {
543     int32_t ret;
544 
545     ret = UsbSubmitRequestAsync(g_acm->readReq[0]);
546     EXPECT_EQ(HDF_SUCCESS, ret);
547 }
548 
549 }
550