-
Notifications
You must be signed in to change notification settings - Fork 150
Description
Issue Description:
Background: Currently, Sniffle uses a two-phase approach for multi-channel advertisement monitoring:
- ADVERT_SEEK phase: Monitors all three advertising channels (37/38/39) to learn advertiser timing patterns
- 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:
- Missing advertisements: After learning phase, only synchronized packets from the target device are captured, missing advertisements from other devices on different channels
- Incomplete device validation: Cannot verify that devices properly advertise on all three channels (37/38/39) as required by BLE specification
- 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:
#define COMMAND_ADVERT_SEEK_THRESHOLD 0x28
case COMMAND_ADVERT_SEEK_THRESHOLD:
if (ret != 3) continue;
setAdvertSeekThreshold(msgBuf[2]);
break;
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);
}
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.