diff --git a/interfaces/innerkits/native/include/iusb_srv.h b/interfaces/innerkits/native/include/iusb_srv.h index 0999a78fbbe4d63f34f447c7b0ee4075c1ce2878..10d768cd2dc2112231fea566abf92941b060b0b5 100644 --- a/interfaces/innerkits/native/include/iusb_srv.h +++ b/interfaces/innerkits/native/include/iusb_srv.h @@ -77,6 +77,7 @@ public: virtual int32_t ManageDevice(int32_t vendorId, int32_t productId, bool disable) = 0; virtual int32_t ManageInterfaceStorage(InterfaceType interfaceType, bool disable) = 0; virtual int32_t ManageInterfaceType(const std::vector &disableType, bool disable) = 0; + virtual int32_t ClearHalt(uint8_t busNum, uint8_t devAddr, uint8_t interfaceid, uint8_t endpointId) = 0; virtual int32_t GetDeviceSpeed(uint8_t busNum, uint8_t devAddr, uint8_t &speed) = 0; virtual int32_t GetInterfaceActiveStatus(uint8_t busNum, uint8_t devAddr, uint8_t interfaceid, bool &unactivated) = 0; diff --git a/interfaces/innerkits/native/include/usb_srv_client.h b/interfaces/innerkits/native/include/usb_srv_client.h index d561813b420672b21c61d0d170d5806ec72be3ca..75a46e0250c580b6431adb41c663d1e9d0e93e0d 100644 --- a/interfaces/innerkits/native/include/usb_srv_client.h +++ b/interfaces/innerkits/native/include/usb_srv_client.h @@ -93,6 +93,7 @@ public: int32_t ManageDevice(int32_t vendorId, int32_t productId, bool disable); int32_t ManageInterfaceStorage(InterfaceType interfaceType, bool disable); int32_t ManageInterfaceType(const std::vector &disableType, bool disable); + int32_t ClearHalt(USBDevicePipe &pipe, const USBEndpoint &endpoint); private: UsbSrvClient(); ~UsbSrvClient(); diff --git a/interfaces/innerkits/native/src/usb_srv_client.cpp b/interfaces/innerkits/native/src/usb_srv_client.cpp index e90d119d82928d11f2777aac37a93ee466eb984f..f91377dbe547443ccaafd38cc6ef618fa86304da 100644 --- a/interfaces/innerkits/native/src/usb_srv_client.cpp +++ b/interfaces/innerkits/native/src/usb_srv_client.cpp @@ -516,6 +516,16 @@ int32_t UsbSrvClient::ManageInterfaceType(const std::vector &disa return ret; } +int32_t UsbSrvClient::ClearHalt(USBDevicePipe &pipe, const USBEndpoint &ep) +{ + RETURN_IF_WITH_RET(proxy_ == nullptr, UEC_INTERFACE_NO_INIT); + int32_t ret = proxy_->ClearHalt(pipe.GetBusNum(), pipe.GetDevAddr(), ep.GetInterfaceId(), ep.GetAddress()); + if (ret != UEC_OK) { + USB_HILOGE(MODULE_USB_INNERKIT, "ClearHalt failed ret = %{public}d !", ret); + } + return ret; +} + int32_t UsbSrvClient::GetDeviceSpeed(USBDevicePipe &pipe, uint8_t &speed) { RETURN_IF_WITH_RET(Connect() != UEC_OK, UEC_INTERFACE_NO_INIT); diff --git a/services/native/include/usb_service.h b/services/native/include/usb_service.h index f80a5c0447a93778b01a1befb24b8755b68ed99d..f3349622094de1a3f48c71e4ac485c40eeb8f719 100644 --- a/services/native/include/usb_service.h +++ b/services/native/include/usb_service.h @@ -127,6 +127,7 @@ public: int32_t ManageInterfaceStorage(InterfaceType interfaceType, bool disable) override; int32_t ManageInterfaceType(const std::vector &disableType, bool disable) override; int32_t GetInterfaceActiveStatus(uint8_t busNum, uint8_t devAddr, uint8_t interfaceid, bool &unactivated) override; + int32_t ClearHalt(uint8_t busNum, uint8_t devAddr, uint8_t interfaceId, uint8_t endpointId) override; int32_t GetDeviceSpeed(uint8_t busNum, uint8_t devAddr, uint8_t &speed) override; bool GetDeviceProductName(const std::string &deviceName, std::string &productName); diff --git a/services/native/src/usb_service.cpp b/services/native/src/usb_service.cpp index 399e20aad67889200c370fdaa1d8b95c792fb5e9..2af144a5f057d30322e0d9e0fe82386b152ea0d8 100644 --- a/services/native/src/usb_service.cpp +++ b/services/native/src/usb_service.cpp @@ -2048,6 +2048,28 @@ int32_t UsbService::ManageInterface(const HDI::Usb::V1_0::UsbDev &dev, uint8_t i } // LCOV_EXCL_STOP +// LCOV_EXCL_START +int32_t UsbService::ClearHalt(uint8_t busNum, uint8_t devAddr, uint8_t interfaceId, uint8_t endpointId) +{ + if (usbd_ == nullptr) { + USB_HILOGE(MODULE_USB_SERVICE, "ClearHalt: usbd_ is nullptr"); + return UEC_SERVICE_INVALID_VALUE; + } + + if (!UsbService::CheckDevicePermission(busNum, devAddr)) { + return UEC_SERVICE_PERMISSION_DENIED; + } + + const UsbDev dev = {busNum, devAddr}; + const UsbPipe pipe = {interfaceId, endpointId}; + int32_t ret = usbd_->ClearHalt(dev, pipe); + if (ret != UEC_OK) { + USB_HILOGE(MODULE_USB_SERVICE, "ClearHalt error ret:%{public}d", ret); + } + return ret; +} +// LCOV_EXCL_STOP + // LCOV_EXCL_START int32_t UsbService::GetInterfaceActiveStatus(uint8_t busNum, uint8_t devAddr, uint8_t interfaceid, bool &unactivated) { diff --git a/services/zidl/include/usb_server_proxy.h b/services/zidl/include/usb_server_proxy.h index 38f9097da0654695ded499978bfb97bee59397a1..9c2f3bafcaf9d900c0de0b70c3d6a0e028d2b117 100644 --- a/services/zidl/include/usb_server_proxy.h +++ b/services/zidl/include/usb_server_proxy.h @@ -85,6 +85,7 @@ public: int32_t ManageDevice(int32_t vendorId, int32_t productId, bool disable) override; int32_t ManageInterfaceStorage(InterfaceType interfaceType, bool disable) override; int32_t ManageInterfaceType(const std::vector &disableType, bool disable) override; + int32_t ClearHalt(uint8_t busNum, uint8_t devAddr, uint8_t interfaceId, uint8_t endpointId) override; int32_t GetDeviceSpeed(uint8_t busNum, uint8_t devAddr, uint8_t &speed) override; int32_t GetInterfaceActiveStatus(uint8_t busNum, uint8_t devAddr, uint8_t interfaceid, bool &unactivated) override; private: diff --git a/services/zidl/include/usb_server_stub.h b/services/zidl/include/usb_server_stub.h index 54d948cff92c89945f70e679421daf3b6439b39c..2c86d3d28543afd4719bdd0e64a489192c2ea31a 100644 --- a/services/zidl/include/usb_server_stub.h +++ b/services/zidl/include/usb_server_stub.h @@ -95,6 +95,8 @@ private: int32_t DoManageInterfaceStorage(MessageParcel &data, MessageParcel &reply, MessageOption &option); int32_t DoManageInterfaceType(MessageParcel &data, MessageParcel &reply, MessageOption &option); + int32_t DoClearHalt(MessageParcel &data, MessageParcel &reply, MessageOption &option); + int32_t DoGetDeviceSpeed(MessageParcel &data, MessageParcel &reply, MessageOption &option); int32_t DoGetInterfaceActiveStatus(MessageParcel &data, MessageParcel &reply, MessageOption &option); diff --git a/services/zidl/include/usb_service_ipc_interface_code.h b/services/zidl/include/usb_service_ipc_interface_code.h index 3c95b96c8d6ed9723c21c2b4e7c5aef7d3e8f947..a4751a0e2da244069bff5e07f48bbb2f0e922a4e 100644 --- a/services/zidl/include/usb_service_ipc_interface_code.h +++ b/services/zidl/include/usb_service_ipc_interface_code.h @@ -58,6 +58,7 @@ namespace USB { USB_FUN_DISABLE_DEVICE, USB_FUN_DISABLE_INTERFACE_STORAGE, USB_FUN_DISABLE_INTERFACE_TYPE, + USB_FUN_CLEAR_HALT, USB_FUN_GET_DEVICE_SPEED, USB_FUN_GET_DRIVER_ACTIVE_STATUS, USB_FUN_ADD_ACCESS_RIGHT, diff --git a/services/zidl/src/usb_srv_proxy.cpp b/services/zidl/src/usb_srv_proxy.cpp index 88e52b10868a60c7563fc22c4a64d74879a9a3c1..57e9eaf9e26248158584b8137e2ede7c67bd1029 100644 --- a/services/zidl/src/usb_srv_proxy.cpp +++ b/services/zidl/src/usb_srv_proxy.cpp @@ -1308,6 +1308,29 @@ int32_t UsbServerProxy::ManageInterfaceType(const std::vector &di return ret; } +int32_t UsbServerProxy::ClearHalt(uint8_t busNum, uint8_t devAddr, uint8_t interfaceId, uint8_t endpointId) +{ + sptr remote = Remote(); + RETURN_IF_WITH_RET(remote == nullptr, UEC_SERVICE_INNER_ERR); + MessageParcel data; + MessageParcel reply; + MessageOption option; + if (!data.WriteInterfaceToken(UsbServerProxy::GetDescriptor())) { + USB_HILOGE(MODULE_INNERKIT, "write descriptor failed!"); + return ERR_ENOUGH_DATA; + } + SetDeviceMessage(data, busNum, devAddr); + WRITE_PARCEL_WITH_RET(data, Uint8, interfaceId, UEC_SERVICE_WRITE_PARCEL_ERROR); + WRITE_PARCEL_WITH_RET(data, Uint8, endpointId, UEC_SERVICE_WRITE_PARCEL_ERROR); + int32_t ret = remote->SendRequest(static_cast(UsbInterfaceCode::USB_FUN_CLEAR_HALT), data, reply, option); + if (ret != UEC_OK) { + USB_HILOGE(MODULE_USB_SERVICE, "ClearHalt is failed, error code: %{public}d", ret); + return ret; + } + READ_PARCEL_WITH_RET(reply, Int32, ret, UEC_INTERFACE_READ_PARCEL_ERROR); + return ret; +} + int32_t UsbServerProxy::GetDeviceSpeed(uint8_t busNum, uint8_t devAddr, uint8_t &speed) { sptr remote = Remote(); diff --git a/services/zidl/src/usb_srv_stub.cpp b/services/zidl/src/usb_srv_stub.cpp index a1fc20d999430c08aeb626c39ca25e7dee993fcb..6189f22c8629522db5d278686d4c5094ee7b7dc8 100644 --- a/services/zidl/src/usb_srv_stub.cpp +++ b/services/zidl/src/usb_srv_stub.cpp @@ -208,6 +208,9 @@ bool UsbServerStub::StubHost( case static_cast(UsbInterfaceCode::USB_FUN_DISABLE_INTERFACE_TYPE): result = DoManageInterfaceType(data, reply, option); return true; + case static_cast(UsbInterfaceCode::USB_FUN_CLEAR_HALT): + result = DoClearHalt(data, reply, option); + return true; case static_cast(UsbInterfaceCode::USB_FUN_GET_DEVICE_SPEED): result = DoGetDeviceSpeed(data, reply, option); return true; @@ -1114,6 +1117,22 @@ int32_t UsbServerStub::DoManageInterfaceType(MessageParcel &data, MessageParcel return ret; } +int32_t UsbServerStub::DoClearHalt(MessageParcel &data, MessageParcel &reply, MessageOption &option) +{ + HITRACE_METER_NAME(HITRACE_TAG_USB, "ClearHalt"); + uint8_t busNum = 0; + uint8_t devAddr = 0; + uint8_t interfaceId = 0; + uint8_t endpointId = 0; + READ_PARCEL_WITH_RET(data, Uint8, busNum, UEC_SERVICE_WRITE_PARCEL_ERROR); + READ_PARCEL_WITH_RET(data, Uint8, devAddr, UEC_SERVICE_WRITE_PARCEL_ERROR); + READ_PARCEL_WITH_RET(data, Uint8, interfaceId, UEC_SERVICE_WRITE_PARCEL_ERROR); + READ_PARCEL_WITH_RET(data, Uint8, endpointId, UEC_SERVICE_WRITE_PARCEL_ERROR); + int32_t ret = ClearHalt(busNum, devAddr, interfaceId, endpointId); + WRITE_PARCEL_WITH_RET(reply, Int32, ret, UEC_SERVICE_WRITE_PARCEL_ERROR); + return UEC_OK; +} + int32_t UsbServerStub::DoGetInterfaceActiveStatus(MessageParcel &data, MessageParcel &reply, MessageOption &option) { uint8_t busNum = 0; diff --git a/test/native/service_unittest/src/usb_device_status_test.cpp b/test/native/service_unittest/src/usb_device_status_test.cpp index 3b443b94974b1624eb8be8de11690047454ecb57..85031b05488ceb9837ec39287b5f2c9164b83a4e 100644 --- a/test/native/service_unittest/src/usb_device_status_test.cpp +++ b/test/native/service_unittest/src/usb_device_status_test.cpp @@ -230,6 +230,48 @@ HWTEST_F(UsbDeviceStatusTest, GetDeviceSpeed004, TestSize.Level1) USB_HILOGI(MODULE_USB_SERVICE, "Case End : GetDeviceSpeed004"); } +/** + * @tc.name: ClearHalt001 + * @tc.desc: Test functions to ClearHalt + * @tc.type: FUNC + */ +HWTEST_F(UsbDeviceStatusTest, ClearHalt001, TestSize.Level1) +{ + USB_HILOGI(MODULE_USB_SERVICE, "Case Start : ClearHalt001"); + vector devi; + auto &UsbSrvClient = UsbSrvClient::GetInstance(); + auto ret = UsbSrvClient.GetDevices(devi); + EXPECT_TRUE(ret == 0); + USB_HILOGI(MODULE_USB_SERVICE, "ClearHalt001 %{public}d ret=%{public}d", __LINE__, ret); + EXPECT_TRUE(!(devi.empty())) << "delist NULL"; + USB_HILOGI(MODULE_USB_SERVICE, "ClearHalt001 %{public}d size=%{public}zu", __LINE__, + devi.size()); + USBDevicePipe pipe; + UsbDevice device = devi.front(); + UsbSrvClient.RequestRight(device.GetName()); + ret = UsbSrvClient.OpenDevice(device, pipe); + USB_HILOGI(MODULE_USB_SERVICE, "ClearHalt001 %{public}d OpenDevice=%{public}d", __LINE__, ret); + EXPECT_TRUE(ret == 0); + UsbInterface interface = device.GetConfigs().front().GetInterfaces().at(0); + ret = UsbSrvClient.ClaimInterface(pipe, interface, true); + USB_HILOGI(MODULE_USB_SERVICE, "UsbDeviceStatusTest::ClearHalt001 %{public}d ClaimInterface=%{public}d", __LINE__, + ret); + EXPECT_TRUE(ret == 0); + + if (!interface.GetEndpoints().empty()) { + USBEndpoint ep = interface.GetEndpoints().front(); + ret = UsbSrvClient.ClearHalt(pipe, ep); + USB_HILOGI(MODULE_USB_SERVICE, "ClearHalt001 %{public}d ClearHalt=%{public}d", __LINE__, ret); + } else { + USB_HILOGW(MODULE_USB_SERVICE, "ClearHalt001 %{public}d no endpoints", __LINE__); + } + + bool close = UsbSrvClient.Close(pipe); + USB_HILOGI(MODULE_USB_SERVICE, "ClearHalt001 %{public}d close=%{public}d", __LINE__, close); + EXPECT_TRUE(close); + USB_HILOGI(MODULE_USB_SERVICE, "Case End : ClearHalt001"); +} + /** * @tc.name: GetInterfaceStatus001 * @tc.desc: Test functions to GetInterfaceStatus