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 "usb_port_impl.h"
17
18 #include <cerrno>
19 #include <climits>
20 #include <fcntl.h>
21 #include <hdf_base.h>
22 #include <hdf_log.h>
23 #include <sys/mman.h>
24 #include <sys/stat.h>
25 #include <sys/types.h>
26 #include <unistd.h>
27
28 #include "ddk_device_manager.h"
29 #include "ddk_pnp_listener_mgr.h"
30 #include "ddk_uevent_handle.h"
31 #include "device_resource_if.h"
32 #include "hitrace_meter.h"
33 #include "ipc_skeleton.h"
34 #include "parameter.h"
35 #include "parameters.h"
36 #include "usbd_wrapper.h"
37
38 #define HDF_LOG_TAG UsbPortImpl
39 constexpr int32_t DEFAULT_DEVICE_ROLE = 2;
40 using namespace OHOS::HiviewDFX;
41 bool g_productFlag = false;
42 namespace OHOS {
43 namespace HDI {
44 namespace Usb {
45 namespace V2_0 {
46 UsbdSubscriber UsbPortImpl::subscribers_[MAX_SUBSCRIBER] = {{0}};
47 bool UsbPortImpl::isGadgetConnected_ = false;
48 std::vector<int32_t> usbPid_;
UsbPortInterfaceImplGetInstance(void)49 extern "C" IUsbPortInterface *UsbPortInterfaceImplGetInstance(void)
50 {
51 using OHOS::HDI::Usb::V2_0::UsbPortImpl;
52 UsbPortImpl *service = new (std::nothrow) UsbPortImpl();
53 if (service == nullptr) {
54 return nullptr;
55 }
56 return service;
57 }
58
UsbPortImpl()59 UsbPortImpl::UsbPortImpl() : device_(nullptr) {}
60
~UsbPortImpl()61 UsbPortImpl::~UsbPortImpl() {}
62
SetPortRole(int32_t portId,int32_t powerRole,int32_t dataRole)63 int32_t UsbPortImpl::SetPortRole(int32_t portId, int32_t powerRole, int32_t dataRole)
64 {
65 HDF_LOGI("%{public}s: enter", __func__);
66 int32_t ret = 0;
67 if (g_productFlag) {
68 ret = V1_2::UsbdPorts::GetInstance().SetPort(portId, powerRole, dataRole, subscribers_, MAX_SUBSCRIBER);
69 } else {
70 ret = V1_2::UsbdPort::GetInstance().SetUsbPort(portId, powerRole, dataRole, subscribers_, MAX_SUBSCRIBER);
71 }
72
73 if (ret != HDF_SUCCESS) {
74 HDF_LOGE("%{public}s:SetUsbPort failed, ret:%{public}d", __func__, ret);
75 return ret;
76 }
77
78 return HDF_SUCCESS;
79 }
80
QueryPort(int32_t & portId,int32_t & powerRole,int32_t & dataRole,int32_t & mode)81 int32_t UsbPortImpl::QueryPort(int32_t &portId, int32_t &powerRole, int32_t &dataRole, int32_t &mode)
82 {
83 HDF_LOGI("%{public}s: enter", __func__);
84 int32_t ret = 0;
85 if (g_productFlag) {
86 ret = V1_2::UsbdPorts::GetInstance().QueryPort(portId, powerRole, dataRole, mode);
87 } else {
88 ret = V1_2::UsbdPort::GetInstance().QueryPort(portId, powerRole, dataRole, mode);
89 }
90 if (ret != HDF_SUCCESS) {
91 HDF_LOGE("%{public}s:QueryPort failed, ret:%{public}d", __func__, ret);
92 return ret;
93 }
94
95 return HDF_SUCCESS;
96 }
97
QueryPorts(std::vector<UsbPort> & portList)98 int32_t UsbPortImpl::QueryPorts(std::vector<UsbPort>& portList)
99 {
100 HDF_LOGI("%{public}s: enter", __func__);
101 int32_t ret = 0;
102 if (g_productFlag) {
103 ret = V1_2::UsbdPorts::GetInstance().QueryPorts(portList);
104 if (ret != HDF_SUCCESS) {
105 HDF_LOGE("%{public}s:QueryPorts failed, ret:%{public}d", __func__, ret);
106 return ret;
107 }
108 if (!portList.empty()) {
109 portList[0].usbPortStatus.currentDataRole = DEFAULT_DEVICE_ROLE;
110 }
111 return HDF_SUCCESS;
112 }
113 int32_t portId = 0;
114 int32_t powerRole = 0;
115 int32_t dataRole = 0;
116 int32_t mode = 0;
117 ret = V1_2::UsbdPort::GetInstance().QueryPort(portId, powerRole, dataRole, mode);
118 if (ret != HDF_SUCCESS) {
119 HDF_LOGE("%{public}s:QueryPorts failed, ret:%{public}d", __func__, ret);
120 return ret;
121 }
122
123 UsbPort port;
124 port.id = portId;
125 int32_t supportedModes = 0;
126 ret = V1_2::UsbdPort::GetInstance().GetSupportedModes(supportedModes);
127 if (ret != HDF_SUCCESS) {
128 HDF_LOGE("%{public}s:GetSupportedModes, ret:%{public}d", __func__, ret);
129 return ret;
130 }
131 port.supportedModes = supportedModes;
132 port.usbPortStatus.currentMode = mode;
133 port.usbPortStatus.currentPowerRole = powerRole;
134 port.usbPortStatus.currentDataRole = dataRole;
135 portList.push_back(port);
136 return HDF_SUCCESS;
137 }
138
OnRemoteDied(const wptr<IRemoteObject> & object)139 void UsbPortImpl::UsbDeathRecipient::OnRemoteDied(const wptr<IRemoteObject> &object)
140 {
141 int32_t i;
142 for (i = 0; i < MAX_SUBSCRIBER; i++) {
143 if (UsbPortImpl::subscribers_[i].subscriber == deathSubscriber_) {
144 break;
145 }
146 }
147 if (i == MAX_SUBSCRIBER) {
148 HDF_LOGE("%{public}s: current subscriber not bind", __func__);
149 return;
150 }
151 UsbPortImpl::subscribers_[i].subscriber = nullptr;
152 subscribers_[i].remote = nullptr;
153 subscribers_[i].deathRecipient = nullptr;
154 if (DdkListenerMgrRemove(&UsbPortImpl::subscribers_[i].usbPnpListener) != HDF_SUCCESS) {
155 HDF_LOGE("%{public}s: remove listener failed", __func__);
156 }
157 }
158
UsbdPnpLoaderEventReceived(void * priv,uint32_t id,HdfSBuf * data)159 int32_t UsbPortImpl::UsbdPnpLoaderEventReceived(void *priv, uint32_t id, HdfSBuf *data)
160 {
161 HDF_LOGI("%{public}s: enter %{public}u", __func__, id);
162 UsbdSubscriber *usbdSubscriber = static_cast<UsbdSubscriber *>(priv);
163 const sptr<IUsbdSubscriber> subscriber = usbdSubscriber->subscriber;
164
165 int32_t ret = HDF_SUCCESS;
166 if (id == USB_PNP_DRIVER_PORT_HOST) {
167 HITRACE_METER_NAME(HITRACE_TAG_HDF, "USB_PNP_DRIVER_PORT_HOST");
168 if (g_productFlag) {
169 return V1_2::UsbdPorts::GetInstance().UpdatePort(PORT_MODE_HOST, subscriber);
170 } else {
171 return V1_2::UsbdPort::GetInstance().UpdateUsbPort(PORT_MODE_HOST, subscriber);
172 }
173 } else if (id == USB_PNP_DRIVER_PORT_DEVICE) {
174 HITRACE_METER_NAME(HITRACE_TAG_HDF, "USB_PNP_DRIVER_PORT_DEVICE");
175 if (g_productFlag) {
176 return V1_2::UsbdPorts::GetInstance().UpdatePort(PORT_MODE_DEVICE, subscriber);
177 } else {
178 return V1_2::UsbdPort::GetInstance().UpdateUsbPort(PORT_MODE_DEVICE, subscriber);
179 }
180 } else {
181 HDF_LOGW("%{public}s: port not support this id %{public}u", __func__, id);
182 return HDF_ERR_NOT_SUPPORT;
183 }
184 return ret;
185 }
186
BindUsbdPortSubscriber(const sptr<IUsbdSubscriber> & subscriber)187 int32_t UsbPortImpl::BindUsbdPortSubscriber(const sptr<IUsbdSubscriber> &subscriber)
188 {
189 HDF_LOGI("%{public}s: enter", __func__);
190 int32_t i;
191 if (subscriber == nullptr) {
192 HDF_LOGE("%{public}s:subscriber is null", __func__);
193 return HDF_ERR_INVALID_PARAM;
194 }
195 const sptr<IRemoteObject> &remote = OHOS::HDI::hdi_objcast<IUsbdSubscriber>(subscriber);
196 for (i = 0; i < MAX_SUBSCRIBER; i++) {
197 if (subscribers_[i].remote == remote) {
198 break;
199 }
200 }
201 if (i < MAX_SUBSCRIBER) {
202 HDF_LOGI("%{public}s: current subscriber was bind", __func__);
203 return HDF_SUCCESS;
204 }
205 for (i = 0; i < MAX_SUBSCRIBER; i++) {
206 if (subscribers_[i].subscriber == nullptr) {
207 subscribers_[i].subscriber = subscriber;
208 subscribers_[i].impl = this;
209 subscribers_[i].usbPnpListener.callBack = UsbdPnpLoaderEventReceived;
210 subscribers_[i].usbPnpListener.priv = &subscribers_[i];
211 subscribers_[i].remote = remote;
212 subscribers_[i].deathRecipient = new UsbPortImpl::UsbDeathRecipient(subscriber);
213 if (subscribers_[i].deathRecipient == nullptr) {
214 HDF_LOGE("%{public}s: new deathRecipient failed", __func__);
215 return HDF_FAILURE;
216 }
217 bool result = subscribers_[i].remote->AddDeathRecipient(
218 static_cast<UsbDeathRecipient *>(subscribers_[i].deathRecipient));
219 if (!result) {
220 HDF_LOGE("%{public}s:AddUsbDeathRecipient failed", __func__);
221 return HDF_FAILURE;
222 }
223
224 HDF_LOGI("%{public}s: index = %{public}d", __func__, i);
225 break;
226 }
227 }
228 if (i == MAX_SUBSCRIBER) {
229 HDF_LOGE("%{public}s: too many listeners", __func__);
230 return HDF_ERR_OUT_OF_RANGE;
231 }
232 if (DdkListenerMgrAdd(&subscribers_[i].usbPnpListener) != HDF_SUCCESS) {
233 HDF_LOGE("%{public}s: register listerer failed", __func__);
234 return HDF_FAILURE;
235 }
236 return HDF_SUCCESS;
237 }
238
UnbindUsbdPortSubscriber(const sptr<IUsbdSubscriber> & subscriber)239 int32_t UsbPortImpl::UnbindUsbdPortSubscriber(const sptr<IUsbdSubscriber> &subscriber)
240 {
241 HDF_LOGI("%{public}s: enter", __func__);
242 if (subscriber == nullptr) {
243 HDF_LOGE("%{public}s:subscriber is null", __func__);
244 return HDF_ERR_INVALID_PARAM;
245 }
246 int32_t i;
247 const sptr<IRemoteObject> &remote = OHOS::HDI::hdi_objcast<IUsbdSubscriber>(subscriber);
248 for (i = 0; i < MAX_SUBSCRIBER; i++) {
249 if (subscribers_[i].remote == remote) {
250 break;
251 }
252 }
253 if (i == MAX_SUBSCRIBER) {
254 HDF_LOGE("%{public}s: current subscriber not bind", __func__);
255 return HDF_DEV_ERR_NO_DEVICE;
256 }
257 bool result = remote->RemoveDeathRecipient(static_cast<UsbDeathRecipient *>(subscribers_[i].deathRecipient));
258 if (!result) {
259 HDF_LOGE("%{public}s:RemoveUsbDeathRecipient failed", __func__);
260 return HDF_FAILURE;
261 }
262
263 subscribers_[i].subscriber = nullptr;
264 subscribers_[i].remote = nullptr;
265 subscribers_[i].deathRecipient = nullptr;
266 if (DdkListenerMgrRemove(&subscribers_[i].usbPnpListener) != HDF_SUCCESS) {
267 HDF_LOGE("%{public}s: remove listener failed", __func__);
268 return HDF_FAILURE;
269 }
270 return HDF_SUCCESS;
271 }
272
ParsePortPath()273 void UsbPortImpl::ParsePortPath()
274 {
275 HDF_LOGI("%{public}s: enter", __func__);
276 const char *path_ = nullptr;
277 const char *pathDef_ = nullptr;
278 struct DeviceResourceIface *iface = DeviceResourceGetIfaceInstance(HDF_CONFIG_SOURCE);
279 if (iface == nullptr) {
280 HDF_LOGE("%{public}s: iface is nullptr", __func__);
281 return;
282 }
283
284 if (device_ == nullptr) {
285 HDF_LOGE("%{public}s: device_ is nullptr", __func__);
286 return;
287 }
288 if (iface->GetString(device_->property, "port_file_path", &path_, pathDef_) != HDF_SUCCESS) {
289 HDF_LOGE("%{public}s: read port_file_path failed", __func__);
290 return;
291 }
292 HDF_LOGI("%{public}s: parsePortPath path_=%{public}s", __func__, path_);
293
294 if (strcmp(path_, "/sys/class/dual_role_pd/") == 0) {
295 g_productFlag = true;
296 V1_2::UsbdPorts::GetInstance().setPortPath(path_);
297 return;
298 }
299
300 g_productFlag = false;
301 V1_2::UsbdPort::GetInstance().setPortPath(path_);
302 return;
303 }
304
UsbdEventHandle(const sptr<UsbPortImpl> & inst)305 int32_t UsbPortImpl::UsbdEventHandle(const sptr<UsbPortImpl> &inst)
306 {
307 HDF_LOGI("%{public}s: enter", __func__);
308 inst->ParsePortPath();
309 return HDF_SUCCESS;
310 }
311 } // namespace V2_0
312 } // namespace Usb
313 } // namespace HDI
314 } // namespace OHOS
315