diff --git a/proto b/proto index f713e0c03..adf4127fe 160000 --- a/proto +++ b/proto @@ -1 +1 @@ -Subproject commit f713e0c039140a1f2189274c9c28f219943e88de +Subproject commit adf4127fe3e4140bfd97b48a2d11b53ee34a16c8 diff --git a/src/mesh/DSRRouter.cpp b/src/mesh/DSRRouter.cpp index d59fc36e2..cb22c5467 100644 --- a/src/mesh/DSRRouter.cpp +++ b/src/mesh/DSRRouter.cpp @@ -36,20 +36,32 @@ when we receive a routeError packet - fixme, eventually keep caches of possible other routes. */ +ErrorCode DSRRouter::send(MeshPacket *p) +{ + // If we have an entry in our routing tables, just send it, otherwise start a route discovery + + return ReliableRouter::send(p); +} + void DSRRouter::sniffReceived(const MeshPacket *p) { + // 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 + // ignore rebroadcasts. + // this will also add records for any ACKs we receive for our messages + if (p->to != NODENUM_BROADCAST || p->hop_limit != HOP_RELIABLE) { + addRoute(p->from, p->from, 0); // We are adjacent with zero hops + } - // FIXME, update nodedb - - // Handle route discovery packets (will be a broadcast message) - if (p->decoded.which_payload == SubPacket_route_request_tag) { + switch (p->decoded.which_payload) { + case SubPacket_route_request_tag: + // Handle route discovery packets (will be a broadcast message) // FIXME - always start request with the senders nodenum - if (weAreInRoute(p->decoded.route_request)) { DEBUG_MSG("Ignoring a route request that contains us\n"); } else { updateRoutes(p->decoded.route_request, - false); // 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()) { // They were looking for us, send back a route reply (the sender address will be first in the list) @@ -66,23 +78,21 @@ void DSRRouter::sniffReceived(const MeshPacket *p) } } } - } + break; + case SubPacket_route_reply_tag: + updateRoutes(p->decoded.route_reply, false); - // Handle route reply packets - if (p->decoded.which_payload == SubPacket_route_reply_tag) { - updateRoutes(p->decoded.route_reply, true); - } + // 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 SubPacket_route_error_tag: + removeRoute(p->decoded.dest); - // Handle route error packets - if (p->decoded.which_payload == SubPacket_route_error_tag) { - // FIXME - } - - // 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 - // ignore rebroadcasts. - if (p->to != NODENUM_BROADCAST || p->hop_limit != HOP_RELIABLE) { - addRoute(p->from, p->from, 0); // We are adjacent with zero hops + // 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 @@ -92,7 +102,7 @@ void DSRRouter::sniffReceived(const MeshPacket *p) // We need to route this packet to some other node if (p->decoded.dest && p->decoded.dest != p->to) { - // FIXME if we have a route out, resend the packet to the next hop, otherwise return RouteError no-route available + // if we have a route out, resend the packet to the next hop, otherwise return RouteError no-route available NodeNum nextHop = getNextHop(p->decoded.dest); if (nextHop) { @@ -101,6 +111,7 @@ void DSRRouter::sniffReceived(const MeshPacket *p) // We don't have a route out assert(p->decoded.source); // I think this is guaranteed by now + // FIXME - what if the current packet _is_ a route error packet? sendRouteError(p, RouteError_NO_ROUTE); } @@ -113,7 +124,7 @@ void DSRRouter::sniffReceived(const MeshPacket *p) if (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 - removeRoute(pending->packet->decoded.dest, p->to); // 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, RouteError_GOT_NAK); } diff --git a/src/mesh/DSRRouter.h b/src/mesh/DSRRouter.h index a6004260a..904f99980 100644 --- a/src/mesh/DSRRouter.h +++ b/src/mesh/DSRRouter.h @@ -10,6 +10,13 @@ class DSRRouter : public ReliableRouter */ virtual void sniffReceived(const MeshPacket *p); + /** + * Send a packet on a suitable interface. This routine will + * later free() the packet to pool. This routine is not allowed to stall. + * If the txmit queue is full it might return an error + */ + virtual ErrorCode send(MeshPacket *p); + private: /** * Does our node appear in the specified route @@ -18,8 +25,12 @@ class DSRRouter : public ReliableRouter /** * Given a DSR route, use that route to update our DB of possible routes + * + * Note: routes are always listed in the same order - from sender to receipient (i.e. route_replies also use this some order) + * + * @param isRequest is true if we are looking at a route request, else we are looking at a reply **/ - void updateRoutes(const RouteDiscovery &route, bool reverse); + void updateRoutes(const RouteDiscovery &route, bool isRequest); /** * send back a route reply (the sender address will be first in the list) @@ -34,6 +45,8 @@ class DSRRouter : public ReliableRouter NodeNum getNextHop(NodeNum dest); /** Not in our route cache, rebroadcast on their behalf (after adding ourselves to the request route) + * + * We will bump down hop_limit in this call. */ void resendRouteRequest(const MeshPacket *p); @@ -45,9 +58,9 @@ class DSRRouter : public ReliableRouter void addRoute(NodeNum dest, NodeNum forwarder, uint8_t numHops); /** - * Record that the specified forwarder no longer has a route to the dest + * Record that we no longer have a route to the dest */ - void removeRoute(NodeNum dest, NodeNum forwarder); + void removeRoute(NodeNum dest); /** * Forward the specified packet to the specified node diff --git a/src/mesh/Router.cpp b/src/mesh/Router.cpp index bf92f3f1e..1c8d1763e 100644 --- a/src/mesh/Router.cpp +++ b/src/mesh/Router.cpp @@ -141,6 +141,7 @@ ErrorCode Router::send(MeshPacket *p) void Router::sniffReceived(const MeshPacket *p) { DEBUG_MSG("FIXME-update-db Sniffing packet fr=0x%x,to=0x%x,id=%d\n", p->from, p->to, p->id); + // FIXME, update nodedb } bool Router::perhapsDecode(MeshPacket *p) diff --git a/src/mesh/mesh.pb.h b/src/mesh/mesh.pb.h index 087af997e..fe9cd575c 100644 --- a/src/mesh/mesh.pb.h +++ b/src/mesh/mesh.pb.h @@ -17,7 +17,8 @@ extern "C" { typedef enum _RouteError { RouteError_NONE = 0, RouteError_NO_ROUTE = 1, - RouteError_GOT_NAK = 2 + RouteError_GOT_NAK = 2, + RouteError_TIMEOUT = 3 } RouteError; typedef enum _Constants { @@ -140,6 +141,7 @@ typedef struct _SubPacket { RouteDiscovery route_reply; RouteError route_error; }; + uint32_t original_id; bool want_response; uint32_t dest; pb_size_t which_ack; @@ -209,8 +211,8 @@ typedef struct _ToRadio { /* Helper constants for enums */ #define _RouteError_MIN RouteError_NONE -#define _RouteError_MAX RouteError_GOT_NAK -#define _RouteError_ARRAYSIZE ((RouteError)(RouteError_GOT_NAK+1)) +#define _RouteError_MAX RouteError_TIMEOUT +#define _RouteError_ARRAYSIZE ((RouteError)(RouteError_TIMEOUT+1)) #define _Constants_MIN Constants_Unused #define _Constants_MAX Constants_Unused @@ -230,7 +232,7 @@ typedef struct _ToRadio { #define Data_init_default {_Data_Type_MIN, {0, {0}}} #define User_init_default {"", "", "", {0}} #define RouteDiscovery_init_default {0, {0, 0, 0, 0, 0, 0, 0, 0}} -#define SubPacket_init_default {0, {Position_init_default}, 0, 0, 0, {0}, 0} +#define SubPacket_init_default {0, {Position_init_default}, 0, 0, 0, 0, {0}, 0} #define MeshPacket_init_default {0, 0, 0, {SubPacket_init_default}, 0, 0, 0, 0, 0} #define ChannelSettings_init_default {0, _ChannelSettings_ModemConfig_MIN, {0, {0}}, ""} #define RadioConfig_init_default {false, RadioConfig_UserPreferences_init_default, false, ChannelSettings_init_default} @@ -246,7 +248,7 @@ typedef struct _ToRadio { #define Data_init_zero {_Data_Type_MIN, {0, {0}}} #define User_init_zero {"", "", "", {0}} #define RouteDiscovery_init_zero {0, {0, 0, 0, 0, 0, 0, 0, 0}} -#define SubPacket_init_zero {0, {Position_init_zero}, 0, 0, 0, {0}, 0} +#define SubPacket_init_zero {0, {Position_init_zero}, 0, 0, 0, 0, {0}, 0} #define MeshPacket_init_zero {0, 0, 0, {SubPacket_init_zero}, 0, 0, 0, 0, 0} #define ChannelSettings_init_zero {0, _ChannelSettings_ModemConfig_MIN, {0, {0}}, ""} #define RadioConfig_init_zero {false, RadioConfig_UserPreferences_init_zero, false, ChannelSettings_init_zero} @@ -322,6 +324,7 @@ typedef struct _ToRadio { #define SubPacket_want_response_tag 5 #define SubPacket_dest_tag 9 #define SubPacket_source_tag 12 +#define SubPacket_original_id_tag 2 #define MeshPacket_decoded_tag 3 #define MeshPacket_encrypted_tag 8 #define MeshPacket_from_tag 1 @@ -387,6 +390,7 @@ X(a, STATIC, ONEOF, MESSAGE, (payload,user,user), 4) \ X(a, STATIC, ONEOF, MESSAGE, (payload,route_request,route_request), 6) \ X(a, STATIC, ONEOF, MESSAGE, (payload,route_reply,route_reply), 7) \ X(a, STATIC, ONEOF, ENUM, (payload,route_error,route_error), 13) \ +X(a, STATIC, SINGULAR, UINT32, original_id, 2) \ X(a, STATIC, SINGULAR, BOOL, want_response, 5) \ X(a, STATIC, SINGULAR, UINT32, dest, 9) \ X(a, STATIC, ONEOF, UINT32, (ack,success_id,ack.success_id), 10) \ @@ -570,17 +574,17 @@ extern const pb_msgdesc_t ManufacturingData_msg; #define Data_size 256 #define User_size 72 #define RouteDiscovery_size 88 -#define SubPacket_size 279 -#define MeshPacket_size 318 +#define SubPacket_size 285 +#define MeshPacket_size 324 #define ChannelSettings_size 60 #define RadioConfig_size 157 #define RadioConfig_UserPreferences_size 93 #define NodeInfo_size 132 #define MyNodeInfo_size 80 -#define DeviceState_size 15235 +#define DeviceState_size 15433 #define DebugString_size 258 -#define FromRadio_size 327 -#define ToRadio_size 321 +#define FromRadio_size 333 +#define ToRadio_size 327 /* ManufacturingData_size depends on runtime parameters */ #ifdef __cplusplus