Compare commits

...

18 Commits
1.2.4 ... 1.2.6

Author SHA1 Message Date
Kevin Hester
96c4286e7d Merge pull request #733 from geeksville/dev1.2
1.2.6
2021-03-07 10:00:00 +08:00
Kevin Hester
f320ecbde8 1.2.6 2021-03-07 09:51:51 +08:00
Kevin Hester
d014ae0bff fix ls_sleeps communication to device clients 2021-03-07 09:51:17 +08:00
Kevin Hester
12a7934ca1 add RU 2021-03-07 09:34:35 +08:00
Kevin Hester
64bc791e48 fix docs 2021-03-07 09:34:29 +08:00
Kevin Hester
1f33506962 Add RU region 2021-03-06 21:10:36 +08:00
Kevin Hester
ba9a94d026 fix is_low_power detection 2021-03-06 18:00:20 +08:00
Kevin Hester
6f13966d19 fix missing acks for broadcasts 2021-03-06 17:48:35 +08:00
Kevin Hester
96cfad4e57 less logspam 2021-03-06 14:52:26 +08:00
Kevin Hester
a26ebb1b69 Merge pull request #732 from geeksville/dev1.2
Dev1.2 - fix lora message rx
2021-03-06 14:31:59 +08:00
Kevin Hester
7a764efc10 1.2.5 2021-03-06 14:30:53 +08:00
Kevin Hester
49b1f4c5af oops - fix failed text message rx 2021-03-06 14:21:20 +08:00
Kevin Hester
fbe56531d2 Merge remote-tracking branch 'root/master' into dev1.2 2021-03-06 11:20:08 +08:00
Kevin Hester
aa6b29a4b5 fix from address on naks 2021-03-06 11:19:52 +08:00
Kevin Hester
c88b9732eb REALLY IMPORTANT: fix bug with retransmissions not happening 2021-03-06 11:13:33 +08:00
Kevin Hester
2c29e8b179 make nodeinfo & position plugins optional 2021-03-06 10:36:30 +08:00
Kevin Hester
d2d6b8e12f fix log formatting 2021-03-06 10:27:48 +08:00
Kevin Hester
badfaa8545 make error message clearer for packets that are too big 2021-03-06 10:27:31 +08:00
19 changed files with 140 additions and 59 deletions

View File

@@ -34,8 +34,8 @@ You probably don't care about this section - skip to the next one.
* DONE combine acks and responses in a single message if possible (do routing plugin LAST and drop ACK if someone else has already replied) * DONE combine acks and responses in a single message if possible (do routing plugin LAST and drop ACK if someone else has already replied)
* DONE don't send packets we received from the phone BACK TOWARDS THE PHONE (possibly use fromnode 0 for packets the phone sends?) * DONE don't send packets we received from the phone BACK TOWARDS THE PHONE (possibly use fromnode 0 for packets the phone sends?)
* fix 1.1.50 android debug panel display * fix 1.1.50 android debug panel display
* test android channel setting * DONE test android channel setting
* release to users * DONE release to users
* DONE warn in android app about unset regions * DONE warn in android app about unset regions
* DONE use set-channel from android * DONE use set-channel from android
* DONE add gui in android app for setting region * DONE add gui in android app for setting region

2
proto

Submodule proto updated: ac4f53ed8c...7c025b9a4d

View File

@@ -178,10 +178,11 @@ void PowerFSM_setup()
bool isLowPower = radioConfig.preferences.is_low_power || isRouter; bool isLowPower = radioConfig.preferences.is_low_power || isRouter;
/* To determine if we're externally powered, assumptions /* To determine if we're externally powered, assumptions
1) If we're powered up and there's no battery, we must be getting power externally. 1) If we're powered up and there's no battery, we must be getting power externally. (because we'd be dead otherwise)
2) If we detect USB power from the power management chip, we must be getting power externally. 2) If we detect USB power from the power management chip, we must be getting power externally.
*/ */
bool hasPower = (powerStatus && !powerStatus->getHasBattery()) || (!isLowPower && powerStatus && powerStatus->getHasUSB()); bool hasPower = !isLowPower && powerStatus && (!powerStatus->getHasBattery() || powerStatus->getHasUSB());
DEBUG_MSG("PowerFSM init, USB power=%d\n", hasPower); DEBUG_MSG("PowerFSM init, USB power=%d\n", hasPower);
powerFSM.add_timed_transition(&stateBOOT, hasPower ? &statePOWER : &stateON, 3 * 1000, NULL, "boot timeout"); powerFSM.add_timed_transition(&stateBOOT, hasPower ? &statePOWER : &stateON, 3 * 1000, NULL, "boot timeout");

