[WIP] SDK Version 6 Updates

* SDK Protocol
    * Server sends its name to client
    * ProfileManager
      * Rename existing profile commands
      * Add Upload Profile, Download Profile, and Get Active Profile commands
    * SettingsManager
      * Add Get, Set, and Save Settings commands
  * NetworkServer
    * Formatting cleanup
    * Use per-controller threads for handling NetworkServer controller-specific packets to avoid delays from controller mutexes
  * NetworkClient
    * Formatting cleanup
This commit is contained in:
Adam Honse
2025-07-16 00:01:03 -05:00
parent f565956495
commit 5e678b2f72
12 changed files with 1622 additions and 886 deletions

View File

@@ -44,8 +44,8 @@ NetworkClient::NetworkClient(std::vector<RGBController *>& control) : controller
server_reinitialize = false;
change_in_progress = false;
ListenThread = NULL;
ConnectionThread = NULL;
ListenThread = NULL;
ConnectionThread = NULL;
}
NetworkClient::~NetworkClient()
@@ -53,37 +53,22 @@ NetworkClient::~NetworkClient()
StopClient();
}
void NetworkClient::ClearCallbacks()
/*---------------------------------------------------------*\
| Client Information functions |
\*---------------------------------------------------------*/
bool NetworkClient::GetConnected()
{
ClientInfoChangeCallbacks.clear();
ClientInfoChangeCallbackArgs.clear();
}
void NetworkClient::ClientInfoChanged()
{
ClientInfoChangeMutex.lock();
ControllerListMutex.lock();
/*---------------------------------------------------------*\
| Client info has changed, call the callbacks |
\*---------------------------------------------------------*/
for(unsigned int callback_idx = 0; callback_idx < ClientInfoChangeCallbacks.size(); callback_idx++)
{
ClientInfoChangeCallbacks[callback_idx](ClientInfoChangeCallbackArgs[callback_idx]);
}
ControllerListMutex.unlock();
ClientInfoChangeMutex.unlock();
return(server_connected);
}
std::string NetworkClient::GetIP()
{
return port_ip;
return(port_ip);
}
unsigned short NetworkClient::GetPort()
{
return port_num;
return(port_num);
}
unsigned int NetworkClient::GetProtocolVersion()
@@ -102,22 +87,19 @@ unsigned int NetworkClient::GetProtocolVersion()
return(protocol_version);
}
bool NetworkClient::GetConnected()
{
return(server_connected);
}
bool NetworkClient::GetOnline()
{
return(server_connected && client_string_sent && protocol_initialized && server_initialized);
}
void NetworkClient::RegisterClientInfoChangeCallback(NetClientCallback new_callback, void * new_callback_arg)
std::string NetworkClient::GetServerName()
{
ClientInfoChangeCallbacks.push_back(new_callback);
ClientInfoChangeCallbackArgs.push_back(new_callback_arg);
return(server_name);
}
/*---------------------------------------------------------*\
| Client Control functions |
\*---------------------------------------------------------*/
void NetworkClient::SetIP(std::string new_ip)
{
if(server_connected == false)
@@ -214,6 +196,452 @@ void NetworkClient::StopClient()
ClientInfoChanged();
}
void NetworkClient::SendRequest_ControllerData(unsigned int dev_idx)
{
NetPacketHeader request_hdr;
unsigned int protocol_version;
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)
{
request_hdr.pkt_size = 0;
send_in_progress.lock();
send(client_sock, (char *)&request_hdr, sizeof(NetPacketHeader), MSG_NOSIGNAL);
send_in_progress.unlock();
}
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;
}
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();
}
}
void NetworkClient::SendRequest_RescanDevices()
{
if(GetProtocolVersion() >= 5)
{
NetPacketHeader request_hdr;
InitNetPacketHeader(&request_hdr, 0, NET_PACKET_ID_REQUEST_RESCAN_DEVICES, 0);
send_in_progress.lock();
send(client_sock, (char *)&request_hdr, sizeof(NetPacketHeader), MSG_NOSIGNAL);
send_in_progress.unlock();
}
}
/*---------------------------------------------------------*\
| Client Callback functions |
\*---------------------------------------------------------*/
void NetworkClient::ClearCallbacks()
{
ClientInfoChangeCallbacks.clear();
ClientInfoChangeCallbackArgs.clear();
}
void NetworkClient::RegisterClientInfoChangeCallback(NetClientCallback new_callback, void * new_callback_arg)
{
ClientInfoChangeCallbacks.push_back(new_callback);
ClientInfoChangeCallbackArgs.push_back(new_callback_arg);
}
/*---------------------------------------------------------*\
| ProfileManager functions |
\*---------------------------------------------------------*/
char * NetworkClient::ProfileManager_GetProfileList()
{
NetPacketHeader reply_hdr;
char * response_data = NULL;
InitNetPacketHeader(&reply_hdr, 0, NET_PACKET_ID_PROFILEMANAGER_GET_PROFILE_LIST, 0);
send_in_progress.lock();
send(client_sock, (char *)&reply_hdr, sizeof(NetPacketHeader), MSG_NOSIGNAL);
send_in_progress.unlock();
std::unique_lock<std::mutex> wait_lock(waiting_on_response_mutex);
waiting_on_response_cv.wait(wait_lock);
if(response_header.pkt_id == NET_PACKET_ID_PROFILEMANAGER_GET_PROFILE_LIST && response_data_ptr != NULL)
{
response_data = response_data_ptr;
response_data_ptr = NULL;
}
return(response_data);
}
void NetworkClient::ProfileManager_LoadProfile(std::string profile_name)
{
NetPacketHeader reply_hdr;
InitNetPacketHeader(&reply_hdr, 0, NET_PACKET_ID_PROFILEMANAGER_LOAD_PROFILE, (unsigned int)strlen(profile_name.c_str()) + 1);
send_in_progress.lock();
send(client_sock, (char *)&reply_hdr, sizeof(NetPacketHeader), MSG_NOSIGNAL);
send(client_sock, (char *)profile_name.c_str(), reply_hdr.pkt_size, MSG_NOSIGNAL);
send_in_progress.unlock();
}
void NetworkClient::ProfileManager_SaveProfile(std::string profile_name)
{
NetPacketHeader reply_hdr;
InitNetPacketHeader(&reply_hdr, 0, NET_PACKET_ID_PROFILEMANAGER_SAVE_PROFILE, (unsigned int)strlen(profile_name.c_str()) + 1);
send_in_progress.lock();
send(client_sock, (char *)&reply_hdr, sizeof(NetPacketHeader), MSG_NOSIGNAL);
send(client_sock, (char *)profile_name.c_str(), reply_hdr.pkt_size, MSG_NOSIGNAL);
send_in_progress.unlock();
}
void NetworkClient::ProfileManager_DeleteProfile(std::string profile_name)
{
NetPacketHeader reply_hdr;
InitNetPacketHeader(&reply_hdr, 0, NET_PACKET_ID_PROFILEMANAGER_DELETE_PROFILE, (unsigned int)strlen(profile_name.c_str()) + 1);
send_in_progress.lock();
send(client_sock, (char *)&reply_hdr, sizeof(NetPacketHeader), MSG_NOSIGNAL);
send(client_sock, (char *)profile_name.c_str(), reply_hdr.pkt_size, MSG_NOSIGNAL);
send_in_progress.unlock();
}
void NetworkClient::ProfileManager_UploadProfile(std::string profile_json_str)
{
NetPacketHeader request_hdr;
InitNetPacketHeader(&request_hdr, 0, NET_PACKET_ID_PROFILEMANAGER_UPLOAD_PROFILE, (unsigned int)strlen(profile_json_str.c_str()) + 1);
send_in_progress.lock();
send(client_sock, (char *)&request_hdr, sizeof(NetPacketHeader), MSG_NOSIGNAL);
send(client_sock, (char *)profile_json_str.c_str(), request_hdr.pkt_size, MSG_NOSIGNAL);
send_in_progress.unlock();
}
std::string NetworkClient::ProfileManager_DownloadProfile(std::string profile_name)
{
NetPacketHeader request_hdr;
std::string response_string;
InitNetPacketHeader(&request_hdr, 0, NET_PACKET_ID_PROFILEMANAGER_DOWNLOAD_PROFILE, (unsigned int)strlen(profile_name.c_str()) + 1);
send_in_progress.lock();
send(client_sock, (char *)&request_hdr, sizeof(NetPacketHeader), MSG_NOSIGNAL);
send(client_sock, (char *)profile_name.c_str(), request_hdr.pkt_size, MSG_NOSIGNAL);
send_in_progress.unlock();
std::unique_lock<std::mutex> wait_lock(waiting_on_response_mutex);
waiting_on_response_cv.wait(wait_lock);
if(response_header.pkt_id == NET_PACKET_ID_PROFILEMANAGER_DOWNLOAD_PROFILE && response_data_ptr != NULL)
{
response_string.assign(response_data_ptr, response_header.pkt_size);
delete[] response_data_ptr;
response_data_ptr = NULL;
}
return(response_string);
}
std::string NetworkClient::ProfileManager_GetActiveProfile()
{
NetPacketHeader request_hdr;
std::string response_string;
InitNetPacketHeader(&request_hdr, 0, NET_PACKET_ID_PROFILEMANAGER_GET_ACTIVE_PROFILE, 0);
send_in_progress.lock();
send(client_sock, (char *)&request_hdr, sizeof(NetPacketHeader), MSG_NOSIGNAL);
send_in_progress.unlock();
std::unique_lock<std::mutex> wait_lock(waiting_on_response_mutex);
waiting_on_response_cv.wait(wait_lock);
if(response_header.pkt_id == NET_PACKET_ID_PROFILEMANAGER_GET_ACTIVE_PROFILE && response_data_ptr != NULL)
{
response_string.assign(response_data_ptr, response_header.pkt_size);
delete[] response_data_ptr;
response_data_ptr = NULL;
}
return(response_string);
}
/*---------------------------------------------------------*\
| SettingsManager functions |
\*---------------------------------------------------------*/
std::string NetworkClient::SettingsManager_GetSettings(std::string settings_key)
{
NetPacketHeader request_hdr;
std::string response_string;
InitNetPacketHeader(&request_hdr, 0, NET_PACKET_ID_SETTINGSMANAGER_GET_SETTINGS, (unsigned int)strlen(settings_key.c_str()) + 1);
send_in_progress.lock();
send(client_sock, (char *)&request_hdr, sizeof(NetPacketHeader), MSG_NOSIGNAL);
send(client_sock, (char *)settings_key.c_str(), request_hdr.pkt_size, MSG_NOSIGNAL);
send_in_progress.unlock();
std::unique_lock<std::mutex> wait_lock(waiting_on_response_mutex);
waiting_on_response_cv.wait(wait_lock);
if(response_header.pkt_id == NET_PACKET_ID_SETTINGSMANAGER_GET_SETTINGS && response_data_ptr != NULL)
{
response_string.assign(response_data_ptr, response_header.pkt_size);
delete[] response_data_ptr;
response_data_ptr = NULL;
}
return(response_string);
}
void NetworkClient::SettingsManager_SaveSettings()
{
NetPacketHeader request_hdr;
InitNetPacketHeader(&request_hdr, 0, NET_PACKET_ID_SETTINGSMANAGER_SAVE_SETTINGS, 0);
send_in_progress.lock();
send(client_sock, (char *)&request_hdr, sizeof(NetPacketHeader), MSG_NOSIGNAL);
send_in_progress.unlock();
}
void NetworkClient::SettingsManager_SetSettings(std::string settings_json_str)
{
NetPacketHeader request_hdr;
InitNetPacketHeader(&request_hdr, 0, NET_PACKET_ID_SETTINGSMANAGER_SET_SETTINGS, (unsigned int)strlen(settings_json_str.c_str()) + 1);
send_in_progress.lock();
send(client_sock, (char *)&request_hdr, sizeof(NetPacketHeader), MSG_NOSIGNAL);
send(client_sock, (char *)settings_json_str.c_str(), request_hdr.pkt_size, MSG_NOSIGNAL);
send_in_progress.unlock();
}
/*---------------------------------------------------------*\
| RGBController functions |
\*---------------------------------------------------------*/
void NetworkClient::SendRequest_RGBController_ClearSegments(unsigned int dev_idx, int zone)
{
if(change_in_progress)
{
return;
}
NetPacketHeader request_hdr;
int request_data[1];
InitNetPacketHeader(&request_hdr, dev_idx, NET_PACKET_ID_RGBCONTROLLER_CLEARSEGMENTS, sizeof(request_data));
request_data[0] = zone;
send_in_progress.lock();
send(client_sock, (char *)&request_hdr, sizeof(NetPacketHeader), MSG_NOSIGNAL);
send(client_sock, (char *)&request_data, sizeof(request_data), MSG_NOSIGNAL);
send_in_progress.unlock();
}
void NetworkClient::SendRequest_RGBController_AddSegment(unsigned int dev_idx, unsigned char * data, unsigned int size)
{
if(change_in_progress)
{
return;
}
NetPacketHeader request_hdr;
InitNetPacketHeader(&request_hdr, dev_idx, NET_PACKET_ID_RGBCONTROLLER_ADDSEGMENT, size);
send_in_progress.lock();
send(client_sock, (char *)&request_hdr, sizeof(NetPacketHeader), MSG_NOSIGNAL);
send(client_sock, (char *)data, size, 0);
send_in_progress.unlock();
}
void NetworkClient::SendRequest_RGBController_ResizeZone(unsigned int dev_idx, int zone, int new_size)
{
if(change_in_progress)
{
return;
}
NetPacketHeader request_hdr;
int request_data[2];
InitNetPacketHeader(&request_hdr, dev_idx, NET_PACKET_ID_RGBCONTROLLER_RESIZEZONE, sizeof(request_data));
request_data[0] = zone;
request_data[1] = new_size;
send_in_progress.lock();
send(client_sock, (char *)&request_hdr, sizeof(NetPacketHeader), MSG_NOSIGNAL);
send(client_sock, (char *)&request_data, sizeof(request_data), MSG_NOSIGNAL);
send_in_progress.unlock();
}
void NetworkClient::SendRequest_RGBController_UpdateLEDs(unsigned int dev_idx, unsigned char * data, unsigned int size)
{
if(change_in_progress)
{
return;
}
NetPacketHeader request_hdr;
InitNetPacketHeader(&request_hdr, dev_idx, NET_PACKET_ID_RGBCONTROLLER_UPDATELEDS, size);
send_in_progress.lock();
send(client_sock, (char *)&request_hdr, sizeof(NetPacketHeader), MSG_NOSIGNAL);
send(client_sock, (char *)data, size, 0);
send_in_progress.unlock();
}
void NetworkClient::SendRequest_RGBController_UpdateZoneLEDs(unsigned int dev_idx, unsigned char * data, unsigned int size)
{
if(change_in_progress)
{
return;
}
NetPacketHeader request_hdr;
InitNetPacketHeader(&request_hdr, dev_idx, NET_PACKET_ID_RGBCONTROLLER_UPDATEZONELEDS, size);
send_in_progress.lock();
send(client_sock, (char *)&request_hdr, sizeof(NetPacketHeader), MSG_NOSIGNAL);
send(client_sock, (char *)data, size, MSG_NOSIGNAL);
send_in_progress.unlock();
}
void NetworkClient::SendRequest_RGBController_UpdateSingleLED(unsigned int dev_idx, unsigned char * data, unsigned int size)
{
if(change_in_progress)
{
return;
}
NetPacketHeader request_hdr;
InitNetPacketHeader(&request_hdr, dev_idx, NET_PACKET_ID_RGBCONTROLLER_UPDATESINGLELED, size);
send_in_progress.lock();
send(client_sock, (char *)&request_hdr, sizeof(NetPacketHeader), MSG_NOSIGNAL);
send(client_sock, (char *)data, size, MSG_NOSIGNAL);
send_in_progress.unlock();
}
void NetworkClient::SendRequest_RGBController_SetCustomMode(unsigned int dev_idx)
{
if(change_in_progress)
{
return;
}
NetPacketHeader request_hdr;
InitNetPacketHeader(&request_hdr, dev_idx, NET_PACKET_ID_RGBCONTROLLER_SETCUSTOMMODE, 0);
send_in_progress.lock();
send(client_sock, (char *)&request_hdr, sizeof(NetPacketHeader), MSG_NOSIGNAL);
send_in_progress.unlock();
}
void NetworkClient::SendRequest_RGBController_UpdateMode(unsigned int dev_idx, unsigned char * data, unsigned int size)
{
if(change_in_progress)
{
return;
}
NetPacketHeader request_hdr;
InitNetPacketHeader(&request_hdr, dev_idx, NET_PACKET_ID_RGBCONTROLLER_UPDATEMODE, size);
send_in_progress.lock();
send(client_sock, (char *)&request_hdr, sizeof(NetPacketHeader), MSG_NOSIGNAL);
send(client_sock, (char *)data, size, MSG_NOSIGNAL);
send_in_progress.unlock();
}
void NetworkClient::SendRequest_RGBController_SaveMode(unsigned int dev_idx, unsigned char * data, unsigned int size)
{
if(change_in_progress)
{
return;
}
NetPacketHeader request_hdr;
InitNetPacketHeader(&request_hdr, dev_idx, NET_PACKET_ID_RGBCONTROLLER_SAVEMODE, size);
send_in_progress.lock();
send(client_sock, (char *)&request_hdr, sizeof(NetPacketHeader), MSG_NOSIGNAL);
send(client_sock, (char *)data, size, MSG_NOSIGNAL);
send_in_progress.unlock();
}
void NetworkClient::WaitOnControllerData()
{
for(int i = 0; i < 1000; i++)
{
if(controller_data_received)
{
break;
}
std::this_thread::sleep_for(1ms);
}
return;
}
/*---------------------------------------------------------*\
| Client callback signal functions |
\*---------------------------------------------------------*/
void NetworkClient::ClientInfoChanged()
{
ClientInfoChangeMutex.lock();
ControllerListMutex.lock();
/*---------------------------------------------------------*\
| Client info has changed, call the callbacks |
\*---------------------------------------------------------*/
for(unsigned int callback_idx = 0; callback_idx < ClientInfoChangeCallbacks.size(); callback_idx++)
{
ClientInfoChangeCallbacks[callback_idx](ClientInfoChangeCallbackArgs[callback_idx]);
}
ControllerListMutex.unlock();
ClientInfoChangeMutex.unlock();
}
/*---------------------------------------------------------*\
| Client thread functions |
\*---------------------------------------------------------*/
void NetworkClient::ConnectionThreadFunction()
{
std::unique_lock<std::mutex> lock(connection_mutex);
@@ -413,37 +841,6 @@ void NetworkClient::ConnectionThreadFunction()
}
}
int NetworkClient::recv_select(SOCKET s, char *buf, int len, int flags)
{
fd_set set;
struct timeval timeout;
while(1)
{
timeout.tv_sec = 5;
timeout.tv_usec = 0;
FD_ZERO(&set);
FD_SET(s, &set);
int rv = select((int)s + 1, &set, NULL, NULL, &timeout);
if(rv == SOCKET_ERROR || server_connected == false)
{
return 0;
}
else if(rv == 0)
{
continue;
}
else
{
return(recv(s, buf, len, flags));
}
}
}
void NetworkClient::ListenThreadFunction()
{
printf("Network client listener started\n");
@@ -456,6 +853,7 @@ void NetworkClient::ListenThreadFunction()
NetPacketHeader header;
int bytes_read = 0;
char * data = NULL;
bool delete_data = true;
for(unsigned int i = 0; i < 4; i++)
{
@@ -540,12 +938,40 @@ void NetworkClient::ListenThreadFunction()
ProcessReply_ProtocolVersion(header.pkt_size, data);
break;
case NET_PACKET_ID_SET_SERVER_NAME:
if(data == NULL)
{
break;
}
ProcessRequest_ServerString(header.pkt_size, data);
break;
case NET_PACKET_ID_DEVICE_LIST_UPDATED:
ProcessRequest_DeviceListChanged();
break;
case NET_PACKET_ID_PROFILEMANAGER_GET_PROFILE_LIST:
case NET_PACKET_ID_PROFILEMANAGER_DOWNLOAD_PROFILE:
case NET_PACKET_ID_PROFILEMANAGER_GET_ACTIVE_PROFILE:
case NET_PACKET_ID_SETTINGSMANAGER_GET_SETTINGS:
{
std::unique_lock<std::mutex> lock(waiting_on_response_mutex);
response_header = header;
response_data_ptr = data;
delete_data = false;
lock.unlock();
waiting_on_response_cv.notify_all();
}
break;
}
delete[] data;
if(delete_data)
{
delete[] data;
}
}
listen_done:
@@ -592,20 +1018,9 @@ listen_done:
ClientInfoChanged();
}
void NetworkClient::WaitOnControllerData()
{
for(int i = 0; i < 1000; i++)
{
if(controller_data_received)
{
break;
}
std::this_thread::sleep_for(1ms);
}
return;
}
/*---------------------------------------------------------*\
| Private Client functions |
\*---------------------------------------------------------*/
void NetworkClient::ProcessReply_ControllerCount(unsigned int data_size, char * data)
{
if(data_size == sizeof(unsigned int))
@@ -730,6 +1145,16 @@ void NetworkClient::ProcessRequest_DeviceListChanged()
change_in_progress = false;
}
void NetworkClient::ProcessRequest_ServerString(unsigned int data_size, char * data)
{
server_name.assign(data, data_size);
/*---------------------------------------------------------*\
| Client info has changed, call the callbacks |
\*---------------------------------------------------------*/
ClientInfoChanged();
}
void NetworkClient::SendData_ClientString()
{
NetPacketHeader reply_hdr;
@@ -753,50 +1178,6 @@ void NetworkClient::SendRequest_ControllerCount()
send_in_progress.unlock();
}
void NetworkClient::SendRequest_ControllerData(unsigned int dev_idx)
{
NetPacketHeader request_hdr;
unsigned int protocol_version;
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)
{
request_hdr.pkt_size = 0;
send_in_progress.lock();
send(client_sock, (char *)&request_hdr, sizeof(NetPacketHeader), MSG_NOSIGNAL);
send_in_progress.unlock();
}
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;
}
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();
}
}
void NetworkClient::SendRequest_ProtocolVersion()
{
NetPacketHeader request_hdr;
@@ -812,226 +1193,9 @@ void NetworkClient::SendRequest_ProtocolVersion()
send_in_progress.unlock();
}
void NetworkClient::SendRequest_RescanDevices()
{
if(GetProtocolVersion() >= 5)
{
NetPacketHeader request_hdr;
InitNetPacketHeader(&request_hdr, 0, NET_PACKET_ID_REQUEST_RESCAN_DEVICES, 0);
send_in_progress.lock();
send(client_sock, (char *)&request_hdr, sizeof(NetPacketHeader), MSG_NOSIGNAL);
send_in_progress.unlock();
}
}
void NetworkClient::SendRequest_RGBController_ClearSegments(unsigned int dev_idx, int zone)
{
if(change_in_progress)
{
return;
}
NetPacketHeader request_hdr;
int request_data[1];
InitNetPacketHeader(&request_hdr, dev_idx, NET_PACKET_ID_RGBCONTROLLER_CLEARSEGMENTS, sizeof(request_data));
request_data[0] = zone;
send_in_progress.lock();
send(client_sock, (char *)&request_hdr, sizeof(NetPacketHeader), MSG_NOSIGNAL);
send(client_sock, (char *)&request_data, sizeof(request_data), MSG_NOSIGNAL);
send_in_progress.unlock();
}
void NetworkClient::SendRequest_RGBController_AddSegment(unsigned int dev_idx, unsigned char * data, unsigned int size)
{
if(change_in_progress)
{
return;
}
NetPacketHeader request_hdr;
InitNetPacketHeader(&request_hdr, dev_idx, NET_PACKET_ID_RGBCONTROLLER_ADDSEGMENT, size);
send_in_progress.lock();
send(client_sock, (char *)&request_hdr, sizeof(NetPacketHeader), MSG_NOSIGNAL);
send(client_sock, (char *)data, size, 0);
send_in_progress.unlock();
}
void NetworkClient::SendRequest_RGBController_ResizeZone(unsigned int dev_idx, int zone, int new_size)
{
if(change_in_progress)
{
return;
}
NetPacketHeader request_hdr;
int request_data[2];
InitNetPacketHeader(&request_hdr, dev_idx, NET_PACKET_ID_RGBCONTROLLER_RESIZEZONE, sizeof(request_data));
request_data[0] = zone;
request_data[1] = new_size;
send_in_progress.lock();
send(client_sock, (char *)&request_hdr, sizeof(NetPacketHeader), MSG_NOSIGNAL);
send(client_sock, (char *)&request_data, sizeof(request_data), MSG_NOSIGNAL);
send_in_progress.unlock();
}
void NetworkClient::SendRequest_RGBController_UpdateLEDs(unsigned int dev_idx, unsigned char * data, unsigned int size)
{
if(change_in_progress)
{
return;
}
NetPacketHeader request_hdr;
InitNetPacketHeader(&request_hdr, dev_idx, NET_PACKET_ID_RGBCONTROLLER_UPDATELEDS, size);
send_in_progress.lock();
send(client_sock, (char *)&request_hdr, sizeof(NetPacketHeader), MSG_NOSIGNAL);
send(client_sock, (char *)data, size, 0);
send_in_progress.unlock();
}
void NetworkClient::SendRequest_RGBController_UpdateZoneLEDs(unsigned int dev_idx, unsigned char * data, unsigned int size)
{
if(change_in_progress)
{
return;
}
NetPacketHeader request_hdr;
InitNetPacketHeader(&request_hdr, dev_idx, NET_PACKET_ID_RGBCONTROLLER_UPDATEZONELEDS, size);
send_in_progress.lock();
send(client_sock, (char *)&request_hdr, sizeof(NetPacketHeader), MSG_NOSIGNAL);
send(client_sock, (char *)data, size, MSG_NOSIGNAL);
send_in_progress.unlock();
}
void NetworkClient::SendRequest_RGBController_UpdateSingleLED(unsigned int dev_idx, unsigned char * data, unsigned int size)
{
if(change_in_progress)
{
return;
}
NetPacketHeader request_hdr;
InitNetPacketHeader(&request_hdr, dev_idx, NET_PACKET_ID_RGBCONTROLLER_UPDATESINGLELED, size);
send_in_progress.lock();
send(client_sock, (char *)&request_hdr, sizeof(NetPacketHeader), MSG_NOSIGNAL);
send(client_sock, (char *)data, size, MSG_NOSIGNAL);
send_in_progress.unlock();
}
void NetworkClient::SendRequest_RGBController_SetCustomMode(unsigned int dev_idx)
{
if(change_in_progress)
{
return;
}
NetPacketHeader request_hdr;
InitNetPacketHeader(&request_hdr, dev_idx, NET_PACKET_ID_RGBCONTROLLER_SETCUSTOMMODE, 0);
send_in_progress.lock();
send(client_sock, (char *)&request_hdr, sizeof(NetPacketHeader), MSG_NOSIGNAL);
send_in_progress.unlock();
}
void NetworkClient::SendRequest_RGBController_UpdateMode(unsigned int dev_idx, unsigned char * data, unsigned int size)
{
if(change_in_progress)
{
return;
}
NetPacketHeader request_hdr;
InitNetPacketHeader(&request_hdr, dev_idx, NET_PACKET_ID_RGBCONTROLLER_UPDATEMODE, size);
send_in_progress.lock();
send(client_sock, (char *)&request_hdr, sizeof(NetPacketHeader), MSG_NOSIGNAL);
send(client_sock, (char *)data, size, MSG_NOSIGNAL);
send_in_progress.unlock();
}
void NetworkClient::SendRequest_RGBController_SaveMode(unsigned int dev_idx, unsigned char * data, unsigned int size)
{
if(change_in_progress)
{
return;
}
NetPacketHeader request_hdr;
InitNetPacketHeader(&request_hdr, dev_idx, NET_PACKET_ID_RGBCONTROLLER_SAVEMODE, size);
send_in_progress.lock();
send(client_sock, (char *)&request_hdr, sizeof(NetPacketHeader), MSG_NOSIGNAL);
send(client_sock, (char *)data, size, MSG_NOSIGNAL);
send_in_progress.unlock();
}
void NetworkClient::SendRequest_LoadProfile(std::string profile_name)
{
NetPacketHeader reply_hdr;
InitNetPacketHeader(&reply_hdr, 0, NET_PACKET_ID_REQUEST_LOAD_PROFILE, (unsigned int)strlen(profile_name.c_str()) + 1);
send_in_progress.lock();
send(client_sock, (char *)&reply_hdr, sizeof(NetPacketHeader), MSG_NOSIGNAL);
send(client_sock, (char *)profile_name.c_str(), reply_hdr.pkt_size, MSG_NOSIGNAL);
send_in_progress.unlock();
}
void NetworkClient::SendRequest_SaveProfile(std::string profile_name)
{
NetPacketHeader reply_hdr;
InitNetPacketHeader(&reply_hdr, 0, NET_PACKET_ID_REQUEST_SAVE_PROFILE, (unsigned int)strlen(profile_name.c_str()) + 1);
send_in_progress.lock();
send(client_sock, (char *)&reply_hdr, sizeof(NetPacketHeader), MSG_NOSIGNAL);
send(client_sock, (char *)profile_name.c_str(), reply_hdr.pkt_size, MSG_NOSIGNAL);
send_in_progress.unlock();
}
void NetworkClient::SendRequest_DeleteProfile(std::string profile_name)
{
NetPacketHeader reply_hdr;
InitNetPacketHeader(&reply_hdr, 0, NET_PACKET_ID_REQUEST_DELETE_PROFILE, (unsigned int)strlen(profile_name.c_str()) + 1);
send_in_progress.lock();
send(client_sock, (char *)&reply_hdr, sizeof(NetPacketHeader), MSG_NOSIGNAL);
send(client_sock, (char *)profile_name.c_str(), reply_hdr.pkt_size, MSG_NOSIGNAL);
send_in_progress.unlock();
}
void NetworkClient::SendRequest_GetProfileList()
{
NetPacketHeader reply_hdr;
InitNetPacketHeader(&reply_hdr, 0, NET_PACKET_ID_REQUEST_PROFILE_LIST, 0);
send_in_progress.lock();
send(client_sock, (char *)&reply_hdr, sizeof(NetPacketHeader), MSG_NOSIGNAL);
send_in_progress.unlock();
}
/*---------------------------------------------------------*\
| Private ProfileManager functions |
\*---------------------------------------------------------*/
std::vector<std::string> * NetworkClient::ProcessReply_ProfileList(unsigned int data_size, char * data)
{
std::vector<std::string> * profile_list;
@@ -1071,3 +1235,37 @@ std::vector<std::string> * NetworkClient::ProcessReply_ProfileList(unsigned int
return profile_list;
}
/*---------------------------------------------------------*\
| Private helper functions |
\*---------------------------------------------------------*/
int NetworkClient::recv_select(SOCKET s, char *buf, int len, int flags)
{
fd_set set;
struct timeval timeout;
while(1)
{
timeout.tv_sec = 5;
timeout.tv_usec = 0;
FD_ZERO(&set);
FD_SET(s, &set);
int rv = select((int)s + 1, &set, NULL, NULL, &timeout);
if(rv == SOCKET_ERROR || server_connected == false)
{
return 0;
}
else if(rv == 0)
{
continue;
}
else
{
return(recv(s, buf, len, flags));
}
}
}

View File

@@ -11,6 +11,7 @@
#pragma once
#include <condition_variable>
#include <mutex>
#include <thread>
#include <condition_variable>
@@ -26,104 +27,165 @@ public:
NetworkClient(std::vector<RGBController *>& control);
~NetworkClient();
void ClientInfoChanged();
/*-----------------------------------------------------*\
| Client Information functions |
\*-----------------------------------------------------*/
bool GetConnected();
std::string GetIP();
unsigned short GetPort();
unsigned int GetProtocolVersion();
bool GetOnline();
std::string GetServerName();
bool GetConnected();
std::string GetIP();
unsigned short GetPort();
unsigned int GetProtocolVersion();
bool GetOnline();
/*-----------------------------------------------------*\
| Client Control functions |
\*-----------------------------------------------------*/
void SetIP(std::string new_ip);
void SetName(std::string new_name);
void SetPort(unsigned short new_port);
void ClearCallbacks();
void RegisterClientInfoChangeCallback(NetClientCallback new_callback, void * new_callback_arg);
void StartClient();
void StopClient();
void SetIP(std::string new_ip);
void SetName(std::string new_name);
void SetPort(unsigned short new_port);
void SendRequest_ControllerData(unsigned int dev_idx);
void SendRequest_RescanDevices();
void StartClient();
void StopClient();
/*-----------------------------------------------------*\
| Client Callback functions |
\*-----------------------------------------------------*/
void ClearCallbacks();
void RegisterClientInfoChangeCallback(NetClientCallback new_callback, void * new_callback_arg);
void ConnectionThreadFunction();
void ListenThreadFunction();
/*-----------------------------------------------------*\
| ProfileManager functions |
\*-----------------------------------------------------*/
char * ProfileManager_GetProfileList();
void ProfileManager_LoadProfile(std::string profile_name);
void ProfileManager_SaveProfile(std::string profile_name);
void ProfileManager_DeleteProfile(std::string profile_name);
void ProfileManager_UploadProfile(std::string profile_json_str);
std::string ProfileManager_DownloadProfile(std::string profile_name);
std::string ProfileManager_GetActiveProfile();
void WaitOnControllerData();
/*-----------------------------------------------------*\
| SettingsManager functions |
\*-----------------------------------------------------*/
std::string SettingsManager_GetSettings(std::string settings_key);
void SettingsManager_SaveSettings();
void SettingsManager_SetSettings(std::string settings_json_str);
void ProcessReply_ControllerCount(unsigned int data_size, char * data);
void ProcessReply_ControllerData(unsigned int data_size, char * data, unsigned int dev_idx);
void ProcessReply_ProtocolVersion(unsigned int data_size, char * data);
/*-----------------------------------------------------*\
| RGBController functions |
\*-----------------------------------------------------*/
void SendRequest_RGBController_ClearSegments(unsigned int dev_idx, int zone);
void SendRequest_RGBController_AddSegment(unsigned int dev_idx, unsigned char * data, unsigned int size);
void SendRequest_RGBController_ResizeZone(unsigned int dev_idx, int zone, int new_size);
void ProcessRequest_DeviceListChanged();
void SendRequest_RGBController_UpdateLEDs(unsigned int dev_idx, unsigned char * data, unsigned int size);
void SendRequest_RGBController_UpdateZoneLEDs(unsigned int dev_idx, unsigned char * data, unsigned int size);
void SendRequest_RGBController_UpdateSingleLED(unsigned int dev_idx, unsigned char * data, unsigned int size);
void SendData_ClientString();
void SendRequest_RGBController_SetCustomMode(unsigned int dev_idx);
void SendRequest_ControllerCount();
void SendRequest_ControllerData(unsigned int dev_idx);
void SendRequest_ProtocolVersion();
void SendRequest_RGBController_UpdateMode(unsigned int dev_idx, unsigned char * data, unsigned int size);
void SendRequest_RGBController_SaveMode(unsigned int dev_idx, unsigned char * data, unsigned int size);
void SendRequest_RescanDevices();
void SendRequest_RGBController_ClearSegments(unsigned int dev_idx, int zone);
void SendRequest_RGBController_AddSegment(unsigned int dev_idx, unsigned char * data, unsigned int size);
void SendRequest_RGBController_ResizeZone(unsigned int dev_idx, int zone, int new_size);
void SendRequest_RGBController_UpdateLEDs(unsigned int dev_idx, unsigned char * data, unsigned int size);
void SendRequest_RGBController_UpdateZoneLEDs(unsigned int dev_idx, unsigned char * data, unsigned int size);
void SendRequest_RGBController_UpdateSingleLED(unsigned int dev_idx, unsigned char * data, unsigned int size);
void SendRequest_RGBController_SetCustomMode(unsigned int dev_idx);
void SendRequest_RGBController_UpdateMode(unsigned int dev_idx, unsigned char * data, unsigned int size);
void SendRequest_RGBController_SaveMode(unsigned int dev_idx, unsigned char * data, unsigned int size);
std::vector<std::string> * ProcessReply_ProfileList(unsigned int data_size, char * data);
void SendRequest_GetProfileList();
void SendRequest_LoadProfile(std::string profile_name);
void SendRequest_SaveProfile(std::string profile_name);
void SendRequest_DeleteProfile(std::string profile_name);
std::vector<RGBController *> server_controllers;
std::mutex ControllerListMutex;
protected:
std::vector<RGBController *>& controllers;
void WaitOnControllerData();
std::vector<RGBController *> server_controllers;
private:
SOCKET client_sock;
std::string client_name;
net_port port;
std::string port_ip;
unsigned short port_num;
std::atomic<bool> client_active;
bool client_string_sent;
bool controller_data_received;
bool controller_data_requested;
bool protocol_initialized;
bool server_connected;
bool server_initialized;
bool server_reinitialize;
unsigned int server_controller_count;
bool server_controller_count_requested;
bool server_controller_count_received;
unsigned int server_protocol_version;
bool server_protocol_version_received;
bool change_in_progress;
unsigned int requested_controllers;
std::mutex send_in_progress;
/*-----------------------------------------------------*\
| Client state variables |
\*-----------------------------------------------------*/
std::atomic<bool> client_active;
bool client_string_sent;
bool controller_data_received;
bool controller_data_requested;
bool protocol_initialized;
bool change_in_progress;
unsigned int requested_controllers;
std::mutex send_in_progress;
std::mutex connection_mutex;
std::condition_variable connection_cv;
NetPacketHeader response_header;
char * response_data_ptr;
std::mutex waiting_on_response_mutex;
std::condition_variable waiting_on_response_cv;
std::thread * ConnectionThread;
std::thread * ListenThread;
/*-----------------------------------------------------*\
| Client information |
\*-----------------------------------------------------*/
std::string client_name;
SOCKET client_sock;
net_port port;
std::string port_ip;
unsigned short port_num;
/*-----------------------------------------------------*\
| Server information |
\*-----------------------------------------------------*/
std::string server_name;
bool server_connected;
bool server_initialized;
bool server_reinitialize;
unsigned int server_controller_count;
bool server_controller_count_requested;
bool server_controller_count_received;
unsigned int server_protocol_version;
bool server_protocol_version_received;
/*-----------------------------------------------------*\
| Client threads |
\*-----------------------------------------------------*/
std::mutex connection_mutex;
std::condition_variable connection_cv;
std::thread * ConnectionThread;
std::thread * ListenThread;
/*-----------------------------------------------------*\
| Callbacks |
\*-----------------------------------------------------*/
std::mutex ClientInfoChangeMutex;
std::vector<NetClientCallback> ClientInfoChangeCallbacks;
std::vector<void *> ClientInfoChangeCallbackArgs;
int recv_select(SOCKET s, char *buf, int len, int flags);
/*-----------------------------------------------------*\
| Controller list |
\*-----------------------------------------------------*/
std::mutex ControllerListMutex;
std::vector<RGBController *>& controllers;
/*-----------------------------------------------------*\
| Client callback signal functions |
\*-----------------------------------------------------*/
void ClientInfoChanged();
/*-----------------------------------------------------*\
| Client thread functions |
\*-----------------------------------------------------*/
void ConnectionThreadFunction();
void ListenThreadFunction();
/*-----------------------------------------------------*\
| 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_ProtocolVersion(unsigned int data_size, char * data);
void ProcessRequest_DeviceListChanged();
void ProcessRequest_ServerString(unsigned int data_size, char * data);
void SendData_ClientString();
void SendRequest_ControllerCount();
void SendRequest_ProtocolVersion();
/*-----------------------------------------------------*\
| Private ProfileManager functions |
\*-----------------------------------------------------*/
std::vector<std::string> * ProcessReply_ProfileList(unsigned int data_size, char * data);
/*-----------------------------------------------------*\
| Private helper functions |
\*-----------------------------------------------------*/
int recv_select(SOCKET s, char *buf, int len, int flags);
};

