1 /*
2 * Copyright (c) 2022 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 <hdf_base.h>
17 #include <hdf_device_desc.h>
18 #include <hdf_log.h>
19 #include <hdf_sbuf_ipc.h>
20
21 #include "hdf_usb_pnp_manage.h"
22 #include "usb_impl.h"
23 #include "usbd_dispatcher.h"
24 #include "usbd_wrapper.h"
25 #include "v1_1/usb_interface_stub.h"
26
27 #define HDF_LOG_TAG Usbd
28
29 using namespace OHOS::HDI::Usb::V1_1;
30
31 struct HdfUsbInterfaceHost {
32 struct IDeviceIoService ioService;
33 OHOS::sptr<OHOS::IRemoteObject> stub;
34 };
35
UsbInterfaceDriverDispatch(struct HdfDeviceIoClient * client,int cmdId,struct HdfSBuf * data,struct HdfSBuf * reply)36 static int32_t UsbInterfaceDriverDispatch(
37 struct HdfDeviceIoClient *client, int cmdId, struct HdfSBuf *data, struct HdfSBuf *reply)
38 {
39 if (client == nullptr || client->device == nullptr || client->device->service == nullptr) {
40 HDF_LOGE("%{public}s:invalid param", __func__);
41 return HDF_ERR_INVALID_PARAM;
42 }
43 OHOS::MessageParcel *dataParcel = nullptr;
44 OHOS::MessageParcel *replyParcel = nullptr;
45 OHOS::MessageOption option;
46
47 if (SbufToParcel(data, &dataParcel) != HDF_SUCCESS) {
48 HDF_LOGE("%{public}s:invalid data sbuf object to dispatch", __func__);
49 return HDF_ERR_INVALID_PARAM;
50 }
51 if (SbufToParcel(reply, &replyParcel) != HDF_SUCCESS) {
52 HDF_LOGE("%{public}s:invalid reply sbuf object to dispatch", __func__);
53 return HDF_ERR_INVALID_PARAM;
54 }
55
56 auto *hdfUsbInterfaceHost = CONTAINER_OF(client->device->service, struct HdfUsbInterfaceHost, ioService);
57 if (hdfUsbInterfaceHost == nullptr || hdfUsbInterfaceHost->stub == nullptr) {
58 HDF_LOGE("%{public}s:host or stub are nullptr", __func__);
59 return HDF_ERR_INVALID_PARAM;
60 }
61 return hdfUsbInterfaceHost->stub->SendRequest(cmdId, *dataParcel, *replyParcel, option);
62 }
63
HdfUsbInterfaceDriverInit(struct HdfDeviceObject * const deviceObject)64 static int HdfUsbInterfaceDriverInit(struct HdfDeviceObject * const deviceObject)
65 {
66 if (deviceObject == nullptr) {
67 HDF_LOGE("%{public}s:deviceObject is nullptr", __func__);
68 return HDF_ERR_INVALID_OBJECT;
69 }
70 return HDF_SUCCESS;
71 }
72
HdfUsbInterfaceDriverBind(struct HdfDeviceObject * const deviceObject)73 static int HdfUsbInterfaceDriverBind(struct HdfDeviceObject * const deviceObject)
74 {
75 if (deviceObject == nullptr) {
76 HDF_LOGE("%{public}s:deviceObject is nullptr", __func__);
77 return HDF_ERR_INVALID_OBJECT;
78 }
79 auto *hdfUsbInterfaceHost = new (std::nothrow) HdfUsbInterfaceHost;
80 if (hdfUsbInterfaceHost == nullptr) {
81 HDF_LOGE("%{public}s: failed to create HdfUsbInterfaceHost object", __func__);
82 return HDF_FAILURE;
83 }
84
85 hdfUsbInterfaceHost->ioService.Dispatch = UsbInterfaceDriverDispatch;
86 hdfUsbInterfaceHost->ioService.Open = nullptr;
87 hdfUsbInterfaceHost->ioService.Release = nullptr;
88
89 auto serviceImpl = OHOS::HDI::Usb::V1_1::IUsbInterface::Get(true);
90 if (serviceImpl == nullptr) {
91 HDF_LOGE("%{public}s: failed to get of implement service", __func__);
92 delete hdfUsbInterfaceHost;
93 hdfUsbInterfaceHost = nullptr;
94 return HDF_FAILURE;
95 }
96
97 hdfUsbInterfaceHost->stub =
98 OHOS::HDI::ObjectCollector::GetInstance().GetOrNewObject(serviceImpl,
99 OHOS::HDI::Usb::V1_1::IUsbInterface::GetDescriptor());
100 if (hdfUsbInterfaceHost->stub == nullptr) {
101 HDF_LOGE("%{public}s: failed to get stub object", __func__);
102 delete hdfUsbInterfaceHost;
103 hdfUsbInterfaceHost = nullptr;
104 return HDF_FAILURE;
105 }
106
107 sptr<UsbImpl> impl = static_cast<UsbImpl *>(serviceImpl.GetRefPtr());
108 impl->device_ = deviceObject;
109 int32_t ret = UsbImpl::UsbdEventHandle(impl);
110 if (ret != HDF_SUCCESS) {
111 HDF_LOGE("%{public}s: UsbdEventHandle failed", __func__);
112 hdfUsbInterfaceHost->stub = nullptr;
113 delete hdfUsbInterfaceHost;
114 hdfUsbInterfaceHost = nullptr;
115 return HDF_FAILURE;
116 }
117
118 deviceObject->service = &hdfUsbInterfaceHost->ioService;
119 return HDF_SUCCESS;
120 }
121
HdfUsbInterfaceDriverRelease(struct HdfDeviceObject * const deviceObject)122 static void HdfUsbInterfaceDriverRelease(struct HdfDeviceObject *const deviceObject)
123 {
124 int32_t ret = UsbImpl::UsbdEventHandleRelease();
125 if (ret != HDF_SUCCESS) {
126 HDF_LOGW("%{public}s:UsbdEventHandleRelease ret=%{public}d", __func__, ret);
127 }
128
129 if (deviceObject == nullptr || deviceObject->service == nullptr) {
130 HDF_LOGE("HdfUsbInterfaceDriverRelease not initted");
131 return;
132 }
133
134 auto *hdfUsbInterfaceHost = CONTAINER_OF(deviceObject->service, struct HdfUsbInterfaceHost, ioService);
135 if (hdfUsbInterfaceHost == nullptr) {
136 HDF_LOGE("%{public}s:invalid param", __func__);
137 return;
138 }
139 delete hdfUsbInterfaceHost;
140 hdfUsbInterfaceHost = nullptr;
141 deviceObject->service = nullptr;
142 return;
143 }
144
145 static struct HdfDriverEntry g_usbInterfaceDriverEntry = {
146 .moduleVersion = 1,
147 .moduleName = "usbd",
148 .Bind = HdfUsbInterfaceDriverBind,
149 .Init = HdfUsbInterfaceDriverInit,
150 .Release = HdfUsbInterfaceDriverRelease,
151 };
152
153 #ifdef __cplusplus
154 extern "C" {
155 #endif /* __cplusplus */
156 HDF_INIT(g_usbInterfaceDriverEntry);
157 #ifdef __cplusplus
158 }
159 #endif /* __cplusplus */
160