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