220 lines
6.9 KiB
Markdown
220 lines
6.9 KiB
Markdown
TASK_ID = RF001A_OTA_TX_003
|
|
TASK_TITLE = Transmit one coordinated RF-001A QPSK burst
|
|
SOURCE_BRANCH = video-development
|
|
EXPECTED_HEAD = bc55d0516dc1ee36cefa1ff096e7d86f60645303
|
|
REQUIRES_APPROVAL = YES
|
|
HARDWARE_ACCESS = YES
|
|
RF_RX = NO
|
|
RF_TX = YES
|
|
ALLOW_COMMIT = NO
|
|
ALLOW_PUSH = NO
|
|
RISK_LEVEL = RED
|
|
|
|
This file is the authoritative current task for the MAIN PC TX node.
|
|
Read TX_NODE_STATE.md first. If chat history, this file, the shared RF-001A spec or current Git HEAD conflicts, stop and report the conflict.
|
|
|
|
# Current TX task
|
|
|
|
TASK =
|
|
TRANSMIT ONE COORDINATED RF-001A QPSK BURST
|
|
|
|
This is a new RED task. Publication of this file is not permission to transmit. It does not inherit any approval from RF001A_OTA_TX_001, RF001A_OTA_TX_002, the RX task, a previous watcher prompt or a previous RF run.
|
|
|
|
## 1. Coordination gate
|
|
|
|
Start the local model-free watcher before the RX task begins:
|
|
|
|
tools\start_tx_watcher.cmd
|
|
|
|
The watcher polls origin/rx-node every 5 seconds and accepts only a strict result for:
|
|
|
|
RX TASK_ID = RF001A_OTA_CAPTURE_003
|
|
STATE = RX_READY_FOR_TX
|
|
RX_READY_FOR_TX = YES
|
|
PROCESS_ALIVE = YES
|
|
FILE_GROWING = YES
|
|
COMMON_CLOCK_VERIFIED = YES
|
|
RF_TX = 0
|
|
|
|
The watcher records RF_HANDOFF_CHANNEL_TEST_001 READY and COMPLETE states without prompting for RED approval and never treats them as production readiness. A production READY publication must be no more than 30 seconds old. Its planned capture window must be 120 seconds. At least 10 seconds must remain. COMMON_CLOCK_VERIFIED must be YES, source_head must equal the expected video-development HEAD, and the result commit must be the current valid origin/rx-node HEAD.
|
|
|
|
When a valid new READY result appears, the watcher prints:
|
|
|
|
RX IS READY
|
|
|
|
TASK ID =
|
|
CAPTURE STARTED =
|
|
CAPTURE END EXPECTED =
|
|
|
|
TX TASK =
|
|
RF001A_OTA_TX_003
|
|
|
|
RF TX REQUIRES RED APPROVAL
|
|
|
|
Enter:
|
|
AUTHORIZE RF TX
|
|
|
|
Without the exact phrase AUTHORIZE RF TX, do not transmit.
|
|
|
|
After the phrase, the watcher fetches rx-node again and repeats the result commit, digest, task ID, source HEAD, READY, freshness, common-clock and capture-window checks. If the result changed or less than 10 seconds remain, it refuses authorization and requires a new RX capture.
|
|
|
|
The watcher never opens HackRF hardware. On success it writes one local authorization record under:
|
|
|
|
.local\tx_authorizations\
|
|
|
|
The record has rf_tx_started = false and rf_tx = 0. It is the handoff to the separately controlled TX executor. It is not evidence that transmission occurred.
|
|
|
|
## 2. Fixed RF-001A parameters
|
|
|
|
center frequency = 1400000000 Hz
|
|
sample rate = 8000000 samples/s
|
|
modulation = QPSK
|
|
symbol rate = 500000 symbols/s
|
|
inner FEC = 2/3
|
|
payload = 256 bytes
|
|
packet count = 100
|
|
inter-packet gap = 5 ms
|
|
digital carrier offset = +125000 Hz
|
|
TX VGA = 20 dB
|
|
RF amp = OFF
|
|
antenna bias = OFF
|
|
common 10 MHz reference = VERIFIED
|
|
distance = approximately 2 m
|
|
LOS = YES
|
|
video = OFF
|
|
|
|
The waveform is one finite burst. Never add repeat mode.
|
|
|
|
## 3. Read-only preflight
|
|
|
|
Before the watcher can request RED approval:
|
|
|
|
1. Run git pull --ff-only origin video-development.
|
|
2. Require branch video-development.
|
|
3. Require git status --short --untracked-files=no to produce no output.
|
|
4. Require local HEAD to equal origin/video-development and EXPECTED_HEAD to be its ancestor.
|
|
5. Run hackrf_info and preserve complete stdout.
|
|
6. Require TX serial 000000000000000097c063dc323b97d3.
|
|
7. Require the recorded MASTER CLKOUT command result = PASS.
|
|
8. Require confirmation that both antennas are connected, the nodes are approximately 2 m apart, and LOS is clear.
|
|
9. Verify the prepared waveform without radio access:
|
|
|
|
python -B -X utf8 tools/rf001a_prepare.py --verify-dir data/raw/rf001/rf001a_common_clock_001
|
|
|
|
10. Verify the actual cs8 bytes through the existing offline receiver:
|
|
|
|
python -B -X utf8 tools/qpsk_rf_rx.py --iq-file data/raw/rf001/rf001a_common_clock_001/tx_waveform.cs8 --iq-format cs8 --truth-metadata configs/rf/rf001a_truth_metadata.json --report <new-path-outside-git>\rf001a_tx_offline_verify.json
|
|
|
|
Require:
|
|
|
|
canonical waveform = PASS
|
|
hardware-format cs8 = PASS
|
|
offline hardware-format roundtrip = 100/100 exact
|
|
TX waveform path = data/raw/rf001/rf001a_common_clock_001/tx_waveform.cs8
|
|
TX waveform size = 17667656 bytes
|
|
TX waveform SHA256 = 75f3fa39bfa4ee419f0676c54e4b9c486d7ff64bd0fe2fc06343b20c9d117ecd
|
|
sample count = 8833828 complex samples
|
|
expected duration = 1.1042285 s
|
|
|
|
If any value differs, do not transmit.
|
|
|
|
## 4. Final check before opening TX hardware
|
|
|
|
The controlled TX executor must read the authorization record immediately before TX and require:
|
|
|
|
- task_id = RF001A_OTA_TX_003;
|
|
- authorization = AUTHORIZE RF TX;
|
|
- rx_task_id = RF001A_OTA_CAPTURE_003;
|
|
- dry_run = false;
|
|
- action = MANUAL_EXECUTOR_GATE_OPEN;
|
|
- rf_tx_started = false;
|
|
- rf_tx = 0;
|
|
- the authorization references the latest fetched rx-node result commit and digest;
|
|
- current time is still inside the READY capture window with at least 10 seconds remaining.
|
|
|
|
Fetch origin/rx-node once more and compare its current result digest and commit with the authorization record. Re-run the READY and time checks. If anything differs, if the result is stale, or if fewer than 10 seconds remain, do not transmit and require a new RX capture and a new exact RED approval.
|
|
|
|
## 5. One authorized TX execution
|
|
|
|
Only after every preceding condition passes may the executor create a new unique evidence directory outside Git and run exactly one finite command:
|
|
|
|
hackrf_transfer.exe
|
|
-d 000000000000000097c063dc323b97d3
|
|
-t data/raw/rf001/rf001a_common_clock_001/tx_waveform.cs8
|
|
-f 1400000000
|
|
-s 8000000
|
|
-n 8833828
|
|
-x 20
|
|
-a 0
|
|
-p 0
|
|
-B
|
|
|
|
Run it once, synchronously, and preserve:
|
|
|
|
- exact process PID;
|
|
- start and end UTC timestamps;
|
|
- exact exit code;
|
|
- complete stdout and stderr;
|
|
- every TX underrun line;
|
|
- every USB error;
|
|
- waveform path, size and SHA256;
|
|
- command parameters.
|
|
|
|
Set RF TX STOPPED = YES only after the finite process exits. Never retry automatically. Never start a second burst.
|
|
|
|
## 6. Final TX report
|
|
|
|
TASK_ID =
|
|
RF001A_OTA_TX_003
|
|
|
|
RED AUTHORIZATION =
|
|
AUTHORIZE RF TX / MISSING
|
|
|
|
RX READY FOR TX =
|
|
YES / NO
|
|
|
|
RX RESULT HEAD =
|
|
|
|
RX RESULT DIGEST =
|
|
|
|
TX SERIAL =
|
|
|
|
TX WAVEFORM SHA256 =
|
|
|
|
TX START TIME =
|
|
|
|
TX END TIME =
|
|
|
|
TX EXIT CODE =
|
|
|
|
TX UNDERRUNS =
|
|
|
|
USB ERRORS =
|
|
|
|
RF TX STOPPED =
|
|
YES / NO
|
|
|
|
BURSTS TRANSMITTED =
|
|
0 / 1
|
|
|
|
RF TX =
|
|
0
|
|
|
|
At report time, RF TX = 0 means no transmission process remains active.
|
|
|
|
## 7. Prohibited actions
|
|
|
|
Do not:
|
|
|
|
- transmit without the fresh READY state and exact RED phrase;
|
|
- reuse an earlier authorization record;
|
|
- use repeat mode;
|
|
- transmit a second burst;
|
|
- retry automatically;
|
|
- change frequency, gains, clock configuration or waveform;
|
|
- update firmware or CPLD;
|
|
- use Zadig or change USB drivers;
|
|
- commit or push from this task.
|
|
|
|
STOP after the single finite burst or any failed gate.
|