diff --git a/hal_st/middlewares/ble_middleware/GattClientSt.cpp b/hal_st/middlewares/ble_middleware/GattClientSt.cpp index dbcf1d76..06d07aab 100644 --- a/hal_st/middlewares/ble_middleware/GattClientSt.cpp +++ b/hal_st/middlewares/ble_middleware/GattClientSt.cpp @@ -18,79 +18,125 @@ namespace hal void GattClientSt::StartServiceDiscovery() { - onDiscoveryCompletion = [](services::GattClientDiscoveryObserver& observer) - { - observer.ServiceDiscoveryComplete(); - }; + claimerDiscovery.Claim([this]() + { + onDiscoveryCompletion = [this]() + { + infra::Subject::NotifyObservers([](auto& observer) + { + observer.ServiceDiscoveryComplete(); + }); + + claimerDiscovery.Release(); + }; - aci_gatt_disc_all_primary_services(connectionHandle); + aci_gatt_disc_all_primary_services(connectionHandle); + }); } void GattClientSt::StartCharacteristicDiscovery(services::AttAttribute::Handle handle, services::AttAttribute::Handle endHandle) { - onDiscoveryCompletion = [](services::GattClientDiscoveryObserver& observer) - { - observer.CharacteristicDiscoveryComplete(); - }; + claimerDiscovery.Claim([this, handle, endHandle]() + { + onDiscoveryCompletion = [this]() + { + infra::Subject::NotifyObservers([](auto& observer) + { + observer.CharacteristicDiscoveryComplete(); + }); - aci_gatt_disc_all_char_of_service(connectionHandle, handle, endHandle); + claimerDiscovery.Release(); + }; + + aci_gatt_disc_all_char_of_service(connectionHandle, handle, endHandle); + }); } void GattClientSt::StartDescriptorDiscovery(services::AttAttribute::Handle handle, services::AttAttribute::Handle endHandle) { - onDiscoveryCompletion = [](services::GattClientDiscoveryObserver& observer) - { - observer.DescriptorDiscoveryComplete(); - }; + claimerDiscovery.Claim([this, handle, endHandle]() + { + onDiscoveryCompletion = [this]() + { + infra::Subject::NotifyObservers([](auto& observer) + { + observer.DescriptorDiscoveryComplete(); + }); + + claimerDiscovery.Release(); + }; - aci_gatt_disc_all_char_desc(connectionHandle, handle, endHandle); + aci_gatt_disc_all_char_desc(connectionHandle, handle, endHandle); + }); } void GattClientSt::Read(const services::GattClientCharacteristicOperationsObserver& characteristic, const infra::Function& onResponse) { this->onResponse = onResponse; - aci_gatt_read_char_value(connectionHandle, characteristic.CharacteristicValueHandle()); + claimerCharacteristicOperations.Claim([this, &characteristic]() + { + aci_gatt_read_char_value(connectionHandle, characteristic.CharacteristicValueHandle()); + }); } void GattClientSt::Write(const services::GattClientCharacteristicOperationsObserver& characteristic, infra::ConstByteRange data, const infra::Function& onDone) { this->onDone = onDone; - aci_gatt_write_char_value(connectionHandle, characteristic.CharacteristicValueHandle(), data.size(), data.cbegin()); + claimerCharacteristicOperations.Claim([this, &characteristic, data]() + { + aci_gatt_write_char_value(connectionHandle, characteristic.CharacteristicValueHandle(), data.size(), data.cbegin()); + }); } void GattClientSt::WriteWithoutResponse(const services::GattClientCharacteristicOperationsObserver& characteristic, infra::ConstByteRange data) { - aci_gatt_write_without_resp(connectionHandle, characteristic.CharacteristicValueHandle(), data.size(), data.cbegin()); + claimerCharacteristicOperations.Claim([this, &characteristic, data]() + { + aci_gatt_write_without_resp(connectionHandle, characteristic.CharacteristicValueHandle(), data.size(), data.cbegin()); + claimerCharacteristicOperations.Release(); + }); } void GattClientSt::EnableNotification(const services::GattClientCharacteristicOperationsObserver& characteristic, const infra::Function& onDone) { this->onDone = onDone; - WriteCharacteristicDescriptor(characteristic, services::GattCharacteristic::PropertyFlags::notify, services::GattDescriptor::ClientCharacteristicConfiguration::CharacteristicValue::enableNotification); + claimerCharacteristicOperations.Claim([this, &characteristic]() + { + WriteCharacteristicDescriptor(characteristic, services::GattCharacteristic::PropertyFlags::notify, services::GattDescriptor::ClientCharacteristicConfiguration::CharacteristicValue::enableNotification); + }); } void GattClientSt::DisableNotification(const services::GattClientCharacteristicOperationsObserver& characteristic, const infra::Function& onDone) { this->onDone = onDone; - WriteCharacteristicDescriptor(characteristic, services::GattCharacteristic::PropertyFlags::notify, services::GattDescriptor::ClientCharacteristicConfiguration::CharacteristicValue::disable); + claimerCharacteristicOperations.Claim([this, &characteristic]() + { + WriteCharacteristicDescriptor(characteristic, services::GattCharacteristic::PropertyFlags::notify, services::GattDescriptor::ClientCharacteristicConfiguration::CharacteristicValue::disable); + }); } void GattClientSt::EnableIndication(const services::GattClientCharacteristicOperationsObserver& characteristic, const infra::Function& onDone) { this->onDone = onDone; - WriteCharacteristicDescriptor(characteristic, services::GattCharacteristic::PropertyFlags::indicate, services::GattDescriptor::ClientCharacteristicConfiguration::CharacteristicValue::enableIndication); + claimerCharacteristicOperations.Claim([this, &characteristic]() + { + WriteCharacteristicDescriptor(characteristic, services::GattCharacteristic::PropertyFlags::indicate, services::GattDescriptor::ClientCharacteristicConfiguration::CharacteristicValue::enableIndication); + }); } void GattClientSt::DisableIndication(const services::GattClientCharacteristicOperationsObserver& characteristic, const infra::Function& onDone) { this->onDone = onDone; - WriteCharacteristicDescriptor(characteristic, services::GattCharacteristic::PropertyFlags::indicate, services::GattDescriptor::ClientCharacteristicConfiguration::CharacteristicValue::disable); + claimerCharacteristicOperations.Claim([this, &characteristic]() + { + WriteCharacteristicDescriptor(characteristic, services::GattCharacteristic::PropertyFlags::indicate, services::GattDescriptor::ClientCharacteristicConfiguration::CharacteristicValue::disable); + }); } void GattClientSt::HciEvent(hci_event_pckt& event) @@ -204,9 +250,12 @@ namespace hal really_assert(gattProcedureEvent.Connection_Handle == connectionHandle); if (onDiscoveryCompletion) - infra::Subject::NotifyObservers(std::exchange(onDiscoveryCompletion, nullptr)); + onDiscoveryCompletion(); else if (onDone) - std::exchange(onDone, nullptr)(); + { + onDone(); + claimerCharacteristicOperations.Release(); + } } } @@ -245,7 +294,10 @@ namespace hal really_assert(attReadResponse.Connection_Handle == connectionHandle); if (onResponse) - std::exchange(onResponse, nullptr)(data); + { + onResponse(data); + claimerCharacteristicOperations.Release(); + } } void GattClientSt::HandleGattIndicationEvent(evt_blecore_aci* vendorEvent) diff --git a/hal_st/middlewares/ble_middleware/GattClientSt.hpp b/hal_st/middlewares/ble_middleware/GattClientSt.hpp index b81dc481..478de56f 100644 --- a/hal_st/middlewares/ble_middleware/GattClientSt.hpp +++ b/hal_st/middlewares/ble_middleware/GattClientSt.hpp @@ -3,6 +3,7 @@ #include "ble/ble.h" #include "hal_st/middlewares/ble_middleware/HciEventObserver.hpp" +#include "infra/event/ClaimableResource.hpp" #include "infra/stream/ByteInputStream.hpp" #include "infra/util/AutoResetFunction.hpp" #include "infra/util/BoundedVector.hpp" @@ -75,9 +76,13 @@ namespace hal static constexpr uint16_t invalidConnection = 0xffff; - infra::Function onDiscoveryCompletion; + infra::AutoResetFunction onDiscoveryCompletion; infra::AutoResetFunction onResponse; infra::AutoResetFunction onDone; + + infra::ClaimableResource resource; + infra::ClaimableResource::Claimer claimerDiscovery{ resource }; + infra::ClaimableResource::Claimer::WithSize<2 * sizeof(services::GattClientDiscovery&) + sizeof(infra::ByteRange)> claimerCharacteristicOperations{ resource }; }; }