feat: detect firmware vendor transitions within a BBL file#41
Conversation
When a BBL file contains sessions from multiple firmware vendors (e.g. Betaflight sessions left on flash before reflashing to EmuFlight), bbl_parser now detects the transition and: - Prints a WARNING listing session ranges per vendor with the suggestion to erase flash before reflashing - Corrects the output filename prefix for sessions whose firmware vendor does not match the BBL filename prefix (e.g. EMUF_* file + Betaflight session → output named BTFL_*), preventing EMUF_BTFL_* or BTFL_BTFL_* duplicate prefixes New public API in export module: - `firmware_prefix_for_revision(revision)` — maps a firmware revision string to its canonical filename prefix (EMUF_, BTFL_, INAV_) - `corrected_session_base_name(bbl_path, firmware_revision)` — returns a corrected base name when the session vendor differs from the BBL filename prefix, or None when they match All export functions (`export_to_csv`, `export_to_gpx`, `export_to_event`, `compute_export_paths`) accept an optional `base_name_override` parameter. Existing callers pass `None` to preserve prior behaviour. Known firmware prefixes are defined in one place (`KNOWN_FIRMWARE_PREFIXES`) and extended by adding a single `(&str, &str)` entry. Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
|
Important Review skippedAuto incremental reviews are disabled on this repository. Please check the settings in the CodeRabbit UI or the ⚙️ Run configurationConfiguration used: Organization UI Review profile: CHILL Plan: Pro Run ID: You can disable this status message by setting the Use the checkbox below for a quick retry:
📝 WalkthroughWalkthroughThis PR adds firmware vendor detection and session-aware base-name correction to export paths. A new base_name_override: Option<&str> parameter extends the export API; the CLI tracks firmware revisions per session and computes corrected base names when they differ from the BBL filename prefix, then passes these overrides through to all export functions. Firmware vendor transitions within a file trigger a post-processing warning. ChangesFirmware-Vendor Export Path Correction
Estimated code review effort🎯 3 (Moderate) | ⏱️ ~25 minutes Possibly related PRs
🚥 Pre-merge checks | ✅ 5✅ Passed checks (5 passed)
✏️ Tip: You can configure your own custom pre-merge checks in the settings. ✨ 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 |
Register Quicksilver and Kiss FC in the KNOWN_FIRMWARE_PREFIXES table so their sessions are correctly identified and prefixed when detected in mixed-firmware BBL files. Keywords are best-effort guesses based on firmware names; update if actual revision strings differ. Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
There was a problem hiding this comment.
Caution
Some comments are outside the diff and can’t be posted inline due to platform limitations.
⚠️ Outside diff range comments (1)
src/export.rs (1)
145-176:⚠️ Potential issue | 🟠 Major | ⚡ Quick winValidate
base_name_overridebefore path construction (path traversal/write-outside-output-dir risk).Line 157 and Line 246 trust
base_name_overridedirectly in filenames. A caller can pass absolute paths or../segments and escape the intended output directory.🔧 Suggested hardening
+use std::path::Component; + +fn sanitize_base_name_override(base_name_override: Option<&str>) -> Option<&str> { + let raw = base_name_override?; + let p = Path::new(raw); + if p.is_absolute() { + return None; + } + if p.components().any(|c| { + matches!( + c, + Component::ParentDir | Component::RootDir | Component::Prefix(_) + ) + }) { + return None; + } + p.file_name().and_then(|s| s.to_str()) +} + pub fn compute_export_paths( @@ - let base_name = base_name_override.unwrap_or_else(|| extract_base_name(input_path)); + let base_name = sanitize_base_name_override(base_name_override) + .unwrap_or_else(|| extract_base_name(input_path)); @@ pub fn export_to_csv( @@ - let base_name = base_name_override.unwrap_or_else(|| extract_base_name(input_path)); + let base_name = sanitize_base_name_override(base_name_override) + .unwrap_or_else(|| extract_base_name(input_path));Also applies to: 240-271
🤖 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 `@src/export.rs` around lines 145 - 176, compute_export_paths currently trusts base_name_override directly which allows absolute paths or path traversal; validate and sanitize base_name_override before constructing filenames: when base_name_override is Some, convert it to a Path and extract only the final file-stem/file-name component (e.g. via Path::new(base_name_override).file_name() or file_stem) and reject or fallback if it contains separators, parent segments, or is absolute; ensure the sanitized base name contains no path separators or leading dots and only safe characters (or else use extract_base_name(input_path)); keep using export_options.output_dir/output_dir for directory placement so callers cannot escape the intended output directory.
🧹 Nitpick comments (2)
src/export.rs (1)
985-1005: ⚡ Quick winAdd coverage for the newly added QUIC/KISS prefix mappings.
KNOWN_FIRMWARE_PREFIXESincludes Quicksilver/Kiss, buttest_firmware_prefix_for_revisioncurrently verifies only EMUF/BTFL/INAV plus unknown cases.✅ Minimal test additions
assert_eq!(firmware_prefix_for_revision("INAV 7.1.2"), Some("INAV_")); + assert_eq!( + firmware_prefix_for_revision("Quicksilver 0.1.0"), + Some("QUIC_") + ); + assert_eq!(firmware_prefix_for_revision("Kiss Ultra"), Some("KISS_")); assert_eq!(firmware_prefix_for_revision(""), None); assert_eq!(firmware_prefix_for_revision("Unknown firmware"), None);🤖 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 `@src/export.rs` around lines 985 - 1005, The test test_firmware_prefix_for_revision is missing assertions for the newly added QUIC/KISS mappings; update this test to include cases that exercise the QUIC and KISS entries in KNOWN_FIRMWARE_PREFIXES by calling firmware_prefix_for_revision with representative revision strings (e.g., "Quicksilver ..." and "KISS ..." or uppercase variants) and asserting they return the expected prefixes (e.g., "QUIC_" and "KISS_"); ensure you add both typical and uppercase/lowercase variations similar to the existing EMUF/BTFL checks so the mapping logic is covered.src/main.rs (1)
942-949: ⚡ Quick winAvoid duplicating vendor mapping in CLI warning output.
This
matchduplicates prefix/vendor knowledge already maintained insrc/export.rs. Future prefix additions can silently drift and printUnknownhere.🤖 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 `@src/main.rs` around lines 942 - 949, The inline match that sets vendor_name duplicates the prefix->vendor mapping maintained elsewhere; replace this block by calling the shared lookup in export.rs (e.g., a function like vendor_for_prefix or get_vendor_by_prefix) instead of re-implementing the mapping. Update the code that currently computes vendor_name (using prefix) to call that shared function, and ensure the shared function is made public if necessary so the CLI warning uses the single source of truth for prefix->vendor mappings.
🤖 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.
Outside diff comments:
In `@src/export.rs`:
- Around line 145-176: compute_export_paths currently trusts base_name_override
directly which allows absolute paths or path traversal; validate and sanitize
base_name_override before constructing filenames: when base_name_override is
Some, convert it to a Path and extract only the final file-stem/file-name
component (e.g. via Path::new(base_name_override).file_name() or file_stem) and
reject or fallback if it contains separators, parent segments, or is absolute;
ensure the sanitized base name contains no path separators or leading dots and
only safe characters (or else use extract_base_name(input_path)); keep using
export_options.output_dir/output_dir for directory placement so callers cannot
escape the intended output directory.
---
Nitpick comments:
In `@src/export.rs`:
- Around line 985-1005: The test test_firmware_prefix_for_revision is missing
assertions for the newly added QUIC/KISS mappings; update this test to include
cases that exercise the QUIC and KISS entries in KNOWN_FIRMWARE_PREFIXES by
calling firmware_prefix_for_revision with representative revision strings (e.g.,
"Quicksilver ..." and "KISS ..." or uppercase variants) and asserting they
return the expected prefixes (e.g., "QUIC_" and "KISS_"); ensure you add both
typical and uppercase/lowercase variations similar to the existing EMUF/BTFL
checks so the mapping logic is covered.
In `@src/main.rs`:
- Around line 942-949: The inline match that sets vendor_name duplicates the
prefix->vendor mapping maintained elsewhere; replace this block by calling the
shared lookup in export.rs (e.g., a function like vendor_for_prefix or
get_vendor_by_prefix) instead of re-implementing the mapping. Update the code
that currently computes vendor_name (using prefix) to call that shared function,
and ensure the shared function is made public if necessary so the CLI warning
uses the single source of truth for prefix->vendor mappings.
ℹ️ Review info
⚙️ Run configuration
Configuration used: Organization UI
Review profile: CHILL
Plan: Pro
Run ID: 63d03f66-064b-49af-885f-60be10440394
📒 Files selected for processing (11)
examples/csv_export.rsexamples/event_export.rsexamples/export_demo.rsexamples/gpx_export.rsexamples/multi_export.rsexamples/multi_flight_export.rssrc/conversion.rssrc/export.rssrc/lib.rssrc/main.rstests/export_integration_tests.rs
📜 Review details
🧰 Additional context used
📓 Path-based instructions (6)
src/**/*.rs
📄 CodeRabbit inference engine (AGENTS.md)
src/**/*.rs: Do not remove or modify comments unless the related code is changed; only add comments that explain code functionality, no AI instructional comments
Never embed or call external binaries from Rust code
Ensurecargo build --releasehas no errors or warnings
Only commit if:cargo clippy --all-targets --all-features -- -D warnings,cargo fmt --all -- --check,cargo test --verbose,cargo test --features=cli --verbose, andcargo build --releaseall pass with no errors or warnings
BEFORE ANY CODE CHANGES: Runcargo clippy --all-targets --all-features -- -D warningsto catch all issues
BEFORE ANY CODE CHANGES: Runcargo fmt --all -- --checkto ensure formatting compliance
Ifcargo fmt --all -- --checkfails, IMMEDIATELY runcargo fmt --allto fix formatting
Code must passcargo fmt --all -- --checkwithout any formatting issues
Never skip clippy checks or formatting checks; never allow warnings to pass
ALWAYS runcargo fmt --allafter making ANY code changes before moving to next steps
After runningcargo fmt --all, ALWAYS verify withcargo fmt --all -- --checkbefore proceeding
Files:
src/conversion.rssrc/lib.rssrc/main.rssrc/export.rs
src/{main,lib}.rs
📄 CodeRabbit inference engine (AGENTS.md)
Maintain CLI source as
src/main.rsand library core assrc/lib.rs
Files:
src/lib.rssrc/main.rs
src/{lib.rs,parser/**/*.rs,export.rs}
📄 CodeRabbit inference engine (AGENTS.md)
Core logic in
src/lib.rswith parser modules (src/parser/) and export functions (src/export.rs) shared by both library and CLI
Files:
src/lib.rssrc/export.rs
src/lib.rs
📄 CodeRabbit inference engine (AGENTS.md)
Public API must include:
parse_bbl_file(),parse_bbl_bytes(),BBLLog,ExportOptions,export_to_csv(),export_to_gpx(),export_to_event(), conversion utilities, parser helpers
Files:
src/lib.rs
src/main.rs
📄 CodeRabbit inference engine (AGENTS.md)
CLI (
src/main.rs) uses library export functions (export_to_csv,export_to_gpx,export_to_event) with CLI-specific status messages as thin wrapper with zero public functions
Files:
src/main.rs
src/export.rs
📄 CodeRabbit inference engine (AGENTS.md)
The CSV output must precisely match the format and header order of blackbox_decode CSV files
Files:
src/export.rs
🧠 Learnings (6)
📓 Common learnings
Learnt from: nerdCopter
Repo: nerdCopter/bbl_parser PR: 0
File: :0-0
Timestamp: 2025-12-08T21:15:02.434Z
Learning: Repo nerdCopter/bbl_parser: For outside-diff review notes, prefer a compact, single-block comment with flat bullets (file:line → note), no nested <details> or admonitions; overflow should be linked via gist. Maintainer: nerdCopter.
Learnt from: nerdCopter
Repo: nerdCopter/bbl_parser PR: 2
File: LICENSE_COMMERCIAL:1-4
Timestamp: 2025-08-29T19:52:05.099Z
Learning: nerdCopter prefers to avoid publishing personal information in license files for privacy and security reasons, as they are an individual maintainer rather than a company.
Learnt from: nerdCopter
Repo: nerdCopter/bbl_parser PR: 2
File: README.md:520-521
Timestamp: 2025-08-29T19:53:41.354Z
Learning: nerdCopter uses AGPL-3.0-or-later licensing for the bbl_parser project with a dual-licensing approach that includes a separate commercial license option.
Learnt from: nerdCopter
Repo: nerdCopter/bbl_parser PR: 2
File: CONTRIBUTING.md:9-14
Timestamp: 2025-08-21T20:25:45.741Z
Learning: nerdCopter prefers to keep CLA language general using "project maintainer" rather than specifying a legal entity name, as they are an individual maintainer without an associated company.
Learnt from: nerdCopter
Repo: nerdCopter/bbl_parser PR: 2
File: LICENSE_COMMERCIAL:0-0
Timestamp: 2025-08-29T20:15:04.624Z
Learning: nerdCopter prefers clear positive indicators (✅) when describing fixes rather than using ❌ symbols which can be confusing when describing what was corrected in a positive context.
📚 Learning: 2025-12-19T21:17:26.889Z
Learnt from: CR
Repo: nerdCopter/bbl_parser PR: 0
File: AGENTS.md:0-0
Timestamp: 2025-12-19T21:17:26.889Z
Learning: Applies to src/main.rs : CLI (`src/main.rs`) uses library export functions (`export_to_csv`, `export_to_gpx`, `export_to_event`) with CLI-specific status messages as thin wrapper with zero public functions
Applied to files:
examples/csv_export.rsexamples/multi_flight_export.rsexamples/gpx_export.rssrc/lib.rsexamples/event_export.rsexamples/multi_export.rsexamples/export_demo.rstests/export_integration_tests.rssrc/main.rssrc/export.rs
📚 Learning: 2025-12-19T21:17:26.889Z
Learnt from: CR
Repo: nerdCopter/bbl_parser PR: 0
File: AGENTS.md:0-0
Timestamp: 2025-12-19T21:17:26.889Z
Learning: Applies to src/lib.rs : Public API must include: `parse_bbl_file()`, `parse_bbl_bytes()`, `BBLLog`, `ExportOptions`, `export_to_csv()`, `export_to_gpx()`, `export_to_event()`, conversion utilities, parser helpers
Applied to files:
examples/csv_export.rsexamples/multi_flight_export.rsexamples/gpx_export.rssrc/lib.rsexamples/event_export.rsexamples/multi_export.rsexamples/export_demo.rstests/export_integration_tests.rssrc/main.rssrc/export.rs
📚 Learning: 2025-12-19T21:17:26.889Z
Learnt from: CR
Repo: nerdCopter/bbl_parser PR: 0
File: AGENTS.md:0-0
Timestamp: 2025-12-19T21:17:26.889Z
Learning: Applies to src/export.rs : The CSV output must precisely match the format and header order of blackbox_decode CSV files
Applied to files:
examples/csv_export.rsexamples/multi_flight_export.rssrc/lib.rsexamples/multi_export.rsexamples/export_demo.rstests/export_integration_tests.rssrc/main.rs
📚 Learning: 2025-12-19T21:17:26.889Z
Learnt from: CR
Repo: nerdCopter/bbl_parser PR: 0
File: AGENTS.md:0-0
Timestamp: 2025-12-19T21:17:26.889Z
Learning: Applies to Cargo.toml : Feature flags `csv`, `cli`, `json`, `serde` control optional dependencies; default: `csv` + `cli`
Applied to files:
examples/csv_export.rs
📚 Learning: 2025-12-19T21:17:26.889Z
Learnt from: CR
Repo: nerdCopter/bbl_parser PR: 0
File: AGENTS.md:0-0
Timestamp: 2025-12-19T21:17:26.889Z
Learning: Applies to src/{lib.rs,parser/**/*.rs,export.rs} : Core logic in `src/lib.rs` with parser modules (`src/parser/`) and export functions (`src/export.rs`) shared by both library and CLI
Applied to files:
examples/csv_export.rssrc/lib.rssrc/main.rs
🔇 Additional comments (13)
src/conversion.rs (1)
346-346: LGTM!src/export.rs (2)
86-131: LGTM!
467-578: LGTM!Also applies to: 629-638, 917-926
src/main.rs (2)
9-903: LGTM!
908-941: LGTM!Also applies to: 950-960
examples/gpx_export.rs (1)
43-52: LGTM!examples/multi_export.rs (1)
70-71: LGTM!Also applies to: 79-88, 105-112
examples/multi_flight_export.rs (1)
63-64: LGTM!examples/csv_export.rs (1)
57-57: LGTM!examples/event_export.rs (1)
50-50: LGTM!examples/export_demo.rs (1)
87-87: LGTM!Also applies to: 112-112, 131-131
src/lib.rs (1)
39-39: LGTM!tests/export_integration_tests.rs (1)
39-39: LGTM!Also applies to: 88-88, 127-127, 156-156, 188-188, 249-249
|
@coderabbitai review.
|
🧩 Analysis chain🏁 Script executed: #!/bin/bash
cat src/main.rsLength of output: 42877 🏁 Script executed: #!/bin/bash
cat src/export.rsLength of output: 35544
On the "log 1 not repaired" concern: after tracing through the code, log 1 is actually handled correctly. Here's why: In for (log_index, &start_pos) in log_positions.iter().enumerate() {
// ...
let (should_skip, reason) = should_skip_export(&log, export_options.force_export);
if should_skip { continue; }
// ← called for log 1 (log_index=0) too
let base_name_override =
corrected_session_base_name(file_path, &log.header.firmware_revision);For your exact scenario (
One edge case worth noting: if log 1 is filtered out by One minor real concern I do see: the transition warning message always says "Consider excluding earlier sessions", which assumes old firmware always appears first. That holds for the reflash scenario (flash not erased before upgrade), but if someone reflashed back to an older firmware, the message could be misleading. Not a blocker but worth a Triggering the full review now. ✅ Action performedFull review finished. |
|
@coderabbitai, what is better verbiage to fix your reported (output unified-diff format): |
|
Tip For best results, initiate chat on the files or code changes. 🧩 Analysis chain🏁 Script executed: #!/bin/bash
rg -n "earlier sessions\|firmware transition\|Consider\|WARNING\|vendor" src/main.rs -A2 -B2Length of output: 347 🏁 Script executed: #!/bin/bash
rg -n "WARNING\|transition\|erase\|earlier\|session" src/main.rs -A2 -B2Length of output: 327 🏁 Script executed: #!/bin/bash
grep -n "WARNING\|transition\|erase\|earlier\|Consider\|firmware" src/main.rs | head -60Length of output: 1688 🏁 Script executed: #!/bin/bash
sed -n '908,965p' src/main.rsLength of output: 1983
--- a/src/main.rs
+++ b/src/main.rs
@@ -954,7 +954,8 @@ fn print_firmware_transition_warning(file_path: &Path, session_firmware: &[(usiz
}
}
- println!(" The flash was not erased before reflashing. Consider excluding earlier sessions.");
+ println!(" This typically occurs when flash is not erased before reflashing.");
+ println!(" Consider excluding sessions from the unintended firmware vendor listed above.");
}Why this is better:
The new phrasing refers to the vendor name (already printed above in the grouped list) rather than a positional word, so it stays correct regardless of which direction the firmware transition went. |
BossHobby Configurator confirmed QUIC_ as the standard filename prefix for Quicksilver blackbox exports (BossHobby/Configurator@39b8715). Keyword "quicksilver" matches the expected firmware revision header. Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Add FORK_REVISION_MAP constant mapping fork filename prefixes to the base firmware revision prefix they intentionally report. Quicksilver (QUIC_) writes Betaflight revision headers for Blackbox Explorer compatibility, so QUIC_* files must not be renamed to BTFL_* even though the revision string matches betaflight. Add test_corrected_session_base_name_fork_exemption to cover this case. Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
|
@coderabbitai review AI Generated comment Local |
🧩 Analysis chain🏁 Script executed: #!/bin/bash
# Check export_to_gpx signature
rg -n "pub fn export_to_gpx\|pub fn export_to_csv\|pub fn export_to_event" src/export.rs -A5
echo "---TESTS---"
rg -n "export_to_gpx\|export_to_csv\|export_to_event" tests/export_integration_tests.rs -B1 -A2Length of output: 507 🏁 Script executed: #!/bin/bash
# Find relevant files first
fd "export.rs" --type f
fd "export_integration" --type f
echo "---EXPORT SIGNATURES---"
grep -n "pub fn export_to_gpx\|pub fn export_to_csv\|pub fn export_to_event" src/export.rs || true
echo "---TEST CALLS---"
grep -n "export_to_gpx\|export_to_csv\|export_to_event" tests/export_integration_tests.rs || trueLength of output: 1046 🏁 Script executed: #!/bin/bash
# Check full signatures for all three export functions
sed -n '262,275p' src/export.rs
echo "---"
sed -n '490,505p' src/export.rs
echo "---"
sed -n '581,595p' src/export.rsLength of output: 1653
✏️ Learnings added
✅ Action performedReview finished.
|
|
@coderabbitai review |
✅ Action performedReview finished.
|
Add sanitize_base_name_override() to strip path separators and parent segments from base_name_override before file path construction, preventing path traversal on the public library API (export_to_csv, compute_export_paths). Add vendor_name_for_prefix() as the single source of truth for prefix->display-name mapping; remove the duplicate match block in print_firmware_transition_warning (main.rs) in favour of the shared function. Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
|
@coderabbitai, AI generated comment Addressing review findings from #41 (review) — resolved in ce9a1b4: Fixed — Outside diff / Major: Fixed — Nitpick 2: Duplicated vendor name Skipped — Nitpick 1 (QUIC_/KISS_ test coverage): Stale. |
|
Tip For best results, initiate chat on the files or code changes. 🧩 Analysis chain🏁 Script executed: #!/bin/bash
echo "=== sanitize_base_name_override ==="
rg -n "sanitize_base_name_override" src/export.rs src/main.rs -A8
echo ""
echo "=== vendor_name_for_prefix ==="
rg -n "vendor_name_for_prefix" src/export.rs src/main.rs -A10
echo ""
echo "=== base_name_override usages in compute_export_paths and export_to_csv ==="
rg -n "sanitize_base_name_override\|base_name_override" src/export.rs -B2 -A2 | head -60Length of output: 3765
✅ ✅ ✅ Skipped Nitpick 1 — the rationale is sound. Since Quicksilver always emits One remaining item — the warning text at The direction-neutral patch from earlier in this thread was not yet applied. If you'd like to land it, the diff is: - println!(" The flash was not erased before reflashing. Consider excluding earlier sessions.");
+ println!(" This typically occurs when flash is not erased before reflashing.");
+ println!(" Consider excluding sessions from the unintended firmware vendor listed above.");✏️ Learnings added
|
|
@coderabbitai, i did not like your recommended verbiage, so i did not implement. - println!(" The flash was not erased before reflashing. Consider excluding earlier sessions.");
+ println!(" This typically occurs when flash is not erased before reflashing.");
+ println!(" Consider excluding sessions from the unintended firmware vendor listed above."); |
|
Tip For best results, initiate chat on the files or code changes.
🐇 (˘・_・˘) |
AI Generated pull-request
Summary
WARNINGwith per-vendor session ranges and the hint to erase flash before reflashingEMUF_BLACKBOX_LOG_...01.csvfor a Betaflight session in anEMUF_*file becomesBTFL_BLACKBOX_LOG_...01.csv, preventingEMUF_BTFL_*orBTFL_BTFL_*duplicatesNew public API (
exportmodule)firmware_prefix_for_revision(revision: &str) -> Option<&'static str>— maps a firmware revision string to its canonical filename prefix (EMUF_,BTFL_,INAV_)corrected_session_base_name(bbl_path: &Path, firmware_revision: &str) -> Option<String>— returns a corrected base name when the session vendor differs from the BBL filename prefix, orNonewhen they matchAll export functions (
export_to_csv,export_to_gpx,export_to_event,compute_export_paths) gain an optionalbase_name_override: Option<&str>parameter. Existing callers passNone— no behaviour change.Known firmware prefixes are defined in one
consttable (KNOWN_FIRMWARE_PREFIXES). Adding support for a new firmware (Quicksilver, Kiss, etc.) requires adding a single(&str, &str)entry.Example output on
EMUF_BLACKBOX_LOG_STELLARH7DEV_20260531_172007.BBL(mixed BF + EF flash)Test plan
cargo test— all unit + integration tests pass (4 new tests forfirmware_prefix_for_revisionandcorrected_session_base_name)cargo clippy -- -D warnings— cleanEMUF_BLACKBOX_LOG_STELLARH7DEV_20260531_172007.BBL— sessions 1–3 renamed toBTFL_*, sessions 4–5 kept asEMUF_*, warning printed🤖 Generated with Claude Code
Summary by CodeRabbit
New Features
Documentation
Tests