1.2 WIP at least doesn't crash

This commit is contained in:
Kevin Hester 2021-02-21 12:59:47 +08:00
parent 587102f6bc
commit 99467cd874
12 changed files with 89 additions and 76 deletions

View File

@ -4,14 +4,14 @@ You probably don't care about this section - skip to the next one.
1.2 cleanup & multichannel support: 1.2 cleanup & multichannel support:
* call RouterPlugin for *all* packets - not just Router packets * DONE call RouterPlugin for *all* packets - not just Router packets
* clear priority before sending (to keep wire size small)
* generate channel hash from the name of the channel+the psk (not just one or the other) * generate channel hash from the name of the channel+the psk (not just one or the other)
* DONE remove deprecated * DONE remove deprecated
* DONE fix setchannel in phoneapi.cpp * DONE fix setchannel in phoneapi.cpp
* DONE set mynodeinfo.max_channels * DONE set mynodeinfo.max_channels
* DONE set mynodeinfo.num_bands (formerly num_channels) * DONE set mynodeinfo.num_bands (formerly num_channels)
* fix sniffing of non Routing packets * DONE fix sniffing of non Routing packets
* enable remote setttings access by moving settings operations into a regular plugin (move settings ops out of PhoneAPI)
* DONE move portnum up? * DONE move portnum up?
* DONE remove region specific builds from the firmware * DONE remove region specific builds from the firmware
* add gui in android app for setting region * add gui in android app for setting region
@ -22,6 +22,9 @@ You probably don't care about this section - skip to the next one.
* DONE move most parts of meshpacket into the Data packet, so that we can chain multiple Data for sending when they all have a common destination and key. * DONE move most parts of meshpacket into the Data packet, so that we can chain multiple Data for sending when they all have a common destination and key.
* when selecting a MeshPacket for transmit, scan the TX queue for any Data packets we can merge together as a WirePayload. In the low level send/rx code expand that into multiple MeshPackets as needed (thus 'hiding' from MeshPacket that over the wire we send multiple datapackets * when selecting a MeshPacket for transmit, scan the TX queue for any Data packets we can merge together as a WirePayload. In the low level send/rx code expand that into multiple MeshPackets as needed (thus 'hiding' from MeshPacket that over the wire we send multiple datapackets
* confirm we are still calling the plugins for messages inbound from the phone (or generated locally) * confirm we are still calling the plugins for messages inbound from the phone (or generated locally)
* confirm we are still multi hop routing flood broadcasts
* confirm we are still doing resends on unicast reliable packets
* add support for full DSR unicast delivery
* DONE move acks into routing * DONE move acks into routing
* DONE make all subpackets different versions of data * DONE make all subpackets different versions of data
* DONE move routing control into a data packet * DONE move routing control into a data packet
@ -31,6 +34,7 @@ You probably don't care about this section - skip to the next one.
* add multichannel support in python * add multichannel support in python
* add channel selection for sending * add channel selection for sending
* record recevied channel in meshpacket * record recevied channel in meshpacket
* test remote settings operations (confirm it works 3 hops away)
* add channel restrictions for plugins (and restrict routing plugin to the "control" channel) * 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

2
proto

@ -1 +1 @@
Subproject commit 527b0fdc343f89843158977a1c1a7c14db854565 Subproject commit f23417aa7dcb8f61bbb2c1ea07c7b988ae66ec38

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, const Routing &c) 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,47 +72,49 @@ void DSRRouter::sniffReceived(const MeshPacket *p, const Routing &c)
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 (c.which_variant) { if (c)
case Routing_route_request_tag: switch (c->which_variant) {
// Handle route discovery packets (will be a broadcast message) case Routing_route_request_tag:
// FIXME - always start request with the senders nodenum // Handle route discovery packets (will be a broadcast message)
if (weAreInRoute(c.route_request)) { // FIXME - always start request with the senders nodenum
DEBUG_MSG("Ignoring a route request that contains us\n"); if (weAreInRoute(c->route_request)) {
} else { DEBUG_MSG("Ignoring a route request that contains us\n");
updateRoutes(c.route_request,
true); // Update our routing tables based on the route that came in so far on this request
if (p->decoded.dest == getNodeNum()) {
// They were looking for us, send back a route reply (the sender address will be first in the list)
sendRouteReply(c.route_request);
} else { } else {
// They were looking for someone else, forward it along (as a zero hop broadcast) updateRoutes(c->route_request,
NodeNum nextHop = getNextHop(p->decoded.dest); true); // Update our routing tables based on the route that came in so far on this request
if (nextHop) {
// in our route cache, reply to the requester (the sender address will be first in the list) if (p->decoded.dest == getNodeNum()) {
sendRouteReply(c.route_request, nextHop); // They were looking for us, send back a route reply (the sender address will be first in the list)
sendRouteReply(c->route_request);
} else { } else {
// Not in our route cache, rebroadcast on their behalf (after adding ourselves to the request route) // They were looking for someone else, forward it along (as a zero hop broadcast)
resendRouteRequest(p); NodeNum nextHop = getNextHop(p->decoded.dest);
if (nextHop) {
// in our route cache, reply to the requester (the sender address will be first in the list)
sendRouteReply(c->route_request, nextHop);
} else {
// Not in our route cache, rebroadcast on their behalf (after adding ourselves to the request route)
resendRouteRequest(p);
}
} }
} }
break;
case Routing_route_reply_tag:
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 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...
break;
case Routing_error_reason_tag:
removeRoute(p->decoded.dest);
// FIXME: if any pending packets were waiting on this route, delete them
break;
default:
break;
} }
break;
case Routing_route_reply_tag:
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
// 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...
break;
case Routing_error_reason_tag:
removeRoute(p->decoded.dest);
// FIXME: if any pending packets were waiting on this route, delete them
break;
default:
break;
}
// We simply ignore ACKs - because ReliableRouter will delete the pending packet for us // We simply ignore ACKs - because ReliableRouter will delete the pending packet for us
@ -137,15 +139,18 @@ void DSRRouter::sniffReceived(const MeshPacket *p, const Routing &c)
// FIXME, stop local processing of this packet // FIXME, stop local processing of this packet
} }
// handle naks - convert them to route error packets if (c) {
// All naks are generated locally, because we failed resending the packet too many times // handle naks - convert them to route error packets
PacketId nakId = c.fail_id; // All naks are generated locally, because we failed resending the packet too many times
if (nakId) { PacketId nakId = c->fail_id;
auto pending = findPendingPacket(p->to, nakId); if (nakId) {
if (pending && pending->packet->decoded.source) { // if source not set, this was not a multihop packet, just ignore auto pending = findPendingPacket(p->to, nakId);
removeRoute(pending->packet->decoded.dest); // We no longer have a route to the specified node 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
sendRouteError(p, Routing_Error_GOT_NAK); sendRouteError(p, Routing_Error_GOT_NAK);
}
} }
} }
} }

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, const Routing &c); 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

