From 5deb6de7ee29883d95d1a2d70de3f7b13c798da4 Mon Sep 17 00:00:00 2001 From: evgeny Date: Sat, 31 Oct 2026 00:36:16 +0100 Subject: [PATCH] Verify canonical UUID conversion across WinRT GUID byte order --- lib/ble/ble_winrt.cpp | 10 ++++++++-- lib/ble/tests/test_ble_winrt.cpp | 5 +++++ 2 files changed, 13 insertions(+), 2 deletions(-) diff --git a/lib/ble/ble_winrt.cpp b/lib/ble/ble_winrt.cpp index 9dbb3007f..ba4e7c64f 100644 --- a/lib/ble/ble_winrt.cpp +++ b/lib/ble/ble_winrt.cpp @@ -33,6 +33,12 @@ using namespace Windows::Devices::Bluetooth::Advertisement; using namespace Windows::Devices::Bluetooth::GenericAttributeProfile; using namespace Windows::Storage::Streams; static constexpr auto CAT = DEBUG_CATEGORY_DISCOVERY; +/* WinRT форматирует GUID со скобками; в общий codec передаём canonical36, не раскладываем GUID повторно. */ +static uint64_t service_node(guid const& uuid) { + auto text = to_string(to_hstring(uuid)); + if (text.size() == 38 && text.front() == '{' && text.back() == '}') text = text.substr(1, 36); + uint64_t node = 0; return ble_service_uuid_decode(text.c_str(), &node) ? 0 : node; +} static const char* bluetooth_error(BluetoothError error) { switch (error) { case BluetoothError::Success: return "Success"; @@ -579,7 +585,7 @@ struct WinState : std::enable_shared_from_this { auto type = args.AdvertisementType(); if (type != BluetoothLEAdvertisementType::ScannableUndirected && type != BluetoothLEAdvertisementType::NonConnectableUndirected) for (auto const& uuid : args.Advertisement().ServiceUuids()) { - uint64_t peer; if (!ble_service_uuid_decode(to_string(uuid).c_str(), &peer)) { matching = true; break; } + if (service_node(uuid)) { matching = true; break; } } if (!matching) { ++state->scan_foreign; return; } ++state->scan_matching; @@ -590,7 +596,7 @@ struct WinState : std::enable_shared_from_this { state->post("Watcher.Received", 0, [args](WinState& s) { auto advertisement = args.Advertisement(); for (auto const& uuid : advertisement.ServiceUuids()) { - uint64_t peer = 0; if (ble_service_uuid_decode(to_string(uuid).c_str(), &peer)) continue; + uint64_t peer = service_node(uuid); if (!peer) continue; auto ep = s.advertisement_endpoint(args); auto name = to_string(advertisement.LocalName()); uint8_t data[BLE_BROADCAST_MAX]; int len = ble_identity_encode(data, peer, name.c_str()); if (len < 0) len = ble_identity_encode(data, peer, ""); diff --git a/lib/ble/tests/test_ble_winrt.cpp b/lib/ble/tests/test_ble_winrt.cpp index d1a760f1d..ef618167b 100644 --- a/lib/ble/tests/test_ble_winrt.cpp +++ b/lib/ble/tests/test_ble_winrt.cpp @@ -293,6 +293,11 @@ static void pending_shutdown(UASYNC* ua) { int main() { debug_config_init(); debug_set_level(DEBUG_LEVEL_INFO); + for (unsigned bit = 0; bit < 64; ++bit) { + uint64_t node = UINT64_C(1) << bit; char uuid[37]; CHECK(!ble_service_uuid_encode(uuid, node)); + CHECK(service_node(guid(uuid)) == node); + } + CHECK(!service_node(guid(BLE_SERVICE_UUID_FILTER)) && !service_node(guid(BLE_RX_UUID))); init_apartment(apartment_type::multi_threaded); UASYNC* ua = uasync_create(); CHECK(ua); incoming_speed(ua); advertisement_addresses(ua); radio_snapshot(ua); publication_lifecycle(ua);