Merge branch 'feature-bloomrouter' of https://github.com/medentem/firmware into feature-bloomrouter

This commit is contained in:
medentem 2025-01-02 10:57:23 -06:00
commit 6d04cd6210
26 changed files with 336 additions and 192 deletions

14
.github/actions/setup-native/action.yml vendored Normal file
View File

@ -0,0 +1,14 @@
name: Setup native build
description: Install libraries needed for building the Native/Portduino build
runs:
using: composite
steps:
- name: Setup base
id: base
uses: ./.github/actions/setup-base
- name: Install libs needed for native build
shell: bash
run: |
sudo apt-get install -y libbluetooth-dev libgpiod-dev libyaml-cpp-dev openssl libssl-dev libulfius-dev liborcania-dev libusb-1.0-0-dev libi2c-dev

View File

@ -10,12 +10,6 @@ jobs:
build-native:
runs-on: ubuntu-latest
steps:
- name: Install libs needed for native build
shell: bash
run: |
sudo apt-get update --fix-missing
sudo apt-get install -y libbluetooth-dev libgpiod-dev libyaml-cpp-dev openssl libssl-dev libulfius-dev liborcania-dev libusb-1.0-0-dev libi2c-dev
- name: Checkout code
uses: actions/checkout@v4
with:
@ -23,17 +17,9 @@ jobs:
ref: ${{github.event.pull_request.head.ref}}
repository: ${{github.event.pull_request.head.repo.full_name}}
- name: Upgrade python tools
shell: bash
run: |
python -m pip install --upgrade pip
pip install -U platformio adafruit-nrfutil
pip install -U meshtastic --pre
- name: Upgrade platformio
shell: bash
run: |
pio upgrade
- name: Setup native build
id: base
uses: ./.github/actions/setup-native
- name: Build Native
run: bin/build-native.sh

View File

@ -137,6 +137,9 @@ jobs:
package-native:
uses: ./.github/workflows/package_amd64.yml
test-native:
uses: ./.github/workflows/test_native.yml
build-docker:
if: ${{ github.event_name == 'workflow_dispatch' }}
uses: ./.github/workflows/build_docker.yml

169
.github/workflows/test_native.yml vendored Normal file
View File