View File

@@ -54,7 +54,7 @@ class ESP32CryptoEngine : public CryptoEngine
static uint8_t scratch[MAX_BLOCKSIZE]; static uint8_t scratch[MAX_BLOCKSIZE];
size_t nc_off = 0; size_t nc_off = 0;
// DEBUG_MSG("ESP32 encrypt!\n"); // DEBUG_MSG("ESP32 crypt fr=%x, num=%x, numBytes=%d!\n", fromNode, (uint32_t) packetNum, numBytes);
initNonce(fromNode, packetNum); initNonce(fromNode, packetNum);
assert(numBytes <= MAX_BLOCKSIZE); assert(numBytes <= MAX_BLOCKSIZE);
memcpy(scratch, bytes, numBytes); memcpy(scratch, bytes, numBytes);

View File

@@ -275,10 +275,11 @@ const char *Channels::getPrimaryName()
bool Channels::decryptForHash(ChannelIndex chIndex, ChannelHash channelHash) bool Channels::decryptForHash(ChannelIndex chIndex, ChannelHash channelHash)
{ {
if(chIndex > getNumChannels() || getHash(chIndex) != channelHash) { if(chIndex > getNumChannels() || getHash(chIndex) != channelHash) {
DEBUG_MSG("Skipping channel %d due to invalid hash/index\n", chIndex); // DEBUG_MSG("Skipping channel %d (hash %x) due to invalid hash/index, want=%x\n", chIndex, getHash(chIndex), channelHash);
return false; return false;
} }
else { else {
DEBUG_MSG("Using channel %d (hash 0x%x)\n", chIndex, channelHash);
setCrypto(chIndex); setCrypto(chIndex);
return true; return true;
} }

View File

@@ -4,6 +4,10 @@
void CryptoEngine::setKey(const CryptoKey &k) void CryptoEngine::setKey(const CryptoKey &k)
{ {
DEBUG_MSG("Installing AES%d key!\n", k.length * 8); DEBUG_MSG("Installing AES%d key!\n", k.length * 8);
/* for(uint8_t i = 0; i < k.length; i++)
DEBUG_MSG("%02x ", k.bytes[i]);
DEBUG_MSG("\n"); */
key = k; key = k;
} }

View File

@@ -114,7 +114,8 @@ bool MeshService::reloadConfig()
void MeshService::reloadOwner() void MeshService::reloadOwner()
{ {
assert(nodeInfoPlugin); assert(nodeInfoPlugin);
nodeInfoPlugin->sendOurNodeInfo(); if(nodeInfoPlugin)
nodeInfoPlugin->sendOurNodeInfo();
nodeDB.saveToDisk(); nodeDB.saveToDisk();
} }
@@ -170,12 +171,18 @@ void MeshService::sendNetworkPing(NodeNum dest, bool wantReplies)
NodeInfo *node = nodeDB.getNode(nodeDB.getNodeNum()); NodeInfo *node = nodeDB.getNode(nodeDB.getNodeNum());
assert(node); assert(node);
DEBUG_MSG("Sending network ping to 0x%x, with position=%d, wantReplies=%d\n", dest, node->has_position, wantReplies); if (node->has_position) {
assert(positionPlugin && nodeInfoPlugin); if(positionPlugin) {
if (node->has_position) DEBUG_MSG("Sending position ping to 0x%x, wantReplies=%d\n", dest, wantReplies);
positionPlugin->sendOurPosition(dest, wantReplies); positionPlugin->sendOurPosition(dest, wantReplies);
else }
nodeInfoPlugin->sendOurNodeInfo(dest, wantReplies); }
else {
if(nodeInfoPlugin) {
DEBUG_MSG("Sending nodeinfo ping to 0x%x, wantReplies=%d\n", dest, wantReplies);
nodeInfoPlugin->sendOurNodeInfo(dest, wantReplies);
}
}
} }
NodeInfo *MeshService::refreshMyNodeInfo() NodeInfo *MeshService::refreshMyNodeInfo()

