#include "hybbx/mains_proxy.h" #include "hybbx/util.h" #include #include #include static unsigned g_failures; static void check_str(const char *label, const char *got, const char *want) { if (got == NULL || want == NULL || strcmp(got, want) != 0) { fprintf(stderr, "FAIL %s: got '%s' want '%s'\n", label, got != NULL ? got : "(null)", want); g_failures++; } } static void check_int(const char *label, int got, int want) { if (got != want) { fprintf(stderr, "FAIL %s: got %d want %d\n", label, got, want); g_failures++; } } static void check_uint(const char *label, unsigned got, unsigned want) { if (got != want) { fprintf(stderr, "FAIL %s: got %u want %u\n", label, got, want); g_failures++; } } static void parse_one_peer(const char *section, hybbx_mains_proxy_peer_config_t *out) { hybbx_result_t rc = hybbx_mains_proxy_peer_parse(section, out); if (rc != HYBBX_OK) { fprintf(stderr, "FAIL peer_parse returned %d for '%s'\n", (int)rc, section); g_failures++; } } int main(void) { hybbx_mains_proxy_peer_config_t peer; const char *multi; const char *sep; char section_buf[1024]; /* 1. semicolon-separated section (serialized by hybbx_config_format_section) */ parse_one_peer( "peer_id=alpha;circuit_host=127.0.0.1;circuit_port=7323;" "link_id=alpha-main;link_password=secret;enabled=yes;wire=circuit;" "duplex=full;use_secondary=yes", &peer); check_str("semicolon peer_id", peer.peer_id, "alpha"); check_str("semicolon circuit_host", peer.circuit_host, "127.0.0.1"); check_uint("semicolon circuit_port", peer.circuit_port, 7323u); check_str("semicolon link_id", peer.link_id, "alpha-main"); check_str("semicolon link_password", peer.link_password, "secret"); check_int("semicolon enabled", peer.enabled, 1); check_int("semicolon wire", (int)peer.wire, (int)HYBBX_MAINS_PROXY_WIRE_CIRCUIT); check_int("semicolon duplex", (int)peer.duplex, (int)HYBBX_MAINS_PROXY_DUPLEX_FULL); check_int("semicolon use_secondary", peer.use_secondary, 1); /* 2. newline-separated section */ parse_one_peer( "peer_id=beta\ncircuit_host=127.0.0.2\ncircuit_port=7324\n" "link_id=beta-main\nlink_password=other\nenabled=no\n" "wire=ax25\nduplex=half\nuse_secondary=no", &peer); check_str("newline peer_id", peer.peer_id, "beta"); check_str("newline circuit_host", peer.circuit_host, "127.0.0.2"); check_uint("newline circuit_port", peer.circuit_port, 7324u); check_str("newline link_id", peer.link_id, "beta-main"); check_str("newline link_password", peer.link_password, "other"); check_int("newline enabled", peer.enabled, 0); check_int("newline wire", (int)peer.wire, (int)HYBBX_MAINS_PROXY_WIRE_AX25); check_int("newline duplex", (int)peer.duplex, (int)HYBBX_MAINS_PROXY_DUPLEX_HALF); check_int("newline use_secondary", peer.use_secondary, 0); /* 3. multiple peers separated by instance separator */ multi = "peer_id=first;circuit_host=127.0.0.1;enabled=yes\x1e" "peer_id=second;circuit_host=127.0.0.2;enabled=yes\x1e" "enabled=no\x1e" "peer_id=fourth;circuit_host=127.0.0.4;enabled=yes"; sep = multi; for (unsigned i = 0; i < 4; i++) { const char *next = strchr(sep, HYBBX_MAINS_PROXY_INSTANCE_SEP); size_t len; if (next != NULL) { len = (size_t)(next - sep); } else { len = strlen(sep); } if (len >= sizeof(section_buf)) { len = sizeof(section_buf) - 1; } memcpy(section_buf, sep, len); section_buf[len] = '\0'; parse_one_peer(section_buf, &peer); switch (i) { case 0: check_str("multi[0] peer_id", peer.peer_id, "first"); check_str("multi[0] circuit_host", peer.circuit_host, "127.0.0.1"); check_int("multi[0] enabled", peer.enabled, 1); break; case 1: check_str("multi[1] peer_id", peer.peer_id, "second"); check_str("multi[1] circuit_host", peer.circuit_host, "127.0.0.2"); check_int("multi[1] enabled", peer.enabled, 1); break; case 2: /* section with only enabled=no: disabled peer preserves defaults */ check_int("multi[2] enabled", peer.enabled, 0); check_str("multi[2] peer_id", peer.peer_id, ""); check_str("multi[2] circuit_host", peer.circuit_host, ""); break; case 3: check_str("multi[3] peer_id", peer.peer_id, "fourth"); check_str("multi[3] circuit_host", peer.circuit_host, "127.0.0.4"); check_int("multi[3] enabled", peer.enabled, 1); break; } if (next == NULL) { break; } sep = next + 1; } /* 4. missing credentials: empty peer_id, empty link_password, invalid port */ parse_one_peer( "circuit_host=127.0.0.1;circuit_port=99999;link_id=main;enabled=yes", &peer); check_str("missing peer_id", peer.peer_id, ""); check_str("missing link_password", peer.link_password, ""); /* invalid port should fall back to default */ check_uint("invalid port default", peer.circuit_port, (unsigned)HYBBX_CIRCUIT_DEFAULT_PORT); /* 5. legacy host/port keys: host maps to circuit_host, port is ignored */ parse_one_peer( "peer_id=legacy;circuit_host=127.0.0.1;host=127.0.0.9;port=9999;" "link_id=main;link_password=secret;enabled=yes", &peer); check_str("legacy host ignored", peer.circuit_host, "127.0.0.1"); check_uint("legacy port ignored", peer.port, 9999u); /* 6. empty section should yield defaults */ parse_one_peer("", &peer); check_str("empty peer_id", peer.peer_id, ""); check_int("empty enabled default", peer.enabled, 1); check_int("empty wire default", (int)peer.wire, (int)HYBBX_MAINS_PROXY_WIRE_CIRCUIT); check_int("empty duplex default", (int)peer.duplex, (int)HYBBX_MAINS_PROXY_DUPLEX_FULL); check_int("empty use_secondary default", peer.use_secondary, 1); /* 7. mesh active: stopped mesh reports inactive */ hybbx_mains_proxy_mesh_stop(NULL); check_int("mesh_active when stopped", hybbx_mains_proxy_mesh_active(), 0); /* 8. peer parse leaves legacy host intact when circuit_host is set */ parse_one_peer( "peer_id=explicit;circuit_host=127.0.0.1;host=127.0.0.9;" "link_id=main;link_password=secret;enabled=yes", &peer); check_str("circuit_host wins over host", peer.circuit_host, "127.0.0.1"); if (g_failures != 0) { fprintf(stderr, "%u failure(s)\n", g_failures); return 1; } puts("test_mains_proxy: ok"); return 0; } /* Test kept separate above; this file ends after main() in the original. */