• 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 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