#include "DebugService.h" #include "DebugCore.h" #include "ObjectRegistryDatabase.h" #include "StandardParser.h" #include "StreamString.h" #include "BasicUDPSocket.h" #include "BasicTCPSocket.h" #include "RealTimeApplication.h" #include "GlobalObjectsDatabase.h" #include #include using namespace MARTe; const char8 * const config_text = "+DebugService = {" " Class = DebugService " " ControlPort = 8080 " " UdpPort = 8081 " " StreamIP = \"127.0.0.1\" " "}" "+App = {" " Class = RealTimeApplication " " +Functions = {" " Class = ReferenceContainer " " +GAM1 = {" " Class = IOGAM " " InputSignals = {" " Counter = {" " DataSource = Timer " " Type = uint32 " " Frequency = 100 " " }" " }" " OutputSignals = {" " Counter = {" " DataSource = DDB " " Type = uint32 " " }" " }" " }" " }" " +Data = {" " Class = ReferenceContainer " " DefaultDataSource = DDB " " +Timer = {" " Class = LinuxTimer " " SleepTime = 10000 " " Signals = {" " Counter = { Type = uint32 }" " Time = { Type = uint32 }" " }" " }" " +DDB = {" " Class = GAMDataSource " " Signals = { Counter = { Type = uint32 } }" " }" " +DAMS = { Class = TimingDataSource }" " }" " +States = {" " Class = ReferenceContainer " " +State1 = {" " Class = RealTimeState " " +Threads = {" " Class = ReferenceContainer " " +Thread1 = {" " Class = RealTimeThread " " Functions = {GAM1} " " }" " }" " }" " }" " +Scheduler = {" " Class = GAMScheduler " " TimingDataSource = DAMS " " }" "}"; void RunValidationTest() { printf("--- MARTe2 100Hz Trace Validation Test ---\n"); ObjectRegistryDatabase::Instance()->Purge(); ConfigurationDatabase cdb; StreamString ss = config_text; ss.Seek(0); StandardParser parser(ss, cdb); if (!parser.Parse()) { printf("ERROR: Failed to parse configuration\n"); return; } if (!ObjectRegistryDatabase::Instance()->Initialise(cdb)) { printf("ERROR: Failed to initialise ObjectRegistryDatabase.\n"); return; } ReferenceT service = ObjectRegistryDatabase::Instance()->Find("DebugService"); if (!service.IsValid()) { printf("ERROR: DebugService not found\n"); return; } ReferenceT app = ObjectRegistryDatabase::Instance()->Find("App"); if (!app.IsValid()) { printf("ERROR: App not found\n"); return; } if (!app->ConfigureApplication()) { printf("ERROR: Failed to configure application\n"); return; } if (app->PrepareNextState("State1") != ErrorManagement::NoError) { printf("ERROR: Failed to prepare state State1\n"); return; } if (app->StartNextStateExecution() != ErrorManagement::NoError) { printf("ERROR: Failed to start execution\n"); return; } printf("Application and DebugService are active.\n"); Sleep::MSec(1000); // DIRECT ACTIVATION: Use the public TraceSignal method printf("Activating trace directly...\n"); // We try multiple potential paths to be safe uint32 traceCount = 0; traceCount += service->TraceSignal("App.Data.Timer.Counter", true, 1); traceCount += service->TraceSignal("Timer.Counter", true, 1); traceCount += service->TraceSignal("Counter", true, 1); printf("Trace enabled (Matched Aliases: %u)\n", traceCount); // 4. Setup UDP Listener BasicUDPSocket listener; if (!listener.Open()) { printf("ERROR: Failed to open UDP socket\n"); return; } if (!listener.Listen(8081)) { printf("ERROR: Failed to listen on UDP 8081\n"); return; } // 5. Validate for 10 seconds printf("Validating telemetry for 10 seconds...\n"); uint32 lastVal = 0; bool first = true; uint32 packetCount = 0; uint32 discontinuityCount = 0; float64 startTime = HighResolutionTimer::Counter() * HighResolutionTimer::Period(); float64 globalTimeout = startTime + 30.0; while ((HighResolutionTimer::Counter() * HighResolutionTimer::Period() - startTime) < 10.0) { if (HighResolutionTimer::Counter() * HighResolutionTimer::Period() > globalTimeout) { printf("CRITICAL ERROR: Global test timeout reached.\n"); break; } char buffer[2048]; uint32 size = 2048; TimeoutType timeout(200); if (listener.Read(buffer, size, timeout)) { TraceHeader *h = (TraceHeader*)buffer; if (h->magic == 0xDA7A57AD && h->count > 0) { uint32 offset = sizeof(TraceHeader); // Packet format: [Header][ID:4][Size:4][Value:N] uint32 val = *(uint32*)(&buffer[offset + 8]); if (!first) { if (val != lastVal + 1) { discontinuityCount++; } } lastVal = val; first = false; packetCount++; if (packetCount % 200 == 0) { printf("Received %u packets... Current Value: %u\n", packetCount, val); } } } } printf("Test Finished.\n"); printf("Total Packets Received: %u (Expected ~1000)\n", packetCount); printf("Discontinuities: %u\n", discontinuityCount); float64 actualFreq = (float64)packetCount / 10.0; printf("Average Frequency: %.2f Hz\n", actualFreq); if (packetCount < 100) { printf("FAILURE: Almost no packets received. Telemetry is broken.\n"); } else if (packetCount < 800) { printf("WARNING: Too few packets received (Expected 1000, Got %u).\n", packetCount); } else if (discontinuityCount > 20) { printf("FAILURE: Too many discontinuities (%u).\n", discontinuityCount); } else { printf("VALIDATION SUCCESSFUL!\n"); } app->StopCurrentStateExecution(); listener.Close(); ObjectRegistryDatabase::Instance()->Purge(); } int main() { RunValidationTest(); return 0; }