interface added and web ui created
This commit is contained in:
@@ -0,0 +1,205 @@
|
||||
#ifndef WEBDEBUGSERVICE_H
|
||||
#define WEBDEBUGSERVICE_H
|
||||
|
||||
#include "BasicTCPSocket.h"
|
||||
#include "ConfigurationDatabase.h"
|
||||
#include "DataSourceI.h"
|
||||
#include "DebugServiceI.h"
|
||||
#include "EmbeddedServiceMethodBinderI.h"
|
||||
#include "ReferenceContainer.h"
|
||||
#include "ReferenceT.h"
|
||||
#include "SingleThreadService.h"
|
||||
|
||||
namespace MARTe {
|
||||
|
||||
/**
|
||||
* @brief HTTP/SSE implementation of DebugServiceI.
|
||||
*
|
||||
* Serves a single-page web UI on httpPort (default 8090).
|
||||
* Endpoints:
|
||||
* GET / — embedded HTML application
|
||||
* 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().
|
||||
*/
|
||||
class WebDebugService : public ReferenceContainer,
|
||||
public EmbeddedServiceMethodBinderI,
|
||||
public DebugServiceI {
|
||||
public:
|
||||
friend class WebDebugServiceTest;
|
||||
CLASS_REGISTER_DECLARATION()
|
||||
|
||||
WebDebugService();
|
||||
virtual ~WebDebugService();
|
||||
|
||||
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;
|
||||
};
|
||||
|
||||
private:
|
||||
// HTTP server helpers
|
||||
bool ParseRequest(BasicTCPSocket *client, StreamString &method,
|
||||
StreamString &path, StreamString &body);
|
||||
void SendHttp(BasicTCPSocket *client, uint32 code, const char8 *ct,
|
||||
StreamString &body);
|
||||
void HandleRequest(BasicTCPSocket *client, const StreamString &method,
|
||||
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();
|
||||
|
||||
// Service thread entry points
|
||||
ErrorManagement::ErrorType HttpServer(ExecutionInfo &info);
|
||||
ErrorManagement::ErrorType Streamer (ExecutionInfo &info);
|
||||
|
||||
// Sub-binder so the framework can dispatch to two separate threads
|
||||
class WdsBinder : public EmbeddedServiceMethodBinderI {
|
||||
public:
|
||||
enum ServiceType { Http, Stream };
|
||||
WdsBinder(WebDebugService *p, ServiceType t) : parent(p), stype(t) {}
|
||||
virtual ErrorManagement::ErrorType Execute(ExecutionInfo &info) {
|
||||
return (stype == Stream) ? parent->Streamer(info)
|
||||
: parent->HttpServer(info);
|
||||
}
|
||||
private:
|
||||
WebDebugService *parent;
|
||||
ServiceType stype;
|
||||
};
|
||||
|
||||
uint16 httpPort;
|
||||
|
||||
volatile bool isPaused;
|
||||
volatile uint32 stepRemaining;
|
||||
StreamString pausedAtGam;
|
||||
StreamString stepThreadFilter;
|
||||
|
||||
BasicTCPSocket tcpServer;
|
||||
|
||||
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];
|
||||
FastPollingMutexSem sseMutex;
|
||||
|
||||
// Streamer packet state
|
||||
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;
|
||||
char8 logHistory[64][512];
|
||||
uint32 logHistoryWriteIdx;
|
||||
uint32 logHistoryFill;
|
||||
FastPollingMutexSem logHistoryMutex;
|
||||
};
|
||||
|
||||
} // namespace MARTe
|
||||
|
||||
#endif // WEBDEBUGSERVICE_H
|
||||
Reference in New Issue
Block a user