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