• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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