Files
meshtastic_firmware/src/mesh/ProtobufModule.h
T
Ben MeadorsGitHubcopilot-swe-agent[bot] <198982749+Copilot@users.noreply.github.com>Copilot Autofix powered by AI
94bb21ecc7 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>
2026-05-09 15:12:10 -05:00

125 lines
4.7 KiB
C++

#pragma once
#include "SinglePortModule.h"
/**
* A base class for mesh modules that assume that they are sending/receiving one particular protobuf based
* payload. Using one particular app ID.
*
* If you are using protobufs to encode your packets (recommended) you can use this as a baseclass for your module
* and avoid a bunch of boilerplate code.
*/
template <class T> class ProtobufModule : protected SinglePortModule
{
const pb_msgdesc_t *fields;
public:
uint16_t numOnlineNodes = 0;
/** Constructor
* name is for debugging output
*/
ProtobufModule(const char *_name, meshtastic_PortNum _ourPortNum, const pb_msgdesc_t *_fields)
: SinglePortModule(_name, _ourPortNum), fields(_fields)
{
}
protected:
/**
* Handle a received message, the data field in the message is already decoded and is provided
*
* In general decoded will always be !NULL. But in some special applications (where you have handling packets
* for multiple port numbers, decoding will ONLY be attempted for packets where the portnum matches our expected ourPortNum.
*/
virtual bool handleReceivedProtobuf(const meshtastic_MeshPacket &mp, T *decoded) = 0;
/** Called to make changes to a particular incoming message
*/
virtual void alterReceivedProtobuf(meshtastic_MeshPacket &mp, T *decoded){};
/**
* Return a mesh packet which has been preinited with a particular protobuf data payload and port number.
* You can then send this packet (after customizing any of the payload fields you might need) with
* service->sendToMesh()
*/
meshtastic_MeshPacket *allocDataProtobuf(const T &payload)
{
// Update our local node info with our position (even if we don't decide to update anyone else)
meshtastic_MeshPacket *p = allocDataPacket();
p->decoded.payload.size =
pb_encode_to_bytes(p->decoded.payload.bytes, sizeof(p->decoded.payload.bytes), fields, &payload);
// LOG_DEBUG("did encode");
return p;
}
/**
* Gets the short name from the sender of the mesh packet
* Returns "???" if unknown sender
*/
const char *getSenderShortName(const meshtastic_MeshPacket &mp)
{
auto node = nodeDB->getMeshNode(getFrom(&mp));
const char *sender = (node && nodeInfoLiteHasUser(node) && node->short_name[0]) ? node->short_name : "???";
return sender;
}
int handleStatusUpdate(const meshtastic::Status *arg)
{
if (arg->getStatusType() == STATUS_TYPE_NODE) {
numOnlineNodes = nodeStatus->getNumOnline();
}
return 0;
}
private:
/** Called to handle a particular incoming message
@return ProcessMessage::STOP if you've guaranteed you've handled this message and no other handlers should be considered for
it
*/
virtual ProcessMessage handleReceived(const meshtastic_MeshPacket &mp) override
{
// FIXME - we currently update position data in the DB only if the message was a broadcast or destined to us
// it would be better to update even if the message was destined to others.
auto &p = mp.decoded;
T scratch;
T *decoded = NULL;
if (mp.which_payload_variant == meshtastic_MeshPacket_decoded_tag && mp.decoded.portnum == ourPortNum) {
memset(&scratch, 0, sizeof(scratch));
if (pb_decode_from_bytes(p.payload.bytes, p.payload.size, fields, &scratch)) {
decoded = &scratch;
LOG_INFO("Received %s from=0x%0x, id=0x%x, portnum=%d, payloadlen=%d", name, mp.from, mp.id, p.portnum,
p.payload.size);
} else {
LOG_ERROR("Error decoding proto module!");
// if we can't decode it, nobody can process it!
return ProcessMessage::STOP;
}
}
return handleReceivedProtobuf(mp, decoded) ? ProcessMessage::STOP : ProcessMessage::CONTINUE;
}
/** Called to alter a particular incoming message
*/
virtual void alterReceived(meshtastic_MeshPacket &mp) override
{
T scratch;
T *decoded = NULL;
if (mp.which_payload_variant == meshtastic_MeshPacket_decoded_tag && mp.decoded.portnum == ourPortNum) {
memset(&scratch, 0, sizeof(scratch));
const meshtastic_Data &p = mp.decoded;
if (pb_decode_from_bytes(p.payload.bytes, p.payload.size, fields, &scratch)) {
decoded = &scratch;
} else {
LOG_ERROR("Error decoding proto module!");
// if we can't decode it, nobody can process it!
return;
}
return alterReceivedProtobuf(mp, decoded);
}
}
};