From 7d75432b69775e036d5a23a5fdc77a5a234ecfcc Mon Sep 17 00:00:00 2001 From: Adam Honse Date: Wed, 6 May 2026 17:43:13 -0500 Subject: [PATCH] Log manager SDK protocol --- LogManager.cpp | 130 +++++++++++++++++----------- LogManager.h | 3 +- NetworkClient.cpp | 107 +++++++++++++++++++++++ NetworkClient.h | 11 +++ NetworkProtocol.h | 25 ++++-- NetworkServer.cpp | 204 +++++++++++++++++++++++++++++++++++++++++++- NetworkServer.h | 9 ++ ResourceManager.cpp | 11 +++ 8 files changed, 440 insertions(+), 60 deletions(-) diff --git a/LogManager.cpp b/LogManager.cpp index eeb361b5b..9bc83cc3a 100644 --- a/LogManager.cpp +++ b/LogManager.cpp @@ -15,6 +15,9 @@ #include "filesystem.h" #include "JsonUtils.h" #include "LogManager.h" +#include "NetworkClient.h" +#include "NetworkServer.h" +#include "ResourceManager.h" const char* LogManager::LOG_CODES[] = {"Fatal", "Error", "Warning", "Info", "Verbose", "Debug", "Trace", "Dialog"}; @@ -244,6 +247,11 @@ void LogManager::Configure(json config, const filesystem::path& config_dir) \*---------------------------------------------------------*/ void LogManager::ClearLogBuffer() { + if(ResourceManager::get()->IsLocalClient() && (ResourceManager::get()->GetLocalClient()->GetSupportsProfileManagerAPI())) + { + ResourceManager::get()->GetLocalClient()->LogManager_ClearLogBuffer(); + } + all_messages.clear(); } @@ -265,7 +273,7 @@ unsigned int LogManager::GetVerbosity() return(verbosity); } -void LogManager::SetLogLevel(unsigned int level) +void LogManager::SetLogLevel(unsigned int level, bool local_only) { /*-----------------------------------------------------*\ | Check that the new log level is valid, otherwise set | @@ -276,6 +284,14 @@ void LogManager::SetLogLevel(unsigned int level) level = LL_TRACE; } + /*-----------------------------------------------------*\ + | Set the server's log level if local client | + \*-----------------------------------------------------*/ + if(!local_only && ResourceManager::get()->IsLocalClient() && (ResourceManager::get()->GetLocalClient()->GetSupportsLogManagerAPI())) + { + ResourceManager::get()->GetLocalClient()->LogManager_SetLogLevel(level); + } + LOG_DEBUG("[%s] LogLevel set to %d", LOGMANAGER, level); /*-----------------------------------------------------*\ @@ -325,13 +341,73 @@ void LogManager::LogEntry(const char* filename, int line, unsigned int level, co va_end(va); } -void LogManager::LogEntry_va(const char* filename, int line, unsigned int level, const char* fmt, va_list va) +void LogManager::LogEntry_message(PLogMessage message) { /*-----------------------------------------------------*\ | Lock the entry mutex while adding an entry | \*-----------------------------------------------------*/ std::lock_guard guard(entry_mutex); + /*-----------------------------------------------------*\ + | If this is a dialog message, call the dialog show | + | callback | + \*-----------------------------------------------------*/ + if(message->level == LL_DIALOG) + { + for(size_t idx = 0; idx < LogManagerCallbacks.size(); idx++) + { + LogManagerCallbacks[idx](LogManagerCallbackArgs[idx], LOGMANAGER_UPDATE_REASON_SHOW_DIALOG, message); + } + } + else + { + for(size_t idx = 0; idx < LogManagerCallbacks.size(); idx++) + { + LogManagerCallbacks[idx](LogManagerCallbackArgs[idx], LOGMANAGER_UPDATE_REASON_LOG_ENTRY, message); + } + } + + /*-----------------------------------------------------*\ + | If the message is within the current verbosity, print | + | it on the screen | + \*-----------------------------------------------------*/ + if(message->level <= verbosity || message->level == LL_DIALOG) + { + std::cout << std::left << "[" << std::setw(10) << message->timestamp << "]"; + std::cout << std::left << "[" << std::setw(7) << LOG_CODES[message->level] << "]"; + if(print_source) + { + std::cout << " [" << message->filename << ":" << message->line << "]"; + } + std::cout << message->text; + std::cout << std::endl; + } + + /*-----------------------------------------------------*\ + | Add the message to the logfile queue | + \*-----------------------------------------------------*/ + temp_messages.push_back(message); + + if(log_console_enabled) + { + all_messages.push_back(message); + + NetworkServer* server = ResourceManager::get()->GetServer(); + + if(server) + { + server->SignalLogManagerLoggedEntry(*message); + } + } + + /*-----------------------------------------------------*\ + | Flush the queues | + \*-----------------------------------------------------*/ + flush(); +} + +void LogManager::LogEntry_va(const char* filename, int line, unsigned int level, const char* fmt, va_list va) +{ /*-----------------------------------------------------*\ | If a critical message occurs, enable source | | printing and set loglevel and verbosity to highest | @@ -376,55 +452,7 @@ void LogManager::LogEntry_va(const char* filename, int line, unsigned int level, message->text.erase(std::remove(message->text.begin(), message->text.end(), '\r'), message->text.end()); } - /*-----------------------------------------------------*\ - | If this is a dialog message, call the dialog show | - | callback | - \*-----------------------------------------------------*/ - if(level == LL_DIALOG) - { - for(size_t idx = 0; idx < LogManagerCallbacks.size(); idx++) - { - LogManagerCallbacks[idx](LogManagerCallbackArgs[idx], LOGMANAGER_UPDATE_REASON_SHOW_DIALOG, message); - } - } - else - { - for(size_t idx = 0; idx < LogManagerCallbacks.size(); idx++) - { - LogManagerCallbacks[idx](LogManagerCallbackArgs[idx], LOGMANAGER_UPDATE_REASON_LOG_ENTRY, message); - } - } - - /*-----------------------------------------------------*\ - | If the message is within the current verbosity, print | - | it on the screen | - \*-----------------------------------------------------*/ - if(level <= verbosity || level == LL_DIALOG) - { - std::cout << std::left << "[" << std::setw(10) << message->timestamp << "]"; - std::cout << std::left << "[" << std::setw(7) << LOG_CODES[message->level] << "]"; - if(print_source) - { - std::cout << " [" << message->filename << ":" << message->line << "]"; - } - std::cout << message->text; - std::cout << std::endl; - } - - /*-----------------------------------------------------*\ - | Add the message to the logfile queue | - \*-----------------------------------------------------*/ - temp_messages.push_back(message); - - if(log_console_enabled) - { - all_messages.push_back(message); - } - - /*-----------------------------------------------------*\ - | Flush the queues | - \*-----------------------------------------------------*/ - flush(); + LogEntry_message(message); } /*---------------------------------------------------------*\ diff --git a/LogManager.h b/LogManager.h index b0571f07e..9583c81b1 100644 --- a/LogManager.h +++ b/LogManager.h @@ -99,7 +99,7 @@ public: unsigned int GetLogLevel(); unsigned int GetVerbosity(); - void SetLogLevel(unsigned int); + void SetLogLevel(unsigned int, bool local_only = false); void SetVerbosity(unsigned int); /*-----------------------------------------------------*\ @@ -111,6 +111,7 @@ public: | Log Entry Functions | \*-----------------------------------------------------*/ void LogEntry(const char* filename, int line, unsigned int level, const char* fmt, ...); + void LogEntry_message(PLogMessage message); void LogEntry_va(const char* filename, int line, unsigned int level, const char* fmt, va_list va); /*-----------------------------------------------------*\ diff --git a/NetworkClient.cpp b/NetworkClient.cpp index 1c0eb0fa4..a019198cf 100644 --- a/NetworkClient.cpp +++ b/NetworkClient.cpp @@ -50,6 +50,7 @@ NetworkClient::NetworkClient() port_ip = "127.0.0.1"; port_num = OPENRGB_SDK_PORT; client_flags = NET_CLIENT_FLAG_SUPPORTS_RGBCONTROLLER + | NET_CLIENT_FLAG_SUPPORTS_LOGMANAGER | NET_CLIENT_FLAG_SUPPORTS_PROFILEMANAGER | NET_CLIENT_FLAG_SUPPORTS_SETTINGSMANAGER; client_flags_sent = false; @@ -120,6 +121,11 @@ bool NetworkClient::GetSupportsRGBControllerAPI() return(server_flags & NET_SERVER_FLAG_SUPPORTS_RGBCONTROLLER); } +bool NetworkClient::GetSupportsLogManagerAPI() +{ + return(server_flags & NET_SERVER_FLAG_SUPPORTS_LOGMANAGER); +} + bool NetworkClient::GetSupportsProfileManagerAPI() { return(server_flags & NET_SERVER_FLAG_SUPPORTS_PROFILEMANAGER); @@ -341,6 +347,71 @@ std::string NetworkClient::DetectionManager_GetDetectionString() return(detection_string); } +/*---------------------------------------------------------*\ +| LogManager functions | +\*---------------------------------------------------------*/ +void NetworkClient::LogManager_ClearLogBuffer() +{ + NetPacketHeader reply_hdr; + + InitNetPacketHeader(&reply_hdr, 0, NET_PACKET_ID_LOGMANAGER_CLEAR_LOG_BUFFER, 0); + + send_in_progress.lock(); + send(client_sock, (char *)&reply_hdr, sizeof(NetPacketHeader), MSG_NOSIGNAL); + send_in_progress.unlock(); +} + +void NetworkClient::LogManager_GetLogBuffer() +{ + NetPacketHeader reply_hdr; + + InitNetPacketHeader(&reply_hdr, 0, NET_PACKET_ID_LOGMANAGER_GET_LOG_BUFFER, 0); + + send_in_progress.lock(); + send(client_sock, (char *)&reply_hdr, sizeof(NetPacketHeader), MSG_NOSIGNAL); + send_in_progress.unlock(); +} + +unsigned int NetworkClient::LogManager_GetLogLevel() +{ + unsigned int log_level = 0; + NetPacketHeader reply_hdr; + + InitNetPacketHeader(&reply_hdr, 0, NET_PACKET_ID_LOGMANAGER_GET_LOG_LEVEL, 0); + + send_in_progress.lock(); + send(client_sock, (char *)&reply_hdr, sizeof(NetPacketHeader), MSG_NOSIGNAL); + send_in_progress.unlock(); + + std::unique_lock wait_lock(waiting_on_response_mutex); + waiting_on_response_cv.wait(wait_lock); + + if(response_header.pkt_id == NET_PACKET_ID_LOGMANAGER_GET_LOG_LEVEL && response_data_ptr != NULL) + { + if(response_header.pkt_size >= sizeof(log_level)) + { + memcpy(&log_level, response_data_ptr, sizeof(log_level)); + } + + delete[] response_data_ptr; + response_data_ptr = NULL; + } + + return(log_level); +} + +void NetworkClient::LogManager_SetLogLevel(unsigned int log_level) +{ + NetPacketHeader reply_hdr; + + InitNetPacketHeader(&reply_hdr, 0, NET_PACKET_ID_LOGMANAGER_SET_LOG_LEVEL, sizeof(log_level)); + + send_in_progress.lock(); + send(client_sock, (char *)&reply_hdr, sizeof(NetPacketHeader), MSG_NOSIGNAL); + send(client_sock, (char*)&log_level, sizeof(log_level), MSG_NOSIGNAL); + send_in_progress.unlock(); +} + /*---------------------------------------------------------*\ | ProfileManager functions | \*---------------------------------------------------------*/ @@ -1176,6 +1247,11 @@ void NetworkClient::ListenThreadFunction() SignalNetworkClientUpdate(NETWORKCLIENT_UPDATE_REASON_DETECTION_COMPLETE); break; + case NET_PACKET_ID_LOGMANAGER_LOGGED_ENTRY: + ProcessRequest_LogManager_LoggedEntry(header.pkt_size, data); + break; + + case NET_PACKET_ID_LOGMANAGER_GET_LOG_LEVEL: case NET_PACKET_ID_PROFILEMANAGER_DOWNLOAD_PROFILE: case NET_PACKET_ID_PROFILEMANAGER_GET_ACTIVE_PROFILE: case NET_PACKET_ID_SETTINGSMANAGER_GET_SETTINGS: @@ -1446,6 +1522,37 @@ void NetworkClient::ProcessRequest_DeviceListChanged() server_initialized = false; } +void NetworkClient::ProcessRequest_LogManager_LoggedEntry(unsigned int data_size, char * data) +{ + PLogMessage message = std::make_shared(); + + data += sizeof(unsigned int); + + memcpy(&message->level, data, sizeof(message->level)); + data += sizeof(message->level); + + memcpy(&message->line, data, sizeof(message->line)); + data += sizeof(message->line); + + unsigned short filename_size; + memcpy(&filename_size, data, sizeof(filename_size)); + data += sizeof(filename_size); + + message->filename.assign(data, filename_size); + data += filename_size; + message->filename = StringUtils::remove_null_terminating_chars(message->filename); + + unsigned short text_size; + memcpy(&text_size, data, sizeof(text_size)); + data += sizeof(text_size); + + message->text.assign(data, text_size); + data += text_size; + message->text = StringUtils::remove_null_terminating_chars(message->text); + + LogManager::get()->LogEntry_message(message); +} + void NetworkClient::ProcessRequest_ProfileManager_ActiveProfileChanged(unsigned int data_size, char * data) { if(data_size == 0 || data == NULL) diff --git a/NetworkClient.h b/NetworkClient.h index 02f4a7c9a..b7829e7b3 100644 --- a/NetworkClient.h +++ b/NetworkClient.h @@ -62,6 +62,7 @@ public: bool GetOnline(); std::string GetServerName(); bool GetSupportsRGBControllerAPI(); + bool GetSupportsLogManagerAPI(); bool GetSupportsProfileManagerAPI(); bool GetSupportsPluginManagerAPI(); bool GetSupportsSettingsManagerAPI(); @@ -93,6 +94,14 @@ public: unsigned int DetectionManager_GetDetectionPercent(); std::string DetectionManager_GetDetectionString(); + /*-----------------------------------------------------*\ + | LogManager functions | + \*-----------------------------------------------------*/ + void LogManager_ClearLogBuffer(); + void LogManager_GetLogBuffer(); + unsigned int LogManager_GetLogLevel(); + void LogManager_SetLogLevel(unsigned int log_level); + /*-----------------------------------------------------*\ | ProfileManager functions | \*-----------------------------------------------------*/ @@ -235,6 +244,8 @@ private: void ProcessRequest_ServerFlags(unsigned int data_size, char * data); void ProcessRequest_ServerString(unsigned int data_size, char * data); + void ProcessRequest_LogManager_LoggedEntry(unsigned int data_size, char * data); + void ProcessRequest_ProfileManager_ActiveProfileChanged(unsigned int data_size, char * data); void ProcessRequest_ProfileManager_ProfileAboutToLoad(); void ProcessRequest_ProfileManager_ProfileListUpdated(unsigned int data_size, char * data); diff --git a/NetworkProtocol.h b/NetworkProtocol.h index 4308267c1..6f65b2227 100644 --- a/NetworkProtocol.h +++ b/NetworkProtocol.h @@ -71,9 +71,10 @@ typedef struct enum { NET_CLIENT_FLAG_SUPPORTS_RGBCONTROLLER = ( 1 << 0 ), /* Client supports RGBController API */ - NET_CLIENT_FLAG_SUPPORTS_PROFILEMANAGER = ( 1 << 1 ), /* Client supports ProfileManager API */ - NET_CLIENT_FLAG_SUPPORTS_PLUGINMANAGER = ( 1 << 2 ), /* Client supports PluginManager API */ - NET_CLIENT_FLAG_SUPPORTS_SETTINGSMANAGER = ( 1 << 3 ), /* Client supports SettingsManager API */ + NET_CLIENT_FLAG_SUPPORTS_LOGMANAGER = ( 1 << 1 ), /* Client supports LogManager API */ + NET_CLIENT_FLAG_SUPPORTS_PROFILEMANAGER = ( 1 << 2 ), /* Client supports ProfileManager API */ + NET_CLIENT_FLAG_SUPPORTS_PLUGINMANAGER = ( 1 << 3 ), /* Client supports PluginManager API */ + NET_CLIENT_FLAG_SUPPORTS_SETTINGSMANAGER = ( 1 << 4 ), /* Client supports SettingsManager API */ NET_CLIENT_FLAG_REQUEST_LOCAL_CLIENT = ( 1 << 16 ), /* Request local client */ }; @@ -81,10 +82,11 @@ enum enum { NET_SERVER_FLAG_SUPPORTS_RGBCONTROLLER = ( 1 << 0 ), /* Server supports RGBController API */ - NET_SERVER_FLAG_SUPPORTS_PROFILEMANAGER = ( 1 << 1 ), /* Server supports ProfileManager API */ - NET_SERVER_FLAG_SUPPORTS_PLUGINMANAGER = ( 1 << 2 ), /* Server supports PluginManager API */ - NET_SERVER_FLAG_SUPPORTS_SETTINGSMANAGER = ( 1 << 3 ), /* Server supports SettingsManager API */ - NET_SERVER_FLAG_SUPPORTS_DETECTION = ( 1 << 4 ), /* Server supports detection functions */ + NET_SERVER_FLAG_SUPPORTS_LOGMANAGER = ( 1 << 1 ), /* Server supports LogManager API */ + NET_SERVER_FLAG_SUPPORTS_PROFILEMANAGER = ( 1 << 2 ), /* Server supports ProfileManager API */ + NET_SERVER_FLAG_SUPPORTS_PLUGINMANAGER = ( 1 << 3 ), /* Server supports PluginManager API */ + NET_SERVER_FLAG_SUPPORTS_SETTINGSMANAGER = ( 1 << 4 ), /* Server supports SettingsManager API */ + NET_SERVER_FLAG_SUPPORTS_DETECTION = ( 1 << 5 ), /* Server supports detection functions */ NET_SERVER_FLAG_LOCAL_CLIENT = ( 1 << 16), /* Confirm that client is local client */ }; @@ -153,6 +155,15 @@ enum NET_PACKET_ID_SETTINGSMANAGER_SET_SETTINGS = 253, /* Set settings for a given key in JSON format */ NET_PACKET_ID_SETTINGSMANAGER_SAVE_SETTINGS = 254, /* Save settings */ + /*----------------------------------------------------------------------------------------------------------*\ + | LogManager functions | + \*----------------------------------------------------------------------------------------------------------*/ + NET_PACKET_ID_LOGMANAGER_CLEAR_LOG_BUFFER = 300, /* LogManager::ClearLogBuffer() */ + NET_PACKET_ID_LOGMANAGER_GET_LOG_BUFFER = 301, /* LogManager::GetLogBuffer() */ + NET_PACKET_ID_LOGMANAGER_GET_LOG_LEVEL = 302, /* LogManager::GetLogLevel() */ + NET_PACKET_ID_LOGMANAGER_SET_LOG_LEVEL = 303, /* LogManager::SetLogLevel() */ + NET_PACKET_ID_LOGMANAGER_LOGGED_ENTRY = 304, /* LogManager::LogEntry Callback */ + /*----------------------------------------------------------------------------------------------------------*\ | RGBController functions | \*----------------------------------------------------------------------------------------------------------*/ diff --git a/NetworkServer.cpp b/NetworkServer.cpp index afa5c3e89..f39cc3a3f 100644 --- a/NetworkServer.cpp +++ b/NetworkServer.cpp @@ -27,7 +27,6 @@ #include #include #include -#include #ifdef _WIN32 #include @@ -104,6 +103,7 @@ NetworkServer::NetworkServer() controller_next_idx = 0; controller_updating = false; server_flags = NET_SERVER_FLAG_SUPPORTS_RGBCONTROLLER + | NET_SERVER_FLAG_SUPPORTS_LOGMANAGER | NET_SERVER_FLAG_SUPPORTS_PROFILEMANAGER | NET_SERVER_FLAG_SUPPORTS_PLUGINMANAGER | NET_SERVER_FLAG_SUPPORTS_SETTINGSMANAGER @@ -224,6 +224,64 @@ unsigned int NetworkServer::GetClientProtocolVersion(unsigned int client_num) /*---------------------------------------------------------*\ | Callback functions | \*---------------------------------------------------------*/ +void NetworkServer::SignalLogManagerLoggedEntry(LogMessage& logged_entry) +{ + if(ServerClients.size() > 0) + { + /*-------------------------------------------------*\ + | Create data buffer for message | + \*-------------------------------------------------*/ + unsigned int data_size = 0; + unsigned short filename_size = strlen(logged_entry.filename.c_str()) + 1; + unsigned short text_size = strlen(logged_entry.text.c_str()) + 1; + + data_size += sizeof(data_size); + data_size += sizeof(logged_entry.level); + data_size += sizeof(logged_entry.line); + data_size += sizeof(filename_size); + data_size += filename_size; + data_size += sizeof(text_size); + data_size += text_size; + + unsigned char* data_buf = new unsigned char[data_size]; + unsigned char* data_ptr = data_buf; + + memcpy(data_ptr, &data_size, sizeof(data_size)); + data_ptr += sizeof(data_size); + + memcpy(data_ptr, &logged_entry.level, sizeof(logged_entry.level)); + data_ptr += sizeof(logged_entry.level); + + memcpy(data_ptr, &logged_entry.line, sizeof(logged_entry.line)); + data_ptr += sizeof(logged_entry.line); + + memcpy(data_ptr, &filename_size, sizeof(filename_size)); + data_ptr += sizeof(filename_size); + + memcpy(data_ptr, logged_entry.filename.c_str(), filename_size); + data_ptr += filename_size; + + memcpy(data_ptr, &text_size, sizeof(text_size)); + data_ptr += sizeof(text_size); + + memcpy(data_ptr, logged_entry.text.c_str(), text_size); + data_ptr += text_size; + + /*-------------------------------------------------*\ + | Send Logged Entry request for all clients | + \*-------------------------------------------------*/ + for(unsigned int client_idx = 0; client_idx < ServerClients.size(); client_idx++) + { + if(ServerClients[client_idx]->client_is_local_client) + { + SendRequest_LoggedEntry(ServerClients[client_idx], data_buf, data_size); + } + } + + delete[] data_buf; + } +} + void NetworkServer::SignalProfileManagerUpdate(unsigned int update_reason) { switch(update_reason) @@ -1184,6 +1242,25 @@ void NetworkServer::ListenThreadFunction(NetworkClientInfo * client_info) status = ProcessRequest_RescanDevices(); break; + /*-------------------------------------------------*\ + | LogManager functions | + \*-------------------------------------------------*/ + case NET_PACKET_ID_LOGMANAGER_CLEAR_LOG_BUFFER: + status = ProcessRequest_LogManager_ClearLogBuffer(client_info); + break; + + case NET_PACKET_ID_LOGMANAGER_GET_LOG_BUFFER: + status = ProcessRequest_LogManager_GetLogBuffer(client_info); + break; + + case NET_PACKET_ID_LOGMANAGER_GET_LOG_LEVEL: + status = ProcessRequest_LogManager_GetLogLevel(client_info); + break; + + case NET_PACKET_ID_LOGMANAGER_SET_LOG_LEVEL: + status = ProcessRequest_LogManager_SetLogLevel(client_info, header.pkt_size, data); + break; + /*-------------------------------------------------*\ | ProfileManager functions are handled in a | | separate thread, queue the messages | @@ -1576,6 +1653,119 @@ NetPacketStatus NetworkServer::ProcessRequest_RescanDevices() return(NET_PACKET_STATUS_OK); } +NetPacketStatus NetworkServer::ProcessRequest_LogManager_ClearLogBuffer(NetworkClientInfo* client_info) +{ + if(!client_info->client_is_local_client) + { + return(NET_PACKET_STATUS_ERROR_NOT_ALLOWED); + } + + LogManager::get()->ClearLogBuffer(); + + return(NET_PACKET_STATUS_OK); +} + +NetPacketStatus NetworkServer::ProcessRequest_LogManager_GetLogBuffer(NetworkClientInfo* client_info) +{ + if(!client_info->client_is_local_client) + { + return(NET_PACKET_STATUS_ERROR_NOT_ALLOWED); + } + + for(PLogMessage& logged_entry: LogManager::get()->GetLogBuffer()) + { + /*-------------------------------------------------*\ + | Create data buffer for message | + \*-------------------------------------------------*/ + unsigned int data_size = 0; + unsigned short filename_size = strlen(logged_entry->filename.c_str()) + 1; + unsigned short text_size = strlen(logged_entry->text.c_str()) + 1; + + data_size += sizeof(data_size); + data_size += sizeof(logged_entry->level); + data_size += sizeof(logged_entry->line); + data_size += sizeof(filename_size); + data_size += filename_size; + data_size += sizeof(text_size); + data_size += text_size; + + unsigned char* data_buf = new unsigned char[data_size]; + unsigned char* data_ptr = data_buf; + + memcpy(data_ptr, &data_size, sizeof(data_size)); + data_ptr += sizeof(data_size); + + memcpy(data_ptr, &logged_entry->level, sizeof(logged_entry->level)); + data_ptr += sizeof(logged_entry->level); + + memcpy(data_ptr, &logged_entry->line, sizeof(logged_entry->line)); + data_ptr += sizeof(logged_entry->line); + + memcpy(data_ptr, &filename_size, sizeof(filename_size)); + data_ptr += sizeof(filename_size); + + memcpy(data_ptr, logged_entry->filename.c_str(), filename_size); + data_ptr += filename_size; + + memcpy(data_ptr, &text_size, sizeof(text_size)); + data_ptr += sizeof(text_size); + + memcpy(data_ptr, logged_entry->text.c_str(), text_size); + data_ptr += text_size; + + /*---------------------------------------------*\ + | Send Logged Entry request to client | + \*---------------------------------------------*/ + SendRequest_LoggedEntry(client_info, data_buf, data_size); + + delete[] data_buf; + } + + return(NET_PACKET_STATUS_OK); +} + +NetPacketStatus NetworkServer::ProcessRequest_LogManager_GetLogLevel(NetworkClientInfo* client_info) +{ + if(!client_info->client_is_local_client) + { + return(NET_PACKET_STATUS_ERROR_NOT_ALLOWED); + } + + unsigned int log_level = LogManager::get()->GetLogLevel(); + + NetPacketHeader reply_hdr; + + InitNetPacketHeader(&reply_hdr, 0, NET_PACKET_ID_LOGMANAGER_GET_LOG_LEVEL, sizeof(log_level)); + + send_in_progress.lock(); + send(client_info->client_sock, (char *)&reply_hdr, sizeof(NetPacketHeader), MSG_NOSIGNAL); + send(client_info->client_sock, (char *)&log_level, reply_hdr.pkt_size, MSG_NOSIGNAL); + send_in_progress.unlock(); + + return(NET_PACKET_STATUS_OK); +} + +NetPacketStatus NetworkServer::ProcessRequest_LogManager_SetLogLevel(NetworkClientInfo* client_info, unsigned int data_size, char* data) +{ + unsigned int log_level; + + if(data_size < sizeof(log_level)) + { + return(NET_PACKET_STATUS_ERROR_INVALID_DATA); + } + + if(!client_info->client_is_local_client) + { + return(NET_PACKET_STATUS_ERROR_NOT_ALLOWED); + } + + memcpy(&log_level, data, sizeof(log_level)); + + LogManager::get()->SetLogLevel(log_level); + + return(NET_PACKET_STATUS_OK); +} + NetPacketStatus NetworkServer::ProcessRequest_ProfileManager_ClearActiveProfile(NetworkClientInfo* /*client_info*/) { if(profile_manager) @@ -2882,6 +3072,18 @@ void NetworkServer::SendReply_PluginSpecific(SOCKET client_sock, unsigned int pk delete [] data; } +void NetworkServer::SendRequest_LoggedEntry(NetworkClientInfo* client_info, unsigned char* data, unsigned int data_size) +{ + NetPacketHeader pkt_hdr; + + InitNetPacketHeader(&pkt_hdr, 0, NET_PACKET_ID_LOGMANAGER_LOGGED_ENTRY, data_size); + + send_in_progress.lock(); + send(client_info->client_sock, (char *)&pkt_hdr, sizeof(NetPacketHeader), MSG_NOSIGNAL); + send(client_info->client_sock, (char *)data, pkt_hdr.pkt_size, MSG_NOSIGNAL); + send_in_progress.unlock(); +} + void NetworkServer::SendRequest_ProfileManager_ActiveProfileChanged(SOCKET client_sock, std::string active_profile) { NetPacketHeader pkt_hdr; diff --git a/NetworkServer.h b/NetworkServer.h index 8d4872ef7..7a549b8da 100644 --- a/NetworkServer.h +++ b/NetworkServer.h @@ -17,6 +17,7 @@ #include #include #include +#include "LogManager.h" #include "RGBController.h" #include "NetworkProtocol.h" #include "net_port.h" @@ -103,6 +104,7 @@ public: /*-----------------------------------------------------*\ | Functions for forwarding callback sigals over network | \*-----------------------------------------------------*/ + void SignalLogManagerLoggedEntry(LogMessage& logged_entry); void SignalProfileManagerUpdate(unsigned int update_reason); void SignalResourceManagerUpdate(unsigned int update_reason); @@ -228,6 +230,11 @@ private: NetPacketStatus ProcessRequest_ClientString(SOCKET client_sock, unsigned int data_size, char * data); NetPacketStatus ProcessRequest_RescanDevices(); + NetPacketStatus ProcessRequest_LogManager_ClearLogBuffer(NetworkClientInfo* client_info); + NetPacketStatus ProcessRequest_LogManager_GetLogBuffer(NetworkClientInfo* client_info); + NetPacketStatus ProcessRequest_LogManager_GetLogLevel(NetworkClientInfo* client_info); + NetPacketStatus ProcessRequest_LogManager_SetLogLevel(NetworkClientInfo* client_info, unsigned int data_size, char* data); + NetPacketStatus ProcessRequest_ProfileManager_ClearActiveProfile(NetworkClientInfo* client_info); NetPacketStatus ProcessRequest_ProfileManager_DeleteProfile(NetworkClientInfo* client_info, unsigned int data_size, char* data); NetPacketStatus ProcessRequest_ProfileManager_DownloadProfile(NetworkClientInfo* client_info, unsigned int data_size, char* data); @@ -272,6 +279,8 @@ private: void SendRequest_DetectionStarted(SOCKET client_sock, unsigned int protocol_version); void SendRequest_DeviceListChanged(SOCKET client_sock); + void SendRequest_LoggedEntry(NetworkClientInfo* client_info, unsigned char* data, unsigned int data_size); + void SendRequest_ProfileManager_ActiveProfileChanged(SOCKET client_sock, std::string active_profile); void SendRequest_ProfileManager_ProfileAboutToLoad(); void SendRequest_ProfileManager_ProfileListChanged(SOCKET client_sock, unsigned char *profile_list_description); diff --git a/ResourceManager.cpp b/ResourceManager.cpp index a77fe4bfc..e25444550 100644 --- a/ResourceManager.cpp +++ b/ResourceManager.cpp @@ -720,6 +720,17 @@ bool ResourceManager::AttemptLocalConnection() } std::this_thread::sleep_for(5ms); } + + /*-------------------------------------------------*\ + | If local client, set local log level to server's | + | log level and download log entries | + \*-------------------------------------------------*/ + if(auto_connection_client->GetLocal() && auto_connection_client->GetSupportsLogManagerAPI()) + { + unsigned int log_level = auto_connection_client->LogManager_GetLogLevel(); + LogManager::get()->SetLogLevel(log_level, true); + auto_connection_client->LogManager_GetLogBuffer(); + } } return success;