Skip to content

[RFC] Feature Request: Add configurable ADVERT_SEEK threshold for persistent multi-channel advertisement capture #118

@NeverMin

Description

@NeverMin

Issue Description:
Background: Currently, Sniffle uses a two-phase approach for multi-channel advertisement monitoring:

  1. ADVERT_SEEK phase: Monitors all three advertising channels (37/38/39) to learn advertiser timing patterns
  2. ADVERT_HOP phase: Switches to synchronized hopping based on learned patterns

The transition from ADVERT_SEEK to ADVERT_HOP occurs after 5 advertising events hardcoded in fw/RadioTask.c:409, which limits the ability to capture advertisements from multiple devices or validate device behavior across all three channels.

Problem Statement: When testing BLE devices or analyzing multi-device environments, the automatic transition to ADVERT_HOP mode causes several issues:

  1. Missing advertisements: After learning phase, only synchronized packets from the target device are captured, missing advertisements from other devices on different channels
  2. Incomplete device validation: Cannot verify that devices properly advertise on all three channels (37/38/39) as required by BLE specification
  3. Limited debugging capability: Cannot observe timing variations or channel-specific behavior that occurs after the initial learning phase

Use Cases:

  • Device compliance testing: Verify that BLE devices advertise on all required channels
  • Multi-device environments: Capture advertisements from multiple devices simultaneously
  • RF interference analysis: Monitor how different channels are affected by interference
  • Timing analysis: Study advertisement timing patterns across all channels
  • Debugging: Identify devices that don't follow standard advertising patterns

Current Behavior:

// fw/RadioTask.c:409
if (connEventCount >= 5) {
    reportMeasAdvHop(rconf.hopIntervalTicks >> 2);
    stateTransition(ADVERT_HOP);
}

Proposed Solution:
Add a configurable threshold for ADVERT_SEEK to ADVERT_HOP transition, allowing users to:

  • Extend learning phase (e.g., threshold = 50)
  • Disable automatic transition (threshold = 255 for "always learn")
  • Maintain current behavior (threshold = 5, default)

Suggestion:

CommandTask.h:

#define COMMAND_ADVERT_SEEK_THRESHOLD  0x28

CommandTask.c:

case COMMAND_ADVERT_SEEK_THRESHOLD:
    if (ret != 3) continue;
    setAdvertSeekThreshold(msgBuf[2]);
    break;

RadioTask.c:

static uint8_t advertSeekThreshold = 5;

void setAdvertSeekThreshold(uint8_t threshold) {
    advertSeekThreshold = threshold;
}

// Modified transition logic
if (connEventCount >= advertSeekThreshold) {
    reportMeasAdvHop(rconf.hopIntervalTicks >> 2);
    stateTransition(ADVERT_HOP);
}

sniffle_hw.py:

def cmd_advert_seek_threshold(self, threshold=5):
    """Set the threshold for transitioning from ADVERT_SEEK to ADVERT_HOP mode.
    
    Args:
        threshold: Number of advertising events before switching from learning 
                  mode to synchronized hopping. 
                  - Default: 5 (current behavior)
                  - 0: Skip ADVERT_SEEK, go directly to ADVERT_HOP
                  - 255: Stay in ADVERT_SEEK indefinitely
    """
    if not (0 <= threshold <= 255):
        raise ValueError("Threshold must be between 0 and 255")
    self._send_cmd([0x28, threshold])

Benefits:

  • Backward compatible: Default behavior unchanged
  • Flexible: Users can choose appropriate threshold based on use case
  • Non-invasive: No changes to existing command protocol structure
  • Extensible: Foundation for future multi-channel enhancements

Technical Notes:
The existing RadioWrapper_recvAdv3() function already implements the hardware capability for three-channel monitoring. This feature request simply exposes control over when to transition between monitoring modes, allowing users to maintain the more comprehensive ADVERT_SEEK behavior when needed.

Alternative Considered:
While true simultaneous three-channel capture would be ideal, the CC26x2/CC13x2 hardware has a single RF frontend that can only tune to one frequency at a time. The proposed solution maximizes the utility of the existing recvAdv3 implementation.

Would this enhancement be acceptable for inclusion in Sniffle? I'm happy to implement and test the changes if there's interest from the maintainers.

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions