trunk roundhouse kick
This commit is contained in:
@@ -120,7 +120,7 @@ CryptoKey Channels::getKey(ChannelIndex chIndex)
|
||||
else if (oemStore.oem_aes_key.size > 1) {
|
||||
// Use the OEM key
|
||||
LOG_DEBUG("Using OEM Key with %d bytes\n", oemStore.oem_aes_key.size);
|
||||
memcpy(k.bytes, oemStore.oem_aes_key.bytes , oemStore.oem_aes_key.size);
|
||||
memcpy(k.bytes, oemStore.oem_aes_key.bytes, oemStore.oem_aes_key.size);
|
||||
k.length = oemStore.oem_aes_key.size;
|
||||
// Bump up the last byte of PSK as needed
|
||||
uint8_t *last = k.bytes + oemStore.oem_aes_key.size - 1;
|
||||
@@ -196,7 +196,7 @@ Channel &Channels::getByIndex(ChannelIndex chIndex)
|
||||
Channel *ch = channelFile.channels + chIndex;
|
||||
return *ch;
|
||||
} else {
|
||||
LOG_ERROR("Invalid channel index %d > %d, malformed packet received?\n", chIndex , channelFile.channels_count);
|
||||
LOG_ERROR("Invalid channel index %d > %d, malformed packet received?\n", chIndex, channelFile.channels_count);
|
||||
|
||||
static Channel *ch = (Channel *)malloc(sizeof(Channel));
|
||||
memset(ch, 0, sizeof(Channel));
|
||||
@@ -207,7 +207,7 @@ Channel &Channels::getByIndex(ChannelIndex chIndex)
|
||||
}
|
||||
}
|
||||
|
||||
Channel &Channels::getByName(const char* chName)
|
||||
Channel &Channels::getByName(const char *chName)
|
||||
{
|
||||
for (ChannelIndex i = 0; i < getNumChannels(); i++) {
|
||||
if (strcasecmp(getGlobalId(i), chName) == 0) {
|
||||
@@ -267,8 +267,7 @@ const char *Channels::getName(size_t chIndex)
|
||||
channelName = "Invalid";
|
||||
break;
|
||||
}
|
||||
}
|
||||
else {
|
||||
} else {
|
||||
channelName = "Custom";
|
||||
}
|
||||
}
|
||||
|
||||
+2
-3
@@ -29,7 +29,6 @@ class Channels
|
||||
int16_t hashes[MAX_NUM_CHANNELS] = {};
|
||||
|
||||
public:
|
||||
|
||||
Channels() {}
|
||||
|
||||
/// Well known channel names
|
||||
@@ -40,8 +39,8 @@ class Channels
|
||||
/** Return the Channel for a specified index */
|
||||
Channel &getByIndex(ChannelIndex chIndex);
|
||||
|
||||
/** Return the Channel for a specified name, return primary if not found. */
|
||||
Channel &getByName(const char* chName);
|
||||
/** Return the Channel for a specified name, return primary if not found. */
|
||||
Channel &getByName(const char *chName);
|
||||
|
||||
/** Using the index inside the channel, update the specified channel's settings and role. If this channel is being promoted
|
||||
* to be primary, force all other channels to be secondary.
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
#include "configuration.h"
|
||||
#include "CryptoEngine.h"
|
||||
#include "configuration.h"
|
||||
|
||||
void CryptoEngine::setKey(const CryptoKey &k)
|
||||
{
|
||||
|
||||
@@ -31,10 +31,10 @@ void FloodingRouter::sniffReceived(const MeshPacket *p, const Routing *c)
|
||||
{
|
||||
bool isAck = ((c && c->error_reason == Routing_Error_NONE)); // consider only ROUTING_APP message without error as ACK
|
||||
if (isAck && p->to != getNodeNum()) {
|
||||
// do not flood direct message that is ACKed
|
||||
// do not flood direct message that is ACKed
|
||||
LOG_DEBUG("Receiving an ACK not for me, but don't need to rebroadcast this direct message anymore.\n");
|
||||
Router::cancelSending(p->to, p->decoded.request_id); // cancel rebroadcast for this DM
|
||||
}
|
||||
Router::cancelSending(p->to, p->decoded.request_id); // cancel rebroadcast for this DM
|
||||
}
|
||||
if ((p->to != getNodeNum()) && (p->hop_limit > 0) && (getFrom(p) != getNodeNum())) {
|
||||
if (p->id != 0) {
|
||||
if (config.device.role != Config_DeviceConfig_Role_CLIENT_MUTE) {
|
||||
|
||||
@@ -1,9 +1,9 @@
|
||||
#include "SX126xInterface.h"
|
||||
#include "SX126xInterface.cpp"
|
||||
#include "SX128xInterface.h"
|
||||
#include "SX126xInterface.h"
|
||||
#include "SX128xInterface.cpp"
|
||||
#include "api/ServerAPI.h"
|
||||
#include "SX128xInterface.h"
|
||||
#include "api/ServerAPI.cpp"
|
||||
#include "api/ServerAPI.h"
|
||||
|
||||
// We need this declaration for proper linking in derived classes
|
||||
template class SX126xInterface<SX1262>;
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
#include "configuration.h"
|
||||
#include "LLCC68Interface.h"
|
||||
#include "configuration.h"
|
||||
#include "error.h"
|
||||
|
||||
LLCC68Interface::LLCC68Interface(RADIOLIB_PIN_TYPE cs, RADIOLIB_PIN_TYPE irq, RADIOLIB_PIN_TYPE rst, RADIOLIB_PIN_TYPE busy,
|
||||
|
||||
+13
-21
@@ -1,8 +1,8 @@
|
||||
#include "configuration.h"
|
||||
#include "MeshModule.h"
|
||||
#include "Channels.h"
|
||||
#include "MeshService.h"
|
||||
#include "NodeDB.h"
|
||||
#include "configuration.h"
|
||||
#include "modules/RoutingModule.h"
|
||||
#include <assert.h>
|
||||
|
||||
@@ -106,8 +106,8 @@ void MeshModule::callPlugins(const MeshPacket &mp, RxSource src)
|
||||
/// Is the channel this packet arrived on acceptable? (security check)
|
||||
/// Note: we can't know channel names for encrypted packets, so those are NEVER sent to boundChannel modules
|
||||
|
||||
/// Also: if a packet comes in on the local PC interface, we don't check for bound channels, because it is TRUSTED and it needs to
|
||||
/// to be able to fetch the initial admin packets without yet knowing any channels.
|
||||
/// Also: if a packet comes in on the local PC interface, we don't check for bound channels, because it is TRUSTED and
|
||||
/// it needs to to be able to fetch the initial admin packets without yet knowing any channels.
|
||||
|
||||
bool rxChannelOk = !pi.boundChannel || (mp.from == 0) || (strcasecmp(ch->settings.name, pi.boundChannel) == 0);
|
||||
|
||||
@@ -161,7 +161,7 @@ void MeshModule::callPlugins(const MeshPacket &mp, RxSource src)
|
||||
printPacket("Sending response", currentReply);
|
||||
service.sendToMesh(currentReply);
|
||||
currentReply = NULL;
|
||||
} else if(mp.from != ourNodeNum) {
|
||||
} else if (mp.from != ourNodeNum) {
|
||||
// Note: if the message started with the local node we don't want to send a no response reply
|
||||
|
||||
// No one wanted to reply to this requst, tell the requster that happened
|
||||
@@ -175,9 +175,8 @@ void MeshModule::callPlugins(const MeshPacket &mp, RxSource src)
|
||||
}
|
||||
|
||||
if (!moduleFound)
|
||||
LOG_DEBUG("No modules interested in portnum=%d, src=%s\n",
|
||||
mp.decoded.portnum,
|
||||
(src == RX_SRC_LOCAL) ? "LOCAL":"REMOTE");
|
||||
LOG_DEBUG("No modules interested in portnum=%d, src=%s\n", mp.decoded.portnum,
|
||||
(src == RX_SRC_LOCAL) ? "LOCAL" : "REMOTE");
|
||||
}
|
||||
|
||||
MeshPacket *MeshModule::allocReply()
|
||||
@@ -235,14 +234,12 @@ std::vector<MeshModule *> MeshModule::GetMeshModulesWithUIFrames()
|
||||
return modulesWithUIFrames;
|
||||
}
|
||||
|
||||
void MeshModule::observeUIEvents(
|
||||
Observer<const UIFrameEvent *> *observer)
|
||||
void MeshModule::observeUIEvents(Observer<const UIFrameEvent *> *observer)
|
||||
{
|
||||
if (modules) {
|
||||
for (auto i = modules->begin(); i != modules->end(); ++i) {
|
||||
auto &pi = **i;
|
||||
Observable<const UIFrameEvent *> *observable =
|
||||
pi.getUIFrameObservable();
|
||||
Observable<const UIFrameEvent *> *observable = pi.getUIFrameObservable();
|
||||
if (observable != NULL) {
|
||||
LOG_DEBUG("Module wants a UI Frame\n");
|
||||
observer->observe(observable);
|
||||
@@ -251,24 +248,19 @@ void MeshModule::observeUIEvents(
|
||||
}
|
||||
}
|
||||
|
||||
AdminMessageHandleResult MeshModule::handleAdminMessageForAllPlugins(const MeshPacket &mp, AdminMessage *request, AdminMessage *response)
|
||||
AdminMessageHandleResult MeshModule::handleAdminMessageForAllPlugins(const MeshPacket &mp, AdminMessage *request,
|
||||
AdminMessage *response)
|
||||
{
|
||||
AdminMessageHandleResult handled = AdminMessageHandleResult::NOT_HANDLED;
|
||||
if (modules) {
|
||||
for (auto i = modules->begin(); i != modules->end(); ++i) {
|
||||
auto &pi = **i;
|
||||
AdminMessageHandleResult h = pi.handleAdminMessageForModule(mp, request, response);
|
||||
if (h == AdminMessageHandleResult::HANDLED_WITH_RESPONSE)
|
||||
{
|
||||
if (h == AdminMessageHandleResult::HANDLED_WITH_RESPONSE) {
|
||||
// In case we have a response it always has priority.
|
||||
LOG_DEBUG("Reply prepared by module '%s' of variant: %d\n",
|
||||
pi.name,
|
||||
response->which_payload_variant);
|
||||
LOG_DEBUG("Reply prepared by module '%s' of variant: %d\n", pi.name, response->which_payload_variant);
|
||||
handled = h;
|
||||
}
|
||||
else if ((handled != AdminMessageHandleResult::HANDLED_WITH_RESPONSE) &&
|
||||
(h == AdminMessageHandleResult::HANDLED))
|
||||
{
|
||||
} else if ((handled != AdminMessageHandleResult::HANDLED_WITH_RESPONSE) && (h == AdminMessageHandleResult::HANDLED)) {
|
||||
// In case the message is handled it should be populated, but will not overwrite
|
||||
// a result with response.
|
||||
handled = h;
|
||||
|
||||
+41
-27
@@ -10,15 +10,14 @@
|
||||
#endif
|
||||
|
||||
/** handleReceived return enumeration
|
||||
*
|
||||
*
|
||||
* Use ProcessMessage::CONTINUE to allows other modules to process a message.
|
||||
*
|
||||
*
|
||||
* Use ProcessMessage::STOP to stop further message processing.
|
||||
*/
|
||||
enum class ProcessMessage
|
||||
{
|
||||
CONTINUE = 0,
|
||||
STOP = 1,
|
||||
enum class ProcessMessage {
|
||||
CONTINUE = 0,
|
||||
STOP = 1,
|
||||
};
|
||||
|
||||
/**
|
||||
@@ -27,8 +26,7 @@ enum class ProcessMessage
|
||||
* If response is also prepared for the request, then HANDLED_WITH_RESPONSE
|
||||
* should be returned.
|
||||
*/
|
||||
enum class AdminMessageHandleResult
|
||||
{
|
||||
enum class AdminMessageHandleResult {
|
||||
NOT_HANDLED = 0,
|
||||
HANDLED = 1,
|
||||
HANDLED_WITH_RESPONSE = 2,
|
||||
@@ -70,10 +68,13 @@ class MeshModule
|
||||
|
||||
static std::vector<MeshModule *> GetMeshModulesWithUIFrames();
|
||||
static void observeUIEvents(Observer<const UIFrameEvent *> *observer);
|
||||
static AdminMessageHandleResult handleAdminMessageForAllPlugins(
|
||||
const MeshPacket &mp, AdminMessage *request, AdminMessage *response);
|
||||
static AdminMessageHandleResult handleAdminMessageForAllPlugins(const MeshPacket &mp, AdminMessage *request,
|
||||
AdminMessage *response);
|
||||
#if HAS_SCREEN
|
||||
virtual void drawFrame(OLEDDisplay *display, OLEDDisplayUiState *state, int16_t x, int16_t y) { return; }
|
||||
virtual void drawFrame(OLEDDisplay *display, OLEDDisplayUiState *state, int16_t x, int16_t y)
|
||||
{
|
||||
return;
|
||||
}
|
||||
#endif
|
||||
protected:
|
||||
const char *name;
|
||||
@@ -127,9 +128,13 @@ class MeshModule
|
||||
|
||||
/** Called to handle a particular incoming message
|
||||
|
||||
@return ProcessMessage::STOP if you've guaranteed you've handled this message and no other handlers should be considered for it
|
||||
@return ProcessMessage::STOP if you've guaranteed you've handled this message and no other handlers should be considered for
|
||||
it
|
||||
*/
|
||||
virtual ProcessMessage handleReceived(const MeshPacket &mp) { return ProcessMessage::CONTINUE; }
|
||||
virtual ProcessMessage handleReceived(const MeshPacket &mp)
|
||||
{
|
||||
return ProcessMessage::CONTINUE;
|
||||
}
|
||||
|
||||
/** Messages can be received that have the want_response bit set. If set, this callback will be invoked
|
||||
* so that subclasses can (optionally) send a response back to the original sender.
|
||||
@@ -142,26 +147,35 @@ class MeshModule
|
||||
/***
|
||||
* @return true if you want to be alloced a UI screen frame
|
||||
*/
|
||||
virtual bool wantUIFrame() { return false; }
|
||||
virtual Observable<const UIFrameEvent *>* getUIFrameObservable() { return NULL; }
|
||||
virtual bool wantUIFrame()
|
||||
{
|
||||
return false;
|
||||
}
|
||||
virtual Observable<const UIFrameEvent *> *getUIFrameObservable()
|
||||
{
|
||||
return NULL;
|
||||
}
|
||||
|
||||
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);
|
||||
|
||||
/**
|
||||
* @brief An admin message arrived to AdminModule. Module was asked whether it want to handle the request.
|
||||
*
|
||||
* @param mp The mesh packet arrived.
|
||||
* @param request The AdminMessage request extracted from the packet.
|
||||
* @param response The prepared response
|
||||
* @return AdminMessageHandleResult
|
||||
* HANDLED if message was handled
|
||||
* HANDLED_WITH_RESPONSE if a response is also prepared and to be sent.
|
||||
*/
|
||||
virtual AdminMessageHandleResult handleAdminMessageForModule(
|
||||
const MeshPacket &mp, AdminMessage *request, AdminMessage *response) { return AdminMessageHandleResult::NOT_HANDLED; };
|
||||
/**
|
||||
* @brief An admin message arrived to AdminModule. Module was asked whether it want to handle the request.
|
||||
*
|
||||
* @param mp The mesh packet arrived.
|
||||
* @param request The AdminMessage request extracted from the packet.
|
||||
* @param response The prepared response
|
||||
* @return AdminMessageHandleResult
|
||||
* HANDLED if message was handled
|
||||
* HANDLED_WITH_RESPONSE if a response is also prepared and to be sent.
|
||||
*/
|
||||
virtual AdminMessageHandleResult handleAdminMessageForModule(const MeshPacket &mp, AdminMessage *request,
|
||||
AdminMessage *response)
|
||||
{
|
||||
return AdminMessageHandleResult::NOT_HANDLED;
|
||||
};
|
||||
|
||||
private:
|
||||
/**
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
#include "configuration.h"
|
||||
#include "MeshPacketQueue.h"
|
||||
#include "configuration.h"
|
||||
#include <assert.h>
|
||||
|
||||
#include <algorithm>
|
||||
@@ -26,7 +26,8 @@ bool CompareMeshPacketFunc(const MeshPacket *p1, const MeshPacket *p2)
|
||||
|
||||
MeshPacketQueue::MeshPacketQueue(size_t _maxLen) : maxLen(_maxLen) {}
|
||||
|
||||
bool MeshPacketQueue::empty() {
|
||||
bool MeshPacketQueue::empty()
|
||||
{
|
||||
return queue.empty();
|
||||
}
|
||||
|
||||
@@ -40,8 +41,9 @@ void fixPriority(MeshPacket *p)
|
||||
if (p->priority == MeshPacket_Priority_UNSET) {
|
||||
// if acks give high priority
|
||||
// if a reliable message give a bit higher default priority
|
||||
p->priority = (p->decoded.portnum == PortNum_ROUTING_APP) ? MeshPacket_Priority_ACK :
|
||||
(p->want_ack ? MeshPacket_Priority_RELIABLE : MeshPacket_Priority_DEFAULT);
|
||||
p->priority = (p->decoded.portnum == PortNum_ROUTING_APP)
|
||||
? MeshPacket_Priority_ACK
|
||||
: (p->want_ack ? MeshPacket_Priority_RELIABLE : MeshPacket_Priority_DEFAULT);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -99,7 +101,8 @@ MeshPacket *MeshPacketQueue::remove(NodeNum from, PacketId id)
|
||||
}
|
||||
|
||||
/** Attempt to find and remove a packet from this queue. Returns the packet which was removed from the queue */
|
||||
bool MeshPacketQueue::replaceLowerPriorityPacket(MeshPacket *p) {
|
||||
bool MeshPacketQueue::replaceLowerPriorityPacket(MeshPacket *p)
|
||||
{
|
||||
std::sort_heap(queue.begin(), queue.end(), &CompareMeshPacketFunc); // sort ascending based on priority (0 -> 127)
|
||||
|
||||
// find first packet which does not compare less (in priority) than parameter packet
|
||||
@@ -119,7 +122,7 @@ bool MeshPacketQueue::replaceLowerPriorityPacket(MeshPacket *p) {
|
||||
|
||||
if (getPriority(p) > getPriority(*low)) {
|
||||
packetPool.release(*low); // deallocate and drop the packet we're replacing
|
||||
*low = p; // replace low-pri packet at this position with incoming packet with higher priority
|
||||
*low = p; // replace low-pri packet at this position with incoming packet with higher priority
|
||||
}
|
||||
|
||||
std::make_heap(queue.begin(), queue.end(), &CompareMeshPacketFunc);
|
||||
|
||||
@@ -4,7 +4,6 @@
|
||||
|
||||
#include <queue>
|
||||
|
||||
|
||||
/**
|
||||
* A priority queue of packets
|
||||
*/
|
||||
@@ -13,7 +12,8 @@ class MeshPacketQueue
|
||||
size_t maxLen;
|
||||
std::vector<MeshPacket *> queue;
|
||||
|
||||
/** Replace a lower priority package in the queue with 'mp' (provided there are lower pri packages). Return true if replaced. */
|
||||
/** Replace a lower priority package in the queue with 'mp' (provided there are lower pri packages). Return true if replaced.
|
||||
*/
|
||||
bool replaceLowerPriorityPacket(MeshPacket *mp);
|
||||
|
||||
public:
|
||||
|
||||
@@ -2,9 +2,9 @@
|
||||
#include <assert.h>
|
||||
#include <string>
|
||||
|
||||
#include "GPS.h"
|
||||
#include "../concurrency/Periodic.h"
|
||||
#include "BluetoothCommon.h" // needed for updateBatteryLevel, FIXME, eventually when we pull mesh out into a lib we shouldn't be whacking bluetooth from here
|
||||
#include "GPS.h"
|
||||
#include "MeshService.h"
|
||||
#include "NodeDB.h"
|
||||
#include "PowerFSM.h"
|
||||
@@ -59,7 +59,7 @@ Allocator<QueueStatus> &queueStatusPool = staticQueueStatusPool;
|
||||
|
||||
MeshService::MeshService() : toPhoneQueue(MAX_RX_TOPHONE), toPhoneQueueStatusQueue(MAX_RX_TOPHONE)
|
||||
{
|
||||
lastQueueStatus = { 0, 0, 16, 0 };
|
||||
lastQueueStatus = {0, 0, 16, 0};
|
||||
}
|
||||
|
||||
void MeshService::init()
|
||||
@@ -132,7 +132,7 @@ void MeshService::reloadOwner(bool shouldSave)
|
||||
*/
|
||||
void MeshService::handleToRadio(MeshPacket &p)
|
||||
{
|
||||
#ifdef ARCH_PORTDUINO
|
||||
#ifdef ARCH_PORTDUINO
|
||||
// Simulates device is receiving a packet via the LoRa chip
|
||||
if (p.decoded.portnum == PortNum_SIMULATOR_APP) {
|
||||
// Simulator packet (=Compressed packet) is encapsulated in a MeshPacket, so need to unwrap first
|
||||
@@ -140,21 +140,22 @@ void MeshService::handleToRadio(MeshPacket &p)
|
||||
Compressed *decoded = NULL;
|
||||
if (p.which_payload_variant == MeshPacket_decoded_tag) {
|
||||
memset(&scratch, 0, sizeof(scratch));
|
||||
p.decoded.payload.size = pb_decode_from_bytes(p.decoded.payload.bytes, p.decoded.payload.size, &Compressed_msg, &scratch);
|
||||
p.decoded.payload.size =
|
||||
pb_decode_from_bytes(p.decoded.payload.bytes, p.decoded.payload.size, &Compressed_msg, &scratch);
|
||||
if (p.decoded.payload.size) {
|
||||
decoded = &scratch;
|
||||
// Extract the original payload and replace
|
||||
memcpy(&p.decoded.payload, &decoded->data, sizeof(decoded->data));
|
||||
// Switch the port from PortNum_SIMULATOR_APP back to the original PortNum
|
||||
// Switch the port from PortNum_SIMULATOR_APP back to the original PortNum
|
||||
p.decoded.portnum = decoded->portnum;
|
||||
} else
|
||||
LOG_ERROR("Error decoding protobuf for simulator message!\n");
|
||||
}
|
||||
// Let SimRadio receive as if it did via its LoRa chip
|
||||
SimRadio::instance->startReceive(&p);
|
||||
return;
|
||||
SimRadio::instance->startReceive(&p);
|
||||
return;
|
||||
}
|
||||
#endif
|
||||
#endif
|
||||
if (p.from != 0) { // We don't let phones assign nodenums to their sent messages
|
||||
LOG_WARN("phone tried to pick a nodenum, we don't allow that.\n");
|
||||
p.from = 0;
|
||||
@@ -323,7 +324,7 @@ int MeshService::onGPSChanged(const meshtastic::GPSStatus *newStatus)
|
||||
return 0;
|
||||
}
|
||||
|
||||
bool MeshService::isToPhoneQueueEmpty()
|
||||
bool MeshService::isToPhoneQueueEmpty()
|
||||
{
|
||||
return toPhoneQueue.isEmpty();
|
||||
}
|
||||
|
||||
@@ -80,7 +80,7 @@ class MeshService
|
||||
/** The radioConfig object just changed, call this to force the hw to change to the new settings
|
||||
* @return true if client devices should be sent a new set of radio configs
|
||||
*/
|
||||
bool reloadConfig(int saveWhat=SEGMENT_CONFIG | SEGMENT_MODULECONFIG | SEGMENT_DEVICESTATE | SEGMENT_CHANNELS);
|
||||
bool reloadConfig(int saveWhat = SEGMENT_CONFIG | SEGMENT_MODULECONFIG | SEGMENT_DEVICESTATE | SEGMENT_CHANNELS);
|
||||
|
||||
/// The owner User record just got updated, update our node DB and broadcast the info into the mesh
|
||||
void reloadOwner(bool shouldSave = true);
|
||||
@@ -100,7 +100,7 @@ class MeshService
|
||||
/// Pull the latest power and time info into my nodeinfo
|
||||
NodeInfo *refreshMyNodeInfo();
|
||||
|
||||
/// Send a packet to the phone
|
||||
/// Send a packet to the phone
|
||||
void sendToPhone(MeshPacket *p);
|
||||
|
||||
bool isToPhoneQueueEmpty();
|
||||
|
||||
@@ -19,9 +19,9 @@ typedef uint32_t PacketId; // A packet sequence number
|
||||
* Source of a received message
|
||||
*/
|
||||
enum RxSource {
|
||||
RX_SRC_LOCAL, // message was generated locally
|
||||
RX_SRC_RADIO, // message was received from radio mesh
|
||||
RX_SRC_USER // message was received from end-user device
|
||||
RX_SRC_LOCAL, // message was generated locally
|
||||
RX_SRC_RADIO, // message was received from radio mesh
|
||||
RX_SRC_USER // message was received from end-user device
|
||||
};
|
||||
|
||||
/**
|
||||
|
||||
+24
-20
@@ -13,9 +13,9 @@
|
||||
#include "error.h"
|
||||
#include "main.h"
|
||||
#include "mesh-pb-constants.h"
|
||||
#include <ErriezCRC32.h>
|
||||
#include <pb_decode.h>
|
||||
#include <pb_encode.h>
|
||||
#include <ErriezCRC32.h>
|
||||
|
||||
#ifdef ARCH_ESP32
|
||||
#include "mesh/http/WiFiAPClient.h"
|
||||
@@ -81,7 +81,7 @@ bool NodeDB::resetRadioConfig(bool factory_reset)
|
||||
radioGeneration++;
|
||||
|
||||
if (factory_reset) {
|
||||
didFactoryReset = factoryReset();
|
||||
didFactoryReset = factoryReset();
|
||||
}
|
||||
|
||||
if (channelFile.channels_count != MAX_NUM_CHANNELS) {
|
||||
@@ -121,7 +121,7 @@ bool NodeDB::resetRadioConfig(bool factory_reset)
|
||||
return didFactoryReset;
|
||||
}
|
||||
|
||||
bool NodeDB::factoryReset()
|
||||
bool NodeDB::factoryReset()
|
||||
{
|
||||
LOG_INFO("Performing factory reset!\n");
|
||||
// first, remove the "/prefs" (this removes most prefs)
|
||||
@@ -160,8 +160,9 @@ void NodeDB::installDefaultConfig()
|
||||
config.has_power = true;
|
||||
config.has_network = true;
|
||||
config.has_bluetooth = true;
|
||||
config.lora.tx_enabled = true; // FIXME: maybe false in the future, and setting region to enable it. (unset region forces it off)
|
||||
config.lora.override_duty_cycle = false;
|
||||
config.lora.tx_enabled =
|
||||
true; // FIXME: maybe false in the future, and setting region to enable it. (unset region forces it off)
|
||||
config.lora.override_duty_cycle = false;
|
||||
config.lora.region = Config_LoRaConfig_RegionCode_UNSET;
|
||||
config.lora.modem_preset = Config_LoRaConfig_ModemPreset_LONG_FAST;
|
||||
config.lora.hop_limit = HOP_RELIABLE;
|
||||
@@ -178,14 +179,16 @@ void NodeDB::installDefaultConfig()
|
||||
#else
|
||||
bool hasScreen = screen_found;
|
||||
#endif
|
||||
config.bluetooth.mode = hasScreen ? Config_BluetoothConfig_PairingMode_RANDOM_PIN : Config_BluetoothConfig_PairingMode_FIXED_PIN;
|
||||
config.bluetooth.mode =
|
||||
hasScreen ? Config_BluetoothConfig_PairingMode_RANDOM_PIN : Config_BluetoothConfig_PairingMode_FIXED_PIN;
|
||||
// for backward compat, default position flags are ALT+MSL
|
||||
config.position.position_flags = (Config_PositionConfig_PositionFlags_ALTITUDE | Config_PositionConfig_PositionFlags_ALTITUDE_MSL);
|
||||
|
||||
config.position.position_flags =
|
||||
(Config_PositionConfig_PositionFlags_ALTITUDE | Config_PositionConfig_PositionFlags_ALTITUDE_MSL);
|
||||
|
||||
initConfigIntervals();
|
||||
}
|
||||
|
||||
void NodeDB::initConfigIntervals()
|
||||
void NodeDB::initConfigIntervals()
|
||||
{
|
||||
config.position.gps_update_interval = default_gps_update_interval;
|
||||
config.position.gps_attempt_time = default_gps_attempt_time;
|
||||
@@ -196,7 +199,7 @@ void NodeDB::initConfigIntervals()
|
||||
config.power.min_wake_secs = default_min_wake_secs;
|
||||
config.power.sds_secs = default_sds_secs;
|
||||
config.power.wait_bluetooth_secs = default_wait_bluetooth_secs;
|
||||
|
||||
|
||||
config.display.screen_on_secs = default_screen_on_secs;
|
||||
}
|
||||
|
||||
@@ -204,7 +207,7 @@ void NodeDB::installDefaultModuleConfig()
|
||||
{
|
||||
LOG_INFO("Installing default ModuleConfig\n");
|
||||
memset(&moduleConfig, 0, sizeof(ModuleConfig));
|
||||
|
||||
|
||||
moduleConfig.version = DEVICESTATE_CUR_VER;
|
||||
moduleConfig.has_mqtt = true;
|
||||
moduleConfig.has_range_test = true;
|
||||
@@ -221,7 +224,7 @@ void NodeDB::installDefaultModuleConfig()
|
||||
initModuleConfigIntervals();
|
||||
}
|
||||
|
||||
void NodeDB::initModuleConfigIntervals()
|
||||
void NodeDB::initModuleConfigIntervals()
|
||||
{
|
||||
moduleConfig.telemetry.device_update_interval = default_broadcast_interval_secs;
|
||||
moduleConfig.telemetry.environment_update_interval = default_broadcast_interval_secs;
|
||||
@@ -247,7 +250,7 @@ void NodeDB::installDefaultDeviceState()
|
||||
memset(&devicestate, 0, sizeof(DeviceState));
|
||||
|
||||
*numNodes = 0;
|
||||
|
||||
|
||||
// init our devicestate with valid flags so protobuf writing/reading will work
|
||||
devicestate.has_my_node = true;
|
||||
devicestate.has_owner = true;
|
||||
@@ -285,7 +288,8 @@ void NodeDB::init()
|
||||
|
||||
myNodeInfo.max_channels = MAX_NUM_CHANNELS; // tell others the max # of channels we can understand
|
||||
|
||||
myNodeInfo.error_code = CriticalErrorCode_NONE; // For the error code, only show values from this boot (discard value from flash)
|
||||
myNodeInfo.error_code =
|
||||
CriticalErrorCode_NONE; // For the error code, only show values from this boot (discard value from flash)
|
||||
myNodeInfo.error_address = 0;
|
||||
|
||||
// likewise - we always want the app requirements to come from the running appload
|
||||
@@ -364,7 +368,6 @@ static const char *moduleConfigFileName = "/prefs/module.proto";
|
||||
static const char *channelFileName = "/prefs/channels.proto";
|
||||
static const char *oemConfigFile = "/oem/oem.proto";
|
||||
|
||||
|
||||
/** Load a protobuf from a file, return true for success */
|
||||
bool NodeDB::loadProto(const char *filename, size_t protoSize, size_t objSize, const pb_msgdesc_t *fields, void *dest_struct)
|
||||
{
|
||||
@@ -422,7 +425,8 @@ void NodeDB::loadFromDisk()
|
||||
}
|
||||
}
|
||||
|
||||
if (!loadProto(moduleConfigFileName, LocalModuleConfig_size, sizeof(LocalModuleConfig), &LocalModuleConfig_msg, &moduleConfig)) {
|
||||
if (!loadProto(moduleConfigFileName, LocalModuleConfig_size, sizeof(LocalModuleConfig), &LocalModuleConfig_msg,
|
||||
&moduleConfig)) {
|
||||
installDefaultModuleConfig(); // Our in RAM copy might now be corrupt
|
||||
} else {
|
||||
if (moduleConfig.version < DEVICESTATE_MIN_VER) {
|
||||
@@ -478,9 +482,9 @@ bool NodeDB::saveProto(const char *filename, size_t protoSize, const pb_msgdesc_
|
||||
#ifdef ARCH_NRF52
|
||||
static uint8_t failedCounter = 0;
|
||||
failedCounter++;
|
||||
if(failedCounter >= 2){
|
||||
if (failedCounter >= 2) {
|
||||
FSCom.format();
|
||||
//After formatting, the device needs to be restarted
|
||||
// After formatting, the device needs to be restarted
|
||||
nodeDB.resetRadioConfig(true);
|
||||
}
|
||||
#endif
|
||||
@@ -501,7 +505,7 @@ void NodeDB::saveChannelsToDisk()
|
||||
}
|
||||
}
|
||||
|
||||
void NodeDB::saveDeviceStateToDisk()
|
||||
void NodeDB::saveDeviceStateToDisk()
|
||||
{
|
||||
if (!devicestate.no_save) {
|
||||
#ifdef FSCom
|
||||
@@ -599,7 +603,7 @@ void NodeDB::updatePosition(uint32_t nodeId, const Position &p, RxSource src)
|
||||
if (src == RX_SRC_LOCAL) {
|
||||
// Local packet, fully authoritative
|
||||
LOG_INFO("updatePosition LOCAL pos@%x, time=%u, latI=%d, lonI=%d, alt=%d\n", p.timestamp, p.time, p.latitude_i,
|
||||
p.longitude_i, p.altitude);
|
||||
p.longitude_i, p.altitude);
|
||||
info->position = p;
|
||||
|
||||
} else if ((p.time > 0) && !p.latitude_i && !p.longitude_i && !p.timestamp && !p.location_source) {
|
||||
|
||||
+12
-8
@@ -58,7 +58,8 @@ class NodeDB
|
||||
void init();
|
||||
|
||||
/// write to flash
|
||||
void saveToDisk(int saveWhat = SEGMENT_CONFIG | SEGMENT_MODULECONFIG | SEGMENT_DEVICESTATE | SEGMENT_CHANNELS), saveChannelsToDisk(), saveDeviceStateToDisk();
|
||||
void saveToDisk(int saveWhat = SEGMENT_CONFIG | SEGMENT_MODULECONFIG | SEGMENT_DEVICESTATE | SEGMENT_CHANNELS),
|
||||
saveChannelsToDisk(), saveDeviceStateToDisk();
|
||||
|
||||
/** Reinit radio config if needed, because either:
|
||||
* a) sometimes a buggy android app might send us bogus settings or
|
||||
@@ -122,7 +123,7 @@ class NodeDB
|
||||
size_t getNumOnlineNodes();
|
||||
|
||||
void initConfigIntervals(), initModuleConfigIntervals(), resetNodes();
|
||||
|
||||
|
||||
bool factoryReset();
|
||||
|
||||
bool loadProto(const char *filename, size_t protoSize, size_t objSize, const pb_msgdesc_t *fields, void *dest_struct);
|
||||
@@ -140,13 +141,11 @@ class NodeDB
|
||||
newStatus.notifyObservers(&status);
|
||||
}
|
||||
|
||||
|
||||
/// read our db from flash
|
||||
void loadFromDisk();
|
||||
|
||||
/// Reinit device state from scratch (not loading from disk)
|
||||
void installDefaultDeviceState(), installDefaultChannels(), installDefaultConfig(),
|
||||
installDefaultModuleConfig();
|
||||
void installDefaultDeviceState(), installDefaultChannels(), installDefaultConfig(), installDefaultModuleConfig();
|
||||
};
|
||||
|
||||
/**
|
||||
@@ -203,13 +202,15 @@ extern NodeDB nodeDB;
|
||||
|
||||
inline uint32_t getConfiguredOrDefaultMs(uint32_t configuredInterval)
|
||||
{
|
||||
if (configuredInterval > 0) return configuredInterval * 1000;
|
||||
if (configuredInterval > 0)
|
||||
return configuredInterval * 1000;
|
||||
return default_broadcast_interval_secs * 1000;
|
||||
}
|
||||
|
||||
inline uint32_t getConfiguredOrDefaultMs(uint32_t configuredInterval, uint32_t defaultInterval)
|
||||
{
|
||||
if (configuredInterval > 0) return configuredInterval * 1000;
|
||||
if (configuredInterval > 0)
|
||||
return configuredInterval * 1000;
|
||||
return defaultInterval * 1000;
|
||||
}
|
||||
|
||||
@@ -218,4 +219,7 @@ inline uint32_t getConfiguredOrDefaultMs(uint32_t configuredInterval, uint32_t d
|
||||
*/
|
||||
extern uint32_t radioGeneration;
|
||||
|
||||
#define Module_Config_size (ModuleConfig_CannedMessageConfig_size + ModuleConfig_ExternalNotificationConfig_size + ModuleConfig_MQTTConfig_size + ModuleConfig_RangeTestConfig_size + ModuleConfig_SerialConfig_size + ModuleConfig_StoreForwardConfig_size + ModuleConfig_TelemetryConfig_size + ModuleConfig_size)
|
||||
#define Module_Config_size \
|
||||
(ModuleConfig_CannedMessageConfig_size + ModuleConfig_ExternalNotificationConfig_size + ModuleConfig_MQTTConfig_size + \
|
||||
ModuleConfig_RangeTestConfig_size + ModuleConfig_SerialConfig_size + ModuleConfig_StoreForwardConfig_size + \
|
||||
ModuleConfig_TelemetryConfig_size + ModuleConfig_size)
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
#include "configuration.h"
|
||||
#include "PacketHistory.h"
|
||||
#include "configuration.h"
|
||||
#include "mesh-pb-constants.h"
|
||||
|
||||
PacketHistory::PacketHistory()
|
||||
@@ -26,10 +26,10 @@ bool PacketHistory::wasSeenRecently(const MeshPacket *p, bool withUpdate)
|
||||
r.rxTimeMsec = now;
|
||||
|
||||
auto found = recentPackets.find(r);
|
||||
bool seenRecently = (found != recentPackets.end()); // found not equal to .end() means packet was seen recently
|
||||
bool seenRecently = (found != recentPackets.end()); // found not equal to .end() means packet was seen recently
|
||||
|
||||
if (seenRecently && (now - found->rxTimeMsec) >= FLOOD_EXPIRE_TIME) { // Check whether found packet has already expired
|
||||
recentPackets.erase(found); // Erase and pretend packet has not been seen recently
|
||||
recentPackets.erase(found); // Erase and pretend packet has not been seen recently
|
||||
found = recentPackets.end();
|
||||
seenRecently = false;
|
||||
}
|
||||
@@ -58,12 +58,13 @@ bool PacketHistory::wasSeenRecently(const MeshPacket *p, bool withUpdate)
|
||||
/**
|
||||
* Iterate through all recent packets, and remove all older than FLOOD_EXPIRE_TIME
|
||||
*/
|
||||
void PacketHistory::clearExpiredRecentPackets() {
|
||||
void PacketHistory::clearExpiredRecentPackets()
|
||||
{
|
||||
uint32_t now = millis();
|
||||
|
||||
LOG_DEBUG("recentPackets size=%ld\n", recentPackets.size());
|
||||
|
||||
for (auto it = recentPackets.begin(); it != recentPackets.end(); ) {
|
||||
for (auto it = recentPackets.begin(); it != recentPackets.end();) {
|
||||
if ((now - it->rxTimeMsec) >= FLOOD_EXPIRE_TIME) {
|
||||
it = recentPackets.erase(it); // erase returns iterator pointing to element immediately following the one erased
|
||||
} else {
|
||||
|
||||
@@ -1,4 +1,2 @@
|
||||
#include "configuration.h"
|
||||
#include "ProtobufModule.h"
|
||||
|
||||
|
||||
#include "configuration.h"
|
||||
|
||||
@@ -22,8 +22,6 @@ template <class T> class ProtobufModule : protected SinglePortModule
|
||||
}
|
||||
|
||||
protected:
|
||||
|
||||
|
||||
/**
|
||||
* Handle a received message, the data field in the message is already decoded and is provided
|
||||
*
|
||||
@@ -62,7 +60,8 @@ template <class T> class ProtobufModule : protected SinglePortModule
|
||||
private:
|
||||
/** Called to handle a particular incoming message
|
||||
|
||||
@return ProcessMessage::STOP if you've guaranteed you've handled this message and no other handlers should be considered for it
|
||||
@return ProcessMessage::STOP if you've guaranteed you've handled this message and no other handlers should be considered for
|
||||
it
|
||||
*/
|
||||
virtual ProcessMessage handleReceived(const MeshPacket &mp) override
|
||||
{
|
||||
@@ -70,8 +69,7 @@ template <class T> class ProtobufModule : protected SinglePortModule
|
||||
// it would be better to update even if the message was destined to others.
|
||||
|
||||
auto &p = mp.decoded;
|
||||
LOG_INFO("Received %s from=0x%0x, id=0x%x, portnum=%d, payloadlen=%d\n", name, mp.from, mp.id, p.portnum,
|
||||
p.payload.size);
|
||||
LOG_INFO("Received %s from=0x%0x, id=0x%x, portnum=%d, payloadlen=%d\n", name, mp.from, mp.id, p.portnum, p.payload.size);
|
||||
|
||||
T scratch;
|
||||
T *decoded = NULL;
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
#include "configuration.h"
|
||||
#include "RF95Interface.h"
|
||||
#include "MeshRadio.h" // kinda yucky, but we need to know which region we are in
|
||||
#include "RadioLibRF95.h"
|
||||
#include "configuration.h"
|
||||
#include "error.h"
|
||||
|
||||
#define MAX_POWER 20
|
||||
@@ -70,9 +70,9 @@ bool RF95Interface::init()
|
||||
int res = lora->begin(getFreq(), bw, sf, cr, syncWord, power, currentLimit, preambleLength);
|
||||
LOG_INFO("RF95 init result %d\n", res);
|
||||
|
||||
LOG_INFO("Frequency set to %f\n", getFreq());
|
||||
LOG_INFO("Bandwidth set to %f\n", bw);
|
||||
LOG_INFO("Power output set to %d\n", power);
|
||||
LOG_INFO("Frequency set to %f\n", getFreq());
|
||||
LOG_INFO("Bandwidth set to %f\n", bw);
|
||||
LOG_INFO("Power output set to %d\n", power);
|
||||
|
||||
// current limit was removed from module' ctor
|
||||
// override default value (60 mA)
|
||||
@@ -129,7 +129,7 @@ bool RF95Interface::reconfigure()
|
||||
|
||||
if (power > MAX_POWER) // This chip has lower power limits than some
|
||||
power = MAX_POWER;
|
||||
|
||||
|
||||
err = lora->setOutputPower(power);
|
||||
if (err != RADIOLIB_ERR_NONE)
|
||||
RECORD_CRITICALERROR(CriticalErrorCode_INVALID_RADIO_SETTING);
|
||||
@@ -146,7 +146,6 @@ void RF95Interface::addReceiveMetadata(MeshPacket *mp)
|
||||
{
|
||||
mp->rx_snr = lora->getSNR();
|
||||
mp->rx_rssi = lround(lora->getRSSI());
|
||||
|
||||
}
|
||||
|
||||
void RF95Interface::setStandby()
|
||||
@@ -186,15 +185,15 @@ bool RF95Interface::isChannelActive()
|
||||
// check if we can detect a LoRa preamble on the current channel
|
||||
int16_t result;
|
||||
setTransmitEnable(false);
|
||||
setStandby(); // needed for smooth transition
|
||||
setStandby(); // needed for smooth transition
|
||||
result = lora->scanChannel();
|
||||
|
||||
|
||||
if (result == RADIOLIB_PREAMBLE_DETECTED) {
|
||||
// LOG_DEBUG("Channel is busy!\n");
|
||||
return true;
|
||||
}
|
||||
assert(result != RADIOLIB_ERR_WRONG_MODEM);
|
||||
|
||||
|
||||
// LOG_DEBUG("Channel is free!\n");
|
||||
return false;
|
||||
}
|
||||
|
||||
@@ -13,8 +13,8 @@ class RF95Interface : public RadioLibInterface
|
||||
|
||||
public:
|
||||
RF95Interface(RADIOLIB_PIN_TYPE cs, RADIOLIB_PIN_TYPE irq, RADIOLIB_PIN_TYPE rst, SPIClass &spi);
|
||||
|
||||
//TODO: Verify that this irq flag works with RFM95 / SX1276 radios the way it used to
|
||||
|
||||
// TODO: Verify that this irq flag works with RFM95 / SX1276 radios the way it used to
|
||||
bool isIRQPending() override { return lora->getIRQFlags() & RADIOLIB_SX127X_MASK_IRQ_FLAG_VALID_HEADER; }
|
||||
|
||||
/// Initialise the Driver transport hardware and software.
|
||||
|
||||
+15
-15
@@ -11,10 +11,10 @@
|
||||
#include <pb_decode.h>
|
||||
#include <pb_encode.h>
|
||||
|
||||
#define RDEF(name, freq_start, freq_end, duty_cycle, spacing, power_limit, audio_permitted, frequency_switching, wide_lora) \
|
||||
#define RDEF(name, freq_start, freq_end, duty_cycle, spacing, power_limit, audio_permitted, frequency_switching, wide_lora) \
|
||||
{ \
|
||||
Config_LoRaConfig_RegionCode_##name, freq_start, freq_end, duty_cycle, spacing, power_limit, audio_permitted, \
|
||||
frequency_switching, wide_lora, #name \
|
||||
frequency_switching, wide_lora, #name \
|
||||
}
|
||||
|
||||
const RegionInfo regions[] = {
|
||||
@@ -38,9 +38,9 @@ const RegionInfo regions[] = {
|
||||
|
||||
Special Note:
|
||||
The link above describes LoRaWAN's band plan, stating a power limit of 16 dBm. This is their own suggested specification,
|
||||
we do not need to follow it. The European Union regulations clearly state that the power limit for this frequency range is 500 mW, or 27 dBm.
|
||||
It also states that we can use interference avoidance and spectrum access techniques to avoid a duty cycle.
|
||||
(Please refer to section 4.21 in the following document)
|
||||
we do not need to follow it. The European Union regulations clearly state that the power limit for this frequency range is
|
||||
500 mW, or 27 dBm. It also states that we can use interference avoidance and spectrum access techniques to avoid a duty
|
||||
cycle. (Please refer to section 4.21 in the following document)
|
||||
https://ec.europa.eu/growth/tools-databases/tris/index.cfm/ro/search/?trisaction=search.detail&year=2021&num=528&dLang=EN
|
||||
*/
|
||||
RDEF(EU_868, 869.4f, 869.65f, 10, 0, 27, false, false, false),
|
||||
@@ -94,7 +94,7 @@ const RegionInfo regions[] = {
|
||||
https://lora-alliance.org/wp-content/uploads/2020/11/lorawan_regional_parameters_v1.0.3reva_0.pdf
|
||||
*/
|
||||
RDEF(TH, 920.0f, 925.0f, 100, 0, 16, true, false, false),
|
||||
|
||||
|
||||
/*
|
||||
433,05-434,7 Mhz 10 mW
|
||||
https://nkrzi.gov.ua/images/upload/256/5810/PDF_UUZ_19_01_2016.pdf
|
||||
@@ -178,7 +178,7 @@ uint32_t RadioInterface::getPacketTime(uint32_t pl)
|
||||
uint32_t RadioInterface::getPacketTime(MeshPacket *p)
|
||||
{
|
||||
uint32_t pl = 0;
|
||||
if(p->which_payload_variant == MeshPacket_encrypted_tag) {
|
||||
if (p->which_payload_variant == MeshPacket_encrypted_tag) {
|
||||
pl = p->encrypted.size + sizeof(PacketHeader);
|
||||
} else {
|
||||
size_t numbytes = pb_encode_to_bytes(bytes, sizeof(bytes), &Data_msg, &p->decoded);
|
||||
@@ -197,7 +197,7 @@ uint32_t RadioInterface::getRetransmissionMsec(const MeshPacket *p)
|
||||
float channelUtil = airTime->channelUtilizationPercent();
|
||||
uint8_t CWsize = map(channelUtil, 0, 100, CWmin, CWmax);
|
||||
// Assuming we pick max. of CWsize and there will be a receiver with SNR at half the range
|
||||
return 2*packetAirtime + (pow(2, CWsize) + pow(2, int((CWmax+CWmin)/2))) * slotTimeMsec + PROCESSING_TIME_MSEC;
|
||||
return 2 * packetAirtime + (pow(2, CWsize) + pow(2, int((CWmax + CWmin) / 2))) * slotTimeMsec + PROCESSING_TIME_MSEC;
|
||||
}
|
||||
|
||||
/** The delay to use when we want to send something */
|
||||
@@ -226,9 +226,8 @@ uint32_t RadioInterface::getTxDelayMsecWeighted(float snr)
|
||||
uint32_t delay = 0;
|
||||
uint8_t CWsize = map(snr, SNR_MIN, SNR_MAX, CWmin, CWmax);
|
||||
// LOG_DEBUG("rx_snr of %f so setting CWsize to:%d\n", snr, CWsize);
|
||||
if (config.device.role == Config_DeviceConfig_Role_ROUTER ||
|
||||
config.device.role == Config_DeviceConfig_Role_ROUTER_CLIENT) {
|
||||
delay = random(0, 2*CWsize) * slotTimeMsec;
|
||||
if (config.device.role == Config_DeviceConfig_Role_ROUTER || config.device.role == Config_DeviceConfig_Role_ROUTER_CLIENT) {
|
||||
delay = random(0, 2 * CWsize) * slotTimeMsec;
|
||||
LOG_DEBUG("rx_snr found in packet. As a router, setting tx delay:%d\n", delay);
|
||||
} else {
|
||||
delay = random(0, pow(2, CWsize)) * slotTimeMsec;
|
||||
@@ -453,14 +452,16 @@ void RadioInterface::applyModemConfig()
|
||||
// float freq = myRegion->freqStart + ((((myRegion->freqEnd - myRegion->freqStart) / numChannels) / 2) * channel_num);
|
||||
|
||||
// New frequency selection formula
|
||||
float freq = myRegion->freqStart + (bw / 2000) + ( channel_num * (bw / 1000));
|
||||
float freq = myRegion->freqStart + (bw / 2000) + (channel_num * (bw / 1000));
|
||||
|
||||
saveChannelNum(channel_num);
|
||||
saveFreq(freq + config.lora.frequency_offset);
|
||||
|
||||
LOG_INFO("Radio freq=%.3f, config.lora.frequency_offset=%.3f\n", freq, config.lora.frequency_offset);
|
||||
LOG_INFO("Set radio: region=%s, name=%s, config=%u, ch=%d, power=%d\n", myRegion->name, channelName, loraConfig.modem_preset, channel_num, power);
|
||||
LOG_INFO("Radio myRegion->freqStart -> myRegion->freqEnd: %f -> %f (%f mhz)\n", myRegion->freqStart, myRegion->freqEnd, myRegion->freqEnd - myRegion->freqStart);
|
||||
LOG_INFO("Set radio: region=%s, name=%s, config=%u, ch=%d, power=%d\n", myRegion->name, channelName, loraConfig.modem_preset,
|
||||
channel_num, power);
|
||||
LOG_INFO("Radio myRegion->freqStart -> myRegion->freqEnd: %f -> %f (%f mhz)\n", myRegion->freqStart, myRegion->freqEnd,
|
||||
myRegion->freqEnd - myRegion->freqStart);
|
||||
LOG_INFO("Radio myRegion->numChannels: %d x %.3fkHz\n", numChannels, bw);
|
||||
LOG_INFO("Radio channel_num: %d\n", channel_num);
|
||||
LOG_INFO("Radio frequency: %f\n", getFreq());
|
||||
@@ -486,7 +487,6 @@ void RadioInterface::limitPower()
|
||||
LOG_INFO("Set radio: final power level=%d\n", power);
|
||||
}
|
||||
|
||||
|
||||
void RadioInterface::deliverToReceiver(MeshPacket *p)
|
||||
{
|
||||
if (router)
|
||||
|
||||
+10
-11
@@ -51,23 +51,23 @@ class RadioInterface
|
||||
CallbackObserver<RadioInterface, void *> notifyDeepSleepObserver =
|
||||
CallbackObserver<RadioInterface, void *>(this, &RadioInterface::notifyDeepSleepCb);
|
||||
|
||||
|
||||
protected:
|
||||
bool disabled = false;
|
||||
|
||||
float bw = 125;
|
||||
uint8_t sf = 9;
|
||||
uint8_t cr = 7;
|
||||
/** Slottime is the minimum time to wait, consisting of:
|
||||
- CAD duration (maximum of SX126x and SX127x);
|
||||
- roundtrip air propagation time (assuming max. 30km between nodes);
|
||||
/** Slottime is the minimum time to wait, consisting of:
|
||||
- CAD duration (maximum of SX126x and SX127x);
|
||||
- roundtrip air propagation time (assuming max. 30km between nodes);
|
||||
- Tx/Rx turnaround time (maximum of SX126x and SX127x);
|
||||
- MAC processing time (measured on T-beam) */
|
||||
uint32_t slotTimeMsec = 8.5 * pow(2, sf)/bw + 0.2 + 0.4 + 7;
|
||||
uint32_t slotTimeMsec = 8.5 * pow(2, sf) / bw + 0.2 + 0.4 + 7;
|
||||
uint16_t preambleLength = 32; // 8 is default, but we use longer to increase the amount of sleep time when receiving
|
||||
const uint32_t PROCESSING_TIME_MSEC = 4500; // time to construct, process and construct a packet again (empirically determined)
|
||||
const uint8_t CWmin = 2; // minimum CWsize
|
||||
const uint8_t CWmax = 8; // maximum CWsize
|
||||
const uint32_t PROCESSING_TIME_MSEC =
|
||||
4500; // time to construct, process and construct a packet again (empirically determined)
|
||||
const uint8_t CWmin = 2; // minimum CWsize
|
||||
const uint8_t CWmax = 8; // maximum CWsize
|
||||
|
||||
MeshPacket *sendingPacket = NULL; // The packet we are currently sending
|
||||
uint32_t lastTxStart = 0L;
|
||||
@@ -116,7 +116,8 @@ class RadioInterface
|
||||
virtual ErrorCode send(MeshPacket *p) = 0;
|
||||
|
||||
/** Return TX queue status */
|
||||
virtual QueueStatus getQueueStatus() {
|
||||
virtual QueueStatus getQueueStatus()
|
||||
{
|
||||
QueueStatus qs;
|
||||
qs.res = qs.mesh_packet_id = qs.free = qs.maxlen = 0;
|
||||
return qs;
|
||||
@@ -146,7 +147,6 @@ class RadioInterface
|
||||
/** The delay to use when we want to flood a message. Use a weighted scale based on SNR */
|
||||
uint32_t getTxDelayMsecWeighted(float snr);
|
||||
|
||||
|
||||
/**
|
||||
* Calculate airtime per
|
||||
* https://www.rs-online.com/designspark/rel-assets/ds-assets/uploads/knowledge-items/application-notes-for-the-internet-of-things/LoRa%20Design%20Guide.pdf
|
||||
@@ -220,6 +220,5 @@ class RadioInterface
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
/// Debug printing for packets
|
||||
void printPacket(const char *prefix, const MeshPacket *p);
|
||||
|
||||
@@ -1,8 +1,8 @@
|
||||
#pragma once
|
||||
|
||||
#include "concurrency/NotifiedWorkerThread.h"
|
||||
#include "RadioInterface.h"
|
||||
#include "MeshPacketQueue.h"
|
||||
#include "RadioInterface.h"
|
||||
#include "concurrency/NotifiedWorkerThread.h"
|
||||
|
||||
#include <RadioLib.h>
|
||||
|
||||
@@ -39,7 +39,7 @@ class LockingModule : public Module
|
||||
: Module(cs, irq, rst, gpio, spi, spiSettings)
|
||||
{
|
||||
}
|
||||
|
||||
|
||||
void SPIbeginTransaction() override;
|
||||
void SPIendTransaction() override;
|
||||
};
|
||||
@@ -62,17 +62,16 @@ class RadioLibInterface : public RadioInterface, protected concurrency::Notified
|
||||
MeshPacketQueue txQueue = MeshPacketQueue(MAX_TX_QUEUE);
|
||||
|
||||
protected:
|
||||
|
||||
/**
|
||||
* We use a meshtastic sync word, but hashed with the Channel name. For releases before 1.2 we used 0x12 (or for very old loads 0x14)
|
||||
* Note: do not use 0x34 - that is reserved for lorawan
|
||||
*
|
||||
* We now use 0x2b (so that someday we can possibly use NOT 2b - because that would be funny pun). We will be staying with this code
|
||||
* for a long time.
|
||||
* We use a meshtastic sync word, but hashed with the Channel name. For releases before 1.2 we used 0x12 (or for very old
|
||||
* loads 0x14) Note: do not use 0x34 - that is reserved for lorawan
|
||||
*
|
||||
* We now use 0x2b (so that someday we can possibly use NOT 2b - because that would be funny pun). We will be staying with
|
||||
* this code for a long time.
|
||||
*/
|
||||
const uint8_t syncWord = 0x2b;
|
||||
|
||||
float currentLimit = 100; // 100mA OCP - Should be acceptable for RFM95/SX127x chipset.
|
||||
|
||||
float currentLimit = 100; // 100mA OCP - Should be acceptable for RFM95/SX127x chipset.
|
||||
|
||||
LockingModule module; // The HW interface to the radio
|
||||
|
||||
@@ -131,8 +130,8 @@ class RadioLibInterface : public RadioInterface, protected concurrency::Notified
|
||||
virtual bool cancelSending(NodeNum from, PacketId id) override;
|
||||
|
||||
private:
|
||||
/** if we have something waiting to send, start a short (random) timer so we can come check for collision before actually doing
|
||||
* the transmit */
|
||||
/** if we have something waiting to send, start a short (random) timer so we can come check for collision before actually
|
||||
* doing the transmit */
|
||||
void setTransmitDelay();
|
||||
|
||||
/** random timer with certain min. and max. settings */
|
||||
@@ -156,7 +155,6 @@ class RadioLibInterface : public RadioInterface, protected concurrency::Notified
|
||||
QueueStatus getQueueStatus();
|
||||
|
||||
protected:
|
||||
|
||||
/** Do any hardware setup needed on entry into send configuration for the radio. Subclasses can customize */
|
||||
virtual void configHardwareForSend() {}
|
||||
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
#include "configuration.h"
|
||||
#include "RadioLibRF95.h"
|
||||
#include "configuration.h"
|
||||
|
||||
#define RF95_CHIP_VERSION 0x12
|
||||
#define RF95_ALT_VERSION 0x11 // Supposedly some versions of the chip have id 0x11
|
||||
@@ -7,11 +7,10 @@
|
||||
// From datasheet but radiolib doesn't know anything about this
|
||||
#define SX127X_REG_TCXO 0x4B
|
||||
|
||||
|
||||
RadioLibRF95::RadioLibRF95(Module *mod) : SX1278(mod) {}
|
||||
|
||||
int16_t RadioLibRF95::begin(float freq, float bw, uint8_t sf, uint8_t cr, uint8_t syncWord, int8_t power,
|
||||
uint16_t preambleLength, uint8_t gain)
|
||||
int16_t RadioLibRF95::begin(float freq, float bw, uint8_t sf, uint8_t cr, uint8_t syncWord, int8_t power, uint16_t preambleLength,
|
||||
uint8_t gain)
|
||||
{
|
||||
// execute common part
|
||||
int16_t state = SX127x::begin(RF95_CHIP_VERSION, syncWord, preambleLength);
|
||||
|
||||
+12
-11
@@ -6,9 +6,9 @@
|
||||
|
||||
\brief Derived class for %RFM95 modules. Overrides some methods from SX1278 due to different parameter ranges.
|
||||
*/
|
||||
class RadioLibRF95: public SX1278 {
|
||||
class RadioLibRF95 : public SX1278
|
||||
{
|
||||
public:
|
||||
|
||||
// constructor
|
||||
|
||||
/*!
|
||||
@@ -16,7 +16,7 @@ class RadioLibRF95: public SX1278 {
|
||||
|
||||
\param mod Instance of Module that will be used to communicate with the %LoRa chip.
|
||||
*/
|
||||
explicit RadioLibRF95(Module* mod);
|
||||
explicit RadioLibRF95(Module *mod);
|
||||
|
||||
// basic methods
|
||||
|
||||
@@ -31,19 +31,21 @@ class RadioLibRF95: public SX1278 {
|
||||
|
||||
\param cr %LoRa link coding rate denominator. Allowed values range from 5 to 8.
|
||||
|
||||
\param syncWord %LoRa sync word. Can be used to distinguish different networks. Note that value 0x34 is reserved for LoRaWAN networks.
|
||||
\param syncWord %LoRa sync word. Can be used to distinguish different networks. Note that value 0x34 is reserved for LoRaWAN
|
||||
networks.
|
||||
|
||||
\param power Transmission output power in dBm. Allowed values range from 2 to 17 dBm.
|
||||
|
||||
\param preambleLength Length of %LoRa transmission preamble in symbols. The actual preamble length is 4.25 symbols longer than the set number.
|
||||
Allowed values range from 6 to 65535.
|
||||
\param preambleLength Length of %LoRa transmission preamble in symbols. The actual preamble length is 4.25 symbols longer
|
||||
than the set number. Allowed values range from 6 to 65535.
|
||||
|
||||
\param gain Gain of receiver LNA (low-noise amplifier). Can be set to any integer in range 1 to 6 where 1 is the highest gain.
|
||||
Set to 0 to enable automatic gain control (recommended).
|
||||
\param gain Gain of receiver LNA (low-noise amplifier). Can be set to any integer in range 1 to 6 where 1 is the highest
|
||||
gain. Set to 0 to enable automatic gain control (recommended).
|
||||
|
||||
\returns \ref status_codes
|
||||
*/
|
||||
int16_t begin(float freq = 915.0, float bw = 125.0, uint8_t sf = 9, uint8_t cr = 7, uint8_t syncWord = RADIOLIB_SX127X_SYNC_WORD, int8_t power = 17, uint16_t preambleLength = 8, uint8_t gain = 0);
|
||||
int16_t begin(float freq = 915.0, float bw = 125.0, uint8_t sf = 9, uint8_t cr = 7,
|
||||
uint8_t syncWord = RADIOLIB_SX127X_SYNC_WORD, int8_t power = 17, uint16_t preambleLength = 8, uint8_t gain = 0);
|
||||
|
||||
// configuration methods
|
||||
|
||||
@@ -60,11 +62,10 @@ class RadioLibRF95: public SX1278 {
|
||||
bool isReceiving();
|
||||
|
||||
/// For debugging
|
||||
uint8_t readReg(uint8_t addr);
|
||||
uint8_t readReg(uint8_t addr);
|
||||
|
||||
protected:
|
||||
// since default current limit for SX126x/127x in updated RadioLib is 60mA
|
||||
// use the previous value
|
||||
float currentLimit = 100;
|
||||
};
|
||||
|
||||
|
||||
@@ -38,7 +38,7 @@ bool ReliableRouter::shouldFilterReceived(const MeshPacket *p)
|
||||
// the original sending process.
|
||||
|
||||
// This "optimization", does save lots of airtime. For DMs, you also get a real ACK back
|
||||
// from the intended recipient.
|
||||
// from the intended recipient.
|
||||
auto key = GlobalPacketId(getFrom(p), p->id);
|
||||
auto old = findPendingPacket(key);
|
||||
if (old) {
|
||||
@@ -54,9 +54,9 @@ bool ReliableRouter::shouldFilterReceived(const MeshPacket *p)
|
||||
}
|
||||
|
||||
/* Resend implicit ACKs for repeated packets (assuming the original packet was sent with HOP_RELIABLE)
|
||||
* this way if an implicit ACK is dropped and a packet is resent we'll rebroadcast again.
|
||||
* Resending real ACKs is omitted, as you might receive a packet multiple times due to flooding and
|
||||
* flooding this ACK back to the original sender already adds redundancy. */
|
||||
* this way if an implicit ACK is dropped and a packet is resent we'll rebroadcast again.
|
||||
* Resending real ACKs is omitted, as you might receive a packet multiple times due to flooding and
|
||||
* flooding this ACK back to the original sender already adds redundancy. */
|
||||
if (wasSeenRecently(p, false) && p->hop_limit == HOP_RELIABLE && !MeshModule::currentReply && p->to != nodeDB.getNodeNum()) {
|
||||
// retransmission on broadcast has hop_limit still equal to HOP_RELIABLE
|
||||
LOG_DEBUG("Resending implicit ack for a repeated floodmsg\n");
|
||||
@@ -88,12 +88,11 @@ void ReliableRouter::sniffReceived(const MeshPacket *p, const Routing *c)
|
||||
if (p->want_ack) {
|
||||
if (MeshModule::currentReply)
|
||||
LOG_DEBUG("Some other module has replied to this message, no need for a 2nd ack\n");
|
||||
else if (p->which_payload_variant == MeshPacket_decoded_tag)
|
||||
sendAckNak(Routing_Error_NONE, getFrom(p), p->id, p->channel);
|
||||
else
|
||||
if (p->which_payload_variant == MeshPacket_decoded_tag)
|
||||
sendAckNak(Routing_Error_NONE, getFrom(p), p->id, p->channel);
|
||||
else
|
||||
// Send a 'NO_CHANNEL' error on the primary channel if want_ack packet destined for us cannot be decoded
|
||||
sendAckNak(Routing_Error_NO_CHANNEL, getFrom(p), p->id, channels.getPrimaryIndex());
|
||||
// Send a 'NO_CHANNEL' error on the primary channel if want_ack packet destined for us cannot be decoded
|
||||
sendAckNak(Routing_Error_NO_CHANNEL, getFrom(p), p->id, channels.getPrimaryIndex());
|
||||
}
|
||||
|
||||
// We consider an ack to be either a !routing packet with a request ID or a routing packet with !error
|
||||
|
||||
+13
-13
@@ -1,8 +1,8 @@
|
||||
#include "Router.h"
|
||||
#include "Channels.h"
|
||||
#include "CryptoEngine.h"
|
||||
#include "NodeDB.h"
|
||||
#include "MeshRadio.h"
|
||||
#include "NodeDB.h"
|
||||
#include "RTC.h"
|
||||
#include "configuration.h"
|
||||
#include "main.h"
|
||||
@@ -202,10 +202,10 @@ ErrorCode Router::send(MeshPacket *p)
|
||||
if (!config.lora.override_duty_cycle && myRegion->dutyCycle < 100) {
|
||||
float hourlyTxPercent = airTime->utilizationTXPercent();
|
||||
if (hourlyTxPercent > myRegion->dutyCycle) {
|
||||
uint8_t silentMinutes = airTime->getSilentMinutes(hourlyTxPercent, myRegion->dutyCycle);
|
||||
uint8_t silentMinutes = airTime->getSilentMinutes(hourlyTxPercent, myRegion->dutyCycle);
|
||||
LOG_WARN("Duty cycle limit exceeded. Aborting send for now, you can send again in %d minutes.\n", silentMinutes);
|
||||
Routing_Error err = Routing_Error_DUTY_CYCLE_LIMIT;
|
||||
if (getFrom(p) == nodeDB.getNodeNum()) { // only send NAK to API, not to the mesh
|
||||
if (getFrom(p) == nodeDB.getNodeNum()) { // only send NAK to API, not to the mesh
|
||||
abortSendAndNak(err, p);
|
||||
} else {
|
||||
packetPool.release(p);
|
||||
@@ -235,21 +235,21 @@ ErrorCode Router::send(MeshPacket *p)
|
||||
if (p->which_payload_variant == MeshPacket_decoded_tag) {
|
||||
ChannelIndex chIndex = p->channel; // keep as a local because we are about to change it
|
||||
|
||||
bool shouldActuallyEncrypt = true;
|
||||
bool shouldActuallyEncrypt = true;
|
||||
|
||||
#if HAS_WIFI || HAS_ETHERNET
|
||||
if(moduleConfig.mqtt.enabled) {
|
||||
if (moduleConfig.mqtt.enabled) {
|
||||
// check if we should send decrypted packets to mqtt
|
||||
|
||||
// truth table:
|
||||
/* mqtt_server mqtt_encryption_enabled should_encrypt
|
||||
* not set 0 1
|
||||
* not set 1 1
|
||||
* set 0 0
|
||||
* set 1 1
|
||||
*
|
||||
* => so we only decrypt mqtt if they have a custom mqtt server AND mqtt_encryption_enabled is FALSE
|
||||
*/
|
||||
* not set 0 1
|
||||
* not set 1 1
|
||||
* set 0 0
|
||||
* set 1 1
|
||||
*
|
||||
* => so we only decrypt mqtt if they have a custom mqtt server AND mqtt_encryption_enabled is FALSE
|
||||
*/
|
||||
|
||||
if (*moduleConfig.mqtt.address && !moduleConfig.mqtt.encryption_enabled) {
|
||||
shouldActuallyEncrypt = false;
|
||||
@@ -330,7 +330,7 @@ bool perhapsDecode(MeshPacket *p)
|
||||
} else {
|
||||
// parsing was successful
|
||||
p->which_payload_variant = 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
|
||||
|
||||
// Decompress if needed. jm
|
||||
if (p->decoded.portnum == PortNum_TEXT_MESSAGE_COMPRESSED_APP) {
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
#include "configuration.h"
|
||||
#include "SX1262Interface.h"
|
||||
#include "configuration.h"
|
||||
#include "error.h"
|
||||
|
||||
SX1262Interface::SX1262Interface(RADIOLIB_PIN_TYPE cs, RADIOLIB_PIN_TYPE irq, RADIOLIB_PIN_TYPE rst, RADIOLIB_PIN_TYPE busy,
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
#include "configuration.h"
|
||||
#include "SX1268Interface.h"
|
||||
#include "configuration.h"
|
||||
#include "error.h"
|
||||
|
||||
SX1268Interface::SX1268Interface(RADIOLIB_PIN_TYPE cs, RADIOLIB_PIN_TYPE irq, RADIOLIB_PIN_TYPE rst, RADIOLIB_PIN_TYPE busy,
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
#include "configuration.h"
|
||||
#include "SX126xInterface.h"
|
||||
#include "configuration.h"
|
||||
#include "error.h"
|
||||
|
||||
// Particular boards might define a different max power based on what their hardware can do
|
||||
@@ -7,9 +7,9 @@
|
||||
#define SX126X_MAX_POWER 22
|
||||
#endif
|
||||
|
||||
template<typename T>
|
||||
template <typename T>
|
||||
SX126xInterface<T>::SX126xInterface(RADIOLIB_PIN_TYPE cs, RADIOLIB_PIN_TYPE irq, RADIOLIB_PIN_TYPE rst, RADIOLIB_PIN_TYPE busy,
|
||||
SPIClass &spi)
|
||||
SPIClass &spi)
|
||||
: RadioLibInterface(cs, irq, rst, busy, spi, &lora), lora(&module)
|
||||
{
|
||||
LOG_WARN("SX126xInterface(cs=%d, irq=%d, rst=%d, busy=%d)\n", cs, irq, rst, busy);
|
||||
@@ -18,8 +18,7 @@ SX126xInterface<T>::SX126xInterface(RADIOLIB_PIN_TYPE cs, RADIOLIB_PIN_TYPE irq,
|
||||
/// Initialise the Driver transport hardware and software.
|
||||
/// Make sure the Driver is properly configured before calling init().
|
||||
/// \return true if initialisation succeeded.
|
||||
template<typename T>
|
||||
bool SX126xInterface<T>::init()
|
||||
template <typename T> bool SX126xInterface<T>::init()
|
||||
{
|
||||
#ifdef SX126X_POWER_EN
|
||||
digitalWrite(SX126X_POWER_EN, HIGH);
|
||||
@@ -27,7 +26,7 @@ bool SX126xInterface<T>::init()
|
||||
#endif
|
||||
|
||||
#if defined(SX126X_RXEN) && (SX126X_RXEN != RADIOLIB_NC) // set not rx or tx mode
|
||||
digitalWrite(SX126X_RXEN, LOW); // Set low before becoming an output
|
||||
digitalWrite(SX126X_RXEN, LOW); // Set low before becoming an output
|
||||
pinMode(SX126X_RXEN, OUTPUT);
|
||||
#endif
|
||||
#if defined(SX126X_TXEN) && (SX126X_TXEN != RADIOLIB_NC)
|
||||
@@ -106,8 +105,7 @@ bool SX126xInterface<T>::init()
|
||||
return res == RADIOLIB_ERR_NONE;
|
||||
}
|
||||
|
||||
template<typename T>
|
||||
bool SX126xInterface<T>::reconfigure()
|
||||
template <typename T> bool SX126xInterface<T>::reconfigure()
|
||||
{
|
||||
RadioLibInterface::reconfigure();
|
||||
|
||||
@@ -156,14 +154,12 @@ bool SX126xInterface<T>::reconfigure()
|
||||
return RADIOLIB_ERR_NONE;
|
||||
}
|
||||
|
||||
template<typename T>
|
||||
void INTERRUPT_ATTR SX126xInterface<T>::disableInterrupt()
|
||||
template <typename T> void INTERRUPT_ATTR SX126xInterface<T>::disableInterrupt()
|
||||
{
|
||||
lora.clearDio1Action();
|
||||
}
|
||||
|
||||
template<typename T>
|
||||
void SX126xInterface<T>::setStandby()
|
||||
template <typename T> void SX126xInterface<T>::setStandby()
|
||||
{
|
||||
checkNotification(); // handle any pending interrupts before we force standby
|
||||
|
||||
@@ -189,8 +185,7 @@ void SX126xInterface<T>::setStandby()
|
||||
/**
|
||||
* Add SNR data to received messages
|
||||
*/
|
||||
template<typename T>
|
||||
void SX126xInterface<T>::addReceiveMetadata(MeshPacket *mp)
|
||||
template <typename T> void SX126xInterface<T>::addReceiveMetadata(MeshPacket *mp)
|
||||
{
|
||||
// LOG_DEBUG("PacketStatus %x\n", lora.getPacketStatus());
|
||||
mp->rx_snr = lora.getSNR();
|
||||
@@ -199,8 +194,7 @@ void SX126xInterface<T>::addReceiveMetadata(MeshPacket *mp)
|
||||
|
||||
/** We override to turn on transmitter power as needed.
|
||||
*/
|
||||
template<typename T>
|
||||
void SX126xInterface<T>::configHardwareForSend()
|
||||
template <typename T> void SX126xInterface<T>::configHardwareForSend()
|
||||
{
|
||||
#if defined(SX126X_TXEN) && (SX126X_TXEN != RADIOLIB_NC) // we have RXEN/TXEN control - turn on TX power / off RX power
|
||||
digitalWrite(SX126X_TXEN, HIGH);
|
||||
@@ -215,8 +209,7 @@ void SX126xInterface<T>::configHardwareForSend()
|
||||
// For power draw measurements, helpful to force radio to stay sleeping
|
||||
// #define SLEEP_ONLY
|
||||
|
||||
template<typename T>
|
||||
void SX126xInterface<T>::startReceive()
|
||||
template <typename T> void SX126xInterface<T>::startReceive()
|
||||
{
|
||||
#ifdef SLEEP_ONLY
|
||||
sleep();
|
||||
@@ -244,8 +237,7 @@ void SX126xInterface<T>::startReceive()
|
||||
}
|
||||
|
||||
/** Could we send right now (i.e. either not actively receving or transmitting)? */
|
||||
template<typename T>
|
||||
bool SX126xInterface<T>::isChannelActive()
|
||||
template <typename T> bool SX126xInterface<T>::isChannelActive()
|
||||
{
|
||||
// check if we can detect a LoRa preamble on the current channel
|
||||
int16_t result;
|
||||
@@ -261,8 +253,7 @@ bool SX126xInterface<T>::isChannelActive()
|
||||
}
|
||||
|
||||
/** Could we send right now (i.e. either not actively receving or transmitting)? */
|
||||
template<typename T>
|
||||
bool SX126xInterface<T>::isActivelyReceiving()
|
||||
template <typename T> bool SX126xInterface<T>::isActivelyReceiving()
|
||||
{
|
||||
// The IRQ status will be cleared when we start our read operation. Check if we've started a header, but haven't yet
|
||||
// received and handled the interrupt for reading the packet/handling errors.
|
||||
@@ -279,8 +270,7 @@ bool SX126xInterface<T>::isActivelyReceiving()
|
||||
return hasPreamble;
|
||||
}
|
||||
|
||||
template<typename T>
|
||||
bool SX126xInterface<T>::sleep()
|
||||
template <typename T> bool SX126xInterface<T>::sleep()
|
||||
{
|
||||
// Not keeping config is busted - next time nrf52 board boots lora sending fails tcxo related? - see datasheet
|
||||
// \todo Display actual typename of the adapter, not just `SX126x`
|
||||
|
||||
@@ -6,8 +6,7 @@
|
||||
* \brief Adapter for SX126x radio family. Implements common logic for child classes.
|
||||
* \tparam T RadioLib module type for SX126x: SX1262, SX1268.
|
||||
*/
|
||||
template<class T>
|
||||
class SX126xInterface : public RadioLibInterface
|
||||
template <class T> class SX126xInterface : public RadioLibInterface
|
||||
{
|
||||
public:
|
||||
SX126xInterface(RADIOLIB_PIN_TYPE cs, RADIOLIB_PIN_TYPE irq, RADIOLIB_PIN_TYPE rst, RADIOLIB_PIN_TYPE busy, SPIClass &spi);
|
||||
@@ -28,11 +27,10 @@ class SX126xInterface : public RadioLibInterface
|
||||
bool isIRQPending() override { return lora.getIrqStatus() != 0; }
|
||||
|
||||
protected:
|
||||
|
||||
float currentLimit = 140; // Higher OCP limit for SX126x PA
|
||||
|
||||
/**
|
||||
* Specific module instance
|
||||
* Specific module instance
|
||||
*/
|
||||
T lora;
|
||||
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
#include "configuration.h"
|
||||
#include "SX1280Interface.h"
|
||||
#include "configuration.h"
|
||||
#include "error.h"
|
||||
|
||||
SX1280Interface::SX1280Interface(RADIOLIB_PIN_TYPE cs, RADIOLIB_PIN_TYPE irq, RADIOLIB_PIN_TYPE rst, RADIOLIB_PIN_TYPE busy,
|
||||
|
||||
@@ -6,7 +6,6 @@
|
||||
* Our adapter for SX1280 radios
|
||||
*/
|
||||
|
||||
|
||||
class SX1280Interface : public SX128xInterface<SX1280>
|
||||
{
|
||||
public:
|
||||
|
||||
@@ -1,16 +1,16 @@
|
||||
#include "configuration.h"
|
||||
#include "SX128xInterface.h"
|
||||
#include "mesh/NodeDB.h"
|
||||
#include "configuration.h"
|
||||
#include "error.h"
|
||||
#include "mesh/NodeDB.h"
|
||||
|
||||
// Particular boards might define a different max power based on what their hardware can do
|
||||
#ifndef SX128X_MAX_POWER
|
||||
#define SX128X_MAX_POWER 13
|
||||
#endif
|
||||
|
||||
template<typename T>
|
||||
template <typename T>
|
||||
SX128xInterface<T>::SX128xInterface(RADIOLIB_PIN_TYPE cs, RADIOLIB_PIN_TYPE irq, RADIOLIB_PIN_TYPE rst, RADIOLIB_PIN_TYPE busy,
|
||||
SPIClass &spi)
|
||||
SPIClass &spi)
|
||||
: RadioLibInterface(cs, irq, rst, busy, spi, &lora), lora(&module)
|
||||
{
|
||||
}
|
||||
@@ -18,21 +18,20 @@ SX128xInterface<T>::SX128xInterface(RADIOLIB_PIN_TYPE cs, RADIOLIB_PIN_TYPE irq,
|
||||
/// Initialise the Driver transport hardware and software.
|
||||
/// Make sure the Driver is properly configured before calling init().
|
||||
/// \return true if initialisation succeeded.
|
||||
template<typename T>
|
||||
bool SX128xInterface<T>::init()
|
||||
template <typename T> bool SX128xInterface<T>::init()
|
||||
{
|
||||
#ifdef SX128X_POWER_EN
|
||||
digitalWrite(SX128X_POWER_EN, HIGH);
|
||||
pinMode(SX128X_POWER_EN, OUTPUT);
|
||||
#endif
|
||||
|
||||
|
||||
#ifdef RF95_FAN_EN
|
||||
pinMode(RF95_FAN_EN, OUTPUT);
|
||||
digitalWrite(RF95_FAN_EN, 1);
|
||||
#endif
|
||||
|
||||
|
||||
#if defined(SX128X_RXEN) && (SX128X_RXEN != RADIOLIB_NC) // set not rx or tx mode
|
||||
digitalWrite(SX128X_RXEN, LOW); // Set low before becoming an output
|
||||
digitalWrite(SX128X_RXEN, LOW); // Set low before becoming an output
|
||||
pinMode(SX128X_RXEN, OUTPUT);
|
||||
#endif
|
||||
#if defined(SX128X_TXEN) && (SX128X_TXEN != RADIOLIB_NC)
|
||||
@@ -56,7 +55,7 @@ bool SX128xInterface<T>::init()
|
||||
// \todo Display actual typename of the adapter, not just `SX128x`
|
||||
LOG_INFO("SX128x init result %d\n", res);
|
||||
|
||||
if((config.lora.region != Config_LoRaConfig_RegionCode_LORA_24) && (res == RADIOLIB_ERR_INVALID_FREQUENCY)) {
|
||||
if ((config.lora.region != Config_LoRaConfig_RegionCode_LORA_24) && (res == RADIOLIB_ERR_INVALID_FREQUENCY)) {
|
||||
LOG_WARN("Radio chip only supports 2.4GHz LoRa. Adjusting Region and rebooting.\n");
|
||||
config.lora.region = Config_LoRaConfig_RegionCode_LORA_24;
|
||||
nodeDB.saveToDisk(SEGMENT_CONFIG);
|
||||
@@ -70,9 +69,9 @@ bool SX128xInterface<T>::init()
|
||||
#endif
|
||||
}
|
||||
|
||||
LOG_INFO("Frequency set to %f\n", getFreq());
|
||||
LOG_INFO("Bandwidth set to %f\n", bw);
|
||||
LOG_INFO("Power output set to %d\n", power);
|
||||
LOG_INFO("Frequency set to %f\n", getFreq());
|
||||
LOG_INFO("Bandwidth set to %f\n", bw);
|
||||
LOG_INFO("Power output set to %d\n", power);
|
||||
|
||||
if (res == RADIOLIB_ERR_NONE)
|
||||
res = lora.setCRC(2);
|
||||
@@ -83,8 +82,7 @@ bool SX128xInterface<T>::init()
|
||||
return res == RADIOLIB_ERR_NONE;
|
||||
}
|
||||
|
||||
template<typename T>
|
||||
bool SX128xInterface<T>::reconfigure()
|
||||
template <typename T> bool SX128xInterface<T>::reconfigure()
|
||||
{
|
||||
RadioLibInterface::reconfigure();
|
||||
|
||||
@@ -130,23 +128,20 @@ bool SX128xInterface<T>::reconfigure()
|
||||
return RADIOLIB_ERR_NONE;
|
||||
}
|
||||
|
||||
template<typename T>
|
||||
void INTERRUPT_ATTR SX128xInterface<T>::disableInterrupt()
|
||||
template <typename T> void INTERRUPT_ATTR SX128xInterface<T>::disableInterrupt()
|
||||
{
|
||||
lora.clearDio1Action();
|
||||
}
|
||||
|
||||
template<typename T>
|
||||
bool SX128xInterface<T>::wideLora()
|
||||
template <typename T> bool SX128xInterface<T>::wideLora()
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
||||
template<typename T>
|
||||
void SX128xInterface<T>::setStandby()
|
||||
template <typename T> void SX128xInterface<T>::setStandby()
|
||||
{
|
||||
checkNotification(); // handle any pending interrupts before we force standby
|
||||
|
||||
|
||||
int err = lora.standby();
|
||||
|
||||
if (err != RADIOLIB_ERR_NONE)
|
||||
@@ -169,8 +164,7 @@ void SX128xInterface<T>::setStandby()
|
||||
/**
|
||||
* Add SNR data to received messages
|
||||
*/
|
||||
template<typename T>
|
||||
void SX128xInterface<T>::addReceiveMetadata(MeshPacket *mp)
|
||||
template <typename T> void SX128xInterface<T>::addReceiveMetadata(MeshPacket *mp)
|
||||
{
|
||||
// LOG_DEBUG("PacketStatus %x\n", lora.getPacketStatus());
|
||||
mp->rx_snr = lora.getSNR();
|
||||
@@ -179,8 +173,7 @@ void SX128xInterface<T>::addReceiveMetadata(MeshPacket *mp)
|
||||
|
||||
/** We override to turn on transmitter power as needed.
|
||||
*/
|
||||
template<typename T>
|
||||
void SX128xInterface<T>::configHardwareForSend()
|
||||
template <typename T> void SX128xInterface<T>::configHardwareForSend()
|
||||
{
|
||||
#if defined(SX128X_TXEN) && (SX128X_TXEN != RADIOLIB_NC) // we have RXEN/TXEN control - turn on TX power / off RX power
|
||||
digitalWrite(SX128X_TXEN, HIGH);
|
||||
@@ -195,8 +188,7 @@ void SX128xInterface<T>::configHardwareForSend()
|
||||
// For power draw measurements, helpful to force radio to stay sleeping
|
||||
// #define SLEEP_ONLY
|
||||
|
||||
template<typename T>
|
||||
void SX128xInterface<T>::startReceive()
|
||||
template <typename T> void SX128xInterface<T>::startReceive()
|
||||
{
|
||||
#ifdef SLEEP_ONLY
|
||||
sleep();
|
||||
@@ -210,7 +202,7 @@ void SX128xInterface<T>::startReceive()
|
||||
#if defined(SX128X_TXEN) && (SX128X_TXEN != RADIOLIB_NC)
|
||||
digitalWrite(SX128X_TXEN, LOW);
|
||||
#endif
|
||||
|
||||
|
||||
int err = lora.startReceive();
|
||||
|
||||
assert(err == RADIOLIB_ERR_NONE);
|
||||
@@ -223,33 +215,30 @@ void SX128xInterface<T>::startReceive()
|
||||
}
|
||||
|
||||
/** Could we send right now (i.e. either not actively receving or transmitting)? */
|
||||
template<typename T>
|
||||
bool SX128xInterface<T>::isChannelActive()
|
||||
template <typename T> bool SX128xInterface<T>::isChannelActive()
|
||||
{
|
||||
// check if we can detect a LoRa preamble on the current channel
|
||||
int16_t result;
|
||||
|
||||
setStandby();
|
||||
setStandby();
|
||||
result = lora.scanChannel();
|
||||
if (result == RADIOLIB_PREAMBLE_DETECTED)
|
||||
if (result == RADIOLIB_PREAMBLE_DETECTED)
|
||||
return true;
|
||||
|
||||
|
||||
assert(result != RADIOLIB_ERR_WRONG_MODEM);
|
||||
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
/** Could we send right now (i.e. either not actively receving or transmitting)? */
|
||||
template<typename T>
|
||||
bool SX128xInterface<T>::isActivelyReceiving()
|
||||
template <typename T> bool SX128xInterface<T>::isActivelyReceiving()
|
||||
{
|
||||
uint16_t irq = lora.getIrqStatus();
|
||||
bool hasPreamble = (irq & RADIOLIB_SX128X_IRQ_HEADER_VALID);
|
||||
return hasPreamble;
|
||||
}
|
||||
|
||||
template<typename T>
|
||||
bool SX128xInterface<T>::sleep()
|
||||
template <typename T> bool SX128xInterface<T>::sleep()
|
||||
{
|
||||
// Not keeping config is busted - next time nrf52 board boots lora sending fails tcxo related? - see datasheet
|
||||
// \todo Display actual typename of the adapter, not just `SX128x`
|
||||
|
||||
@@ -6,8 +6,7 @@
|
||||
* \brief Adapter for SX128x radio family. Implements common logic for child classes.
|
||||
* \tparam T RadioLib module type for SX128x: SX1280.
|
||||
*/
|
||||
template<class T>
|
||||
class SX128xInterface : public RadioLibInterface
|
||||
template <class T> class SX128xInterface : public RadioLibInterface
|
||||
{
|
||||
public:
|
||||
SX128xInterface(RADIOLIB_PIN_TYPE cs, RADIOLIB_PIN_TYPE irq, RADIOLIB_PIN_TYPE rst, RADIOLIB_PIN_TYPE busy, SPIClass &spi);
|
||||
@@ -30,9 +29,8 @@ class SX128xInterface : public RadioLibInterface
|
||||
bool isIRQPending() override { return lora.getIrqStatus() != 0; }
|
||||
|
||||
protected:
|
||||
|
||||
/**
|
||||
* Specific module instance
|
||||
* Specific module instance
|
||||
*/
|
||||
T lora;
|
||||
|
||||
|
||||
@@ -27,15 +27,16 @@ int32_t StreamAPI::readStream()
|
||||
} else {
|
||||
while (stream->available()) { // Currently we never want to block
|
||||
int cInt = stream->read();
|
||||
if(cInt < 0)
|
||||
break; // We ran out of characters (even though available said otherwise) - this can happen on rf52 adafruit arduino
|
||||
if (cInt < 0)
|
||||
break; // We ran out of characters (even though available said otherwise) - this can happen on rf52 adafruit
|
||||
// arduino
|
||||
|
||||
uint8_t c = (uint8_t) cInt;
|
||||
uint8_t c = (uint8_t)cInt;
|
||||
|
||||
// Use the read pointer for a little state machine, first look for framing, then length bytes, then payload
|
||||
size_t ptr = rxPtr;
|
||||
|
||||
rxPtr++; // assume we will probably advance the rxPtr
|
||||
rxPtr++; // assume we will probably advance the rxPtr
|
||||
rxBuf[ptr] = c; // store all bytes (including framing)
|
||||
|
||||
// console->printf("rxPtr %d ptr=%d c=0x%x\n", rxPtr, ptr, c);
|
||||
@@ -58,9 +59,9 @@ int32_t StreamAPI::readStream()
|
||||
rxPtr = 0; // length is bogus, restart search for framing
|
||||
}
|
||||
|
||||
if (rxPtr != 0) // Is packet still considered 'good'?
|
||||
if (rxPtr != 0) // Is packet still considered 'good'?
|
||||
if (ptr + 1 >= len + HEADER_LEN) { // have we received all of the payload?
|
||||
rxPtr = 0; // start over again on the next packet
|
||||
rxPtr = 0; // start over again on the next packet
|
||||
|
||||
// If we didn't just fail the packet and we now have the right # of bytes, parse it
|
||||
handleToRadio(rxBuf + HEADER_LEN, len);
|
||||
|
||||
@@ -19,10 +19,7 @@ template <class T> class TypedQueue
|
||||
concurrency::OSThread *reader = NULL;
|
||||
|
||||
public:
|
||||
explicit TypedQueue(int maxElements) : h(xQueueCreate(maxElements, sizeof(T)))
|
||||
{
|
||||
assert(h);
|
||||
}
|
||||
explicit TypedQueue(int maxElements) : h(xQueueCreate(maxElements, sizeof(T))) { assert(h); }
|
||||
|
||||
~TypedQueue() { vQueueDelete(h); }
|
||||
|
||||
|
||||
@@ -2,34 +2,30 @@
|
||||
#include "configuration.h"
|
||||
#include <Arduino.h>
|
||||
|
||||
template<typename T>
|
||||
template <typename T>
|
||||
ServerAPI<T>::ServerAPI(T &_client) : StreamAPI(&client), concurrency::OSThread("ServerAPI"), client(_client)
|
||||
{
|
||||
LOG_INFO("Incoming wifi connection\n");
|
||||
}
|
||||
|
||||
template<typename T>
|
||||
ServerAPI<T>::~ServerAPI()
|
||||
template <typename T> ServerAPI<T>::~ServerAPI()
|
||||
{
|
||||
client.stop();
|
||||
}
|
||||
|
||||
template<typename T>
|
||||
void ServerAPI<T>::close()
|
||||
template <typename T> void ServerAPI<T>::close()
|
||||
{
|
||||
client.stop(); // drop tcp connection
|
||||
StreamAPI::close();
|
||||
}
|
||||
|
||||
/// Check the current underlying physical link to see if the client is currently connected
|
||||
template<typename T>
|
||||
bool ServerAPI<T>::checkIsConnected()
|
||||
template <typename T> bool ServerAPI<T>::checkIsConnected()
|
||||
{
|
||||
return client.connected();
|
||||
}
|
||||
|
||||
template<class T>
|
||||
int32_t ServerAPI<T>::runOnce()
|
||||
template <class T> int32_t ServerAPI<T>::runOnce()
|
||||
{
|
||||
if (client.connected()) {
|
||||
return StreamAPI::runOncePart();
|
||||
@@ -40,17 +36,14 @@ int32_t ServerAPI<T>::runOnce()
|
||||
}
|
||||
}
|
||||
|
||||
template<class T, class U>
|
||||
APIServerPort<T, U>::APIServerPort(int port) : U(port), concurrency::OSThread("ApiServer") {}
|
||||
template <class T, class U> APIServerPort<T, U>::APIServerPort(int port) : U(port), concurrency::OSThread("ApiServer") {}
|
||||
|
||||
template<class T, class U>
|
||||
void APIServerPort<T, U>::init()
|
||||
template <class T, class U> void APIServerPort<T, U>::init()
|
||||
{
|
||||
U::begin();
|
||||
}
|
||||
|
||||
template<class T, class U>
|
||||
int32_t APIServerPort<T, U>::runOnce()
|
||||
template <class T, class U> int32_t APIServerPort<T, U>::runOnce()
|
||||
{
|
||||
auto client = U::available();
|
||||
if (client) {
|
||||
|
||||
@@ -6,8 +6,7 @@
|
||||
* Provides both debug printing and, if the client starts sending protobufs to us, switches to send/receive protobufs
|
||||
* (and starts dropping debug printing - FIXME, eventually those prints should be encapsulated in protobufs).
|
||||
*/
|
||||
template<class T>
|
||||
class ServerAPI : public StreamAPI, private concurrency::OSThread
|
||||
template <class T> class ServerAPI : public StreamAPI, private concurrency::OSThread
|
||||
{
|
||||
private:
|
||||
T client;
|
||||
@@ -34,8 +33,7 @@ class ServerAPI : public StreamAPI, private concurrency::OSThread
|
||||
/**
|
||||
* Listens for incoming connections and does accepts and creates instances of WiFiServerAPI as needed
|
||||
*/
|
||||
template<class T, class U>
|
||||
class APIServerPort : public U, private concurrency::OSThread
|
||||
template <class T, class U> class APIServerPort : public U, private concurrency::OSThread
|
||||
{
|
||||
/** The currently open port
|
||||
*
|
||||
|
||||
@@ -9,8 +9,8 @@
|
||||
*/
|
||||
class WiFiServerAPI : public ServerAPI<WiFiClient>
|
||||
{
|
||||
public:
|
||||
explicit WiFiServerAPI(WiFiClient &_client);
|
||||
public:
|
||||
explicit WiFiServerAPI(WiFiClient &_client);
|
||||
};
|
||||
|
||||
/**
|
||||
@@ -18,8 +18,8 @@ class WiFiServerAPI : public ServerAPI<WiFiClient>
|
||||
*/
|
||||
class WiFiServerPort : public APIServerPort<WiFiServerAPI, WiFiServer>
|
||||
{
|
||||
public:
|
||||
explicit WiFiServerPort(int port);
|
||||
public:
|
||||
explicit WiFiServerPort(int port);
|
||||
};
|
||||
|
||||
void initApiServer(int port=4403);
|
||||
void initApiServer(int port = 4403);
|
||||
|
||||
@@ -9,8 +9,8 @@
|
||||
*/
|
||||
class ethServerAPI : public ServerAPI<EthernetClient>
|
||||
{
|
||||
public:
|
||||
explicit ethServerAPI(EthernetClient &_client);
|
||||
public:
|
||||
explicit ethServerAPI(EthernetClient &_client);
|
||||
};
|
||||
|
||||
/**
|
||||
@@ -18,8 +18,8 @@ class ethServerAPI : public ServerAPI<EthernetClient>
|
||||
*/
|
||||
class ethServerPort : public APIServerPort<ethServerAPI, EthernetServer>
|
||||
{
|
||||
public:
|
||||
explicit ethServerPort(int port);
|
||||
public:
|
||||
explicit ethServerPort(int port);
|
||||
};
|
||||
|
||||
void initApiServer(int port=4403);
|
||||
void initApiServer(int port = 4403);
|
||||
|
||||
+1114
-1058
File diff suppressed because it is too large
Load Diff
+177
-66
@@ -30,7 +30,7 @@
|
||||
#ifndef unishox2
|
||||
#define unishox2
|
||||
|
||||
#define UNISHOX_VERSION "2.0" ///< Unicode spec version
|
||||
#define UNISHOX_VERSION "2.0" ///< Unicode spec version
|
||||
|
||||
/**
|
||||
* Macro switch to enable/disable output buffer length parameter in low level api \n
|
||||
@@ -45,104 +45,217 @@
|
||||
* The simple api, i.e. unishox2_(de)compress_simple will always omit the buffer length
|
||||
*/
|
||||
#ifndef UNISHOX_API_WITH_OUTPUT_LEN
|
||||
# define UNISHOX_API_WITH_OUTPUT_LEN 0
|
||||
#define UNISHOX_API_WITH_OUTPUT_LEN 0
|
||||
#endif
|
||||
|
||||
/// Upto 8 bits of initial magic bit sequence can be included. Bit count can be specified with UNISHOX_MAGIC_BIT_LEN
|
||||
#ifndef UNISHOX_MAGIC_BITS
|
||||
# define UNISHOX_MAGIC_BITS 0xFF
|
||||
#define UNISHOX_MAGIC_BITS 0xFF
|
||||
#endif
|
||||
|
||||
/// Desired length of Magic bits defined by UNISHOX_MAGIC_BITS
|
||||
#ifdef UNISHOX_MAGIC_BIT_LEN
|
||||
# if UNISHOX_MAGIC_BIT_LEN < 0 || 9 <= UNISHOX_MAGIC_BIT_LEN
|
||||
# error "UNISHOX_MAGIC_BIT_LEN need between [0, 8)"
|
||||
# endif
|
||||
#if UNISHOX_MAGIC_BIT_LEN < 0 || 9 <= UNISHOX_MAGIC_BIT_LEN
|
||||
#error "UNISHOX_MAGIC_BIT_LEN need between [0, 8)"
|
||||
#endif
|
||||
#else
|
||||
# define UNISHOX_MAGIC_BIT_LEN 1
|
||||
#define UNISHOX_MAGIC_BIT_LEN 1
|
||||
#endif
|
||||
|
||||
//enum {USX_ALPHA = 0, USX_SYM, USX_NUM, USX_DICT, USX_DELTA};
|
||||
// enum {USX_ALPHA = 0, USX_SYM, USX_NUM, USX_DICT, USX_DELTA};
|
||||
|
||||
/// Default Horizontal codes. When composition of text is know beforehand, the other hcodes in this section can be used to achieve more compression.
|
||||
#define USX_HCODES_DFLT (const unsigned char[]) {0x00, 0x40, 0x80, 0xC0, 0xE0}
|
||||
/// Default Horizontal codes. When composition of text is know beforehand, the other hcodes in this section can be used to achieve
|
||||
/// more compression.
|
||||
#define USX_HCODES_DFLT \
|
||||
(const unsigned char[]) \
|
||||
{ \
|
||||
0x00, 0x40, 0x80, 0xC0, 0xE0 \
|
||||
}
|
||||
/// Length of each default hcode
|
||||
#define USX_HCODE_LENS_DFLT (const unsigned char[]) {2, 2, 2, 3, 3}
|
||||
#define USX_HCODE_LENS_DFLT \
|
||||
(const unsigned char[]) \
|
||||
{ \
|
||||
2, 2, 2, 3, 3 \
|
||||
}
|
||||
|
||||
/// Horizontal codes preset for English Alphabet content only
|
||||
#define USX_HCODES_ALPHA_ONLY (const unsigned char[]) {0x00, 0x00, 0x00, 0x00, 0x00}
|
||||
#define USX_HCODES_ALPHA_ONLY \
|
||||
(const unsigned char[]) \
|
||||
{ \
|
||||
0x00, 0x00, 0x00, 0x00, 0x00 \
|
||||
}
|
||||
/// Length of each Alpha only hcode
|
||||
#define USX_HCODE_LENS_ALPHA_ONLY (const unsigned char[]) {0, 0, 0, 0, 0}
|
||||
#define USX_HCODE_LENS_ALPHA_ONLY \
|
||||
(const unsigned char[]) \
|
||||
{ \
|
||||
0, 0, 0, 0, 0 \
|
||||
}
|
||||
|
||||
/// Horizontal codes preset for Alpha Numeric content only
|
||||
#define USX_HCODES_ALPHA_NUM_ONLY (const unsigned char[]) {0x00, 0x00, 0x80, 0x00, 0x00}
|
||||
#define USX_HCODES_ALPHA_NUM_ONLY \
|
||||
(const unsigned char[]) \
|
||||
{ \
|
||||
0x00, 0x00, 0x80, 0x00, 0x00 \
|
||||
}
|
||||
/// Length of each Alpha numeric hcode
|
||||
#define USX_HCODE_LENS_ALPHA_NUM_ONLY (const unsigned char[]) {1, 0, 1, 0, 0}
|
||||
#define USX_HCODE_LENS_ALPHA_NUM_ONLY \
|
||||
(const unsigned char[]) \
|
||||
{ \
|
||||
1, 0, 1, 0, 0 \
|
||||
}
|
||||
|
||||
/// Horizontal codes preset for Alpha Numeric and Symbol content only
|
||||
#define USX_HCODES_ALPHA_NUM_SYM_ONLY (const unsigned char[]) {0x00, 0x80, 0xC0, 0x00, 0x00}
|
||||
#define USX_HCODES_ALPHA_NUM_SYM_ONLY \
|
||||
(const unsigned char[]) \
|
||||
{ \
|
||||
0x00, 0x80, 0xC0, 0x00, 0x00 \
|
||||
}
|
||||
/// Length of each Alpha numeric and symbol hcodes
|
||||
#define USX_HCODE_LENS_ALPHA_NUM_SYM_ONLY (const unsigned char[]) {1, 2, 2, 0, 0}
|
||||
#define USX_HCODE_LENS_ALPHA_NUM_SYM_ONLY \
|
||||
(const unsigned char[]) \
|
||||
{ \
|
||||
1, 2, 2, 0, 0 \
|
||||
}
|
||||
|
||||
/// Horizontal codes preset favouring Alphabet content
|
||||
#define USX_HCODES_FAVOR_ALPHA (const unsigned char[]) {0x00, 0x80, 0xA0, 0xC0, 0xE0}
|
||||
#define USX_HCODES_FAVOR_ALPHA \
|
||||
(const unsigned char[]) \
|
||||
{ \
|
||||
0x00, 0x80, 0xA0, 0xC0, 0xE0 \
|
||||
}
|
||||
/// Length of each hcode favouring Alpha content
|
||||
#define USX_HCODE_LENS_FAVOR_ALPHA (const unsigned char[]) {1, 3, 3, 3, 3}
|
||||
#define USX_HCODE_LENS_FAVOR_ALPHA \
|
||||
(const unsigned char[]) \
|
||||
{ \
|
||||
1, 3, 3, 3, 3 \
|
||||
}
|
||||
|
||||
/// Horizontal codes preset favouring repeating sequences
|
||||
#define USX_HCODES_FAVOR_DICT (const unsigned char[]) {0x00, 0x40, 0xC0, 0x80, 0xE0}
|
||||
#define USX_HCODES_FAVOR_DICT \
|
||||
(const unsigned char[]) \
|
||||
{ \
|
||||
0x00, 0x40, 0xC0, 0x80, 0xE0 \
|
||||
}
|
||||
/// Length of each hcode favouring repeating sequences
|
||||
#define USX_HCODE_LENS_FAVOR_DICT (const unsigned char[]) {2, 2, 3, 2, 3}
|
||||
#define USX_HCODE_LENS_FAVOR_DICT \
|
||||
(const unsigned char[]) \
|
||||
{ \
|
||||
2, 2, 3, 2, 3 \
|
||||
}
|
||||
|
||||
/// Horizontal codes preset favouring symbols
|
||||
#define USX_HCODES_FAVOR_SYM (const unsigned char[]) {0x80, 0x00, 0xA0, 0xC0, 0xE0}
|
||||
#define USX_HCODES_FAVOR_SYM \
|
||||
(const unsigned char[]) \
|
||||
{ \
|
||||
0x80, 0x00, 0xA0, 0xC0, 0xE0 \
|
||||
}
|
||||
/// Length of each hcode favouring symbols
|
||||
#define USX_HCODE_LENS_FAVOR_SYM (const unsigned char[]) {3, 1, 3, 3, 3}
|
||||
#define USX_HCODE_LENS_FAVOR_SYM \
|
||||
(const unsigned char[]) \
|
||||
{ \
|
||||
3, 1, 3, 3, 3 \
|
||||
}
|
||||
|
||||
//#define USX_HCODES_FAVOR_UMLAUT {0x00, 0x40, 0xE0, 0xC0, 0x80}
|
||||
//#define USX_HCODE_LENS_FAVOR_UMLAUT {2, 2, 3, 3, 2}
|
||||
|
||||
/// Horizontal codes preset favouring umlaut letters
|
||||
#define USX_HCODES_FAVOR_UMLAUT (const unsigned char[]) {0x80, 0xA0, 0xC0, 0xE0, 0x00}
|
||||
#define USX_HCODES_FAVOR_UMLAUT \
|
||||
(const unsigned char[]) \
|
||||
{ \
|
||||
0x80, 0xA0, 0xC0, 0xE0, 0x00 \
|
||||
}
|
||||
/// Length of each hcode favouring umlaut letters
|
||||
#define USX_HCODE_LENS_FAVOR_UMLAUT (const unsigned char[]) {3, 3, 3, 3, 1}
|
||||
#define USX_HCODE_LENS_FAVOR_UMLAUT \
|
||||
(const unsigned char[]) \
|
||||
{ \
|
||||
3, 3, 3, 3, 1 \
|
||||
}
|
||||
|
||||
/// Horizontal codes preset for no repeating sequences
|
||||
#define USX_HCODES_NO_DICT (const unsigned char[]) {0x00, 0x40, 0x80, 0x00, 0xC0}
|
||||
#define USX_HCODES_NO_DICT \
|
||||
(const unsigned char[]) \
|
||||
{ \
|
||||
0x00, 0x40, 0x80, 0x00, 0xC0 \
|
||||
}
|
||||
/// Length of each hcode for no repeating sequences
|
||||
#define USX_HCODE_LENS_NO_DICT (const unsigned char[]) {2, 2, 2, 0, 2}
|
||||
#define USX_HCODE_LENS_NO_DICT \
|
||||
(const unsigned char[]) \
|
||||
{ \
|
||||
2, 2, 2, 0, 2 \
|
||||
}
|
||||
|
||||
/// Horizontal codes preset for no Unicode characters
|
||||
#define USX_HCODES_NO_UNI (const unsigned char[]) {0x00, 0x40, 0x80, 0xC0, 0x00}
|
||||
#define USX_HCODES_NO_UNI \
|
||||
(const unsigned char[]) \
|
||||
{ \
|
||||
0x00, 0x40, 0x80, 0xC0, 0x00 \
|
||||
}
|
||||
/// Length of each hcode for no Unicode characters
|
||||
#define USX_HCODE_LENS_NO_UNI (const unsigned char[]) {2, 2, 2, 2, 0}
|
||||
#define USX_HCODE_LENS_NO_UNI \
|
||||
(const unsigned char[]) \
|
||||
{ \
|
||||
2, 2, 2, 2, 0 \
|
||||
}
|
||||
|
||||
/// Default frequently occuring sequences. When composition of text is know beforehand, the other sequences in this section can be used to achieve more compression.
|
||||
#define USX_FREQ_SEQ_DFLT (const char *[]) {"\": \"", "\": ", "</", "=\"", "\":\"", "://"}
|
||||
/// Default frequently occuring sequences. When composition of text is know beforehand, the other sequences in this section can be
|
||||
/// used to achieve more compression.
|
||||
#define USX_FREQ_SEQ_DFLT \
|
||||
(const char *[]) \
|
||||
{ \
|
||||
"\": \"", "\": ", "</", "=\"", "\":\"", "://" \
|
||||
}
|
||||
/// Frequently occuring sequences in text content
|
||||
#define USX_FREQ_SEQ_TXT (const char *[]) {" the ", " and ", "tion", " with", "ing", "ment"}
|
||||
#define USX_FREQ_SEQ_TXT \
|
||||
(const char *[]) \
|
||||
{ \
|
||||
" the ", " and ", "tion", " with", "ing", "ment" \
|
||||
}
|
||||
/// Frequently occuring sequences in URL content
|
||||
#define USX_FREQ_SEQ_URL (const char *[]) {"https://", "www.", ".com", "http://", ".org", ".net"}
|
||||
#define USX_FREQ_SEQ_URL \
|
||||
(const char *[]) \
|
||||
{ \
|
||||
"https://", "www.", ".com", "http://", ".org", ".net" \
|
||||
}
|
||||
/// Frequently occuring sequences in JSON content
|
||||
#define USX_FREQ_SEQ_JSON (const char *[]) {"\": \"", "\": ", "\",", "}}}", "\":\"", "}}"}
|
||||
#define USX_FREQ_SEQ_JSON \
|
||||
(const char *[]) \
|
||||
{ \
|
||||
"\": \"", "\": ", "\",", "}}}", "\":\"", "}}" \
|
||||
}
|
||||
/// Frequently occuring sequences in HTML content
|
||||
#define USX_FREQ_SEQ_HTML (const char *[]) {"</", "=\"", "div", "href", "class", "<p>"}
|
||||
#define USX_FREQ_SEQ_HTML \
|
||||
(const char *[]) \
|
||||
{ \
|
||||
"</", "=\"", "div", "href", "class", "<p>" \
|
||||
}
|
||||
/// Frequently occuring sequences in XML content
|
||||
#define USX_FREQ_SEQ_XML (const char *[]) {"</", "=\"", "\">", "<?xml version=\"1.0\"", "xmlns:", "://"}
|
||||
#define USX_FREQ_SEQ_XML \
|
||||
(const char *[]) \
|
||||
{ \
|
||||
"</", "=\"", "\">", "<?xml version=\"1.0\"", "xmlns:", "://" \
|
||||
}
|
||||
|
||||
/// Commonly occuring templates (ISO Date/Time, ISO Date, US Phone number, ISO Time, Unused)
|
||||
#define USX_TEMPLATES (const char *[]) {"tfff-of-tfTtf:rf:rf.fffZ", "tfff-of-tf", "(fff) fff-ffff", "tf:rf:rf", 0}
|
||||
#define USX_TEMPLATES \
|
||||
(const char *[]) \
|
||||
{ \
|
||||
"tfff-of-tfTtf:rf:rf.fffZ", "tfff-of-tf", "(fff) fff-ffff", "tf:rf:rf", 0 \
|
||||
}
|
||||
|
||||
/// Default preset parameter set. When composition of text is know beforehand, the other parameter sets in this section can be used to achieve more compression.
|
||||
/// Default preset parameter set. When composition of text is know beforehand, the other parameter sets in this section can be
|
||||
/// used to achieve more compression.
|
||||
#define USX_PSET_DFLT USX_HCODES_DFLT, USX_HCODE_LENS_DFLT, USX_FREQ_SEQ_DFLT, USX_TEMPLATES
|
||||
/// Preset parameter set for English Alphabet only content
|
||||
#define USX_PSET_ALPHA_ONLY USX_HCODES_ALPHA_ONLY, USX_HCODE_LENS_ALPHA_ONLY, USX_FREQ_SEQ_TXT, USX_TEMPLATES
|
||||
/// Preset parameter set for Alpha numeric content
|
||||
#define USX_PSET_ALPHA_NUM_ONLY USX_HCODES_ALPHA_NUM_ONLY, USX_HCODE_LENS_ALPHA_NUM_ONLY, USX_FREQ_SEQ_TXT, USX_TEMPLATES
|
||||
/// Preset parameter set for Alpha numeric and symbol content
|
||||
#define USX_PSET_ALPHA_NUM_SYM_ONLY USX_HCODES_ALPHA_NUM_SYM_ONLY, USX_HCODE_LENS_ALPHA_NUM_SYM_ONLY, USX_FREQ_SEQ_DFLT, USX_TEMPLATES
|
||||
#define USX_PSET_ALPHA_NUM_SYM_ONLY \
|
||||
USX_HCODES_ALPHA_NUM_SYM_ONLY, USX_HCODE_LENS_ALPHA_NUM_SYM_ONLY, USX_FREQ_SEQ_DFLT, USX_TEMPLATES
|
||||
/// Preset parameter set for Alpha numeric symbol content having predominantly text
|
||||
#define USX_PSET_ALPHA_NUM_SYM_ONLY_TXT USX_HCODES_ALPHA_NUM_SYM_ONLY, USX_HCODE_LENS_ALPHA_NUM_SYM_ONLY, USX_FREQ_SEQ_DFLT, USX_TEMPLATES
|
||||
#define USX_PSET_ALPHA_NUM_SYM_ONLY_TXT \
|
||||
USX_HCODES_ALPHA_NUM_SYM_ONLY, USX_HCODE_LENS_ALPHA_NUM_SYM_ONLY, USX_FREQ_SEQ_DFLT, USX_TEMPLATES
|
||||
/// Preset parameter set favouring Alphabet content
|
||||
#define USX_PSET_FAVOR_ALPHA USX_HCODES_FAVOR_ALPHA, USX_HCODE_LENS_FAVOR_ALPHA, USX_FREQ_SEQ_TXT, USX_TEMPLATES
|
||||
/// Preset parameter set favouring repeating sequences
|
||||
@@ -173,8 +286,8 @@
|
||||
* This is passed as a parameter to the unishox2_decompress_lines() function
|
||||
*/
|
||||
struct us_lnk_lst {
|
||||
char *data;
|
||||
struct us_lnk_lst *previous;
|
||||
char *data;
|
||||
struct us_lnk_lst *previous;
|
||||
};
|
||||
|
||||
/**
|
||||
@@ -188,32 +301,32 @@ struct us_lnk_lst {
|
||||
* for output length is not performed at each step
|
||||
*/
|
||||
#if defined(UNISHOX_API_WITH_OUTPUT_LEN) && UNISHOX_API_WITH_OUTPUT_LEN != 0
|
||||
# define UNISHOX_API_OUT_AND_LEN(out, olen) out, olen
|
||||
#define UNISHOX_API_OUT_AND_LEN(out, olen) out, olen
|
||||
#else
|
||||
# define UNISHOX_API_OUT_AND_LEN(out, olen) out
|
||||
#define UNISHOX_API_OUT_AND_LEN(out, olen) out
|
||||
#endif
|
||||
|
||||
/**
|
||||
/**
|
||||
* Simple API for compressing a string
|
||||
* @param[in] in Input ASCII / UTF-8 string
|
||||
* @param[in] len length in bytes
|
||||
* @param[out] out output buffer - should be large enough to hold compressed output
|
||||
*/
|
||||
extern int unishox2_compress_simple(const char *in, int len, char *out);
|
||||
/**
|
||||
/**
|
||||
* Simple API for decompressing a string
|
||||
* @param[in] in Input compressed bytes (output of unishox2_compress functions)
|
||||
* @param[in] len length of 'in' in bytes
|
||||
* @param[out] out output buffer for ASCII / UTF-8 string - should be large enough
|
||||
*/
|
||||
extern int unishox2_decompress_simple(const char *in, int len, char *out);
|
||||
/**
|
||||
/**
|
||||
* Comprehensive API for compressing a string
|
||||
*
|
||||
*
|
||||
* Presets are available for the last four parameters so they can be passed as single parameter. \n
|
||||
* See USX_PSET_* macros. Example call: \n
|
||||
* unishox2_compress(in, len, out, olen, USX_PSET_ALPHA_ONLY);
|
||||
*
|
||||
*
|
||||
* @param[in] in Input ASCII / UTF-8 string
|
||||
* @param[in] len length in bytes
|
||||
* @param[out] out output buffer - should be large enough to hold compressed output
|
||||
@@ -224,15 +337,15 @@ extern int unishox2_decompress_simple(const char *in, int len, char *out);
|
||||
* @param[in] usx_templates Templates of frequently occuring patterns. See USX_TEMPLATES macro.
|
||||
*/
|
||||
extern int unishox2_compress(const char *in, int len, UNISHOX_API_OUT_AND_LEN(char *out, int olen),
|
||||
const unsigned char usx_hcodes[], const unsigned char usx_hcode_lens[],
|
||||
const char *usx_freq_seq[], const char *usx_templates[]);
|
||||
/**
|
||||
const unsigned char usx_hcodes[], const unsigned char usx_hcode_lens[], const char *usx_freq_seq[],
|
||||
const char *usx_templates[]);
|
||||
/**
|
||||
* Comprehensive API for de-compressing a string
|
||||
*
|
||||
*
|
||||
* Presets are available for the last four parameters so they can be passed as single parameter. \n
|
||||
* See USX_PSET_* macros. Example call: \n
|
||||
* unishox2_decompress(in, len, out, olen, USX_PSET_ALPHA_ONLY);
|
||||
*
|
||||
*
|
||||
* @param[in] in Input compressed bytes (output of unishox2_compress functions)
|
||||
* @param[in] len length of 'in' in bytes
|
||||
* @param[out] out output buffer - should be large enough to hold de-compressed output
|
||||
@@ -243,11 +356,11 @@ extern int unishox2_compress(const char *in, int len, UNISHOX_API_OUT_AND_LEN(ch
|
||||
* @param[in] usx_templates Templates of frequently occuring patterns. See USX_TEMPLATES macro.
|
||||
*/
|
||||
extern int unishox2_decompress(const char *in, int len, UNISHOX_API_OUT_AND_LEN(char *out, int olen),
|
||||
const unsigned char usx_hcodes[], const unsigned char usx_hcode_lens[],
|
||||
const char *usx_freq_seq[], const char *usx_templates[]);
|
||||
/**
|
||||
const unsigned char usx_hcodes[], const unsigned char usx_hcode_lens[], const char *usx_freq_seq[],
|
||||
const char *usx_templates[]);
|
||||
/**
|
||||
* More Comprehensive API for compressing array of strings
|
||||
*
|
||||
*
|
||||
* See unishox2_compress() function for parameter definitions. \n
|
||||
* This function takes an additional parameter, i.e. 'prev_lines' - the usx_lnk_lst structure \n
|
||||
* See -g parameter in test_unishox2.c to find out how this can be used. \n
|
||||
@@ -256,13 +369,12 @@ extern int unishox2_decompress(const char *in, int len, UNISHOX_API_OUT_AND_LEN(
|
||||
* where each element of the array can be decompressed and used at runtime.
|
||||
*/
|
||||
extern int unishox2_compress_lines(const char *in, int len, UNISHOX_API_OUT_AND_LEN(char *out, int olen),
|
||||
const unsigned char usx_hcodes[], const unsigned char usx_hcode_lens[],
|
||||
const char *usx_freq_seq[], const char *usx_templates[],
|
||||
struct us_lnk_lst *prev_lines);
|
||||
/**
|
||||
const unsigned char usx_hcodes[], const unsigned char usx_hcode_lens[],
|
||||
const char *usx_freq_seq[], const char *usx_templates[], struct us_lnk_lst *prev_lines);
|
||||
/**
|
||||
* More Comprehensive API for de-compressing array of strings \n
|
||||
* This function is not be used in conjuction with unishox2_compress_lines()
|
||||
*
|
||||
*
|
||||
* See unishox2_decompress() function for parameter definitions. \n
|
||||
* Typically an array is compressed using unishox2_compress_lines() and \n
|
||||
* a header (.h) file is generated using the resultant compressed array. \n
|
||||
@@ -271,8 +383,7 @@ extern int unishox2_compress_lines(const char *in, int len, UNISHOX_API_OUT_AND_
|
||||
* decompressed.
|
||||
*/
|
||||
extern int unishox2_decompress_lines(const char *in, int len, UNISHOX_API_OUT_AND_LEN(char *out, int olen),
|
||||
const unsigned char usx_hcodes[], const unsigned char usx_hcode_lens[],
|
||||
const char *usx_freq_seq[], const char *usx_templates[],
|
||||
struct us_lnk_lst *prev_lines);
|
||||
const unsigned char usx_hcodes[], const unsigned char usx_hcode_lens[],
|
||||
const char *usx_freq_seq[], const char *usx_templates[], struct us_lnk_lst *prev_lines);
|
||||
|
||||
#endif
|
||||
|
||||
+20
-15
@@ -2,11 +2,11 @@
|
||||
#include "NodeDB.h"
|
||||
#include "RTC.h"
|
||||
#include "concurrency/Periodic.h"
|
||||
#include <SPI.h>
|
||||
#include <RAK13800_W5100S.h>
|
||||
#include "target_specific.h"
|
||||
#include "mesh/api/ethServerAPI.h"
|
||||
#include "mqtt/MQTT.h"
|
||||
#include "target_specific.h"
|
||||
#include <RAK13800_W5100S.h>
|
||||
#include <SPI.h>
|
||||
|
||||
#ifndef DISABLE_NTP
|
||||
#include <NTPClient.h>
|
||||
@@ -35,7 +35,7 @@ static int32_t reconnectETH()
|
||||
LOG_INFO("Starting NTP time client\n");
|
||||
timeClient.begin();
|
||||
timeClient.setUpdateInterval(60 * 60); // Update once an hour
|
||||
#endif
|
||||
#endif
|
||||
// initWebServer();
|
||||
initApiServer();
|
||||
|
||||
@@ -50,7 +50,7 @@ static int32_t reconnectETH()
|
||||
|
||||
#ifndef DISABLE_NTP
|
||||
if (isEthernetAvailable() && (ntp_renew < millis())) {
|
||||
|
||||
|
||||
LOG_INFO("Updating NTP time from %s\n", config.network.ntp_server);
|
||||
if (timeClient.update()) {
|
||||
LOG_DEBUG("NTP Request Success - Setting RTCQualityNTP if needed\n");
|
||||
@@ -80,12 +80,12 @@ bool initEthernet()
|
||||
|
||||
#ifdef PIN_ETHERNET_RESET
|
||||
pinMode(PIN_ETHERNET_RESET, OUTPUT);
|
||||
digitalWrite(PIN_ETHERNET_RESET, LOW); // Reset Time.
|
||||
digitalWrite(PIN_ETHERNET_RESET, LOW); // Reset Time.
|
||||
delay(100);
|
||||
digitalWrite(PIN_ETHERNET_RESET, HIGH); // Reset Time.
|
||||
digitalWrite(PIN_ETHERNET_RESET, HIGH); // Reset Time.
|
||||
#endif
|
||||
|
||||
Ethernet.init( ETH_SPI_PORT, PIN_ETHERNET_SS );
|
||||
Ethernet.init(ETH_SPI_PORT, PIN_ETHERNET_SS);
|
||||
|
||||
uint8_t mac[6];
|
||||
|
||||
@@ -94,7 +94,7 @@ bool initEthernet()
|
||||
// createSSLCert();
|
||||
|
||||
getMacAddr(mac); // FIXME use the BLE MAC for now...
|
||||
mac[0] &= 0xfe; // Make sure this is not a multicast MAC
|
||||
mac[0] &= 0xfe; // Make sure this is not a multicast MAC
|
||||
|
||||
if (config.network.address_mode == Config_NetworkConfig_AddressMode_DHCP) {
|
||||
LOG_INFO("starting Ethernet DHCP\n");
|
||||
@@ -114,15 +114,19 @@ bool initEthernet()
|
||||
} else if (Ethernet.linkStatus() == LinkOFF) {
|
||||
LOG_ERROR("Ethernet cable is not connected.\n");
|
||||
return false;
|
||||
} else{
|
||||
} else {
|
||||
LOG_ERROR("Unknown Ethernet error.\n");
|
||||
return false;
|
||||
}
|
||||
} else {
|
||||
LOG_INFO("Local IP %u.%u.%u.%u\n",Ethernet.localIP()[0], Ethernet.localIP()[1], Ethernet.localIP()[2], Ethernet.localIP()[3]);
|
||||
LOG_INFO("Subnet Mask %u.%u.%u.%u\n",Ethernet.subnetMask()[0], Ethernet.subnetMask()[1], Ethernet.subnetMask()[2], Ethernet.subnetMask()[3]);
|
||||
LOG_INFO("Gateway IP %u.%u.%u.%u\n",Ethernet.gatewayIP()[0], Ethernet.gatewayIP()[1], Ethernet.gatewayIP()[2], Ethernet.gatewayIP()[3]);
|
||||
LOG_INFO("DNS Server IP %u.%u.%u.%u\n",Ethernet.dnsServerIP()[0], Ethernet.dnsServerIP()[1], Ethernet.dnsServerIP()[2], Ethernet.dnsServerIP()[3]);
|
||||
LOG_INFO("Local IP %u.%u.%u.%u\n", Ethernet.localIP()[0], Ethernet.localIP()[1], Ethernet.localIP()[2],
|
||||
Ethernet.localIP()[3]);
|
||||
LOG_INFO("Subnet Mask %u.%u.%u.%u\n", Ethernet.subnetMask()[0], Ethernet.subnetMask()[1], Ethernet.subnetMask()[2],
|
||||
Ethernet.subnetMask()[3]);
|
||||
LOG_INFO("Gateway IP %u.%u.%u.%u\n", Ethernet.gatewayIP()[0], Ethernet.gatewayIP()[1], Ethernet.gatewayIP()[2],
|
||||
Ethernet.gatewayIP()[3]);
|
||||
LOG_INFO("DNS Server IP %u.%u.%u.%u\n", Ethernet.dnsServerIP()[0], Ethernet.dnsServerIP()[1],
|
||||
Ethernet.dnsServerIP()[2], Ethernet.dnsServerIP()[3]);
|
||||
}
|
||||
|
||||
ethEvent = new Periodic("ethConnect", reconnectETH);
|
||||
@@ -135,7 +139,8 @@ bool initEthernet()
|
||||
}
|
||||
}
|
||||
|
||||
bool isEthernetAvailable() {
|
||||
bool isEthernetAvailable()
|
||||
{
|
||||
|
||||
if (!config.network.eth_enabled) {
|
||||
return false;
|
||||
|
||||
@@ -6,13 +6,13 @@
|
||||
#include "mesh/http/ContentHelper.h"
|
||||
#include "mesh/http/WebServer.h"
|
||||
#include "mesh/http/WiFiAPClient.h"
|
||||
#include "mqtt/JSON.h"
|
||||
#include "power.h"
|
||||
#include "sleep.h"
|
||||
#include <FSCommon.h>
|
||||
#include <HTTPBodyParser.hpp>
|
||||
#include <HTTPMultipartBodyParser.hpp>
|
||||
#include <HTTPURLEncodedBodyParser.hpp>
|
||||
#include "mqtt/JSON.h"
|
||||
|
||||
#ifdef ARCH_ESP32
|
||||
#include "esp_task_wdt.h"
|
||||
@@ -321,7 +321,7 @@ void handleFsBrowseStatic(HTTPRequest *req, HTTPResponse *res)
|
||||
|
||||
res->print(value->Stringify().c_str());
|
||||
|
||||
delete value;
|
||||
delete value;
|
||||
}
|
||||
|
||||
void handleFsDeleteStatic(HTTPRequest *req, HTTPResponse *res)
|
||||
@@ -336,7 +336,7 @@ void handleFsDeleteStatic(HTTPRequest *req, HTTPResponse *res)
|
||||
std::string pathDelete = "/" + paramValDelete;
|
||||
if (FSCom.remove(pathDelete.c_str())) {
|
||||
LOG_INFO("%s\n", pathDelete.c_str());
|
||||
JSONObject jsonObjOuter;
|
||||
JSONObject jsonObjOuter;
|
||||
jsonObjOuter["status"] = new JSONValue("ok");
|
||||
JSONValue *value = new JSONValue(jsonObjOuter);
|
||||
res->print(value->Stringify().c_str());
|
||||
|
||||
@@ -1,6 +1,5 @@
|
||||
#pragma once
|
||||
|
||||
|
||||
void registerHandlers(HTTPServer *insecureServer, HTTPSServer *secureServer);
|
||||
|
||||
// Declare some handler functions for the various URLs on the server
|
||||
@@ -22,7 +21,6 @@ void handleAdmin(HTTPRequest *req, HTTPResponse *res);
|
||||
void handleAdminSettings(HTTPRequest *req, HTTPResponse *res);
|
||||
void handleAdminSettingsApply(HTTPRequest *req, HTTPResponse *res);
|
||||
|
||||
|
||||
// Interface to the PhoneAPI to access the protobufs with messages
|
||||
class HttpAPI : public PhoneAPI
|
||||
{
|
||||
@@ -34,7 +32,6 @@ class HttpAPI : public PhoneAPI
|
||||
// Nothing here yet
|
||||
|
||||
protected:
|
||||
|
||||
/// Check the current underlying physical link to see if the client is currently connected
|
||||
virtual bool checkIsConnected() override { return true; } // FIXME, be smarter about this
|
||||
};
|
||||
|
||||
@@ -152,7 +152,7 @@ void createSSLCert()
|
||||
if (millis() / 1000 >= 3) {
|
||||
screen->setSSLFrames();
|
||||
}
|
||||
#endif
|
||||
#endif
|
||||
}
|
||||
runLoop = false;
|
||||
} else {
|
||||
@@ -165,7 +165,8 @@ void createSSLCert()
|
||||
|
||||
WebServerThread *webServerThread;
|
||||
|
||||
WebServerThread::WebServerThread() : concurrency::OSThread("WebServerThread") {
|
||||
WebServerThread::WebServerThread() : concurrency::OSThread("WebServerThread")
|
||||
{
|
||||
if (!config.network.wifi_enabled) {
|
||||
disable();
|
||||
}
|
||||
|
||||
@@ -1,17 +1,17 @@
|
||||
#include "mesh/http/WiFiAPClient.h"
|
||||
#include "NodeDB.h"
|
||||
#include "RTC.h"
|
||||
#include "concurrency/Periodic.h"
|
||||
#include "mesh/http/WiFiAPClient.h"
|
||||
#include "configuration.h"
|
||||
#include "main.h"
|
||||
#include "mesh/http/WebServer.h"
|
||||
#include "mesh/api/WiFiServerAPI.h"
|
||||
#include "mesh/http/WebServer.h"
|
||||
#include "mqtt/MQTT.h"
|
||||
#include "target_specific.h"
|
||||
#include <ESPmDNS.h>
|
||||
#include <esp_wifi.h>
|
||||
#include <WiFi.h>
|
||||
#include <WiFiUdp.h>
|
||||
#include <esp_wifi.h>
|
||||
|
||||
#ifndef DISABLE_NTP
|
||||
#include <NTPClient.h>
|
||||
@@ -47,7 +47,7 @@ static int32_t reconnectWiFi()
|
||||
const char *wifiPsw = config.network.wifi_psk;
|
||||
|
||||
if (config.network.wifi_enabled && needReconnect) {
|
||||
|
||||
|
||||
if (!*wifiPsw) // Treat empty password as no password
|
||||
wifiPsw = NULL;
|
||||
|
||||
@@ -55,7 +55,7 @@ static int32_t reconnectWiFi()
|
||||
|
||||
// Make sure we clear old connection credentials
|
||||
WiFi.disconnect(false, true);
|
||||
LOG_INFO("Reconnecting to WiFi access point %s\n",wifiName);
|
||||
LOG_INFO("Reconnecting to WiFi access point %s\n", wifiName);
|
||||
|
||||
delay(5000);
|
||||
|
||||
@@ -66,7 +66,7 @@ static int32_t reconnectWiFi()
|
||||
|
||||
#ifndef DISABLE_NTP
|
||||
if (WiFi.isConnected() && (((millis() - lastrun_ntp) > 43200000) || (lastrun_ntp == 0))) { // every 12 hours
|
||||
LOG_DEBUG("Updating NTP time from %s\n",config.network.ntp_server);
|
||||
LOG_DEBUG("Updating NTP time from %s\n", config.network.ntp_server);
|
||||
if (timeClient.update()) {
|
||||
LOG_DEBUG("NTP Request Success - Setting RTCQualityNTP if needed\n");
|
||||
|
||||
@@ -172,10 +172,8 @@ bool initWifi()
|
||||
WiFi.setAutoReconnect(true);
|
||||
WiFi.setSleep(false);
|
||||
if (config.network.address_mode == Config_NetworkConfig_AddressMode_STATIC && config.network.ipv4_config.ip != 0) {
|
||||
WiFi.config(config.network.ipv4_config.ip,
|
||||
config.network.ipv4_config.gateway,
|
||||
config.network.ipv4_config.subnet,
|
||||
config.network.ipv4_config.dns,
|
||||
WiFi.config(config.network.ipv4_config.ip, config.network.ipv4_config.gateway, config.network.ipv4_config.subnet,
|
||||
config.network.ipv4_config.dns,
|
||||
config.network.ipv4_config.dns); // Wifi wants two DNS servers... set both to the same value
|
||||
}
|
||||
|
||||
@@ -184,7 +182,6 @@ bool initWifi()
|
||||
|
||||
WiFi.onEvent(
|
||||
[](WiFiEvent_t event, WiFiEventInfo_t info) {
|
||||
|
||||
LOG_WARN("WiFi lost connection. Reason: %d\n", info.wifi_sta_disconnected.reason);
|
||||
|
||||
/*
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
#pragma once
|
||||
|
||||
#include "configuration.h"
|
||||
#include "concurrency/Periodic.h"
|
||||
#include "configuration.h"
|
||||
#include <Arduino.h>
|
||||
#include <functional>
|
||||
|
||||
|
||||
@@ -13,7 +13,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);
|
||||
if (!pb_encode(&stream, fields, src_struct)) {
|
||||
LOG_ERROR("Panic: can't encode protobuf reason='%s'\n", PB_GET_ERROR(&stream));
|
||||
assert(0); // If this asser fails it probably means you made a field too large for the max limits specified in mesh.options
|
||||
assert(
|
||||
0); // If this asser fails it probably means you made a field too large for the max limits specified in mesh.options
|
||||
} else {
|
||||
return stream.bytes_written;
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user