mirror of
https://github.com/meshtastic/firmware.git
synced 2025-12-30 14:40:40 +00:00
Merge branch 'master' into master
This commit is contained in:
@@ -97,7 +97,8 @@ static void lsIdle()
|
||||
static void lsExit()
|
||||
{
|
||||
// setGPSPower(true); // restore GPS power
|
||||
if (gps) gps->forceWake(true);
|
||||
if (gps)
|
||||
gps->forceWake(true);
|
||||
}
|
||||
|
||||
static void nbEnter()
|
||||
@@ -172,7 +173,7 @@ Fsm powerFSM(&stateBOOT);
|
||||
void PowerFSM_setup()
|
||||
{
|
||||
bool isRouter = radioConfig.preferences.is_router;
|
||||
|
||||
|
||||
// If we are not a router and we already have AC power go to POWER state after init, otherwise go to ON
|
||||
// We assume routers might be powered all the time, but from a low current (solar) source
|
||||
bool isLowPower = radioConfig.preferences.is_low_power || isRouter;
|
||||
@@ -180,7 +181,7 @@ void PowerFSM_setup()
|
||||
/* 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. (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 = !isLowPower && powerStatus && (!powerStatus->getHasBattery() || powerStatus->getHasUSB());
|
||||
|
||||
@@ -249,6 +250,11 @@ void PowerFSM_setup()
|
||||
|
||||
powerFSM.add_transition(&stateDARK, &stateDARK, EVENT_CONTACT_FROM_PHONE, NULL, "Contact from phone");
|
||||
|
||||
// each time we get a new update packet make sure we are staying in the ON state so the screen stays awake (also we don't
|
||||
// shutdown bluetooth if is_router)
|
||||
powerFSM.add_transition(&stateDARK, &stateON, EVENT_FIRMWARE_UPDATE, NULL, "Got firmware update");
|
||||
powerFSM.add_transition(&stateON, &stateON, EVENT_FIRMWARE_UPDATE, NULL, "Got firmware update");
|
||||
|
||||
powerFSM.add_transition(&stateNB, &stateDARK, EVENT_PACKET_FOR_PHONE, NULL, "Packet for phone");
|
||||
|
||||
powerFSM.add_timed_transition(&stateON, &stateDARK, getPref_screen_on_secs() * 1000, NULL, "Screen-on timeout");
|
||||
|
||||
@@ -18,6 +18,7 @@
|
||||
#define EVENT_SERIAL_DISCONNECTED 12
|
||||
#define EVENT_POWER_CONNECTED 13
|
||||
#define EVENT_POWER_DISCONNECTED 14
|
||||
#define EVENT_FIRMWARE_UPDATE 15 // We just received a new firmware update packet from the phone
|
||||
|
||||
extern Fsm powerFSM;
|
||||
extern State statePOWER, stateSERIAL;
|
||||
|
||||
@@ -1,14 +1,14 @@
|
||||
#include <Arduino.h>
|
||||
|
||||
#include "../concurrency/LockGuard.h"
|
||||
#include "../graphics/Screen.h"
|
||||
#include "../main.h"
|
||||
#include "BluetoothSoftwareUpdate.h"
|
||||
#include "NodeDB.h"
|
||||
#include "PowerFSM.h"
|
||||
#include "RadioLibInterface.h"
|
||||
#include "configuration.h"
|
||||
#include "nimble/BluetoothUtil.h"
|
||||
#include "NodeDB.h"
|
||||
#include "../graphics/Screen.h"
|
||||
#include "../main.h"
|
||||
|
||||
#include <CRC32.h>
|
||||
#include <Update.h>
|
||||
@@ -51,8 +51,8 @@ int update_size_callback(uint16_t conn_handle, uint16_t attr_handle, struct ble_
|
||||
|
||||
screen->startFirmwareUpdateScreen();
|
||||
if (RadioLibInterface::instance)
|
||||
RadioLibInterface::instance->disable(); // FIXME, nasty hack - the RF95 ISR/SPI code on ESP32 can fail while we are
|
||||
// writing flash - shut the radio off during updates
|
||||
RadioLibInterface::instance->disable(); // FIXME, nasty hack - the RF95 ISR/SPI code on ESP32 can fail while we
|
||||
// are writing flash - shut the radio off during updates
|
||||
}
|
||||
}
|
||||
|
||||
@@ -78,7 +78,7 @@ int update_data_callback(uint16_t conn_handle, uint16_t attr_handle, struct ble_
|
||||
crc.update(data, len);
|
||||
Update.write(data, len);
|
||||
updateActualSize += len;
|
||||
powerFSM.trigger(EVENT_CONTACT_FROM_PHONE);
|
||||
powerFSM.trigger(EVENT_FIRMWARE_UPDATE);
|
||||
|
||||
return 0;
|
||||
}
|
||||
@@ -107,8 +107,7 @@ int update_crc32_callback(uint16_t conn_handle, uint16_t attr_handle, struct ble
|
||||
if (update_region == U_SPIFFS) {
|
||||
DEBUG_MSG("SPIFFS updated!\n");
|
||||
nodeDB.saveToDisk(); // Since we just wiped spiffs, we need to save our current state
|
||||
}
|
||||
else {
|
||||
} else {
|
||||
DEBUG_MSG("Appload updated, rebooting in 5 seconds!\n");
|
||||
rebootAtMsec = millis() + 5000;
|
||||
}
|
||||
|
||||
@@ -33,7 +33,7 @@ int16_t Channels::generateHash(ChannelIndex channelNum)
|
||||
return -1; // invalid
|
||||
else {
|
||||
const char *name = getName(channelNum);
|
||||
uint8_t h = xorHash((const uint8_t *) name, strlen(name));
|
||||
uint8_t h = xorHash((const uint8_t *)name, strlen(name));
|
||||
|
||||
h ^= xorHash(k.bytes, k.length);
|
||||
|
||||
@@ -184,7 +184,7 @@ void Channels::onConfigChanged()
|
||||
|
||||
Channel &Channels::getByIndex(ChannelIndex chIndex)
|
||||
{
|
||||
assert(chIndex < channelFile.channels_count);
|
||||
assert(chIndex < channelFile.channels_count); // This should be equal to MAX_NUM_CHANNELS
|
||||
Channel *ch = channelFile.channels + chIndex;
|
||||
return *ch;
|
||||
}
|
||||
@@ -278,11 +278,11 @@ const char *Channels::getPrimaryName()
|
||||
*/
|
||||
bool Channels::decryptForHash(ChannelIndex chIndex, ChannelHash channelHash)
|
||||
{
|
||||
if(chIndex > getNumChannels() || getHash(chIndex) != channelHash) {
|
||||
// DEBUG_MSG("Skipping channel %d (hash %x) due to invalid hash/index, want=%x\n", chIndex, getHash(chIndex), channelHash);
|
||||
if (chIndex > getNumChannels() || getHash(chIndex) != channelHash) {
|
||||
// DEBUG_MSG("Skipping channel %d (hash %x) due to invalid hash/index, want=%x\n", chIndex, getHash(chIndex),
|
||||
// channelHash);
|
||||
return false;
|
||||
}
|
||||
else {
|
||||
} else {
|
||||
DEBUG_MSG("Using channel %d (hash 0x%x)\n", chIndex, channelHash);
|
||||
setCrypto(chIndex);
|
||||
return true;
|
||||
|
||||
@@ -31,6 +31,39 @@ MeshPlugin::~MeshPlugin()
|
||||
assert(0); // FIXME - remove from list of plugins once someone needs this feature
|
||||
}
|
||||
|
||||
MeshPacket *MeshPlugin::allocAckNak(Routing_Error err, NodeNum to, PacketId idFrom, ChannelIndex chIndex)
|
||||
{
|
||||
Routing c = Routing_init_default;
|
||||
|
||||
c.error_reason = err;
|
||||
|
||||
// Now that we have moded sendAckNak up one level into the class heirarchy we can no longer assume we are a RoutingPlugin
|
||||
// So we manually call pb_encode_to_bytes and specify routing port number
|
||||
// auto p = allocDataProtobuf(c);
|
||||
MeshPacket *p = router->allocForSending();
|
||||
p->decoded.portnum = PortNum_ROUTING_APP;
|
||||
p->decoded.payload.size = pb_encode_to_bytes(p->decoded.payload.bytes, sizeof(p->decoded.payload.bytes), Routing_fields, &c);
|
||||
|
||||
p->priority = MeshPacket_Priority_ACK;
|
||||
|
||||
p->hop_limit = 0; // Assume just immediate neighbors for now
|
||||
p->to = to;
|
||||
p->decoded.request_id = idFrom;
|
||||
p->channel = chIndex;
|
||||
DEBUG_MSG("Alloc an err=%d,to=0x%x,idFrom=0x%x,id=0x%x\n", err, to, idFrom, p->id);
|
||||
|
||||
return p;
|
||||
}
|
||||
|
||||
MeshPacket *MeshPlugin::allocErrorResponse(Routing_Error err, const MeshPacket *p)
|
||||
{
|
||||
auto r = allocAckNak(err, getFrom(p), p->id, p->channel);
|
||||
|
||||
setReplyTo(r, *p);
|
||||
|
||||
return r;
|
||||
}
|
||||
|
||||
void MeshPlugin::callPlugins(const MeshPacket &mp)
|
||||
{
|
||||
// DEBUG_MSG("In call plugins\n");
|
||||
@@ -52,33 +85,47 @@ void MeshPlugin::callPlugins(const MeshPacket &mp)
|
||||
auto ch = channels.getByIndex(mp.channel);
|
||||
assert(ch.has_settings);
|
||||
|
||||
/// Is the channel this packet arrived on acceptable? (security check)
|
||||
bool rxChannelOk = !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)
|
||||
bool wantsPacket = rxChannelOk && (pi.isPromiscuous || toUs) && pi.wantPacket(&mp);
|
||||
// DEBUG_MSG("Plugin %s wantsPacket=%d\n", pi.name, wantsPacket);
|
||||
bool wantsPacket = (pi.isPromiscuous || toUs) && pi.wantPacket(&mp);
|
||||
|
||||
if (wantsPacket) {
|
||||
// DEBUG_MSG("Plugin %s wantsPacket=%d\n", pi.name, wantsPacket);
|
||||
pluginFound = true;
|
||||
|
||||
bool handled = pi.handleReceived(mp);
|
||||
/// Is the channel this packet arrived on acceptable? (security check)
|
||||
bool rxChannelOk = !pi.boundChannel || (mp.from == 0) || (strcmp(ch.settings.name, pi.boundChannel) == 0);
|
||||
|
||||
// Possibly send replies (but only if the message was directed to us specifically, i.e. not for promiscious sniffing)
|
||||
// also: we only let the one plugin send a reply, once that happens, remaining plugins are not considered
|
||||
if (!rxChannelOk) {
|
||||
// no one should have already replied!
|
||||
assert(!currentReply);
|
||||
|
||||
// NOTE: we send a reply *even if the (non broadcast) request was from us* which is unfortunate but necessary because
|
||||
// currently when the phone sends things, it sends things using the local node ID as the from address. A better
|
||||
// solution (FIXME) would be to let phones have their own distinct addresses and we 'route' to them like any other
|
||||
// node.
|
||||
if (mp.decoded.want_response && toUs && (getFrom(&mp) != ourNodeNum || mp.to == ourNodeNum) && !currentReply) {
|
||||
pi.sendResponse(mp);
|
||||
DEBUG_MSG("Plugin %s sent a response\n", pi.name);
|
||||
if (mp.decoded.want_response) {
|
||||
DEBUG_MSG("packet on wrong channel, returning error\n");
|
||||
currentReply = pi.allocErrorResponse(Routing_Error_NOT_AUTHORIZED, &mp);
|
||||
} else
|
||||
DEBUG_MSG("packet on wrong channel, but client didn't want response\n");
|
||||
} else {
|
||||
DEBUG_MSG("Plugin %s considered\n", pi.name);
|
||||
}
|
||||
if (handled) {
|
||||
DEBUG_MSG("Plugin %s handled and skipped other processing\n", pi.name);
|
||||
break;
|
||||
|
||||
bool handled = pi.handleReceived(mp);
|
||||
|
||||
// Possibly send replies (but only if the message was directed to us specifically, i.e. not for promiscious
|
||||
// sniffing) also: we only let the one plugin send a reply, once that happens, remaining plugins are not
|
||||
// considered
|
||||
|
||||
// NOTE: we send a reply *even if the (non broadcast) request was from us* which is unfortunate but necessary
|
||||
// because currently when the phone sends things, it sends things using the local node ID as the from address. A
|
||||
// better solution (FIXME) would be to let phones have their own distinct addresses and we 'route' to them like
|
||||
// any other node.
|
||||
if (mp.decoded.want_response && toUs && (getFrom(&mp) != ourNodeNum || mp.to == ourNodeNum) && !currentReply) {
|
||||
pi.sendResponse(mp);
|
||||
DEBUG_MSG("Plugin %s sent a response\n", pi.name);
|
||||
} else {
|
||||
DEBUG_MSG("Plugin %s considered\n", pi.name);
|
||||
}
|
||||
if (handled) {
|
||||
DEBUG_MSG("Plugin %s handled and skipped other processing\n", pi.name);
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -90,8 +137,7 @@ void MeshPlugin::callPlugins(const MeshPacket &mp)
|
||||
DEBUG_MSG("Sending response\n");
|
||||
service.sendToMesh(currentReply);
|
||||
currentReply = NULL;
|
||||
}
|
||||
else {
|
||||
} 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);
|
||||
|
||||
@@ -1,5 +1,6 @@
|
||||
#pragma once
|
||||
|
||||
#include "mesh/Channels.h"
|
||||
#include "mesh/MeshTypes.h"
|
||||
#include <vector>
|
||||
|
||||
@@ -90,6 +91,11 @@ class MeshPlugin
|
||||
*/
|
||||
virtual bool wantUIFrame() { return false; }
|
||||
|
||||
MeshPacket *allocAckNak(Routing_Error err, NodeNum to, PacketId idFrom, ChannelIndex chIndex);
|
||||
|
||||
/// Send an error response for the specified packet.
|
||||
MeshPacket *allocErrorResponse(Routing_Error err, const MeshPacket *p);
|
||||
|
||||
private:
|
||||
/**
|
||||
* If any of the current chain of plugins has already sent a reply, it will be here. This is useful to allow
|
||||
|
||||
@@ -83,16 +83,17 @@ bool NodeDB::resetRadioConfig()
|
||||
|
||||
radioGeneration++;
|
||||
|
||||
radioConfig.has_preferences = true;
|
||||
if (radioConfig.preferences.factory_reset) {
|
||||
DEBUG_MSG("Performing factory reset!\n");
|
||||
installDefaultDeviceState();
|
||||
didFactoryReset = true;
|
||||
} else if (channelFile.channels_count == 0) {
|
||||
}
|
||||
|
||||
if (channelFile.channels_count != MAX_NUM_CHANNELS) {
|
||||
DEBUG_MSG("Setting default channel and radio preferences!\n");
|
||||
|
||||
channels.initDefaults();
|
||||
|
||||
radioConfig.has_preferences = true;
|
||||
}
|
||||
|
||||
channels.onConfigChanged();
|
||||
@@ -451,6 +452,8 @@ void NodeDB::updatePosition(uint32_t nodeId, const Position &p)
|
||||
info->position.latitude_i = p.latitude_i;
|
||||
info->position.longitude_i = p.longitude_i;
|
||||
}
|
||||
if (p.altitude)
|
||||
info->position.altitude = p.altitude;
|
||||
info->has_position = true;
|
||||
updateGUIforNode = info;
|
||||
notifyObservers(true); // Force an update whether or not our node counts have changed
|
||||
@@ -486,8 +489,7 @@ void NodeDB::updateUser(uint32_t nodeId, const User &p)
|
||||
/// we updateGUI and updateGUIforNode if we think our this change is big enough for a redraw
|
||||
void NodeDB::updateFrom(const MeshPacket &mp)
|
||||
{
|
||||
|
||||
if (mp.which_payloadVariant == MeshPacket_decoded_tag) {
|
||||
if (mp.which_payloadVariant == MeshPacket_decoded_tag && mp.from) {
|
||||
DEBUG_MSG("Update DB node 0x%x, rx_time=%u\n", mp.from, mp.rx_time);
|
||||
|
||||
NodeInfo *info = getOrCreateNode(getFrom(&mp));
|
||||
@@ -498,7 +500,8 @@ void NodeDB::updateFrom(const MeshPacket &mp)
|
||||
info->position.time = mp.rx_time;
|
||||
}
|
||||
|
||||
info->snr = mp.rx_snr; // keep the most recent SNR we received for this node.
|
||||
if (mp.rx_snr)
|
||||
info->snr = mp.rx_snr; // keep the most recent SNR we received for this node.
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -115,7 +115,8 @@ void Router::abortSendAndNak(Routing_Error err, MeshPacket *p)
|
||||
packetPool.release(p);
|
||||
}
|
||||
|
||||
void Router::setReceivedMessage() {
|
||||
void Router::setReceivedMessage()
|
||||
{
|
||||
setInterval(0); // Run ASAP, so we can figure out our correct sleep time
|
||||
}
|
||||
|
||||
@@ -123,9 +124,13 @@ ErrorCode Router::sendLocal(MeshPacket *p)
|
||||
{
|
||||
// No need to deliver externally if the destination is the local node
|
||||
if (p->to == nodeDB.getNodeNum()) {
|
||||
printPacket("Enqueuing local", p);
|
||||
fromRadioQueue.enqueue(p);
|
||||
setReceivedMessage();
|
||||
if (fromRadioQueue.enqueue(p, 0)) {
|
||||
printPacket("Enqueued local", p);
|
||||
setReceivedMessage();
|
||||
} else {
|
||||
printPacket("BUG! fromRadioQueue is full! Discarding!", p);
|
||||
packetPool.release(p);
|
||||
}
|
||||
return ERRNO_OK;
|
||||
} else if (!iface) {
|
||||
// We must be sending to remote nodes also, fail if no interface found
|
||||
@@ -143,9 +148,10 @@ ErrorCode Router::sendLocal(MeshPacket *p)
|
||||
}
|
||||
}
|
||||
|
||||
void printBytes(const char *label, const uint8_t *p, size_t numbytes) {
|
||||
void printBytes(const char *label, const uint8_t *p, size_t numbytes)
|
||||
{
|
||||
DEBUG_MSG("%s: ", label);
|
||||
for(size_t i = 0; i < numbytes; i++)
|
||||
for (size_t i = 0; i < numbytes; i++)
|
||||
DEBUG_MSG("%02x ", p[i]);
|
||||
DEBUG_MSG("\n");
|
||||
}
|
||||
@@ -189,7 +195,7 @@ ErrorCode Router::send(MeshPacket *p)
|
||||
return ERRNO_TOO_LARGE;
|
||||
}
|
||||
|
||||
//printBytes("plaintext", bytes, numbytes);
|
||||
// printBytes("plaintext", bytes, numbytes);
|
||||
|
||||
auto hash = channels.setActiveByIndex(p->channel);
|
||||
if (hash < 0) {
|
||||
@@ -247,19 +253,18 @@ bool Router::perhapsDecode(MeshPacket *p)
|
||||
rawSize); // 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);
|
||||
|
||||
//printBytes("plaintext", bytes, p->encrypted.size);
|
||||
// printBytes("plaintext", bytes, p->encrypted.size);
|
||||
|
||||
// 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, rawSize, Data_fields, &p->decoded)) {
|
||||
DEBUG_MSG("Invalid protobufs in received mesh packet (bad psk?)!\n");
|
||||
} else if(p->decoded.portnum == PortNum_UNKNOWN_APP) {
|
||||
} else if (p->decoded.portnum == PortNum_UNKNOWN_APP) {
|
||||
DEBUG_MSG("Invalid portnum (bad psk?)!\n");
|
||||
}
|
||||
else {
|
||||
} else {
|
||||
// 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);
|
||||
return true;
|
||||
}
|
||||
@@ -285,7 +290,7 @@ void Router::handleReceived(MeshPacket *p)
|
||||
p->rx_time = getValidTime(RTCQualityFromNet); // store the arrival timestamp for the phone
|
||||
|
||||
// Take those raw bytes and convert them back into a well structured protobuf we can understand
|
||||
bool decoded = perhapsDecode(p);
|
||||
bool decoded = perhapsDecode(p);
|
||||
if (decoded) {
|
||||
// parsing was successful, queue for our recipient
|
||||
printPacket("handleReceived", p);
|
||||
@@ -293,18 +298,20 @@ void Router::handleReceived(MeshPacket *p)
|
||||
// call any promiscious plugins here, make a (non promisiocous) plugin for forwarding messages to phone api
|
||||
// sniffReceived(p);
|
||||
MeshPlugin::callPlugins(*p);
|
||||
} else {
|
||||
DEBUG_MSG("packet decoding failed\n");
|
||||
}
|
||||
}
|
||||
|
||||
void Router::perhapsHandleReceived(MeshPacket *p)
|
||||
{
|
||||
assert(radioConfig.has_preferences);
|
||||
bool ignore = is_in_repeated(radioConfig.preferences.ignore_incoming, getFrom(p));
|
||||
bool ignore = is_in_repeated(radioConfig.preferences.ignore_incoming, p->from);
|
||||
|
||||
if (ignore)
|
||||
DEBUG_MSG("Ignoring incoming message, 0x%x is in our ignore list\n", p->from);
|
||||
else if (ignore |= shouldFilterReceived(p)) {
|
||||
// DEBUG_MSG("Incoming message was filtered 0x%x\n", p->from);
|
||||
DEBUG_MSG("Incoming message was filtered 0x%x\n", p->from);
|
||||
}
|
||||
|
||||
// Note: we avoid calling shouldFilterReceived if we are supposed to ignore certain nodes - because some overrides might
|
||||
|
||||
@@ -142,6 +142,7 @@ void SX1262Interface::addReceiveMetadata(MeshPacket *mp)
|
||||
{
|
||||
// DEBUG_MSG("PacketStatus %x\n", lora.getPacketStatus());
|
||||
mp->rx_snr = lora.getSNR();
|
||||
mp->rx_rssi = lround(lora.getRSSI());
|
||||
}
|
||||
|
||||
/** We override to turn on transmitter power as needed.
|
||||
|
||||
@@ -31,7 +31,9 @@ template <class T> class TypedQueue
|
||||
|
||||
bool isEmpty() { return uxQueueMessagesWaiting(h) == 0; }
|
||||
|
||||
bool enqueue(T x, TickType_t maxWait = portMAX_DELAY)
|
||||
/** euqueue a packet. Also, maxWait used to default to portMAX_DELAY, but we now want to callers to THINK about what blocking
|
||||
* they want */
|
||||
bool enqueue(T x, TickType_t maxWait)
|
||||
{
|
||||
if (reader) {
|
||||
reader->setInterval(0);
|
||||
|
||||
@@ -125,7 +125,7 @@ extern const pb_msgdesc_t ChannelFile_msg;
|
||||
/* Maximum encoded size of messages (where known) */
|
||||
#define LegacyRadioConfig_size 4
|
||||
#define LegacyRadioConfig_LegacyPreferences_size 2
|
||||
#define DeviceState_size 4898
|
||||
#define DeviceState_size 4920
|
||||
#define ChannelFile_size 832
|
||||
|
||||
#ifdef __cplusplus
|
||||
|
||||
@@ -57,7 +57,9 @@ typedef enum _Routing_Error {
|
||||
Routing_Error_MAX_RETRANSMIT = 5,
|
||||
Routing_Error_NO_CHANNEL = 6,
|
||||
Routing_Error_TOO_LARGE = 7,
|
||||
Routing_Error_NO_RESPONSE = 8
|
||||
Routing_Error_NO_RESPONSE = 8,
|
||||
Routing_Error_BAD_REQUEST = 32,
|
||||
Routing_Error_NOT_AUTHORIZED = 33
|
||||
} Routing_Error;
|
||||
|
||||
typedef enum _MeshPacket_Priority {
|
||||
@@ -150,6 +152,7 @@ typedef struct _MeshPacket {
|
||||
uint8_t hop_limit;
|
||||
bool want_ack;
|
||||
MeshPacket_Priority priority;
|
||||
int32_t rx_rssi;
|
||||
} MeshPacket;
|
||||
|
||||
typedef struct _NodeInfo {
|
||||
@@ -206,8 +209,8 @@ typedef struct _ToRadio {
|
||||
#define _CriticalErrorCode_ARRAYSIZE ((CriticalErrorCode)(CriticalErrorCode_Brownout+1))
|
||||
|
||||
#define _Routing_Error_MIN Routing_Error_NONE
|
||||
#define _Routing_Error_MAX Routing_Error_NO_RESPONSE
|
||||
#define _Routing_Error_ARRAYSIZE ((Routing_Error)(Routing_Error_NO_RESPONSE+1))
|
||||
#define _Routing_Error_MAX Routing_Error_NOT_AUTHORIZED
|
||||
#define _Routing_Error_ARRAYSIZE ((Routing_Error)(Routing_Error_NOT_AUTHORIZED+1))
|
||||
|
||||
#define _MeshPacket_Priority_MIN MeshPacket_Priority_UNSET
|
||||
#define _MeshPacket_Priority_MAX MeshPacket_Priority_MAX
|
||||
@@ -228,7 +231,7 @@ extern "C" {
|
||||
#define RouteDiscovery_init_default {0, {0, 0, 0, 0, 0, 0, 0, 0}}
|
||||
#define Routing_init_default {0, {RouteDiscovery_init_default}}
|
||||
#define Data_init_default {_PortNum_MIN, {0, {0}}, 0, 0, 0, 0}
|
||||
#define MeshPacket_init_default {0, 0, 0, 0, {Data_init_default}, 0, 0, 0, 0, 0, _MeshPacket_Priority_MIN}
|
||||
#define MeshPacket_init_default {0, 0, 0, 0, {Data_init_default}, 0, 0, 0, 0, 0, _MeshPacket_Priority_MIN, 0}
|
||||
#define NodeInfo_init_default {0, false, User_init_default, false, Position_init_default, 0}
|
||||
#define MyNodeInfo_init_default {0, 0, 0, "", "", "", _CriticalErrorCode_MIN, 0, 0, 0, 0, 0}
|
||||
#define LogRecord_init_default {"", 0, "", _LogRecord_Level_MIN}
|
||||
@@ -239,7 +242,7 @@ extern "C" {
|
||||
#define RouteDiscovery_init_zero {0, {0, 0, 0, 0, 0, 0, 0, 0}}
|
||||
#define Routing_init_zero {0, {RouteDiscovery_init_zero}}
|
||||
#define Data_init_zero {_PortNum_MIN, {0, {0}}, 0, 0, 0, 0}
|
||||
#define MeshPacket_init_zero {0, 0, 0, 0, {Data_init_zero}, 0, 0, 0, 0, 0, _MeshPacket_Priority_MIN}
|
||||
#define MeshPacket_init_zero {0, 0, 0, 0, {Data_init_zero}, 0, 0, 0, 0, 0, _MeshPacket_Priority_MIN, 0}
|
||||
#define NodeInfo_init_zero {0, false, User_init_zero, false, Position_init_zero, 0}
|
||||
#define MyNodeInfo_init_zero {0, 0, 0, "", "", "", _CriticalErrorCode_MIN, 0, 0, 0, 0, 0}
|
||||
#define LogRecord_init_zero {"", 0, "", _LogRecord_Level_MIN}
|
||||
@@ -291,6 +294,7 @@ extern "C" {
|
||||
#define MeshPacket_hop_limit_tag 10
|
||||
#define MeshPacket_want_ack_tag 11
|
||||
#define MeshPacket_priority_tag 12
|
||||
#define MeshPacket_rx_rssi_tag 13
|
||||
#define NodeInfo_num_tag 1
|
||||
#define NodeInfo_user_tag 2
|
||||
#define NodeInfo_position_tag 3
|
||||
@@ -362,7 +366,8 @@ X(a, STATIC, SINGULAR, FIXED32, rx_time, 7) \
|
||||
X(a, STATIC, SINGULAR, FLOAT, rx_snr, 8) \
|
||||
X(a, STATIC, SINGULAR, UINT32, hop_limit, 10) \
|
||||
X(a, STATIC, SINGULAR, BOOL, want_ack, 11) \
|
||||
X(a, STATIC, SINGULAR, UENUM, priority, 12)
|
||||
X(a, STATIC, SINGULAR, UENUM, priority, 12) \
|
||||
X(a, STATIC, SINGULAR, INT32, rx_rssi, 13)
|
||||
#define MeshPacket_CALLBACK NULL
|
||||
#define MeshPacket_DEFAULT NULL
|
||||
#define MeshPacket_payloadVariant_decoded_MSGTYPE Data
|
||||
@@ -454,12 +459,12 @@ extern const pb_msgdesc_t ToRadio_msg;
|
||||
#define RouteDiscovery_size 40
|
||||
#define Routing_size 42
|
||||
#define Data_size 260
|
||||
#define MeshPacket_size 298
|
||||
#define MeshPacket_size 309
|
||||
#define NodeInfo_size 126
|
||||
#define MyNodeInfo_size 89
|
||||
#define LogRecord_size 81
|
||||
#define FromRadio_size 307
|
||||
#define ToRadio_size 301
|
||||
#define FromRadio_size 318
|
||||
#define ToRadio_size 312
|
||||
|
||||
#ifdef __cplusplus
|
||||
} /* extern "C" */
|
||||
|
||||
@@ -77,7 +77,8 @@ void registerHandlers(HTTPServer *insecureServer, HTTPSServer *secureServer)
|
||||
ResourceNode *nodeAPIv1ToRadio = new ResourceNode("/api/v1/toradio", "PUT", &handleAPIv1ToRadio);
|
||||
ResourceNode *nodeAPIv1FromRadio = new ResourceNode("/api/v1/fromradio", "GET", &handleAPIv1FromRadio);
|
||||
|
||||
ResourceNode *nodeHotspot = new ResourceNode("/hotspot-detect.html", "GET", &handleHotspot);
|
||||
ResourceNode *nodeHotspotApple = new ResourceNode("/hotspot-detect.html", "GET", &handleHotspot);
|
||||
ResourceNode *nodeHotspotAndroid = new ResourceNode("/generate_204", "GET", &handleHotspot);
|
||||
ResourceNode *nodeFavicon = new ResourceNode("/favicon.ico", "GET", &handleFavicon);
|
||||
ResourceNode *nodeRoot = new ResourceNode("/", "GET", &handleRoot);
|
||||
ResourceNode *nodeStaticBrowse = new ResourceNode("/static", "GET", &handleStaticBrowse);
|
||||
@@ -96,7 +97,8 @@ void registerHandlers(HTTPServer *insecureServer, HTTPSServer *secureServer)
|
||||
secureServer->registerNode(nodeAPIv1ToRadioOptions);
|
||||
secureServer->registerNode(nodeAPIv1ToRadio);
|
||||
secureServer->registerNode(nodeAPIv1FromRadio);
|
||||
secureServer->registerNode(nodeHotspot);
|
||||
secureServer->registerNode(nodeHotspotApple);
|
||||
secureServer->registerNode(nodeHotspotAndroid);
|
||||
secureServer->registerNode(nodeFavicon);
|
||||
secureServer->registerNode(nodeRoot);
|
||||
secureServer->registerNode(nodeStaticBrowse);
|
||||
@@ -117,7 +119,8 @@ void registerHandlers(HTTPServer *insecureServer, HTTPSServer *secureServer)
|
||||
insecureServer->registerNode(nodeAPIv1ToRadioOptions);
|
||||
insecureServer->registerNode(nodeAPIv1ToRadio);
|
||||
insecureServer->registerNode(nodeAPIv1FromRadio);
|
||||
insecureServer->registerNode(nodeHotspot);
|
||||
insecureServer->registerNode(nodeHotspotApple);
|
||||
insecureServer->registerNode(nodeHotspotAndroid);
|
||||
insecureServer->registerNode(nodeFavicon);
|
||||
insecureServer->registerNode(nodeRoot);
|
||||
insecureServer->registerNode(nodeStaticBrowse);
|
||||
|
||||
@@ -56,13 +56,21 @@ bool AdminPlugin::handleReceivedProtobuf(const MeshPacket &mp, const AdminMessag
|
||||
|
||||
case AdminMessage_set_channel_tag:
|
||||
DEBUG_MSG("Client is setting channel %d\n", r->set_channel.index);
|
||||
handleSetChannel(r->set_channel);
|
||||
if (r->set_channel.index < 0 || r->set_channel.index >= MAX_NUM_CHANNELS)
|
||||
reply = allocErrorResponse(Routing_Error_BAD_REQUEST, &mp);
|
||||
else
|
||||
handleSetChannel(r->set_channel);
|
||||
break;
|
||||
|
||||
case AdminMessage_get_channel_request_tag:
|
||||
DEBUG_MSG("Client is getting channel %d\n", r->get_channel_request - 1);
|
||||
handleGetChannel(mp, r->get_channel_request - 1);
|
||||
case AdminMessage_get_channel_request_tag: {
|
||||
uint32_t i = r->get_channel_request - 1;
|
||||
DEBUG_MSG("Client is getting channel %u\n", i);
|
||||
if (i >= MAX_NUM_CHANNELS)
|
||||
reply = allocErrorResponse(Routing_Error_BAD_REQUEST, &mp);
|
||||
else
|
||||
handleGetChannel(mp, i);
|
||||
break;
|
||||
}
|
||||
|
||||
case AdminMessage_get_radio_request_tag:
|
||||
DEBUG_MSG("Client is getting radio\n");
|
||||
|
||||
@@ -18,17 +18,16 @@ bool RoutingPlugin::handleReceivedProtobuf(const MeshPacket &mp, const Routing *
|
||||
printPacket("Delivering rx packet", &mp);
|
||||
service.handleFromRadio(&mp);
|
||||
}
|
||||
|
||||
|
||||
return false; // Let others look at this message also if they want
|
||||
}
|
||||
|
||||
|
||||
MeshPacket *RoutingPlugin::allocReply()
|
||||
{
|
||||
assert(currentRequest);
|
||||
|
||||
// We only consider making replies if the request was a legit routing packet (not just something we were sniffing)
|
||||
if(currentRequest->decoded.portnum == PortNum_ROUTING_APP) {
|
||||
if (currentRequest->decoded.portnum == PortNum_ROUTING_APP) {
|
||||
assert(0); // 1.2 refactoring fixme, Not sure if anything needs this yet?
|
||||
// return allocDataProtobuf(u);
|
||||
}
|
||||
@@ -37,26 +36,12 @@ MeshPacket *RoutingPlugin::allocReply()
|
||||
|
||||
void RoutingPlugin::sendAckNak(Routing_Error err, NodeNum to, PacketId idFrom, ChannelIndex chIndex)
|
||||
{
|
||||
Routing c = Routing_init_default;
|
||||
|
||||
c.error_reason = err;
|
||||
|
||||
auto p = allocDataProtobuf(c);
|
||||
p->priority = MeshPacket_Priority_ACK;
|
||||
|
||||
p->hop_limit = 0; // Assume just immediate neighbors for now
|
||||
p->to = to;
|
||||
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);
|
||||
auto p = allocAckNak(err, to, idFrom, chIndex);
|
||||
|
||||
router->sendLocal(p); // we sometimes send directly to the local node
|
||||
}
|
||||
|
||||
RoutingPlugin::RoutingPlugin()
|
||||
: ProtobufPlugin("routing", PortNum_ROUTING_APP, Routing_fields)
|
||||
RoutingPlugin::RoutingPlugin() : ProtobufPlugin("routing", PortNum_ROUTING_APP, Routing_fields)
|
||||
{
|
||||
isPromiscuous = true;
|
||||
}
|
||||
|
||||
|
||||
|
||||
@@ -232,8 +232,6 @@ StoreForwardPlugin::StoreForwardPlugin()
|
||||
Uncomment the preferences below if you want to use the plugin
|
||||
without having to configure it from the PythonAPI or WebUI.
|
||||
|
||||
*/
|
||||
|
||||
if (StoreForward_Dev) {
|
||||
radioConfig.preferences.store_forward_plugin_enabled = 1;
|
||||
radioConfig.preferences.is_router = 1;
|
||||
|
||||
Reference in New Issue
Block a user