Compare commits
2 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
3ac5570ebb | ||
|
|
e194f6d307 |
@@ -43,4 +43,6 @@ public:
|
||||
virtual void newMsg(uint8_t path_len, const char* from_name, const char* text, int msgcount) = 0;
|
||||
virtual void notify(UIEventType t = UIEventType::none) = 0;
|
||||
virtual void loop() = 0;
|
||||
virtual void showAlert(const char* text, int duration_millis) {}
|
||||
virtual void forceRefresh() {}
|
||||
};
|
||||
@@ -446,9 +446,37 @@ void MyMesh::queueMessage(const ContactInfo &from, uint8_t txt_type, mesh::Packe
|
||||
}
|
||||
|
||||
bool MyMesh::filterRecvFloodPacket(mesh::Packet* packet) {
|
||||
// REVISIT: try to determine which Region (from transport_codes[1]) that Sender is indicating for replies/responses
|
||||
// if unknown, fallback to finding Region from transport_codes[0], the 'scope' used by Sender
|
||||
return false;
|
||||
// Check if this incoming flood packet is a repeat of a message we recently sent
|
||||
if (packet->payload_len >= SENT_FINGERPRINT_SIZE) {
|
||||
unsigned long now = millis();
|
||||
for (int i = 0; i < SENT_TRACK_SIZE; i++) {
|
||||
SentMsgTrack* t = &_sent_track[i];
|
||||
if (!t->active) continue;
|
||||
|
||||
// Expire old entries
|
||||
if ((now - t->sent_millis) > SENT_TRACK_EXPIRY_MS) {
|
||||
t->active = false;
|
||||
continue;
|
||||
}
|
||||
|
||||
// Compare payload fingerprint
|
||||
if (memcmp(packet->payload, t->fingerprint, SENT_FINGERPRINT_SIZE) == 0) {
|
||||
t->repeat_count++;
|
||||
MESH_DEBUG_PRINTLN("SentTrack: heard repeat #%d (SNR=%.1f)", t->repeat_count, packet->getSNR());
|
||||
|
||||
#ifdef DISPLAY_CLASS
|
||||
if (_ui) {
|
||||
char buf[40];
|
||||
snprintf(buf, sizeof(buf), "Sent! (%d)", t->repeat_count);
|
||||
_ui->showAlert(buf, 2000); // show/extend alert with updated count
|
||||
}
|
||||
#endif
|
||||
break; // found match, no need to check other entries
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return false; // never filter — let normal processing continue
|
||||
}
|
||||
|
||||
void MyMesh::sendFloodScoped(const ContactInfo& recipient, mesh::Packet* pkt, uint32_t delay_millis) {
|
||||
@@ -463,6 +491,17 @@ void MyMesh::sendFloodScoped(const ContactInfo& recipient, mesh::Packet* pkt, ui
|
||||
}
|
||||
}
|
||||
void MyMesh::sendFloodScoped(const mesh::GroupChannel& channel, mesh::Packet* pkt, uint32_t delay_millis) {
|
||||
// Capture payload fingerprint for repeat tracking before sending
|
||||
if (pkt->payload_len >= SENT_FINGERPRINT_SIZE) {
|
||||
SentMsgTrack* t = &_sent_track[_sent_track_idx];
|
||||
memcpy(t->fingerprint, pkt->payload, SENT_FINGERPRINT_SIZE);
|
||||
t->repeat_count = 0;
|
||||
t->sent_millis = millis();
|
||||
t->active = true;
|
||||
_sent_track_idx = (_sent_track_idx + 1) % SENT_TRACK_SIZE;
|
||||
MESH_DEBUG_PRINTLN("SentTrack: captured fingerprint for channel msg");
|
||||
}
|
||||
|
||||
// TODO: have per-channel send_scope
|
||||
if (send_scope.isNull()) {
|
||||
sendFlood(pkt, delay_millis);
|
||||
@@ -826,6 +865,8 @@ MyMesh::MyMesh(mesh::Radio &radio, mesh::RNG &rng, mesh::RTCClock &rtc, SimpleMe
|
||||
dirty_contacts_expiry = 0;
|
||||
memset(advert_paths, 0, sizeof(advert_paths));
|
||||
memset(send_scope.key, 0, sizeof(send_scope.key));
|
||||
memset(_sent_track, 0, sizeof(_sent_track));
|
||||
_sent_track_idx = 0;
|
||||
|
||||
// defaults
|
||||
memset(&_prefs, 0, sizeof(_prefs));
|
||||
|
||||
@@ -12,7 +12,7 @@
|
||||
#endif
|
||||
|
||||
#ifndef FIRMWARE_VERSION
|
||||
#define FIRMWARE_VERSION "Meck v0.6.3"
|
||||
#define FIRMWARE_VERSION "Meck v0.6.4"
|
||||
#endif
|
||||
|
||||
#if defined(NRF52_PLATFORM) || defined(STM32_PLATFORM)
|
||||
@@ -231,6 +231,19 @@ private:
|
||||
|
||||
#define ADVERT_PATH_TABLE_SIZE 16
|
||||
AdvertPath advert_paths[ADVERT_PATH_TABLE_SIZE]; // circular table
|
||||
|
||||
// Sent message repeat tracking
|
||||
#define SENT_TRACK_SIZE 4
|
||||
#define SENT_FINGERPRINT_SIZE 12
|
||||
#define SENT_TRACK_EXPIRY_MS 30000 // stop tracking after 30 seconds
|
||||
struct SentMsgTrack {
|
||||
uint8_t fingerprint[SENT_FINGERPRINT_SIZE];
|
||||
uint8_t repeat_count;
|
||||
unsigned long sent_millis;
|
||||
bool active;
|
||||
};
|
||||
SentMsgTrack _sent_track[SENT_TRACK_SIZE];
|
||||
int _sent_track_idx; // next slot in circular buffer
|
||||
};
|
||||
|
||||
extern MyMesh the_mesh;
|
||||
@@ -103,12 +103,10 @@ class HomeScreen : public UIScreen {
|
||||
AdvertPath recent[UI_RECENT_LIST_SIZE];
|
||||
|
||||
|
||||
void renderBatteryIndicator(DisplayDriver& display, uint16_t batteryMilliVolts) {
|
||||
// Try to get accurate SOC from BQ27220 fuel gauge first
|
||||
uint8_t batteryPercentage = board.getBatteryPercent();
|
||||
|
||||
// Fall back to voltage-based estimation if fuel gauge returns 0
|
||||
if (batteryPercentage == 0 && batteryMilliVolts > 0) {
|
||||
void renderBatteryIndicator(DisplayDriver& display, uint16_t batteryMilliVolts) {
|
||||
// Use voltage-based estimation to match BLE app readings
|
||||
uint8_t batteryPercentage = 0;
|
||||
if (batteryMilliVolts > 0) {
|
||||
const int minMilliVolts = 3000;
|
||||
const int maxMilliVolts = 4200;
|
||||
int pct = ((batteryMilliVolts - minMilliVolts) * 100) / (maxMilliVolts - minMilliVolts);
|
||||
@@ -612,6 +610,7 @@ void UITask::begin(DisplayDriver* display, SensorManager* sensors, NodePrefs* no
|
||||
void UITask::showAlert(const char* text, int duration_millis) {
|
||||
strcpy(_alert, text);
|
||||
_alert_expiry = millis() + duration_millis;
|
||||
_next_refresh = millis() + 100; // trigger re-render to show updated text
|
||||
}
|
||||
|
||||
void UITask::notify(UIEventType t) {
|
||||
|
||||
@@ -75,7 +75,8 @@ public:
|
||||
|
||||
void gotoHomeScreen() { setCurrScreen(home); }
|
||||
void gotoChannelScreen(); // Navigate to channel message screen
|
||||
void showAlert(const char* text, int duration_millis);
|
||||
void showAlert(const char* text, int duration_millis) override;
|
||||
void forceRefresh() override { _next_refresh = 100; }
|
||||
int getMsgCount() const { return _msgcount; }
|
||||
bool hasDisplay() const { return _display != NULL; }
|
||||
bool isButtonPressed() const;
|
||||
|
||||
Reference in New Issue
Block a user