Files
MARTe-Integrated-Components/Source/Components/Interfaces/DebugService/DebugService.h
T
Martino Ferrari 617b5bd712 Initial release
2026-05-29 13:29:59 +02:00

184 lines
6.6 KiB
C++

#ifndef DEBUGSERVICE_H
#define DEBUGSERVICE_H
#include "BasicTCPSocket.h"
#include "BasicUDPSocket.h"
#include "DebugServiceBase.h"
#include "EmbeddedServiceMethodBinderI.h"
#include "MessageI.h"
#include "ReferenceT.h"
#include "SingleThreadService.h"
#include "UDPSProtocol.h"
namespace MARTe {
/**
* @brief TCP/UDP implementation of DebugServiceI (via DebugServiceBase).
*
* Signal tracing now uses the UDPS binary protocol (same wire format as
* UDPStreamer) so that the same Go web client can consume both sources.
*
* Flow:
* 1. The Go client listens on udpPort.
* 2. DebugService binds the same port on its end (or uses the client's
* configured IP:port as destination for the old push model).
* 3. On startup and on every TRACE change, DebugService sends a CONFIG
* packet listing the currently-traced signals.
* 4. For each RT drain cycle that contains new data, DebugService sends
* one DATA packet (Strict mode) with the most-recent value per signal.
*/
class DebugService : public DebugServiceBase,
public MessageI,
public EmbeddedServiceMethodBinderI {
public:
friend class DebugServiceTest;
CLASS_REGISTER_DECLARATION()
DebugService();
virtual ~DebugService();
virtual bool Initialise(StructuredDataI &data);
virtual ErrorManagement::ErrorType Execute(ExecutionInfo &info);
virtual ErrorManagement::ErrorType HandleMessage(ReferenceT<Message> &data);
/**
* @brief Override TraceSignal to trigger a CONFIG re-send after each change.
*/
virtual uint32 TraceSignal(const char8 *name, bool enable, uint32 decimation = 1u);
protected:
virtual void GetServiceInfo(StreamString &out);
virtual void RebuildTransportConfig();
private:
void InjectTcpLoggerIfNeeded();
ErrorManagement::ErrorType Server (ExecutionInfo &info);
ErrorManagement::ErrorType Streamer(ExecutionInfo &info);
/**
* @brief Build and transmit a CONFIG packet for the current traced-signal set.
* @details Iterates over all registered signals, selects those with
* isTracing == true, builds UDPSSignalDescriptor array, and sends
* a (possibly fragmented) UDPS CONFIG packet. Also rebuilds the
* udpsSlots table and udpsWirePayload buffer.
* @return true on success.
*/
bool SendUDPSConfig();
/**
* @brief Fragment and send a payload as one or more UDPS datagrams.
* @param type Packet type (UDPS_TYPE_CONFIG or UDPS_TYPE_DATA).
* @param payload Pointer to fully-built payload.
* @param payloadSize Byte count of payload.
* @return true if all datagrams were written without error.
*/
bool SendUDPSFragmented(uint8 type, const uint8 *payload, uint32 payloadSize);
// -----------------------------------------------------------------------
// TCP/UDP transport configuration
// -----------------------------------------------------------------------
uint16 controlPort;
uint16 streamPort;
uint16 logPort;
StreamString streamIP;
bool isServer;
bool suppressTimeoutLogs;
BasicTCPSocket tcpServer;
BasicUDPSocket udpSocket;
// -----------------------------------------------------------------------
// Server-thread helper class
// -----------------------------------------------------------------------
class ServiceBinder : public EmbeddedServiceMethodBinderI {
public:
enum ServiceType { ServerType, StreamerType };
ServiceBinder(DebugService *parent, ServiceType type)
: parent(parent), type(type) {}
virtual ErrorManagement::ErrorType Execute(ExecutionInfo &info) {
if (type == StreamerType) return parent->Streamer(info);
return parent->Server(info);
}
private:
DebugService *parent;
ServiceType type;
};
ServiceBinder binderServer;
ServiceBinder binderStreamer;
SingleThreadService threadService;
SingleThreadService streamerService;
ThreadIdentifier serverThreadId;
ThreadIdentifier streamerThreadId;
FastPollingMutexSem clientMutex;
BasicTCPSocket *activeClient;
// -----------------------------------------------------------------------
// TCP server rate limiting and idle detection
// -----------------------------------------------------------------------
static const uint32 CMD_RATE_LIMIT = 100u;
static const uint32 CLIENT_IDLE_TIMEOUT_MS = 120000u;
static const uint32 INPUT_BUFFER_MAX = 8192u;
uint32 cmdCountInWindow;
uint64 cmdWindowStartMs;
uint64 lastDataTimeMs;
StreamString inputBuffer;
// -----------------------------------------------------------------------
// UDPS streaming state (replaces the old custom-format streamer buffers)
// -----------------------------------------------------------------------
/**
* @brief Per-slot descriptor for DATA packet assembly.
* One slot per currently-traced signal; index mirrors CONFIG order.
*/
struct UDPSSlot {
uint32 internalID; ///< DebugSignalInfo::internalID
uint32 wireOffset; ///< Byte offset in udpsDataPayload (after 8-byte HRT)
uint32 wireSize; ///< Bytes occupied by this signal in the DATA payload
bool everFilled; ///< True once at least one sample has been placed
};
/** Maximum number of simultaneously traced signals. */
static const uint32 UDPS_MAX_SLOTS = 512u;
/** Maximum payload per UDP datagram (signal data bytes, excluding header). */
static const uint32 UDPS_MAX_PAYLOAD = 1400u;
/** Hard cap on a single signal's data: 65535 - header(17) - HRT(8). */
static const uint32 UDPS_MAX_SAMPLE_BYTES = 65510u;
UDPSSlot udpsSlots[UDPS_MAX_SLOTS]; ///< Slot table (valid for [0, udpsNumSlots))
uint32 udpsNumSlots; ///< Number of active slots
/** Heap-allocated DATA payload buffer: [HRT:8][sig0_data]...[sigN_data].
* Re-allocated by SendUDPSConfig(). NULL when no signals are traced. */
uint8 *udpsDataPayload;
uint32 udpsDataPayloadSize;
/** Staging buffer: a single sample popped from traceBuffer. */
uint8 udpsSampleBuf[65535u];
/** General-purpose TX buffer for CONFIG and DATA packet assembly. */
uint8 udpsTxBuf[65535u];
/** Packet sequence counter (incremented per DATA/CONFIG datagram group). */
uint32 udpsPacketCounter;
/**
* @brief Set to true by TraceSignal() to request a CONFIG re-send.
* Read and cleared by the Streamer thread.
*/
volatile bool udpsConfigPending;
};
} // namespace MARTe
#endif // DEBUGSERVICE_H