Files
giglez/docs/MULTI_FREQUENCY_HANDLING.md
Trilltechnician 9bd9f4f43b docs: Multi-frequency RF file handling analysis
Comprehensive analysis of how the system handles .sub files with
multiple frequencies.

Key findings:
- Standard Flipper Zero files contain ONE frequency per file
- Multiple .sub files in one upload: WORKS correctly
- Multiple Frequency: lines in one file: Only last used (silent loss)
- Recommended: Add validation warning for multi-frequency edge case

Analysis includes:
- Current parser behavior
- Flipper Zero file format specification
- 4 solution options with pros/cons
- Testing scenarios
- Impact assessment
- Short-term and long-term recommendations
2026-01-14 13:20:08 -08:00

12 KiB

Multi-Frequency RF File Handling - Analysis & Recommendations

Date: January 14, 2026 Status: Current Limitation Identified Priority: Medium (Future Enhancement)


Current Behavior

How the System Handles .sub Files Today

Current Implementation:

# src/parser/sub_parser.py (line 79)
frequency = int(self.fields.get('Frequency', 0))  # Single frequency only

# src/api/main_simple.py (line 323)
frequency = metadata.frequency  # Extracts single frequency

What Happens:

  1. Parser reads the Frequency: field from .sub file
  2. Extracts ONE frequency value (integer)
  3. Creates ONE capture record per file
  4. Stores that single frequency with GPS coordinates

Flipper Zero .sub File Format

Standard Single-Frequency File:

Filetype: Flipper SubGhz Key File
Version: 1
Frequency: 433920000
Preset: FuriHalSubGhzPresetOok270Async
Protocol: Princeton
Bit: 24
Key: 00 00 00 00 00 95 D5 D4

Can .sub Files Contain Multiple Frequencies?

Based on Flipper Zero's firmware and file format specification:

NO - Standard Flipper Zero .sub files contain ONE frequency per file

Each .sub file represents a single capture at a single frequency.

Multi-Frequency Scenarios

However, there are edge cases where multiple frequencies might appear:

Scenario 1: Multiple .sub Files in One Upload

SUPPORTED - System handles this correctly

# User uploads multiple files at once
files = [
    "capture_315MHz.sub",  # Frequency: 315000000
    "capture_433MHz.sub",  # Frequency: 433920000
    "capture_868MHz.sub"   # Frequency: 868000000
]

# System behavior:
for file in files:
    metadata = sub_parser.parse(file)  # Each file parsed separately
    capture = create_capture(metadata)  # Each creates separate capture
    # Result: 3 separate captures with 3 different frequencies

Result: Works correctly - creates 3 separate map markers

Scenario 2: Frequency-Hopping Devices (Future)

NOT SUPPORTED - Would require new file format

Some devices transmit on multiple frequencies (e.g., Bluetooth frequency hopping, LoRa adaptive data rate):

Device transmits: 315 MHz → 433 MHz → 868 MHz

Current behavior: Flipper Zero would create 3 separate .sub files

Hypothetical multi-frequency file (NOT STANDARD):

Filetype: Flipper SubGhz Multi File  # DOES NOT EXIST
Version: 1
Frequency: 315000000
Frequency: 433920000  # Multiple Frequency fields
Frequency: 868000000

Our parser behavior: Only reads first Frequency field (line 79)

Scenario 3: Scanning/Waterfall Captures

NOT SUPPORTED - Different file format

Flipper Zero's spectrum analyzer creates different file types:

  • .sub files = Single frequency capture
  • Waterfall scans = Not saved to .sub format

Current System Limitations

What Happens If Someone Manually Edits a .sub File?

Let's test what happens if a .sub file has multiple Frequency: lines:

Malformed File:

Filetype: Flipper SubGhz Key File
Version: 1
Frequency: 315000000
Frequency: 433920000  # Second frequency line
Protocol: Princeton

Parser Behavior:

# src/parser/sub_parser.py (lines 54-61)
for line in content.split('\n'):
    if ':' in line:
        key, value = line.split(':', 1)
        self.fields[key.strip()] = value.strip()  # OVERWRITES previous value!

