Add laser_tracking_cli_tool/src/main.c

This commit is contained in:
Mika 2026-05-17 02:07:30 +00:00
commit 8adac2f6db

View file

@ -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 <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <stdbool.h>
#include <time.h>
#include <getopt.h>
#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.090.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, "<time-format-error>", sizeof(timebuf) - 1);
timebuf[sizeof(timebuf) - 1] = '\0';
}
} else {
strncpy(timebuf, "<time-error>", 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;
}
}