diff --git a/Documentation/OpenRGB SDK Wireshark Dissector.lua b/Documentation/OpenRGB SDK Wireshark Dissector.lua index ea06711b9..3c70a4e7f 100644 --- a/Documentation/OpenRGB SDK Wireshark Dissector.lua +++ b/Documentation/OpenRGB SDK Wireshark Dissector.lua @@ -110,6 +110,14 @@ get_usb_device_info_manufacturer_string = ProtoField.string("openrgb get_usb_device_info_product_string_size = ProtoField.uint16("openrgb.product_string_size", "product_string_size", base.DEC) get_usb_device_info_product_string = ProtoField.string("openrgb.product_string", "product_string", base.STRING) +--[[--------------------------------------------------------- +- NET_PACKET_ID_GET_SERIAL_PORTS fields - +-----------------------------------------------------------]] +get_serial_ports_data_size = ProtoField.uint32("openrgb.data_size", "data_size", base.DEC) +get_serial_ports_port_count = ProtoField.uint32("openrgb.port_count", "port_count", base.DEC) +get_serial_ports_port_string_size = ProtoField.uint16("openrgb.port_string_size", "port_string_size", base.DEC) +get_serial_ports_port_string = ProtoField.string("openrgb.port_string", "port_string", base.STRING) + --[[--------------------------------------------------------- - NET_PACKET_ID_PROFILEMANAGER_GET_PROFILE_LIST fields - -----------------------------------------------------------]] @@ -380,6 +388,10 @@ openrgb_protocol.fields = get_usb_device_info_manufacturer_string, get_usb_device_info_product_string_size, get_usb_device_info_product_string, + get_serial_ports_data_size, + get_serial_ports_port_count, + get_serial_ports_port_string_size, + get_serial_ports_port_string, profilemanager_get_profile_list_data_size, profilemanager_get_profile_list_num_profiles, profilemanager_get_profile_list_profile_name_len, @@ -597,6 +609,8 @@ function openrgb_protocol.dissector(buffer, pinfo, tree) get_hid_device_info(buffer(16), pinfo, subtree, client) elseif pkt_id == 122 then get_usb_device_info(buffer(16), pinfo, subtree, client) + elseif pkt_id == 123 then + get_serial_ports(buffer(16), pinfo, subtree, client) elseif pkt_id == 140 then request_rescan_devices(buffer(16), pinfo, subtree) elseif pkt_id == 150 then @@ -1010,6 +1024,39 @@ function get_usb_device_info(buffer, pinfo, tree, client) end end +--[[--------------------------------------------------------- +- NET_PACKET_ID_GET_SERIAL_PORTS - +-----------------------------------------------------------]] +function get_serial_ports(buffer, pinfo, tree, client) + local length = buffer:len() + + if length == 0 then + return + end + + if client == false then + local subtree = tree:add("Get Serial Ports") + + local data_size = buffer(0,4):le_uint() + subtree:add_le(get_serial_ports_data_size, buffer(0,4)) + + local port_count = buffer(4,4):le_uint() + subtree:add_le(get_serial_ports_port_count, buffer(4,4)) + + local offset = 8 + + for i = 1, port_count do + local port_tree = subtree:add("Serial Port " .. i) + + local port_string_size = buffer(offset,2):le_uint() + port_tree:add_le(get_serial_ports_port_string_size, buffer(offset,2)); offset = offset + 2 + if port_string_size > 0 then + port_tree:add(get_serial_ports_port_string, buffer(offset, port_string_size)); offset = offset + port_string_size + end + end + end +end + --[[--------------------------------------------------------- - NET_PACKET_ID_REQUEST_RESCAN_DEVICES - -----------------------------------------------------------]] @@ -1759,6 +1806,7 @@ function get_pkt_id_name(pkt_id) elseif pkt_id == 120 then pkt_id_name = "NET_PACKET_ID_GET_I2C_BUS_INFO" elseif pkt_id == 121 then pkt_id_name = "NET_PACKET_ID_GET_HID_DEVICE_INFO" elseif pkt_id == 122 then pkt_id_name = "NET_PACKET_ID_GET_USB_DEVICE_INFO" + elseif pkt_id == 123 then pkt_id_name = "NET_PACKET_ID_GET_SERIAL_PORTS" elseif pkt_id == 140 then pkt_id_name = "NET_PACKET_ID_REQUEST_RESCAN_DEVICES" elseif pkt_id == 150 then pkt_id_name = "NET_PACKET_ID_PROFILEMANAGER_GET_PROFILE_LIST" elseif pkt_id == 151 then pkt_id_name = "NET_PACKET_ID_PROFILEMANAGER_SAVE_PROFILE" diff --git a/Documentation/OpenRGBSDK.md b/Documentation/OpenRGBSDK.md index 101dc14c8..bb30cc720 100644 --- a/Documentation/OpenRGBSDK.md +++ b/Documentation/OpenRGBSDK.md @@ -62,6 +62,7 @@ The following IDs represent different SDK commands. Each ID packet has a certai | 120 | [NET_PACKET_ID_GET_I2C_BUS_INFO](#net_packet_id_get_i2c_bus_info) | Request list of I2C bus info | 6 | | 121 | [NET_PACKET_ID_GET_HID_DEVICE_INFO](#net_packet_id_get_hid_device_info) | Request list of HID device info | 6 | | 122 | [NET_PACKET_ID_GET_USB_DEVICE_INFO](#net_packet_id_get_usb_device_info) | Request list of USB device info | 6 | +| 123 | [NET_PACKET_ID_GET_SERIAL_PORTS](#net_packet_id_get_serial_ports) | Request list of serial ports | 6 | | 140 | [NET_PACKET_ID_REQUEST_RESCAN_DEVICES](#net_packet_id_request_rescan_devices) | Request server to rescan devices | 5 | | 150 | [NET_PACKET_ID_PROFILEMANAGER_GET_PROFILE_LIST](#net_packet_id_profilemanager_get_profile_list) | Get profile list | 2 | | 151 | [NET_PACKET_ID_PROFILEMANAGER_SAVE_PROFILE](#net_packet_id_profilemanager_save_profile) | Save current configuration in a new profile | 2 | @@ -458,6 +459,29 @@ The server responds with a data block containing USB device information. | 2 | unsigned short | product_string_size | 6 | Length of product string, including null termination | | product_string_size | char[product_string_size] | product_string | 6 | Product string value, including null termination | +## NET_PACKET_ID_GET_SERIAL_PORTS + +### Request [Size: 0] + +The client uses this ID to request a list of serial ports from the server. The request contains no data. This request should only be used if the server sets the NET_SERVER_FLAG_SUPPORTS_DEVICE_INFO flag. + +### Response [Size: Variable] + +The server responds with a data block containing serial port information. + +| Size | Format | Name | Protocol Version | Description | +| -------- | ------------------------------- | -------------- | ---------------- | ------------------------------------------------------------------------------------------ | +| 4 | unsigned int | data_size | 6 | Size of all data in packet | +| 4 | unsigned int | port_count | 6 | Number of serial port entries | +| Variable | Serial Port Data[port_count] | port_data | 6 | See [Serial Port Data](#serial-port-data) block format table. Repeat port_count times | + +### Serial Port Data + +| Size | Format | Name | Protocol Version | Description | +| ------------------- | -------------------------- | --------------------- | ---------------- | -------------------------------------------------------------- | +| 2 | unsigned short | port_string_size | 6 | Length of port string, including null termination | +| port_string_size | char[port_string_size] | port_string | 6 | Port string value, including null termination | + ## NET_PACKET_ID_REQUEST_RESCAN_DEVICES ### Client Only [Size: 0] diff --git a/NetworkClient.cpp b/NetworkClient.cpp index 5a8a5843e..e72575b84 100644 --- a/NetworkClient.cpp +++ b/NetworkClient.cpp @@ -527,6 +527,64 @@ std::vector NetworkClient::GetI2CBusInfo() return(bus_info); } +std::vector NetworkClient::GetSerialPorts() +{ + /*-----------------------------------------------------*\ + | Send request | + \*-----------------------------------------------------*/ + std::vector serial_ports; + NetPacketHeader reply_hdr; + + if(GetSupportsDeviceInfoAPI()) + { + InitNetPacketHeader(&reply_hdr, 0, NET_PACKET_ID_GET_SERIAL_PORTS, 0); + + send_in_progress.lock(); + send(client_sock, (char *)&reply_hdr, sizeof(NetPacketHeader), MSG_NOSIGNAL); + send_in_progress.unlock(); + + /*-------------------------------------------------*\ + | Wait for response | + \*-------------------------------------------------*/ + std::unique_lock wait_lock(waiting_on_response_mutex); + waiting_on_response_cv.wait(wait_lock); + + /*-------------------------------------------------*\ + | Parse response into device list | + \*-------------------------------------------------*/ + if(response_header.pkt_id == NET_PACKET_ID_GET_SERIAL_PORTS && response_data_ptr != NULL) + { + unsigned int port_count = 0; + unsigned char* data_ptr = response_data_ptr; + unsigned int& data_size = response_header.pkt_size; + unsigned int data_size_pkt; + + COPY_DATA_FIELD(data_ptr, response_data_ptr, data_size_pkt); + + if(data_size_pkt == data_size) + { + COPY_DATA_FIELD(data_ptr, response_data_ptr, port_count); + + for(unsigned int port_idx = 0; port_idx < port_count; port_idx++) + { + std::string port_string; + unsigned short port_string_size; + COPY_DATA_FIELD(data_ptr, response_data_ptr, port_string_size); + COPY_STRING_FIELD(data_ptr, response_data_ptr, port_string_size, port_string); + + serial_ports.push_back(port_string); + } + } + + COPY_DATA_ERROR: + delete[] response_data_ptr; + response_data_ptr = NULL; + } + } + + return(serial_ports); +} + std::vector NetworkClient::GetUSBDeviceInfo() { /*-----------------------------------------------------*\ @@ -1670,6 +1728,7 @@ void NetworkClient::ListenThreadFunction() case NET_PACKET_ID_GET_I2C_BUS_INFO: case NET_PACKET_ID_GET_HID_DEVICE_INFO: case NET_PACKET_ID_GET_USB_DEVICE_INFO: + case NET_PACKET_ID_GET_SERIAL_PORTS: case NET_PACKET_ID_LOGMANAGER_GET_LOG_LEVEL: case NET_PACKET_ID_PROFILEMANAGER_DOWNLOAD_PROFILE: case NET_PACKET_ID_PROFILEMANAGER_GET_ACTIVE_PROFILE: diff --git a/NetworkClient.h b/NetworkClient.h index 02f7493b1..ed2f37c83 100644 --- a/NetworkClient.h +++ b/NetworkClient.h @@ -113,6 +113,7 @@ public: \*-----------------------------------------------------*/ std::vector GetHIDDeviceInfo(); std::vector GetI2CBusInfo(); + std::vector GetSerialPorts(); std::vector GetUSBDeviceInfo(); /*-----------------------------------------------------*\ diff --git a/NetworkProtocol.h b/NetworkProtocol.h index 487160a39..e32da5a39 100644 --- a/NetworkProtocol.h +++ b/NetworkProtocol.h @@ -120,6 +120,7 @@ enum NET_PACKET_ID_GET_I2C_BUS_INFO = 120, /* Request list of I2C bus info */ NET_PACKET_ID_GET_HID_DEVICE_INFO = 121, /* Request list of HID device info */ NET_PACKET_ID_GET_USB_DEVICE_INFO = 122, /* Request list of USB device info */ + NET_PACKET_ID_GET_SERIAL_PORTS = 123, /* Request list of serial ports */ NET_PACKET_ID_REQUEST_RESCAN_DEVICES = 140, /* Request rescan of devices */ diff --git a/NetworkServer.cpp b/NetworkServer.cpp index c51e3cfba..c334dea4e 100644 --- a/NetworkServer.cpp +++ b/NetworkServer.cpp @@ -1296,6 +1296,10 @@ void NetworkServer::ListenThreadFunction(NetworkClientInfo* client_info) status = ProcessRequest_GetUSBDeviceInfo(client_info); break; + case NET_PACKET_ID_GET_SERIAL_PORTS: + status = ProcessRequest_GetSerialPorts(client_info); + break; + /*-------------------------------------------------*\ | LogManager functions | \*-------------------------------------------------*/ @@ -1778,6 +1782,66 @@ NetPacketStatus NetworkServer::ProcessRequest_GetI2CBusInfo(NetworkClientInfo* c return(NET_PACKET_STATUS_OK); } +NetPacketStatus NetworkServer::ProcessRequest_GetSerialPorts(NetworkClientInfo* client_info) +{ + /*-----------------------------------------------------*\ + | Require local client for this packet | + \*-----------------------------------------------------*/ + if(!client_info->client_is_local_client) + { + return(NET_PACKET_STATUS_ERROR_NOT_ALLOWED); + } + + std::vector serial_ports = ResourceManager::get()->GetSerialPorts(); + + unsigned int data_size = 0; + unsigned int port_count = (unsigned int)serial_ports.size(); + + /*-----------------------------------------------------*\ + | Calculate data size | + \*-----------------------------------------------------*/ + data_size += sizeof(data_size); + data_size += sizeof(port_count); + + for(unsigned int port_idx = 0; port_idx < port_count; port_idx++) + { + data_size += sizeof(unsigned short); + data_size += (unsigned int)strlen(serial_ports[port_idx].c_str()) + 1; + } + + /*-----------------------------------------------------*\ + | Copy in data | + \*-----------------------------------------------------*/ + unsigned char* data_buf = new unsigned char[data_size]; + unsigned char* data_ptr = data_buf; + + memcpy(data_ptr, &data_size, sizeof(data_size)); + data_ptr += sizeof(data_size); + + memcpy(data_ptr, &port_count, sizeof(port_count)); + data_ptr += sizeof(port_count); + + for(unsigned int port_idx = 0; port_idx < port_count; port_idx++) + { + unsigned short port_string_size = (unsigned short)strlen(serial_ports[port_idx].c_str()) + 1; + memcpy(data_ptr, &port_string_size, sizeof(port_string_size)); + data_ptr += sizeof(port_string_size); + memcpy(data_ptr, serial_ports[port_idx].c_str(), port_string_size); + data_ptr += port_string_size; + } + + NetPacketHeader reply_hdr; + + InitNetPacketHeader(&reply_hdr, 0, NET_PACKET_ID_GET_SERIAL_PORTS, data_size); + + send_in_progress.lock(); + send(client_info->client_sock, (char *)&reply_hdr, sizeof(NetPacketHeader), MSG_NOSIGNAL); + send(client_info->client_sock, (char *)data_buf, reply_hdr.pkt_size, MSG_NOSIGNAL); + send_in_progress.unlock(); + + return(NET_PACKET_STATUS_OK); +} + NetPacketStatus NetworkServer::ProcessRequest_GetUSBDeviceInfo(NetworkClientInfo* client_info) { /*-----------------------------------------------------*\ diff --git a/NetworkServer.h b/NetworkServer.h index 56b72919e..cebd653c9 100644 --- a/NetworkServer.h +++ b/NetworkServer.h @@ -232,6 +232,7 @@ private: NetPacketStatus ProcessRequest_GetHIDDeviceInfo(NetworkClientInfo* client_info); NetPacketStatus ProcessRequest_GetI2CBusInfo(NetworkClientInfo* client_info); + NetPacketStatus ProcessRequest_GetSerialPorts(NetworkClientInfo* client_info); NetPacketStatus ProcessRequest_GetUSBDeviceInfo(NetworkClientInfo* client_info); NetPacketStatus ProcessRequest_LogManager_ClearLogBuffer(NetworkClientInfo* client_info); diff --git a/ResourceManager.cpp b/ResourceManager.cpp index b67a080cd..c4da2edd5 100644 --- a/ResourceManager.cpp +++ b/ResourceManager.cpp @@ -23,6 +23,7 @@ #include "ResourceManager.h" #include "ProfileManager.h" #include "LogManager.h" +#include "serial_port.h" #include "SettingsManager.h" #include "StringUtils.h" #include "NetworkClient.h" @@ -377,6 +378,18 @@ std::vector ResourceManager::GetI2CBusInfo() } } +std::vector ResourceManager::GetSerialPorts() +{ + if(IsLocalClient()) + { + return(GetLocalClient()->GetSerialPorts()); + } + else + { + return(serial_port::getSerialPorts()); + } +} + std::vector ResourceManager::GetUSBDeviceInfo() { if(IsLocalClient()) diff --git a/ResourceManager.h b/ResourceManager.h index b67b4d983..ad12b26b2 100644 --- a/ResourceManager.h +++ b/ResourceManager.h @@ -81,6 +81,7 @@ public: std::vector GetHIDDeviceInfo(); std::vector& GetI2CBuses(); std::vector GetI2CBusInfo(); + std::vector GetSerialPorts(); std::vector GetUSBDeviceInfo(); PluginManagerInterface* GetPluginManager(); ProfileManager* GetProfileManager(); diff --git a/qt/ManualDevicesSettingsPage/DMXSettingsEntry/DMXSettingsEntry.cpp b/qt/ManualDevicesSettingsPage/DMXSettingsEntry/DMXSettingsEntry.cpp index bd80ef26c..89c596524 100644 --- a/qt/ManualDevicesSettingsPage/DMXSettingsEntry/DMXSettingsEntry.cpp +++ b/qt/ManualDevicesSettingsPage/DMXSettingsEntry/DMXSettingsEntry.cpp @@ -10,8 +10,8 @@ #include "DMXSettingsEntry.h" #include "ui_DMXSettingsEntry.h" -#include "serial_port.h" #include +#include "ResourceManager.h" DMXSettingsEntry::DMXSettingsEntry(QWidget *parent) : BaseManualDeviceEntry(parent), @@ -19,7 +19,8 @@ DMXSettingsEntry::DMXSettingsEntry(QWidget *parent) : { ui->setupUi(this); - std::vector serialPorts = serial_port::getSerialPorts(); + std::vector serialPorts = ResourceManager::get()->GetSerialPorts(); + for(size_t i = 0; i < serialPorts.size(); ++i) { ui->PortComboBox->addItem(QString::fromStdString(serialPorts[i])); diff --git a/qt/ManualDevicesSettingsPage/SerialSettingsEntry/SerialSettingsEntry.cpp b/qt/ManualDevicesSettingsPage/SerialSettingsEntry/SerialSettingsEntry.cpp index a30e5d647..7ca9cff72 100644 --- a/qt/ManualDevicesSettingsPage/SerialSettingsEntry/SerialSettingsEntry.cpp +++ b/qt/ManualDevicesSettingsPage/SerialSettingsEntry/SerialSettingsEntry.cpp @@ -10,8 +10,8 @@ #include "SerialSettingsEntry.h" #include "ui_SerialSettingsEntry.h" -#include "serial_port.h" #include +#include "ResourceManager.h" SerialSettingsEntry::SerialSettingsEntry(QWidget *parent) : BaseManualDeviceEntry(parent), @@ -24,7 +24,8 @@ SerialSettingsEntry::SerialSettingsEntry(QWidget *parent) : ui->ProtocolComboBox->addItem("TPM2"); ui->ProtocolComboBox->addItem("Basic I2C"); - std::vector serialPorts = serial_port::getSerialPorts(); + std::vector serialPorts = ResourceManager::get()->GetSerialPorts(); + for(size_t i = 0; i < serialPorts.size(); ++i) { ui->PortComboBox->addItem(QString::fromStdString(serialPorts[i]));