View File

@@ -61,33 +61,50 @@ enum
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 */
NET_PACKET_ID_SET_SERVER_NAME = 51, /* Send server name string to client */
NET_PACKET_ID_DEVICE_LIST_UPDATED = 100, /* Indicate to clients that device list has updated */
NET_PACKET_ID_REQUEST_RESCAN_DEVICES = 140, /* Request rescan of devices */
NET_PACKET_ID_REQUEST_PROFILE_LIST = 150, /* Request profile list */
NET_PACKET_ID_REQUEST_SAVE_PROFILE = 151, /* Save current configuration in a new profile */
NET_PACKET_ID_REQUEST_LOAD_PROFILE = 152, /* Load a given profile */
NET_PACKET_ID_REQUEST_DELETE_PROFILE = 153, /* Delete a given profile */
NET_PACKET_ID_REQUEST_PLUGIN_LIST = 200, /* Request list of plugins */
NET_PACKET_ID_PLUGIN_SPECIFIC = 201, /* Interact with a plugin */
/*----------------------------------------------------------------------------------------------------------*\
| ProfileManager functions |
\*----------------------------------------------------------------------------------------------------------*/
NET_PACKET_ID_PROFILEMANAGER_GET_PROFILE_LIST = 150, /* Get profile list */
NET_PACKET_ID_PROFILEMANAGER_SAVE_PROFILE = 151, /* Save current configuration in a new profile */
NET_PACKET_ID_PROFILEMANAGER_LOAD_PROFILE = 152, /* Load a given profile */
NET_PACKET_ID_PROFILEMANAGER_DELETE_PROFILE = 153, /* Delete a given profile */
NET_PACKET_ID_PROFILEMANAGER_UPLOAD_PROFILE = 154, /* Upload a profile to the server in JSON format */
NET_PACKET_ID_PROFILEMANAGER_DOWNLOAD_PROFILE = 155, /* Download a profile from the server in JSON format*/
NET_PACKET_ID_PROFILEMANAGER_GET_ACTIVE_PROFILE = 156, /* Get the active profile name */
/*----------------------------------------------------------------------------------------------------------*\
| RGBController class functions |
| PluginManager functions |
\*----------------------------------------------------------------------------------------------------------*/
NET_PACKET_ID_RGBCONTROLLER_RESIZEZONE = 1000, /* RGBController::ResizeZone() */
NET_PACKET_ID_RGBCONTROLLER_CLEARSEGMENTS = 1001, /* RGBController::ClearSegments() */
NET_PACKET_ID_RGBCONTROLLER_ADDSEGMENT = 1002, /* RGBController::AddSegment() */
NET_PACKET_ID_PLUGINMANAGER_GET_PLUGIN_LIST = 200, /* Get list of plugins */
NET_PACKET_ID_PLUGINMANAGER_PLUGIN_SPECIFIC = 201, /* Interact with a plugin */
NET_PACKET_ID_RGBCONTROLLER_UPDATELEDS = 1050, /* RGBController::UpdateLEDs() */
NET_PACKET_ID_RGBCONTROLLER_UPDATEZONELEDS = 1051, /* RGBController::UpdateZoneLEDs() */
NET_PACKET_ID_RGBCONTROLLER_UPDATESINGLELED = 1052, /* RGBController::UpdateSingleLED() */
/*----------------------------------------------------------------------------------------------------------*\
| SettingsManager functions |
\*----------------------------------------------------------------------------------------------------------*/
NET_PACKET_ID_SETTINGSMANAGER_GET_SETTINGS = 250, /* Get settings for a given key in JSON format */
NET_PACKET_ID_SETTINGSMANAGER_SET_SETTINGS = 251, /* Set settings for a given key in JSON format */
NET_PACKET_ID_SETTINGSMANAGER_SAVE_SETTINGS = 252, /* Save settings */
NET_PACKET_ID_RGBCONTROLLER_SETCUSTOMMODE = 1100, /* RGBController::SetCustomMode() */
NET_PACKET_ID_RGBCONTROLLER_UPDATEMODE = 1101, /* RGBController::UpdateMode() */
NET_PACKET_ID_RGBCONTROLLER_SAVEMODE = 1102, /* RGBController::SaveMode() */
/*----------------------------------------------------------------------------------------------------------*\
| RGBController functions |
\*----------------------------------------------------------------------------------------------------------*/
NET_PACKET_ID_RGBCONTROLLER_RESIZEZONE = 1000, /* RGBController::ResizeZone() */
NET_PACKET_ID_RGBCONTROLLER_CLEARSEGMENTS = 1001, /* RGBController::ClearSegments() */
NET_PACKET_ID_RGBCONTROLLER_ADDSEGMENT = 1002, /* RGBController::AddSegment() */
NET_PACKET_ID_RGBCONTROLLER_UPDATELEDS = 1050, /* RGBController::UpdateLEDs() */
NET_PACKET_ID_RGBCONTROLLER_UPDATEZONELEDS = 1051, /* RGBController::UpdateZoneLEDs() */
NET_PACKET_ID_RGBCONTROLLER_UPDATESINGLELED = 1052, /* RGBController::UpdateSingleLED() */
NET_PACKET_ID_RGBCONTROLLER_SETCUSTOMMODE = 1100, /* RGBController::SetCustomMode() */
NET_PACKET_ID_RGBCONTROLLER_UPDATEMODE = 1101, /* RGBController::UpdateMode() */
NET_PACKET_ID_RGBCONTROLLER_SAVEMODE = 1102, /* RGBController::SaveMode() */
};
void InitNetPacketHeader

