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 "usb_port_manager.h"
17 #include "hisysevent.h"
18 #include "usb_errors.h"
19 #include "usb_srv_support.h"
20
21 using namespace OHOS::HiviewDFX;
22 using namespace OHOS::HDI::Usb::V1_0;
23
24 namespace OHOS {
25 namespace USB {
26 constexpr int32_t SUPPORTED_MODES = 3;
27 constexpr int32_t PARAM_COUNT_TWO = 2;
28 constexpr int32_t PARAM_COUNT_THR = 3;
29 constexpr int32_t DEFAULT_ROLE_HOST = 1;
30 constexpr int32_t DEFAULT_ROLE_DEVICE = 2;
31 constexpr uint32_t CMD_INDEX = 1;
32 constexpr uint32_t PARAM_INDEX = 2;
33 constexpr int32_t HOST_MODE = 2;
UsbPortManager()34 UsbPortManager::UsbPortManager()
35 {
36 USB_HILOGI(MODULE_USB_SERVICE, "UsbPortManager::Init start");
37 usbd_ = IUsbInterface::Get();
38 if (usbd_ == nullptr) {
39 USB_HILOGE(MODULE_USB_SERVICE, "UsbPortManager::Get inteface failed");
40 }
41 }
42
~UsbPortManager()43 UsbPortManager::~UsbPortManager()
44 {
45 USB_HILOGI(MODULE_USB_SERVICE, "UsbPortManager::unInit start");
46 }
47
Init()48 void UsbPortManager::Init()
49 {
50 USB_HILOGI(MODULE_USB_SERVICE, "UsbPortManager::QueryPort start");
51 int32_t ret = QueryPort();
52 if (ret) {
53 USB_HILOGE(MODULE_USB_SERVICE, "UsbPortManager::QueryPort false");
54 }
55 }
56
SetUsbd(const sptr<IUsbInterface> & usbd)57 int32_t UsbPortManager::SetUsbd(const sptr<IUsbInterface> &usbd)
58 {
59 if (usbd == nullptr) {
60 USB_HILOGE(MODULE_USB_SERVICE, "UsbPortManager usbd is nullptr");
61 return UEC_SERVICE_INVALID_VALUE;
62 }
63 usbd_ = usbd;
64 return UEC_OK;
65 }
66
GetPorts(std::vector<UsbPort> & ports)67 int32_t UsbPortManager::GetPorts(std::vector<UsbPort> &ports)
68 {
69 std::lock_guard<std::mutex> lock(mutex_);
70 if (portMap_.size() > 0) {
71 for (auto it = portMap_.begin(); it != portMap_.end(); ++it) {
72 ports.push_back(it->second);
73 }
74 USB_HILOGI(MODULE_USB_SERVICE, "UsbPortManager::GetPorts success");
75 return UEC_OK;
76 } else {
77 int32_t ret = QueryPort();
78 if (ret == UEC_OK) {
79 for (auto it = portMap_.begin(); it != portMap_.end(); ++it) {
80 ports.push_back(it->second);
81 }
82 USB_HILOGI(MODULE_USB_SERVICE, "UsbPortManager::QueryPort and GetPorts success");
83 return ret;
84 }
85 }
86 USB_HILOGE(MODULE_USB_SERVICE, "UsbPortManager::GetPorts false");
87 return UEC_SERVICE_INVALID_VALUE;
88 }
89
GetSupportedModes(int32_t portId,int32_t & supportedModes)90 int32_t UsbPortManager::GetSupportedModes(int32_t portId, int32_t &supportedModes)
91 {
92 std::lock_guard<std::mutex> lock(mutex_);
93 auto it = portMap_.find(portId);
94 if (it != portMap_.end()) {
95 supportedModes = it->second.supportedModes;
96 USB_HILOGI(MODULE_USB_SERVICE, "UsbPortManager::GetSupportedModes success");
97 return UEC_OK;
98 }
99 USB_HILOGE(MODULE_USB_SERVICE, "UsbPortManager::GetSupportedModes false");
100 return UEC_SERVICE_INVALID_VALUE;
101 }
102
QueryPort()103 int32_t UsbPortManager::QueryPort()
104 {
105 int32_t portId = 0;
106 int32_t powerRole = 0;
107 int32_t dataRole = 0;
108 int32_t mode = 0;
109
110 if (usbd_ == nullptr) {
111 USB_HILOGE(MODULE_USB_SERVICE, "UsbPortManager::usbd_ is nullptr");
112 return UEC_SERVICE_INVALID_VALUE;
113 }
114 int32_t ret = usbd_->QueryPort(portId, powerRole, dataRole, mode);
115 USB_HILOGI(MODULE_USB_SERVICE, "portId:%{public}d powerRole:%{public}d dataRole:%{public}d mode:%{public}d ",
116 portId, powerRole, dataRole, mode);
117 if (ret) {
118 USB_HILOGE(MODULE_USB_SERVICE, "Get().queryPorts failed");
119 return ret;
120 }
121 UsbPortStatus usbPortStatus;
122 UsbPort usbPort;
123 usbPortStatus.currentMode = mode;
124 usbPortStatus.currentDataRole = dataRole;
125 usbPortStatus.currentPowerRole = powerRole;
126 usbPort.id = portId;
127 usbPort.supportedModes = SUPPORTED_MODES;
128 usbPort.usbPortStatus = usbPortStatus;
129 AddPort(usbPort);
130 return ret;
131 }
132
UpdatePort(int32_t portId,int32_t powerRole,int32_t dataRole,int32_t mode)133 void UsbPortManager::UpdatePort(int32_t portId, int32_t powerRole, int32_t dataRole, int32_t mode)
134 {
135 USB_HILOGI(MODULE_USB_SERVICE, "UsbPortManager::updatePort run");
136 std::lock_guard<std::mutex> lock(mutex_);
137 auto it = portMap_.find(portId);
138 if (it != portMap_.end()) {
139 if (it->second.id == portId) {
140 ReportPortRoleChangeSysEvent(it->second.usbPortStatus.currentPowerRole, powerRole,
141 it->second.usbPortStatus.currentDataRole, dataRole);
142 it->second.usbPortStatus.currentPowerRole = powerRole;
143 it->second.usbPortStatus.currentDataRole = dataRole;
144 it->second.usbPortStatus.currentMode = mode;
145 USB_HILOGI(MODULE_USB_SERVICE, "UsbPortManager::updatePort seccess");
146 return;
147 }
148 }
149 USB_HILOGE(MODULE_USB_SERVICE, "updatePort false");
150 }
151
AddPort(UsbPort & port)152 void UsbPortManager::AddPort(UsbPort &port)
153 {
154 USB_HILOGI(MODULE_USB_SERVICE, "addPort run");
155
156 auto res = portMap_.insert(std::map<int32_t, UsbPort>::value_type(port.id, port));
157 if (!res.second) {
158 USB_HILOGW(MODULE_USB_SERVICE, "addPort port id duplicated");
159 return;
160 }
161 USB_HILOGI(MODULE_USB_SERVICE, "addPort successed");
162 }
163
RemovePort(int32_t portId)164 void UsbPortManager::RemovePort(int32_t portId)
165 {
166 USB_HILOGI(MODULE_USB_SERVICE, "removePort run");
167 std::lock_guard<std::mutex> lock(mutex_);
168 size_t num = portMap_.erase(portId);
169 if (num == 0) {
170 USB_HILOGW(MODULE_USB_SERVICE, "removePort false");
171 return;
172 }
173 USB_HILOGI(MODULE_USB_SERVICE, "removePort seccess");
174 }
175
GetPortsInfo(int32_t fd)176 void UsbPortManager::GetPortsInfo(int32_t fd)
177 {
178 std::vector<UsbPort> usbports;
179 int32_t ret = GetPorts(usbports);
180 if (ret != UEC_OK) {
181 dprintf(fd, "%s:GetPorts failed\n", __func__);
182 return;
183 }
184
185 if (usbports[0].usbPortStatus.currentMode == HOST_MODE) {
186 dprintf(fd, "get current port %d: host\n", usbports[0].usbPortStatus.currentMode);
187 } else {
188 dprintf(fd, "get current port %d: device\n", usbports[0].usbPortStatus.currentMode);
189 }
190 }
191
GetDumpHelp(int32_t fd)192 void UsbPortManager::GetDumpHelp(int32_t fd)
193 {
194 dprintf(fd, "=========== dump the all device port ===========\n");
195 dprintf(fd, "usb_port -a: Query All Port List\n");
196 dprintf(fd, "usb_port -p Q: Query Port\n");
197 dprintf(fd, "usb_port -p 1: Switch to host\n");
198 dprintf(fd, "usb_port -p 2: Switch to device\n");
199 dprintf(fd, "------------------------------------------------\n");
200 }
201
DumpGetSupportPort(int32_t fd)202 void UsbPortManager::DumpGetSupportPort(int32_t fd)
203 {
204 dprintf(fd, "Usb Port device status:\n");
205 std::vector<UsbPort> ports;
206 if (GetPorts(ports) != UEC_OK) {
207 dprintf(fd, "UsbPortManager::GetPorts failed, port is empty\n");
208 return;
209 }
210
211 if (ports.size() == 0) {
212 dprintf(fd, "all port list is empty\n");
213 return;
214 }
215 for (size_t i = 0; i < ports.size(); ++i) {
216 dprintf(fd, "id: %d | supportedModes: %d | currentMode: %d | currentPowerRole: %d | currentDataRole: %d\n",
217 ports[i].id, ports[i].supportedModes, ports[i].usbPortStatus.currentMode,
218 ports[i].usbPortStatus.currentPowerRole, ports[i].usbPortStatus.currentDataRole);
219 }
220 }
221
DumpSetPortRoles(int32_t fd,const std::string & args)222 void UsbPortManager::DumpSetPortRoles(int32_t fd, const std::string &args)
223 {
224 if (args.compare("Q") == 0) {
225 GetPortsInfo(fd);
226 return;
227 }
228
229 int32_t mode = stoi(args);
230 switch (mode) {
231 case DEFAULT_ROLE_HOST:
232 usbd_->SetPortRole(
233 UsbSrvSupport::PORT_MODE_DEVICE, UsbSrvSupport::POWER_ROLE_SOURCE, UsbSrvSupport::DATA_ROLE_HOST);
234 GetPortsInfo(fd);
235 break;
236 case DEFAULT_ROLE_DEVICE:
237 usbd_->SetPortRole(
238 UsbSrvSupport::PORT_MODE_DEVICE, UsbSrvSupport::POWER_ROLE_SINK, UsbSrvSupport::DATA_ROLE_DEVICE);
239 GetPortsInfo(fd);
240 break;
241 default:
242 dprintf(fd, "port param error, please enter again\n");
243 GetDumpHelp(fd);
244 }
245 }
246
Dump(int32_t fd,const std::vector<std::string> & args)247 void UsbPortManager::Dump(int32_t fd, const std::vector<std::string> &args)
248 {
249 if (args.size() < PARAM_COUNT_TWO || args.size() > PARAM_COUNT_THR) {
250 GetDumpHelp(fd);
251 return;
252 }
253
254 if (args[CMD_INDEX] == "-a" && args.size() == PARAM_COUNT_TWO) {
255 DumpGetSupportPort(fd);
256 } else if (args[CMD_INDEX] == "-p" && args.size() == PARAM_COUNT_THR) {
257 DumpSetPortRoles(fd, args[PARAM_INDEX]);
258 } else {
259 dprintf(fd, "port param error, please enter again\n");
260 GetDumpHelp(fd);
261 }
262 }
263
ReportPortRoleChangeSysEvent(int32_t currentPowerRole,int32_t updatePowerRole,int32_t currentDataRole,int32_t updateDataRole)264 void UsbPortManager::ReportPortRoleChangeSysEvent(
265 int32_t currentPowerRole, int32_t updatePowerRole, int32_t currentDataRole, int32_t updateDataRole)
266 {
267 USB_HILOGI(MODULE_USB_SERVICE, "Port switch points are as follows:");
268 HiSysEventWrite(HiSysEvent::Domain::USB, "PORT_ROLE_CHANGED",
269 HiSysEvent::EventType::BEHAVIOR, "CURRENT_POWERROLE",
270 currentPowerRole, "UPDATE_POWERROLE", updatePowerRole, "CURRENT_DATAROLE", currentDataRole, "UPDATE_DATAROLE",
271 updateDataRole);
272 }
273 } // namespace USB
274 } // namespace OHOS
275