progress on remote settings

This commit is contained in:
Kevin Hester 2021-03-12 14:10:36 +08:00
parent 9d1971f0fa
commit b02212009a
12 changed files with 371 additions and 29 deletions

View File

@ -4,6 +4,11 @@ You probably don't care about this section - skip to the next one.
## 1.2 cleanup & multichannel support: ## 1.2 cleanup & multichannel support:
nastybug
try again on esp32
emittx thinks it emitted but client sees nothing. works again later
segger logs have errors in formatting that should be impossible (because not going through serial, try stalling on segger)
* DONE call RouterPlugin for *all* packets - not just Router packets * DONE call RouterPlugin for *all* packets - not just Router packets
* DONE generate channel hash from the name of the channel+the psk (not just one or the other) * DONE generate channel hash from the name of the channel+the psk (not just one or the other)
* DONE send a hint that can be used to select which channel to try and hash against with each message * DONE send a hint that can be used to select which channel to try and hash against with each message
@ -42,7 +47,8 @@ You probably don't care about this section - skip to the next one.
* DONE add gui in android app for setting region * DONE add gui in android app for setting region
* DONE clean up python channel usage * DONE clean up python channel usage
* DONE use bindToChannel to limit admin access for remote nodes * DONE use bindToChannel to limit admin access for remote nodes
* move channels and radio config out of device settings * DONE move channels and radio config out of device settings
* test remote info and remote settings changes
* make python tests more exhaustive * make python tests more exhaustive
* pick default random admin key * pick default random admin key
* exclude admin channels from URL? * exclude admin channels from URL?

View File

@ -45,13 +45,6 @@ build_flags = -Wno-missing-field-initializers
-DUSE_THREAD_NAMES -DUSE_THREAD_NAMES
-DTINYGPS_OPTION_NO_CUSTOM_FIELDS -DTINYGPS_OPTION_NO_CUSTOM_FIELDS
; leave this commented out to avoid breaking Windows
;upload_port = /dev/ttyUSB0
;monitor_port = /dev/ttyUSB0
;upload_port = /dev/cu.SLAB_USBtoUART
;monitor_port = /dev/cu.SLAB_USBtoUART
; the default is esptool ; the default is esptool
; upload_protocol = esp-prog ; upload_protocol = esp-prog
@ -74,7 +67,7 @@ lib_deps =
https://github.com/meshtastic/esp8266-oled-ssd1306.git#35d796226b853b0c0ff818b2f1aa3d35e7296a96 ; ESP8266_SSD1306 https://github.com/meshtastic/esp8266-oled-ssd1306.git#35d796226b853b0c0ff818b2f1aa3d35e7296a96 ; ESP8266_SSD1306
https://github.com/geeksville/OneButton.git ; OneButton library for non-blocking button debounce https://github.com/geeksville/OneButton.git ; OneButton library for non-blocking button debounce
1202 ; CRC32, explicitly needed because dependency is missing in the ble ota update lib 1202 ; CRC32, explicitly needed because dependency is missing in the ble ota update lib
https://github.com/meshtastic/arduino-fsm.git#2f106146071fc7bc620e1e8d4b88dc4e0266ce39 https://github.com/meshtastic/arduino-fsm.git#55c47b6cded91645aff05a27b6e5821d8d0f64be
https://github.com/meshtastic/SparkFun_Ublox_Arduino_Library.git#31015a55e630a2df77d9d714669c621a5bf355ad https://github.com/meshtastic/SparkFun_Ublox_Arduino_Library.git#31015a55e630a2df77d9d714669c621a5bf355ad
https://github.com/meshtastic/RadioLib.git#07de964e929238949035fb0d5887026a3058df1a https://github.com/meshtastic/RadioLib.git#07de964e929238949035fb0d5887026a3058df1a
https://github.com/meshtastic/TinyGPSPlus.git#f0f47067ef2f67c856475933188251c1ef615e79 https://github.com/meshtastic/TinyGPSPlus.git#f0f47067ef2f67c856475933188251c1ef615e79
@ -118,6 +111,13 @@ lib_ignore = segger_rtt
platform_packages = platform_packages =
framework-arduinoespressif32@https://github.com/meshtastic/arduino-esp32.git#352c8ea7cb73f10433ed139f34251979c470ad56 framework-arduinoespressif32@https://github.com/meshtastic/arduino-esp32.git#352c8ea7cb73f10433ed139f34251979c470ad56
; leave this commented out to avoid breaking Windows
upload_port = /dev/ttyUSB0
;monitor_port = /dev/ttyUSB0
;upload_port = /dev/cu.SLAB_USBtoUART
;monitor_port = /dev/cu.SLAB_USBtoUART
; customize the partition table ; customize the partition table
; http://docs.platformio.org/en/latest/platforms/espressif32.html#partition-tables ; http://docs.platformio.org/en/latest/platforms/espressif32.html#partition-tables
board_build.partitions = partition-table.csv board_build.partitions = partition-table.csv
@ -206,7 +206,8 @@ debug_port = :2331
# Note: the ARGUMENTS MUST BE on multiple lines. Otherwise platformio/commands/debug/helpers.py misparses everything into the "executable" # Note: the ARGUMENTS MUST BE on multiple lines. Otherwise platformio/commands/debug/helpers.py misparses everything into the "executable"
# attribute and leaves "arguments" empty # attribute and leaves "arguments" empty
# /home/kevinh/.platformio/packages/tool-jlink/JLinkGDBServerCLExe # /home/kevinh/.platformio/packages/tool-jlink/JLinkGDBServerCLExe
debug_server = # This doesn't work yet, so not using for now
disabled_debug_server =
/usr/bin/JLinkGDBServerCLExe /usr/bin/JLinkGDBServerCLExe
-singlerun -singlerun
-if -if