@ -0,0 +1,169 @@
name: Run Tests on Native platform
on:
workflow_call:
workflow_dispatch:
permissions: {}
env:
LCOV_CAPTURE_FLAGS: --quiet --capture --include "${PWD}/src/*" --exclude '*/src/mesh/generated/*' --directory .pio/build/coverage/src --base-directory "${PWD}"
jobs:
simulator-tests:
name: Native Simulator Tests
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
with:
ref: ${{github.event.pull_request.head.ref}}
repository: ${{github.event.pull_request.head.repo.full_name}}
submodules: recursive
- name: Setup native build
id: base
uses: ./.github/actions/setup-native
- name: Install simulator dependencies
run: pip install -U dotmap
# We now run integration test before other build steps (to quickly see runtime failures)
- name: Build for native/coverage
run: platformio run -e coverage
- name: Capture initial coverage information
shell: bash
run: |
sudo apt-get install -y lcov
lcov ${{ env.LCOV_CAPTURE_FLAGS }} --initial --output-file coverage_base.info
sed -i -e "s#${PWD}#.#" coverage_base.info # Make paths relative.
- name: Integration test
run: |
.pio/build/coverage/program &
PID=$!
timeout 20 bash -c "until ls -al /proc/$PID/fd | grep socket; do sleep 1; done"
echo "Simulator started, launching python test..."
python3 -c 'from meshtastic.test import testSimulator; testSimulator()'
wait
- name: Capture coverage information
if: always() # run this step even if previous step failed
run: |
lcov ${{ env.LCOV_CAPTURE_FLAGS }} --test-name integration --output-file coverage_integration.info
sed -i -e "s#${PWD}#.#" coverage_integration.info # Make paths relative.
- name: Get release version string
if: always() # run this step even if previous step failed
run: echo "version=$(./bin/buildinfo.py long)" >> $GITHUB_OUTPUT
id: version
- name: Save coverage information
uses: actions/upload-artifact@v4
if: always() # run this step even if previous step failed
with:
name: lcov-coverage-info-native-simulator-test-${{ steps.version.outputs.version }}.zip
overwrite: true
path: ./coverage_*.info
platformio-tests:
name: Native PlatformIO Tests
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
with:
ref: ${{github.event.pull_request.head.ref}}
repository: ${{github.event.pull_request.head.repo.full_name}}
submodules: recursive
- name: Setup native build
id: base
uses: ./.github/actions/setup-native
- name: Get release version string
run: echo "version=$(./bin/buildinfo.py long)" >> $GITHUB_OUTPUT
id: version
# Disable (comment-out) BUILD_EPOCH. It causes a full rebuild between tests and resets the
# coverage information each time.
- name: Disable BUILD_EPOCH
run: sed -i 's/-DBUILD_EPOCH=$UNIX_TIME/#-DBUILD_EPOCH=$UNIX_TIME/' platformio.ini
- name: PlatformIO Tests
run: platformio test -e coverage --junit-output-path testreport.xml
- name: Save test results
if: always() # run this step even if previous step failed
uses: actions/upload-artifact@v4
with:
name: platformio-test-report-${{ steps.version.outputs.version }}.zip
overwrite: true
path: ./testreport.xml
- name: Capture coverage information
if: always() # run this step even if previous step failed
run: |
sudo apt-get install -y lcov
lcov ${{ env.LCOV_CAPTURE_FLAGS }} --test-name tests --output-file coverage_tests.info
sed -i -e "s#${PWD}#.#" coverage_tests.info # Make paths relative.
- name: Save coverage information
uses: actions/upload-artifact@v4
if: always() # run this step even if previous step failed
with:
name: lcov-coverage-info-native-platformio-tests-${{ steps.version.outputs.version }}.zip
overwrite: true
path: ./coverage_*.info
generate-reports:
name: Generate Test Reports
runs-on: ubuntu-latest
permissions: # Needed for dorny/test-reporter.
contents: read
actions: read
checks: write
needs:
- simulator-tests
- platformio-tests
if: always()
steps:
- uses: actions/checkout@v4
with:
ref: ${{github.event.pull_request.head.ref}}
repository: ${{github.event.pull_request.head.repo.full_name}}
- name: Get release version string
run: echo "version=$(./bin/buildinfo.py long)" >> $GITHUB_OUTPUT
id: version
- name: Download test artifacts
uses: actions/download-artifact@v4
with:
name: platformio-test-report-${{ steps.version.outputs.version }}.zip
merge-multiple: true
- name: Test Report
uses: dorny/test-reporter@v1.9.1
with:
name: PlatformIO Tests
path: testreport.xml
reporter: java-junit
- name: Download coverage artifacts
uses: actions/download-artifact@v4
with:
pattern: lcov-coverage-info-native-*-${{ steps.version.outputs.version }}.zip
path: code-coverage-report
merge-multiple: true
- name: Generate Code Coverage Report
run: |
sudo apt-get install -y lcov
lcov --quiet --add-tracefile code-coverage-report/coverage_base.info --add-tracefile code-coverage-report/coverage_integration.info --add-tracefile code-coverage-report/coverage_tests.info --output-file code-coverage-report/coverage_src.info
genhtml --quiet --legend --prefix "${PWD}" code-coverage-report/coverage_src.info --output-directory code-coverage-report
- name: Save Code Coverage Report
uses: actions/upload-artifact@v4
with:
name: code-coverage-report-${{ steps.version.outputs.version }}.zip
path: code-coverage-report

View File

@ -6,79 +6,8 @@ on:
workflow_dispatch: {}
jobs:
test-simulator:
runs-on: ubuntu-latest
env:
LCOV_CAPTURE_FLAGS: --quiet --capture --include "${PWD}/src/*" --exclude '*/src/mesh/generated/*' --directory .pio/build/coverage/src --base-directory "${PWD}"
steps:
- name: Install libs needed for native build
shell: bash
run: |
sudo apt-get update --fix-missing
sudo apt-get install -y libbluetooth-dev libgpiod-dev libyaml-cpp-dev openssl libssl-dev libulfius-dev liborcania-dev libusb-1.0-0-dev libi2c-dev
sudo apt-get install -y lcov
- name: Checkout code
uses: actions/checkout@v4
with:
submodules: recursive
- name: Upgrade python tools
shell: bash
run: |
python -m pip install --upgrade pip
pip install -U platformio adafruit-nrfutil dotmap
pip install -U meshtastic --pre
- name: Upgrade platformio
shell: bash
run: |
pio upgrade
- name: Build Native
run: bin/build-native.sh
# We now run integration test before other build steps (to quickly see runtime failures)
- name: Build for native/coverage
run: |
platformio run -e coverage
lcov ${{ env.LCOV_CAPTURE_FLAGS }} --initial --output-file coverage_base.info
- name: Integration test
run: |
.pio/build/coverage/program &
PID=$!
timeout 20 bash -c "until ls -al /proc/$PID/fd | grep socket; do sleep 1; done"
echo "Simulator started, launching python test..."
python3 -c 'from meshtastic.test import testSimulator; testSimulator()'
wait
lcov ${{ env.LCOV_CAPTURE_FLAGS }} --test-name integration --output-file coverage_integration.info
- name: PlatformIO Tests
run: |
platformio test -e coverage --junit-output-path testreport.xml
lcov ${{ env.LCOV_CAPTURE_FLAGS }} --test-name tests --output-file coverage_tests.info
- name: Test Report
uses: dorny/test-reporter@v1.9.1
if: success() || failure() # run this step even if previous step failed
with:
name: PlatformIO Tests
path: testreport.xml
reporter: java-junit
- name: Generate Code Coverage Report
run: |
lcov --quiet --add-tracefile coverage_base.info --add-tracefile coverage_integration.info --add-tracefile coverage_tests.info --output-file coverage_src.info
mkdir code-coverage-report
genhtml --quiet --legend --prefix "${PWD}" coverage_src.info --output-directory code-coverage-report
mv coverage_*.info code-coverage-report
- name: Save Code Coverage Report
uses: actions/upload-artifact@v4
with:
name: code-coverage-report
path: code-coverage-report
native-tests:
uses: ./.github/workflows/test_native.yml
hardware-tests:
runs-on: test-runner

