1 /*
2 * Copyright (c) 2025 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 "usbd_async_iso_transfer_test.h"
17 #include "libusb_adapter.h"
18
19 #include <unistd.h>
20 #include <vector>
21 #include <hdf_base.h>
22
23 #include "UsbSubscriberTest.h"
24 #include "usbd_type.h"
25 #include "usbd_wrapper.h"
26 #include "v1_2/iusb_interface.h"
27
28 constexpr uint8_t INTERFACEID_IN = 1;
29 constexpr uint8_t INTERFACEID_OUT = 2;
30 constexpr uint32_t MAX_BUFFER_LENGTH = 0x0100U;
31 constexpr int32_t ASHMEM_MAX_SIZE = 1024;
32 constexpr int32_t ASYNC_TRANSFER_TIME_OUT = 1000;
33 constexpr int32_t ENDPOINT_ADDRESS_IN = 0x84; // device-to-host
34 constexpr int32_t ENDPOINT_ADDRESS_OUT = 0x5; // host-to-device
35 constexpr int32_t ISOCHRONOUS_PACKETS = 2;
36 constexpr int32_t CONNECT_TIMEOUT = 5;
37
38 using namespace testing::ext;
39 using namespace OHOS;
40 using namespace OHOS::USB;
41 using namespace OHOS::HDI::Usb::V1_2;
42 using OHOS::HDI::Usb::V1_2::USBTransferInfo;
43
44 namespace OHOS::USB::UsbdAsyncIsoTransfer {
45
46 UsbDev UsbdAsyncIsoTransferTest::dev_ = {0, 0};
47 sptr<UsbSubscriberTest> UsbdAsyncIsoTransferTest::subscriber_ = nullptr;
48 sptr<OHOS::HDI::Usb::V1_2::IUsbInterface> g_usbInterface = nullptr;
49
InitAshmemOne(sptr<Ashmem> & asmptr,int32_t asmSize,uint8_t rflg)50 int32_t InitAshmemOne(sptr<Ashmem> &asmptr, int32_t asmSize, uint8_t rflg)
51 {
52 asmptr = Ashmem::CreateAshmem("ttashmem000", asmSize);
53 if (asmptr == nullptr) {
54 HDF_LOGE("InitAshmemOne CreateAshmem failed");
55 return HDF_FAILURE;
56 }
57
58 asmptr->MapReadAndWriteAshmem();
59
60 if (rflg == 0) {
61 uint8_t tdata[ASHMEM_MAX_SIZE];
62 int32_t offset = 0;
63 int32_t tlen = 0;
64
65 int32_t retSafe = memset_s(tdata, sizeof(tdata), 'Y', ASHMEM_MAX_SIZE);
66 if (retSafe != EOK) {
67 HDF_LOGE("InitAshmemOne memset_s failed");
68 return HDF_FAILURE;
69 }
70 while (offset < asmSize) {
71 tlen = (asmSize - offset) < ASHMEM_MAX_SIZE ? (asmSize - offset) : ASHMEM_MAX_SIZE;
72 asmptr->WriteToAshmem(tdata, tlen, offset);
73 offset += tlen;
74 }
75 }
76 return HDF_SUCCESS;
77 }
78
SwitchErrCode(int32_t ret)79 int32_t SwitchErrCode(int32_t ret)
80 {
81 return ret == HDF_ERR_NOT_SUPPORT ? HDF_SUCCESS : ret;
82 }
83
SetUpTestCase(void)84 void UsbdAsyncIsoTransferTest::SetUpTestCase(void)
85 {
86 std::cout << "Please connect the device that supports Iso, and press Enter." << std::endl;
87 int c;
88 do {
89 c = getchar();
90 } while (c != '\n' && c != EOF);
91 sleep(CONNECT_TIMEOUT);
92 SubscriberEvent();
93 }
94
TearDownTestCase(void)95 void UsbdAsyncIsoTransferTest::TearDownTestCase(void)
96 {
97 g_usbInterface->UnbindUsbdSubscriber(subscriber_);
98 dev_ = {subscriber_->busNum_, subscriber_->devAddr_};
99 auto ret = g_usbInterface->CloseDevice(dev_);
100 HDF_LOGI("UsbdAsyncIsoTransferTest:: %{public}d Close=%{public}d", __LINE__, ret);
101 ASSERT_EQ(0, ret);
102 }
103
SetUp(void)104 void UsbdAsyncIsoTransferTest::SetUp(void) {}
105
TearDown(void)106 void UsbdAsyncIsoTransferTest::TearDown(void) {}
107
SubscriberEvent()108 void UsbdAsyncIsoTransferTest::SubscriberEvent()
109 {
110 g_usbInterface = OHOS::HDI::Usb::V1_2::IUsbInterface::Get();
111 if (g_usbInterface == nullptr) {
112 HDF_LOGE("%{public}s:IUsbInterface::Get() failed.", __func__);
113 exit(0);
114 }
115 subscriber_ = new UsbSubscriberTest();
116 if (subscriber_ == nullptr) {
117 HDF_LOGE("%{public}s:UsbSubscriberTest new failed.", __func__);
118 exit(0);
119 }
120
121 if (g_usbInterface->BindUsbdSubscriber(subscriber_) != HDF_SUCCESS) {
122 HDF_LOGE("%{public}s: bind usbd subscriber_ failed", __func__);
123 exit(0);
124 }
125 dev_ = {subscriber_->busNum_, subscriber_->devAddr_};
126 int32_t ret = g_usbInterface->OpenDevice(dev_);
127 HDF_LOGI("UsbdAsyncIsoTransferTest:: %{public}d OpenDevice=%{public}d", __LINE__, ret);
128 ASSERT_EQ(0, ret);
129 }
130
131 /**
132 * @tc.name: IsochronousRead001
133 * @tc.desc: Test functions to UsbSubmitTransfer
134 * @tc.desc: int32_t UsbSubmitTransfer(const UsbDev &dev, const USBTransferInfo &info,
135 * const sptr<IUsbdTransferCallback> &cb, const sptr<Ashmem> &ashmem);
136 * @tc.desc: Positive test: isochronous read, The parameters are correct.
137 * @tc.type: FUNC
138 */
139 HWTEST_F(UsbdAsyncIsoTransferTest, IsochronousRead001, TestSize.Level1)
140 {
141 HDF_LOGI("Case Start: IsochronousRead001");
142 struct UsbDev dev = dev_;
143 struct USBTransferInfo info = {
144 .endpoint = ENDPOINT_ADDRESS_IN,
145 .flags = 0,
146 .type = LIBUSB_TRANSFER_TYPE_ISOCHRONOUS,
147 .timeOut = ASYNC_TRANSFER_TIME_OUT,
148 .length = MAX_BUFFER_LENGTH,
149 .userData = 0,
150 .numIsoPackets = ISOCHRONOUS_PACKETS,
151 };
152 sptr<UsbdTransferCallbackTest> usbdBulkCallback = new UsbdTransferCallbackTest();
153 if (usbdBulkCallback == nullptr) {
154 HDF_LOGE("%{public}s:UsbdTransferCallbackTest new failed.", __func__);
155 exit(0);
156 }
157 sptr<Ashmem> ashmem;
158 int32_t asmSize = MAX_BUFFER_LENGTH;
159 uint8_t rflg = 1;
160 (void)InitAshmemOne(ashmem, asmSize, rflg);
161 auto ret = g_usbInterface->ClaimInterface(dev, INTERFACEID_IN, 1);
162 HDF_LOGI("UsbdAsyncIsoTransferTest::IsochronousRead001 %{public}d ClaimInterface=%{public}d", __LINE__, ret);
163 ret = g_usbInterface->UsbSubmitTransfer(dev, info, usbdBulkCallback, ashmem);
164 HDF_LOGI("UsbdAsyncIsoTransferTest::IsochronousRead001 %{public}d UsbSubmitTransfer=%{public}d", __LINE__, ret);
165 EXPECT_EQ(ret, 0);
166 HDF_LOGI("Case End: IsochronousRead001");
167 }
168
169 /**
170 * @tc.name: IsochronousWrite001
171 * @tc.desc: Test functions to UsbSubmitTransfer
172 * @tc.desc: int32_t UsbSubmitTransfer(const UsbDev &dev, const USBTransferInfo &info,
173 * const sptr<IUsbdTransferCallback> &cb, const sptr<Ashmem> &ashmem);
174 * @tc.desc: Positive test: isochronous write, The parameters are correct.
175 * @tc.type: FUNC
176 */
177 HWTEST_F(UsbdAsyncIsoTransferTest, IsochronousWrite001, TestSize.Level1)
178 {
179 HDF_LOGI("Case Start: IsochronousWrite001");
180 struct UsbDev dev = dev_;
181 struct USBTransferInfo info = {
182 .endpoint = ENDPOINT_ADDRESS_OUT,
183 .flags = 0,
184 .type = LIBUSB_TRANSFER_TYPE_ISOCHRONOUS,
185 .timeOut = ASYNC_TRANSFER_TIME_OUT,
186 .length = MAX_BUFFER_LENGTH,
187 .userData = 0,
188 .numIsoPackets = ISOCHRONOUS_PACKETS,
189 };
190 sptr<UsbdTransferCallbackTest> usbdBulkCallback = new UsbdTransferCallbackTest();
191 if (usbdBulkCallback == nullptr) {
192 HDF_LOGE("%{public}s:UsbdTransferCallbackTest new failed.", __func__);
193 exit(0);
194 }
195 sptr<Ashmem> ashmem;
196 int32_t asmSize = MAX_BUFFER_LENGTH;
197 uint8_t rflg = 0;
198 (void)InitAshmemOne(ashmem, asmSize, rflg);
199 auto ret = g_usbInterface->ClaimInterface(dev, INTERFACEID_OUT, 1);
200 HDF_LOGI("UsbdAsyncIsoTransferTest::IsochronousWrite001 %{public}d ClaimInterface=%{public}d", __LINE__, ret);
201 ret = g_usbInterface->UsbSubmitTransfer(dev, info, usbdBulkCallback, ashmem);
202 HDF_LOGI("UsbdAsyncIsoTransferTest::IsochronousWrite001 %{public}d UsbSubmitTransfer=%{public}d", __LINE__, ret);
203 EXPECT_EQ(ret, 0);
204 HDF_LOGI("Case End: IsochronousWrite001");
205 }
206
207 /**
208 * @tc.name: CancelIsoTransfer001
209 * @tc.desc: Test functions to UsbCancelTransfer
210 * @tc.desc: int32_t UsbCancelTransfer(const UsbDev &dev, const int32_t endpoint);
211 * @tc.desc: Positive test: the parameters are correct.
212 * @tc.type: FUNC
213 */
214 HWTEST_F(UsbdAsyncIsoTransferTest, CancelIsoTransfer001, TestSize.Level1)
215 {
216 HDF_LOGI("Case Start: CancelIsoTransfer001");
217 struct UsbDev dev = dev_;
218 struct USBTransferInfo info = {
219 .endpoint = ENDPOINT_ADDRESS_IN,
220 .flags = 0,
221 .type = LIBUSB_TRANSFER_TYPE_ISOCHRONOUS,
222 .timeOut = 0,
223 .length = MAX_BUFFER_LENGTH,
224 .userData = 0,
225 .numIsoPackets = 0,
226 };
227 sptr<UsbdTransferCallbackTest> usbdBulkCallback = new UsbdTransferCallbackTest();
228 if (usbdBulkCallback == nullptr) {
229 HDF_LOGE("%{public}s:UsbdTransferCallbackTest new failed.", __func__);
230 exit(0);
231 }
232 sptr<Ashmem> ashmem;
233 int32_t asmSize = MAX_BUFFER_LENGTH;
234 uint8_t rflg = 0;
235 (void)InitAshmemOne(ashmem, asmSize, rflg);
236 auto ret = g_usbInterface->ClaimInterface(dev, INTERFACEID_IN, 1);
237 HDF_LOGI("UsbdAsyncIsoTransferTest::CancelIsoTransfer001 %{public}d ClaimInterface=%{public}d", __LINE__, ret);
238 int32_t submitTransferRet = 0;
239 for (int i = 0; i < 10; i++) {
240 submitTransferRet = g_usbInterface->UsbSubmitTransfer(dev, info, usbdBulkCallback, ashmem);
241 HDF_LOGI("UsbdAsyncIsoTransferTest::CancelIsoTransfer001 %{public}d UsbSubmitTransfer=%{public}d",
242 __LINE__, submitTransferRet);
243 }
244 auto cancelTransferRet = g_usbInterface->UsbCancelTransfer(dev, ENDPOINT_ADDRESS_IN);
245 if (cancelTransferRet == LIBUSB_ERROR_NOT_SUPPORTED) {
246 cancelTransferRet = 0;
247 }
248 HDF_LOGI("UsbdAsyncIsoTransferTest::CancelIsoTransfer001 %{public}d UsbCancelTransfer=%{public}d",
249 __LINE__, cancelTransferRet);
250 if (cancelTransferRet == 0 || cancelTransferRet == -5) {
251 EXPECT_TRUE(true);
252 } else {
253 EXPECT_TRUE(false);
254 }
255 HDF_LOGI("Case End: CancelIsoTransfer001");
256 }
257
258 /**
259 * @tc.name: CancelIsoTransfer002
260 * @tc.desc: Test functions to UsbCancelTransfer
261 * @tc.desc: int32_t UsbCancelTransfer(const UsbDev &dev, const int32_t endpoint);
262 * @tc.desc: Positive test: the parameters are correct.
263 * @tc.type: FUNC
264 */
265 HWTEST_F(UsbdAsyncIsoTransferTest, CancelIsoTransfer002, TestSize.Level1)
266 {
267 HDF_LOGI("Case Start: CancelIsoTransfer002");
268 struct UsbDev dev = dev_;
269 struct USBTransferInfo info = {
270 .endpoint = ENDPOINT_ADDRESS_OUT,
271 .flags = 0,
272 .type = LIBUSB_TRANSFER_TYPE_ISOCHRONOUS,
273 .timeOut = 0,
274 .length = MAX_BUFFER_LENGTH,
275 .userData = 0,
276 .numIsoPackets = 0,
277 };
278 sptr<UsbdTransferCallbackTest> usbdBulkCallback = new UsbdTransferCallbackTest();
279 if (usbdBulkCallback == nullptr) {
280 HDF_LOGE("%{public}s:UsbdTransferCallbackTest new failed.", __func__);
281 exit(0);
282 }
283 sptr<Ashmem> ashmem;
284 int32_t asmSize = MAX_BUFFER_LENGTH;
285 uint8_t rflg = 0;
286 (void)InitAshmemOne(ashmem, asmSize, rflg);
287 auto ret = g_usbInterface->ClaimInterface(dev, INTERFACEID_OUT, 1);
288 HDF_LOGI("UsbdAsyncIsoTransferTest::CancelIsoTransfer002 %{public}d ClaimInterface=%{public}d", __LINE__, ret);
289 int32_t submitTransferRet = 0;
290 for (int i = 0; i < 10; i++) {
291 submitTransferRet = g_usbInterface->UsbSubmitTransfer(dev, info, usbdBulkCallback, ashmem);
292 HDF_LOGI("UsbdAsyncIsoTransferTest::CancelIsoTransfer002 %{public}d UsbSubmitTransfer=%{public}d",
293 __LINE__, submitTransferRet);
294 }
295 auto cancelTransferRet = g_usbInterface->UsbCancelTransfer(dev, ENDPOINT_ADDRESS_OUT);
296 if (cancelTransferRet == LIBUSB_ERROR_NOT_SUPPORTED) {
297 cancelTransferRet = 0;
298 }
299 HDF_LOGI("UsbdAsyncIsoTransferTest::CancelIsoTransfer002 %{public}d UsbCancelTransfer=%{public}d",
300 __LINE__, cancelTransferRet);
301 if (cancelTransferRet == 0 || cancelTransferRet == -5) {
302 EXPECT_TRUE(true);
303 } else {
304 EXPECT_TRUE(false);
305 }
306 HDF_LOGI("Case End: CancelIsoTransfer002");
307 }
308
309 /**
310 * @tc.name: CancelIsoTransfer003
311 * @tc.desc: Test functions to int32_t AsyncSubmitTransfer(const UsbDev &dev, const USBTransferInfo &info,
312 const sptr<IUsbdTransferCallback> &cb, const sptr<Ashmem> &ashmem)
313 * @tc.desc: negative test: error device busnum and devaddr
314 * @tc.type: FUNC
315 */
316 HWTEST_F(UsbdAsyncIsoTransferTest, CancelIsoTransfer003, TestSize.Level1)
317 {
318 HDF_LOGI("Case Start: CancelIsoTransfer003");
319 std::shared_ptr<LibusbAdapter> adapter = LibusbAdapter::GetInstance();
320 UsbDev device_ = {0, 0};
321 int errEndPoint = 0x12;
322
323 int32_t ret = adapter->AsyncCancelTransfer(device_, errEndPoint);
324 EXPECT_NE(ret, 0);
325 HDF_LOGI("Case End: CancelIsoTransfer003");
326 }
327
328 /**
329 * @tc.name: CancelIsoTransfer004
330 * @tc.desc: Test functions to int32_t AsyncSubmitTransfer(const UsbDev &dev, const USBTransferInfo &info,
331 const sptr<IUsbdTransferCallback> &cb, const sptr<Ashmem> &ashmem)
332 * @tc.desc: negative test: device exit and transferList is nullptr
333 * @tc.type: FUNC
334 */
335 HWTEST_F(UsbdAsyncIsoTransferTest, CancelIsoTransfer004, TestSize.Level1)
336 {
337 HDF_LOGI("Case Start: CancelIsoTransfer004");
338 std::shared_ptr<LibusbAdapter> adapter = LibusbAdapter::GetInstance();
339 UsbDev device_ = dev_;
340 int errEndPoint = 0x13;
341
342 int32_t ret = adapter->AsyncCancelTransfer(device_, errEndPoint);
343 EXPECT_NE(ret, 0);
344 HDF_LOGI("Case End: CancelIsoTransfer004");
345 }
346
347 /**
348 * @tc.name: AsyncSubmitTransfer001
349 * @tc.desc: Test functions to int32_t AsyncSubmitTransfer(const UsbDev &dev, const USBTransferInfo &info,
350 * const sptr<IUsbdTransferCallback> &cb, const sptr<Ashmem> &ashmem)
351 * @tc.desc: negative test: Wrong device bus number and bus address
352 * @tc.type: FUNC
353 */
354 HWTEST_F(UsbdAsyncIsoTransferTest, AsyncSubmitTransfer001, TestSize.Level1)
355 {
356 HDF_LOGI("Case Start: AsyncSubmitTransfer001");
357 std::shared_ptr<LibusbAdapter> adapter = LibusbAdapter::GetInstance();
358 UsbDev device_ = {1, 2};
359 USBTransferInfo usbInfo_;
360
361 int32_t ret = adapter->AsyncSubmitTransfer(device_, usbInfo_, nullptr, nullptr);
362 EXPECT_NE(ret, 0);
363 HDF_LOGI("Case End: AsyncSubmitTransfer001");
364 }
365
366 /**
367 * @tc.name: AsyncSubmitTransfer002
368 * @tc.desc: Test functions to int32_t AsyncSubmitTransfer(const UsbDev &dev, const USBTransferInfo &info,
369 * const sptr<IUsbdTransferCallback> &cb, const sptr<Ashmem> &ashmem)
370 * @tc.desc: negative test: data transfer length is zero
371 * @tc.type: FUNC
372 */
373 HWTEST_F(UsbdAsyncIsoTransferTest, AsyncSubmitTransfer002, TestSize.Level1)
374 {
375 HDF_LOGI("Case Start: AsyncSubmitTransfer002");
376 std::shared_ptr<LibusbAdapter> adapter = LibusbAdapter::GetInstance();
377 UsbDev device_ = dev_;
378 USBTransferInfo usbInfo_;
379 usbInfo_.length = 0;
380
381 int32_t ret = adapter->AsyncSubmitTransfer(device_, usbInfo_, nullptr, nullptr);
382 EXPECT_NE(ret, 0);
383 HDF_LOGI("Case End: AsyncSubmitTransfer002");
384 }
385
386 /**
387 * @tc.name: AsyncSubmitTransfer003
388 * @tc.desc: Test functions to int32_t AsyncSubmitTransfer(const UsbDev &dev, const USBTransferInfo &info,
389 * const sptr<IUsbdTransferCallback> &cb, const sptr<Ashmem> &ashmem)
390 * @tc.desc: negative test, use error endpoint
391 * @tc.type: FUNC
392 */
393 HWTEST_F(UsbdAsyncIsoTransferTest, AsyncSubmitTransfer003, TestSize.Level1)
394 {
395 HDF_LOGI("Case Start: AsyncSubmitTransfer003");
396 std::shared_ptr<LibusbAdapter> adapter = LibusbAdapter::GetInstance();
397 UsbDev device_ = dev_;
398 USBTransferInfo usbInfo_;
399 usbInfo_.endpoint = ENDPOINT_ADDRESS_IN - 0x09;
400 usbInfo_.flags = 0;
401 usbInfo_.type = LIBUSB_TRANSFER_TYPE_ISOCHRONOUS;
402 usbInfo_.timeOut = 1000;
403 usbInfo_.userData = 0;
404 usbInfo_.numIsoPackets = 0;
405 usbInfo_.length = 0;
406
407 int32_t ret = adapter->AsyncSubmitTransfer(device_, usbInfo_, nullptr, nullptr);
408 EXPECT_NE(ret, 0);
409 HDF_LOGI("Case End: AsyncSubmitTransfer003");
410 }
411 } // namespace OHOS::USB::UsbdAsyncBulkTransfer
412