upstream dev sync + bump to 1.18

This commit is contained in:
liquidraver committed 2026-10-15 20:14:53 +02:00
1 parent ec55eb0f4c
commit 38c59ee10f
14 files changed
+117 -104

No files matched your search

+1 -1
View File
@@ -33,7 +33,7 @@ list(APPEND BOARD_ROOT ${CMAKE_CURRENT_SOURCE_DIR})
# Service advertises (CONFIG_BT_DIS_FW_REV_STR, generated from it below), what the
# GitHub release is tagged/named, and what the Mesh America catalog uses as its
# version key. The release workflow reads this line directly — keep its form.
set(ZEPHCORE_FIRMWARE_VERSION "1.17.7-zephcore")
set(ZEPHCORE_FIRMWARE_VERSION "1.18.0-zephcore")
# ========== Helpers ==========
# Append FILE to the overlay list once, keeping its FIRST position. Position is
+6 -5
View File
@@ -674,20 +674,21 @@ uint32_t RepeaterMesh::getDirectRetransmitDelay(const mesh::Packet* packet) {
return computeAdaptiveDirectDelay(packet);
}
// ZEPHCORE: ours. Also records whether the packet was an unscoped flood.
// ZEPHCORE: ours. Also records whether the packet was an unscoped flood; a
// transport flood with code 0 is one, wildcard deny included (UPSTREAM_TRACKER 01f9293b).
mesh::DispatcherAction RepeaterMesh::onRecvPacket(mesh::Packet* pkt) {
// Determine the request packet's region so sendFloodReply() can echo the same
// scope. Runs for every packet (not just floods) so recv_pkt_region is cleared
// for direct packets instead of inheriting the last flood's region.
recv_pkt_unscoped_flood = (pkt->getRouteType() == ROUTE_TYPE_FLOOD);
if (pkt->getRouteType() == ROUTE_TYPE_TRANSPORT_FLOOD) {
recv_pkt_region = region_map.findMatch(pkt, REGION_DENY_FLOOD);
} else if (pkt->getRouteType() == ROUTE_TYPE_FLOOD) {
recv_pkt_unscoped_flood = mesh::isUnscopedFlood(pkt);
if (recv_pkt_unscoped_flood) {
if (region_map.getWildcard().flags & REGION_DENY_FLOOD) {
recv_pkt_region = nullptr;
} else {
recv_pkt_region = &region_map.getWildcard();
}
} else if (pkt->getRouteType() == ROUTE_TYPE_TRANSPORT_FLOOD) {
recv_pkt_region = region_map.findMatch(pkt, REGION_DENY_FLOOD);
} else {
recv_pkt_region = nullptr;
}
+8 -5
View File
@@ -354,20 +354,21 @@ bool RoomServerMesh::allowPacketForward(const mesh::Packet* /*packet*/) {
return false;
}
// ZEPHCORE: ours. Also records whether the packet was an unscoped flood.
// ZEPHCORE: ours. Also records whether the packet was an unscoped flood; a
// transport flood with code 0 is one, wildcard deny included (UPSTREAM_TRACKER 01f9293b).
mesh::DispatcherAction RoomServerMesh::onRecvPacket(mesh::Packet* pkt) {
// Determine the request packet's region so sendFloodReply() can echo the same
// scope. Runs for every packet (not just floods) so recv_pkt_region is cleared
// for direct packets instead of inheriting the last flood's region.
recv_pkt_unscoped_flood = (pkt->getRouteType() == ROUTE_TYPE_FLOOD);
if (pkt->getRouteType() == ROUTE_TYPE_TRANSPORT_FLOOD) {
recv_pkt_region = region_map.findMatch(pkt, REGION_DENY_FLOOD);
} else if (pkt->getRouteType() == ROUTE_TYPE_FLOOD) {
recv_pkt_unscoped_flood = mesh::isUnscopedFlood(pkt);
if (recv_pkt_unscoped_flood) {
if (region_map.getWildcard().flags & REGION_DENY_FLOOD) {
recv_pkt_region = nullptr;
} else {
recv_pkt_region = &region_map.getWildcard();
}
} else if (pkt->getRouteType() == ROUTE_TYPE_TRANSPORT_FLOOD) {
recv_pkt_region = region_map.findMatch(pkt, REGION_DENY_FLOOD);
} else {
recv_pkt_region = nullptr;
}
@@ -1003,6 +1004,8 @@ void RoomServerMesh::handleCommand(uint32_t sender_timestamp, char* command, cha
addSystemPost(msg);
strcpy(reply, "OK");
}
} else if (memcmp(command, "set repeat on", 13) == 0) {
strcpy(reply, "ERR - repeat now deprecated"); // a room server never forwards (upstream 8579c667, 481f72ca)
} else {
_cli.handleCommand(sender_timestamp, command, reply);
}
+1
View File
@@ -189,6 +189,7 @@ int RegionMap::getTransportKeysFor(const RegionEntry& src, TransportKey dest[],
}
RegionEntry* RegionMap::findMatch(mesh::Packet* packet, uint8_t mask) {
if (packet->transport_codes[0] == 0) return &wildcard;
for (int i = 0; i < num_regions; i++) {
auto region = &regions[i];
if ((region->flags & mask) == 0) { // does region allow this? (per 'mask' param)
+12 -2
View File
@@ -14,12 +14,22 @@
namespace mesh {
/**
* An un-scoped flood: ROUTE_TYPE_FLOOD, or a transport flood whose first code
* is 0 (no Region computes 0; upstream 01f9293b treats it as un-scoped).
*/
inline bool isUnscopedFlood(const Packet *packet)
{
return packet->getRouteType() == ROUTE_TYPE_FLOOD
|| (packet->getRouteType() == ROUTE_TYPE_TRANSPORT_FLOOD && packet->transport_codes[0] == 0);
}
/**
* Test a flood packet against the configured hop limits.
*
* @param packet inbound flood packet (caller has already checked isRouteFlood())
* @param flood_max hop ceiling for any flood packet
* @param flood_max_unscoped hop ceiling for un-scoped (ROUTE_TYPE_FLOOD) packets;
* @param flood_max_unscoped hop ceiling for un-scoped packets (isUnscopedFlood());
* may be clamped lower than scoped/transport floods
* @param flood_max_advert hop ceiling for ADVERT floods, typically tighter still
* so advert churn stays local
@@ -31,7 +41,7 @@ inline bool isFloodHopLimitExceeded(const Packet *packet, uint8_t flood_max,
uint8_t hops = packet->getPathHashCount();
if (hops >= flood_max) return true;
if (packet->getRouteType() == ROUTE_TYPE_FLOOD && hops >= flood_max_unscoped) return true;
if (isUnscopedFlood(packet) && hops >= flood_max_unscoped) return true;
if (packet->getPayloadType() == PAYLOAD_TYPE_ADVERT && hops >= flood_max_advert) return true;
return false;
}
+1 -1
View File
@@ -34,7 +34,7 @@ class Mesh : public Dispatcher {
void removeSelfFromPath(Packet* packet);
void routeDirectRecvAcks(Packet* packet, uint32_t delay_millis);
//void routeRecvAcks(Packet* packet, uint32_t delay_millis);
DispatcherAction forwardMultipartDirect(Packet* pkt);
DispatcherAction forwardMultipartDirect(Packet* pkt, uint32_t delay_millis);
protected:
// ZEPHCORE: adaptive contention window — dupe tracking, reactive backoff,
+6 -6
View File
@@ -142,13 +142,14 @@ DispatcherAction Mesh::onRecvPacket(Packet* pkt) {
}
if (self_id.isHashMatch(pkt->path, pkt->getPathHashSize()) && allowPacketForward(pkt)) {
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);
removeSelfFromPath(pkt);
routeDirectRecvAcks(pkt, 0);
routeDirectRecvAcks(pkt, d);
}
return ACTION_RELEASE;
}
@@ -157,7 +158,6 @@ DispatcherAction Mesh::onRecvPacket(Packet* pkt) {
_tables->markSeen(pkt);
removeSelfFromPath(pkt);
uint32_t d = getDirectRetransmitDelay(pkt);
return ACTION_RETRANSMIT_DELAYED(0, d); // Routed traffic is HIGHEST priority
}
}
@@ -430,7 +430,7 @@ DispatcherAction Mesh::routeRecvPacket(Packet* packet) {
return ACTION_RELEASE;
}
DispatcherAction Mesh::forwardMultipartDirect(Packet* pkt) {
DispatcherAction Mesh::forwardMultipartDirect(Packet* pkt, uint32_t delay_millis) {
uint8_t remaining = pkt->payload[0] >> 4; // num of packets in this multipart sequence still to be sent
uint8_t type = pkt->payload[0] & 0x0F;
@@ -444,7 +444,7 @@ DispatcherAction Mesh::forwardMultipartDirect(Packet* pkt) {
if (!_tables->wasSeen(&tmp)) { // don't retransmit!
_tables->markSeen(&tmp);
removeSelfFromPath(&tmp);
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;
@@ -454,13 +454,13 @@ 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->path_len = Packet::copyPath(a1->path, packet->path, packet->path_len);
a1->header &= ~PH_ROUTE_MASK;
a1->header |= ROUTE_TYPE_DIRECT;
sendPacket(a1, 0, delay_millis);
delay_millis += 300;
}
extra--;
}