/* * Copyright (c) 2025 Huawei Device Co., Ltd. * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ #include "libusb_serial.h" #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include "usbd_wrapper.h" #include "securec.h" namespace OHOS { namespace HDI { namespace Usb { namespace Serial { namespace V1_0 { #define TARGET_INTERFACE 0xFF #define MAX_TRANS_DATA_SIZE 8192 #define ENABLE_UNREF 1 #define TRANSFER_TIMEOUT 1000 #define DIRECT_NUM 2 #define TRANSFER_CONTROL_OUT_CODE 0x20 #define TRANSFER_CONTROL_IN_CODE 0x21 #define RETRY_NUM 5 #define BUFFER_SIZE 256 #define SERIAL_NUM 256 #define ERR_CODE_IOEXCEPTION (-5) #define ERR_CODE_DEVICENOTOPEN (-6) #define OUTPUT_WIDTH 2 constexpr int RETRY_TIMEOUT = 10; static const std::string BUS_NUM_STR = "/busnum"; static const std::string DEV_NUM_STR = "/devnum"; static const std::string DEV_FILENAME_PREFIX = "ttyUSB"; static const std::string DEV_PATH_PREFIX = "/sys/bus/usb-serial/devices"; static const std::string TTYUSB_PATH = "/sys/class/tty"; static const std::string THREAD_NAME = "serialHotPlug"; namespace fs = std::filesystem; LibusbSerial &LibusbSerial::GetInstance() { static LibusbSerial instance; return instance; } LibusbSerial::LibusbSerial(): ctx_(nullptr), running_(true) { HDF_LOGI("%{public}s: enter SerialUSBWrapper initialization.", __func__); int ret = libusb_init(&ctx_); if (ret != LIBUSB_SUCCESS) { HDF_LOGE("%{public}s: Failed to initialize libusb: %{public}d", __func__, ret); ctx_ = nullptr; return; } if (!libusb_has_capability(LIBUSB_CAP_HAS_HOTPLUG)) { HDF_LOGE("%{public}s: Hotplug capability is not supported on this platform", __func__); libusb_exit(ctx_); ctx_ = nullptr; return; } ret = libusb_hotplug_register_callback(ctx_, static_cast( LIBUSB_HOTPLUG_EVENT_DEVICE_ARRIVED | LIBUSB_HOTPLUG_EVENT_DEVICE_LEFT), LIBUSB_HOTPLUG_NO_FLAGS, LIBUSB_HOTPLUG_MATCH_ANY, LIBUSB_HOTPLUG_MATCH_ANY, LIBUSB_HOTPLUG_MATCH_ANY, HotplugCallback, this, &hotplug_handle_); if (ret != LIBUSB_SUCCESS) { HDF_LOGE("%{public}s: Failed to register hotplug callback: %{public}d", __func__, ret); libusb_exit(ctx_); ctx_ = nullptr; return; } GetExistedDevices(); event_thread_ = std::thread(&LibusbSerial::EventHandlingThread, this); HDF_LOGI("%{public}s: SerialUSBWrapper initialization completed.", __func__); } LibusbSerial::~LibusbSerial() { HDF_LOGI("%{public}s: enter Destroying SerialUSBWrapper.", __func__); running_ = false; if (event_thread_.joinable()) { event_thread_.join(); } if (ctx_) { libusb_hotplug_deregister_callback(ctx_, hotplug_handle_); } std::lock_guard lock(map_mutex_); for (auto& pair : devices_) { if (pair.second.handle) { libusb_close(pair.second.handle); pair.second.handle = nullptr; } } devices_.clear(); if (ctx_) { libusb_exit(ctx_); ctx_ = nullptr; } HDF_LOGI("%{public}s: SerialUSBWrapper destroyed.", __func__); } void LibusbSerial::GetExistedDevices() { libusb_device** device_list = nullptr; ssize_t count = libusb_get_device_list(ctx_, &device_list); if (count < 0) { HDF_LOGE("%{public}s: Failed to get device list: %{public}d", __func__, (int)count); return; } for (ssize_t idx = 0; idx < count; ++idx) { libusb_device* device = device_list[idx]; struct libusb_device_descriptor desc; int ret = libusb_get_device_descriptor(device, &desc); if (ret < 0) { continue; } if (desc.bDeviceClass == LIBUSB_CLASS_HUB) { continue; } HandleDeviceArrival(device); } libusb_free_device_list(device_list, ENABLE_UNREF); HDF_LOGI("%{public}s: Existing devices enumeration completed. device count: %{public}zd", __func__, count); } int32_t LibusbSerial::SerialOpen(int32_t num) { HDF_LOGI("%{public}s: enter SerialOpen called for num: %{public}d.", __func__, num); std::lock_guard lock(map_mutex_); for (auto& pair : devices_) { if (pair.second.num == num) { if (pair.second.isOpen) { return HDF_SUCCESS; } pair.second.isOpen = true; return HDF_SUCCESS; } } HDF_LOGE("%{public}s: Device not found: num = %{public}d", __func__, num); return HDF_FAILURE; } int32_t LibusbSerial::SerialClose(int32_t num) { HDF_LOGI("%{public}s: enter SerialClose called for num: %{public}d.", __func__, num); std::lock_guard lock(map_mutex_); for (auto& pair : devices_) { if (pair.second.num == num) { if (pair.second.isOpen) { pair.second.isOpen = false; HDF_LOGI("%{public}s: Device logically closed: num = %{public}d", __func__, num); } return HDF_SUCCESS; } } return HDF_SUCCESS; } int32_t LibusbSerial::GetSerialDeviceInfo(libusb_device* device, libusb_device_handle* handle, DeviceInfo &deviceInfo) { HDF_LOGI("%{public}s: enter GetSerialDeviceInfo.", __func__); struct libusb_device_descriptor desc; int result = -1; result = libusb_get_device_descriptor(device, &desc); if (result < 0) { HDF_LOGE("%{public}s: get device descriptor error: %{public}d", __func__, result); return HDF_FAILURE; } char serialNumber[BUFFER_SIZE] = {'\0'}; unsigned char serial[BUFFER_SIZE] = {'\0'}; if (handle && desc.iSerialNumber) { HDF_LOGI("%{public}s: desc serialNum: %{public}hhu", __func__, desc.iSerialNumber); result = libusb_get_string_descriptor_ascii(handle, desc.iSerialNumber, serial, sizeof(serial)); } if (result > 0) { int n = snprintf_s(serialNumber, sizeof(serialNumber), sizeof(serialNumber)-1, "%s", reinterpret_cast(serial)); if (n < 0) { return HDF_FAILURE; } } else { HDF_LOGE("%{public}s: get serial num error, result: %{public}d", __func__, result); return HDF_FAILURE; } deviceInfo.vid = desc.idVendor; deviceInfo.pid = desc.idProduct; deviceInfo.busNum = libusb_get_bus_number(device); deviceInfo.devAddr = libusb_get_device_address(device); deviceInfo.serialNum = std::string(serialNumber); return HDF_SUCCESS; } int32_t LibusbSerial::SerialGetPortList(std::vector& portIds) { HDF_LOGI("%{public}s: enter SerialGetPortList.", __func__); std::lock_guard lock(map_mutex_); portIds.clear(); for (const auto& device : devices_) { SerialPort serialPort; libusb_device* dev = device.first; libusb_device_handle* handle = device.second.handle; GetSerialDeviceInfo(dev, handle, serialPort.deviceInfo); serialPort.portId = device.second.num; portIds.push_back(serialPort); } return HDF_SUCCESS; } libusb_device_handle* LibusbSerial::GetDeviceHandle(int portId) { std::lock_guard guard(map_mutex_); for (auto ite = devices_.cbegin(); ite != devices_.cend(); ++ite) { if (ite->second.num == portId) { return ite->second.handle; } } return nullptr; } libusb_device* LibusbSerial::GetDevice(int portId) { std::lock_guard guard(map_mutex_); for (auto ite = devices_.cbegin(); ite != devices_.cend(); ++ite) { if (ite->second.num == portId) { return ite->first; } } return nullptr; } std::string VectorToHex(const std::vector& data) { std::ostringstream oss; oss << std::hex << std::setfill('0'); for (uint8_t byte : data) { oss << std::setw(OUTPUT_WIDTH) << static_cast(byte); } return oss.str(); } int32_t LibusbSerial::SerialRead(int32_t portId, std::vector& data, uint32_t size, uint32_t timeout) { HDF_LOGI("%{public}s: enter serial read.", __func__); libusb_device* device = GetDevice(portId); if (device == nullptr) { HDF_LOGE("%{public}s: get device failed", __func__); return ERR_CODE_IOEXCEPTION; } DeviceHandleInfo deviceHandleInfo = devices_[device]; if (!deviceHandleInfo.isOpen) { HDF_LOGE("%{public}s: device not open", __func__); return ERR_CODE_DEVICENOTOPEN; } int ret = 0; int actualLength = 0; uint8_t dataIn[MAX_TRANS_DATA_SIZE] = {0}; std::lock_guard lock(writeMutex_); libusb_release_interface(deviceHandleInfo.handle, deviceHandleInfo.interface); libusb_attach_kernel_driver(deviceHandleInfo.handle, deviceHandleInfo.interface); libusb_detach_kernel_driver(deviceHandleInfo.handle, deviceHandleInfo.interface); ret = libusb_claim_interface(deviceHandleInfo.handle, deviceHandleInfo.interface); if (ret < 0) { HDF_LOGE("%{public}s: libusb claim failed, ret:%{public}d", __func__, ret); return HDF_FAILURE; } ret = 0; ret = libusb_bulk_transfer(deviceHandleInfo.handle, deviceHandleInfo.inputEndpointAddr, dataIn, size, &actualLength, timeout); if (ret < 0 && actualLength == 0) { libusb_release_interface(deviceHandleInfo.handle, deviceHandleInfo.interface); libusb_attach_kernel_driver(deviceHandleInfo.handle, deviceHandleInfo.interface); HDF_LOGE("%{public}s: read message failed, ret:%{public}d", __func__, ret); return ret; } std::vector vec(dataIn, dataIn + actualLength); data.insert(data.end(), vec.begin(), vec.end()); std::string tempHexBuff = VectorToHex(vec); HDF_LOGI("%{public}s: read msg : %{public}s", __func__, data.data()); HDF_LOGI("%{public}s: read msg hex : %{public}s", __func__, tempHexBuff.c_str()); libusb_release_interface(deviceHandleInfo.handle, deviceHandleInfo.interface); libusb_attach_kernel_driver(deviceHandleInfo.handle, deviceHandleInfo.interface); return actualLength; } int32_t LibusbSerial::SerialWrite(int32_t portId, const std::vector& data, uint32_t size, uint32_t timeout) { HDF_LOGI("%{public}s: enter serial write.", __func__); libusb_device* device = GetDevice(portId); if (device == nullptr) { HDF_LOGE("%{public}s: get device failed", __func__); return ERR_CODE_IOEXCEPTION; } DeviceHandleInfo deviceHandleInfo = devices_[device]; if (!deviceHandleInfo.isOpen) { HDF_LOGE("%{public}s: device not open", __func__); return ERR_CODE_DEVICENOTOPEN; } int ret = 0; int actualLength = 0; const uint8_t* dataOut = data.data(); std::lock_guard lock(writeMutex_); libusb_release_interface(deviceHandleInfo.handle, deviceHandleInfo.interface); libusb_attach_kernel_driver(deviceHandleInfo.handle, deviceHandleInfo.interface); libusb_detach_kernel_driver(deviceHandleInfo.handle, deviceHandleInfo.interface); ret = libusb_claim_interface(deviceHandleInfo.handle, deviceHandleInfo.interface); if (ret < 0) { HDF_LOGE("%{public}s: libusb claim failed, ret:%{public}d", __func__, ret); return HDF_FAILURE; } HDF_LOGI("%{public}s: write msg : %{public}s", __func__, data.data()); ret = libusb_bulk_transfer(deviceHandleInfo.handle, deviceHandleInfo.outputEndpointAddr, const_cast(dataOut), data.size(), &actualLength, timeout); if (ret < 0) { HDF_LOGE("%{public}s: write message failed, ret:%{public}d", __func__, ret); libusb_release_interface(deviceHandleInfo.handle, deviceHandleInfo.interface); libusb_attach_kernel_driver(deviceHandleInfo.handle, deviceHandleInfo.interface); return ret; } libusb_release_interface(deviceHandleInfo.handle, deviceHandleInfo.interface); libusb_attach_kernel_driver(deviceHandleInfo.handle, deviceHandleInfo.interface); return actualLength; } int LibusbSerial::GetEndPoint(DeviceHandleInfo *deviceHandleInfo) { int endpointNum = 0; struct libusb_config_descriptor *config; libusb_device *device = libusb_get_device(deviceHandleInfo->handle); libusb_get_active_config_descriptor(device, &config); for (int j = 0; j < config->bNumInterfaces; j++) { const struct libusb_interface *interface = &config->interface[j]; const struct libusb_interface_descriptor *interfaceDesc = interface->altsetting; if (interfaceDesc->bInterfaceClass != TARGET_INTERFACE) { continue; } for (int k = 0; k < interfaceDesc->bNumEndpoints; k++) { const struct libusb_endpoint_descriptor *endpoint = &interfaceDesc->endpoint[k]; if ((endpoint->bmAttributes & LIBUSB_TRANSFER_TYPE_MASK) == LIBUSB_TRANSFER_TYPE_BULK && (endpoint->bEndpointAddress & LIBUSB_ENDPOINT_DIR_MASK) == LIBUSB_ENDPOINT_IN) { deviceHandleInfo->interface = j; deviceHandleInfo->inputEndpointAddr = endpoint->bEndpointAddress; endpointNum++; } if ((endpoint->bmAttributes & LIBUSB_TRANSFER_TYPE_MASK) == LIBUSB_TRANSFER_TYPE_BULK && (endpoint->bEndpointAddress & LIBUSB_ENDPOINT_DIR_MASK) == LIBUSB_ENDPOINT_OUT) { endpointNum++; deviceHandleInfo->interface = j; deviceHandleInfo->outputEndpointAddr = endpoint->bEndpointAddress; } } } libusb_free_config_descriptor(config); return endpointNum != DIRECT_NUM ? HDF_FAILURE : HDF_SUCCESS; } int32_t LibusbSerial::SerialGetAttribute(int32_t portId, struct SerialAttribute& attribute) { HDF_LOGI("%{public}s: enter GetAttribute msg", __func__); libusb_device* device = GetDevice(portId); if (device == nullptr) { HDF_LOGE("%{public}s: libusb_device is null", __func__); return HDF_FAILURE; } DeviceHandleInfo deviceHandleInfo = devices_[device]; if (!deviceHandleInfo.isOpen) { HDF_LOGE("%{public}s: device not open", __func__); return ERR_CODE_DEVICENOTOPEN; } int ret = 0; libusb_release_interface(deviceHandleInfo.handle, deviceHandleInfo.interface); libusb_attach_kernel_driver(deviceHandleInfo.handle, deviceHandleInfo.interface); libusb_detach_kernel_driver(deviceHandleInfo.handle, deviceHandleInfo.interface); ret = libusb_claim_interface(deviceHandleInfo.handle, deviceHandleInfo.interface); if (ret < 0) { HDF_LOGE("%{public}s: libusb claim failed, ret:%{public}d", __func__, ret); return HDF_FAILURE; } unsigned char requestType = LIBUSB_ENDPOINT_IN | LIBUSB_REQUEST_TYPE_CLASS | LIBUSB_RECIPIENT_INTERFACE; uint16_t index = 0; uint16_t value = 0; int length = sizeof(struct SerialAttribute); ret = libusb_control_transfer(deviceHandleInfo.handle, requestType, TRANSFER_CONTROL_IN_CODE, value, index, (unsigned char *)&attribute, length, TRANSFER_TIMEOUT); libusb_release_interface(deviceHandleInfo.handle, deviceHandleInfo.interface); libusb_attach_kernel_driver(deviceHandleInfo.handle, deviceHandleInfo.interface); HDF_LOGI("%{public}s: getattribute baudrate :%{public}d" "databit :%{public}d stop :%{public}d parity :%{public}d", __func__, attribute.baudrate, attribute.dataBits, attribute.stopBits, attribute.parity); if (ret < 0) { HDF_LOGE("%{public}s: libusb get attribute failed, ret:%{public}d", __func__, ret); return HDF_FAILURE; } return HDF_SUCCESS; } int32_t LibusbSerial::SerialSetAttribute(int32_t portId, const struct SerialAttribute& attribute) { HDF_LOGI("%{public}s: setattribute baudrate :%{public}d" "databit :%{public}d stop :%{public}d parity :%{public}d", __func__, attribute.baudrate, attribute.dataBits, attribute.stopBits, attribute.parity); HDF_LOGI("%{public}s: enter setAttribute msg", __func__); libusb_device* device = GetDevice(portId); if (device == nullptr) { return HDF_FAILURE; } DeviceHandleInfo deviceHandleInfo = devices_[device]; if (!deviceHandleInfo.isOpen) { HDF_LOGE("%{public}s: device not open", __func__); return ERR_CODE_DEVICENOTOPEN; } int ret = 0; libusb_release_interface(deviceHandleInfo.handle, deviceHandleInfo.interface); libusb_attach_kernel_driver(deviceHandleInfo.handle, deviceHandleInfo.interface); libusb_detach_kernel_driver(deviceHandleInfo.handle, deviceHandleInfo.interface); ret = libusb_claim_interface(deviceHandleInfo.handle, deviceHandleInfo.interface); if (ret < 0) { HDF_LOGE("%{public}s: libusb claim failed, ret:%{public}d", __func__, ret); return HDF_FAILURE; } unsigned char requestType = LIBUSB_REQUEST_TYPE_CLASS | LIBUSB_RECIPIENT_INTERFACE; uint16_t index = 0; uint16_t value = 0; int length = sizeof(struct SerialAttribute); ret = libusb_control_transfer(deviceHandleInfo.handle, requestType, TRANSFER_CONTROL_OUT_CODE, value, index, (unsigned char *)&attribute, length, TRANSFER_TIMEOUT); libusb_release_interface(deviceHandleInfo.handle, deviceHandleInfo.interface); libusb_attach_kernel_driver(deviceHandleInfo.handle, deviceHandleInfo.interface); if (ret < 0) { HDF_LOGE("%{public}s: libusb set attribute failed, ret:%{public}d", __func__, ret); return HDF_FAILURE; } HDF_LOGI("%{public}s: set attribute success", __func__); return HDF_SUCCESS; } int32_t LibusbSerial::HotplugCallback(libusb_context* ctx, libusb_device* device, libusb_hotplug_event event, void* user_data) { LibusbSerial* self = static_cast(user_data); if (event == LIBUSB_HOTPLUG_EVENT_DEVICE_ARRIVED) { self->HandleDeviceArrival(device); } else if (event == LIBUSB_HOTPLUG_EVENT_DEVICE_LEFT) { self->HandleDeviceRemoval(device); } return HDF_SUCCESS; } int32_t LibusbSerial::HandleDeviceArrival(libusb_device* device) { HDF_LOGI("%{public}s: Device arrival detected.", __func__); struct libusb_device_descriptor desc; int ret = libusb_get_device_descriptor(device, &desc); if (ret < 0) { HDF_LOGW("%{public}s: get device descriptor failed.", __func__); return HDF_FAILURE; } if (desc.bDeviceClass == LIBUSB_CLASS_HUB) { HDF_LOGE("%{public}s: hub device pass.", __func__); return HDF_FAILURE; } std::lock_guard lock(map_mutex_); int num = -1; int retry = RETRY_NUM; while (retry-- > 0) { HDF_LOGI("%{public}s: Attempting to get device number, retry count: %{public}d", __func__, (RETRY_NUM - retry)); num = GetPortIdByDevice(device); if (num >= 0) { break; } std::this_thread::sleep_for(std::chrono::milliseconds(RETRY_TIMEOUT)); } if (num < 0) { HDF_LOGE("%{public}s: Failed to find matching /dev/ttyUSBN for the device after retries", __func__); return HDF_FAILURE; } libusb_device_handle* handle = nullptr; ret = libusb_open(device, &handle); if (ret != LIBUSB_SUCCESS) { HDF_LOGE("%{public}s: Failed to open device: %{public}d", __func__, ret); return HDF_FAILURE; } DeviceHandleInfo info; info.num = num; info.handle = handle; info.isOpen = false; if (GetEndPoint(&info) != HDF_SUCCESS) { HDF_LOGE("%{public}s: get endpoint failed", __func__); return HDF_FAILURE; } devices_[device] = info; HDF_LOGI("%{public}s: Device arrived and opened: num = %{public}d", __func__, num); return HDF_SUCCESS; } void LibusbSerial::HandleDeviceRemoval(libusb_device* device) { HDF_LOGI("%{public}s: Device removal detected.", __func__); struct libusb_device_descriptor desc; int ret = libusb_get_device_descriptor(device, &desc); if (ret < 0) { HDF_LOGW("%{public}s: get device descriptor failed.", __func__); return; } if (desc.bDeviceClass == LIBUSB_CLASS_HUB) { HDF_LOGE("%{public}s: hub device pass.", __func__); return; } std::lock_guard lock(map_mutex_); auto it = devices_.find(device); if (it == devices_.end()) { HDF_LOGE("%{public}s: Device not found in map during removal.", __func__); return; } if (it->second.handle) { libusb_close(it->second.handle); it->second.handle = nullptr; } int num = it->second.num; devices_.erase(it); HDF_LOGI("%{public}s: Device removed: num = %{public}d", __func__, num); } void LibusbSerial::EventHandlingThread() { HDF_LOGI("%{public}s: enter Event handling thread.", __func__); pthread_setname_np(pthread_self(), THREAD_NAME.c_str()); while (running_) { int ret = libusb_handle_events_completed(ctx_, nullptr); if (ret != LIBUSB_SUCCESS) { HDF_LOGE("%{public}s: libusb_handle_events_completed failed: %{public}d", __func__, ret); } } HDF_LOGI("%{public}s: Event handling thread end.", __func__); } std::string GetTtyDevicePath(const std::string& ttyDevice) { HDF_LOGI("%{public}s : enter GetTtyDevicePath.", __func__); std::string ttyPathStr = TTYUSB_PATH + "/" + ttyDevice; fs::path ttyPath(ttyPathStr); if (!fs::exists(ttyPath) || !fs::is_symlink(ttyPath)) { HDF_LOGE("%{public}s: path %{public}s not exist", __func__, ttyPath.string().c_str()); return NULL; } fs::path realPath = fs::read_symlink(ttyPath); std::string tempPath = ttyPath.parent_path().string() + "/" + realPath.string(); realPath = fs::weakly_canonical(fs::path(tempPath)); std::string targetPath = realPath.parent_path().parent_path().parent_path().parent_path().string(); return targetPath; } bool CheckTtyDeviceInfo(std::string ttyUsbPath, libusb_device* device) { HDF_LOGI("%{public}s : enter checkTtyDeviceInfo.", __func__); int busnumFd = 0; int devnumFd = 0; char realpathStr[PATH_MAX] = {'\0'}; if (realpath((ttyUsbPath + BUS_NUM_STR).c_str(), realpathStr) == nullptr || realpath((ttyUsbPath + DEV_NUM_STR).c_str(), realpathStr) == nullptr) { HDF_LOGE("%{public}s : realpath failed. ret = %{public}s", __func__, strerror(errno)); return false; } busnumFd = open((ttyUsbPath + BUS_NUM_STR).c_str(), O_RDONLY); if (busnumFd < 0) { HDF_LOGE("%{public}s : open file failed. ret = %{public}s", __func__, strerror(errno)); return false; } fdsan_exchange_owner_tag(busnumFd, 0, fdsan_create_owner_tag(FDSAN_OWNER_TYPE_FILE, LOG_DOMAIN)); char busnumBuff[BUFFER_SIZE] = {'\0'}; ssize_t readBytes = read(busnumFd, busnumBuff, BUFFER_SIZE); fdsan_close_with_tag(busnumFd, fdsan_create_owner_tag(FDSAN_OWNER_TYPE_FILE, LOG_DOMAIN)); if (readBytes < 0) { HDF_LOGE("%{public}s : busnumFd readbytes < 0. ret = %{public}s", __func__, strerror(errno)); return false; } devnumFd = open((ttyUsbPath + DEV_NUM_STR).c_str(), O_RDONLY); if (devnumFd < 0) { HDF_LOGE("%{public}s : open file failed. ret = %{public}s", __func__, strerror(errno)); return false; } fdsan_exchange_owner_tag(devnumFd, 0, fdsan_create_owner_tag(FDSAN_OWNER_TYPE_FILE, LOG_DOMAIN)); char devnumBuff[BUFFER_SIZE] = {'\0'}; readBytes = read(devnumFd, devnumBuff, BUFFER_SIZE); fdsan_close_with_tag(devnumFd, fdsan_create_owner_tag(FDSAN_OWNER_TYPE_FILE, LOG_DOMAIN)); if (readBytes < 0) { HDF_LOGE("%{public}s : busnumFd readbytes < 0. ret = %{public}s", __func__, strerror(errno)); return false; } if (atoi(devnumBuff) == libusb_get_device_address(device) && atoi(busnumBuff) == libusb_get_bus_number(device)) { return true; } return false; } int32_t LibusbSerial::GetPortIdByDevice(libusb_device* device) { HDF_LOGI("%{public}s : enter GetPortIdByDevice.", __func__); DIR* dir = opendir(DEV_PATH_PREFIX.c_str()); if (dir == nullptr) { HDF_LOGI("%{public}s : dir is not existed %{public}s", __func__, strerror(errno)); return -1; } struct dirent* entry = nullptr; while ((entry = readdir(dir)) != nullptr) { if (strncmp(entry->d_name, DEV_FILENAME_PREFIX.c_str(), DEV_FILENAME_PREFIX.size()) == 0) { std::string devName = entry->d_name; std::string targetPath = GetTtyDevicePath(devName); if (targetPath.size() == 0) { continue; } if (CheckTtyDeviceInfo(targetPath, device)) { closedir(dir); int32_t target = atoi(devName.substr(DEV_FILENAME_PREFIX.size()).c_str()); return target; } } } closedir(dir); HDF_LOGI("%{public}s : it's not a serial device", __func__); return -1; } } // V1_0 } // Serial } // Usb } // HDI } // OHOS