Merge meshcore-dev dev with routing, WiFi and power-policy compatibility
Integrate upstream 1.18.0, delayed direct ACK forwarding, zero-scope routing, Waveshare LR1121 and dynamic WiFi variants. Preserve fork chemistry-aware power management and bounded multi-interface UI; retain retry/dedup safety while adding upstream ACK delay. Qualify LR1121 band power and HP-only Morse handling with native regressions.
This commit is contained in:
commit
285267e3a1
32 files changed
+765
-27
No files matched your search
+6
-6
@@ -1145,13 +1145,14 @@ DispatcherAction Mesh::onRecvPacket(Packet* pkt) {
|
||||
removePathPrefix(pkt, pkt->getPathHashCount());
|
||||
} else if (self_id.isHashMatch(pkt->path, pkt->getPathHashSize()) || maybeShortCircuitDirect(pkt)) {
|
||||
if (allowPacketForward(pkt)) {
|
||||
const uint32_t d = getDirectRetransmitDelay(pkt);
|
||||
if (pkt->getPayloadType() == PAYLOAD_TYPE_MULTIPART) {
|
||||
return forwardMultipartDirect(pkt);
|
||||
return forwardMultipartDirect(pkt, d);
|
||||
} else if (pkt->getPayloadType() == PAYLOAD_TYPE_ACK) {
|
||||
if (!_tables->wasSeen(pkt)) { // don't retransmit!
|
||||
_tables->markSeen(pkt);
|
||||
removePathPrefix(pkt, 1);
|
||||
routeDirectRecvAcks(pkt, 0);
|
||||
routeDirectRecvAcks(pkt, d);
|
||||
}
|
||||
return ACTION_RELEASE;
|
||||
}
|
||||
@@ -1163,7 +1164,6 @@ DispatcherAction Mesh::onRecvPacket(Packet* pkt) {
|
||||
&& hasValidEncryptedPayloadLength(pkt->payload_len, 2);
|
||||
removePathPrefix(pkt, 1);
|
||||
|
||||
uint32_t d = getDirectRetransmitDelay(pkt);
|
||||
maybeScheduleDirectRetry(pkt, 0, final_hop_retry);
|
||||
return ACTION_RETRANSMIT_DELAYED(0, d); // Routed traffic is HIGHEST priority
|
||||
}
|
||||
@@ -1563,7 +1563,7 @@ DispatcherAction Mesh::routeRecvPacket(Packet* packet) {
|
||||
return ACTION_RELEASE;
|
||||
}
|
||||
|
||||
DispatcherAction Mesh::forwardMultipartDirect(Packet* pkt) {
|
||||
DispatcherAction Mesh::forwardMultipartDirect(Packet* pkt, uint32_t delay_millis) {
|
||||
if (pkt == NULL || pkt->payload_len < 1) {
|
||||
return ACTION_RELEASE;
|
||||
}
|
||||
@@ -1580,7 +1580,7 @@ DispatcherAction Mesh::forwardMultipartDirect(Packet* pkt) {
|
||||
tmp.payload_len = pkt->payload_len - 1;
|
||||
memcpy(tmp.payload, &pkt->payload[1], tmp.payload_len);
|
||||
removePathPrefix(&tmp, 1);
|
||||
routeDirectRecvAcks(&tmp, ((uint32_t)remaining + 1) * 300); // expect multipart ACKs 300ms apart (x2)
|
||||
routeDirectRecvAcks(&tmp, delay_millis + ((uint32_t)remaining + 1) * 300); // expect multipart ACKs 300ms apart (x2)
|
||||
}
|
||||
}
|
||||
return ACTION_RELEASE;
|
||||
@@ -1590,7 +1590,6 @@ void Mesh::routeDirectRecvAcks(Packet* packet, uint32_t delay_millis) {
|
||||
if (!packet->isMarkedDoNotRetransmit()) {
|
||||
uint8_t extra = getExtraAckTransmitCount();
|
||||
while (extra > 0) {
|
||||
delay_millis += getDirectRetransmitDelay(packet) + 300;
|
||||
auto a1 = createMultiAck(packet->payload, packet->payload_len, extra);
|
||||
if (a1) {
|
||||
a1->radio_reply = false; // relayed ACK, not a local response
|
||||
@@ -1599,6 +1598,7 @@ void Mesh::routeDirectRecvAcks(Packet* packet, uint32_t delay_millis) {
|
||||
a1->header |= ROUTE_TYPE_DIRECT;
|
||||
maybeScheduleDirectRetry(a1, 0);
|
||||
sendPacket(a1, 0, delay_millis);
|
||||
delay_millis += 300;
|
||||
}
|
||||
extra--;
|
||||
}
|
||||
|
||||
+1
-1
@@ -216,7 +216,7 @@ class Mesh : public Dispatcher {
|
||||
void decayOtaRelayBackoff();
|
||||
void serviceLoopMaintenance();
|
||||
//void routeRecvAcks(Packet* packet, uint32_t delay_millis);
|
||||
DispatcherAction forwardMultipartDirect(Packet* pkt);
|
||||
DispatcherAction forwardMultipartDirect(Packet* pkt, uint32_t delay_millis);
|
||||
|
||||
protected:
|
||||
// Roles with lazily persisted state can veto an OTA reset until that state
|
||||
|
||||
@@ -288,6 +288,7 @@ int RegionMap::getTransportKeysFor(const RegionEntry& src, TransportKey dest[],
|
||||
}
|
||||
|
||||
RegionEntry* RegionMap::findMatch(const mesh::Packet* packet, uint8_t mask) {
|
||||
if (packet->transport_codes[0] == 0) return &wildcard;
|
||||
for (int i = 0; i < num_regions; i++) {
|
||||
auto region = ®ions[i];
|
||||
if ((region->flags & mask) == 0) { // does region allow this? (per 'mask' param)
|
||||
|
||||
@@ -12,6 +12,8 @@ class CustomLR1121 : public LR1121 {
|
||||
bool _headerSeen = false;
|
||||
bool _rx_boosted = false;
|
||||
LR11x0MorseRfSwitch _morse_rf_switch;
|
||||
int8_t _txPower = 0;
|
||||
bool _txPowerSet = false;
|
||||
|
||||
public:
|
||||
CustomLR1121(Module *mod) : LR1121(mod) { }
|
||||
@@ -70,6 +72,33 @@ class CustomLR1121 : public LR1121 {
|
||||
return len;
|
||||
}
|
||||
|
||||
using LR1121::setOutputPower;
|
||||
using LR1121::setFrequency;
|
||||
|
||||
int16_t setOutputPower(int8_t power) override {
|
||||
#ifdef LR1121_FORCE_HP_PA
|
||||
const bool force_hp = true; // boards with only RFO_HP_LF wired: never select the LP PA
|
||||
#else
|
||||
const bool force_hp = false;
|
||||
#endif
|
||||
// clip to the active PA's range (HF PA tops out at 13 dBm) rather than fail and keep the other band's PA
|
||||
int8_t clipped = power;
|
||||
checkOutputPower(power, &clipped, force_hp);
|
||||
int16_t state = LR1121::setOutputPower(clipped, force_hp);
|
||||
if (state == RADIOLIB_ERR_NONE) {
|
||||
_txPower = power;
|
||||
_txPowerSet = true;
|
||||
}
|
||||
return state;
|
||||
}
|
||||
|
||||
int16_t setFrequency(float freq) override {
|
||||
int16_t state = LR1121::setFrequency(freq);
|
||||
// PA selection depends on the band, and set radio / tempradio don't call setTxPower
|
||||
if (state == RADIOLIB_ERR_NONE && _txPowerSet) state = setOutputPower(_txPower);
|
||||
return state;
|
||||
}
|
||||
|
||||
float getFreqMHz() const { return freqMHz; }
|
||||
|
||||
int16_t setRxBoostedGainMode(bool en) {
|
||||
|
||||
@@ -54,8 +54,17 @@ protected:
|
||||
if (!_board->prepareRadioFrequency(frequency_mhz)) return RADIOLIB_ERR_INVALID_FREQUENCY;
|
||||
auto* radio = static_cast<CustomLR1121*>(_radio);
|
||||
const int16_t status = radio->setFrequency(frequency_mhz);
|
||||
return status == RADIOLIB_ERR_NONE
|
||||
? radio->setOutputPower(_dbm_valid ? _cur_dbm : LORA_TX_POWER, false, 304) : status;
|
||||
if (status != RADIOLIB_ERR_NONE) return status;
|
||||
#ifdef LR1121_FORCE_HP_PA
|
||||
const bool force_hp = true;
|
||||
#else
|
||||
const bool force_hp = false;
|
||||
#endif
|
||||
// Preserve the Morse ramp while honoring HP-only wiring and the HF PA's
|
||||
// 13 dBm ceiling, just like the normal packet-power path.
|
||||
int8_t clipped = _dbm_valid ? _cur_dbm : LORA_TX_POWER;
|
||||
radio->checkOutputPower(clipped, &clipped, force_hp);
|
||||
return radio->setOutputPower(clipped, force_hp, 304);
|
||||
}
|
||||
bool restoreCarrierWaveModem() override {
|
||||
if (_morse_rx_fsk_mode) {
|
||||
|
||||
Reference in new issue
Block a user