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 using namespace OHOS::HiviewDFX;
40 constexpr uint32_t FUNCTION_VALUE_MAX_LEN = 32;
41 namespace OHOS {
42 namespace HDI {
43 namespace Usb {
44 namespace V2_0 {
45 UsbdSubscriber UsbPortImpl::subscribers_[MAX_SUBSCRIBER] = {{0}};
46 bool UsbPortImpl::isGadgetConnected_ = false;
47 std::vector<int32_t> usbPid_;
48 static const std::map<std::string, uint32_t> configMap = {
49 {HDC_CONFIG_OFF, USB_FUNCTION_NONE},
50 {HDC_CONFIG_HDC, USB_FUNCTION_HDC},
51 {HDC_CONFIG_ON, USB_FUNCTION_HDC},
52 {HDC_CONFIG_RNDIS, USB_FUNCTION_RNDIS},
53 {HDC_CONFIG_STORAGE, USB_FUNCTION_STORAGE},
54 {HDC_CONFIG_RNDIS_HDC, USB_FUNCTION_HDC + USB_FUNCTION_RNDIS},
55 {HDC_CONFIG_STORAGE_HDC, USB_FUNCTION_HDC + USB_FUNCTION_STORAGE},
56 {HDC_CONFIG_MANUFACTURE_HDC, USB_FUNCTION_MANUFACTURE}
57 };
UsbPortInterfaceImplGetInstance(void)58 extern "C" IUsbPortInterface *UsbPortInterfaceImplGetInstance(void)
59 {
60 using OHOS::HDI::Usb::V2_0::UsbPortImpl;
61 UsbPortImpl *service = new (std::nothrow) UsbPortImpl();
62 if (service == nullptr) {
63 return nullptr;
64 }
65 return service;
66 }
67
UsbPortImpl()68 UsbPortImpl::UsbPortImpl() : device_(nullptr) {}
69
~UsbPortImpl()70 UsbPortImpl::~UsbPortImpl() {}
71
SetPortRole(int32_t portId,int32_t powerRole,int32_t dataRole)72 int32_t UsbPortImpl::SetPortRole(int32_t portId, int32_t powerRole, int32_t dataRole)
73 {
74 HDF_LOGI("%{public}s: enter", __func__);
75 int32_t ret = V1_2::UsbdPort::GetInstance().SetUsbPort(portId, powerRole, dataRole, subscribers_, MAX_SUBSCRIBER);
76 if (ret != HDF_SUCCESS) {
77 HDF_LOGE("%{public}s:SetUsbPort failed, ret:%{public}d", __func__, ret);
78 return ret;
79 }
80
81 return HDF_SUCCESS;
82 }
83
QueryPort(int32_t & portId,int32_t & powerRole,int32_t & dataRole,int32_t & mode)84 int32_t UsbPortImpl::QueryPort(int32_t &portId, int32_t &powerRole, int32_t &dataRole, int32_t &mode)
85 {
86 HDF_LOGI("%{public}s: enter", __func__);
87 int32_t ret = V1_2::UsbdPort::GetInstance().QueryPort(portId, powerRole, dataRole, mode);
88 if (ret != HDF_SUCCESS) {
89 HDF_LOGE("%{public}s:QueryPort failed, ret:%{public}d", __func__, ret);
90 return ret;
91 }
92
93 return HDF_SUCCESS;
94 }
95
QueryPorts(std::vector<UsbPort> & portList)96 int32_t UsbPortImpl::QueryPorts(std::vector<UsbPort>& portList)
97 {
98 HDF_LOGE("UsbPortImpl::QueryPorts Function not supported ");
99 return HDF_SUCCESS;
100 }
101
OnRemoteDied(const wptr<IRemoteObject> & object)102 void UsbPortImpl::UsbDeathRecipient::OnRemoteDied(const wptr<IRemoteObject> &object)
103 {
104 int32_t i;
105 for (i = 0; i < MAX_SUBSCRIBER; i++) {
106 if (UsbPortImpl::subscribers_[i].subscriber == deathSubscriber_) {
107 break;
108 }
109 }
110 if (i == MAX_SUBSCRIBER) {
111 HDF_LOGE("%{public}s: current subscriber not bind", __func__);
112 return;
113 }
114 UsbPortImpl::subscribers_[i].subscriber = nullptr;
115 subscribers_[i].remote = nullptr;
116 subscribers_[i].deathRecipient = nullptr;
117 if (DdkListenerMgrRemove(&UsbPortImpl::subscribers_[i].usbPnpListener) != HDF_SUCCESS) {
118 HDF_LOGE("%{public}s: remove listener failed", __func__);
119 }
120 }
121
UsbdPnpLoaderEventReceived(void * priv,uint32_t id,HdfSBuf * data)122 int32_t UsbPortImpl::UsbdPnpLoaderEventReceived(void *priv, uint32_t id, HdfSBuf *data)
123 {
124 HDF_LOGI("%{public}s: enter %{public}u", __func__, id);
125 UsbdSubscriber *usbdSubscriber = static_cast<UsbdSubscriber *>(priv);
126 const sptr<IUsbdSubscriber> subscriber = usbdSubscriber->subscriber;
127
128 int32_t ret = HDF_SUCCESS;
129 if (id == USB_PNP_DRIVER_PORT_HOST) {
130 HITRACE_METER_NAME(HITRACE_TAG_HDF, "USB_PNP_DRIVER_PORT_HOST");
131 ret = V1_2::UsbdPort::GetInstance().UpdateUsbPort(PORT_MODE_HOST, subscriber);
132 } else if (id == USB_PNP_DRIVER_PORT_DEVICE) {
133 HITRACE_METER_NAME(HITRACE_TAG_HDF, "USB_PNP_DRIVER_PORT_DEVICE");
134 ret = V1_2::UsbdPort::GetInstance().UpdateUsbPort(PORT_MODE_DEVICE, subscriber);
135 } else {
136 HDF_LOGW("%{public}s: port not support this id %{public}u", __func__, id);
137 return HDF_ERR_NOT_SUPPORT;
138 }
139 return ret;
140 }
141
BindUsbdPortSubscriber(const sptr<IUsbdSubscriber> & subscriber)142 int32_t UsbPortImpl::BindUsbdPortSubscriber(const sptr<IUsbdSubscriber> &subscriber)
143 {
144 HDF_LOGI("%{public}s: enter", __func__);
145 int32_t i;
146 if (subscriber == nullptr) {
147 HDF_LOGE("%{public}s:subscriber is null", __func__);
148 return HDF_ERR_INVALID_PARAM;
149 }
150 const sptr<IRemoteObject> &remote = OHOS::HDI::hdi_objcast<IUsbdSubscriber>(subscriber);
151 for (i = 0; i < MAX_SUBSCRIBER; i++) {
152 if (subscribers_[i].remote == remote) {
153 break;
154 }
155 }
156 if (i < MAX_SUBSCRIBER) {
157 HDF_LOGI("%{public}s: current subscriber was bind", __func__);
158 return HDF_SUCCESS;
159 }
160 for (i = 0; i < MAX_SUBSCRIBER; i++) {
161 if (subscribers_[i].subscriber == nullptr) {
162 subscribers_[i].subscriber = subscriber;
163 subscribers_[i].impl = this;
164 subscribers_[i].usbPnpListener.callBack = UsbdPnpLoaderEventReceived;
165 subscribers_[i].usbPnpListener.priv = &subscribers_[i];
166 subscribers_[i].remote = remote;
167 subscribers_[i].deathRecipient = new UsbPortImpl::UsbDeathRecipient(subscriber);
168 if (subscribers_[i].deathRecipient == nullptr) {
169 HDF_LOGE("%{public}s: new deathRecipient failed", __func__);
170 return HDF_FAILURE;
171 }
172 bool result = subscribers_[i].remote->AddDeathRecipient(
173 static_cast<UsbDeathRecipient *>(subscribers_[i].deathRecipient));
174 if (!result) {
175 HDF_LOGE("%{public}s:AddUsbDeathRecipient failed", __func__);
176 return HDF_FAILURE;
177 }
178
179 HDF_LOGI("%{public}s: index = %{public}d", __func__, i);
180 break;
181 }
182 }
183 if (i == MAX_SUBSCRIBER) {
184 HDF_LOGE("%{public}s: too many listeners", __func__);
185 return HDF_ERR_OUT_OF_RANGE;
186 }
187 if (DdkListenerMgrAdd(&subscribers_[i].usbPnpListener) != HDF_SUCCESS) {
188 HDF_LOGE("%{public}s: register listerer failed", __func__);
189 return HDF_FAILURE;
190 }
191 return HDF_SUCCESS;
192 }
193
UnbindUsbdPortSubscriber(const sptr<IUsbdSubscriber> & subscriber)194 int32_t UsbPortImpl::UnbindUsbdPortSubscriber(const sptr<IUsbdSubscriber> &subscriber)
195 {
196 HDF_LOGI("%{public}s: enter", __func__);
197 if (subscriber == nullptr) {
198 HDF_LOGE("%{public}s:subscriber is null", __func__);
199 return HDF_ERR_INVALID_PARAM;
200 }
201 int32_t i;
202 const sptr<IRemoteObject> &remote = OHOS::HDI::hdi_objcast<IUsbdSubscriber>(subscriber);
203 for (i = 0; i < MAX_SUBSCRIBER; i++) {
204 if (subscribers_[i].remote == remote) {
205 break;
206 }
207 }
208 if (i == MAX_SUBSCRIBER) {
209 HDF_LOGE("%{public}s: current subscriber not bind", __func__);
210 return HDF_DEV_ERR_NO_DEVICE;
211 }
212 bool result = remote->RemoveDeathRecipient(static_cast<UsbDeathRecipient *>(subscribers_[i].deathRecipient));
213 if (!result) {
214 HDF_LOGE("%{public}s:RemoveUsbDeathRecipient failed", __func__);
215 return HDF_FAILURE;
216 }
217
218 subscribers_[i].subscriber = nullptr;
219 subscribers_[i].remote = nullptr;
220 subscribers_[i].deathRecipient = nullptr;
221 if (DdkListenerMgrRemove(&subscribers_[i].usbPnpListener) != HDF_SUCCESS) {
222 HDF_LOGE("%{public}s: remove listener failed", __func__);
223 return HDF_FAILURE;
224 }
225 return HDF_SUCCESS;
226 }
227
ParsePortPath()228 void UsbPortImpl::ParsePortPath()
229 {
230 HDF_LOGI("%{public}s: enter", __func__);
231 const char *path_ = nullptr;
232 const char *pathDef_ = nullptr;
233 struct DeviceResourceIface *iface = DeviceResourceGetIfaceInstance(HDF_CONFIG_SOURCE);
234 if (iface == nullptr) {
235 HDF_LOGE("%{public}s: iface is nullptr", __func__);
236 return;
237 }
238
239 if (device_ == nullptr) {
240 HDF_LOGE("%{public}s: device_ is nullptr", __func__);
241 return;
242 }
243 if (iface->GetString(device_->property, "port_file_path", &path_, pathDef_) != HDF_SUCCESS) {
244 HDF_LOGE("%{public}s: read port_file_path failed", __func__);
245 return;
246 }
247 HDF_LOGI("%{public}s: parsePortPath path_=%{public}s", __func__, path_);
248 V1_2::UsbdPort::GetInstance().setPortPath(path_);
249 return;
250 }
251
UpdateFunctionStatus()252 void UsbPortImpl::UpdateFunctionStatus()
253 {
254 HDF_LOGI("%{public}s: enter", __func__);
255 char cFunctionValue[FUNCTION_VALUE_MAX_LEN] = {0};
256 int32_t ret = GetParameter(PERSIST_SYS_USB_CONFIG, "invalid", cFunctionValue, FUNCTION_VALUE_MAX_LEN);
257 if (ret <= 0) {
258 HDF_LOGE("%{public}s: GetParameter failed", __func__);
259 }
260
261 std::string functionValue(cFunctionValue);
262 auto it = configMap.find(functionValue);
263 if (it != configMap.end()) {
264 HDF_LOGI("Function is %{public}s", functionValue.c_str());
265 ret = V1_2::UsbdFunction::UsbdUpdateFunction(it->second);
266 if (ret != HDF_SUCCESS) {
267 HDF_LOGE("%{public}s: UsbdUpdateFunction failed", __func__);
268 }
269 }
270 }
271
UsbdEventHandle(const sptr<UsbPortImpl> & inst)272 int32_t UsbPortImpl::UsbdEventHandle(const sptr<UsbPortImpl> &inst)
273 {
274 HDF_LOGI("%{public}s: enter", __func__);
275 UpdateFunctionStatus();
276 inst->ParsePortPath();
277 return HDF_SUCCESS;
278 }
279 } // namespace V2_0
280 } // namespace Usb
281 } // namespace HDI
282 } // namespace OHOS