Skip to content

fix: parse multiple 16-bit and 32-bit Service UUIDs in BLE advertisement data#155

Merged
bdraco merged 5 commits into
mainfrom
uuid_parsing
Jul 2, 2025
Merged

fix: parse multiple 16-bit and 32-bit Service UUIDs in BLE advertisement data#155
bdraco merged 5 commits into
mainfrom
uuid_parsing

Conversation

@bdraco
Copy link
Copy Markdown
Member

@bdraco bdraco commented Jul 2, 2025

fixes esphome/issues#7182

Fix parsing of multiple Service UUIDs in BLE advertisement data

Summary

This PR fixes a bug in the BLE GAP advertisement parser where only the first UUID was being parsed when multiple 16-bit or 32-bit Service UUIDs were present in a single advertisement data structure. The parser now correctly iterates through all UUIDs in the data.

Changes

Parser fixes (src/bluetooth_data_tools/gap.py)

  1. 16-bit UUIDs: Now iterates through the data in 2-byte chunks to extract all UUIDs
  2. 32-bit UUIDs: Added missing support for parsing 32-bit UUIDs (was completely missing), iterating in 4-byte chunks
  3. 128-bit UUIDs: Kept as single UUID parsing (correct per BLE spec - only one 128-bit UUID fits per record)

Test updates (tests/test_gap.py)

  1. Updated existing test: Fixed test_parse_adv_data to expect two separate 16-bit UUIDs instead of one combined UUID
  2. Added new test: test_parse_multiple_16bit_uuids - Tests parsing of 3 16-bit UUIDs
  3. Added new test: test_parse_multiple_32bit_uuids - Tests parsing of 2 32-bit UUIDs
  4. Added new test: test_parse_mixed_16bit_32bit_uuids - Tests parsing mixed 16-bit and 32-bit UUIDs in one advertisement
  5. Added new test: test_parse_mixed_16bit_128bit_uuids - Tests parsing mixed 16-bit and 128-bit UUIDs in one advertisement

Technical details

The BLE advertisement data format allows multiple UUIDs to be packed in a single record:

  • For 16-bit UUIDs (types 0x02, 0x03): Each UUID occupies 2 bytes
  • For 32-bit UUIDs (types 0x04, 0x05): Each UUID occupies 4 bytes
  • For 128-bit UUIDs (types 0x06, 0x07): Each UUID occupies 16 bytes (only one fits per record)

The previous implementation incorrectly treated the entire data block as a single UUID, leading to malformed UUID strings.

Testing

All tests pass:

  • 52 tests in test_gap.py (added 4 new tests)
  • New tests verify correct parsing of multiple UUIDs and mixed UUID types
  • No regressions in existing tests

@codecov
Copy link
Copy Markdown

codecov Bot commented Jul 2, 2025

Codecov Report

✅ All modified and coverable lines are covered by tests.
✅ Project coverage is 100.00%. Comparing base (45fe00b) to head (760c3a7).
⚠️ Report is 3 commits behind head on main.

Additional details and impacted files
@@             Coverage Diff             @@
##             main      #155      +/-   ##
===========================================
+ Coverage   99.59%   100.00%   +0.40%     
===========================================
  Files           6         6              
  Lines         245       255      +10     
  Branches       32        38       +6     
===========================================
+ Hits          244       255      +11     
+ Partials        1         0       -1     

☔ View full report in Codecov by Sentry.
📢 Have feedback on the report? Share it here.

🚀 New features to boost your workflow:
  • ❄️ Test Analytics: Detect flaky tests, report on failures, and find test suite problems.
  • 📦 JS Bundle Analysis: Save yourself from yourself by tracking and limiting bundle sizes in JS merges.

@codspeed-hq
Copy link
Copy Markdown

codspeed-hq Bot commented Jul 2, 2025

CodSpeed Performance Report

Merging #155 will not alter performance

Comparing uuid_parsing (760c3a7) with main (45fe00b)

Summary

✅ 9 untouched benchmarks

@bdraco bdraco changed the title fix: parse incomplete list of 16-bit Service UUIDs fix: parse multiple 16-bit and 32-bit Service UUIDs in BLE advertisement data Jul 2, 2025
@bdraco bdraco marked this pull request as ready for review July 2, 2025 03:13
@bdraco bdraco merged commit 4b1d6e2 into main Jul 2, 2025
32 checks passed
@bdraco bdraco deleted the uuid_parsing branch July 2, 2025 03:13
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.

Data corruption in BluetoothLERawAdvertisementsResponse/BluetoothLERawAdvertisement/Data

1 participant