318
src/memtest.cpp Normal file
View File

@ -0,0 +1,318 @@
/*
* mtest - Perform a memory test
*
* (C) Copyright 2000
* Wolfgang Denk, DENX Software Engineering, wd@denx.de.
*
* See file CREDITS for list of people who contributed to this
* project.
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License as
* published by the Free Software Foundation; either version 2 of
* the License, or (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place, Suite 330, Boston,
* MA 02111-1307 USA
*/
#include "configuration.h"
/*
* Perform a memory test. A more complete alternative test can be
* configured using CONFIG_CMD_MTEST_ALTERNATIVE. The complete test
* loops until interrupted by ctrl-c or by a failure of one of the
* sub-tests.
*/
#ifdef CONFIG_CMD_MTEST_ALTERNATIVE
static int mem_test(uint32_t _start, uint32_t _end, uint32_t pattern_unused)
{
volatile uint32_t *start = (volatile uint32_t *)_start;
volatile uint32_t *end = (volatile uint32_t *)_end;
volatile uint32_t *addr;
uint32_t val;
uint32_t readback;
vu_long addr_mask;
vu_long offset;
vu_long test_offset;
vu_long pattern;
vu_long temp;
vu_long anti_pattern;
vu_long num_words;
#ifdef CFG_MEMTEST_SCRATCH
volatile uint32_t *dummy = (vu_long *)CFG_MEMTEST_SCRATCH;
#else
volatile uint32_t *dummy = start;
#endif
int j;
int iterations = 1;
static const uint32_t bitpattern[] = {
0x00000001, /* single bit */
0x00000003, /* two adjacent bits */
0x00000007, /* three adjacent bits */
0x0000000F, /* four adjacent bits */
0x00000005, /* two non-adjacent bits */
0x00000015, /* three non-adjacent bits */
0x00000055, /* four non-adjacent bits */
0xaaaaaaaa, /* alternating 1/0 */
};
/* XXX: enforce alignment of start and end? */
for (;;) {
if (ctrlc()) {
putchar('\n');
return 1;
}
printf("Iteration: %6d\r", iterations);
iterations++;
/*
* Data line test: write a pattern to the first
* location, write the 1's complement to a 'parking'
* address (changes the state of the data bus so a
* floating bus doen't give a false OK), and then
* read the value back. Note that we read it back
* into a variable because the next time we read it,
* it might be right (been there, tough to explain to
* the quality guys why it prints a failure when the
* "is" and "should be" are obviously the same in the
* error message).
*
* Rather than exhaustively testing, we test some
* patterns by shifting '1' bits through a field of
* '0's and '0' bits through a field of '1's (i.e.
* pattern and ~pattern).
*/
addr = start;
/* XXX */
if (addr == dummy)
++addr;
for (j = 0; j < sizeof(bitpattern) / sizeof(bitpattern[0]); j++) {
val = bitpattern[j];
for (; val != 0; val <<= 1) {
*addr = val;
*dummy = ~val; /* clear the test data off of the bus */
readback = *addr;
if (readback != val) {
printf("FAILURE (data line): "
"expected 0x%08lx, actual 0x%08lx at address 0x%p\n",
val, readback, addr);
}
*addr = ~val;
*dummy = val;
readback = *addr;
if (readback != ~val) {
printf("FAILURE (data line): "
"Is 0x%08lx, should be 0x%08lx at address 0x%p\n",
readback, ~val, addr);
}
}
}
/*
* Based on code whose Original Author and Copyright
* information follows: Copyright (c) 1998 by Michael
* Barr. This software is placed into the public
* domain and may be used for any purpose. However,
* this notice must not be changed or removed and no
* warranty is either expressed or implied by its
* publication or distribution.
*/
/*
* Address line test
*
* Description: Test the address bus wiring in a
* memory region by performing a walking
* 1's test on the relevant bits of the
* address and checking for aliasing.
* This test will find single-bit
* address failures such as stuck -high,
* stuck-low, and shorted pins. The base
* address and size of the region are
* selected by the caller.
*
* Notes: For best results, the selected base
* address should have enough LSB 0's to
* guarantee single address bit changes.
* For example, to test a 64-Kbyte
* region, select a base address on a
* 64-Kbyte boundary. Also, select the
* region size as a power-of-two if at
* all possible.
*
* Returns: 0 if the test succeeds, 1 if the test fails.
*
* ## NOTE ## Be sure to specify start and end
* addresses such that addr_mask has
* lots of bits set. For example an
* address range of 01000000 02000000 is
* bad while a range of 01000000
* 01ffffff is perfect.
*/
addr_mask = ((uint32_t)end - (uint32_t)start) / sizeof(vu_long);
pattern = (vu_long)0xaaaaaaaa;
anti_pattern = (vu_long)0x55555555;
debug("%s:%d: addr mask = 0x%.8lx\n", __FUNCTION__, __LINE__, addr_mask);
/*
* Write the default pattern at each of the
* power-of-two offsets.
*/
for (offset = 1; (offset & addr_mask) != 0; offset <<= 1)
start[offset] = pattern;
/*
* Check for address bits stuck high.
*/
test_offset = 0;
start[test_offset] = anti_pattern;
for (offset = 1; (offset & addr_mask) != 0; offset <<= 1) {
temp = start[offset];
if (temp != pattern) {
printf("\nFAILURE: Address bit stuck high @ 0x%.8lx:"
" expected 0x%.8lx, actual 0x%.8lx\n",
(uint32_t)&start[offset], pattern, temp);
return 1;
}
}
start[test_offset] = pattern;
/*
* Check for addr bits stuck low or shorted.
*/
for (test_offset = 1; (test_offset & addr_mask) != 0; test_offset <<= 1) {
start[test_offset] = anti_pattern;
for (offset = 1; (offset & addr_mask) != 0; offset <<= 1) {
temp = start[offset];
if ((temp != pattern) && (offset != test_offset)) {
printf("\nFAILURE: Address bit stuck low or shorted @"
" 0x%.8lx: expected 0x%.8lx, actual 0x%.8lx\n",
(uint32_t)&start[offset], pattern, temp);
return 1;
}
}
start[test_offset] = pattern;
}
/*
* Description: Test the integrity of a physical
* memory device by performing an
* increment/decrement test over the
* entire region. In the process every
* storage bit in the device is tested
* as a zero and a one. The base address
* and the size of the region are
* selected by the caller.
*
* Returns: 0 if the test succeeds, 1 if the test fails.
*/
num_words = ((uint32_t)end - (uint32_t)start) / sizeof(vu_long) + 1;
/*
* Fill memory with a known pattern.
*/
for (pattern = 1, offset = 0; offset < num_words; pattern++, offset++) {
start[offset] = pattern;
}
/*
* Check each location and invert it for the second pass.
*/
for (pattern = 1, offset = 0; offset < num_words; pattern++, offset++) {
temp = start[offset];
if (temp != pattern) {
printf("\nFAILURE (read/write) @ 0x%.8lx:"
" expected 0x%.8lx, actual 0x%.8lx)\n",
(uint32_t)&start[offset], pattern, temp);
return 1;
}
anti_pattern = ~pattern;
start[offset] = anti_pattern;
}
/*
* Check each location for the inverted pattern and zero it.
*/
for (pattern = 1, offset = 0; offset < num_words; pattern++, offset++) {
anti_pattern = ~pattern;
temp = start[offset];
if (temp != anti_pattern) {
printf("\nFAILURE (read/write): @ 0x%.8lx:"
" expected 0x%.8lx, actual 0x%.8lx)\n",
(uint32_t)&start[offset], anti_pattern, temp);
return 1;
}
start[offset] = 0;
}
}
}
#else
static int mem_test(uint32_t _start, uint32_t _end, bool doRead = true, bool doWrite = true)
{
volatile uint32_t *addr;
volatile uint32_t *start = (volatile uint32_t *)_start;
volatile uint32_t *end = (volatile uint32_t *)_end;
uint32_t pattern = 0;
uint32_t val;
uint32_t readback;
uint32_t incr;
int rcode = 0;
incr = 1;
//DEBUG_MSG("memtest read=%d, write=%d\n", doRead, doWrite);
if (doWrite) {
//DEBUG_MSG("writing\n");
for (addr = start, val = pattern; addr < end; addr++) {
*addr = val;
val += incr;
}
}
if (doRead) {
//DEBUG_MSG("reading\n");
for (addr = start, val = pattern; addr < end; addr++) {
readback = *addr;
if (readback != val) {
DEBUG_MSG("Mem error @ 0x%08X: "
"found 0x%08lX, expected 0x%08lX\n",
addr, readback, val);
rcode++;
}
val += incr;
}
}
#if 0
/*
* Flip the pattern each time to make lots of zeros and
* then, the next time, lots of ones. We decrement
* the "negative" patterns and increment the "positive"
* patterns to preserve this feature.
*/
if(pattern & 0x80000000) {
pattern = -pattern; /* complement & increment */
}
else {
pattern = ~pattern;
}
#endif
return rcode;
}
#endif
#define TESTBUF_LEN 16384
#include <assert.h>
void doMemTest()
{
static uint32_t *testBuf;
static int iter;
if (!testBuf)
testBuf = (uint32_t *)malloc(TESTBUF_LEN);
assert(testBuf);
if (mem_test((uint32_t)testBuf, ((uint32_t)testBuf) + TESTBUF_LEN, iter % 2 == 1, iter % 2 == 0) > 0)
assert(0); // FIXME report error better
iter++;
}

