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