mirror of
https://github.com/meshtastic/firmware.git
synced 2025-12-19 09:12:45 +00:00
Merge branch 'master' into neighborinfo
This commit is contained in:
@@ -11,6 +11,7 @@
|
||||
#include "PowerFSM.h"
|
||||
#include "RTC.h"
|
||||
#include "Router.h"
|
||||
#include "TypeConversions.h"
|
||||
#include "error.h"
|
||||
#include "main.h"
|
||||
#include "mesh-pb-constants.h"
|
||||
@@ -56,14 +57,18 @@ extern void getMacAddr(uint8_t *dmac);
|
||||
* we use !macaddr (no colons).
|
||||
*/
|
||||
meshtastic_User &owner = devicestate.owner;
|
||||
|
||||
meshtastic_Position localPosition = meshtastic_Position_init_default;
|
||||
meshtastic_CriticalErrorCode error_code =
|
||||
meshtastic_CriticalErrorCode_NONE; // For the error code, only show values from this boot (discard value from flash)
|
||||
uint32_t error_address = 0;
|
||||
|
||||
static uint8_t ourMacAddr[6];
|
||||
|
||||
NodeDB::NodeDB() : nodes(devicestate.node_db), numNodes(&devicestate.node_db_count) {}
|
||||
NodeDB::NodeDB()
|
||||
: nodes(devicestate.node_db), numNodes(&devicestate.node_db_count), meshNodes(devicestate.node_db_lite),
|
||||
numMeshNodes(&devicestate.node_db_lite_count)
|
||||
{
|
||||
}
|
||||
|
||||
/**
|
||||
* Most (but not always) of the time we want to treat packets 'from' the local phone (where from == 0), as if they originated on
|
||||
@@ -265,6 +270,9 @@ void NodeDB::resetNodes()
|
||||
{
|
||||
devicestate.node_db_count = 0;
|
||||
memset(devicestate.node_db, 0, sizeof(devicestate.node_db));
|
||||
|
||||
devicestate.node_db_lite_count = 0;
|
||||
memset(devicestate.node_db_lite, 0, sizeof(devicestate.node_db_lite));
|
||||
saveDeviceStateToDisk();
|
||||
neighborInfoModule->resetNeighbors();
|
||||
}
|
||||
@@ -280,6 +288,7 @@ void NodeDB::installDefaultDeviceState()
|
||||
devicestate.has_my_node = true;
|
||||
devicestate.has_owner = true;
|
||||
devicestate.node_db_count = 0;
|
||||
devicestate.node_db_lite_count = 0;
|
||||
devicestate.version = DEVICESTATE_CUR_VER;
|
||||
devicestate.receive_queue_count = 0; // Not yet implemented FIXME
|
||||
|
||||
@@ -319,10 +328,23 @@ void NodeDB::init()
|
||||
owner.hw_model = HW_VENDOR;
|
||||
|
||||
// Include our owner in the node db under our nodenum
|
||||
meshtastic_NodeInfo *info = getOrCreateNode(getNodeNum());
|
||||
meshtastic_NodeInfoLite *info = getOrCreateMeshNode(getNodeNum());
|
||||
info->user = owner;
|
||||
info->has_user = true;
|
||||
|
||||
if (*numNodes > 0) {
|
||||
LOG_DEBUG("Legacy NodeDB detected... Migrating to NodeDBLite\n");
|
||||
uint32_t readIndex = 0;
|
||||
const meshtastic_NodeInfo *oldNodeInfo = nodeDB.readNextNodeInfo(readIndex);
|
||||
while (oldNodeInfo != NULL) {
|
||||
migrateToNodeInfoLite(oldNodeInfo);
|
||||
oldNodeInfo = nodeDB.readNextNodeInfo(readIndex);
|
||||
}
|
||||
LOG_DEBUG("Migration complete! Clearing out legacy NodeDB...\n");
|
||||
devicestate.node_db_count = 0;
|
||||
memset(devicestate.node_db, 0, sizeof(devicestate.node_db));
|
||||
}
|
||||
|
||||
#ifdef ARCH_ESP32
|
||||
Preferences preferences;
|
||||
preferences.begin("meshtastic", false);
|
||||
@@ -366,8 +388,8 @@ void NodeDB::pickNewNodeNum()
|
||||
if (r == NODENUM_BROADCAST || r < NUM_RESERVED)
|
||||
r = NUM_RESERVED; // don't pick a reserved node number
|
||||
|
||||
meshtastic_NodeInfo *found;
|
||||
while ((found = getNode(r)) && memcmp(found->user.macaddr, owner.macaddr, sizeof(owner.macaddr))) {
|
||||
meshtastic_NodeInfoLite *found;
|
||||
while ((found = getMeshNode(r)) && memcmp(found->user.macaddr, owner.macaddr, sizeof(owner.macaddr))) {
|
||||
NodeNum n = random(NUM_RESERVED, NODENUM_BROADCAST); // try a new random choice
|
||||
LOG_DEBUG("NOTE! Our desired nodenum 0x%x is in use, so trying for 0x%x\n", r, n);
|
||||
r = n;
|
||||
@@ -576,7 +598,7 @@ void NodeDB::saveToDisk(int saveWhat)
|
||||
}
|
||||
}
|
||||
|
||||
const meshtastic_NodeInfo *NodeDB::readNextInfo(uint32_t &readIndex)
|
||||
const meshtastic_NodeInfo *NodeDB::readNextNodeInfo(uint32_t &readIndex)
|
||||
{
|
||||
if (readIndex < *numNodes)
|
||||
return &nodes[readIndex++];
|
||||
@@ -584,8 +606,16 @@ const meshtastic_NodeInfo *NodeDB::readNextInfo(uint32_t &readIndex)
|
||||
return NULL;
|
||||
}
|
||||
|
||||
const meshtastic_NodeInfoLite *NodeDB::readNextMeshNode(uint32_t &readIndex)
|
||||
{
|
||||
if (readIndex < *numMeshNodes)
|
||||
return &meshNodes[readIndex++];
|
||||
else
|
||||
return NULL;
|
||||
}
|
||||
|
||||
/// Given a node, return how many seconds in the past (vs now) that we last heard from it
|
||||
uint32_t sinceLastSeen(const meshtastic_NodeInfo *n)
|
||||
uint32_t sinceLastSeen(const meshtastic_NodeInfoLite *n)
|
||||
{
|
||||
uint32_t now = getTime();
|
||||
|
||||
@@ -609,13 +639,13 @@ uint32_t sinceReceived(const meshtastic_MeshPacket *p)
|
||||
|
||||
#define NUM_ONLINE_SECS (60 * 60 * 2) // 2 hrs to consider someone offline
|
||||
|
||||
size_t NodeDB::getNumOnlineNodes()
|
||||
size_t NodeDB::getNumOnlineMeshNodes()
|
||||
{
|
||||
size_t numseen = 0;
|
||||
|
||||
// FIXME this implementation is kinda expensive
|
||||
for (int i = 0; i < *numNodes; i++)
|
||||
if (sinceLastSeen(&nodes[i]) < NUM_ONLINE_SECS)
|
||||
for (int i = 0; i < *numMeshNodes; i++)
|
||||
if (sinceLastSeen(&meshNodes[i]) < NUM_ONLINE_SECS)
|
||||
numseen++;
|
||||
|
||||
return numseen;
|
||||
@@ -627,7 +657,7 @@ size_t NodeDB::getNumOnlineNodes()
|
||||
*/
|
||||
void NodeDB::updatePosition(uint32_t nodeId, const meshtastic_Position &p, RxSource src)
|
||||
{
|
||||
meshtastic_NodeInfo *info = getOrCreateNode(nodeId);
|
||||
meshtastic_NodeInfoLite *info = getOrCreateMeshNode(nodeId);
|
||||
if (!info) {
|
||||
return;
|
||||
}
|
||||
@@ -636,7 +666,9 @@ void NodeDB::updatePosition(uint32_t nodeId, const meshtastic_Position &p, RxSou
|
||||
// Local packet, fully authoritative
|
||||
LOG_INFO("updatePosition LOCAL pos@%x, time=%u, latI=%d, lonI=%d, alt=%d\n", p.timestamp, p.time, p.latitude_i,
|
||||
p.longitude_i, p.altitude);
|
||||
info->position = p;
|
||||
|
||||
info->position = ConvertToPositionLite(p);
|
||||
localPosition = p;
|
||||
} else if ((p.time > 0) && !p.latitude_i && !p.longitude_i && !p.timestamp && !p.location_source) {
|
||||
// FIXME SPECIAL TIME SETTING PACKET FROM EUD TO RADIO
|
||||
// (stop-gap fix for issue #900)
|
||||
@@ -654,7 +686,7 @@ void NodeDB::updatePosition(uint32_t nodeId, const meshtastic_Position &p, RxSou
|
||||
uint32_t tmp_time = info->position.time;
|
||||
|
||||
// Next, update atomically
|
||||
info->position = p;
|
||||
info->position = ConvertToPositionLite(p);
|
||||
|
||||
// Last, restore any fields that may have been overwritten
|
||||
if (!info->position.time)
|
||||
@@ -670,7 +702,7 @@ void NodeDB::updatePosition(uint32_t nodeId, const meshtastic_Position &p, RxSou
|
||||
*/
|
||||
void NodeDB::updateTelemetry(uint32_t nodeId, const meshtastic_Telemetry &t, RxSource src)
|
||||
{
|
||||
meshtastic_NodeInfo *info = getOrCreateNode(nodeId);
|
||||
meshtastic_NodeInfoLite *info = getOrCreateMeshNode(nodeId);
|
||||
// Environment metrics should never go to NodeDb but we'll safegaurd anyway
|
||||
if (!info || t.which_variant != meshtastic_Telemetry_device_metrics_tag) {
|
||||
return;
|
||||
@@ -692,7 +724,7 @@ void NodeDB::updateTelemetry(uint32_t nodeId, const meshtastic_Telemetry &t, RxS
|
||||
*/
|
||||
bool NodeDB::updateUser(uint32_t nodeId, const meshtastic_User &p)
|
||||
{
|
||||
meshtastic_NodeInfo *info = getOrCreateNode(nodeId);
|
||||
meshtastic_NodeInfoLite *info = getOrCreateMeshNode(nodeId);
|
||||
if (!info) {
|
||||
return false;
|
||||
}
|
||||
@@ -725,7 +757,7 @@ void NodeDB::updateFrom(const meshtastic_MeshPacket &mp)
|
||||
if (mp.which_payload_variant == meshtastic_MeshPacket_decoded_tag && mp.from) {
|
||||
LOG_DEBUG("Update DB node 0x%x, rx_time=%u, channel=%d\n", mp.from, mp.rx_time, mp.channel);
|
||||
|
||||
meshtastic_NodeInfo *info = getOrCreateNode(getFrom(&mp));
|
||||
meshtastic_NodeInfoLite *info = getOrCreateMeshNode(getFrom(&mp));
|
||||
if (!info) {
|
||||
return;
|
||||
}
|
||||
@@ -742,9 +774,9 @@ void NodeDB::updateFrom(const meshtastic_MeshPacket &mp)
|
||||
}
|
||||
}
|
||||
|
||||
uint8_t NodeDB::getNodeChannel(NodeNum n)
|
||||
uint8_t NodeDB::getMeshNodeChannel(NodeNum n)
|
||||
{
|
||||
meshtastic_NodeInfo *info = getNode(n);
|
||||
meshtastic_NodeInfoLite *info = getMeshNode(n);
|
||||
if (!info) {
|
||||
return 0; // defaults to PRIMARY
|
||||
}
|
||||
@@ -753,7 +785,7 @@ uint8_t NodeDB::getNodeChannel(NodeNum n)
|
||||
|
||||
/// Find a node in our DB, return null for missing
|
||||
/// NOTE: This function might be called from an ISR
|
||||
meshtastic_NodeInfo *NodeDB::getNode(NodeNum n)
|
||||
meshtastic_NodeInfo *NodeDB::getNodeInfo(NodeNum n)
|
||||
{
|
||||
for (int i = 0; i < *numNodes; i++)
|
||||
if (nodes[i].num == n)
|
||||
@@ -762,38 +794,100 @@ meshtastic_NodeInfo *NodeDB::getNode(NodeNum n)
|
||||
return NULL;
|
||||
}
|
||||
|
||||
/// Find a node in our DB, create an empty NodeInfo if missing
|
||||
meshtastic_NodeInfo *NodeDB::getOrCreateNode(NodeNum n)
|
||||
/// Find a node in our DB, return null for missing
|
||||
/// NOTE: This function might be called from an ISR
|
||||
meshtastic_NodeInfoLite *NodeDB::getMeshNode(NodeNum n)
|
||||
{
|
||||
meshtastic_NodeInfo *info = getNode(n);
|
||||
for (int i = 0; i < *numMeshNodes; i++)
|
||||
if (meshNodes[i].num == n)
|
||||
return &meshNodes[i];
|
||||
|
||||
if (!info) {
|
||||
if ((*numNodes >= MAX_NUM_NODES) || (memGet.getFreeHeap() < meshtastic_NodeInfo_size * 3)) {
|
||||
screen->print("warning: node_db full! erasing oldest entry\n");
|
||||
return NULL;
|
||||
}
|
||||
|
||||
/// Find a node in our DB, create an empty NodeInfo if missing
|
||||
meshtastic_NodeInfoLite *NodeDB::getOrCreateMeshNode(NodeNum n)
|
||||
{
|
||||
meshtastic_NodeInfoLite *lite = getMeshNode(n);
|
||||
|
||||
if (!lite) {
|
||||
if ((*numMeshNodes >= MAX_NUM_NODES) || (memGet.getFreeHeap() < meshtastic_NodeInfoLite_size * 3)) {
|
||||
screen->print("warning: node_db_lite full! erasing oldest entry\n");
|
||||
// look for oldest node and erase it
|
||||
uint32_t oldest = UINT32_MAX;
|
||||
int oldestIndex = -1;
|
||||
for (int i = 0; i < *numNodes; i++) {
|
||||
if (nodes[i].last_heard < oldest) {
|
||||
oldest = nodes[i].last_heard;
|
||||
for (int i = 0; i < *numMeshNodes; i++) {
|
||||
if (meshNodes[i].last_heard < oldest) {
|
||||
oldest = meshNodes[i].last_heard;
|
||||
oldestIndex = i;
|
||||
}
|
||||
}
|
||||
// Shove the remaining nodes down the chain
|
||||
for (int i = oldestIndex; i < *numNodes - 1; i++) {
|
||||
nodes[i] = nodes[i + 1];
|
||||
for (int i = oldestIndex; i < *numMeshNodes - 1; i++) {
|
||||
meshNodes[i] = meshNodes[i + 1];
|
||||
}
|
||||
(*numNodes)--;
|
||||
(*numMeshNodes)--;
|
||||
}
|
||||
// add the node at the end
|
||||
info = &nodes[(*numNodes)++];
|
||||
lite = &meshNodes[(*numMeshNodes)++];
|
||||
|
||||
// everything is missing except the nodenum
|
||||
memset(info, 0, sizeof(*info));
|
||||
info->num = n;
|
||||
memset(lite, 0, sizeof(*lite));
|
||||
lite->num = n;
|
||||
}
|
||||
|
||||
return info;
|
||||
return lite;
|
||||
}
|
||||
|
||||
void NodeDB::migrateToNodeInfoLite(const meshtastic_NodeInfo *node)
|
||||
{
|
||||
meshtastic_NodeInfoLite *lite = getMeshNode(node->num);
|
||||
|
||||
if (!lite) {
|
||||
if ((*numMeshNodes >= MAX_NUM_NODES) || (memGet.getFreeHeap() < meshtastic_NodeInfoLite_size * 3)) {
|
||||
screen->print("warning: node_db_lite full! erasing oldest entry\n");
|
||||
// look for oldest node and erase it
|
||||
uint32_t oldest = UINT32_MAX;
|
||||
int oldestIndex = -1;
|
||||
for (int i = 0; i < *numMeshNodes; i++) {
|
||||
if (meshNodes[i].last_heard < oldest) {
|
||||
oldest = meshNodes[i].last_heard;
|
||||
oldestIndex = i;
|
||||
}
|
||||
}
|
||||
// Shove the remaining nodes down the chain
|
||||
for (int i = oldestIndex; i < *numMeshNodes - 1; i++) {
|
||||
meshNodes[i] = meshNodes[i + 1];
|
||||
}
|
||||
(*numMeshNodes)--;
|
||||
}
|
||||
// add the node at the end
|
||||
lite = &meshNodes[(*numMeshNodes)++];
|
||||
|
||||
// everything is missing except the nodenum
|
||||
memset(lite, 0, sizeof(*lite));
|
||||
lite->num = node->num;
|
||||
lite->snr = node->snr;
|
||||
lite->last_heard = node->last_heard;
|
||||
lite->channel = node->channel;
|
||||
|
||||
if (node->has_position) {
|
||||
lite->has_position = true;
|
||||
lite->position.latitude_i = node->position.latitude_i;
|
||||
lite->position.longitude_i = node->position.longitude_i;
|
||||
lite->position.altitude = node->position.altitude;
|
||||
lite->position.location_source = node->position.location_source;
|
||||
lite->position.time = node->position.time;
|
||||
}
|
||||
if (node->has_user) {
|
||||
lite->has_user = true;
|
||||
lite->user = node->user;
|
||||
}
|
||||
if (node->has_device_metrics) {
|
||||
lite->has_device_metrics = true;
|
||||
lite->device_metrics = node->device_metrics;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/// Record an error that should be reported via analytics
|
||||
|
||||
Reference in New Issue
Block a user