Implemented common base for debug services

This commit is contained in:
Martino Ferrari
2026-05-07 12:12:14 +02:00
parent 774808a054
commit e9f25f5867
9 changed files with 1947 additions and 3436 deletions
@@ -1,4 +1,4 @@
OBJSX=WebDebugService.x
OBJSX=WebDebugService.x DebugServiceBase.x
PACKAGE=Components/Interfaces
@@ -26,9 +26,16 @@ INCLUDES += -I$(MARTe2_DIR)/Source/Core/Scheduler/L5GAMs
INCLUDES += -I$(MARTe2_DIR)/Source/Core/FileSystem/L1Portability
INCLUDES += -I$(MARTe2_DIR)/Source/Core/FileSystem/L3Streams
DEBUGSERVICE_SRC=$(ROOT_DIR)/Source/Components/Interfaces/DebugService
all: $(OBJS) $(SUBPROJ) \
$(BUILD_DIR)/WebDebugService$(LIBEXT) \
$(BUILD_DIR)/WebDebugService$(DLLEXT)
echo $(OBJS)
include $(MAKEDEFAULTDIR)/MakeStdLibRules.$(TARGET)
# Explicit rule to compile DebugServiceBase.cpp from the DebugService directory
$(BUILD_DIR)/DebugServiceBase.o: $(DEBUGSERVICE_SRC)/DebugServiceBase.cpp
$(COMPILER) -c $(OPTIM) $(INCLUDES) $(CPPFLAGS) $(CFLAGSPEC) $(DEBUG) \
$(DEBUGSERVICE_SRC)/DebugServiceBase.cpp -o $(BUILD_DIR)/DebugServiceBase.o
File diff suppressed because it is too large Load Diff
@@ -2,18 +2,15 @@
#define WEBDEBUGSERVICE_H
#include "BasicTCPSocket.h"
#include "ConfigurationDatabase.h"
#include "DataSourceI.h"
#include "DebugServiceI.h"
#include "DebugServiceBase.h"
#include "EmbeddedServiceMethodBinderI.h"
#include "ReferenceContainer.h"
#include "ReferenceT.h"
#include "SingleThreadService.h"
namespace MARTe {
/**
* @brief HTTP/SSE implementation of DebugServiceI.
* @brief HTTP/SSE implementation of DebugServiceI (via DebugServiceBase).
*
* Serves a single-page web UI on httpPort (default 8090).
* Endpoints:
@@ -21,20 +18,11 @@ namespace MARTe {
* POST /api/command — execute a debug command; returns text response
* GET /api/events — Server-Sent Events stream for real-time telemetry
*
* SSE event types (JSON payload on each "data:" line):
* {"type":"trace", "name":"…","ts":<ns>,"value":<f64>}
* {"type":"monitor", "name":"…","ts":<ns>,"value":<f64>}
* {"type":"log", "level":"…","msg":"…"}
* {"type":"status", "paused":<bool>,"gam":"…","remaining":<u32>}
* {"type":"discover","signals":[…]}
* {"type":"tree", "tree":{…}}
*
* This is an alternative to DebugService (TCP/UDP) and registers itself as the
* global DebugServiceI singleton on Initialise().
* All signal management and command dispatch logic lives in DebugServiceBase.
* This class adds only the HTTP/SSE transport.
*/
class WebDebugService : public ReferenceContainer,
public EmbeddedServiceMethodBinderI,
public DebugServiceI {
class WebDebugService : public DebugServiceBase,
public EmbeddedServiceMethodBinderI {
public:
friend class WebDebugServiceTest;
CLASS_REGISTER_DECLARATION()
@@ -44,60 +32,13 @@ public:
virtual bool Initialise(StructuredDataI &data);
// -------------------------------------------------------------------------
// DebugServiceI RT-path overrides
// -------------------------------------------------------------------------
virtual DebugSignalInfo *RegisterSignal(void *memoryAddress,
TypeDescriptor type,
const char8 *name,
uint8 numberOfDimensions = 0,
uint32 numberOfElements = 1);
virtual void ProcessSignal(DebugSignalInfo *signalInfo, uint32 size,
uint64 timestamp);
virtual void RegisterBroker(DebugSignalInfo **signalPointers,
uint32 numSignals, MemoryMapBroker *broker,
volatile bool *anyActiveFlag,
Vec<uint32> *activeIndices,
Vec<uint32> *activeSizes,
FastPollingMutexSem *activeMutex,
volatile bool *anyBreakFlag,
Vec<uint32> *breakIndices,
const char8 *gamName = NULL_PTR(const char8 *),
bool isOutput = false);
virtual bool IsPaused() const { return isPaused; }
virtual void SetPaused(bool paused) { isPaused = paused; }
virtual bool IsStepPending() const { return stepRemaining > 0u; }
virtual void ConsumeStepIfNeeded(const char8 *gamName,
const char8 *threadName = NULL_PTR(const char8 *));
// -------------------------------------------------------------------------
// DebugServiceI control-path overrides
// -------------------------------------------------------------------------
virtual uint32 ForceSignal (const char8 *name, const char8 *valueStr);
virtual uint32 UnforceSignal (const char8 *name);
virtual uint32 TraceSignal (const char8 *name, bool enable, uint32 decimation = 1);
virtual uint32 SetBreak (const char8 *name, uint8 op, float64 threshold);
virtual uint32 ClearBreak (const char8 *name);
virtual bool IsInstrumented(const char8 *fullPath, bool &traceable, bool &forcable);
virtual uint32 RegisterMonitorSignal(const char8 *path, uint32 periodMs);
virtual uint32 UnmonitorSignal (const char8 *path);
// EmbeddedServiceMethodBinderI (framework dispatches to sub-binders)
virtual ErrorManagement::ErrorType Execute(ExecutionInfo &info);
// Inject the full config CDB (call after ConfigureApplication)
void SetFullConfig(ConfigurationDatabase &config);
void RebuildConfigFromRegistry();
struct MonitoredSignal {
ReferenceT<DataSourceI> dataSource;
uint32 signalIdx;
uint32 internalID;
uint32 periodMs;
uint64 lastPollTime;
uint32 size;
StreamString path;
};
protected:
// Transport-specific overrides of DebugServiceBase hooks
virtual void GetServiceInfo(StreamString &out);
virtual void RebuildTransportConfig() {} // no transport-specific keys
private:
// HTTP server helpers
@@ -109,29 +50,6 @@ private:
const StreamString &path, const StreamString &body);
void UpgradeToSse(BasicTCPSocket *client);
// Command handler — writes response to StreamString (not a socket)
void HandleCommand(const StreamString &cmd, StreamString &out);
void Discover (StreamString &out);
void InfoNode (const char8 *path, StreamString &out);
void ListNodes (const char8 *path, StreamString &out);
void GetSignalValue(const char8 *name, StreamString &out);
void ServeConfig (StreamString &out);
void GetStepStatus(StreamString &out);
void Step(uint32 n, const char8 *threadName = NULL_PTR(const char8 *));
// Tree / config helpers
uint32 ExportTree(ReferenceContainer *container, StreamString &json,
const char8 *pathPrefix);
void EnrichWithConfig(const char8 *path, StreamString &json);
static void JsonifyDatabase(ConfigurationDatabase &db, StreamString &json);
// Registry patching (same as DebugService)
void PatchRegistry();
// Broker index maintenance
void UpdateBrokersActiveStatus();
void UpdateBrokersBreakStatus();
// SSE broadcast
void BroadcastSse(const char8 *eventType, const StreamString &data);
void RemoveDeadSseClients();
@@ -156,27 +74,13 @@ private:
uint16 httpPort;
volatile bool isPaused;
volatile uint32 stepRemaining;
StreamString pausedAtGam;
StreamString stepThreadFilter;
BasicTCPSocket tcpServer;
WdsBinder binderHttp;
WdsBinder binderStream;
WdsBinder binderHttp;
WdsBinder binderStream;
SingleThreadService httpService;
SingleThreadService streamerService;
Vec<DebugSignalInfo *> signals;
Vec<SignalAlias> aliases;
Vec<BrokerInfo> brokers;
Vec<MonitoredSignal> monitoredSignals;
FastPollingMutexSem mutex;
FastPollingMutexSem tracePushMutex;
TraceRingBuffer traceBuffer;
// SSE client list
static const uint32 MAX_SSE_CLIENTS = 8u;
BasicTCPSocket *sseClients[MAX_SSE_CLIENTS];
@@ -186,11 +90,6 @@ private:
uint32 streamerSeq;
uint64 streamerT0Ns; // nanosecond origin for relative timestamps sent over SSE
ConfigurationDatabase fullConfig;
bool manualConfigSet;
static const uint32 GET_VALUE_MAX_ELEMENTS = 256u;
// Log history buffer — replayed to newly connecting SSE clients
static const uint32 LOG_HISTORY_SIZE = 64u;
static const uint32 LOG_ENTRY_MAX_SIZE = 512u;