View File

@ -27,11 +27,11 @@ bool FloodingRouter::shouldFilterReceived(const MeshPacket *p)
return Router::shouldFilterReceived(p); return Router::shouldFilterReceived(p);
} }
void FloodingRouter::sniffReceived(const MeshPacket *p, const Routing &c) 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)
if (p->to == NODENUM_BROADCAST && p->hop_limit > 0) { if (p->to == NODENUM_BROADCAST && p->hop_limit > 0 && p->from != getNodeNum()) {
if (p->id != 0) { if (p->id != 0) {
MeshPacket *tosend = packetPool.allocCopy(*p); // keep a copy because we will be sending it MeshPacket *tosend = packetPool.allocCopy(*p); // keep a copy because we will be sending it

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, const Routing &c); virtual void sniffReceived(const MeshPacket *p, const Routing *c);
}; };

View File

@ -89,9 +89,10 @@ class MeshService
/// returns 0 to allow futher processing /// returns 0 to allow futher processing
int onGPSChanged(const meshtastic::GPSStatus *arg); int onGPSChanged(const meshtastic::GPSStatus *arg);
/// Handle a packet that just arrived from the radio. This method does _not_ free the provided packet. If it needs /// Handle a packet that just arrived from the radio. This method does _ReliableRouternot_ free the provided packet. If it needs
/// to keep the packet around it makes a copy /// to keep the packet around it makes a copy
int handleFromRadio(const MeshPacket *p); int handleFromRadio(const MeshPacket *p);
friend class RoutingPlugin;
}; };
extern MeshService service; extern MeshService service;