View File

@ -178,13 +178,6 @@ along with this program. If not, see <http://www.gnu.org/licenses/>.
#define TCA9535_ADDR 0x20
#define TCA9555_ADDR 0x26
// -----------------------------------------------------------------------------
// GPS
// -----------------------------------------------------------------------------
#ifndef GPS_THREAD_INTERVAL
#define GPS_THREAD_INTERVAL 200
#endif
// -----------------------------------------------------------------------------
// Touchscreen
// -----------------------------------------------------------------------------
@ -206,6 +199,10 @@ along with this program. If not, see <http://www.gnu.org/licenses/>.
#define VEXT_ON_VALUE LOW
#endif
// -----------------------------------------------------------------------------
// GPS
// -----------------------------------------------------------------------------
#ifndef GPS_BAUDRATE
#define GPS_BAUDRATE 9600
#define GPS_BAUDRATE_FIXED 0
@ -213,6 +210,10 @@ along with this program. If not, see <http://www.gnu.org/licenses/>.
#define GPS_BAUDRATE_FIXED 1
#endif
#ifndef GPS_THREAD_INTERVAL
#define GPS_THREAD_INTERVAL 200
#endif
/* Step #2: follow with defines common to the architecture;
also enable HAS_ option not specifically disabled by variant.h */
#include "architecture.h"

View File

