Merge branch 'master' into sketch

This commit is contained in:
Thomas Göttgens
2022-06-12 18:48:08 +02:00
committed by GitHub
46 changed files with 576 additions and 246 deletions

View File

@@ -51,7 +51,8 @@
"iterator": "cpp", "iterator": "cpp",
"shared_mutex": "cpp", "shared_mutex": "cpp",
"iostream": "cpp", "iostream": "cpp",
"esp_nimble_hci.h": "c" "esp_nimble_hci.h": "c",
"map": "cpp"
}, },
"cSpell.words": [ "cSpell.words": [
"Blox", "Blox",

View File

@@ -17,7 +17,7 @@ Import("projenv")
prefsLoc = projenv["PROJECT_DIR"] + "/version.properties" prefsLoc = projenv["PROJECT_DIR"] + "/version.properties"
verObj = readProps(prefsLoc) verObj = readProps(prefsLoc)
print("Using meshtastic platform-custom.py, firmare version " + verObj['long']) print("Using meshtastic platformio-custom.py, firmare version " + verObj['long'])
# print("path is" + ','.join(sys.path)) # print("path is" + ','.join(sys.path))
# General options that are passed to the C and C++ compilers # General options that are passed to the C and C++ compilers

View File

@@ -20,6 +20,7 @@ default_envs = tbeam
;default_envs = pca10059_diy_eink ;default_envs = pca10059_diy_eink
;default_envs = meshtastic-diy-v1 ;default_envs = meshtastic-diy-v1
;default_envs = meshtastic-diy-v1.1 ;default_envs = meshtastic-diy-v1.1
;default_envs = m5stack-coreink
extra_configs = variants/*/platformio.ini extra_configs = variants/*/platformio.ini
@@ -83,7 +84,8 @@ lib_deps =
adafruit/Adafruit BME280 Library@^2.2.2 adafruit/Adafruit BME280 Library@^2.2.2
adafruit/Adafruit BME680 Library@^2.0.1 adafruit/Adafruit BME680 Library@^2.0.1
adafruit/Adafruit MCP9808 Library@^2.0.0 adafruit/Adafruit MCP9808 Library@^2.0.0
adafruit/Adafruit INA260 Library@^1.5.0
adafruit/Adafruit INA219@^1.2.0
; Common settings for ESP targes, mixin with extends = esp32_base ; Common settings for ESP targes, mixin with extends = esp32_base
[esp32_base] [esp32_base]
extends = arduino_base extends = arduino_base

View File

@@ -5,6 +5,7 @@
#include "main.h" #include "main.h"
#include "sleep.h" #include "sleep.h"
#include "utils.h" #include "utils.h"
#include "buzz/buzz.h"
#ifdef TBEAM_V10 #ifdef TBEAM_V10
// FIXME. nasty hack cleanup how we load axp192 // FIXME. nasty hack cleanup how we load axp192
@@ -211,8 +212,12 @@ void Power::shutdown()
{ {
#ifdef TBEAM_V10 #ifdef TBEAM_V10
DEBUG_MSG("Shutting down\n"); DEBUG_MSG("Shutting down\n");
axp.setChgLEDMode(AXP20X_LED_OFF);
axp.shutdown(); axp.shutdown();
#elif NRF52_SERIES #elif NRF52_SERIES
playBeep();
ledOff(PIN_LED1);
ledOff(PIN_LED2);
doDeepSleep(DELAY_FOREVER); doDeepSleep(DELAY_FOREVER);
#endif #endif
} }

View File

@@ -335,7 +335,7 @@ void PowerFSM_setup()
powerFSM.add_timed_transition(&stateON, &stateDARK, powerFSM.add_timed_transition(&stateON, &stateDARK,
config.display.screen_on_secs ? config.display.screen_on_secs config.display.screen_on_secs ? config.display.screen_on_secs
: 60 * 1000, : 60 * 1000 * 10,
NULL, "Screen-on timeout"); NULL, "Screen-on timeout");
// On most boards we use light-sleep to be our main state, but on NRF52 we just stay in DARK // On most boards we use light-sleep to be our main state, but on NRF52 we just stay in DARK
@@ -348,9 +348,6 @@ void PowerFSM_setup()
// See: https://github.com/meshtastic/Meshtastic-device/issues/1071 // See: https://github.com/meshtastic/Meshtastic-device/issues/1071
if (isRouter || config.power.is_power_saving) { if (isRouter || config.power.is_power_saving) {
// I don't think this transition is correct, turning off for now - @geeksville
// powerFSM.add_timed_transition(&stateDARK, &stateNB, getPref_phone_timeout_secs() * 1000, NULL, "Phone timeout");
powerFSM.add_timed_transition(&stateNB, &stateLS, powerFSM.add_timed_transition(&stateNB, &stateLS,
config.power.min_wake_secs ? config.power.min_wake_secs config.power.min_wake_secs ? config.power.min_wake_secs
: default_min_wake_secs * 1000, : default_min_wake_secs * 1000,

View File

@@ -4,6 +4,8 @@
#include "configuration.h" #include "configuration.h"
#define Port Serial #define Port Serial
// Defaulting to the formerly removed phone_timeout_secs value of 15 minutes
#define SERIAL_CONNECTION_TIMEOUT (15 * 60) * 1000UL
SerialConsole *console; SerialConsole *console;
@@ -41,13 +43,12 @@ SerialConsole::SerialConsole() : StreamAPI(&Port), RedirectablePrint(&Port)
emitRebooted(); emitRebooted();
} }
// For the serial port we can't really detect if any client is on the other side, so instead just look for recent messages // For the serial port we can't really detect if any client is on the other side, so instead just look for recent messages
bool SerialConsole::checkIsConnected() bool SerialConsole::checkIsConnected()
{ {
uint32_t now = millis(); uint32_t now = millis();
return (now - lastContactMsec) < config.power.phone_timeout_secs return (now - lastContactMsec) < SERIAL_CONNECTION_TIMEOUT;
? config.power.phone_timeout_secs
: default_phone_timeout_secs * 1000UL;
} }
/** /**

View File

@@ -25,6 +25,7 @@ along with this program. If not, see <http://www.gnu.org/licenses/>.
#pragma once #pragma once
#include <Arduino.h> #include <Arduino.h>
#ifdef RV3028_RTC #ifdef RV3028_RTC
#include "Melopero_RV3028.h" #include "Melopero_RV3028.h"
#endif #endif
@@ -144,7 +145,7 @@ along with this program. If not, see <http://www.gnu.org/licenses/>.
//#define DISABLE_NTP //#define DISABLE_NTP
// Disable the welcome screen and allow // Disable the welcome screen and allow
//#define DISABLE_WELCOME_UNSET #define DISABLE_WELCOME_UNSET
// ----------------------------------------------------------------------------- // -----------------------------------------------------------------------------
// OLED & Input // OLED & Input
@@ -170,6 +171,15 @@ along with this program. If not, see <http://www.gnu.org/licenses/>.
// The older M5 Faces I2C Keyboard // The older M5 Faces I2C Keyboard
#define FACESKB_ADDR 0x88 #define FACESKB_ADDR 0x88
// -----------------------------------------------------------------------------
// SENSOR
// -----------------------------------------------------------------------------
#define BME_ADDR 0x76
#define BME_ADDR_ALTERNATE 0x77
#define MCP9808_ADDR 0x18
#define INA_ADDR 0x40
#define INA_ADDR_ALTERNATE 0x41
// ----------------------------------------------------------------------------- // -----------------------------------------------------------------------------
// GPS // GPS
// ----------------------------------------------------------------------------- // -----------------------------------------------------------------------------

View File

@@ -1,8 +1,27 @@
#include "../configuration.h" #include "../configuration.h"
#include "../main.h" #include "../main.h"
#include <Wire.h> #include <Wire.h>
#include "mesh/generated/telemetry.pb.h"
#ifndef NO_WIRE #ifndef NO_WIRE
uint16_t getRegisterValue(uint8_t address, uint8_t reg, uint8_t length) {
uint16_t value = 0x00;
Wire.beginTransmission(address);
Wire.write(reg);
Wire.endTransmission();
delay(20);
Wire.requestFrom(address, length);
DEBUG_MSG("Wire.available() = %d\n", Wire.available());
if (Wire.available() == 2) {
// Read MSB, then LSB
value = (uint16_t)Wire.read() << 8;
value |= Wire.read();
} else if (Wire.available()) {
value = Wire.read();
}
return value;
}
uint8_t oled_probe(byte addr) uint8_t oled_probe(byte addr)
{ {
uint8_t r = 0; uint8_t r = 0;
@@ -34,7 +53,7 @@ uint8_t oled_probe(byte addr)
void scanI2Cdevice(void) void scanI2Cdevice(void)
{ {
byte err, addr; byte err, addr;
uint8_t r = 0x00; uint16_t registerValue = 0x00;
int nDevices = 0; int nDevices = 0;
for (addr = 1; addr < 127; addr++) { for (addr = 1; addr < 127; addr++) {
Wire.beginTransmission(addr); Wire.beginTransmission(addr);
@@ -74,15 +93,8 @@ void scanI2Cdevice(void)
if (addr == CARDKB_ADDR) { if (addr == CARDKB_ADDR) {
cardkb_found = addr; cardkb_found = addr;
// Do we have the RAK14006 instead? // Do we have the RAK14006 instead?
Wire.beginTransmission(addr); registerValue = getRegisterValue(addr, 0x04, 1);
Wire.write(0x04); // SENSOR_GET_VERSION if (registerValue == 0x02) { // KEYPAD_VERSION
Wire.endTransmission();
delay(20);
Wire.requestFrom((int)addr, 1);
if (Wire.available()) {
r = Wire.read();
}
if (r == 0x02) { // KEYPAD_VERSION
DEBUG_MSG("RAK14004 found\n"); DEBUG_MSG("RAK14004 found\n");
kb_model = 0x02; kb_model = 0x02;
} else { } else {
@@ -104,6 +116,31 @@ void scanI2Cdevice(void)
DEBUG_MSG("axp192 PMU found\n"); DEBUG_MSG("axp192 PMU found\n");
} }
#endif #endif
if (addr == BME_ADDR || addr == BME_ADDR_ALTERNATE) {
registerValue = getRegisterValue(addr, 0xD0, 1); // GET_ID
if (registerValue == 0x61) {
DEBUG_MSG("BME-680 sensor found at address 0x%x\n", (uint8_t)addr);
nodeTelemetrySensorsMap[TelemetrySensorType_BME680] = addr;
} else if (registerValue == 0x60) {
DEBUG_MSG("BME-280 sensor found at address 0x%x\n", (uint8_t)addr);
nodeTelemetrySensorsMap[TelemetrySensorType_BME280] = addr;
}
}
if (addr == INA_ADDR || addr == INA_ADDR_ALTERNATE) {
registerValue = getRegisterValue(addr, 0xFE, 2);
DEBUG_MSG("Register MFG_UID: 0x%x\n", registerValue);
if (registerValue == 0x5449) {
DEBUG_MSG("INA260 sensor found at address 0x%x\n", (uint8_t)addr);
nodeTelemetrySensorsMap[TelemetrySensorType_INA260] = addr;
} else { // Assume INA219 if INA260 ID is not found
DEBUG_MSG("INA219 sensor found at address 0x%x\n", (uint8_t)addr);
nodeTelemetrySensorsMap[TelemetrySensorType_INA219] = addr;
}
}
if (addr == MCP9808_ADDR) {
nodeTelemetrySensorsMap[TelemetrySensorType_MCP9808] = addr;
DEBUG_MSG("MCP9808 sensor found at address 0x%x\n", (uint8_t)addr);
}
} else if (err == 4) { } else if (err == 4) {
DEBUG_MSG("Unknow error at address 0x%x\n", addr); DEBUG_MSG("Unknow error at address 0x%x\n", addr);
} }

View File

@@ -49,12 +49,13 @@ class ESP32CryptoEngine : public CryptoEngine
*/ */
virtual void encrypt(uint32_t fromNode, uint64_t packetId, size_t numBytes, uint8_t *bytes) override virtual void encrypt(uint32_t fromNode, uint64_t packetId, size_t numBytes, uint8_t *bytes) override
{ {
hexDump("before", bytes, numBytes, 16);
if (key.length > 0) { if (key.length > 0) {
uint8_t stream_block[16]; uint8_t stream_block[16];
static uint8_t scratch[MAX_BLOCKSIZE]; static uint8_t scratch[MAX_BLOCKSIZE];
size_t nc_off = 0; size_t nc_off = 0;
// DEBUG_MSG("ESP32 crypt fr=%x, num=%x, numBytes=%d!\n", fromNode, (uint32_t) packetId, numBytes); DEBUG_MSG("ESP32 crypt fr=%x, num=%x, numBytes=%d!\n", fromNode, (uint32_t) packetId, numBytes);
initNonce(fromNode, packetId); initNonce(fromNode, packetId);
assert(numBytes <= MAX_BLOCKSIZE); assert(numBytes <= MAX_BLOCKSIZE);
memcpy(scratch, bytes, numBytes); memcpy(scratch, bytes, numBytes);
@@ -64,12 +65,11 @@ class ESP32CryptoEngine : public CryptoEngine
auto res = mbedtls_aes_crypt_ctr(&aes, numBytes, &nc_off, nonce, stream_block, scratch, bytes); auto res = mbedtls_aes_crypt_ctr(&aes, numBytes, &nc_off, nonce, stream_block, scratch, bytes);
assert(!res); assert(!res);
} }
hexDump("after", bytes, numBytes, 16);
} }
virtual void decrypt(uint32_t fromNode, uint64_t packetId, size_t numBytes, uint8_t *bytes) override virtual void decrypt(uint32_t fromNode, uint64_t packetId, size_t numBytes, uint8_t *bytes) override
{ {
// DEBUG_MSG("ESP32 decrypt!\n");
// For CTR, the implementation is the same // For CTR, the implementation is the same
encrypt(fromNode, packetId, numBytes, bytes); encrypt(fromNode, packetId, numBytes, bytes);
} }

View File

@@ -31,6 +31,11 @@
//4.2 inch 300x400 - GxEPD2_420_M01 //4.2 inch 300x400 - GxEPD2_420_M01
#define TECHO_DISPLAY_MODEL GxEPD2_420_M01 #define TECHO_DISPLAY_MODEL GxEPD2_420_M01
#elif defined(M5_COREINK)
//M5Stack CoreInk
//1.54 inch 200x200 - GxEPD2_154_M09
#define TECHO_DISPLAY_MODEL GxEPD2_154_M09
#endif #endif
GxEPD2_BW<TECHO_DISPLAY_MODEL, TECHO_DISPLAY_MODEL::HEIGHT> *adafruitDisplay; GxEPD2_BW<TECHO_DISPLAY_MODEL, TECHO_DISPLAY_MODEL::HEIGHT> *adafruitDisplay;
@@ -58,6 +63,12 @@ EInkDisplay::EInkDisplay(uint8_t address, int sda, int scl)
//GxEPD2_420_M01 //GxEPD2_420_M01
setGeometry(GEOMETRY_RAWMODE, 300, 400); setGeometry(GEOMETRY_RAWMODE, 300, 400);
#elif defined(M5_COREINK)
//M5Stack_CoreInk 200x200
//1.54 inch 200x200 - GxEPD2_154_M09
setGeometry(GEOMETRY_RAWMODE, EPD_HEIGHT, EPD_WIDTH);
#endif #endif
// setGeometry(GEOMETRY_RAWMODE, 128, 64); // old resolution // setGeometry(GEOMETRY_RAWMODE, 128, 64); // old resolution
// setGeometry(GEOMETRY_128_64); // We originally used this because I wasn't sure if rawmode worked - it does // setGeometry(GEOMETRY_128_64); // We originally used this because I wasn't sure if rawmode worked - it does
@@ -108,7 +119,7 @@ bool EInkDisplay::forceDisplay(uint32_t msecLimit)
// 4.2 inch 300x400 - GxEPD2_420_M01 // 4.2 inch 300x400 - GxEPD2_420_M01
//adafruitDisplay->nextPage(); //adafruitDisplay->nextPage();
#elif defined(PCA10059) #elif defined(PCA10059) || defined(M5_COREINK)
adafruitDisplay->nextPage(); adafruitDisplay->nextPage();
#endif #endif
@@ -180,35 +191,10 @@ bool EInkDisplay::connect()
adafruitDisplay->init(115200, true, 10, false, SPI1, SPISettings(4000000, MSBFIRST, SPI_MODE0)); adafruitDisplay->init(115200, true, 10, false, SPI1, SPISettings(4000000, MSBFIRST, SPI_MODE0));
//RAK14000 2.13 inch b/w 250x122 does not support partial updates //RAK14000 2.13 inch b/w 250x122 does not support partial updates
//RAK14000 2.13 inch b/w 250x122 does not support partial updates
//RAK14000 2.13 inch b/w 250x122 does not support partial updates
//RAK14000 2.13 inch b/w 250x122 does not support partial updates
//RAK14000 2.13 inch b/w 250x122 does not support partial updates
//RAK14000 2.13 inch b/w 250x122 does not support partial updates
//RAK14000 2.13 inch b/w 250x122 does not support partial updates
//RAK14000 2.13 inch b/w 250x122 does not support partial updates
//RAK14000 2.13 inch b/w 250x122 does not support partial updates
//RAK14000 2.13 inch b/w 250x122 does not support partial updates
//RAK14000 2.13 inch b/w 250x122 does not support partial updates
//RAK14000 2.13 inch b/w 250x122 does not support partial updates
//RAK14000 2.13 inch b/w 250x122 does not support partial updates
adafruitDisplay->setRotation(3); adafruitDisplay->setRotation(3);
//For 1.54, 2.9 and 4.2 //For 1.54, 2.9 and 4.2
//adafruitDisplay->setRotation(1); //adafruitDisplay->setRotation(1);
//adafruitDisplay->setPartialWindow(0, 0, displayWidth, displayHeight);
adafruitDisplay->setPartialWindow(0, 0, displayWidth, displayHeight);
adafruitDisplay->setPartialWindow(0, 0, displayWidth, displayHeight);
adafruitDisplay->setPartialWindow(0, 0, displayWidth, displayHeight);
adafruitDisplay->setPartialWindow(0, 0, displayWidth, displayHeight);
adafruitDisplay->setPartialWindow(0, 0, displayWidth, displayHeight);
adafruitDisplay->setPartialWindow(0, 0, displayWidth, displayHeight);
adafruitDisplay->setPartialWindow(0, 0, displayWidth, displayHeight);
adafruitDisplay->setPartialWindow(0, 0, displayWidth, displayHeight);
adafruitDisplay->setPartialWindow(0, 0, displayWidth, displayHeight);
adafruitDisplay->setPartialWindow(0, 0, displayWidth, displayHeight);
adafruitDisplay->setPartialWindow(0, 0, displayWidth, displayHeight);
adafruitDisplay->setPartialWindow(0, 0, displayWidth, displayHeight);
adafruitDisplay->setPartialWindow(0, 0, displayWidth, displayHeight);
} else { } else {
(void)adafruitDisplay; (void)adafruitDisplay;
} }
@@ -221,6 +207,13 @@ bool EInkDisplay::connect()
adafruitDisplay->setRotation(3); adafruitDisplay->setRotation(3);
adafruitDisplay->setPartialWindow(0, 0, displayWidth, displayHeight); adafruitDisplay->setPartialWindow(0, 0, displayWidth, displayHeight);
} }
#elif defined(M5_COREINK)
auto lowLevel = new TECHO_DISPLAY_MODEL(PIN_EINK_CS, PIN_EINK_DC, PIN_EINK_RES, PIN_EINK_BUSY);
adafruitDisplay = new GxEPD2_BW<TECHO_DISPLAY_MODEL, TECHO_DISPLAY_MODEL::HEIGHT>(*lowLevel);
delay(100);
adafruitDisplay->init(115200, true, 20, false, SPI, SPISettings(4000000, MSBFIRST, SPI_MODE0));
adafruitDisplay->setRotation(0);
adafruitDisplay->setPartialWindow(0, 0, EPD_WIDTH, EPD_HEIGHT);
#endif #endif

View File

@@ -90,6 +90,9 @@ uint32_t serialSinceMsec;
bool axp192_found; bool axp192_found;
// Array map of sensor types (as array index) and i2c address as value we'll find in the i2c scan
uint8_t nodeTelemetrySensorsMap[12] = { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 };
Router *router = NULL; // Users of router don't care what sort of subclass implements that API Router *router = NULL; // Users of router don't care what sort of subclass implements that API
const char *getDeviceName() const char *getDeviceName()

View File

@@ -1,9 +1,11 @@
#pragma once #pragma once
#include <map>
#include "GPSStatus.h" #include "GPSStatus.h"
#include "NodeStatus.h" #include "NodeStatus.h"
#include "PowerStatus.h" #include "PowerStatus.h"
#include "graphics/Screen.h" #include "graphics/Screen.h"
#include "mesh/generated/telemetry.pb.h"
extern uint8_t screen_found; extern uint8_t screen_found;
extern uint8_t screen_model; extern uint8_t screen_model;
@@ -17,6 +19,8 @@ extern bool axp192_found;
extern bool isCharging; extern bool isCharging;
extern bool isUSBPowered; extern bool isUSBPowered;
extern uint8_t nodeTelemetrySensorsMap[12];
// Global Screen singleton. // Global Screen singleton.
extern graphics::Screen *screen; extern graphics::Screen *screen;
// extern Observable<meshtastic::PowerStatus> newPowerStatus; //TODO: move this to main-esp32.cpp somehow or a helper class // extern Observable<meshtastic::PowerStatus> newPowerStatus; //TODO: move this to main-esp32.cpp somehow or a helper class

View File

@@ -3,7 +3,7 @@
void CryptoEngine::setKey(const CryptoKey &k) void CryptoEngine::setKey(const CryptoKey &k)
{ {
DEBUG_MSG("Installing AES%d key!\n", k.length * 8); DEBUG_MSG("Using AES%d key!\n", k.length * 8);
/* for(uint8_t i = 0; i < k.length; i++) /* for(uint8_t i = 0; i < k.length; i++)
DEBUG_MSG("%02x ", k.bytes[i]); DEBUG_MSG("%02x ", k.bytes[i]);
DEBUG_MSG("\n"); */ DEBUG_MSG("\n"); */
@@ -26,6 +26,78 @@ void CryptoEngine::decrypt(uint32_t fromNode, uint64_t packetId, size_t numBytes
DEBUG_MSG("WARNING: noop decryption!\n"); DEBUG_MSG("WARNING: noop decryption!\n");
} }
// Usage:
// hexDump(desc, addr, len, perLine);
// desc: if non-NULL, printed as a description before hex dump.
// addr: the address to start dumping from.
// len: the number of bytes to dump.
// perLine: number of bytes on each output line.
void CryptoEngine::hexDump (const char * desc, const void * addr, const int len, int perLine)
{
// Silently ignore silly per-line values.
if (perLine < 4 || perLine > 64) perLine = 16;
int i;
unsigned char buff[perLine+1];
const unsigned char * pc = (const unsigned char *)addr;
// Output description if given.
if (desc != NULL) DEBUG_MSG ("%s:\n", desc);
// Length checks.
if (len == 0) {
DEBUG_MSG(" ZERO LENGTH\n");
return;
}
if (len < 0) {
DEBUG_MSG(" NEGATIVE LENGTH: %d\n", len);
return;
}
// Process every byte in the data.
for (i = 0; i < len; i++) {
// Multiple of perLine means new or first line (with line offset).
if ((i % perLine) == 0) {
// Only print previous-line ASCII buffer for lines beyond first.
if (i != 0) DEBUG_MSG (" %s\n", buff);
// Output the offset of current line.
DEBUG_MSG (" %04x ", i);
}
// Now the hex code for the specific character.
DEBUG_MSG (" %02x", pc[i]);
// And buffer a printable ASCII character for later.
if ((pc[i] < 0x20) || (pc[i] > 0x7e)) // isprint() may be better.
buff[i % perLine] = '.';
else
buff[i % perLine] = pc[i];
buff[(i % perLine) + 1] = '\0';
}
// Pad out last line if not exactly perLine characters.
while ((i % perLine) != 0) {
DEBUG_MSG (" ");
i++;
}
// And print the final ASCII buffer.
DEBUG_MSG (" %s\n", buff);
}
/** /**
* Init our 128 bit nonce for a new packet * Init our 128 bit nonce for a new packet
*/ */

View File

@@ -56,6 +56,8 @@ class CryptoEngine
* a 32 bit block counter (starts at zero) * a 32 bit block counter (starts at zero)
*/ */
void initNonce(uint32_t fromNode, uint64_t packetId); void initNonce(uint32_t fromNode, uint64_t packetId);
void hexDump(const char * desc, const void * addr, const int len, int perLine);
}; };
extern CryptoEngine *crypto; extern CryptoEngine *crypto;

View File

@@ -308,12 +308,12 @@ static const char *channelfile = "/prefs/channels.proto";
/** Load a protobuf from a file, return true for success */ /** Load a protobuf from a file, return true for success */
bool loadProto(const char *filename, size_t protoSize, size_t objSize, const pb_msgdesc_t *fields, void *dest_struct) bool loadProto(const char *filename, size_t protoSize, size_t objSize, const pb_msgdesc_t *fields, void *dest_struct)
{ {
bool okay = false;
#ifdef FSCom #ifdef FSCom
// static DeviceState scratch; We no longer read into a tempbuf because this structure is 15KB of valuable RAM // static DeviceState scratch; We no longer read into a tempbuf because this structure is 15KB of valuable RAM
auto f = FSCom.open(filename); auto f = FSCom.open(filename);
bool okay = false;
if (f) { if (f) {
DEBUG_MSG("Loading %s\n", filename); DEBUG_MSG("Loading %s\n", filename);
pb_istream_t stream = {&readcb, &f, protoSize}; pb_istream_t stream = {&readcb, &f, protoSize};
@@ -367,12 +367,12 @@ void NodeDB::loadFromDisk()
/** Save a protobuf from a file, return true for success */ /** Save a protobuf from a file, return true for success */
bool saveProto(const char *filename, size_t protoSize, size_t objSize, const pb_msgdesc_t *fields, const void *dest_struct) bool saveProto(const char *filename, size_t protoSize, size_t objSize, const pb_msgdesc_t *fields, const void *dest_struct)
{ {
bool okay = false;
#ifdef FSCom #ifdef FSCom
// static DeviceState scratch; We no longer read into a tempbuf because this structure is 15KB of valuable RAM // static DeviceState scratch; We no longer read into a tempbuf because this structure is 15KB of valuable RAM
String filenameTmp = filename; String filenameTmp = filename;
filenameTmp += ".tmp"; filenameTmp += ".tmp";
auto f = FSCom.open(filenameTmp.c_str(), FILE_O_WRITE); auto f = FSCom.open(filenameTmp.c_str(), FILE_O_WRITE);
bool okay = false;
if (f) { if (f) {
DEBUG_MSG("Saving %s\n", filename); DEBUG_MSG("Saving %s\n", filename);
pb_ostream_t stream = {&writecb, &f, protoSize}; pb_ostream_t stream = {&writecb, &f, protoSize};

View File

@@ -168,7 +168,6 @@ extern NodeDB nodeDB;
#define default_mesh_sds_timeout_secs IF_ROUTER(NODE_DELAY_FOREVER, 2 * 60 * 60) #define default_mesh_sds_timeout_secs IF_ROUTER(NODE_DELAY_FOREVER, 2 * 60 * 60)
#define default_sds_secs 365 * 24 * 60 * 60 #define default_sds_secs 365 * 24 * 60 * 60
#define default_ls_secs IF_ROUTER(24 * 60 * 60, 5 * 60) #define default_ls_secs IF_ROUTER(24 * 60 * 60, 5 * 60)
#define default_phone_timeout_secs 15 * 60
#define default_min_wake_secs 10 #define default_min_wake_secs 10

View File

@@ -77,10 +77,13 @@ template <class T> class ProtobufModule : protected SinglePortModule
T *decoded = NULL; T *decoded = NULL;
if (mp.which_payloadVariant == MeshPacket_decoded_tag && mp.decoded.portnum == ourPortNum) { if (mp.which_payloadVariant == MeshPacket_decoded_tag && mp.decoded.portnum == ourPortNum) {
memset(&scratch, 0, sizeof(scratch)); memset(&scratch, 0, sizeof(scratch));
if (pb_decode_from_bytes(p.payload.bytes, p.payload.size, fields, &scratch)) if (pb_decode_from_bytes(p.payload.bytes, p.payload.size, fields, &scratch)) {
decoded = &scratch; decoded = &scratch;
else } else {
DEBUG_MSG("Error decoding protobuf module!\n"); DEBUG_MSG("Error decoding protobuf module!\n");
// if we can't decode it, nobody can process it!
return ProcessMessage::STOP;
}
} }
return handleReceivedProtobuf(mp, decoded) ? ProcessMessage::STOP : ProcessMessage::CONTINUE; return handleReceivedProtobuf(mp, decoded) ? ProcessMessage::STOP : ProcessMessage::CONTINUE;

View File

@@ -120,8 +120,6 @@ typedef struct _Config_PositionConfig {
bool gps_disabled; bool gps_disabled;
uint32_t gps_update_interval; uint32_t gps_update_interval;
uint32_t gps_attempt_time; uint32_t gps_attempt_time;
bool gps_accept_2d;
uint32_t gps_max_dop;
uint32_t position_flags; uint32_t position_flags;
} Config_PositionConfig; } Config_PositionConfig;
@@ -133,7 +131,6 @@ typedef struct _Config_PowerConfig {
bool is_power_saving; bool is_power_saving;
float adc_multiplier_override; float adc_multiplier_override;
uint32_t wait_bluetooth_secs; uint32_t wait_bluetooth_secs;
uint32_t phone_timeout_secs;
uint32_t mesh_sds_timeout_secs; uint32_t mesh_sds_timeout_secs;
uint32_t sds_secs; uint32_t sds_secs;
uint32_t ls_secs; uint32_t ls_secs;
@@ -194,15 +191,15 @@ extern "C" {
/* Initializer values for message structs */ /* Initializer values for message structs */
#define Config_init_default {0, {Config_DeviceConfig_init_default}} #define Config_init_default {0, {Config_DeviceConfig_init_default}}
#define Config_DeviceConfig_init_default {_Config_DeviceConfig_Role_MIN, 0, 0, 0, ""} #define Config_DeviceConfig_init_default {_Config_DeviceConfig_Role_MIN, 0, 0, 0, ""}
#define Config_PositionConfig_init_default {0, 0, 0, 0, 0, 0, 0, 0, 0} #define Config_PositionConfig_init_default {0, 0, 0, 0, 0, 0, 0}
#define Config_PowerConfig_init_default {_Config_PowerConfig_ChargeCurrent_MIN, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0} #define Config_PowerConfig_init_default {_Config_PowerConfig_ChargeCurrent_MIN, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}
#define Config_WiFiConfig_init_default {"", "", 0, 0} #define Config_WiFiConfig_init_default {"", "", 0, 0}
#define Config_DisplayConfig_init_default {0, _Config_DisplayConfig_GpsCoordinateFormat_MIN, 0} #define Config_DisplayConfig_init_default {0, _Config_DisplayConfig_GpsCoordinateFormat_MIN, 0}
#define Config_LoRaConfig_init_default {0, _Config_LoRaConfig_ModemPreset_MIN, 0, 0, 0, 0, _Config_LoRaConfig_RegionCode_MIN, 0, 0, 0, {0, 0, 0}} #define Config_LoRaConfig_init_default {0, _Config_LoRaConfig_ModemPreset_MIN, 0, 0, 0, 0, _Config_LoRaConfig_RegionCode_MIN, 0, 0, 0, {0, 0, 0}}
#define Config_init_zero {0, {Config_DeviceConfig_init_zero}} #define Config_init_zero {0, {Config_DeviceConfig_init_zero}}
#define Config_DeviceConfig_init_zero {_Config_DeviceConfig_Role_MIN, 0, 0, 0, ""} #define Config_DeviceConfig_init_zero {_Config_DeviceConfig_Role_MIN, 0, 0, 0, ""}
#define Config_PositionConfig_init_zero {0, 0, 0, 0, 0, 0, 0, 0, 0} #define Config_PositionConfig_init_zero {0, 0, 0, 0, 0, 0, 0}
#define Config_PowerConfig_init_zero {_Config_PowerConfig_ChargeCurrent_MIN, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0} #define Config_PowerConfig_init_zero {_Config_PowerConfig_ChargeCurrent_MIN, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}
#define Config_WiFiConfig_init_zero {"", "", 0, 0} #define Config_WiFiConfig_init_zero {"", "", 0, 0}
#define Config_DisplayConfig_init_zero {0, _Config_DisplayConfig_GpsCoordinateFormat_MIN, 0} #define Config_DisplayConfig_init_zero {0, _Config_DisplayConfig_GpsCoordinateFormat_MIN, 0}
#define Config_LoRaConfig_init_zero {0, _Config_LoRaConfig_ModemPreset_MIN, 0, 0, 0, 0, _Config_LoRaConfig_RegionCode_MIN, 0, 0, 0, {0, 0, 0}} #define Config_LoRaConfig_init_zero {0, _Config_LoRaConfig_ModemPreset_MIN, 0, 0, 0, 0, _Config_LoRaConfig_RegionCode_MIN, 0, 0, 0, {0, 0, 0}}
@@ -232,8 +229,6 @@ extern "C" {
#define Config_PositionConfig_gps_disabled_tag 5 #define Config_PositionConfig_gps_disabled_tag 5
#define Config_PositionConfig_gps_update_interval_tag 6 #define Config_PositionConfig_gps_update_interval_tag 6
#define Config_PositionConfig_gps_attempt_time_tag 7 #define Config_PositionConfig_gps_attempt_time_tag 7
#define Config_PositionConfig_gps_accept_2d_tag 8
#define Config_PositionConfig_gps_max_dop_tag 9
#define Config_PositionConfig_position_flags_tag 10 #define Config_PositionConfig_position_flags_tag 10
#define Config_PowerConfig_charge_current_tag 1 #define Config_PowerConfig_charge_current_tag 1
#define Config_PowerConfig_is_low_power_tag 2 #define Config_PowerConfig_is_low_power_tag 2
@@ -242,7 +237,6 @@ extern "C" {
#define Config_PowerConfig_is_power_saving_tag 5 #define Config_PowerConfig_is_power_saving_tag 5
#define Config_PowerConfig_adc_multiplier_override_tag 6 #define Config_PowerConfig_adc_multiplier_override_tag 6
#define Config_PowerConfig_wait_bluetooth_secs_tag 7 #define Config_PowerConfig_wait_bluetooth_secs_tag 7
#define Config_PowerConfig_phone_timeout_secs_tag 8
#define Config_PowerConfig_mesh_sds_timeout_secs_tag 9 #define Config_PowerConfig_mesh_sds_timeout_secs_tag 9
#define Config_PowerConfig_sds_secs_tag 10 #define Config_PowerConfig_sds_secs_tag 10
#define Config_PowerConfig_ls_secs_tag 11 #define Config_PowerConfig_ls_secs_tag 11
@@ -291,8 +285,6 @@ X(a, STATIC, SINGULAR, BOOL, fixed_position, 3) \
X(a, STATIC, SINGULAR, BOOL, gps_disabled, 5) \ X(a, STATIC, SINGULAR, BOOL, gps_disabled, 5) \
X(a, STATIC, SINGULAR, UINT32, gps_update_interval, 6) \ X(a, STATIC, SINGULAR, UINT32, gps_update_interval, 6) \
X(a, STATIC, SINGULAR, UINT32, gps_attempt_time, 7) \ X(a, STATIC, SINGULAR, UINT32, gps_attempt_time, 7) \
X(a, STATIC, SINGULAR, BOOL, gps_accept_2d, 8) \
X(a, STATIC, SINGULAR, UINT32, gps_max_dop, 9) \
X(a, STATIC, SINGULAR, UINT32, position_flags, 10) X(a, STATIC, SINGULAR, UINT32, position_flags, 10)
#define Config_PositionConfig_CALLBACK NULL #define Config_PositionConfig_CALLBACK NULL
#define Config_PositionConfig_DEFAULT NULL #define Config_PositionConfig_DEFAULT NULL
@@ -305,7 +297,6 @@ X(a, STATIC, SINGULAR, UINT32, on_battery_shutdown_after_secs, 4) \
X(a, STATIC, SINGULAR, BOOL, is_power_saving, 5) \ X(a, STATIC, SINGULAR, BOOL, is_power_saving, 5) \
X(a, STATIC, SINGULAR, FLOAT, adc_multiplier_override, 6) \ X(a, STATIC, SINGULAR, FLOAT, adc_multiplier_override, 6) \
X(a, STATIC, SINGULAR, UINT32, wait_bluetooth_secs, 7) \ X(a, STATIC, SINGULAR, UINT32, wait_bluetooth_secs, 7) \
X(a, STATIC, SINGULAR, UINT32, phone_timeout_secs, 8) \
X(a, STATIC, SINGULAR, UINT32, mesh_sds_timeout_secs, 9) \ X(a, STATIC, SINGULAR, UINT32, mesh_sds_timeout_secs, 9) \
X(a, STATIC, SINGULAR, UINT32, sds_secs, 10) \ X(a, STATIC, SINGULAR, UINT32, sds_secs, 10) \
X(a, STATIC, SINGULAR, UINT32, ls_secs, 11) \ X(a, STATIC, SINGULAR, UINT32, ls_secs, 11) \
@@ -363,8 +354,8 @@ extern const pb_msgdesc_t Config_LoRaConfig_msg;
#define Config_DeviceConfig_size 42 #define Config_DeviceConfig_size 42
#define Config_DisplayConfig_size 14 #define Config_DisplayConfig_size 14
#define Config_LoRaConfig_size 67 #define Config_LoRaConfig_size 67
#define Config_PositionConfig_size 38 #define Config_PositionConfig_size 30
#define Config_PowerConfig_size 55 #define Config_PowerConfig_size 49
#define Config_WiFiConfig_size 103 #define Config_WiFiConfig_size 103
#define Config_size 105 #define Config_size 105

View File

@@ -44,7 +44,7 @@ typedef struct _DeviceState {
User owner; User owner;
/* TODO: REPLACE */ /* TODO: REPLACE */
pb_size_t node_db_count; pb_size_t node_db_count;
NodeInfo node_db[64]; NodeInfo node_db[80];
/* Received packets saved for delivery to the phone */ /* Received packets saved for delivery to the phone */
pb_size_t receive_queue_count; pb_size_t receive_queue_count;
MeshPacket receive_queue[1]; MeshPacket receive_queue[1];
@@ -92,10 +92,10 @@ extern "C" {
#endif #endif
/* Initializer values for message structs */ /* Initializer values for message structs */
#define DeviceState_init_default {false, MyNodeInfo_init_default, false, User_init_default, 0, {NodeInfo_init_default, NodeInfo_init_default, NodeInfo_init_default, NodeInfo_init_default, NodeInfo_init_default, NodeInfo_init_default, NodeInfo_init_default, NodeInfo_init_default, NodeInfo_init_default, NodeInfo_init_default, NodeInfo_init_default, NodeInfo_init_default, NodeInfo_init_default, NodeInfo_init_default, NodeInfo_init_default, NodeInfo_init_default, NodeInfo_init_default, NodeInfo_init_default, NodeInfo_init_default, NodeInfo_init_default, NodeInfo_init_default, NodeInfo_init_default, NodeInfo_init_default, NodeInfo_init_default, NodeInfo_init_default, NodeInfo_init_default, NodeInfo_init_default, NodeInfo_init_default, NodeInfo_init_default, NodeInfo_init_default, NodeInfo_init_default, NodeInfo_init_default, NodeInfo_init_default, NodeInfo_init_default, NodeInfo_init_default, NodeInfo_init_default, NodeInfo_init_default, NodeInfo_init_default, NodeInfo_init_default, NodeInfo_init_default, NodeInfo_init_default, NodeInfo_init_default, NodeInfo_init_default, NodeInfo_init_default, NodeInfo_init_default, NodeInfo_init_default, NodeInfo_init_default, NodeInfo_init_default, NodeInfo_init_default, NodeInfo_init_default, NodeInfo_init_default, NodeInfo_init_default, NodeInfo_init_default, NodeInfo_init_default, NodeInfo_init_default, NodeInfo_init_default, NodeInfo_init_default, NodeInfo_init_default, NodeInfo_init_default, NodeInfo_init_default, NodeInfo_init_default, NodeInfo_init_default, NodeInfo_init_default, NodeInfo_init_default}, 0, {MeshPacket_init_default}, false, MeshPacket_init_default, 0, 0, 0} #define DeviceState_init_default {false, MyNodeInfo_init_default, false, User_init_default, 0, {NodeInfo_init_default, NodeInfo_init_default, NodeInfo_init_default, NodeInfo_init_default, NodeInfo_init_default, NodeInfo_init_default, NodeInfo_init_default, NodeInfo_init_default, NodeInfo_init_default, NodeInfo_init_default, NodeInfo_init_default, NodeInfo_init_default, NodeInfo_init_default, NodeInfo_init_default, NodeInfo_init_default, NodeInfo_init_default, NodeInfo_init_default, NodeInfo_init_default, NodeInfo_init_default, NodeInfo_init_default, NodeInfo_init_default, NodeInfo_init_default, NodeInfo_init_default, NodeInfo_init_default, NodeInfo_init_default, NodeInfo_init_default, NodeInfo_init_default, NodeInfo_init_default, NodeInfo_init_default, NodeInfo_init_default, NodeInfo_init_default, NodeInfo_init_default, NodeInfo_init_default, NodeInfo_init_default, NodeInfo_init_default, NodeInfo_init_default, NodeInfo_init_default, NodeInfo_init_default, NodeInfo_init_default, NodeInfo_init_default, NodeInfo_init_default, NodeInfo_init_default, NodeInfo_init_default, NodeInfo_init_default, NodeInfo_init_default, NodeInfo_init_default, NodeInfo_init_default, NodeInfo_init_default, NodeInfo_init_default, NodeInfo_init_default, NodeInfo_init_default, NodeInfo_init_default, NodeInfo_init_default, NodeInfo_init_default, NodeInfo_init_default, NodeInfo_init_default, NodeInfo_init_default, NodeInfo_init_default, NodeInfo_init_default, NodeInfo_init_default, NodeInfo_init_default, NodeInfo_init_default, NodeInfo_init_default, NodeInfo_init_default, NodeInfo_init_default, NodeInfo_init_default, NodeInfo_init_default, NodeInfo_init_default, NodeInfo_init_default, NodeInfo_init_default, NodeInfo_init_default, NodeInfo_init_default, NodeInfo_init_default, NodeInfo_init_default, NodeInfo_init_default, NodeInfo_init_default, NodeInfo_init_default, NodeInfo_init_default, NodeInfo_init_default, NodeInfo_init_default}, 0, {MeshPacket_init_default}, false, MeshPacket_init_default, 0, 0, 0}
#define ChannelFile_init_default {0, {Channel_init_default, Channel_init_default, Channel_init_default, Channel_init_default, Channel_init_default, Channel_init_default, Channel_init_default, Channel_init_default}} #define ChannelFile_init_default {0, {Channel_init_default, Channel_init_default, Channel_init_default, Channel_init_default, Channel_init_default, Channel_init_default, Channel_init_default, Channel_init_default}}
#define OEMStore_init_default {0, 0, {0, {0}}, _ScreenFonts_MIN, ""} #define OEMStore_init_default {0, 0, {0, {0}}, _ScreenFonts_MIN, ""}
#define DeviceState_init_zero {false, MyNodeInfo_init_zero, false, User_init_zero, 0, {NodeInfo_init_zero, NodeInfo_init_zero, NodeInfo_init_zero, NodeInfo_init_zero, NodeInfo_init_zero, NodeInfo_init_zero, NodeInfo_init_zero, NodeInfo_init_zero, NodeInfo_init_zero, NodeInfo_init_zero, NodeInfo_init_zero, NodeInfo_init_zero, NodeInfo_init_zero, NodeInfo_init_zero, NodeInfo_init_zero, NodeInfo_init_zero, NodeInfo_init_zero, NodeInfo_init_zero, NodeInfo_init_zero, NodeInfo_init_zero, NodeInfo_init_zero, NodeInfo_init_zero, NodeInfo_init_zero, NodeInfo_init_zero, NodeInfo_init_zero, NodeInfo_init_zero, NodeInfo_init_zero, NodeInfo_init_zero, NodeInfo_init_zero, NodeInfo_init_zero, NodeInfo_init_zero, NodeInfo_init_zero, NodeInfo_init_zero, NodeInfo_init_zero, NodeInfo_init_zero, NodeInfo_init_zero, NodeInfo_init_zero, NodeInfo_init_zero, NodeInfo_init_zero, NodeInfo_init_zero, NodeInfo_init_zero, NodeInfo_init_zero, NodeInfo_init_zero, NodeInfo_init_zero, NodeInfo_init_zero, NodeInfo_init_zero, NodeInfo_init_zero, NodeInfo_init_zero, NodeInfo_init_zero, NodeInfo_init_zero, NodeInfo_init_zero, NodeInfo_init_zero, NodeInfo_init_zero, NodeInfo_init_zero, NodeInfo_init_zero, NodeInfo_init_zero, NodeInfo_init_zero, NodeInfo_init_zero, NodeInfo_init_zero, NodeInfo_init_zero, NodeInfo_init_zero, NodeInfo_init_zero, NodeInfo_init_zero, NodeInfo_init_zero}, 0, {MeshPacket_init_zero}, false, MeshPacket_init_zero, 0, 0, 0} #define DeviceState_init_zero {false, MyNodeInfo_init_zero, false, User_init_zero, 0, {NodeInfo_init_zero, NodeInfo_init_zero, NodeInfo_init_zero, NodeInfo_init_zero, NodeInfo_init_zero, NodeInfo_init_zero, NodeInfo_init_zero, NodeInfo_init_zero, NodeInfo_init_zero, NodeInfo_init_zero, NodeInfo_init_zero, NodeInfo_init_zero, NodeInfo_init_zero, NodeInfo_init_zero, NodeInfo_init_zero, NodeInfo_init_zero, NodeInfo_init_zero, NodeInfo_init_zero, NodeInfo_init_zero, NodeInfo_init_zero, NodeInfo_init_zero, NodeInfo_init_zero, NodeInfo_init_zero, NodeInfo_init_zero, NodeInfo_init_zero, NodeInfo_init_zero, NodeInfo_init_zero, NodeInfo_init_zero, NodeInfo_init_zero, NodeInfo_init_zero, NodeInfo_init_zero, NodeInfo_init_zero, NodeInfo_init_zero, NodeInfo_init_zero, NodeInfo_init_zero, NodeInfo_init_zero, NodeInfo_init_zero, NodeInfo_init_zero, NodeInfo_init_zero, NodeInfo_init_zero, NodeInfo_init_zero, NodeInfo_init_zero, NodeInfo_init_zero, NodeInfo_init_zero, NodeInfo_init_zero, NodeInfo_init_zero, NodeInfo_init_zero, NodeInfo_init_zero, NodeInfo_init_zero, NodeInfo_init_zero, NodeInfo_init_zero, NodeInfo_init_zero, NodeInfo_init_zero, NodeInfo_init_zero, NodeInfo_init_zero, NodeInfo_init_zero, NodeInfo_init_zero, NodeInfo_init_zero, NodeInfo_init_zero, NodeInfo_init_zero, NodeInfo_init_zero, NodeInfo_init_zero, NodeInfo_init_zero, NodeInfo_init_zero, NodeInfo_init_zero, NodeInfo_init_zero, NodeInfo_init_zero, NodeInfo_init_zero, NodeInfo_init_zero, NodeInfo_init_zero, NodeInfo_init_zero, NodeInfo_init_zero, NodeInfo_init_zero, NodeInfo_init_zero, NodeInfo_init_zero, NodeInfo_init_zero, NodeInfo_init_zero, NodeInfo_init_zero, NodeInfo_init_zero, NodeInfo_init_zero}, 0, {MeshPacket_init_zero}, false, MeshPacket_init_zero, 0, 0, 0}
#define ChannelFile_init_zero {0, {Channel_init_zero, Channel_init_zero, Channel_init_zero, Channel_init_zero, Channel_init_zero, Channel_init_zero, Channel_init_zero, Channel_init_zero}} #define ChannelFile_init_zero {0, {Channel_init_zero, Channel_init_zero, Channel_init_zero, Channel_init_zero, Channel_init_zero, Channel_init_zero, Channel_init_zero, Channel_init_zero}}
#define OEMStore_init_zero {0, 0, {0, {0}}, _ScreenFonts_MIN, ""} #define OEMStore_init_zero {0, 0, {0, {0}}, _ScreenFonts_MIN, ""}
@@ -159,7 +159,7 @@ extern const pb_msgdesc_t OEMStore_msg;
/* Maximum encoded size of messages (where known) */ /* Maximum encoded size of messages (where known) */
#define ChannelFile_size 624 #define ChannelFile_size 624
#define DeviceState_size 19184 #define DeviceState_size 23728
#define OEMStore_size 2106 #define OEMStore_size 2106
#ifdef __cplusplus #ifdef __cplusplus

View File

@@ -126,7 +126,7 @@ extern const pb_msgdesc_t LocalModuleConfig_msg;
#define LocalModuleConfig_fields &LocalModuleConfig_msg #define LocalModuleConfig_fields &LocalModuleConfig_msg
/* Maximum encoded size of messages (where known) */ /* Maximum encoded size of messages (where known) */
#define LocalConfig_size 331 #define LocalConfig_size 317
#define LocalModuleConfig_size 282 #define LocalModuleConfig_size 282
#ifdef __cplusplus #ifdef __cplusplus

View File

@@ -48,6 +48,8 @@ typedef enum _PortNum {
PortNum_ADMIN_APP = 6, PortNum_ADMIN_APP = 6,
/* Compressed TEXT_MESSAGE payloads. */ /* Compressed TEXT_MESSAGE payloads. */
PortNum_TEXT_MESSAGE_COMPRESSED_APP = 7, PortNum_TEXT_MESSAGE_COMPRESSED_APP = 7,
/* Waypoint payloads. */
PortNum_WAYPOINT_APP = 8,
/* Provides a 'ping' service that replies to any packet it receives. /* Provides a 'ping' service that replies to any packet it receives.
Also serves as a small example module. */ Also serves as a small example module. */
PortNum_REPLY_APP = 32, PortNum_REPLY_APP = 32,

View File

@@ -12,26 +12,30 @@
/* Enum definitions */ /* Enum definitions */
/* TODO: REPLACE */ /* TODO: REPLACE */
typedef enum _TelemetrySensorType { typedef enum _TelemetrySensorType {
/* No external telemetry sensor */ /* No external telemetry sensor explicitly set */
TelemetrySensorType_NotSet = 0, TelemetrySensorType_NotSet = 0,
/* TODO: REPLACE */ /* Moderate accuracy temperature */
TelemetrySensorType_DHT11 = 1, TelemetrySensorType_DHT11 = 1,
/* TODO: REPLACE */ /* High accuracy temperature */
TelemetrySensorType_DS18B20 = 2, TelemetrySensorType_DS18B20 = 2,
/* TODO: REPLACE */ /* Moderate accuracy temperature and humidity */
TelemetrySensorType_DHT12 = 3, TelemetrySensorType_DHT12 = 3,
/* TODO: REPLACE */ /* Moderate accuracy temperature and humidity */
TelemetrySensorType_DHT21 = 4, TelemetrySensorType_DHT21 = 4,
/* TODO: REPLACE */ /* Moderate accuracy temperature and humidity */
TelemetrySensorType_DHT22 = 5, TelemetrySensorType_DHT22 = 5,
/* TODO: REPLACE */ /* High accuracy temperature, pressure, humidity */
TelemetrySensorType_BME280 = 6, TelemetrySensorType_BME280 = 6,
/* TODO: REPLACE */ /* High accuracy temperature, pressure, humidity, and air resistance */
TelemetrySensorType_BME680 = 7, TelemetrySensorType_BME680 = 7,
/* TODO: REPLACE */ /* Very high accuracy temperature */
TelemetrySensorType_MCP9808 = 8, TelemetrySensorType_MCP9808 = 8,
/* TODO: REPLACE */ /* Moderate accuracy temperature and humidity */
TelemetrySensorType_SHTC3 = 9 TelemetrySensorType_SHTC3 = 9,
/* Moderate accuracy current and voltage */
TelemetrySensorType_INA260 = 10,
/* Moderate accuracy current and voltage */
TelemetrySensorType_INA219 = 11
} TelemetrySensorType; } TelemetrySensorType;
/* Struct definitions */ /* Struct definitions */
@@ -82,8 +86,8 @@ typedef struct _Telemetry {
/* Helper constants for enums */ /* Helper constants for enums */
#define _TelemetrySensorType_MIN TelemetrySensorType_NotSet #define _TelemetrySensorType_MIN TelemetrySensorType_NotSet
#define _TelemetrySensorType_MAX TelemetrySensorType_SHTC3 #define _TelemetrySensorType_MAX TelemetrySensorType_INA219
#define _TelemetrySensorType_ARRAYSIZE ((TelemetrySensorType)(TelemetrySensorType_SHTC3+1)) #define _TelemetrySensorType_ARRAYSIZE ((TelemetrySensorType)(TelemetrySensorType_INA219+1))
#ifdef __cplusplus #ifdef __cplusplus

View File

@@ -17,14 +17,6 @@ AdminModule *adminModule;
/// a change. /// a change.
static const char *secretReserved = "sekrit"; static const char *secretReserved = "sekrit";
/// If buf is !empty, change it to secret
static void hideSecret(char *buf)
{
if (*buf) {
strcpy(buf, secretReserved);
}
}
/// If buf is the reserved secret word, replace the buffer with currentVal /// If buf is the reserved secret word, replace the buffer with currentVal
static void writeSecret(char *buf, const char *currentVal) static void writeSecret(char *buf, const char *currentVal)
{ {
@@ -314,11 +306,10 @@ void AdminModule::handleGetConfig(const MeshPacket &req, const uint32_t configTy
break; break;
} }
// NOTE: The phone app needs to know the ls_secs & phone_timeout value so it can properly expect sleep behavior. // NOTE: The phone app needs to know the ls_secs value so it can properly expect sleep behavior.
// So even if we internally use 0 to represent 'use default' we still need to send the value we are // So even if we internally use 0 to represent 'use default' we still need to send the value we are
// using to the app (so that even old phone apps work with new device loads). // using to the app (so that even old phone apps work with new device loads).
// r.get_radio_response.preferences.ls_secs = getPref_ls_secs(); // r.get_radio_response.preferences.ls_secs = getPref_ls_secs();
// r.get_radio_response.preferences.phone_timeout_secs = getPref_phone_timeout_secs();
// hideSecret(r.get_radio_response.preferences.wifi_ssid); // hmm - leave public for now, because only minimally private // hideSecret(r.get_radio_response.preferences.wifi_ssid); // hmm - leave public for now, because only minimally private
// and useful for users to know current provisioning) hideSecret(r.get_radio_response.preferences.wifi_password); // and useful for users to know current provisioning) hideSecret(r.get_radio_response.preferences.wifi_password);
// r.get_config_response.which_payloadVariant = Config_ModuleConfig_telemetry_tag; // r.get_config_response.which_payloadVariant = Config_ModuleConfig_telemetry_tag;
@@ -371,11 +362,10 @@ void AdminModule::handleGetModuleConfig(const MeshPacket &req, const uint32_t co
break; break;
} }
// NOTE: The phone app needs to know the ls_secs & phone_timeout value so it can properly expect sleep behavior. // NOTE: The phone app needs to know the ls_secsvalue so it can properly expect sleep behavior.
// So even if we internally use 0 to represent 'use default' we still need to send the value we are // So even if we internally use 0 to represent 'use default' we still need to send the value we are
// using to the app (so that even old phone apps work with new device loads). // using to the app (so that even old phone apps work with new device loads).
// r.get_radio_response.preferences.ls_secs = getPref_ls_secs(); // r.get_radio_response.preferences.ls_secs = getPref_ls_secs();
// r.get_radio_response.preferences.phone_timeout_secs = getPref_phone_timeout_secs();
// hideSecret(r.get_radio_response.preferences.wifi_ssid); // hmm - leave public for now, because only minimally private // hideSecret(r.get_radio_response.preferences.wifi_ssid); // hmm - leave public for now, because only minimally private
// and useful for users to know current provisioning) hideSecret(r.get_radio_response.preferences.wifi_password); // and useful for users to know current provisioning) hideSecret(r.get_radio_response.preferences.wifi_password);
// r.get_config_response.which_payloadVariant = Config_ModuleConfig_telemetry_tag; // r.get_config_response.which_payloadVariant = Config_ModuleConfig_telemetry_tag;

View File

@@ -16,12 +16,17 @@
#include "Sensor/DHTSensor.h" #include "Sensor/DHTSensor.h"
#include "Sensor/DallasSensor.h" #include "Sensor/DallasSensor.h"
#include "Sensor/MCP9808Sensor.h" #include "Sensor/MCP9808Sensor.h"
#include "Sensor/INA260Sensor.h"
#include "Sensor/INA219Sensor.h"
BME280Sensor bme280Sensor; BME280Sensor bme280Sensor;
BME680Sensor bme680Sensor; BME680Sensor bme680Sensor;
DHTSensor dhtSensor; DHTSensor dhtSensor;
DallasSensor dallasSensor; DallasSensor dallasSensor;
MCP9808Sensor mcp9808Sensor; MCP9808Sensor mcp9808Sensor;
INA260Sensor ina260Sensor;
INA219Sensor ina219Sensor;
#define FAILED_STATE_SENSOR_READ_MULTIPLIER 10 #define FAILED_STATE_SENSOR_READ_MULTIPLIER 10
#define DISPLAY_RECEIVEID_MEASUREMENTS_ON_SCREEN true #define DISPLAY_RECEIVEID_MEASUREMENTS_ON_SCREEN true
@@ -45,10 +50,12 @@ MCP9808Sensor mcp9808Sensor;
int32_t EnvironmentTelemetryModule::runOnce() int32_t EnvironmentTelemetryModule::runOnce()
{ {
#ifndef PORTDUINO #ifndef PORTDUINO
int32_t result = INT32_MAX;
/* /*
Uncomment the preferences below if you want to use the module Uncomment the preferences below if you want to use the module
without having to configure it from the PythonAPI or WebUI. without having to configure it from the PythonAPI or WebUI.
*/ */
/* /*
moduleConfig.telemetry.environment_measurement_enabled = 1; moduleConfig.telemetry.environment_measurement_enabled = 1;
moduleConfig.telemetry.environment_screen_enabled = 1; moduleConfig.telemetry.environment_screen_enabled = 1;
@@ -62,7 +69,7 @@ int32_t EnvironmentTelemetryModule::runOnce()
if (!(moduleConfig.telemetry.environment_measurement_enabled || if (!(moduleConfig.telemetry.environment_measurement_enabled ||
moduleConfig.telemetry.environment_screen_enabled)) { moduleConfig.telemetry.environment_screen_enabled)) {
// If this module is not enabled, and the user doesn't want the display screen don't waste any OSThread time on it // If this module is not enabled, and the user doesn't want the display screen don't waste any OSThread time on it
return (INT32_MAX); return result;
} }
if (firstTime) { if (firstTime) {
@@ -73,32 +80,37 @@ int32_t EnvironmentTelemetryModule::runOnce()
DEBUG_MSG("Environment Telemetry: Initializing\n"); DEBUG_MSG("Environment Telemetry: Initializing\n");
// it's possible to have this module enabled, only for displaying values on the screen. // it's possible to have this module enabled, only for displaying values on the screen.
// therefore, we should only enable the sensor loop if measurement is also enabled // therefore, we should only enable the sensor loop if measurement is also enabled
switch (moduleConfig.telemetry.environment_sensor_type) {
switch (moduleConfig.telemetry.environment_sensor_type) {
case TelemetrySensorType_DHT11: case TelemetrySensorType_DHT11:
case TelemetrySensorType_DHT12: case TelemetrySensorType_DHT12:
case TelemetrySensorType_DHT21: case TelemetrySensorType_DHT21:
case TelemetrySensorType_DHT22: case TelemetrySensorType_DHT22:
return dhtSensor.runOnce(); result = dhtSensor.runOnce();
break;
case TelemetrySensorType_DS18B20: case TelemetrySensorType_DS18B20:
return dallasSensor.runOnce(); result = dallasSensor.runOnce();
case TelemetrySensorType_BME280: break;
return bme280Sensor.runOnce();
case TelemetrySensorType_BME680:
return bme680Sensor.runOnce();
case TelemetrySensorType_MCP9808:
return mcp9808Sensor.runOnce();
default: default:
DEBUG_MSG("Environment Telemetry: Invalid sensor type selected; Disabling module"); DEBUG_MSG("Environment Telemetry: No sensor type specified; Checking for detected i2c sensors\n");
return (INT32_MAX);
break; break;
} }
if (bme680Sensor.hasSensor())
result = bme680Sensor.runOnce();
if (bme280Sensor.hasSensor())
result = bme280Sensor.runOnce();
if (mcp9808Sensor.hasSensor())
result = mcp9808Sensor.runOnce();
if (ina260Sensor.hasSensor())
result = ina260Sensor.runOnce();
if (ina219Sensor.hasSensor())
result = ina219Sensor.runOnce();
} }
return (INT32_MAX); return result;
} else { } else {
// if we somehow got to a second run of this module with measurement disabled, then just wait forever // if we somehow got to a second run of this module with measurement disabled, then just wait forever
if (!moduleConfig.telemetry.environment_measurement_enabled) if (!moduleConfig.telemetry.environment_measurement_enabled)
return (INT32_MAX); return result;
// this is not the first time OSThread library has called this function // this is not the first time OSThread library has called this function
// so just do what we intend to do on the interval // so just do what we intend to do on the interval
if (sensor_read_error_count > moduleConfig.telemetry.environment_read_error_count_threshold) { if (sensor_read_error_count > moduleConfig.telemetry.environment_read_error_count_threshold) {
@@ -114,7 +126,7 @@ int32_t EnvironmentTelemetryModule::runOnce()
DEBUG_MSG("Environment Telemetry: DISABLED; The telemetry_module_environment_read_error_count_threshold has " DEBUG_MSG("Environment Telemetry: DISABLED; The telemetry_module_environment_read_error_count_threshold has "
"been exceed: %d. Reads will not be retried until after device reset\n", "been exceed: %d. Reads will not be retried until after device reset\n",
moduleConfig.telemetry.environment_read_error_count_threshold); moduleConfig.telemetry.environment_read_error_count_threshold);
return (INT32_MAX); return result;
} else if (sensor_read_error_count > 0) { } else if (sensor_read_error_count > 0) {
DEBUG_MSG("Environment Telemetry: There have been %d sensor read failures. Will retry %d more times\n", DEBUG_MSG("Environment Telemetry: There have been %d sensor read failures. Will retry %d more times\n",
@@ -124,23 +136,7 @@ int32_t EnvironmentTelemetryModule::runOnce()
if (!sendOurTelemetry()) { if (!sendOurTelemetry()) {
// if we failed to read the sensor, then try again // if we failed to read the sensor, then try again
// as soon as we can according to the maximum polling frequency // as soon as we can according to the maximum polling frequency
return DEFAULT_SENSOR_MINIMUM_WAIT_TIME_BETWEEN_READS;
switch (moduleConfig.telemetry.environment_sensor_type) {
case TelemetrySensorType_DHT11:
case TelemetrySensorType_DHT12:
case TelemetrySensorType_DHT21:
case TelemetrySensorType_DHT22:
return (DHT_SENSOR_MINIMUM_WAIT_TIME_BETWEEN_READS);
case TelemetrySensorType_DS18B20:
return (DS18B20_SENSOR_MINIMUM_WAIT_TIME_BETWEEN_READS);
case TelemetrySensorType_BME280:
case TelemetrySensorType_BME680:
return (BME_SENSOR_MINIMUM_WAIT_TIME_BETWEEN_READS);
case TelemetrySensorType_MCP9808:
return (MCP_SENSOR_MINIMUM_WAIT_TIME_BETWEEN_READS);
default:
return (DEFAULT_SENSOR_MINIMUM_WAIT_TIME_BETWEEN_READS);
}
} }
} }
return getIntervalOrDefaultMs(moduleConfig.telemetry.environment_update_interval); return getIntervalOrDefaultMs(moduleConfig.telemetry.environment_update_interval);
@@ -246,28 +242,29 @@ bool EnvironmentTelemetryModule::sendOurTelemetry(NodeNum dest, bool wantReplies
switch (moduleConfig.telemetry.environment_sensor_type) { switch (moduleConfig.telemetry.environment_sensor_type) {
case TelemetrySensorType_DS18B20: case TelemetrySensorType_DS18B20:
if (!dallasSensor.getMeasurement(&m)) if (!dallasSensor.getMetrics(&m))
sensor_read_error_count++; sensor_read_error_count++;
break; break;
case TelemetrySensorType_DHT11: case TelemetrySensorType_DHT11:
case TelemetrySensorType_DHT12: case TelemetrySensorType_DHT12:
case TelemetrySensorType_DHT21: case TelemetrySensorType_DHT21:
case TelemetrySensorType_DHT22: case TelemetrySensorType_DHT22:
if (!dhtSensor.getMeasurement(&m)) if (!dhtSensor.getMetrics(&m))
sensor_read_error_count++; sensor_read_error_count++;
break; break;
case TelemetrySensorType_BME280:
bme280Sensor.getMeasurement(&m);
break;
case TelemetrySensorType_BME680:
bme680Sensor.getMeasurement(&m);
break;
case TelemetrySensorType_MCP9808:
mcp9808Sensor.getMeasurement(&m);
break;
default: default:
DEBUG_MSG("Environment Telemetry: No external sensor type selected; Only sending internal metrics\n"); DEBUG_MSG("Environment Telemetry: No specified sensor type; Trying any detected i2c sensors\n");
} }
if (bme280Sensor.hasSensor())
bme280Sensor.getMetrics(&m);
if (bme680Sensor.hasSensor())
bme680Sensor.getMetrics(&m);
if (mcp9808Sensor.hasSensor())
mcp9808Sensor.getMetrics(&m);
if (ina219Sensor.hasSensor())
ina219Sensor.getMetrics(&m);
if (ina260Sensor.hasSensor())
ina260Sensor.getMetrics(&m);
DEBUG_MSG("Telemetry->time: %i\n", m.time); DEBUG_MSG("Telemetry->time: %i\n", m.time);
DEBUG_MSG("Telemetry->barometric_pressure: %f\n", m.variant.environment_metrics.barometric_pressure); DEBUG_MSG("Telemetry->barometric_pressure: %f\n", m.variant.environment_metrics.barometric_pressure);

View File

@@ -3,24 +3,26 @@
#include "TelemetrySensor.h" #include "TelemetrySensor.h"
#include "BME280Sensor.h" #include "BME280Sensor.h"
#include <Adafruit_BME280.h> #include <Adafruit_BME280.h>
#include <typeinfo>
BME280Sensor::BME280Sensor() : TelemetrySensor {} { BME280Sensor::BME280Sensor() :
TelemetrySensor(TelemetrySensorType_BME280, "BME280")
{
} }
int32_t BME280Sensor::runOnce() { int32_t BME280Sensor::runOnce() {
unsigned bme280Status; DEBUG_MSG("Init sensor: %s\n", sensorName);
// Default i2c address for BME280 if (!hasSensor()) {
bme280Status = bme280.begin(0x76); return DEFAULT_SENSOR_MINIMUM_WAIT_TIME_BETWEEN_READS;
if (!bme280Status) {
DEBUG_MSG("Could not find a valid BME280 sensor, check wiring, address, sensor ID!");
// TODO more verbose diagnostics
} else {
DEBUG_MSG("Telemetry: Opened BME280 on default i2c bus");
} }
return BME_SENSOR_MINIMUM_WAIT_TIME_BETWEEN_READS; status = bme280.begin(nodeTelemetrySensorsMap[sensorType]);
return initI2CSensor();
} }
bool BME280Sensor::getMeasurement(Telemetry *measurement) { void BME280Sensor::setup() { }
bool BME280Sensor::getMetrics(Telemetry *measurement) {
DEBUG_MSG("BME280Sensor::getMetrics\n");
measurement->variant.environment_metrics.temperature = bme280.readTemperature(); measurement->variant.environment_metrics.temperature = bme280.readTemperature();
measurement->variant.environment_metrics.relative_humidity = bme280.readHumidity(); measurement->variant.environment_metrics.relative_humidity = bme280.readHumidity();
measurement->variant.environment_metrics.barometric_pressure = bme280.readPressure() / 100.0F; measurement->variant.environment_metrics.barometric_pressure = bme280.readPressure() / 100.0F;

View File

@@ -2,14 +2,15 @@
#include "TelemetrySensor.h" #include "TelemetrySensor.h"
#include <Adafruit_BME280.h> #include <Adafruit_BME280.h>
#define BME_SENSOR_MINIMUM_WAIT_TIME_BETWEEN_READS 1000
class BME280Sensor : virtual public TelemetrySensor { class BME280Sensor : virtual public TelemetrySensor {
private: private:
Adafruit_BME280 bme280; Adafruit_BME280 bme280;
protected:
virtual void setup() override;
public: public:
BME280Sensor(); BME280Sensor();
virtual int32_t runOnce() override; virtual int32_t runOnce() override;
virtual bool getMeasurement(Telemetry *measurement) override; virtual bool getMetrics(Telemetry *measurement) override;
}; };

View File

@@ -4,18 +4,22 @@
#include "BME680Sensor.h" #include "BME680Sensor.h"
#include <Adafruit_BME680.h> #include <Adafruit_BME680.h>
BME680Sensor::BME680Sensor() : TelemetrySensor {} { BME680Sensor::BME680Sensor() :
TelemetrySensor(TelemetrySensorType_BME680, "BME680")
{
} }
int32_t BME680Sensor::runOnce() { int32_t BME680Sensor::runOnce() {
unsigned bme680Status; DEBUG_MSG("Init sensor: %s\n", sensorName);
// Default i2c address for BME680 if (!hasSensor()) {
bme680Status = bme680.begin(0x76); return DEFAULT_SENSOR_MINIMUM_WAIT_TIME_BETWEEN_READS;
if (!bme680Status) { }
DEBUG_MSG("Could not find a valid BME680 sensor, check wiring, address, sensor ID!"); status = bme680.begin(nodeTelemetrySensorsMap[sensorType]);
// TODO more verbose TelemetrySensor return initI2CSensor();
} else { }
DEBUG_MSG("Telemetry: Opened BME680 on default i2c bus");
void BME680Sensor::setup()
{
// Set up oversampling and filter initialization // Set up oversampling and filter initialization
bme680.setTemperatureOversampling(BME680_OS_8X); bme680.setTemperatureOversampling(BME680_OS_8X);
bme680.setHumidityOversampling(BME680_OS_2X); bme680.setHumidityOversampling(BME680_OS_2X);
@@ -23,10 +27,8 @@ int32_t BME680Sensor::runOnce() {
bme680.setIIRFilterSize(BME680_FILTER_SIZE_3); bme680.setIIRFilterSize(BME680_FILTER_SIZE_3);
bme680.setGasHeater(320, 150); // 320*C for 150 ms bme680.setGasHeater(320, 150); // 320*C for 150 ms
} }
return (BME_680_SENSOR_MINIMUM_WAIT_TIME_BETWEEN_READS);
}
bool BME680Sensor::getMeasurement(Telemetry *measurement) { bool BME680Sensor::getMetrics(Telemetry *measurement) {
measurement->variant.environment_metrics.temperature = bme680.readTemperature(); measurement->variant.environment_metrics.temperature = bme680.readTemperature();
measurement->variant.environment_metrics.relative_humidity = bme680.readHumidity(); measurement->variant.environment_metrics.relative_humidity = bme680.readHumidity();
measurement->variant.environment_metrics.barometric_pressure = bme680.readPressure() / 100.0F; measurement->variant.environment_metrics.barometric_pressure = bme680.readPressure() / 100.0F;

View File

@@ -2,14 +2,15 @@
#include "TelemetrySensor.h" #include "TelemetrySensor.h"
#include <Adafruit_BME680.h> #include <Adafruit_BME680.h>
#define BME_680_SENSOR_MINIMUM_WAIT_TIME_BETWEEN_READS 1000
class BME680Sensor : virtual public TelemetrySensor { class BME680Sensor : virtual public TelemetrySensor {
private: private:
Adafruit_BME680 bme680; Adafruit_BME680 bme680;
protected:
virtual void setup() override;
public: public:
BME680Sensor(); BME680Sensor();
virtual int32_t runOnce() override; virtual int32_t runOnce() override;
virtual bool getMeasurement(Telemetry *measurement) override; virtual bool getMetrics(Telemetry *measurement) override;
}; };

View File

@@ -5,11 +5,14 @@
#include "configuration.h" #include "configuration.h"
#include <DHT.h> #include <DHT.h>
DHTSensor::DHTSensor() : TelemetrySensor{} {} DHTSensor::DHTSensor() :
TelemetrySensor(TelemetrySensorType_NotSet, "DHT")
int32_t DHTSensor::runOnce()
{ {
if (TelemetrySensorType_DHT11 || TelemetrySensorType_DHT12) { }
int32_t DHTSensor::runOnce() {
if (moduleConfig.telemetry.environment_sensor_type == TelemetrySensorType_DHT11 ||
moduleConfig.telemetry.environment_sensor_type == TelemetrySensorType_DHT12) {
dht = new DHT(moduleConfig.telemetry.environment_sensor_pin, DHT11); dht = new DHT(moduleConfig.telemetry.environment_sensor_pin, DHT11);
} else { } else {
dht = new DHT(moduleConfig.telemetry.environment_sensor_pin, DHT22); dht = new DHT(moduleConfig.telemetry.environment_sensor_pin, DHT22);
@@ -17,13 +20,15 @@ int32_t DHTSensor::runOnce()
dht->begin(); dht->begin();
dht->read(); dht->read();
DEBUG_MSG("Telemetry: Opened DHT11/DHT12 on pin: %d\n", moduleConfig.telemetry.environment_sensor_pin); DEBUG_MSG("Opened DHT11/DHT12 on pin: %d\n", moduleConfig.telemetry.environment_sensor_pin);
return (DHT_SENSOR_MINIMUM_WAIT_TIME_BETWEEN_READS); return DEFAULT_SENSOR_MINIMUM_WAIT_TIME_BETWEEN_READS;
} }
bool DHTSensor::getMeasurement(Telemetry *measurement) void DHTSensor::setup() { }
{
bool DHTSensor::getMetrics(Telemetry *measurement) {
DEBUG_MSG("DHTSensor::getMetrics\n");
if (!dht->read(true)) { if (!dht->read(true)) {
DEBUG_MSG("Telemetry: FAILED TO READ DATA\n"); DEBUG_MSG("Telemetry: FAILED TO READ DATA\n");
return false; return false;

View File

@@ -2,14 +2,15 @@
#include "TelemetrySensor.h" #include "TelemetrySensor.h"
#include <DHT.h> #include <DHT.h>
#define DHT_SENSOR_MINIMUM_WAIT_TIME_BETWEEN_READS 1000
class DHTSensor : virtual public TelemetrySensor { class DHTSensor : virtual public TelemetrySensor {
private: private:
DHT *dht = NULL; DHT *dht = NULL;
protected:
virtual void setup() override;
public: public:
DHTSensor(); DHTSensor();
virtual int32_t runOnce() override; virtual int32_t runOnce() override;
virtual bool getMeasurement(Telemetry *measurement) override; virtual bool getMetrics(Telemetry *measurement) override;
}; };

View File

@@ -6,21 +6,25 @@
#include <DS18B20.h> #include <DS18B20.h>
#include <OneWire.h> #include <OneWire.h>
DallasSensor::DallasSensor() : TelemetrySensor{} {} DallasSensor::DallasSensor() :
TelemetrySensor(TelemetrySensorType_DS18B20, "DS18B20")
int32_t DallasSensor::runOnce()
{ {
}
int32_t DallasSensor::runOnce() {
oneWire = new OneWire(moduleConfig.telemetry.environment_sensor_pin); oneWire = new OneWire(moduleConfig.telemetry.environment_sensor_pin);
ds18b20 = new DS18B20(oneWire); ds18b20 = new DS18B20(oneWire);
ds18b20->begin(); ds18b20->begin();
ds18b20->setResolution(12); ds18b20->setResolution(12);
ds18b20->requestTemperatures(); ds18b20->requestTemperatures();
DEBUG_MSG("Telemetry: Opened DS18B20 on pin: %d\n", moduleConfig.telemetry.environment_sensor_pin); DEBUG_MSG("Opened DS18B20 on pin: %d\n", moduleConfig.telemetry.environment_sensor_pin);
return (DS18B20_SENSOR_MINIMUM_WAIT_TIME_BETWEEN_READS); return DEFAULT_SENSOR_MINIMUM_WAIT_TIME_BETWEEN_READS;
} }
bool DallasSensor::getMeasurement(Telemetry *measurement) void DallasSensor::setup() {}
{
bool DallasSensor::getMetrics(Telemetry *measurement){
DEBUG_MSG("DallasSensor::getMetrics\n");
if (ds18b20->isConversionComplete()) { if (ds18b20->isConversionComplete()) {
measurement->variant.environment_metrics.temperature = ds18b20->getTempC(); measurement->variant.environment_metrics.temperature = ds18b20->getTempC();
measurement->variant.environment_metrics.relative_humidity = 0; measurement->variant.environment_metrics.relative_humidity = 0;

View File

@@ -3,15 +3,16 @@
#include <DS18B20.h> #include <DS18B20.h>
#include <OneWire.h> #include <OneWire.h>
#define DS18B20_SENSOR_MINIMUM_WAIT_TIME_BETWEEN_READS 1000
class DallasSensor : virtual public TelemetrySensor { class DallasSensor : virtual public TelemetrySensor {
private: private:
OneWire *oneWire = NULL; OneWire *oneWire = NULL;
DS18B20 *ds18b20 = NULL; DS18B20 *ds18b20 = NULL;
protected:
virtual void setup() override;
public: public:
DallasSensor(); DallasSensor();
virtual int32_t runOnce() override; virtual int32_t runOnce() override;
virtual bool getMeasurement(Telemetry *measurement) override; virtual bool getMetrics(Telemetry *measurement) override;
}; };

View File

@@ -0,0 +1,30 @@
#include "../mesh/generated/telemetry.pb.h"
#include "configuration.h"
#include "TelemetrySensor.h"
#include "INA219Sensor.h"
#include <Adafruit_INA219.h>
INA219Sensor::INA219Sensor() :
TelemetrySensor(TelemetrySensorType_INA219, "INA219")
{
}
int32_t INA219Sensor::runOnce() {
DEBUG_MSG("Init sensor: %s\n", sensorName);
if (!hasSensor()) {
return DEFAULT_SENSOR_MINIMUM_WAIT_TIME_BETWEEN_READS;
}
ina219 = Adafruit_INA219(nodeTelemetrySensorsMap[sensorType]);
status = ina219.begin();
return initI2CSensor();
}
void INA219Sensor::setup()
{
}
bool INA219Sensor::getMetrics(Telemetry *measurement) {
measurement->variant.environment_metrics.voltage = ina219.getBusVoltage_V();
measurement->variant.environment_metrics.current = ina219.getCurrent_mA();
return true;
}

View File

@@ -0,0 +1,17 @@
#include "../mesh/generated/telemetry.pb.h"
#include "TelemetrySensor.h"
#include <Adafruit_INA219.h>
class INA219Sensor : virtual public TelemetrySensor {
private:
Adafruit_INA219 ina219;
protected:
virtual void setup() override;
public:
INA219Sensor();
virtual int32_t runOnce() override;
virtual bool getMetrics(Telemetry *measurement) override;
};

View File

@@ -0,0 +1,30 @@
#include "../mesh/generated/telemetry.pb.h"
#include "configuration.h"
#include "TelemetrySensor.h"
#include "INA260Sensor.h"
#include <Adafruit_INA260.h>
INA260Sensor::INA260Sensor() :
TelemetrySensor(TelemetrySensorType_INA260, "INA260")
{
}
int32_t INA260Sensor::runOnce() {
DEBUG_MSG("Init sensor: %s\n", sensorName);
if (!hasSensor()) {
return DEFAULT_SENSOR_MINIMUM_WAIT_TIME_BETWEEN_READS;
}
status = ina260.begin(nodeTelemetrySensorsMap[sensorType]);
return initI2CSensor();
}
void INA260Sensor::setup()
{
}
bool INA260Sensor::getMetrics(Telemetry *measurement) {
// mV conversion to V
measurement->variant.environment_metrics.voltage = ina260.readBusVoltage() / 1000;
measurement->variant.environment_metrics.current = ina260.readCurrent();
return true;
}

View File

@@ -0,0 +1,17 @@
#include "../mesh/generated/telemetry.pb.h"
#include "TelemetrySensor.h"
#include <Adafruit_INA260.h>
class INA260Sensor : virtual public TelemetrySensor {
private:
Adafruit_INA260 ina260 = Adafruit_INA260();
protected:
virtual void setup() override;
public:
INA260Sensor();
virtual int32_t runOnce() override;
virtual bool getMetrics(Telemetry *measurement) override;
};

View File

@@ -4,25 +4,26 @@
#include "MCP9808Sensor.h" #include "MCP9808Sensor.h"
#include <Adafruit_MCP9808.h> #include <Adafruit_MCP9808.h>
MCP9808Sensor::MCP9808Sensor() : TelemetrySensor {} { MCP9808Sensor::MCP9808Sensor() :
TelemetrySensor(TelemetrySensorType_MCP9808, "MCP9808")
{
} }
int32_t MCP9808Sensor::runOnce() { int32_t MCP9808Sensor::runOnce() {
unsigned mcp9808Status; DEBUG_MSG("Init sensor: %s\n", sensorName);
// Default i2c address for MCP9808 if (!hasSensor()) {
mcp9808Status = mcp9808.begin(0x18); return DEFAULT_SENSOR_MINIMUM_WAIT_TIME_BETWEEN_READS;
if (!mcp9808Status) { }
DEBUG_MSG("Could not find a valid MCP9808 sensor, check wiring, address, sensor ID!"); status = mcp9808.begin(nodeTelemetrySensorsMap[sensorType]);
} else { return initI2CSensor();
DEBUG_MSG("TelemetrySensor: Opened MCP9808 on default i2c bus"); }
// Reduce resolution from 0.0625 degrees (precision) to 0.125 degrees (high).
void MCP9808Sensor::setup() {
mcp9808.setResolution(2); mcp9808.setResolution(2);
} }
return (MCP_SENSOR_MINIMUM_WAIT_TIME_BETWEEN_READS);
}
bool MCP9808Sensor::getMeasurement(Telemetry *measurement) { bool MCP9808Sensor::getMetrics(Telemetry *measurement) {
DEBUG_MSG("MCP9808Sensor::getMetrics\n");
measurement->variant.environment_metrics.temperature = mcp9808.readTempC(); measurement->variant.environment_metrics.temperature = mcp9808.readTempC();
return true; return true;
} }

View File

@@ -2,14 +2,15 @@
#include "TelemetrySensor.h" #include "TelemetrySensor.h"
#include <Adafruit_MCP9808.h> #include <Adafruit_MCP9808.h>
#define MCP_SENSOR_MINIMUM_WAIT_TIME_BETWEEN_READS 1000
class MCP9808Sensor : virtual public TelemetrySensor { class MCP9808Sensor : virtual public TelemetrySensor {
private: private:
Adafruit_MCP9808 mcp9808; Adafruit_MCP9808 mcp9808;
protected:
virtual void setup() override;
public: public:
MCP9808Sensor(); MCP9808Sensor();
virtual int32_t runOnce() override; virtual int32_t runOnce() override;
virtual bool getMeasurement(Telemetry *measurement) override; virtual bool getMetrics(Telemetry *measurement) override;
}; };

View File

@@ -0,0 +1,4 @@
#include "TelemetrySensor.h"
#include "../mesh/generated/telemetry.pb.h"
#include "NodeDB.h"
#include "main.h"

View File

@@ -1,14 +1,41 @@
#pragma once #pragma once
#include "../mesh/generated/telemetry.pb.h" #include "../mesh/generated/telemetry.pb.h"
#include "NodeDB.h" #include "NodeDB.h"
#include "main.h"
#define DEFAULT_SENSOR_MINIMUM_WAIT_TIME_BETWEEN_READS 1000 #define DEFAULT_SENSOR_MINIMUM_WAIT_TIME_BETWEEN_READS 1000
class TelemetrySensor class TelemetrySensor
{ {
protected: protected:
TelemetrySensor() {} TelemetrySensor(TelemetrySensorType sensorType, const char *sensorName)
{
this->sensorName = sensorName;
this->sensorType = sensorType;
this->status = 0;
}
const char *sensorName;
TelemetrySensorType sensorType;
unsigned status;
int32_t initI2CSensor() {
if (!status) {
DEBUG_MSG("Could not connect to detected %s sensor.\n Removing from nodeTelemetrySensorsMap.\n", sensorName);
nodeTelemetrySensorsMap[sensorType] = 0;
} else {
DEBUG_MSG("Opened %s sensor on default i2c bus\n", sensorName);
setup();
}
return DEFAULT_SENSOR_MINIMUM_WAIT_TIME_BETWEEN_READS;
}
virtual void setup();
public: public:
bool hasSensor() {
return sensorType < sizeof(nodeTelemetrySensorsMap) && nodeTelemetrySensorsMap[sensorType] > 0;
}
virtual int32_t runOnce() = 0; virtual int32_t runOnce() = 0;
virtual bool getMeasurement(Telemetry *measurement) = 0; virtual bool getMetrics(Telemetry *measurement) = 0;
}; };

View File

@@ -16,48 +16,54 @@ class NRF52CryptoEngine : public CryptoEngine
*/ */
virtual void encrypt(uint32_t fromNode, uint64_t packetId, size_t numBytes, uint8_t *bytes) override virtual void encrypt(uint32_t fromNode, uint64_t packetId, size_t numBytes, uint8_t *bytes) override
{ {
// DEBUG_MSG("NRF52 encrypt!\n"); hexDump("before", bytes, numBytes, 16);
if (key.length > 16) { if (key.length > 16) {
DEBUG_MSG("Software encrypt fr=%x, num=%x, numBytes=%d!\n", fromNode, (uint32_t) packetId, numBytes);
AES_ctx ctx; AES_ctx ctx;
initNonce(fromNode, packetId); initNonce(fromNode, packetId);
AES_init_ctx_iv(&ctx, key.bytes, nonce); AES_init_ctx_iv(&ctx, key.bytes, nonce);
AES_CTR_xcrypt_buffer(&ctx, bytes, numBytes); AES_CTR_xcrypt_buffer(&ctx, bytes, numBytes);
} else if (key.length > 0) { } else if (key.length > 0) {
DEBUG_MSG("nRF52 encrypt fr=%x, num=%x, numBytes=%d!\n", fromNode, (uint32_t) packetId, numBytes);
nRFCrypto.begin(); nRFCrypto.begin();
nRFCrypto_AES ctx; nRFCrypto_AES ctx;
uint8_t myLen = ctx.blockLen(numBytes); uint8_t myLen = ctx.blockLen(numBytes);
DEBUG_MSG("nRF52 encBuf myLen=%d!\n", myLen);
char encBuf[myLen] = {0}; char encBuf[myLen] = {0};
memcpy(encBuf, bytes, numBytes);
initNonce(fromNode, packetId); initNonce(fromNode, packetId);
ctx.begin(); ctx.begin();
ctx.Process(encBuf, numBytes, nonce, key.bytes, key.length, (char*)bytes, ctx.encryptFlag, ctx.ctrMode); ctx.Process((char*)bytes, numBytes, nonce, key.bytes, key.length, encBuf, ctx.encryptFlag, ctx.ctrMode);
ctx.end(); ctx.end();
nRFCrypto.end(); nRFCrypto.end();
memcpy(bytes, encBuf, numBytes);
} }
hexDump("after", bytes, numBytes, 16);
} }
virtual void decrypt(uint32_t fromNode, uint64_t packetId, size_t numBytes, uint8_t *bytes) override virtual void decrypt(uint32_t fromNode, uint64_t packetId, size_t numBytes, uint8_t *bytes) override
{ {
// DEBUG_MSG("NRF52 decrypt!\n"); hexDump("before", bytes, numBytes, 16);
if (key.length > 16) { if (key.length > 16) {
DEBUG_MSG("Software decrypt fr=%x, num=%x, numBytes=%d!\n", fromNode, (uint32_t) packetId, numBytes);
AES_ctx ctx; AES_ctx ctx;
initNonce(fromNode, packetId); initNonce(fromNode, packetId);
AES_init_ctx_iv(&ctx, key.bytes, nonce); AES_init_ctx_iv(&ctx, key.bytes, nonce);
AES_CTR_xcrypt_buffer(&ctx, bytes, numBytes); AES_CTR_xcrypt_buffer(&ctx, bytes, numBytes);
} else if (key.length > 0) { } else if (key.length > 0) {
DEBUG_MSG("nRF52 decrypt fr=%x, num=%x, numBytes=%d!\n", fromNode, (uint32_t) packetId, numBytes);
nRFCrypto.begin(); nRFCrypto.begin();
nRFCrypto_AES ctx; nRFCrypto_AES ctx;
uint8_t myLen = ctx.blockLen(numBytes); uint8_t myLen = ctx.blockLen(numBytes);
DEBUG_MSG("nRF52 decBuf myLen=%d!\n", myLen);
char decBuf[myLen] = {0}; char decBuf[myLen] = {0};
memcpy(decBuf, bytes, numBytes);
initNonce(fromNode, packetId); initNonce(fromNode, packetId);
ctx.begin(); ctx.begin();
ctx.Process(decBuf, numBytes, nonce, key.bytes, key.length, (char*)bytes, ctx.decryptFlag, ctx.ctrMode); ctx.Process((char*)bytes, numBytes, nonce, key.bytes, key.length, decBuf, ctx.decryptFlag, ctx.ctrMode);
ctx.end(); ctx.end();
nRFCrypto.end(); nRFCrypto.end();
memcpy(bytes, decBuf, numBytes);
} }
hexDump("after", bytes, numBytes, 16);
} }
private: private:

View File

@@ -30,7 +30,7 @@ void powerCommandsCheck()
DEBUG_MSG("Shutting down from admin command\n"); DEBUG_MSG("Shutting down from admin command\n");
#ifdef TBEAM_V10 #ifdef TBEAM_V10
if (axp192_found == true) { if (axp192_found == true) {
// setLed(false); //TODO: FIXME: this is not working playShutdownMelody();
power->shutdown(); power->shutdown();
} }
#elif NRF52_SERIES #elif NRF52_SERIES

View File

@@ -0,0 +1,18 @@
[env:m5stack-coreink]
extends = esp32_base
board = m5stack-coreink
build_flags =
${esp32_base.build_flags} -D M5_COREINK -I variants/m5stack_coreink
;-D RADIOLIB_VERBOSE
-Ofast
-D__MCUXPRESSO
-DEPD_HEIGHT=200
-DEPD_WIDTH=200
-DM5STACK
lib_deps =
${esp32_base.lib_deps}
zinggjm/GxEPD2@^1.4.5
lewisxhe/PCF8563_Library@^0.0.1
board_build.f_cpu = 240000000L
upload_protocol = esptool
upload_port = /dev/ttyACM*

View File

@@ -0,0 +1,49 @@
#define I2C_SDA 21 //-1
#define I2C_SCL 22 //-1
//#define LED_PIN 10
#include "pcf8563.h"
// PCF8563 RTC Module
#define PCF8563_RTC 0x51
#define BUTTON_NEED_PULLUP
#define BUTTON_PIN 5
//Wheel
// Down 37
// Push 38
// Up 39
// Top Physical Button 5
#undef RF95_SCK
#undef RF95_MISO
#undef RF95_MOSI
#undef RF95_NSS
#define USE_RF95
#define RF95_SCK 18 //13
#define RF95_MISO 34 //26
#define RF95_MOSI 23 //25
#define RF95_NSS 14
#define LORA_DIO0 25 //32 now moved from ext port
#define LORA_RESET 26 //33 now moved from ext port
#define LORA_DIO1 RADIOLIB_NC
#define LORA_DIO2 RADIOLIB_NC
#define NO_GPS
// This board has no GPS for now
#undef GPS_RX_PIN
#undef GPS_TX_PIN
#define HAS_EINK
//https://docs.m5stack.com/en/core/coreink
//https://m5stack.oss-cn-shenzhen.aliyuncs.com/resource/docs/schematic/Core/coreink/coreink_sch.pdf
#define PIN_EINK_EN -1
#define PIN_EINK_CS 9 // EPD_CS
#define PIN_EINK_BUSY 4 // EPD_BUSY
#define PIN_EINK_DC 15 // EPD_D/C
#define PIN_EINK_RES -1 // Connected to GPIO0 but no needed !!!! maybe causing issue ?
#define PIN_EINK_SCLK 18 // EPD_SCLK
#define PIN_EINK_MOSI 23 // EPD_MOSI

View File

@@ -1,4 +1,4 @@
[VERSION] [VERSION]
major = 1 major = 1
minor = 3 minor = 3
build = 12 build = 16