/*---------------------------------------------------------*\ | NetworkServer.h | | | | OpenRGB SDK network server | | | | Adam Honse (CalcProgrammer1) 09 May 2020 | | | | This file is part of the OpenRGB project | | SPDX-License-Identifier: GPL-2.0-or-later | \*---------------------------------------------------------*/ #pragma once #include #include #include #include "RGBController.h" #include "NetworkProtocol.h" #include "net_port.h" #include "ProfileManager.h" #include "ResourceManager.h" #define MAXSOCK 32 #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 { public: NetworkClientInfo(); ~NetworkClientInfo(); SOCKET client_sock; std::thread * client_listen_thread; std::string client_string; unsigned int client_protocol_version; std::string client_ip; }; class NetworkServer { public: NetworkServer(std::vector& control); ~NetworkServer(); std::string GetHost(); unsigned short GetPort(); bool GetOnline(); bool GetListening(); unsigned int GetNumClients(); const char * GetClientString(unsigned int client_num); const char * GetClientIP(unsigned int client_num); unsigned int GetClientProtocolVersion(unsigned int client_num); void ClientInfoChanged(); void DeviceListChanged(); void RegisterClientInfoChangeCallback(NetServerCallback, void * new_callback_arg); void ServerListeningChanged(); void RegisterServerListeningChangeCallback(NetServerCallback, void * new_callback_arg); void SetHost(std::string host); void SetLegacyWorkaroundEnable(bool enable); void SetPort(unsigned short new_port); void StartServer(); void StopServer(); void ConnectionThreadFunction(int socket_idx); void ListenThreadFunction(NetworkClientInfo * client_sock); 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(); 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 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; unsigned short port_num; std::atomic server_online; std::atomic server_listening; std::vector& controllers; std::mutex ServerClientsMutex; std::vector ServerClients; std::thread * ConnectionThread[MAXSOCK]; std::mutex ClientInfoChangeMutex; std::vector ClientInfoChangeCallbacks; std::vector ClientInfoChangeCallbackArgs; std::mutex ServerListeningChangeMutex; std::vector ServerListeningChangeCallbacks; std::vector ServerListeningChangeCallbackArgs; ProfileManagerInterface* profile_manager; std::vector plugins; 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); };