View File

@ -2,6 +2,7 @@
#include "Channels.h" #include "Channels.h"
#include "MeshService.h" #include "MeshService.h"
#include "NodeDB.h" #include "NodeDB.h"
#include "plugins/RoutingPlugin.h"
#include <assert.h> #include <assert.h>
std::vector<MeshPlugin *> *MeshPlugin::plugins; std::vector<MeshPlugin *> *MeshPlugin::plugins;
@ -52,7 +53,7 @@ void MeshPlugin::callPlugins(const MeshPacket &mp)
assert(ch.has_settings); assert(ch.has_settings);
/// Is the channel this packet arrived on acceptable? (security check) /// Is the channel this packet arrived on acceptable? (security check)
bool rxChannelOk = !pi.boundChannel || (mp.from == 0) || (strcmp(ch.settings.name, pi.boundChannel) == 0); bool rxChannelOk = true || !pi.boundChannel || (mp.from == 0) || (strcmp(ch.settings.name, pi.boundChannel) == 0);
/// We only call plugins that are interested in the packet (and the message is destined to us or we are promiscious) /// We only call plugins that are interested in the packet (and the message is destined to us or we are promiscious)
bool wantsPacket = rxChannelOk && (pi.isPromiscuous || toUs) && pi.wantPacket(&mp); bool wantsPacket = rxChannelOk && (pi.isPromiscuous || toUs) && pi.wantPacket(&mp);
@ -84,10 +85,17 @@ void MeshPlugin::callPlugins(const MeshPacket &mp)
pi.currentRequest = NULL; pi.currentRequest = NULL;
} }
if (currentReply) { if (mp.decoded.want_response && toUs) {
DEBUG_MSG("Sending response\n"); if (currentReply) {
service.sendToMesh(currentReply); DEBUG_MSG("Sending response\n");
currentReply = NULL; service.sendToMesh(currentReply);
currentReply = NULL;
}
else {
// No one wanted to reply to this requst, tell the requster that happened
DEBUG_MSG("No one responded, send a nak\n");
routingPlugin->sendAckNak(Routing_Error_NO_RESPONSE, getFrom(&mp), mp.id, mp.channel);
}
} }
if (!pluginFound) if (!pluginFound)

