/** * @file main.cpp * @brief StreamHub entry point. * * Usage: * StreamHub.ex [-cfg ] [-port ] [-maxPoints ] * * If -cfg is not given a minimal in-memory configuration is used with defaults. * -port and -maxPoints override values from the config file. */ #include "StreamHub.h" #include "ConfigurationDatabase.h" #include "StandardParser.h" #include "BasicFile.h" #include "AdvancedErrorManagement.h" #include "ErrorManagement.h" #include "StreamString.h" #include #include #include #include /* Simple stderr logger for MARTe2 REPORT_ERROR_STATIC messages */ static void StderrErrorProcessFunction(const MARTe::ErrorManagement::ErrorInformation &info, const MARTe::char8 * const errorDescription) { const char *level = "Info"; MARTe::ErrorManagement::ErrorType et = info.header.errorType; if (et == MARTe::ErrorManagement::FatalError) { level = "FatalError"; } else if (et == MARTe::ErrorManagement::Warning) { level = "Warning"; } else if (et == MARTe::ErrorManagement::Information) { level = "Information"; } else if (et == MARTe::ErrorManagement::Debug) { level = "Debug"; } const char *fname = info.fileName; if (fname == static_cast(0)) { fname = "?"; } /* strip path — just filename */ for (const char *p = fname; *p != '\0'; p++) { if (*p == '/') { fname = p + 1; } } fprintf(stderr, "[StreamHub][%s - %s:%u]: %s\n", level, fname, static_cast(info.header.lineNumber), errorDescription != static_cast(0) ? errorDescription : ""); } using MARTe::ConfigurationDatabase; using MARTe::StandardParser; using MARTe::StreamString; using MARTe::uint32; using MARTe::BasicFile; /* Global flag set by SIGINT/SIGTERM handler */ static volatile int gStop = 0; static StreamHub::StreamHub *gHub = static_cast(0); static void SignalHandler(int /*sig*/) { gStop = 1; if (gHub != static_cast(0)) { gHub->Stop(); } } int main(int argc, char **argv) { /* Install MARTe2 error handler so REPORT_ERROR_STATIC messages go to stderr */ MARTe::ErrorManagement::SetErrorProcessFunction(&StderrErrorProcessFunction); const char *cfgFile = static_cast(0); uint32 portOverride = 0u; uint32 maxPtsOverride = 0u; /* Parse command line */ for (int i = 1; i < argc; i++) { if ((strcmp(argv[i], "-cfg") == 0) && (i + 1 < argc)) { cfgFile = argv[++i]; } else if ((strcmp(argv[i], "-port") == 0) && (i + 1 < argc)) { portOverride = static_cast(atoi(argv[++i])); } else if ((strcmp(argv[i], "-maxPoints") == 0) && (i + 1 < argc)) { maxPtsOverride = static_cast(atoi(argv[++i])); } else if ((strcmp(argv[i], "-h") == 0) || (strcmp(argv[i], "--help") == 0)) { printf("Usage: StreamHub.ex [-cfg file.cfg] [-port N] [-maxPoints N]\n"); return 0; } } /* Build ConfigurationDatabase */ ConfigurationDatabase cfg; if (cfgFile != static_cast(0)) { /* Load from file via StandardParser */ BasicFile f; if (!f.Open(cfgFile, BasicFile::ACCESS_MODE_R | BasicFile::FLAG_CREAT)) { fprintf(stderr, "StreamHub: cannot open config file '%s'\n", cfgFile); return 1; } StreamString cfgContent; StreamString errStream; StandardParser parser(f, cfg, &errStream); if (!parser.Parse()) { fprintf(stderr, "StreamHub: config parse error: %s\n", errStream.Buffer()); f.Close(); return 1; } f.Close(); /* Navigate into +Hub node if present */ if (cfg.MoveRelative("Hub")) { /* already inside */ } } /* Apply command-line overrides */ if (portOverride > 0u) { (void) cfg.Write("WSPort", portOverride); } if (maxPtsOverride > 0u) { (void) cfg.Write("MaxPoints", maxPtsOverride); } /* Install signal handlers */ signal(SIGINT, SignalHandler); signal(SIGTERM, SignalHandler); /* Allocate on the heap: StreamHub embeds 32 UDPSourceSession objects, * each ~327 KB (4 reassembly slots × 65 KB + recv buffer), totalling * ~10 MB — well above the default 8 MB thread stack limit. */ StreamHub::StreamHub *hub = new StreamHub::StreamHub(); gHub = hub; if (!hub->Initialise(cfg)) { fprintf(stderr, "StreamHub: Initialise() failed.\n"); delete hub; return 1; } (void) hub->Run(); delete hub; printf("StreamHub: stopped.\n"); return 0; }