mirror of
https://github.com/liquidraver/ZephCore.git
synced 2026-09-02 08:43:43 +00:00
rx_boost state is undefined at boot (minor fix)
every LBT-retried flood packet loses its priority (fixed) witching between LBT and non-LBT mode (or any cad.mode change) could silently skip full reconfiguration and leave the radio in the wrong mode (fixed)
This commit is contained in:
@@ -256,7 +256,8 @@ static bool configParamsEqual(const struct lora_modem_config &a,
|
||||
a.tx_power == b.tx_power &&
|
||||
a.tx == b.tx &&
|
||||
a.iq_inverted == b.iq_inverted &&
|
||||
a.public_network == b.public_network;
|
||||
a.public_network == b.public_network &&
|
||||
a.cad.mode == b.cad.mode;
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -275,6 +276,7 @@ static bool onlyDirectionDiffers(const struct lora_modem_config &a,
|
||||
a.tx_power == b.tx_power &&
|
||||
a.iq_inverted == b.iq_inverted &&
|
||||
a.public_network == b.public_network &&
|
||||
a.cad.mode == b.cad.mode &&
|
||||
a.tx != b.tx;
|
||||
}
|
||||
|
||||
@@ -363,6 +365,13 @@ void LoRaRadioBase::begin()
|
||||
|
||||
startReceive();
|
||||
|
||||
/* Sync _rx_boost_enabled to the driver. The driver initialises its own
|
||||
* rx_boost_enabled flag from DTS (rx-boosted property), which may differ
|
||||
* from our constructor default (true). Push our intent now so the
|
||||
* hardware state matches _rx_boost_enabled from the moment begin()
|
||||
* returns, before the caller applies prefs via setRxBoost(). */
|
||||
hwSetRxBoost(_rx_boost_enabled);
|
||||
|
||||
uint32_t freq = _prefs ? (uint32_t)(_prefs->freq * 1000000.0f)
|
||||
: LoRaConfig::FREQ_HZ;
|
||||
uint8_t sf = _prefs ? _prefs->sf : LoRaConfig::SPREADING_FACTOR;
|
||||
|
||||
@@ -28,6 +28,7 @@ public:
|
||||
virtual Packet *removeOutboundByIdx(int i) = 0;
|
||||
virtual uint32_t getOutboundSchedule(int i) const = 0;
|
||||
virtual bool rescheduleOutbound(int i, uint32_t new_scheduled_for) = 0;
|
||||
virtual uint8_t peekNextOutboundPriority(uint32_t now) const = 0;
|
||||
virtual void queueInbound(Packet *packet, uint32_t scheduled_for) = 0;
|
||||
virtual Packet *getNextInbound(uint32_t now) = 0;
|
||||
};
|
||||
@@ -48,6 +49,7 @@ typedef uint32_t DispatcherAction;
|
||||
|
||||
class Dispatcher {
|
||||
Packet *outbound;
|
||||
uint8_t outbound_priority;
|
||||
uint32_t outbound_expiry, outbound_start, total_air_time, rx_air_time;
|
||||
uint32_t next_tx_time;
|
||||
uint32_t cad_busy_start;
|
||||
|
||||
@@ -22,6 +22,7 @@ public:
|
||||
Packet *removeOutboundByIdx(int i) override;
|
||||
uint32_t getOutboundSchedule(int i) const override;
|
||||
bool rescheduleOutbound(int i, uint32_t new_scheduled_for) override;
|
||||
uint8_t peekNextOutboundPriority(uint32_t now) const override;
|
||||
void queueInbound(Packet *packet, uint32_t scheduled_for) override;
|
||||
Packet *getNextInbound(uint32_t now) override;
|
||||
};
|
||||
|
||||
@@ -28,6 +28,7 @@ Dispatcher::Dispatcher(Radio &radio, MillisecondClock &ms, PacketManager &mgr)
|
||||
: _radio(&radio), _ms(&ms), _mgr(&mgr)
|
||||
{
|
||||
outbound = nullptr;
|
||||
outbound_priority = 0;
|
||||
total_air_time = rx_air_time = 0;
|
||||
next_tx_time = 0;
|
||||
cad_busy_start = 0;
|
||||
@@ -410,6 +411,10 @@ void Dispatcher::checkSend()
|
||||
}
|
||||
cad_busy_start = 0;
|
||||
|
||||
/* Snapshot the priority of the packet we're about to dequeue so it
|
||||
* can be preserved if the send attempt fails and we need to re-queue.
|
||||
* Must be called before getNextOutbound() removes the entry. */
|
||||
outbound_priority = _mgr->peekNextOutboundPriority(now);
|
||||
outbound = _mgr->getNextOutbound(now);
|
||||
if (outbound) {
|
||||
uint8_t raw[MAX_TRANS_UNIT];
|
||||
@@ -460,7 +465,7 @@ void Dispatcher::checkSend()
|
||||
LOG_DBG("checkSend: final gate blocked TX (isReceiving=%d, isRadioReady=%d, inRecvMode=%d)",
|
||||
(int)final_is_receiving, (int)final_is_radio_ready,
|
||||
(int)_radio->isInRecvMode());
|
||||
_mgr->queueOutbound(outbound, 0, futureMillis((int)retry));
|
||||
_mgr->queueOutbound(outbound, outbound_priority, futureMillis((int)retry));
|
||||
outbound = nullptr;
|
||||
if (_tx_queued_cb) {
|
||||
_tx_queued_cb(retry, _tx_queued_user_data);
|
||||
@@ -473,7 +478,7 @@ void Dispatcher::checkSend()
|
||||
uint32_t retry = getCADFailRetryDelay();
|
||||
LOG_ERR("checkSend: startSendRaw failed! re-queuing delay=%u", retry);
|
||||
logTxFail(outbound, outbound->getRawLength());
|
||||
_mgr->queueOutbound(outbound, 0, futureMillis((int)retry));
|
||||
_mgr->queueOutbound(outbound, outbound_priority, futureMillis((int)retry));
|
||||
outbound = nullptr;
|
||||
if (_tx_queued_cb) {
|
||||
_tx_queued_cb(retry, _tx_queued_user_data);
|
||||
|
||||
@@ -96,6 +96,17 @@ struct PacketQueue {
|
||||
return (i < _num) ? _schedule_table[i] : 0;
|
||||
}
|
||||
|
||||
/* Priority of the next packet that get(now) would return, without
|
||||
* removing it. Returns 0xFF if no due packet exists. */
|
||||
uint8_t peekPriority(uint32_t now) const {
|
||||
uint8_t best = 0xFF;
|
||||
for (int j = 0; j < _num; j++) {
|
||||
if ((int32_t)(_schedule_table[j] - now) > 0) continue;
|
||||
if (_pri_table[j] < best) best = _pri_table[j];
|
||||
}
|
||||
return best;
|
||||
}
|
||||
|
||||
bool reschedule(int i, uint32_t new_scheduled_for) {
|
||||
if (i >= _num) return false;
|
||||
_schedule_table[i] = new_scheduled_for;
|
||||
@@ -193,6 +204,11 @@ bool StaticPoolPacketManager::rescheduleOutbound(int i, uint32_t new_scheduled_f
|
||||
return _send_queue.reschedule(i, new_scheduled_for);
|
||||
}
|
||||
|
||||
uint8_t StaticPoolPacketManager::peekNextOutboundPriority(uint32_t now) const
|
||||
{
|
||||
return _send_queue.peekPriority(now);
|
||||
}
|
||||
|
||||
void StaticPoolPacketManager::queueInbound(Packet *packet, uint32_t scheduled_for)
|
||||
{
|
||||
if (!_rx_queue.add(packet, 0, scheduled_for)) {
|
||||
|
||||
Reference in New Issue
Block a user