WIP 1.2 move routing into plugin

This commit is contained in:
Kevin Hester
2021-02-17 13:06:23 +08:00
parent 205282c4bc
commit 42ae27973e
33 changed files with 317 additions and 233 deletions

View File

@@ -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

Submodule proto updated: 481beb41ba...65914b84f1

View File

@@ -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);
} }

View File

@@ -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);

View File

@@ -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");
} }

View File

@@ -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

View File

@@ -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);
} }

View File

@@ -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);
}; };

View File

@@ -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);
} }
} }

View File

@@ -32,7 +32,7 @@ void MeshPlugin::callPlugins(const MeshPacket &mp)
auto &pi = **i; auto &pi = **i;
pi.currentRequest = &mp; pi.currentRequest = &mp;
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

View File

@@ -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.

View File

@@ -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
}
}
} }
} }

View File

@@ -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;

View File

@@ -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");
} }
@@ -156,7 +149,7 @@ void printPacket(const char *prefix, const MeshPacket *p)
if (p->rx_snr != 0.0) { if (p->rx_snr != 0.0) {
DEBUG_MSG(" rxSNR=%g", p->rx_snr); DEBUG_MSG(" rxSNR=%g", p->rx_snr);
} }
if(p->priority != 0) if (p->priority != 0)
DEBUG_MSG(" priority=%d", p->priority); DEBUG_MSG(" priority=%d", p->priority);
DEBUG_MSG(")\n"); DEBUG_MSG(")\n");

View File

@@ -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);

View File

@@ -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)

View File

@@ -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);

View File

@@ -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:
/** /**

View File

@@ -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;
} }

View File

@@ -9,4 +9,7 @@
PB_BIND(ServiceEnvelope, ServiceEnvelope, 2) PB_BIND(ServiceEnvelope, ServiceEnvelope, 2)
PB_BIND(ChannelSet, ChannelSet, AUTO)

View File

@@ -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" */

View File

@@ -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" */

View File

@@ -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)

View File

@@ -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" */

View File

@@ -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,

View File

@@ -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

View File

@@ -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();

View File

@@ -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);
} }

View File

@@ -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;
} }

View 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;
}

View 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;

View File

@@ -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);
} }

View File

@@ -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.