#ifndef DEBUGSERVICE_H #define DEBUGSERVICE_H #include "DataSourceI.h" #include "GAM.h" #include "MessageI.h" #include "StreamString.h" #include "BasicUDPSocket.h" #include "BasicTCPSocket.h" #include "ReferenceContainer.h" #include "SingleThreadService.h" #include "EmbeddedServiceMethodBinderI.h" #include "FastMath.h" #include "CompilerTypes.h" #include "Object.h" #include "DebugCore.h" #include "ClassRegistryDatabase.h" #include "ErrorManagement.h" #include "AdvancedErrorManagement.h" #include "LoggerConsumerI.h" #include "Threads.h" #include "EventSem.h" namespace MARTe { struct LogEntry { ErrorManagement::ErrorInformation info; char8 description[MAX_ERROR_MESSAGE_SIZE]; }; struct SignalAlias { StreamString name; uint32 signalIndex; }; class DebugService : public ReferenceContainer, public MessageI, public EmbeddedServiceMethodBinderI, public LoggerConsumerI { public: CLASS_REGISTER_DECLARATION() DebugService(); virtual ~DebugService(); virtual bool Initialise(StructuredDataI & data); DebugSignalInfo* RegisterSignal(void* memoryAddress, TypeDescriptor type, const char8* name); void ProcessSignal(DebugSignalInfo* signalInfo, uint32 size); virtual ErrorManagement::ErrorType Execute(ExecutionInfo & info); virtual void ConsumeLogMessage(LoggerPage *logPage); static void LogCallback(const ErrorManagement::ErrorInformation &errorInfo, const char8 * const errorDescription); void InsertLogIntoQueue(LoggerPage *logPage); bool IsPaused() const { return isPaused; } void SetPaused(bool paused) { isPaused = paused; } static bool GetFullObjectName(const Object &obj, StreamString &fullPath); private: void HandleCommand(StreamString cmd, BasicTCPSocket *client); uint32 ForceSignal(const char8* name, const char8* valueStr); uint32 UnforceSignal(const char8* name); uint32 TraceSignal(const char8* name, bool enable, uint32 decimation = 1); void Discover(BasicTCPSocket *client); void ListNodes(const char8* path, BasicTCPSocket *client); void InfoNode(const char8* path, BasicTCPSocket *client); uint32 ExportTree(ReferenceContainer *container, StreamString &json); void PatchRegistry(); ErrorManagement::ErrorType Server(ExecutionInfo & info); ErrorManagement::ErrorType Streamer(ExecutionInfo & info); ErrorManagement::ErrorType LogStreamer(ExecutionInfo & info); uint16 controlPort; uint16 streamPort; uint16 logPort; StreamString streamIP; bool isServer; bool suppressTimeoutLogs; volatile bool isPaused; BasicTCPSocket tcpServer; BasicUDPSocket udpSocket; BasicTCPSocket logServer; class ServiceBinder : public EmbeddedServiceMethodBinderI { public: enum ServiceType { ServerType, StreamerType, LogStreamerType }; ServiceBinder(DebugService *parent, ServiceType type) : parent(parent), type(type) {} virtual ErrorManagement::ErrorType Execute(ExecutionInfo & info) { if (type == StreamerType) return parent->Streamer(info); if (type == LogStreamerType) return parent->LogStreamer(info); return parent->Server(info); } private: DebugService *parent; ServiceType type; }; ServiceBinder binderServer; ServiceBinder binderStreamer; ServiceBinder binderLogStreamer; SingleThreadService threadService; SingleThreadService streamerService; SingleThreadService logStreamerService; ThreadIdentifier serverThreadId; ThreadIdentifier streamerThreadId; ThreadIdentifier logStreamerThreadId; static const uint32 MAX_SIGNALS = 4096; DebugSignalInfo signals[MAX_SIGNALS]; uint32 numberOfSignals; static const uint32 MAX_ALIASES = 8192; SignalAlias aliases[MAX_ALIASES]; uint32 numberOfAliases; FastPollingMutexSem mutex; TraceRingBuffer traceBuffer; static const uint32 MAX_CLIENTS = 16; BasicTCPSocket* activeClients[MAX_CLIENTS]; FastPollingMutexSem clientsMutex; BasicTCPSocket* activeLogClients[MAX_CLIENTS]; FastPollingMutexSem logClientsMutex; static const uint32 LOG_QUEUE_SIZE = 1024; LogEntry logQueue[LOG_QUEUE_SIZE]; volatile uint32 logQueueRead; volatile uint32 logQueueWrite; EventSem logEvent; static DebugService* instance; static ErrorManagement::ErrorProcessFunctionType originalLogCallback; }; } #endif