From f0628d362aac52e5be427b71f306e06f64fd4171 Mon Sep 17 00:00:00 2001 From: Adam Honse Date: Mon, 30 Mar 2026 21:32:11 -0500 Subject: [PATCH] Add ACK to network packets processed by NetworkServer --- Documentation/OpenRGBSDK.md | 18 ++++++++++++++++++ NetworkProtocol.h | 20 +++++++++++++++++++ NetworkServer.cpp | 38 +++++++++++++++++++++++++++++++++++++ NetworkServer.h | 2 ++ 4 files changed, 78 insertions(+) diff --git a/Documentation/OpenRGBSDK.md b/Documentation/OpenRGBSDK.md index b1e073416..2b24c27eb 100644 --- a/Documentation/OpenRGBSDK.md +++ b/Documentation/OpenRGBSDK.md @@ -49,6 +49,7 @@ The following IDs represent different SDK commands. Each ID packet has a certai | ----- | ----------------------------------------------------------------------------------------------------- | ------------------------------------------------------------- | ---------------- | | 0 | [NET_PACKET_ID_REQUEST_CONTROLLER_COUNT](#net_packet_id_request_controller_count) | Request RGBController device count/device IDs from server | 0 | | 1 | [NET_PACKET_ID_REQUEST_CONTROLLER_DATA](#net_packet_id_request_controller_data) | Request RGBController data block | 0 | +| 10 | [NET_PACKET_ID_ACK](#net_packet_id_ack) | Acknowledgement | 6 | | 40 | [NET_PACKET_ID_REQUEST_PROTOCOL_VERSION](#net_packet_id_request_protocol_version) | Request OpenRGB SDK protocol version from server | 1* | | 50 | [NET_PACKET_ID_SET_CLIENT_NAME](#net_packet_id_set_client_name) | Send client name string to server | 0 | | 51 | [NET_PACKET_ID_SET_SERVER_NAME](#net_packet_id_set_server_name) | Send server name string to client | 6 | @@ -257,6 +258,23 @@ The client uses this ID to request the server's highest supported protocol versi The server responds to this request with a single `unsigned int`, size 4, containing the server's highest supported protocol version. If the server is using protocol version 0, it will not send a response. If no response is received, assume the server's highest supported protocol version is version 0. +## NET_PACKET_ID_ACK + +### Acknowledgement [Size: 8] + +This packet is sent by the server to acknowledge any packet sent by the client. The ACK contains two unsigned 32-bit integer values, the first being the packet ID of the packet being acknowledged and the second being a status code. The `pkt_dev_id` field of the header is also set to the `pkt_dev_id` of the packet being acknowledged. + +The status codes are shown below. + +| Status Code | Name | Description | +| ----------- | ------------------------------------ | -------------------------------- | +| 0 | NET_PACKET_STATUS_OK | OK/Success | +| 1 | NET_PACKET_STATUS_ERROR_GENERIC | Generic error | +| 2 | NET_PACKET_STATUS_ERROR_UNSUPPORTED | Unsupported error | +| 3 | NET_PACKET_STATUS_ERROR_NOT_ALLOWED | Not allowed error | +| 4 | NET_PACKET_STATUS_ERROR_INVALID_ID | Invalid device ID or index error | +| 5 | NET_PACKET_STATUS_ERROR_INVALID_DATA | Invalid data error | + ## NET_PACKET_ID_SET_CLIENT_NAME ### Client Only [Size: Variable] diff --git a/NetworkProtocol.h b/NetworkProtocol.h index 5af9542d5..a16564e65 100644 --- a/NetworkProtocol.h +++ b/NetworkProtocol.h @@ -50,6 +50,24 @@ typedef struct NetPacketHeader unsigned int pkt_size; /* Packet size */ } NetPacketHeader; +typedef unsigned int NetPacketStatus; + +enum +{ + NET_PACKET_STATUS_OK = 0, /* OK/Success */ + NET_PACKET_STATUS_ERROR_GENERIC = 1, /* Generic error */ + NET_PACKET_STATUS_ERROR_UNSUPPORTED = 2, /* Unsupported error */ + NET_PACKET_STATUS_ERROR_NOT_ALLOWED = 4, /* Not allowed error */ + NET_PACKET_STATUS_ERROR_INVALID_ID = 5, /* Invalid device ID or index error */ + NET_PACKET_STATUS_ERROR_INVALID_DATA = 6, /* Invalid data error */ +}; + +typedef struct NetPacketAck +{ + unsigned int acked_pkt_id; /* Packet ID of acknowledged packet */ + NetPacketStatus status; /* Status code */ +}; + enum { NET_CLIENT_FLAG_SUPPORTS_RGBCONTROLLER = ( 1 << 0 ), /* Client supports RGBController API */ @@ -79,6 +97,8 @@ enum NET_PACKET_ID_REQUEST_CONTROLLER_COUNT = 0, /* Request RGBController device count from server */ NET_PACKET_ID_REQUEST_CONTROLLER_DATA = 1, /* Request RGBController data block */ + NET_PACKET_ID_ACK = 10, /* Acknowledge an SDK packet */ + NET_PACKET_ID_REQUEST_PROTOCOL_VERSION = 40, /* Request OpenRGB SDK protocol version from server */ NET_PACKET_ID_SET_CLIENT_NAME = 50, /* Send client name string to server */ diff --git a/NetworkServer.cpp b/NetworkServer.cpp index e83f426a0..a392e7922 100644 --- a/NetworkServer.cpp +++ b/NetworkServer.cpp @@ -911,6 +911,7 @@ void NetworkServer::ControllerListenThread(NetworkServerControllerThread * this_ while(this_thread->queue.size() > 0) { NetworkServerControllerThreadQueueEntry queue_entry; + NetPacketStatus status = NET_PACKET_STATUS_OK; this_thread->queue_mutex.lock(); queue_entry = this_thread->queue.front(); @@ -940,11 +941,17 @@ void NetworkServer::ControllerListenThread(NetworkServerControllerThread * this_ case NET_PACKET_ID_RGBCONTROLLER_UPDATEZONEMODE: ProcessRequest_RGBController_UpdateZoneMode(this_thread->id, (unsigned char *)queue_entry.data, queue_entry.client_protocol_version); break; + + default: + status = NET_PACKET_STATUS_ERROR_UNSUPPORTED; + break; } controller_ids_mutex.unlock_shared(); delete[] queue_entry.data; + + SendAck(queue_entry.client_sock, queue_entry.header.pkt_id, queue_entry.header.pkt_id, status, queue_entry.client_protocol_version); } } else @@ -1025,6 +1032,7 @@ void NetworkServer::ListenThreadFunction(NetworkClientInfo * client_info) int bytes_read = 0; char * data = NULL; bool delete_data = true; + NetPacketStatus status = NET_PACKET_STATUS_OK; for(unsigned int i = 0; i < 4; i++) { @@ -1431,12 +1439,18 @@ void NetworkServer::ListenThreadFunction(NetworkClientInfo * client_info) goto listen_done; } break; + + default: + status = NET_PACKET_STATUS_ERROR_UNSUPPORTED; + break; } if(delete_data) { delete[] data; } + + SendAck(client_info->client_sock, header.pkt_dev_id, header.pkt_id, status, client_info->client_protocol_version); } listen_done: @@ -2187,6 +2201,30 @@ void NetworkServer::ProcessRequest_RGBController_UpdateZoneMode(unsigned int con controllers[controller_idx]->UpdateZoneMode(zone_idx); } +void NetworkServer::SendAck(SOCKET client_sock, unsigned int acked_pkt_dev_id, unsigned int acked_pkt_id, NetPacketStatus status, unsigned int protocol_version) +{ + /*-----------------------------------------------------*\ + | ACKs were introduced in protocol version 6 | + \*-----------------------------------------------------*/ + if(protocol_version < 6) + { + return; + } + + NetPacketHeader ack_hdr; + NetPacketAck ack_data; + + InitNetPacketHeader(&ack_hdr, acked_pkt_dev_id, NET_PACKET_ID_ACK, sizeof(NetPacketAck)); + + ack_data.acked_pkt_id = acked_pkt_id; + ack_data.status = status; + + send_in_progress.lock(); + send(client_sock, (const char *)&ack_hdr, sizeof(NetPacketHeader), MSG_NOSIGNAL); + send(client_sock, (const char *)&ack_data, sizeof(ack_data), MSG_NOSIGNAL); + send_in_progress.unlock(); +} + void NetworkServer::SendReply_ControllerCount(SOCKET client_sock, unsigned int protocol_version) { controller_ids_mutex.lock_shared(); diff --git a/NetworkServer.h b/NetworkServer.h index fd2e07619..08647322d 100644 --- a/NetworkServer.h +++ b/NetworkServer.h @@ -248,6 +248,8 @@ private: void ProcessRequest_RGBController_UpdateZoneLEDs(unsigned int controller_id, unsigned char* data_ptr, unsigned int protocol_version); void ProcessRequest_RGBController_UpdateZoneMode(unsigned int controller_id, unsigned char * data_ptr, unsigned int protocol_version); + void SendAck(SOCKET client_sock, unsigned int acked_pkt_dev_id, unsigned int acked_pkt_id, NetPacketStatus status, unsigned int protocol_version); + void SendReply_ControllerCount(SOCKET client_sock, unsigned int protocol_version); void SendReply_ControllerData(SOCKET client_sock, unsigned int dev_id, unsigned int protocol_version); void SendReply_ProtocolVersion(SOCKET client_sock);