diff --git a/NetworkClient.cpp b/NetworkClient.cpp index 43419d08b..ed0d517b8 100644 --- a/NetworkClient.cpp +++ b/NetworkClient.cpp @@ -45,10 +45,10 @@ NetworkClient::NetworkClient() detection_percent = 100; detection_string = ""; protocol_initialized = false; + protocol_version = 0; server_connected = false; - server_controller_count = 0; - server_controller_count_requested = false; - server_controller_count_received = false; + server_controller_ids_requested = false; + server_controller_ids_received = false; server_protocol_version = 0; server_reinitialize = false; change_in_progress = false; @@ -82,17 +82,6 @@ unsigned short NetworkClient::GetPort() unsigned int NetworkClient::GetProtocolVersion() { - unsigned int protocol_version = 0; - - if(server_protocol_version > OPENRGB_SDK_PROTOCOL_VERSION) - { - protocol_version = OPENRGB_SDK_PROTOCOL_VERSION; - } - else - { - protocol_version = server_protocol_version; - } - return(protocol_version); } @@ -208,47 +197,48 @@ void NetworkClient::StopClient() void NetworkClient::SendRequest_ControllerData(unsigned int dev_idx) { NetPacketHeader request_hdr; - unsigned int protocol_version; + /*---------------------------------------------------------*\ + | Clear the controller data received flag | + \*---------------------------------------------------------*/ controller_data_received = false; - memcpy(request_hdr.pkt_magic, openrgb_sdk_magic, sizeof(openrgb_sdk_magic)); - - request_hdr.pkt_dev_idx = dev_idx; - request_hdr.pkt_id = NET_PACKET_ID_REQUEST_CONTROLLER_DATA; - - if(server_protocol_version == 0) + /*---------------------------------------------------------*\ + | Protocol version 0 sends no data, all other protocols | + | send the protocol version | + \*---------------------------------------------------------*/ + if(protocol_version == 0) { - request_hdr.pkt_size = 0; - - send_in_progress.lock(); - send(client_sock, (char *)&request_hdr, sizeof(NetPacketHeader), MSG_NOSIGNAL); - send_in_progress.unlock(); + InitNetPacketHeader(&request_hdr, dev_idx, NET_PACKET_ID_REQUEST_CONTROLLER_DATA, 0); + } + /*---------------------------------------------------------*\ + | Starting with protocol version 6, controllers are | + | identified by a unique identifier received from the | + | server. Previous protocol versions have controllers | + | identified by list index. | + \*---------------------------------------------------------*/ + else if(protocol_version >= 6) + { + InitNetPacketHeader(&request_hdr, server_controller_ids[dev_idx], NET_PACKET_ID_REQUEST_CONTROLLER_DATA, sizeof(protocol_version)); } else { - request_hdr.pkt_size = sizeof(unsigned int); - - /*-------------------------------------------------------------*\ - | Limit the protocol version to the highest supported by both | - | the client and the server. | - \*-------------------------------------------------------------*/ - if(server_protocol_version > OPENRGB_SDK_PROTOCOL_VERSION) - { - protocol_version = OPENRGB_SDK_PROTOCOL_VERSION; - } - else - { - protocol_version = server_protocol_version; - } - - SignalNetworkClientUpdate(NETWORKCLIENT_UPDATE_REASON_PROTOCOL_NEGOTIATED); - - send_in_progress.lock(); - send(client_sock, (char *)&request_hdr, sizeof(NetPacketHeader), MSG_NOSIGNAL); - send(client_sock, (char *)&protocol_version, sizeof(unsigned int), MSG_NOSIGNAL); - send_in_progress.unlock(); + InitNetPacketHeader(&request_hdr, dev_idx, NET_PACKET_ID_REQUEST_CONTROLLER_DATA, sizeof(protocol_version)); } + + /*---------------------------------------------------------*\ + | Send the packet, including the data field if protocol is | + | greater than 0. | + \*---------------------------------------------------------*/ + send_in_progress.lock(); + send(client_sock, (char *)&request_hdr, sizeof(NetPacketHeader), MSG_NOSIGNAL); + + if(protocol_version > 0) + { + send(client_sock, (char *)&protocol_version, sizeof(unsigned int), MSG_NOSIGNAL); + } + + send_in_progress.unlock(); } void NetworkClient::SendRequest_RescanDevices() @@ -779,6 +769,21 @@ void NetworkClient::ConnectionThreadFunction() } } + /*-------------------------------------------------------------*\ + | Limit the protocol version to the highest supported by both | + | the client and the server. | + \*-------------------------------------------------------------*/ + if(server_protocol_version > OPENRGB_SDK_PROTOCOL_VERSION) + { + protocol_version = OPENRGB_SDK_PROTOCOL_VERSION; + } + else + { + protocol_version = server_protocol_version; + } + + SignalNetworkClientUpdate(NETWORKCLIENT_UPDATE_REASON_PROTOCOL_NEGOTIATED); + protocol_initialized = true; } @@ -804,11 +809,11 @@ void NetworkClient::ConnectionThreadFunction() /*-----------------------------------------------------*\ | Request the server controller count | \*-----------------------------------------------------*/ - if(!server_controller_count_requested) + if(!server_controller_ids_requested) { - SendRequest_ControllerCount(); + SendRequest_ControllerIDs(); - server_controller_count_requested = true; + server_controller_ids_requested = true; } else { @@ -816,7 +821,7 @@ void NetworkClient::ConnectionThreadFunction() | Wait for the server controller count to be | | received | \*-------------------------------------------------*/ - if(server_controller_count_received) + if(server_controller_ids_received) { /*---------------------------------------------*\ | Once count is received, request controllers | @@ -824,21 +829,21 @@ void NetworkClient::ConnectionThreadFunction() | requested controllers until all controllers | | have been received | \*---------------------------------------------*/ - if(requested_controllers < server_controller_count) + if(requested_controller_index < server_controller_ids.size()) { if(!controller_data_requested) { - printf("Client: Requesting controller %d\r\n", requested_controllers); + printf("Client: Requesting controller ID %d\r\n", server_controller_ids[requested_controller_index]); controller_data_received = false; - SendRequest_ControllerData(requested_controllers); + SendRequest_ControllerData(requested_controller_index); controller_data_requested = true; } if(controller_data_received) { - requested_controllers++; + requested_controller_index++; controller_data_requested = false; } } @@ -951,7 +956,7 @@ void NetworkClient::ListenThreadFunction() switch(header.pkt_id) { case NET_PACKET_ID_REQUEST_CONTROLLER_COUNT: - ProcessReply_ControllerCount(header.pkt_size, data); + ProcessReply_ControllerIDs(header.pkt_size, data); break; case NET_PACKET_ID_REQUEST_CONTROLLER_DATA: @@ -1020,10 +1025,9 @@ listen_done: controller_data_requested = false; controller_data_received = false; protocol_initialized = false; - requested_controllers = 0; - server_controller_count = 0; - server_controller_count_requested = false; - server_controller_count_received = false; + requested_controller_index = 0; + server_controller_ids_requested = false; + server_controller_ids_received = false; server_initialized = false; server_connected = false; @@ -1049,20 +1053,6 @@ listen_done: /*---------------------------------------------------------*\ | Private Client functions | \*---------------------------------------------------------*/ -void NetworkClient::ProcessReply_ControllerCount(unsigned int data_size, char * data) -{ - if(data_size == sizeof(unsigned int)) - { - memcpy(&server_controller_count, data, sizeof(unsigned int)); - - server_controller_count_received = true; - requested_controllers = 0; - controller_data_requested = false; - - printf("Client: Received controller count from server: %d\r\n", server_controller_count); - } -} - void NetworkClient::ProcessReply_ControllerData(unsigned int data_size, char * data, unsigned int dev_idx) { /*-----------------------------------------------------*\ @@ -1118,6 +1108,50 @@ void NetworkClient::ProcessReply_ControllerData(unsigned int data_size, char * d } } +void NetworkClient::ProcessReply_ControllerIDs(unsigned int data_size, char * data_ptr) +{ + unsigned int controller_count = 0; + + if(data_size >= sizeof(unsigned int)) + { + memcpy(&controller_count, data_ptr, sizeof(controller_count)); + data_ptr += sizeof(controller_count); + + if(protocol_version >= 6) + { + server_controller_ids.clear(); + server_controller_ids.resize(controller_count); + + for(unsigned int controller_id_idx = 0; controller_id_idx < controller_count; controller_id_idx++) + { + memcpy(&server_controller_ids[controller_id_idx], data_ptr, sizeof(server_controller_ids[controller_id_idx])); + data_ptr += sizeof(server_controller_ids[controller_id_idx]); + } + } + else + { + server_controller_ids.clear(); + server_controller_ids.resize(controller_count); + + for(unsigned int controller_id_idx = 0; controller_id_idx < controller_count; controller_id_idx++) + { + server_controller_ids[controller_id_idx] = controller_id_idx; + } + } + + server_controller_ids_received = true; + requested_controller_index = 0; + controller_data_requested = false; + + printf("Client: Received controller ID list of size %d from server: ", (unsigned int)server_controller_ids.size()); + for(std::size_t controller_id_idx = 0; controller_id_idx < server_controller_ids.size(); controller_id_idx++) + { + printf("%d, ", server_controller_ids[controller_id_idx]); + } + printf("\r\n"); + } +} + void NetworkClient::ProcessReply_ProtocolVersion(unsigned int data_size, char * data) { if(data_size == sizeof(unsigned int)) @@ -1184,10 +1218,9 @@ void NetworkClient::ProcessRequest_DeviceListChanged() \*-----------------------------------------------------*/ controller_data_requested = false; controller_data_received = false; - requested_controllers = 0; - server_controller_count = 0; - server_controller_count_requested = false; - server_controller_count_received = false; + requested_controller_index = 0; + server_controller_ids_requested = false; + server_controller_ids_received = false; server_initialized = false; change_in_progress = false; @@ -1281,7 +1314,7 @@ void NetworkClient::SendData_ClientString() send_in_progress.unlock(); } -void NetworkClient::SendRequest_ControllerCount() +void NetworkClient::SendRequest_ControllerIDs() { NetPacketHeader request_hdr; @@ -1340,7 +1373,7 @@ std::vector * NetworkClient::ProcessReply_ProfileList(unsigned int data_ptr += name_len; } - server_controller_count_received = true; + server_controller_ids_received = true; } else { diff --git a/NetworkClient.h b/NetworkClient.h index 58eb15dcf..70544a035 100644 --- a/NetworkClient.h +++ b/NetworkClient.h @@ -132,8 +132,9 @@ private: bool controller_data_received; bool controller_data_requested; bool protocol_initialized; + unsigned int protocol_version; bool change_in_progress; - unsigned int requested_controllers; + unsigned int requested_controller_index; std::mutex send_in_progress; NetPacketHeader response_header; @@ -157,9 +158,8 @@ private: bool server_connected; bool server_initialized; bool server_reinitialize; - unsigned int server_controller_count; - bool server_controller_count_requested; - bool server_controller_count_received; + bool server_controller_ids_requested; + bool server_controller_ids_received; unsigned int server_protocol_version; bool server_protocol_version_received; @@ -183,6 +183,7 @@ private: \*-----------------------------------------------------*/ std::mutex ControllerListMutex; std::vector server_controllers; + std::vector server_controller_ids; /*-----------------------------------------------------*\ | Detection variables | @@ -204,8 +205,8 @@ private: /*-----------------------------------------------------*\ | Private Client functions | \*-----------------------------------------------------*/ - void ProcessReply_ControllerCount(unsigned int data_size, char * data); void ProcessReply_ControllerData(unsigned int data_size, char * data, unsigned int dev_idx); + void ProcessReply_ControllerIDs(unsigned int data_size, char * data_ptr); void ProcessReply_ProtocolVersion(unsigned int data_size, char * data); void ProcessRequest_DetectionProgressChanged(unsigned int data_size, char * data); void ProcessRequest_DeviceListChanged(); @@ -213,7 +214,7 @@ private: void ProcessRequest_ServerString(unsigned int data_size, char * data); void SendData_ClientString(); - void SendRequest_ControllerCount(); + void SendRequest_ControllerIDs(); void SendRequest_ProtocolVersion(); /*-----------------------------------------------------*\ diff --git a/NetworkServer.cpp b/NetworkServer.cpp index 754d9c99e..5ea253684 100644 --- a/NetworkServer.cpp +++ b/NetworkServer.cpp @@ -77,6 +77,8 @@ NetworkServer::NetworkServer(std::vector& control) : controller server_listening = false; legacy_workaround_enabled = false; + controller_next_idx = 0; + for(int i = 0; i < MAXSOCK; i++) { ConnectionThread[i] = nullptr; @@ -85,6 +87,8 @@ NetworkServer::NetworkServer(std::vector& control) : controller plugin_manager = nullptr; profile_manager = nullptr; settings_manager = nullptr; + + DeviceListUpdated(); } NetworkServer::~NetworkServer() @@ -189,6 +193,95 @@ unsigned int NetworkServer::GetClientProtocolVersion(unsigned int client_num) return result; } +/*---------------------------------------------------------*\ +| Signal that device list has been updated | +\*---------------------------------------------------------*/ +void NetworkServer::DeviceListUpdated() +{ + controller_ids_mutex.lock(); + + /*-----------------------------------------------------*\ + | Look for removed controllers and remove their ID | + | entries | + \*-----------------------------------------------------*/ + std::size_t controller_id_idx = 0; + + while(controller_id_idx < controller_ids.size()) + { + /*-------------------------------------------------*\ + | Check to see if there is a controller matching | + | this ID | + \*-------------------------------------------------*/ + bool match = false; + + for(std::size_t controller_idx = 0; controller_idx < controllers.size(); controller_idx++) + { + if(controllers[controller_idx] == controller_ids[controller_id_idx].controller) + { + match = true; + break; + } + } + + /*-------------------------------------------------*\ + | If it does not match, that means the controller | + | has been removed, so we should remove its ID | + \*-------------------------------------------------*/ + if(!match) + { + controller_ids.erase(controller_ids.begin() + controller_id_idx); + } + else + { + controller_id_idx++; + } + } + + /*-----------------------------------------------------*\ + | Create new controller IDs for newly added controllers | + \*-----------------------------------------------------*/ + for(std::size_t controller_idx = 0; controller_idx < controllers.size(); controller_idx++) + { + /*-------------------------------------------------*\ + | Check to see if this controller already has an ID | + \*-------------------------------------------------*/ + bool match = false; + + for(std::size_t controller_id_idx = 0; controller_id_idx < controller_ids.size(); controller_id_idx++) + { + if(controllers[controller_idx] == controller_ids[controller_id_idx].controller) + { + match = true; + break; + } + } + + /*-------------------------------------------------*\ + | If not, create a new ID for this controller | + \*-------------------------------------------------*/ + if(!match) + { + NetworkControllerID new_controller_id; + + new_controller_id.controller = controllers[controller_idx]; + new_controller_id.id = controller_next_idx; + + controller_next_idx++; + + controller_ids.push_back(new_controller_id); + } + } + + printf("Server IDs: "); + for(std::size_t controller_id_idx = 0; controller_id_idx < controller_ids.size(); controller_id_idx++) + { + printf("%d, ", controller_ids[controller_id_idx].id); + } + printf("\r\n"); + + controller_ids_mutex.unlock(); +} + /*---------------------------------------------------------*\ | Callback functions | \*---------------------------------------------------------*/ @@ -197,6 +290,7 @@ void NetworkServer::SignalResourceManagerUpdate(unsigned int update_reason) switch(update_reason) { case RESOURCEMANAGER_UPDATE_REASON_DEVICE_LIST_UPDATED: + DeviceListUpdated(); SignalDeviceListUpdated(); break; @@ -776,7 +870,7 @@ void NetworkServer::ListenThreadFunction(NetworkClientInfo * client_info) | Network requests | \*-------------------------------------------------*/ case NET_PACKET_ID_REQUEST_CONTROLLER_COUNT: - SendReply_ControllerCount(client_sock); + SendReply_ControllerCount(client_sock, client_info->client_protocol_version); break; case NET_PACKET_ID_REQUEST_CONTROLLER_DATA: @@ -1505,19 +1599,55 @@ void NetworkServer::ProcessRequest_RGBController_UpdateZoneMode(std::size_t cont controllers[controller_idx]->UpdateZoneMode(zone_idx); } -void NetworkServer::SendReply_ControllerCount(SOCKET client_sock) +void NetworkServer::SendReply_ControllerCount(SOCKET client_sock, unsigned int protocol_version) { + controller_ids_mutex.lock_shared(); + NetPacketHeader reply_hdr; - unsigned int reply_data; + unsigned int controller_count = (unsigned int)controller_ids.size(); + unsigned int data_size = 0; - InitNetPacketHeader(&reply_hdr, 0, NET_PACKET_ID_REQUEST_CONTROLLER_COUNT, sizeof(unsigned int)); + /*-----------------------------------------------------*\ + | Determine data size | + \*-----------------------------------------------------*/ + data_size += sizeof(controller_count); - reply_data = (unsigned int)controllers.size(); + /*-----------------------------------------------------*\ + | Starting with protocol > 6, a list of controller IDs | + | is sent in addition to the size | + \*-----------------------------------------------------*/ + if(protocol_version >= 6) + { + data_size += (controller_count * sizeof(unsigned int)); + } + + unsigned char * data_buf = new unsigned char[data_size]; + unsigned char * data_ptr = data_buf; + + memcpy(data_ptr, &controller_count, sizeof(controller_count)); + data_ptr += sizeof(controller_count); + + if(protocol_version >= 6) + { + for(unsigned int controller_id_idx = 0; controller_id_idx < controller_count; controller_id_idx++) + { + memcpy(data_ptr, &controller_ids[controller_id_idx].id, sizeof(controller_ids[controller_id_idx].id)); + data_ptr += sizeof(controller_ids[controller_id_idx].id); + } + } + + controller_ids_mutex.unlock_shared(); + + InitNetPacketHeader(&reply_hdr, 0, NET_PACKET_ID_REQUEST_CONTROLLER_COUNT, data_size); + + controller_count = (unsigned int)controllers.size(); send_in_progress.lock(); send(client_sock, (const char *)&reply_hdr, sizeof(NetPacketHeader), 0); - send(client_sock, (const char *)&reply_data, sizeof(unsigned int), 0); + send(client_sock, (const char *)data_buf, data_size, 0); send_in_progress.unlock(); + + delete[] data_buf; } void NetworkServer::SendReply_ControllerData(SOCKET client_sock, unsigned int dev_idx, unsigned int protocol_version) diff --git a/NetworkServer.h b/NetworkServer.h index 3086b3fa8..93d89f758 100644 --- a/NetworkServer.h +++ b/NetworkServer.h @@ -62,6 +62,12 @@ public: std::string client_ip; }; +typedef struct +{ + RGBController * controller; + unsigned int id; +} NetworkControllerID; + class NetworkServer { public: @@ -80,6 +86,11 @@ public: const char * GetClientIP(unsigned int client_num); unsigned int GetClientProtocolVersion(unsigned int client_num); + /*-----------------------------------------------------*\ + | Signal that device list has been updated | + \*-----------------------------------------------------*/ + void DeviceListUpdated(); + /*-----------------------------------------------------*\ | Callback functions | \*-----------------------------------------------------*/ @@ -131,6 +142,9 @@ private: /*-----------------------------------------------------*\ | Server controller list | \*-----------------------------------------------------*/ + std::vector controller_ids; + std::shared_mutex controller_ids_mutex; + unsigned int controller_next_idx; std::vector& controllers; std::vector controller_threads; @@ -201,7 +215,7 @@ private: void ProcessRequest_RGBController_UpdateZoneLEDs(std::size_t controller_idx, unsigned char* data_ptr); void ProcessRequest_RGBController_UpdateZoneMode(std::size_t controller_idx, unsigned char * data_ptr, unsigned int protocol_version); - void SendReply_ControllerCount(SOCKET client_sock); + void SendReply_ControllerCount(SOCKET client_sock, unsigned int protocol_version); void SendReply_ControllerData(SOCKET client_sock, unsigned int dev_idx, unsigned int protocol_version); void SendReply_ProtocolVersion(SOCKET client_sock); void SendReply_ServerString(SOCKET client_sock);