Merge pull request #678 from geeksville/dev

misc bugs
This commit is contained in:
Kevin Hester 2021-02-07 11:00:09 +08:00 committed by GitHub
commit f7beec4728
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
15 changed files with 102 additions and 70 deletions

View File

@ -22,5 +22,15 @@ jobs:
- name: Install extra python tools - name: Install extra python tools
run: | run: |
pip install -U adafruit-nrfutil pip install -U adafruit-nrfutil
- name: Build - name: Install libs needed for linux build
run: platformio run -e tbeam -e heltec -e lora-relay-v1 -e linux run: |
sudo apt install -y libpsocksxx-dev
- name: Build for tbeam
run: platformio run -e tbeam
- name: Build for heltec
run: platformio run -e heltec
- name: Build for lora-relay-v1
run: platformio run -e lora-relay-v1
- name: Build for linux
run: platformio run -e linux

View File

@ -4,7 +4,7 @@ This is the device side code for the [meshtastic.org](https://www.meshtastic.org
![Continuous Integration](https://github.com/meshtastic/Meshtastic-esp32/workflows/Continuous%20Integration/badge.svg) ![Continuous Integration](https://github.com/meshtastic/Meshtastic-esp32/workflows/Continuous%20Integration/badge.svg)
Meshtastic is a project that lets you use Meshtastic® is a project that lets you use
inexpensive GPS mesh radios as an extensible, super long battery life mesh GPS communicator. These radios are great for hiking, skiing, paragliding - inexpensive GPS mesh radios as an extensible, super long battery life mesh GPS communicator. These radios are great for hiking, skiing, paragliding -
essentially any hobby where you don't have reliable internet access. Each member of your private mesh can always see the location and distance of all other essentially any hobby where you don't have reliable internet access. Each member of your private mesh can always see the location and distance of all other
members and any text messages sent to your group chat. members and any text messages sent to your group chat.

View File

@ -14,8 +14,6 @@ BOARDS_ESP32="tlora-v2 tlora-v1 tlora-v2-1-1.6 tbeam heltec tbeam0.7"
# FIXME note nrf52840dk build is for some reason only generating a BIN file but not a HEX file nrf52840dk-geeksville is fine # FIXME note nrf52840dk build is for some reason only generating a BIN file but not a HEX file nrf52840dk-geeksville is fine
BOARDS_NRF52="lora-relay-v1" BOARDS_NRF52="lora-relay-v1"
NUM_JOBS=2 || true
OUTDIR=release/latest OUTDIR=release/latest
# We keep all old builds (and their map files in the archive dir) # We keep all old builds (and their map files in the archive dir)
@ -51,7 +49,7 @@ function do_build() {
basename=universal/firmware-$BOARD-$VERSION basename=universal/firmware-$BOARD-$VERSION
fi fi
pio run --jobs $NUM_JOBS --environment $BOARD # -v pio run --environment $BOARD # -v
SRCELF=.pio/build/$BOARD/firmware.elf SRCELF=.pio/build/$BOARD/firmware.elf
cp $SRCELF $OUTDIR/elfs/$basename.elf cp $SRCELF $OUTDIR/elfs/$basename.elf

View File

@ -1,13 +1,13 @@
# What is Meshtastic? # What is Meshtastic?
Meshtastic is a project that lets you use Meshtastic® is a project that lets you use
inexpensive (\$30 ish) GPS radios as an extensible, long battery life, secure, mesh GPS communicator. These radios are great for hiking, skiing, paragliding - essentially any hobby where you don't have reliable internet access. Each member of your private mesh can always see the location and distance of all other members and any text messages sent to your group chat. inexpensive (\$30 ish) GPS radios as an extensible, long battery life, secure, mesh GPS communicator. These radios are great for hiking, skiing, paragliding - essentially any hobby where you don't have reliable internet access. Each member of your private mesh can always see the location and distance of all other members and any text messages sent to your group chat.
The radios automatically create a mesh to forward packets as needed, so everyone in the group can receive messages from even the furthest member. The radios will optionally work with your phone, but no phone is required. The radios automatically create a mesh to forward packets as needed, so everyone in the group can receive messages from even the furthest member. The radios will optionally work with your phone, but no phone is required.
Note: Questions after reading this? See our new [forum](https://meshtastic.discourse.group/). Note: Questions after reading this? See our new [forum](https://meshtastic.discourse.group/).
### Uses ## Uses
- Outdoor sports where cellular coverage is limited. (Hiking, Skiing, Boating, Paragliding, Gliders etc..) - Outdoor sports where cellular coverage is limited. (Hiking, Skiing, Boating, Paragliding, Gliders etc..)
- Applications where closed source GPS communicators just won't cut it (it is easy to add features for glider pilots etc...) - Applications where closed source GPS communicators just won't cut it (it is easy to add features for glider pilots etc...)
@ -17,7 +17,7 @@ Note: Questions after reading this? See our new [forum](https://meshtastic.disco
[![Youtube video demo](desk-video-screenshot.png)](https://www.youtube.com/watch?v=WlNbMbVZlHI "Meshtastic early demo") [![Youtube video demo](desk-video-screenshot.png)](https://www.youtube.com/watch?v=WlNbMbVZlHI "Meshtastic early demo")
### Features ## Features
Not all of these features are fully implemented yet - see **important** disclaimers below. But they should be in by the time we decide to call this project beta (three months?) Not all of these features are fully implemented yet - see **important** disclaimers below. But they should be in by the time we decide to call this project beta (three months?)

2
proto

@ -1 +1 @@
Subproject commit c9ad10d7e2f7f465dc477e98d6ec9d3b7059336c Subproject commit 106f4bfdebe277ab0b86d2b8c950ab78a35b0654

View File

@ -490,6 +490,8 @@ void setup()
DEBUG_MSG("Warning: Failed to find RF95 radio\n"); DEBUG_MSG("Warning: Failed to find RF95 radio\n");
delete rIf; delete rIf;
rIf = NULL; rIf = NULL;
} else {
DEBUG_MSG("Radio init succeeded, using RF95 radio\n");
} }
} }
#endif #endif
@ -501,6 +503,8 @@ void setup()
DEBUG_MSG("Warning: Failed to find SX1262 radio\n"); DEBUG_MSG("Warning: Failed to find SX1262 radio\n");
delete rIf; delete rIf;
rIf = NULL; rIf = NULL;
} else {
DEBUG_MSG("Radio init succeeded, using SX1262 radio\n");
} }
} }
#endif #endif
@ -512,6 +516,8 @@ void setup()
DEBUG_MSG("Warning: Failed to find simulated radio\n"); DEBUG_MSG("Warning: Failed to find simulated radio\n");
delete rIf; delete rIf;
rIf = NULL; rIf = NULL;
} else {
DEBUG_MSG("Using SIMULATED radio!\n");
} }
} }
#endif #endif

