Add Septentrio message-file configuration and reply handling#347
Add Septentrio message-file configuration and reply handling#347jclark wants to merge 25 commits into
Conversation
Switch the connection descriptor from COM1 to USB1 throughout to match the port satpulsetool actually connects over, and comment out the default.line eol/responsePattern so commands work best-effort until the "septentrio" analyzer exists. Replace the get-version lstInternalFile probe with getReceiverInterface + getReceiverCapabilities (compact ordinary command replies), and add a cmd-escape recovery tag (ten "S" characters) for a connection that has stopped accepting commands. Update plan/septentrio-msgfile.md to match the get-version change. Claude-Session: https://claude.ai/code/session_01Giuwab4jijWsXtiKimJDqr
Make port-specific tags carry the connection descriptor as a suffix instead of hardcoding USB1 behind a "stand-in" convention: output tags (NMEA/SBF/RTCM) become "-usb1", and the serial-port baud settings become "-com1" with the Cd switched to COM1. setCOMSettings/getCOMSettings reject a USB Cd -- baud applies only to physical COM ports -- so the old speed-*/get-uart tags failed on the default USB connection. Fix the reload tag. It used "exeResetReceiver, Hard, none", which reboots the receiver; reload's semantics are to load the boot configuration into the active configuration without a restart, so it now uses "exeCopyConfigFile, Boot, Current" (the inverse of save). Reword the reset tag description so it no longer borrows reload's "load NVM" wording. Rename nmea-ver-410 to nmea-ver-411: the setNMEAVersion command definition says v4x adds fields per NMEA 4.11 (the guide's overview text loosely calls it 4.10). Drop the now-incorrect nmea-ver-411 TODO. Verified on a mosaic-G5 (firmware 1.1.0): reload keeps the receiver up and replaces Current with Boot; get-uart-com1 (getCOMSettings, COM1) is accepted where the USB1 form was rejected; and the command/block syntax throughout was exercised while building the packet-log corpus. Claude-Session: https://claude.ai/code/session_01Giuwab4jijWsXtiKimJDqr
Frame a whole ASCII command reply as a single packet (`$R` through the terminating prompt) under one format and tag, replacing the earlier two-format echo-line/state-line sketch. Correlate replies with a shared fixed ack key rather than the echoed command text, since `$R!` and `$R?` do not echo the sent command; single-flight is enforced by the existing `ReadyToSend` gate. Define the packet format declaratively (header + body + first-match terminator) with the two load-bearing invariants stated explicitly, plus is/is-not tricky cases, instead of prescribing state-machine transitions. Fixes verified against the mosaic reference guide sec 3.1.3: no `lst` reply frames past its `---->` pseudo-prompt (single- and multi-block alike, not just multi-block); `factoryReset` ends in the normal prompt, not `STOP>`; and `$T*` event lines are named among the `$`-led message boundaries. Claude-Session: https://claude.ai/code/session_01Giuwab4jijWsXtiKimJDqr
Implement Tier 2 message-file reply handling for Septentrio receivers. The receiver answers each set/get/exe/lst command on its ASCII command line with a reply that begins with "$R", spans an echo line plus zero or more state lines, and ends with the command prompt. A new checksum-free ReplyPacketFormat (TagSepReply) in gps/internal/septentrio frames the whole reply, echo through prompt, as one packet; the terminating ">" is the command-done signal. A new "septentrio" responsePattern analyzer (gps/msgfile/sep.go) classifies replies on the "$R" type char: ":"/"!"/";" are acks, "?" is a nak carrying the reply's error text. Every Septentrio line message shares a single ackCorrelate key, so ReadyToSend serializes sends to match the receiver's single-flight rule; the state lines ride inside the ack packet (expectDataWithAck), surfaced as the readback. Wire-up: ResponsePatternSeptentrio in the enum and the JSON schema, the dispatch branch in LineMsg.analyzeRequest, sepAnalyzer registered under TagSepReply in NewCorrelator, and the reply format registered in gpsreg.reg.go. formatText now passes internal CR/LF through so a multi-line reply displays as its lines instead of hex. Claude-Session: https://claude.ai/code/session_01Giuwab4jijWsXtiKimJDqr
…rification Tested every non-destructive tag against a live mosaic-G5 (v1.1.0, USB1 /dev/ttyACM1) and added ACK/readback/observable-effect verification comments. All get-* queries, NMEA enable/disable pairs, NMEA version, elevation mask, constellation selection, PPS, fix rate, COM speed, survey/mode/fixed-pos, RTCM output, SBF daemon, and the G5-only PPP tags ACK with readbacks matching intent. Notes added where an observable differs from expectation (gnss-* verified via getSatelliteTracking, not GSV, which reports in-view sats regardless of tracking; fixed-pos-off leaves the Geodetic1 slot populated). The five destructive tags (save/factory-reset/hot-start/cold-start/reset) are marked not-hardware-tested since they reboot or persist to NVM. Claude-Session: https://claude.ai/code/session_01Giuwab4jijWsXtiKimJDqr
Third bullet of the Septentrio support section: satpulsetool can configure Septentrio receivers from a message file, with ASCII reply framing for success/failure reporting. Claude-Session: https://claude.ai/code/session_01Giuwab4jijWsXtiKimJDqr
"sep" read too much like "separator"/"separation". Rename the Septentrio reply-analyzer files and identifiers in gps/msgfile to a "sept" prefix (sept.go, sept_test.go, sept-test.toml, septAnalyzer, septCorrelate, septNakError, recvSeptReply, recvSEPTREvent). The reply Tag is now septentrio.TagReply with value "SEPTR", exported as gpsreg.TagSeptentrioReply. Update plan/septentrio-msgfile.md to match.
Align the reset/restart tags with the satpulsetool gps man page (the definitive source) and the Soft-vs-Hard distinction in the mosaic guide, where Soft restarts the firmware keeping the running config and Hard reboots and reloads the boot config from non-volatile memory.
reset now adds PVTData so it discards the last known position and current time as well as the satellite orbital data, matching --reset ("reloads the configuration from non-volatile memory ... and discards information about the last known position, current time, and satellite orbital data"). It previously erased only SatData, leaving the position/time seed in NVM.
cold-start becomes Soft, PVTData+SatData: a restart (not a reset) that preserves the running configuration while clearing all satellite data and the last position/time. It was previously identical to reset (Hard, SatData), which both reloaded the config and failed to clear PVTData.
warm-start stays unimplemented; its rationale is reworded to note that keeping the ephemeris while clearing the almanac (and everything else) is impossible because SatData erases ephemeris and almanac together.
reload and factory-reset already matched the man page and are unchanged.
Claude-Session: https://claude.ai/code/session_01Giuwab4jijWsXtiKimJDqr
There was a problem hiding this comment.
💡 Codex Review
Here are some automated review suggestions for this pull request.
Reviewed commit: 9eb72ccf51
ℹ️ About Codex in GitHub
Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you
- Open a pull request for review
- Mark a draft as ready
- Comment "@codex review".
If Codex has suggestions, it will comment; otherwise it will react with 👍.
Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".
Set the shared mosaic line default to the Septentrio response pattern now that the analyzer exists, so receiver replies are correlated as ACK/NAK responses instead of generic line data. Add the same default in mosaic-g5.toml because include defaults are applied per file before merge; without it, the G5-only PPP commands keep responsePattern = none.
…entrio-msgfile
The command-input-recovery escape (ten S characters) is answered with a bare prompt, which is deliberately not framed as a $R reply packet. Under the file's default responsePattern = "septentrio", cmd-escape expected an ack it never receives: it reported a false "no response received" and, because every Septentrio command shares one single-flight ack key, it also broke ack correlation for the command sent after it -- cmd-escape,get-version reported get-version as "no response" even though its readback arrived and printed. Override responsePattern = "none" on cmd-escape so it expects no reply. Verified on mosaic-G5: cmd-escape,get-version now reports get-version OK. Claude-Session: https://claude.ai/code/session_01Giuwab4jijWsXtiKimJDqr
Give each SBF block and NMEA sentence two enable tags: a self-contained -usb1 form that sets the port (USB1), rate (1 Hz) and message in one command, so it works on a factory-fresh stream; and a -cur form that adds only the message, riding whatever port and rate the stream already has (compose with the sbf-port-*/nmea-port-* and sbf-rate-*/nmea-rate-* setters). A single port-neutral -off disables the message. This replaces the earlier scheme where the block toggles set neither port nor rate and so produced no output until separate commands were sent -- the port and rate must be present for a single tag to yield output, because a Septentrio stream starts with Cd none and interval off. The SBF and NMEA output streams are separate pools that merely share the Stream1..Stream10 labels, so the port and rate setters exist for each independently. Cd, interval and the message list bind independently and live: setting one leaves the others in place, and changing the port or rate moves or regates an already-enabled message with no re-enable. Cover all 25 SBF blocks that satpulse decodes (gps/lib/sbfbin). Drop the sbf-daemon convenience group -- no other message file carries a binary daemon group -- and keep the standard nmea-daemon-usb1. Remove the misguided admin-login step from factory-reset: the tag sent "login, admin, admin" before factoryReset, but the placeholder credentials do not authenticate, so factory-reset is now just factoryReset. Verified on mosaic-G5 hardware: readbacks plus USB1/USB2 captures confirmed the self-contained tags, the -cur composition, the port and rate setters, and the nmea-daemon group.
Update the coverage section and tag descriptions to the shipped state: the SBF/NMEA output-tag scheme (self-contained -usb1, composable -cur, port-neutral -off, plus the port/rate setters and get-sbf/get-nmea), factory-reset without the login step, and the dropped sbf-daemon group. Correct the reply PacketFormat registration: it follows the NMEA and RTCM formats that CreatePacketFormats prepends, rather than being ordered ahead of NMEA as the plan originally described.
The Tier 2 message-file reply handling this plan designs is implemented and verified on mosaic-G5 hardware, so move it to plan/archive/ per plan/CLAUDE.md.
|
@codex review |
There was a problem hiding this comment.
💡 Codex Review
Here are some automated review suggestions for this pull request.
Reviewed commit: bef7593ae4
ℹ️ About Codex in GitHub
Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you
- Open a pull request for review
- Mark a draft as ready
- Comment "@codex review".
If Codex has suggestions, it will comment; otherwise it will react with 👍.
Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".
| case ':', '!', ';': | ||
| return responseAnalysis{kind: responseAck, ackCorrelate: septCorrelate} |
There was a problem hiding this comment.
Wait for the real prompt after lst replies
When the command is a Septentrio lst* command, the $R; line is followed by a ----> pseudo-prompt and then $--BLOCK ... output until the final real prompt, but treating ';' as a completed ACK here makes expectDataWithAck mark the request complete at the pseudo-prompt. In that scenario ReadyToSend can release the next command while the receiver is still emitting the listing, and the block output is also dropped instead of being correlated/displayed.
Useful? React with 👍 / 👎.
The mosaic.toml and mosaic-g5.toml headers still said hardware had not arrived and the commands were UNTESTED, contradicting the per-entry "Verified ... on mosaic-G5" notes throughout both files and the G5 now being connected. Replace them with an accurate status that points at the per-entry notes and keeps the genuine caveats (mosaic-X5 behavior inferred from the reference guides, not X5 hardware; reboot/reset commands not hardware-tested).
An lst* command's reply arrives as several units -- the "$R;" echo, then one or more "$--BLOCK" sections, each intermediate one ending with the "---->" pseudo-prompt and only the last ending with the real prompt. The reply scanner previously framed only the opener up to its "---->", so the block sections were never framed and the listing was lost -- only the first line of an lst reply was shown. Frame each unit as its own reply packet: the format now also syncs on "$--" so the "$--BLOCK" sections frame, and a "---->" closes a packet just as a real prompt does. The analyzer stitches the units back together -- the "$R;" opener reports the ack immediately (the command was accepted; a rejection is "$R?") while keeping the request open, each intermediate "$--BLOCK" is shown but not correlated, and the final "$--BLOCK" at the real prompt completes the command with no second ack line. Two new correlator response kinds, responseAckMore and responseDone, decouple reporting the ack from completing the request. Verified on a mosaic-G5: lstInternalFile, Identification returns a five-block XML identity dump; OK is reported at the opener, all five blocks display in order, and a command sent after it is held until the prompt then acked cleanly.
Add low-level configuration for Septentrio receivers using ASCII command line syntax. A checksum-free $R reply PacketFormat frames a whole reply -- the echo line, any state lines, and the terminating prompt -- as a single packet, and a new "septentrio" responsePattern analyzer classifies each reply as an ack or nak and correlates it to the command that was sent. The mosaic-G5 and shared mosaic message files are included, validated against real mosaic-G5 hardware.
Stacked on the sbfbin PR (base branch sbfbin), which provides the vendor packet-format registration it extends. Independent of the SBF-to-gpsprot PR.
Part of #340.
Design: https://github.com/jclark/satpulse/blob/septentrio-msgfile/plan/septentrio-msgfile.md