Initial release
This commit is contained in:
@@ -0,0 +1,183 @@
|
||||
#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
|
||||
Reference in New Issue
Block a user