From 8adac2f6db9f8619a3e671ee88d51a1c7bb18b79 Mon Sep 17 00:00:00 2001 From: Mika Date: Sun, 17 May 2026 02:07:30 +0000 Subject: [PATCH] Add laser_tracking_cli_tool/src/main.c --- laser_tracking_cli_tool/src/main.c | 288 +++++++++++++++++++++++++++++ 1 file changed, 288 insertions(+) create mode 100644 laser_tracking_cli_tool/src/main.c diff --git a/laser_tracking_cli_tool/src/main.c b/laser_tracking_cli_tool/src/main.c new file mode 100644 index 0000000..0473f39 --- /dev/null +++ b/laser_tracking_cli_tool/src/main.c @@ -0,0 +1,288 @@ +/* + * W A R N U N G – K I – G E N E R I E R T E S P R O G R A M M + * + * Dieses Kommandozeilenprogramm wurde vollständig von einer KI generiert. + * Es ist rein experimentell und wurde in KEINER Weise auf Sicherheit, Korrektheit + * oder Robustheit geprüft. + * + * - KEIN PRODUKTIVEINSATZ! + * - KEINE GARANTIE FÜR FUNKTIONALITÄT ODER SICHERHEIT! + * - Kann Abstürze, Speicherfehler, undefiniertes Verhalten oder Sicherheitslücken verursachen + * - Nur für Lern-, Demonstrations- und Forschungszwecke gedacht + * + * Sprache: C + */ + +/* + * laser_tracking_cli_tool + * + * Einfaches, simuliertes CLI-Tool zur Steuerung eines (fiktiven) Laser-Tracking-Systems + * für Satelliten. Es bietet Befehle zum Starten des Trackings und zum Abfragen des + * aktuellen Tracking-Status. + * + * WICHTIG: Dieses Programm steuert KEINE echte Hardware und führt KEINE + * Netzwerkoperationen durch. Alle Werte sind simuliert. + */ + +#include +#include +#include +#include +#include +#include + +#include "tracking.h" + +#define TOOL_VERSION "0.1.0-experimental" + +static void print_usage(const char *progname) +{ + if (progname == NULL) { + progname = "laser_tracking"; + } + + printf("Usage: %s [OPTION]... COMMAND [ARGS]\n", progname); + printf("Simuliertes CLI-Tool zur Steuerung eines Laser-Tracking-Systems für Satelliten.\n"); + printf("KEIN PRODUKTIVEINSATZ – NUR DEMO!\n\n"); + + printf("Globale Optionen:\n"); + printf(" -h, --help diese Hilfe anzeigen\n"); + printf(" -v, --version Versionsinformationen ausgeben\n"); + printf(" -q, --quiet weniger Ausgaben\n"); + printf(" --debug Debug-Informationen\n"); + printf(" --seed=N Zufalls-Seed setzen (Reproduzierbarkeit)\n"); + printf("\n"); + + printf("Befehle:\n"); + printf(" start Tracking für einen Satelliten starten\n"); + printf(" status aktuellen Tracking-Status anzeigen\n"); + printf("\n"); + + printf("Beispiele:\n"); + printf(" %s start --sat COMM-SAT-RX --elev 67\n", progname); + printf(" %s status\n", progname); + printf("\n"); +} + +static void print_version(void) +{ + printf("laser_tracking_cli_tool %s\n", TOOL_VERSION); +} + +static void print_start_usage(const char *progname) +{ + printf("Usage: %s [GLOBAL-OPTION]... start --sat NAME --elev WINKEL\n", progname); + printf("Startet ein simuliertes Laser-Tracking auf einen Satelliten.\n\n"); + printf("Optionen für 'start':\n"); + printf(" --sat NAME Name/ID des Ziel-Satelliten (z.B. COMM-SAT-RX)\n"); + printf(" --elev WINKEL Elevationswinkel in Grad (0.0–90.0)\n"); + printf("\nBeispiel:\n"); + printf(" %s start --sat COMM-SAT-RX --elev 67\n", progname); +} + +static void print_status_usage(const char *progname) +{ + printf("Usage: %s [GLOBAL-OPTION]... status\n", progname); + printf("Zeigt den aktuellen simulierten Tracking-Status an.\n"); +} + +static void print_tracking_status(const tracking_status *st, int quiet) +{ + if (st == NULL) { + fprintf(stderr, "[ERROR] tracking_status ist NULL.\n"); + return; + } + + char timebuf[64]; + struct tm tm_info; + + if (localtime_r(&st->last_update, &tm_info) != NULL) { + if (strftime(timebuf, sizeof(timebuf), "%Y-%m-%d %H:%M:%S %Z", &tm_info) == 0) { + strncpy(timebuf, "", sizeof(timebuf) - 1); + timebuf[sizeof(timebuf) - 1] = '\0'; + } + } else { + strncpy(timebuf, "", sizeof(timebuf) - 1); + timebuf[sizeof(timebuf) - 1] = '\0'; + } + + if (!quiet) { + printf("Tracking-Status:\n"); + } + + printf(" active : %s\n", st->active ? "yes" : "no"); + printf(" last_update : %s\n", timebuf); + printf(" deviation : %.4f deg\n", st->deviation); +} + +int main(int argc, char *argv[]) +{ + int quiet = 0; + int debug = 0; + unsigned int seed = 0; + int seed_set = 0; + + static struct option long_opts[] = { + {"help", no_argument, 0, 'h'}, + {"version",no_argument, 0, 'v'}, + {"quiet", no_argument, 0, 'q'}, + {"debug", no_argument, 0, 1 }, + {"seed", required_argument, 0, 2 }, + {0, 0, 0, 0} + }; + + int opt; + int opt_index = 0; + + /* Nur globale Optionen bis zum ersten Nicht-Options-Argument parsen */ + while ((opt = getopt_long(argc, argv, "hvq", long_opts, &opt_index)) != -1) { + switch (opt) { + case 'h': + print_usage(argv[0]); + return 0; + case 'v': + print_version(); + return 0; + case 'q': + quiet = 1; + break; + case 1: /* --debug */ + debug = 1; + break; + case 2: /* --seed */ + { + char *endptr = NULL; + seed = (unsigned int)strtoul(optarg, &endptr, 10); + if (endptr == optarg || *endptr != '\0') { + fprintf(stderr, "Ungueltiger Seed-Wert: '%s'\n", optarg); + return 1; + } + seed_set = 1; + break; + } + default: + print_usage(argv[0]); + return 1; + } + } + + if (seed_set) { + if (!quiet) { + printf("[INFO] Seed gesetzt auf %u\n", seed); + } + srand(seed); + } else { + /* Reproduzierbarkeit ist nicht notwendig, aber wir initialisieren */ + srand((unsigned int)time(NULL)); + } + + if (optind >= argc) { + /* Kein Kommando angegeben */ + print_usage(argv[0]); + return 0; + } + + const char *command = argv[optind]; + + if (debug) { + printf("[DEBUG] Global quiet=%d, debug=%d, command='%s'\n", quiet, debug, command); + } + + if (strcmp(command, "start") == 0) { + /* Subkommando 'start' */ + const char *sat_name = NULL; + double elev = -1.0; + + /* Einfache Sub-Argumentverarbeitung: --sat NAME --elev WINKEL */ + int i = optind + 1; + while (i < argc) { + const char *arg = argv[i]; + if (strcmp(arg, "--sat") == 0) { + if (i + 1 >= argc) { + fprintf(stderr, "Fehlender Wert für --sat.\n"); + print_start_usage(argv[0]); + return 1; + } + sat_name = argv[i + 1]; + i += 2; + } else if (strcmp(arg, "--elev") == 0) { + if (i + 1 >= argc) { + fprintf(stderr, "Fehlender Wert für --elev.\n"); + print_start_usage(argv[0]); + return 1; + } + char *endptr = NULL; + elev = strtod(argv[i + 1], &endptr); + if (endptr == argv[i + 1] || *endptr != '\0') { + fprintf(stderr, "Ungueltiger Elevationswinkel: '%s'\n", argv[i + 1]); + return 1; + } + i += 2; + } else if (strcmp(arg, "-h") == 0 || strcmp(arg, "--help") == 0) { + print_start_usage(argv[0]); + return 0; + } else { + fprintf(stderr, "Unbekanntes Argument fuer 'start': %s\n", arg); + print_start_usage(argv[0]); + return 1; + } + } + + if (sat_name == NULL || elev < 0.0) { + fprintf(stderr, "Fehlende oder ungueltige Parameter fuer 'start'.\n"); + print_start_usage(argv[0]); + return 1; + } + + if (elev < 0.0 || elev > 90.0) { + fprintf(stderr, "Elevation muss zwischen 0.0 und 90.0 Grad liegen.\n"); + return 1; + } + + if (!quiet) { + printf("tracking – target=%s, elev=%.2fdeg\n", sat_name, elev); + } + + if (debug) { + printf("[DEBUG] Aufruf start_tracking(""%s"", %.2f)\n", sat_name, elev); + } + + tracking_status st; + memset(&st, 0, sizeof(st)); + + bool ok = start_tracking(sat_name, elev, &st, debug); + if (!ok) { + fprintf(stderr, "Start des Trackings fehlgeschlagen (Simulation).\n"); + return 1; + } + + if (!quiet) { + printf("Tracking simuliert gestartet. Status:\n"); + } + + print_tracking_status(&st, quiet); + return 0; + + } else if (strcmp(command, "status") == 0) { + /* Subkommando 'status' – hier nur aktuelles (simuliertes) Statusobjekt + * aus der Library abfragen. In dieser einfachen Demo generieren wir es + * bei jedem Aufruf neu. */ + tracking_status st; + memset(&st, 0, sizeof(st)); + + if (!get_status(&st)) { + fprintf(stderr, "Konnte Tracking-Status nicht abrufen (Simulation).\n"); + return 1; + } + + print_tracking_status(&st, quiet); + return 0; + } else if (strcmp(command, "help") == 0) { + print_usage(argv[0]); + return 0; + } else { + fprintf(stderr, "Unbekanntes Kommando: %s\n\n", command); + print_usage(argv[0]); + return 1; + } +}