Files
marte-debug/Source/Components/Interfaces/DebugService/DebugServiceBase.h
T
2026-05-20 11:30:05 +02:00

191 lines
7.7 KiB
C++

#ifndef DEBUGSERVICEBASE_H
#define DEBUGSERVICEBASE_H
/**
* @file DebugServiceBase.h
* @brief Shared base class for DebugService and WebDebugService.
*
* Extracts all signal-management, command-handling and config logic that is
* common to both the TCP/UDP transport (DebugService) and the HTTP/SSE
* transport (WebDebugService), eliminating the previous code duplication.
*/
#include "ConfigurationDatabase.h"
#include "DataSourceI.h"
#include "DebugServiceI.h"
#include "FastPollingMutexSem.h"
#include "ReferenceContainer.h"
#include "ReferenceT.h"
#include "StreamString.h"
namespace MARTe {
/**
* @brief Intermediate base class that holds all shared debugging logic.
*
* Inherits from ReferenceContainer (to be a MARTe2 Object) and DebugServiceI
* (to expose the RT-path / control-path interface). Transport subclasses
* (DebugService, WebDebugService) inherit from this class and add only their
* transport-specific threading and socket logic.
*/
class DebugServiceBase : public ReferenceContainer, public DebugServiceI {
public:
friend class DebugServiceTest;
DebugServiceBase();
virtual ~DebugServiceBase();
// =========================================================================
// DebugServiceI RT-path overrides (shared implementation)
// =========================================================================
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,
Vector<uint32> *activeIndices,
Vector<uint32> *activeSizes,
FastPollingMutexSem *activeMutex,
volatile bool *anyBreakFlag,
Vector<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 (shared implementation)
// =========================================================================
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);
// =========================================================================
// Shared control-path methods (used by transport subclasses)
// =========================================================================
/**
* @brief Parse and dispatch a debug command; write text response to @p out.
*
* Handles: TRACE, FORCE, UNFORCE, BREAK, PAUSE, RESUME, STEP, STEP_STATUS,
* VALUE, DISCOVER, TREE, INFO, LS, CONFIG, MONITOR, UNMONITOR,
* SERVICE_INFO, MSG.
*
* SERVICE_INFO delegates to GetServiceInfo() so each transport can fill in
* its own port/state information.
*/
void HandleCommand(const StreamString &cmdIn, StreamString &out);
void GetStepStatus(StreamString &out);
void GetSignalValue(const char8 *name, StreamString &out);
void Discover (StreamString &out);
void InfoNode (const char8 *path, StreamString &out);
void ListNodes (const char8 *path, StreamString &out);
void ServeConfig (StreamString &out);
void SetFullConfig(ConfigurationDatabase &config);
void RebuildConfigFromRegistry();
// =========================================================================
// Struct shared by both transports
// =========================================================================
struct MonitoredSignal {
ReferenceT<DataSourceI> dataSource;
uint32 signalIdx;
uint32 internalID;
uint32 periodMs;
uint64 lastPollTime;
uint32 size;
StreamString path;
};
// =========================================================================
// Constants
// =========================================================================
static const uint32 GET_VALUE_MAX_ELEMENTS = 256u;
protected:
// =========================================================================
// Virtual hooks for transport subclasses
// =========================================================================
/**
* @brief Fill the SERVICE_INFO response text (transport-specific).
*
* Called by HandleCommand when the SERVICE_INFO command is received.
* The base implementation writes nothing; subclasses override to append
* e.g. "OK SERVICE_INFO TCP_CTRL:8080 UDP_STREAM:8081 STATE:RUNNING\n".
*/
virtual void GetServiceInfo(StreamString &out) = 0;
/**
* @brief Write back transport-specific config keys after RebuildConfigFromRegistry().
*
* Called at the end of RebuildConfigFromRegistry() so that port numbers
* and other transport parameters that were read in Initialise() are
* reflected back into fullConfig (ExportData on ReferenceContainers
* doesn't re-emit config-file parameters).
*/
virtual void RebuildTransportConfig() {}
// =========================================================================
// Shared protected helpers
// =========================================================================
void Step(uint32 n, const char8 *threadName = NULL_PTR(const char8 *));
void UpdateBrokersActiveStatus();
void UpdateBrokersBreakStatus();
void PatchRegistry();
uint32 ExportTree(ReferenceContainer *container, StreamString &json,
const char8 *pathPrefix);
void EnrichWithConfig(const char8 *path, StreamString &json);
static void JsonifyDatabase(ConfigurationDatabase &db, StreamString &json);
// =========================================================================
// Shared data members
// =========================================================================
Vector<DebugSignalInfo *> signals;
Vector<SignalAlias> aliases;
Vector<BrokerInfo> brokers;
Vector<MonitoredSignal> monitoredSignals;
FastPollingMutexSem mutex;
FastPollingMutexSem tracePushMutex;
TraceRingBuffer traceBuffer;
volatile bool isPaused;
volatile uint32 stepRemaining;
StreamString pausedAtGam;
StreamString stepThreadFilter;
ConfigurationDatabase fullConfig;
bool manualConfigSet;
};
} // namespace MARTe
#endif // DEBUGSERVICEBASE_H