View File

@@ -179,9 +179,8 @@ size_t PhoneAPI::getFromRadio(uint8_t *buf)
// Do we have a message from the mesh? // Do we have a message from the mesh?
if (fromRadioScratch.which_payloadVariant != 0) { if (fromRadioScratch.which_payloadVariant != 0) {
// Encapsulate as a FromRadio packet // Encapsulate as a FromRadio packet
DEBUG_MSG("encoding toPhone packet to phone variant=%d", fromRadioScratch.which_payloadVariant);
size_t numbytes = pb_encode_to_bytes(buf, FromRadio_size, FromRadio_fields, &fromRadioScratch); size_t numbytes = pb_encode_to_bytes(buf, FromRadio_size, FromRadio_fields, &fromRadioScratch);
DEBUG_MSG(", %d bytes\n", numbytes); // DEBUG_MSG("encoding toPhone packet to phone variant=%d, %d bytes\n", fromRadioScratch.which_payloadVariant, numbytes);
return numbytes; return numbytes;
} }

View File

@@ -1,16 +1,16 @@
#include "configuration.h"
#include "RadioInterface.h" #include "RadioInterface.h"
#include "Channels.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 "Router.h"
#include "sleep.h" #include "sleep.h"
#include <assert.h> #include <assert.h>
#include <pb_decode.h> #include <pb_decode.h>
#include <pb_encode.h> #include <pb_encode.h>
#include "Channels.h"
#define RDEF(name, freq, spacing, num_ch, power_limit) \ #define RDEF(name, freq, spacing, num_ch, power_limit) \
{ \ { \
@@ -25,9 +25,27 @@ const RegionInfo regions[] = {
RDEF(KR, 921.9f, 0.2f, 8, 0), // KR channel settings (KR920-923) Start from TTN download channel RDEF(KR, 921.9f, 0.2f, 8, 0), // KR channel settings (KR920-923) Start from TTN download channel
// freq. (921.9f is for download, others are for uplink) // freq. (921.9f is for download, others are for uplink)
RDEF(TW, 923.0f, 0.2f, 10, 0), // TW channel settings (AS2 bandplan 923-925MHz) RDEF(TW, 923.0f, 0.2f, 10, 0), // TW channel settings (AS2 bandplan 923-925MHz)
RDEF(RU, 868.9f, 0.2f, 2, 20), // See notes below
RDEF(Unset, 903.08f, 2.16f, 13, 0) // Assume US freqs if unset, Must be last RDEF(Unset, 903.08f, 2.16f, 13, 0) // Assume US freqs if unset, Must be last
}; };
/* Notes about the RU bandplan (from @denis-d in https://meshtastic.discourse.group/t/russian-band-plan-proposal/2786/2):
According to Annex 12 to GKRCh (National Radio Frequency Commission) decision № 18-46-03-1 (September 11th 2018) https://digital.gov.ru/uploaded/files/prilozhenie-12-k-reshenyu-gkrch-18-46-03-1.pdf 1
We have 3 options for 868 MHz:
864,0 - 865,0 MHz ERP 25mW, Duty Cycle 0.1% (3.6 sec in hour) or LBT (Listen Before Talk), prohibited in airports.
866,0 - 868,0 MHz ERP 25mW, Duty Cycle 1% or LBT, PSD (Power Spectrum Density) 1000mW/MHz, prohibited in airports
868,7 - 869,2 MHz ERP 100mW, Duty Cycle 10% or LBT, no resctrictions
and according to RP2-1.0.2 LoRaWAN® Regional Parameters RP2-1.0.2 LoRaWAN® Regional Parameters - LoRa Alliance®
I propose to use following meshtastic bandplan:
1 channel - central frequency 868.9MHz 125kHz band
Protective band - 75kHz
2 channel - central frequency 869.1MHz 125kHz band
RDEF(RU, 868.9f, 0.2f, 2, 20)
*/
const RegionInfo *myRegion; const RegionInfo *myRegion;
void initRegion() void initRegion()
@@ -119,8 +137,8 @@ uint32_t RadioInterface::getTxDelayMsec()
void printPacket(const char *prefix, const MeshPacket *p) void printPacket(const char *prefix, const MeshPacket *p)
{ {
DEBUG_MSG("%s (id=0x%08x Fr0x%02x To0x%02x, WantAck%d, HopLim%d Ch0x%x", prefix, p->id, p->from & 0xff, p->to & 0xff, p->want_ack, DEBUG_MSG("%s (id=0x%08x Fr0x%02x To0x%02x, WantAck%d, HopLim%d Ch0x%x", prefix, p->id, p->from & 0xff, p->to & 0xff,
p->hop_limit, p->channel); p->want_ack, p->hop_limit, p->channel);
if (p->which_payloadVariant == MeshPacket_decoded_tag) { if (p->which_payloadVariant == MeshPacket_decoded_tag) {
auto &s = p->decoded; auto &s = p->decoded;
@@ -332,6 +350,10 @@ void RadioInterface::deliverToReceiver(MeshPacket *p)
{ {
assert(rxDest); assert(rxDest);
assert(rxDest->enqueue(p, 0)); // NOWAIT - fixme, if queue is full, delete older messages assert(rxDest->enqueue(p, 0)); // NOWAIT - fixme, if queue is full, delete older messages
// Nasty hack because our threading is primitive. interfaces shouldn't need to know about routers FIXME
if (router)
router->setReceivedMessage();
} }
/*** /***

View File

@@ -1,8 +1,8 @@
#include "ReliableRouter.h" #include "ReliableRouter.h"
#include "MeshPlugin.h"
#include "MeshTypes.h" #include "MeshTypes.h"
#include "configuration.h" #include "configuration.h"
#include "mesh-pb-constants.h" #include "mesh-pb-constants.h"
#include "MeshPlugin.h"
// ReliableRouter::ReliableRouter() {} // ReliableRouter::ReliableRouter() {}
@@ -35,9 +35,10 @@ bool ReliableRouter::shouldFilterReceived(const MeshPacket *p)
// If this is the first time we saw this, cancel any retransmissions we have queued up and generate an internal ack for // If this is the first time we saw this, cancel any retransmissions we have queued up and generate an internal ack for
// the original sending process. // the original sending process.
if (stopRetransmission(getFrom(p), p->id)) { if (stopRetransmission(getFrom(p), p->id)) {
DEBUG_MSG("Someone is retransmitting for us, generate implicit ack\n"); DEBUG_MSG("generating implicit ack\n");
if(p->want_ack) // NOTE: we do NOT check p->wantAck here because p is the INCOMING rebroadcast and that packet is not expected to be
sendAckNak(Routing_Error_NONE, getFrom(p), p->id); // marked as wantAck
sendAckNak(Routing_Error_NONE, getFrom(p), p->id);
} }
} }
@@ -63,7 +64,7 @@ void ReliableRouter::sniffReceived(const MeshPacket *p, const Routing *c)
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) {
if(MeshPlugin::currentReply) if (MeshPlugin::currentReply)
DEBUG_MSG("Someone else has replied to this message, no need for a 2nd ack"); DEBUG_MSG("Someone else has replied to this message, no need for a 2nd ack");
else else
sendAckNak(Routing_Error_NONE, getFrom(p), p->id); sendAckNak(Routing_Error_NONE, getFrom(p), p->id);
@@ -136,8 +137,9 @@ PendingPacket *ReliableRouter::startRetransmission(MeshPacket *p)
auto id = GlobalPacketId(p); auto id = GlobalPacketId(p);
auto rec = PendingPacket(p); auto rec = PendingPacket(p);
setNextTx(&rec);
stopRetransmission(getFrom(p), p->id); stopRetransmission(getFrom(p), p->id);
setNextTx(&rec);
pending[id] = rec; pending[id] = rec;
return &pending[id]; return &pending[id];
@@ -157,18 +159,21 @@ int32_t ReliableRouter::doRetransmissions()
++nextIt; // we use this odd pattern because we might be deleting it... ++nextIt; // we use this odd pattern because we might be deleting it...
auto &p = it->second; auto &p = it->second;
bool stillValid = true; // assume we'll keep this record around
// FIXME, handle 51 day rolloever here!!! // FIXME, handle 51 day rolloever here!!!
if (p.nextTxMsec <= now) { if (p.nextTxMsec <= now) {
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 for fr=0x%x,to=0x%x,id=0x%x\n", p.packet->from, p.packet->to,
p.packet->id); p.packet->id);
sendAckNak(Routing_Error_MAX_RETRANSMIT, p.packet->from, p.packet->id); sendAckNak(Routing_Error_MAX_RETRANSMIT, getFrom(p.packet), 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);
stillValid = false; // just deleted it
} else { } else {
DEBUG_MSG("Sending reliable retransmission fr=0x%x,to=0x%x,id=%d, tries left=%d\n", p.packet->from, p.packet->to, DEBUG_MSG("Sending reliable retransmission fr=0x%x,to=0x%x,id=0x%x, tries left=%d\n", p.packet->from,
p.packet->id, p.numRetransmissions); p.packet->to, p.packet->id, p.numRetransmissions);
// Note: we call the superclass version because we don't want to have our version of send() add a new // Note: we call the superclass version because we don't want to have our version of send() add a new
// retransmission record // retransmission record
@@ -178,8 +183,10 @@ int32_t ReliableRouter::doRetransmissions()
--p.numRetransmissions; --p.numRetransmissions;
setNextTx(&p); setNextTx(&p);
} }
} else { }
// Not yet time
if (stillValid) {
// Update our desired sleep delay
int32_t t = p.nextTxMsec - now; int32_t t = p.nextTxMsec - now;
d = min(t, d); d = min(t, d);
@@ -188,3 +195,13 @@ int32_t ReliableRouter::doRetransmissions()
return d; return d;
} }
void ReliableRouter::setNextTx(PendingPacket *pending)
{
assert(iface);
auto d = iface->getRetransmissionMsec(pending->packet);
pending->nextTxMsec = millis() + d;
DEBUG_MSG("Setting next retransmission in %u msecs: ", d);
printPacket("", pending->packet);
setReceivedMessage(); // Run ASAP, so we can figure out our correct sleep time
}

View File

@@ -125,7 +125,5 @@ class ReliableRouter : public FloodingRouter
*/ */
int32_t doRetransmissions(); int32_t doRetransmissions();
void setNextTx(PendingPacket *pending) { void setNextTx(PendingPacket *pending);
assert(iface);
pending->nextTxMsec = millis() + iface->getRetransmissionMsec(pending->packet); }
}; };

View File

@@ -115,12 +115,17 @@ void Router::abortSendAndNak(Routing_Error err, MeshPacket *p)
packetPool.release(p); packetPool.release(p);
} }
void Router::setReceivedMessage() {
setInterval(0); // Run ASAP, so we can figure out our correct sleep time
}
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
if (p->to == nodeDB.getNodeNum()) { if (p->to == nodeDB.getNodeNum()) {
printPacket("Enqueuing local", p); printPacket("Enqueuing local", p);
fromRadioQueue.enqueue(p); fromRadioQueue.enqueue(p);
setReceivedMessage();
return ERRNO_OK; return ERRNO_OK;
} else if (!iface) { } else if (!iface) {
// We must be sending to remote nodes also, fail if no interface found // We must be sending to remote nodes also, fail if no interface found
@@ -138,6 +143,13 @@ ErrorCode Router::sendLocal(MeshPacket *p)
} }
} }
void printBytes(const char *label, const uint8_t *p, size_t numbytes) {
DEBUG_MSG("%s: ", label);
for(size_t i = 0; i < numbytes; i++)
DEBUG_MSG("%02x ", p[i]);
DEBUG_MSG("\n");
}
/** /**
* 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.
@@ -168,6 +180,8 @@ 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
// printPacket("pre encrypt", p); // portnum valid here
size_t numbytes = pb_encode_to_bytes(bytes, sizeof(bytes), Data_fields, &p->decoded); size_t numbytes = pb_encode_to_bytes(bytes, sizeof(bytes), Data_fields, &p->decoded);
if (numbytes > MAX_RHPACKETLEN) { if (numbytes > MAX_RHPACKETLEN) {
@@ -175,6 +189,8 @@ ErrorCode Router::send(MeshPacket *p)
return ERRNO_TOO_LARGE; return ERRNO_TOO_LARGE;
} }
//printBytes("plaintext", bytes, numbytes);
auto hash = channels.setActiveByIndex(p->channel); auto hash = channels.setActiveByIndex(p->channel);
if (hash < 0) { if (hash < 0) {
// No suitable channel could be found for sending // No suitable channel could be found for sending
@@ -184,7 +200,7 @@ ErrorCode Router::send(MeshPacket *p)
// Now that we are encrypting the packet channel should be the hash (no longer the index) // Now that we are encrypting the packet channel should be the hash (no longer the index)
p->channel = hash; p->channel = hash;
crypto->encrypt(p->from, p->id, numbytes, bytes); crypto->encrypt(getFrom(p), p->id, numbytes, bytes);
// Copy back into the packet and set the variant type // Copy back into the packet and set the variant type
memcpy(p->encrypted.bytes, bytes, numbytes); memcpy(p->encrypted.bytes, bytes, numbytes);
@@ -225,20 +241,26 @@ bool Router::perhapsDecode(MeshPacket *p)
if (channels.decryptForHash(chIndex, p->channel)) { if (channels.decryptForHash(chIndex, p->channel)) {
// Try to decrypt the packet if we can // Try to decrypt the packet if we can
static uint8_t bytes[MAX_RHPACKETLEN]; static uint8_t bytes[MAX_RHPACKETLEN];
size_t rawSize = p->encrypted.size;
assert(rawSize <= sizeof(bytes));
memcpy(bytes, p->encrypted.bytes, memcpy(bytes, p->encrypted.bytes,
p->encrypted rawSize); // we have to copy into a scratch buffer, because these bytes are a union with the decoded protobuf
.size); // we have to copy into a scratch buffer, because these bytes are a union with the decoded protobuf crypto->decrypt(p->from, p->id, rawSize, bytes);
crypto->decrypt(p->from, p->id, p->encrypted.size, bytes);
//printBytes("plaintext", bytes, p->encrypted.size);
// 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
memset(&p->decoded, 0, sizeof(p->decoded)); memset(&p->decoded, 0, sizeof(p->decoded));
if (!pb_decode_from_bytes(bytes, p->encrypted.size, Data_fields, &p->decoded)) { if (!pb_decode_from_bytes(bytes, rawSize, Data_fields, &p->decoded)) {
DEBUG_MSG("Invalid protobufs in received mesh packet (bad psk?!\n"); DEBUG_MSG("Invalid protobufs in received mesh packet (bad psk?)!\n");
} else { } else if(p->decoded.portnum == PortNum_UNKNOWN_APP) {
DEBUG_MSG("Invalid portnum (bad psk?)!\n");
}
else {
// parsing was successful // parsing was successful
p->which_payloadVariant = MeshPacket_decoded_tag; // change type to decoded
p->channel = chIndex; // change to store the index instead of the hash p->channel = chIndex; // change to store the index instead of the hash
// printPacket("decoded message", p); printPacket("decoded message", p);
p->which_payloadVariant = MeshPacket_decoded_tag;
return true; return true;
} }
} }
@@ -264,10 +286,9 @@ void Router::handleReceived(MeshPacket *p)
// 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
bool decoded = perhapsDecode(p); bool decoded = perhapsDecode(p);
printPacket("handleReceived", p);
DEBUG_MSG("decoded=%d\n", decoded);
if (decoded) { if (decoded) {
// parsing was successful, queue for our recipient // parsing was successful, queue for our recipient
printPacket("handleReceived", 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);

View File

@@ -63,6 +63,11 @@ class Router : protected concurrency::OSThread
* @return our local nodenum */ * @return our local nodenum */
NodeNum getNodeNum(); NodeNum getNodeNum();
/** Wake up the router thread ASAP, because we just queued a message for it.
* FIXME, this is kinda a hack because we don't have a nice way yet to say 'wake us because we are 'blocked on this queue'
*/
void setReceivedMessage();
protected: protected:
friend class RoutingPlugin; friend class RoutingPlugin;