Result:

  • First Frequency: 315000000 is stored
  • Second Frequency: 433920000 OVERWRITES it
  • Only 433920000 is used

Silent data loss - First frequency is discarded without warning

Upload Endpoint Behavior

# src/api/main_simple.py (lines 305-376)
for file in files:
    metadata = sub_parser.parse(temp_path)  # Parses single frequency
    frequency = metadata.frequency          # Gets single frequency

    # Creates ONE capture per file
    capture_info = {
        "id": upload_counter,
        "frequency": frequency,  # Single frequency stored
        # ... other fields
    }

Result: One file = One frequency = One capture = One map marker


Proposed Solutions

Pros:

  • Maintains data integrity
  • Prevents silent data loss
  • Simple to implement

Implementation:

def parse(self, file_path: str) -> SignalMetadata:
    # Count frequency fields
    freq_count = content.count('Frequency:')

    if freq_count > 1:
        raise ValueError(
            f"Multi-frequency files not supported. "
            f"Found {freq_count} frequency fields. "
            f"Please split into separate .sub files."
        )

    # Rest of parsing...

Option 2: Parse All Frequencies and Create Multiple Captures (Complex)

Pros:

  • Handles edge cases gracefully
  • Future-proof for multi-frequency devices

Cons:

  • Significant code changes required
  • Not aligned with Flipper Zero standard
  • GPS coordinates ambiguous (which freq was captured where?)

Implementation:

def parse(self, file_path: str) -> List[SignalMetadata]:
    """Returns LIST of metadata objects"""

    # Parse all frequency fields
    frequencies = []
    for line in content.split('\n'):
        if line.startswith('Frequency:'):
            freq = int(line.split(':', 1)[1].strip())
            frequencies.append(freq)

    if len(frequencies) == 0:
        raise ValueError("No frequency found")

    # Create separate metadata for each frequency
    results = []
    for freq in frequencies:
        metadata = SignalMetadata(frequency=freq, ...)
        results.append(metadata)

    return results

# Upload endpoint changes needed:
for file in files:
    metadatas = sub_parser.parse(temp_path)  # Returns LIST
    for metadata in metadatas:  # Create multiple captures
        capture = create_capture(metadata)

Database changes:

  • captures_storage would need to link related captures
  • GPS coordinates: same for all captures from one file
  • Map display: Multiple markers at same location?

Option 3: Store Multiple Frequencies in Single Capture (Database Change)

Pros:

  • Preserves all frequency data
  • Single capture per file (simpler logic)

Cons:

  • Database schema change required
  • Map display complexity (show all frequencies?)
  • Matching logic needs update

Implementation:

# Database schema:
capture_info = {
    "id": 1,
    "filename": "multi_freq.sub",
    "frequencies": [315000000, 433920000, 868000000],  # Array instead of single
    "primary_frequency": 315000000,  # First or dominant frequency
    # ...
}

# Map display:
# Option A: Show primary frequency only
# Option B: Show all frequencies in popup
# Option C: Create multiple semi-transparent markers

Option 4: Do Nothing (Current Behavior)

Pros:

  • No code changes needed
  • Aligns with Flipper Zero standard (one freq per file)

Cons:

  • Silent data loss if malformed file uploaded
  • No user feedback about issue

Recommendations

Short-Term (Implement Now)

1. Add Validation Warning

def parse(self, file_path: str) -> SignalMetadata:
    freq_count = content.count('Frequency:')

    if freq_count > 1:
        logger.warning(
            f"File {file_path} contains {freq_count} frequency fields. "
            f"Only the last one will be used: {self.fields['Frequency']}"
        )

2. Document Behavior

  • Update API docs to clarify: "One frequency per .sub file"
  • Add to upload UI: "Multi-frequency files not supported"

3. Add to Upload Response

if freq_count > 1:
    warnings.append({
        "filename": file.filename,
        "warning": "Multiple frequencies detected. Only last frequency used.",
        "frequencies_found": freq_count
    })

