#ifndef WEBDEBUGSERVICE_H #define WEBDEBUGSERVICE_H #include "BasicTCPSocket.h" #include "DebugServiceBase.h" #include "EmbeddedServiceMethodBinderI.h" #include "ReferenceT.h" #include "SingleThreadService.h" namespace MARTe { /** * @brief HTTP/SSE implementation of DebugServiceI (via DebugServiceBase). * * 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 * * All signal management and command dispatch logic lives in DebugServiceBase. * This class adds only the HTTP/SSE transport. */ class WebDebugService : public DebugServiceBase, public EmbeddedServiceMethodBinderI { public: friend class WebDebugServiceTest; CLASS_REGISTER_DECLARATION() WebDebugService(); virtual ~WebDebugService(); virtual bool Initialise(StructuredDataI &data); // EmbeddedServiceMethodBinderI (framework dispatches to sub-binders) virtual ErrorManagement::ErrorType Execute(ExecutionInfo &info); protected: // Transport-specific overrides of DebugServiceBase hooks virtual void GetServiceInfo(StreamString &out); virtual void RebuildTransportConfig() {} // no transport-specific keys 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); // 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; BasicTCPSocket tcpServer; WdsBinder binderHttp; WdsBinder binderStream; SingleThreadService httpService; SingleThreadService streamerService; // 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 // 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; // Staging buffer for trace ring-buffer pops (max UDP datagram payload). static const uint32 TRACE_SAMPLE_MAX = 65499u; uint8 traceSampleBuffer[TRACE_SAMPLE_MAX]; }; } // namespace MARTe #endif // WEBDEBUGSERVICE_H