Introduction
+The ESP32-C5 is Espressif's first RISC-V microcontroller with dual-band WiFi 6 (802.11ax) support. This guide demonstrates advanced GDB debugging techniques for WiFi monitor mode, including real-time 802.11 frame analysis, runtime threshold tuning, and WiFi collapse detection.
+ +New in This Edition: WiFi Monitor Mode
+-
+
- 802.11 Frame Capture: Debug WiFi at the packet level +
- Runtime Threshold Tuning: Adjust detection parameters without rebuilding +
- Duration Analysis: Analyze PHY rates, NAV, and expected vs actual duration +
- WiFi Collapse Detection: Real-time network degradation analysis +
- GDB Integration: Combine C code performance with GDB flexibility +
WiFi Monitor Mode Debugging
+ +The WiFi monitor mode implementation in the feature/wifi-monitor-mode branch provides real-time 802.11 frame capture and analysis capabilities. This section shows how to debug WiFi at the packet level using GDB.
Branch Setup
+cd ~/Code/esp32/esp32-iperf
+git checkout feature/wifi-monitor-mode
+git pull
+
+# Build and flash
+idf.py build
+idf.py -p /dev/ttyACM0 flash
+
+ Component Architecture
+The WiFi monitor is implemented as a reusable ESP-IDF component:
+esp32-iperf/
+├── components/
+│ └── wifi_monitor/
+│ ├── wifi_monitor.c # Frame capture & analysis
+│ ├── wifi_monitor.h # API definitions
+│ └── CMakeLists.txt
+└── main/
+ └── main.c # Monitor mode integration
+
+ Starting a WiFi Monitor Debug Session
+# Terminal 1: Start OpenOCD
+cd ~/Code/esp32/esp32-iperf
+idf.py openocd
+
+# Terminal 2: Start GDB
+idf.py gdb
+
+ .gdbinit file with WiFi debugging commands. Enable it once:
+ mkdir -p ~/.config/gdb
+echo "set auto-load safe-path /" >> ~/.config/gdb/gdbinit
+ 802.11 Frame Analysis
+ +GDB can inspect captured WiFi frames in real-time, showing detailed 802.11 MAC header information.
+ +Frame Callback Breakpoint
+(gdb) break monitor_frame_callback
+Breakpoint 1 at 0x4200e926
+
+(gdb) continue
+
+# When frame is captured:
+Thread 6 "main" hit Breakpoint 1, monitor_frame_callback (
+ frame=0x4082a6e4,
+ payload=0x40833c34,
+ len=1268
+) at main.c:212
+
+ Displaying Frame Information
+Use the show_frame_full command (auto-loaded from .gdbinit):
(gdb) show_frame_full
+━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
+Frame: DATA
+━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
+RSSI: -45 dBm
+Channel: 36
+Retry: no
+
+PHY Rate: 433500 Kbps (433.5 Mbps)
+Mode: MCS 8, BW 80MHz, SGI Yes
+
+Byte Count: 1500 bytes
+Expected Duration: 71 us (27 tx + 44 overhead)
+Actual Duration (NAV): 68 us
+Difference: -3 us shorter
+
+Dest: ff:ff:ff:ff:ff:ff
+Source: e0:46:ee:07:df:01
+━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
+
+ Frame Structure Breakdown
+| Field | +GDB Access | +Description | +
|---|---|---|
| Frame Type | +frame->type |
+ 0=Management, 1=Control, 2=Data | +
| Subtype | +frame->subtype |
+ Specific frame subtype (e.g., BEACON, ACK, DATA) | +
| NAV | +frame->duration_id |
+ Network Allocation Vector (microseconds) | +
| Retry Bit | +frame->retry |
+ true if frame is a retransmission | +
| RSSI | +frame->rssi |
+ Received Signal Strength (dBm) | +
| PHY Rate | +frame->phy_rate_kbps |
+ Physical layer rate (Kbps) | +
| MAC Addresses | +frame->addr1/2/3 |
+ Destination, Source, BSSID | +
Conditional Breakpoints for WiFi Analysis
+ +Break on High NAV (Potential Collapse)
+(gdb) break monitor_frame_callback if frame->duration_id > 10000
+Breakpoint 2 at 0x4200e926
+
+(gdb) commands 2
+>printf "⚠ HIGH NAV: %u us\n", frame->duration_id
+>show_duration
+>continue
+>end
+
+(gdb) continue
+
+ Break on Retry Frames (Collisions)
+(gdb) break monitor_frame_callback if frame->retry == 1
+Breakpoint 3 at 0x4200e926
+
+(gdb) continue
+
+ Break on Collision Indicators
+# Retry + High NAV = Strong collision indicator
+(gdb) break monitor_frame_callback if frame->retry && frame->duration_id > 5000
+Breakpoint 4 at 0x4200e926
+
+(gdb) commands 4
+>printf "🚨 COLLISION DETECTED!\n"
+>show_frame_full
+>end
+
+(gdb) continue
+ Runtime Threshold Tuning
+ +One of the most powerful features is the ability to adjust WiFi detection thresholds at runtime via GDB without rebuilding firmware.
+ +Tunable Thresholds
+The WiFi monitor exposes 9 threshold variables that control detection sensitivity:
+ +| Variable | +Default | +Purpose | +
|---|---|---|
threshold_high_nav_us |
+ 5000 | +NAV above this = "high" | +
threshold_duration_mismatch_us |
+ 10000 | +Log mismatches when NAV exceeds this | +
threshold_phy_rate_fallback_mbps |
+ 100 | +PHY rate below this = fallback | +
threshold_duration_multiplier |
+ 2 | +NAV > expected × this = mismatch | +
threshold_retry_rate_percent |
+ 20.0 | +Retry % for collapse detection | +
threshold_avg_nav_collapse_us |
+ 10000 | +Average NAV threshold for collapse | +
threshold_collision_percent |
+ 10.0 | +Collision % for collapse | +
threshold_mismatch_percent |
+ 5.0 | +Duration mismatch % for collapse | +
log_every_n_mismatches |
+ 1 | +Log every Nth mismatch (1=all) | +
GDB Commands for Threshold Control
+ +View Current Thresholds
+(gdb) show_thresholds
+━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
+WiFi Monitor Thresholds (GDB-tunable)
+━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
+High NAV threshold: 5000 us
+Duration mismatch log: 10000 us
+PHY rate fallback: 100 Mbps
+Duration multiplier: 2x expected
+
+Collapse Detection:
+ Retry rate threshold: 20.0%
+ Avg NAV collapse: 10000 us
+ Collision percentage: 10.0%
+ Mismatch percentage: 5.0%
+
+Logging Control:
+ Log every N mismatches: 1 (1=all, 10=every 10th)
+━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
+
+ Preset Profiles
+Three pre-configured profiles for different scenarios:
+ +# Sensitive - Catch more issues (stricter thresholds)
+(gdb) tune_sensitive
+Thresholds set to SENSITIVE (catch more issues)
+
+# Normal - Default balanced settings
+(gdb) tune_normal
+Thresholds set to NORMAL (default)
+
+# Relaxed - Fewer false positives (lenient thresholds)
+(gdb) tune_relaxed
+Thresholds set to RELAXED (fewer false positives)
+
+ Adjust Individual Thresholds
+# Set high NAV threshold to 8000 us (8ms)
+(gdb) set_high_nav 8000
+High NAV threshold set to 8000 us
+
+# Set mismatch logging threshold to 15000 us
+(gdb) set_mismatch_log 15000
+Duration mismatch logging threshold set to 15000 us
+
+# Set rate fallback to 50 Mbps
+(gdb) set_rate_fallback 50
+PHY rate fallback threshold set to 50 Mbps
+
+# Set duration multiplier (NAV > 3x expected = mismatch)
+(gdb) set_multiplier 3
+Duration multiplier set to 3x expected
+
+# Log every 10th mismatch (reduce verbosity)
+(gdb) set_log_rate 10
+Logging every 10 mismatch(es)
+
+ Direct Variable Modification
+You can also modify threshold variables directly:
+(gdb) set threshold_high_nav_us = 7500
+(gdb) set threshold_phy_rate_fallback_mbps = 75
+(gdb) set log_every_n_mismatches = 5
+
+(gdb) continue
+# Changes take effect immediately!
+
+ Real-World Tuning Examples
+ +Example 1: Noisy 2.4GHz Environment
+Problem: Too many false positives on 2.4GHz
+(gdb) tune_relaxed
+(gdb) set_rate_fallback 24 # 2.4GHz rates lower
+(gdb) set_log_rate 10 # Reduce log spam
+(gdb) continue
+
+ Example 2: Clean 5GHz Network
+Problem: Want to catch subtle issues early
+(gdb) tune_sensitive
+(gdb) set_rate_fallback 200 # Expect >200 Mbps
+(gdb) set_multiplier 1.5 # Catch 1.5x mismatches
+(gdb) continue
+
+ Example 3: Production Monitoring
+Problem: Need to reduce log spam while maintaining detection
+(gdb) tune_normal
+(gdb) set_log_rate 100 # Log every 100th mismatch
+(gdb) set_mismatch_log 20000 # Only log severe (>20ms)
+(gdb) continue
+
+ Duration Analysis
+ +The WiFi monitor calculates expected frame duration based on PHY rate and compares it with the actual NAV (Network Allocation Vector). Large mismatches indicate WiFi problems.
+ +Duration Calculation
+For each captured frame:
+TX Time = (Frame Bytes × 8000) / PHY Rate (Kbps)
+Overhead = Preamble + PLCP + SIFS + ACK ≈ 44 us
+Expected Duration = TX Time + Overhead
+
+Mismatch = Actual NAV - Expected Duration
+
+ GDB Commands for Duration Analysis
+ +Quick Duration Check
+(gdb) break monitor_frame_callback
+(gdb) continue
+
+(gdb) show_duration
+DATA: 1500 bytes @ 433.5 Mbps → Expected 71 us, NAV 68 us (-3)
+
+ Watch DATA Frames
+(gdb) watch_data
+Watching DATA frames
+Continuing.
+
+# Output streams:
+DATA: 1500 bytes @ 433.5 Mbps → Expected 71 us, NAV 68 us (-3)
+DATA: 1200 bytes @ 433.5 Mbps → Expected 66 us, NAV 64 us (-2)
+DATA: 800 bytes @ 54.0 Mbps → Expected 162 us, NAV 158 us (-4)
+
+ Find Duration Mismatches
+(gdb) find_mismatch
+Watching for NAV 2x+ expected duration
+Continuing.
+
+# Stops when mismatch detected:
+DATA: 1200 bytes @ 54.0 Mbps → Expected 222 us, NAV 8500 us (+8278)
+⚠ DURATION MISMATCH!
+
+ Interpreting Duration Differences
+| Difference | +Interpretation | +
|---|---|
| -5 to +500 us | +✅ Normal overhead variation | +
| +500 to +5000 us | +⚠️ Possible retransmission or fragmentation | +
| +5000 to +20000 us | +⚠️⚠️ Likely collision or high contention | +
| +20000+ us | +🚨 Severe WiFi collapse | +
Example: Detecting WiFi Collapse
+# Normal WiFi
+(gdb) show_duration
+DATA: 1500 bytes @ 433.5 Mbps → Expected 71 us, NAV 68 us (-3)
+✅ Healthy
+
+# WiFi Collapse
+(gdb) show_duration
+DATA: 1200 bytes @ 54.0 Mbps → Expected 222 us, NAV 32000 us (+31778)
+🚨 Severe collapse!
+ - PHY rate dropped: 433.5 → 54 Mbps
+ - NAV 144x expected duration
+ - Likely severe contention/collisions
+
+ Debugging Strategies
+ +WiFi Collapse Investigation Workflow
+-
+
- Start with normal thresholds
+
+(gdb) tune_normal +(gdb) continue
+ - Run WiFi traffic test
+
+# From another machine +iperf -c 192.168.1.81 -t 60 -P 4
+ - Monitor serial output for automatic detection +
- If too noisy, adjust thresholds
+
+(gdb) Ctrl-C +(gdb) set_log_rate 10 +(gdb) continue
+ - If not catching issues, increase sensitivity
+
+(gdb) Ctrl-C +(gdb) tune_sensitive +(gdb) continue
+ - Document optimal settings for your network +
Best Practices
+Threshold Tuning
+-
+
- Start conservative (tune_sensitive), then relax if needed +
- Use log_every_n_mismatches to control verbosity +
- Match thresholds to band (2.4GHz vs 5GHz) +
- Document final thresholds for each network/environment +
Frame Analysis
+-
+
- Use conditional breakpoints to catch specific issues +
- Focus on DATA frames for throughput analysis +
- Watch for retry+high NAV combination (collision indicator) +
- Compare RSSI across frames to detect signal issues +
Performance Monitoring
+-
+
- C code processes 10,000+ frames/sec +
- GDB adds minimal overhead for threshold tuning +
- Use GDB for deep inspection, C code for continuous monitoring +
- Combine automated detection (C) with interactive debugging (GDB) +
Real-World Examples
+ +Example 1: Debugging Rate Fallback
+Symptom: WiFi throughput suddenly drops
+# Set breakpoint on low PHY rates
+(gdb) break monitor_frame_callback if frame->phy_rate_kbps < 100000
+Breakpoint 1 at 0x4200e926
+
+(gdb) commands 1
+>printf "Low PHY rate: %u Kbps, RSSI: %d dBm\n", frame->phy_rate_kbps, frame->rssi
+>show_frame_full
+>end
+
+(gdb) continue
+
+# Output reveals:
+Low PHY rate: 54000 Kbps, RSSI: -82 dBm
+# Root cause: Weak signal → rate adaptation → lower throughput
+
+ Example 2: Finding Collision Hotspots
+Goal: Identify devices causing collisions
+# Break on collision indicators
+(gdb) break monitor_frame_callback if frame->retry && frame->duration_id > 5000
+Breakpoint 1 at 0x4200e926
+
+(gdb) commands 1
+>printf "Collision from: %02x:%02x:%02x:%02x:%02x:%02x\n", \
+ frame->addr2[0], frame->addr2[1], frame->addr2[2], \
+ frame->addr2[3], frame->addr2[4], frame->addr2[5]
+>continue
+>end
+
+(gdb) continue
+
+# Track which MAC addresses retry most frequently
+
+ Example 3: Tuning for 2.4GHz vs 5GHz
+# 2.4GHz network (more interference, lower rates)
+(gdb) set_high_nav 8000 # More lenient
+(gdb) set_rate_fallback 24 # Expected lower rates
+(gdb) set_log_rate 20 # Reduce noise
+(gdb) continue
+
+# Later, switch to 5GHz
+(gdb) Ctrl-C
+(gdb) set_high_nav 5000 # Stricter
+(gdb) set_rate_fallback 100 # Expect higher rates
+(gdb) set_log_rate 1 # Log all
+(gdb) continue
+ Troubleshooting
+ +GDB Commands Not Found
+Symptom: show_thresholds, tune_sensitive, etc. not recognized
Solution: Enable .gdbinit auto-loading
+mkdir -p ~/.config/gdb
+echo "set auto-load safe-path /" >> ~/.config/gdb/gdbinit
+
+# Restart GDB
+quit
+idf.py gdb
+
+ Compilation Errors
+Symptom: Build fails with "has no member named 'mcs'" errors
+Solution: Make sure you have the latest code from feature/wifi-monitor-mode branch
+git checkout feature/wifi-monitor-mode
+git pull
+cp wifi_monitor.h components/wifi_monitor/
+cp wifi_monitor.c components/wifi_monitor/
+rm -rf build
+idf.py build
+
+ No Frames Captured
+Symptom: Breakpoint never hits, no frames captured
+Possible Causes:
+-
+
- WiFi not connected or monitor mode not started +
- Wrong channel +
- RSSI too low (out of range) +
Solution: Check monitor mode status
+(gdb) print current_led_state
+# Should be LED_STATE_MONITORING (4)
+
+(gdb) print frame->channel
+# Should match your AP's channel
+
+ Too Much Logging
+Symptom: Serial output floods with mismatch logs
+Solution: Increase log rate or mismatch threshold
+(gdb) set_log_rate 50 # Log every 50th
+(gdb) set_mismatch_log 20000 # Only log >20ms NAV
+(gdb) continue
+ Advanced Techniques
+ +Creating Custom .gdbinit Profiles
+Add your own tuning profiles to .gdbinit:
+define tune_my_network
+ set threshold_high_nav_us = 6500
+ set threshold_phy_rate_fallback_mbps = 120
+ set log_every_n_mismatches = 5
+ printf "Custom profile loaded for my network\n"
+end
+
+ Logging Frame Data to File
+(gdb) set logging file wifi_frames.log
+(gdb) set logging on
+(gdb) watch_data
+# All output goes to wifi_frames.log
+
+ Combining Multiple Conditions
+# Break on: High NAV + Retry + Low RSSI
+(gdb) break monitor_frame_callback if \
+ frame->duration_id > 10000 && \
+ frame->retry == 1 && \
+ frame->rssi < -70
+
+# Very specific debugging target
+
+ Performance: C Code vs GDB
+| Method | +Speed | +Use Case | +
|---|---|---|
| C Code (Running) | +10,000+ frames/sec | +Continuous monitoring, production | +
| GDB (Breakpoints) | +~10 frames/sec | +Interactive inspection, debugging | +
| GDB (Threshold Tuning) | +Full speed | +Runtime configuration, no overhead | +
Resources
+ +Git Repository
+# Clone repository
+git clone https://github.com/yourusername/esp32-iperf.git
+cd esp32-iperf
+
+# Checkout WiFi monitor branch
+git checkout feature/wifi-monitor-mode
+
+ Key Files
+-
+
components/wifi_monitor/wifi_monitor.c- Frame capture implementation
+ components/wifi_monitor/wifi_monitor.h- API definitions
+ main/main.c- Monitor mode integration
+ .gdbinit- GDB commands for WiFi debugging
+
Documentation Files
+-
+
GDB_THRESHOLD_TUNING_GUIDE.md- Complete threshold tuning guide
+ DURATION_ANALYSIS_GUIDE.md- Duration analysis details
+ C_DURATION_ANALYSIS_GUIDE.md- C code implementation guide
+ COMPILATION_FIX_GUIDE.md- Troubleshooting build issues
+ WIFI_MONITOR_MODE_GUIDE.md- Full WiFi monitor documentation
+
External Resources
+ + +Quick Reference
+| Command | +Purpose | +
|---|---|
show_thresholds |
+ Display current thresholds | +
tune_sensitive |
+ Strict thresholds (catch more) | +
tune_normal |
+ Default balanced settings | +
tune_relaxed |
+ Lenient thresholds (fewer alerts) | +
set_high_nav <us> |
+ Set high NAV threshold | +
set_rate_fallback <mbps> |
+ Set rate fallback threshold | +
set_log_rate <n> |
+ Log every Nth mismatch | +
show_frame_full |
+ Complete frame analysis | +
show_duration |
+ Quick duration comparison | +
watch_data |
+ Monitor DATA frames | +
find_mismatch |
+ Auto-break on NAV mismatches | +