Initial release
This commit is contained in:
@@ -0,0 +1,214 @@
|
||||
#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;
|
||||
|
||||
/**
|
||||
* @brief Pre-build DISCOVER and TREE response caches.
|
||||
*
|
||||
* Called automatically by SetFullConfig() once the application is fully
|
||||
* initialised. After this point, DISCOVER and TREE are served from the
|
||||
* pre-built string with no mutex contention and no JSON generation cost.
|
||||
* Both caches are invalidated whenever a new signal is registered (which
|
||||
* normally only happens during broker init, before SetFullConfig).
|
||||
*/
|
||||
void BuildDiscoverCache();
|
||||
void BuildTreeCache();
|
||||
|
||||
// Number of signals per DISCOVER_PART TCP chunk. Responses larger than
|
||||
// this are split so the Go client can start parsing immediately.
|
||||
static const uint32 DISCOVER_CHUNK_SIGNALS = 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 ExportTreeNode(const char8 *path, StreamString &out);
|
||||
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;
|
||||
|
||||
// Pre-built response caches. Guarded by mutex (brief lock for swap,
|
||||
// none needed for reads once cacheValid is true and construction is done).
|
||||
StreamString discoverCache; // full chunked DISCOVER_PART+DISCOVER payload
|
||||
StreamString treeCache; // full TREE payload including sentinel
|
||||
volatile bool discoverCacheValid;
|
||||
volatile bool treeCacheValid;
|
||||
};
|
||||
|
||||
} // namespace MARTe
|
||||
|
||||
#endif // DEBUGSERVICEBASE_H
|
||||
Reference in New Issue
Block a user