Add Label B0 AFN (FANS 1/A Logon) decoder plugin#412
Add Label B0 AFN (FANS 1/A Logon) decoder plugin#412thepacket wants to merge 1 commit intoairframesio:masterfrom
Conversation
New plugin registered in official.ts and MessageDecoder.ts.
|
Warning Rate limit exceeded
Your organization is not enrolled in usage-based pricing. Contact your admin to enable usage-based pricing to continue reviews beyond the rate limit, or try again in 55 minutes and 23 seconds. ⌛ How to resolve this issue?After the wait time has elapsed, a review can be triggered using the We recommend that you space out your commits to avoid hitting the rate limit. 🚦 How do rate limits work?CodeRabbit enforces hourly rate limits for each developer per organization. Our paid plans have higher rate limits than the trial, open-source and free plans. In all cases, we re-allow further reviews after a brief timeout. Please see our FAQ for further information. ℹ️ Review info⚙️ Run configurationConfiguration used: Repository UI Review profile: CHILL Plan: Pro Run ID: 📒 Files selected for processing (3)
✨ Finishing Touches🧪 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 |
kevinelliott
left a comment
There was a problem hiding this comment.
Summary
Adds Label_B0_AFN for the FANS 1/A AFN-Contact (FN_CON / CPDLC logon request) message. Parses the /<ATSU>.AFN/FMH<callsign>,.<tail>,<icao24>,<HHMMSS>/<cap-block>... envelope and surfaces ATSU, callsign, tail, ICAO 24-bit address, UTC time, capability blocks, and trailing CRC. Registered in both lib/MessageDecoder.ts and lib/plugins/official.ts. Build passes per the description.
Verdict
Needs changes before merge. Solid envelope decomposition and capability-block parsing, but the formatted output has duplicated rows from antipatterns flagged in the project conventions, and there are no tests.
Must Fix
- No tests. Please add
Label_B0_AFN.test.tscovering: (a) the wire-format example from the PR description, (b) a header without ICAO24 or time (the regex's optional groups), (c) multiple capability blocks, (d) no capability blocks. Uselib/plugins/Label_15.test.tsas a template. - Duplicate Time row (project antipattern). Lines 108-112 call
ResultFormatter.timestamp(...)which already pushes a{type:'time', code:'TIMESTAMP', label:'Message Timestamp'}item. Then lines 211-218 explicitly push another{type:'time', code:'TIME', label:'Logon Time (UTC)'}row using the same HHMMSS string. Two time rows for the same value. Pick one — either keepResultFormatter.timestamp(preferred — uses canonicalmessage_timestampraw key and consistent formatting) and drop the explicit push, or drop the formatter call and only push the explicit row. - Duplicate Callsign row (project antipattern). Line 98 calls
ResultFormatter.flightNumber(decodeResult, callsign)which adds aFlight Numberitem. Then lines 195-201 push a separate{code:'CALLSIGN', label:'Callsign'}row with the same value. Two rows, same string. UseResultFormatter.callsign(...)(which exists atlib/utils/result_formatter.tsline 93-101) instead offlightNumber(...), and drop the manual push — or vice versa. - HHMMSS validation missing. Line 107: any 6-digit string passes through to
DateTimeUtils.convertHHMMSSToTod. A malformed999999will produce a nonsensical time-of-day value silently. Validatehh<24, mm<60, ss<60before calling the converter (see PR #413 line 71-74 for an example of the same check).
Should Fix
- Header regex tail group is too permissive. Line 83:
(?<tail>[A-Z0-9-]{3,10})?. With no anchor, this can absorb the next-field separator if a comma is missing. The wire format always uses,.to delimit callsign and tail; consider requiring the leading.and matching[A-Z0-9-]{3,10}only after it, e.g.\.(?<tail>[A-Z0-9-]{3,10}). As written the optional-comma + optional-dot pattern (,?\.?) accepts inputs the spec wouldn't. atsu_addressraw key vs. existingground_address.RawFields.ground_addressalready exists in the canonical interface (lib/DecoderPluginInterface.tsline 107). Using a new keyatsu_addressfor the same concept fragments downstream consumers. Suggest usingground_addressand adding a separate display label "ATSU Address" if you want the human-readable form to differ.capability_blocksraw value is the structured array. That's fine for downstream code, but the formatted output flattens each block into a one-row string"/FCPP → token1, token2". Worth considering whether the block's individual flags (e.g. capability bits) could be parsed into named fields rather than left as opaque tokens — even partial enrichment would make this more useful.- Non-standard
raw.icao_24bit. Other parts of the codebase don't have this key. Add toRawFieldsif it's going to land, or reuse a canonical alternative. - Direction is hardcoded. "Downlink (aircraft → ground)" — this is correct for an FN_CON, but if/when B0 ever carries a logon-acknowledge from the ground side, the hardcoding will be wrong. Comment or guard.
Nits
- The descriptor says "AFN — ATS Facilities Notification (FANS 1/A CPDLC Logon)" but the formatted message-type row says "AFN Contact (FN_CON) — FANS 1/A CPDLC Logon Request" and the application row says "AFN (ATS Facilities Notification)". Three slightly different descriptions of the same thing in three places — consider unifying.
parsedCaps.forEach((cap, i) => { const idx = i + 1; … type: \capability_block_${idx}`, code: `CAP${idx}` … })— emitting per-block typed rows means downstream type matching becomes a moving target. Suggest a single row with all blocks, or a stable row type likecapability_block` and an index column inside the value.- "Application" row hardcodes "AFN (ATS Facilities Notification)" but the regex already requires
.AFN/literally — the row carries no information beyond what the descriptor already states. Consider dropping it.
Tests
Missing entirely. Suggested fixtures, beyond the four scenarios under Must Fix:
- Header with
,but no.. - Last capability block where the final token is exactly 4 hex chars (so
flagPartis empty after CRC strip — the code currently leaves an empty string in the tokens array). - Last capability block where the final token is < 5 chars (the
^[A-F0-9]{5,}$guard skips CRC stripping — verify behavior).
Notes
- Registration: confirmed in both
lib/MessageDecoder.ts(line 81) andlib/plugins/official.ts(line 67) at the PR HEAD. - FANS 1/A consistency: this plugin shares CRC-stripping and tail-detection patterns with PRs #409 and #411. Please coordinate raw-key naming (
crcvscrc_hex,tailvsair_address,ground_addressvsatsu_address) across the trio before merging — landing them with three different conventions for the same fields will be painful to undo. See review on PR #411 for the suggested shared-helper approach.
Thanks @thepacket!
Adds a decoder for FANS 1/A AFN-Contact messages carried under label B0 (parallel to label A0, different operators / sub-networks).
Wire format
Surfaces ATSU, application, callsign, tail, ICAO 24-bit, UTC time, capability blocks (FCPP variant included in the descriptor alternation), and CRC.
npm run buildpasses.