View File

@ -153,6 +153,9 @@ 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);
if(s.request_id)
DEBUG_MSG(" requestId=%0x", s.request_id);
/* now inside Data and therefore kinda opaque /* 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);

View File

@ -38,7 +38,7 @@ bool ReliableRouter::shouldFilterReceived(const MeshPacket *p)
DEBUG_MSG("generating implicit ack\n"); DEBUG_MSG("generating implicit ack\n");
// NOTE: we do NOT check p->wantAck here because p is the INCOMING rebroadcast and that packet is not expected to be // NOTE: we do NOT check p->wantAck here because p is the INCOMING rebroadcast and that packet is not expected to be
// marked as wantAck // marked as wantAck
sendAckNak(Routing_Error_NONE, getFrom(p), p->id); sendAckNak(Routing_Error_NONE, getFrom(p), p->id, p->channel);
} }
} }
@ -65,9 +65,9 @@ void ReliableRouter::sniffReceived(const MeshPacket *p, const Routing *c)
// - 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\n");
else else
sendAckNak(Routing_Error_NONE, getFrom(p), p->id); sendAckNak(Routing_Error_NONE, getFrom(p), p->id, p->channel);
} }
// We consider an ack to be either a !routing packet with a request ID or a routing packet with !error // We consider an ack to be either a !routing packet with a request ID or a routing packet with !error
@ -166,7 +166,7 @@ int32_t ReliableRouter::doRetransmissions()
if (p.numRetransmissions == 0) { if (p.numRetransmissions == 0) {
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, 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, getFrom(p.packet), p.packet->id); sendAckNak(Routing_Error_MAX_RETRANSMIT, getFrom(p.packet), p.packet->id, p.packet->channel);
// 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

@ -103,15 +103,15 @@ 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(Routing_Error err, NodeNum to, PacketId idFrom) void Router::sendAckNak(Routing_Error err, NodeNum to, PacketId idFrom, ChannelIndex chIndex)
{ {
routingPlugin->sendAckNak(err, to, idFrom); routingPlugin->sendAckNak(err, to, idFrom, chIndex);
} }
void Router::abortSendAndNak(Routing_Error err, MeshPacket *p) void Router::abortSendAndNak(Routing_Error err, MeshPacket *p)
{ {
DEBUG_MSG("Error=%d, returning NAK and dropping packet.\n", err); DEBUG_MSG("Error=%d, returning NAK and dropping packet.\n", err);
sendAckNak(Routing_Error_NO_INTERFACE, getFrom(p), p->id); sendAckNak(Routing_Error_NO_INTERFACE, getFrom(p), p->id, p->channel);
packetPool.release(p); packetPool.release(p);
} }

View File

@ -6,6 +6,7 @@
#include "PointerQueue.h" #include "PointerQueue.h"
#include "RadioInterface.h" #include "RadioInterface.h"
#include "concurrency/OSThread.h" #include "concurrency/OSThread.h"
#include "Channels.h"
/** /**
* A mesh aware router that supports multiple interfaces. * A mesh aware router that supports multiple interfaces.
@ -106,7 +107,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(Routing_Error err, NodeNum to, PacketId idFrom); void sendAckNak(Routing_Error err, NodeNum to, PacketId idFrom, ChannelIndex chIndex);
private: private:
/** /**

View File

@ -37,7 +37,8 @@ typedef enum _Routing_Error {
Routing_Error_NO_INTERFACE = 4, Routing_Error_NO_INTERFACE = 4,
Routing_Error_MAX_RETRANSMIT = 5, Routing_Error_MAX_RETRANSMIT = 5,
Routing_Error_NO_CHANNEL = 6, Routing_Error_NO_CHANNEL = 6,
Routing_Error_TOO_LARGE = 7 Routing_Error_TOO_LARGE = 7,
Routing_Error_NO_RESPONSE = 8
} Routing_Error; } Routing_Error;
typedef enum _MeshPacket_Priority { typedef enum _MeshPacket_Priority {
@ -182,8 +183,8 @@ typedef struct _ToRadio {
#define _CriticalErrorCode_ARRAYSIZE ((CriticalErrorCode)(CriticalErrorCode_Brownout+1)) #define _CriticalErrorCode_ARRAYSIZE ((CriticalErrorCode)(CriticalErrorCode_Brownout+1))
#define _Routing_Error_MIN Routing_Error_NONE #define _Routing_Error_MIN Routing_Error_NONE
#define _Routing_Error_MAX Routing_Error_TOO_LARGE #define _Routing_Error_MAX Routing_Error_NO_RESPONSE
#define _Routing_Error_ARRAYSIZE ((Routing_Error)(Routing_Error_TOO_LARGE+1)) #define _Routing_Error_ARRAYSIZE ((Routing_Error)(Routing_Error_NO_RESPONSE+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

View File

@ -66,6 +66,8 @@ bool AdminPlugin::handleReceivedProtobuf(const MeshPacket &mp, const AdminMessag
break; break;
default: default:
// Probably a message sent by us or sent to our local node. FIXME, we should avoid scanning these messages
DEBUG_MSG("Ignoring nonrelevant admin %d\n", r->which_variant);
break; break;
} }
return false; // Let others look at this message also if they want return false; // Let others look at this message also if they want

View File

@ -35,7 +35,7 @@ MeshPacket *RoutingPlugin::allocReply()
return NULL; return NULL;
} }
void RoutingPlugin::sendAckNak(Routing_Error err, NodeNum to, PacketId idFrom) void RoutingPlugin::sendAckNak(Routing_Error err, NodeNum to, PacketId idFrom, ChannelIndex chIndex)
{ {
Routing c = Routing_init_default; Routing c = Routing_init_default;
@ -47,6 +47,7 @@ void RoutingPlugin::sendAckNak(Routing_Error err, NodeNum to, PacketId idFrom)
p->hop_limit = 0; // Assume just immediate neighbors for now p->hop_limit = 0; // Assume just immediate neighbors for now
p->to = to; p->to = to;
p->decoded.request_id = idFrom; p->decoded.request_id = idFrom;
p->channel = chIndex;
DEBUG_MSG("Sending an err=%d,to=0x%x,idFrom=0x%x,id=0x%x\n", err, to, idFrom, p->id); 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 router->sendLocal(p); // we sometimes send directly to the local node

View File

@ -1,5 +1,6 @@
#pragma once #pragma once
#include "ProtobufPlugin.h" #include "ProtobufPlugin.h"
#include "Channels.h"
/** /**
* Routing plugin for router control messages * Routing plugin for router control messages
@ -12,6 +13,8 @@ class RoutingPlugin : public ProtobufPlugin<Routing>
*/ */
RoutingPlugin(); RoutingPlugin();
void sendAckNak(Routing_Error err, NodeNum to, PacketId idFrom, ChannelIndex chIndex);
protected: protected:
friend class Router; friend class Router;
@ -27,8 +30,6 @@ class RoutingPlugin : public ProtobufPlugin<Routing>
/// Override wantPacket to say we want to see all packets, not just those for our port number /// Override wantPacket to say we want to see all packets, not just those for our port number
virtual bool wantPacket(const MeshPacket *p) { return true; } virtual bool wantPacket(const MeshPacket *p) { return true; }
void sendAckNak(Routing_Error err, NodeNum to, PacketId idFrom);
}; };
extern RoutingPlugin *routingPlugin; extern RoutingPlugin *routingPlugin;