View File

File diff suppressed because it is too large Load Diff

View File

@@ -11,21 +11,44 @@
#pragma once
#include <atomic>
#include <chrono>
#include <condition_variable>
#include <mutex>
#include <thread>
#include <chrono>
#include <queue>
#include "RGBController.h"
#include "NetworkProtocol.h"
#include "net_port.h"
#include "PluginManagerInterface.h"
#include "ProfileManager.h"
#include "ResourceManager.h"
#include "SettingsManager.h"
#define MAXSOCK 32
#define TCP_TIMEOUT_SECONDS 5
typedef void (*NetServerCallback)(void *);
typedef struct
{
char * data;
unsigned int id;
unsigned int size;
unsigned int client_protocol_version;
} NetworkServerControllerThreadQueueEntry;
typedef struct
{
unsigned int index;
std::queue<NetworkServerControllerThreadQueueEntry> queue;
std::mutex queue_mutex;
std::mutex start_mutex;
std::condition_variable start_cv;
std::thread * thread;
std::atomic<bool> online;
} NetworkServerControllerThread;
class NetworkClientInfo
{
public:
@@ -45,6 +68,9 @@ public:
NetworkServer(std::vector<RGBController *>& control);
~NetworkServer();
/*-----------------------------------------------------*\
| Server Information functions |
\*-----------------------------------------------------*/
std::string GetHost();
unsigned short GetPort();
bool GetOnline();
@@ -54,23 +80,106 @@ public:
const char * GetClientIP(unsigned int client_num);
unsigned int GetClientProtocolVersion(unsigned int client_num);
void ClientInfoChanged();
/*-----------------------------------------------------*\
| Callback functions |
\*-----------------------------------------------------*/
void DeviceListChanged();
void RegisterClientInfoChangeCallback(NetServerCallback, void * new_callback_arg);
void ServerListeningChanged();
void RegisterServerListeningChangeCallback(NetServerCallback, void * new_callback_arg);
/*-----------------------------------------------------*\
| Server Configuration functions |
\*-----------------------------------------------------*/
void SetHost(std::string host);
void SetLegacyWorkaroundEnable(bool enable);
void SetName(std::string new_name);
void SetPort(unsigned short new_port);
/*-----------------------------------------------------*\
| Server Control functions |
\*-----------------------------------------------------*/
void StartServer();
void StopServer();
/*-----------------------------------------------------*\
| Server Interface functions |
\*-----------------------------------------------------*/
void SetPluginManager(PluginManagerInterface* plugin_manager_pointer);
void SetProfileManager(ProfileManagerInterface* profile_manager_pointer);
void SetSettingsManager(SettingsManagerInterface* settings_manager_pointer);
private:
/*-----------------------------------------------------*\
| Server variables |
\*-----------------------------------------------------*/
std::string host;
bool legacy_workaround_enabled;
unsigned short port_num;
std::mutex send_in_progress;
std::string server_name;
std::atomic<bool> server_online;
std::atomic<bool> server_listening;
SOCKET server_sock[MAXSOCK];
int socket_count;
/*-----------------------------------------------------*\
| Server controller list |
\*-----------------------------------------------------*/
std::vector<RGBController *>& controllers;
std::vector<NetworkServerControllerThread *> controller_threads;
/*-----------------------------------------------------*\
| Server clients |
\*-----------------------------------------------------*/
std::mutex ServerClientsMutex;
std::vector<NetworkClientInfo *> ServerClients;
std::thread * ConnectionThread[MAXSOCK];
/*-----------------------------------------------------*\
| Client information change callbacks |
\*-----------------------------------------------------*/
std::mutex ClientInfoChangeMutex;
std::vector<NetServerCallback> ClientInfoChangeCallbacks;
std::vector<void *> ClientInfoChangeCallbackArgs;
/*-----------------------------------------------------*\
| Server listening change callbacks |
\*-----------------------------------------------------*/
std::mutex ServerListeningChangeMutex;
std::vector<NetServerCallback> ServerListeningChangeCallbacks;
std::vector<void *> ServerListeningChangeCallbackArgs;
/*-----------------------------------------------------*\
| Pointers to components that integrate with server |
\*-----------------------------------------------------*/
PluginManagerInterface* plugin_manager;
ProfileManagerInterface* profile_manager;
SettingsManagerInterface* settings_manager;
private:
#ifdef WIN32
/*-----------------------------------------------------*\
| Windows-specific WSA data |
\*-----------------------------------------------------*/
WSADATA wsa;
#endif
/*-----------------------------------------------------*\
| Server callback signal functions |
\*-----------------------------------------------------*/
void ClientInfoChanged();
void ServerListeningChanged();
/*-----------------------------------------------------*\
| Server Thread functions |
\*-----------------------------------------------------*/
void ConnectionThreadFunction(int socket_idx);
void ControllerListenThread(NetworkServerControllerThread * this_thread);
void ListenThreadFunction(NetworkClientInfo * client_sock);
/*-----------------------------------------------------*\
| Server Protocol functions |
\*-----------------------------------------------------*/
void ProcessRequest_ClientProtocolVersion(SOCKET client_sock, unsigned int data_size, char * data);
void ProcessRequest_ClientString(SOCKET client_sock, unsigned int data_size, char * data);
void ProcessRequest_RescanDevices();
@@ -78,49 +187,16 @@ public:
void SendReply_ControllerCount(SOCKET client_sock);
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);
void SendRequest_DeviceListChanged(SOCKET client_sock);
void SendReply_ProfileList(SOCKET client_sock);
void SendReply_PluginList(SOCKET client_sock);
void SendReply_PluginSpecific(SOCKET client_sock, unsigned int pkt_type, unsigned char* data, unsigned int data_size);
void SetPluginManager(PluginManagerInterface* plugin_manager_pointer);
void SetProfileManager(ProfileManagerInterface* profile_manager_pointer);
protected:
std::string host;
unsigned short port_num;
std::atomic<bool> server_online;
std::atomic<bool> server_listening;
std::vector<RGBController *>& controllers;
std::mutex ServerClientsMutex;
std::vector<NetworkClientInfo *> ServerClients;
std::thread * ConnectionThread[MAXSOCK];
std::mutex ClientInfoChangeMutex;
std::vector<NetServerCallback> ClientInfoChangeCallbacks;
std::vector<void *> ClientInfoChangeCallbackArgs;
std::mutex ServerListeningChangeMutex;
std::vector<NetServerCallback> ServerListeningChangeCallbacks;
std::vector<void *> ServerListeningChangeCallbackArgs;
PluginManagerInterface* plugin_manager;
ProfileManagerInterface* profile_manager;
std::mutex send_in_progress;
private:
#ifdef WIN32
WSADATA wsa;
#endif
bool legacy_workaround_enabled;
int socket_count;
SOCKET server_sock[MAXSOCK];
int accept_select(int sockfd);
int recv_select(SOCKET s, char *buf, int len, int flags);
/*-----------------------------------------------------*\
| Private helper functions |
\*-----------------------------------------------------*/
int accept_select(int sockfd);
int recv_select(SOCKET s, char *buf, int len, int flags);
};

