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