1094332d3Sopenharmony_ci/* 2094332d3Sopenharmony_ci * Copyright (c) 2022-2023 Huawei Device Co., Ltd. 3094332d3Sopenharmony_ci * Licensed under the Apache License, Version 2.0 (the "License"); 4094332d3Sopenharmony_ci * you may not use this file except in compliance with the License. 5094332d3Sopenharmony_ci * You may obtain a copy of the License at 6094332d3Sopenharmony_ci * 7094332d3Sopenharmony_ci * http://www.apache.org/licenses/LICENSE-2.0 8094332d3Sopenharmony_ci * 9094332d3Sopenharmony_ci * Unless required by applicable law or agreed to in writing, software 10094332d3Sopenharmony_ci * distributed under the License is distributed on an "AS IS" BASIS, 11094332d3Sopenharmony_ci * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12094332d3Sopenharmony_ci * See the License for the specific language governing permissions and 13094332d3Sopenharmony_ci * limitations under the License. 14094332d3Sopenharmony_ci */ 15094332d3Sopenharmony_ci 16094332d3Sopenharmony_ci#include "usbd_port.h" 17094332d3Sopenharmony_ci#include "hdf_base.h" 18094332d3Sopenharmony_ci#include "hdf_log.h" 19094332d3Sopenharmony_ci#include "usbd_function.h" 20094332d3Sopenharmony_ci#include "usbd_wrapper.h" 21094332d3Sopenharmony_ci 22094332d3Sopenharmony_cinamespace OHOS { 23094332d3Sopenharmony_cinamespace HDI { 24094332d3Sopenharmony_cinamespace Usb { 25094332d3Sopenharmony_cinamespace V1_1 { 26094332d3Sopenharmony_ciUsbdPort &UsbdPort::GetInstance() 27094332d3Sopenharmony_ci{ 28094332d3Sopenharmony_ci static UsbdPort instance; 29094332d3Sopenharmony_ci return instance; 30094332d3Sopenharmony_ci} 31094332d3Sopenharmony_ci 32094332d3Sopenharmony_ciint32_t UsbdPort::IfCanSwitch(int32_t portId, int32_t powerRole, int32_t dataRole) 33094332d3Sopenharmony_ci{ 34094332d3Sopenharmony_ci if (portId != DEFAULT_PORT_ID) { 35094332d3Sopenharmony_ci HDF_LOGE("%{public}s: portId error", __func__); 36094332d3Sopenharmony_ci return HDF_FAILURE; 37094332d3Sopenharmony_ci } 38094332d3Sopenharmony_ci 39094332d3Sopenharmony_ci if (powerRole <= POWER_ROLE_NONE || powerRole >= POWER_ROLE_MAX) { 40094332d3Sopenharmony_ci HDF_LOGE("%{public}s: powerRole error", __func__); 41094332d3Sopenharmony_ci return HDF_FAILURE; 42094332d3Sopenharmony_ci } 43094332d3Sopenharmony_ci 44094332d3Sopenharmony_ci if (dataRole <= DATA_ROLE_NONE || dataRole >= DATA_ROLE_MAX) { 45094332d3Sopenharmony_ci HDF_LOGE("%{public}s: dataRole error", __func__); 46094332d3Sopenharmony_ci return HDF_FAILURE; 47094332d3Sopenharmony_ci } 48094332d3Sopenharmony_ci 49094332d3Sopenharmony_ci if (path_ == "/data/service/el1/public/usb/mode") { 50094332d3Sopenharmony_ci HDF_LOGE("%{public}s: not support", __func__); 51094332d3Sopenharmony_ci return HDF_ERR_NOT_SUPPORT; 52094332d3Sopenharmony_ci } 53094332d3Sopenharmony_ci return HDF_SUCCESS; 54094332d3Sopenharmony_ci} 55094332d3Sopenharmony_ci 56094332d3Sopenharmony_ciint32_t UsbdPort::OpenPortFile(int32_t flags) 57094332d3Sopenharmony_ci{ 58094332d3Sopenharmony_ci if (path_.empty()) { 59094332d3Sopenharmony_ci return HDF_FAILURE; 60094332d3Sopenharmony_ci } 61094332d3Sopenharmony_ci 62094332d3Sopenharmony_ci char pathBuf[PATH_MAX] = {'\0'}; 63094332d3Sopenharmony_ci if (realpath(path_.c_str(), pathBuf) == NULL) { 64094332d3Sopenharmony_ci HDF_LOGE("%{public}s: path conversion failed", __func__); 65094332d3Sopenharmony_ci return HDF_FAILURE; 66094332d3Sopenharmony_ci } 67094332d3Sopenharmony_ci 68094332d3Sopenharmony_ci return open(pathBuf, flags); 69094332d3Sopenharmony_ci} 70094332d3Sopenharmony_ci 71094332d3Sopenharmony_ciint32_t UsbdPort::WritePortFile(int32_t powerRole, int32_t dataRole, int32_t mode) 72094332d3Sopenharmony_ci{ 73094332d3Sopenharmony_ci std::string modeStr; 74094332d3Sopenharmony_ci 75094332d3Sopenharmony_ci if (mode == PORT_MODE_HOST || mode == PORT_MODE_DEVICE) { 76094332d3Sopenharmony_ci switch (mode) { 77094332d3Sopenharmony_ci case PORT_MODE_HOST: 78094332d3Sopenharmony_ci modeStr = PORT_MODE_HOST_STR; 79094332d3Sopenharmony_ci UsbdFunction::UsbdSetFunction(USB_FUNCTION_NONE); 80094332d3Sopenharmony_ci break; 81094332d3Sopenharmony_ci case PORT_MODE_DEVICE: 82094332d3Sopenharmony_ci modeStr = PORT_MODE_DEVICE_STR; 83094332d3Sopenharmony_ci break; 84094332d3Sopenharmony_ci default: 85094332d3Sopenharmony_ci break; 86094332d3Sopenharmony_ci } 87094332d3Sopenharmony_ci } 88094332d3Sopenharmony_ci if (modeStr.empty()) { 89094332d3Sopenharmony_ci HDF_LOGE("%{public}s: modeStr error", __func__); 90094332d3Sopenharmony_ci return HDF_FAILURE; 91094332d3Sopenharmony_ci } 92094332d3Sopenharmony_ci 93094332d3Sopenharmony_ci uint32_t len = modeStr.size(); 94094332d3Sopenharmony_ci int32_t fd = OpenPortFile(O_WRONLY | O_TRUNC); 95094332d3Sopenharmony_ci if (fd < 0) { 96094332d3Sopenharmony_ci HDF_LOGE("%{public}s: file open error fd = %{public}d", __func__, fd); 97094332d3Sopenharmony_ci return HDF_FAILURE; 98094332d3Sopenharmony_ci } 99094332d3Sopenharmony_ci 100094332d3Sopenharmony_ci int32_t ret = write(fd, modeStr.c_str(), len); 101094332d3Sopenharmony_ci close(fd); 102094332d3Sopenharmony_ci if (ret < 0) { 103094332d3Sopenharmony_ci HDF_LOGE("%{public}s: write error", __func__); 104094332d3Sopenharmony_ci return HDF_FAILURE; 105094332d3Sopenharmony_ci } 106094332d3Sopenharmony_ci return HDF_SUCCESS; 107094332d3Sopenharmony_ci} 108094332d3Sopenharmony_ci 109094332d3Sopenharmony_ciint32_t UsbdPort::ReadPortFile(int32_t &powerRole, int32_t &dataRole, int32_t &mode) 110094332d3Sopenharmony_ci{ 111094332d3Sopenharmony_ci int32_t fd = OpenPortFile(O_RDONLY); 112094332d3Sopenharmony_ci if (fd < 0) { 113094332d3Sopenharmony_ci HDF_LOGE("%{public}s: file open error fd = %{public}d", __func__, fd); 114094332d3Sopenharmony_ci return HDF_FAILURE; 115094332d3Sopenharmony_ci } 116094332d3Sopenharmony_ci 117094332d3Sopenharmony_ci char modeBuf[PATH_MAX] = {'\0'}; 118094332d3Sopenharmony_ci int32_t ret = read(fd, modeBuf, PATH_MAX - 1); 119094332d3Sopenharmony_ci close(fd); 120094332d3Sopenharmony_ci 121094332d3Sopenharmony_ci if (ret < 0) { 122094332d3Sopenharmony_ci HDF_LOGE("%{public}s: read error: %{public}s", __func__, path_.c_str()); 123094332d3Sopenharmony_ci return HDF_FAILURE; 124094332d3Sopenharmony_ci } 125094332d3Sopenharmony_ci 126094332d3Sopenharmony_ci if (strcmp(modeBuf, PORT_MODE_HOST_STR) == 0) { 127094332d3Sopenharmony_ci powerRole = POWER_ROLE_SOURCE; 128094332d3Sopenharmony_ci dataRole = DATA_ROLE_HOST; 129094332d3Sopenharmony_ci mode = PORT_MODE_HOST; 130094332d3Sopenharmony_ci return HDF_SUCCESS; 131094332d3Sopenharmony_ci } 132094332d3Sopenharmony_ci 133094332d3Sopenharmony_ci if (strcmp(modeBuf, PORT_MODE_DEVICE_STR) == 0) { 134094332d3Sopenharmony_ci powerRole = POWER_ROLE_SINK; 135094332d3Sopenharmony_ci dataRole = DATA_ROLE_DEVICE; 136094332d3Sopenharmony_ci mode = PORT_MODE_DEVICE; 137094332d3Sopenharmony_ci return HDF_SUCCESS; 138094332d3Sopenharmony_ci } 139094332d3Sopenharmony_ci 140094332d3Sopenharmony_ci HDF_LOGE("%{public}s: read invalid mode: %{public}s", __func__, modeBuf); 141094332d3Sopenharmony_ci return HDF_FAILURE; 142094332d3Sopenharmony_ci} 143094332d3Sopenharmony_ci 144094332d3Sopenharmony_civoid UsbdPort::setPortPath(const std::string &path) 145094332d3Sopenharmony_ci{ 146094332d3Sopenharmony_ci path_ = path; 147094332d3Sopenharmony_ci} 148094332d3Sopenharmony_ci 149094332d3Sopenharmony_ciint32_t UsbdPort::SetPortInit(int32_t portId, int32_t powerRole, int32_t dataRole) 150094332d3Sopenharmony_ci{ 151094332d3Sopenharmony_ci auto ret = IfCanSwitch(portId, powerRole, dataRole); 152094332d3Sopenharmony_ci if (ret != HDF_SUCCESS) { 153094332d3Sopenharmony_ci HDF_LOGE("%{public}s: can not switch function", __func__); 154094332d3Sopenharmony_ci return ret; 155094332d3Sopenharmony_ci } 156094332d3Sopenharmony_ci 157094332d3Sopenharmony_ci int32_t mode = PORT_MODE_DEVICE; 158094332d3Sopenharmony_ci if (powerRole == POWER_ROLE_SOURCE && dataRole == DATA_ROLE_HOST) { 159094332d3Sopenharmony_ci mode = PORT_MODE_HOST; 160094332d3Sopenharmony_ci } 161094332d3Sopenharmony_ci 162094332d3Sopenharmony_ci if (powerRole == POWER_ROLE_SINK && dataRole == DATA_ROLE_DEVICE) { 163094332d3Sopenharmony_ci mode = PORT_MODE_DEVICE; 164094332d3Sopenharmony_ci } 165094332d3Sopenharmony_ci 166094332d3Sopenharmony_ci if (WritePortFile(powerRole, dataRole, mode)) { 167094332d3Sopenharmony_ci return HDF_FAILURE; 168094332d3Sopenharmony_ci } 169094332d3Sopenharmony_ci currentPortInfo_.portId = portId; 170094332d3Sopenharmony_ci currentPortInfo_.powerRole = powerRole; 171094332d3Sopenharmony_ci currentPortInfo_.dataRole = dataRole; 172094332d3Sopenharmony_ci currentPortInfo_.mode = mode; 173094332d3Sopenharmony_ci if (currentPortInfo_.mode == PORT_MODE_DEVICE) { 174094332d3Sopenharmony_ci UsbdFunction::UsbdSetFunction(USB_FUNCTION_HDC); 175094332d3Sopenharmony_ci } 176094332d3Sopenharmony_ci return HDF_SUCCESS; 177094332d3Sopenharmony_ci} 178094332d3Sopenharmony_ci 179094332d3Sopenharmony_ciint32_t UsbdPort::SetPort( 180094332d3Sopenharmony_ci int32_t portId, int32_t powerRole, int32_t dataRole, UsbdSubscriber *usbdSubscribers, uint32_t len) 181094332d3Sopenharmony_ci{ 182094332d3Sopenharmony_ci int32_t ret = SetPortInit(portId, powerRole, dataRole); 183094332d3Sopenharmony_ci if (ret != HDF_SUCCESS) { 184094332d3Sopenharmony_ci HDF_LOGE("%{public}s: SetPortInit failed! ret:%{public}d", __func__, ret); 185094332d3Sopenharmony_ci return ret; 186094332d3Sopenharmony_ci } 187094332d3Sopenharmony_ci for (uint32_t i = 0; i < len; i++) { 188094332d3Sopenharmony_ci if (usbdSubscribers[i].subscriber != nullptr) { 189094332d3Sopenharmony_ci usbdSubscribers[i].subscriber->PortChangedEvent(currentPortInfo_); 190094332d3Sopenharmony_ci } 191094332d3Sopenharmony_ci } 192094332d3Sopenharmony_ci 193094332d3Sopenharmony_ci return HDF_SUCCESS; 194094332d3Sopenharmony_ci} 195094332d3Sopenharmony_ci 196094332d3Sopenharmony_ciint32_t UsbdPort::QueryPort(int32_t &portId, int32_t &powerRole, int32_t &dataRole, int32_t &mode) 197094332d3Sopenharmony_ci{ 198094332d3Sopenharmony_ci (void)ReadPortFile(currentPortInfo_.powerRole, currentPortInfo_.dataRole, currentPortInfo_.mode); 199094332d3Sopenharmony_ci portId = currentPortInfo_.portId; 200094332d3Sopenharmony_ci powerRole = currentPortInfo_.powerRole; 201094332d3Sopenharmony_ci dataRole = currentPortInfo_.dataRole; 202094332d3Sopenharmony_ci mode = currentPortInfo_.mode; 203094332d3Sopenharmony_ci return HDF_SUCCESS; 204094332d3Sopenharmony_ci} 205094332d3Sopenharmony_ci 206094332d3Sopenharmony_ciint32_t UsbdPort::UpdatePort(int32_t mode, const sptr<IUsbdSubscriber> &subscriber) 207094332d3Sopenharmony_ci{ 208094332d3Sopenharmony_ci switch (mode) { 209094332d3Sopenharmony_ci case PORT_MODE_HOST: 210094332d3Sopenharmony_ci currentPortInfo_.powerRole = POWER_ROLE_SOURCE; 211094332d3Sopenharmony_ci currentPortInfo_.dataRole = DATA_ROLE_HOST; 212094332d3Sopenharmony_ci currentPortInfo_.mode = PORT_MODE_HOST; 213094332d3Sopenharmony_ci break; 214094332d3Sopenharmony_ci case PORT_MODE_DEVICE: 215094332d3Sopenharmony_ci currentPortInfo_.powerRole = POWER_ROLE_SINK; 216094332d3Sopenharmony_ci currentPortInfo_.dataRole = DATA_ROLE_DEVICE; 217094332d3Sopenharmony_ci currentPortInfo_.mode = PORT_MODE_DEVICE; 218094332d3Sopenharmony_ci break; 219094332d3Sopenharmony_ci default: 220094332d3Sopenharmony_ci HDF_LOGE("%{public}s invalid mode:%{public}d", __func__, mode); 221094332d3Sopenharmony_ci return HDF_FAILURE; 222094332d3Sopenharmony_ci } 223094332d3Sopenharmony_ci 224094332d3Sopenharmony_ci if (subscriber == nullptr) { 225094332d3Sopenharmony_ci HDF_LOGE("%{public}s subscriber is nullptr", __func__); 226094332d3Sopenharmony_ci return HDF_FAILURE; 227094332d3Sopenharmony_ci } 228094332d3Sopenharmony_ci subscriber->PortChangedEvent(currentPortInfo_); 229094332d3Sopenharmony_ci return HDF_SUCCESS; 230094332d3Sopenharmony_ci} 231094332d3Sopenharmony_ci} // namespace V1_1 232094332d3Sopenharmony_ci} // namespace Usb 233094332d3Sopenharmony_ci} // namespace HDI 234094332d3Sopenharmony_ci} // namespace OHOS 235