Skip to content

Add test framework and fix blocking buzzer crash#39

Open
avenstewart wants to merge 11 commits intocolonelpanichacks:mainfrom
avenstewart:dev-testing
Open

Add test framework and fix blocking buzzer crash#39
avenstewart wants to merge 11 commits intocolonelpanichacks:mainfrom
avenstewart:dev-testing

Conversation

@avenstewart
Copy link
Copy Markdown

Summary

Adds a native test framework and a hardware test injection endpoint, which led to discovering and fixing a crash bug in the BLE detection callback.

Changes

Test framework

  • Extract detection patterns and matching logic into src/fy_detect.h (no behavior change, identical compiled binary)
  • 30 native unit tests covering MAC prefix, device name, manufacturer ID, and Raven UUID matching
  • Run on host with pio test -e native — no hardware needed

Hardware test endpoint

  • /api/test/inject?type=flock|raven|soundthinking|mfr simulates detections through the full pipeline (storage, dashboard, buzzer, serial, BLE, SPIFFS)
  • Compile-guarded behind FY_ENABLE_TEST_API — absent from production firmware
  • Build with pio run -e xiao_esp32s3_test
  • Automated crash reproduction script: python3 test/test_buzzer_crash.py

Bug fix: watchdog reset under sustained BLE detections

fyDetectBeep() was called directly inside FYBLECallbacks::onResult(), blocking the NimBLE host task for ~500ms with delay() calls. Under sustained detections this triggers a watchdog reset, rebooting the device and losing all unsaved data.

Fixed by deferring the buzzer to loop() via a fyDetectBeepPending flag, matching the existing fyCompanionChangePending pattern.

Verified with automated testing:

  • Unfixed firmware crashes consistently at ~12 rapid detections
  • Fixed firmware survives 30+ detections with no crash

Likely resolves issue #37.

dougborg and others added 11 commits February 7, 2026 20:38
Enable DeFlock mobile app connectivity via BLE GATT notifications,
and desktop host detection via USB serial heartbeat. When a companion
is connected, WiFi AP is disabled to free radio bandwidth and BLE
scan duty cycle is increased for better detection performance.

- BLE GATT server advertising service UUID a1b2c3d4-e5f6-7890-abcd-ef0123456789
  with TX characteristic (NOTIFY) for streaming detection JSON
- Chunked BLE notification sender respecting negotiated MTU
- "event":"detection" field added to JSON output for DeFlock parser
- Serial host detection via heartbeat timeout (5s)
- Companion mode: WiFi AP off + scan duration 2s→3s when connected
- Scan interval/duration converted from #define to mutable variables

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
…tSpotter

Expand MAC prefix detection with entries sourced from:

- Flock WiFi (Liteon/USI): f4:6a:dd, f8:a2:d6, e0:0a:f6, 00:f4:8d,
  d0:39:57, e8:d0:fc — contract manufacturer OUIs (Liteon Technology and
  USI/Universal Scientific Industrial) identified via the OUI-SPY firmware
  ecosystem table and cross-referenced against the IEEE OUI registry.
  These manufacturers produce Flock Safety's WiFi-enabled camera hardware.

- Flock Safety direct: b4:1e:52 — registered directly to "Flock Safety"
  in the IEEE OUI database (MA-L assignment). This is their own prefix
  rather than a contract manufacturer's.

- SoundThinking/ShotSpotter: d4:11:d6 — registered to "SoundThinking Inc"
  (formerly ShotSpotter) in the IEEE OUI database. Their acoustic gunshot
  detection sensors use BLE for local diagnostics and provisioning.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
BLE server callbacks run on the NimBLE host task, not the Arduino
loop task. Calling WiFi state changes and delay() from that context
can stall BLE processing or trip watchdogs, and mutating scan
duration creates a cross-task data race.

Fix: callbacks now just set a volatile pending flag. The actual
WiFi/scan changes are applied in loop() where they're safe.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Collapse the two-branch snprintf into a single call so every
detection message includes is_raven (true/false) and raven_fw,
making the format self-describing regardless of device type.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Address Copilot review: contract manufacturer OUIs (Liteon/USI) are now
in a separate flock_mfr_mac_prefixes[] array emitting "mac_prefix_mfr"
as the detection method. SoundThinking/ShotSpotter gets its own array
and "mac_prefix_soundthinking" method. Low-confidence detections (mfr
OUIs) suppress buzzer/heartbeat but still emit JSON events so consumers
can apply their own thresholds.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
…uffer

Low-confidence mac_prefix_mfr hits no longer update fyLastDetTime/fyLastHB,
preventing them from keeping the heartbeat alive after a high-confidence
device leaves range. Bump FYDetection::method from 24 to 32 bytes so
"mac_prefix_soundthinking" (23 chars) has headroom.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Add OUI prefixes for Flock WiFi, Flock Safety direct, and ShotSpotter
Add BLE GATT server, serial host detection, and companion mode
…tion patterns and matching functions into fy_detect.h for host-side testing via PlatformIO native environment. 30 tests covering MAC prefix, device name, manufacturer ID, and Raven UUID detection. No firmware behavior changes.
…ed /api/test/inject endpoint for simulating detections. Fix fyDetectBeep() blocking BLE/HTTP tasks by deferring to loop() via fyDetectBeepPending flag. Rename test dirs for clarity.
…nv breaking pio run with default_envs and build_src_filter.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants