Skip to content

Windows: map ATT errors to UniversalBleErrorCode; share the mapping table - #353

Merged
rohitsangwan01 merged 4 commits into
Navideck:mainfrom
fotiDim:windows-att-error-codes
Oct 19, 2026
Merged

rohitsangwan01 merged 4 commits into
Navideck:mainfrom
fotiDim:windows-att-error-codes

Conversation

@fotiDim

@fotiDim fotiDim commented Oct 16, 2026 •

Copy link
Copy Markdown
Contributor

Fixes the Windows half of #348, and guards the ATT error mapping so the per-platform tables cannot drift apart.

Windows: map ATT errors to UniversalBleErrorCode

On Windows, a read, write or subscription that the peripheral refuses now reports the matching UniversalBleErrorCode (insufficientEncryption, insufficientAuthentication, readNotPermitted, ...), as Android already does. Until now every refusal reached Dart as the generic failed.

Windows reports a refused GATT operation as GattCommunicationStatus::ProtocolError and puts the ATT error code in the result's ProtocolError byte, which the plugin was discarding.

  • New att_error_mapper maps every ATT error code to the same UniversalBleErrorCode Android's gattStatusToUniversalBleErrorCode gives the same code.
  • create_flutter_error_from_gatt_result uses that mapping when the status is ProtocolError and Windows supplied a protocol error, otherwise it falls back to create_flutter_error_from_gatt_communication_status. The raw ATT code is kept in details.
  • Covered paths: characteristic read, descriptor read, characteristic write, descriptor write, subscribe, and descriptor discovery (GetDescriptorsForUuidAsync). Writes and subscribe move to the ...WithResultAsync overloads (GattWriteResult carries ProtocolError); these require Windows 10 1703 (API contract v4), and the plugin already requires SDK 10.0.19041.
  • Service/characteristic discovery at connect time still surfaces a connection failure with a message, so it is left as-is.

Shared conformance fixture

New test/fixtures/att_error_cases.tsv is driven by the Dart, Kotlin and C++ tests, so the Android, Dart and Windows mappings are held to one table instead of four hand-maintained copies (the same pattern as test/fixtures/scan_filter_cases.tsv):

  • test/att_error_conformance_test.dart
  • android/src/test/.../UniversalBleAttErrorConformanceTest.kt
  • windows/test/att_error_mapper_test.cpp

Apple's attErrorToUniversalBleErrorCode (#350, now on main) maps identically; its XCTest still asserts a hand-written list and can be pointed at this fixture later.

Linux: stricter BlueZ ATT-code extraction

UniversalBleErrorParser.extractBlueZAttErrorCode now matches the ATT error: 0xNN phrase before falling back to a bare hex value, so an unrelated hex value elsewhere in the BlueZ message is no longer mistaken for the ATT code. Extracted into the parser so it is unit tested.

Docs

Corrected the createFlutterError (details is numeric, not the enum name) comments on Apple and Windows.

Tests

  • flutter test: 290 pass, including the new Dart conformance test and the BlueZ extraction tests.
  • flutter analyze and dart format clean.
  • ctest (portable Windows suite) passes locally, including the fixture-driven att_error_mapper_test.
  • clang-format applied to changed lines only.

Notes

  • The Windows plugin itself is not built in this environment (no Windows SDK). The WinRT changes follow the patterns already in these functions and use documented ...WithResultAsync/ProtocolError APIs; CI's windows job (flutter build windows + ctest) validates them.
  • Web is unaffected: the browser does not expose ATT codes.

@fotiDim fotiDim changed the title Windows: map ATT errors to UniversalBleErrorCode Windows: map ATT errors to UniversalBleErrorCode; share the mapping table Oct 16, 2026
@fotiDim
fotiDim force-pushed the windows-att-error-codes branch from bfe7b2a to c5fa51f Compare October 16, 2026 13:02
Clarify the docs touched by the Windows ATT error mapping change:

- att_error_cases.tsv: 0x80-0xFF are unknownError only for the mappings
  the fixture drives (Dart/Android/Windows); note the Linux wrapper falls
  back to the caller's default code.
- extractBlueZAttErrorCode: document the case-insensitive phrase match
  and the best-effort bare 0x fallback.
- att_error_mapper.h: describe the raw ProtocolError byte (also used for
  descriptor discovery) and the application-defined range.
- CHANGELOG/README: state what is covered on Windows (characteristic and
  descriptor reads/writes, SetNotifiable) and that connect-time discovery
  and Linux/Web are unchanged.
- universal_ble_plugin.cpp: comment why discovery failures skip the ATT
  code mapping.
@rohitsangwan01
rohitsangwan01 merged commit 1d69330 into Navideck:main Oct 19, 2026
3 checks passed
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.

2 participants