From 70be81c92d36c071eb8d909e4223d79d0897575a Mon Sep 17 00:00:00 2001 From: Yohan Date: Tue, 27 Jan 2026 16:54:51 +0000 Subject: [PATCH] Merge: Add CDC Check in JGINYUE Usb Controller #5128 --- .../JGINYUEInternalUSBV2Controller.cpp | 56 ++++++++++++++++++---- .../JGINYUEInternalUSBV2ControllerDetect.cpp | 41 +++++++++++----- serial_port/find_usb_serial_port_linux.cpp | 8 ++++ 3 files changed, 84 insertions(+), 21 deletions(-) diff --git a/Controllers/JGINYUEInternalUSBV2Controller/JGINYUEInternalUSBV2Controller.cpp b/Controllers/JGINYUEInternalUSBV2Controller/JGINYUEInternalUSBV2Controller.cpp index 78e20009..f391a720 100644 --- a/Controllers/JGINYUEInternalUSBV2Controller/JGINYUEInternalUSBV2Controller.cpp +++ b/Controllers/JGINYUEInternalUSBV2Controller/JGINYUEInternalUSBV2Controller.cpp @@ -18,7 +18,7 @@ #include "ResourceManager.h" #include "SettingsManager.h" #include "JGINYUEInternalUSBV2Controller.h" - +#include "LogManager.h" #include "dmiinfo.h" #define JGINYUE_V2_HID_GENERAL_COMMAND_HEADER 0x01 @@ -55,8 +55,10 @@ JGINYUEInternalUSBV2Controller::JGINYUEInternalUSBV2Controller(hid_device* jy_hi JGINYUEInternalUSBV2Controller::~JGINYUEInternalUSBV2Controller() { hid_close(jy_hid_interface); - delete jy_cdc_interface; - + if(jy_cdc_interface != nullptr) + { + delete jy_cdc_interface; + } } unsigned int JGINYUEInternalUSBV2Controller::GetZoneCount() @@ -91,14 +93,26 @@ void JGINYUEInternalUSBV2Controller::Init_device() memset(usb_buf, 0x00, sizeof(usb_buf)); usb_buf[0] = JGINYUE_V2_HID_GENERAL_COMMAND_HEADER; usb_buf[1] = 0x0F; - hid_write(jy_hid_interface, usb_buf, 64); + + int write_result = hid_write(jy_hid_interface, usb_buf, 64); + if(write_result < 0) + { + LOG_ERROR("[JGINYUEInternalUSBV2Controller] Failed to write to JGINYUE device during initialization"); + ZoneCount = 0x00; + memset(device_config, 0x00, sizeof(device_config)); + memset(&device_config_Global, 0x00, sizeof(device_config_Global)); + return; + } + std::this_thread::sleep_for(20ms); - hid_read(jy_hid_interface, usb_buf, 64); - if(usb_buf[1] != 0x0F) + + int bytes_read = hid_read_timeout(jy_hid_interface, usb_buf, 64, 1000); + if(bytes_read <= 0 || usb_buf[1] != 0x0F) { + LOG_ERROR("[JGINYUEInternalUSBV2Controller] JGINYUE device did not respond or invalid response (bytes read: %d)", bytes_read); ZoneCount = 0x00; memset(device_config, 0x00, sizeof(device_config)); - memset (&device_config_Global, 0x00, sizeof(device_config_Global)); + memset(&device_config_Global, 0x00, sizeof(device_config_Global)); return; } unsigned char Zone_Info = usb_buf[4]; @@ -135,13 +149,25 @@ void JGINYUEInternalUSBV2Controller::Init_Zone(int zone) usb_buf[1] = JGINYUE_V2_HID_REQUEST_ARGB_SETTING; usb_buf[2] = Area_ID; - hid_write(jy_hid_interface, usb_buf, 64); + int write_result = hid_write(jy_hid_interface, usb_buf, 64); + if(write_result < 0) + { + LOG_ERROR("[JGINYUEInternalUSBV2Controller] Failed to write to JGINYUE device for zone %d", zone); + return; + } + std::this_thread::sleep_for(20ms); - hid_read(jy_hid_interface, usb_buf, 64); + int bytes_read = hid_read_timeout(jy_hid_interface, usb_buf, 64, 1000); + if(bytes_read <= 0) + { + LOG_ERROR("[JGINYUEInternalUSBV2Controller] Failed to read zone %d config from JGINYUE device (bytes read: %d)", zone, bytes_read); + return; + } - if((usb_buf[1] != JGINYUE_V2_HID_REQUEST_ARGB_SETTING)|(usb_buf[2] != Area_ID)) + if((usb_buf[1] != JGINYUE_V2_HID_REQUEST_ARGB_SETTING) || (usb_buf[2] != Area_ID)) { + LOG_ERROR("[JGINYUEInternalUSBV2Controller] Invalid response for zone %d from JGINYUE device", zone); return; } @@ -200,6 +226,16 @@ void JGINYUEInternalUSBV2Controller::DirectLEDControl unsigned char Area ) { + /*-----------------------------------------------------*\ + | Direct mode requires CDC interface | + | If CDC is not available, log error and return | + \*-----------------------------------------------------*/ + if(jy_cdc_interface == nullptr) + { + LOG_WARNING("[JGINYUEInternalUSBV2Controller] Direct mode requires serial port (CDC) which is not available. Use other modes instead."); + return; + } + unsigned char cdc_buf[512]; memset(cdc_buf, 0x00, sizeof(cdc_buf)); cdc_buf[0] = JGINYUE_V2_CDC_COMMAND_HEADER; diff --git a/Controllers/JGINYUEInternalUSBV2Controller/JGINYUEInternalUSBV2ControllerDetect.cpp b/Controllers/JGINYUEInternalUSBV2Controller/JGINYUEInternalUSBV2ControllerDetect.cpp index e98234ba..f5af6934 100644 --- a/Controllers/JGINYUEInternalUSBV2Controller/JGINYUEInternalUSBV2ControllerDetect.cpp +++ b/Controllers/JGINYUEInternalUSBV2Controller/JGINYUEInternalUSBV2ControllerDetect.cpp @@ -46,30 +46,49 @@ void DetectJGINYUEInternalUSBV2Controller(hid_device_info* info,const std::strin std::transform(manufacturer.begin(), manufacturer.end(), manufacturer.begin(), ::toupper); if(manufacturer.find("JGINYUE") == std::string::npos) { - LOG_INFO("JGINYUE Internal USB ControllerV2 not found,error manufacturer name:%s",manufacturer.c_str()); + LOG_INFO("[JGINYUEInternalUSBV2ControllerDetect] JGINYUE Internal USB ControllerV2 not found,error manufacturer name:%s",manufacturer.c_str()); + hid_close(hid_dev); return; } - LOG_INFO("Pass manufacture name check.Start to init HID and CDC interface"); + LOG_INFO("[JGINYUEInternalUSBV2ControllerDetect] Pass manufacture name check.Start to init HID and CDC interface"); if(hid_dev != nullptr ) { + serial_port *port = nullptr; std::vector serial_ports = find_usb_serial_port(JGINYUE_VID_V2, JGINYUE_MOTHERBOARD_PID_V2); - if(serial_ports.size() ==1) + + if(serial_ports.size() == 0) + { + LOG_WARNING("[JGINYUEInternalUSBV2ControllerDetect] JGINYUE device found but no serial port detected - Direct mode will be unavailable"); + } + else if(serial_ports.size() > 1) + { + LOG_WARNING("[JGINYUEInternalUSBV2ControllerDetect] Multiple serial ports found for JGINYUE device, using first one"); + } + + if(serial_ports.size() >= 1) { - serial_port *port = new serial_port(); + port = new serial_port(); if(!port->serial_open(serial_ports[0]->c_str(), 115200)) { - LOG_ERROR("Failed to open serial port %s", serial_ports[0]->c_str()); + LOG_WARNING("[JGINYUEInternalUSBV2ControllerDetect] Failed to open serial port %s - Direct mode will be unavailable. HID modes will still work.", serial_ports[0]->c_str()); delete port; - hid_close(hid_dev); - return; + port = nullptr; } - JGINYUEInternalUSBV2Controller *controller = new JGINYUEInternalUSBV2Controller(hid_dev, info->path,port); - RGBController_JGINYUEInternalUSBV2 *rgb_controller = new RGBController_JGINYUEInternalUSBV2(controller); - ResourceManager::get()->RegisterRGBController(rgb_controller); - LOG_INFO("JGINYUE Internal USB ControllerV2 found"); } + + /*-----------------------------------------------------*\ + | Clean up serial port string vector | + \*-----------------------------------------------------*/ + for(std::string* str_ptr : serial_ports) + { + delete str_ptr; + } + + JGINYUEInternalUSBV2Controller *controller = new JGINYUEInternalUSBV2Controller(hid_dev, info->path, port); + RGBController_JGINYUEInternalUSBV2 *rgb_controller = new RGBController_JGINYUEInternalUSBV2(controller); + ResourceManager::get()->RegisterRGBController(rgb_controller); } } diff --git a/serial_port/find_usb_serial_port_linux.cpp b/serial_port/find_usb_serial_port_linux.cpp index a3997b61..062392db 100644 --- a/serial_port/find_usb_serial_port_linux.cpp +++ b/serial_port/find_usb_serial_port_linux.cpp @@ -65,6 +65,14 @@ std::vector find_usb_serial_port(unsigned short vid, unsigned sho | readlink() does not null-terminate, so manually terminate it | \*-----------------------------------------------------------------*/ ssize_t link_path_size = readlink(tty_path, symlink_path, 1024); + if(link_path_size < 0 || link_path_size >= 1024) + { + /*-----------------------------------------------------------------*\ + | readlink failed or buffer too small, skip this device | + \*-----------------------------------------------------------------*/ + ent = readdir(dir); + continue; + } symlink_path[link_path_size] = '\0'; char * usb_string = strstr(symlink_path, "usb");