View File

@ -105,7 +105,7 @@ void DSRRouter::sniffReceived(const MeshPacket *p)
// 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_route_error_tag: case SubPacket_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, RouteError_NO_ROUTE); sendRouteError(p, ErrorReason_NO_ROUTE);
} }
// FIXME, stop local processing of this packet // FIXME, stop local processing of this packet
@ -145,7 +145,7 @@ void DSRRouter::sniffReceived(const MeshPacket *p)
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, RouteError_GOT_NAK); sendRouteError(p, ErrorReason_GOT_NAK);
} }
} }
} }
@ -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, RouteError err) void DSRRouter::sendRouteError(const MeshPacket *p, ErrorReason err)
{ {
DEBUG_MSG("FIXME not implemented sendRouteError\n"); DEBUG_MSG("FIXME not implemented sendRouteError\n");
} }

View File

@ -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, RouteError err); void sendRouteError(const MeshPacket *p, ErrorReason 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

@ -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(true, p->from, p->id); sendAckNak(ErrorReason_NONE, p->from, p->id);
} }
} }
@ -60,7 +60,7 @@ void ReliableRouter::sniffReceived(const MeshPacket *p)
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(true, p->from, p->id); sendAckNak(ErrorReason_NONE, p->from, p->id);
} }
// If the payload is valid, look for ack/nak // If the payload is valid, look for ack/nak
@ -84,27 +84,6 @@ void ReliableRouter::sniffReceived(const MeshPacket *p)
FloodingRouter::sniffReceived(p); FloodingRouter::sniffReceived(p);
} }
/**
* Send an ack or a nak packet back towards whoever sent idFrom
*/
void ReliableRouter::sendAckNak(bool isAck, NodeNum to, PacketId idFrom)
{
auto p = allocForSending();
p->hop_limit = 0; // Assume just immediate neighbors for now
p->to = to;
DEBUG_MSG("Sending an ack=0x%x,to=0x%x,idFrom=0x%x,id=0x%x\n", isAck, to, idFrom, p->id);
if (isAck) {
p->decoded.ack.success_id = idFrom;
p->decoded.which_ack = SubPacket_success_id_tag;
} else {
p->decoded.ack.fail_id = idFrom;
p->decoded.which_ack = SubPacket_fail_id_tag;
}
sendLocal(p); // we sometimes send directly to the local node
}
#define NUM_RETRANSMISSIONS 3 #define NUM_RETRANSMISSIONS 3
PendingPacket::PendingPacket(MeshPacket *p) PendingPacket::PendingPacket(MeshPacket *p)
@ -176,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(false, p.packet->from, p.packet->id); sendAckNak(ErrorReason_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

@ -109,10 +109,6 @@ class ReliableRouter : public FloodingRouter
PendingPacket *startRetransmission(MeshPacket *p); PendingPacket *startRetransmission(MeshPacket *p);
private: private:
/**
* Send an ack or a nak packet back towards whoever sent idFrom
*/
void sendAckNak(bool isAck, NodeNum to, PacketId idFrom);
/** /**
* Stop any retransmissions we are doing of the specified node/packet ID pair * Stop any retransmissions we are doing of the specified node/packet ID pair

View File

@ -99,6 +99,31 @@ MeshPacket *Router::allocForSending()
return p; return p;
} }
/**
* Send an ack or a nak packet back towards whoever sent idFrom
*/
void Router::sendAckNak(ErrorReason err, NodeNum to, PacketId idFrom)
{
auto p = allocForSending();
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.ack.success_id = idFrom;
p->decoded.which_ack = SubPacket_success_id_tag;
} else {
p->decoded.ack.fail_id = idFrom;
p->decoded.which_ack = SubPacket_fail_id_tag;
// Also send back the error reason
p->decoded.which_payload = SubPacket_error_reason_tag;
p->decoded.error_reason = err;
}
sendLocal(p); // we sometimes send directly to the local node
}
ErrorCode Router::sendLocal(MeshPacket *p) ErrorCode Router::sendLocal(MeshPacket *p)
{ {
// No need to deliver externally if the destination is the local node // No need to deliver externally if the destination is the local node
@ -106,8 +131,16 @@ ErrorCode Router::sendLocal(MeshPacket *p)
printPacket("Enqueuing local", p); printPacket("Enqueuing local", p);
fromRadioQueue.enqueue(p); fromRadioQueue.enqueue(p);
return ERRNO_OK; return ERRNO_OK;
} } else if (!iface) {
// We must be sending to remote nodes also, fail if no interface found
// 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");
sendAckNak(ErrorReason_NO_INTERFACE, p->from, p->id);
packetPool.release(p);
return ERRNO_NO_INTERFACES;
} else {
// If we are sending a broadcast, we also treat it as if we just received it ourself // If we are sending a broadcast, we also treat it as if we just received it ourself
// this allows local apps (and PCs) to see broadcasts sourced locally // this allows local apps (and PCs) to see broadcasts sourced locally
if (p->to == NODENUM_BROADCAST) { if (p->to == NODENUM_BROADCAST) {
@ -116,6 +149,7 @@ ErrorCode Router::sendLocal(MeshPacket *p)
return send(p); return send(p);
} }
}
/** /**
* Send a packet on a suitable interface. This routine will * Send a packet on a suitable interface. This routine will
@ -154,14 +188,15 @@ ErrorCode Router::send(MeshPacket *p)
p->which_payload = MeshPacket_encrypted_tag; p->which_payload = MeshPacket_encrypted_tag;
} }
if (iface) { assert(iface); // This should have been detected already in sendLocal (or we just received a packet from outside)
// if (iface) {
// DEBUG_MSG("Sending packet via interface fr=0x%x,to=0x%x,id=%d\n", p->from, p->to, p->id); // DEBUG_MSG("Sending packet via interface fr=0x%x,to=0x%x,id=%d\n", p->from, p->to, p->id);
return iface->send(p); return iface->send(p);
} else { /* } else {
DEBUG_MSG("Dropping packet - no interfaces - fr=0x%x,to=0x%x,id=%d\n", p->from, p->to, p->id); DEBUG_MSG("Dropping packet - no interfaces - fr=0x%x,to=0x%x,id=%d\n", p->from, p->to, p->id);
packetPool.release(p); packetPool.release(p);
return ERRNO_NO_INTERFACES; return ERRNO_NO_INTERFACES;
} } */
} }
/** /**

View File

@ -48,7 +48,8 @@ class Router : protected concurrency::OSThread
virtual int32_t runOnce(); virtual int32_t runOnce();
/** /**
* Works like send, but if we are sending to the local node, we directly put the message in the receive queue * Works like send, but if we are sending to the local node, we directly put the message in the receive queue.
* This is the primary method used for sending packets, because it handles both the remote and local cases.
* *
* NOTE: This method will free the provided packet (even if we return an error code) * NOTE: This method will free the provided packet (even if we return an error code)
*/ */
@ -92,6 +93,11 @@ class Router : protected concurrency::OSThread
*/ */
bool perhapsDecode(MeshPacket *p); bool perhapsDecode(MeshPacket *p);
/**
* Send an ack or a nak packet back towards whoever sent idFrom
*/
void sendAckNak(ErrorReason err, NodeNum to, PacketId idFrom);
private: private:
/** /**
* Called from loop() * Called from loop()

View File

@ -11,12 +11,14 @@
#endif #endif
/* Enum definitions */ /* Enum definitions */
typedef enum _RouteError { typedef enum _ErrorReason {
RouteError_NONE = 0, ErrorReason_NONE = 0,
RouteError_NO_ROUTE = 1, ErrorReason_NO_ROUTE = 1,
RouteError_GOT_NAK = 2, ErrorReason_GOT_NAK = 2,
RouteError_TIMEOUT = 3 ErrorReason_TIMEOUT = 3,
} RouteError; ErrorReason_NO_INTERFACE = 4,
ErrorReason_MAX_RETRANSMIT = 5
} ErrorReason;
typedef enum _Constants { typedef enum _Constants {
Constants_Unused = 0, Constants_Unused = 0,
@ -230,7 +232,7 @@ typedef struct _SubPacket {
User user; User user;
RouteDiscovery route_request; RouteDiscovery route_request;
RouteDiscovery route_reply; RouteDiscovery route_reply;
RouteError route_error; ErrorReason error_reason;
}; };
uint32_t original_id; uint32_t original_id;
bool want_response; bool want_response;
@ -288,9 +290,9 @@ typedef struct _ToRadio {
/* Helper constants for enums */ /* Helper constants for enums */
#define _RouteError_MIN RouteError_NONE #define _ErrorReason_MIN ErrorReason_NONE
#define _RouteError_MAX RouteError_TIMEOUT #define _ErrorReason_MAX ErrorReason_MAX_RETRANSMIT
#define _RouteError_ARRAYSIZE ((RouteError)(RouteError_TIMEOUT+1)) #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
@ -450,7 +452,7 @@ extern "C" {
#define SubPacket_user_tag 4 #define SubPacket_user_tag 4
#define SubPacket_route_request_tag 6 #define SubPacket_route_request_tag 6
#define SubPacket_route_reply_tag 7 #define SubPacket_route_reply_tag 7
#define SubPacket_route_error_tag 13 #define SubPacket_error_reason_tag 13
#define SubPacket_original_id_tag 2 #define SubPacket_original_id_tag 2
#define SubPacket_want_response_tag 5 #define SubPacket_want_response_tag 5
#define SubPacket_dest_tag 9 #define SubPacket_dest_tag 9
@ -517,7 +519,7 @@ X(a, STATIC, ONEOF, MESSAGE, (payload,data,data), 3) \
X(a, STATIC, ONEOF, MESSAGE, (payload,user,user), 4) \ 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_request,route_request), 6) \
X(a, STATIC, ONEOF, MESSAGE, (payload,route_reply,route_reply), 7) \ X(a, STATIC, ONEOF, MESSAGE, (payload,route_reply,route_reply), 7) \
X(a, STATIC, ONEOF, UENUM, (payload,route_error,route_error), 13) \ X(a, STATIC, ONEOF, UENUM, (payload,error_reason,error_reason), 13) \
X(a, STATIC, SINGULAR, UINT32, original_id, 2) \ X(a, STATIC, SINGULAR, UINT32, original_id, 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, UINT32, dest, 9) \

View File

@ -19,7 +19,7 @@ typedef enum _PortNum {
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,
PortNum_STORE_REQUEST_APP = 65, PortNum_STORE_FORWARD_APP = 65,
PortNum_PRIVATE_APP = 256, PortNum_PRIVATE_APP = 256,
PortNum_ATAK_FORWARDER = 257 PortNum_ATAK_FORWARDER = 257
} PortNum; } PortNum;

View File

@ -1,4 +1,4 @@
[VERSION] [VERSION]
major = 1 major = 1
minor = 1 minor = 1
build = 34 build = 42