Iridium: IMS pager messages, voice/IP/sync tagging#50
Conversation
Gap series 3/6 (vs iridium-toolkit). The toolkit's headline trick — plain-text pager messages — now decodes natively: MS frames (32-bit messaging header, 2-way interleave, BCH poly 1897) parse through the ported IridiumMSMessage chain (BSD, attributed): header block with super-frame counters and group, acquisition-group extras, all-ones trailers, odd-bit stream, LSB-first RIC, format 5 ASCII (block checksum, multi-part counters, ETX) and format 3 BCD. Multi-part pages reassemble by RIC into msg-complete frames; the console prints 'IRIDIUM msg ric=1234567 | CALL OPS ...'. Oracle-validated: a synthetic page built by our TX helpers parses field-identically in bitsparser.py (IridiumMessagingAscii, ric/fmt/seq/text), vendored as a CI vector alongside a bit-level e2e test and unit roundtrips. Duplex traffic classes tag by LCW frame type (toolkit mapping): voice (AMBE candidate payload extracted as hex — the codec is proprietary), ip-data, sync. ITL deferred: the toolkit's itl.py is orbital tooling, not a frame parser. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
📝 WalkthroughWalkthroughThis PR extends the Iridium decoder with IMS pager messaging support, adding frame parsing and multi-part message reassembly to both single-channel and wideband decoders. It includes LCW duplex traffic class mapping for voice/IP-data/sync frames, console output formatting for RIC and message text, comprehensive tests, and updated documentation. ChangesIMS Pager Messaging Decoder
Estimated code review effort🎯 4 (Complex) | ⏱️ ~60 minutes Possibly related PRs
Poem
🚥 Pre-merge checks | ✅ 5✅ Passed checks (5 passed)
✏️ Tip: You can configure your own custom pre-merge checks in the settings. ✨ Finishing Touches📝 Generate docstrings
🧪 Generate unit tests (beta)
Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out. Comment |
There was a problem hiding this comment.
💡 Codex Review
Here are some automated review suggestions for this pull request.
Reviewed commit: 8b9d79bbd6
ℹ️ 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".
| if *ctr_max == 0 { | ||
| return Some(text.clone()); // single-part page |
There was a problem hiding this comment.
Avoid duplicating single-part IMS pages
For any single-part ASCII page (ctr_max == 0), this returns the text as if a reassembly just completed; handle_bits then emits a synthetic msg-complete frame and still pushes the original msg frame, so normal one-frame pager messages show up twice in downstream outputs. This should only complete multipart pages, or the caller should suppress the raw frame when creating a completion frame.
Useful? React with 👍 / 👎.
| let entry = self | ||
| .pending | ||
| .entry(body.ric) | ||
| .or_insert_with(|| (vec![None; *ctr_max as usize + 1], time)); |
There was a problem hiding this comment.
Include sequence in the multipart page key
When two multipart ASCII pages for the same RIC overlap within the timeout, this single body.ric key lets parts from different seq values overwrite each other and can emit a corrupted concatenation, e.g. part 0 of message B plus part 1 of message A. Since MsBody already carries seq, the pending map needs to distinguish at least (ric, seq) for multipart reassembly.
Useful? React with 👍 / 👎.
There was a problem hiding this comment.
🧹 Nitpick comments (1)
crates/xng-mode-iridium/src/lib.rs (1)
279-284: 💤 Low valuePartial byte at end of payload may have incorrect interpretation.
chunks(8)will yield a partial chunk ifpayload.len() % 8 != 0. The fold will left-shift those fewer bits, producing a value as if the missing bits were zeros on the right. This may misrepresent the actual bit pattern for the last byte.Consider using
chunks_exact(8)if trailing bits should be excluded, or document that the last hex byte may be partial.🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the rest with a brief reason, keep changes minimal, and validate. In `@crates/xng-mode-iridium/src/lib.rs` around lines 279 - 284, The current payload -> payload_hex logic uses payload.chunks(8) which yields a partial final chunk and the fold treats missing bits as zeros; change the code to use payload.chunks_exact(8) and handle the remainder explicitly (using chunks_exact(8).remainder()) so you either exclude the trailing bits or compute the final byte correctly (e.g., by computing the folded value for the remainder with the intended padding/bit-alignment), or if you intend to keep the current semantics, add a comment documenting that the last hex byte may be partial; update the code around payload.chunks(8) and payload_hex accordingly.
🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.
Nitpick comments:
In `@crates/xng-mode-iridium/src/lib.rs`:
- Around line 279-284: The current payload -> payload_hex logic uses
payload.chunks(8) which yields a partial final chunk and the fold treats missing
bits as zeros; change the code to use payload.chunks_exact(8) and handle the
remainder explicitly (using chunks_exact(8).remainder()) so you either exclude
the trailing bits or compute the final byte correctly (e.g., by computing the
folded value for the remainder with the intended padding/bit-alignment), or if
you intend to keep the current semantics, add a comment documenting that the
last hex byte may be partial; update the code around payload.chunks(8) and
payload_hex accordingly.
ℹ️ Review info
⚙️ Run configuration
Configuration used: defaults
Review profile: CHILL
Plan: Pro
Run ID: aad9a8e6-e894-4e0d-91a4-1d96b0c862de
📒 Files selected for processing (7)
README.mdcrates/xng-mode-iridium/PROVENANCE.mdcrates/xng-mode-iridium/examples/genframe.rscrates/xng-mode-iridium/src/lib.rscrates/xng-mode-iridium/src/ms.rscrates/xng-mode-iridium/tests/e2e.rssrc/outputs/console.rs
Gap series 3/6 (vs iridium-toolkit).
msg-completeframes. Console:IRIDIUM msg ric=1234567 | CALL OPS +14155550100.IridiumMessagingAscii ... ric:1234567 fmt:05 seq:07 TXT: CALL OPS +14155550100), vendored as a CI vector;genframe --imsregenerates it for future cross-checks.voice(AMBE candidate bytes extracted as hex — codec proprietary, same stance as the toolkit),ip-data,sync.🤖 Generated with Claude Code
Summary by CodeRabbit
New Features
Documentation
Tests