View File

@@ -19,7 +19,8 @@ typedef enum _RegionCode {
RegionCode_JP = 5, RegionCode_JP = 5,
RegionCode_ANZ = 6, RegionCode_ANZ = 6,
RegionCode_KR = 7, RegionCode_KR = 7,
RegionCode_TW = 8 RegionCode_TW = 8,
RegionCode_RU = 9
} RegionCode; } RegionCode;
typedef enum _ChargeCurrent { typedef enum _ChargeCurrent {
@@ -123,8 +124,8 @@ typedef struct _RadioConfig {
/* Helper constants for enums */ /* Helper constants for enums */
#define _RegionCode_MIN RegionCode_Unset #define _RegionCode_MIN RegionCode_Unset
#define _RegionCode_MAX RegionCode_TW #define _RegionCode_MAX RegionCode_RU
#define _RegionCode_ARRAYSIZE ((RegionCode)(RegionCode_TW+1)) #define _RegionCode_ARRAYSIZE ((RegionCode)(RegionCode_RU+1))
#define _ChargeCurrent_MIN ChargeCurrent_MAUnset #define _ChargeCurrent_MIN ChargeCurrent_MAUnset
#define _ChargeCurrent_MAX ChargeCurrent_MA1320 #define _ChargeCurrent_MAX ChargeCurrent_MA1320

View File

@@ -18,8 +18,8 @@ size_t pb_encode_to_bytes(uint8_t *destbuf, size_t destbufsize, const pb_msgdesc
pb_ostream_t stream = pb_ostream_from_buffer(destbuf, destbufsize); pb_ostream_t stream = pb_ostream_from_buffer(destbuf, destbufsize);
if (!pb_encode(&stream, fields, src_struct)) { if (!pb_encode(&stream, fields, src_struct)) {
DEBUG_MSG("Error: can't encode protobuf %s\n", PB_GET_ERROR(&stream)); DEBUG_MSG("Panic: can't encode protobuf %s, did you make a field too large?\n", PB_GET_ERROR(&stream));
assert(0); // FIXME - panic assert(0); // If this asser fails it probably means you made a field too large for the max limits specified in mesh.options
} else { } else {
return stream.bytes_written; return stream.bytes_written;
} }

View File

@@ -24,6 +24,12 @@ void AdminPlugin::handleGetRadio(const MeshPacket &req)
// We create the reply here // We create the reply here
AdminMessage r = AdminMessage_init_default; AdminMessage r = AdminMessage_init_default;
r.get_radio_response = devicestate.radio; r.get_radio_response = devicestate.radio;
// NOTE: The phone app needs to know the ls_secs value so it can properly expect sleep behavior.
// So even if we internally use 0 to represent 'use default' we still need to send the value we are
// using to the app (so that even old phone apps work with new device loads).
r.get_radio_response.preferences.ls_secs = getPref_ls_secs();
r.which_variant = AdminMessage_get_radio_response_tag; r.which_variant = AdminMessage_get_radio_response_tag;
reply = allocDataProtobuf(r); reply = allocDataProtobuf(r);
} }

View File

@@ -65,8 +65,7 @@ int32_t NodeInfoPlugin::runOnce()
currentGeneration = radioGeneration; currentGeneration = radioGeneration;
DEBUG_MSG("Sending our nodeinfo to mesh (wantReplies=%d)\n", requestReplies); DEBUG_MSG("Sending our nodeinfo to mesh (wantReplies=%d)\n", requestReplies);
assert(nodeInfoPlugin); sendOurNodeInfo(NODENUM_BROADCAST, requestReplies); // Send our info (don't request replies)
nodeInfoPlugin->sendOurNodeInfo(NODENUM_BROADCAST, requestReplies); // Send our info (don't request replies)
return getPref_position_broadcast_secs() * 1000; return getPref_position_broadcast_secs() * 1000;
} }

View File

@@ -8,7 +8,7 @@ TextMessagePlugin *textMessagePlugin;
bool TextMessagePlugin::handleReceived(const MeshPacket &mp) bool TextMessagePlugin::handleReceived(const MeshPacket &mp)
{ {
auto &p = mp.decoded; 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=0x%x, 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.
// Keep a copy of the most recent text message. // Keep a copy of the most recent text message.

View File

@@ -1,4 +1,4 @@
[VERSION] [VERSION]
major = 1 major = 1
minor = 2 minor = 2
build = 4 build = 6