Medium-Term (Future Enhancement)

If multi-frequency support becomes needed:

  1. Update File Format Spec

    • Define multi-frequency .sub format
    • OR: Use separate file per frequency (Flipper standard)
  2. Update Parser

    • Return List[SignalMetadata] instead of single
    • Parse all frequency fields
  3. Update Upload Endpoint

    • Handle list of metadata objects
    • Create multiple captures per file
    • Link captures with parent_file_id
  4. Update Map Display

    • Show multiple markers at same GPS location
    • OR: Single marker with frequency list in popup
  5. Update Database Schema

    # New fields:
    "is_multi_frequency": True,
    "parent_capture_id": None,  # For linked captures
    "frequency_index": 0,       # Which frequency in multi-freq file
    

Testing

Test Case 1: Normal Single-Frequency File

# Input: standard_capture.sub
Frequency: 433920000

# Expected:
- Parse succeeds
- frequency = 433920000
- One capture created

Test Case 2: Duplicate Frequency Lines

# Input: duplicate_freq.sub
Frequency: 315000000
Frequency: 315000000  # Same frequency twice

# Current behavior:
- Parse succeeds
- frequency = 315000000 (last value)
- Warning logged

# Recommended:
- Parse succeeds
- Warning returned to user

Test Case 3: Different Frequency Lines

# Input: multi_freq.sub
Frequency: 315000000
Frequency: 433920000  # Different frequency

# Current behavior:
- Parse succeeds
- frequency = 433920000 (last value)
- 315000000 silently discarded

# Recommended:
- Parse fails OR
- Parse succeeds with warning
- User informed of data loss

Test Case 4: Multiple Files Uploaded

# Input: 3 separate .sub files
file1.sub: Frequency: 315000000
file2.sub: Frequency: 433920000
file3.sub: Frequency: 868000000

# Current behavior: ✅ WORKS
- Parse each file separately
- Create 3 captures
- 3 map markers with different frequencies

FAQ

Q: Can a single .sub file contain multiple frequencies? A: Not in the standard Flipper Zero format. Each .sub file represents one capture at one frequency.

Q: What if I scan multiple frequencies? A: Flipper Zero creates separate .sub files for each frequency. Upload all files together.

Q: What happens if I manually add multiple Frequency: lines? A: Currently, only the last frequency is used. Earlier ones are silently discarded.

Q: Can I upload multiple .sub files with different frequencies? A: Yes! Upload them all at once. Each file creates a separate capture.

Q: Why not support multi-frequency files? A:

  1. Not part of Flipper Zero standard
  2. GPS coordinates are per-file, not per-frequency
  3. Adds significant complexity
  4. No known devices that require this

Q: Will this be supported in the future? A: Maybe, if:

  1. Users frequently encounter multi-frequency devices
  2. A clear use case emerges (frequency-hopping, channel scanning)
  3. Standard file format is defined

Impact Assessment

Current Impact

  • Low - Flipper Zero doesn't create multi-frequency files
  • Edge case only - Manually edited/malformed files

User Impact if Implemented

  • Positive: Handle more file types
  • Negative: Increased complexity, potential confusion (multiple markers at same GPS)

Development Effort

  • Option 1 (Validation): Low - 1-2 hours
  • Option 2 (Multi-capture): High - 1-2 days
  • Option 3 (Database change): Very High - 3-5 days + migration

Conclusion

Current Status: System handles one frequency per .sub file correctly.

Recommendation: Implement Option 1 (validation warning) in short-term.

Reasoning:

  1. Aligns with Flipper Zero standard (one freq per file)
  2. No known use cases for multi-frequency files
  3. Minimal development effort
  4. Prevents silent data loss
  5. Future-proof: can enhance later if needed

Action Items:

  • Add frequency count validation
  • Log warning if multiple frequencies detected
  • Return warning in upload API response
  • Document behavior in API docs
  • Add user-facing note in upload UI

Status: Analysis complete, awaiting decision on implementation priority.