1 /*
2 * Copyright (c) 2022-2025 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 "usbd_port.h"
17 #include <dirent.h>
18 #include <string>
19 #include "hdf_base.h"
20 #include "hdf_log.h"
21 #include "usbd_function.h"
22 #include "usbd_wrapper.h"
23 #include "usb_report_sys_event.h"
24 #include "parameter.h"
25
26 namespace OHOS {
27 namespace HDI {
28 namespace Usb {
29 namespace V1_2 {
30
31 constexpr uint32_t PERSIST_CONFIG_NAME_MAX_LEN = 32;
32
GetInstance()33 UsbdPort &UsbdPort::GetInstance()
34 {
35 static UsbdPort instance;
36 return instance;
37 }
38
IfCanSwitch(int32_t portId,int32_t powerRole,int32_t dataRole)39 int32_t UsbdPort::IfCanSwitch(int32_t portId, int32_t powerRole, int32_t dataRole)
40 {
41 if (portId != DEFAULT_PORT_ID) {
42 HDF_LOGE("%{public}s: portId error", __func__);
43 return HDF_FAILURE;
44 }
45
46 if (powerRole <= POWER_ROLE_NONE || powerRole >= POWER_ROLE_MAX) {
47 HDF_LOGE("%{public}s: powerRole error", __func__);
48 return HDF_FAILURE;
49 }
50
51 if (dataRole <= DATA_ROLE_NONE || dataRole >= DATA_ROLE_MAX) {
52 HDF_LOGE("%{public}s: dataRole error", __func__);
53 return HDF_FAILURE;
54 }
55 if (!isPdV2_0) {
56 int32_t supported_modes = 0;
57 int32_t ret = GetSupportedModes(supported_modes);
58 if (ret >= 0 && supported_modes == 0) {
59 HDF_LOGE("%{public}s: supported_modes is none not support", __func__);
60 return HDF_ERR_NOT_SUPPORT;
61 }
62 }
63 if (path_ == "/data/service/el1/public/usb/mode") {
64 HDF_LOGE("%{public}s: not support", __func__);
65 return HDF_ERR_NOT_SUPPORT;
66 }
67 return HDF_SUCCESS;
68 }
69
OpenPortFile(int32_t flags,const std::string & subPath)70 int32_t UsbdPort::OpenPortFile(int32_t flags, const std::string &subPath)
71 {
72 std::string fullPath;
73 if (isPdV2_0) {
74 fullPath = path_;
75 } else {
76 fullPath = path_ + subPath;
77 }
78 if (fullPath.empty()) {
79 HDF_LOGE("%{public}s: Empty path provided", __func__);
80 return HDF_FAILURE;
81 }
82
83 char pathBuf[PATH_MAX] = {'\0'};
84 if (realpath(fullPath.c_str(), pathBuf) == nullptr) {
85 HDF_LOGE("%{public}s: Path conversion failed for: %{public}s", __func__, fullPath.c_str());
86 return HDF_FAILURE;
87 }
88
89 int32_t fd = open(pathBuf, flags);
90 if (fd < 0) {
91 HDF_LOGE("%{public}s: Failed to open file: %{public}s, errno: %{public}d", __func__, pathBuf, errno);
92 return fd;
93 }
94
95 fdsan_exchange_owner_tag(fd, 0, fdsan_create_owner_tag(FDSAN_OWNER_TYPE_FILE, LOG_DOMAIN));
96 return fd;
97 }
98
WritePortFile(int32_t role,const std::string & subPath)99 int32_t UsbdPort::WritePortFile(int32_t role, const std::string &subPath)
100 {
101 std::string modeStr;
102 static const std::unordered_map<std::string, std::unordered_map<int32_t, std::string>> roleWriteMaps = {
103 {DATA_ROLE_PATH, {
104 {DATA_ROLE_HOST, DATA_ROLE_UFP_STR},
105 {DATA_ROLE_DEVICE, DATA_ROLE_DFP_STR},
106 {DATA_ROLE_NONE, DATA_ROLE_NONE_STR}
107 }},
108 {POWER_ROLE_PATH, {
109 {POWER_ROLE_SOURCE, POWER_ROLE_SOURCE_STR},
110 {POWER_ROLE_SINK, POWER_ROLE_SINK_STR},
111 {POWER_ROLE_NONE, POWER_ROLE_NONE_STR}
112 }}
113 };
114 auto pathIt = roleWriteMaps.find(subPath);
115 if (pathIt == roleWriteMaps.end()) {
116 HDF_LOGE("%{public}s: Invalid subPath: %{public}s", __func__, subPath.c_str());
117 return HDF_FAILURE;
118 }
119 auto roleIt = pathIt->second.find(role);
120 if (roleIt == pathIt->second.end()) {
121 HDF_LOGE("%{public}s: Invalid role: %{public}d for path: %{public}s",
122 __func__, role, subPath.c_str());
123 return HDF_FAILURE;
124 }
125 modeStr = roleIt->second;
126 int32_t fd = OpenPortFile(O_WRONLY | O_TRUNC, subPath);
127 if (fd < 0) {
128 return HDF_FAILURE;
129 }
130 int32_t ret = write(fd, modeStr.c_str(), modeStr.size());
131 fdsan_close_with_tag(fd, fdsan_create_owner_tag(FDSAN_OWNER_TYPE_FILE, LOG_DOMAIN));
132
133 if (ret < 0) {
134 HDF_LOGE("%{public}s: Write failed for: %{public}s, errno: %{public}d", __func__, modeStr.c_str(), errno);
135 return HDF_FAILURE;
136 }
137
138 if (path_.find("/otg_default") == std::string::npos) {
139 return HDF_SUCCESS;
140 }
141
142 int32_t devRole = -1;
143 ret = ReadPortFile(devRole, subPath);
144 if (ret != HDF_SUCCESS || devRole != role) {
145 HDF_LOGE("%{public}s: target: %{public}d, device: %{public}d, subpath:%{public}s",
146 __func__, role, devRole, subPath.c_str());
147 return HDF_FAILURE;
148 }
149 return HDF_SUCCESS;
150 }
151
ReadPortFile(int32_t & role,const std::string & subPath)152 int32_t UsbdPort::ReadPortFile(int32_t &role, const std::string &subPath)
153 {
154 int32_t fd = OpenPortFile(O_RDONLY, subPath);
155 if (fd < 0) {
156 return HDF_FAILURE;
157 }
158 char modeBuf[PATH_MAX] = {'\0'};
159 int32_t ret = read(fd, modeBuf, sizeof(modeBuf) - 1);
160 fdsan_close_with_tag(fd, fdsan_create_owner_tag(FDSAN_OWNER_TYPE_FILE, LOG_DOMAIN));
161 if (ret <= 0) {
162 HDF_LOGE("%{public}s: Read failed for: %{public}s, errno: %{public}d", __func__, path_.c_str(), errno);
163 return HDF_FAILURE;
164 }
165 std::string modeStr = std::string(modeBuf).substr(0, ret); // Trim to actual read length
166 modeStr.erase(modeStr.find_last_not_of(" \n\r\t") + 1); // Trim whitespace
167 static const std::unordered_map<std::string, std::unordered_map<std::string, int32_t>> roleReadMaps = {
168 {DATA_ROLE_PATH, {
169 {DATA_ROLE_NONE_STR, DATA_ROLE_NONE},
170 {DATA_ROLE_UFP_STR, DATA_ROLE_HOST},
171 {DATA_ROLE_DFP_STR, DATA_ROLE_DEVICE}
172 }},
173 {POWER_ROLE_PATH, {
174 {POWER_ROLE_NONE_STR, POWER_ROLE_NONE},
175 {POWER_ROLE_SOURCE_STR, POWER_ROLE_SOURCE},
176 {POWER_ROLE_SINK_STR, POWER_ROLE_SINK}
177 }},
178 {MODE_PATH, {
179 {MODES_NONE_STR, MODES_NONE},
180 {MODES_UFP_STR, MODES_UFP},
181 {MODES_DFP_STR, MODES_DFP},
182 {MODES_DRP_STR, MODES_DRP}
183 }}
184 };
185 auto pathIt = roleReadMaps.find(subPath);
186 if (pathIt == roleReadMaps.end()) {
187 HDF_LOGE("%{public}s: Invalid subPath: %{public}s", __func__, subPath.c_str());
188 return HDF_FAILURE;
189 }
190 auto roleIt = pathIt->second.find(modeStr);
191 if (roleIt == pathIt->second.end()) {
192 role = 0;
193 HDF_LOGE("%{public}s: Invalid mode: %{public}s", __func__, modeStr.c_str());
194 return HDF_FAILURE;
195 }
196 role = roleIt->second;
197 return HDF_SUCCESS;
198 }
199
setPortPath(const std::string & path)200 void UsbdPort::setPortPath(const std::string &path)
201 {
202 path_ = DEFAULT_USB_MODE_PATH;
203 if (path == DEFAULT_USB_MODE_PATH) {
204 isPdV2_0 = true;
205 HDF_LOGE("%{public}s: not support", __func__);
206 return;
207 }
208 if (path == PD_V2_0) {
209 isPdV2_0 = true;
210 path_ = PD_V2_0;
211 HDF_LOGE("%{public}s: default path", __func__);
212 return;
213 }
214 DIR *dir = opendir(path.c_str());
215 if (dir == nullptr) {
216 HDF_LOGE("%{public}s: Failed to open directory: %{public}s", __func__, path.c_str());
217 return;
218 }
219 struct dirent *entry;
220 while ((entry = readdir(dir)) != nullptr) {
221 if (strcmp(entry->d_name, ".") == 0 || strcmp(entry->d_name, "..") == 0) {
222 continue;
223 } else {
224 path_ = path + entry->d_name;
225 HDF_LOGE("%{public}s: Full path: %{public}s", __func__, path_.c_str());
226 break;
227 }
228 }
229 closedir(dir);
230 }
231
SetPortInit(int32_t portId,int32_t powerRole,int32_t dataRole)232 int32_t UsbdPort::SetPortInit(int32_t portId, int32_t powerRole, int32_t dataRole)
233 {
234 auto ret = IfCanSwitch(portId, powerRole, dataRole);
235 if (ret != HDF_SUCCESS) {
236 HDF_LOGE("%{public}s: can not switch function", __func__);
237 return ret;
238 }
239 if (isPdV2_0) {
240 if (WritePdPortFile(powerRole, dataRole)) {
241 HDF_LOGE("%{public}s: WritePdPortFile failed", __func__);
242 return HDF_FAILURE;
243 }
244 currentPortInfo_.portId = portId;
245 return HDF_SUCCESS;
246 }
247
248 if (currentPortInfo_.powerRole != powerRole) {
249 HDF_LOGI("%{public}s: powerRole switch from %{public}d to %{public}d", __func__,
250 currentPortInfo_.powerRole, powerRole);
251 ret = WritePortFile(powerRole, POWER_ROLE_PATH);
252 if (ret != HDF_SUCCESS) {
253 HDF_LOGE("%{public}s: write powerRole failed, ret: %{public}d", __func__, ret);
254 return ret;
255 }
256 }
257 if (currentPortInfo_.dataRole != dataRole) {
258 HDF_LOGI("%{public}s: dataRole switch from %{public}d to %{public}d", __func__,
259 currentPortInfo_.dataRole, dataRole);
260 ret = WritePortFile(dataRole, DATA_ROLE_PATH);
261 if (ret != HDF_SUCCESS) {
262 HDF_LOGE("%{public}s: write dataRole failed, ret: %{public}d", __func__, ret);
263 return ret;
264 }
265 if (currentPortInfo_.dataRole == DATA_ROLE_DEVICE && dataRole == DATA_ROLE_HOST) {
266 ret = SwitchFunction(DATA_ROLE_HOST);
267 }
268 if (currentPortInfo_.dataRole == DATA_ROLE_HOST && dataRole == DATA_ROLE_DEVICE) {
269 ret = SwitchFunction(DATA_ROLE_DEVICE);
270 }
271 }
272 currentPortInfo_.portId = portId;
273 currentPortInfo_.powerRole = powerRole;
274 currentPortInfo_.dataRole = dataRole;
275 return HDF_SUCCESS;
276 }
277
IsHdcOpen()278 bool UsbdPort::IsHdcOpen()
279 {
280 char persistConfig[PERSIST_CONFIG_NAME_MAX_LEN] = {0};
281 int32_t ret = GetParameter("persist.sys.usb.config", "invalid", persistConfig, PERSIST_CONFIG_NAME_MAX_LEN);
282 if (ret <= 0) {
283 HDF_LOGE("%{public}s:GetPersistParameter failed", __func__);
284 return false;
285 }
286 const char HDC_SIGNATURE[] = "hdc";
287 if (strstr(persistConfig, HDC_SIGNATURE) != nullptr) {
288 HDF_LOGI("%{public}s:hdc is opening", __func__);
289 return true;
290 }
291 return false;
292 }
293
IsDevInterfaceConn()294 bool UsbdPort::IsDevInterfaceConn()
295 {
296 if (usbDeviceInterface_ == nullptr) {
297 usbDeviceInterface_ = HDI::Usb::V2_0::IUsbDeviceInterface::Get(true);
298 if (usbDeviceInterface_ == nullptr) {
299 return false;
300 }
301 }
302
303 return true;
304 }
305
UsbdSetFunction(int32_t func)306 int32_t UsbdPort::UsbdSetFunction(int32_t func)
307 {
308 if (!IsDevInterfaceConn()) {
309 return HDF_FAILURE;
310 }
311 return usbDeviceInterface_->SetCurrentFunctions(func);
312 }
313
SwitchFunction(int32_t dataRole)314 int32_t UsbdPort::SwitchFunction(int32_t dataRole)
315 {
316 int32_t ret = HDF_SUCCESS;
317 if (!IsDevInterfaceConn()) {
318 return HDF_FAILURE;
319 }
320 int32_t currentFuncs = USB_FUNCTION_NONE;
321 ret = usbDeviceInterface_->GetCurrentFunctions(currentFuncs);
322 if (ret == HDF_SUCCESS &&
323 (currentFuncs == USB_FUNCTION_HDC || currentFuncs == USB_FUNCTION_STORAGE)) {
324 HDF_LOGI("%{public}s: skip, currentFuncs: %{public}d", __func__, currentFuncs);
325 return HDF_SUCCESS;
326 }
327 if (IsHdcOpen()) {
328 ret = usbDeviceInterface_->SetCurrentFunctions(USB_FUNCTION_HDC);
329 } else {
330 ret = usbDeviceInterface_->SetCurrentFunctions(USB_FUNCTION_STORAGE);
331 }
332 return ret;
333 }
334
SetPort(int32_t portId,int32_t powerRole,int32_t dataRole,UsbdSubscriber * usbdSubscribers,uint32_t len)335 int32_t UsbdPort::SetPort(
336 int32_t portId, int32_t powerRole, int32_t dataRole, UsbdSubscriber *usbdSubscribers, uint32_t len)
337 {
338 int32_t ret = SetPortInit(portId, powerRole, dataRole);
339 if (ret != HDF_SUCCESS) {
340 HDF_LOGE("%{public}s: SetPortInit failed! ret:%{public}d", __func__, ret);
341 return ret;
342 }
343 for (uint32_t i = 0; i < len; i++) {
344 if (usbdSubscribers[i].subscriber != nullptr) {
345 usbdSubscribers[i].subscriber->PortChangedEvent(currentPortInfo_);
346 }
347 }
348
349 return HDF_SUCCESS;
350 }
351
SetUsbPort(int32_t portId,int32_t powerRole,int32_t dataRole,HDI::Usb::V2_0::UsbdSubscriber * usbdSubscribers,uint32_t len)352 int32_t UsbdPort::SetUsbPort(int32_t portId, int32_t powerRole, int32_t dataRole,
353 HDI::Usb::V2_0::UsbdSubscriber *usbdSubscribers, uint32_t len)
354 {
355 int32_t ret = SetPortInit(portId, powerRole, dataRole);
356 if (ret != HDF_SUCCESS) {
357 HDF_LOGE("%{public}s: SetPortInit failed! ret:%{public}d", __func__, ret);
358 UsbReportSysEvent::ReportUsbRecognitionFailSysEvent("SetUsbPort", HDF_FAILURE, "UsbdWaitUdc error");
359 return ret;
360 }
361 currentPortInfos_ = {currentPortInfo_.portId,
362 currentPortInfo_.powerRole, currentPortInfo_.dataRole, currentPortInfo_.mode};
363 for (uint32_t i = 0; i < len; i++) {
364 if (usbdSubscribers[i].subscriber != nullptr) {
365 usbdSubscribers[i].subscriber->PortChangedEvent(currentPortInfos_);
366 }
367 }
368
369 return HDF_SUCCESS;
370 }
371
QueryPort(int32_t & portId,int32_t & powerRole,int32_t & dataRole,int32_t & mode)372 int32_t UsbdPort::QueryPort(int32_t &portId, int32_t &powerRole, int32_t &dataRole, int32_t &mode)
373 {
374 if (path_ == DEFAULT_USB_MODE_PATH) {
375 HDF_LOGE("%{public}s: not support", __func__);
376 return HDF_SUCCESS;
377 }
378
379 portId = currentPortInfo_.portId;
380 if (isPdV2_0) {
381 QueryPdPort(powerRole, dataRole, mode);
382 return HDF_SUCCESS;
383 }
384 int32_t ret = ReadPortFile(powerRole, POWER_ROLE_PATH);
385 if (ret < 0) {
386 HDF_LOGE("%{public}s: read power_role failed ret = %{public}d", __func__, ret);
387 return HDF_FAILURE;
388 }
389 ret = ReadPortFile(dataRole, DATA_ROLE_PATH);
390 if (ret < 0) {
391 HDF_LOGE("%{public}s: read data_role failed ret = %{public}d", __func__, ret);
392 return HDF_FAILURE;
393 }
394 ret = ReadPortFile(mode, MODE_PATH);
395 if (ret < 0) {
396 HDF_LOGE("%{public}s: read mode failed ret = %{public}d", __func__, ret);
397 return HDF_FAILURE;
398 }
399 return HDF_SUCCESS;
400 }
401
GetSupportedModes(int32_t & supported_modes)402 int32_t UsbdPort::GetSupportedModes(int32_t &supported_modes)
403 {
404 if (isPdV2_0) {
405 supported_modes = SUPPORTED_MODES_UFP_DFP;
406 return true;
407 }
408
409 int32_t fd = OpenPortFile(O_RDONLY, SUPPORTED_MODES_PATH);
410 if (fd < 0) {
411 HDF_LOGE("%{public}s: file open error fd = %{public}d", __func__, fd);
412 return HDF_FAILURE;
413 }
414 char modeBuf[PATH_MAX] = {'\0'};
415 int32_t ret = read(fd, modeBuf, PATH_MAX - 1);
416 fdsan_close_with_tag(fd, fdsan_create_owner_tag(FDSAN_OWNER_TYPE_FILE, LOG_DOMAIN));
417
418 if (ret < 0) {
419 HDF_LOGE("%{public}s: read error: %{public}s, errno: %{public}d", __func__, path_.c_str(), errno);
420 return HDF_FAILURE;
421 }
422 modeBuf[ret] = '\0';
423 static const std::unordered_map<std::string, int32_t> supportedModesMap = {
424 {SUPPORTED_MODES_NONE_STR, SUPPORTED_MODES_NONE},
425 {SUPPORTED_MODES_UFP_STR, SUPPORTED_MODES_UFP},
426 {SUPPORTED_MODES_DFP_STR, SUPPORTED_MODES_DFP},
427 {SUPPORTED_MODES_UFP_DFP_STR, SUPPORTED_MODES_UFP_DFP}
428 };
429 for (const auto& [str, mode] : supportedModesMap) {
430 if (strncmp(modeBuf, str.data(), str.length()) == 0) {
431 supported_modes = mode;
432 HDF_LOGE("%{public}s: read supported_modes: %{public}d", __func__, mode);
433 return HDF_SUCCESS;
434 }
435 }
436 HDF_LOGE("%{public}s: read invalid supported_modes: %{public}s", __func__, modeBuf);
437 return HDF_FAILURE;
438 }
439
UpdatePort(int32_t mode,const sptr<IUsbdSubscriber> & subscriber)440 int32_t UsbdPort::UpdatePort(int32_t mode, const sptr<IUsbdSubscriber> &subscriber)
441 {
442 if (subscriber == nullptr) {
443 HDF_LOGE("%{public}s subscriber is nullptr", __func__);
444 return HDF_FAILURE;
445 }
446 if (isPdV2_0) {
447 UpdatePdPort(mode, subscriber);
448 return HDF_SUCCESS;
449 }
450 if (mode > 0 && mode <= PORT_MODE_HOST) {
451 int32_t ret = QueryPort(currentPortInfo_.portId,
452 currentPortInfo_.powerRole, currentPortInfo_.dataRole, currentPortInfo_.mode);
453 if (ret < 0) {
454 HDF_LOGE("%{public}s: QueryPort failed ret = %{public}d", __func__, ret);
455 return HDF_FAILURE;
456 }
457 currentPortInfo_.mode = mode;
458 } else {
459 HDF_LOGE("%{public}s invalid mode:%{public}d", __func__, mode);
460 return HDF_FAILURE;
461 }
462 subscriber->PortChangedEvent(currentPortInfo_);
463 return HDF_SUCCESS;
464 }
465
UpdateUsbPort(int32_t mode,const sptr<V2_0::IUsbdSubscriber> & subscriber)466 int32_t UsbdPort::UpdateUsbPort(int32_t mode, const sptr<V2_0::IUsbdSubscriber> &subscriber)
467 {
468 if (subscriber == nullptr) {
469 HDF_LOGE("%{public}s subscriber is nullptr", __func__);
470 return HDF_FAILURE;
471 }
472 if (isPdV2_0) {
473 UpdatePdPorts(mode, subscriber);
474 return HDF_SUCCESS;
475 }
476 if (mode > 0 && mode <= PORT_MODE_HOST) {
477 int32_t ret = QueryPort(currentPortInfo_.portId,
478 currentPortInfo_.powerRole, currentPortInfo_.dataRole, currentPortInfo_.mode);
479 if (ret < 0) {
480 HDF_LOGE("%{public}s: QueryPort failed ret = %{public}d", __func__, ret);
481 return HDF_FAILURE;
482 }
483 currentPortInfo_.mode = mode;
484 } else {
485 HDF_LOGE("%{public}s invalid mode:%{public}d", __func__, mode);
486 return HDF_FAILURE;
487 }
488
489 currentPortInfos_ = {currentPortInfo_.portId,
490 currentPortInfo_.powerRole, currentPortInfo_.dataRole, currentPortInfo_.mode};
491 subscriber->PortChangedEvent(currentPortInfos_);
492 HDF_LOGD("%{public}s exit", __func__);
493 return HDF_SUCCESS;
494 }
495
WritePdPortFile(int32_t powerRole,int32_t dataRole)496 int32_t UsbdPort::WritePdPortFile(int32_t powerRole, int32_t dataRole)
497 {
498 std::string modeStr;
499 int32_t mode = PORT_MODE_DEVICE;
500 if (powerRole == POWER_ROLE_SOURCE && dataRole == DATA_ROLE_HOST) {
501 mode = PORT_MODE_HOST;
502 modeStr = DATA_ROLE_UFP_STR;
503 UsbdSetFunction(USB_FUNCTION_NONE);
504 }
505
506 if (powerRole == POWER_ROLE_SINK && dataRole == DATA_ROLE_DEVICE) {
507 mode = PORT_MODE_DEVICE;
508 modeStr = DATA_ROLE_DFP_STR;
509 UsbdSetFunction(USB_FUNCTION_HDC);
510 }
511 uint32_t len = modeStr.size();
512 int32_t fd = OpenPortFile(O_WRONLY | O_TRUNC, "");
513 if (fd < 0) {
514 HDF_LOGE("%{public}s: file open error fd = %{public}d", __func__, fd);
515 return HDF_FAILURE;
516 }
517 int32_t ret = write(fd, modeStr.c_str(), len);
518 close(fd);
519 if (ret < 0) {
520 HDF_LOGE("%{public}s: write error", __func__);
521 return HDF_FAILURE;
522 }
523 currentPortInfo_.powerRole = powerRole;
524 currentPortInfo_.dataRole = dataRole;
525 currentPortInfo_.mode = mode;
526
527 return HDF_SUCCESS;
528 }
529
QueryPdPort(int32_t & powerRole,int32_t & dataRole,int32_t & mode)530 void UsbdPort::QueryPdPort(int32_t &powerRole, int32_t &dataRole, int32_t &mode)
531 {
532 int32_t fd = OpenPortFile(O_RDONLY, "");
533 if (fd < 0) {
534 return;
535 }
536 char modeBuf[PATH_MAX] = {'\0'};
537 int32_t ret = read(fd, modeBuf, PATH_MAX - 1);
538 close(fd);
539
540 if (ret < 0) {
541 HDF_LOGE("%{public}s: read error: %{public}s", __func__, path_.c_str());
542 return;
543 }
544 if (strcmp(modeBuf, DATA_ROLE_UFP_STR) == 0) {
545 powerRole = POWER_ROLE_SOURCE;
546 dataRole = DATA_ROLE_HOST;
547 mode = PORT_MODE_HOST;
548 return;
549 }
550
551 if (strcmp(modeBuf, DATA_ROLE_DFP_STR) == 0) {
552 powerRole = POWER_ROLE_SINK;
553 dataRole = DATA_ROLE_DEVICE;
554 mode = PORT_MODE_DEVICE;
555 return;
556 }
557
558 HDF_LOGE("%{public}s: read invalid mode: %{public}s", __func__, modeBuf);
559 return;
560 }
561
UpdatePdPort(int32_t mode,const sptr<IUsbdSubscriber> & subscriber)562 void UsbdPort::UpdatePdPort(int32_t mode, const sptr<IUsbdSubscriber> &subscriber)
563 {
564 switch (mode) {
565 case PORT_MODE_HOST:
566 currentPortInfo_.powerRole = POWER_ROLE_SOURCE;
567 currentPortInfo_.dataRole = DATA_ROLE_HOST;
568 currentPortInfo_.mode = PORT_MODE_HOST;
569 break;
570 case PORT_MODE_DEVICE:
571 currentPortInfo_.powerRole = POWER_ROLE_SINK;
572 currentPortInfo_.dataRole = DATA_ROLE_DEVICE;
573 currentPortInfo_.mode = PORT_MODE_DEVICE;
574 break;
575 default:
576 HDF_LOGE("%{public}s invalid mode:%{public}d", __func__, mode);
577 return;
578 }
579 subscriber->PortChangedEvent(currentPortInfo_);
580 return;
581 }
582
UpdatePdPorts(int32_t mode,const sptr<V2_0::IUsbdSubscriber> & subscriber)583 void UsbdPort::UpdatePdPorts(int32_t mode, const sptr<V2_0::IUsbdSubscriber> &subscriber)
584 {
585 switch (mode) {
586 case PORT_MODE_HOST:
587 currentPortInfo_.powerRole = POWER_ROLE_SOURCE;
588 currentPortInfo_.dataRole = DATA_ROLE_HOST;
589 currentPortInfo_.mode = PORT_MODE_HOST;
590 break;
591 case PORT_MODE_DEVICE:
592 currentPortInfo_.powerRole = POWER_ROLE_SINK;
593 currentPortInfo_.dataRole = DATA_ROLE_DEVICE;
594 currentPortInfo_.mode = PORT_MODE_DEVICE;
595 break;
596 default:
597 HDF_LOGE("%{public}s invalid mode:%{public}d", __func__, mode);
598 return;
599 }
600 currentPortInfos_ = {currentPortInfo_.portId,
601 currentPortInfo_.powerRole, currentPortInfo_.dataRole, currentPortInfo_.mode};
602 subscriber->PortChangedEvent(currentPortInfos_);
603 return;
604 }
605 } // namespace V1_2
606 } // namespace Usb
607 } // namespace HDI
608 } // namespace OHOS
609