Merge branch 'master' into tft-gui-work

This commit is contained in:
Manuel 2024-04-19 20:32:03 +02:00 committed by GitHub
commit e8706ec4d2
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
6 changed files with 74 additions and 149 deletions

@ -1 +1 @@
Subproject commit ecf105f66d182531423b73f4408c53701313c4eb Subproject commit 0d08acd9c51c4e5575f3ea42368834ec990b2278

View File

@ -465,21 +465,22 @@ void Router::handleReceived(meshtastic_MeshPacket *p, RxSource src)
cancelSending(p->from, p->id); cancelSending(p->from, p->id);
skipHandle = true; skipHandle = true;
} }
#if !MESHTASTIC_EXCLUDE_MQTT
// Publish received message to MQTT if we're not the original transmitter of the packet
if (!skipHandle && moduleConfig.mqtt.enabled && getFrom(p) != nodeDB->getNodeNum() && mqtt)
mqtt->onSend(*p_encrypted, *p, p->channel);
#endif
} else { } else {
printPacket("packet decoding failed or skipped (no PSK?)", p); printPacket("packet decoding failed or skipped (no PSK?)", p);
} }
packetPool.release(p_encrypted); // Release the encrypted packet
// call modules here // call modules here
if (!skipHandle) if (!skipHandle) {
MeshModule::callModules(*p, src); MeshModule::callModules(*p, src);
#if !MESHTASTIC_EXCLUDE_MQTT
// After potentially altering it, publish received message to MQTT if we're not the original transmitter of the packet
if (decoded && moduleConfig.mqtt.enabled && getFrom(p) != nodeDB->getNodeNum() && mqtt)
mqtt->onSend(*p_encrypted, *p, p->channel);
#endif
}
packetPool.release(p_encrypted); // Release the encrypted packet
} }
void Router::perhapsHandleReceived(meshtastic_MeshPacket *p) void Router::perhapsHandleReceived(meshtastic_MeshPacket *p)

View File

