mirror of
https://github.com/meshtastic/firmware.git
synced 2025-04-25 09:42:35 +00:00
Merge branch 'master' into t3s3-1121
This commit is contained in:
commit
5c77e29d66
@ -13,16 +13,13 @@
|
||||
},
|
||||
"customizations": {
|
||||
"vscode": {
|
||||
"extensions": [
|
||||
"ms-vscode.cpptools",
|
||||
"platformio.platformio-ide",
|
||||
]
|
||||
"extensions": ["ms-vscode.cpptools", "platformio.platformio-ide"]
|
||||
}
|
||||
},
|
||||
|
||||
// Use 'forwardPorts' to make a list of ports inside the container available locally.
|
||||
"forwardPorts": [ 4403 ],
|
||||
"forwardPorts": [4403],
|
||||
|
||||
// Run commands to prepare the container for use
|
||||
"postCreateCommand": ".devcontainer/setup.sh",
|
||||
"postCreateCommand": ".devcontainer/setup.sh"
|
||||
}
|
||||
|
@ -1,3 +1,3 @@
|
||||
#!/usr/bin/env sh
|
||||
|
||||
git submodule update --init
|
||||
git submodule update --init
|
||||
|
8
.github/workflows/tests.yml
vendored
8
.github/workflows/tests.yml
vendored
@ -65,7 +65,7 @@ jobs:
|
||||
# - uses: actions/setup-python@v5
|
||||
# with:
|
||||
# python-version: '3.10'
|
||||
|
||||
|
||||
# pipx install "setuptools<72"
|
||||
- name: Upgrade python tools
|
||||
shell: bash
|
||||
@ -76,10 +76,10 @@ jobs:
|
||||
|
||||
- name: Install PlatformIO from script
|
||||
shell: bash
|
||||
run: |
|
||||
run: |
|
||||
curl -fsSL -o get-platformio.py https://raw.githubusercontent.com/platformio/platformio-core-installer/master/get-platformio.py
|
||||
python3 get-platformio.py
|
||||
|
||||
|
||||
- name: Upgrade platformio
|
||||
shell: bash
|
||||
run: |
|
||||
@ -90,7 +90,7 @@ jobs:
|
||||
uses: actions/setup-node@v4
|
||||
with:
|
||||
node-version: 18
|
||||
|
||||
|
||||
- name: Setup pnpm
|
||||
uses: pnpm/action-setup@v4
|
||||
with:
|
||||
|
12
SECURITY.md
Normal file
12
SECURITY.md
Normal file
@ -0,0 +1,12 @@
|
||||
# Security Policy
|
||||
|
||||
## Supported Versions
|
||||
|
||||
| Firmware Version | Supported |
|
||||
| ---------------- | ------------------ |
|
||||
| 2.5.x | :white_check_mark: |
|
||||
| <= 2.4.x | :x: |
|
||||
|
||||
## Reporting a Vulnerability
|
||||
|
||||
We support the private reporting of potential security vulnerabilities. Please go to the Security tab to file a report with a description of the potential vulnerability and reproduction scripts (preferred) or steps, and our developers will review.
|
@ -147,6 +147,8 @@ using namespace meshtastic;
|
||||
*/
|
||||
static HasBatteryLevel *batteryLevel; // Default to NULL for no battery level sensor
|
||||
|
||||
#ifdef BATTERY_PIN
|
||||
|
||||
static void adcEnable()
|
||||
{
|
||||
#ifdef ADC_CTRL // enable adc voltage divider when we need to read
|
||||
@ -171,6 +173,8 @@ static void adcDisable()
|
||||
#endif
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
/**
|
||||
* A simple battery level sensor that assumes the battery voltage is attached via a voltage-divider to an analog input
|
||||
*/
|
||||
|
@ -7,6 +7,7 @@
|
||||
#include "PowerMon.h"
|
||||
#include "RTC.h"
|
||||
#include "Throttle.h"
|
||||
#include "meshUtils.h"
|
||||
|
||||
#include "main.h" // pmu_found
|
||||
#include "sleep.h"
|
||||
@ -511,7 +512,7 @@ bool GPS::setup()
|
||||
delay(250);
|
||||
_serial_gps->write("$CFGMSG,6,1,0\r\n");
|
||||
delay(250);
|
||||
} else if (gnssModel == GNSS_MODEL_AG3335 || gnssModel == GNSS_MODEL_AG3352) {
|
||||
} else if (IS_ONE_OF(gnssModel, GNSS_MODEL_AG3335, GNSS_MODEL_AG3352)) {
|
||||
|
||||
_serial_gps->write("$PAIR066,1,0,1,0,0,1*3B\r\n"); // Enable GPS+GALILEO+NAVIC
|
||||
|
||||
@ -553,7 +554,7 @@ bool GPS::setup()
|
||||
} else {
|
||||
LOG_INFO("GNSS module configuration saved!\n");
|
||||
}
|
||||
} else if (gnssModel == GNSS_MODEL_UBLOX7 || gnssModel == GNSS_MODEL_UBLOX8 || gnssModel == GNSS_MODEL_UBLOX9) {
|
||||
} else if (IS_ONE_OF(gnssModel, GNSS_MODEL_UBLOX7, GNSS_MODEL_UBLOX8, GNSS_MODEL_UBLOX9)) {
|
||||
if (gnssModel == GNSS_MODEL_UBLOX7) {
|
||||
LOG_DEBUG("Setting GPS+SBAS\n");
|
||||
msglen = makeUBXPacket(0x06, 0x3e, sizeof(_message_GNSS_7), _message_GNSS_7);
|
||||
@ -826,8 +827,7 @@ void GPS::setPowerPMU(bool on)
|
||||
void GPS::setPowerUBLOX(bool on, uint32_t sleepMs)
|
||||
{
|
||||
// Abort: if not UBLOX hardware
|
||||
if (!(gnssModel == GNSS_MODEL_UBLOX6 || gnssModel == GNSS_MODEL_UBLOX7 || gnssModel == GNSS_MODEL_UBLOX8 ||
|
||||
gnssModel == GNSS_MODEL_UBLOX9 || gnssModel == GNSS_MODEL_UBLOX10))
|
||||
if (!IS_ONE_OF(gnssModel, GNSS_MODEL_UBLOX6, GNSS_MODEL_UBLOX7, GNSS_MODEL_UBLOX8, GNSS_MODEL_UBLOX9, GNSS_MODEL_UBLOX10))
|
||||
return;
|
||||
|
||||
// If waking
|
||||
@ -910,8 +910,7 @@ void GPS::down()
|
||||
// If not, fallback to GPS_HARDSLEEP instead
|
||||
bool softsleepSupported = false;
|
||||
// U-blox is supported via PMREQ
|
||||
if (gnssModel == GNSS_MODEL_UBLOX6 || gnssModel == GNSS_MODEL_UBLOX7 || gnssModel == GNSS_MODEL_UBLOX8 ||
|
||||
gnssModel == GNSS_MODEL_UBLOX9 || gnssModel == GNSS_MODEL_UBLOX10)
|
||||
if (IS_ONE_OF(gnssModel, GNSS_MODEL_UBLOX6, GNSS_MODEL_UBLOX7, GNSS_MODEL_UBLOX8, GNSS_MODEL_UBLOX9, GNSS_MODEL_UBLOX10))
|
||||
softsleepSupported = true;
|
||||
#ifdef PIN_GPS_STANDBY // L76B, L76K and clones have a standby pin
|
||||
softsleepSupported = true;
|
||||
@ -987,8 +986,8 @@ int32_t GPS::runOnce()
|
||||
setConnected();
|
||||
} else {
|
||||
if ((config.position.gps_mode == meshtastic_Config_PositionConfig_GpsMode_ENABLED) &&
|
||||
(gnssModel == GNSS_MODEL_UBLOX6 || gnssModel == GNSS_MODEL_UBLOX7 || gnssModel == GNSS_MODEL_UBLOX8 ||
|
||||
gnssModel == GNSS_MODEL_UBLOX9 || gnssModel == GNSS_MODEL_UBLOX10)) {
|
||||
IS_ONE_OF(gnssModel, GNSS_MODEL_UBLOX6, GNSS_MODEL_UBLOX7, GNSS_MODEL_UBLOX8, GNSS_MODEL_UBLOX9,
|
||||
GNSS_MODEL_UBLOX10)) {
|
||||
// reset the GPS on next bootup
|
||||
if (devicestate.did_gps_reset && scheduling.elapsedSearchMs() > 60 * 1000UL && !hasFlow()) {
|
||||
LOG_DEBUG("GPS is not communicating, trying factory reset on next bootup.\n");
|
||||
|
@ -32,6 +32,7 @@
|
||||
#include "graphics/Screen.h"
|
||||
#include "main.h"
|
||||
#include "mesh/generated/meshtastic/config.pb.h"
|
||||
#include "meshUtils.h"
|
||||
#include "modules/Modules.h"
|
||||
#include "shutdown.h"
|
||||
#include "sleep.h"
|
||||
@ -628,9 +629,9 @@ void setup()
|
||||
#endif
|
||||
|
||||
// only play start melody when role is not tracker or sensor
|
||||
if (config.power.is_power_saving == true && (config.device.role == meshtastic_Config_DeviceConfig_Role_TRACKER ||
|
||||
config.device.role == meshtastic_Config_DeviceConfig_Role_TAK_TRACKER ||
|
||||
config.device.role == meshtastic_Config_DeviceConfig_Role_SENSOR))
|
||||
if (config.power.is_power_saving == true &&
|
||||
IS_ONE_OF(config.device.role, meshtastic_Config_DeviceConfig_Role_TRACKER,
|
||||
meshtastic_Config_DeviceConfig_Role_TAK_TRACKER, meshtastic_Config_DeviceConfig_Role_SENSOR))
|
||||
LOG_DEBUG("Tracker/Sensor: Skipping start melody\n");
|
||||
else
|
||||
playStartMelody();
|
||||
|
@ -296,29 +296,8 @@ template <typename T> bool LR11x0Interface<T>::isActivelyReceiving()
|
||||
{
|
||||
// The IRQ status will be cleared when we start our read operation. Check if we've started a header, but haven't yet
|
||||
// received and handled the interrupt for reading the packet/handling errors.
|
||||
|
||||
uint16_t irq = lora.getIrqStatus();
|
||||
bool detected = (irq & (RADIOLIB_LR11X0_IRQ_SYNC_WORD_HEADER_VALID | RADIOLIB_LR11X0_IRQ_PREAMBLE_DETECTED));
|
||||
// Handle false detections
|
||||
if (detected) {
|
||||
if (!activeReceiveStart) {
|
||||
activeReceiveStart = millis();
|
||||
} else if (!Throttle::isWithinTimespanMs(activeReceiveStart, 2 * preambleTimeMsec) &&
|
||||
!(irq & RADIOLIB_LR11X0_IRQ_SYNC_WORD_HEADER_VALID)) {
|
||||
// The HEADER_VALID flag should be set by now if it was really a packet, so ignore PREAMBLE_DETECTED flag
|
||||
activeReceiveStart = 0;
|
||||
LOG_DEBUG("Ignore false preamble detection.\n");
|
||||
return false;
|
||||
} else if (!Throttle::isWithinTimespanMs(activeReceiveStart, maxPacketTimeMsec)) {
|
||||
// We should have gotten an RX_DONE IRQ by now if it was really a packet, so ignore HEADER_VALID flag
|
||||
activeReceiveStart = 0;
|
||||
LOG_DEBUG("Ignore false header detection.\n");
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
// if (detected) LOG_DEBUG("rx detected\n");
|
||||
return detected;
|
||||
return receiveDetected(lora.getIrqStatus(), RADIOLIB_LR11X0_IRQ_SYNC_WORD_HEADER_VALID,
|
||||
RADIOLIB_LR11X0_IRQ_PREAMBLE_DETECTED);
|
||||
}
|
||||
|
||||
template <typename T> bool LR11x0Interface<T>::sleep()
|
||||
|
@ -65,7 +65,4 @@ template <class T> class LR11x0Interface : public RadioLibInterface
|
||||
virtual void addReceiveMetadata(meshtastic_MeshPacket *mp) override;
|
||||
|
||||
virtual void setStandby() override;
|
||||
|
||||
private:
|
||||
uint32_t activeReceiveStart = 0;
|
||||
};
|
||||
|
@ -2,6 +2,7 @@
|
||||
|
||||
#include "Observer.h"
|
||||
#include <Arduino.h>
|
||||
#include <algorithm>
|
||||
#include <assert.h>
|
||||
#include <vector>
|
||||
|
||||
|
@ -129,6 +129,28 @@ bool RadioLibInterface::canSendImmediately()
|
||||
return true;
|
||||
}
|
||||
|
||||
bool RadioLibInterface::receiveDetected(uint16_t irq, ulong syncWordHeaderValidFlag, ulong preambleDetectedFlag)
|
||||
{
|
||||
bool detected = (irq & (syncWordHeaderValidFlag | preambleDetectedFlag));
|
||||
// Handle false detections
|
||||
if (detected) {
|
||||
if (!activeReceiveStart) {
|
||||
activeReceiveStart = millis();
|
||||
} else if (!Throttle::isWithinTimespanMs(activeReceiveStart, 2 * preambleTimeMsec) && !(irq & syncWordHeaderValidFlag)) {
|
||||
// The HEADER_VALID flag should be set by now if it was really a packet, so ignore PREAMBLE_DETECTED flag
|
||||
activeReceiveStart = 0;
|
||||
LOG_DEBUG("Ignore false preamble detection.\n");
|
||||
return false;
|
||||
} else if (!Throttle::isWithinTimespanMs(activeReceiveStart, maxPacketTimeMsec)) {
|
||||
// We should have gotten an RX_DONE IRQ by now if it was really a packet, so ignore HEADER_VALID flag
|
||||
activeReceiveStart = 0;
|
||||
LOG_DEBUG("Ignore false header detection.\n");
|
||||
return false;
|
||||
}
|
||||
}
|
||||
return detected;
|
||||
}
|
||||
|
||||
/// Send a packet (possibly by enquing in a private fifo). This routine will
|
||||
/// later free() the packet to pool. This routine is not allowed to stall because it is called from
|
||||
/// bluetooth comms code. If the txmit queue is empty it might return an error
|
||||
|
@ -167,6 +167,10 @@ class RadioLibInterface : public RadioInterface, protected concurrency::Notified
|
||||
meshtastic_QueueStatus getQueueStatus();
|
||||
|
||||
protected:
|
||||
uint32_t activeReceiveStart = 0;
|
||||
|
||||
bool receiveDetected(uint16_t irq, ulong syncWordHeaderValidFlag, ulong preambleDetectedFlag);
|
||||
|
||||
/** Do any hardware setup needed on entry into send configuration for the radio.
|
||||
* Subclasses can customize, but must also call this base method */
|
||||
virtual void configHardwareForSend();
|
||||
|
@ -316,29 +316,7 @@ template <typename T> bool SX126xInterface<T>::isActivelyReceiving()
|
||||
{
|
||||
// The IRQ status will be cleared when we start our read operation. Check if we've started a header, but haven't yet
|
||||
// received and handled the interrupt for reading the packet/handling errors.
|
||||
|
||||
uint16_t irq = lora.getIrqFlags();
|
||||
bool detected = (irq & (RADIOLIB_SX126X_IRQ_HEADER_VALID | RADIOLIB_SX126X_IRQ_PREAMBLE_DETECTED));
|
||||
// Handle false detections
|
||||
if (detected) {
|
||||
if (!activeReceiveStart) {
|
||||
activeReceiveStart = millis();
|
||||
} else if (!Throttle::isWithinTimespanMs(activeReceiveStart, 2 * preambleTimeMsec) &&
|
||||
!(irq & RADIOLIB_SX126X_IRQ_HEADER_VALID)) {
|
||||
// The HEADER_VALID flag should be set by now if it was really a packet, so ignore PREAMBLE_DETECTED flag
|
||||
activeReceiveStart = 0;
|
||||
LOG_DEBUG("Ignore false preamble detection.\n");
|
||||
return false;
|
||||
} else if (!Throttle::isWithinTimespanMs(activeReceiveStart, maxPacketTimeMsec)) {
|
||||
// We should have gotten an RX_DONE IRQ by now if it was really a packet, so ignore HEADER_VALID flag
|
||||
activeReceiveStart = 0;
|
||||
LOG_DEBUG("Ignore false header detection.\n");
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
// if (detected) LOG_DEBUG("rx detected\n");
|
||||
return detected;
|
||||
return receiveDetected(lora.getIrqFlags(), RADIOLIB_SX126X_IRQ_HEADER_VALID, RADIOLIB_SX126X_IRQ_PREAMBLE_DETECTED);
|
||||
}
|
||||
|
||||
template <typename T> bool SX126xInterface<T>::sleep()
|
||||
|
@ -67,7 +67,4 @@ template <class T> class SX126xInterface : public RadioLibInterface
|
||||
virtual void addReceiveMetadata(meshtastic_MeshPacket *mp) override;
|
||||
|
||||
virtual void setStandby() override;
|
||||
|
||||
private:
|
||||
uint32_t activeReceiveStart = 0;
|
||||
};
|
||||
|
@ -290,28 +290,7 @@ template <typename T> bool SX128xInterface<T>::isChannelActive()
|
||||
/** Could we send right now (i.e. either not actively receiving or transmitting)? */
|
||||
template <typename T> bool SX128xInterface<T>::isActivelyReceiving()
|
||||
{
|
||||
uint16_t irq = lora.getIrqStatus();
|
||||
bool detected = (irq & (RADIOLIB_SX128X_IRQ_HEADER_VALID | RADIOLIB_SX128X_IRQ_PREAMBLE_DETECTED));
|
||||
|
||||
// Handle false detections
|
||||
if (detected) {
|
||||
if (!activeReceiveStart) {
|
||||
activeReceiveStart = millis();
|
||||
} else if (!Throttle::isWithinTimespanMs(activeReceiveStart, 2 * preambleTimeMsec) &&
|
||||
!(irq & RADIOLIB_SX128X_IRQ_HEADER_VALID)) {
|
||||
// The HEADER_VALID flag should be set by now if it was really a packet, so ignore PREAMBLE_DETECTED flag
|
||||
activeReceiveStart = 0;
|
||||
LOG_DEBUG("Ignore false preamble detection.\n");
|
||||
return false;
|
||||
} else if (Throttle::isWithinTimespanMs(activeReceiveStart, maxPacketTimeMsec)) {
|
||||
// We should have gotten an RX_DONE IRQ by now if it was really a packet, so ignore HEADER_VALID flag
|
||||
activeReceiveStart = 0;
|
||||
LOG_DEBUG("Ignore false header detection.\n");
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
return detected;
|
||||
return receiveDetected(lora.getIrqStatus(), RADIOLIB_SX128X_IRQ_HEADER_VALID, RADIOLIB_SX128X_IRQ_PREAMBLE_DETECTED);
|
||||
}
|
||||
|
||||
template <typename T> bool SX128xInterface<T>::sleep()
|
||||
|
@ -67,7 +67,4 @@ template <class T> class SX128xInterface : public RadioLibInterface
|
||||
virtual void addReceiveMetadata(meshtastic_MeshPacket *mp) override;
|
||||
|
||||
virtual void setStandby() override;
|
||||
|
||||
private:
|
||||
uint32_t activeReceiveStart = 0;
|
||||
};
|
||||
|
@ -80,4 +80,19 @@ bool memfll(const uint8_t *mem, uint8_t find, size_t numbytes)
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
bool isOneOf(int item, int count, ...)
|
||||
{
|
||||
va_list args;
|
||||
va_start(args, count);
|
||||
bool found = false;
|
||||
for (int i = 0; i < count; ++i) {
|
||||
if (item == va_arg(args, int)) {
|
||||
found = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
va_end(args);
|
||||
return found;
|
||||
}
|
@ -1,5 +1,8 @@
|
||||
#pragma once
|
||||
#include "DebugConfiguration.h"
|
||||
#include <algorithm>
|
||||
#include <cstdarg>
|
||||
#include <iterator>
|
||||
#include <stdint.h>
|
||||
|
||||
/// C++ v17+ clamp function, limits a given value to a range defined by lo and hi
|
||||
@ -17,4 +20,8 @@ char *strnstr(const char *s, const char *find, size_t slen);
|
||||
void printBytes(const char *label, const uint8_t *p, size_t numbytes);
|
||||
|
||||
// is the memory region filled with a single character?
|
||||
bool memfll(const uint8_t *mem, uint8_t find, size_t numbytes);
|
||||
bool memfll(const uint8_t *mem, uint8_t find, size_t numbytes);
|
||||
|
||||
bool isOneOf(int item, int count, ...);
|
||||
|
||||
#define IS_ONE_OF(item, ...) isOneOf(item, sizeof((int[]){__VA_ARGS__}) / sizeof(int), __VA_ARGS__)
|
||||
|
@ -11,6 +11,41 @@ DetectionSensorModule *detectionSensorModule;
|
||||
#define GPIO_POLLING_INTERVAL 100
|
||||
#define DELAYED_INTERVAL 1000
|
||||
|
||||
typedef enum {
|
||||
DetectionSensorVerdictDetected,
|
||||
DetectionSensorVerdictSendState,
|
||||
DetectionSensorVerdictNoop,
|
||||
} DetectionSensorTriggerVerdict;
|
||||
|
||||
typedef DetectionSensorTriggerVerdict (*DetectionSensorTriggerHandler)(bool prev, bool current);
|
||||
|
||||
static DetectionSensorTriggerVerdict detection_trigger_logic_level(bool prev, bool current)
|
||||
{
|
||||
return current ? DetectionSensorVerdictDetected : DetectionSensorVerdictNoop;
|
||||
}
|
||||
|
||||
static DetectionSensorTriggerVerdict detection_trigger_single_edge(bool prev, bool current)
|
||||
{
|
||||
return (!prev && current) ? DetectionSensorVerdictDetected : DetectionSensorVerdictNoop;
|
||||
}
|
||||
|
||||
static DetectionSensorTriggerVerdict detection_trigger_either_edge(bool prev, bool current)
|
||||
{
|
||||
if (prev == current) {
|
||||
return DetectionSensorVerdictNoop;
|
||||
}
|
||||
return current ? DetectionSensorVerdictDetected : DetectionSensorVerdictSendState;
|
||||
}
|
||||
|
||||
const static DetectionSensorTriggerHandler handlers[_meshtastic_ModuleConfig_DetectionSensorConfig_TriggerType_MAX + 1] = {
|
||||
[meshtastic_ModuleConfig_DetectionSensorConfig_TriggerType_LOGIC_LOW] = detection_trigger_logic_level,
|
||||
[meshtastic_ModuleConfig_DetectionSensorConfig_TriggerType_LOGIC_HIGH] = detection_trigger_logic_level,
|
||||
[meshtastic_ModuleConfig_DetectionSensorConfig_TriggerType_FALLING_EDGE] = detection_trigger_single_edge,
|
||||
[meshtastic_ModuleConfig_DetectionSensorConfig_TriggerType_RISING_EDGE] = detection_trigger_single_edge,
|
||||
[meshtastic_ModuleConfig_DetectionSensorConfig_TriggerType_EITHER_EDGE_ACTIVE_LOW] = detection_trigger_either_edge,
|
||||
[meshtastic_ModuleConfig_DetectionSensorConfig_TriggerType_EITHER_EDGE_ACTIVE_HIGH] = detection_trigger_either_edge,
|
||||
};
|
||||
|
||||
int32_t DetectionSensorModule::runOnce()
|
||||
{
|
||||
/*
|
||||
@ -22,7 +57,8 @@ int32_t DetectionSensorModule::runOnce()
|
||||
// moduleConfig.detection_sensor.monitor_pin = 21; // WisBlock RAK12013 Radar IO6
|
||||
// moduleConfig.detection_sensor.minimum_broadcast_secs = 30;
|
||||
// moduleConfig.detection_sensor.state_broadcast_secs = 120;
|
||||
// moduleConfig.detection_sensor.detection_triggered_high = true;
|
||||
// moduleConfig.detection_sensor.detection_trigger_type =
|
||||
// meshtastic_ModuleConfig_DetectionSensorConfig_TriggerType_LOGIC_HIGH;
|
||||
// strcpy(moduleConfig.detection_sensor.name, "Motion");
|
||||
|
||||
if (moduleConfig.detection_sensor.enabled == false)
|
||||
@ -51,19 +87,30 @@ int32_t DetectionSensorModule::runOnce()
|
||||
// LOG_DEBUG("Detection Sensor Module: Current pin state: %i\n", digitalRead(moduleConfig.detection_sensor.monitor_pin));
|
||||
|
||||
if (!Throttle::isWithinTimespanMs(lastSentToMesh,
|
||||
Default::getConfiguredOrDefaultMs(moduleConfig.detection_sensor.minimum_broadcast_secs)) &&
|
||||
hasDetectionEvent()) {
|
||||
sendDetectionMessage();
|
||||
return DELAYED_INTERVAL;
|
||||
Default::getConfiguredOrDefaultMs(moduleConfig.detection_sensor.minimum_broadcast_secs))) {
|
||||
bool isDetected = hasDetectionEvent();
|
||||
DetectionSensorTriggerVerdict verdict =
|
||||
handlers[moduleConfig.detection_sensor.detection_trigger_type](wasDetected, isDetected);
|
||||
wasDetected = isDetected;
|
||||
switch (verdict) {
|
||||
case DetectionSensorVerdictDetected:
|
||||
sendDetectionMessage();
|
||||
return DELAYED_INTERVAL;
|
||||
case DetectionSensorVerdictSendState:
|
||||
sendCurrentStateMessage(isDetected);
|
||||
return DELAYED_INTERVAL;
|
||||
case DetectionSensorVerdictNoop:
|
||||
break;
|
||||
}
|
||||
}
|
||||
// Even if we haven't detected an event, broadcast our current state to the mesh on the scheduled interval as a sort
|
||||
// of heartbeat. We only do this if the minimum broadcast interval is greater than zero, otherwise we'll only broadcast state
|
||||
// change detections.
|
||||
else if (moduleConfig.detection_sensor.state_broadcast_secs > 0 &&
|
||||
!Throttle::isWithinTimespanMs(lastSentToMesh,
|
||||
Default::getConfiguredOrDefaultMs(moduleConfig.detection_sensor.state_broadcast_secs,
|
||||
default_telemetry_broadcast_interval_secs))) {
|
||||
sendCurrentStateMessage();
|
||||
if (moduleConfig.detection_sensor.state_broadcast_secs > 0 &&
|
||||
!Throttle::isWithinTimespanMs(lastSentToMesh,
|
||||
Default::getConfiguredOrDefaultMs(moduleConfig.detection_sensor.state_broadcast_secs,
|
||||
default_telemetry_broadcast_interval_secs))) {
|
||||
sendCurrentStateMessage(hasDetectionEvent());
|
||||
return DELAYED_INTERVAL;
|
||||
}
|
||||
return GPIO_POLLING_INTERVAL;
|
||||
@ -89,10 +136,10 @@ void DetectionSensorModule::sendDetectionMessage()
|
||||
delete[] message;
|
||||
}
|
||||
|
||||
void DetectionSensorModule::sendCurrentStateMessage()
|
||||
void DetectionSensorModule::sendCurrentStateMessage(bool state)
|
||||
{
|
||||
char *message = new char[40];
|
||||
sprintf(message, "%s state: %i", moduleConfig.detection_sensor.name, hasDetectionEvent());
|
||||
sprintf(message, "%s state: %i", moduleConfig.detection_sensor.name, state);
|
||||
|
||||
meshtastic_MeshPacket *p = allocDataPacket();
|
||||
p->want_ack = false;
|
||||
@ -108,5 +155,5 @@ bool DetectionSensorModule::hasDetectionEvent()
|
||||
{
|
||||
bool currentState = digitalRead(moduleConfig.detection_sensor.monitor_pin);
|
||||
// LOG_DEBUG("Detection Sensor Module: Current state: %i\n", currentState);
|
||||
return moduleConfig.detection_sensor.detection_trigger_type ? currentState : !currentState;
|
||||
return (moduleConfig.detection_sensor.detection_trigger_type & 1) ? currentState : !currentState;
|
||||
}
|
@ -15,8 +15,9 @@ class DetectionSensorModule : public SinglePortModule, private concurrency::OSTh
|
||||
private:
|
||||
bool firstTime = true;
|
||||
uint32_t lastSentToMesh = 0;
|
||||
bool wasDetected = false;
|
||||
void sendDetectionMessage();
|
||||
void sendCurrentStateMessage();
|
||||
void sendCurrentStateMessage(bool state);
|
||||
bool hasDetectionEvent();
|
||||
};
|
||||
|
||||
|
@ -12,6 +12,7 @@
|
||||
#include "gps/GeoCoord.h"
|
||||
#include "main.h"
|
||||
#include "mesh/compression/unishox2.h"
|
||||
#include "meshUtils.h"
|
||||
#include "meshtastic/atak.pb.h"
|
||||
#include "sleep.h"
|
||||
#include "target_specific.h"
|
||||
@ -347,8 +348,8 @@ void PositionModule::sendOurPosition(NodeNum dest, bool wantReplies, uint8_t cha
|
||||
|
||||
service->sendToMesh(p, RX_SRC_LOCAL, true);
|
||||
|
||||
if ((config.device.role == meshtastic_Config_DeviceConfig_Role_TRACKER ||
|
||||
config.device.role == meshtastic_Config_DeviceConfig_Role_TAK_TRACKER) &&
|
||||
if (IS_ONE_OF(config.device.role, meshtastic_Config_DeviceConfig_Role_TRACKER,
|
||||
meshtastic_Config_DeviceConfig_Role_TAK_TRACKER) &&
|
||||
config.power.is_power_saving) {
|
||||
LOG_DEBUG("Starting next execution in 5 seconds and then going to sleep.\n");
|
||||
sleepOnNextExecution = true;
|
||||
|
@ -11,14 +11,15 @@
|
||||
#include "main.h"
|
||||
#include <OLEDDisplay.h>
|
||||
#include <OLEDDisplayUi.h>
|
||||
#include <meshUtils.h>
|
||||
|
||||
#define MAGIC_USB_BATTERY_LEVEL 101
|
||||
|
||||
int32_t DeviceTelemetryModule::runOnce()
|
||||
{
|
||||
refreshUptime();
|
||||
bool isImpoliteRole = config.device.role == meshtastic_Config_DeviceConfig_Role_SENSOR ||
|
||||
config.device.role == meshtastic_Config_DeviceConfig_Role_ROUTER;
|
||||
bool isImpoliteRole =
|
||||
IS_ONE_OF(config.device.role, meshtastic_Config_DeviceConfig_Role_SENSOR, meshtastic_Config_DeviceConfig_Role_ROUTER);
|
||||
if (((lastSentToMesh == 0) ||
|
||||
((uptimeLastMs - lastSentToMesh) >=
|
||||
Default::getConfiguredOrDefaultMsScaled(moduleConfig.telemetry.device_update_interval,
|
||||
|
@ -158,7 +158,6 @@ int32_t EnvironmentTelemetryModule::runOnce()
|
||||
result = bme680Sensor.runTrigger();
|
||||
}
|
||||
|
||||
uint32_t now = millis();
|
||||
if (((lastSentToMesh == 0) ||
|
||||
!Throttle::isWithinTimespanMs(lastSentToMesh, Default::getConfiguredOrDefaultMsScaled(
|
||||
moduleConfig.telemetry.environment_update_interval,
|
||||
|
@ -32,6 +32,9 @@ static MemoryDynamic<meshtastic_ServiceEnvelope> staticMqttPool;
|
||||
|
||||
Allocator<meshtastic_ServiceEnvelope> &mqttPool = staticMqttPool;
|
||||
|
||||
// FIXME - this size calculation is super sloppy, but it will go away once we dynamically alloc meshpackets
|
||||
static uint8_t bytes[meshtastic_MqttClientProxyMessage_size + 30]; // 12 for channel name and 16 for nodeid
|
||||
|
||||
void MQTT::mqttCallback(char *topic, byte *payload, unsigned int length)
|
||||
{
|
||||
mqtt->onReceive(topic, payload, length);
|
||||
@ -482,9 +485,7 @@ void MQTT::publishQueuedMessages()
|
||||
{
|
||||
if (!mqttQueue.isEmpty()) {
|
||||
LOG_DEBUG("Publishing enqueued MQTT message\n");
|
||||
// FIXME - this size calculation is super sloppy, but it will go away once we dynamically alloc meshpackets
|
||||
meshtastic_ServiceEnvelope *env = mqttQueue.dequeuePtr(0);
|
||||
static uint8_t bytes[meshtastic_MqttClientProxyMessage_size];
|
||||
size_t numBytes = pb_encode_to_bytes(bytes, sizeof(bytes), &meshtastic_ServiceEnvelope_msg, env);
|
||||
std::string topic;
|
||||
if (env->packet->pki_encrypted) {
|
||||
@ -570,8 +571,6 @@ void MQTT::onSend(const meshtastic_MeshPacket &mp, const meshtastic_MeshPacket &
|
||||
}
|
||||
|
||||
if (moduleConfig.mqtt.proxy_to_client_enabled || this->isConnectedDirectly()) {
|
||||
// FIXME - this size calculation is super sloppy, but it will go away once we dynamically alloc meshpackets
|
||||
static uint8_t bytes[meshtastic_MqttClientProxyMessage_size];
|
||||
size_t numBytes = pb_encode_to_bytes(bytes, sizeof(bytes), &meshtastic_ServiceEnvelope_msg, env);
|
||||
std::string topic = cryptTopic + channelId + "/" + owner.id;
|
||||
LOG_DEBUG("MQTT Publish %s, %u bytes\n", topic.c_str(), numBytes);
|
||||
@ -666,8 +665,6 @@ void MQTT::perhapsReportToMap()
|
||||
&meshtastic_MapReport_msg, &mapReport);
|
||||
se->packet = mp;
|
||||
|
||||
// FIXME - this size calculation is super sloppy, but it will go away once we dynamically alloc meshpackets
|
||||
static uint8_t bytes[meshtastic_MqttClientProxyMessage_size];
|
||||
size_t numBytes = pb_encode_to_bytes(bytes, sizeof(bytes), &meshtastic_ServiceEnvelope_msg, se);
|
||||
|
||||
LOG_INFO("MQTT Publish map report to %s\n", mapTopic.c_str());
|
||||
|
@ -12,6 +12,7 @@
|
||||
#include "PowerMon.h"
|
||||
#include "error.h"
|
||||
#include "main.h"
|
||||
#include "meshUtils.h"
|
||||
|
||||
#ifdef BQ25703A_ADDR
|
||||
#include "BQ25713.h"
|
||||
@ -157,6 +158,7 @@ void nrf52Loop()
|
||||
|
||||
#ifdef USE_SEMIHOSTING
|
||||
#include <SemihostingStream.h>
|
||||
#include <meshUtils.h>
|
||||
|
||||
/**
|
||||
* Note: this variable is in BSS and therfore false by default. But the gdbinit
|
||||
@ -261,10 +263,9 @@ void cpuDeepSleep(uint32_t msecToWake)
|
||||
// Sleepy trackers or sensors can low power "sleep"
|
||||
// Don't enter this if we're sleeping portMAX_DELAY, since that's a shutdown event
|
||||
if (msecToWake != portMAX_DELAY &&
|
||||
(config.device.role == meshtastic_Config_DeviceConfig_Role_TRACKER ||
|
||||
config.device.role == meshtastic_Config_DeviceConfig_Role_TAK_TRACKER ||
|
||||
config.device.role == meshtastic_Config_DeviceConfig_Role_SENSOR) &&
|
||||
config.power.is_power_saving == true) {
|
||||
(IS_ONE_OF(config.device.role, meshtastic_Config_DeviceConfig_Role_TRACKER,
|
||||
meshtastic_Config_DeviceConfig_Role_TAK_TRACKER, meshtastic_Config_DeviceConfig_Role_SENSOR) &&
|
||||
config.power.is_power_saving == true)) {
|
||||
sd_power_mode_set(NRF_POWER_MODE_LOWPWR);
|
||||
delay(msecToWake);
|
||||
NVIC_SystemReset();
|
||||
|
Loading…
Reference in New Issue
Block a user