@ -1506,7 +1506,7 @@ Screen::Screen(ScanI2C::DeviceAddress address, meshtastic_Config_DisplayConfig_O
#elif defined(USE_ST7567)
dispdev = new ST7567Wire(address.address, -1, -1, geometry,
(address.port == ScanI2C::I2CPort::WIRE1) ? HW_I2C::I2C_TWO : HW_I2C::I2C_ONE);
#elif ARCH_PORTDUINO
#elif ARCH_PORTDUINO && !HAS_TFT
if (settingsMap[displayPanel] != no_screen) {
LOG_DEBUG("Make TFTDisplay!");
dispdev = new TFTDisplay(address.address, -1, -1, geometry,

View File

@ -4,6 +4,7 @@
#include "NodeDB.h"
#include "configuration.h"
#include "modules/RoutingModule.h"
#include <algorithm>
#include <assert.h>
std::vector<MeshModule *> *MeshModule::modules;
@ -29,7 +30,9 @@ void MeshModule::setup() {}
MeshModule::~MeshModule()
{
assert(0); // FIXME - remove from list of modules once someone needs this feature
auto it = std::find(modules->begin(), modules->end(), this);
assert(it != modules->end());
modules->erase(it);
}
meshtastic_MeshPacket *MeshModule::allocAckNak(meshtastic_Routing_Error err, NodeNum to, PacketId idFrom, ChannelIndex chIndex,

View File

@ -1068,8 +1068,11 @@ void NodeDB::loadFromDisk()
// Make sure we load hard coded admin keys even when the configuration file has none.
// Initialize admin_key_count to zero
byte numAdminKeys = 0;
#if defined(USERPREFS_USE_ADMIN_KEY_0) || defined(USERPREFS_USE_ADMIN_KEY_1) || defined(USERPREFS_USE_ADMIN_KEY_2)
uint16_t sum = 0;
#endif
#ifdef USERPREFS_USE_ADMIN_KEY_0
for (uint8_t b = 0; b < 32; b++) {
sum += config.security.admin_key[0].bytes[b];
}
@ -1078,8 +1081,6 @@ void NodeDB::loadFromDisk()
LOG_INFO("Admin 0 key zero. Loading hard coded key from user preferences.");
memcpy(config.security.admin_key[0].bytes, userprefs_admin_key_0, 32);
config.security.admin_key[0].size = 32;
config.security.admin_key_count = numAdminKeys;
saveToDisk(SEGMENT_CONFIG);
}
#endif
@ -1093,8 +1094,6 @@ void NodeDB::loadFromDisk()
LOG_INFO("Admin 1 key zero. Loading hard coded key from user preferences.");
memcpy(config.security.admin_key[1].bytes, userprefs_admin_key_1, 32);
config.security.admin_key[1].size = 32;
config.security.admin_key_count = numAdminKeys;
saveToDisk(SEGMENT_CONFIG);
}
#endif
@ -1108,10 +1107,14 @@ void NodeDB::loadFromDisk()
LOG_INFO("Admin 2 key zero. Loading hard coded key from user preferences.");
memcpy(config.security.admin_key[2].bytes, userprefs_admin_key_2, 32);
config.security.admin_key[2].size = 32;
}
#endif
if (numAdminKeys > 0) {
LOG_INFO("Saving %d hard coded admin keys.", numAdminKeys);
config.security.admin_key_count = numAdminKeys;
saveToDisk(SEGMENT_CONFIG);
}
#endif
state = loadProto(moduleConfigFileName, meshtastic_LocalModuleConfig_size, sizeof(meshtastic_LocalModuleConfig),
&meshtastic_LocalModuleConfig_msg, &moduleConfig);

View File

@ -982,6 +982,7 @@ bool CannedMessageModule::interceptingKeyboardInput()
}
}
#if !HAS_TFT
void CannedMessageModule::drawFrame(OLEDDisplay *display, OLEDDisplayUiState *state, int16_t x, int16_t y)
{
char buffer[50];
@ -1140,6 +1141,7 @@ void CannedMessageModule::drawFrame(OLEDDisplay *display, OLEDDisplayUiState *st
}
}
}
#endif //! HAS_TFT
ProcessMessage CannedMessageModule::handleReceived(const meshtastic_MeshPacket &mp)
{

View File

@ -41,13 +41,12 @@ void CGRadSensSensor::begin(TwoWire *wire, uint8_t addr)
float CGRadSensSensor::getStaticRadiation()
{
// Read a register, following the same pattern as the RCWL9620Sensor
uint32_t data;
_wire->beginTransmission(_addr); // Transfer data to addr.
_wire->write(0x06); // Radiation intensity (static period T = 500 sec)
if (_wire->endTransmission() == 0) {
if (_wire->requestFrom(_addr, (uint8_t)3)) {
; // Request 3 bytes
data = _wire->read();
uint32_t data = _wire->read();
data <<= 8;
data |= _wire->read();
data <<= 8;

View File

@ -35,8 +35,8 @@ enum sensor_pkt_type {
static int cmd_send(uint8_t cmd, const char *p_data, uint8_t len)
{
uint8_t buf[32] = {0};
uint8_t data[32] = {0};
uint8_t send_buf[32] = {0};
uint8_t send_data[32] = {0};
if (len > 31) {
return -1;
@ -44,18 +44,18 @@ static int cmd_send(uint8_t cmd, const char *p_data, uint8_t len)
uint8_t index = 1;
data[0] = cmd;
send_data[0] = cmd;
if (len > 0 && p_data != NULL) {
memcpy(&data[1], p_data, len);
memcpy(&send_data[1], p_data, len);
index += len;
}
cobs_encode_result ret = cobs_encode(buf, sizeof(buf), data, index);
cobs_encode_result ret = cobs_encode(send_buf, sizeof(send_buf), send_data, index);
// LOG_DEBUG("cobs TX status:%d, len:%d, type 0x%x", ret.status, ret.out_len, cmd);
if (ret.status == COBS_ENCODE_OK) {
return uart_write_bytes(SENSOR_PORT_NUM, buf, ret.out_len + 1);
return uart_write_bytes(SENSOR_PORT_NUM, send_buf, ret.out_len + 1);
}
return -1;
@ -96,7 +96,6 @@ bool IndicatorSensor::getMetrics(meshtastic_Telemetry *measurement)
int len = uart_read_bytes(SENSOR_PORT_NUM, buf, (SENSOR_BUF_SIZE - 1), 100 / portTICK_PERIOD_MS);
float value = 0.0;
uint8_t pkt_type = 0;
uint8_t *p_buf_start = buf;
uint8_t *p_buf_end = buf;
if (len > 0) {
@ -117,7 +116,7 @@ bool IndicatorSensor::getMetrics(meshtastic_Telemetry *measurement)
if (ret.out_len > 1 && ret.status == COBS_DECODE_OK) {
value = 0.0;
pkt_type = data[0];
uint8_t pkt_type = data[0];
switch (pkt_type) {
case PKT_TYPE_SENSOR_SCD41_CO2: {
memcpy(&value, &data[1], sizeof(value));

View File

@ -2,6 +2,7 @@
#include "MeshService.h"
#include "NodeDB.h"
#include "PowerFSM.h"
#include "ServiceEnvelope.h"
#include "configuration.h"
#include "main.h"
#include "mesh/Channels.h"
@ -25,7 +26,6 @@
#endif
#include <Throttle.h>
#include <assert.h>
#include <pb_decode.h>
#include <utility>
#include <IPAddress.h>
@ -47,23 +47,6 @@ static uint8_t bytes[meshtastic_MqttClientProxyMessage_size + 30]; // 12 for cha
static bool isMqttServerAddressPrivate = false;
// meshtastic_ServiceEnvelope that automatically releases dynamically allocated memory when it goes out of scope.
struct DecodedServiceEnvelope : public meshtastic_ServiceEnvelope {
DecodedServiceEnvelope() = delete;
DecodedServiceEnvelope(const uint8_t *payload, size_t length)
: meshtastic_ServiceEnvelope(meshtastic_ServiceEnvelope_init_default),
validDecode(pb_decode_from_bytes(payload, length, &meshtastic_ServiceEnvelope_msg, this))
{
}
~DecodedServiceEnvelope()
{
if (validDecode)
pb_release(&meshtastic_ServiceEnvelope_msg, this);
}
// Clients must check that this is true before using.
const bool validDecode;
};
inline void onReceiveProto(char *topic, byte *payload, size_t length)
{
const DecodedServiceEnvelope e(payload, length);
@ -299,7 +282,9 @@ void mqttInit()
}
#if HAS_NETWORKING
MQTT::MQTT() : concurrency::OSThread("mqtt"), pubSub(mqttClient), mqttQueue(MAX_MQTT_QUEUE)
MQTT::MQTT() : MQTT(std::unique_ptr<MQTTClient>(new MQTTClient())) {}
MQTT::MQTT(std::unique_ptr<MQTTClient> _mqttClient)
: concurrency::OSThread("mqtt"), mqttQueue(MAX_MQTT_QUEUE), mqttClient(std::move(_mqttClient)), pubSub(*mqttClient)
#else
MQTT::MQTT() : concurrency::OSThread("mqtt"), mqttQueue(MAX_MQTT_QUEUE)
#endif
@ -437,13 +422,13 @@ void MQTT::reconnect()
}
} else {
LOG_INFO("Use non-TLS-encrypted session");
pubSub.setClient(mqttClient);
pubSub.setClient(*mqttClient);
}
#else
pubSub.setClient(mqttClient);
pubSub.setClient(*mqttClient);
#endif
#elif HAS_NETWORKING
pubSub.setClient(mqttClient);
pubSub.setClient(*mqttClient);
#endif
std::pair<String, uint16_t> hostAndPort = parseHostAndPort(serverAddr, serverPort);
@ -461,7 +446,7 @@ void MQTT::reconnect()
enabled = true; // Start running background process again
runASAP = true;
reconnectCount = 0;
isMqttServerAddressPrivate = isPrivateIpAddress(mqttClient.remoteIP());
isMqttServerAddressPrivate = isPrivateIpAddress(mqttClient->remoteIP());
publishNodeInfo();
sendSubscriptions();

View File

@ -22,6 +22,7 @@
#if HAS_NETWORKING
#include <PubSubClient.h>
#include <memory>
#endif
#define MAX_MQTT_QUEUE 16
@ -32,24 +33,7 @@
*/
class MQTT : private concurrency::OSThread
{
// supposedly the current version is busted:
// http://www.iotsharing.com/2017/08/how-to-use-esp32-mqtts-with-mqtts-mosquitto-broker-tls-ssl.html
#if HAS_WIFI
WiFiClient mqttClient;
#if !defined(ARCH_PORTDUINO)
#if (defined(ESP_ARDUINO_VERSION_MAJOR) && ESP_ARDUINO_VERSION_MAJOR < 3) || defined(RPI_PICO)
WiFiClientSecure wifiSecureClient;
#endif
#endif
#endif
#if HAS_ETHERNET
EthernetClient mqttClient;
#endif
public:
#if HAS_NETWORKING
PubSubClient pubSub;
#endif
MQTT();
/**
@ -93,7 +77,29 @@ class MQTT : private concurrency::OSThread
virtual int32_t runOnce() override;
#ifndef PIO_UNIT_TESTING
private:
#endif
// supposedly the current version is busted:
// http://www.iotsharing.com/2017/08/how-to-use-esp32-mqtts-with-mqtts-mosquitto-broker-tls-ssl.html
#if HAS_WIFI
using MQTTClient = WiFiClient;
#if !defined(ARCH_PORTDUINO)
#if (defined(ESP_ARDUINO_VERSION_MAJOR) && ESP_ARDUINO_VERSION_MAJOR < 3) || defined(RPI_PICO)
WiFiClientSecure wifiSecureClient;
#endif
#endif
#endif
#if HAS_ETHERNET
using MQTTClient = EthernetClient;
#endif
#if HAS_NETWORKING
std::unique_ptr<MQTTClient> mqttClient;
PubSubClient pubSub;
explicit MQTT(std::unique_ptr<MQTTClient> mqttClient);
#endif
std::string cryptTopic = "/2/e/"; // msh/2/e/CHANNELID/NODEID
std::string jsonTopic = "/2/json/"; // msh/2/json/CHANNELID/NODEID
std::string mapTopic = "/2/map/"; // For protobuf-encoded MapReport messages

View File

@ -0,0 +1,23 @@
#include "ServiceEnvelope.h"
#include "mesh-pb-constants.h"
#include <pb_decode.h>
DecodedServiceEnvelope::DecodedServiceEnvelope(const uint8_t *payload, size_t length)
: meshtastic_ServiceEnvelope(meshtastic_ServiceEnvelope_init_default),
validDecode(pb_decode_from_bytes(payload, length, &meshtastic_ServiceEnvelope_msg, this))
{
}
DecodedServiceEnvelope::DecodedServiceEnvelope(DecodedServiceEnvelope &&other)
: meshtastic_ServiceEnvelope(meshtastic_ServiceEnvelope_init_zero), validDecode(other.validDecode)
{
std::swap(packet, other.packet);
std::swap(channel_id, other.channel_id);
std::swap(gateway_id, other.gateway_id);
}
DecodedServiceEnvelope::~DecodedServiceEnvelope()
{
if (validDecode)
pb_release(&meshtastic_ServiceEnvelope_msg, this);
}

View File

@ -0,0 +1,13 @@
#pragma once
#include "mesh/generated/meshtastic/mqtt.pb.h"
// meshtastic_ServiceEnvelope that automatically releases dynamically allocated memory when it goes out of scope.
struct DecodedServiceEnvelope : public meshtastic_ServiceEnvelope {
DecodedServiceEnvelope(const uint8_t *payload, size_t length);
DecodedServiceEnvelope(DecodedServiceEnvelope &) = delete;
DecodedServiceEnvelope(DecodedServiceEnvelope &&);
~DecodedServiceEnvelope();
// Clients must check that this is true before using.
const bool validDecode;
};

View File

@ -18,7 +18,6 @@
#include <fstream>
#include <iostream>
#include <map>
#include <sstream>
#include <sys/ioctl.h>
#include <unistd.h>
@ -232,9 +231,9 @@ void portduinoSetup()
dmac[3] = hash[3];
dmac[4] = hash[4];
dmac[5] = hash[5];
std::stringstream mactmp;
mactmp << std::hex << +dmac[0] << +dmac[1] << +dmac[2] << +dmac[3] << +dmac[4] << +dmac[5];
settingsStrings[mac_address] = mactmp.str();
char macBuf[13] = {0};
sprintf(macBuf, "%02X%02X%02X%02X%02X%02X", dmac[0], dmac[1], dmac[2], dmac[3], dmac[4], dmac[5]);
settingsStrings[mac_address] = macBuf;
}
}
@ -244,7 +243,7 @@ void portduinoSetup()
std::cout << "Please set a MAC Address in config.yaml using either MACAddress or MACAddressSource." << std::endl;
exit(EXIT_FAILURE);
}
std::cout << "MAC Address: " << std::hex << +dmac[0] << +dmac[1] << +dmac[2] << +dmac[3] << +dmac[4] << +dmac[5] << std::endl;
printf("MAC ADDRESS: %02X:%02X:%02X:%02X:%02X:%02X\n", dmac[0], dmac[1], dmac[2], dmac[3], dmac[4], dmac[5]);
// Rather important to set this, if not running simulated.
randomSeed(time(NULL));

View File

@ -26,7 +26,7 @@ class Ch341Hal : public RadioLibHal
{
public:
// default constructor - initializes the base HAL and any needed private members
Ch341Hal(uint8_t spiChannel, uint32_t spiSpeed = 2000000, uint8_t spiDevice = 0, uint8_t gpioDevice = 0)
explicit Ch341Hal(uint8_t spiChannel, uint32_t spiSpeed = 2000000, uint8_t spiDevice = 0, uint8_t gpioDevice = 0)
: RadioLibHal(PI_INPUT, PI_OUTPUT, PI_LOW, PI_HIGH, PI_RISING, PI_FALLING)
{
}

View File

@ -13,6 +13,8 @@
#include "mesh/generated/meshtastic/remote_hardware.pb.h"
#include <sys/types.h>
static const char *errStr = "Error decoding proto for %s message!";
std::string MeshPacketSerializer::JsonSerialize(const meshtastic_MeshPacket *mp, bool shouldLog)
{
// the created jsonObj is immutable after creation, so

View File

@ -2,7 +2,6 @@
#include <string>
static const char hexChars[16] = {'0', '1', '2', '3', '4', '5', '6', '7', '8', '9', 'A', 'B', 'C', 'D', 'E', 'F'};
static const char *errStr = "Error decoding proto for %s message!";
class MeshPacketSerializer
{

View File

@ -5,21 +5,22 @@
cobs_encode_result cobs_encode(uint8_t *dst_buf_ptr, size_t dst_buf_len, const uint8_t *src_ptr, size_t src_len)
{
cobs_encode_result result = {0, COBS_ENCODE_OK};
if (!dst_buf_ptr || !src_ptr) {
result.status = COBS_ENCODE_NULL_POINTER;
return result;
}
const uint8_t *src_read_ptr = src_ptr;
const uint8_t *src_end_ptr = src_read_ptr + src_len;
uint8_t *dst_buf_start_ptr = dst_buf_ptr;
uint8_t *dst_buf_end_ptr = dst_buf_start_ptr + dst_buf_len;
uint8_t *dst_code_write_ptr = dst_buf_ptr;
uint8_t *dst_write_ptr = dst_code_write_ptr + 1;
uint8_t src_byte = 0;
uint8_t search_len = 1;
if ((dst_buf_ptr == NULL) || (src_ptr == NULL)) {
result.status = COBS_ENCODE_NULL_POINTER;
return result;
}
if (src_len != 0) {
for (;;) {
if (dst_write_ptr >= dst_buf_end_ptr) {
@ -27,7 +28,7 @@ cobs_encode_result cobs_encode(uint8_t *dst_buf_ptr, size_t dst_buf_len, const u
break;
}
src_byte = *src_read_ptr++;
uint8_t src_byte = *src_read_ptr++;
if (src_byte == 0) {
*dst_code_write_ptr = search_len;
dst_code_write_ptr = dst_write_ptr++;
@ -65,31 +66,28 @@ cobs_encode_result cobs_encode(uint8_t *dst_buf_ptr, size_t dst_buf_len, const u
cobs_decode_result cobs_decode(uint8_t *dst_buf_ptr, size_t dst_buf_len, const uint8_t *src_ptr, size_t src_len)
{
cobs_decode_result result = {0, COBS_DECODE_OK};
const uint8_t *src_read_ptr = src_ptr;
const uint8_t *src_end_ptr = src_read_ptr + src_len;
uint8_t *dst_buf_start_ptr = dst_buf_ptr;
uint8_t *dst_buf_end_ptr = dst_buf_start_ptr + dst_buf_len;
uint8_t *dst_write_ptr = dst_buf_ptr;
size_t remaining_bytes;
uint8_t src_byte;
uint8_t i;
uint8_t len_code;
if ((dst_buf_ptr == NULL) || (src_ptr == NULL)) {
if (!dst_buf_ptr || !src_ptr) {
result.status = COBS_DECODE_NULL_POINTER;
return result;
}
const uint8_t *src_read_ptr = src_ptr;
const uint8_t *src_end_ptr = src_read_ptr + src_len;
uint8_t *dst_buf_start_ptr = dst_buf_ptr;
const uint8_t *dst_buf_end_ptr = dst_buf_start_ptr + dst_buf_len;
uint8_t *dst_write_ptr = dst_buf_ptr;
if (src_len != 0) {
for (;;) {
len_code = *src_read_ptr++;
uint8_t len_code = *src_read_ptr++;
if (len_code == 0) {
result.status = (cobs_decode_status)(result.status | (cobs_decode_status)COBS_DECODE_ZERO_BYTE_IN_INPUT);
break;
}
len_code--;
remaining_bytes = src_end_ptr - src_read_ptr;
size_t remaining_bytes = src_end_ptr - src_read_ptr;
if (len_code > remaining_bytes) {
result.status = (cobs_decode_status)(result.status | (cobs_decode_status)COBS_DECODE_INPUT_TOO_SHORT);
len_code = remaining_bytes;
@ -101,8 +99,8 @@ cobs_decode_result cobs_decode(uint8_t *dst_buf_ptr, size_t dst_buf_len, const u
len_code = remaining_bytes;
}
for (i = len_code; i != 0; i--) {
src_byte = *src_read_ptr++;
for (uint8_t i = len_code; i != 0; i--) {
uint8_t src_byte = *src_read_ptr++;
if (src_byte == 0) {
result.status = (cobs_decode_status)(result.status | (cobs_decode_status)COBS_DECODE_ZERO_BYTE_IN_INPUT);
}

View File

@ -58,7 +58,7 @@ RTC_DATA_ATTR int bootCount = 0;
*/
void setCPUFast(bool on)
{
#if defined(ARCH_ESP32) && HAS_WIFI
#if defined(ARCH_ESP32) && HAS_WIFI && !HAS_TFT
if (isWifiAvailable()) {
/*
@ -271,6 +271,12 @@ void doDeepSleep(uint32_t msecToWake, bool skipPreflight = false, bool skipSaveN
gpio_hold_en((gpio_num_t)BUTTON_PIN);
}
#endif
#ifdef SENSECAP_INDICATOR
// Portexpander definition does not pass GPIO_IS_VALID_OUTPUT_GPIO
pinMode(LORA_CS, OUTPUT);
digitalWrite(LORA_CS, HIGH);
gpio_hold_en((gpio_num_t)LORA_CS);
#else
if (GPIO_IS_VALID_OUTPUT_GPIO(LORA_CS)) {
// LoRa CS (RADIO_NSS) needs to stay HIGH, even during deep sleep
pinMode(LORA_CS, OUTPUT);
@ -278,6 +284,7 @@ void doDeepSleep(uint32_t msecToWake, bool skipPreflight = false, bool skipSaveN
gpio_hold_en((gpio_num_t)LORA_CS);
}
#endif
#endif
#ifdef HAS_PMU
if (pmu_found && PMU) {
@ -384,6 +391,9 @@ esp_sleep_wakeup_cause_t doLightSleep(uint64_t sleepMsec) // FIXME, use a more r
gpio_wakeup_enable(pin, GPIO_INTR_LOW_LEVEL);
esp_sleep_enable_gpio_wakeup();
#endif
#ifdef INPUTDRIVER_ENCODER_BTN
gpio_wakeup_enable((gpio_num_t)INPUTDRIVER_ENCODER_BTN, GPIO_INTR_LOW_LEVEL);
#endif
#ifdef T_WATCH_S3
gpio_wakeup_enable((gpio_num_t)SCREEN_TOUCH_INT, GPIO_INTR_LOW_LEVEL);
#endif

View File

@ -24,5 +24,5 @@ build_flags = ${esp32_base.build_flags}
lib_deps = ${esp32s3_base.lib_deps}
https://github.com/mverch67/LovyanGFX#develop
earlephilhower/ESP8266Audio@^1.9.7
earlephilhower/ESP8266Audio@^1.9.9
earlephilhower/ESP8266SAM@^1.0.1

View File

@ -25,8 +25,7 @@
#define ST7701_BL 45
#define ST7701_SPI_HOST SPI2_HOST
#define ST7701_BACKLIGHT_EN 45
#define SPI_FREQUENCY 20000000
#define SPI_READ_FREQUENCY 16000000
#define SPI_FREQUENCY 12000000
#define TFT_HEIGHT 480
#define TFT_WIDTH 480
#define TFT_OFFSET_X 0

View File

@ -6,7 +6,7 @@ board_check = true
upload_protocol = esptool
#upload_port = COM29
build_flags = ${esp32_base.build_flags}
build_flags = ${esp32s3_base.build_flags}
-DT_DECK
-DBOARD_HAS_PSRAM
-DMAX_THREADS=40

View File

@ -27,8 +27,10 @@
#define SLEEP_TIME 120
#ifndef HAS_TFT
#define BUTTON_PIN 0
// #define BUTTON_NEED_PULLUP
#endif
#define GPS_DEFAULT_NOT_PRESENT 1
#define GPS_RX_PIN 44
#define GPS_TX_PIN 43
@ -60,7 +62,7 @@
#define TB_DOWN 15
#define TB_LEFT 1
#define TB_RIGHT 2
#define TB_PRESS BUTTON_PIN
#define TB_PRESS 0 // BUTTON_PIN
// microphone
#define ES7210_SCK 47