mirror of
https://github.com/meshcore-dev/MeshCore.git
synced 2026-04-20 22:13:47 +00:00
* Repeater/Room server: new diagnostics, stats.n_full_events now repurposed to 'err_events' (bit flags)
* new Radio::isInRecvMode() method
This commit is contained in:
parent
62a5115cc9
commit
177dd90ca1
8 changed files with 46 additions and 9 deletions
|
|
@ -91,7 +91,7 @@ struct RepeaterStats {
|
||||||
uint32_t total_up_time_secs;
|
uint32_t total_up_time_secs;
|
||||||
uint32_t n_sent_flood, n_sent_direct;
|
uint32_t n_sent_flood, n_sent_direct;
|
||||||
uint32_t n_recv_flood, n_recv_direct;
|
uint32_t n_recv_flood, n_recv_direct;
|
||||||
uint16_t n_full_events;
|
uint16_t err_events; // was 'n_full_events'
|
||||||
int16_t last_snr; // x 4
|
int16_t last_snr; // x 4
|
||||||
uint16_t n_direct_dups, n_flood_dups;
|
uint16_t n_direct_dups, n_flood_dups;
|
||||||
};
|
};
|
||||||
|
|
@ -195,7 +195,7 @@ class MyMesh : public mesh::Mesh, public CommonCLICallbacks {
|
||||||
stats.n_sent_direct = getNumSentDirect();
|
stats.n_sent_direct = getNumSentDirect();
|
||||||
stats.n_recv_flood = getNumRecvFlood();
|
stats.n_recv_flood = getNumRecvFlood();
|
||||||
stats.n_recv_direct = getNumRecvDirect();
|
stats.n_recv_direct = getNumRecvDirect();
|
||||||
stats.n_full_events = getNumFullEvents();
|
stats.err_events = _err_flags;
|
||||||
stats.last_snr = (int16_t)(radio_driver.getLastSNR() * 4);
|
stats.last_snr = (int16_t)(radio_driver.getLastSNR() * 4);
|
||||||
stats.n_direct_dups = ((SimpleMeshTables *)getTables())->getNumDirectDups();
|
stats.n_direct_dups = ((SimpleMeshTables *)getTables())->getNumDirectDups();
|
||||||
stats.n_flood_dups = ((SimpleMeshTables *)getTables())->getNumFloodDups();
|
stats.n_flood_dups = ((SimpleMeshTables *)getTables())->getNumFloodDups();
|
||||||
|
|
|
||||||
|
|
@ -138,7 +138,7 @@ struct ServerStats {
|
||||||
uint32_t total_up_time_secs;
|
uint32_t total_up_time_secs;
|
||||||
uint32_t n_sent_flood, n_sent_direct;
|
uint32_t n_sent_flood, n_sent_direct;
|
||||||
uint32_t n_recv_flood, n_recv_direct;
|
uint32_t n_recv_flood, n_recv_direct;
|
||||||
uint16_t n_full_events;
|
uint16_t err_events; // was 'n_full_events'
|
||||||
int16_t last_snr; // x 4
|
int16_t last_snr; // x 4
|
||||||
uint16_t n_direct_dups, n_flood_dups;
|
uint16_t n_direct_dups, n_flood_dups;
|
||||||
uint16_t n_posted, n_post_push;
|
uint16_t n_posted, n_post_push;
|
||||||
|
|
@ -301,7 +301,7 @@ class MyMesh : public mesh::Mesh, public CommonCLICallbacks {
|
||||||
stats.n_sent_direct = getNumSentDirect();
|
stats.n_sent_direct = getNumSentDirect();
|
||||||
stats.n_recv_flood = getNumRecvFlood();
|
stats.n_recv_flood = getNumRecvFlood();
|
||||||
stats.n_recv_direct = getNumRecvDirect();
|
stats.n_recv_direct = getNumRecvDirect();
|
||||||
stats.n_full_events = getNumFullEvents();
|
stats.err_events = _err_flags;
|
||||||
stats.last_snr = (int16_t)(radio_driver.getLastSNR() * 4);
|
stats.last_snr = (int16_t)(radio_driver.getLastSNR() * 4);
|
||||||
stats.n_direct_dups = ((SimpleMeshTables *)getTables())->getNumDirectDups();
|
stats.n_direct_dups = ((SimpleMeshTables *)getTables())->getNumDirectDups();
|
||||||
stats.n_flood_dups = ((SimpleMeshTables *)getTables())->getNumFloodDups();
|
stats.n_flood_dups = ((SimpleMeshTables *)getTables())->getNumFloodDups();
|
||||||
|
|
|
||||||
|
|
@ -13,7 +13,7 @@ namespace mesh {
|
||||||
void Dispatcher::begin() {
|
void Dispatcher::begin() {
|
||||||
n_sent_flood = n_sent_direct = 0;
|
n_sent_flood = n_sent_direct = 0;
|
||||||
n_recv_flood = n_recv_direct = 0;
|
n_recv_flood = n_recv_direct = 0;
|
||||||
n_full_events = 0;
|
_err_flags = 0;
|
||||||
|
|
||||||
_radio->begin();
|
_radio->begin();
|
||||||
}
|
}
|
||||||
|
|
@ -34,6 +34,18 @@ uint32_t Dispatcher::getCADFailMaxDuration() const {
|
||||||
}
|
}
|
||||||
|
|
||||||
void Dispatcher::loop() {
|
void Dispatcher::loop() {
|
||||||
|
// check for radio 'stuck' in mode other than Rx
|
||||||
|
bool is_recv = _radio->isInRecvMode();
|
||||||
|
if (is_recv != prev_isrecv_mode) {
|
||||||
|
prev_isrecv_mode = is_recv;
|
||||||
|
if (!is_recv) {
|
||||||
|
radio_nonrx_start = _ms->getMillis();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (!is_recv && _ms->getMillis() - radio_nonrx_start > 8000) { // radio has not been in Rx mode for 8 seconds!
|
||||||
|
_err_flags |= ERR_EVENT_STARTRX_TIMEOUT;
|
||||||
|
}
|
||||||
|
|
||||||
if (outbound) { // waiting for outbound send to be completed
|
if (outbound) { // waiting for outbound send to be completed
|
||||||
if (_radio->isSendComplete()) {
|
if (_radio->isSendComplete()) {
|
||||||
long t = _ms->getMillis() - outbound_start;
|
long t = _ms->getMillis() - outbound_start;
|
||||||
|
|
@ -199,6 +211,8 @@ void Dispatcher::checkSend() {
|
||||||
}
|
}
|
||||||
|
|
||||||
if (_ms->getMillis() - cad_busy_start > getCADFailMaxDuration()) {
|
if (_ms->getMillis() - cad_busy_start > getCADFailMaxDuration()) {
|
||||||
|
_err_flags |= ERR_EVENT_CAD_TIMEOUT;
|
||||||
|
|
||||||
MESH_DEBUG_PRINTLN("%s Dispatcher::checkSend(): CAD busy max duration reached!", getLogDateTime());
|
MESH_DEBUG_PRINTLN("%s Dispatcher::checkSend(): CAD busy max duration reached!", getLogDateTime());
|
||||||
// channel activity has gone on too long... (Radio might be in a bad state)
|
// channel activity has gone on too long... (Radio might be in a bad state)
|
||||||
// force the pending transmit below...
|
// force the pending transmit below...
|
||||||
|
|
@ -264,7 +278,7 @@ void Dispatcher::checkSend() {
|
||||||
Packet* Dispatcher::obtainNewPacket() {
|
Packet* Dispatcher::obtainNewPacket() {
|
||||||
auto pkt = _mgr->allocNew(); // TODO: zero out all fields
|
auto pkt = _mgr->allocNew(); // TODO: zero out all fields
|
||||||
if (pkt == NULL) {
|
if (pkt == NULL) {
|
||||||
n_full_events++;
|
_err_flags |= ERR_EVENT_FULL;
|
||||||
} else {
|
} else {
|
||||||
pkt->payload_len = pkt->path_len = 0;
|
pkt->payload_len = pkt->path_len = 0;
|
||||||
pkt->_snr = 0;
|
pkt->_snr = 0;
|
||||||
|
|
|
||||||
|
|
@ -56,6 +56,8 @@ public:
|
||||||
*/
|
*/
|
||||||
virtual void onSendFinished() = 0;
|
virtual void onSendFinished() = 0;
|
||||||
|
|
||||||
|
virtual bool isInRecvMode() const = 0;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* \returns true if the radio is currently mid-receive of a packet.
|
* \returns true if the radio is currently mid-receive of a packet.
|
||||||
*/
|
*/
|
||||||
|
|
@ -91,6 +93,10 @@ typedef uint32_t DispatcherAction;
|
||||||
#define ACTION_RETRANSMIT(pri) (((uint32_t)1 + (pri))<<24)
|
#define ACTION_RETRANSMIT(pri) (((uint32_t)1 + (pri))<<24)
|
||||||
#define ACTION_RETRANSMIT_DELAYED(pri, _delay) ((((uint32_t)1 + (pri))<<24) | (_delay))
|
#define ACTION_RETRANSMIT_DELAYED(pri, _delay) ((((uint32_t)1 + (pri))<<24) | (_delay))
|
||||||
|
|
||||||
|
#define ERR_EVENT_FULL (1 << 0)
|
||||||
|
#define ERR_EVENT_CAD_TIMEOUT (1 << 1)
|
||||||
|
#define ERR_EVENT_STARTRX_TIMEOUT (1 << 2)
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* \brief The low-level task that manages detecting incoming Packets, and the queueing
|
* \brief The low-level task that manages detecting incoming Packets, and the queueing
|
||||||
* and scheduling of outbound Packets.
|
* and scheduling of outbound Packets.
|
||||||
|
|
@ -100,9 +106,10 @@ class Dispatcher {
|
||||||
unsigned long outbound_expiry, outbound_start, total_air_time;
|
unsigned long outbound_expiry, outbound_start, total_air_time;
|
||||||
unsigned long next_tx_time;
|
unsigned long next_tx_time;
|
||||||
unsigned long cad_busy_start;
|
unsigned long cad_busy_start;
|
||||||
|
unsigned long radio_nonrx_start;
|
||||||
|
bool prev_isrecv_mode;
|
||||||
uint32_t n_sent_flood, n_sent_direct;
|
uint32_t n_sent_flood, n_sent_direct;
|
||||||
uint32_t n_recv_flood, n_recv_direct;
|
uint32_t n_recv_flood, n_recv_direct;
|
||||||
uint32_t n_full_events;
|
|
||||||
|
|
||||||
void processRecvPacket(Packet* pkt);
|
void processRecvPacket(Packet* pkt);
|
||||||
|
|
||||||
|
|
@ -110,12 +117,16 @@ protected:
|
||||||
PacketManager* _mgr;
|
PacketManager* _mgr;
|
||||||
Radio* _radio;
|
Radio* _radio;
|
||||||
MillisecondClock* _ms;
|
MillisecondClock* _ms;
|
||||||
|
uint16_t _err_flags;
|
||||||
|
|
||||||
Dispatcher(Radio& radio, MillisecondClock& ms, PacketManager& mgr)
|
Dispatcher(Radio& radio, MillisecondClock& ms, PacketManager& mgr)
|
||||||
: _radio(&radio), _ms(&ms), _mgr(&mgr)
|
: _radio(&radio), _ms(&ms), _mgr(&mgr)
|
||||||
{
|
{
|
||||||
outbound = NULL; total_air_time = 0; next_tx_time = 0;
|
outbound = NULL; total_air_time = 0; next_tx_time = 0;
|
||||||
cad_busy_start = 0;
|
cad_busy_start = 0;
|
||||||
|
_err_flags = 0;
|
||||||
|
radio_nonrx_start = 0;
|
||||||
|
prev_isrecv_mode = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
virtual DispatcherAction onRecvPacket(Packet* pkt) = 0;
|
virtual DispatcherAction onRecvPacket(Packet* pkt) = 0;
|
||||||
|
|
@ -145,7 +156,6 @@ public:
|
||||||
uint32_t getNumSentDirect() const { return n_sent_direct; }
|
uint32_t getNumSentDirect() const { return n_sent_direct; }
|
||||||
uint32_t getNumRecvFlood() const { return n_recv_flood; }
|
uint32_t getNumRecvFlood() const { return n_recv_flood; }
|
||||||
uint32_t getNumRecvDirect() const { return n_recv_direct; }
|
uint32_t getNumRecvDirect() const { return n_recv_direct; }
|
||||||
uint32_t getNumFullEvents() const { return n_full_events; }
|
|
||||||
|
|
||||||
// helper methods
|
// helper methods
|
||||||
bool millisHasNowPassed(unsigned long timestamp) const;
|
bool millisHasNowPassed(unsigned long timestamp) const;
|
||||||
|
|
|
||||||
|
|
@ -44,6 +44,10 @@ void RadioLibWrapper::startRecv() {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
bool RadioLibWrapper::isInRecvMode() const {
|
||||||
|
return (state & ~STATE_INT_READY) == STATE_RX;
|
||||||
|
}
|
||||||
|
|
||||||
int RadioLibWrapper::recvRaw(uint8_t* bytes, int sz) {
|
int RadioLibWrapper::recvRaw(uint8_t* bytes, int sz) {
|
||||||
if (state & STATE_INT_READY) {
|
if (state & STATE_INT_READY) {
|
||||||
int len = _radio->getPacketLength();
|
int len = _radio->getPacketLength();
|
||||||
|
|
|
||||||
|
|
@ -22,6 +22,7 @@ public:
|
||||||
bool startSendRaw(const uint8_t* bytes, int len) override;
|
bool startSendRaw(const uint8_t* bytes, int len) override;
|
||||||
bool isSendComplete() override;
|
bool isSendComplete() override;
|
||||||
void onSendFinished() override;
|
void onSendFinished() override;
|
||||||
|
bool isInRecvMode() const override;
|
||||||
|
|
||||||
uint32_t getPacketsRecv() const { return n_recv; }
|
uint32_t getPacketsRecv() const { return n_recv; }
|
||||||
uint32_t getPacketsSent() const { return n_sent; }
|
uint32_t getPacketsSent() const { return n_sent; }
|
||||||
|
|
|
||||||
|
|
@ -5,7 +5,7 @@
|
||||||
|
|
||||||
static uint8_t broadcastAddress[] = {0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF};
|
static uint8_t broadcastAddress[] = {0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF};
|
||||||
static esp_now_peer_info_t peerInfo;
|
static esp_now_peer_info_t peerInfo;
|
||||||
static bool is_send_complete = false;
|
static volatile bool is_send_complete = false;
|
||||||
static esp_err_t last_send_result;
|
static esp_err_t last_send_result;
|
||||||
static uint8_t rx_buf[256];
|
static uint8_t rx_buf[256];
|
||||||
static uint8_t last_rx_len = 0;
|
static uint8_t last_rx_len = 0;
|
||||||
|
|
@ -44,6 +44,8 @@ void ESPNOWRadio::init() {
|
||||||
peerInfo.channel = 0;
|
peerInfo.channel = 0;
|
||||||
peerInfo.encrypt = false;
|
peerInfo.encrypt = false;
|
||||||
|
|
||||||
|
is_send_complete = true;
|
||||||
|
|
||||||
// Add peer
|
// Add peer
|
||||||
if (esp_now_add_peer(&peerInfo) == ESP_OK) {
|
if (esp_now_add_peer(&peerInfo) == ESP_OK) {
|
||||||
ESPNOW_DEBUG_PRINTLN("init success");
|
ESPNOW_DEBUG_PRINTLN("init success");
|
||||||
|
|
@ -86,6 +88,11 @@ bool ESPNOWRadio::isSendComplete() {
|
||||||
return is_send_complete;
|
return is_send_complete;
|
||||||
}
|
}
|
||||||
void ESPNOWRadio::onSendFinished() {
|
void ESPNOWRadio::onSendFinished() {
|
||||||
|
is_send_complete = true;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool ESPNOWRadio::isInRecvMode() const {
|
||||||
|
return is_send_complete; // if NO send in progress, then we're in Rx mode
|
||||||
}
|
}
|
||||||
|
|
||||||
float ESPNOWRadio::getLastRSSI() const { return 0; }
|
float ESPNOWRadio::getLastRSSI() const { return 0; }
|
||||||
|
|
|
||||||
|
|
@ -15,6 +15,7 @@ public:
|
||||||
bool startSendRaw(const uint8_t* bytes, int len) override;
|
bool startSendRaw(const uint8_t* bytes, int len) override;
|
||||||
bool isSendComplete() override;
|
bool isSendComplete() override;
|
||||||
void onSendFinished() override;
|
void onSendFinished() override;
|
||||||
|
bool isInRecvMode() const override;
|
||||||
|
|
||||||
uint32_t getPacketsRecv() const { return n_recv; }
|
uint32_t getPacketsRecv() const { return n_recv; }
|
||||||
uint32_t getPacketsSent() const { return n_sent; }
|
uint32_t getPacketsSent() const { return n_sent; }
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue