mirror of
https://github.com/meshtastic/firmware.git
synced 2025-06-16 01:52:04 +00:00
Merge branch 'develop' of github.com:meshtastic/firmware into xmodem-proto
This commit is contained in:
commit
80d1a993dd
@ -8,7 +8,7 @@ build_flags =
|
|||||||
${arduino_base.build_flags} -Wno-unused-variable
|
${arduino_base.build_flags} -Wno-unused-variable
|
||||||
-Isrc/platform/nrf52
|
-Isrc/platform/nrf52
|
||||||
build_src_filter =
|
build_src_filter =
|
||||||
${arduino_base.build_src_filter} -<platform/esp32/> -<platform/stm32wl> -<nimble/> -<mesh/wifi/> -<mesh/http/> -<modules/esp32> -<mqtt/> -<platform/rp2040> -<mesh/eth/>
|
${arduino_base.build_src_filter} -<platform/esp32/> -<platform/stm32wl> -<nimble/> -<mesh/api/> -<mesh/http/> -<modules/esp32> -<mqtt/> -<platform/rp2040> -<mesh/eth/>
|
||||||
lib_ignore =
|
lib_ignore =
|
||||||
BluetoothOTA
|
BluetoothOTA
|
||||||
|
|
||||||
|
@ -12,7 +12,7 @@ build_flags =
|
|||||||
-D__PLAT_RP2040__
|
-D__PLAT_RP2040__
|
||||||
# -D _POSIX_THREADS
|
# -D _POSIX_THREADS
|
||||||
build_src_filter =
|
build_src_filter =
|
||||||
${arduino_base.build_src_filter} -<platform/esp32/> -<nimble/> -<mesh/wifi/> -<mesh/http/> -<modules/esp32> -<mqtt/> -<platform/nrf52/> -<platform/stm32wl> -<mesh/eth/>
|
${arduino_base.build_src_filter} -<platform/esp32/> -<nimble/> -<mesh/api/> -<mesh/http/> -<modules/esp32> -<mqtt/> -<platform/nrf52/> -<platform/stm32wl> -<mesh/eth/>
|
||||||
lib_ignore =
|
lib_ignore =
|
||||||
BluetoothOTA
|
BluetoothOTA
|
||||||
lib_deps =
|
lib_deps =
|
||||||
|
@ -10,7 +10,7 @@ build_flags =
|
|||||||
# Arduino/PlatformIO framework-arduinoststm32 package does not presently have SUBGHZSPI support
|
# Arduino/PlatformIO framework-arduinoststm32 package does not presently have SUBGHZSPI support
|
||||||
# -DPIN_SPI_MOSI=PINSUBGHZSPIMOSI -DPIN_SPI_MISO=PINSUBGHZSPIMISO -DPIN_SPI_SCK=PINSUBGHZSPISCK
|
# -DPIN_SPI_MOSI=PINSUBGHZSPIMOSI -DPIN_SPI_MISO=PINSUBGHZSPIMISO -DPIN_SPI_SCK=PINSUBGHZSPISCK
|
||||||
build_src_filter =
|
build_src_filter =
|
||||||
${arduino_base.build_src_filter} -<platform/esp32/> -<nimble/> -<mesh/wifi/> -<mesh/http/> -<modules/esp32> -<mesh/eth/> -<mqtt/> -<graphics> -<input> -<buzz> -<modules/Telemetry> -<platform/nrf52> -<platform/portduino> -<platform/rp2040>
|
${arduino_base.build_src_filter} -<platform/esp32/> -<nimble/> -<mesh/api/> -<mesh/http/> -<modules/esp32> -<mesh/eth/> -<mqtt/> -<graphics> -<input> -<buzz> -<modules/Telemetry> -<platform/nrf52> -<platform/portduino> -<platform/rp2040>
|
||||||
lib_deps =
|
lib_deps =
|
||||||
${env.lib_deps}
|
${env.lib_deps}
|
||||||
https://github.com/kokke/tiny-AES-c.git#f06ac37fc31dfdaca2e0d9bec83f90d5663c319b
|
https://github.com/kokke/tiny-AES-c.git#f06ac37fc31dfdaca2e0d9bec83f90d5663c319b
|
||||||
|
@ -1 +1 @@
|
|||||||
Subproject commit 3b0d871ca1e0f8a2ed823f0696e2d7cf31ed2ebd
|
Subproject commit e00b5ba7d06053d820f1123351881fc4fa9270d1
|
@ -3,7 +3,6 @@
|
|||||||
#include "RTC.h"
|
#include "RTC.h"
|
||||||
#include "NodeDB.h"
|
#include "NodeDB.h"
|
||||||
#include "concurrency/OSThread.h"
|
#include "concurrency/OSThread.h"
|
||||||
// #include "wifi/WiFiServerAPI.h"
|
|
||||||
#include <assert.h>
|
#include <assert.h>
|
||||||
#include <sys/time.h>
|
#include <sys/time.h>
|
||||||
#include <time.h>
|
#include <time.h>
|
||||||
@ -27,10 +26,6 @@ size_t RedirectablePrint::write(uint8_t c)
|
|||||||
SEGGER_RTT_PutChar(SEGGER_STDOUT_CH, c);
|
SEGGER_RTT_PutChar(SEGGER_STDOUT_CH, c);
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
// FIXME - clean this up, the whole relationship of this class to SerialConsole to TCP/bluetooth debug log output is kinda messed up. But for now, just have this hack to
|
|
||||||
// optionally send chars to TCP also
|
|
||||||
//WiFiServerPort::debugOut(c);
|
|
||||||
|
|
||||||
if (!config.has_lora || config.device.serial_enabled)
|
if (!config.has_lora || config.device.serial_enabled)
|
||||||
dest->write(c);
|
dest->write(c);
|
||||||
|
|
||||||
@ -108,3 +103,31 @@ size_t RedirectablePrint::log(const char *logLevel, const char *format, ...)
|
|||||||
|
|
||||||
return r;
|
return r;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void RedirectablePrint::hexDump(const char *logLevel, unsigned char *buf, uint16_t len) {
|
||||||
|
const char alphabet[17] = "0123456789abcdef";
|
||||||
|
log(logLevel, " +------------------------------------------------+ +----------------+\n");
|
||||||
|
log(logLevel, " |.0 .1 .2 .3 .4 .5 .6 .7 .8 .9 .a .b .c .d .e .f | | ASCII |\n");
|
||||||
|
for (uint16_t i = 0; i < len; i += 16) {
|
||||||
|
if (i % 128 == 0)
|
||||||
|
log(logLevel, " +------------------------------------------------+ +----------------+\n");
|
||||||
|
char s[] = "| | | |\n";
|
||||||
|
uint8_t ix = 1, iy = 52;
|
||||||
|
for (uint8_t j = 0; j < 16; j++) {
|
||||||
|
if (i + j < len) {
|
||||||
|
uint8_t c = buf[i + j];
|
||||||
|
s[ix++] = alphabet[(c >> 4) & 0x0F];
|
||||||
|
s[ix++] = alphabet[c & 0x0F];
|
||||||
|
ix++;
|
||||||
|
if (c > 31 && c < 128) s[iy++] = c;
|
||||||
|
else s[iy++] = '.';
|
||||||
|
}
|
||||||
|
}
|
||||||
|
uint8_t index = i / 16;
|
||||||
|
if (i < 256) log(logLevel, " ");
|
||||||
|
log(logLevel, "%02x",index);
|
||||||
|
log(logLevel, ".");
|
||||||
|
log(logLevel, s);
|
||||||
|
}
|
||||||
|
log(logLevel, " +------------------------------------------------+ +----------------+\n");
|
||||||
|
}
|
||||||
|
@ -38,6 +38,8 @@ class RedirectablePrint : public Print
|
|||||||
|
|
||||||
/** like printf but va_list based */
|
/** like printf but va_list based */
|
||||||
size_t vprintf(const char *format, va_list arg);
|
size_t vprintf(const char *format, va_list arg);
|
||||||
|
|
||||||
|
void hexDump(const char *logLevel, unsigned char *buf, uint16_t len);
|
||||||
};
|
};
|
||||||
|
|
||||||
class NoopPrint : public Print
|
class NoopPrint : public Print
|
||||||
|
@ -117,6 +117,31 @@ float AirTime::utilizationTXPercent()
|
|||||||
return (float(sum) / float(MS_IN_HOUR)) * 100;
|
return (float(sum) / float(MS_IN_HOUR)) * 100;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
bool AirTime::isTxAllowedChannelUtil(bool polite)
|
||||||
|
{
|
||||||
|
uint8_t percentage = (polite ? polite_channel_util_percent : max_channel_util_percent);
|
||||||
|
if (channelUtilizationPercent() < percentage) {
|
||||||
|
return true;
|
||||||
|
} else {
|
||||||
|
LOG_WARN("Channel utilization is >%d percent. Skipping this opportunity to send.\n", percentage);
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
bool AirTime::isTxAllowedAirUtil()
|
||||||
|
{
|
||||||
|
if (!config.lora.override_duty_cycle && myRegion->dutyCycle < 100) {
|
||||||
|
if (utilizationTXPercent() < polite_tx_util_percent) {
|
||||||
|
return true;
|
||||||
|
} else {
|
||||||
|
LOG_WARN("Tx air utilization is >%d percent. Skipping this opportunity to send.\n", polite_tx_util_percent);
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
// Get the amount of minutes we have to be silent before we can send again
|
// Get the amount of minutes we have to be silent before we can send again
|
||||||
uint8_t AirTime::getSilentMinutes(float txPercent, float dutyCycle)
|
uint8_t AirTime::getSilentMinutes(float txPercent, float dutyCycle)
|
||||||
{
|
{
|
||||||
|
@ -4,6 +4,7 @@
|
|||||||
#include "configuration.h"
|
#include "configuration.h"
|
||||||
#include <Arduino.h>
|
#include <Arduino.h>
|
||||||
#include <functional>
|
#include <functional>
|
||||||
|
#include "MeshRadio.h"
|
||||||
|
|
||||||
/*
|
/*
|
||||||
TX_LOG - Time on air this device has transmitted
|
TX_LOG - Time on air this device has transmitted
|
||||||
@ -59,12 +60,17 @@ class AirTime : private concurrency::OSThread
|
|||||||
uint32_t getSecondsSinceBoot();
|
uint32_t getSecondsSinceBoot();
|
||||||
uint32_t *airtimeReport(reportTypes reportType);
|
uint32_t *airtimeReport(reportTypes reportType);
|
||||||
uint8_t getSilentMinutes(float txPercent, float dutyCycle);
|
uint8_t getSilentMinutes(float txPercent, float dutyCycle);
|
||||||
|
bool isTxAllowedChannelUtil(bool polite=false);
|
||||||
|
bool isTxAllowedAirUtil();
|
||||||
|
|
||||||
private:
|
private:
|
||||||
bool firstTime = true;
|
bool firstTime = true;
|
||||||
uint8_t lastUtilPeriod = 0;
|
uint8_t lastUtilPeriod = 0;
|
||||||
uint8_t lastUtilPeriodTX = 0;
|
uint8_t lastUtilPeriodTX = 0;
|
||||||
uint32_t secSinceBoot = 0;
|
uint32_t secSinceBoot = 0;
|
||||||
|
uint8_t max_channel_util_percent = 40;
|
||||||
|
uint8_t polite_channel_util_percent = 25;
|
||||||
|
uint8_t polite_tx_util_percent = 5;
|
||||||
|
|
||||||
struct airtimeStruct {
|
struct airtimeStruct {
|
||||||
uint32_t periodTX[PERIODS_TO_LOG]; // AirTime transmitted
|
uint32_t periodTX[PERIODS_TO_LOG]; // AirTime transmitted
|
||||||
|
@ -36,12 +36,12 @@
|
|||||||
#endif
|
#endif
|
||||||
|
|
||||||
#if HAS_WIFI
|
#if HAS_WIFI
|
||||||
#include "mesh/wifi/WiFiServerAPI.h"
|
#include "mesh/api/WiFiServerAPI.h"
|
||||||
#include "mqtt/MQTT.h"
|
#include "mqtt/MQTT.h"
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#if HAS_ETHERNET
|
#if HAS_ETHERNET
|
||||||
#include "mesh/eth/ethServerAPI.h"
|
#include "mesh/api/ethServerAPI.h"
|
||||||
#include "mqtt/MQTT.h"
|
#include "mqtt/MQTT.h"
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
@ -239,7 +239,7 @@ void setup()
|
|||||||
#ifdef RAK4630
|
#ifdef RAK4630
|
||||||
// We need to enable 3.3V periphery in order to scan it
|
// We need to enable 3.3V periphery in order to scan it
|
||||||
pinMode(PIN_3V3_EN, OUTPUT);
|
pinMode(PIN_3V3_EN, OUTPUT);
|
||||||
digitalWrite(PIN_3V3_EN, 1);
|
digitalWrite(PIN_3V3_EN, HIGH);
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
// Currently only the tbeam has a PMU
|
// Currently only the tbeam has a PMU
|
||||||
|
@ -210,7 +210,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++) {
|
for (ChannelIndex i = 0; i < getNumChannels(); i++) {
|
||||||
if (strcasecmp(channelFile.channels[i].settings.name, chName) == 0) {
|
if (strcasecmp(getGlobalId(i), chName) == 0) {
|
||||||
return channelFile.channels[i];
|
return channelFile.channels[i];
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -2,9 +2,23 @@
|
|||||||
#include "SX126xInterface.cpp"
|
#include "SX126xInterface.cpp"
|
||||||
#include "SX128xInterface.h"
|
#include "SX128xInterface.h"
|
||||||
#include "SX128xInterface.cpp"
|
#include "SX128xInterface.cpp"
|
||||||
|
#include "api/ServerAPI.h"
|
||||||
|
#include "api/ServerAPI.cpp"
|
||||||
|
|
||||||
// We need this declaration for proper linking in derived classes
|
// We need this declaration for proper linking in derived classes
|
||||||
template class SX126xInterface<SX1262>;
|
template class SX126xInterface<SX1262>;
|
||||||
template class SX126xInterface<SX1268>;
|
template class SX126xInterface<SX1268>;
|
||||||
template class SX126xInterface<LLCC68>;
|
template class SX126xInterface<LLCC68>;
|
||||||
template class SX128xInterface<SX1280>;
|
template class SX128xInterface<SX1280>;
|
||||||
|
|
||||||
|
#if HAS_ETHERNET
|
||||||
|
#include "api/ethServerAPI.h"
|
||||||
|
template class ServerAPI<EthernetClient>;
|
||||||
|
template class APIServerPort<ethServerAPI, EthernetServer>;
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#if HAS_WIFI
|
||||||
|
#include "api/WiFiServerAPI.h"
|
||||||
|
template class ServerAPI<WiFiClient>;
|
||||||
|
template class APIServerPort<WiFiServerAPI, WiFiServer>;
|
||||||
|
#endif
|
@ -280,8 +280,7 @@ NodeInfo *MeshService::refreshMyNodeInfo()
|
|||||||
node->last_heard =
|
node->last_heard =
|
||||||
getValidTime(RTCQualityFromNet); // This nodedb timestamp might be stale, so update it if our clock is kinda valid
|
getValidTime(RTCQualityFromNet); // This nodedb timestamp might be stale, so update it if our clock is kinda valid
|
||||||
|
|
||||||
// For the time in the position field, only set that if we have a real GPS clock
|
position.time = getValidTime(RTCQualityFromNet);
|
||||||
position.time = getValidTime(RTCQualityGPS);
|
|
||||||
|
|
||||||
updateBatteryLevel(powerStatus->getBatteryChargePercent());
|
updateBatteryLevel(powerStatus->getBatteryChargePercent());
|
||||||
|
|
||||||
@ -327,4 +326,4 @@ int MeshService::onGPSChanged(const meshtastic::GPSStatus *newStatus)
|
|||||||
bool MeshService::isToPhoneQueueEmpty()
|
bool MeshService::isToPhoneQueueEmpty()
|
||||||
{
|
{
|
||||||
return toPhoneQueue.isEmpty();
|
return toPhoneQueue.isEmpty();
|
||||||
}
|
}
|
||||||
|
@ -89,9 +89,6 @@ class PhoneAPI : public Observer<uint32_t> // FIXME, we shouldn't be inheriting
|
|||||||
|
|
||||||
void setInitialState() { state = STATE_SEND_MY_INFO; }
|
void setInitialState() { state = STATE_SEND_MY_INFO; }
|
||||||
|
|
||||||
/// emit a debugging log character, FIXME - implement
|
|
||||||
void debugOut(char c) { }
|
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
/// Our fromradio packet while it is being assembled
|
/// Our fromradio packet while it is being assembled
|
||||||
FromRadio fromRadioScratch = {};
|
FromRadio fromRadioScratch = {};
|
||||||
|
@ -138,7 +138,7 @@ void Router::sendAckNak(Routing_Error err, NodeNum to, PacketId idFrom, ChannelI
|
|||||||
void Router::abortSendAndNak(Routing_Error err, MeshPacket *p)
|
void Router::abortSendAndNak(Routing_Error err, MeshPacket *p)
|
||||||
{
|
{
|
||||||
LOG_ERROR("Error=%d, returning NAK and dropping packet.\n", err);
|
LOG_ERROR("Error=%d, returning NAK and dropping packet.\n", err);
|
||||||
sendAckNak(Routing_Error_NO_INTERFACE, getFrom(p), p->id, p->channel);
|
sendAckNak(err, getFrom(p), p->id, p->channel);
|
||||||
packetPool.release(p);
|
packetPool.release(p);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -199,15 +199,19 @@ ErrorCode Router::send(MeshPacket *p)
|
|||||||
} // should have already been handled by sendLocal
|
} // should have already been handled by sendLocal
|
||||||
|
|
||||||
// Abort sending if we are violating the duty cycle
|
// Abort sending if we are violating the duty cycle
|
||||||
if (!config.lora.override_duty_cycle && myRegion->dutyCycle != 100) {
|
if (!config.lora.override_duty_cycle && myRegion->dutyCycle < 100) {
|
||||||
float hourlyTxPercent = airTime->utilizationTXPercent();
|
float hourlyTxPercent = airTime->utilizationTXPercent();
|
||||||
if (hourlyTxPercent > myRegion->dutyCycle) {
|
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);
|
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;
|
Routing_Error err = Routing_Error_DUTY_CYCLE_LIMIT;
|
||||||
abortSendAndNak(err, p);
|
if (getFrom(p) == nodeDB.getNodeNum()) { // only send NAK to API, not to the mesh
|
||||||
return err;
|
abortSendAndNak(err, p);
|
||||||
}
|
} else {
|
||||||
|
packetPool.release(p);
|
||||||
|
}
|
||||||
|
return err;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// PacketId nakId = p->decoded.which_ackVariant == SubPacket_fail_id_tag ? p->decoded.ackVariant.fail_id : 0;
|
// PacketId nakId = p->decoded.which_ackVariant == SubPacket_fail_id_tag ? p->decoded.ackVariant.fail_id : 0;
|
||||||
|
@ -70,7 +70,7 @@ bool SX126xInterface<T>::init()
|
|||||||
#if defined(SX126X_TXEN) && (SX126X_TXEN != RADIOLIB_NC)
|
#if defined(SX126X_TXEN) && (SX126X_TXEN != RADIOLIB_NC)
|
||||||
// lora.begin sets Dio2 as RF switch control, which is not true if we are manually controlling RX and TX
|
// lora.begin sets Dio2 as RF switch control, which is not true if we are manually controlling RX and TX
|
||||||
if (res == RADIOLIB_ERR_NONE)
|
if (res == RADIOLIB_ERR_NONE)
|
||||||
res = lora.setDio2AsRfSwitch(false);
|
res = lora.setDio2AsRfSwitch(true);
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#if 0
|
#if 0
|
||||||
|
@ -18,9 +18,6 @@ class SinglePortModule : public MeshModule
|
|||||||
SinglePortModule(const char *_name, PortNum _ourPortNum) : MeshModule(_name), ourPortNum(_ourPortNum) {}
|
SinglePortModule(const char *_name, PortNum _ourPortNum) : MeshModule(_name), ourPortNum(_ourPortNum) {}
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
uint32_t max_channel_util_percent = 40;
|
|
||||||
uint32_t polite_channel_util_percent = 25;
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @return true if you want to receive the specified portnum
|
* @return true if you want to receive the specified portnum
|
||||||
*/
|
*/
|
||||||
|
67
src/mesh/api/ServerAPI.cpp
Normal file
67
src/mesh/api/ServerAPI.cpp
Normal file
@ -0,0 +1,67 @@
|
|||||||
|
#include "ServerAPI.h"
|
||||||
|
#include "configuration.h"
|
||||||
|
#include <Arduino.h>
|
||||||
|
|
||||||
|
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()
|
||||||
|
{
|
||||||
|
client.stop();
|
||||||
|
}
|
||||||
|
|
||||||
|
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()
|
||||||
|
{
|
||||||
|
return client.connected();
|
||||||
|
}
|
||||||
|
|
||||||
|
template<class T>
|
||||||
|
int32_t ServerAPI<T>::runOnce()
|
||||||
|
{
|
||||||
|
if (client.connected()) {
|
||||||
|
return StreamAPI::runOncePart();
|
||||||
|
} else {
|
||||||
|
LOG_INFO("Client dropped connection, suspending API service\n");
|
||||||
|
enabled = false; // we no longer need to run
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
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()
|
||||||
|
{
|
||||||
|
U::begin();
|
||||||
|
}
|
||||||
|
|
||||||
|
template<class T, class U>
|
||||||
|
int32_t APIServerPort<T, U>::runOnce()
|
||||||
|
{
|
||||||
|
auto client = U::available();
|
||||||
|
if (client) {
|
||||||
|
// Close any previous connection (see FIXME in header file)
|
||||||
|
if (openAPI) {
|
||||||
|
LOG_INFO("Force closing previous TCP connection\n");
|
||||||
|
delete openAPI;
|
||||||
|
}
|
||||||
|
|
||||||
|
openAPI = new T(client);
|
||||||
|
}
|
||||||
|
|
||||||
|
return 100; // only check occasionally for incoming connections
|
||||||
|
}
|
@ -1,21 +1,21 @@
|
|||||||
#pragma once
|
#pragma once
|
||||||
|
|
||||||
#include "StreamAPI.h"
|
#include "StreamAPI.h"
|
||||||
#include <WiFi.h>
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Provides both debug printing and, if the client starts sending protobufs to us, switches to send/receive protobufs
|
* 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).
|
* (and starts dropping debug printing - FIXME, eventually those prints should be encapsulated in protobufs).
|
||||||
*/
|
*/
|
||||||
class WiFiServerAPI : public StreamAPI, private concurrency::OSThread
|
template<class T>
|
||||||
|
class ServerAPI : public StreamAPI, private concurrency::OSThread
|
||||||
{
|
{
|
||||||
private:
|
private:
|
||||||
WiFiClient client;
|
T client;
|
||||||
|
|
||||||
public:
|
public:
|
||||||
explicit WiFiServerAPI(WiFiClient &_client);
|
explicit ServerAPI(T &_client);
|
||||||
|
|
||||||
virtual ~WiFiServerAPI();
|
virtual ~ServerAPI();
|
||||||
|
|
||||||
/// override close to also shutdown the TCP link
|
/// override close to also shutdown the TCP link
|
||||||
virtual void close();
|
virtual void close();
|
||||||
@ -34,25 +34,21 @@ class WiFiServerAPI : public StreamAPI, private concurrency::OSThread
|
|||||||
/**
|
/**
|
||||||
* Listens for incoming connections and does accepts and creates instances of WiFiServerAPI as needed
|
* Listens for incoming connections and does accepts and creates instances of WiFiServerAPI as needed
|
||||||
*/
|
*/
|
||||||
class WiFiServerPort : public WiFiServer, private concurrency::OSThread
|
template<class T, class U>
|
||||||
|
class APIServerPort : public U, private concurrency::OSThread
|
||||||
{
|
{
|
||||||
/** The currently open port
|
/** The currently open port
|
||||||
*
|
*
|
||||||
* FIXME: We currently only allow one open TCP connection at a time, because we depend on the loop() call in this class to
|
* FIXME: We currently only allow one open TCP connection at a time, because we depend on the loop() call in this class to
|
||||||
* delegate to the worker. Once coroutines are implemented we can relax this restriction.
|
* delegate to the worker. Once coroutines are implemented we can relax this restriction.
|
||||||
*/
|
*/
|
||||||
WiFiServerAPI *openAPI = NULL;
|
T *openAPI = NULL;
|
||||||
|
|
||||||
public:
|
public:
|
||||||
explicit WiFiServerPort(int port);
|
explicit APIServerPort(int port);
|
||||||
|
|
||||||
void init();
|
void init();
|
||||||
|
|
||||||
/// If an api server is running, we try to spit out debug 'serial' characters there
|
|
||||||
static void debugOut(char c);
|
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
int32_t runOnce() override;
|
int32_t runOnce() override;
|
||||||
};
|
};
|
||||||
|
|
||||||
void initApiServer(int port=4403);
|
|
25
src/mesh/api/WiFiServerAPI.cpp
Normal file
25
src/mesh/api/WiFiServerAPI.cpp
Normal file
@ -0,0 +1,25 @@
|
|||||||
|
#include "configuration.h"
|
||||||
|
#include <Arduino.h>
|
||||||
|
|
||||||
|
#if HAS_WIFI
|
||||||
|
#include "WiFiServerAPI.h"
|
||||||
|
|
||||||
|
static WiFiServerPort *apiPort;
|
||||||
|
|
||||||
|
void initApiServer(int port)
|
||||||
|
{
|
||||||
|
// Start API server on port 4403
|
||||||
|
if (!apiPort) {
|
||||||
|
apiPort = new WiFiServerPort(port);
|
||||||
|
LOG_INFO("API server listening on TCP port %d\n", port);
|
||||||
|
apiPort->init();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
WiFiServerAPI::WiFiServerAPI(WiFiClient &_client) : ServerAPI(_client)
|
||||||
|
{
|
||||||
|
LOG_INFO("Incoming wifi connection\n");
|
||||||
|
}
|
||||||
|
|
||||||
|
WiFiServerPort::WiFiServerPort(int port) : APIServerPort(port) {}
|
||||||
|
#endif
|
25
src/mesh/api/WiFiServerAPI.h
Normal file
25
src/mesh/api/WiFiServerAPI.h
Normal file
@ -0,0 +1,25 @@
|
|||||||
|
#pragma once
|
||||||
|
|
||||||
|
#include "ServerAPI.h"
|
||||||
|
#include <WiFi.h>
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 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).
|
||||||
|
*/
|
||||||
|
class WiFiServerAPI : public ServerAPI<WiFiClient>
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
explicit WiFiServerAPI(WiFiClient &_client);
|
||||||
|
};
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Listens for incoming connections and does accepts and creates instances of WiFiServerAPI as needed
|
||||||
|
*/
|
||||||
|
class WiFiServerPort : public APIServerPort<WiFiServerAPI, WiFiServer>
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
explicit WiFiServerPort(int port);
|
||||||
|
};
|
||||||
|
|
||||||
|
void initApiServer(int port=4403);
|
27
src/mesh/api/ethServerAPI.cpp
Normal file
27
src/mesh/api/ethServerAPI.cpp
Normal file
@ -0,0 +1,27 @@
|
|||||||
|
#include "configuration.h"
|
||||||
|
#include <Arduino.h>
|
||||||
|
|
||||||
|
#if HAS_ETHERNET
|
||||||
|
|
||||||
|
#include "ethServerAPI.h"
|
||||||
|
|
||||||
|
static ethServerPort *apiPort;
|
||||||
|
|
||||||
|
void initApiServer(int port)
|
||||||
|
{
|
||||||
|
// Start API server on port 4403
|
||||||
|
if (!apiPort) {
|
||||||
|
apiPort = new ethServerPort(port);
|
||||||
|
LOG_INFO("API server listening on TCP port %d\n", port);
|
||||||
|
apiPort->init();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
ethServerAPI::ethServerAPI(EthernetClient &_client) : ServerAPI(_client)
|
||||||
|
{
|
||||||
|
LOG_INFO("Incoming ethernet connection\n");
|
||||||
|
}
|
||||||
|
|
||||||
|
ethServerPort::ethServerPort(int port) : APIServerPort(port) {}
|
||||||
|
|
||||||
|
#endif
|
25
src/mesh/api/ethServerAPI.h
Normal file
25
src/mesh/api/ethServerAPI.h
Normal file
@ -0,0 +1,25 @@
|
|||||||
|
#pragma once
|
||||||
|
|
||||||
|
#include "ServerAPI.h"
|
||||||
|
#include <RAK13800_W5100S.h>
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 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).
|
||||||
|
*/
|
||||||
|
class ethServerAPI : public ServerAPI<EthernetClient>
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
explicit ethServerAPI(EthernetClient &_client);
|
||||||
|
};
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Listens for incoming connections and does accepts and creates instances of WiFiServerAPI as needed
|
||||||
|
*/
|
||||||
|
class ethServerPort : public APIServerPort<ethServerAPI, EthernetServer>
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
explicit ethServerPort(int port);
|
||||||
|
};
|
||||||
|
|
||||||
|
void initApiServer(int port=4403);
|
@ -5,7 +5,7 @@
|
|||||||
#include <SPI.h>
|
#include <SPI.h>
|
||||||
#include <RAK13800_W5100S.h>
|
#include <RAK13800_W5100S.h>
|
||||||
#include "target_specific.h"
|
#include "target_specific.h"
|
||||||
#include "mesh/eth/ethServerAPI.h"
|
#include "mesh/api/ethServerAPI.h"
|
||||||
#include "mqtt/MQTT.h"
|
#include "mqtt/MQTT.h"
|
||||||
|
|
||||||
#ifndef DISABLE_NTP
|
#ifndef DISABLE_NTP
|
||||||
|
@ -1,82 +0,0 @@
|
|||||||
#include "ethServerAPI.h"
|
|
||||||
#include "configuration.h"
|
|
||||||
#include <Arduino.h>
|
|
||||||
|
|
||||||
static ethServerPort *apiPort;
|
|
||||||
|
|
||||||
void initApiServer(int port)
|
|
||||||
{
|
|
||||||
// Start API server on port 4403
|
|
||||||
if (!apiPort) {
|
|
||||||
apiPort = new ethServerPort(port);
|
|
||||||
LOG_INFO("API server listening on TCP port %d\n", port);
|
|
||||||
apiPort->init();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
ethServerAPI::ethServerAPI(EthernetClient &_client) : StreamAPI(&client), concurrency::OSThread("ethServerAPI"), client(_client)
|
|
||||||
{
|
|
||||||
LOG_INFO("Incoming ethernet connection\n");
|
|
||||||
}
|
|
||||||
|
|
||||||
ethServerAPI::~ethServerAPI()
|
|
||||||
{
|
|
||||||
client.stop();
|
|
||||||
|
|
||||||
// FIXME - delete this if the client dropps the connection!
|
|
||||||
}
|
|
||||||
|
|
||||||
/// override close to also shutdown the TCP link
|
|
||||||
void ethServerAPI::close()
|
|
||||||
{
|
|
||||||
client.stop(); // drop tcp connection
|
|
||||||
StreamAPI::close();
|
|
||||||
}
|
|
||||||
|
|
||||||
/// Check the current underlying physical link to see if the client is currently connected
|
|
||||||
bool ethServerAPI::checkIsConnected()
|
|
||||||
{
|
|
||||||
return client.connected();
|
|
||||||
}
|
|
||||||
|
|
||||||
int32_t ethServerAPI::runOnce()
|
|
||||||
{
|
|
||||||
if (client.connected()) {
|
|
||||||
return StreamAPI::runOncePart();
|
|
||||||
} else {
|
|
||||||
LOG_INFO("Client dropped connection, suspending API service\n");
|
|
||||||
enabled = false; // we no longer need to run
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/// If an api server is running, we try to spit out debug 'serial' characters there
|
|
||||||
void ethServerPort::debugOut(char c)
|
|
||||||
{
|
|
||||||
if (apiPort && apiPort->openAPI)
|
|
||||||
apiPort->openAPI->debugOut(c);
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
ethServerPort::ethServerPort(int port) : EthernetServer(port), concurrency::OSThread("ApiServer") {}
|
|
||||||
|
|
||||||
void ethServerPort::init()
|
|
||||||
{
|
|
||||||
begin();
|
|
||||||
}
|
|
||||||
|
|
||||||
int32_t ethServerPort::runOnce()
|
|
||||||
{
|
|
||||||
auto client = available();
|
|
||||||
if (client) {
|
|
||||||
// Close any previous connection (see FIXME in header file)
|
|
||||||
if (openAPI) {
|
|
||||||
LOG_WARN("Force closing previous TCP connection\n");
|
|
||||||
delete openAPI;
|
|
||||||
}
|
|
||||||
|
|
||||||
openAPI = new ethServerAPI(client);
|
|
||||||
}
|
|
||||||
|
|
||||||
return 100; // only check occasionally for incoming connections
|
|
||||||
}
|
|
@ -1,58 +0,0 @@
|
|||||||
#pragma once
|
|
||||||
|
|
||||||
#include "StreamAPI.h"
|
|
||||||
#include <RAK13800_W5100S.h>
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 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).
|
|
||||||
*/
|
|
||||||
class ethServerAPI : public StreamAPI, private concurrency::OSThread
|
|
||||||
{
|
|
||||||
private:
|
|
||||||
EthernetClient client;
|
|
||||||
|
|
||||||
public:
|
|
||||||
explicit ethServerAPI(EthernetClient &_client);
|
|
||||||
|
|
||||||
virtual ~ethServerAPI();
|
|
||||||
|
|
||||||
/// override close to also shutdown the TCP link
|
|
||||||
virtual void close();
|
|
||||||
|
|
||||||
protected:
|
|
||||||
/// We override this method to prevent publishing EVENT_SERIAL_CONNECTED/DISCONNECTED for wifi links (we want the board to
|
|
||||||
/// stay in the POWERED state to prevent disabling wifi)
|
|
||||||
virtual void onConnectionChanged(bool connected) override {}
|
|
||||||
|
|
||||||
virtual int32_t runOnce() override; // Check for dropped client connections
|
|
||||||
|
|
||||||
/// Check the current underlying physical link to see if the client is currently connected
|
|
||||||
virtual bool checkIsConnected() override;
|
|
||||||
};
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Listens for incoming connections and does accepts and creates instances of WiFiServerAPI as needed
|
|
||||||
*/
|
|
||||||
class ethServerPort : public EthernetServer, private concurrency::OSThread
|
|
||||||
{
|
|
||||||
/** The currently open port
|
|
||||||
*
|
|
||||||
* FIXME: We currently only allow one open TCP connection at a time, because we depend on the loop() call in this class to
|
|
||||||
* delegate to the worker. Once coroutines are implemented we can relax this restriction.
|
|
||||||
*/
|
|
||||||
ethServerAPI *openAPI = NULL;
|
|
||||||
|
|
||||||
public:
|
|
||||||
explicit ethServerPort(int port);
|
|
||||||
|
|
||||||
void init();
|
|
||||||
|
|
||||||
/// If an api server is running, we try to spit out debug 'serial' characters there
|
|
||||||
static void debugOut(char c);
|
|
||||||
|
|
||||||
protected:
|
|
||||||
int32_t runOnce() override;
|
|
||||||
};
|
|
||||||
|
|
||||||
void initApiServer(int port=4403);
|
|
@ -157,7 +157,7 @@ extern const pb_msgdesc_t LocalModuleConfig_msg;
|
|||||||
|
|
||||||
/* Maximum encoded size of messages (where known) */
|
/* Maximum encoded size of messages (where known) */
|
||||||
#define LocalConfig_size 391
|
#define LocalConfig_size 391
|
||||||
#define LocalModuleConfig_size 380
|
#define LocalModuleConfig_size 412
|
||||||
|
|
||||||
#ifdef __cplusplus
|
#ifdef __cplusplus
|
||||||
} /* extern "C" */
|
} /* extern "C" */
|
||||||
|
@ -85,6 +85,8 @@ typedef enum _HardwareModel {
|
|||||||
HardwareModel_HELTEC_V3 = 43,
|
HardwareModel_HELTEC_V3 = 43,
|
||||||
/* New Heltec Wireless Stick Lite with ESP32-S3 CPU */
|
/* New Heltec Wireless Stick Lite with ESP32-S3 CPU */
|
||||||
HardwareModel_HELTEC_WSL_V3 = 44,
|
HardwareModel_HELTEC_WSL_V3 = 44,
|
||||||
|
/* New BETAFPV ELRS Micro TX Module 2.4G with ESP32 CPU */
|
||||||
|
HardwareModel_BETAFPV_2400_TX = 45,
|
||||||
/* Reserved ID For developing private Ports. These will show up in live traffic sparsely, so we can use a high number. Keep it within 8 bits. */
|
/* Reserved ID For developing private Ports. These will show up in live traffic sparsely, so we can use a high number. Keep it within 8 bits. */
|
||||||
HardwareModel_PRIVATE_HW = 255
|
HardwareModel_PRIVATE_HW = 255
|
||||||
} HardwareModel;
|
} HardwareModel;
|
||||||
@ -440,9 +442,10 @@ typedef struct _Waypoint {
|
|||||||
bool locked;
|
bool locked;
|
||||||
/* Name of the waypoint - max 30 chars */
|
/* Name of the waypoint - max 30 chars */
|
||||||
char name[30];
|
char name[30];
|
||||||
/* *
|
/* Description of the waypoint - max 100 chars */
|
||||||
Description of the waypoint - max 100 chars */
|
|
||||||
char description[100];
|
char description[100];
|
||||||
|
/* Designator icon for the waypoint in the form of a unicode emoji */
|
||||||
|
uint32_t icon;
|
||||||
} Waypoint;
|
} Waypoint;
|
||||||
|
|
||||||
typedef PB_BYTES_ARRAY_T(256) MeshPacket_encrypted_t;
|
typedef PB_BYTES_ARRAY_T(256) MeshPacket_encrypted_t;
|
||||||
@ -783,7 +786,7 @@ extern "C" {
|
|||||||
#define RouteDiscovery_init_default {0, {0, 0, 0, 0, 0, 0, 0, 0}}
|
#define RouteDiscovery_init_default {0, {0, 0, 0, 0, 0, 0, 0, 0}}
|
||||||
#define Routing_init_default {0, {RouteDiscovery_init_default}}
|
#define Routing_init_default {0, {RouteDiscovery_init_default}}
|
||||||
#define Data_init_default {_PortNum_MIN, {0, {0}}, 0, 0, 0, 0, 0, 0}
|
#define Data_init_default {_PortNum_MIN, {0, {0}}, 0, 0, 0, 0, 0, 0}
|
||||||
#define Waypoint_init_default {0, 0, 0, 0, 0, "", ""}
|
#define Waypoint_init_default {0, 0, 0, 0, 0, "", "", 0}
|
||||||
#define MeshPacket_init_default {0, 0, 0, 0, {Data_init_default}, 0, 0, 0, 0, 0, _MeshPacket_Priority_MIN, 0, _MeshPacket_Delayed_MIN}
|
#define MeshPacket_init_default {0, 0, 0, 0, {Data_init_default}, 0, 0, 0, 0, 0, _MeshPacket_Priority_MIN, 0, _MeshPacket_Delayed_MIN}
|
||||||
#define NodeInfo_init_default {0, false, User_init_default, false, Position_init_default, 0, 0, false, DeviceMetrics_init_default}
|
#define NodeInfo_init_default {0, false, User_init_default, false, Position_init_default, 0, 0, false, DeviceMetrics_init_default}
|
||||||
#define MyNodeInfo_init_default {0, 0, 0, "", _CriticalErrorCode_MIN, 0, 0, 0, 0, 0, 0, 0, {0, 0, 0, 0, 0, 0, 0, 0}, 0, {0, 0, 0, 0, 0, 0, 0, 0}, 0, 0, 0}
|
#define MyNodeInfo_init_default {0, 0, 0, "", _CriticalErrorCode_MIN, 0, 0, 0, 0, 0, 0, 0, {0, 0, 0, 0, 0, 0, 0, 0}, 0, {0, 0, 0, 0, 0, 0, 0, 0}, 0, 0, 0}
|
||||||
@ -797,7 +800,7 @@ extern "C" {
|
|||||||
#define RouteDiscovery_init_zero {0, {0, 0, 0, 0, 0, 0, 0, 0}}
|
#define RouteDiscovery_init_zero {0, {0, 0, 0, 0, 0, 0, 0, 0}}
|
||||||
#define Routing_init_zero {0, {RouteDiscovery_init_zero}}
|
#define Routing_init_zero {0, {RouteDiscovery_init_zero}}
|
||||||
#define Data_init_zero {_PortNum_MIN, {0, {0}}, 0, 0, 0, 0, 0, 0}
|
#define Data_init_zero {_PortNum_MIN, {0, {0}}, 0, 0, 0, 0, 0, 0}
|
||||||
#define Waypoint_init_zero {0, 0, 0, 0, 0, "", ""}
|
#define Waypoint_init_zero {0, 0, 0, 0, 0, "", "", 0}
|
||||||
#define MeshPacket_init_zero {0, 0, 0, 0, {Data_init_zero}, 0, 0, 0, 0, 0, _MeshPacket_Priority_MIN, 0, _MeshPacket_Delayed_MIN}
|
#define MeshPacket_init_zero {0, 0, 0, 0, {Data_init_zero}, 0, 0, 0, 0, 0, _MeshPacket_Priority_MIN, 0, _MeshPacket_Delayed_MIN}
|
||||||
#define NodeInfo_init_zero {0, false, User_init_zero, false, Position_init_zero, 0, 0, false, DeviceMetrics_init_zero}
|
#define NodeInfo_init_zero {0, false, User_init_zero, false, Position_init_zero, 0, 0, false, DeviceMetrics_init_zero}
|
||||||
#define MyNodeInfo_init_zero {0, 0, 0, "", _CriticalErrorCode_MIN, 0, 0, 0, 0, 0, 0, 0, {0, 0, 0, 0, 0, 0, 0, 0}, 0, {0, 0, 0, 0, 0, 0, 0, 0}, 0, 0, 0}
|
#define MyNodeInfo_init_zero {0, 0, 0, "", _CriticalErrorCode_MIN, 0, 0, 0, 0, 0, 0, 0, {0, 0, 0, 0, 0, 0, 0, 0}, 0, {0, 0, 0, 0, 0, 0, 0, 0}, 0, 0, 0}
|
||||||
@ -855,6 +858,7 @@ extern "C" {
|
|||||||
#define Waypoint_locked_tag 5
|
#define Waypoint_locked_tag 5
|
||||||
#define Waypoint_name_tag 6
|
#define Waypoint_name_tag 6
|
||||||
#define Waypoint_description_tag 7
|
#define Waypoint_description_tag 7
|
||||||
|
#define Waypoint_icon_tag 8
|
||||||
#define MeshPacket_from_tag 1
|
#define MeshPacket_from_tag 1
|
||||||
#define MeshPacket_to_tag 2
|
#define MeshPacket_to_tag 2
|
||||||
#define MeshPacket_channel_tag 3
|
#define MeshPacket_channel_tag 3
|
||||||
@ -987,7 +991,8 @@ X(a, STATIC, SINGULAR, SFIXED32, longitude_i, 3) \
|
|||||||
X(a, STATIC, SINGULAR, UINT32, expire, 4) \
|
X(a, STATIC, SINGULAR, UINT32, expire, 4) \
|
||||||
X(a, STATIC, SINGULAR, BOOL, locked, 5) \
|
X(a, STATIC, SINGULAR, BOOL, locked, 5) \
|
||||||
X(a, STATIC, SINGULAR, STRING, name, 6) \
|
X(a, STATIC, SINGULAR, STRING, name, 6) \
|
||||||
X(a, STATIC, SINGULAR, STRING, description, 7)
|
X(a, STATIC, SINGULAR, STRING, description, 7) \
|
||||||
|
X(a, STATIC, SINGULAR, FIXED32, icon, 8)
|
||||||
#define Waypoint_CALLBACK NULL
|
#define Waypoint_CALLBACK NULL
|
||||||
#define Waypoint_DEFAULT NULL
|
#define Waypoint_DEFAULT NULL
|
||||||
|
|
||||||
@ -1144,7 +1149,7 @@ extern const pb_msgdesc_t Compressed_msg;
|
|||||||
#define Routing_size 42
|
#define Routing_size 42
|
||||||
#define ToRadio_size 324
|
#define ToRadio_size 324
|
||||||
#define User_size 77
|
#define User_size 77
|
||||||
#define Waypoint_size 156
|
#define Waypoint_size 161
|
||||||
|
|
||||||
#ifdef __cplusplus
|
#ifdef __cplusplus
|
||||||
} /* extern "C" */
|
} /* extern "C" */
|
||||||
|
@ -80,7 +80,7 @@ typedef struct _ModuleConfig_MQTTConfig {
|
|||||||
bool enabled;
|
bool enabled;
|
||||||
/* The server to use for our MQTT global message gateway feature.
|
/* The server to use for our MQTT global message gateway feature.
|
||||||
If not set, the default server will be used */
|
If not set, the default server will be used */
|
||||||
char address[32];
|
char address[64];
|
||||||
/* MQTT username to use (most useful for a custom MQTT server).
|
/* MQTT username to use (most useful for a custom MQTT server).
|
||||||
If using a custom server, this will be honoured even if empty.
|
If using a custom server, this will be honoured even if empty.
|
||||||
If using the default server, this will only be honoured if set, otherwise the device will use the default username */
|
If using the default server, this will only be honoured if set, otherwise the device will use the default username */
|
||||||
@ -553,13 +553,13 @@ extern const pb_msgdesc_t ModuleConfig_CannedMessageConfig_msg;
|
|||||||
#define ModuleConfig_AudioConfig_size 19
|
#define ModuleConfig_AudioConfig_size 19
|
||||||
#define ModuleConfig_CannedMessageConfig_size 49
|
#define ModuleConfig_CannedMessageConfig_size 49
|
||||||
#define ModuleConfig_ExternalNotificationConfig_size 40
|
#define ModuleConfig_ExternalNotificationConfig_size 40
|
||||||
#define ModuleConfig_MQTTConfig_size 169
|
#define ModuleConfig_MQTTConfig_size 201
|
||||||
#define ModuleConfig_RangeTestConfig_size 10
|
#define ModuleConfig_RangeTestConfig_size 10
|
||||||
#define ModuleConfig_RemoteHardwareConfig_size 2
|
#define ModuleConfig_RemoteHardwareConfig_size 2
|
||||||
#define ModuleConfig_SerialConfig_size 26
|
#define ModuleConfig_SerialConfig_size 26
|
||||||
#define ModuleConfig_StoreForwardConfig_size 22
|
#define ModuleConfig_StoreForwardConfig_size 22
|
||||||
#define ModuleConfig_TelemetryConfig_size 18
|
#define ModuleConfig_TelemetryConfig_size 18
|
||||||
#define ModuleConfig_size 172
|
#define ModuleConfig_size 204
|
||||||
|
|
||||||
#ifdef __cplusplus
|
#ifdef __cplusplus
|
||||||
} /* extern "C" */
|
} /* extern "C" */
|
||||||
|
@ -5,7 +5,7 @@
|
|||||||
#include "configuration.h"
|
#include "configuration.h"
|
||||||
#include "main.h"
|
#include "main.h"
|
||||||
#include "mesh/http/WebServer.h"
|
#include "mesh/http/WebServer.h"
|
||||||
#include "mesh/wifi/WiFiServerAPI.h"
|
#include "mesh/api/WiFiServerAPI.h"
|
||||||
#include "mqtt/MQTT.h"
|
#include "mqtt/MQTT.h"
|
||||||
#include "target_specific.h"
|
#include "target_specific.h"
|
||||||
#include <ESPmDNS.h>
|
#include <ESPmDNS.h>
|
||||||
@ -55,11 +55,13 @@ static int32_t reconnectWiFi()
|
|||||||
|
|
||||||
// Make sure we clear old connection credentials
|
// Make sure we clear old connection credentials
|
||||||
WiFi.disconnect(false, true);
|
WiFi.disconnect(false, true);
|
||||||
|
|
||||||
LOG_INFO("Reconnecting to WiFi access point %s\n",wifiName);
|
LOG_INFO("Reconnecting to WiFi access point %s\n",wifiName);
|
||||||
|
|
||||||
WiFi.mode(WIFI_MODE_STA);
|
delay(5000);
|
||||||
WiFi.begin(wifiName, wifiPsw);
|
|
||||||
|
if (!WiFi.isConnected()) {
|
||||||
|
WiFi.begin(wifiName, wifiPsw);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
#ifndef DISABLE_NTP
|
#ifndef DISABLE_NTP
|
||||||
@ -167,7 +169,7 @@ bool initWifi()
|
|||||||
WiFi.mode(WIFI_MODE_STA);
|
WiFi.mode(WIFI_MODE_STA);
|
||||||
WiFi.setHostname(ourHost);
|
WiFi.setHostname(ourHost);
|
||||||
WiFi.onEvent(WiFiEvent);
|
WiFi.onEvent(WiFiEvent);
|
||||||
WiFi.setAutoReconnect(false);
|
WiFi.setAutoReconnect(true);
|
||||||
WiFi.setSleep(false);
|
WiFi.setSleep(false);
|
||||||
if (config.network.address_mode == Config_NetworkConfig_AddressMode_STATIC && config.network.ipv4_config.ip != 0) {
|
if (config.network.address_mode == Config_NetworkConfig_AddressMode_STATIC && config.network.ipv4_config.ip != 0) {
|
||||||
WiFi.config(config.network.ipv4_config.ip,
|
WiFi.config(config.network.ipv4_config.ip,
|
||||||
@ -182,7 +184,8 @@ bool initWifi()
|
|||||||
|
|
||||||
WiFi.onEvent(
|
WiFi.onEvent(
|
||||||
[](WiFiEvent_t event, WiFiEventInfo_t info) {
|
[](WiFiEvent_t event, WiFiEventInfo_t info) {
|
||||||
LOG_WARN("WiFi lost connection. Reason: %d", info.wifi_sta_disconnected.reason);
|
|
||||||
|
LOG_WARN("WiFi lost connection. Reason: %d\n", info.wifi_sta_disconnected.reason);
|
||||||
|
|
||||||
/*
|
/*
|
||||||
If we are disconnected from the AP for some reason,
|
If we are disconnected from the AP for some reason,
|
||||||
|
@ -1,82 +0,0 @@
|
|||||||
#include "WiFiServerAPI.h"
|
|
||||||
#include "configuration.h"
|
|
||||||
#include <Arduino.h>
|
|
||||||
|
|
||||||
static WiFiServerPort *apiPort;
|
|
||||||
|
|
||||||
void initApiServer(int port)
|
|
||||||
{
|
|
||||||
// Start API server on port 4403
|
|
||||||
if (!apiPort) {
|
|
||||||
apiPort = new WiFiServerPort(port);
|
|
||||||
LOG_INFO("API server listening on TCP port %d\n", port);
|
|
||||||
apiPort->init();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
WiFiServerAPI::WiFiServerAPI(WiFiClient &_client) : StreamAPI(&client), concurrency::OSThread("WiFiServerAPI"), client(_client)
|
|
||||||
{
|
|
||||||
LOG_INFO("Incoming wifi connection\n");
|
|
||||||
}
|
|
||||||
|
|
||||||
WiFiServerAPI::~WiFiServerAPI()
|
|
||||||
{
|
|
||||||
client.stop();
|
|
||||||
|
|
||||||
// FIXME - delete this if the client dropps the connection!
|
|
||||||
}
|
|
||||||
|
|
||||||
/// override close to also shutdown the TCP link
|
|
||||||
void WiFiServerAPI::close()
|
|
||||||
{
|
|
||||||
client.stop(); // drop tcp connection
|
|
||||||
StreamAPI::close();
|
|
||||||
}
|
|
||||||
|
|
||||||
/// Check the current underlying physical link to see if the client is currently connected
|
|
||||||
bool WiFiServerAPI::checkIsConnected()
|
|
||||||
{
|
|
||||||
return client.connected();
|
|
||||||
}
|
|
||||||
|
|
||||||
int32_t WiFiServerAPI::runOnce()
|
|
||||||
{
|
|
||||||
if (client.connected()) {
|
|
||||||
return StreamAPI::runOncePart();
|
|
||||||
} else {
|
|
||||||
LOG_INFO("Client dropped connection, suspending API service\n");
|
|
||||||
enabled = false; // we no longer need to run
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/// If an api server is running, we try to spit out debug 'serial' characters there
|
|
||||||
void WiFiServerPort::debugOut(char c)
|
|
||||||
{
|
|
||||||
if (apiPort && apiPort->openAPI)
|
|
||||||
apiPort->openAPI->debugOut(c);
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
WiFiServerPort::WiFiServerPort(int port) : WiFiServer(port), concurrency::OSThread("ApiServer") {}
|
|
||||||
|
|
||||||
void WiFiServerPort::init()
|
|
||||||
{
|
|
||||||
begin();
|
|
||||||
}
|
|
||||||
|
|
||||||
int32_t WiFiServerPort::runOnce()
|
|
||||||
{
|
|
||||||
auto client = available();
|
|
||||||
if (client) {
|
|
||||||
// Close any previous connection (see FIXME in header file)
|
|
||||||
if (openAPI) {
|
|
||||||
LOG_INFO("Force closing previous TCP connection\n");
|
|
||||||
delete openAPI;
|
|
||||||
}
|
|
||||||
|
|
||||||
openAPI = new WiFiServerAPI(client);
|
|
||||||
}
|
|
||||||
|
|
||||||
return 100; // only check occasionally for incoming connections
|
|
||||||
}
|
|
@ -65,8 +65,10 @@ int32_t NodeInfoModule::runOnce()
|
|||||||
bool requestReplies = currentGeneration != radioGeneration;
|
bool requestReplies = currentGeneration != radioGeneration;
|
||||||
currentGeneration = radioGeneration;
|
currentGeneration = radioGeneration;
|
||||||
|
|
||||||
LOG_INFO("Sending our nodeinfo to mesh (wantReplies=%d)\n", requestReplies);
|
if (airTime->isTxAllowedAirUtil()) {
|
||||||
sendOurNodeInfo(NODENUM_BROADCAST, requestReplies); // Send our info (don't request replies)
|
LOG_INFO("Sending our nodeinfo to mesh (wantReplies=%d)\n", requestReplies);
|
||||||
|
sendOurNodeInfo(NODENUM_BROADCAST, requestReplies); // Send our info (don't request replies)
|
||||||
|
}
|
||||||
|
|
||||||
return default_broadcast_interval_secs * 1000;
|
return default_broadcast_interval_secs * 1000;
|
||||||
}
|
}
|
||||||
|
@ -144,7 +144,7 @@ int32_t PositionModule::runOnce()
|
|||||||
if (lastGpsSend == 0 || (now - lastGpsSend) >= intervalMs) {
|
if (lastGpsSend == 0 || (now - lastGpsSend) >= intervalMs) {
|
||||||
|
|
||||||
// Only send packets if the channel is less than 40% utilized.
|
// Only send packets if the channel is less than 40% utilized.
|
||||||
if (airTime->channelUtilizationPercent() < max_channel_util_percent) {
|
if (airTime->isTxAllowedChannelUtil()) {
|
||||||
if (node->has_position && (node->position.latitude_i != 0 || node->position.longitude_i != 0)) {
|
if (node->has_position && (node->position.latitude_i != 0 || node->position.longitude_i != 0)) {
|
||||||
lastGpsSend = now;
|
lastGpsSend = now;
|
||||||
|
|
||||||
@ -158,14 +158,12 @@ int32_t PositionModule::runOnce()
|
|||||||
LOG_INFO("Sending pos@%x:6 to mesh (wantReplies=%d)\n", node->position.timestamp, requestReplies);
|
LOG_INFO("Sending pos@%x:6 to mesh (wantReplies=%d)\n", node->position.timestamp, requestReplies);
|
||||||
sendOurPosition(NODENUM_BROADCAST, requestReplies);
|
sendOurPosition(NODENUM_BROADCAST, requestReplies);
|
||||||
}
|
}
|
||||||
} else {
|
|
||||||
LOG_WARN("Channel utilization is >40 percent. Skipping this opportunity to send.\n");
|
|
||||||
}
|
}
|
||||||
|
|
||||||
} else if (config.position.position_broadcast_smart_enabled) {
|
} else if (config.position.position_broadcast_smart_enabled) {
|
||||||
|
|
||||||
// Only send packets if the channel is less than 25% utilized.
|
// Only send packets if the channel is less than 25% utilized.
|
||||||
if (airTime->channelUtilizationPercent() < polite_channel_util_percent) {
|
if (airTime->isTxAllowedChannelUtil(true)) {
|
||||||
|
|
||||||
NodeInfo *node2 = service.refreshMyNodeInfo(); // should guarantee there is now a position
|
NodeInfo *node2 = service.refreshMyNodeInfo(); // should guarantee there is now a position
|
||||||
|
|
||||||
@ -208,8 +206,6 @@ int32_t PositionModule::runOnce()
|
|||||||
lastGpsSend = now;
|
lastGpsSend = now;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
} else {
|
|
||||||
LOG_WARN("Channel utilization is >25 percent. Skipping this opportunity to send.\n");
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -13,11 +13,10 @@
|
|||||||
|
|
||||||
int32_t DeviceTelemetryModule::runOnce()
|
int32_t DeviceTelemetryModule::runOnce()
|
||||||
{
|
{
|
||||||
#ifndef ARCH_PORTDUINO
|
|
||||||
uint32_t now = millis();
|
uint32_t now = millis();
|
||||||
if ((lastSentToMesh == 0 ||
|
if ((lastSentToMesh == 0 ||
|
||||||
(now - lastSentToMesh) >= getConfiguredOrDefaultMs(moduleConfig.telemetry.device_update_interval)) &&
|
(now - lastSentToMesh) >= getConfiguredOrDefaultMs(moduleConfig.telemetry.device_update_interval)) &&
|
||||||
airTime->channelUtilizationPercent() < max_channel_util_percent) {
|
airTime->isTxAllowedChannelUtil() && airTime->isTxAllowedAirUtil()) {
|
||||||
sendTelemetry();
|
sendTelemetry();
|
||||||
lastSentToMesh = now;
|
lastSentToMesh = now;
|
||||||
} else if (service.isToPhoneQueueEmpty()) {
|
} else if (service.isToPhoneQueueEmpty()) {
|
||||||
@ -26,7 +25,6 @@ int32_t DeviceTelemetryModule::runOnce()
|
|||||||
sendTelemetry(NODENUM_BROADCAST, true);
|
sendTelemetry(NODENUM_BROADCAST, true);
|
||||||
}
|
}
|
||||||
return sendToPhoneIntervalMs;
|
return sendToPhoneIntervalMs;
|
||||||
#endif
|
|
||||||
}
|
}
|
||||||
|
|
||||||
bool DeviceTelemetryModule::handleReceivedProtobuf(const MeshPacket &mp, Telemetry *t)
|
bool DeviceTelemetryModule::handleReceivedProtobuf(const MeshPacket &mp, Telemetry *t)
|
||||||
|
@ -107,7 +107,7 @@ int32_t EnvironmentTelemetryModule::runOnce()
|
|||||||
uint32_t now = millis();
|
uint32_t now = millis();
|
||||||
if ((lastSentToMesh == 0 ||
|
if ((lastSentToMesh == 0 ||
|
||||||
(now - lastSentToMesh) >= getConfiguredOrDefaultMs(moduleConfig.telemetry.environment_update_interval)) &&
|
(now - lastSentToMesh) >= getConfiguredOrDefaultMs(moduleConfig.telemetry.environment_update_interval)) &&
|
||||||
airTime->channelUtilizationPercent() < max_channel_util_percent) {
|
airTime->isTxAllowedAirUtil()) {
|
||||||
sendTelemetry();
|
sendTelemetry();
|
||||||
lastSentToMesh = now;
|
lastSentToMesh = now;
|
||||||
} else if (service.isToPhoneQueueEmpty()) {
|
} else if (service.isToPhoneQueueEmpty()) {
|
||||||
|
@ -73,10 +73,8 @@ int32_t RangeTestModule::runOnce()
|
|||||||
LOG_INFO("fixed_position() %d\n", config.position.fixed_position);
|
LOG_INFO("fixed_position() %d\n", config.position.fixed_position);
|
||||||
|
|
||||||
// Only send packets if the channel is less than 25% utilized.
|
// Only send packets if the channel is less than 25% utilized.
|
||||||
if (airTime->channelUtilizationPercent() < 25) {
|
if (airTime->isTxAllowedChannelUtil(true)) {
|
||||||
rangeTestModuleRadio->sendPayload();
|
rangeTestModuleRadio->sendPayload();
|
||||||
} else {
|
|
||||||
LOG_WARN("RangeTest - Channel utilization is >25 percent. Skipping this opportunity to send.\n");
|
|
||||||
}
|
}
|
||||||
|
|
||||||
return (senderHeartbeat);
|
return (senderHeartbeat);
|
||||||
|
@ -21,7 +21,7 @@ int32_t StoreForwardModule::runOnce()
|
|||||||
// Send out the message queue.
|
// Send out the message queue.
|
||||||
if (this->busy) {
|
if (this->busy) {
|
||||||
// Only send packets if the channel is less than 25% utilized.
|
// Only send packets if the channel is less than 25% utilized.
|
||||||
if (airTime->channelUtilizationPercent() < polite_channel_util_percent) {
|
if (airTime->isTxAllowedChannelUtil(true)) {
|
||||||
storeForwardModule->sendPayload(this->busyTo, this->packetHistoryTXQueue_index);
|
storeForwardModule->sendPayload(this->busyTo, this->packetHistoryTXQueue_index);
|
||||||
if (this->packetHistoryTXQueue_index == packetHistoryTXQueue_size) {
|
if (this->packetHistoryTXQueue_index == packetHistoryTXQueue_size) {
|
||||||
// Tell the client we're done sending
|
// Tell the client we're done sending
|
||||||
@ -34,12 +34,10 @@ int32_t StoreForwardModule::runOnce()
|
|||||||
} else {
|
} else {
|
||||||
this->packetHistoryTXQueue_index++;
|
this->packetHistoryTXQueue_index++;
|
||||||
}
|
}
|
||||||
} else {
|
|
||||||
LOG_WARN("*** Channel utilization is too high. Retrying later.\n");
|
|
||||||
}
|
}
|
||||||
LOG_DEBUG("*** SF bitrate = %f bytes / sec\n", myNodeInfo.bitrate);
|
LOG_DEBUG("*** SF bitrate = %f bytes / sec\n", myNodeInfo.bitrate);
|
||||||
|
|
||||||
} else if ((millis() - lastHeartbeat > (heartbeatInterval * 1000)) && (airTime->channelUtilizationPercent() < polite_channel_util_percent)) {
|
} else if ((millis() - lastHeartbeat > (heartbeatInterval * 1000)) && airTime->isTxAllowedChannelUtil(true)) {
|
||||||
lastHeartbeat = millis();
|
lastHeartbeat = millis();
|
||||||
LOG_INFO("*** Sending heartbeat\n");
|
LOG_INFO("*** Sending heartbeat\n");
|
||||||
StoreAndForward sf = StoreAndForward_init_zero;
|
StoreAndForward sf = StoreAndForward_init_zero;
|
||||||
|
@ -43,9 +43,20 @@ void MQTT::onPublish(char *topic, byte *payload, unsigned int length)
|
|||||||
JSONValue *json_value = JSON::Parse(payloadStr);
|
JSONValue *json_value = JSON::Parse(payloadStr);
|
||||||
if (json_value != NULL) {
|
if (json_value != NULL) {
|
||||||
LOG_INFO("JSON Received on MQTT, parsing..\n");
|
LOG_INFO("JSON Received on MQTT, parsing..\n");
|
||||||
|
|
||||||
// check if it is a valid envelope
|
// check if it is a valid envelope
|
||||||
JSONObject json;
|
JSONObject json;
|
||||||
json = json_value->AsObject();
|
json = json_value->AsObject();
|
||||||
|
|
||||||
|
// parse the channel name from the topic string
|
||||||
|
char *ptr = strtok(topic, "/");
|
||||||
|
for (int i = 0; i < 3; i++) {
|
||||||
|
ptr = strtok(NULL, "/");
|
||||||
|
}
|
||||||
|
LOG_DEBUG("Looking for Channel name: %s\n", ptr);
|
||||||
|
Channel sendChannel = channels.getByName(ptr);
|
||||||
|
LOG_DEBUG("Found Channel name: %s (Index %d)\n", channels.getGlobalId(sendChannel.settings.channel_num), sendChannel.settings.channel_num);
|
||||||
|
|
||||||
if ((json.find("sender") != json.end()) && (json.find("payload") != json.end()) && (json.find("type") != json.end()) && json["type"]->IsString() && (json["type"]->AsString().compare("sendtext") == 0)) {
|
if ((json.find("sender") != json.end()) && (json.find("payload") != json.end()) && (json.find("type") != json.end()) && json["type"]->IsString() && (json["type"]->AsString().compare("sendtext") == 0)) {
|
||||||
// this is a valid envelope
|
// this is a valid envelope
|
||||||
if (json["payload"]->IsString() && json["type"]->IsString() && (json["sender"]->AsString().compare(owner.id) != 0)) {
|
if (json["payload"]->IsString() && json["type"]->IsString() && (json["sender"]->AsString().compare(owner.id) != 0)) {
|
||||||
@ -55,13 +66,18 @@ void MQTT::onPublish(char *topic, byte *payload, unsigned int length)
|
|||||||
// construct protobuf data packet using TEXT_MESSAGE, send it to the mesh
|
// construct protobuf data packet using TEXT_MESSAGE, send it to the mesh
|
||||||
MeshPacket *p = router->allocForSending();
|
MeshPacket *p = router->allocForSending();
|
||||||
p->decoded.portnum = PortNum_TEXT_MESSAGE_APP;
|
p->decoded.portnum = PortNum_TEXT_MESSAGE_APP;
|
||||||
if (jsonPayloadStr.length() <= sizeof(p->decoded.payload.bytes)) {
|
p->channel = sendChannel.settings.channel_num;
|
||||||
memcpy(p->decoded.payload.bytes, jsonPayloadStr.c_str(), jsonPayloadStr.length());
|
if (sendChannel.settings.downlink_enabled) {
|
||||||
p->decoded.payload.size = jsonPayloadStr.length();
|
if (jsonPayloadStr.length() <= sizeof(p->decoded.payload.bytes)) {
|
||||||
MeshPacket *packet = packetPool.allocCopy(*p);
|
memcpy(p->decoded.payload.bytes, jsonPayloadStr.c_str(), jsonPayloadStr.length());
|
||||||
service.sendToMesh(packet, RX_SRC_LOCAL);
|
p->decoded.payload.size = jsonPayloadStr.length();
|
||||||
|
MeshPacket *packet = packetPool.allocCopy(*p);
|
||||||
|
service.sendToMesh(packet, RX_SRC_LOCAL);
|
||||||
|
} else {
|
||||||
|
LOG_WARN("Received MQTT json payload too long, dropping\n");
|
||||||
|
}
|
||||||
} else {
|
} else {
|
||||||
LOG_WARN("Received MQTT json payload too long, dropping\n");
|
LOG_WARN("Received MQTT json payload on channel %s, but downlink is disabled, dropping\n", sendChannel.settings.name);
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
LOG_DEBUG("JSON Ignoring downlink message we originally sent.\n");
|
LOG_DEBUG("JSON Ignoring downlink message we originally sent.\n");
|
||||||
@ -80,9 +96,13 @@ void MQTT::onPublish(char *topic, byte *payload, unsigned int length)
|
|||||||
// construct protobuf data packet using POSITION, send it to the mesh
|
// construct protobuf data packet using POSITION, send it to the mesh
|
||||||
MeshPacket *p = router->allocForSending();
|
MeshPacket *p = router->allocForSending();
|
||||||
p->decoded.portnum = PortNum_POSITION_APP;
|
p->decoded.portnum = PortNum_POSITION_APP;
|
||||||
p->decoded.payload.size = pb_encode_to_bytes(p->decoded.payload.bytes, sizeof(p->decoded.payload.bytes), &Position_msg, &pos); //make the Data protobuf from position
|
p->channel = sendChannel.settings.channel_num;
|
||||||
service.sendToMesh(p, RX_SRC_LOCAL);
|
if (sendChannel.settings.downlink_enabled) {
|
||||||
|
p->decoded.payload.size = pb_encode_to_bytes(p->decoded.payload.bytes, sizeof(p->decoded.payload.bytes), &Position_msg, &pos); //make the Data protobuf from position
|
||||||
|
service.sendToMesh(p, RX_SRC_LOCAL);
|
||||||
|
} else {
|
||||||
|
LOG_WARN("Received MQTT json payload on channel %s, but downlink is disabled, dropping\n", sendChannel.settings.name);
|
||||||
|
}
|
||||||
} else {
|
} else {
|
||||||
LOG_DEBUG("JSON Ignoring downlink message we originally sent.\n");
|
LOG_DEBUG("JSON Ignoring downlink message we originally sent.\n");
|
||||||
}
|
}
|
||||||
@ -187,14 +207,17 @@ void MQTT::reconnect()
|
|||||||
|
|
||||||
sendSubscriptions();
|
sendSubscriptions();
|
||||||
} else {
|
} else {
|
||||||
LOG_ERROR("Failed to contact MQTT server (%d/10)...\n",reconnectCount);
|
|
||||||
#if HAS_WIFI && !defined(ARCH_PORTDUINO)
|
#if HAS_WIFI && !defined(ARCH_PORTDUINO)
|
||||||
if (reconnectCount > 9) {
|
LOG_ERROR("Failed to contact MQTT server (%d/5)...\n",reconnectCount + 1);
|
||||||
|
if (reconnectCount >= 4) {
|
||||||
needReconnect = true;
|
needReconnect = true;
|
||||||
wifiReconnect->setIntervalFromNow(1000);
|
wifiReconnect->setIntervalFromNow(0);
|
||||||
|
reconnectCount = 0;
|
||||||
|
} else {
|
||||||
|
reconnectCount++;
|
||||||
}
|
}
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
reconnectCount++;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -264,7 +287,6 @@ int32_t MQTT::runOnce()
|
|||||||
|
|
||||||
String topic = cryptTopic + env->channel_id + "/" + owner.id;
|
String topic = cryptTopic + env->channel_id + "/" + owner.id;
|
||||||
LOG_INFO("publish %s, %u bytes from queue\n", topic.c_str(), numBytes);
|
LOG_INFO("publish %s, %u bytes from queue\n", topic.c_str(), numBytes);
|
||||||
|
|
||||||
|
|
||||||
pubSub.publish(topic.c_str(), bytes, numBytes, false);
|
pubSub.publish(topic.c_str(), bytes, numBytes, false);
|
||||||
|
|
||||||
@ -279,7 +301,7 @@ int32_t MQTT::runOnce()
|
|||||||
}
|
}
|
||||||
mqttPool.release(env);
|
mqttPool.release(env);
|
||||||
}
|
}
|
||||||
return 20;
|
return 200;
|
||||||
} else {
|
} else {
|
||||||
return 30000;
|
return 30000;
|
||||||
}
|
}
|
||||||
|
@ -13,7 +13,7 @@
|
|||||||
#include <EthernetClient.h>
|
#include <EthernetClient.h>
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#define MAX_MQTT_QUEUE 32
|
#define MAX_MQTT_QUEUE 16
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Our wrapper/singleton for sending/receiving MQTT "udp" packets. This object isolates the MQTT protocol implementation from
|
* Our wrapper/singleton for sending/receiving MQTT "udp" packets. This object isolates the MQTT protocol implementation from
|
||||||
|
@ -172,6 +172,9 @@ void cpuDeepSleep(uint64_t msecToWake)
|
|||||||
Serial1.end();
|
Serial1.end();
|
||||||
#endif
|
#endif
|
||||||
setBluetoothEnable(false);
|
setBluetoothEnable(false);
|
||||||
|
#ifdef RAK4630
|
||||||
|
digitalWrite(PIN_3V3_EN, LOW);
|
||||||
|
#endif
|
||||||
// FIXME, use system off mode with ram retention for key state?
|
// FIXME, use system off mode with ram retention for key state?
|
||||||
// FIXME, use non-init RAM per
|
// FIXME, use non-init RAM per
|
||||||
// https://devzone.nordicsemi.com/f/nordic-q-a/48919/ram-retention-settings-with-softdevice-enabled
|
// https://devzone.nordicsemi.com/f/nordic-q-a/48919/ram-retention-settings-with-softdevice-enabled
|
||||||
|
@ -2,7 +2,7 @@
|
|||||||
|
|
||||||
#include "RadioInterface.h"
|
#include "RadioInterface.h"
|
||||||
#include "MeshPacketQueue.h"
|
#include "MeshPacketQueue.h"
|
||||||
#include "wifi/WiFiServerAPI.h"
|
#include "api/WiFiServerAPI.h"
|
||||||
|
|
||||||
#include <RadioLib.h>
|
#include <RadioLib.h>
|
||||||
|
|
||||||
|
@ -3,7 +3,7 @@
|
|||||||
extends = nrf52840_base
|
extends = nrf52840_base
|
||||||
board = wiscore_rak4631
|
board = wiscore_rak4631
|
||||||
build_flags = ${nrf52840_base.build_flags} -Ivariants/rak4631 -D RAK_4631
|
build_flags = ${nrf52840_base.build_flags} -Ivariants/rak4631 -D RAK_4631
|
||||||
build_src_filter = ${nrf52_base.build_src_filter} +<../variants/rak4631> +<mesh/eth/> +<mqtt/>
|
build_src_filter = ${nrf52_base.build_src_filter} +<../variants/rak4631> +<mesh/eth/> +<mesh/api/> +<mqtt/>
|
||||||
lib_deps =
|
lib_deps =
|
||||||
${nrf52840_base.lib_deps}
|
${nrf52840_base.lib_deps}
|
||||||
${networking_base.lib_deps}
|
${networking_base.lib_deps}
|
||||||
|
@ -1,4 +1,4 @@
|
|||||||
[VERSION]
|
[VERSION]
|
||||||
major = 2
|
major = 2
|
||||||
minor = 0
|
minor = 0
|
||||||
build = 12
|
build = 13
|
||||||
|
Loading…
Reference in New Issue
Block a user