1 /*
2 * Copyright (c) 2022-2023 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 <regex>
17 #include "usb_port_manager.h"
18 #include <unistd.h>
19 #include "hisysevent.h"
20 #include "usb_errors.h"
21 #include "usb_srv_support.h"
22
23 using namespace OHOS::HiviewDFX;
24 using namespace OHOS::HDI::Usb::V1_0;
25
26 namespace OHOS {
27 namespace USB {
28 constexpr int32_t SUPPORTED_MODES = 3;
29 constexpr int32_t PARAM_COUNT_TWO = 2;
30 constexpr int32_t PARAM_COUNT_THR = 3;
31 constexpr int32_t DEFAULT_ROLE_HOST = 1;
32 constexpr int32_t DEFAULT_ROLE_DEVICE = 2;
33 constexpr uint32_t CMD_INDEX = 1;
34 constexpr uint32_t PARAM_INDEX = 2;
35 constexpr int32_t HOST_MODE = 2;
36 constexpr int32_t WAIT_DELAY_US = 20000;
UsbPortManager()37 UsbPortManager::UsbPortManager()
38 {
39 USB_HILOGI(MODULE_USB_SERVICE, "UsbPortManager::Init start");
40 #ifndef USB_MANAGER_V2_0
41 GetIUsbInterface();
42 #endif // USB_MANAGER_V2_0
43 }
44
~UsbPortManager()45 UsbPortManager::~UsbPortManager()
46 {
47 USB_HILOGI(MODULE_USB_SERVICE, "UsbPortManager::unInit start");
48 }
49
Init()50 void UsbPortManager::Init()
51 {
52 USB_HILOGI(MODULE_USB_SERVICE, "UsbPortManager::QueryPort start");
53 int32_t ret = QueryPort();
54 if (ret) {
55 USB_HILOGE(MODULE_USB_SERVICE, "UsbPortManager::QueryPort false");
56 }
57 }
58
59 #ifdef USB_MANAGER_V2_0
InitUsbPortInterface()60 bool UsbPortManager::InitUsbPortInterface()
61 {
62 USB_HILOGI(MODULE_USB_SERVICE, "InitUsbPortInterface in");
63 for (int32_t i = 0; i < PARAM_COUNT_THR; i++) {
64 usbPortInterface_ = HDI::Usb::V2_0::IUsbPortInterface::Get();
65 if (usbPortInterface_ == nullptr) {
66 USB_HILOGE(MODULE_USB_SERVICE, "GetIUsbInterface get usbPortInterface_ is nullptr");
67 usleep(WAIT_DELAY_US);
68 } else {
69 break;
70 }
71 }
72 if (usbPortInterface_ == nullptr) {
73 USB_HILOGE(MODULE_USB_SERVICE, "InitUsbPortInterface get usbPortInterface_ is nullptr");
74 return false;
75 }
76 usbManagerSubscriber_ = new (std::nothrow) UsbManagerSubscriber();
77 if (usbManagerSubscriber_ == nullptr) {
78 USB_HILOGE(MODULE_USB_SERVICE, "Init failed");
79 return false;
80 }
81
82 ErrCode ret = usbPortInterface_->BindUsbdPortSubscriber(usbManagerSubscriber_);
83 USB_HILOGI(MODULE_USB_SERVICE, "entry InitUsbPortInterface ret: %{public}d", ret);
84 return SUCCEEDED(ret);
85 }
86
Stop()87 void UsbPortManager::Stop()
88 {
89 if (usbPortInterface_ == nullptr) {
90 USB_HILOGE(MODULE_USB_SERVICE, "UsbPortManager::usbPortInterface_ is nullptr");
91 return;
92 }
93 Memory::MemMgrClient::GetInstance().NotifyProcessStatus(getpid(), 1, 0, USB_SYSTEM_ABILITY_ID);
94 }
95
BindUsbdSubscriber(const sptr<HDI::Usb::V2_0::IUsbdSubscriber> & subscriber)96 int32_t UsbPortManager::BindUsbdSubscriber(const sptr<HDI::Usb::V2_0::IUsbdSubscriber> &subscriber)
97 {
98 if (usbPortInterface_ == nullptr) {
99 USB_HILOGE(MODULE_USB_SERVICE, "UsbPortManager::BulkCancel usbPortInterface_ is nullptr");
100 return UEC_SERVICE_INVALID_VALUE;
101 }
102 return usbPortInterface_->BindUsbdPortSubscriber(subscriber);
103 }
104
UnbindUsbdSubscriber(const sptr<HDI::Usb::V2_0::IUsbdSubscriber> & subscriber)105 int32_t UsbPortManager::UnbindUsbdSubscriber(const sptr<HDI::Usb::V2_0::IUsbdSubscriber> &subscriber)
106 {
107 if (usbPortInterface_ == nullptr) {
108 USB_HILOGE(MODULE_USB_SERVICE, "UsbPortManager::BulkCancel usbPortInterface_ is nullptr");
109 return UEC_SERVICE_INVALID_VALUE;
110 }
111 return usbPortInterface_->UnbindUsbdPortSubscriber(subscriber);
112 }
113 #endif // USB_MANAGER_V2_0
114
SetPortRole(int32_t portId,int32_t powerRole,int32_t dataRole)115 int32_t UsbPortManager::SetPortRole(int32_t portId, int32_t powerRole, int32_t dataRole)
116 {
117 #ifdef USB_MANAGER_V2_0
118 if (usbPortInterface_ == nullptr) {
119 USB_HILOGE(MODULE_USB_SERVICE, "UsbPortManager::SetPortRole usbPortInterface_ is nullptr");
120 return UEC_SERVICE_INVALID_VALUE;
121 }
122 return usbPortInterface_->SetPortRole(portId, powerRole, dataRole);
123 #else
124 if (usbd_ == nullptr) {
125 USB_HILOGE(MODULE_USB_SERVICE, "UsbPortManager::usbd_ is nullptr");
126 return UEC_SERVICE_INVALID_VALUE;
127 }
128 return usbd_->SetPortRole(portId, powerRole, dataRole);
129 #endif // USB_MANAGER_V2_0
130 }
131
GetIUsbInterface()132 void UsbPortManager::GetIUsbInterface()
133 {
134 if (usbd_ == nullptr) {
135 for (int32_t i = 0; i < PARAM_COUNT_THR; i++) {
136 usbd_ = IUsbInterface::Get();
137 if (usbd_ == nullptr) {
138 USB_HILOGE(MODULE_USB_SERVICE, "Get iUsbInteface failed");
139 usleep(WAIT_DELAY_US);
140 } else {
141 break;
142 }
143 }
144 }
145 }
146
SetUsbd(const sptr<IUsbInterface> & usbd)147 int32_t UsbPortManager::SetUsbd(const sptr<IUsbInterface> &usbd)
148 {
149 if (usbd == nullptr) {
150 USB_HILOGE(MODULE_USB_SERVICE, "UsbPortManager usbd is nullptr");
151 return UEC_SERVICE_INVALID_VALUE;
152 }
153 usbd_ = usbd;
154 return UEC_OK;
155 }
156
GetPorts(std::vector<UsbPort> & ports)157 int32_t UsbPortManager::GetPorts(std::vector<UsbPort> &ports)
158 {
159 std::lock_guard<std::mutex> lock(mutex_);
160 if (portMap_.size() > 0) {
161 for (auto it = portMap_.begin(); it != portMap_.end(); ++it) {
162 ports.push_back(it->second);
163 }
164 USB_HILOGI(MODULE_USB_SERVICE, "UsbPortManager::GetPorts success");
165 return UEC_OK;
166 } else {
167 int32_t ret = QueryPort();
168 if (ret == UEC_OK) {
169 for (auto it = portMap_.begin(); it != portMap_.end(); ++it) {
170 ports.push_back(it->second);
171 }
172 USB_HILOGI(MODULE_USB_SERVICE, "UsbPortManager::QueryPort and GetPorts success");
173 return ret;
174 }
175 }
176 USB_HILOGE(MODULE_USB_SERVICE, "UsbPortManager::GetPorts false");
177 return UEC_SERVICE_INVALID_VALUE;
178 }
179
GetSupportedModes(int32_t portId,int32_t & supportedModes)180 int32_t UsbPortManager::GetSupportedModes(int32_t portId, int32_t &supportedModes)
181 {
182 std::lock_guard<std::mutex> lock(mutex_);
183 auto it = portMap_.find(portId);
184 if (it != portMap_.end()) {
185 supportedModes = it->second.supportedModes;
186 USB_HILOGI(MODULE_USB_SERVICE, "UsbPortManager::GetSupportedModes success");
187 return UEC_OK;
188 }
189 USB_HILOGE(MODULE_USB_SERVICE, "UsbPortManager::GetSupportedModes false");
190 return UEC_SERVICE_INVALID_VALUE;
191 }
192
QueryPort()193 int32_t UsbPortManager::QueryPort()
194 {
195 int32_t portId = 0;
196 int32_t powerRole = 0;
197 int32_t dataRole = 0;
198 int32_t mode = 0;
199 #ifdef USB_MANAGER_V2_0
200 if (usbPortInterface_ == nullptr) {
201 USB_HILOGE(MODULE_USB_SERVICE, "UsbPortManager::QueryPort usbPortInterface_ is nullptr");
202 return UEC_SERVICE_INVALID_VALUE;
203 }
204 int32_t ret = usbPortInterface_->QueryPort(portId, powerRole, dataRole, mode);
205 #else
206 GetIUsbInterface();
207 if (usbd_ == nullptr) {
208 USB_HILOGE(MODULE_USB_SERVICE, "UsbPortManager::usbd_ is nullptr");
209 return UEC_SERVICE_INVALID_VALUE;
210 }
211 int32_t ret = usbd_->QueryPort(portId, powerRole, dataRole, mode);
212 #endif // USB_MANAGER_V2_0
213 USB_HILOGI(MODULE_USB_SERVICE, "portId:%{public}d powerRole:%{public}d dataRole:%{public}d mode:%{public}d ",
214 portId, powerRole, dataRole, mode);
215 if (ret) {
216 USB_HILOGE(MODULE_USB_SERVICE, "Get().queryPorts failed");
217 return ret;
218 }
219 UsbPortStatus usbPortStatus;
220 UsbPort usbPort;
221 usbPortStatus.currentMode = mode;
222 usbPortStatus.currentDataRole = dataRole;
223 usbPortStatus.currentPowerRole = powerRole;
224 usbPort.id = portId;
225 usbPort.supportedModes = SUPPORTED_MODES;
226 usbPort.usbPortStatus = usbPortStatus;
227 AddPort(usbPort);
228 return ret;
229 }
230
UpdatePort(int32_t portId,int32_t powerRole,int32_t dataRole,int32_t mode)231 void UsbPortManager::UpdatePort(int32_t portId, int32_t powerRole, int32_t dataRole, int32_t mode)
232 {
233 USB_HILOGI(MODULE_USB_SERVICE, "UsbPortManager::updatePort run");
234 std::lock_guard<std::mutex> lock(mutex_);
235 auto it = portMap_.find(portId);
236 if (it != portMap_.end()) {
237 if (it->second.id == portId) {
238 ReportPortRoleChangeSysEvent(it->second.usbPortStatus.currentPowerRole, powerRole,
239 it->second.usbPortStatus.currentDataRole, dataRole);
240 it->second.usbPortStatus.currentPowerRole = powerRole;
241 it->second.usbPortStatus.currentDataRole = dataRole;
242 it->second.usbPortStatus.currentMode = mode;
243 USB_HILOGI(MODULE_USB_SERVICE, "UsbPortManager::updatePort seccess");
244 return;
245 }
246 }
247 USB_HILOGE(MODULE_USB_SERVICE, "updatePort false");
248 }
249
AddPort(UsbPort & port)250 void UsbPortManager::AddPort(UsbPort &port)
251 {
252 USB_HILOGI(MODULE_USB_SERVICE, "addPort run");
253
254 auto res = portMap_.insert(std::map<int32_t, UsbPort>::value_type(port.id, port));
255 if (!res.second) {
256 USB_HILOGW(MODULE_USB_SERVICE, "addPort port id duplicated");
257 return;
258 }
259 USB_HILOGI(MODULE_USB_SERVICE, "addPort successed");
260 }
261
RemovePort(int32_t portId)262 void UsbPortManager::RemovePort(int32_t portId)
263 {
264 USB_HILOGI(MODULE_USB_SERVICE, "removePort run");
265 std::lock_guard<std::mutex> lock(mutex_);
266 size_t num = portMap_.erase(portId);
267 if (num == 0) {
268 USB_HILOGW(MODULE_USB_SERVICE, "removePort false");
269 return;
270 }
271 USB_HILOGI(MODULE_USB_SERVICE, "removePort seccess");
272 }
273
GetPortsInfo(int32_t fd)274 void UsbPortManager::GetPortsInfo(int32_t fd)
275 {
276 std::vector<UsbPort> usbports;
277 int32_t ret = GetPorts(usbports);
278 if (ret != UEC_OK) {
279 dprintf(fd, "%s:GetPorts failed\n", __func__);
280 return;
281 }
282
283 if (usbports[0].usbPortStatus.currentMode == HOST_MODE) {
284 dprintf(fd, "get current port %d: host\n", usbports[0].usbPortStatus.currentMode);
285 } else {
286 dprintf(fd, "get current port %d: device\n", usbports[0].usbPortStatus.currentMode);
287 }
288 }
289
GetDumpHelp(int32_t fd)290 void UsbPortManager::GetDumpHelp(int32_t fd)
291 {
292 dprintf(fd, "=========== dump the all device port ===========\n");
293 dprintf(fd, "usb_port -a: Query All Port List\n");
294 dprintf(fd, "usb_port -p Q: Query Port\n");
295 dprintf(fd, "usb_port -p 1: Switch to host\n");
296 dprintf(fd, "usb_port -p 2: Switch to device\n");
297 dprintf(fd, "------------------------------------------------\n");
298 }
299
DumpGetSupportPort(int32_t fd)300 void UsbPortManager::DumpGetSupportPort(int32_t fd)
301 {
302 dprintf(fd, "Usb Port device status:\n");
303 std::vector<UsbPort> ports;
304 if (GetPorts(ports) != UEC_OK) {
305 dprintf(fd, "UsbPortManager::GetPorts failed, port is empty\n");
306 return;
307 }
308
309 if (ports.size() == 0) {
310 dprintf(fd, "all port list is empty\n");
311 return;
312 }
313 for (size_t i = 0; i < ports.size(); ++i) {
314 dprintf(fd, "id: %d | supportedModes: %d | currentMode: %d | currentPowerRole: %d | currentDataRole: %d\n",
315 ports[i].id, ports[i].supportedModes, ports[i].usbPortStatus.currentMode,
316 ports[i].usbPortStatus.currentPowerRole, ports[i].usbPortStatus.currentDataRole);
317 }
318 }
319
DumpSetPortRoles(int32_t fd,const std::string & args)320 void UsbPortManager::DumpSetPortRoles(int32_t fd, const std::string &args)
321 {
322 if (args.compare("Q") == 0) {
323 GetPortsInfo(fd);
324 return;
325 }
326 #ifdef USB_MANAGER_V2_0
327 if (usbPortInterface_ == nullptr) {
328 USB_HILOGE(MODULE_USB_SERVICE, "UsbPortManager::DumpSetPortRoles usbPortInterface_ is nullptr");
329 return;
330 }
331 #else
332 if (usbd_ == nullptr) {
333 USB_HILOGE(MODULE_USB_SERVICE, "UsbPortManager::DumpSetPortRoles usbd_ is nullptr");
334 return;
335 }
336 #endif // USB_MANAGER_V2_0
337 if (!std::regex_match(args, std::regex("^[0-9]+$"))) {
338 dprintf(fd, "Invalid input, please enter a valid integer\n");
339 GetDumpHelp(fd);
340 return;
341 }
342 int32_t mode = stoi(args);
343 switch (mode) {
344 case DEFAULT_ROLE_HOST:
345 SetPortRole(
346 UsbSrvSupport::PORT_MODE_DEVICE, UsbSrvSupport::POWER_ROLE_SOURCE, UsbSrvSupport::DATA_ROLE_HOST);
347 GetPortsInfo(fd);
348 break;
349 case DEFAULT_ROLE_DEVICE:
350 SetPortRole(
351 UsbSrvSupport::PORT_MODE_DEVICE, UsbSrvSupport::POWER_ROLE_SINK, UsbSrvSupport::DATA_ROLE_DEVICE);
352 GetPortsInfo(fd);
353 break;
354 default:
355 dprintf(fd, "port param error, please enter again\n");
356 GetDumpHelp(fd);
357 }
358 }
359
Dump(int32_t fd,const std::vector<std::string> & args)360 void UsbPortManager::Dump(int32_t fd, const std::vector<std::string> &args)
361 {
362 if (args.size() < PARAM_COUNT_TWO || args.size() > PARAM_COUNT_THR) {
363 GetDumpHelp(fd);
364 return;
365 }
366
367 if (args[CMD_INDEX] == "-a" && args.size() == PARAM_COUNT_TWO) {
368 DumpGetSupportPort(fd);
369 } else if (args[CMD_INDEX] == "-p" && args.size() == PARAM_COUNT_THR) {
370 DumpSetPortRoles(fd, args[PARAM_INDEX]);
371 } else {
372 dprintf(fd, "port param error, please enter again\n");
373 GetDumpHelp(fd);
374 }
375 }
376
ReportPortRoleChangeSysEvent(int32_t currentPowerRole,int32_t updatePowerRole,int32_t currentDataRole,int32_t updateDataRole)377 void UsbPortManager::ReportPortRoleChangeSysEvent(
378 int32_t currentPowerRole, int32_t updatePowerRole, int32_t currentDataRole, int32_t updateDataRole)
379 {
380 USB_HILOGI(MODULE_USB_SERVICE, "Port switch points are as follows:");
381 HiSysEventWrite(HiSysEvent::Domain::USB, "PORT_ROLE_CHANGED",
382 HiSysEvent::EventType::BEHAVIOR, "CURRENT_POWERROLE",
383 currentPowerRole, "UPDATE_POWERROLE", updatePowerRole, "CURRENT_DATAROLE", currentDataRole, "UPDATE_DATAROLE",
384 updateDataRole);
385 }
386 } // namespace USB
387 } // namespace OHOS
388