mirror of
https://github.com/meshtastic/firmware.git
synced 2025-12-21 10:12:50 +00:00
WIP 1.2 move routing into plugin
This commit is contained in:
@@ -4,16 +4,26 @@ You probably don't care about this section - skip to the next one.
|
|||||||
|
|
||||||
1.2 cleanup & multichannel:
|
1.2 cleanup & multichannel:
|
||||||
|
|
||||||
* remove deprecated
|
* DONE remove deprecated
|
||||||
* allow chaning packets in single transmission
|
* allow chaning packets in single transmission
|
||||||
* fix setchannel in phoneapi.cpp
|
* DONE fix setchannel in phoneapi.cpp
|
||||||
* set mynodeinfo.max_channels
|
* DONE set mynodeinfo.max_channels
|
||||||
* set mynodeinfo.num_bands (formerly num_channels)
|
* DONE set mynodeinfo.num_bands (formerly num_channels)
|
||||||
|
* fix sniffing of non Routing packets
|
||||||
|
* move portnum up?
|
||||||
|
* scrub protobufs to make sure they are absoloute minimum wiresize (in particular packets, ChannelSets and positions)
|
||||||
* send a hint that can be used to select which channel to try and hash against with each message
|
* send a hint that can be used to select which channel to try and hash against with each message
|
||||||
* change syncword
|
* change syncword
|
||||||
* move acks into routing
|
* DONE move acks into routing
|
||||||
* make all subpackets different versions of data
|
* DONE make all subpackets different versions of data
|
||||||
* move routing control into a data packet
|
* DONE move routing control into a data packet
|
||||||
|
* have phoneapi done via plugin
|
||||||
|
* figure out how to add micro_delta to position, make it so that phone apps don't need to understand it?
|
||||||
|
* only send battery updates a max of once a minute
|
||||||
|
* add multichannel support in python
|
||||||
|
* add channel selection for sending
|
||||||
|
* record recevied channel in meshpacket
|
||||||
|
* add channel restrictions for plugins (and restrict routing plugin to the "control" channel)
|
||||||
* make a primaryChannel global and properly maintain it when the phone sends setChannel
|
* make a primaryChannel global and properly maintain it when the phone sends setChannel
|
||||||
* move setCrypto call into packet send and packet decode code
|
* move setCrypto call into packet send and packet decode code
|
||||||
* implement'small locations' change?
|
* implement'small locations' change?
|
||||||
|
|||||||
2
proto
2
proto
Submodule proto updated: 481beb41ba...65914b84f1
@@ -216,8 +216,7 @@ static void drawTextMessageFrame(OLEDDisplay *display, OLEDDisplayUiState *state
|
|||||||
|
|
||||||
// the max length of this buffer is much longer than we can possibly print
|
// the max length of this buffer is much longer than we can possibly print
|
||||||
static char tempBuf[96];
|
static char tempBuf[96];
|
||||||
assert(mp.decoded.which_payloadVariant == SubPacket_data_tag);
|
snprintf(tempBuf, sizeof(tempBuf), " %s", mp.decoded.payload.bytes);
|
||||||
snprintf(tempBuf, sizeof(tempBuf), " %s", mp.decoded.data.payload.bytes);
|
|
||||||
|
|
||||||
display->drawStringMaxWidth(4 + x, 10 + y, SCREEN_WIDTH - (6 + x), tempBuf);
|
display->drawStringMaxWidth(4 + x, 10 + y, SCREEN_WIDTH - (6 + x), tempBuf);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -118,7 +118,7 @@ void setCrypto(size_t chIndex)
|
|||||||
|
|
||||||
void Channels::initDefaults()
|
void Channels::initDefaults()
|
||||||
{
|
{
|
||||||
devicestate.channels_count = MAX_CHANNELS;
|
devicestate.channels_count = MAX_NUM_CHANNELS;
|
||||||
for (int i = 0; i < devicestate.channels_count; i++)
|
for (int i = 0; i < devicestate.channels_count; i++)
|
||||||
fixupChannel(i);
|
fixupChannel(i);
|
||||||
initDefaultChannel(0);
|
initDefaultChannel(0);
|
||||||
|
|||||||
@@ -62,7 +62,7 @@ ErrorCode DSRRouter::send(MeshPacket *p)
|
|||||||
return ReliableRouter::send(p);
|
return ReliableRouter::send(p);
|
||||||
}
|
}
|
||||||
|
|
||||||
void DSRRouter::sniffReceived(const MeshPacket *p)
|
void DSRRouter::sniffReceived(const MeshPacket *p, const Routing &c)
|
||||||
{
|
{
|
||||||
// Learn 0 hop routes by just hearing any adjacent nodes
|
// Learn 0 hop routes by just hearing any adjacent nodes
|
||||||
// But treat broadcasts carefully, because when flood broadcasts go out they keep the same original "from". So we want to
|
// But treat broadcasts carefully, because when flood broadcasts go out they keep the same original "from". So we want to
|
||||||
@@ -72,25 +72,25 @@ void DSRRouter::sniffReceived(const MeshPacket *p)
|
|||||||
addRoute(p->from, p->from, 0); // We are adjacent with zero hops
|
addRoute(p->from, p->from, 0); // We are adjacent with zero hops
|
||||||
}
|
}
|
||||||
|
|
||||||
switch (p->decoded.which_payloadVariant) {
|
switch (c.which_variant) {
|
||||||
case SubPacket_route_request_tag:
|
case Routing_route_request_tag:
|
||||||
// Handle route discovery packets (will be a broadcast message)
|
// Handle route discovery packets (will be a broadcast message)
|
||||||
// FIXME - always start request with the senders nodenum
|
// FIXME - always start request with the senders nodenum
|
||||||
if (weAreInRoute(p->decoded.route_request)) {
|
if (weAreInRoute(c.route_request)) {
|
||||||
DEBUG_MSG("Ignoring a route request that contains us\n");
|
DEBUG_MSG("Ignoring a route request that contains us\n");
|
||||||
} else {
|
} else {
|
||||||
updateRoutes(p->decoded.route_request,
|
updateRoutes(c.route_request,
|
||||||
true); // Update our routing tables based on the route that came in so far on this request
|
true); // Update our routing tables based on the route that came in so far on this request
|
||||||
|
|
||||||
if (p->decoded.dest == getNodeNum()) {
|
if (p->decoded.dest == getNodeNum()) {
|
||||||
// They were looking for us, send back a route reply (the sender address will be first in the list)
|
// They were looking for us, send back a route reply (the sender address will be first in the list)
|
||||||
sendRouteReply(p->decoded.route_request);
|
sendRouteReply(c.route_request);
|
||||||
} else {
|
} else {
|
||||||
// They were looking for someone else, forward it along (as a zero hop broadcast)
|
// They were looking for someone else, forward it along (as a zero hop broadcast)
|
||||||
NodeNum nextHop = getNextHop(p->decoded.dest);
|
NodeNum nextHop = getNextHop(p->decoded.dest);
|
||||||
if (nextHop) {
|
if (nextHop) {
|
||||||
// in our route cache, reply to the requester (the sender address will be first in the list)
|
// in our route cache, reply to the requester (the sender address will be first in the list)
|
||||||
sendRouteReply(p->decoded.route_request, nextHop);
|
sendRouteReply(c.route_request, nextHop);
|
||||||
} else {
|
} else {
|
||||||
// Not in our route cache, rebroadcast on their behalf (after adding ourselves to the request route)
|
// Not in our route cache, rebroadcast on their behalf (after adding ourselves to the request route)
|
||||||
resendRouteRequest(p);
|
resendRouteRequest(p);
|
||||||
@@ -98,14 +98,14 @@ void DSRRouter::sniffReceived(const MeshPacket *p)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
case SubPacket_route_reply_tag:
|
case Routing_route_reply_tag:
|
||||||
updateRoutes(p->decoded.route_reply, false);
|
updateRoutes(c.route_reply, false);
|
||||||
|
|
||||||
// FIXME, if any of our current pending packets were waiting for this route, send them (and leave them as regular pending
|
// FIXME, if any of our current pending packets were waiting for this route, send them (and leave them as regular pending
|
||||||
// packets until ack arrives)
|
// packets until ack arrives)
|
||||||
// FIXME, if we don't get a route reply at all (or a route error), timeout and generate a routeerror TIMEOUT on our own...
|
// FIXME, if we don't get a route reply at all (or a route error), timeout and generate a routeerror TIMEOUT on our own...
|
||||||
break;
|
break;
|
||||||
case SubPacket_error_reason_tag:
|
case Routing_error_reason_tag:
|
||||||
removeRoute(p->decoded.dest);
|
removeRoute(p->decoded.dest);
|
||||||
|
|
||||||
// FIXME: if any pending packets were waiting on this route, delete them
|
// FIXME: if any pending packets were waiting on this route, delete them
|
||||||
@@ -131,7 +131,7 @@ void DSRRouter::sniffReceived(const MeshPacket *p)
|
|||||||
assert(p->decoded.source); // I think this is guaranteed by now
|
assert(p->decoded.source); // I think this is guaranteed by now
|
||||||
|
|
||||||
// FIXME - what if the current packet _is_ a route error packet?
|
// FIXME - what if the current packet _is_ a route error packet?
|
||||||
sendRouteError(p, ErrorReason_NO_ROUTE);
|
sendRouteError(p, Routing_Error_NO_ROUTE);
|
||||||
}
|
}
|
||||||
|
|
||||||
// FIXME, stop local processing of this packet
|
// FIXME, stop local processing of this packet
|
||||||
@@ -139,18 +139,18 @@ void DSRRouter::sniffReceived(const MeshPacket *p)
|
|||||||
|
|
||||||
// handle naks - convert them to route error packets
|
// handle naks - convert them to route error packets
|
||||||
// All naks are generated locally, because we failed resending the packet too many times
|
// All naks are generated locally, because we failed resending the packet too many times
|
||||||
PacketId nakId = p->decoded.which_ackVariant == SubPacket_fail_id_tag ? p->decoded.ackVariant.fail_id : 0;
|
PacketId nakId = c.fail_id;
|
||||||
if (nakId) {
|
if (nakId) {
|
||||||
auto pending = findPendingPacket(p->to, nakId);
|
auto pending = findPendingPacket(p->to, nakId);
|
||||||
if (pending && pending->packet->decoded.source) { // if source not set, this was not a multihop packet, just ignore
|
if (pending && pending->packet->decoded.source) { // if source not set, this was not a multihop packet, just ignore
|
||||||
removeRoute(pending->packet->decoded.dest); // We no longer have a route to the specified node
|
removeRoute(pending->packet->decoded.dest); // We no longer have a route to the specified node
|
||||||
|
|
||||||
sendRouteError(p, ErrorReason_GOT_NAK);
|
sendRouteError(p, Routing_Error_GOT_NAK);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
return ReliableRouter::sniffReceived(p);
|
ReliableRouter::sniffReceived(p, c);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -230,7 +230,7 @@ void DSRRouter::sendNextHop(NodeNum n, const MeshPacket *p)
|
|||||||
/**
|
/**
|
||||||
* Send a route error packet towards whoever originally sent this message
|
* Send a route error packet towards whoever originally sent this message
|
||||||
*/
|
*/
|
||||||
void DSRRouter::sendRouteError(const MeshPacket *p, ErrorReason err)
|
void DSRRouter::sendRouteError(const MeshPacket *p, Routing_Error err)
|
||||||
{
|
{
|
||||||
DEBUG_MSG("FIXME not implemented sendRouteError\n");
|
DEBUG_MSG("FIXME not implemented sendRouteError\n");
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -8,7 +8,7 @@ class DSRRouter : public ReliableRouter
|
|||||||
* Every (non duplicate) packet this node receives will be passed through this method. This allows subclasses to
|
* Every (non duplicate) packet this node receives will be passed through this method. This allows subclasses to
|
||||||
* update routing tables etc... based on what we overhear (even for messages not destined to our node)
|
* update routing tables etc... based on what we overhear (even for messages not destined to our node)
|
||||||
*/
|
*/
|
||||||
virtual void sniffReceived(const MeshPacket *p);
|
virtual void sniffReceived(const MeshPacket *p, const Routing &c);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Send a packet on a suitable interface. This routine will
|
* Send a packet on a suitable interface. This routine will
|
||||||
@@ -70,7 +70,7 @@ class DSRRouter : public ReliableRouter
|
|||||||
/**
|
/**
|
||||||
* Send a route error packet towards whoever originally sent this message
|
* Send a route error packet towards whoever originally sent this message
|
||||||
*/
|
*/
|
||||||
void sendRouteError(const MeshPacket *p, ErrorReason err);
|
void sendRouteError(const MeshPacket *p, Routing_Error err);
|
||||||
|
|
||||||
/** make a copy of p, start discovery, but only if we don't
|
/** make a copy of p, start discovery, but only if we don't
|
||||||
* already a discovery in progress for that node number. Caller has already scheduled this message for retransmission
|
* already a discovery in progress for that node number. Caller has already scheduled this message for retransmission
|
||||||
|
|||||||
@@ -27,7 +27,7 @@ bool FloodingRouter::shouldFilterReceived(const MeshPacket *p)
|
|||||||
return Router::shouldFilterReceived(p);
|
return Router::shouldFilterReceived(p);
|
||||||
}
|
}
|
||||||
|
|
||||||
void FloodingRouter::sniffReceived(const MeshPacket *p)
|
void FloodingRouter::sniffReceived(const MeshPacket *p, const Routing &c)
|
||||||
{
|
{
|
||||||
// If a broadcast, possibly _also_ send copies out into the mesh.
|
// If a broadcast, possibly _also_ send copies out into the mesh.
|
||||||
// (FIXME, do something smarter than naive flooding here)
|
// (FIXME, do something smarter than naive flooding here)
|
||||||
@@ -48,5 +48,5 @@ void FloodingRouter::sniffReceived(const MeshPacket *p)
|
|||||||
}
|
}
|
||||||
|
|
||||||
// handle the packet as normal
|
// handle the packet as normal
|
||||||
Router::sniffReceived(p);
|
Router::sniffReceived(p, c);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -55,5 +55,5 @@ class FloodingRouter : public Router, protected PacketHistory
|
|||||||
/**
|
/**
|
||||||
* Look for broadcasts we need to rebroadcast
|
* Look for broadcasts we need to rebroadcast
|
||||||
*/
|
*/
|
||||||
virtual void sniffReceived(const MeshPacket *p);
|
virtual void sniffReceived(const MeshPacket *p, const Routing &c);
|
||||||
};
|
};
|
||||||
|
|||||||
@@ -33,7 +33,7 @@ void fixPriority(MeshPacket *p)
|
|||||||
if (p->priority == MeshPacket_Priority_UNSET) {
|
if (p->priority == MeshPacket_Priority_UNSET) {
|
||||||
// if acks give high priority
|
// if acks give high priority
|
||||||
// if a reliable message give a bit higher default priority
|
// if a reliable message give a bit higher default priority
|
||||||
p->priority = p->decoded.which_ackVariant ? MeshPacket_Priority_ACK :
|
p->priority = (p->decoded.portnum == PortNum_ROUTING_APP) ? MeshPacket_Priority_ACK :
|
||||||
(p->want_ack ? MeshPacket_Priority_RELIABLE : MeshPacket_Priority_DEFAULT);
|
(p->want_ack ? MeshPacket_Priority_RELIABLE : MeshPacket_Priority_DEFAULT);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -32,7 +32,7 @@ void MeshPlugin::callPlugins(const MeshPacket &mp)
|
|||||||
auto &pi = **i;
|
auto &pi = **i;
|
||||||
|
|
||||||
pi.currentRequest = ∓
|
pi.currentRequest = ∓
|
||||||
if (pi.wantPortnum(mp.decoded.data.portnum)) {
|
if (pi.wantPortnum(mp.decoded.portnum)) {
|
||||||
pluginFound = true;
|
pluginFound = true;
|
||||||
|
|
||||||
bool handled = pi.handleReceived(mp);
|
bool handled = pi.handleReceived(mp);
|
||||||
@@ -50,7 +50,7 @@ void MeshPlugin::callPlugins(const MeshPacket &mp)
|
|||||||
}
|
}
|
||||||
|
|
||||||
if(!pluginFound)
|
if(!pluginFound)
|
||||||
DEBUG_MSG("No plugins interested in portnum=%d\n", mp.decoded.data.portnum);
|
DEBUG_MSG("No plugins interested in portnum=%d\n", mp.decoded.portnum);
|
||||||
}
|
}
|
||||||
|
|
||||||
/** Messages can be received that have the want_response bit set. If set, this callback will be invoked
|
/** Messages can be received that have the want_response bit set. If set, this callback will be invoked
|
||||||
|
|||||||
@@ -31,6 +31,12 @@ class MeshPlugin
|
|||||||
protected:
|
protected:
|
||||||
const char *name;
|
const char *name;
|
||||||
|
|
||||||
|
/* Most plugins only care about packets that are destined for their node (i.e. broadcasts or has their node as the specific recipient)
|
||||||
|
But some plugs might want to 'sniff' packets that are merely being routed (passing through the current node). Those plugins can set this to
|
||||||
|
true and their handleReceived() will be called for every packet.
|
||||||
|
*/
|
||||||
|
bool isPromiscuous = false;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* If this plugin is currently handling a request currentRequest will be preset
|
* If this plugin is currently handling a request currentRequest will be preset
|
||||||
* to the packet with the request. This is mostly useful for reply handlers.
|
* to the packet with the request. This is mostly useful for reply handlers.
|
||||||
|
|||||||
@@ -4,6 +4,7 @@
|
|||||||
|
|
||||||
#include "FS.h"
|
#include "FS.h"
|
||||||
|
|
||||||
|
#include "Channels.h"
|
||||||
#include "CryptoEngine.h"
|
#include "CryptoEngine.h"
|
||||||
#include "FSCommon.h"
|
#include "FSCommon.h"
|
||||||
#include "GPS.h"
|
#include "GPS.h"
|
||||||
@@ -16,7 +17,6 @@
|
|||||||
#include "configuration.h"
|
#include "configuration.h"
|
||||||
#include "error.h"
|
#include "error.h"
|
||||||
#include "main.h"
|
#include "main.h"
|
||||||
#include "Channels.h"
|
|
||||||
#include "mesh-pb-constants.h"
|
#include "mesh-pb-constants.h"
|
||||||
#include <pb_decode.h>
|
#include <pb_decode.h>
|
||||||
#include <pb_encode.h>
|
#include <pb_encode.h>
|
||||||
@@ -160,7 +160,7 @@ void NodeDB::init()
|
|||||||
loadFromDisk();
|
loadFromDisk();
|
||||||
// saveToDisk();
|
// saveToDisk();
|
||||||
|
|
||||||
myNodeInfo.max_channels = MAX_CHANNELS; // tell others the max # of channels we can understand
|
myNodeInfo.max_channels = MAX_NUM_CHANNELS; // tell others the max # of channels we can understand
|
||||||
|
|
||||||
myNodeInfo.error_code =
|
myNodeInfo.error_code =
|
||||||
CriticalErrorCode_None; // For the error code, only show values from this boot (discard value from flash)
|
CriticalErrorCode_None; // For the error code, only show values from this boot (discard value from flash)
|
||||||
@@ -394,7 +394,7 @@ void NodeDB::updateUser(uint32_t nodeId, const User &p)
|
|||||||
void NodeDB::updateFrom(const MeshPacket &mp)
|
void NodeDB::updateFrom(const MeshPacket &mp)
|
||||||
{
|
{
|
||||||
if (mp.which_payloadVariant == MeshPacket_decoded_tag) {
|
if (mp.which_payloadVariant == MeshPacket_decoded_tag) {
|
||||||
const SubPacket &p = mp.decoded;
|
const Data &p = mp.decoded;
|
||||||
DEBUG_MSG("Update DB node 0x%x, rx_time=%u\n", mp.from, mp.rx_time);
|
DEBUG_MSG("Update DB node 0x%x, rx_time=%u\n", mp.from, mp.rx_time);
|
||||||
|
|
||||||
NodeInfo *info = getOrCreateNode(mp.from);
|
NodeInfo *info = getOrCreateNode(mp.from);
|
||||||
@@ -406,18 +406,8 @@ void NodeDB::updateFrom(const MeshPacket &mp)
|
|||||||
|
|
||||||
info->snr = mp.rx_snr; // keep the most recent SNR we received for this node.
|
info->snr = mp.rx_snr; // keep the most recent SNR we received for this node.
|
||||||
|
|
||||||
switch (p.which_payloadVariant) {
|
|
||||||
|
|
||||||
case SubPacket_data_tag: {
|
|
||||||
if (mp.to == NODENUM_BROADCAST || mp.to == nodeDB.getNodeNum())
|
if (mp.to == NODENUM_BROADCAST || mp.to == nodeDB.getNodeNum())
|
||||||
MeshPlugin::callPlugins(mp);
|
MeshPlugin::callPlugins(mp);
|
||||||
break;
|
|
||||||
}
|
|
||||||
|
|
||||||
default: {
|
|
||||||
notifyObservers(); // If the node counts have changed, notify observers
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -8,7 +8,7 @@
|
|||||||
* If you are using protobufs to encode your packets (recommended) you can use this as a baseclass for your plugin
|
* If you are using protobufs to encode your packets (recommended) you can use this as a baseclass for your plugin
|
||||||
* and avoid a bunch of boilerplate code.
|
* and avoid a bunch of boilerplate code.
|
||||||
*/
|
*/
|
||||||
template <class T> class ProtobufPlugin : private SinglePortPlugin
|
template <class T> class ProtobufPlugin : protected SinglePortPlugin
|
||||||
{
|
{
|
||||||
const pb_msgdesc_t *fields;
|
const pb_msgdesc_t *fields;
|
||||||
|
|
||||||
@@ -38,8 +38,8 @@ template <class T> class ProtobufPlugin : private SinglePortPlugin
|
|||||||
// Update our local node info with our position (even if we don't decide to update anyone else)
|
// Update our local node info with our position (even if we don't decide to update anyone else)
|
||||||
MeshPacket *p = allocDataPacket();
|
MeshPacket *p = allocDataPacket();
|
||||||
|
|
||||||
p->decoded.data.payload.size =
|
p->decoded.payload.size =
|
||||||
pb_encode_to_bytes(p->decoded.data.payload.bytes, sizeof(p->decoded.data.payload.bytes), fields, &payload);
|
pb_encode_to_bytes(p->decoded.payload.bytes, sizeof(p->decoded.payload.bytes), fields, &payload);
|
||||||
// DEBUG_MSG("did encode\n");
|
// DEBUG_MSG("did encode\n");
|
||||||
return p;
|
return p;
|
||||||
}
|
}
|
||||||
@@ -54,7 +54,7 @@ template <class T> class ProtobufPlugin : private SinglePortPlugin
|
|||||||
// FIXME - we currently update position data in the DB only if the message was a broadcast or destined to us
|
// 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.
|
// it would be better to update even if the message was destined to others.
|
||||||
|
|
||||||
auto &p = mp.decoded.data;
|
auto &p = mp.decoded;
|
||||||
DEBUG_MSG("Received %s from=0x%0x, id=0x%x, payloadlen=%d\n", name, mp.from, mp.id, p.payload.size);
|
DEBUG_MSG("Received %s from=0x%0x, id=0x%x, payloadlen=%d\n", name, mp.from, mp.id, p.payload.size);
|
||||||
|
|
||||||
T scratch;
|
T scratch;
|
||||||
|
|||||||
@@ -1,12 +1,12 @@
|
|||||||
|
|
||||||
#include "RadioInterface.h"
|
#include "RadioInterface.h"
|
||||||
|
#include "Channels.h"
|
||||||
#include "MeshRadio.h"
|
#include "MeshRadio.h"
|
||||||
#include "MeshService.h"
|
#include "MeshService.h"
|
||||||
#include "NodeDB.h"
|
#include "NodeDB.h"
|
||||||
#include "assert.h"
|
#include "assert.h"
|
||||||
#include "configuration.h"
|
#include "configuration.h"
|
||||||
#include "sleep.h"
|
#include "sleep.h"
|
||||||
#include "Channels.h"
|
|
||||||
#include <assert.h>
|
#include <assert.h>
|
||||||
#include <pb_decode.h>
|
#include <pb_decode.h>
|
||||||
#include <pb_encode.h>
|
#include <pb_encode.h>
|
||||||
@@ -122,17 +122,9 @@ void printPacket(const char *prefix, const MeshPacket *p)
|
|||||||
p->hop_limit);
|
p->hop_limit);
|
||||||
if (p->which_payloadVariant == MeshPacket_decoded_tag) {
|
if (p->which_payloadVariant == MeshPacket_decoded_tag) {
|
||||||
auto &s = p->decoded;
|
auto &s = p->decoded;
|
||||||
switch (s.which_payloadVariant) {
|
|
||||||
case SubPacket_data_tag:
|
DEBUG_MSG(" Portnum=%d", s.portnum);
|
||||||
DEBUG_MSG(" Portnum=%d", s.data.portnum);
|
|
||||||
break;
|
|
||||||
case 0:
|
|
||||||
DEBUG_MSG(" Payload:None");
|
|
||||||
break;
|
|
||||||
default:
|
|
||||||
DEBUG_MSG(" Payload:%d", s.which_payloadVariant);
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
if (s.want_response)
|
if (s.want_response)
|
||||||
DEBUG_MSG(" WANTRESP");
|
DEBUG_MSG(" WANTRESP");
|
||||||
|
|
||||||
@@ -142,10 +134,11 @@ void printPacket(const char *prefix, const MeshPacket *p)
|
|||||||
if (s.dest != 0)
|
if (s.dest != 0)
|
||||||
DEBUG_MSG(" dest=%08x", s.dest);
|
DEBUG_MSG(" dest=%08x", s.dest);
|
||||||
|
|
||||||
|
/* now inside Data and therefore kinda opaque
|
||||||
if (s.which_ackVariant == SubPacket_success_id_tag)
|
if (s.which_ackVariant == SubPacket_success_id_tag)
|
||||||
DEBUG_MSG(" successId=%08x", s.ackVariant.success_id);
|
DEBUG_MSG(" successId=%08x", s.ackVariant.success_id);
|
||||||
else if (s.which_ackVariant == SubPacket_fail_id_tag)
|
else if (s.which_ackVariant == SubPacket_fail_id_tag)
|
||||||
DEBUG_MSG(" failId=%08x", s.ackVariant.fail_id);
|
DEBUG_MSG(" failId=%08x", s.ackVariant.fail_id); */
|
||||||
} else {
|
} else {
|
||||||
DEBUG_MSG(" encrypted");
|
DEBUG_MSG(" encrypted");
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -34,7 +34,7 @@ bool ReliableRouter::shouldFilterReceived(const MeshPacket *p)
|
|||||||
// the original sending process.
|
// the original sending process.
|
||||||
if (stopRetransmission(p->from, p->id)) {
|
if (stopRetransmission(p->from, p->id)) {
|
||||||
DEBUG_MSG("Someone is retransmitting for us, generate implicit ack\n");
|
DEBUG_MSG("Someone is retransmitting for us, generate implicit ack\n");
|
||||||
sendAckNak(ErrorReason_NONE, p->from, p->id);
|
sendAckNak(Routing_Error_NONE, p->from, p->id);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -53,20 +53,20 @@ bool ReliableRouter::shouldFilterReceived(const MeshPacket *p)
|
|||||||
*
|
*
|
||||||
* Otherwise, let superclass handle it.
|
* Otherwise, let superclass handle it.
|
||||||
*/
|
*/
|
||||||
void ReliableRouter::sniffReceived(const MeshPacket *p)
|
void ReliableRouter::sniffReceived(const MeshPacket *p, const Routing &c)
|
||||||
{
|
{
|
||||||
NodeNum ourNode = getNodeNum();
|
NodeNum ourNode = getNodeNum();
|
||||||
|
|
||||||
if (p->to == ourNode) { // ignore ack/nak/want_ack packets that are not address to us (we only handle 0 hop reliability
|
if (p->to == ourNode) { // ignore ack/nak/want_ack packets that are not address to us (we only handle 0 hop reliability
|
||||||
// - not DSR routing)
|
// - not DSR routing)
|
||||||
if (p->want_ack) {
|
if (p->want_ack) {
|
||||||
sendAckNak(ErrorReason_NONE, p->from, p->id);
|
sendAckNak(Routing_Error_NONE, p->from, p->id);
|
||||||
}
|
}
|
||||||
|
|
||||||
// If the payload is valid, look for ack/nak
|
// If the payload is valid, look for ack/nak
|
||||||
|
|
||||||
PacketId ackId = p->decoded.which_ackVariant == SubPacket_success_id_tag ? p->decoded.ackVariant.success_id : 0;
|
PacketId ackId = c.success_id;
|
||||||
PacketId nakId = p->decoded.which_ackVariant == SubPacket_fail_id_tag ? p->decoded.ackVariant.fail_id : 0;
|
PacketId nakId = c.fail_id;
|
||||||
|
|
||||||
// We intentionally don't check wasSeenRecently, because it is harmless to delete non existent retransmission records
|
// We intentionally don't check wasSeenRecently, because it is harmless to delete non existent retransmission records
|
||||||
if (ackId || nakId) {
|
if (ackId || nakId) {
|
||||||
@@ -81,7 +81,7 @@ void ReliableRouter::sniffReceived(const MeshPacket *p)
|
|||||||
}
|
}
|
||||||
|
|
||||||
// handle the packet as normal
|
// handle the packet as normal
|
||||||
FloodingRouter::sniffReceived(p);
|
FloodingRouter::sniffReceived(p, c);
|
||||||
}
|
}
|
||||||
|
|
||||||
#define NUM_RETRANSMISSIONS 3
|
#define NUM_RETRANSMISSIONS 3
|
||||||
@@ -155,7 +155,7 @@ int32_t ReliableRouter::doRetransmissions()
|
|||||||
if (p.numRetransmissions == 0) {
|
if (p.numRetransmissions == 0) {
|
||||||
DEBUG_MSG("Reliable send failed, returning a nak fr=0x%x,to=0x%x,id=%d\n", p.packet->from, p.packet->to,
|
DEBUG_MSG("Reliable send failed, returning a nak fr=0x%x,to=0x%x,id=%d\n", p.packet->from, p.packet->to,
|
||||||
p.packet->id);
|
p.packet->id);
|
||||||
sendAckNak(ErrorReason_MAX_RETRANSMIT, p.packet->from, p.packet->id);
|
sendAckNak(Routing_Error_MAX_RETRANSMIT, p.packet->from, p.packet->id);
|
||||||
// Note: we don't stop retransmission here, instead the Nak packet gets processed in sniffReceived - which
|
// Note: we don't stop retransmission here, instead the Nak packet gets processed in sniffReceived - which
|
||||||
// allows the DSR version to still be able to look at the PendingPacket
|
// allows the DSR version to still be able to look at the PendingPacket
|
||||||
stopRetransmission(it->first);
|
stopRetransmission(it->first);
|
||||||
|
|||||||
@@ -90,7 +90,7 @@ class ReliableRouter : public FloodingRouter
|
|||||||
/**
|
/**
|
||||||
* Look for acks/naks or someone retransmitting us
|
* Look for acks/naks or someone retransmitting us
|
||||||
*/
|
*/
|
||||||
virtual void sniffReceived(const MeshPacket *p);
|
virtual void sniffReceived(const MeshPacket *p, const Routing &c);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Try to find the pending packet record for this ID (or NULL if not found)
|
* Try to find the pending packet record for this ID (or NULL if not found)
|
||||||
|
|||||||
@@ -4,6 +4,7 @@
|
|||||||
#include "configuration.h"
|
#include "configuration.h"
|
||||||
#include "mesh-pb-constants.h"
|
#include "mesh-pb-constants.h"
|
||||||
#include <NodeDB.h>
|
#include <NodeDB.h>
|
||||||
|
#include "plugins/RoutingPlugin.h"
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Router todo
|
* Router todo
|
||||||
@@ -101,27 +102,9 @@ MeshPacket *Router::allocForSending()
|
|||||||
/**
|
/**
|
||||||
* Send an ack or a nak packet back towards whoever sent idFrom
|
* Send an ack or a nak packet back towards whoever sent idFrom
|
||||||
*/
|
*/
|
||||||
void Router::sendAckNak(ErrorReason err, NodeNum to, PacketId idFrom)
|
void Router::sendAckNak(Routing_Error err, NodeNum to, PacketId idFrom)
|
||||||
{
|
{
|
||||||
auto p = allocForSending();
|
routingPlugin->sendAckNak(err, to, idFrom);
|
||||||
p->hop_limit = 0; // Assume just immediate neighbors for now
|
|
||||||
p->to = to;
|
|
||||||
DEBUG_MSG("Sending an err=%d,to=0x%x,idFrom=0x%x,id=0x%x\n", err, to, idFrom, p->id);
|
|
||||||
|
|
||||||
if (!err) {
|
|
||||||
p->decoded.ackVariant.success_id = idFrom;
|
|
||||||
p->decoded.which_ackVariant = SubPacket_success_id_tag;
|
|
||||||
} else {
|
|
||||||
p->decoded.ackVariant.fail_id = idFrom;
|
|
||||||
p->decoded.which_ackVariant = SubPacket_fail_id_tag;
|
|
||||||
|
|
||||||
// Also send back the error reason
|
|
||||||
p->decoded.which_payloadVariant = SubPacket_error_reason_tag;
|
|
||||||
p->decoded.error_reason = err;
|
|
||||||
}
|
|
||||||
p->priority = MeshPacket_Priority_ACK;
|
|
||||||
|
|
||||||
sendLocal(p); // we sometimes send directly to the local node
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@@ -138,7 +121,7 @@ ErrorCode Router::sendLocal(MeshPacket *p)
|
|||||||
|
|
||||||
// ERROR! no radio found, report failure back to the client and drop the packet
|
// ERROR! no radio found, report failure back to the client and drop the packet
|
||||||
DEBUG_MSG("Error: No interface, returning NAK and dropping packet.\n");
|
DEBUG_MSG("Error: No interface, returning NAK and dropping packet.\n");
|
||||||
sendAckNak(ErrorReason_NO_INTERFACE, p->from, p->id);
|
sendAckNak(Routing_Error_NO_INTERFACE, p->from, p->id);
|
||||||
packetPool.release(p);
|
packetPool.release(p);
|
||||||
|
|
||||||
return ERRNO_NO_INTERFACES;
|
return ERRNO_NO_INTERFACES;
|
||||||
@@ -162,9 +145,8 @@ ErrorCode Router::send(MeshPacket *p)
|
|||||||
{
|
{
|
||||||
assert(p->to != nodeDB.getNodeNum()); // should have already been handled by sendLocal
|
assert(p->to != nodeDB.getNodeNum()); // should have already been handled by sendLocal
|
||||||
|
|
||||||
PacketId nakId = p->decoded.which_ackVariant == SubPacket_fail_id_tag ? p->decoded.ackVariant.fail_id : 0;
|
// PacketId nakId = p->decoded.which_ackVariant == SubPacket_fail_id_tag ? p->decoded.ackVariant.fail_id : 0;
|
||||||
assert(
|
// assert(!nakId); // I don't think we ever send 0hop naks over the wire (other than to the phone), test that assumption with assert
|
||||||
!nakId); // I don't think we ever send 0hop naks over the wire (other than to the phone), test that assumption with assert
|
|
||||||
|
|
||||||
// Never set the want_ack flag on broadcast packets sent over the air.
|
// Never set the want_ack flag on broadcast packets sent over the air.
|
||||||
if (p->to == NODENUM_BROADCAST)
|
if (p->to == NODENUM_BROADCAST)
|
||||||
@@ -179,7 +161,7 @@ ErrorCode Router::send(MeshPacket *p)
|
|||||||
if (p->which_payloadVariant == MeshPacket_decoded_tag) {
|
if (p->which_payloadVariant == MeshPacket_decoded_tag) {
|
||||||
static uint8_t bytes[MAX_RHPACKETLEN]; // we have to use a scratch buffer because a union
|
static uint8_t bytes[MAX_RHPACKETLEN]; // we have to use a scratch buffer because a union
|
||||||
|
|
||||||
size_t numbytes = pb_encode_to_bytes(bytes, sizeof(bytes), SubPacket_fields, &p->decoded);
|
size_t numbytes = pb_encode_to_bytes(bytes, sizeof(bytes), Data_fields, &p->decoded);
|
||||||
|
|
||||||
assert(numbytes <= MAX_RHPACKETLEN);
|
assert(numbytes <= MAX_RHPACKETLEN);
|
||||||
crypto->encrypt(p->from, p->id, numbytes, bytes);
|
crypto->encrypt(p->from, p->id, numbytes, bytes);
|
||||||
@@ -212,7 +194,7 @@ bool Router::cancelSending(NodeNum from, PacketId id) {
|
|||||||
* Every (non duplicate) packet this node receives will be passed through this method. This allows subclasses to
|
* Every (non duplicate) packet this node receives will be passed through this method. This allows subclasses to
|
||||||
* update routing tables etc... based on what we overhear (even for messages not destined to our node)
|
* update routing tables etc... based on what we overhear (even for messages not destined to our node)
|
||||||
*/
|
*/
|
||||||
void Router::sniffReceived(const MeshPacket *p)
|
void Router::sniffReceived(const MeshPacket *p, const Routing &c)
|
||||||
{
|
{
|
||||||
DEBUG_MSG("FIXME-update-db Sniffing packet\n");
|
DEBUG_MSG("FIXME-update-db Sniffing packet\n");
|
||||||
// FIXME, update nodedb here for any packet that passes through us
|
// FIXME, update nodedb here for any packet that passes through us
|
||||||
@@ -234,7 +216,7 @@ bool Router::perhapsDecode(MeshPacket *p)
|
|||||||
crypto->decrypt(p->from, p->id, p->encrypted.size, bytes);
|
crypto->decrypt(p->from, p->id, p->encrypted.size, bytes);
|
||||||
|
|
||||||
// Take those raw bytes and convert them back into a well structured protobuf we can understand
|
// Take those raw bytes and convert them back into a well structured protobuf we can understand
|
||||||
if (!pb_decode_from_bytes(bytes, p->encrypted.size, SubPacket_fields, &p->decoded)) {
|
if (!pb_decode_from_bytes(bytes, p->encrypted.size, Data_fields, &p->decoded)) {
|
||||||
DEBUG_MSG("Invalid protobufs in received mesh packet!\n");
|
DEBUG_MSG("Invalid protobufs in received mesh packet!\n");
|
||||||
return false;
|
return false;
|
||||||
} else {
|
} else {
|
||||||
@@ -262,7 +244,8 @@ void Router::handleReceived(MeshPacket *p)
|
|||||||
if (perhapsDecode(p)) {
|
if (perhapsDecode(p)) {
|
||||||
// parsing was successful, queue for our recipient
|
// parsing was successful, queue for our recipient
|
||||||
|
|
||||||
sniffReceived(p);
|
assert(0); // FIXME, call any promiscious plugins here, make a (non promisiocous) plugin for forwarding messages to phone api
|
||||||
|
// sniffReceived(p);
|
||||||
|
|
||||||
if (p->to == NODENUM_BROADCAST || p->to == getNodeNum()) {
|
if (p->to == NODENUM_BROADCAST || p->to == getNodeNum()) {
|
||||||
printPacket("Delivering rx packet", p);
|
printPacket("Delivering rx packet", p);
|
||||||
|
|||||||
@@ -68,6 +68,8 @@ class Router : protected concurrency::OSThread
|
|||||||
NodeNum getNodeNum();
|
NodeNum getNodeNum();
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
|
friend class RoutingPlugin;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Send a packet on a suitable interface. This routine will
|
* Send a packet on a suitable interface. This routine will
|
||||||
* later free() the packet to pool. This routine is not allowed to stall.
|
* later free() the packet to pool. This routine is not allowed to stall.
|
||||||
@@ -80,6 +82,8 @@ class Router : protected concurrency::OSThread
|
|||||||
/**
|
/**
|
||||||
* Should this incoming filter be dropped?
|
* Should this incoming filter be dropped?
|
||||||
*
|
*
|
||||||
|
* FIXME, move this into the new RoutingPlugin and do the filtering there using the regular plugin logic
|
||||||
|
*
|
||||||
* Called immedately on receiption, before any further processing.
|
* Called immedately on receiption, before any further processing.
|
||||||
* @return true to abandon the packet
|
* @return true to abandon the packet
|
||||||
*/
|
*/
|
||||||
@@ -89,7 +93,7 @@ class Router : protected concurrency::OSThread
|
|||||||
* Every (non duplicate) packet this node receives will be passed through this method. This allows subclasses to
|
* Every (non duplicate) packet this node receives will be passed through this method. This allows subclasses to
|
||||||
* update routing tables etc... based on what we overhear (even for messages not destined to our node)
|
* update routing tables etc... based on what we overhear (even for messages not destined to our node)
|
||||||
*/
|
*/
|
||||||
virtual void sniffReceived(const MeshPacket *p);
|
virtual void sniffReceived(const MeshPacket *p, const Routing &c);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Remove any encryption and decode the protobufs inside this packet (if necessary).
|
* Remove any encryption and decode the protobufs inside this packet (if necessary).
|
||||||
@@ -101,7 +105,7 @@ class Router : protected concurrency::OSThread
|
|||||||
/**
|
/**
|
||||||
* Send an ack or a nak packet back towards whoever sent idFrom
|
* Send an ack or a nak packet back towards whoever sent idFrom
|
||||||
*/
|
*/
|
||||||
void sendAckNak(ErrorReason err, NodeNum to, PacketId idFrom);
|
void sendAckNak(Routing_Error err, NodeNum to, PacketId idFrom);
|
||||||
|
|
||||||
private:
|
private:
|
||||||
/**
|
/**
|
||||||
|
|||||||
@@ -32,8 +32,7 @@ class SinglePortPlugin : public MeshPlugin
|
|||||||
{
|
{
|
||||||
// Update our local node info with our position (even if we don't decide to update anyone else)
|
// Update our local node info with our position (even if we don't decide to update anyone else)
|
||||||
MeshPacket *p = router->allocForSending();
|
MeshPacket *p = router->allocForSending();
|
||||||
p->decoded.which_payloadVariant = SubPacket_data_tag;
|
p->decoded.portnum = ourPortNum;
|
||||||
p->decoded.data.portnum = ourPortNum;
|
|
||||||
|
|
||||||
return p;
|
return p;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -9,4 +9,7 @@
|
|||||||
PB_BIND(ServiceEnvelope, ServiceEnvelope, 2)
|
PB_BIND(ServiceEnvelope, ServiceEnvelope, 2)
|
||||||
|
|
||||||
|
|
||||||
|
PB_BIND(ChannelSet, ChannelSet, AUTO)
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
@@ -11,6 +11,10 @@
|
|||||||
#endif
|
#endif
|
||||||
|
|
||||||
/* Struct definitions */
|
/* Struct definitions */
|
||||||
|
typedef struct _ChannelSet {
|
||||||
|
pb_callback_t settings;
|
||||||
|
} ChannelSet;
|
||||||
|
|
||||||
typedef struct _ServiceEnvelope {
|
typedef struct _ServiceEnvelope {
|
||||||
bool has_packet;
|
bool has_packet;
|
||||||
MeshPacket packet;
|
MeshPacket packet;
|
||||||
@@ -25,9 +29,12 @@ extern "C" {
|
|||||||
|
|
||||||
/* Initializer values for message structs */
|
/* Initializer values for message structs */
|
||||||
#define ServiceEnvelope_init_default {false, MeshPacket_init_default, {{NULL}, NULL}, {{NULL}, NULL}}
|
#define ServiceEnvelope_init_default {false, MeshPacket_init_default, {{NULL}, NULL}, {{NULL}, NULL}}
|
||||||
|
#define ChannelSet_init_default {{{NULL}, NULL}}
|
||||||
#define ServiceEnvelope_init_zero {false, MeshPacket_init_zero, {{NULL}, NULL}, {{NULL}, NULL}}
|
#define ServiceEnvelope_init_zero {false, MeshPacket_init_zero, {{NULL}, NULL}, {{NULL}, NULL}}
|
||||||
|
#define ChannelSet_init_zero {{{NULL}, NULL}}
|
||||||
|
|
||||||
/* Field tags (for use in manual encoding/decoding) */
|
/* Field tags (for use in manual encoding/decoding) */
|
||||||
|
#define ChannelSet_settings_tag 1
|
||||||
#define ServiceEnvelope_packet_tag 1
|
#define ServiceEnvelope_packet_tag 1
|
||||||
#define ServiceEnvelope_channel_id_tag 2
|
#define ServiceEnvelope_channel_id_tag 2
|
||||||
#define ServiceEnvelope_gateway_id_tag 3
|
#define ServiceEnvelope_gateway_id_tag 3
|
||||||
@@ -41,13 +48,22 @@ X(a, CALLBACK, SINGULAR, STRING, gateway_id, 3)
|
|||||||
#define ServiceEnvelope_DEFAULT NULL
|
#define ServiceEnvelope_DEFAULT NULL
|
||||||
#define ServiceEnvelope_packet_MSGTYPE MeshPacket
|
#define ServiceEnvelope_packet_MSGTYPE MeshPacket
|
||||||
|
|
||||||
|
#define ChannelSet_FIELDLIST(X, a) \
|
||||||
|
X(a, CALLBACK, REPEATED, MESSAGE, settings, 1)
|
||||||
|
#define ChannelSet_CALLBACK pb_default_field_callback
|
||||||
|
#define ChannelSet_DEFAULT NULL
|
||||||
|
#define ChannelSet_settings_MSGTYPE ChannelSettings
|
||||||
|
|
||||||
extern const pb_msgdesc_t ServiceEnvelope_msg;
|
extern const pb_msgdesc_t ServiceEnvelope_msg;
|
||||||
|
extern const pb_msgdesc_t ChannelSet_msg;
|
||||||
|
|
||||||
/* Defines for backwards compatibility with code written before nanopb-0.4.0 */
|
/* Defines for backwards compatibility with code written before nanopb-0.4.0 */
|
||||||
#define ServiceEnvelope_fields &ServiceEnvelope_msg
|
#define ServiceEnvelope_fields &ServiceEnvelope_msg
|
||||||
|
#define ChannelSet_fields &ChannelSet_msg
|
||||||
|
|
||||||
/* Maximum encoded size of messages (where known) */
|
/* Maximum encoded size of messages (where known) */
|
||||||
/* ServiceEnvelope_size depends on runtime parameters */
|
/* ServiceEnvelope_size depends on runtime parameters */
|
||||||
|
/* ChannelSet_size depends on runtime parameters */
|
||||||
|
|
||||||
#ifdef __cplusplus
|
#ifdef __cplusplus
|
||||||
} /* extern "C" */
|
} /* extern "C" */
|
||||||
|
|||||||
@@ -80,7 +80,7 @@ extern const pb_msgdesc_t DeviceState_msg;
|
|||||||
#define DeviceState_fields &DeviceState_msg
|
#define DeviceState_fields &DeviceState_msg
|
||||||
|
|
||||||
/* Maximum encoded size of messages (where known) */
|
/* Maximum encoded size of messages (where known) */
|
||||||
#define DeviceState_size 6265
|
#define DeviceState_size 6225
|
||||||
|
|
||||||
#ifdef __cplusplus
|
#ifdef __cplusplus
|
||||||
} /* extern "C" */
|
} /* extern "C" */
|
||||||
|
|||||||
@@ -9,16 +9,16 @@
|
|||||||
PB_BIND(Position, Position, AUTO)
|
PB_BIND(Position, Position, AUTO)
|
||||||
|
|
||||||
|
|
||||||
PB_BIND(Data, Data, AUTO)
|
|
||||||
|
|
||||||
|
|
||||||
PB_BIND(User, User, AUTO)
|
PB_BIND(User, User, AUTO)
|
||||||
|
|
||||||
|
|
||||||
PB_BIND(RouteDiscovery, RouteDiscovery, AUTO)
|
PB_BIND(RouteDiscovery, RouteDiscovery, AUTO)
|
||||||
|
|
||||||
|
|
||||||
PB_BIND(SubPacket, SubPacket, 2)
|
PB_BIND(Routing, Routing, AUTO)
|
||||||
|
|
||||||
|
|
||||||
|
PB_BIND(Data, Data, 2)
|
||||||
|
|
||||||
|
|
||||||
PB_BIND(MeshPacket, MeshPacket, 2)
|
PB_BIND(MeshPacket, MeshPacket, 2)
|
||||||
|
|||||||
@@ -11,15 +11,6 @@
|
|||||||
#endif
|
#endif
|
||||||
|
|
||||||
/* Enum definitions */
|
/* Enum definitions */
|
||||||
typedef enum _ErrorReason {
|
|
||||||
ErrorReason_NONE = 0,
|
|
||||||
ErrorReason_NO_ROUTE = 1,
|
|
||||||
ErrorReason_GOT_NAK = 2,
|
|
||||||
ErrorReason_TIMEOUT = 3,
|
|
||||||
ErrorReason_NO_INTERFACE = 4,
|
|
||||||
ErrorReason_MAX_RETRANSMIT = 5
|
|
||||||
} ErrorReason;
|
|
||||||
|
|
||||||
typedef enum _Constants {
|
typedef enum _Constants {
|
||||||
Constants_Unused = 0,
|
Constants_Unused = 0,
|
||||||
Constants_DATA_PAYLOAD_LEN = 240
|
Constants_DATA_PAYLOAD_LEN = 240
|
||||||
@@ -83,6 +74,15 @@ typedef enum _CriticalErrorCode {
|
|||||||
CriticalErrorCode_TransmitFailed = 8
|
CriticalErrorCode_TransmitFailed = 8
|
||||||
} CriticalErrorCode;
|
} CriticalErrorCode;
|
||||||
|
|
||||||
|
typedef enum _Routing_Error {
|
||||||
|
Routing_Error_NONE = 0,
|
||||||
|
Routing_Error_NO_ROUTE = 1,
|
||||||
|
Routing_Error_GOT_NAK = 2,
|
||||||
|
Routing_Error_TIMEOUT = 3,
|
||||||
|
Routing_Error_NO_INTERFACE = 4,
|
||||||
|
Routing_Error_MAX_RETRANSMIT = 5
|
||||||
|
} Routing_Error;
|
||||||
|
|
||||||
typedef enum _MeshPacket_Priority {
|
typedef enum _MeshPacket_Priority {
|
||||||
MeshPacket_Priority_UNSET = 0,
|
MeshPacket_Priority_UNSET = 0,
|
||||||
MeshPacket_Priority_MIN = 1,
|
MeshPacket_Priority_MIN = 1,
|
||||||
@@ -136,6 +136,9 @@ typedef PB_BYTES_ARRAY_T(240) Data_payload_t;
|
|||||||
typedef struct _Data {
|
typedef struct _Data {
|
||||||
PortNum portnum;
|
PortNum portnum;
|
||||||
Data_payload_t payload;
|
Data_payload_t payload;
|
||||||
|
bool want_response;
|
||||||
|
uint32_t dest;
|
||||||
|
uint32_t source;
|
||||||
} Data;
|
} Data;
|
||||||
|
|
||||||
typedef struct _LogRecord {
|
typedef struct _LogRecord {
|
||||||
@@ -216,7 +219,7 @@ typedef struct _RadioConfig_UserPreferences {
|
|||||||
|
|
||||||
typedef struct _RouteDiscovery {
|
typedef struct _RouteDiscovery {
|
||||||
pb_size_t route_count;
|
pb_size_t route_count;
|
||||||
int32_t route[8];
|
uint32_t route[8];
|
||||||
} RouteDiscovery;
|
} RouteDiscovery;
|
||||||
|
|
||||||
typedef struct _User {
|
typedef struct _User {
|
||||||
@@ -233,6 +236,24 @@ typedef struct _Channel {
|
|||||||
Channel_Role role;
|
Channel_Role role;
|
||||||
} Channel;
|
} Channel;
|
||||||
|
|
||||||
|
typedef PB_BYTES_ARRAY_T(256) MeshPacket_encrypted_t;
|
||||||
|
typedef struct _MeshPacket {
|
||||||
|
uint32_t from;
|
||||||
|
uint32_t to;
|
||||||
|
pb_size_t which_payloadVariant;
|
||||||
|
union {
|
||||||
|
Data decoded;
|
||||||
|
MeshPacket_encrypted_t encrypted;
|
||||||
|
};
|
||||||
|
uint32_t channel_index;
|
||||||
|
uint32_t id;
|
||||||
|
float rx_snr;
|
||||||
|
uint32_t rx_time;
|
||||||
|
uint32_t hop_limit;
|
||||||
|
bool want_ack;
|
||||||
|
MeshPacket_Priority priority;
|
||||||
|
} MeshPacket;
|
||||||
|
|
||||||
typedef struct _NodeInfo {
|
typedef struct _NodeInfo {
|
||||||
uint32_t num;
|
uint32_t num;
|
||||||
bool has_user;
|
bool has_user;
|
||||||
@@ -248,48 +269,22 @@ typedef struct _RadioConfig {
|
|||||||
RadioConfig_UserPreferences preferences;
|
RadioConfig_UserPreferences preferences;
|
||||||
} RadioConfig;
|
} RadioConfig;
|
||||||
|
|
||||||
typedef struct _SubPacket {
|
typedef struct _Routing {
|
||||||
uint32_t original_id;
|
pb_size_t which_variant;
|
||||||
pb_size_t which_payloadVariant;
|
|
||||||
union {
|
union {
|
||||||
Data data;
|
|
||||||
RouteDiscovery route_request;
|
RouteDiscovery route_request;
|
||||||
RouteDiscovery route_reply;
|
RouteDiscovery route_reply;
|
||||||
ErrorReason error_reason;
|
Routing_Error error_reason;
|
||||||
};
|
|
||||||
bool want_response;
|
|
||||||
uint32_t dest;
|
|
||||||
pb_size_t which_ackVariant;
|
|
||||||
union {
|
|
||||||
uint32_t success_id;
|
uint32_t success_id;
|
||||||
uint32_t fail_id;
|
uint32_t fail_id;
|
||||||
} ackVariant;
|
|
||||||
uint32_t source;
|
|
||||||
} SubPacket;
|
|
||||||
|
|
||||||
typedef PB_BYTES_ARRAY_T(256) MeshPacket_encrypted_t;
|
|
||||||
typedef struct _MeshPacket {
|
|
||||||
uint32_t from;
|
|
||||||
uint32_t to;
|
|
||||||
pb_size_t which_payloadVariant;
|
|
||||||
union {
|
|
||||||
SubPacket decoded;
|
|
||||||
MeshPacket_encrypted_t encrypted;
|
|
||||||
};
|
};
|
||||||
uint32_t channel_index;
|
uint32_t original_id;
|
||||||
uint32_t id;
|
} Routing;
|
||||||
float rx_snr;
|
|
||||||
uint32_t rx_time;
|
|
||||||
uint32_t hop_limit;
|
|
||||||
bool want_ack;
|
|
||||||
MeshPacket_Priority priority;
|
|
||||||
} MeshPacket;
|
|
||||||
|
|
||||||
typedef struct _FromRadio {
|
typedef struct _FromRadio {
|
||||||
uint32_t num;
|
uint32_t num;
|
||||||
pb_size_t which_payloadVariant;
|
pb_size_t which_payloadVariant;
|
||||||
union {
|
union {
|
||||||
MeshPacket packet;
|
|
||||||
MyNodeInfo my_info;
|
MyNodeInfo my_info;
|
||||||
NodeInfo node_info;
|
NodeInfo node_info;
|
||||||
RadioConfig radio;
|
RadioConfig radio;
|
||||||
@@ -297,6 +292,7 @@ typedef struct _FromRadio {
|
|||||||
uint32_t config_complete_id;
|
uint32_t config_complete_id;
|
||||||
bool rebooted;
|
bool rebooted;
|
||||||
Channel channel;
|
Channel channel;
|
||||||
|
MeshPacket packet;
|
||||||
};
|
};
|
||||||
} FromRadio;
|
} FromRadio;
|
||||||
|
|
||||||
@@ -313,10 +309,6 @@ typedef struct _ToRadio {
|
|||||||
|
|
||||||
|
|
||||||
/* Helper constants for enums */
|
/* Helper constants for enums */
|
||||||
#define _ErrorReason_MIN ErrorReason_NONE
|
|
||||||
#define _ErrorReason_MAX ErrorReason_MAX_RETRANSMIT
|
|
||||||
#define _ErrorReason_ARRAYSIZE ((ErrorReason)(ErrorReason_MAX_RETRANSMIT+1))
|
|
||||||
|
|
||||||
#define _Constants_MIN Constants_Unused
|
#define _Constants_MIN Constants_Unused
|
||||||
#define _Constants_MAX Constants_DATA_PAYLOAD_LEN
|
#define _Constants_MAX Constants_DATA_PAYLOAD_LEN
|
||||||
#define _Constants_ARRAYSIZE ((Constants)(Constants_DATA_PAYLOAD_LEN+1))
|
#define _Constants_ARRAYSIZE ((Constants)(Constants_DATA_PAYLOAD_LEN+1))
|
||||||
@@ -341,6 +333,10 @@ typedef struct _ToRadio {
|
|||||||
#define _CriticalErrorCode_MAX CriticalErrorCode_TransmitFailed
|
#define _CriticalErrorCode_MAX CriticalErrorCode_TransmitFailed
|
||||||
#define _CriticalErrorCode_ARRAYSIZE ((CriticalErrorCode)(CriticalErrorCode_TransmitFailed+1))
|
#define _CriticalErrorCode_ARRAYSIZE ((CriticalErrorCode)(CriticalErrorCode_TransmitFailed+1))
|
||||||
|
|
||||||
|
#define _Routing_Error_MIN Routing_Error_NONE
|
||||||
|
#define _Routing_Error_MAX Routing_Error_MAX_RETRANSMIT
|
||||||
|
#define _Routing_Error_ARRAYSIZE ((Routing_Error)(Routing_Error_MAX_RETRANSMIT+1))
|
||||||
|
|
||||||
#define _MeshPacket_Priority_MIN MeshPacket_Priority_UNSET
|
#define _MeshPacket_Priority_MIN MeshPacket_Priority_UNSET
|
||||||
#define _MeshPacket_Priority_MAX MeshPacket_Priority_MAX
|
#define _MeshPacket_Priority_MAX MeshPacket_Priority_MAX
|
||||||
#define _MeshPacket_Priority_ARRAYSIZE ((MeshPacket_Priority)(MeshPacket_Priority_MAX+1))
|
#define _MeshPacket_Priority_ARRAYSIZE ((MeshPacket_Priority)(MeshPacket_Priority_MAX+1))
|
||||||
@@ -364,11 +360,11 @@ extern "C" {
|
|||||||
|
|
||||||
/* Initializer values for message structs */
|
/* Initializer values for message structs */
|
||||||
#define Position_init_default {0, 0, 0, 0, 0}
|
#define Position_init_default {0, 0, 0, 0, 0}
|
||||||
#define Data_init_default {_PortNum_MIN, {0, {0}}}
|
|
||||||
#define User_init_default {"", "", "", {0}}
|
#define User_init_default {"", "", "", {0}}
|
||||||
#define RouteDiscovery_init_default {0, {0, 0, 0, 0, 0, 0, 0, 0}}
|
#define RouteDiscovery_init_default {0, {0, 0, 0, 0, 0, 0, 0, 0}}
|
||||||
#define SubPacket_init_default {0, 0, {Data_init_default}, 0, 0, 0, {0}, 0}
|
#define Routing_init_default {0, {RouteDiscovery_init_default}, 0}
|
||||||
#define MeshPacket_init_default {0, 0, 0, {SubPacket_init_default}, 0, 0, 0, 0, 0, 0, _MeshPacket_Priority_MIN}
|
#define Data_init_default {_PortNum_MIN, {0, {0}}, 0, 0, 0}
|
||||||
|
#define MeshPacket_init_default {0, 0, 0, {Data_init_default}, 0, 0, 0, 0, 0, 0, _MeshPacket_Priority_MIN}
|
||||||
#define ChannelSettings_init_default {0, _ChannelSettings_ModemConfig_MIN, {0, {0}}, "", 0, 0, 0, 0, 0, 0, 0}
|
#define ChannelSettings_init_default {0, _ChannelSettings_ModemConfig_MIN, {0, {0}}, "", 0, 0, 0, 0, 0, 0, 0}
|
||||||
#define Channel_init_default {0, false, ChannelSettings_init_default, _Channel_Role_MIN}
|
#define Channel_init_default {0, false, ChannelSettings_init_default, _Channel_Role_MIN}
|
||||||
#define RadioConfig_init_default {false, RadioConfig_UserPreferences_init_default}
|
#define RadioConfig_init_default {false, RadioConfig_UserPreferences_init_default}
|
||||||
@@ -376,14 +372,14 @@ extern "C" {
|
|||||||
#define NodeInfo_init_default {0, false, User_init_default, false, Position_init_default, 0, 0}
|
#define NodeInfo_init_default {0, false, User_init_default, false, Position_init_default, 0, 0}
|
||||||
#define MyNodeInfo_init_default {0, 0, 0, "", "", "", _CriticalErrorCode_MIN, 0, 0, 0, 0, 0}
|
#define MyNodeInfo_init_default {0, 0, 0, "", "", "", _CriticalErrorCode_MIN, 0, 0, 0, 0, 0}
|
||||||
#define LogRecord_init_default {"", 0, "", _LogRecord_Level_MIN}
|
#define LogRecord_init_default {"", 0, "", _LogRecord_Level_MIN}
|
||||||
#define FromRadio_init_default {0, 0, {MeshPacket_init_default}}
|
#define FromRadio_init_default {0, 0, {MyNodeInfo_init_default}}
|
||||||
#define ToRadio_init_default {0, {MeshPacket_init_default}}
|
#define ToRadio_init_default {0, {MeshPacket_init_default}}
|
||||||
#define Position_init_zero {0, 0, 0, 0, 0}
|
#define Position_init_zero {0, 0, 0, 0, 0}
|
||||||
#define Data_init_zero {_PortNum_MIN, {0, {0}}}
|
|
||||||
#define User_init_zero {"", "", "", {0}}
|
#define User_init_zero {"", "", "", {0}}
|
||||||
#define RouteDiscovery_init_zero {0, {0, 0, 0, 0, 0, 0, 0, 0}}
|
#define RouteDiscovery_init_zero {0, {0, 0, 0, 0, 0, 0, 0, 0}}
|
||||||
#define SubPacket_init_zero {0, 0, {Data_init_zero}, 0, 0, 0, {0}, 0}
|
#define Routing_init_zero {0, {RouteDiscovery_init_zero}, 0}
|
||||||
#define MeshPacket_init_zero {0, 0, 0, {SubPacket_init_zero}, 0, 0, 0, 0, 0, 0, _MeshPacket_Priority_MIN}
|
#define Data_init_zero {_PortNum_MIN, {0, {0}}, 0, 0, 0}
|
||||||
|
#define MeshPacket_init_zero {0, 0, 0, {Data_init_zero}, 0, 0, 0, 0, 0, 0, _MeshPacket_Priority_MIN}
|
||||||
#define ChannelSettings_init_zero {0, _ChannelSettings_ModemConfig_MIN, {0, {0}}, "", 0, 0, 0, 0, 0, 0, 0}
|
#define ChannelSettings_init_zero {0, _ChannelSettings_ModemConfig_MIN, {0, {0}}, "", 0, 0, 0, 0, 0, 0, 0}
|
||||||
#define Channel_init_zero {0, false, ChannelSettings_init_zero, _Channel_Role_MIN}
|
#define Channel_init_zero {0, false, ChannelSettings_init_zero, _Channel_Role_MIN}
|
||||||
#define RadioConfig_init_zero {false, RadioConfig_UserPreferences_init_zero}
|
#define RadioConfig_init_zero {false, RadioConfig_UserPreferences_init_zero}
|
||||||
@@ -391,7 +387,7 @@ extern "C" {
|
|||||||
#define NodeInfo_init_zero {0, false, User_init_zero, false, Position_init_zero, 0, 0}
|
#define NodeInfo_init_zero {0, false, User_init_zero, false, Position_init_zero, 0, 0}
|
||||||
#define MyNodeInfo_init_zero {0, 0, 0, "", "", "", _CriticalErrorCode_MIN, 0, 0, 0, 0, 0}
|
#define MyNodeInfo_init_zero {0, 0, 0, "", "", "", _CriticalErrorCode_MIN, 0, 0, 0, 0, 0}
|
||||||
#define LogRecord_init_zero {"", 0, "", _LogRecord_Level_MIN}
|
#define LogRecord_init_zero {"", 0, "", _LogRecord_Level_MIN}
|
||||||
#define FromRadio_init_zero {0, 0, {MeshPacket_init_zero}}
|
#define FromRadio_init_zero {0, 0, {MyNodeInfo_init_zero}}
|
||||||
#define ToRadio_init_zero {0, {MeshPacket_init_zero}}
|
#define ToRadio_init_zero {0, {MeshPacket_init_zero}}
|
||||||
|
|
||||||
/* Field tags (for use in manual encoding/decoding) */
|
/* Field tags (for use in manual encoding/decoding) */
|
||||||
@@ -408,6 +404,9 @@ extern "C" {
|
|||||||
#define ChannelSettings_downlink_enabled_tag 17
|
#define ChannelSettings_downlink_enabled_tag 17
|
||||||
#define Data_portnum_tag 1
|
#define Data_portnum_tag 1
|
||||||
#define Data_payload_tag 2
|
#define Data_payload_tag 2
|
||||||
|
#define Data_want_response_tag 5
|
||||||
|
#define Data_dest_tag 9
|
||||||
|
#define Data_source_tag 12
|
||||||
#define LogRecord_message_tag 1
|
#define LogRecord_message_tag 1
|
||||||
#define LogRecord_time_tag 2
|
#define LogRecord_time_tag 2
|
||||||
#define LogRecord_source_tag 3
|
#define LogRecord_source_tag 3
|
||||||
@@ -479,22 +478,6 @@ extern "C" {
|
|||||||
#define Channel_index_tag 1
|
#define Channel_index_tag 1
|
||||||
#define Channel_settings_tag 2
|
#define Channel_settings_tag 2
|
||||||
#define Channel_role_tag 3
|
#define Channel_role_tag 3
|
||||||
#define NodeInfo_num_tag 1
|
|
||||||
#define NodeInfo_user_tag 2
|
|
||||||
#define NodeInfo_position_tag 3
|
|
||||||
#define NodeInfo_next_hop_tag 5
|
|
||||||
#define NodeInfo_snr_tag 7
|
|
||||||
#define RadioConfig_preferences_tag 1
|
|
||||||
#define SubPacket_original_id_tag 2
|
|
||||||
#define SubPacket_data_tag 3
|
|
||||||
#define SubPacket_route_request_tag 6
|
|
||||||
#define SubPacket_route_reply_tag 7
|
|
||||||
#define SubPacket_error_reason_tag 13
|
|
||||||
#define SubPacket_want_response_tag 5
|
|
||||||
#define SubPacket_dest_tag 9
|
|
||||||
#define SubPacket_success_id_tag 10
|
|
||||||
#define SubPacket_fail_id_tag 11
|
|
||||||
#define SubPacket_source_tag 12
|
|
||||||
#define MeshPacket_from_tag 1
|
#define MeshPacket_from_tag 1
|
||||||
#define MeshPacket_to_tag 2
|
#define MeshPacket_to_tag 2
|
||||||
#define MeshPacket_decoded_tag 3
|
#define MeshPacket_decoded_tag 3
|
||||||
@@ -506,8 +489,19 @@ extern "C" {
|
|||||||
#define MeshPacket_hop_limit_tag 10
|
#define MeshPacket_hop_limit_tag 10
|
||||||
#define MeshPacket_want_ack_tag 11
|
#define MeshPacket_want_ack_tag 11
|
||||||
#define MeshPacket_priority_tag 12
|
#define MeshPacket_priority_tag 12
|
||||||
|
#define NodeInfo_num_tag 1
|
||||||
|
#define NodeInfo_user_tag 2
|
||||||
|
#define NodeInfo_position_tag 3
|
||||||
|
#define NodeInfo_next_hop_tag 5
|
||||||
|
#define NodeInfo_snr_tag 7
|
||||||
|
#define RadioConfig_preferences_tag 1
|
||||||
|
#define Routing_route_request_tag 1
|
||||||
|
#define Routing_route_reply_tag 2
|
||||||
|
#define Routing_error_reason_tag 3
|
||||||
|
#define Routing_success_id_tag 4
|
||||||
|
#define Routing_fail_id_tag 5
|
||||||
|
#define Routing_original_id_tag 6
|
||||||
#define FromRadio_num_tag 1
|
#define FromRadio_num_tag 1
|
||||||
#define FromRadio_packet_tag 2
|
|
||||||
#define FromRadio_my_info_tag 3
|
#define FromRadio_my_info_tag 3
|
||||||
#define FromRadio_node_info_tag 4
|
#define FromRadio_node_info_tag 4
|
||||||
#define FromRadio_radio_tag 6
|
#define FromRadio_radio_tag 6
|
||||||
@@ -515,7 +509,8 @@ extern "C" {
|
|||||||
#define FromRadio_config_complete_id_tag 8
|
#define FromRadio_config_complete_id_tag 8
|
||||||
#define FromRadio_rebooted_tag 9
|
#define FromRadio_rebooted_tag 9
|
||||||
#define FromRadio_channel_tag 10
|
#define FromRadio_channel_tag 10
|
||||||
#define ToRadio_packet_tag 1
|
#define FromRadio_packet_tag 11
|
||||||
|
#define ToRadio_packet_tag 2
|
||||||
#define ToRadio_want_config_id_tag 100
|
#define ToRadio_want_config_id_tag 100
|
||||||
#define ToRadio_set_radio_tag 101
|
#define ToRadio_set_radio_tag 101
|
||||||
#define ToRadio_set_owner_tag 102
|
#define ToRadio_set_owner_tag 102
|
||||||
@@ -531,12 +526,6 @@ X(a, STATIC, SINGULAR, FIXED32, time, 9)
|
|||||||
#define Position_CALLBACK NULL
|
#define Position_CALLBACK NULL
|
||||||
#define Position_DEFAULT NULL
|
#define Position_DEFAULT NULL
|
||||||
|
|
||||||
#define Data_FIELDLIST(X, a) \
|
|
||||||
X(a, STATIC, SINGULAR, UENUM, portnum, 1) \
|
|
||||||
X(a, STATIC, SINGULAR, BYTES, payload, 2)
|
|
||||||
#define Data_CALLBACK NULL
|
|
||||||
#define Data_DEFAULT NULL
|
|
||||||
|
|
||||||
#define User_FIELDLIST(X, a) \
|
#define User_FIELDLIST(X, a) \
|
||||||
X(a, STATIC, SINGULAR, STRING, id, 1) \
|
X(a, STATIC, SINGULAR, STRING, id, 1) \
|
||||||
X(a, STATIC, SINGULAR, STRING, long_name, 2) \
|
X(a, STATIC, SINGULAR, STRING, long_name, 2) \
|
||||||
@@ -546,34 +535,38 @@ X(a, STATIC, SINGULAR, FIXED_LENGTH_BYTES, macaddr, 4)
|
|||||||
#define User_DEFAULT NULL
|
#define User_DEFAULT NULL
|
||||||
|
|
||||||
#define RouteDiscovery_FIELDLIST(X, a) \
|
#define RouteDiscovery_FIELDLIST(X, a) \
|
||||||
X(a, STATIC, REPEATED, INT32, route, 2)
|
X(a, STATIC, REPEATED, FIXED32, route, 2)
|
||||||
#define RouteDiscovery_CALLBACK NULL
|
#define RouteDiscovery_CALLBACK NULL
|
||||||
#define RouteDiscovery_DEFAULT NULL
|
#define RouteDiscovery_DEFAULT NULL
|
||||||
|
|
||||||
#define SubPacket_FIELDLIST(X, a) \
|
#define Routing_FIELDLIST(X, a) \
|
||||||
X(a, STATIC, SINGULAR, UINT32, original_id, 2) \
|
X(a, STATIC, ONEOF, MESSAGE, (variant,route_request,route_request), 1) \
|
||||||
X(a, STATIC, ONEOF, MESSAGE, (payloadVariant,data,data), 3) \
|
X(a, STATIC, ONEOF, MESSAGE, (variant,route_reply,route_reply), 2) \
|
||||||
X(a, STATIC, ONEOF, MESSAGE, (payloadVariant,route_request,route_request), 6) \
|
X(a, STATIC, ONEOF, UENUM, (variant,error_reason,error_reason), 3) \
|
||||||
X(a, STATIC, ONEOF, MESSAGE, (payloadVariant,route_reply,route_reply), 7) \
|
X(a, STATIC, ONEOF, FIXED32, (variant,success_id,success_id), 4) \
|
||||||
X(a, STATIC, ONEOF, UENUM, (payloadVariant,error_reason,error_reason), 13) \
|
X(a, STATIC, ONEOF, FIXED32, (variant,fail_id,fail_id), 5) \
|
||||||
|
X(a, STATIC, SINGULAR, FIXED32, original_id, 6)
|
||||||
|
#define Routing_CALLBACK NULL
|
||||||
|
#define Routing_DEFAULT NULL
|
||||||
|
#define Routing_variant_route_request_MSGTYPE RouteDiscovery
|
||||||
|
#define Routing_variant_route_reply_MSGTYPE RouteDiscovery
|
||||||
|
|
||||||
|
#define Data_FIELDLIST(X, a) \
|
||||||
|
X(a, STATIC, SINGULAR, UENUM, portnum, 1) \
|
||||||
|
X(a, STATIC, SINGULAR, BYTES, payload, 2) \
|
||||||
X(a, STATIC, SINGULAR, BOOL, want_response, 5) \
|
X(a, STATIC, SINGULAR, BOOL, want_response, 5) \
|
||||||
X(a, STATIC, SINGULAR, UINT32, dest, 9) \
|
X(a, STATIC, SINGULAR, FIXED32, dest, 9) \
|
||||||
X(a, STATIC, ONEOF, UINT32, (ackVariant,success_id,ackVariant.success_id), 10) \
|
X(a, STATIC, SINGULAR, FIXED32, source, 12)
|
||||||
X(a, STATIC, ONEOF, UINT32, (ackVariant,fail_id,ackVariant.fail_id), 11) \
|
#define Data_CALLBACK NULL
|
||||||
X(a, STATIC, SINGULAR, UINT32, source, 12)
|
#define Data_DEFAULT NULL
|
||||||
#define SubPacket_CALLBACK NULL
|
|
||||||
#define SubPacket_DEFAULT NULL
|
|
||||||
#define SubPacket_payloadVariant_data_MSGTYPE Data
|
|
||||||
#define SubPacket_payloadVariant_route_request_MSGTYPE RouteDiscovery
|
|
||||||
#define SubPacket_payloadVariant_route_reply_MSGTYPE RouteDiscovery
|
|
||||||
|
|
||||||
#define MeshPacket_FIELDLIST(X, a) \
|
#define MeshPacket_FIELDLIST(X, a) \
|
||||||
X(a, STATIC, SINGULAR, UINT32, from, 1) \
|
X(a, STATIC, SINGULAR, FIXED32, from, 1) \
|
||||||
X(a, STATIC, SINGULAR, UINT32, to, 2) \
|
X(a, STATIC, SINGULAR, FIXED32, to, 2) \
|
||||||
X(a, STATIC, ONEOF, MESSAGE, (payloadVariant,decoded,decoded), 3) \
|
X(a, STATIC, ONEOF, MESSAGE, (payloadVariant,decoded,decoded), 3) \
|
||||||
X(a, STATIC, ONEOF, BYTES, (payloadVariant,encrypted,encrypted), 8) \
|
X(a, STATIC, ONEOF, BYTES, (payloadVariant,encrypted,encrypted), 8) \
|
||||||
X(a, STATIC, SINGULAR, UINT32, channel_index, 4) \
|
X(a, STATIC, SINGULAR, UINT32, channel_index, 4) \
|
||||||
X(a, STATIC, SINGULAR, UINT32, id, 6) \
|
X(a, STATIC, SINGULAR, FIXED32, id, 6) \
|
||||||
X(a, STATIC, SINGULAR, FLOAT, rx_snr, 7) \
|
X(a, STATIC, SINGULAR, FLOAT, rx_snr, 7) \
|
||||||
X(a, STATIC, SINGULAR, FIXED32, rx_time, 9) \
|
X(a, STATIC, SINGULAR, FIXED32, rx_time, 9) \
|
||||||
X(a, STATIC, SINGULAR, UINT32, hop_limit, 10) \
|
X(a, STATIC, SINGULAR, UINT32, hop_limit, 10) \
|
||||||
@@ -581,7 +574,7 @@ X(a, STATIC, SINGULAR, BOOL, want_ack, 11) \
|
|||||||
X(a, STATIC, SINGULAR, UENUM, priority, 12)
|
X(a, STATIC, SINGULAR, UENUM, priority, 12)
|
||||||
#define MeshPacket_CALLBACK NULL
|
#define MeshPacket_CALLBACK NULL
|
||||||
#define MeshPacket_DEFAULT NULL
|
#define MeshPacket_DEFAULT NULL
|
||||||
#define MeshPacket_payloadVariant_decoded_MSGTYPE SubPacket
|
#define MeshPacket_payloadVariant_decoded_MSGTYPE Data
|
||||||
|
|
||||||
#define ChannelSettings_FIELDLIST(X, a) \
|
#define ChannelSettings_FIELDLIST(X, a) \
|
||||||
X(a, STATIC, SINGULAR, INT32, tx_power, 1) \
|
X(a, STATIC, SINGULAR, INT32, tx_power, 1) \
|
||||||
@@ -695,25 +688,25 @@ X(a, STATIC, SINGULAR, UENUM, level, 4)
|
|||||||
|
|
||||||
#define FromRadio_FIELDLIST(X, a) \
|
#define FromRadio_FIELDLIST(X, a) \
|
||||||
X(a, STATIC, SINGULAR, UINT32, num, 1) \
|
X(a, STATIC, SINGULAR, UINT32, num, 1) \
|
||||||
X(a, STATIC, ONEOF, MESSAGE, (payloadVariant,packet,packet), 2) \
|
|
||||||
X(a, STATIC, ONEOF, MESSAGE, (payloadVariant,my_info,my_info), 3) \
|
X(a, STATIC, ONEOF, MESSAGE, (payloadVariant,my_info,my_info), 3) \
|
||||||
X(a, STATIC, ONEOF, MESSAGE, (payloadVariant,node_info,node_info), 4) \
|
X(a, STATIC, ONEOF, MESSAGE, (payloadVariant,node_info,node_info), 4) \
|
||||||
X(a, STATIC, ONEOF, MESSAGE, (payloadVariant,radio,radio), 6) \
|
X(a, STATIC, ONEOF, MESSAGE, (payloadVariant,radio,radio), 6) \
|
||||||
X(a, STATIC, ONEOF, MESSAGE, (payloadVariant,log_record,log_record), 7) \
|
X(a, STATIC, ONEOF, MESSAGE, (payloadVariant,log_record,log_record), 7) \
|
||||||
X(a, STATIC, ONEOF, UINT32, (payloadVariant,config_complete_id,config_complete_id), 8) \
|
X(a, STATIC, ONEOF, UINT32, (payloadVariant,config_complete_id,config_complete_id), 8) \
|
||||||
X(a, STATIC, ONEOF, BOOL, (payloadVariant,rebooted,rebooted), 9) \
|
X(a, STATIC, ONEOF, BOOL, (payloadVariant,rebooted,rebooted), 9) \
|
||||||
X(a, STATIC, ONEOF, MESSAGE, (payloadVariant,channel,channel), 10)
|
X(a, STATIC, ONEOF, MESSAGE, (payloadVariant,channel,channel), 10) \
|
||||||
|
X(a, STATIC, ONEOF, MESSAGE, (payloadVariant,packet,packet), 11)
|
||||||
#define FromRadio_CALLBACK NULL
|
#define FromRadio_CALLBACK NULL
|
||||||
#define FromRadio_DEFAULT NULL
|
#define FromRadio_DEFAULT NULL
|
||||||
#define FromRadio_payloadVariant_packet_MSGTYPE MeshPacket
|
|
||||||
#define FromRadio_payloadVariant_my_info_MSGTYPE MyNodeInfo
|
#define FromRadio_payloadVariant_my_info_MSGTYPE MyNodeInfo
|
||||||
#define FromRadio_payloadVariant_node_info_MSGTYPE NodeInfo
|
#define FromRadio_payloadVariant_node_info_MSGTYPE NodeInfo
|
||||||
#define FromRadio_payloadVariant_radio_MSGTYPE RadioConfig
|
#define FromRadio_payloadVariant_radio_MSGTYPE RadioConfig
|
||||||
#define FromRadio_payloadVariant_log_record_MSGTYPE LogRecord
|
#define FromRadio_payloadVariant_log_record_MSGTYPE LogRecord
|
||||||
#define FromRadio_payloadVariant_channel_MSGTYPE Channel
|
#define FromRadio_payloadVariant_channel_MSGTYPE Channel
|
||||||
|
#define FromRadio_payloadVariant_packet_MSGTYPE MeshPacket
|
||||||
|
|
||||||
#define ToRadio_FIELDLIST(X, a) \
|
#define ToRadio_FIELDLIST(X, a) \
|
||||||
X(a, STATIC, ONEOF, MESSAGE, (payloadVariant,packet,packet), 1) \
|
X(a, STATIC, ONEOF, MESSAGE, (payloadVariant,packet,packet), 2) \
|
||||||
X(a, STATIC, ONEOF, UINT32, (payloadVariant,want_config_id,want_config_id), 100) \
|
X(a, STATIC, ONEOF, UINT32, (payloadVariant,want_config_id,want_config_id), 100) \
|
||||||
X(a, STATIC, ONEOF, MESSAGE, (payloadVariant,set_radio,set_radio), 101) \
|
X(a, STATIC, ONEOF, MESSAGE, (payloadVariant,set_radio,set_radio), 101) \
|
||||||
X(a, STATIC, ONEOF, MESSAGE, (payloadVariant,set_owner,set_owner), 102) \
|
X(a, STATIC, ONEOF, MESSAGE, (payloadVariant,set_owner,set_owner), 102) \
|
||||||
@@ -726,10 +719,10 @@ X(a, STATIC, ONEOF, MESSAGE, (payloadVariant,set_channel,set_channel), 104
|
|||||||
#define ToRadio_payloadVariant_set_channel_MSGTYPE Channel
|
#define ToRadio_payloadVariant_set_channel_MSGTYPE Channel
|
||||||
|
|
||||||
extern const pb_msgdesc_t Position_msg;
|
extern const pb_msgdesc_t Position_msg;
|
||||||
extern const pb_msgdesc_t Data_msg;
|
|
||||||
extern const pb_msgdesc_t User_msg;
|
extern const pb_msgdesc_t User_msg;
|
||||||
extern const pb_msgdesc_t RouteDiscovery_msg;
|
extern const pb_msgdesc_t RouteDiscovery_msg;
|
||||||
extern const pb_msgdesc_t SubPacket_msg;
|
extern const pb_msgdesc_t Routing_msg;
|
||||||
|
extern const pb_msgdesc_t Data_msg;
|
||||||
extern const pb_msgdesc_t MeshPacket_msg;
|
extern const pb_msgdesc_t MeshPacket_msg;
|
||||||
extern const pb_msgdesc_t ChannelSettings_msg;
|
extern const pb_msgdesc_t ChannelSettings_msg;
|
||||||
extern const pb_msgdesc_t Channel_msg;
|
extern const pb_msgdesc_t Channel_msg;
|
||||||
@@ -743,10 +736,10 @@ extern const pb_msgdesc_t ToRadio_msg;
|
|||||||
|
|
||||||
/* Defines for backwards compatibility with code written before nanopb-0.4.0 */
|
/* Defines for backwards compatibility with code written before nanopb-0.4.0 */
|
||||||
#define Position_fields &Position_msg
|
#define Position_fields &Position_msg
|
||||||
#define Data_fields &Data_msg
|
|
||||||
#define User_fields &User_msg
|
#define User_fields &User_msg
|
||||||
#define RouteDiscovery_fields &RouteDiscovery_msg
|
#define RouteDiscovery_fields &RouteDiscovery_msg
|
||||||
#define SubPacket_fields &SubPacket_msg
|
#define Routing_fields &Routing_msg
|
||||||
|
#define Data_fields &Data_msg
|
||||||
#define MeshPacket_fields &MeshPacket_msg
|
#define MeshPacket_fields &MeshPacket_msg
|
||||||
#define ChannelSettings_fields &ChannelSettings_msg
|
#define ChannelSettings_fields &ChannelSettings_msg
|
||||||
#define Channel_fields &Channel_msg
|
#define Channel_fields &Channel_msg
|
||||||
@@ -760,11 +753,11 @@ extern const pb_msgdesc_t ToRadio_msg;
|
|||||||
|
|
||||||
/* Maximum encoded size of messages (where known) */
|
/* Maximum encoded size of messages (where known) */
|
||||||
#define Position_size 37
|
#define Position_size 37
|
||||||
#define Data_size 246
|
|
||||||
#define User_size 72
|
#define User_size 72
|
||||||
#define RouteDiscovery_size 88
|
#define RouteDiscovery_size 40
|
||||||
#define SubPacket_size 275
|
#define Routing_size 47
|
||||||
#define MeshPacket_size 322
|
#define Data_size 258
|
||||||
|
#define MeshPacket_size 302
|
||||||
#define ChannelSettings_size 95
|
#define ChannelSettings_size 95
|
||||||
#define Channel_size 105
|
#define Channel_size 105
|
||||||
#define RadioConfig_size 308
|
#define RadioConfig_size 308
|
||||||
@@ -772,8 +765,8 @@ extern const pb_msgdesc_t ToRadio_msg;
|
|||||||
#define NodeInfo_size 130
|
#define NodeInfo_size 130
|
||||||
#define MyNodeInfo_size 89
|
#define MyNodeInfo_size 89
|
||||||
#define LogRecord_size 81
|
#define LogRecord_size 81
|
||||||
#define FromRadio_size 331
|
#define FromRadio_size 317
|
||||||
#define ToRadio_size 325
|
#define ToRadio_size 312
|
||||||
|
|
||||||
#ifdef __cplusplus
|
#ifdef __cplusplus
|
||||||
} /* extern "C" */
|
} /* extern "C" */
|
||||||
|
|||||||
@@ -16,6 +16,7 @@ typedef enum _PortNum {
|
|||||||
PortNum_REMOTE_HARDWARE_APP = 2,
|
PortNum_REMOTE_HARDWARE_APP = 2,
|
||||||
PortNum_POSITION_APP = 3,
|
PortNum_POSITION_APP = 3,
|
||||||
PortNum_NODEINFO_APP = 4,
|
PortNum_NODEINFO_APP = 4,
|
||||||
|
PortNum_ROUTING_APP = 5,
|
||||||
PortNum_REPLY_APP = 32,
|
PortNum_REPLY_APP = 32,
|
||||||
PortNum_IP_TUNNEL_APP = 33,
|
PortNum_IP_TUNNEL_APP = 33,
|
||||||
PortNum_SERIAL_APP = 64,
|
PortNum_SERIAL_APP = 64,
|
||||||
|
|||||||
@@ -17,7 +17,7 @@
|
|||||||
#define MAX_NUM_NODES (member_size(DeviceState, node_db) / member_size(DeviceState, node_db[0]))
|
#define MAX_NUM_NODES (member_size(DeviceState, node_db) / member_size(DeviceState, node_db[0]))
|
||||||
|
|
||||||
/// Max number of channels allowed
|
/// Max number of channels allowed
|
||||||
#define MAX_CHANNELS (member_size(DeviceState, channels) / member_size(DeviceState, channels[0]))
|
#define MAX_NUM_CHANNELS (member_size(DeviceState, channels) / member_size(DeviceState, channels[0]))
|
||||||
|
|
||||||
/// helper function for encoding a record as a protobuf, any failures to encode are fatal and we will panic
|
/// helper function for encoding a record as a protobuf, any failures to encode are fatal and we will panic
|
||||||
/// returns the encoded packet size
|
/// returns the encoded packet size
|
||||||
|
|||||||
@@ -7,12 +7,14 @@
|
|||||||
#include "plugins/SerialPlugin.h"
|
#include "plugins/SerialPlugin.h"
|
||||||
#include "plugins/StoreForwardPlugin.h"
|
#include "plugins/StoreForwardPlugin.h"
|
||||||
#include "plugins/TextMessagePlugin.h"
|
#include "plugins/TextMessagePlugin.h"
|
||||||
|
#include "plugins/RoutingPlugin.h"
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Create plugin instances here. If you are adding a new plugin, you must 'new' it here (or somewhere else)
|
* Create plugin instances here. If you are adding a new plugin, you must 'new' it here (or somewhere else)
|
||||||
*/
|
*/
|
||||||
void setupPlugins()
|
void setupPlugins()
|
||||||
{
|
{
|
||||||
|
routingPlugin = new RoutingPlugin();
|
||||||
nodeInfoPlugin = new NodeInfoPlugin();
|
nodeInfoPlugin = new NodeInfoPlugin();
|
||||||
positionPlugin = new PositionPlugin();
|
positionPlugin = new PositionPlugin();
|
||||||
textMessagePlugin = new TextMessagePlugin();
|
textMessagePlugin = new TextMessagePlugin();
|
||||||
|
|||||||
@@ -108,8 +108,8 @@ void RangeTestPluginRadio::sendPayload(NodeNum dest, bool wantReplies)
|
|||||||
static char heartbeatString[20];
|
static char heartbeatString[20];
|
||||||
snprintf(heartbeatString, sizeof(heartbeatString), "seq %d", packetSequence);
|
snprintf(heartbeatString, sizeof(heartbeatString), "seq %d", packetSequence);
|
||||||
|
|
||||||
p->decoded.data.payload.size = strlen(heartbeatString); // You must specify how many bytes are in the reply
|
p->decoded.payload.size = strlen(heartbeatString); // You must specify how many bytes are in the reply
|
||||||
memcpy(p->decoded.data.payload.bytes, heartbeatString, p->decoded.data.payload.size);
|
memcpy(p->decoded.payload.bytes, heartbeatString, p->decoded.payload.size);
|
||||||
|
|
||||||
service.sendToMesh(p);
|
service.sendToMesh(p);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -9,7 +9,7 @@ MeshPacket *ReplyPlugin::allocReply()
|
|||||||
{
|
{
|
||||||
assert(currentRequest); // should always be !NULL
|
assert(currentRequest); // should always be !NULL
|
||||||
auto req = *currentRequest;
|
auto req = *currentRequest;
|
||||||
auto &p = req.decoded.data;
|
auto &p = req.decoded;
|
||||||
// The incoming message is in p.payload
|
// The incoming message is in p.payload
|
||||||
DEBUG_MSG("Received message from=0x%0x, id=%d, msg=%.*s\n", req.from, req.id, p.payload.size, p.payload.bytes);
|
DEBUG_MSG("Received message from=0x%0x, id=%d, msg=%.*s\n", req.from, req.id, p.payload.size, p.payload.bytes);
|
||||||
|
|
||||||
@@ -17,8 +17,8 @@ MeshPacket *ReplyPlugin::allocReply()
|
|||||||
|
|
||||||
const char *replyStr = "Message Received";
|
const char *replyStr = "Message Received";
|
||||||
auto reply = allocDataPacket(); // Allocate a packet for sending
|
auto reply = allocDataPacket(); // Allocate a packet for sending
|
||||||
reply->decoded.data.payload.size = strlen(replyStr); // You must specify how many bytes are in the reply
|
reply->decoded.payload.size = strlen(replyStr); // You must specify how many bytes are in the reply
|
||||||
memcpy(reply->decoded.data.payload.bytes, replyStr, reply->decoded.data.payload.size);
|
memcpy(reply->decoded.payload.bytes, replyStr, reply->decoded.payload.size);
|
||||||
|
|
||||||
return reply;
|
return reply;
|
||||||
}
|
}
|
||||||
|
|||||||
54
src/plugins/RoutingPlugin.cpp
Normal file
54
src/plugins/RoutingPlugin.cpp
Normal file
@@ -0,0 +1,54 @@
|
|||||||
|
#include "RoutingPlugin.h"
|
||||||
|
#include "MeshService.h"
|
||||||
|
#include "NodeDB.h"
|
||||||
|
#include "RTC.h"
|
||||||
|
#include "Router.h"
|
||||||
|
#include "configuration.h"
|
||||||
|
#include "main.h"
|
||||||
|
|
||||||
|
RoutingPlugin *routingPlugin;
|
||||||
|
|
||||||
|
bool RoutingPlugin::handleReceivedProtobuf(const MeshPacket &mp, const Routing &p)
|
||||||
|
{
|
||||||
|
|
||||||
|
return false; // Let others look at this message also if they want
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
MeshPacket *RoutingPlugin::allocReply()
|
||||||
|
{
|
||||||
|
assert(0); // 1.2 refactoring fixme, Not sure if anything needs this yet?
|
||||||
|
// return allocDataProtobuf(u);
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
void RoutingPlugin::sendAckNak(Routing_Error err, NodeNum to, PacketId idFrom)
|
||||||
|
{
|
||||||
|
Routing c = Routing_init_default;
|
||||||
|
|
||||||
|
if (!err) {
|
||||||
|
c.success_id = idFrom;
|
||||||
|
} else {
|
||||||
|
c.fail_id = idFrom;
|
||||||
|
|
||||||
|
// Also send back the error reason
|
||||||
|
c.error_reason = err;
|
||||||
|
}
|
||||||
|
|
||||||
|
auto p = allocDataProtobuf(c);
|
||||||
|
p->priority = MeshPacket_Priority_ACK;
|
||||||
|
|
||||||
|
p->hop_limit = 0; // Assume just immediate neighbors for now
|
||||||
|
p->to = to;
|
||||||
|
DEBUG_MSG("Sending an err=%d,to=0x%x,idFrom=0x%x,id=0x%x\n", err, to, idFrom, p->id);
|
||||||
|
|
||||||
|
router->sendLocal(p); // we sometimes send directly to the local node
|
||||||
|
}
|
||||||
|
|
||||||
|
RoutingPlugin::RoutingPlugin()
|
||||||
|
: ProtobufPlugin("routing", PortNum_ROUTING_APP, User_fields)
|
||||||
|
{
|
||||||
|
isPromiscuous = true;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
31
src/plugins/RoutingPlugin.h
Normal file
31
src/plugins/RoutingPlugin.h
Normal file
@@ -0,0 +1,31 @@
|
|||||||
|
#pragma once
|
||||||
|
#include "ProtobufPlugin.h"
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Routing plugin for router control messages
|
||||||
|
*/
|
||||||
|
class RoutingPlugin : public ProtobufPlugin<Routing>
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
/** Constructor
|
||||||
|
* name is for debugging output
|
||||||
|
*/
|
||||||
|
RoutingPlugin();
|
||||||
|
|
||||||
|
protected:
|
||||||
|
friend class Router;
|
||||||
|
|
||||||
|
/** 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
|
||||||
|
*/
|
||||||
|
virtual bool handleReceivedProtobuf(const MeshPacket &mp, const Routing &p);
|
||||||
|
|
||||||
|
/** Messages can be received that have the want_response bit set. If set, this callback will be invoked
|
||||||
|
* so that subclasses can (optionally) send a response back to the original sender. */
|
||||||
|
virtual MeshPacket *allocReply();
|
||||||
|
|
||||||
|
void sendAckNak(Routing_Error err, NodeNum to, PacketId idFrom);
|
||||||
|
};
|
||||||
|
|
||||||
|
extern RoutingPlugin *routingPlugin;
|
||||||
@@ -144,8 +144,8 @@ void SerialPluginRadio::sendPayload(NodeNum dest, bool wantReplies)
|
|||||||
|
|
||||||
p->want_ack = SERIALPLUGIN_ACK;
|
p->want_ack = SERIALPLUGIN_ACK;
|
||||||
|
|
||||||
p->decoded.data.payload.size = strlen(serialStringChar); // You must specify how many bytes are in the reply
|
p->decoded.payload.size = strlen(serialStringChar); // You must specify how many bytes are in the reply
|
||||||
memcpy(p->decoded.data.payload.bytes, serialStringChar, p->decoded.data.payload.size);
|
memcpy(p->decoded.payload.bytes, serialStringChar, p->decoded.payload.size);
|
||||||
|
|
||||||
service.sendToMesh(p);
|
service.sendToMesh(p);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -7,7 +7,7 @@ TextMessagePlugin *textMessagePlugin;
|
|||||||
|
|
||||||
bool TextMessagePlugin::handleReceived(const MeshPacket &mp)
|
bool TextMessagePlugin::handleReceived(const MeshPacket &mp)
|
||||||
{
|
{
|
||||||
auto &p = mp.decoded.data;
|
auto &p = mp.decoded;
|
||||||
DEBUG_MSG("Received text msg from=0x%0x, id=%d, msg=%.*s\n", mp.from, mp.id, p.payload.size, p.payload.bytes);
|
DEBUG_MSG("Received text msg from=0x%0x, id=%d, msg=%.*s\n", mp.from, mp.id, p.payload.size, p.payload.bytes);
|
||||||
|
|
||||||
// We only store/display messages destined for us.
|
// We only store/display messages destined for us.
|
||||||
|
|||||||
Reference in New Issue
Block a user