2.8: NodeDB shrink, decoupling, and restructuring (#10413)
* 2.8: NodeDB refactor to decouple satellite entries and decrease size * Regen * Refactor node mute handling to use dedicated functions for clarity and consistency * Develop ref * Fix NodeDB review follow-ups Agent-Logs-Url: https://github.com/meshtastic/firmware/sessions/6b1d6cf6-ed6b-43b6-95cb-8e141757664e Co-authored-by: thebentern <9000580+thebentern@users.noreply.github.com> * Address review validation nits Agent-Logs-Url: https://github.com/meshtastic/firmware/sessions/6b1d6cf6-ed6b-43b6-95cb-8e141757664e Co-authored-by: thebentern <9000580+thebentern@users.noreply.github.com> * Trunk * Potential fix for pull request finding Co-authored-by: Copilot Autofix powered by AI <175728472+Copilot@users.noreply.github.com> * Extract legacy NodeDatabase migration * Fix remaining NodeDB review issues Agent-Logs-Url: https://github.com/meshtastic/firmware/sessions/c76b9a5a-7244-4fbc-9ef0-98091d8caaea Co-authored-by: thebentern <9000580+thebentern@users.noreply.github.com> * Fixes * Trunk * Fix latest review compile follow-ups Agent-Logs-Url: https://github.com/meshtastic/firmware/sessions/5198da01-ec4c-4c16-8a09-68b8e6d5d410 Co-authored-by: thebentern <9000580+thebentern@users.noreply.github.com> * Fix cppcheck style warnings Agent-Logs-Url: https://github.com/meshtastic/firmware/sessions/e60287ba-4ece-46e0-83d8-a6d89664c0bb Co-authored-by: thebentern <9000580+thebentern@users.noreply.github.com> * Change pointer type for mesh node in set_favorite function * Change pointer types for mesh node references to const in multiple applets * Add NodeDB layout v25 documentation and migration guidelines * Remove tests for uninitialized PacketHistory state due to undefined behavior * Fix code block formatting in copilot instructions --------- Co-authored-by: copilot-swe-agent[bot] <198982749+Copilot@users.noreply.github.com> Co-authored-by: Copilot Autofix powered by AI <175728472+Copilot@users.noreply.github.com>
This commit is contained in:
co-authored by
GitHub
copilot-swe-agent[bot] <198982749+Copilot@users.noreply.github.com>
Copilot Autofix powered by AI
parent
1bcabb893b
commit
94bb21ecc7
@@ -362,8 +362,8 @@ std::string InkHUD::Applet::parseShortName(meshtastic_NodeInfoLite *node)
|
||||
assert(node);
|
||||
|
||||
// Use the true shortname if known, and doesn't contain any unprintable characters (emoji, etc.)
|
||||
if (node->has_user) {
|
||||
std::string parsed = parse(node->user.short_name);
|
||||
if (nodeInfoLiteHasUser(node)) {
|
||||
std::string parsed = parse(node->short_name);
|
||||
if (isPrintable(parsed))
|
||||
return parsed;
|
||||
}
|
||||
|
||||
@@ -136,9 +136,10 @@ void InkHUD::MapApplet::onRender(bool full)
|
||||
printAt(vertBarX + (bottomLabelW / 2) + 1, bottomLabelY + (bottomLabelH / 2), vertBottomLabel, CENTER, MIDDLE);
|
||||
|
||||
// Draw our node LAST with full white fill + outline
|
||||
meshtastic_NodeInfoLite *ourNode = nodeDB->getMeshNode(nodeDB->getNodeNum());
|
||||
if (ourNode && nodeDB->hasValidPosition(ourNode)) {
|
||||
Marker self = calculateMarker(ourNode->position.latitude_i * 1e-7, ourNode->position.longitude_i * 1e-7, false, 0);
|
||||
const meshtastic_NodeInfoLite *ourNode = nodeDB->getMeshNode(nodeDB->getNodeNum());
|
||||
meshtastic_PositionLite ourSelfPos;
|
||||
if (ourNode && nodeDB->hasValidPosition(ourNode) && nodeDB->copyNodePosition(ourNode->num, ourSelfPos)) {
|
||||
Marker self = calculateMarker(ourSelfPos.latitude_i * 1e-7, ourSelfPos.longitude_i * 1e-7, false, 0);
|
||||
|
||||
int16_t centerX = X(0.5) + (self.eastMeters * metersToPx);
|
||||
int16_t centerY = Y(0.5) - (self.northMeters * metersToPx);
|
||||
@@ -168,10 +169,11 @@ void InkHUD::MapApplet::onRender(bool full)
|
||||
void InkHUD::MapApplet::getMapCenter(float *lat, float *lng)
|
||||
{
|
||||
// If we have a valid position for our own node, use that as the anchor
|
||||
meshtastic_NodeInfoLite *ourNode = nodeDB->getMeshNode(nodeDB->getNodeNum());
|
||||
if (ourNode && nodeDB->hasValidPosition(ourNode)) {
|
||||
*lat = ourNode->position.latitude_i * 1e-7;
|
||||
*lng = ourNode->position.longitude_i * 1e-7;
|
||||
const meshtastic_NodeInfoLite *ourNode = nodeDB->getMeshNode(nodeDB->getNodeNum());
|
||||
meshtastic_PositionLite ourSelfPos;
|
||||
if (ourNode && nodeDB->hasValidPosition(ourNode) && nodeDB->copyNodePosition(ourNode->num, ourSelfPos)) {
|
||||
*lat = ourSelfPos.latitude_i * 1e-7;
|
||||
*lng = ourSelfPos.longitude_i * 1e-7;
|
||||
} else {
|
||||
// Find mean lat long coords
|
||||
// ============================
|
||||
@@ -201,9 +203,13 @@ void InkHUD::MapApplet::getMapCenter(float *lat, float *lng)
|
||||
if (!shouldDrawNode(node))
|
||||
continue;
|
||||
|
||||
meshtastic_PositionLite pos;
|
||||
if (!nodeDB->copyNodePosition(node->num, pos))
|
||||
continue;
|
||||
|
||||
// Latitude and Longitude of node, in radians
|
||||
float latRad = node->position.latitude_i * (1e-7) * DEG_TO_RAD;
|
||||
float lngRad = node->position.longitude_i * (1e-7) * DEG_TO_RAD;
|
||||
float latRad = pos.latitude_i * (1e-7) * DEG_TO_RAD;
|
||||
float lngRad = pos.longitude_i * (1e-7) * DEG_TO_RAD;
|
||||
|
||||
// Convert to cartesian points, with center of earth at 0, 0, 0
|
||||
// Exact distance from center is irrelevant, as we're only interested in the vector
|
||||
@@ -300,13 +306,17 @@ void InkHUD::MapApplet::getMapCenter(float *lat, float *lng)
|
||||
if (!shouldDrawNode(node))
|
||||
continue;
|
||||
|
||||
meshtastic_PositionLite pos;
|
||||
if (!nodeDB->copyNodePosition(node->num, pos))
|
||||
continue;
|
||||
|
||||
// Check for a new top or bottom latitude
|
||||
float latNode = node->position.latitude_i * 1e-7;
|
||||
float latNode = pos.latitude_i * 1e-7;
|
||||
northernmost = max(northernmost, latNode);
|
||||
southernmost = min(southernmost, latNode);
|
||||
|
||||
// Longitude is trickier
|
||||
float lngNode = node->position.longitude_i * 1e-7;
|
||||
float lngNode = pos.longitude_i * 1e-7;
|
||||
float degEastward = fmod(((lngNode - lngCenter) + 360), 360); // Degrees traveled east from lngCenter to reach node
|
||||
float degWestward = abs(fmod(((lngNode - lngCenter) - 360), 360)); // Degrees traveled west from lngCenter to reach node
|
||||
if (degEastward < degWestward)
|
||||
@@ -372,10 +382,13 @@ void InkHUD::MapApplet::drawLabeledMarker(meshtastic_NodeInfoLite *node)
|
||||
{
|
||||
// Find x and y position based on node's position in nodeDB
|
||||
assert(nodeDB->hasValidPosition(node));
|
||||
Marker m = calculateMarker(node->position.latitude_i * 1e-7, // Lat, converted from Meshtastic's internal int32 style
|
||||
node->position.longitude_i * 1e-7, // Long, converted from Meshtastic's internal int32 style
|
||||
node->has_hops_away, // Is the hopsAway number valid
|
||||
node->hops_away // Hops away
|
||||
meshtastic_PositionLite pos;
|
||||
const bool hasPos = nodeDB->copyNodePosition(node->num, pos);
|
||||
assert(hasPos);
|
||||
Marker m = calculateMarker(pos.latitude_i * 1e-7, // Lat, converted from Meshtastic's internal int32 style
|
||||
pos.longitude_i * 1e-7, // Long, converted from Meshtastic's internal int32 style
|
||||
node->has_hops_away, // Is the hopsAway number valid
|
||||
node->hops_away // Hops away
|
||||
);
|
||||
|
||||
// Convert to pixel coords
|
||||
@@ -516,13 +529,16 @@ void InkHUD::MapApplet::calculateAllMarkers()
|
||||
if (node->num == nodeDB->getNodeNum())
|
||||
continue;
|
||||
|
||||
meshtastic_PositionLite pos;
|
||||
if (!nodeDB->copyNodePosition(node->num, pos))
|
||||
continue;
|
||||
|
||||
// Calculate marker and store it
|
||||
markers.push_back(
|
||||
calculateMarker(node->position.latitude_i * 1e-7, // Lat, converted from Meshtastic's internal int32 style
|
||||
node->position.longitude_i * 1e-7, // Long, converted from Meshtastic's internal int32 style
|
||||
node->has_hops_away, // Is the hopsAway number valid
|
||||
node->hops_away // Hops away
|
||||
));
|
||||
markers.push_back(calculateMarker(pos.latitude_i * 1e-7, // Lat, converted from Meshtastic's internal int32 style
|
||||
pos.longitude_i * 1e-7, // Long, converted from Meshtastic's internal int32 style
|
||||
node->has_hops_away, // Is the hopsAway number valid
|
||||
node->hops_away // Hops away
|
||||
));
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -50,21 +50,23 @@ ProcessMessage InkHUD::NodeListApplet::handleReceived(const meshtastic_MeshPacke
|
||||
c.signal = getSignalStrength(mp.rx_snr, mp.rx_rssi);
|
||||
|
||||
// Assemble info: from nodeDB (needed to detect changes)
|
||||
meshtastic_NodeInfoLite *node = nodeDB->getMeshNode(c.nodeNum);
|
||||
meshtastic_NodeInfoLite *ourNode = nodeDB->getMeshNode(nodeDB->getNodeNum());
|
||||
const meshtastic_NodeInfoLite *node = nodeDB->getMeshNode(c.nodeNum);
|
||||
const meshtastic_NodeInfoLite *ourNode = nodeDB->getMeshNode(nodeDB->getNodeNum());
|
||||
if (node) {
|
||||
if (node->has_hops_away)
|
||||
c.hopsAway = node->hops_away;
|
||||
|
||||
if (nodeDB->hasValidPosition(node) && nodeDB->hasValidPosition(ourNode)) {
|
||||
// Get lat and long as float
|
||||
// Meshtastic stores these as integers internally
|
||||
float ourLat = ourNode->position.latitude_i * 1e-7;
|
||||
float ourLong = ourNode->position.longitude_i * 1e-7;
|
||||
float theirLat = node->position.latitude_i * 1e-7;
|
||||
float theirLong = node->position.longitude_i * 1e-7;
|
||||
meshtastic_PositionLite ourPos;
|
||||
meshtastic_PositionLite theirPos;
|
||||
if (nodeDB->copyNodePosition(ourNode->num, ourPos) && nodeDB->copyNodePosition(node->num, theirPos)) {
|
||||
float ourLat = ourPos.latitude_i * 1e-7;
|
||||
float ourLong = ourPos.longitude_i * 1e-7;
|
||||
float theirLat = theirPos.latitude_i * 1e-7;
|
||||
float theirLong = theirPos.longitude_i * 1e-7;
|
||||
|
||||
c.distanceMeters = (int32_t)GeoCoord::latLongToMeter(theirLat, theirLong, ourLat, ourLong);
|
||||
c.distanceMeters = (int32_t)GeoCoord::latLongToMeter(theirLat, theirLong, ourLat, ourLong);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -179,8 +181,8 @@ void InkHUD::NodeListApplet::onRender(bool full)
|
||||
// -- Longname --
|
||||
// Parse special chars in long name
|
||||
// Use node id if unknown
|
||||
if (node && node->has_user)
|
||||
longName = parse(node->user.long_name); // Found in nodeDB
|
||||
if (nodeInfoLiteHasUser(node))
|
||||
longName = parse(node->long_name); // Found in nodeDB
|
||||
else {
|
||||
// Not found in nodeDB, show a hex nodeid instead
|
||||
longName = hexifyNodeNum(nodeNum);
|
||||
|
||||
@@ -2090,7 +2090,7 @@ void InkHUD::MenuApplet::populateRecipientPage()
|
||||
|
||||
// Count favorites
|
||||
for (uint32_t i = 0; i < nodeCount; i++) {
|
||||
if (nodeDB->getMeshNodeByIndex(i)->is_favorite)
|
||||
if (nodeInfoLiteIsFavorite(nodeDB->getMeshNodeByIndex(i)))
|
||||
favoriteCount++;
|
||||
}
|
||||
|
||||
@@ -2098,10 +2098,10 @@ void InkHUD::MenuApplet::populateRecipientPage()
|
||||
// Don't want some monstrous list that takes 100 clicks to reach exit
|
||||
if (favoriteCount < 20) {
|
||||
for (uint32_t i = 0; i < nodeCount; i++) {
|
||||
meshtastic_NodeInfoLite *node = nodeDB->getMeshNodeByIndex(i);
|
||||
const meshtastic_NodeInfoLite *node = nodeDB->getMeshNodeByIndex(i);
|
||||
|
||||
// Skip node if not a favorite
|
||||
if (!node->is_favorite)
|
||||
if (!nodeInfoLiteIsFavorite(node))
|
||||
continue;
|
||||
|
||||
CannedMessages::RecipientItem r;
|
||||
@@ -2111,8 +2111,8 @@ void InkHUD::MenuApplet::populateRecipientPage()
|
||||
|
||||
// Set a label for the menu item
|
||||
r.label = "DM: ";
|
||||
if (node->has_user)
|
||||
r.label += parse(node->user.long_name);
|
||||
if (nodeInfoLiteHasUser(node))
|
||||
r.label += parse(node->long_name);
|
||||
else
|
||||
r.label += hexifyNodeNum(node->num); // Unsure if it's possible to favorite a node without NodeInfo?
|
||||
|
||||
|
||||
@@ -241,7 +241,7 @@ std::string InkHUD::NotificationApplet::getNotificationText(uint16_t widthAvaila
|
||||
text += msgIsBroadcast ? "From:" : "DM: ";
|
||||
|
||||
// Sender id
|
||||
if (node && node->has_user)
|
||||
if (nodeInfoLiteHasUser(node))
|
||||
text += parseShortName(node);
|
||||
else
|
||||
text += hexifyNodeNum(message->sender);
|
||||
@@ -255,7 +255,7 @@ std::string InkHUD::NotificationApplet::getNotificationText(uint16_t widthAvaila
|
||||
text += msgIsBroadcast ? "Msg from " : "DM from ";
|
||||
|
||||
// Sender id
|
||||
if (node && node->has_user)
|
||||
if (nodeInfoLiteHasUser(node))
|
||||
text += parseShortName(node);
|
||||
else
|
||||
text += hexifyNodeNum(message->sender);
|
||||
|
||||
@@ -70,10 +70,10 @@ void InkHUD::AllMessageApplet::onRender(bool full)
|
||||
// - short name and long name, if available, or
|
||||
// - node id
|
||||
meshtastic_NodeInfoLite *sender = nodeDB->getMeshNode(message->sender);
|
||||
if (sender && sender->has_user) {
|
||||
if (nodeInfoLiteHasUser(sender)) {
|
||||
header += parseShortName(sender); // May be last-four of node if unprintable (emoji, etc)
|
||||
header += " (";
|
||||
header += parse(sender->user.long_name);
|
||||
header += parse(sender->long_name);
|
||||
header += ")";
|
||||
} else
|
||||
header += hexifyNodeNum(message->sender);
|
||||
|
||||
@@ -66,10 +66,10 @@ void InkHUD::DMApplet::onRender(bool full)
|
||||
// - shortname and long name, if available, or
|
||||
// - node id
|
||||
meshtastic_NodeInfoLite *sender = nodeDB->getMeshNode(latestMessage->dm.sender);
|
||||
if (sender && sender->has_user) {
|
||||
if (nodeInfoLiteHasUser(sender)) {
|
||||
header += parseShortName(sender); // May be last-four of node if unprintable (emoji, etc)
|
||||
header += " (";
|
||||
header += parse(sender->user.long_name);
|
||||
header += parse(sender->long_name);
|
||||
header += ")";
|
||||
} else
|
||||
header += hexifyNodeNum(latestMessage->dm.sender);
|
||||
|
||||
@@ -8,7 +8,7 @@ using namespace NicheGraphics;
|
||||
bool InkHUD::FavoritesMapApplet::shouldDrawNode(meshtastic_NodeInfoLite *node)
|
||||
{
|
||||
// Keep our own node available as map anchor/center; all others must be favorited.
|
||||
return node && (node->num == nodeDB->getNodeNum() || node->is_favorite);
|
||||
return node && (node->num == nodeDB->getNodeNum() || nodeInfoLiteIsFavorite(node));
|
||||
}
|
||||
|
||||
void InkHUD::FavoritesMapApplet::onRender(bool full)
|
||||
@@ -25,7 +25,7 @@ void InkHUD::FavoritesMapApplet::onRender(bool full)
|
||||
|
||||
// Draw our latest "node of interest" as a special marker.
|
||||
meshtastic_NodeInfoLite *node = nodeDB->getMeshNode(lastFrom);
|
||||
if (node && node->is_favorite && nodeDB->hasValidPosition(node) && enoughMarkers())
|
||||
if (node && nodeInfoLiteIsFavorite(node) && nodeDB->hasValidPosition(node) && enoughMarkers())
|
||||
drawLabeledMarker(node);
|
||||
}
|
||||
|
||||
@@ -74,7 +74,7 @@ ProcessMessage InkHUD::FavoritesMapApplet::handleReceived(const meshtastic_MeshP
|
||||
} else {
|
||||
// For non-local packets, this applet only reacts to favorited nodes.
|
||||
const meshtastic_NodeInfoLite *sender = nodeDB->getMeshNode(mp.from);
|
||||
if (!sender || !sender->is_favorite)
|
||||
if (!nodeInfoLiteIsFavorite(sender))
|
||||
return ProcessMessage::CONTINUE;
|
||||
|
||||
// Check if this position is from someone different than our previous position packet.
|
||||
|
||||
@@ -80,8 +80,8 @@ void InkHUD::HeardApplet::populateFromNodeDB()
|
||||
ordered.resize(maxCards());
|
||||
|
||||
// Create card info for these (stale) node observations
|
||||
meshtastic_NodeInfoLite *ourNode = nodeDB->getMeshNode(nodeDB->getNodeNum());
|
||||
for (meshtastic_NodeInfoLite *node : ordered) {
|
||||
const meshtastic_NodeInfoLite *ourNode = nodeDB->getMeshNode(nodeDB->getNodeNum());
|
||||
for (const meshtastic_NodeInfoLite *node : ordered) {
|
||||
CardInfo c;
|
||||
c.nodeNum = node->num;
|
||||
|
||||
@@ -89,14 +89,16 @@ void InkHUD::HeardApplet::populateFromNodeDB()
|
||||
c.hopsAway = node->hops_away;
|
||||
|
||||
if (nodeDB->hasValidPosition(node) && nodeDB->hasValidPosition(ourNode)) {
|
||||
// Get lat and long as float
|
||||
// Meshtastic stores these as integers internally
|
||||
float ourLat = ourNode->position.latitude_i * 1e-7;
|
||||
float ourLong = ourNode->position.longitude_i * 1e-7;
|
||||
float theirLat = node->position.latitude_i * 1e-7;
|
||||
float theirLong = node->position.longitude_i * 1e-7;
|
||||
meshtastic_PositionLite ourPos;
|
||||
meshtastic_PositionLite theirPos;
|
||||
if (nodeDB->copyNodePosition(ourNode->num, ourPos) && nodeDB->copyNodePosition(node->num, theirPos)) {
|
||||
float ourLat = ourPos.latitude_i * 1e-7;
|
||||
float ourLong = ourPos.longitude_i * 1e-7;
|
||||
float theirLat = theirPos.latitude_i * 1e-7;
|
||||
float theirLong = theirPos.longitude_i * 1e-7;
|
||||
|
||||
c.distanceMeters = (int32_t)GeoCoord::latLongToMeter(theirLat, theirLong, ourLat, ourLong);
|
||||
c.distanceMeters = (int32_t)GeoCoord::latLongToMeter(theirLat, theirLong, ourLat, ourLong);
|
||||
}
|
||||
}
|
||||
|
||||
// Insert into the card collection (member of base class)
|
||||
@@ -122,4 +124,4 @@ std::string InkHUD::HeardApplet::getHeaderText()
|
||||
return text;
|
||||
}
|
||||
|
||||
#endif
|
||||
#endif
|
||||
|
||||
Reference in New Issue
Block a user