View File

@ -53,7 +53,7 @@ bool ReliableRouter::shouldFilterReceived(const MeshPacket *p)
* *
* Otherwise, let superclass handle it. * Otherwise, let superclass handle it.
*/ */
void ReliableRouter::sniffReceived(const MeshPacket *p, const Routing &c) void ReliableRouter::sniffReceived(const MeshPacket *p, const Routing *c)
{ {
NodeNum ourNode = getNodeNum(); NodeNum ourNode = getNodeNum();
@ -64,18 +64,19 @@ void ReliableRouter::sniffReceived(const MeshPacket *p, const Routing &c)
} }
// If the payload is valid, look for ack/nak // If the payload is valid, look for ack/nak
if (c) {
PacketId ackId = c->success_id;
PacketId nakId = c->fail_id;
PacketId ackId = c.success_id; // We intentionally don't check wasSeenRecently, because it is harmless to delete non existent retransmission records
PacketId nakId = c.fail_id; if (ackId || nakId) {
if (ackId) {
// We intentionally don't check wasSeenRecently, because it is harmless to delete non existent retransmission records DEBUG_MSG("Received a ack=%d, stopping retransmissions\n", ackId);
if (ackId || nakId) { stopRetransmission(p->to, ackId);
if (ackId) { } else {
DEBUG_MSG("Received a ack=%d, stopping retransmissions\n", ackId); DEBUG_MSG("Received a nak=%d, stopping retransmissions\n", nakId);
stopRetransmission(p->to, ackId); stopRetransmission(p->to, nakId);
} else { }
DEBUG_MSG("Received a nak=%d, stopping retransmissions\n", nakId);
stopRetransmission(p->to, nakId);
} }
} }
} }

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, const Routing &c); 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

@ -194,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, const Routing &c) 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
@ -247,11 +247,6 @@ void Router::handleReceived(MeshPacket *p)
// call any promiscious plugins here, make a (non promisiocous) plugin for forwarding messages to phone api // call any promiscious plugins here, make a (non promisiocous) plugin for forwarding messages to phone api
// sniffReceived(p); // sniffReceived(p);
MeshPlugin::callPlugins(*p); MeshPlugin::callPlugins(*p);
if (p->to == NODENUM_BROADCAST || p->to == getNodeNum()) {
printPacket("Delivering rx packet", p);
meshservice.handleFromRadio(p);
}
} }
} }

View File

@ -89,7 +89,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, const Routing &c); 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).

View File

@ -8,9 +8,16 @@
RoutingPlugin *routingPlugin; RoutingPlugin *routingPlugin;
bool RoutingPlugin::handleReceivedProtobuf(const MeshPacket &mp, const Routing *p) bool RoutingPlugin::handleReceivedProtobuf(const MeshPacket &mp, const Routing *r)
{ {
assert(0); router->sniffReceived(&mp, r);
// FIXME - move this to a non promsicious PhoneAPI plugin?
if (mp.to == NODENUM_BROADCAST || mp.to == nodeDB.getNodeNum()) {
printPacket("Delivering rx packet", &mp);
service.handleFromRadio(&mp);
}
return false; // Let others look at this message also if they want return false; // Let others look at this message also if they want
} }