View File

@@ -97,12 +97,22 @@ ProfileManager::~ProfileManager()
void ProfileManager::DeleteProfile(std::string profile_name)
{
/*-----------------------------------------------------*\
| Clean up the profile name |
\*-----------------------------------------------------*/
profile_name = StringUtils::remove_null_terminating_chars(profile_name);
filesystem::path filename = profile_directory / profile_name;
filename.concat(".json");
if(ResourceManager::get()->IsLocalClient())
{
ResourceManager::get()->GetLocalClient()->ProfileManager_DeleteProfile(profile_name);
}
else
{
filesystem::path filename = profile_directory / profile_name;
filename.concat(".json");
filesystem::remove(filename);
filesystem::remove(filename);
}
UpdateProfileList();
}
@@ -230,22 +240,31 @@ bool ProfileManager::LoadProfile(std::string profile_name)
nlohmann::json ProfileManager::ReadProfileJSON(std::string profile_name)
{
nlohmann::json profile_json;
/*-----------------------------------------------------*\
| Clean up the profile name |
\*-----------------------------------------------------*/
profile_name = StringUtils::remove_null_terminating_chars(profile_name);
/*-----------------------------------------------------*\
| File extension for v6+ profiles is .json |
\*-----------------------------------------------------*/
profile_name += ".json";
if(ResourceManager::get()->IsLocalClient())
{
profile_json = nlohmann::json::parse(ResourceManager::get()->GetLocalClient()->ProfileManager_DownloadProfile(profile_name));
}
else
{
/*-------------------------------------------------*\
| File extension for v6+ profiles is .json |
\*-------------------------------------------------*/
profile_name += ".json";
/*-----------------------------------------------------*\
| Read the profile JSON from the file |
\*-----------------------------------------------------*/
filesystem::path profile_path = profile_directory / filesystem::u8path(profile_name);
/*-------------------------------------------------*\
| Read the profile JSON from the file |
\*-------------------------------------------------*/
filesystem::path profile_path = profile_directory / filesystem::u8path(profile_name);
nlohmann::json profile_json = ReadProfileFileJSON(profile_path);
profile_json = ReadProfileFileJSON(profile_path);
}
return(profile_json);
}
@@ -299,15 +318,25 @@ bool ProfileManager::SaveProfile(std::string profile_name)
profile_json["plugins"] = plugin_manager->OnProfileSave();
}
/*-------------------------------------------------*\
| Save the profile to file from the JSON |
\*-------------------------------------------------*/
SaveProfileFromJSON(profile_json);
if(ResourceManager::get()->IsLocalClient())
{
/*---------------------------------------------*\
| Upload the profile to the server |
\*---------------------------------------------*/
ResourceManager::get()->GetLocalClient()->ProfileManager_UploadProfile(profile_json.dump());
/*-------------------------------------------------*\
| Update the profile list |
\*-------------------------------------------------*/
UpdateProfileList();
/*---------------------------------------------*\
| Update the profile list |
\*---------------------------------------------*/
UpdateProfileList();
}
else
{
/*---------------------------------------------*\
| Save the profile to file from the JSON |
\*---------------------------------------------*/
SaveProfileFromJSON(profile_json);
}
return(true);
}
@@ -341,6 +370,11 @@ bool ProfileManager::SaveProfileFromJSON(nlohmann::json profile_json)
\*-------------------------------------------------*/
profile_file.close();
/*-------------------------------------------------*\
| Update the profile list |
\*-------------------------------------------------*/
UpdateProfileList();
return(true);
}
else
@@ -447,29 +481,42 @@ void ProfileManager::UpdateProfileList()
{
profile_list.clear();
/*-----------------------------------------------------*\
| Load profiles by looking for .json files in profile |
| directory |
\*-----------------------------------------------------*/
for(const filesystem::directory_entry &entry : filesystem::directory_iterator(profile_directory))
if(ResourceManager::get()->IsLocalClient())
{
std::string filename = entry.path().filename().string();
char * profile_data = ResourceManager::get()->GetLocalClient()->ProfileManager_GetProfileList();
if(filename.find(".json") != std::string::npos)
if(profile_data != NULL)
{
LOG_INFO("[ProfileManager] Found file: %s attempting to validate header", filename.c_str());
SetProfileListFromDescription(profile_data);
delete[] profile_data;
}
}
else
{
/*-------------------------------------------------*\
| Load profiles by looking for .json files in |
| profile directory |
\*-------------------------------------------------*/
for(const filesystem::directory_entry &entry : filesystem::directory_iterator(profile_directory))
{
std::string filename = entry.path().filename().string();
/*---------------------------------------------*\
| Open input file in binary mode |
\*---------------------------------------------*/
filesystem::path file_path = profile_directory;
file_path.append(filename);
nlohmann::json profile_json = ReadProfileFileJSON(file_path);
if(!profile_json.empty())
if(filename.find(".json") != std::string::npos)
{
profile_list.push_back(filename.erase(filename.length() - 5));
LOG_INFO("[ProfileManager] Found file: %s attempting to validate header", filename.c_str());
/*-----------------------------------------*\
| Open input file in binary mode |
\*-----------------------------------------*/
filesystem::path file_path = profile_directory;
file_path.append(filename);
nlohmann::json profile_json = ReadProfileFileJSON(file_path);
if(!profile_json.empty())
{
profile_list.push_back(filename.erase(filename.length() - 5));
}
}
}
}

View File

@@ -194,6 +194,15 @@ ResourceManager::ResourceManager()
server = new NetworkServer(rgb_controllers_hw);
}
/*-----------------------------------------------------*\
| Set server name |
\*-----------------------------------------------------*/
std::string titleString = "OpenRGB ";
titleString.append(VERSION_STRING);
server->SetName(titleString);
server->SetSettingsManager(settings_manager);
/*-----------------------------------------------------*\
| Enable legacy SDK workaround in server if configured |
\*-----------------------------------------------------*/
@@ -1797,6 +1806,7 @@ void ResourceManager::InitCoroutine()
| detection if the local server was connected |
\*---------------------------------------------*/
auto_connection_active = true;
profile_manager->UpdateProfileList();
DisableDetection();
}
@@ -2123,3 +2133,13 @@ bool ResourceManager::IsAnyDimmDetectorEnabled(json &detector_settings)
}
return false;
}
bool ResourceManager::IsLocalClient()
{
return(auto_connection_active);
}
NetworkClient* ResourceManager::GetLocalClient()
{
return(auto_connection_client);
}

