unisat

UniSat — Software Requirements Specification

Version: 1.2 (TRL-5 hardening baseline) Status: LIVE — amended with every feature commit. Scope: On-board software for the UniSat CubeSat OBC (STM32F446RE

Document conventions

1. Command & Telecommand (CMD)

ID Priority Statement Verification Implemented in Tested by
REQ-CMD-001 MUST Every uplink telecommand shall be authenticated with HMAC-SHA256 over the payload and replay counter. Test command_dispatcher.c test_command_dispatcher.c::test_valid_counter_and_tag_dispatches
REQ-CMD-002 MUST Unauthenticated or tampered telecommands shall be dropped silently with no downlink response. Test command_dispatcher.c test_tampered_tag_rejected
REQ-CMD-003 MUST The dispatcher shall reject replayed telecommands via a 32-bit counter + 64-bit sliding window. Test command_dispatcher.c test_duplicate_counter_is_replay, test_counter_older_than_window_dropped
REQ-CMD-004 MUST Counter value 0 shall be reserved and rejected. Test command_dispatcher.c test_counter_zero_rejected
REQ-CMD-005 MUST HMAC keys shall be stored in a CRC-protected A/B flash layout with strictly monotonic generation numbers. Test key_store.c test_key_store.c
REQ-CMD-006 SHOULD Key rotation shall require new_gen > current active generation. Test key_store.c test_stale_generation_rejected
REQ-CMD-007 MUST A torn write during rotation shall leave the previously-active key intact at the next boot. Test key_store.c test_corrupt_crc_falls_back_to_other_slot
REQ-CMD-008 MUST On boot with no valid key in either slot the dispatcher shall refuse every frame (fail-closed) and FDIR shall report FAULT_KEYSTORE_EMPTY. Test command_dispatcher.c, fdir.c test_no_key_rejects_everything

2. Communication (COMM / AX.25)

ID Priority Statement Verification Implemented in Tested by
REQ-AX25-001 MUST The link layer shall encode AX.25 v2.2 UI frames with bit-stuffing, CRC-16/X.25 FCS, and 0x7E flag framing. Test ax25.c test_ax25_frame
REQ-AX25-006 MUST FCS computation shall match ITU-T X.25 fcs(b"123456789") == 0x906E on both C and Python sides. Test ax25.c, ground-station/utils/ax25.py test_ax25_fcs
REQ-AX25-012 MUST The decoder shall hard-reject any frame exceeding 400 bytes post-unstuffing. Test ax25_decoder.c test_ax25_decoder::test_oversize_rejected
REQ-AX25-014 MUST The decoder shall never crash or leak state on arbitrary byte streams. Test (fuzz) ax25_decoder.c fuzz harness, 10 000 cases
REQ-AX25-015 MUST C and Python decoders shall produce byte-identical output against 28 shared golden vectors. Test both test_ax25_golden + ground-station/tests/test_ax25.py
REQ-AX25-019 MUST Decoder shall run in a dedicated FreeRTOS task, not in interrupt context. Inspection comm.c design review
REQ-AX25-024 MUST Error recovery shall be O(1) per byte (reset to HUNT state, drop offending byte). Analysis ax25_decoder.c design review

3. Telemetry (TLM)

ID Priority Statement Verification Implemented in Tested by
REQ-TLM-001 MUST Housekeeping beacons shall be emitted every 30 s on the UHF channel. Inspection main.c::CommTask, BEACON_PERIOD_MS operator verification
REQ-TLM-002 MUST Beacon packet shall be exactly 48 bytes (raw layout spec §7.2). Test telemetry.c::Telemetry_PackBeacon test_beacon_returns_48_bytes
REQ-TLM-003 MUST Beacon byte 14-15 (Tboard) shall carry the board-temperature in signed 0.1 °C units. Test board_temp.c, telemetry.c:154 test_board_temp.c
REQ-TLM-004 MUST Tboard value 0 shall be used only while the TMP117 has not yet produced a valid reading. Test board_temp.c test_uninitialised_returns_zero_and_invalid
REQ-TLM-005 SHOULD Out-of-range sensor readings (< −60 °C or > +130 °C) shall be rejected and FDIR shall report FAULT_SENSOR_OUT_OF_RANGE. Test board_temp.c, fdir.c test_out_of_range_rejected
REQ-TLM-010 MUST Every housekeeping downlink shall be wrapped in a CCSDS Space Packet with APID 0x07D (beacon) or 0x010-0x014 (per-subsystem). Inspection ccsds.c, telemetry.c design review

4. Attitude Determination & Control (ADCS)

ID Priority Statement Verification Implemented in Tested by
REQ-ADCS-001 MUST B-dot controller shall reduce angular rate to below 0.5 °/s within 90 min of deployment. Analysis adcs.c, bdot.c test_adcs_algorithms + on-orbit TBD
REQ-ADCS-002 MUST Quaternion arithmetic shall preserve unit norm to within 1e-5 after 10 000 iterations. Test quaternion.c test_adcs_algorithms::test_quat_norm_preserved
REQ-ADCS-003 SHOULD Magnetometer saturation shall not crash the attitude filter (clamp + propagate last known attitude). Test adcs.c test_adcs_algorithms::test_saturation_handled
REQ-ADCS-004 MAY Pointing-mode accuracy target: ≤ 5° (sun), ≤ 2° (nadir), ≤ 10° (target). Analysis sun_pointing.c, target_pointing.c design review

5. Electrical Power (EPS)

ID Priority Statement Verification Implemented in Tested by
REQ-EPS-001 MUST MPPT controller shall converge to the solar-panel maximum-power point within 10 iterations across ±20 % irradiance steps. Test mppt.c test_eps::test_mppt_convergence
REQ-EPS-002 MUST Battery manager shall trigger FAULT_BATTERY_UNDERVOLT at ≤ 3.2 V pack voltage. Test battery_manager.c, fdir.c test_eps::test_undervolt_threshold
REQ-EPS-003 MUST Bus-voltage brown-out shall force a safe-mode entry. Analysis eps.c, fdir.c (FAULT_BATTERY_UNDERVOLT → SAFE_MODE) test_fdir::test_aggregate_stats
REQ-EPS-004 SHOULD Load-shedding priority: payload → camera → ADCS actuators → comm TX → OBC. Inspection power_distribution.c design review

6. Fault Detection, Isolation, Recovery (FDIR)

ID Priority Statement Verification Implemented in Tested by
REQ-FDIR-001 MUST The FDIR module shall maintain per-fault occurrence counters and aggregate statistics. Test fdir.c test_fdir::test_empty_state_after_init, test_aggregate_stats
REQ-FDIR-002 MUST Escalation shall trigger once the recent-window counter reaches the per-fault threshold. Test fdir.c test_escalation_after_threshold
REQ-FDIR-003 MUST Per-fault state shall be isolated — reporting fault A shall not affect fault B’s counters. Test fdir.c test_cross_fault_isolation
REQ-FDIR-004 MUST The recent-window shall slide forward — stale events shall NOT accumulate into escalation. Test fdir.c test_recent_window_slides
REQ-FDIR-005 MUST A missed task-feed shall raise FAULT_WATCHDOG_TASK_MISS. Test (integration) watchdog.cfdir.c manual trace
REQ-FDIR-006 SHOULD FDIR recovery actions shall follow the severity ladder LOG_ONLY → RETRY → RESET_BUS → DISABLE_SUBSYS → SAFE_MODE → REBOOT. Inspection fdir.c g_table, docs/reliability/fdir.md design review

7. Safe Mode (SAFE)

ID Priority Statement Verification Implemented in Tested by
REQ-SAFE-001 MUST Safe mode shall be entered on any of: comm loss > 24 h, battery under-volt, repeated FDIR escalations. Test modules/safe_mode.py, fdir.c test_safe_mode.py, test_mission_e2e.py
REQ-SAFE-002 MUST In safe mode only telemetry + comm + health tasks shall remain active. Inspection modules/safe_mode.py, profile disabled_modules test_required_modules_resolve_for_cubesat_leo
REQ-SAFE-003 MUST Safe mode entry shall be idempotent — a second entry call while already active shall not overwrite the original reason. Test modules/safe_mode.py test_safe_mode.py::test_double_enter_does_not_overwrite
REQ-SAFE-004 SHOULD Safe mode exit shall be explicit (ground command or automatic recovery check) — no time-based auto-exit. Inspection modules/safe_mode.py design review

8. Ground Segment (GS)

ID Priority Statement Verification Implemented in Tested by
REQ-GS-001 MUST The Python AX.25 library shall produce output byte-identical to the C implementation against 28 shared golden vectors. Test ground-station/utils/ax25.py test_ax25.py::test_golden_vectors
REQ-GS-002 MUST The Streamlit dashboard shall decode every beacon field defined in docs/design/communication_protocol.md §7.2. Inspection ground-station/pages/* manual demo
REQ-GS-003 SHOULD The ground-side HMAC helper shall mirror RFC 4231 test vectors on the exact same bytes as the firmware library. Test ground-station/utils/hmac_auth.py test_hmac.py

9. Build & Quality (BLD)

ID Priority Statement Verification Implemented in Tested by
REQ-BLD-001 MUST The firmware shall cross-compile for STM32F446RE with arm-none-eabi-gcc out of the box (LD, startup, clock config in the repo). Demo firmware/stm32/Target/ scripts/verify.sh target step
REQ-BLD-002 MUST Flash + RAM usage shall stay below 90 % of STM32F446RE capacity. Analysis scripts/verify.sh 90 % budget gate
REQ-BLD-003 MUST Host ctest + pytest shall pass 100 % on every push. Test CI make ci
REQ-BLD-004 SHOULD cppcheck --enable=warning,portability shall report zero issues. Test scripts/run_cppcheck.sh make cppcheck
REQ-BLD-005 SHOULD Host coverage (lcov) shall be ≥ 80 % lines / ≥ 85 % functions. Test firmware/CMakeLists.txt coverage target make coverage
REQ-BLD-006 SHOULD ASAN + UBSAN shall run clean over the full ctest suite. Test -DSANITIZERS=ON make sanitizers

10. Out-of-scope

Explicitly not covered by this SRS:

See docs/project/GAPS_AND_ROADMAP.md §”Out of scope” for the full list.


Document owner: root3315. Review cadence: updated with every feature commit on feat/trl5-hardening. Traceability regeneration: scripts/gen_trace_matrix.py (Phase 6 follow-up, currently manual).