@ -324,35 +324,30 @@ typedef struct _meshtastic_Config_PositionConfig {
/* Power Config\ /* Power Config\
See [Power Config](/docs/settings/config/power) for additional power config details. */ See [Power Config](/docs/settings/config/power) for additional power config details. */
typedef struct _meshtastic_Config_PowerConfig { typedef struct _meshtastic_Config_PowerConfig {
/* If set, we are powered from a low-current source (i.e. solar), so even if it looks like we have power flowing in /* Description: Will sleep everything as much as possible, for the tracker and sensor role this will also include the lora radio.
we should try to minimize power consumption as much as possible. Don't use this setting if you want to use your device with the phone apps or are using a device without a user button.
YOU DO NOT NEED TO SET THIS IF YOU'VE set is_router (it is implied in that case). Technical Details: Works for ESP32 devices and NRF52 devices in the Sensor or Tracker roles */
Advanced Option */
bool is_power_saving; bool is_power_saving;
/* If non-zero, the device will fully power off this many seconds after external power is removed. */ /* Description: If non-zero, the device will fully power off this many seconds after external power is removed. */
uint32_t on_battery_shutdown_after_secs; uint32_t on_battery_shutdown_after_secs;
/* Ratio of voltage divider for battery pin eg. 3.20 (R1=100k, R2=220k) /* Ratio of voltage divider for battery pin eg. 3.20 (R1=100k, R2=220k)
Overrides the ADC_MULTIPLIER defined in variant for battery voltage calculation. Overrides the ADC_MULTIPLIER defined in variant for battery voltage calculation.
Should be set to floating point value between 2 and 4 https://meshtastic.org/docs/configuration/radio/power/#adc-multiplier-override
Fixes issues on Heltec v2 */ Should be set to floating point value between 2 and 6 */
float adc_multiplier_override; float adc_multiplier_override;
/* Wait Bluetooth Seconds /* Description: The number of seconds for to wait before turning off BLE in No Bluetooth states
The number of seconds for to wait before turning off BLE in No Bluetooth states Technical Details: ESP32 Only 0 for default of 1 minute */
0 for default of 1 minute */
uint32_t wait_bluetooth_secs; uint32_t wait_bluetooth_secs;
/* Super Deep Sleep Seconds /* Super Deep Sleep Seconds
While in Light Sleep if mesh_sds_timeout_secs is exceeded we will lower into super deep sleep While in Light Sleep if mesh_sds_timeout_secs is exceeded we will lower into super deep sleep
for this value (default 1 year) or a button press for this value (default 1 year) or a button press
0 for default of one year */ 0 for default of one year */
uint32_t sds_secs; uint32_t sds_secs;
/* Light Sleep Seconds /* Description: In light sleep the CPU is suspended, LoRa radio is on, BLE is off an GPS is on
In light sleep the CPU is suspended, LoRa radio is on, BLE is off an GPS is on Technical Details: ESP32 Only 0 for default of 300 */
ESP32 Only
0 for default of 300 */
uint32_t ls_secs; uint32_t ls_secs;
/* Minimum Wake Seconds /* Description: While in light sleep when we receive packets on the LoRa radio we will wake and handle them and stay awake in no BLE mode for this value
While in light sleep when we receive packets on the LoRa radio we will wake and handle them and stay awake in no BLE mode for this value Technical Details: ESP32 Only 0 for default of 10 seconds */
0 for default of 10 seconds */
uint32_t min_wake_secs; uint32_t min_wake_secs;
/* I2C address of INA_2XX to use for reading device battery voltage */ /* I2C address of INA_2XX to use for reading device battery voltage */
uint8_t device_battery_ina_address; uint8_t device_battery_ina_address;

View File

@ -4,11 +4,8 @@
#include "NodeDB.h" #include "NodeDB.h"
#include "RTC.h" #include "RTC.h"
#define MAX_NUM_NEIGHBORS 10 // also defined in NeighborInfo protobuf options
NeighborInfoModule *neighborInfoModule; NeighborInfoModule *neighborInfoModule;
static const char *neighborInfoConfigFile = "/prefs/neighbors.proto";
/* /*
Prints a single neighbor info packet and associated neighbors Prints a single neighbor info packet and associated neighbors
Uses LOG_DEBUG, which equates to Console.log Uses LOG_DEBUG, which equates to Console.log
@ -30,26 +27,23 @@ NOTE: for debugging only
*/ */
void NeighborInfoModule::printNodeDBNeighbors() void NeighborInfoModule::printNodeDBNeighbors()
{ {
int num_neighbors = getNumNeighbors(); LOG_DEBUG("Our NodeDB contains %d neighbors\n", neighbors.size());
LOG_DEBUG("Our NodeDB contains %d neighbors\n", num_neighbors); for (size_t i = 0; i < neighbors.size(); i++) {
for (int i = 0; i < num_neighbors; i++) { LOG_DEBUG("Node %d: node_id=0x%x, snr=%.2f\n", i, neighbors[i].node_id, neighbors[i].snr);
const meshtastic_Neighbor *dbEntry = getNeighborByIndex(i);
LOG_DEBUG(" Node %d: node_id=0x%x, snr=%.2f\n", i, dbEntry->node_id, dbEntry->snr);
} }
} }
/* Send our initial owner announcement 35 seconds after we start (to give network time to setup) */ /* Send our initial owner announcement 35 seconds after we start (to give network time to setup) */
NeighborInfoModule::NeighborInfoModule() NeighborInfoModule::NeighborInfoModule()
: ProtobufModule("neighborinfo", meshtastic_PortNum_NEIGHBORINFO_APP, &meshtastic_NeighborInfo_msg), : ProtobufModule("neighborinfo", meshtastic_PortNum_NEIGHBORINFO_APP, &meshtastic_NeighborInfo_msg),
concurrency::OSThread("NeighborInfoModule"), neighbors(neighborState.neighbors), concurrency::OSThread("NeighborInfoModule")
numNeighbors(&neighborState.neighbors_count)
{ {
ourPortNum = meshtastic_PortNum_NEIGHBORINFO_APP; ourPortNum = meshtastic_PortNum_NEIGHBORINFO_APP;
if (moduleConfig.neighbor_info.enabled) { if (moduleConfig.neighbor_info.enabled) {
isPromiscuous = true; // Update neighbors from all packets isPromiscuous = true; // Update neighbors from all packets
this->loadProtoForModule(); setIntervalFromNow(
setIntervalFromNow(35 * 1000); Default::getConfiguredOrDefaultMs(moduleConfig.neighbor_info.update_interval, default_broadcast_interval_secs));
} else { } else {
LOG_DEBUG("NeighborInfoModule is disabled\n"); LOG_DEBUG("NeighborInfoModule is disabled\n");
disable(); disable();
@ -63,18 +57,17 @@ Assumes that the neighborInfo packet has been allocated
*/ */
uint32_t NeighborInfoModule::collectNeighborInfo(meshtastic_NeighborInfo *neighborInfo) uint32_t NeighborInfoModule::collectNeighborInfo(meshtastic_NeighborInfo *neighborInfo)
{ {
uint my_node_id = nodeDB->getNodeNum(); NodeNum my_node_id = nodeDB->getNodeNum();
neighborInfo->node_id = my_node_id; neighborInfo->node_id = my_node_id;
neighborInfo->last_sent_by_id = my_node_id; neighborInfo->last_sent_by_id = my_node_id;
neighborInfo->node_broadcast_interval_secs = moduleConfig.neighbor_info.update_interval; neighborInfo->node_broadcast_interval_secs = moduleConfig.neighbor_info.update_interval;
int num_neighbors = cleanUpNeighbors(); cleanUpNeighbors();
for (int i = 0; i < num_neighbors; i++) { for (auto nbr : neighbors) {
const meshtastic_Neighbor *dbEntry = getNeighborByIndex(i); if ((neighborInfo->neighbors_count < MAX_NUM_NEIGHBORS) && (nbr.node_id != my_node_id)) {
if ((neighborInfo->neighbors_count < MAX_NUM_NEIGHBORS) && (dbEntry->node_id != my_node_id)) { neighborInfo->neighbors[neighborInfo->neighbors_count].node_id = nbr.node_id;
neighborInfo->neighbors[neighborInfo->neighbors_count].node_id = dbEntry->node_id; neighborInfo->neighbors[neighborInfo->neighbors_count].snr = nbr.snr;
neighborInfo->neighbors[neighborInfo->neighbors_count].snr = dbEntry->snr;
// Note: we don't set the last_rx_time and node_broadcast_intervals_secs here, because we don't want to send this over // Note: we don't set the last_rx_time and node_broadcast_intervals_secs here, because we don't want to send this over
// the mesh // the mesh
neighborInfo->neighbors_count++; neighborInfo->neighbors_count++;
@ -85,41 +78,22 @@ uint32_t NeighborInfoModule::collectNeighborInfo(meshtastic_NeighborInfo *neighb
} }
/* /*
Remove neighbors from the database that we haven't heard from in a while Remove neighbors from the database that we haven't heard from in a while
@returns new number of neighbors
*/ */
size_t NeighborInfoModule::cleanUpNeighbors() void NeighborInfoModule::cleanUpNeighbors()
{ {
uint32_t now = getTime(); uint32_t now = getTime();
int num_neighbors = getNumNeighbors();
NodeNum my_node_id = nodeDB->getNodeNum(); NodeNum my_node_id = nodeDB->getNodeNum();
for (auto it = neighbors.rbegin(); it != neighbors.rend();) {
// Find neighbors to remove
std::vector<int> indices_to_remove;
for (int i = 0; i < num_neighbors; i++) {
const meshtastic_Neighbor *dbEntry = getNeighborByIndex(i);
// We will remove a neighbor if we haven't heard from them in twice the broadcast interval // We will remove a neighbor if we haven't heard from them in twice the broadcast interval
if ((now - dbEntry->last_rx_time > dbEntry->node_broadcast_interval_secs * 2) && (dbEntry->node_id != my_node_id)) { if ((now - it->last_rx_time > it->node_broadcast_interval_secs * 2) && (it->node_id != my_node_id)) {
indices_to_remove.push_back(i); LOG_DEBUG("Removing neighbor with node ID 0x%x\n", it->node_id);
it = std::vector<meshtastic_Neighbor>::reverse_iterator(
neighbors.erase(std::next(it).base())); // Erase the element and update the iterator
} else {
++it;
} }
} }
// Update the neighbor list
for (uint i = 0; i < indices_to_remove.size(); i++) {
int index = indices_to_remove[i];
LOG_DEBUG("Removing neighbor with node ID 0x%x\n", neighbors[index].node_id);
for (int j = index; j < num_neighbors - 1; j++) {
neighbors[j] = neighbors[j + 1];
}
(*numNeighbors)--;
}
// Save the neighbor list if we removed any neighbors or neighbors were already updated upon receiving a packet
if (indices_to_remove.size() > 0 || shouldSave) {
saveProtoForModule();
}
return *numNeighbors;
} }
/* Send neighbor info to the mesh */ /* Send neighbor info to the mesh */
@ -143,7 +117,9 @@ Will be used for broadcast.
int32_t NeighborInfoModule::runOnce() int32_t NeighborInfoModule::runOnce()
{ {
bool requestReplies = false; bool requestReplies = false;
sendNeighborInfo(NODENUM_BROADCAST, requestReplies); if (airTime->isTxAllowedChannelUtil(true) && airTime->isTxAllowedAirUtil()) {
sendNeighborInfo(NODENUM_BROADCAST, requestReplies);
}
return Default::getConfiguredOrDefaultMs(moduleConfig.neighbor_info.update_interval, default_broadcast_interval_secs); return Default::getConfiguredOrDefaultMs(moduleConfig.neighbor_info.update_interval, default_broadcast_interval_secs);
} }
@ -178,10 +154,7 @@ void NeighborInfoModule::alterReceivedProtobuf(meshtastic_MeshPacket &p, meshtas
void NeighborInfoModule::resetNeighbors() void NeighborInfoModule::resetNeighbors()
{ {
*numNeighbors = 0; neighbors.clear();
neighborState.neighbors_count = 0;
memset(neighborState.neighbors, 0, sizeof(neighborState.neighbors));
saveProtoForModule();
} }
void NeighborInfoModule::updateNeighbors(const meshtastic_MeshPacket &mp, const meshtastic_NeighborInfo *np) void NeighborInfoModule::updateNeighbors(const meshtastic_MeshPacket &mp, const meshtastic_NeighborInfo *np)
@ -201,61 +174,36 @@ meshtastic_Neighbor *NeighborInfoModule::getOrCreateNeighbor(NodeNum originalSen
n = nodeDB->getNodeNum(); n = nodeDB->getNodeNum();
} }
// look for one in the existing list // look for one in the existing list
for (int i = 0; i < (*numNeighbors); i++) { for (size_t i = 0; i < neighbors.size(); i++) {
meshtastic_Neighbor *nbr = &neighbors[i]; if (neighbors[i].node_id == n) {
if (nbr->node_id == n) {
// if found, update it // if found, update it
nbr->snr = snr; neighbors[i].snr = snr;
nbr->last_rx_time = getTime(); neighbors[i].last_rx_time = getTime();
// Only if this is the original sender, the broadcast interval corresponds to it // Only if this is the original sender, the broadcast interval corresponds to it
if (originalSender == n && node_broadcast_interval_secs != 0) if (originalSender == n && node_broadcast_interval_secs != 0)
nbr->node_broadcast_interval_secs = node_broadcast_interval_secs; neighbors[i].node_broadcast_interval_secs = node_broadcast_interval_secs;
return nbr; return &neighbors[i];
} }
} }
// otherwise, allocate one and assign data to it // otherwise, allocate one and assign data to it
// TODO: max memory for the database should take neighbors into account, but currently doesn't
if (*numNeighbors < MAX_NUM_NEIGHBORS) { meshtastic_Neighbor new_nbr = meshtastic_Neighbor_init_zero;
(*numNeighbors)++; new_nbr.node_id = n;
} new_nbr.snr = snr;
meshtastic_Neighbor *new_nbr = &neighbors[((*numNeighbors) - 1)]; new_nbr.last_rx_time = getTime();
new_nbr->node_id = n;
new_nbr->snr = snr;
new_nbr->last_rx_time = getTime();
// Only if this is the original sender, the broadcast interval corresponds to it // Only if this is the original sender, the broadcast interval corresponds to it
if (originalSender == n && node_broadcast_interval_secs != 0) if (originalSender == n && node_broadcast_interval_secs != 0)
new_nbr->node_broadcast_interval_secs = node_broadcast_interval_secs; new_nbr.node_broadcast_interval_secs = node_broadcast_interval_secs;
else // Assume the same broadcast interval as us for the neighbor if we don't know it else // Assume the same broadcast interval as us for the neighbor if we don't know it
new_nbr->node_broadcast_interval_secs = moduleConfig.neighbor_info.update_interval; new_nbr.node_broadcast_interval_secs = moduleConfig.neighbor_info.update_interval;
shouldSave = true; // Save the new neighbor upon next cleanup
return new_nbr;
}
void NeighborInfoModule::loadProtoForModule() if (neighbors.size() < MAX_NUM_NEIGHBORS) {
{ neighbors.push_back(new_nbr);
if (nodeDB->loadProto(neighborInfoConfigFile, meshtastic_NeighborInfo_size, sizeof(meshtastic_NeighborInfo), } else {
&meshtastic_NeighborInfo_msg, &neighborState) != LoadFileResult::SUCCESS) { // If we have too many neighbors, replace the oldest one
neighborState = meshtastic_NeighborInfo_init_zero; LOG_WARN("Neighbor DB is full, replacing oldest neighbor\n");
neighbors.erase(neighbors.begin());
neighbors.push_back(new_nbr);
} }
} return &neighbors.back();
/**
* @brief Save the module config to file.
*
* @return true On success.
* @return false On error.
*/
bool NeighborInfoModule::saveProtoForModule()
{
bool okay = true;
#ifdef FS
FS.mkdir("/prefs");
#endif
okay &= nodeDB->saveProto(neighborInfoConfigFile, meshtastic_NeighborInfo_size, &meshtastic_NeighborInfo_msg, &neighborState);
if (okay)
shouldSave = false;
return okay;
} }

View File

@ -1,13 +1,13 @@
#pragma once #pragma once
#include "ProtobufModule.h" #include "ProtobufModule.h"
#define MAX_NUM_NEIGHBORS 10 // also defined in NeighborInfo protobuf options
/* /*
* Neighborinfo module for sending info on each node's 0-hop neighbors to the mesh * Neighborinfo module for sending info on each node's 0-hop neighbors to the mesh
*/ */
class NeighborInfoModule : public ProtobufModule<meshtastic_NeighborInfo>, private concurrency::OSThread class NeighborInfoModule : public ProtobufModule<meshtastic_NeighborInfo>, private concurrency::OSThread
{ {
meshtastic_Neighbor *neighbors; std::vector<meshtastic_Neighbor> neighbors;
pb_size_t *numNeighbors;
public: public:
/* /*
@ -18,15 +18,7 @@ class NeighborInfoModule : public ProtobufModule<meshtastic_NeighborInfo>, priva
/* Reset neighbor info after clearing nodeDB*/ /* Reset neighbor info after clearing nodeDB*/
void resetNeighbors(); void resetNeighbors();
bool saveProtoForModule();
private:
bool shouldSave = false; // Whether we should save the neighbor info to flash
protected: protected:
// Note: this holds our local info.
meshtastic_NeighborInfo neighborState;
/* /*
* Called to handle a particular incoming message * Called to handle a particular incoming message
* @return true if you've guaranteed you've handled this message and no other handlers should be considered for it * @return true if you've guaranteed you've handled this message and no other handlers should be considered for it
@ -40,10 +32,9 @@ class NeighborInfoModule : public ProtobufModule<meshtastic_NeighborInfo>, priva
uint32_t collectNeighborInfo(meshtastic_NeighborInfo *neighborInfo); uint32_t collectNeighborInfo(meshtastic_NeighborInfo *neighborInfo);
/* /*
Remove neighbors from the database that we haven't heard from in a while Remove neighbors from the database that we haven't heard from in a while
@returns new number of neighbors
*/ */
size_t cleanUpNeighbors(); void cleanUpNeighbors();
/* Allocate a new NeighborInfo packet */ /* Allocate a new NeighborInfo packet */
meshtastic_NeighborInfo *allocateNeighborInfoPacket(); meshtastic_NeighborInfo *allocateNeighborInfoPacket();
@ -56,22 +47,12 @@ class NeighborInfoModule : public ProtobufModule<meshtastic_NeighborInfo>, priva
*/ */
void sendNeighborInfo(NodeNum dest = NODENUM_BROADCAST, bool wantReplies = false); void sendNeighborInfo(NodeNum dest = NODENUM_BROADCAST, bool wantReplies = false);
size_t getNumNeighbors() { return *numNeighbors; }
meshtastic_Neighbor *getNeighborByIndex(size_t x)
{
assert(x < *numNeighbors);
return &neighbors[x];
}
/* update neighbors with subpacket sniffed from network */ /* update neighbors with subpacket sniffed from network */
void updateNeighbors(const meshtastic_MeshPacket &mp, const meshtastic_NeighborInfo *np); void updateNeighbors(const meshtastic_MeshPacket &mp, const meshtastic_NeighborInfo *np);
/* update a NeighborInfo packet with our NodeNum as last_sent_by_id */ /* update a NeighborInfo packet with our NodeNum as last_sent_by_id */
void alterReceivedProtobuf(meshtastic_MeshPacket &p, meshtastic_NeighborInfo *n) override; void alterReceivedProtobuf(meshtastic_MeshPacket &p, meshtastic_NeighborInfo *n) override;
void loadProtoForModule();
/* Does our periodic broadcast */ /* Does our periodic broadcast */
int32_t runOnce() override; int32_t runOnce() override;

View File

@ -1,4 +1,4 @@
[VERSION] [VERSION]
major = 2 major = 2
minor = 3 minor = 3
build = 6 build = 7