View File

@@ -199,6 +199,9 @@ public:
void WaitForInitialization();
void WaitForDeviceDetection();
bool IsLocalClient();
NetworkClient* GetLocalClient();
private:
void UpdateDetectorSettings();
void SetupConfigurationDirectory();

View File

@@ -13,8 +13,22 @@
#include <fstream>
#include <iostream>
#include "SettingsManager.h"
#include "LogManager.h"
#include "NetworkClient.h"
#include "ResourceManager.h"
#include "SettingsManager.h"
#include "StringUtils.h"
static const std::string ui_settings_keys[7] =
{
"UserInterface",
"AutoStart",
"Theme",
"Plugins",
"Client",
"LogManager",
"Server"
};
SettingsManager::SettingsManager()
{
@@ -28,31 +42,113 @@ SettingsManager::~SettingsManager()
json SettingsManager::GetSettings(std::string settings_key)
{
/*-----------------------------------------------------*\
| Check to see if the key exists in the settings store |
| and return the settings associated with the key if it |
| exists. We lock the mutex to protect the value from |
| changing while data is being read and copy before |
| unlocking. |
\*-----------------------------------------------------*/
json result;
bool ui_settings_key = false;
mutex.lock();
if(settings_data.contains(settings_key))
/*-----------------------------------------------------*\
| Remove any excess null termination from settings key |
\*-----------------------------------------------------*/
settings_key = StringUtils::remove_null_terminating_chars(settings_key);
for(std::size_t settings_key_idx = 0; settings_key_idx < 7; settings_key_idx++)
{
result = settings_data[settings_key];
if(settings_key == ui_settings_keys[settings_key_idx])
{
ui_settings_key = true;
break;
}
}
mutex.unlock();
if(!ui_settings_key && ResourceManager::get()->IsLocalClient())
{
/*-------------------------------------------------*\
| If this is a local client, request the settings |
| from the server |
\*-------------------------------------------------*/
try
{
result = nlohmann::json::parse(ResourceManager::get()->GetLocalClient()->SettingsManager_GetSettings(settings_key));
}
catch(...)
{
}
}
else
{
/*-------------------------------------------------*\
| Check to see if the key exists in the settings |
| store and return the settings associated with the |
| key if it exists. We lock the mutex to protect |
| the value from changing while data is being read |
| and copy before unlocking. |
\*-------------------------------------------------*/
mutex.lock();
if(settings_data.contains(settings_key))
{
result = settings_data[settings_key];
}
mutex.unlock();
}
return result;
}
void SettingsManager::SetSettings(std::string settings_key, json new_settings)
{
mutex.lock();
settings_data[settings_key] = new_settings;
mutex.unlock();
bool ui_settings_key = false;
/*-----------------------------------------------------*\
| Remove any excess null termination from settings key |
\*-----------------------------------------------------*/
settings_key = StringUtils::remove_null_terminating_chars(settings_key);
for(std::size_t settings_key_idx = 0; settings_key_idx < 7; settings_key_idx++)
{
if(settings_key == ui_settings_keys[settings_key_idx])
{
ui_settings_key = true;
break;
}
}
if(!ui_settings_key && ResourceManager::get()->IsLocalClient())
{
/*-------------------------------------------------*\
| If this is a local client, request the settings |
| from the server |
\*-------------------------------------------------*/
nlohmann::json settings_json;
settings_json[settings_key] = new_settings;
ResourceManager::get()->GetLocalClient()->SettingsManager_SetSettings(settings_json.dump());
}
else
{
mutex.lock();
settings_data[settings_key] = new_settings;
mutex.unlock();
}
}
void SettingsManager::SetSettingsFromJsonString(std::string settings_json_str)
{
/*-----------------------------------------------------*\
| Parse the JSON string |
\*-----------------------------------------------------*/
nlohmann::json settings_json = nlohmann::json::parse(settings_json_str);
/*-----------------------------------------------------*\
| Get key/value pairs from JSON, call SetSettings for |
| each key. This use of `auto` is acceptable due to |
| how the JSON library implements iterators, the type |
| would change based on the library version. |
\*-----------------------------------------------------*/
for(auto& element : settings_json.items())
{
SetSettings(element.key(), element.value());
}
}
void SettingsManager::LoadSettings(const filesystem::path& filename)
@@ -109,6 +205,15 @@ void SettingsManager::LoadSettings(const filesystem::path& filename)
void SettingsManager::SaveSettings()
{
if(ResourceManager::get()->IsLocalClient())
{
/*-------------------------------------------------*\
| If this is a local client, save the settings on |
| the server |
\*-------------------------------------------------*/
ResourceManager::get()->GetLocalClient()->SettingsManager_SaveSettings();
}
mutex.lock();
std::ofstream settings_file(settings_filename, std::ios::out | std::ios::binary);

View File

@@ -24,6 +24,7 @@ class SettingsManagerInterface
public:
virtual json GetSettings(std::string settings_key) = 0;
virtual void SetSettings(std::string settings_key, json new_settings) = 0;
virtual void SetSettingsFromJsonString(std::string settings_json_str) = 0;
virtual void LoadSettings(const filesystem::path& filename) = 0;
virtual void SaveSettings() = 0;
@@ -40,6 +41,7 @@ public:
json GetSettings(std::string settings_key) override;
void SetSettings(std::string settings_key, json new_settings) override;
void SetSettingsFromJsonString(std::string settings_json_str) override;
void LoadSettings(const filesystem::path& filename) override;
void SaveSettings() override;

View File

@@ -131,11 +131,29 @@ void OpenRGBClientInfoPage::UpdateInfo()
}
/*-----------------------------------------------------*\
| Create the top level tree widget items and display the|
| client IP addresses and protocol versions in them |
| Create the top level tree widget items |
\*-----------------------------------------------------*/
QTreeWidgetItem* new_top_item = new QTreeWidgetItem(ui->ClientTree);
new_top_item->setText(0, QString::fromStdString(ResourceManager::get()->GetClients()[client_idx]->GetIP()));
/*-----------------------------------------------------*\
| First column, display the server IP and optionally |
| the server name if it exists |
\*-----------------------------------------------------*/
std::string server_name = ResourceManager::get()->GetClients()[client_idx]->GetServerName();
std::string ip = ResourceManager::get()->GetClients()[client_idx]->GetIP();
if(server_name == "")
{
new_top_item->setText(0, QString::fromStdString(ip));
}
else
{
new_top_item->setText(0, QString::fromStdString(ip + ": " + server_name));
}
/*-----------------------------------------------------*\
| Second column, display the protocol version |
\*-----------------------------------------------------*/
new_top_item->setText(1, QString::number(ResourceManager::get()->GetClients()[client_idx]->GetProtocolVersion()));
/*-----------------------------------------------------*\

View File

@@ -52,6 +52,12 @@ int startup(int argc, char* argv[], unsigned int ret_flags)
\*-----------------------------------------------------*/
int exitval = EXIT_SUCCESS;
/*-----------------------------------------------------*\
| Before opening GUI, wait for automatic connection so |
| that settings and profiles can be updated from server |
\*-----------------------------------------------------*/
ResourceManager::get()->WaitForInitialization();
/*-----------------------------------------------------*\
| If the command line parser indicates that the GUI |
| should run, or if there were no command line |