From 3045322ede81d981c423e75a10a99577fe4b0ffa Mon Sep 17 00:00:00 2001 From: caikaisheng Date: Mon, 12 Jan 2026 20:21:20 +0800 Subject: [PATCH] fix(windows): emit error callback when GetCharacteristic/GetDescriptor fails When GetCharacteristic or GetDescriptor fails (e.g., user cancels Windows BLE pairing dialog), the code was only logging the error but not calling the emit callback to notify JavaScript. This caused the Promise/callback to hang indefinitely. Fixed functions: - Read: now calls mEmit.Read() on GetCharacteristic failure - Write: now calls mEmit.Write() on GetCharacteristic failure - Notify: now calls mEmit.Notify() on GetCharacteristic failure - DiscoverDescriptors: now calls mEmit.DescriptorsDiscovered() on failure - ReadValue: now calls mEmit.ReadValue() on GetDescriptor failure - WriteValue: now calls mEmit.WriteValue() on GetDescriptor failure This ensures JavaScript always receives a callback (success or error), preventing hangs when BLE operations fail due to pairing issues. Co-Authored-By: Claude Opus 4.5 --- lib/win/src/ble_manager.cc | 37 ++++++++++++++++++++++--------------- 1 file changed, 22 insertions(+), 15 deletions(-) diff --git a/lib/win/src/ble_manager.cc b/lib/win/src/ble_manager.cc index 657f4047..19d09915 100644 --- a/lib/win/src/ble_manager.cc +++ b/lib/win/src/ble_manager.cc @@ -579,10 +579,10 @@ bool BLEManager::Read(const std::string& uuid, const winrt::guid& serviceUuid, { peripheral.GetCharacteristic( serviceUuid, characteristicUuid, [=](std::optional characteristic) { + std::string serviceId = toStr(serviceUuid); + std::string characteristicId = toStr(characteristicUuid); if (characteristic) { - std::string serviceId = toStr(serviceUuid); - std::string characteristicId = toStr(characteristicUuid); characteristic->ReadValueAsync(BluetoothCacheMode::Uncached) .Completed( bind2(this, &BLEManager::OnRead, uuid, serviceId, characteristicId)); @@ -590,6 +590,7 @@ bool BLEManager::Read(const std::string& uuid, const winrt::guid& serviceUuid, else { LOGE("GetCharacteristic error"); + mEmit.Read(uuid, serviceId, characteristicId, Data(), false, "GetCharacteristic error"); } }); return true; @@ -631,10 +632,10 @@ bool BLEManager::Write(const std::string& uuid, const winrt::guid& serviceUuid, { peripheral.GetCharacteristic( serviceUuid, characteristicUuid, [=](std::optional characteristic) { + std::string serviceId = toStr(serviceUuid); + std::string characteristicId = toStr(characteristicUuid); if (characteristic) { - std::string serviceId = toStr(serviceUuid); - std::string characteristicId = toStr(characteristicUuid); auto writer = DataWriter(); writer.WriteBytes(data); auto value = writer.DetachBuffer(); @@ -647,6 +648,7 @@ bool BLEManager::Write(const std::string& uuid, const winrt::guid& serviceUuid, else { LOGE("GetCharacteristic error"); + mEmit.Write(uuid, serviceId, characteristicId, "GetCharacteristic error"); } }); return true; @@ -689,10 +691,10 @@ bool BLEManager::Notify(const std::string& uuid, const winrt::guid& serviceUuid, IFDEVICE(device, uuid) { auto onCharacteristic = [=](std::optional characteristic) { + std::string serviceId = toStr(serviceUuid); + std::string characteristicId = toStr(characteristicUuid); if (characteristic) { - std::string serviceId = toStr(serviceUuid); - std::string characteristicId = toStr(characteristicUuid); bool subscribed = mNotifyMap.IsSubscribed(uuid, *characteristic); if (on) @@ -703,7 +705,7 @@ bool BLEManager::Notify(const std::string& uuid, const winrt::guid& serviceUuid, mEmit.Notify(uuid, serviceId, characteristicId, true); return; } - + auto onChanged = bind2(this, &BLEManager::OnValueChanged, uuid); auto token = characteristic->ValueChanged(onChanged); mNotifyMap.Add(uuid, *characteristic, token); @@ -741,6 +743,7 @@ bool BLEManager::Notify(const std::string& uuid, const winrt::guid& serviceUuid, else { LOGE("GetCharacteristic error"); + mEmit.Notify(uuid, serviceId, characteristicId, on, "GetCharacteristic error"); } }; peripheral.GetCharacteristic(serviceUuid, characteristicUuid, onCharacteristic); @@ -787,10 +790,10 @@ bool BLEManager::DiscoverDescriptors(const std::string& uuid, const winrt::guid& { peripheral.GetCharacteristic( serviceUuid, characteristicUuid, [=](std::optional characteristic) { + std::string serviceId = toStr(serviceUuid); + std::string characteristicId = toStr(characteristicUuid); if (characteristic) { - std::string serviceId = toStr(serviceUuid); - std::string characteristicId = toStr(characteristicUuid); auto completed = bind2(this, &BLEManager::OnDescriptorsDiscovered, uuid, serviceId, characteristicId); characteristic->GetDescriptorsAsync(BluetoothCacheMode::Uncached) @@ -799,6 +802,8 @@ bool BLEManager::DiscoverDescriptors(const std::string& uuid, const winrt::guid& else { LOGE("GetCharacteristic error"); + std::vector emptyDescriptors; + mEmit.DescriptorsDiscovered(uuid, serviceId, characteristicId, emptyDescriptors, "GetCharacteristic error"); } }); return true; @@ -836,11 +841,11 @@ bool BLEManager::ReadValue(const std::string& uuid, const winrt::guid& serviceUu peripheral.GetDescriptor( serviceUuid, characteristicUuid, descriptorUuid, [=](std::optional descriptor) { + std::string serviceId = toStr(serviceUuid); + std::string characteristicId = toStr(characteristicUuid); + std::string descriptorId = toStr(descriptorUuid); if (descriptor) { - std::string serviceId = toStr(serviceUuid); - std::string characteristicId = toStr(characteristicUuid); - std::string descriptorId = toStr(descriptorUuid); auto completed = bind2(this, &BLEManager::OnReadValue, uuid, serviceId, characteristicId, descriptorId); descriptor->ReadValueAsync(BluetoothCacheMode::Uncached).Completed(completed); @@ -848,6 +853,7 @@ bool BLEManager::ReadValue(const std::string& uuid, const winrt::guid& serviceUu else { LOGE("descriptor not found"); + mEmit.ReadValue(uuid, serviceId, characteristicId, descriptorId, Data(), "descriptor not found"); } }); return true; @@ -888,11 +894,11 @@ bool BLEManager::WriteValue(const std::string& uuid, const winrt::guid& serviceU IFDEVICE(device, uuid) { auto onDescriptor = [=](std::optional descriptor) { + std::string serviceId = toStr(serviceUuid); + std::string characteristicId = toStr(characteristicUuid); + std::string descriptorId = toStr(descriptorUuid); if (descriptor) { - std::string serviceId = toStr(serviceUuid); - std::string characteristicId = toStr(characteristicUuid); - std::string descriptorId = toStr(descriptorUuid); auto writer = DataWriter(); writer.WriteBytes(data); auto value = writer.DetachBuffer(); @@ -903,6 +909,7 @@ bool BLEManager::WriteValue(const std::string& uuid, const winrt::guid& serviceU else { LOGE("descriptor not found"); + mEmit.WriteValue(uuid, serviceId, characteristicId, descriptorId, "descriptor not found"); } }; peripheral.GetDescriptor(serviceUuid, characteristicUuid, descriptorUuid, onDescriptor);