LoraApi callbacks refactored to events (#632)

This commit is contained in:
Ken Van Hoeylandt
2026-08-28 18:56:12 +02:00
committed by GitHub
parent b7577f2328
commit d2442bedb4
7 changed files with 612 additions and 273 deletions
@@ -8,7 +8,6 @@
#include <tactility/drivers/gpio_controller.h>
#include <tactility/log.h>
#include <algorithm>
#include <initializer_list>
#include <RadioLib.h>
@@ -345,12 +344,9 @@ void Sx1262Radio::setState(enum LoraRadioState newState) {
}
LOG_I(TAG, "State: %s -> %s", toString(state), toString(newState));
state = newState;
auto callbacks = stateCallbacks;
unlock();
for (const auto& entry : callbacks) {
entry.callback(settings.device, entry.context, newState);
}
lora_state_event_emit(settings.device, newState);
}
error_t Sx1262Radio::setModulation(enum LoraModulation newModulation) {
@@ -377,76 +373,12 @@ enum LoraModulation Sx1262Radio::getModulation() const {
return result;
}
// Callbacks are invoked on a snapshot of the list, with the radio mutex released:
// consumers take their own locks in callbacks and also call into this API while
// holding those locks, so invoking under the radio mutex would set up an AB-BA
// deadlock between the radio thread and any consumer thread.
void Sx1262Radio::publishRx(const struct LoraRxPacket& packet) {
lock();
auto callbacks = rxCallbacks;
unlock();
for (const auto& entry : callbacks) {
entry.callback(settings.device, entry.context, &packet);
}
error_t Sx1262Radio::publishRx(const uint8_t* data, size_t length, float rssi, float snr) {
return lora_rx_event_emit(settings.device, data, length, rssi, snr);
}
void Sx1262Radio::publishTx(LoraTxId id, enum LoraTransmissionState txState) {
lock();
auto callbacks = txCallbacks;
unlock();
for (const auto& entry : callbacks) {
entry.callback(settings.device, entry.context, id, txState);
}
}
error_t Sx1262Radio::addRxCallback(void* context, LoraRxCallback callback) {
lock();
rxCallbacks.push_back({context, callback});
unlock();
return ERROR_NONE;
}
error_t Sx1262Radio::removeRxCallback(LoraRxCallback callback) {
lock();
const auto old_size = rxCallbacks.size();
std::erase_if(rxCallbacks, [callback](const auto& entry) { return entry.callback == callback; });
const auto result = (rxCallbacks.size() == old_size) ? ERROR_NOT_FOUND : ERROR_NONE;
unlock();
return result;
}
error_t Sx1262Radio::addStateCallback(void* context, LoraStateCallback callback) {
lock();
stateCallbacks.push_back({context, callback});
unlock();
return ERROR_NONE;
}
error_t Sx1262Radio::removeStateCallback(LoraStateCallback callback) {
lock();
const auto old_size = stateCallbacks.size();
std::erase_if(stateCallbacks, [callback](const auto& entry) { return entry.callback == callback; });
const auto result = (stateCallbacks.size() == old_size) ? ERROR_NOT_FOUND : ERROR_NONE;
unlock();
return result;
}
error_t Sx1262Radio::addTxCallback(void* context, LoraTxCallback callback) {
lock();
txCallbacks.push_back({context, callback});
unlock();
return ERROR_NONE;
}
error_t Sx1262Radio::removeTxCallback(LoraTxCallback callback) {
lock();
const auto old_size = txCallbacks.size();
std::erase_if(txCallbacks, [callback](const auto& entry) { return entry.callback == callback; });
const auto result = (txCallbacks.size() == old_size) ? ERROR_NOT_FOUND : ERROR_NONE;
unlock();
return result;
error_t Sx1262Radio::publishTx(LoraTxId id, enum LoraTransmissionState txState) {
return lora_tx_event_emit(settings.device, id, txState);
}
// endregion
@@ -952,15 +884,10 @@ void Sx1262Radio::doReceive() {
} else if (rxSize == 0) {
// Empty read: skip silently to avoid log flooding on spurious IRQs.
} else {
const struct LoraRxPacket packet = {
.data = data.data(),
.length = data.size(),
.rssi = radio.getRSSI(),
.snr = radio.getSNR(),
};
LOG_I(TAG, "RX: %u bytes, RSSI %.1f dBm, SNR %.1f dB", (unsigned)packet.length, packet.rssi, packet.snr);
publishRx(packet);
const float rssi = radio.getRSSI();
const float snr = radio.getSNR();
LOG_I(TAG, "RX: %u bytes, RSSI %.1f dBm, SNR %.1f dB", (unsigned)data.size(), rssi, snr);
publishRx(data.data(), data.size(), rssi, snr);
radio.finishReceive();
}
}