mirror of
https://github.com/liquidraver/ZephCore.git
synced 2026-09-17 08:24:27 +00:00
comment overhaul
This commit is contained in:
@@ -1,6 +1,6 @@
|
||||
/*
|
||||
* SPDX-License-Identifier: Apache-2.0
|
||||
* ZephCore MainBoard interface - matches MeshCore.h
|
||||
* ZephCore MainBoard interface
|
||||
*/
|
||||
|
||||
#pragma once
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
/*
|
||||
* SPDX-License-Identifier: Apache-2.0
|
||||
* ZephCore clock interfaces - matches Dispatcher.h / MeshCore.h
|
||||
* ZephCore clock interfaces
|
||||
*/
|
||||
|
||||
#pragma once
|
||||
|
||||
@@ -1,12 +1,9 @@
|
||||
/*
|
||||
* SPDX-License-Identifier: Apache-2.0
|
||||
* Adaptive Contention Window — replaces static txdelay/rxdelay
|
||||
* Adaptive Contention Window — EMA-based flood retransmit delay
|
||||
*
|
||||
* Measures local retransmit contention by counting how many times
|
||||
* we hear the same flood packet retransmitted by neighbors within
|
||||
* a 10-second window after we decide to retransmit it ourselves.
|
||||
* Feeds dupe counts into a rolling EMA to produce an adaptive
|
||||
* delay factor for future retransmits.
|
||||
* Counts neighbor retransmit dupes within a 10s window per packet.
|
||||
* Dupe counts feed a rolling EMA that drives an adaptive delay factor.
|
||||
*/
|
||||
|
||||
#pragma once
|
||||
@@ -21,35 +18,26 @@ class ContentionTracker {
|
||||
public:
|
||||
ContentionTracker();
|
||||
|
||||
/* Cheap 32-bit hash for packet correlation (FNV-1a).
|
||||
* NOT the same as the SHA256 used for dedup — this is only
|
||||
* for matching packets in the 16-entry ring buffer. */
|
||||
/* FNV-1a 32-bit hash for ring buffer correlation (not dedup SHA256). */
|
||||
static uint32_t computePacketHash32(const Packet *pkt);
|
||||
|
||||
/* Called when we decide to retransmit a flood packet. */
|
||||
void trackRetransmit(uint32_t hash32, uint32_t now_ms);
|
||||
|
||||
/* Called for every received flood packet. Returns true if
|
||||
* the packet matched a tracked retransmit (dupe recorded).
|
||||
* Caller should attempt reactive backoff when true. */
|
||||
/* Returns true if packet matched a tracked retransmit (dupe recorded). */
|
||||
bool recordDupeIfTracked(uint32_t hash32, uint32_t now_ms);
|
||||
|
||||
/* Per-dupe reactive delay: returns backoff_multiplier × airtime,
|
||||
* clamped by hard cap minus cumulative extension so far.
|
||||
/* Returns backoff_multiplier * airtime, clamped by remaining headroom.
|
||||
* Returns 0 when hard cap reached or backoff disabled. */
|
||||
uint16_t getReactiveHeadroom(uint32_t hash32, uint32_t airtime_ms) const;
|
||||
|
||||
/* Record that we added reactive extension to this entry. */
|
||||
void addReactiveExtension(uint32_t hash32, uint16_t added_ms);
|
||||
|
||||
/* Finalize expired entries into EMA. Call from maintenanceLoop. */
|
||||
/* Finalize expired entries into EMA. */
|
||||
void tick(uint32_t now_ms);
|
||||
|
||||
/* Current contention estimate (EMA of dupes per retransmitted packet). */
|
||||
float getContentionEstimate() const;
|
||||
|
||||
/* Adaptive delay factor for flood retransmits.
|
||||
* sqrt curve: 0.05 + 0.116 * sqrt(est), cap 2.0.
|
||||
/* sqrt curve: MIN_FLOOD_FACTOR + FLOOD_SCALE * sqrt(est), cap 2.0.
|
||||
* Returns 0.5 during warmup. */
|
||||
float getFloodDelayFactor() const;
|
||||
|
||||
@@ -59,16 +47,16 @@ public:
|
||||
float getBackoffMultiplier() const { return _backoff_multiplier; }
|
||||
|
||||
private:
|
||||
static constexpr int RING_SIZE = 16;
|
||||
static constexpr uint32_t WINDOW_MS = 10000;
|
||||
static constexpr int EMA_SHIFT = 3; /* alpha = 1/8 */
|
||||
static constexpr int WARMUP_PACKETS = 4;
|
||||
static constexpr float MIN_FLOOD_FACTOR = 0.05f;
|
||||
static constexpr float FLOOD_SCALE = 0.170f; /* (0.5 - 0.05) / sqrt(15) */
|
||||
static constexpr float MAX_FLOOD_FACTOR = 2.0f;
|
||||
static constexpr float DEFAULT_BACKOFF_MULT = 0.5f;
|
||||
static constexpr uint32_t REACTIVE_HARD_CAP_MS = 2000;
|
||||
static constexpr uint32_t STALE_MS = 300000; /* 5 minutes */
|
||||
static constexpr int RING_SIZE = 16; /* max concurrent tracked retransmits */
|
||||
static constexpr uint32_t WINDOW_MS = 10000; /* dupe observation window; covers SF12 2-hop */
|
||||
static constexpr int EMA_SHIFT = 3; /* alpha = 1/8 */
|
||||
static constexpr int WARMUP_PACKETS = 4; /* min samples before EMA is trusted */
|
||||
static constexpr float MIN_FLOOD_FACTOR = 0.05f; /* floor: near-zero delay in quiet networks */
|
||||
static constexpr float FLOOD_SCALE = 0.170f; /* (0.5 - 0.05) / sqrt(15) */
|
||||
static constexpr float MAX_FLOOD_FACTOR = 2.0f; /* ceiling: 2x base airtime */
|
||||
static constexpr float DEFAULT_BACKOFF_MULT = 0.5f; /* half-airtime per dupe heard */
|
||||
static constexpr uint32_t REACTIVE_HARD_CAP_MS = 2000; /* max cumulative reactive extension */
|
||||
static constexpr uint32_t STALE_MS = 300000; /* 5 min: reset EMA if no traffic */
|
||||
|
||||
struct Entry {
|
||||
uint32_t hash32;
|
||||
|
||||
@@ -31,7 +31,7 @@ struct DutyCycleTracker {
|
||||
|
||||
void recordTx(uint32_t duration_ms, uint32_t now) {
|
||||
if (duty_pct == 0) return;
|
||||
if (now - window_start > 3600000UL) {
|
||||
if (now - window_start > 3600000UL) { /* 1 hour window */
|
||||
window_start = now;
|
||||
window_airtime_ms = 0;
|
||||
}
|
||||
@@ -40,14 +40,14 @@ struct DutyCycleTracker {
|
||||
|
||||
bool isExceeded(uint32_t now) const {
|
||||
if (duty_pct == 0) return false;
|
||||
if (now - window_start > 3600000UL) return false; /* window expired */
|
||||
uint32_t budget_ms = (3600000UL / 100) * (uint32_t)duty_pct;
|
||||
if (now - window_start > 3600000UL) return false; /* 1h window expired */
|
||||
uint32_t budget_ms = (3600000UL / 100) * (uint32_t)duty_pct; /* ms per 1% of 1h */
|
||||
return window_airtime_ms >= budget_ms;
|
||||
}
|
||||
|
||||
uint32_t budgetMs() const {
|
||||
if (duty_pct == 0) return 0;
|
||||
return (3600000UL / 100) * (uint32_t)duty_pct;
|
||||
return (3600000UL / 100) * (uint32_t)duty_pct; /* ms per 1% of 1h */
|
||||
}
|
||||
};
|
||||
|
||||
@@ -68,8 +68,7 @@ public:
|
||||
virtual Packet *getNextInbound(uint32_t now) = 0;
|
||||
};
|
||||
|
||||
/* Callback fired when a packet is queued for transmission with a delay.
|
||||
* Allows the event loop to schedule a precise wake at delay expiry. */
|
||||
/* Notifies event loop of pending TX so it can schedule a wake. */
|
||||
typedef void (*tx_queued_callback_t)(uint32_t delay_ms, void *user_data);
|
||||
|
||||
typedef uint32_t DispatcherAction;
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
/*
|
||||
* SPDX-License-Identifier: Apache-2.0
|
||||
* ZephCore Identity - Ed25519 public identity
|
||||
* ZephCore Identity - Ed25519 key pairs
|
||||
*/
|
||||
|
||||
#pragma once
|
||||
|
||||
@@ -10,12 +10,12 @@
|
||||
namespace mesh {
|
||||
|
||||
struct LoRaConfig {
|
||||
static constexpr uint32_t FREQ_HZ = 869618000;
|
||||
static constexpr uint16_t BANDWIDTH = 62; /* BW_62_KHZ */
|
||||
static constexpr uint8_t SPREADING_FACTOR = 8;
|
||||
static constexpr uint8_t CODING_RATE = 8; /* CR_4_8 */
|
||||
static constexpr uint16_t PREAMBLE_LEN = 16;
|
||||
static constexpr int8_t TX_POWER_DBM = 22;
|
||||
static constexpr uint32_t FREQ_HZ = 869618000; /* MeshCore default channel (EU 869 MHz ISM) */
|
||||
static constexpr uint16_t BANDWIDTH = 62; /* BW_62_KHZ — MeshCore default */
|
||||
static constexpr uint8_t SPREADING_FACTOR = 8; /* SF8: balance of range vs airtime */
|
||||
static constexpr uint8_t CODING_RATE = 8; /* CR_4_8: max FEC */
|
||||
static constexpr uint16_t PREAMBLE_LEN = 16; /* MeshCore default; longer aids RX sync */
|
||||
static constexpr int8_t TX_POWER_DBM = 22; /* SX1262 max */
|
||||
};
|
||||
|
||||
} /* namespace mesh */
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
/*
|
||||
* SPDX-License-Identifier: Apache-2.0
|
||||
* ZephCore constants and base types (Zephyr port)
|
||||
* ZephCore constants and base types
|
||||
*/
|
||||
|
||||
#pragma once
|
||||
@@ -8,28 +8,21 @@
|
||||
#include <stdint.h>
|
||||
#include <math.h>
|
||||
|
||||
#define MAX_HASH_SIZE 8
|
||||
#define PUB_KEY_SIZE 32
|
||||
#define PRV_KEY_SIZE 64
|
||||
#define SEED_SIZE 32
|
||||
#define SIGNATURE_SIZE 64
|
||||
#define MAX_HASH_SIZE 8 /* SHA256 truncated to 8 bytes for dedup */
|
||||
#define PUB_KEY_SIZE 32 /* Ed25519 public key */
|
||||
#define PRV_KEY_SIZE 64 /* Ed25519 expanded private key */
|
||||
#define SEED_SIZE 32 /* Ed25519 seed */
|
||||
#define SIGNATURE_SIZE 64 /* Ed25519 signature */
|
||||
#define MAX_ADVERT_DATA_SIZE 32
|
||||
#define CIPHER_KEY_SIZE 16
|
||||
#define CIPHER_BLOCK_SIZE 16
|
||||
#define CIPHER_MAC_SIZE 2
|
||||
#define PATH_HASH_SIZE 1
|
||||
#define CIPHER_KEY_SIZE 16 /* AES-128 */
|
||||
#define CIPHER_BLOCK_SIZE 16 /* AES block size */
|
||||
#define CIPHER_MAC_SIZE 2 /* truncated MAC for bandwidth savings */
|
||||
#define PATH_HASH_SIZE 1 /* 1-byte per-hop hash in path field */
|
||||
|
||||
#define MAX_PACKET_PAYLOAD 184
|
||||
#define MAX_PATH_SIZE 64
|
||||
#define MAX_TRANS_UNIT 255
|
||||
#define MAX_PACKET_PAYLOAD 184 /* fits in SX126x 255-byte FIFO with headers */
|
||||
#define MAX_PATH_SIZE 64 /* max hops * max hash size */
|
||||
#define MAX_TRANS_UNIT 255 /* SX126x FIFO limit */
|
||||
#define MAX_GROUP_DATA_LENGTH (MAX_PACKET_PAYLOAD - CIPHER_BLOCK_SIZE - 3)
|
||||
|
||||
#define MESH_DEBUG_PRINT(...)
|
||||
#define MESH_DEBUG_PRINTLN(...)
|
||||
|
||||
namespace mesh {
|
||||
|
||||
#define BD_STARTUP_NORMAL 0
|
||||
#define BD_STARTUP_RX_PACKET 1
|
||||
|
||||
} /* namespace mesh */
|
||||
|
||||
@@ -51,7 +51,7 @@ public:
|
||||
uint16_t transport_codes[2];
|
||||
uint8_t path[MAX_PATH_SIZE];
|
||||
uint8_t payload[MAX_PACKET_PAYLOAD];
|
||||
int8_t _snr;
|
||||
int8_t _snr; /* SNR * 4 (quarter-dB fixed point) */
|
||||
|
||||
void calculatePacketHash(uint8_t *dest_hash) const;
|
||||
uint8_t getRouteType() const { return header & PH_ROUTE_MASK; }
|
||||
@@ -61,11 +61,12 @@ public:
|
||||
uint8_t getPayloadType() const { return (header >> PH_TYPE_SHIFT) & PH_TYPE_MASK; }
|
||||
uint8_t getPayloadVer() const { return (header >> PH_VER_SHIFT) & PH_VER_MASK; }
|
||||
|
||||
/* path_len layout: bits[7:6] = hash_size - 1, bits[5:0] = hop count */
|
||||
uint8_t getPathHashSize() const { return (path_len >> 6) + 1; }
|
||||
uint8_t getPathHashCount() const { return path_len & 63; }
|
||||
uint8_t getPathHashCount() const { return path_len & 0x3F; }
|
||||
uint8_t getPathByteLen() const { return getPathHashCount() * getPathHashSize(); }
|
||||
void setPathHashCount(uint8_t n) { path_len &= ~63; path_len |= n; }
|
||||
void setPathHashSizeAndCount(uint8_t sz, uint8_t n) { path_len = ((sz - 1) << 6) | (n & 63); }
|
||||
void setPathHashCount(uint8_t n) { path_len &= ~0x3F; path_len |= n; }
|
||||
void setPathHashSizeAndCount(uint8_t sz, uint8_t n) { path_len = ((sz - 1) << 6) | (n & 0x3F); }
|
||||
|
||||
static uint8_t copyPath(uint8_t *dest, const uint8_t *src, uint8_t path_len);
|
||||
static size_t writePath(uint8_t *dest, const uint8_t *src, uint8_t path_len);
|
||||
|
||||
Reference in New Issue
Block a user