diff --git a/NetworkProtocol.h b/NetworkProtocol.h index 37c10d2d..d484ce00 100644 --- a/NetworkProtocol.h +++ b/NetworkProtocol.h @@ -8,15 +8,15 @@ #pragma once -/*-----------------------------------------------------*\ -| OpenRGB SDK protocol version | -| | -| 0: Initial (unversioned) protocol | -| 1: Add versioning, vendor string (Release 0.5) | -| 2: Add profile controls (Release 0.6) | -| 3: Add brightness field to modes (Release 0.7) | -| 4: Add segments field to zones (Release 0.9) | -\*-----------------------------------------------------*/ +/*---------------------------------------------------------------------*\ +| OpenRGB SDK protocol version | +| | +| 0: Initial (unversioned) protocol | +| 1: Add versioning, vendor string (Release 0.5) | +| 2: Add profile controls (Release 0.6) | +| 3: Add brightness field to modes (Release 0.7) | +| 4: Add segments field to zones, network plugins (Release 0.9) | +\*---------------------------------------------------------------------*/ #define OPENRGB_SDK_PROTOCOL_VERSION 4 /*-----------------------------------------------------*\ @@ -57,6 +57,9 @@ enum 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 */ + /*----------------------------------------------------------------------------------------------------------*\ | RGBController class functions | \*----------------------------------------------------------------------------------------------------------*/ diff --git a/NetworkServer.cpp b/NetworkServer.cpp index d6360e51..401de89b 100644 --- a/NetworkServer.cpp +++ b/NetworkServer.cpp @@ -815,6 +815,28 @@ void NetworkServer::ListenThreadFunction(NetworkClientInfo * client_info) } break; + + case NET_PACKET_ID_REQUEST_PLUGIN_LIST: + SendReply_PluginList(client_sock); + break; + + case NET_PACKET_ID_PLUGIN_SPECIFIC: + { + unsigned int plugin_pkt_type = *((unsigned int*)(data)); + unsigned int plugin_pkt_size = header.pkt_size - (sizeof(unsigned int)); + unsigned char* plugin_data = (unsigned char*)(data + sizeof(unsigned int)); + + if(header.pkt_dev_idx < plugins.size()) + { + NetworkPlugin plugin = plugins[header.pkt_dev_idx]; + unsigned char* output = plugin.callback(plugin.callback_arg, plugin_pkt_type, plugin_data, &plugin_pkt_size); + if(output != nullptr) + { + SendReply_PluginSpecific(client_sock, plugin_pkt_type, output, plugin_pkt_size); + } + } + break; + } } delete[] data; @@ -1002,8 +1024,154 @@ void NetworkServer::SendReply_ProfileList(SOCKET client_sock) send(client_sock, (const char *)reply_data, reply_size, 0); } +void NetworkServer::SendReply_PluginList(SOCKET client_sock) +{ + unsigned int data_size = 0; + unsigned int data_ptr = 0; + + /*---------------------------------------------------------*\ + | Calculate data size | + \*---------------------------------------------------------*/ + unsigned short num_plugins = plugins.size(); + + data_size += sizeof(data_size); + data_size += sizeof(num_plugins); + + for(unsigned int i = 0; i < num_plugins; i++) + { + data_size += sizeof(unsigned short) * 3; + data_size += strlen(plugins[i].name.c_str()) + 1; + data_size += strlen(plugins[i].description.c_str()) + 1; + data_size += strlen(plugins[i].version.c_str()) + 1; + data_size += sizeof(unsigned int) * 2; + } + + /*---------------------------------------------------------*\ + | Create data buffer | + \*---------------------------------------------------------*/ + unsigned char *data_buf = new unsigned char[data_size]; + + /*---------------------------------------------------------*\ + | Copy in data size | + \*---------------------------------------------------------*/ + memcpy(&data_buf[data_ptr], &data_size, sizeof(data_size)); + data_ptr += sizeof(data_size); + + /*---------------------------------------------------------*\ + | Copy in num_plugins | + \*---------------------------------------------------------*/ + memcpy(&data_buf[data_ptr], &num_plugins, sizeof(num_plugins)); + data_ptr += sizeof(num_plugins); + + for(unsigned int i = 0; i < num_plugins; i++) + { + /*---------------------------------------------------------*\ + | Copy in plugin name (size+data) | + \*---------------------------------------------------------*/ + unsigned short str_len = strlen(plugins[i].name.c_str()) + 1; + + memcpy(&data_buf[data_ptr], &str_len, sizeof(unsigned short)); + data_ptr += sizeof(unsigned short); + + strcpy((char *)&data_buf[data_ptr], plugins[i].name.c_str()); + data_ptr += str_len; + + /*---------------------------------------------------------*\ + | Copy in plugin description (size+data) | + \*---------------------------------------------------------*/ + str_len = strlen(plugins[i].description.c_str()) + 1; + + memcpy(&data_buf[data_ptr], &str_len, sizeof(unsigned short)); + data_ptr += sizeof(unsigned short); + + strcpy((char *)&data_buf[data_ptr], plugins[i].description.c_str()); + data_ptr += str_len; + + /*---------------------------------------------------------*\ + | Copy in plugin version (size+data) | + \*---------------------------------------------------------*/ + str_len = strlen(plugins[i].version.c_str()) + 1; + + memcpy(&data_buf[data_ptr], &str_len, sizeof(unsigned short)); + data_ptr += sizeof(unsigned short); + + strcpy((char *)&data_buf[data_ptr], plugins[i].version.c_str()); + data_ptr += str_len; + + /*---------------------------------------------------------*\ + | Copy in plugin index (data) | + \*---------------------------------------------------------*/ + memcpy(&data_buf[data_ptr], &i, sizeof(unsigned int)); + data_ptr += sizeof(unsigned int); + + /*---------------------------------------------------------*\ + | Copy in plugin sdk version (data) | + \*---------------------------------------------------------*/ + memcpy(&data_buf[data_ptr], &plugins[i].protocol_version, sizeof(int)); + data_ptr += sizeof(int); + } + + NetPacketHeader reply_hdr; + unsigned int reply_size; + + memcpy(&reply_size, data_buf, sizeof(reply_size)); + + reply_hdr.pkt_magic[0] = 'O'; + reply_hdr.pkt_magic[1] = 'R'; + reply_hdr.pkt_magic[2] = 'G'; + reply_hdr.pkt_magic[3] = 'B'; + + reply_hdr.pkt_dev_idx = 0; + reply_hdr.pkt_id = NET_PACKET_ID_REQUEST_PLUGIN_LIST; + reply_hdr.pkt_size = reply_size; + + send(client_sock, (const char *)&reply_hdr, sizeof(NetPacketHeader), 0); + send(client_sock, (const char *)data_buf, reply_size, 0); + + delete [] data_buf; +} + +void NetworkServer::SendReply_PluginSpecific(SOCKET client_sock, unsigned int pkt_type, unsigned char* data, unsigned int data_size) +{ + NetPacketHeader reply_hdr; + unsigned char* reply = new unsigned char[sizeof(pkt_type) + data_size]; + + memcpy(reply, &pkt_type, sizeof(pkt_type)); + memcpy(reply + sizeof(pkt_type), data, data_size); + + reply_hdr.pkt_magic[0] = 'O'; + reply_hdr.pkt_magic[1] = 'R'; + reply_hdr.pkt_magic[2] = 'G'; + reply_hdr.pkt_magic[3] = 'B'; + + reply_hdr.pkt_dev_idx = 0; + reply_hdr.pkt_id = NET_PACKET_ID_PLUGIN_SPECIFIC; + reply_hdr.pkt_size = data_size + sizeof(pkt_type); + + send(client_sock, (const char *)&reply_hdr, sizeof(NetPacketHeader), 0); + send(client_sock, (const char *)reply, data_size, 0); + delete [] reply; + delete [] data; +} + void NetworkServer::SetProfileManager(ProfileManagerInterface* profile_manager_pointer) { profile_manager = profile_manager_pointer; } +void NetworkServer::RegisterPlugin(NetworkPlugin plugin) +{ + plugins.push_back(plugin); +} + +void NetworkServer::UnregisterPlugin(std::string plugin_name) +{ + for(std::vector::iterator it = plugins.begin(); it != plugins.end(); it++) + { + if(it->name == plugin_name) + { + plugins.erase(it); + break; + } + } +} diff --git a/NetworkServer.h b/NetworkServer.h index 96f33939..c7766599 100644 --- a/NetworkServer.h +++ b/NetworkServer.h @@ -21,6 +21,17 @@ #define TCP_TIMEOUT_SECONDS 5 typedef void (*NetServerCallback)(void *); +typedef unsigned char* (*NetPluginCallback)(void *, unsigned int, unsigned char*, unsigned int*); + +struct NetworkPlugin +{ + std::string name; + std::string description; + std::string version; + NetPluginCallback callback; + void* callback_arg; + unsigned int protocol_version; +}; class NetworkClientInfo { @@ -75,8 +86,13 @@ public: 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 SetProfileManager(ProfileManagerInterface* profile_manager_pointer); + + void RegisterPlugin(NetworkPlugin plugin); + void UnregisterPlugin(std::string plugin_name); protected: std::string host; @@ -100,6 +116,8 @@ protected: ProfileManagerInterface* profile_manager; + std::vector plugins; + private: #ifdef WIN32 WSADATA wsa;