Compare commits

..

6 Commits

Author SHA1 Message Date
Ben Meadors
700397d3ed ugh 2024-08-27 07:32:05 -05:00
Ben Meadors
cd65497ac4 Update to move setup to its own module 2024-08-27 07:02:49 -05:00
Ben Meadors
3c90a65a66 WIP 2024-08-27 06:24:36 -05:00
Ben Meadors
9e8f0814ab Stuff 2024-08-26 16:34:28 -05:00
Ben Meadors
36cadd03ee wip 2024-08-25 15:27:59 -05:00
Ben Meadors
15ee827efd Hello world 2024-08-25 13:41:58 -05:00
136 changed files with 779 additions and 25682 deletions

View File

@@ -12,7 +12,6 @@ RUN apt-get update && export DEBIAN_FRONTEND=noninteractive \
libssl-dev \
libulfius-dev \
libyaml-cpp-dev \
pipx \
pkg-config \
python3 \
python3-pip \
@@ -22,4 +21,4 @@ RUN apt-get update && export DEBIAN_FRONTEND=noninteractive \
zip \
&& apt-get clean && rm -rf /var/lib/apt/lists/*
RUN pipx install platformio==6.1.15
RUN pip3 install --no-cache-dir -U platformio==6.1.15

View File

@@ -1,9 +1,9 @@
### ❌ (Please delete all these tips and replace them with your text) ❌
## Thank you for sending in a pull request, here's some tips to get started!
(Please delete all these tips and replace with your text)
- Before starting on some new big chunk of code, it it is optional but highly recommended to open an issue first
to say "Hey, I think this idea X should be implemented and I'm starting work on it. My general plan is Y, any feedback
to say "hey, I think this idea X should be implemented and I'm starting work on it. My general plan is Y, any feedback
is appreciated." This will allow other devs to potentially save you time by not accidentially duplicating work etc...
- Please do not check in files that don't have real changes
- Please do not reformat lines that you didn't have to change the code on
@@ -12,4 +12,3 @@
- If your PR fixes a bug, mention "fixes #bugnum" somewhere in your pull request description.
- If your other co-developers have comments on your PR please tweak as needed.
- Please also enable "Allow edits by maintainers".
- If your PR gets accepted you can request a "Contributor" role in the Meshtastic Discord

View File

@@ -10,7 +10,7 @@ jobs:
build-native:
runs-on: ubuntu-latest
steps:
- name: Install libs needed for native build
- name: Install libbluetooth
shell: bash
run: |
sudo apt-get update --fix-missing

View File

@@ -1,4 +1,4 @@
name: End to end tests
name: Test Simulator
on:
schedule:
@@ -55,37 +55,3 @@ jobs:
name: PlatformIO Tests
path: testreport.xml
reporter: java-junit
hardware-tests:
runs-on: ubuntu-latest
steps:
- name: Checkout code
uses: actions/checkout@v4
- name: Upgrade python tools
shell: bash
run: |
python -m pip install --upgrade pip
pip install -U --no-build-isolation --no-cache-dir "setuptools<72"
pip install -U platformio adafruit-nrfutil --no-build-isolation
pip install -U poetry --no-build-isolation
pip install -U meshtastic --pre --no-build-isolation
- name: Upgrade platformio
shell: bash
run: |
pio upgrade
- name: Setup pnpm
uses: pnpm/action-setup@v2
with:
version: latest
- name: Install Dependencies
run: pnpm install
- name: Setup devices
run: pnpm run setup
- name: Execute end to end tests on connected hardware
run: pnpm run test

3
.gitmodules vendored
View File

@@ -1,6 +1,3 @@
[submodule "protobufs"]
path = protobufs
url = https://github.com/meshtastic/protobufs.git
[submodule "meshtestic"]
path = meshtestic
url = https://github.com/meshtastic/meshTestic

View File

@@ -1,36 +1,36 @@
version: 0.1
cli:
version: 1.22.3
version: 1.22.2
plugins:
sources:
- id: trunk
ref: v1.6.2
ref: v1.5.0
uri: https://github.com/trunk-io/plugins
lint:
enabled:
- trufflehog@3.81.9
- trufflehog@3.76.3
- yamllint@1.35.1
- bandit@1.7.9
- checkov@3.2.238
- bandit@1.7.8
- checkov@3.2.95
- terrascan@1.19.1
- trivy@0.54.1
- trivy@0.51.1
#- trufflehog@3.63.2-rc0
- taplo@0.9.3
- ruff@0.6.2
- taplo@0.8.1
- ruff@0.4.4
- isort@5.13.2
- markdownlint@0.41.0
- oxipng@9.1.2
- markdownlint@0.40.0
- oxipng@9.1.1
- svgo@3.3.2
- actionlint@1.7.1
- flake8@7.1.1
- actionlint@1.7.0
- flake8@7.0.0
- hadolint@2.12.0
- shfmt@3.6.0
- shellcheck@0.10.0
- black@24.8.0
- black@24.4.2
- git-diff-check
- gitleaks@8.18.4
- gitleaks@8.18.2
- clang-format@16.0.3
- prettier@3.3.3
- prettier@3.2.5
ignore:
- linters: [ALL]
paths:

View File

@@ -2,9 +2,8 @@
// See http://go.microsoft.com/fwlink/?LinkId=827846
// for the documentation about the extensions.json format
"recommendations": [
"platformio.platformio-ide"
"ms-vscode.cpptools",
"platformio.platformio-ide",
"trunk.io"
],
"unwantedRecommendations": [
"ms-vscode.cpptools-extension-pack"
]
}

View File

@@ -1,47 +0,0 @@
# Contributing to Meshtastic Firmware
We're excited that you're interested in contributing to the Meshtastic firmware! This document provides a high-level overview of how you can get involved.
## Important First Steps
Before you begin, please:
1. **Read our documentation**: Our [official documentation](https://meshtastic.org/docs/) is a crucial resource. It contains essential information about the project.
2. **Check out the firmware build guide**: For specific instructions on setting up your development environment and building the firmware, refer to our [Firmware Build Guide](https://meshtastic.org/docs/development/firmware/build/).
3. Read our [Code of Conduct](https://meshtastic.org/docs/legal/conduct/)
4. Join our [Discord community](https://discord.com/invite/ktMAKGBnBs) to connect with developers and other contributors to get help.
## Getting Help and Discussing Ideas
We encourage open communication and discussion before diving into code changes:
1. **Use GitHub Discussions**: For new ideas, questions, or to discuss potential changes, start a conversation in our [GitHub Discussions](https://github.com/meshtastic/firmware/discussions) first. This helps us collaborate and avoid duplicate work.
2. **Join our Discord**: For real-time chat and quick questions, join our [Discord server](https://discord.com/invite/ktMAKGBnBs). It's a great place to get help and connect with other developers and the community.
3. **Reporting Issues**: If you've identified a bug, please use our bug report template when creating a new issue in the [issue tracker](https://github.com/meshtastic/firmware/issues). Ensure you've searched existing issues to avoid duplicates.
## Making Contributions
> [!IMPORTANT]
> Before making any contributions, you must sign our Contributor License Agreement (CLA). You can do this by visiting https://cla-assistant.io/meshtastic/firmware. Be sure to use the GitHub account you will use to submit your contributions when signing.
1. Fork the repository
2. Create a new branch for your feature or bug fix
3. Make your changes
4. Test your changes thoroughly
5. Create a pull request with a clear description, using the provided template, of your changes. Be sure to enable "Allow edits from maintainers".
## Coding Standards
To ensure consistent code formatting across the project:
1. Install the [Trunk](https://marketplace.visualstudio.com/items?itemName=Trunk.io) extension for Visual Studio Code.
2. Before submitting your changes, run `trunk fmt` to automatically format your code according to our standards.
Adhering to these formatting guidelines helps maintain code consistency and makes the review process smoother.
Thank you for contributing to Meshtastic!

Binary file not shown.

View File

@@ -46,8 +46,3 @@ else
cp bin/device-update.* $OUTDIR
cp bin/*.uf2 $OUTDIR
fi
if (echo $1 | grep -q "rak4631"); then
echo "Copying hex file"
cp .pio/build/$1/firmware.hex $OUTDIR/$basename.hex
fi

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

View File

@@ -39,4 +39,4 @@ def readProps(prefsLoc):
return verObj
# print("path is" + ','.join(sys.path))
# print("path is" + ','.join(sys.path))

View File

@@ -19,7 +19,7 @@
"mcu": "esp32s3",
"variant": "CDEBYTE_EoRa-S3"
},
"connectivity": ["wifi", "bluetooth"],
"connectivity": ["wifi"],
"debug": {
"openocd_target": "esp32s3.cfg"
},

View File

@@ -19,7 +19,7 @@
"mcu": "esp32s3",
"variant": "ESP32-S3-WROOM-1-N4"
},
"connectivity": ["wifi", "bluetooth"],
"connectivity": ["wifi"],
"debug": {
"default_tool": "esp-builtin",
"onboard_tools": ["esp-builtin"],

View File

@@ -1,58 +0,0 @@
{
"build": {
"arduino": {
"ldscript": "nrf52840_s140_v7.ld"
},
"core": "nRF5",
"cpu": "cortex-m4",
"extra_flags": "-DARDUINO_WIO_WM1110 -DNRF52840_XXAA",
"f_cpu": "64000000L",
"hwids": [
["0x239A", "0x8029"],
["0x239A", "0x0029"],
["0x239A", "0x002A"],
["0x239A", "0x802A"]
],
"usb_product": "MS24SF1-BOOT",
"mcu": "nrf52840",
"variant": "MINEWSEMI_MS24SF1_SX1262",
"bsp": {
"name": "adafruit"
},
"softdevice": {
"sd_flags": "-DS140",
"sd_name": "s140",
"sd_version": "7.3.0",
"sd_fwid": "0x0123"
},
"bootloader": {
"settings_addr": "0xFF000"
}
},
"connectivity": ["bluetooth"],
"debug": {
"jlink_device": "nRF52840_xxAA",
"svd_path": "nrf52840.svd"
},
"frameworks": ["arduino"],
"name": "MINEWSEMI_MS24SF1_SX1262",
"upload": {
"maximum_ram_size": 248832,
"maximum_size": 815104,
"speed": 115200,
"protocol": "nrfutil",
"protocols": [
"jlink",
"nrfjprog",
"nrfutil",
"stlink",
"cmsis-dap",
"blackmagic"
],
"use_1200bps_touch": true,
"require_upload_port": true,
"wait_for_upload_port": true
},
"url": "https://en.minewsemi.com/lora-module/nrf52840-sx1262-ms24sf1",
"vendor": "Minesemi"
}

View File

@@ -19,7 +19,7 @@
"mcu": "esp32s3",
"variant": "tlora-t3s3-v1"
},
"connectivity": ["wifi", "bluetooth"],
"connectivity": ["wifi"],
"debug": {
"openocd_target": "esp32s3.cfg"
},

Submodule meshtestic deleted from 31ee3d90c8

View File

@@ -81,14 +81,12 @@ build_flags = -Wno-missing-field-initializers
-DRADIOLIB_EXCLUDE_APRS
-DRADIOLIB_EXCLUDE_LORAWAN
-DMESHTASTIC_EXCLUDE_DROPZONE=1
;-D OLED_PL
monitor_speed = 115200
monitor_filters = direct
lib_deps =
; jgromes/RadioLib@~6.6.0
https://github.com/jgromes/RadioLib.git#3115fc2d6700a9aee05888791ac930a910f2628f
jgromes/RadioLib@~6.6.0
https://github.com/meshtastic/esp8266-oled-ssd1306.git#e16cee124fe26490cb14880c679321ad8ac89c95 ; ESP8266_SSD1306
https://github.com/mathertel/OneButton@~2.6.1 ; OneButton library for non-blocking button debounce
https://github.com/meshtastic/arduino-fsm.git#7db3702bf0cfe97b783d6c72595e3f38e0b19159
@@ -132,7 +130,6 @@ lib_deps =
adafruit/Adafruit BMP280 Library@^2.6.8
adafruit/Adafruit BMP085 Library@^1.2.4
adafruit/Adafruit BME280 Library@^2.2.2
adafruit/Adafruit BMP3XX Library@^2.1.5
adafruit/Adafruit MCP9808 Library@^2.0.0
adafruit/Adafruit INA260 Library@^1.5.0
adafruit/Adafruit INA219@^1.2.0
@@ -151,10 +148,13 @@ lib_deps =
ClosedCube OPT3001@^1.1.2
emotibit/EmotiBit MLX90632@^1.0.8
dfrobot/DFRobot_RTU@^1.0.3
https://github.com/boschsensortec/Bosch-BSEC2-Library#v1.7.2502
boschsensortec/BME68x Sensor Library@^1.1.40407
https://github.com/KodinLanewave/INA3221@^1.0.0
lewisxhe/SensorLib@^0.2.0
mprograms/QMC5883LCompass@^1.2.0
https://github.com/meshtastic/DFRobot_LarkWeatherStation#dee914270dc7cb3e43fbf034edd85a63a16a12ee
https://github.com/meshtastic/i2c-sensor#8e97122268960593c8c279df1a84a29970136a8f

View File

@@ -97,14 +97,12 @@ Syslog &Syslog::logMask(uint8_t priMask)
void Syslog::enable()
{
this->_client->begin(this->_port);
this->_enabled = true;
}
void Syslog::disable()
{
this->_enabled = false;
this->_client->stop();
}
bool Syslog::isEnabled()
@@ -195,4 +193,4 @@ inline bool Syslog::_sendLog(uint16_t pri, const char *appName, const char *mess
return true;
}
#endif
#endif

View File

@@ -10,13 +10,6 @@ void GpioVirtPin::set(bool value)
}
}
void GpioHwPin::set(bool value)
{
// if (num == 3) LOG_DEBUG("Setting pin %d to %d\n", num, value);
pinMode(num, OUTPUT);
digitalWrite(num, value);
}
GpioTransformer::GpioTransformer(GpioPin *outPin) : outPin(outPin) {}
void GpioTransformer::set(bool value)
@@ -24,7 +17,7 @@ void GpioTransformer::set(bool value)
outPin->set(value);
}
GpioUnaryTransformer::GpioUnaryTransformer(GpioVirtPin *inPin, GpioPin *outPin) : GpioTransformer(outPin), inPin(inPin)
GpioNotTransformer::GpioNotTransformer(GpioVirtPin *inPin, GpioPin *outPin) : GpioTransformer(outPin), inPin(inPin)
{
assert(!inPin->dependentPin); // We only allow one dependent pin
inPin->dependentPin = this;
@@ -34,18 +27,6 @@ GpioUnaryTransformer::GpioUnaryTransformer(GpioVirtPin *inPin, GpioPin *outPin)
// update();
}
/**
* Update the output pin based on the current state of the input pin.
*/
void GpioUnaryTransformer::update()
{
auto p = inPin->get();
if (p == GpioVirtPin::PinState::Unset)
return; // Not yet fully initialized
set(p);
}
/**
* Update the output pin based on the current state of the input pin.
*/
@@ -88,7 +69,6 @@ void GpioBinaryTransformer::update()
newValue = (GpioVirtPin::PinState)(p1 && p2);
break;
case Or:
// LOG_DEBUG("Doing GPIO OR\n");
newValue = (GpioVirtPin::PinState)(p1 || p2);
break;
case Xor:

View File

@@ -29,7 +29,7 @@ class GpioHwPin : public GpioPin
public:
explicit GpioHwPin(uint32_t num) : num(num) {}
void set(bool value);
void set(bool value) { digitalWrite(num, value); }
};
class GpioTransformer;
@@ -42,7 +42,7 @@ class GpioBinaryTransformer;
class GpioVirtPin : public GpioPin
{
friend class GpioBinaryTransformer;
friend class GpioUnaryTransformer;
friend class GpioNotTransformer;
public:
enum PinState { On = true, Off = false, Unset = 2 };
@@ -78,32 +78,13 @@ class GpioTransformer
GpioPin *outPin;
};
/**
* A transformer that just drives a hw pin based on a virtual pin.
*/
class GpioUnaryTransformer : public GpioTransformer
{
public:
GpioUnaryTransformer(GpioVirtPin *inPin, GpioPin *outPin);
protected:
friend class GpioVirtPin;
/**
* Update the output pin based on the current state of the input pin.
*/
virtual void update();
GpioVirtPin *inPin;
};
/**
* A transformer that performs a unary NOT operation from an input.
*/
class GpioNotTransformer : public GpioUnaryTransformer
class GpioNotTransformer : public GpioTransformer
{
public:
GpioNotTransformer(GpioVirtPin *inPin, GpioPin *outPin) : GpioUnaryTransformer(inPin, outPin) {}
GpioNotTransformer(GpioVirtPin *inPin, GpioPin *outPin);
protected:
friend class GpioVirtPin;
@@ -112,6 +93,9 @@ class GpioNotTransformer : public GpioUnaryTransformer
* Update the output pin based on the current state of the input pin.
*/
void update();
private:
GpioVirtPin *inPin;
};
/**

View File

@@ -136,30 +136,6 @@ using namespace meshtastic;
*/
static HasBatteryLevel *batteryLevel; // Default to NULL for no battery level sensor
static void adcEnable()
{
#ifdef ADC_CTRL // enable adc voltage divider when we need to read
#ifdef ADC_USE_PULLUP
pinMode(ADC_CTRL, INPUT_PULLUP);
#else
pinMode(ADC_CTRL, OUTPUT);
digitalWrite(ADC_CTRL, ADC_CTRL_ENABLED);
#endif
delay(10);
#endif
}
static void adcDisable()
{
#ifdef ADC_CTRL // disable adc voltage divider when we need to read
#ifdef ADC_USE_PULLUP
pinMode(ADC_CTRL, INPUT_PULLDOWN);
#else
digitalWrite(ADC_CTRL, !ADC_CTRL_ENABLED);
#endif
#endif
}
/**
* A simple battery level sensor that assumes the battery voltage is attached via a voltage-divider to an analog input
*/
@@ -250,19 +226,25 @@ class AnalogBatteryLevel : public HasBatteryLevel
uint32_t raw = 0;
float scaled = 0;
adcEnable();
#ifdef ARCH_ESP32 // ADC block for espressif platforms
raw = espAdcRead();
scaled = esp_adc_cal_raw_to_voltage(raw, adc_characs);
scaled *= operativeAdcMultiplier;
#else // block for all other platforms
#else // block for all other platforms
#ifdef ADC_CTRL // enable adc voltage divider when we need to read
pinMode(ADC_CTRL, OUTPUT);
digitalWrite(ADC_CTRL, ADC_CTRL_ENABLED);
delay(10);
#endif
for (uint32_t i = 0; i < BATTERY_SENSE_SAMPLES; i++) {
raw += analogRead(BATTERY_PIN);
}
raw = raw / BATTERY_SENSE_SAMPLES;
scaled = operativeAdcMultiplier * ((1000 * AREF_VOLTAGE) / pow(2, BATTERY_SENSE_RESOLUTION_BITS)) * raw;
#ifdef ADC_CTRL // disable adc voltage divider when we need to read
digitalWrite(ADC_CTRL, !ADC_CTRL_ENABLED);
#endif
#endif
adcDisable();
if (!initial_read_done) {
// Flush the smoothing filter with an ADC reading, if the reading is plausibly correct
@@ -293,6 +275,11 @@ class AnalogBatteryLevel : public HasBatteryLevel
uint8_t raw_c = 0; // raw reading counter
#ifndef BAT_MEASURE_ADC_UNIT // ADC1
#ifdef ADC_CTRL // enable adc voltage divider when we need to read
pinMode(ADC_CTRL, OUTPUT);
digitalWrite(ADC_CTRL, ADC_CTRL_ENABLED);
delay(10);
#endif
for (int i = 0; i < BATTERY_SENSE_SAMPLES; i++) {
int val_ = adc1_get_raw(adc_channel);
if (val_ >= 0) { // save only valid readings
@@ -301,7 +288,18 @@ class AnalogBatteryLevel : public HasBatteryLevel
}
// delayMicroseconds(100);
}
#else // ADC2
#ifdef ADC_CTRL // disable adc voltage divider when we need to read
digitalWrite(ADC_CTRL, !ADC_CTRL_ENABLED);
#endif
#else // ADC2
#ifdef ADC_CTRL
#if defined(HELTEC_WIRELESS_PAPER) || defined(HELTEC_WIRELESS_PAPER_V1_0)
pinMode(ADC_CTRL, OUTPUT);
digitalWrite(ADC_CTRL, LOW); // ACTIVE LOW
delay(10);
#endif
#endif // End ADC_CTRL
#ifdef CONFIG_IDF_TARGET_ESP32S3 // ESP32S3
// ADC2 wifi bug workaround not required, breaks compile
// On ESP32S3, ADC2 can take turns with Wifi (?)
@@ -336,6 +334,12 @@ class AnalogBatteryLevel : public HasBatteryLevel
}
#endif // BAT_MEASURE_ADC_UNIT
#ifdef ADC_CTRL
#if defined(HELTEC_WIRELESS_PAPER) || defined(HELTEC_WIRELESS_PAPER_V1_0)
digitalWrite(ADC_CTRL, HIGH);
#endif
#endif // End ADC_CTRL
#endif // End BAT_MEASURE_ADC_UNIT
return (raw / (raw_c < 1 ? 1 : raw_c));
}

View File

@@ -3,4 +3,5 @@
#define RF95_RESET LORA_RESET
#define RF95_IRQ LORA_DIO0 // on SX1262 version this is a no connect DIO0
#define RF95_DIO1 LORA_DIO1 // Note: not really used for RF95, but used for pure SX127x
#endif
#define RF95_DIO2 LORA_DIO2 // Note: not really used for RF95
#endif

View File

@@ -177,11 +177,6 @@ along with this program. If not, see <http://www.gnu.org/licenses/>.
/* Step #1: offer chance for variant-specific defines */
#include "variant.h"
#if defined(VEXT_ENABLE) && !defined(VEXT_ON_VALUE)
// Older variant.h files might not be defining this value, so stay with the old default
#define VEXT_ON_VALUE LOW
#endif
#ifndef GPS_BAUDRATE
#define GPS_BAUDRATE 9600
#endif

View File

@@ -24,7 +24,6 @@ class ScanI2C
BME_280,
BMP_280,
BMP_085,
BMP_3XX,
INA260,
INA219,
INA3221,
@@ -52,8 +51,7 @@ class ScanI2C
AHT10,
BMX160,
DFROBOT_LARK,
NAU7802,
CUSTOM_SENSOR,
NAU7802
} DeviceType;
// typedef uint8_t DeviceAddress;

View File

@@ -7,7 +7,6 @@
#include "linux/LinuxHardwareI2C.h"
#endif
#if !defined(ARCH_PORTDUINO) && !defined(ARCH_STM32WL)
#include "I2CDefinitions.h"
#include "main.h" // atecc
#endif
@@ -268,19 +267,8 @@ void ScanI2CTwoWire::scanPort(I2CPort port, uint8_t *address, uint8_t asize)
type = BMP_085;
break;
default:
registerValue = getRegisterValue(ScanI2CTwoWire::RegisterLocation(addr, 0x00), 1); // GET_ID
switch (registerValue) {
case 0x50: // BMP-388 should be 0x50
LOG_INFO("BMP-388 sensor found at address 0x%x\n", (uint8_t)addr.address);
type = BMP_3XX;
break;
case 0x58: // BMP-280 should be 0x58
default:
LOG_INFO("BMP-280 sensor found at address 0x%x\n", (uint8_t)addr.address);
type = BMP_280;
break;
}
break;
LOG_INFO("BMP-280 sensor found at address 0x%x\n", (uint8_t)addr.address);
type = BMP_280;
}
break;
#ifndef HAS_NCP5623
@@ -378,7 +366,6 @@ void ScanI2CTwoWire::scanPort(I2CPort port, uint8_t *address, uint8_t asize)
SCAN_SIMPLE_CASE(OPT3001_ADDR, OPT3001, "OPT3001 light sensor found\n");
SCAN_SIMPLE_CASE(MLX90632_ADDR, MLX90632, "MLX90632 IR temp sensor found\n");
SCAN_SIMPLE_CASE(NAU7802_ADDR, NAU7802, "NAU7802 based scale found\n");
SCAN_SIMPLE_CASE(MT_I2C_ADDRESS, CUSTOM_SENSOR, "Meshtastic custom I2C sensor found\n");
default:
LOG_INFO("Device found at address 0x%x was not able to be enumerated\n", addr.address);

View File

@@ -2,7 +2,6 @@
#if !MESHTASTIC_EXCLUDE_GPS
#include "Default.h"
#include "GPS.h"
#include "GpioLogic.h"
#include "NodeDB.h"
#include "PowerMon.h"
#include "RTC.h"
@@ -507,19 +506,19 @@ bool GPS::setup()
delay(250);
} else if (gnssModel == GNSS_MODEL_AG3335) {
_serial_gps->write("$PAIR066,1,0,1,0,0,1*3B\r\n"); // Enable GPS+GALILEO+NAVIC
_serial_gps->write("$PAIR066,1,0,1,0,0,1*3B"); // Enable GPS+GALILEO+NAVIC
// Configure NMEA (sentences will output once per fix)
_serial_gps->write("$PAIR062,0,0*3F\r\n"); // GGA ON
_serial_gps->write("$PAIR062,1,0*3F\r\n"); // GLL OFF
_serial_gps->write("$PAIR062,2,1*3D\r\n"); // GSA ON
_serial_gps->write("$PAIR062,3,0*3D\r\n"); // GSV OFF
_serial_gps->write("$PAIR062,4,0*3B\r\n"); // RMC ON
_serial_gps->write("$PAIR062,5,0*3B\r\n"); // VTG OFF
_serial_gps->write("$PAIR062,6,1*39\r\n"); // ZDA ON
_serial_gps->write("$PAIR062,0,0*3F"); // GGA ON
_serial_gps->write("$PAIR062,1,0*3F"); // GLL OFF
_serial_gps->write("$PAIR062,2,1*3D"); // GSA ON
_serial_gps->write("$PAIR062,3,0*3D"); // GSV OFF
_serial_gps->write("$PAIR062,4,0*3B"); // RMC ON
_serial_gps->write("$PAIR062,5,0*3B"); // VTG OFF
_serial_gps->write("$PAIR062,6,1*39"); // ZDA ON
delay(250);
_serial_gps->write("$PAIR513*3D\r\n"); // save configuration
_serial_gps->write("$PAIR513*3D"); // save configuration
} else if (gnssModel == GNSS_MODEL_UBLOX) {
// Configure GNSS system to GPS+SBAS+GLONASS (Module may restart after this command)
@@ -876,8 +875,16 @@ void GPS::writePinEN(bool on)
if (HW_VENDOR == meshtastic_HardwareModel_RAK4631 && (rotaryEncoderInterruptImpl1 || upDownInterruptImpl1))
return;
// Abort: if pin unset
if (!en_gpio)
return;
// Determine new value for the pin
bool val = GPS_EN_ACTIVE ? on : !on;
// Write and log
enablePin->set(on);
pinMode(en_gpio, OUTPUT);
digitalWrite(en_gpio, val);
#ifdef GPS_EXTRAVERBOSE
LOG_DEBUG("Pin EN %s\n", val == HIGH ? "HIGH" : "LOW");
#endif
@@ -1019,7 +1026,7 @@ void GPS::down()
LOG_DEBUG("%us until next search\n", sleepTime / 1000);
// If update interval less than 10 seconds, no attempt to sleep
if (updateInterval <= 10 * 1000UL || sleepTime == 0)
if (updateInterval <= 10 * 1000UL)
setPowerState(GPS_IDLE);
else {
@@ -1184,15 +1191,6 @@ int GPS::prepareDeepSleep(void *unused)
return 0;
}
#define PROBE_SIMPLE(CHIP, TOWRITE, RESPONSE, DRIVER, TIMEOUT, ...) \
LOG_DEBUG("Trying " TOWRITE " (" CHIP ") ...\n"); \
clearBuffer(); \
_serial_gps->write(TOWRITE "\r\n"); \
if (getACK(RESPONSE, TIMEOUT) == GNSS_RESPONSE_OK) { \
LOG_INFO(CHIP " detected, using " #DRIVER " Module\n"); \
return DRIVER; \
}
GnssModel_t GPS::probe(int serialSpeed)
{
#if defined(ARCH_NRF52) || defined(ARCH_PORTDUINO) || defined(ARCH_RP2040) || defined(ARCH_STM32WL)
@@ -1207,7 +1205,11 @@ GnssModel_t GPS::probe(int serialSpeed)
#ifdef GNSS_AIROHA
return GNSS_MODEL_AG3335;
#endif
#ifdef GPS_DEBUG
for (int i = 0; i < 20; i++) {
getACK("$GP", 200);
}
#endif
memset(&info, 0, sizeof(struct uBloxGnssModelInfo));
uint8_t buffer[768] = {0};
delay(100);
@@ -1216,24 +1218,70 @@ GnssModel_t GPS::probe(int serialSpeed)
_serial_gps->write("$PCAS03,0,0,0,0,0,0,0,0,0,0,,,0,0*02\r\n");
delay(20);
// Unicore UFirebirdII Series: UC6580, UM620, UM621, UM670A, UM680A, or UM681A
PROBE_SIMPLE("UC6580", "$PDTINFO", "UC6580", GNSS_MODEL_UC6580, 500);
PROBE_SIMPLE("UM600", "$PDTINFO", "UM600", GNSS_MODEL_UC6580, 500);
PROBE_SIMPLE("ATGM336H", "$PCAS06,1*1A", "$GPTXT,01,01,02,HW=ATGM336H", GNSS_MODEL_ATGM336H, 500);
// get version information from Unicore UFirebirdII Series
// Works for: UC6580, UM620, UM621, UM670A, UM680A, or UM681A
_serial_gps->write("$PDTINFO\r\n");
delay(750);
if (getACK("UC6580", 500) == GNSS_RESPONSE_OK) {
LOG_INFO("UC6580 detected, using UC6580 Module\n");
return GNSS_MODEL_UC6580;
}
clearBuffer();
_serial_gps->write("$PDTINFO\r\n");
delay(750);
if (getACK("UM600", 500) == GNSS_RESPONSE_OK) {
LOG_INFO("UM600 detected, using UC6580 Module\n");
return GNSS_MODEL_UC6580;
}
// Get version information for ATGM336H
clearBuffer();
_serial_gps->write("$PCAS06,1*1A\r\n");
if (getACK("$GPTXT,01,01,02,HW=ATGM336H", 500) == GNSS_RESPONSE_OK) {
LOG_INFO("ATGM336H GNSS init succeeded, using ATGM336H Module\n");
return GNSS_MODEL_ATGM336H;
}
/* ATGM332D series (-11(GPS), -21(BDS), -31(GPS+BDS), -51(GPS+GLONASS), -71-0(GPS+BDS+GLONASS))
based on AT6558 */
PROBE_SIMPLE("ATGM332D", "$PCAS06,1*1A", "$GPTXT,01,01,02,HW=ATGM332D", GNSS_MODEL_ATGM336H, 500);
clearBuffer();
_serial_gps->write("$PCAS06,1*1A\r\n");
if (getACK("$GPTXT,01,01,02,HW=ATGM332D", 500) == GNSS_RESPONSE_OK) {
LOG_INFO("ATGM332D detected, using ATGM336H Module\n");
return GNSS_MODEL_ATGM336H;
}
/* Airoha (Mediatek) AG3335A/M/S, A3352Q, Quectel L89 2.0, SimCom SIM65M */
PROBE_SIMPLE("AG3335", "PAIR020*38", "$PAIR020,AG3335", GNSS_MODEL_AG3335, 500);
clearBuffer();
_serial_gps->write("PAIR020*38\r\n");
if (getACK("$PAIR020,AG3335", 500) == GNSS_RESPONSE_OK) {
LOG_INFO("Aioha AG3335 detected, using AG3335 Module\n");
return GNSS_MODEL_AG3335;
}
// Get version information for Airoha AG3335
clearBuffer();
_serial_gps->write("$PMTK605*31\r\n");
PROBE_SIMPLE("L76K", "$PCAS06,0*1B", "$GPTXT,01,01,02,SW=", GNSS_MODEL_MTK, 500);
// Get version information
clearBuffer();
_serial_gps->write("$PCAS06,0*1B\r\n");
if (getACK("$GPTXT,01,01,02,SW=", 500) == GNSS_RESPONSE_OK) {
LOG_INFO("L76K GNSS init succeeded, using L76K GNSS Module\n");
return GNSS_MODEL_MTK;
}
// Close all NMEA sentences, valid for L76B MTK platform (Waveshare Pico GPS)
_serial_gps->write("$PMTK514,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0*2E\r\n");
delay(20);
PROBE_SIMPLE("L76B", "$PMTK605*31", "Quectel-L76B", GNSS_MODEL_MTK_L76B, 500);
// Get version information
clearBuffer();
_serial_gps->write("$PMTK605*31\r\n");
if (getACK("Quectel-L76B", 500) == GNSS_RESPONSE_OK) {
LOG_INFO("L76B GNSS init succeeded, using L76B GNSS Module\n");
return GNSS_MODEL_MTK_L76B;
}
uint8_t cfg_rate[] = {0xB5, 0x62, 0x06, 0x08, 0x00, 0x00, 0x00, 0x00};
UBXChecksum(cfg_rate, sizeof(cfg_rate));
@@ -1373,20 +1421,7 @@ GPS *GPS::createGps()
GPS *new_gps = new GPS;
new_gps->rx_gpio = _rx_gpio;
new_gps->tx_gpio = _tx_gpio;
GpioVirtPin *virtPin = new GpioVirtPin();
new_gps->enablePin = virtPin; // Always at least populate a virtual pin
if (_en_gpio) {
GpioPin *p = new GpioHwPin(_en_gpio);
if (!GPS_EN_ACTIVE) { // Need to invert the pin before hardware
new GpioNotTransformer(
virtPin, p); // We just leave this created object on the heap so it can stay watching virtPin and driving en_gpio
} else {
new GpioUnaryTransformer(
virtPin, p); // We just leave this created object on the heap so it can stay watching virtPin and driving en_gpio
}
}
new_gps->en_gpio = _en_gpio;
#ifdef PIN_GPS_PPS
// pulse per second

View File

@@ -3,7 +3,6 @@
#if !MESHTASTIC_EXCLUDE_GPS
#include "GPSStatus.h"
#include "GpioLogic.h"
#include "Observer.h"
#include "TinyGPS++.h"
#include "concurrency/OSThread.h"
@@ -74,6 +73,7 @@ class GPS : private concurrency::OSThread
uint32_t lastWakeStartMsec = 0, lastSleepStartMsec = 0, lastFixStartMsec = 0;
uint32_t rx_gpio = 0;
uint32_t tx_gpio = 0;
uint32_t en_gpio = 0;
int speedSelect = 0;
int probeTries = 2;
@@ -152,13 +152,6 @@ class GPS : private concurrency::OSThread
meshtastic_Position p = meshtastic_Position_init_default;
/** This is normally bound to config.position.gps_en_gpio but some rare boards (like heltec tracker) need more advanced
* implementations. Those boards will set this public variable to a custom implementation.
*
* Normally set by GPS::createGPS()
*/
GpioVirtPin *enablePin = NULL;
GPS() : concurrency::OSThread("GPS") {}
virtual ~GPS();
@@ -297,6 +290,7 @@ class GPS : private concurrency::OSThread
virtual int32_t runOnce() override;
// Get GNSS model
String getNMEA();
GnssModel_t probe(int serialSpeed);
// delay counter to allow more sats before fixed position stops GPS thread

View File

@@ -157,7 +157,7 @@ bool EInkDisplay::connect()
}
#elif defined(HELTEC_WIRELESS_PAPER_V1_0) || defined(HELTEC_WIRELESS_PAPER) || defined(HELTEC_VISION_MASTER_E213) || \
defined(HELTEC_VISION_MASTER_E290) || defined(TLORA_T3S3_EPAPER)
defined(HELTEC_VISION_MASTER_E290)
{
// Start HSPI
hspi = new SPIClass(HSPI);

View File

@@ -68,7 +68,7 @@ class EInkDisplay : public OLEDDisplay
// If display uses HSPI
#if defined(HELTEC_WIRELESS_PAPER) || defined(HELTEC_WIRELESS_PAPER_V1_0) || defined(HELTEC_VISION_MASTER_E213) || \
defined(HELTEC_VISION_MASTER_E290) || defined(TLORA_T3S3_EPAPER)
defined(HELTEC_VISION_MASTER_E290)
SPIClass *hspi = NULL;
#endif

View File

@@ -123,7 +123,7 @@ static bool heartbeat = false;
/// Check if the display can render a string (detect special chars; emoji)
static bool haveGlyphs(const char *str)
{
#if defined(OLED_PL) || defined(OLED_UA) || defined(OLED_RU)
#if defined(OLED_UA) || defined(OLED_RU)
// Don't want to make any assumptions about custom language support
return true;
#endif
@@ -1093,8 +1093,7 @@ static void drawNodes(OLEDDisplay *display, int16_t x, int16_t y, const NodeStat
{
char usersString[20];
snprintf(usersString, sizeof(usersString), "%d/%d", nodeStatus->getNumOnline(), nodeStatus->getNumTotal());
#if (defined(USE_EINK) || defined(ILI9341_DRIVER) || defined(ST7735_CS) || defined(ST7789_CS) || defined(USE_ST7789) || \
defined(HX8357_CS)) && \
#if (defined(USE_EINK) || defined(ILI9341_DRIVER) || defined(ST7735_CS) || defined(ST7789_CS) || defined(HX8357_CS)) && \
!defined(DISPLAY_FORCE_SMALL_FONTS)
display->drawFastImage(x, y + 3, 8, 8, imgUser);
#else
@@ -1766,11 +1765,6 @@ void Screen::forceDisplay(bool forceUiUpdate)
#ifdef USE_EINK
// If requested, make sure queued commands are run, and UI has rendered a new frame
if (forceUiUpdate) {
// Force a display refresh, in addition to the UI update
// Changing the GPS status bar icon apparently doesn't register as a change in image
// (False negative of the image hashing algorithm used to skip identical frames)
EINK_ADD_FRAMEFLAG(dispdev, DEMAND_FAST);
// No delay between UI frame rendering
setFastFramerate();
@@ -2420,8 +2414,7 @@ void DebugInfo::drawFrame(OLEDDisplay *display, OLEDDisplayUiState *state, int16
#ifdef ARCH_ESP32
if (millis() - storeForwardModule->lastHeartbeat >
(storeForwardModule->heartbeatInterval * 1200)) { // no heartbeat, overlap a bit
#if (defined(USE_EINK) || defined(ILI9341_DRIVER) || defined(ST7735_CS) || defined(ST7789_CS) || defined(USE_ST7789) || \
defined(HX8357_CS)) && \
#if (defined(USE_EINK) || defined(ILI9341_DRIVER) || defined(ST7735_CS) || defined(ST7789_CS) || defined(HX8357_CS)) && \
!defined(DISPLAY_FORCE_SMALL_FONTS)
display->drawFastImage(x + SCREEN_WIDTH - 14 - display->getStringWidth(ourId), y + 3 + FONT_HEIGHT_SMALL, 12, 8,
imgQuestionL1);
@@ -2432,8 +2425,7 @@ void DebugInfo::drawFrame(OLEDDisplay *display, OLEDDisplayUiState *state, int16
imgQuestion);
#endif
} else {
#if (defined(USE_EINK) || defined(ILI9341_DRIVER) || defined(ST7735_CS) || defined(ST7789_CS) || defined(USE_ST7789) || \
defined(HX8357_CS)) && \
#if (defined(USE_EINK) || defined(ILI9341_DRIVER) || defined(ST7735_CS) || defined(ST7789_CS) || defined(HX8357_CS)) && \
!defined(DISPLAY_FORCE_SMALL_FONTS)
display->drawFastImage(x + SCREEN_WIDTH - 18 - display->getStringWidth(ourId), y + 3 + FONT_HEIGHT_SMALL, 16, 8,
imgSFL1);
@@ -2447,8 +2439,8 @@ void DebugInfo::drawFrame(OLEDDisplay *display, OLEDDisplayUiState *state, int16
#endif
} else {
// TODO: Raspberry Pi supports more than just the one screen size
#if (defined(USE_EINK) || defined(ILI9341_DRIVER) || defined(ST7735_CS) || defined(ST7789_CS) || defined(USE_ST7789) || \
defined(HX8357_CS) || ARCH_PORTDUINO) && \
#if (defined(USE_EINK) || defined(ILI9341_DRIVER) || defined(ST7735_CS) || defined(ST7789_CS) || defined(HX8357_CS) || \
ARCH_PORTDUINO) && \
!defined(DISPLAY_FORCE_SMALL_FONTS)
display->drawFastImage(x + SCREEN_WIDTH - 14 - display->getStringWidth(ourId), y + 3 + FONT_HEIGHT_SMALL, 12, 8,
imgInfoL1);

View File

@@ -309,7 +309,7 @@ class Screen : public concurrency::OSThread
static char customFontTableLookup(const uint8_t ch)
{
// UTF-8 to font table index converter
// Code from http://playground.arduino.cc/Main/Utf8ascii
// Code form http://playground.arduino.cc/Main/Utf8ascii
static uint8_t LASTCHAR;
static bool SKIPREST; // Only display a single unconvertable-character symbol per sequence of unconvertable characters
@@ -322,57 +322,11 @@ class Screen : public concurrency::OSThread
uint8_t last = LASTCHAR; // get last char
LASTCHAR = ch;
switch (last) {
switch (last) { // conversion depending on first UTF8-character
case 0xC2: {
SKIPREST = false;
return (uint8_t)ch;
}
}
// We want to strip out prefix chars for two-byte char formats
if (ch == 0xC2)
return (uint8_t)0;
#if defined(OLED_PL)
switch (last) {
case 0xC3: {
if (ch == 147)
return (uint8_t)(ch); // Ó
else if (ch == 179)
return (uint8_t)(148); // ó
else
return (uint8_t)(ch | 0xC0);
break;
}
case 0xC4: {
SKIPREST = false;
return (uint8_t)(ch);
}
case 0xC5: {
SKIPREST = false;
if (ch == 132)
return (uint8_t)(136); // ń
else if (ch == 186)
return (uint8_t)(137); // ź
else
return (uint8_t)(ch);
break;
}
}
// We want to strip out prefix chars for two-byte char formats
if (ch == 0xC2 || ch == 0xC3 || ch == 0xC4 || ch == 0xC5)
return (uint8_t)0;
#endif
#if defined(OLED_UA) || defined(OLED_RU)
switch (last) {
case 0xC3: {
SKIPREST = false;
return (uint8_t)(ch | 0xC0);
@@ -422,8 +376,6 @@ class Screen : public concurrency::OSThread
if (ch == 0xC2 || ch == 0xC3 || ch == 0x82 || ch == 0xD0 || ch == 0xD1)
return (uint8_t)0;
#endif
// If we already returned an unconvertable-character symbol for this unconvertable-character sequence, return NULs for the
// rest of it
if (SKIPREST)

View File

@@ -1,9 +1,5 @@
#pragma once
#ifdef OLED_PL
#include "graphics/fonts/OLEDDisplayFontsPL.h"
#endif
#ifdef OLED_RU
#include "graphics/fonts/OLEDDisplayFontsRU.h"
#endif
@@ -12,17 +8,13 @@
#include "graphics/fonts/OLEDDisplayFontsUA.h"
#endif
#if (defined(USE_EINK) || defined(ILI9341_DRIVER) || defined(ST7735_CS) || defined(ST7789_CS) || defined(USE_ST7789) || \
defined(HX8357_CS)) && \
#if (defined(USE_EINK) || defined(ILI9341_DRIVER) || defined(ST7735_CS) || defined(ST7789_CS) || defined(HX8357_CS)) && \
!defined(DISPLAY_FORCE_SMALL_FONTS)
// The screen is bigger so use bigger fonts
#define FONT_SMALL ArialMT_Plain_16 // Height: 19
#define FONT_MEDIUM ArialMT_Plain_24 // Height: 28
#define FONT_LARGE ArialMT_Plain_24 // Height: 28
#else
#ifdef OLED_PL
#define FONT_SMALL ArialMT_Plain_10_PL
#else
#ifdef OLED_RU
#define FONT_SMALL ArialMT_Plain_10_RU
#else
@@ -32,7 +24,6 @@
#define FONT_SMALL ArialMT_Plain_10 // Height: 13
#endif
#endif
#endif
#define FONT_MEDIUM ArialMT_Plain_16 // Height: 19
#define FONT_LARGE ArialMT_Plain_24 // Height: 28
#endif

View File

@@ -21,6 +21,10 @@ extern SX1509 gpioExtender;
#if defined(ST7735S)
#include <LovyanGFX.hpp> // Graphics and font library for ST7735 driver chip
#if defined(ST7735_BACKLIGHT_EN) && !defined(TFT_BL)
#define TFT_BL ST7735_BACKLIGHT_EN
#endif
#ifndef TFT_INVERT
#define TFT_INVERT true
#endif
@@ -87,20 +91,24 @@ class LGFX : public lgfx::LGFX_Device
_panel_instance.config(cfg);
}
#ifdef TFT_BL
// Set the backlight control
{
auto cfg = _light_instance.config(); // Gets a structure for backlight settings.
cfg.pin_bl = TFT_BL; // Pin number to which the backlight is connected
cfg.invert = true; // true to invert the brightness of the backlight
#ifdef ST7735_BL_V03
cfg.pin_bl = ST7735_BL_V03;
#elif defined(ST7735_BL_V05)
cfg.pin_bl = ST7735_BL_V05;
#else
cfg.pin_bl = ST7735_BL; // Pin number to which the backlight is connected
#endif
cfg.invert = true; // true to invert the brightness of the backlight
// cfg.freq = 44100; // PWM frequency of backlight
// cfg.pwm_channel = 1; // PWM channel number to use
_light_instance.config(cfg);
_panel_instance.setLight(&_light_instance); // Set the backlight on the panel.
}
#endif
setPanel(&_panel_instance);
}
@@ -123,6 +131,10 @@ static void rak14014_tpIntHandle(void)
#elif defined(ST7789_CS)
#include <LovyanGFX.hpp> // Graphics and font library for ST7735 driver chip
#if defined(ST7789_BACKLIGHT_EN) && !defined(TFT_BL)
#define TFT_BL ST7789_BACKLIGHT_EN
#endif
class LGFX : public lgfx::LGFX_Device
{
lgfx::Panel_ST7789 _panel_instance;
@@ -192,7 +204,6 @@ class LGFX : public lgfx::LGFX_Device
_panel_instance.config(cfg);
}
#ifdef ST7789_BL
// Set the backlight control. (delete if not necessary)
{
auto cfg = _light_instance.config(); // Gets a structure for backlight settings.
@@ -204,7 +215,6 @@ class LGFX : public lgfx::LGFX_Device
_light_instance.config(cfg);
_panel_instance.setLight(&_light_instance); // Set the backlight on the panel.
}
#endif
#if HAS_TOUCHSCREEN
// Configure settings for touch screen control.
@@ -314,7 +324,6 @@ class LGFX : public lgfx::LGFX_Device
_panel_instance.config(cfg);
}
#ifdef TFT_BL
// Set the backlight control
{
auto cfg = _light_instance.config(); // Gets a structure for backlight settings.
@@ -327,7 +336,6 @@ class LGFX : public lgfx::LGFX_Device
_light_instance.config(cfg);
_panel_instance.setLight(&_light_instance); // Set the backlight on the panel.
}
#endif
setPanel(&_panel_instance);
}
@@ -513,26 +521,9 @@ static LGFX *tft = nullptr;
extern unPhone unphone;
#endif
GpioPin *TFTDisplay::backlightEnable = NULL;
TFTDisplay::TFTDisplay(uint8_t address, int sda, int scl, OLEDDISPLAY_GEOMETRY geometry, HW_I2C i2cBus)
{
LOG_DEBUG("TFTDisplay!\n");
#ifdef TFT_BL
GpioPin *p = new GpioHwPin(TFT_BL);
if (!TFT_BACKLIGHT_ON) { // Need to invert the pin before hardware
auto virtPin = new GpioVirtPin();
new GpioNotTransformer(
virtPin, p); // We just leave this created object on the heap so it can stay watching virtPin and driving en_gpio
p = virtPin;
}
#else
GpioPin *p = new GpioVirtPin(); // Just simulate a pin
#endif
backlightEnable = p;
#if ARCH_PORTDUINO
if (settingsMap[displayRotate]) {
setGeometry(GEOMETRY_RAWMODE, settingsMap[configNames::displayHeight], settingsMap[configNames::displayWidth]);
@@ -586,15 +577,24 @@ void TFTDisplay::sendCommand(uint8_t com)
// handle display on/off directly
switch (com) {
case DISPLAYON: {
// LOG_DEBUG("Display on\n");
backlightEnable->set(true);
#if ARCH_PORTDUINO
display(true);
if (settingsMap[displayBacklight] > 0)
digitalWrite(settingsMap[displayBacklight], TFT_BACKLIGHT_ON);
#elif defined(ST7735_BL_V03)
digitalWrite(ST7735_BL_V03, TFT_BACKLIGHT_ON);
#elif defined(ST7735_BL_V05)
pinMode(ST7735_BL_V05, OUTPUT);
digitalWrite(ST7735_BL_V05, TFT_BACKLIGHT_ON);
#elif !defined(RAK14014) && !defined(M5STACK) && !defined(UNPHONE)
tft->wakeup();
tft->powerSaveOff();
#elif defined(TFT_BL) && defined(TFT_BACKLIGHT_ON)
digitalWrite(TFT_BL, TFT_BACKLIGHT_ON);
#endif
#ifdef VTFT_CTRL_V03
digitalWrite(VTFT_CTRL_V03, LOW);
#endif
#ifdef VTFT_CTRL
@@ -610,17 +610,25 @@ void TFTDisplay::sendCommand(uint8_t com)
break;
}
case DISPLAYOFF: {
// LOG_DEBUG("Display off\n");
backlightEnable->set(false);
#if ARCH_PORTDUINO
tft->clear();
if (settingsMap[displayBacklight] > 0)
digitalWrite(settingsMap[displayBacklight], !TFT_BACKLIGHT_ON);
#elif defined(ST7735_BL_V03)
digitalWrite(ST7735_BL_V03, !TFT_BACKLIGHT_ON);
#elif defined(ST7735_BL_V05)
pinMode(ST7735_BL_V05, OUTPUT);
digitalWrite(ST7735_BL_V05, !TFT_BACKLIGHT_ON);
#elif !defined(RAK14014) && !defined(M5STACK) && !defined(UNPHONE)
tft->sleep();
tft->powerSaveOn();
#elif defined(TFT_BL) && defined(TFT_BACKLIGHT_ON)
digitalWrite(TFT_BL, !TFT_BACKLIGHT_ON);
#endif
#ifdef VTFT_CTRL_V03
digitalWrite(VTFT_CTRL_V03, HIGH);
#endif
#ifdef VTFT_CTRL
digitalWrite(VTFT_CTRL, HIGH);
#endif
@@ -704,9 +712,20 @@ bool TFTDisplay::connect()
tft = new LGFX;
#endif
backlightEnable->set(true);
#ifdef TFT_BL
pinMode(TFT_BL, OUTPUT);
digitalWrite(TFT_BL, TFT_BACKLIGHT_ON);
// pinMode(PIN_3V3_EN, OUTPUT);
// digitalWrite(PIN_3V3_EN, HIGH);
LOG_INFO("Power to TFT Backlight\n");
#endif
#ifdef ST7735_BL_V03
digitalWrite(ST7735_BL_V03, TFT_BACKLIGHT_ON);
#elif defined(ST7735_BL_V05)
pinMode(ST7735_BL_V05, OUTPUT);
digitalWrite(ST7735_BL_V05, TFT_BACKLIGHT_ON);
#endif
#ifdef UNPHONE
unphone.backlight(true); // using unPhone library
LOG_INFO("Power to TFT Backlight\n");

View File

@@ -1,6 +1,5 @@
#pragma once
#include <GpioLogic.h>
#include <OLEDDisplay.h>
/**
@@ -40,14 +39,6 @@ class TFTDisplay : public OLEDDisplay
*/
void setDetected(uint8_t detected);
/**
* This is normally managed entirely by TFTDisplay, but some rare applications (heltec tracker) might need to replace the
* default GPIO behavior with something a bit more complex.
*
* We (cruftily) make it static so that variant.cpp can access it without needing a ptr to the TFTDisplay instance.
*/
static GpioPin *backlightEnable;
protected:
// the header size of the buffer used, e.g. for the SPI command header
virtual int getBufferOffset(void) override { return 0; }

View File

@@ -1,440 +0,0 @@
#include "OLEDDisplayFontsPL.h"
// Font generated or edited with the glyphEditor
const uint8_t ArialMT_Plain_10_PL[] PROGMEM = {
0x0A, // Width: 10
0x0D, // Height: 13
0x20, // First char: 32
0xE0, // Number of chars: 224
// Jump Table:
0xFF, 0xFF, 0x00, 0x03, // 32:65535
0x00, 0x00, 0x04, 0x03, // 33
0x00, 0x04, 0x05, 0x04, // 34
0x00, 0x09, 0x09, 0x06, // 35
0x00, 0x12, 0x0A, 0x06, // 36
0x00, 0x1C, 0x10, 0x09, // 37
0x00, 0x2C, 0x0E, 0x08, // 38
0x00, 0x3A, 0x01, 0x02, // 39
0x00, 0x3B, 0x06, 0x04, // 40
0x00, 0x41, 0x06, 0x04, // 41
0x00, 0x47, 0x05, 0x04, // 42
0x00, 0x4C, 0x09, 0x06, // 43
0x00, 0x55, 0x04, 0x03, // 44
0x00, 0x59, 0x03, 0x03, // 45
0x00, 0x5C, 0x04, 0x03, // 46
0x00, 0x60, 0x05, 0x04, // 47
0x00, 0x65, 0x0A, 0x06, // 48
0x00, 0x6F, 0x08, 0x05, // 49
0x00, 0x77, 0x0A, 0x06, // 50
0x00, 0x81, 0x0A, 0x06, // 51
0x00, 0x8B, 0x0B, 0x07, // 52
0x00, 0x96, 0x0A, 0x06, // 53
0x00, 0xA0, 0x0A, 0x06, // 54
0x00, 0xAA, 0x09, 0x06, // 55
0x00, 0xB3, 0x0A, 0x06, // 56
0x00, 0xBD, 0x0A, 0x06, // 57
0x00, 0xC7, 0x04, 0x03, // 58
0x00, 0xCB, 0x04, 0x03, // 59
0x00, 0xCF, 0x0A, 0x06, // 60
0x00, 0xD9, 0x09, 0x06, // 61
0x00, 0xE2, 0x09, 0x06, // 62
0x00, 0xEB, 0x0B, 0x07, // 63
0x00, 0xF6, 0x14, 0x0B, // 64
0x01, 0x0A, 0x0E, 0x08, // 65
0x01, 0x18, 0x0C, 0x07, // 66
0x01, 0x24, 0x0C, 0x07, // 67
0x01, 0x30, 0x0B, 0x07, // 68
0x01, 0x3B, 0x0C, 0x07, // 69
0x01, 0x47, 0x09, 0x06, // 70
0x01, 0x50, 0x0D, 0x08, // 71
0x01, 0x5D, 0x0C, 0x07, // 72
0x01, 0x69, 0x04, 0x03, // 73
0x01, 0x6D, 0x08, 0x05, // 74
0x01, 0x75, 0x0E, 0x08, // 75
0x01, 0x83, 0x0C, 0x07, // 76
0x01, 0x8F, 0x10, 0x09, // 77
0x01, 0x9F, 0x0C, 0x07, // 78
0x01, 0xAB, 0x0E, 0x08, // 79
0x01, 0xB9, 0x0B, 0x07, // 80
0x01, 0xC4, 0x0E, 0x08, // 81
0x01, 0xD2, 0x0C, 0x07, // 82
0x01, 0xDE, 0x0C, 0x07, // 83
0x01, 0xEA, 0x0B, 0x07, // 84
0x01, 0xF5, 0x0C, 0x07, // 85
0x02, 0x01, 0x0D, 0x08, // 86
0x02, 0x0E, 0x11, 0x0A, // 87
0x02, 0x1F, 0x0E, 0x08, // 88
0x02, 0x2D, 0x0D, 0x08, // 89
0x02, 0x3A, 0x0C, 0x07, // 90
0x02, 0x46, 0x06, 0x04, // 91
0x02, 0x4C, 0x06, 0x04, // 92
0x02, 0x52, 0x04, 0x03, // 93
0x02, 0x56, 0x09, 0x06, // 94
0x02, 0x5F, 0x0C, 0x07, // 95
0x02, 0x6B, 0x03, 0x03, // 96
0x02, 0x6E, 0x0A, 0x06, // 97
0x02, 0x78, 0x0A, 0x06, // 98
0x02, 0x82, 0x0A, 0x06, // 99
0x02, 0x8C, 0x0A, 0x06, // 100
0x02, 0x96, 0x0A, 0x06, // 101
0x02, 0xA0, 0x05, 0x04, // 102
0x02, 0xA5, 0x0A, 0x06, // 103
0x02, 0xAF, 0x0A, 0x06, // 104
0x02, 0xB9, 0x04, 0x03, // 105
0x02, 0xBD, 0x04, 0x03, // 106
0x02, 0xC1, 0x08, 0x05, // 107
0x02, 0xC9, 0x04, 0x03, // 108
0x02, 0xCD, 0x10, 0x09, // 109
0x02, 0xDD, 0x0A, 0x06, // 110
0x02, 0xE7, 0x0A, 0x06, // 111
0x02, 0xF1, 0x0A, 0x06, // 112
0x02, 0xFB, 0x0A, 0x06, // 113
0x03, 0x05, 0x05, 0x04, // 114
0x03, 0x0A, 0x08, 0x05, // 115
0x03, 0x12, 0x06, 0x04, // 116
0x03, 0x18, 0x0A, 0x06, // 117
0x03, 0x22, 0x09, 0x06, // 118
0x03, 0x2B, 0x0E, 0x08, // 119
0x03, 0x39, 0x0A, 0x06, // 120
0x03, 0x43, 0x09, 0x06, // 121
0x03, 0x4C, 0x0A, 0x06, // 122
0x03, 0x56, 0x06, 0x04, // 123
0x03, 0x5C, 0x04, 0x03, // 124
0x03, 0x60, 0x05, 0x04, // 125
0x03, 0x65, 0x09, 0x06, // 126
0xFF, 0xFF, 0x00, 0x0A, // 127
0xFF, 0xFF, 0x00, 0x0A, // 128
0x03, 0x6E, 0x0C, 0x07, // 129
0x03, 0x7A, 0x05, 0x04, // 130
0x03, 0x7F, 0x0C, 0x07, // 131
0x03, 0x8B, 0x0E, 0x08, // 132
0x03, 0x99, 0x0C, 0x07, // 133
0x03, 0xA5, 0x0C, 0x07, // 134
0x03, 0xB1, 0x0A, 0x06, // 135
0x03, 0xBB, 0x0A, 0x06, // 136
0x03, 0xC5, 0x0A, 0x06, // 137
0xFF, 0xFF, 0x00, 0x0A, // 138
0xFF, 0xFF, 0x00, 0x0A, // 139
0xFF, 0xFF, 0x00, 0x0A, // 140
0xFF, 0xFF, 0x00, 0x0A, // 141
0xFF, 0xFF, 0x00, 0x0A, // 142
0xFF, 0xFF, 0x00, 0x0A, // 143
0xFF, 0xFF, 0x00, 0x0A, // 144
0xFF, 0xFF, 0x00, 0x0A, // 145
0xFF, 0xFF, 0x00, 0x0A, // 146
0x03, 0xCF, 0x0E, 0x08, // 147
0x03, 0xDD, 0x0A, 0x06, // 148
0xFF, 0xFF, 0x00, 0x0A, // 149
0xFF, 0xFF, 0x00, 0x0A, // 150
0xFF, 0xFF, 0x00, 0x0A, // 151
0x03, 0xE7, 0x0C, 0x07, // 152
0x03, 0xF3, 0x0C, 0x07, // 153
0x03, 0xFF, 0x0C, 0x07, // 154
0x04, 0x0B, 0x08, 0x05, // 155
0xFF, 0xFF, 0x00, 0x0A, // 156
0xFF, 0xFF, 0x00, 0x0A, // 157
0xFF, 0xFF, 0x00, 0x0A, // 158
0xFF, 0xFF, 0x00, 0x0A, // 159
0xFF, 0xFF, 0x00, 0x0A, // 160
0x04, 0x13, 0x04, 0x03, // 161
0x04, 0x17, 0x0A, 0x06, // 162
0x04, 0x21, 0x0C, 0x07, // 163
0x04, 0x2D, 0x0A, 0x06, // 164
0x04, 0x37, 0x0A, 0x06, // 165
0x04, 0x41, 0x04, 0x03, // 166
0x04, 0x45, 0x0A, 0x06, // 167
0x04, 0x4F, 0x05, 0x04, // 168
0x04, 0x54, 0x0D, 0x08, // 169
0x04, 0x61, 0x07, 0x05, // 170
0x04, 0x68, 0x0A, 0x06, // 171
0x04, 0x72, 0x09, 0x06, // 172
0x04, 0x7B, 0x03, 0x03, // 173
0x04, 0x7E, 0x0D, 0x08, // 174
0x04, 0x8B, 0x0B, 0x07, // 175
0x04, 0x96, 0x07, 0x05, // 176
0x04, 0x9D, 0x0A, 0x06, // 177
0x04, 0xA7, 0x05, 0x04, // 178
0x04, 0xAC, 0x05, 0x04, // 179
0x04, 0xB1, 0x05, 0x04, // 180
0x04, 0xB6, 0x0A, 0x06, // 181
0x04, 0xC0, 0x09, 0x06, // 182
0x04, 0xC9, 0x03, 0x03, // 183
0x04, 0xCC, 0x06, 0x04, // 184
0x04, 0xD2, 0x0C, 0x07, // 185
0x04, 0xDE, 0x07, 0x05, // 186
0x04, 0xE5, 0x0C, 0x07, // 187
0x04, 0xF1, 0x0A, 0x06, // 188
0x04, 0xFB, 0x10, 0x09, // 189
0x05, 0x0B, 0x10, 0x09, // 190
0x05, 0x1B, 0x0A, 0x06, // 191
0x05, 0x25, 0x0E, 0x08, // 192
0x05, 0x33, 0x0E, 0x08, // 193
0x05, 0x41, 0x0E, 0x08, // 194
0x05, 0x4F, 0x0E, 0x08, // 195
0x05, 0x5D, 0x0E, 0x08, // 196
0x05, 0x6B, 0x0E, 0x08, // 197
0x05, 0x79, 0x12, 0x0A, // 198
0x05, 0x8B, 0x0C, 0x07, // 199
0x05, 0x97, 0x0C, 0x07, // 200
0x05, 0xA3, 0x0C, 0x07, // 201
0x05, 0xAF, 0x0C, 0x07, // 202
0x05, 0xBB, 0x0C, 0x07, // 203
0x05, 0xC7, 0x05, 0x04, // 204
0x05, 0xCC, 0x04, 0x03, // 205
0x05, 0xD0, 0x04, 0x03, // 206
0x05, 0xD4, 0x05, 0x04, // 207
0x05, 0xD9, 0x0B, 0x07, // 208
0x05, 0xE4, 0x0C, 0x07, // 209
0x05, 0xF0, 0x0E, 0x08, // 210
0x05, 0xFE, 0x0E, 0x08, // 211
0x06, 0x0C, 0x0E, 0x08, // 212
0x06, 0x1A, 0x0E, 0x08, // 213
0x06, 0x28, 0x0E, 0x08, // 214
0x06, 0x36, 0x0A, 0x06, // 215
0x06, 0x40, 0x0D, 0x08, // 216
0x06, 0x4D, 0x0C, 0x07, // 217
0x06, 0x59, 0x0C, 0x07, // 218
0x06, 0x65, 0x0C, 0x07, // 219
0x06, 0x71, 0x0C, 0x07, // 220
0x06, 0x7D, 0x0D, 0x08, // 221
0x06, 0x8A, 0x0B, 0x07, // 222
0x06, 0x95, 0x0C, 0x07, // 223
0x06, 0xA1, 0x0A, 0x06, // 224
0x06, 0xAB, 0x0A, 0x06, // 225
0x06, 0xB5, 0x0A, 0x06, // 226
0x06, 0xBF, 0x0A, 0x06, // 227
0x06, 0xC9, 0x0A, 0x06, // 228
0x06, 0xD3, 0x0A, 0x06, // 229
0x06, 0xDD, 0x10, 0x09, // 230
0x06, 0xED, 0x0A, 0x06, // 231
0x06, 0xF7, 0x0A, 0x06, // 232
0x07, 0x01, 0x0A, 0x06, // 233
0x07, 0x0B, 0x0A, 0x06, // 234
0x07, 0x15, 0x0A, 0x06, // 235
0x07, 0x1F, 0x05, 0x04, // 236
0x07, 0x24, 0x04, 0x03, // 237
0x07, 0x28, 0x05, 0x04, // 238
0x07, 0x2D, 0x05, 0x04, // 239
0x07, 0x32, 0x0A, 0x06, // 240
0x07, 0x3C, 0x0A, 0x06, // 241
0x07, 0x46, 0x0A, 0x06, // 242
0x07, 0x50, 0x0A, 0x06, // 243
0x07, 0x5A, 0x0A, 0x06, // 244
0x07, 0x64, 0x0A, 0x06, // 245
0x07, 0x6E, 0x0A, 0x06, // 246
0x07, 0x78, 0x09, 0x06, // 247
0x07, 0x81, 0x0A, 0x06, // 248
0x07, 0x8B, 0x0A, 0x06, // 249
0x07, 0x95, 0x0A, 0x06, // 250
0x07, 0x9F, 0x0A, 0x06, // 251
0x07, 0xA9, 0x0A, 0x06, // 252
0x07, 0xB3, 0x09, 0x06, // 253
0x07, 0xBC, 0x0A, 0x06, // 254
0x07, 0xC6, 0x09, 0x06, // 255
// Font Data:
0x00, 0x00, 0xF8, 0x02, // 33
0x38, 0x00, 0x00, 0x00, 0x38, // 34
0xA0, 0x03, 0xE0, 0x00, 0xB8, 0x03, 0xE0, 0x00, 0xB8, // 35
0x30, 0x01, 0x28, 0x02, 0xF8, 0x07, 0x48, 0x02, 0x90, 0x01, // 36
0x00, 0x00, 0x30, 0x00, 0x48, 0x00, 0x30, 0x03, 0xC0, 0x00, 0xB0, 0x01, 0x48, 0x02, 0x80, 0x01, // 37
0x80, 0x01, 0x50, 0x02, 0x68, 0x02, 0xA8, 0x02, 0x18, 0x01, 0x80, 0x03, 0x80, 0x02, // 38
0x38, // 39
0xE0, 0x03, 0x10, 0x04, 0x08, 0x08, // 40
0x08, 0x08, 0x10, 0x04, 0xE0, 0x03, // 41
0x28, 0x00, 0x18, 0x00, 0x28, // 42
0x40, 0x00, 0x40, 0x00, 0xF0, 0x01, 0x40, 0x00, 0x40, // 43
0x00, 0x00, 0x00, 0x06, // 44
0x80, 0x00, 0x80, // 45
0x00, 0x00, 0x00, 0x02, // 46
0x00, 0x03, 0xE0, 0x00, 0x18, // 47
0xF0, 0x01, 0x08, 0x02, 0x08, 0x02, 0x08, 0x02, 0xF0, 0x01, // 48
0x00, 0x00, 0x20, 0x00, 0x10, 0x00, 0xF8, 0x03, // 49
0x10, 0x02, 0x08, 0x03, 0x88, 0x02, 0x48, 0x02, 0x30, 0x02, // 50
0x10, 0x01, 0x08, 0x02, 0x48, 0x02, 0x48, 0x02, 0xB0, 0x01, // 51
0xC0, 0x00, 0xA0, 0x00, 0x90, 0x00, 0x88, 0x00, 0xF8, 0x03, 0x80, // 52
0x60, 0x01, 0x38, 0x02, 0x28, 0x02, 0x28, 0x02, 0xC8, 0x01, // 53
0xF0, 0x01, 0x28, 0x02, 0x28, 0x02, 0x28, 0x02, 0xD0, 0x01, // 54
0x08, 0x00, 0x08, 0x03, 0xC8, 0x00, 0x38, 0x00, 0x08, // 55
0xB0, 0x01, 0x48, 0x02, 0x48, 0x02, 0x48, 0x02, 0xB0, 0x01, // 56
0x70, 0x01, 0x88, 0x02, 0x88, 0x02, 0x88, 0x02, 0xF0, 0x01, // 57
0x00, 0x00, 0x20, 0x02, // 58
0x00, 0x00, 0x20, 0x06, // 59
0x00, 0x00, 0x40, 0x00, 0xA0, 0x00, 0xA0, 0x00, 0x10, 0x01, // 60
0xA0, 0x00, 0xA0, 0x00, 0xA0, 0x00, 0xA0, 0x00, 0xA0, // 61
0x00, 0x00, 0x10, 0x01, 0xA0, 0x00, 0xA0, 0x00, 0x40, // 62
0x10, 0x00, 0x08, 0x00, 0x08, 0x00, 0xC8, 0x02, 0x48, 0x00, 0x30, // 63
0x00, 0x00, 0xC0, 0x03, 0x30, 0x04, 0xD0, 0x09, 0x28, 0x0A, 0x28, 0x0A, 0xC8, 0x0B, 0x68, 0x0A, 0x10, 0x05, 0xE0, 0x04, // 64
0x00, 0x02, 0xC0, 0x01, 0xB0, 0x00, 0x88, 0x00, 0xB0, 0x00, 0xC0, 0x01, 0x00, 0x02, // 65
0x00, 0x00, 0xF8, 0x03, 0x48, 0x02, 0x48, 0x02, 0x48, 0x02, 0xF0, 0x01, // 66
0x00, 0x00, 0xF0, 0x01, 0x08, 0x02, 0x08, 0x02, 0x08, 0x02, 0x10, 0x01, // 67
0x00, 0x00, 0xF8, 0x03, 0x08, 0x02, 0x08, 0x02, 0x10, 0x01, 0xE0, // 68
0x00, 0x00, 0xF8, 0x03, 0x48, 0x02, 0x48, 0x02, 0x48, 0x02, 0x48, 0x02, // 69
0x00, 0x00, 0xF8, 0x03, 0x48, 0x00, 0x48, 0x00, 0x08, // 70
0x00, 0x00, 0xE0, 0x00, 0x10, 0x01, 0x08, 0x02, 0x48, 0x02, 0x50, 0x01, 0xC0, // 71
0x00, 0x00, 0xF8, 0x03, 0x40, 0x00, 0x40, 0x00, 0x40, 0x00, 0xF8, 0x03, // 72
0x00, 0x00, 0xF8, 0x03, // 73
0x00, 0x03, 0x00, 0x02, 0x00, 0x02, 0xF8, 0x01, // 74
0x00, 0x00, 0xF8, 0x03, 0x80, 0x00, 0x60, 0x00, 0x90, 0x00, 0x08, 0x01, 0x00, 0x02, // 75
0x00, 0x00, 0xF8, 0x03, 0x00, 0x02, 0x00, 0x02, 0x00, 0x02, 0x00, 0x02, // 76
0x00, 0x00, 0xF8, 0x03, 0x30, 0x00, 0xC0, 0x01, 0x00, 0x02, 0xC0, 0x01, 0x30, 0x00, 0xF8, 0x03, // 77
0x00, 0x00, 0xF8, 0x03, 0x30, 0x00, 0x40, 0x00, 0x80, 0x01, 0xF8, 0x03, // 78
0x00, 0x00, 0xF0, 0x01, 0x08, 0x02, 0x08, 0x02, 0x08, 0x02, 0x08, 0x02, 0xF0, 0x01, // 79
0x00, 0x00, 0xF8, 0x03, 0x48, 0x00, 0x48, 0x00, 0x48, 0x00, 0x30, // 80
0x00, 0x00, 0xF0, 0x01, 0x08, 0x02, 0x08, 0x02, 0x08, 0x03, 0x08, 0x03, 0xF0, 0x02, // 81
0x00, 0x00, 0xF8, 0x03, 0x48, 0x00, 0x48, 0x00, 0xC8, 0x00, 0x30, 0x03, // 82
0x00, 0x00, 0x30, 0x01, 0x48, 0x02, 0x48, 0x02, 0x48, 0x02, 0x90, 0x01, // 83
0x00, 0x00, 0x08, 0x00, 0x08, 0x00, 0xF8, 0x03, 0x08, 0x00, 0x08, // 84
0x00, 0x00, 0xF8, 0x01, 0x00, 0x02, 0x00, 0x02, 0x00, 0x02, 0xF8, 0x01, // 85
0x08, 0x00, 0x70, 0x00, 0x80, 0x01, 0x00, 0x02, 0x80, 0x01, 0x70, 0x00, 0x08, // 86
0x18, 0x00, 0xE0, 0x01, 0x00, 0x02, 0xF0, 0x01, 0x08, 0x00, 0xF0, 0x01, 0x00, 0x02, 0xE0, 0x01, 0x18, // 87
0x00, 0x02, 0x08, 0x01, 0x90, 0x00, 0x60, 0x00, 0x90, 0x00, 0x08, 0x01, 0x00, 0x02, // 88
0x08, 0x00, 0x10, 0x00, 0x20, 0x00, 0xC0, 0x03, 0x20, 0x00, 0x10, 0x00, 0x08, // 89
0x08, 0x03, 0x88, 0x02, 0xC8, 0x02, 0x68, 0x02, 0x38, 0x02, 0x18, 0x02, // 90
0x00, 0x00, 0xF8, 0x0F, 0x08, 0x08, // 91
0x18, 0x00, 0xE0, 0x00, 0x00, 0x03, // 92
0x08, 0x08, 0xF8, 0x0F, // 93
0x40, 0x00, 0x30, 0x00, 0x08, 0x00, 0x30, 0x00, 0x40, // 94
0x00, 0x08, 0x00, 0x08, 0x00, 0x08, 0x00, 0x08, 0x00, 0x08, 0x00, 0x08, // 95
0x08, 0x00, 0x10, // 96
0x00, 0x00, 0x00, 0x03, 0xA0, 0x02, 0xA0, 0x02, 0xE0, 0x03, // 97
0x00, 0x00, 0xF8, 0x03, 0x20, 0x02, 0x20, 0x02, 0xC0, 0x01, // 98
0x00, 0x00, 0xC0, 0x01, 0x20, 0x02, 0x20, 0x02, 0x40, 0x01, // 99
0x00, 0x00, 0xC0, 0x01, 0x20, 0x02, 0x20, 0x02, 0xF8, 0x03, // 100
0x00, 0x00, 0xC0, 0x01, 0xA0, 0x02, 0xA0, 0x02, 0xC0, 0x02, // 101
0x20, 0x00, 0xF0, 0x03, 0x28, // 102
0x00, 0x00, 0xC0, 0x05, 0x20, 0x0A, 0x20, 0x0A, 0xE0, 0x07, // 103
0x00, 0x00, 0xF8, 0x03, 0x20, 0x00, 0x20, 0x00, 0xC0, 0x03, // 104
0x00, 0x00, 0xE8, 0x03, // 105
0x00, 0x08, 0xE8, 0x07, // 106
0xF8, 0x03, 0x80, 0x00, 0xC0, 0x01, 0x20, 0x02, // 107
0x00, 0x00, 0xF8, 0x03, // 108
0x00, 0x00, 0xE0, 0x03, 0x20, 0x00, 0x20, 0x00, 0xE0, 0x03, 0x20, 0x00, 0x20, 0x00, 0xC0, 0x03, // 109
0x00, 0x00, 0xE0, 0x03, 0x20, 0x00, 0x20, 0x00, 0xC0, 0x03, // 110
0x00, 0x00, 0xC0, 0x01, 0x20, 0x02, 0x20, 0x02, 0xC0, 0x01, // 111
0x00, 0x00, 0xE0, 0x0F, 0x20, 0x02, 0x20, 0x02, 0xC0, 0x01, // 112
0x00, 0x00, 0xC0, 0x01, 0x20, 0x02, 0x20, 0x02, 0xE0, 0x0F, // 113
0x00, 0x00, 0xE0, 0x03, 0x20, // 114
0x40, 0x02, 0xA0, 0x02, 0xA0, 0x02, 0x20, 0x01, // 115
0x20, 0x00, 0xF8, 0x03, 0x20, 0x02, // 116
0x00, 0x00, 0xE0, 0x01, 0x00, 0x02, 0x00, 0x02, 0xE0, 0x03, // 117
0x20, 0x00, 0xC0, 0x01, 0x00, 0x02, 0xC0, 0x01, 0x20, // 118
0xE0, 0x01, 0x00, 0x02, 0xC0, 0x01, 0x20, 0x00, 0xC0, 0x01, 0x00, 0x02, 0xE0, 0x01, // 119
0x20, 0x02, 0x40, 0x01, 0x80, 0x00, 0x40, 0x01, 0x20, 0x02, // 120
0x20, 0x00, 0xC0, 0x09, 0x00, 0x06, 0xC0, 0x01, 0x20, // 121
0x20, 0x02, 0x20, 0x03, 0xA0, 0x02, 0x60, 0x02, 0x20, 0x02, // 122
0x80, 0x00, 0x78, 0x0F, 0x08, 0x08, // 123
0x00, 0x00, 0xF8, 0x0F, // 124
0x08, 0x08, 0x78, 0x0F, 0x80, // 125
0xC0, 0x00, 0x40, 0x00, 0xC0, 0x00, 0x80, 0x00, 0xC0, // 126
0x00, 0x00, 0xF8, 0x03, 0x40, 0x02, 0x20, 0x02, 0x00, 0x02, 0x00, 0x02, // 129
0x40, 0x00, 0xF8, 0x03, 0x20, // 130
0x00, 0x00, 0xF8, 0x03, 0x30, 0x00, 0x44, 0x00, 0x82, 0x01, 0xF8, 0x03, // 131
0x00, 0x02, 0xC0, 0x01, 0xB0, 0x00, 0x88, 0x00, 0xB0, 0x00, 0xC0, 0x05, 0x00, 0x0A, // 132
0x00, 0x00, 0x00, 0x03, 0xA0, 0x02, 0xA0, 0x02, 0xE0, 0x07, 0x00, 0x08, // 133
0x00, 0x00, 0xF0, 0x01, 0x08, 0x02, 0x0A, 0x02, 0x09, 0x02, 0x10, 0x01, // 134
0x00, 0x00, 0xC0, 0x01, 0x20, 0x02, 0x28, 0x02, 0x44, 0x01, // 135
0x00, 0x00, 0xE0, 0x03, 0x20, 0x00, 0x28, 0x00, 0xC4, 0x03, // 136
0x20, 0x02, 0x20, 0x03, 0xA8, 0x02, 0x64, 0x02, 0x20, 0x02, // 137
0x00, 0x00, 0xF0, 0x01, 0x08, 0x02, 0x08, 0x02, 0x0A, 0x02, 0x09, 0x02, 0xF0, 0x01, // 147
0x00, 0x00, 0xC0, 0x01, 0x20, 0x02, 0x28, 0x02, 0xC4, 0x01, // 148
0x00, 0x00, 0xF8, 0x03, 0x48, 0x02, 0x48, 0x02, 0x48, 0x06, 0x48, 0x0A, // 152
0x00, 0x00, 0xC0, 0x01, 0xA0, 0x02, 0xA0, 0x02, 0xC0, 0x06, 0x00, 0x08, // 153
0x00, 0x00, 0x30, 0x01, 0x48, 0x02, 0x4A, 0x02, 0x49, 0x02, 0x90, 0x01, // 154
0x40, 0x02, 0xA0, 0x02, 0xA8, 0x02, 0x24, 0x01, // 155
0x00, 0x00, 0xA0, 0x0F, // 161
0x00, 0x00, 0xC0, 0x01, 0xA0, 0x0F, 0x78, 0x02, 0x40, 0x01, // 162
0x40, 0x02, 0x70, 0x03, 0xC8, 0x02, 0x48, 0x02, 0x08, 0x02, 0x10, 0x02, // 163
0x00, 0x00, 0xE0, 0x01, 0x20, 0x01, 0x20, 0x01, 0xE0, 0x01, // 164
0x48, 0x01, 0x70, 0x01, 0xC0, 0x03, 0x70, 0x01, 0x48, 0x01, // 165
0x00, 0x00, 0x38, 0x0F, // 166
0xD0, 0x04, 0x28, 0x09, 0x48, 0x09, 0x48, 0x0A, 0x90, 0x05, // 167
0x08, 0x00, 0x00, 0x00, 0x08, // 168
0xE0, 0x00, 0x10, 0x01, 0x48, 0x02, 0xA8, 0x02, 0xA8, 0x02, 0x10, 0x01, 0xE0, // 169
0x68, 0x00, 0x68, 0x00, 0x68, 0x00, 0x78, // 170
0x00, 0x00, 0x80, 0x01, 0x40, 0x02, 0x80, 0x01, 0x40, 0x02, // 171
0x20, 0x00, 0x20, 0x00, 0x20, 0x00, 0x20, 0x00, 0xE0, // 172
0x80, 0x00, 0x80, // 173
0xE0, 0x00, 0x10, 0x01, 0xE8, 0x02, 0x68, 0x02, 0xC8, 0x02, 0x10, 0x01, 0xE0, // 174
0x02, 0x00, 0x02, 0x00, 0x02, 0x00, 0x02, 0x00, 0x02, 0x00, 0x02, // 175
0x00, 0x00, 0x38, 0x00, 0x28, 0x00, 0x38, // 176
0x40, 0x02, 0x40, 0x02, 0xF0, 0x03, 0x40, 0x02, 0x40, 0x02, // 177
0x48, 0x00, 0x68, 0x00, 0x58, // 178
0x48, 0x00, 0x58, 0x00, 0x68, // 179
0x00, 0x00, 0x10, 0x00, 0x08, // 180
0x00, 0x00, 0xE0, 0x0F, 0x00, 0x02, 0x00, 0x02, 0xE0, 0x03, // 181
0x70, 0x00, 0xF8, 0x0F, 0x08, 0x00, 0xF8, 0x0F, 0x08, // 182
0x00, 0x00, 0x40, // 183
0x00, 0x00, 0x00, 0x14, 0x00, 0x18, // 184
0x08, 0x03, 0x88, 0x02, 0xCA, 0x02, 0x69, 0x02, 0x38, 0x02, 0x18, 0x02, // 185
0x30, 0x00, 0x48, 0x00, 0x48, 0x00, 0x30, // 186
0x08, 0x03, 0x88, 0x02, 0xC8, 0x02, 0x6A, 0x02, 0x38, 0x02, 0x18, 0x02, // 187
0x20, 0x02, 0x20, 0x03, 0xA8, 0x02, 0x60, 0x02, 0x20, 0x02, // 188
0x00, 0x00, 0x10, 0x02, 0x78, 0x01, 0x80, 0x00, 0x60, 0x00, 0x50, 0x02, 0x48, 0x03, 0xC0, 0x02, // 189
0x48, 0x00, 0x58, 0x00, 0x68, 0x03, 0x80, 0x00, 0x60, 0x01, 0x90, 0x01, 0xC8, 0x03, 0x00, 0x01, // 190
0x00, 0x00, 0x00, 0x06, 0x00, 0x09, 0xA0, 0x09, 0x00, 0x04, // 191
0x00, 0x02, 0xC0, 0x01, 0xB0, 0x00, 0x89, 0x00, 0xB2, 0x00, 0xC0, 0x01, 0x00, 0x02, // 192
0x00, 0x02, 0xC0, 0x01, 0xB0, 0x00, 0x8A, 0x00, 0xB1, 0x00, 0xC0, 0x01, 0x00, 0x02, // 193
0x00, 0x02, 0xC0, 0x01, 0xB2, 0x00, 0x89, 0x00, 0xB2, 0x00, 0xC0, 0x01, 0x00, 0x02, // 194
0x00, 0x02, 0xC2, 0x01, 0xB1, 0x00, 0x8A, 0x00, 0xB1, 0x00, 0xC0, 0x01, 0x00, 0x02, // 195
0x00, 0x02, 0xC0, 0x01, 0xB2, 0x00, 0x88, 0x00, 0xB2, 0x00, 0xC0, 0x01, 0x00, 0x02, // 196
0x00, 0x02, 0xC0, 0x01, 0xBE, 0x00, 0x8A, 0x00, 0xBE, 0x00, 0xC0, 0x01, 0x00, 0x02, // 197
0x00, 0x03, 0xC0, 0x00, 0xE0, 0x00, 0x98, 0x00, 0x88, 0x00, 0xF8, 0x03, 0x48, 0x02, 0x48, 0x02, 0x48, 0x02, // 198
0x00, 0x00, 0xF0, 0x01, 0x08, 0x02, 0x08, 0x16, 0x08, 0x1A, 0x10, 0x01, // 199
0x00, 0x00, 0xF8, 0x03, 0x49, 0x02, 0x4A, 0x02, 0x48, 0x02, 0x48, 0x02, // 200
0x00, 0x00, 0xF8, 0x03, 0x48, 0x02, 0x4A, 0x02, 0x49, 0x02, 0x48, 0x02, // 201
0x00, 0x00, 0xFA, 0x03, 0x49, 0x02, 0x4A, 0x02, 0x48, 0x02, 0x48, 0x02, // 202
0x00, 0x00, 0xF8, 0x03, 0x4A, 0x02, 0x48, 0x02, 0x4A, 0x02, 0x48, 0x02, // 203
0x00, 0x00, 0xF9, 0x03, 0x02, // 204
0x02, 0x00, 0xF9, 0x03, // 205
0x01, 0x00, 0xFA, 0x03, // 206
0x02, 0x00, 0xF8, 0x03, 0x02, // 207
0x40, 0x00, 0xF8, 0x03, 0x48, 0x02, 0x48, 0x02, 0x10, 0x01, 0xE0, // 208
0x00, 0x00, 0xFA, 0x03, 0x31, 0x00, 0x42, 0x00, 0x81, 0x01, 0xF8, 0x03, // 209
0x00, 0x00, 0xF0, 0x01, 0x08, 0x02, 0x09, 0x02, 0x0A, 0x02, 0x08, 0x02, 0xF0, 0x01, // 210
0x00, 0x00, 0xF0, 0x01, 0x08, 0x02, 0x0A, 0x02, 0x09, 0x02, 0x08, 0x02, 0xF0, 0x01, // 211
0x00, 0x00, 0xF0, 0x01, 0x08, 0x02, 0x0A, 0x02, 0x09, 0x02, 0x0A, 0x02, 0xF0, 0x01, // 212
0x00, 0x00, 0xF0, 0x01, 0x0A, 0x02, 0x09, 0x02, 0x0A, 0x02, 0x09, 0x02, 0xF0, 0x01, // 213
0x00, 0x00, 0xF0, 0x01, 0x0A, 0x02, 0x08, 0x02, 0x0A, 0x02, 0x08, 0x02, 0xF0, 0x01, // 214
0x10, 0x01, 0xA0, 0x00, 0xE0, 0x00, 0xA0, 0x00, 0x10, 0x01, // 215
0x00, 0x00, 0xF0, 0x02, 0x08, 0x03, 0xC8, 0x02, 0x28, 0x02, 0x18, 0x03, 0xE8, // 216
0x00, 0x00, 0xF8, 0x01, 0x01, 0x02, 0x02, 0x02, 0x00, 0x02, 0xF8, 0x01, // 217
0x00, 0x00, 0xF8, 0x01, 0x02, 0x02, 0x01, 0x02, 0x00, 0x02, 0xF8, 0x01, // 218
0x00, 0x00, 0xF8, 0x01, 0x02, 0x02, 0x01, 0x02, 0x02, 0x02, 0xF8, 0x01, // 219
0x00, 0x00, 0xF8, 0x01, 0x02, 0x02, 0x00, 0x02, 0x02, 0x02, 0xF8, 0x01, // 220
0x08, 0x00, 0x10, 0x00, 0x20, 0x00, 0xC2, 0x03, 0x21, 0x00, 0x10, 0x00, 0x08, // 221
0x00, 0x00, 0xF8, 0x03, 0x10, 0x01, 0x10, 0x01, 0x10, 0x01, 0xE0, // 222
0x00, 0x00, 0xF0, 0x03, 0x08, 0x01, 0x48, 0x02, 0xB0, 0x02, 0x80, 0x01, // 223
0x00, 0x00, 0x00, 0x03, 0xA4, 0x02, 0xA8, 0x02, 0xE0, 0x03, // 224
0x00, 0x00, 0x00, 0x03, 0xA8, 0x02, 0xA4, 0x02, 0xE0, 0x03, // 225
0x00, 0x00, 0x00, 0x03, 0xA8, 0x02, 0xA4, 0x02, 0xE8, 0x03, // 226
0x00, 0x00, 0x08, 0x03, 0xA4, 0x02, 0xA8, 0x02, 0xE4, 0x03, // 227
0x00, 0x00, 0x00, 0x03, 0xA8, 0x02, 0xA0, 0x02, 0xE8, 0x03, // 228
0x00, 0x00, 0x00, 0x03, 0xAE, 0x02, 0xAA, 0x02, 0xEE, 0x03, // 229
0x00, 0x00, 0x40, 0x03, 0xA0, 0x02, 0xA0, 0x02, 0xC0, 0x01, 0xA0, 0x02, 0xA0, 0x02, 0xC0, 0x02, // 230
0x00, 0x00, 0xC0, 0x01, 0x20, 0x16, 0x20, 0x1A, 0x40, 0x01, // 231
0x00, 0x00, 0xC0, 0x01, 0xA4, 0x02, 0xA8, 0x02, 0xC0, 0x02, // 232
0x00, 0x00, 0xC0, 0x01, 0xA8, 0x02, 0xA4, 0x02, 0xC0, 0x02, // 233
0x00, 0x00, 0xC0, 0x01, 0xA8, 0x02, 0xA4, 0x02, 0xC8, 0x02, // 234
0x00, 0x00, 0xC0, 0x01, 0xA8, 0x02, 0xA0, 0x02, 0xC8, 0x02, // 235
0x00, 0x00, 0xE4, 0x03, 0x08, // 236
0x08, 0x00, 0xE4, 0x03, // 237
0x08, 0x00, 0xE4, 0x03, 0x08, // 238
0x08, 0x00, 0xE0, 0x03, 0x08, // 239
0x00, 0x00, 0xC0, 0x01, 0x28, 0x02, 0x38, 0x02, 0xE0, 0x01, // 240
0x00, 0x00, 0xE8, 0x03, 0x24, 0x00, 0x28, 0x00, 0xC4, 0x03, // 241
0x00, 0x00, 0xC0, 0x01, 0x24, 0x02, 0x28, 0x02, 0xC0, 0x01, // 242
0x00, 0x00, 0xC0, 0x01, 0x28, 0x02, 0x24, 0x02, 0xC0, 0x01, // 243
0x00, 0x00, 0xC0, 0x01, 0x28, 0x02, 0x24, 0x02, 0xC8, 0x01, // 244
0x00, 0x00, 0xC8, 0x01, 0x24, 0x02, 0x28, 0x02, 0xC4, 0x01, // 245
0x00, 0x00, 0xC0, 0x01, 0x28, 0x02, 0x20, 0x02, 0xC8, 0x01, // 246
0x40, 0x00, 0x40, 0x00, 0x50, 0x01, 0x40, 0x00, 0x40, // 247
0x00, 0x00, 0xC0, 0x02, 0xA0, 0x03, 0x60, 0x02, 0xA0, 0x01, // 248
0x00, 0x00, 0xE0, 0x01, 0x04, 0x02, 0x08, 0x02, 0xE0, 0x03, // 249
0x00, 0x00, 0xE0, 0x01, 0x08, 0x02, 0x04, 0x02, 0xE0, 0x03, // 250
0x00, 0x00, 0xE8, 0x01, 0x04, 0x02, 0x08, 0x02, 0xE0, 0x03, // 251
0x00, 0x00, 0xE0, 0x01, 0x08, 0x02, 0x00, 0x02, 0xE8, 0x03, // 252
0x20, 0x00, 0xC0, 0x09, 0x08, 0x06, 0xC4, 0x01, 0x20, // 253
0x00, 0x00, 0xF8, 0x0F, 0x20, 0x02, 0x20, 0x02, 0xC0, 0x01, // 254
0x20, 0x00, 0xC8, 0x09, 0x00, 0x06, 0xC8, 0x01, 0x20, // 255
};

View File

@@ -1,11 +0,0 @@
#ifndef OLEDDISPLAYFONTSPL_h
#define OLEDDISPLAYFONTSPL_h
#ifdef ARDUINO
#include <Arduino.h>
#elif __MBED__
#define PROGMEM
#endif
extern const uint8_t ArialMT_Plain_10_PL[] PROGMEM;
#endif

View File

@@ -20,8 +20,8 @@ const uint8_t bluetoothConnectedIcon[36] PROGMEM = {0xfe, 0x01, 0xff, 0x03, 0x03
0xfe, 0x31, 0x00, 0x30, 0x30, 0x30, 0x30, 0x30, 0xf0, 0x3f, 0xe0, 0x1f};
#endif
#if (defined(USE_EINK) || defined(ILI9341_DRIVER) || defined(ST7735_CS) || defined(ST7789_CS) || defined(USE_ST7789) || \
defined(HX8357_CS) || ARCH_PORTDUINO) && \
#if (defined(USE_EINK) || defined(ILI9341_DRIVER) || defined(ST7735_CS) || defined(ST7789_CS) || defined(HX8357_CS) || \
ARCH_PORTDUINO) && \
!defined(DISPLAY_FORCE_SMALL_FONTS)
const uint8_t imgQuestionL1[] PROGMEM = {0xff, 0x01, 0x01, 0x32, 0x7b, 0x49, 0x49, 0x6f, 0x26, 0x01, 0x01, 0xff};
const uint8_t imgQuestionL2[] PROGMEM = {0x0f, 0x08, 0x08, 0x08, 0x06, 0x0f, 0x0f, 0x06, 0x08, 0x08, 0x08, 0x0f};

View File

@@ -4,20 +4,6 @@
#define ANYKEY 0xFF
#define MATRIXKEY 0xFE
#define INPUT_BROKER_MSG_BRIGHTNESS_UP 0x11
#define INPUT_BROKER_MSG_BRIGHTNESS_DOWN 0x12
#define INPUT_BROKER_MSG_REBOOT 0x90
#define INPUT_BROKER_MSG_SHUTDOWN 0x9b
#define INPUT_BROKER_MSG_GPS_TOGGLE 0x9e
#define INPUT_BROKER_MSG_MUTE_TOGGLE 0xac
#define INPUT_BROKER_MSG_SEND_PING 0xaf
#define INPUT_BROKER_MSG_LEFT 0xb4
#define INPUT_BROKER_MSG_UP 0xb5
#define INPUT_BROKER_MSG_DOWN 0xb6
#define INPUT_BROKER_MSG_RIGHT 0xb7
#define INPUT_BROKER_MSG_FN_SYMBOL_ON 0xf1
#define INPUT_BROKER_MSG_FN_SYMBOL_OFF 0xf2
typedef struct _InputEvent {
const char *source;
char inputEvent;

View File

@@ -147,11 +147,11 @@ int32_t LinuxInput::runOnce()
case KEY_LEFT: // Left
e.inputEvent = meshtastic_ModuleConfig_CannedMessageConfig_InputEventChar_LEFT;
break;
e.kbchar = INPUT_BROKER_MSG_LEFT;
e.kbchar = 0xb4;
case KEY_RIGHT: // Right
e.inputEvent = meshtastic_ModuleConfig_CannedMessageConfig_InputEventChar_RIGHT;
break;
e.kbchar = INPUT_BROKER_MSG_RIGHT;
e.kbchar = 0xb7;
case KEY_ENTER: // Enter
e.inputEvent = meshtastic_ModuleConfig_CannedMessageConfig_InputEventChar_SELECT;
break;

View File

@@ -87,7 +87,7 @@ int32_t SerialKeyboard::runOnce()
e.inputEvent = meshtastic_ModuleConfig_CannedMessageConfig_InputEventChar_UP;
} else if (!(shiftRegister2 & (1 << 2))) {
e.inputEvent = meshtastic_ModuleConfig_CannedMessageConfig_InputEventChar_RIGHT;
e.kbchar = INPUT_BROKER_MSG_RIGHT;
e.kbchar = 0xb7;
} else if (!(shiftRegister2 & (1 << 1))) {
e.inputEvent = meshtastic_ModuleConfig_CannedMessageConfig_InputEventChar_SELECT;
} else if (!(shiftRegister2 & (1 << 0))) {

View File

@@ -94,7 +94,7 @@ int32_t KbI2cBase::runOnce()
case 'e': // sym e
if (is_sym) {
e.inputEvent = meshtastic_ModuleConfig_CannedMessageConfig_InputEventChar_UP;
e.kbchar = INPUT_BROKER_MSG_UP;
e.kbchar = 0xb5;
is_sym = false; // reset sym state after second keypress
} else {
e.inputEvent = ANYKEY;
@@ -104,7 +104,7 @@ int32_t KbI2cBase::runOnce()
case 'x': // sym x
if (is_sym) {
e.inputEvent = meshtastic_ModuleConfig_CannedMessageConfig_InputEventChar_DOWN;
e.kbchar = INPUT_BROKER_MSG_DOWN;
e.kbchar = 0xb6;
is_sym = false; // reset sym state after second keypress
} else {
e.inputEvent = ANYKEY;
@@ -134,8 +134,8 @@ int32_t KbI2cBase::runOnce()
case 0x13: // Code scanner says the SYM key is 0x13
is_sym = !is_sym;
e.inputEvent = ANYKEY;
e.kbchar = is_sym ? INPUT_BROKER_MSG_FN_SYMBOL_ON // send 0xf1 to tell CannedMessages to display that
: INPUT_BROKER_MSG_FN_SYMBOL_OFF; // the modifier key is active
e.kbchar =
is_sym ? 0xf1 : 0xf2; // send 0xf1 to tell CannedMessages to display that the modifier key is active
break;
case 0x0a: // apparently Enter on Q10 is a line feed instead of carriage return
e.inputEvent = meshtastic_ModuleConfig_CannedMessageConfig_InputEventChar_SELECT;
@@ -214,7 +214,7 @@ int32_t KbI2cBase::runOnce()
if (is_sym) {
is_sym = false;
e.inputEvent = ANYKEY;
e.kbchar = INPUT_BROKER_MSG_MUTE_TOGGLE; // mute notifications
e.kbchar = 0xac; // mute notifications
} else {
e.inputEvent = ANYKEY;
e.kbchar = c;
@@ -224,7 +224,7 @@ int32_t KbI2cBase::runOnce()
if (is_sym) {
is_sym = false;
e.inputEvent = ANYKEY;
e.kbchar = INPUT_BROKER_MSG_BRIGHTNESS_UP; // Increase Brightness code
e.kbchar = 0x11; // Increase Brightness code
} else {
e.inputEvent = ANYKEY;
e.kbchar = c;
@@ -234,7 +234,7 @@ int32_t KbI2cBase::runOnce()
if (is_sym) {
is_sym = false;
e.inputEvent = ANYKEY;
e.kbchar = INPUT_BROKER_MSG_BRIGHTNESS_DOWN; // Decrease Brightness code
e.kbchar = 0x12; // Decrease Brightness code
} else {
e.inputEvent = ANYKEY;
e.kbchar = c;
@@ -244,7 +244,7 @@ int32_t KbI2cBase::runOnce()
if (is_sym) {
is_sym = false;
e.inputEvent = ANYKEY;
e.kbchar = INPUT_BROKER_MSG_SEND_PING; // (fn + space)
e.kbchar = 0xaf; // (fn + space)
} else {
e.inputEvent = ANYKEY;
e.kbchar = c;
@@ -254,7 +254,7 @@ int32_t KbI2cBase::runOnce()
if (is_sym) {
is_sym = false;
e.inputEvent = ANYKEY;
e.kbchar = INPUT_BROKER_MSG_GPS_TOGGLE;
e.kbchar = 0x9e;
} else {
e.inputEvent = ANYKEY;
e.kbchar = c;
@@ -269,33 +269,32 @@ int32_t KbI2cBase::runOnce()
break;
case 0xb5: // Up
e.inputEvent = meshtastic_ModuleConfig_CannedMessageConfig_InputEventChar_UP;
e.kbchar = INPUT_BROKER_MSG_UP;
e.kbchar = 0xb5;
break;
case 0xb6: // Down
e.inputEvent = meshtastic_ModuleConfig_CannedMessageConfig_InputEventChar_DOWN;
e.kbchar = INPUT_BROKER_MSG_DOWN;
e.kbchar = 0xb6;
break;
case 0xb4: // Left
e.inputEvent = meshtastic_ModuleConfig_CannedMessageConfig_InputEventChar_LEFT;
e.kbchar = INPUT_BROKER_MSG_LEFT;
e.kbchar = 0xb4;
break;
case 0xb7: // Right
e.inputEvent = meshtastic_ModuleConfig_CannedMessageConfig_InputEventChar_RIGHT;
e.kbchar = INPUT_BROKER_MSG_RIGHT;
e.kbchar = 0xb7;
break;
case 0xc: // Modifier key: 0xc is alt+c (Other options could be: 0xea = shift+mic button or 0x4 shift+$(speaker))
// toggle moddifiers button.
is_sym = !is_sym;
e.inputEvent = ANYKEY;
e.kbchar = is_sym ? INPUT_BROKER_MSG_FN_SYMBOL_ON // send 0xf1 to tell CannedMessages to display that the
: INPUT_BROKER_MSG_FN_SYMBOL_OFF; // modifier key is active
e.kbchar = is_sym ? 0xf1 : 0xf2; // send 0xf1 to tell CannedMessages to display that the modifier key is active
break;
case 0x90: // fn+r INPUT_BROKER_MSG_REBOOT
case 0x90: // fn+r
case 0x91: // fn+t
case 0x9b: // fn+s INPUT_BROKER_MSG_SHUTDOWN
case 0xac: // fn+m INPUT_BROKER_MSG_MUTE_TOGGLE
case 0x9e: // fn+g INPUT_BROKER_MSG_GPS_TOGGLE
case 0xaf: // fn+space INPUT_BROKER_MSG_SEND_PING
case 0x9b: // fn+s
case 0xac: // fn+m
case 0x9e: // fn+g
case 0xaf: // fn+space
// just pass those unmodified
e.inputEvent = ANYKEY;
e.kbchar = c;

View File

@@ -224,11 +224,6 @@ __attribute__((weak, noinline)) bool loopCanSleep()
return true;
}
// Weak empty variant initialization function.
// May be redefined by variant files.
void lateInitVariant() __attribute__((weak));
void lateInitVariant() {}
/**
* Print info as a structured log message (for automated log processing)
*/
@@ -262,12 +257,6 @@ void setup()
#ifdef DEBUG_PORT
consoleInit(); // Set serial baud rate and init our mesh console
#endif
#if ARCH_PORTDUINO
struct timeval tv;
tv.tv_sec = time(NULL);
tv.tv_usec = 0;
perhapsSetRTC(RTCQualityNTP, &tv);
#endif
powerMonInit();
@@ -289,9 +278,29 @@ void setup()
digitalWrite(LORA_TCXO_GPIO, HIGH);
#endif
#if defined(VEXT_ENABLE)
#if defined(VEXT_ENABLE_V03)
pinMode(VEXT_ENABLE_V03, OUTPUT);
pinMode(ST7735_BL_V03, OUTPUT);
digitalWrite(VEXT_ENABLE_V03, 0); // turn on the display power and antenna boost
digitalWrite(ST7735_BL_V03, 1); // display backligth on
LOG_DEBUG("HELTEC Detect Tracker V1.0\n");
#elif defined(VEXT_ENABLE_V05)
pinMode(VEXT_ENABLE_V05, OUTPUT);
pinMode(ST7735_BL_V05, OUTPUT);
digitalWrite(VEXT_ENABLE_V05, 1); // turn on the lora antenna boost
digitalWrite(ST7735_BL_V05, 1); // turn on display backligth
LOG_DEBUG("HELTEC Detect Tracker V1.1\n");
#elif defined(VEXT_ENABLE) && defined(VEXT_ON_VALUE)
pinMode(VEXT_ENABLE, OUTPUT);
digitalWrite(VEXT_ENABLE, VEXT_ON_VALUE); // turn on the display power
#elif defined(VEXT_ENABLE)
pinMode(VEXT_ENABLE, OUTPUT);
digitalWrite(VEXT_ENABLE, 0); // turn on the display power
#endif
#if defined(VTFT_CTRL_V03)
pinMode(VTFT_CTRL_V03, OUTPUT);
digitalWrite(VTFT_CTRL_V03, LOW);
#endif
#if defined(VTFT_CTRL)
@@ -547,7 +556,6 @@ void setup()
SCANNER_TO_SENSORS_MAP(ScanI2C::DeviceType::BME_680, meshtastic_TelemetrySensorType_BME680)
SCANNER_TO_SENSORS_MAP(ScanI2C::DeviceType::BME_280, meshtastic_TelemetrySensorType_BME280)
SCANNER_TO_SENSORS_MAP(ScanI2C::DeviceType::BMP_280, meshtastic_TelemetrySensorType_BMP280)
SCANNER_TO_SENSORS_MAP(ScanI2C::DeviceType::BMP_3XX, meshtastic_TelemetrySensorType_BMP3XX)
SCANNER_TO_SENSORS_MAP(ScanI2C::DeviceType::BMP_085, meshtastic_TelemetrySensorType_BMP085)
SCANNER_TO_SENSORS_MAP(ScanI2C::DeviceType::INA260, meshtastic_TelemetrySensorType_INA260)
SCANNER_TO_SENSORS_MAP(ScanI2C::DeviceType::INA219, meshtastic_TelemetrySensorType_INA219)
@@ -569,7 +577,6 @@ void setup()
SCANNER_TO_SENSORS_MAP(ScanI2C::DeviceType::SHT4X, meshtastic_TelemetrySensorType_SHT4X)
SCANNER_TO_SENSORS_MAP(ScanI2C::DeviceType::AHT10, meshtastic_TelemetrySensorType_AHT10)
SCANNER_TO_SENSORS_MAP(ScanI2C::DeviceType::DFROBOT_LARK, meshtastic_TelemetrySensorType_DFROBOT_LARK)
SCANNER_TO_SENSORS_MAP(ScanI2C::DeviceType::CUSTOM_SENSOR, meshtastic_TelemetrySensorType_CUSTOM_SENSOR)
i2cScanner.reset();
#endif
@@ -636,6 +643,8 @@ void setup()
#if !MESHTASTIC_EXCLUDE_I2C
#if !defined(ARCH_PORTDUINO) && !defined(ARCH_STM32WL) && !MESHTASTIC_EXCLUDE_ENVIRONMENTAL_SENSOR
if (acc_info.type != ScanI2C::DeviceType::NONE) {
config.display.wake_on_tap_or_motion = true;
moduleConfig.external_notification.enabled = true;
accelerometerThread = new AccelerometerThread(acc_info.type);
}
#endif
@@ -1014,8 +1023,6 @@ void setup()
}
}
lateInitVariant(); // Do board specific init (see extra_variants/README.md for documentation)
#if !MESHTASTIC_EXCLUDE_MQTT
mqttInit();
#endif
@@ -1142,4 +1149,4 @@ void loop()
}
// if (didWake) LOG_DEBUG("wake!\n");
}
#endif
#endif

View File

@@ -13,6 +13,10 @@
#include "mqtt/MQTT.h"
#endif
/// 16 bytes of random PSK for our _public_ default channel that all devices power up on (AES128)
static const uint8_t defaultpsk[] = {0xd4, 0xf1, 0xbb, 0x3a, 0x20, 0x29, 0x07, 0x59,
0xf0, 0xbc, 0xff, 0xab, 0xcf, 0x4e, 0x69, 0x01};
Channels channels;
const char *Channels::adminChannel = "admin";

View File

@@ -129,12 +129,4 @@ class Channels
};
/// Singleton channel table
extern Channels channels;
/// 16 bytes of random PSK for our _public_ default channel that all devices power up on (AES128)
static const uint8_t defaultpsk[] = {0xd4, 0xf1, 0xbb, 0x3a, 0x20, 0x29, 0x07, 0x59,
0xf0, 0xbc, 0xff, 0xab, 0xcf, 0x4e, 0x69, 0x01};
static const uint8_t eventpsk[] = {0x38, 0x4b, 0xbc, 0xc0, 0x1d, 0xc0, 0x22, 0xd1, 0x81, 0xbf, 0x36,
0xb8, 0x61, 0x21, 0xe1, 0xfb, 0x96, 0xb7, 0x2e, 0x55, 0xbf, 0x74,
0x22, 0x7e, 0x9d, 0x6a, 0xfb, 0x48, 0xd6, 0x4c, 0xb1, 0xa1};
extern Channels channels;

View File

@@ -11,7 +11,6 @@
#include <Curve25519.h>
#include <SHA256.h>
#if !(MESHTASTIC_EXCLUDE_PKI_KEYGEN)
/**
* Create a public/private key pair with Curve25519.
*
@@ -25,30 +24,6 @@ void CryptoEngine::generateKeyPair(uint8_t *pubKey, uint8_t *privKey)
memcpy(pubKey, public_key, sizeof(public_key));
memcpy(privKey, private_key, sizeof(private_key));
}
/**
* regenerate a public key with Curve25519.
*
* @param pubKey The destination for the public key.
* @param privKey The source for the private key.
*/
bool CryptoEngine::regeneratePublicKey(uint8_t *pubKey, uint8_t *privKey)
{
if (!memfll(privKey, 0, sizeof(private_key))) {
Curve25519::eval(pubKey, privKey, 0);
if (Curve25519::isWeakPoint(pubKey)) {
LOG_ERROR("PKI key generation failed. Specified private key results in a weak\n");
memset(pubKey, 0, 32);
return false;
}
memcpy(private_key, privKey, sizeof(private_key));
memcpy(public_key, pubKey, sizeof(public_key));
} else {
LOG_WARN("X25519 key generation failed due to blank private key\n");
return false;
}
return true;
}
#endif
void CryptoEngine::clearKeys()
{

View File

@@ -21,7 +21,6 @@ struct CryptoKey {
*/
#define MAX_BLOCKSIZE 256
#define TEST_CURVE25519_FIELD_OPS // Exposes Curve25519::isWeakPoint() for testing keys
class CryptoEngine
{
@@ -34,8 +33,6 @@ class CryptoEngine
#if !(MESHTASTIC_EXCLUDE_PKI)
#if !(MESHTASTIC_EXCLUDE_PKI_KEYGEN)
virtual void generateKeyPair(uint8_t *pubKey, uint8_t *privKey);
virtual bool regeneratePublicKey(uint8_t *pubKey, uint8_t *privKey);
#endif
void clearKeys();
void setDHPrivateKey(uint8_t *_private_key);

View File

@@ -50,23 +50,11 @@ template <typename T> bool LR11x0Interface<T>::init()
limitPower();
#ifdef TRACKER_T1000_E // Tracker T1000E uses DIO5, DIO6, DIO7, DIO8 for RF switching
static const uint32_t rfswitch_dio_pins[] = {RADIOLIB_LR11X0_DIO5, RADIOLIB_LR11X0_DIO6, RADIOLIB_LR11X0_DIO7,
RADIOLIB_LR11X0_DIO8, RADIOLIB_NC};
static const Module::RfSwitchMode_t rfswitch_table[] = {
// mode DIO5 DIO6 DIO7 DIO8
{LR11x0::MODE_STBY, {LOW, LOW, LOW, LOW}}, {LR11x0::MODE_RX, {HIGH, LOW, LOW, HIGH}},
{LR11x0::MODE_TX, {HIGH, HIGH, LOW, HIGH}}, {LR11x0::MODE_TX_HP, {LOW, HIGH, LOW, HIGH}},
{LR11x0::MODE_TX_HF, {LOW, LOW, LOW, LOW}}, {LR11x0::MODE_GNSS, {LOW, LOW, HIGH, LOW}},
{LR11x0::MODE_WIFI, {LOW, LOW, LOW, LOW}}, END_OF_MODE_TABLE,
};
#else
// set RF switch configuration for Wio WM1110
// Wio WM1110 uses DIO5 and DIO6 for RF switching
// NOTE: other boards may be different. If you are
// using a different board, you may need to wrap
// this in a conditional.
static const uint32_t rfswitch_dio_pins[] = {RADIOLIB_LR11X0_DIO5, RADIOLIB_LR11X0_DIO6, RADIOLIB_NC, RADIOLIB_NC,
RADIOLIB_NC};
@@ -79,8 +67,6 @@ template <typename T> bool LR11x0Interface<T>::init()
{LR11x0::MODE_WIFI, {LOW, LOW}}, END_OF_MODE_TABLE,
};
#endif
// We need to do this before begin() call
#ifdef LR11X0_DIO_AS_RF_SWITCH
LOG_DEBUG("Setting DIO RF switch\n");
@@ -104,13 +90,6 @@ template <typename T> bool LR11x0Interface<T>::init()
if (res == RADIOLIB_ERR_CHIP_NOT_FOUND)
return false;
LR11x0VersionInfo_t version;
res = lora.getVersionInfo(&version);
if (res == RADIOLIB_ERR_NONE)
LOG_DEBUG("LR11x0 Device %d, HW %d, FW %d.%d, WiFi %d.%d, GNSS %d.%d\n", version.device, version.hardware,
version.fwMajor, version.fwMinor, version.fwMajorWiFi, version.fwMinorWiFi, version.fwGNSS,
version.almanacGNSS);
LOG_INFO("Frequency set to %f\n", getFreq());
LOG_INFO("Bandwidth set to %f\n", bw);
LOG_INFO("Power output set to %d\n", power);
@@ -121,6 +100,13 @@ template <typename T> bool LR11x0Interface<T>::init()
// FIXME: May want to set depending on a definition, currently all LR1110 variant files use the DC-DC regulator option
if (res == RADIOLIB_ERR_NONE)
res = lora.setRegulatorDCDC();
#ifdef TRACKER_T1000_E
#ifdef LR11X0_DIO_RF_SWITCH_CONFIG
res = lora.setDioAsRfSwitch(LR11X0_DIO_RF_SWITCH_CONFIG);
#else
res = lora.setDioAsRfSwitch(0x03, 0x0, 0x01, 0x03, 0x02, 0x0, 0x0, 0x0);
#endif
#endif
if (res == RADIOLIB_ERR_NONE) {
if (config.lora.sx126x_rx_boosted_gain) { // the name is unfortunate but historically accurate
res = lora.setRxBoostedGainMode(true);
@@ -239,7 +225,9 @@ template <typename T> void LR11x0Interface<T>::startReceive()
// We use a 16 bit preamble so this should save some power by letting radio sit in standby mostly.
// Furthermore, we need the PREAMBLE_DETECTED and HEADER_VALID IRQ flag to detect whether we are actively receiving
int err = lora.startReceive(RADIOLIB_LR11X0_RX_TIMEOUT_INF, RADIOLIB_IRQ_RX_DEFAULT_FLAGS, RADIOLIB_IRQ_RX_DEFAULT_MASK, 0);
int err = lora.startReceive(
RADIOLIB_LR11X0_RX_TIMEOUT_INF, RADIOLIB_LR11X0_IRQ_RX_DONE,
0); // only RX_DONE IRQ is needed, we'll check for PREAMBLE_DETECTED and HEADER_VALID in isActivelyReceiving
assert(err == RADIOLIB_ERR_NONE);
RadioLibInterface::startReceive();

View File

@@ -25,7 +25,7 @@ template <class T> class LR11x0Interface : public RadioLibInterface
/// Prepare hardware for sleep. Call this _only_ for deep sleep, not needed for light sleep.
virtual bool sleep() override;
bool isIRQPending() override { return lora.getIrqFlags() != 0; }
bool isIRQPending() override { return lora.getIrqStatus() != 0; }
protected:
/**

View File

@@ -1,5 +1,4 @@
#include "MeshPacketQueue.h"
#include "NodeDB.h"
#include "configuration.h"
#include <assert.h>
@@ -17,9 +16,12 @@ bool CompareMeshPacketFunc(const meshtastic_MeshPacket *p1, const meshtastic_Mes
{
assert(p1 && p2);
auto p1p = getPriority(p1), p2p = getPriority(p2);
// If priorities differ, use that
// for equal priorities, prefer packets already on mesh.
return (p1p != p2p) ? (p1p > p2p) : (getFrom(p1) != nodeDB->getNodeNum() && getFrom(p2) == nodeDB->getNodeNum());
// for equal priorities, order by id (older packets have higher priority - this will briefly be wrong when IDs roll over but
// no big deal)
return (p1p != p2p) ? (p1p < p2p) // prefer bigger priorities
: (p1->id >= p2->id); // prefer smaller packet ids
}
MeshPacketQueue::MeshPacketQueue(size_t _maxLen) : maxLen(_maxLen) {}
@@ -37,38 +39,26 @@ void fixPriority(meshtastic_MeshPacket *p)
// We might receive acks from other nodes (and since generated remotely, they won't have priority assigned. Check for that
// and fix it
if (p->priority == meshtastic_MeshPacket_Priority_UNSET) {
// if acks give high priority
// if a reliable message give a bit higher default priority
p->priority = (p->want_ack ? meshtastic_MeshPacket_Priority_RELIABLE : meshtastic_MeshPacket_Priority_DEFAULT);
if (p->which_payload_variant == meshtastic_MeshPacket_decoded_tag) {
// if acks/naks give very high priority
if (p->decoded.portnum == meshtastic_PortNum_ROUTING_APP) {
p->priority = meshtastic_MeshPacket_Priority_ACK;
// if text or admin, give high priority
} else if (p->decoded.portnum == meshtastic_PortNum_TEXT_MESSAGE_APP ||
p->decoded.portnum == meshtastic_PortNum_ADMIN_APP) {
p->priority = meshtastic_MeshPacket_Priority_HIGH;
// if it is a response, give higher priority to let it arrive early and stop the request being relayed
} else if (p->decoded.request_id != 0) {
p->priority = meshtastic_MeshPacket_Priority_RESPONSE;
// Also if we want a response, give a bit higher priority
} else if (p->decoded.want_response) {
p->priority = meshtastic_MeshPacket_Priority_RELIABLE;
}
}
p->priority = (p->decoded.portnum == meshtastic_PortNum_ROUTING_APP)
? meshtastic_MeshPacket_Priority_ACK
: (p->want_ack ? meshtastic_MeshPacket_Priority_RELIABLE : meshtastic_MeshPacket_Priority_DEFAULT);
}
}
/** enqueue a packet, return false if full */
bool MeshPacketQueue::enqueue(meshtastic_MeshPacket *p)
{
fixPriority(p);
// no space - try to replace a lower priority packet in the queue
if (queue.size() >= maxLen) {
return replaceLowerPriorityPacket(p);
}
// Find the correct position using upper_bound to maintain a stable order
auto it = std::upper_bound(queue.begin(), queue.end(), p, CompareMeshPacketFunc);
queue.insert(it, p); // Insert packet at the found position
queue.push_back(p);
std::push_heap(queue.begin(), queue.end(), &CompareMeshPacketFunc);
return true;
}
@@ -79,7 +69,9 @@ meshtastic_MeshPacket *MeshPacketQueue::dequeue()
}
auto *p = queue.front();
queue.erase(queue.begin()); // Remove the highest-priority packet
std::pop_heap(queue.begin(), queue.end(), &CompareMeshPacketFunc);
queue.pop_back();
return p;
}
@@ -100,6 +92,7 @@ meshtastic_MeshPacket *MeshPacketQueue::remove(NodeNum from, PacketId id)
auto p = (*it);
if (getFrom(p) == from && p->id == id) {
queue.erase(it);
std::make_heap(queue.begin(), queue.end(), &CompareMeshPacketFunc);
return p;
}
}
@@ -110,21 +103,28 @@ meshtastic_MeshPacket *MeshPacketQueue::remove(NodeNum from, PacketId id)
/** Attempt to find and remove a packet from this queue. Returns the packet which was removed from the queue */
bool MeshPacketQueue::replaceLowerPriorityPacket(meshtastic_MeshPacket *p)
{
std::sort_heap(queue.begin(), queue.end(), &CompareMeshPacketFunc); // sort ascending based on priority (0 -> 127)
if (queue.empty()) {
return false; // No packets to replace
}
// Check if the packet at the back has a lower priority than the new packet
auto &backPacket = queue.back();
if (backPacket->priority < p->priority) {
// Remove the back packet
packetPool.release(backPacket);
queue.pop_back();
// Insert the new packet in the correct order
enqueue(p);
return true;
// find first packet which does not compare less (in priority) than parameter packet
auto low = std::lower_bound(queue.begin(), queue.end(), p, &CompareMeshPacketFunc);
if (low == queue.begin()) { // if already at start, there are no packets with lower priority
return false;
}
// If the back packet's priority is not lower, no replacement occurs
return false;
}
if (low == queue.end()) {
// all priorities in the vector are smaller than the incoming packet. Replace the lowest priority (first) element
low = queue.begin();
} else {
// 'low' iterator points to first packet which does not compare less than parameter
--low; // iterate to lower priority packet
}
if (getPriority(p) > getPriority(*low)) {
packetPool.release(*low); // deallocate and drop the packet we're replacing
*low = p; // replace low-pri packet at this position with incoming packet with higher priority
}
std::make_heap(queue.begin(), queue.end(), &CompareMeshPacketFunc);
return true;
}

View File

@@ -14,9 +14,8 @@ typedef uint32_t PacketId; // A packet sequence number
1 // Reserved to only deliver packets over high speed (non-lora) transports, such as MQTT or BLE mesh (not yet implemented)
#define ERRNO_OK 0
#define ERRNO_NO_INTERFACES 33
#define ERRNO_UNKNOWN 32 // pick something that doesn't conflict with RH_ROUTER_ERROR_UNABLE_TO_DELIVER
#define ERRNO_DISABLED 34 // the interface is disabled
#define ID_COUNTER_MASK (UINT32_MAX >> 22) // mask to select the counter portion of the ID
#define ERRNO_UNKNOWN 32 // pick something that doesn't conflict with RH_ROUTER_ERROR_UNABLE_TO_DELIVER
#define ERRNO_DISABLED 34 // the interface is disabled
/*
* Source of a received message
@@ -48,7 +47,4 @@ extern Allocator<meshtastic_MeshPacket> &packetPool;
* Most (but not always) of the time we want to treat packets 'from' the local phone (where from == 0), as if they originated on
* the local node. If from is zero this function returns our node number instead
*/
NodeNum getFrom(const meshtastic_MeshPacket *p);
/* Some clients might not properly set priority, therefore we fix it here. */
void fixPriority(meshtastic_MeshPacket *p);
NodeNum getFrom(const meshtastic_MeshPacket *p);

View File

@@ -139,24 +139,14 @@ NodeDB::NodeDB()
crypto->setDHPrivateKey(config.security.private_key.bytes);
} else {
#if !(MESHTASTIC_EXCLUDE_PKI_KEYGEN)
bool keygenSuccess = false;
if (config.security.private_key.size == 32) {
LOG_INFO("Calculating PKI Public Key\n");
if (crypto->regeneratePublicKey(config.security.public_key.bytes, config.security.private_key.bytes)) {
keygenSuccess = true;
}
} else {
LOG_INFO("Generating new PKI keys\n");
crypto->generateKeyPair(config.security.public_key.bytes, config.security.private_key.bytes);
keygenSuccess = true;
}
if (keygenSuccess) {
config.security.public_key.size = 32;
config.security.private_key.size = 32;
printBytes("New Pubkey", config.security.public_key.bytes, 32);
owner.public_key.size = 32;
memcpy(owner.public_key.bytes, config.security.public_key.bytes, 32);
}
LOG_INFO("Generating new PKI keys\n");
crypto->generateKeyPair(config.security.public_key.bytes, config.security.private_key.bytes);
config.security.public_key.size = 32;
config.security.private_key.size = 32;
printBytes("New Pubkey", config.security.public_key.bytes, 32);
owner.public_key.size = 32;
memcpy(owner.public_key.bytes, config.security.public_key.bytes, 32);
#else
LOG_INFO("No PKI keys set, and generation disabled!\n");
#endif
@@ -285,7 +275,6 @@ void NodeDB::installDefaultConfig()
config.lora.tx_enabled =
true; // FIXME: maybe false in the future, and setting region to enable it. (unset region forces it off)
config.lora.override_duty_cycle = false;
config.lora.config_ok_to_mqtt = false;
#ifdef CONFIG_LORA_REGION_USERPREFS
config.lora.region = CONFIG_LORA_REGION_USERPREFS;
#else
@@ -303,10 +292,10 @@ void NodeDB::installDefaultConfig()
config.lora.ignore_mqtt = false;
#endif
#ifdef ADMIN_KEY_USERPREFS
memcpy(config.security.admin_key[0].bytes, admin_key_userprefs, 32);
config.security.admin_key[0].size = 32;
memcpy(config.security.admin_key.bytes, admin_key_userprefs, 32);
config.security.admin_key.size = 32;
#else
config.security.admin_key[0].size = 0;
config.security.admin_key.size = 0;
#endif
config.security.public_key.size = 0;
config.security.private_key.size = 0;
@@ -318,7 +307,7 @@ void NodeDB::installDefaultConfig()
#else
config.device.disable_triple_click = true;
#endif
#if !HAS_GPS || defined(T_DECK) || defined(TLORA_T3S3_EPAPER)
#if !HAS_GPS || defined(T_DECK)
config.position.gps_mode = meshtastic_Config_PositionConfig_GpsMode_NOT_PRESENT;
#elif !defined(GPS_RX_PIN)
if (config.position.rx_gpio == 0)
@@ -363,9 +352,6 @@ void NodeDB::installDefaultConfig()
#ifdef DISPLAY_FLIP_SCREEN
config.display.flip_screen = true;
#endif
#ifdef RAK4630
config.display.wake_on_tap_or_motion = true;
#endif
#ifdef T_WATCH_S3
config.display.screen_on_secs = 30;
config.display.wake_on_tap_or_motion = true;
@@ -409,13 +395,6 @@ void NodeDB::installDefaultModuleConfig()
moduleConfig.has_store_forward = true;
moduleConfig.has_telemetry = true;
moduleConfig.has_external_notification = true;
#if defined(PIN_BUZZER)
moduleConfig.external_notification.enabled = true;
moduleConfig.external_notification.output_buzzer = PIN_BUZZER;
moduleConfig.external_notification.use_pwm = true;
moduleConfig.external_notification.alert_message_buzzer = true;
moduleConfig.external_notification.nag_timeout = 60;
#endif
#if defined(RAK4630) || defined(RAK11310)
// Default to RAK led pin 2 (blue)
moduleConfig.external_notification.enabled = true;
@@ -425,7 +404,6 @@ void NodeDB::installDefaultModuleConfig()
moduleConfig.external_notification.output_ms = 1000;
moduleConfig.external_notification.nag_timeout = 60;
#endif
#ifdef HAS_I2S
// Don't worry about the other settings for T-Watch, we'll also use the DRV2056 behavior for notifications
moduleConfig.external_notification.enabled = true;
@@ -642,7 +620,7 @@ void NodeDB::pickNewNodeNum()
meshtastic_NodeInfoLite *found;
while ((nodeNum == NODENUM_BROADCAST || nodeNum < NUM_RESERVED) ||
((found = getMeshNode(nodeNum)) && memcmp(found->user.macaddr, ourMacAddr, sizeof(ourMacAddr)) != 0)) {
((found = getMeshNode(nodeNum)) && memcmp(found->user.macaddr, owner.macaddr, sizeof(owner.macaddr)) != 0)) {
NodeNum candidate = random(NUM_RESERVED, LONG_MAX); // try a new random choice
LOG_WARN("NOTE! Our desired nodenum 0x%x is invalid or in use, so trying for 0x%x\n", nodeNum, candidate);
nodeNum = candidate;
@@ -1194,4 +1172,4 @@ void recordCriticalError(meshtastic_CriticalErrorCode code, uint32_t address, co
LOG_ERROR("A critical failure occurred, portduino is exiting...");
exit(2);
#endif
}
}

View File

@@ -194,8 +194,6 @@ size_t PhoneAPI::getFromRadio(uint8_t *buf)
auto us = nodeDB->readNextMeshNode(readIndex);
if (us) {
nodeInfoForPhone = TypeConversions::ConvertToNodeInfo(us);
nodeInfoForPhone.hops_away = 0;
nodeInfoForPhone.is_favorite = true;
fromRadioScratch.which_payload_variant = meshtastic_FromRadio_node_info_tag;
fromRadioScratch.node_info = nodeInfoForPhone;
// Should allow us to resume sending NodeInfo in STATE_SEND_OTHER_NODEINFOS
@@ -261,9 +259,6 @@ size_t PhoneAPI::getFromRadio(uint8_t *buf)
fromRadioScratch.config.which_payload_variant = meshtastic_Config_security_tag;
fromRadioScratch.config.payload_variant.security = config.security;
break;
case meshtastic_Config_sessionkey_tag:
fromRadioScratch.config.which_payload_variant = meshtastic_Config_sessionkey_tag;
break;
default:
LOG_ERROR("Unknown config type %d\n", config_state);
}

View File

@@ -420,7 +420,7 @@ void RadioInterface::applyModemConfig()
switch (loraConfig.modem_preset) {
case meshtastic_Config_LoRaConfig_ModemPreset_SHORT_TURBO:
bw = (myRegion->wideLora) ? 1625.0 : 500;
bw = (myRegion->wideLora) ? 812.5 : 500;
cr = 5;
sf = 7;
break;

View File

@@ -112,7 +112,7 @@ void ReliableRouter::sniffReceived(const meshtastic_MeshPacket *p, const meshtas
sendAckNak(meshtastic_Routing_Error_NONE, getFrom(p), p->id, p->channel, p->hop_start, p->hop_limit);
} else if (p->which_payload_variant == meshtastic_MeshPacket_encrypted_tag && p->channel == 0 &&
(nodeDB->getMeshNode(p->from) == nullptr || nodeDB->getMeshNode(p->from)->user.public_key.size == 0)) {
LOG_INFO("This looks like it might be a PKI packet from an unknown node, so send PKI_UNKNOWN_PUBKEY\n");
// This looks like it might be a PKI packet from an unknown node, so send PKI_UNKNOWN_PUBKEY
sendAckNak(meshtastic_Routing_Error_PKI_UNKNOWN_PUBKEY, getFrom(p), p->id, channels.getPrimaryIndex(),
p->hop_start, p->hop_limit);
} else {

View File

@@ -109,7 +109,7 @@ PacketId generatePacketId()
rollingPacketId++;
rollingPacketId &= ID_COUNTER_MASK; // Mask out the top 22 bits
rollingPacketId &= UINT32_MAX >> 22; // Mask out the top 22 bits
PacketId id = rollingPacketId | random(UINT32_MAX & 0x7fffffff) << 10; // top 22 bits
LOG_DEBUG("Partially randomized packet id %u\n", id);
return id;
@@ -165,9 +165,6 @@ meshtastic_QueueStatus Router::getQueueStatus()
ErrorCode Router::sendLocal(meshtastic_MeshPacket *p, RxSource src)
{
if (p->to == 0) {
LOG_ERROR("Packet received with to: of 0!\n");
}
// No need to deliver externally if the destination is the local node
if (p->to == nodeDB->getNodeNum()) {
printPacket("Enqueued local", p);
@@ -255,8 +252,6 @@ ErrorCode Router::send(meshtastic_MeshPacket *p)
return meshtastic_Routing_Error_BAD_REQUEST;
}
fixPriority(p); // Before encryption, fix the priority if it's unset
// If the packet is not yet encrypted, do so now
if (p->which_payload_variant == meshtastic_MeshPacket_decoded_tag) {
ChannelIndex chIndex = p->channel; // keep as a local because we are about to change it
@@ -378,8 +373,6 @@ bool perhapsDecode(meshtastic_MeshPacket *p)
// parsing was successful
p->which_payload_variant = meshtastic_MeshPacket_decoded_tag; // change type to decoded
p->channel = chIndex; // change to store the index instead of the hash
if (p->decoded.has_bitfield)
p->decoded.want_response |= p->decoded.bitfield & BITFIELD_WANT_RESPONSE_MASK;
/* Not actually ever used.
// Decompress if needed. jm
@@ -426,12 +419,6 @@ meshtastic_Routing_Error perhapsEncode(meshtastic_MeshPacket *p)
// If the packet is not yet encrypted, do so now
if (p->which_payload_variant == meshtastic_MeshPacket_decoded_tag) {
if (p->from == nodeDB->getNodeNum()) {
p->decoded.has_bitfield = true;
p->decoded.bitfield |= (config.lora.config_ok_to_mqtt << BITFIELD_OK_TO_MQTT_SHIFT);
p->decoded.bitfield |= (p->decoded.want_response << BITFIELD_WANT_RESPONSE_SHIFT);
}
size_t numbytes = pb_encode_to_bytes(bytes, sizeof(bytes), &meshtastic_Data_msg, &p->decoded);
/* Not actually used, so save the cycles

View File

@@ -148,8 +148,3 @@ extern Router *router;
/// Generate a unique packet id
// FIXME, move this someplace better
PacketId generatePacketId();
#define BITFIELD_WANT_RESPONSE_SHIFT 1
#define BITFIELD_OK_TO_MQTT_SHIFT 0
#define BITFIELD_WANT_RESPONSE_MASK (1 << BITFIELD_WANT_RESPONSE_SHIFT)
#define BITFIELD_OK_TO_MQTT_MASK (1 << BITFIELD_OK_TO_MQTT_SHIFT)

View File

@@ -264,7 +264,9 @@ template <typename T> void SX126xInterface<T>::startReceive()
// We use a 16 bit preamble so this should save some power by letting radio sit in standby mostly.
// Furthermore, we need the PREAMBLE_DETECTED and HEADER_VALID IRQ flag to detect whether we are actively receiving
int err = lora.startReceiveDutyCycleAuto(preambleLength, 8, RADIOLIB_IRQ_RX_DEFAULT_FLAGS | RADIOLIB_IRQ_PREAMBLE_DETECTED);
int err = lora.startReceiveDutyCycleAuto(preambleLength, 8,
RADIOLIB_SX126X_IRQ_RX_DEFAULT | RADIOLIB_SX126X_IRQ_PREAMBLE_DETECTED |
RADIOLIB_SX126X_IRQ_HEADER_VALID);
if (err != RADIOLIB_ERR_NONE)
LOG_ERROR("Radiolib error %d when attempting SX126X startReceiveDutyCycleAuto!\n", err);
assert(err == RADIOLIB_ERR_NONE);
@@ -299,7 +301,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();
uint16_t irq = lora.getIrqStatus();
bool detected = (irq & (RADIOLIB_SX126X_IRQ_HEADER_VALID | RADIOLIB_SX126X_IRQ_PREAMBLE_DETECTED));
// Handle false detections
if (detected) {

View File

@@ -25,7 +25,7 @@ template <class T> class SX126xInterface : public RadioLibInterface
/// Prepare hardware for sleep. Call this _only_ for deep sleep, not needed for light sleep.
virtual bool sleep() override;
bool isIRQPending() override { return lora.getIrqFlags() != 0; }
bool isIRQPending() override { return lora.getIrqStatus() != 0; }
protected:
float currentLimit = 140; // Higher OCP limit for SX126x PA

View File

@@ -256,7 +256,9 @@ template <typename T> void SX128xInterface<T>::startReceive()
#endif
// We use the PREAMBLE_DETECTED and HEADER_VALID IRQ flag to detect whether we are actively receiving
int err = lora.startReceive(RADIOLIB_SX128X_RX_TIMEOUT_INF, RADIOLIB_IRQ_RX_DEFAULT_FLAGS | RADIOLIB_IRQ_PREAMBLE_DETECTED);
int err =
lora.startReceive(RADIOLIB_SX128X_RX_TIMEOUT_INF, RADIOLIB_SX128X_IRQ_RX_DEFAULT | RADIOLIB_SX128X_IRQ_PREAMBLE_DETECTED |
RADIOLIB_SX128X_IRQ_HEADER_VALID);
if (err != RADIOLIB_ERR_NONE)
LOG_ERROR("Radiolib error %d when attempting SX128X startReceive!\n", err);

View File

@@ -27,7 +27,7 @@ template <class T> class SX128xInterface : public RadioLibInterface
/// Prepare hardware for sleep. Call this _only_ for deep sleep, not needed for light sleep.
virtual bool sleep() override;
bool isIRQPending() override { return lora.getIrqFlags() != 0; }
bool isIRQPending() override { return lora.getIrqStatus() != 0; }
protected:
/**

View File

@@ -5,7 +5,7 @@
template <typename T>
ServerAPI<T>::ServerAPI(T &_client) : StreamAPI(&client), concurrency::OSThread("ServerAPI"), client(_client)
{
LOG_INFO("Incoming API connection\n");
LOG_INFO("Incoming wifi connection\n");
}
template <typename T> ServerAPI<T>::~ServerAPI()
@@ -49,16 +49,6 @@ template <class T, class U> int32_t APIServerPort<T, U>::runOnce()
if (client) {
// Close any previous connection (see FIXME in header file)
if (openAPI) {
#if RAK_4631
// RAK13800 Ethernet requests periodically take more time
// This backoff addresses most cases keeping max wait < 1s
// Reconnections are delayed by full wait time
if (waitTime < 400) {
waitTime *= 2;
LOG_INFO("Previous TCP connection still open, trying again in %dms\n", waitTime);
return waitTime;
}
#endif
LOG_INFO("Force closing previous TCP connection\n");
delete openAPI;
}
@@ -66,8 +56,5 @@ template <class T, class U> int32_t APIServerPort<T, U>::runOnce()
openAPI = new T(client);
}
#if RAK_4631
waitTime = 100;
#endif
return 100; // only check occasionally for incoming connections
}

View File

@@ -31,7 +31,7 @@ template <class T> class ServerAPI : public StreamAPI, private concurrency::OSTh
};
/**
* Listens for incoming connections and does accepts and creates instances of ServerAPI as needed
* Listens for incoming connections and does accepts and creates instances of WiFiServerAPI as needed
*/
template <class T, class U> class APIServerPort : public U, private concurrency::OSThread
{
@@ -41,10 +41,6 @@ template <class T, class U> class APIServerPort : public U, private concurrency:
* delegate to the worker. Once coroutines are implemented we can relax this restriction.
*/
T *openAPI = NULL;
#if RAK_4631
// Track wait time for RAK13800 Ethernet requests
int32_t waitTime = 100;
#endif
public:
explicit APIServerPort(int port);

View File

@@ -14,7 +14,7 @@ class ethServerAPI : public ServerAPI<EthernetClient>
};
/**
* Listens for incoming connections and does accepts and creates instances of EthernetServerAPI as needed
* Listens for incoming connections and does accepts and creates instances of WiFiServerAPI as needed
*/
class ethServerPort : public APIServerPort<ethServerAPI, EthernetServer>
{

View File

@@ -38,7 +38,7 @@ static int32_t reconnectETH()
Ethernet.maintain();
if (!ethStartupComplete) {
// Start web server
LOG_INFO("Starting Ethernet network services\n");
LOG_INFO("... Starting network services\n");
#ifndef DISABLE_NTP
LOG_INFO("Starting NTP time client\n");
@@ -131,8 +131,7 @@ bool initEthernet()
status = Ethernet.begin(mac);
} else if (config.network.address_mode == meshtastic_Config_NetworkConfig_AddressMode_STATIC) {
LOG_INFO("starting Ethernet Static\n");
Ethernet.begin(mac, config.network.ipv4_config.ip, config.network.ipv4_config.dns, config.network.ipv4_config.gateway,
config.network.ipv4_config.subnet);
Ethernet.begin(mac, config.network.ipv4_config.ip, config.network.ipv4_config.dns, config.network.ipv4_config.subnet);
status = 1;
} else {
LOG_INFO("Ethernet Disabled\n");
@@ -187,4 +186,4 @@ bool isEthernetAvailable()
}
}
#endif
#endif

View File

@@ -55,7 +55,7 @@ extern const pb_msgdesc_t meshtastic_ChannelSet_msg;
/* Maximum encoded size of messages (where known) */
#define MESHTASTIC_MESHTASTIC_APPONLY_PB_H_MAX_SIZE meshtastic_ChannelSet_size
#define meshtastic_ChannelSet_size 679
#define meshtastic_ChannelSet_size 676
#ifdef __cplusplus
} /* extern "C" */

View File

@@ -510,8 +510,6 @@ typedef struct _meshtastic_Config_LoRaConfig {
uint32_t ignore_incoming[3];
/* If true, the device will not process any packets received via LoRa that passed via MQTT anywhere on the path towards it. */
bool ignore_mqtt;
/* Sets the ok_to_mqtt bit on outgoing packets */
bool config_ok_to_mqtt;
} meshtastic_Config_LoRaConfig;
typedef struct _meshtastic_Config_BluetoothConfig {
@@ -534,8 +532,7 @@ typedef struct _meshtastic_Config_SecurityConfig {
Used to create a shared key with a remote device. */
meshtastic_Config_SecurityConfig_private_key_t private_key;
/* The public key authorized to send admin messages to this node. */
pb_size_t admin_key_count;
meshtastic_Config_SecurityConfig_admin_key_t admin_key[1];
meshtastic_Config_SecurityConfig_admin_key_t admin_key;
/* If true, device is considered to be "managed" by a mesh administrator via admin messages
Device is managed by a mesh administrator. */
bool is_managed;
@@ -658,9 +655,9 @@ extern "C" {
#define meshtastic_Config_NetworkConfig_init_default {0, "", "", "", 0, _meshtastic_Config_NetworkConfig_AddressMode_MIN, false, meshtastic_Config_NetworkConfig_IpV4Config_init_default, ""}
#define meshtastic_Config_NetworkConfig_IpV4Config_init_default {0, 0, 0, 0}
#define meshtastic_Config_DisplayConfig_init_default {0, _meshtastic_Config_DisplayConfig_GpsCoordinateFormat_MIN, 0, 0, 0, _meshtastic_Config_DisplayConfig_DisplayUnits_MIN, _meshtastic_Config_DisplayConfig_OledType_MIN, _meshtastic_Config_DisplayConfig_DisplayMode_MIN, 0, 0, _meshtastic_Config_DisplayConfig_CompassOrientation_MIN}
#define meshtastic_Config_LoRaConfig_init_default {0, _meshtastic_Config_LoRaConfig_ModemPreset_MIN, 0, 0, 0, 0, _meshtastic_Config_LoRaConfig_RegionCode_MIN, 0, 0, 0, 0, 0, 0, 0, 0, 0, {0, 0, 0}, 0, 0}
#define meshtastic_Config_LoRaConfig_init_default {0, _meshtastic_Config_LoRaConfig_ModemPreset_MIN, 0, 0, 0, 0, _meshtastic_Config_LoRaConfig_RegionCode_MIN, 0, 0, 0, 0, 0, 0, 0, 0, 0, {0, 0, 0}, 0}
#define meshtastic_Config_BluetoothConfig_init_default {0, _meshtastic_Config_BluetoothConfig_PairingMode_MIN, 0}
#define meshtastic_Config_SecurityConfig_init_default {{0, {0}}, {0, {0}}, 0, {{0, {0}}}, 0, 0, 0, 0}
#define meshtastic_Config_SecurityConfig_init_default {{0, {0}}, {0, {0}}, {0, {0}}, 0, 0, 0, 0}
#define meshtastic_Config_SessionkeyConfig_init_default {0}
#define meshtastic_Config_init_zero {0, {meshtastic_Config_DeviceConfig_init_zero}}
#define meshtastic_Config_DeviceConfig_init_zero {_meshtastic_Config_DeviceConfig_Role_MIN, 0, 0, 0, _meshtastic_Config_DeviceConfig_RebroadcastMode_MIN, 0, 0, 0, 0, "", 0}
@@ -669,9 +666,9 @@ extern "C" {
#define meshtastic_Config_NetworkConfig_init_zero {0, "", "", "", 0, _meshtastic_Config_NetworkConfig_AddressMode_MIN, false, meshtastic_Config_NetworkConfig_IpV4Config_init_zero, ""}
#define meshtastic_Config_NetworkConfig_IpV4Config_init_zero {0, 0, 0, 0}
#define meshtastic_Config_DisplayConfig_init_zero {0, _meshtastic_Config_DisplayConfig_GpsCoordinateFormat_MIN, 0, 0, 0, _meshtastic_Config_DisplayConfig_DisplayUnits_MIN, _meshtastic_Config_DisplayConfig_OledType_MIN, _meshtastic_Config_DisplayConfig_DisplayMode_MIN, 0, 0, _meshtastic_Config_DisplayConfig_CompassOrientation_MIN}
#define meshtastic_Config_LoRaConfig_init_zero {0, _meshtastic_Config_LoRaConfig_ModemPreset_MIN, 0, 0, 0, 0, _meshtastic_Config_LoRaConfig_RegionCode_MIN, 0, 0, 0, 0, 0, 0, 0, 0, 0, {0, 0, 0}, 0, 0}
#define meshtastic_Config_LoRaConfig_init_zero {0, _meshtastic_Config_LoRaConfig_ModemPreset_MIN, 0, 0, 0, 0, _meshtastic_Config_LoRaConfig_RegionCode_MIN, 0, 0, 0, 0, 0, 0, 0, 0, 0, {0, 0, 0}, 0}
#define meshtastic_Config_BluetoothConfig_init_zero {0, _meshtastic_Config_BluetoothConfig_PairingMode_MIN, 0}
#define meshtastic_Config_SecurityConfig_init_zero {{0, {0}}, {0, {0}}, 0, {{0, {0}}}, 0, 0, 0, 0}
#define meshtastic_Config_SecurityConfig_init_zero {{0, {0}}, {0, {0}}, {0, {0}}, 0, 0, 0, 0}
#define meshtastic_Config_SessionkeyConfig_init_zero {0}
/* Field tags (for use in manual encoding/decoding) */
@@ -748,7 +745,6 @@ extern "C" {
#define meshtastic_Config_LoRaConfig_pa_fan_disabled_tag 15
#define meshtastic_Config_LoRaConfig_ignore_incoming_tag 103
#define meshtastic_Config_LoRaConfig_ignore_mqtt_tag 104
#define meshtastic_Config_LoRaConfig_config_ok_to_mqtt_tag 105
#define meshtastic_Config_BluetoothConfig_enabled_tag 1
#define meshtastic_Config_BluetoothConfig_mode_tag 2
#define meshtastic_Config_BluetoothConfig_fixed_pin_tag 3
@@ -890,8 +886,7 @@ X(a, STATIC, SINGULAR, BOOL, sx126x_rx_boosted_gain, 13) \
X(a, STATIC, SINGULAR, FLOAT, override_frequency, 14) \
X(a, STATIC, SINGULAR, BOOL, pa_fan_disabled, 15) \
X(a, STATIC, REPEATED, UINT32, ignore_incoming, 103) \
X(a, STATIC, SINGULAR, BOOL, ignore_mqtt, 104) \
X(a, STATIC, SINGULAR, BOOL, config_ok_to_mqtt, 105)
X(a, STATIC, SINGULAR, BOOL, ignore_mqtt, 104)
#define meshtastic_Config_LoRaConfig_CALLBACK NULL
#define meshtastic_Config_LoRaConfig_DEFAULT NULL
@@ -905,7 +900,7 @@ X(a, STATIC, SINGULAR, UINT32, fixed_pin, 3)
#define meshtastic_Config_SecurityConfig_FIELDLIST(X, a) \
X(a, STATIC, SINGULAR, BYTES, public_key, 1) \
X(a, STATIC, SINGULAR, BYTES, private_key, 2) \
X(a, STATIC, REPEATED, BYTES, admin_key, 3) \
X(a, STATIC, SINGULAR, BYTES, admin_key, 3) \
X(a, STATIC, SINGULAR, BOOL, is_managed, 4) \
X(a, STATIC, SINGULAR, BOOL, serial_enabled, 5) \
X(a, STATIC, SINGULAR, BOOL, debug_log_api_enabled, 6) \
@@ -948,12 +943,12 @@ extern const pb_msgdesc_t meshtastic_Config_SessionkeyConfig_msg;
#define meshtastic_Config_BluetoothConfig_size 10
#define meshtastic_Config_DeviceConfig_size 98
#define meshtastic_Config_DisplayConfig_size 30
#define meshtastic_Config_LoRaConfig_size 85
#define meshtastic_Config_LoRaConfig_size 82
#define meshtastic_Config_NetworkConfig_IpV4Config_size 20
#define meshtastic_Config_NetworkConfig_size 196
#define meshtastic_Config_PositionConfig_size 62
#define meshtastic_Config_PowerConfig_size 52
#define meshtastic_Config_SecurityConfig_size 111
#define meshtastic_Config_SecurityConfig_size 110
#define meshtastic_Config_SessionkeyConfig_size 0
#define meshtastic_Config_size 199

View File

@@ -358,7 +358,7 @@ extern const pb_msgdesc_t meshtastic_OEMStore_msg;
#define MESHTASTIC_MESHTASTIC_DEVICEONLY_PB_H_MAX_SIZE meshtastic_OEMStore_size
#define meshtastic_ChannelFile_size 718
#define meshtastic_NodeInfoLite_size 183
#define meshtastic_OEMStore_size 3500
#define meshtastic_OEMStore_size 3496
#define meshtastic_PositionLite_size 28
#define meshtastic_UserLite_size 96

View File

@@ -187,7 +187,7 @@ extern const pb_msgdesc_t meshtastic_LocalModuleConfig_msg;
/* Maximum encoded size of messages (where known) */
#define MESHTASTIC_MESHTASTIC_LOCALONLY_PB_H_MAX_SIZE meshtastic_LocalModuleConfig_size
#define meshtastic_LocalConfig_size 667
#define meshtastic_LocalConfig_size 663
#define meshtastic_LocalModuleConfig_size 687
#ifdef __cplusplus

View File

@@ -196,9 +196,6 @@ typedef enum _meshtastic_HardwareModel {
https://www.adafruit.com/product/938
^^^ short A0 to switch to I2C address 0x3C */
meshtastic_HardwareModel_RP2040_FEATHER_RFM95 = 76,
/* M5 esp32 based MCU modules with enclosure, TFT and LORA Shields. All Variants (Basic, Core, Fire, Core2, Paper) https://m5stack.com/ */
meshtastic_HardwareModel_M5STACK_COREBASIC = 77,
meshtastic_HardwareModel_M5STACK_CORE2 = 78,
/* ------------------------------------------------------------------------------------------------------------------------------------------
Reserved ID For developing private Ports. These will show up in live traffic sparsely, so we can use a high number. Keep it within 8 bits.
------------------------------------------------------------------------------------------------------------------------------------------ */
@@ -350,11 +347,6 @@ typedef enum _meshtastic_MeshPacket_Priority {
/* If priority is unset but the message is marked as want_ack,
assume it is important and use a slightly higher priority */
meshtastic_MeshPacket_Priority_RELIABLE = 70,
/* If priority is unset but the packet is a response to a request, we want it to get there relatively quickly.
Furthermore, responses stop relaying packets directed to a node early. */
meshtastic_MeshPacket_Priority_RESPONSE = 80,
/* Higher priority for specific message types (portnums) to distinguish between other reliable packets. */
meshtastic_MeshPacket_Priority_HIGH = 100,
/* Ack/naks are sent with very high priority to ensure that retransmission
stops as soon as possible */
meshtastic_MeshPacket_Priority_ACK = 120,
@@ -580,9 +572,6 @@ typedef struct _meshtastic_Data {
/* Defaults to false. If true, then what is in the payload should be treated as an emoji like giving
a message a heart or poop emoji. */
uint32_t emoji;
/* Bitfield for extra flags. First use is to indicate that user approves the packet being uploaded to MQTT. */
bool has_bitfield;
uint8_t bitfield;
} meshtastic_Data;
/* Waypoint message, used to share arbitrary locations across the mesh */
@@ -1085,7 +1074,7 @@ extern "C" {
#define meshtastic_User_init_default {"", "", "", {0}, _meshtastic_HardwareModel_MIN, 0, _meshtastic_Config_DeviceConfig_Role_MIN, {0, {0}}}
#define meshtastic_RouteDiscovery_init_default {0, {0, 0, 0, 0, 0, 0, 0, 0}, 0, {0, 0, 0, 0, 0, 0, 0, 0}, 0, {0, 0, 0, 0, 0, 0, 0, 0}, 0, {0, 0, 0, 0, 0, 0, 0, 0}}
#define meshtastic_Routing_init_default {0, {meshtastic_RouteDiscovery_init_default}}
#define meshtastic_Data_init_default {_meshtastic_PortNum_MIN, {0, {0}}, 0, 0, 0, 0, 0, 0, false, 0}
#define meshtastic_Data_init_default {_meshtastic_PortNum_MIN, {0, {0}}, 0, 0, 0, 0, 0, 0}
#define meshtastic_Waypoint_init_default {0, false, 0, false, 0, 0, 0, "", "", 0}
#define meshtastic_MqttClientProxyMessage_init_default {"", 0, {{0, {0}}}, 0}
#define meshtastic_MeshPacket_init_default {0, 0, 0, 0, {meshtastic_Data_init_default}, 0, 0, 0, 0, 0, _meshtastic_MeshPacket_Priority_MIN, 0, _meshtastic_MeshPacket_Delayed_MIN, 0, 0, {0, {0}}, 0}
@@ -1110,7 +1099,7 @@ extern "C" {
#define meshtastic_User_init_zero {"", "", "", {0}, _meshtastic_HardwareModel_MIN, 0, _meshtastic_Config_DeviceConfig_Role_MIN, {0, {0}}}
#define meshtastic_RouteDiscovery_init_zero {0, {0, 0, 0, 0, 0, 0, 0, 0}, 0, {0, 0, 0, 0, 0, 0, 0, 0}, 0, {0, 0, 0, 0, 0, 0, 0, 0}, 0, {0, 0, 0, 0, 0, 0, 0, 0}}
#define meshtastic_Routing_init_zero {0, {meshtastic_RouteDiscovery_init_zero}}
#define meshtastic_Data_init_zero {_meshtastic_PortNum_MIN, {0, {0}}, 0, 0, 0, 0, 0, 0, false, 0}
#define meshtastic_Data_init_zero {_meshtastic_PortNum_MIN, {0, {0}}, 0, 0, 0, 0, 0, 0}
#define meshtastic_Waypoint_init_zero {0, false, 0, false, 0, 0, 0, "", "", 0}
#define meshtastic_MqttClientProxyMessage_init_zero {"", 0, {{0, {0}}}, 0}
#define meshtastic_MeshPacket_init_zero {0, 0, 0, 0, {meshtastic_Data_init_zero}, 0, 0, 0, 0, 0, _meshtastic_MeshPacket_Priority_MIN, 0, _meshtastic_MeshPacket_Delayed_MIN, 0, 0, {0, {0}}, 0}
@@ -1179,7 +1168,6 @@ extern "C" {
#define meshtastic_Data_request_id_tag 6
#define meshtastic_Data_reply_id_tag 7
#define meshtastic_Data_emoji_tag 8
#define meshtastic_Data_bitfield_tag 9
#define meshtastic_Waypoint_id_tag 1
#define meshtastic_Waypoint_latitude_i_tag 2
#define meshtastic_Waypoint_longitude_i_tag 3
@@ -1355,8 +1343,7 @@ X(a, STATIC, SINGULAR, FIXED32, dest, 4) \
X(a, STATIC, SINGULAR, FIXED32, source, 5) \
X(a, STATIC, SINGULAR, FIXED32, request_id, 6) \
X(a, STATIC, SINGULAR, FIXED32, reply_id, 7) \
X(a, STATIC, SINGULAR, FIXED32, emoji, 8) \
X(a, STATIC, OPTIONAL, UINT32, bitfield, 9)
X(a, STATIC, SINGULAR, FIXED32, emoji, 8)
#define meshtastic_Data_CALLBACK NULL
#define meshtastic_Data_DEFAULT NULL
@@ -1634,13 +1621,13 @@ extern const pb_msgdesc_t meshtastic_ChunkedPayloadResponse_msg;
#define meshtastic_ChunkedPayload_size 245
#define meshtastic_ClientNotification_size 415
#define meshtastic_Compressed_size 243
#define meshtastic_Data_size 273
#define meshtastic_Data_size 270
#define meshtastic_DeviceMetadata_size 46
#define meshtastic_FileInfo_size 236
#define meshtastic_FromRadio_size 510
#define meshtastic_Heartbeat_size 0
#define meshtastic_LogRecord_size 426
#define meshtastic_MeshPacket_size 367
#define meshtastic_MeshPacket_size 364
#define meshtastic_MqttClientProxyMessage_size 501
#define meshtastic_MyNodeInfo_size 18
#define meshtastic_NeighborInfo_size 258

View File

@@ -69,9 +69,7 @@ typedef enum _meshtastic_TelemetrySensorType {
/* ICM-20948 9-Axis digital motion processor */
meshtastic_TelemetrySensorType_ICM20948 = 27,
/* MAX17048 1S lipo battery sensor (voltage, state of charge, time to go) */
meshtastic_TelemetrySensorType_MAX17048 = 28,
/* Custom I2C sensor implementation based on https://github.com/meshtastic/i2c-sensor */
meshtastic_TelemetrySensorType_CUSTOM_SENSOR = 29
meshtastic_TelemetrySensorType_MAX17048 = 28
} meshtastic_TelemetrySensorType;
/* Struct definitions */
@@ -267,8 +265,8 @@ extern "C" {
/* Helper constants for enums */
#define _meshtastic_TelemetrySensorType_MIN meshtastic_TelemetrySensorType_SENSOR_UNSET
#define _meshtastic_TelemetrySensorType_MAX meshtastic_TelemetrySensorType_CUSTOM_SENSOR
#define _meshtastic_TelemetrySensorType_ARRAYSIZE ((meshtastic_TelemetrySensorType)(meshtastic_TelemetrySensorType_CUSTOM_SENSOR+1))
#define _meshtastic_TelemetrySensorType_MAX meshtastic_TelemetrySensorType_MAX17048
#define _meshtastic_TelemetrySensorType_ARRAYSIZE ((meshtastic_TelemetrySensorType)(meshtastic_TelemetrySensorType_MAX17048+1))

View File

@@ -15,8 +15,10 @@
#include <WiFiUdp.h>
#ifdef ARCH_ESP32
#if !MESHTASTIC_EXCLUDE_WEBSERVER
#if !MESHTASTIC_EXCLUDE_WEBSERVER
#include "mesh/http/WebServer.h"
#endif
#endif
#include <ESPmDNS.h>
#include <esp_wifi.h>
static void WiFiEvent(WiFiEvent_t event);
@@ -56,7 +58,7 @@ static void onNetworkConnected()
{
if (!APStartupComplete) {
// Start web server
LOG_INFO("Starting WiFi network services\n");
LOG_INFO("Starting network services\n");
#ifdef ARCH_ESP32
// start mdns
@@ -420,4 +422,4 @@ uint8_t getWifiDisconnectReason()
{
return wifiDisconnectReason;
}
#endif
#endif

View File

@@ -68,7 +68,7 @@ void printBytes(const char *label, const uint8_t *p, size_t numbytes)
bool memfll(const uint8_t *mem, uint8_t find, size_t numbytes)
{
for (uint8_t i = 0; i < numbytes; i++) {
for (int i = 0; i < numbytes; i++) {
if (mem[i] != find)
return false;
}

View File

@@ -75,7 +75,7 @@ bool AdminModule::handleReceivedProtobuf(const meshtastic_MeshPacket &mp, meshta
// and only allowing responses from that remote.
if (!((mp.from == 0 && !config.security.is_managed) || messageIsResponse(r) ||
(strcasecmp(ch->settings.name, Channels::adminChannel) == 0 && config.security.admin_channel_enabled) ||
(mp.pki_encrypted && memcmp(mp.public_key.bytes, config.security.admin_key[0].bytes, 32) == 0))) {
(mp.pki_encrypted && memcmp(mp.public_key.bytes, config.security.admin_key.bytes, 32) == 0))) {
LOG_INFO("Ignoring admin payload %i\n", r->which_payload_variant);
return handled;
}
@@ -288,7 +288,7 @@ bool AdminModule::handleReceivedProtobuf(const meshtastic_MeshPacket &mp, meshta
tv.tv_sec = r->set_time_only;
tv.tv_usec = 0;
perhapsSetRTC(RTCQualityNTP, &tv, false);
perhapsSetRTC(RTCQualityFromNet, &tv, false);
break;
}
case meshtastic_AdminMessage_enter_dfu_mode_request_tag: {
@@ -406,8 +406,7 @@ void AdminModule::handleSetConfig(const meshtastic_Config &c)
LOG_INFO("Setting config: Device\n");
config.has_device = true;
#if !defined(ARCH_PORTDUINO) && !defined(ARCH_STM32WL) && !MESHTASTIC_EXCLUDE_ENVIRONMENTAL_SENSOR
if (config.device.double_tap_as_button_press == false && c.payload_variant.device.double_tap_as_button_press == true &&
accelerometerThread->enabled == false) {
if (config.device.double_tap_as_button_press == false && c.payload_variant.device.double_tap_as_button_press == true) {
accelerometerThread->start();
}
#endif
@@ -485,8 +484,7 @@ void AdminModule::handleSetConfig(const meshtastic_Config &c)
requiresReboot = false;
}
#if !defined(ARCH_PORTDUINO) && !defined(ARCH_STM32WL) && !MESHTASTIC_EXCLUDE_ENVIRONMENTAL_SENSOR
if (config.display.wake_on_tap_or_motion == false && c.payload_variant.display.wake_on_tap_or_motion == true &&
accelerometerThread->enabled == false) {
if (config.display.wake_on_tap_or_motion == false && c.payload_variant.display.wake_on_tap_or_motion == true) {
accelerometerThread->start();
}
#endif
@@ -539,15 +537,6 @@ void AdminModule::handleSetConfig(const meshtastic_Config &c)
case meshtastic_Config_security_tag:
LOG_INFO("Setting config: Security\n");
config.security = c.payload_variant.security;
#if !(MESHTASTIC_EXCLUDE_PKI_KEYGEN) && !(MESHTASTIC_EXCLUDE_PKI)
// We check for a potentially valid private key, and a blank public key, and regen the public key if needed.
if (config.security.private_key.size == 32 && !memfll(config.security.private_key.bytes, 0, 32) &&
(config.security.public_key.size == 0 || memfll(config.security.public_key.bytes, 0, 32))) {
if (crypto->regeneratePublicKey(config.security.public_key.bytes, config.security.private_key.bytes)) {
config.security.public_key.size = 32;
}
}
#endif
owner.public_key.size = config.security.public_key.size;
memcpy(owner.public_key.bytes, config.security.public_key.bytes, config.security.public_key.size);
#if !MESHTASTIC_EXCLUDE_PKI
@@ -1030,4 +1019,4 @@ bool AdminModule::messageIsRequest(meshtastic_AdminMessage *r)
return true;
else
return false;
}
}

View File

@@ -190,17 +190,17 @@ int CannedMessageModule::handleInputEvent(const InputEvent *event)
#if defined(T_WATCH_S3) || defined(RAK14014)
if (event->inputEvent == static_cast<char>(meshtastic_ModuleConfig_CannedMessageConfig_InputEventChar_LEFT)) {
this->payload = INPUT_BROKER_MSG_LEFT;
this->payload = 0xb4;
} else if (event->inputEvent == static_cast<char>(meshtastic_ModuleConfig_CannedMessageConfig_InputEventChar_RIGHT)) {
this->payload = INPUT_BROKER_MSG_RIGHT;
this->payload = 0xb7;
}
#else
// tweak for left/right events generated via trackball/touch with empty kbchar
if (!event->kbchar) {
if (event->inputEvent == static_cast<char>(meshtastic_ModuleConfig_CannedMessageConfig_InputEventChar_LEFT)) {
this->payload = INPUT_BROKER_MSG_LEFT;
this->payload = 0xb4;
} else if (event->inputEvent == static_cast<char>(meshtastic_ModuleConfig_CannedMessageConfig_InputEventChar_RIGHT)) {
this->payload = INPUT_BROKER_MSG_RIGHT;
this->payload = 0xb7;
}
} else {
// pass the pressed key
@@ -222,26 +222,26 @@ int CannedMessageModule::handleInputEvent(const InputEvent *event)
// Run modifier key code below, (doesnt inturrupt typing or reset to start screen page)
switch (event->kbchar) {
case INPUT_BROKER_MSG_BRIGHTNESS_UP: // make screen brighter
case 0x11: // make screen brighter
if (screen)
screen->increaseBrightness();
LOG_DEBUG("increasing Screen Brightness\n");
break;
case INPUT_BROKER_MSG_BRIGHTNESS_DOWN: // make screen dimmer
case 0x12: // make screen dimmer
if (screen)
screen->decreaseBrightness();
LOG_DEBUG("Decreasing Screen Brightness\n");
break;
case INPUT_BROKER_MSG_FN_SYMBOL_ON: // draw modifier (function) symbal
case 0xf1: // draw modifier (function) symbal
if (screen)
screen->setFunctionSymbal("Fn");
break;
case INPUT_BROKER_MSG_FN_SYMBOL_OFF: // remove modifier (function) symbal
case 0xf2: // remove modifier (function) symbal
if (screen)
screen->removeFunctionSymbal("Fn");
break;
// mute (switch off/toggle) external notifications on fn+m
case INPUT_BROKER_MSG_MUTE_TOGGLE:
case 0xac:
if (moduleConfig.external_notification.enabled == true) {
if (externalNotificationModule->getMute()) {
externalNotificationModule->setMute(false);
@@ -257,7 +257,7 @@ int CannedMessageModule::handleInputEvent(const InputEvent *event)
}
}
break;
case INPUT_BROKER_MSG_GPS_TOGGLE: // toggle GPS like triple press does
case 0x9e: // toggle GPS like triple press does
#if !MESHTASTIC_EXCLUDE_GPS
if (gps != nullptr) {
gps->toggleGpsMode();
@@ -267,7 +267,7 @@ int CannedMessageModule::handleInputEvent(const InputEvent *event)
showTemporaryMessage("GPS Toggled");
#endif
break;
case INPUT_BROKER_MSG_SEND_PING: // fn+space send network ping like double press does
case 0xaf: // fn+space send network ping like double press does
service->refreshLocalMeshNode();
if (service->trySendPosition(NODENUM_BROADCAST, true)) {
showTemporaryMessage("Position \nUpdate Sent");
@@ -283,7 +283,7 @@ int CannedMessageModule::handleInputEvent(const InputEvent *event)
validEvent = true;
break;
}
if (screen && (event->kbchar != INPUT_BROKER_MSG_FN_SYMBOL_ON)) {
if (screen && (event->kbchar != 0xf1)) {
screen->removeFunctionSymbal("Fn"); // remove modifier (function) symbal
}
}
@@ -505,7 +505,7 @@ int32_t CannedMessageModule::runOnce()
}
} else if (this->runState == CANNED_MESSAGE_RUN_STATE_FREETEXT || this->runState == CANNED_MESSAGE_RUN_STATE_ACTIVE) {
switch (this->payload) {
case INPUT_BROKER_MSG_LEFT:
case 0xb4: // left
if (this->destSelect == CANNED_MESSAGE_DESTINATION_TYPE_NODE) {
size_t numMeshNodes = nodeDB->getNumMeshNodes();
if (this->dest == NODENUM_BROADCAST) {
@@ -540,7 +540,7 @@ int32_t CannedMessageModule::runOnce()
}
}
break;
case INPUT_BROKER_MSG_RIGHT:
case 0xb7: // right
if (this->destSelect == CANNED_MESSAGE_DESTINATION_TYPE_NODE) {
size_t numMeshNodes = nodeDB->getNumMeshNodes();
if (this->dest == NODENUM_BROADCAST) {
@@ -602,19 +602,19 @@ int32_t CannedMessageModule::runOnce()
this->destSelect = CANNED_MESSAGE_DESTINATION_TYPE_NODE;
}
break;
case INPUT_BROKER_MSG_LEFT:
case INPUT_BROKER_MSG_RIGHT:
case 0xb4: // left
case 0xb7: // right
// already handled above
break;
// handle fn+s for shutdown
case INPUT_BROKER_MSG_SHUTDOWN:
case 0x9b:
if (screen)
screen->startAlert("Shutting down...");
shutdownAtMsec = millis() + DEFAULT_SHUTDOWN_SECONDS * 1000;
runState = CANNED_MESSAGE_RUN_STATE_INACTIVE;
break;
// and fn+r for reboot
case INPUT_BROKER_MSG_REBOOT:
case 0x90:
if (screen)
screen->startAlert("Rebooting...");
rebootAtMsec = millis() + DEFAULT_REBOOT_SECONDS * 1000;

View File

@@ -223,4 +223,4 @@ class CannedMessageModule : public SinglePortModule, public Observable<const UIF
};
extern CannedMessageModule *cannedMessageModule;
#endif
#endif

View File

@@ -107,7 +107,6 @@ void NeighborInfoModule::sendNeighborInfo(NodeNum dest, bool wantReplies)
// because we want to get neighbors for the next cycle
p->to = dest;
p->decoded.want_response = wantReplies;
p->priority = meshtastic_MeshPacket_Priority_BACKGROUND;
printNeighborInfo("SENDING", &neighborInfo);
service->sendToMesh(p, RX_SRC_LOCAL, true);
}

View File

@@ -129,10 +129,6 @@ void PositionModule::trySetRtc(meshtastic_Position p, bool isLocal, bool forceUp
LOG_DEBUG("Ignoring time from mesh because we have a GPS, RTC, or Phone/NTP time source in the past day\n");
return;
}
if (!isLocal && p.location_source < meshtastic_Position_LocSource_LOC_INTERNAL) {
LOG_DEBUG("Ignoring time from mesh because it has a unknown or manual source\n");
return;
}
struct timeval tv;
uint32_t secs = p.time;
@@ -146,11 +142,7 @@ bool PositionModule::hasQualityTimesource()
{
bool setFromPhoneOrNtpToday =
lastSetFromPhoneNtpOrGps == 0 ? false : (millis() - lastSetFromPhoneNtpOrGps) <= (SEC_PER_DAY * 1000UL);
#if MESHTASTIC_EXCLUDE_GPS
bool hasGpsOrRtc = (rtc_found.address != ScanI2C::ADDRESS_NONE.address);
#else
bool hasGpsOrRtc = (gps && gps->isConnected()) || (rtc_found.address != ScanI2C::ADDRESS_NONE.address);
#endif
return hasGpsOrRtc || setFromPhoneOrNtpToday;
}
@@ -199,10 +191,6 @@ meshtastic_MeshPacket *PositionModule::allocReply()
p.has_longitude_i = true;
p.time = getValidTime(RTCQualityNTP) > 0 ? getValidTime(RTCQualityNTP) : localPosition.time;
if (config.position.fixed_position) {
p.location_source = meshtastic_Position_LocSource_LOC_MANUAL;
}
if (pos_flags & meshtastic_Config_PositionConfig_PositionFlags_ALTITUDE) {
if (pos_flags & meshtastic_Config_PositionConfig_PositionFlags_ALTITUDE_MSL) {
p.altitude = localPosition.altitude;

View File

@@ -100,9 +100,8 @@ meshtastic_Telemetry DeviceTelemetryModule::getDeviceTelemetry()
#if ARCH_PORTDUINO
t.variant.device_metrics.battery_level = MAGIC_USB_BATTERY_LEVEL;
#else
t.variant.device_metrics.battery_level = (!powerStatus->getHasBattery() || powerStatus->getIsCharging())
? MAGIC_USB_BATTERY_LEVEL
: powerStatus->getBatteryChargePercent();
t.variant.device_metrics.battery_level =
powerStatus->getIsCharging() ? MAGIC_USB_BATTERY_LEVEL : powerStatus->getBatteryChargePercent();
#endif
t.variant.device_metrics.channel_utilization = airTime->channelUtilizationPercent();
t.variant.device_metrics.voltage = powerStatus->getBatteryVoltageMv() / 1000.0;

View File

@@ -23,8 +23,6 @@
#include "Sensor/BME680Sensor.h"
#include "Sensor/BMP085Sensor.h"
#include "Sensor/BMP280Sensor.h"
#include "Sensor/BMP3XXSensor.h"
#include "Sensor/CustomI2CSensor.h"
#include "Sensor/DFRobotLarkSensor.h"
#include "Sensor/LPS22HBSensor.h"
#include "Sensor/MCP9808Sensor.h"
@@ -56,8 +54,6 @@ AHT10Sensor aht10Sensor;
MLX90632Sensor mlx90632Sensor;
DFRobotLarkSensor dfRobotLarkSensor;
NAU7802Sensor nau7802Sensor;
BMP3XXSensor bmp3xxSensor;
CustomI2CSensor customI2CSensor;
#ifdef T1000X_SENSOR_EN
T1000xSensor t1000xSensor;
#endif
@@ -84,7 +80,7 @@ int32_t EnvironmentTelemetryModule::runOnce()
*/
// moduleConfig.telemetry.environment_measurement_enabled = 1;
// moduleConfig.telemetry.environment_screen_enabled = 1;
// moduleConfig.telemetry.environment_screen_enabled = 1;
// moduleConfig.telemetry.environment_update_interval = 15;
if (!(moduleConfig.telemetry.environment_measurement_enabled || moduleConfig.telemetry.environment_screen_enabled)) {
@@ -111,8 +107,6 @@ int32_t EnvironmentTelemetryModule::runOnce()
result = bmp280Sensor.runOnce();
if (bme280Sensor.hasSensor())
result = bme280Sensor.runOnce();
if (bmp3xxSensor.hasSensor())
result = bmp3xxSensor.runOnce();
if (bme680Sensor.hasSensor())
result = bme680Sensor.runOnce();
if (mcp9808Sensor.hasSensor())
@@ -145,8 +139,6 @@ int32_t EnvironmentTelemetryModule::runOnce()
result = mlx90632Sensor.runOnce();
if (nau7802Sensor.hasSensor())
result = nau7802Sensor.runOnce();
if (customI2CSensor.hasSensor())
result = customI2CSensor.runOnce();
#endif
}
return result;
@@ -335,10 +327,6 @@ bool EnvironmentTelemetryModule::getEnvironmentTelemetry(meshtastic_Telemetry *m
valid = valid && bme280Sensor.getMetrics(m);
hasSensor = true;
}
if (bmp3xxSensor.hasSensor()) {
valid = valid && bmp3xxSensor.getMetrics(m);
hasSensor = true;
}
if (bme680Sensor.hasSensor()) {
valid = valid && bme680Sensor.getMetrics(m);
hasSensor = true;
@@ -384,27 +372,17 @@ bool EnvironmentTelemetryModule::getEnvironmentTelemetry(meshtastic_Telemetry *m
hasSensor = true;
}
if (aht10Sensor.hasSensor()) {
if (!bmp280Sensor.hasSensor() && !bmp3xxSensor.hasSensor()) {
if (!bmp280Sensor.hasSensor()) {
valid = valid && aht10Sensor.getMetrics(m);
hasSensor = true;
} else if (bmp280Sensor.hasSensor()) {
} else {
// prefer bmp280 temp if both sensors are present, fetch only humidity
meshtastic_Telemetry m_ahtx = meshtastic_Telemetry_init_zero;
LOG_INFO("AHTX0+BMP280 module detected: using temp from BMP280 and humy from AHTX0\n");
aht10Sensor.getMetrics(&m_ahtx);
m->variant.environment_metrics.relative_humidity = m_ahtx.variant.environment_metrics.relative_humidity;
} else {
// prefer bmp3xx temp if both sensors are present, fetch only humidity
meshtastic_Telemetry m_ahtx = meshtastic_Telemetry_init_zero;
LOG_INFO("AHTX0+BMP3XX module detected: using temp from BMP3XX and humy from AHTX0\n");
aht10Sensor.getMetrics(&m_ahtx);
m->variant.environment_metrics.relative_humidity = m_ahtx.variant.environment_metrics.relative_humidity;
}
}
if (customI2CSensor.hasSensor()) {
valid = valid && customI2CSensor.getMetrics(m);
hasSensor = true;
}
#endif
return valid && hasSensor;
@@ -530,11 +508,6 @@ AdminMessageHandleResult EnvironmentTelemetryModule::handleAdminMessageForModule
if (result != AdminMessageHandleResult::NOT_HANDLED)
return result;
}
if (bmp3xxSensor.hasSensor()) {
result = bmp3xxSensor.handleAdminMessage(mp, request, response);
if (result != AdminMessageHandleResult::NOT_HANDLED)
return result;
}
if (bme680Sensor.hasSensor()) {
result = bme680Sensor.handleAdminMessage(mp, request, response);
if (result != AdminMessageHandleResult::NOT_HANDLED)

View File

@@ -1,89 +0,0 @@
#include "configuration.h"
#if !MESHTASTIC_EXCLUDE_ENVIRONMENTAL_SENSOR
#include "BMP3XXSensor.h"
BMP3XXSensor::BMP3XXSensor() : TelemetrySensor(meshtastic_TelemetrySensorType_BMP3XX, "BMP3XX") {}
void BMP3XXSensor::setup() {}
int32_t BMP3XXSensor::runOnce()
{
LOG_INFO("Init sensor: %s\n", sensorName);
if (!hasSensor()) {
return DEFAULT_SENSOR_MINIMUM_WAIT_TIME_BETWEEN_READS;
}
// Get a singleton instance and initialise the bmp3xx
if (bmp3xx == nullptr) {
bmp3xx = BMP3XXSingleton::GetInstance();
}
status = bmp3xx->begin_I2C(nodeTelemetrySensorsMap[sensorType].first, nodeTelemetrySensorsMap[sensorType].second);
// set up oversampling and filter initialization
bmp3xx->setTemperatureOversampling(BMP3_OVERSAMPLING_4X);
bmp3xx->setPressureOversampling(BMP3_OVERSAMPLING_8X);
bmp3xx->setIIRFilterCoeff(BMP3_IIR_FILTER_COEFF_3);
bmp3xx->setOutputDataRate(BMP3_ODR_25_HZ);
// take a couple of initial readings to settle the sensor filters
for (int i = 0; i < 3; i++) {
bmp3xx->performReading();
}
return initI2CSensor();
}
bool BMP3XXSensor::getMetrics(meshtastic_Telemetry *measurement)
{
if (bmp3xx == nullptr) {
bmp3xx = BMP3XXSingleton::GetInstance();
}
if ((int)measurement->which_variant == meshtastic_Telemetry_environment_metrics_tag) {
bmp3xx->performReading();
measurement->variant.environment_metrics.has_temperature = true;
measurement->variant.environment_metrics.has_barometric_pressure = true;
measurement->variant.environment_metrics.has_relative_humidity = false;
measurement->variant.environment_metrics.temperature = static_cast<float>(bmp3xx->temperature);
measurement->variant.environment_metrics.barometric_pressure = static_cast<float>(bmp3xx->pressure) / 100.0F;
measurement->variant.environment_metrics.relative_humidity = 0.0f;
LOG_DEBUG("BMP3XXSensor::getMetrics id: %i temp: %.1f press %.1f\n", measurement->which_variant,
measurement->variant.environment_metrics.temperature,
measurement->variant.environment_metrics.barometric_pressure);
} else {
LOG_DEBUG("BMP3XXSensor::getMetrics id: %i\n", measurement->which_variant);
}
return true;
}
// Get a singleton wrapper for an Adafruit_bmp3xx
BMP3XXSingleton *BMP3XXSingleton::GetInstance()
{
if (pinstance == nullptr) {
pinstance = new BMP3XXSingleton();
}
return pinstance;
}
BMP3XXSingleton::BMP3XXSingleton() {}
BMP3XXSingleton::~BMP3XXSingleton() {}
BMP3XXSingleton *BMP3XXSingleton::pinstance{nullptr};
bool BMP3XXSingleton::performReading()
{
bool result = Adafruit_BMP3XX::performReading();
if (result) {
double atmospheric = this->pressure / 100.0;
altitudeAmslMetres = 44330.0 * (1.0 - pow(atmospheric / SEAL_LEVEL_HPA, 0.1903));
} else {
altitudeAmslMetres = 0.0;
}
return result;
}
#endif

View File

@@ -1,56 +0,0 @@
#include "configuration.h"
#if !MESHTASTIC_EXCLUDE_ENVIRONMENTAL_SENSOR
#ifndef _BMP3XX_SENSOR_H
#define _BMP3XX_SENSOR_H
#define SEAL_LEVEL_HPA 1013.2f
#include "TelemetrySensor.h"
#include <Adafruit_BMP3XX.h>
#include <typeinfo>
// Singleton wrapper for the Adafruit_BMP3XX class
class BMP3XXSingleton : public Adafruit_BMP3XX
{
private:
static BMP3XXSingleton *pinstance;
protected:
BMP3XXSingleton();
~BMP3XXSingleton();
public:
// Create a singleton instance (not thread safe)
static BMP3XXSingleton *GetInstance();
// Singletons should not be cloneable.
BMP3XXSingleton(BMP3XXSingleton &other) = delete;
// Singletons should not be assignable.
void operator=(const BMP3XXSingleton &) = delete;
// Performs a full reading of all sensors in the BMP3XX. Assigns
// the internal temperature, pressure and altitudeAmsl variables
bool performReading();
// Altitude in metres above mean sea level, assigned after calling performReading()
double altitudeAmslMetres = 0.0f;
};
class BMP3XXSensor : public TelemetrySensor
{
protected:
BMP3XXSingleton *bmp3xx = nullptr;
virtual void setup() override;
public:
BMP3XXSensor();
virtual int32_t runOnce() override;
virtual bool getMetrics(meshtastic_Telemetry *measurement) override;
};
#endif
#endif

View File

@@ -1,107 +0,0 @@
#include "configuration.h"
#if !MESHTASTIC_EXCLUDE_ENVIRONMENTAL_SENSOR
#include "../mesh/generated/meshtastic/telemetry.pb.h"
#include "CustomI2CSensor.h"
#include "I2CClient.h"
#include "I2CDefinitions.h"
#include "TelemetrySensor.h"
CustomI2CSensor::CustomI2CSensor() : TelemetrySensor(meshtastic_TelemetrySensorType_CUSTOM_SENSOR, "CUSTOM") {}
int32_t CustomI2CSensor::runOnce()
{
LOG_INFO("Init sensor: %s\n", sensorName);
if (!hasSensor()) {
return DEFAULT_SENSOR_MINIMUM_WAIT_TIME_BETWEEN_READS;
} else {
status = 1;
}
return initI2CSensor();
}
void CustomI2CSensor::setup()
{
// populates lastMetricsRecieved when data is received
Wire.requestFrom(MT_I2C_ADDRESS, meshtastic_EnvironmentMetrics_size);
Wire.onReceive(onReceiveMetrics);
}
bool CustomI2CSensor::getMetrics(meshtastic_Telemetry *measurement)
{
// Wire.requestFrom(MT_I2C_ADDRESS, meshtastic_EnvironmentMetrics_size);
// auto length = Wire.available();
// LOG_DEBUG("CustomI2CSensor::getMetrics=%d\n", length);
// uint8_t buffer[meshtastic_EnvironmentMetrics_size];
// Wire.readBytes(buffer, length);
// meshtastic_EnvironmentMetrics metrics = meshtastic_EnvironmentMetrics_init_zero;
// proto_decode(buffer, meshtastic_EnvironmentMetrics_size, meshtastic_EnvironmentMetrics_fields, &metrics);
measurement->which_variant = meshtastic_Telemetry_environment_metrics_tag;
if (lastMetricsRecieved.has_temperature) {
measurement->variant.environment_metrics.has_temperature = true;
measurement->variant.environment_metrics.temperature = lastMetricsRecieved.temperature;
}
if (lastMetricsRecieved.has_relative_humidity) {
measurement->variant.environment_metrics.has_relative_humidity = true;
measurement->variant.environment_metrics.relative_humidity = lastMetricsRecieved.relative_humidity;
}
if (lastMetricsRecieved.has_barometric_pressure) {
measurement->variant.environment_metrics.has_barometric_pressure = true;
measurement->variant.environment_metrics.barometric_pressure = lastMetricsRecieved.barometric_pressure;
}
if (lastMetricsRecieved.has_gas_resistance) {
measurement->variant.environment_metrics.has_gas_resistance = true;
measurement->variant.environment_metrics.gas_resistance = lastMetricsRecieved.gas_resistance;
}
if (lastMetricsRecieved.has_iaq) {
measurement->variant.environment_metrics.has_iaq = true;
measurement->variant.environment_metrics.iaq = lastMetricsRecieved.iaq;
}
if (lastMetricsRecieved.has_voltage) {
measurement->variant.environment_metrics.has_voltage = true;
measurement->variant.environment_metrics.voltage = lastMetricsRecieved.voltage;
}
if (lastMetricsRecieved.has_current) {
measurement->variant.environment_metrics.has_current = true;
measurement->variant.environment_metrics.current = lastMetricsRecieved.current;
}
if (lastMetricsRecieved.has_distance) {
measurement->variant.environment_metrics.has_distance = true;
measurement->variant.environment_metrics.distance = lastMetricsRecieved.distance;
}
if (lastMetricsRecieved.has_lux) {
measurement->variant.environment_metrics.has_lux = true;
measurement->variant.environment_metrics.lux = lastMetricsRecieved.lux;
}
if (lastMetricsRecieved.has_white_lux) {
measurement->variant.environment_metrics.has_white_lux = true;
measurement->variant.environment_metrics.white_lux = lastMetricsRecieved.white_lux;
}
if (lastMetricsRecieved.has_ir_lux) {
measurement->variant.environment_metrics.has_ir_lux = true;
measurement->variant.environment_metrics.ir_lux = lastMetricsRecieved.ir_lux;
}
if (lastMetricsRecieved.has_uv_lux) {
measurement->variant.environment_metrics.has_uv_lux = true;
measurement->variant.environment_metrics.uv_lux = lastMetricsRecieved.uv_lux;
}
if (lastMetricsRecieved.has_wind_direction) {
measurement->variant.environment_metrics.has_wind_direction = true;
measurement->variant.environment_metrics.wind_direction = lastMetricsRecieved.wind_direction;
}
if (lastMetricsRecieved.has_wind_speed) {
measurement->variant.environment_metrics.has_wind_speed = true;
measurement->variant.environment_metrics.wind_speed = lastMetricsRecieved.wind_speed;
}
if (lastMetricsRecieved.has_wind_lull) {
measurement->variant.environment_metrics.has_wind_lull = true;
measurement->variant.environment_metrics.wind_lull = lastMetricsRecieved.wind_lull;
}
return true;
}
#endif

View File

@@ -1,19 +0,0 @@
#include "configuration.h"
#if !MESHTASTIC_EXCLUDE_ENVIRONMENTAL_SENSOR
#include "../mesh/generated/meshtastic/telemetry.pb.h"
#include "TelemetrySensor.h"
class CustomI2CSensor : public TelemetrySensor
{
protected:
virtual void setup() override;
public:
CustomI2CSensor();
virtual int32_t runOnce() override;
virtual bool getMetrics(meshtastic_Telemetry *measurement) override;
};
#endif

View File

@@ -167,9 +167,9 @@ void MQTT::onReceive(char *topic, byte *payload, size_t length)
strcmp(e.channel_id, "PKI") == 0) {
meshtastic_NodeInfoLite *tx = nodeDB->getMeshNode(getFrom(p));
meshtastic_NodeInfoLite *rx = nodeDB->getMeshNode(p->to);
// Only accept PKI messages to us, or if we have both the sender and receiver in our nodeDB, as then it's
// likely they discovered each other via a channel we have downlink enabled for
if (p->to == nodeDB->getNodeNum() || (tx && tx->has_user && rx && rx->has_user))
// Only accept PKI messages if we have both the sender and receiver in our nodeDB, as then it's likely
// they discovered each other via a channel we have downlink enabled for
if (tx && tx->has_user && rx && rx->has_user)
router->enqueueReceivedMessage(p);
} else if (router && perhapsDecode(p)) // ignore messages if we don't have the channel key
router->enqueueReceivedMessage(p);
@@ -514,30 +514,20 @@ void MQTT::onSend(const meshtastic_MeshPacket &mp, const meshtastic_MeshPacket &
return; // no channels have an uplink enabled
auto &ch = channels.getByIndex(chIndex);
if (!mp.pki_encrypted) {
if (mp_decoded.which_payload_variant != meshtastic_MeshPacket_decoded_tag) {
LOG_CRIT("MQTT::onSend(): mp_decoded isn't actually decoded\n");
return;
}
// check for the lowest bit of the data bitfield set false, and the use of one of the default keys.
if (mp_decoded.from != nodeDB->getNodeNum() && mp_decoded.decoded.has_bitfield &&
!(mp_decoded.decoded.bitfield & BITFIELD_OK_TO_MQTT_MASK) &&
(ch.settings.psk.size < 2 || (ch.settings.psk.size == 16 && memcmp(ch.settings.psk.bytes, defaultpsk, 16)) ||
(ch.settings.psk.size == 32 && memcmp(ch.settings.psk.bytes, eventpsk, 32)))) {
LOG_INFO("MQTT onSend - Not forwarding packet due to DontMqttMeBro flag\n");
return;
}
if (strcmp(moduleConfig.mqtt.address, default_mqtt_address) == 0 &&
(mp_decoded.decoded.portnum == meshtastic_PortNum_RANGE_TEST_APP ||
mp_decoded.decoded.portnum == meshtastic_PortNum_DETECTION_SENSOR_APP)) {
LOG_DEBUG("MQTT onSend - Ignoring range test or detection sensor message on public mqtt\n");
return;
}
if (mp_decoded.which_payload_variant != meshtastic_MeshPacket_decoded_tag) {
LOG_CRIT("MQTT::onSend(): mp_decoded isn't actually decoded\n");
return;
}
if (mp.pki_encrypted || ch.settings.uplink_enabled) {
const char *channelId = mp.pki_encrypted ? "PKI" : channels.getGlobalId(chIndex);
if (strcmp(moduleConfig.mqtt.address, default_mqtt_address) == 0 &&
(mp_decoded.decoded.portnum == meshtastic_PortNum_RANGE_TEST_APP ||
mp_decoded.decoded.portnum == meshtastic_PortNum_DETECTION_SENSOR_APP)) {
LOG_DEBUG("MQTT onSend - Ignoring range test or detection sensor message on public mqtt\n");
return;
}
if (ch.settings.uplink_enabled || mp.pki_encrypted) {
const char *channelId = channels.getGlobalId(chIndex); // FIXME, for now we just use the human name for the channel
meshtastic_ServiceEnvelope *env = mqttPool.allocZeroed();
env->channel_id = (char *)channelId;
@@ -547,8 +537,7 @@ void MQTT::onSend(const meshtastic_MeshPacket &mp, const meshtastic_MeshPacket &
if (moduleConfig.mqtt.encryption_enabled) {
env->packet = (meshtastic_MeshPacket *)&mp;
LOG_DEBUG("encrypted message\n");
} else if (mp_decoded.which_payload_variant ==
meshtastic_MeshPacket_decoded_tag) { // Don't upload a still-encrypted PKI packet
} else {
env->packet = (meshtastic_MeshPacket *)&mp_decoded;
LOG_DEBUG("portnum %i message\n", env->packet->decoded.portnum);
}
@@ -557,7 +546,12 @@ void MQTT::onSend(const meshtastic_MeshPacket &mp, const meshtastic_MeshPacket &
// FIXME - this size calculation is super sloppy, but it will go away once we dynamically alloc meshpackets
static uint8_t bytes[meshtastic_MeshPacket_size + 64];
size_t numBytes = pb_encode_to_bytes(bytes, sizeof(bytes), &meshtastic_ServiceEnvelope_msg, env);
std::string topic = cryptTopic + channelId + "/" + owner.id;
std::string topic;
if (mp.pki_encrypted) {
topic = cryptTopic + "PKI/" + owner.id;
} else {
topic = cryptTopic + channelId + "/" + owner.id;
}
LOG_DEBUG("MQTT Publish %s, %u bytes\n", topic.c_str(), numBytes);
publish(topic.c_str(), bytes, numBytes, false);
@@ -567,7 +561,12 @@ void MQTT::onSend(const meshtastic_MeshPacket &mp, const meshtastic_MeshPacket &
// handle json topic
auto jsonString = MeshPacketSerializer::JsonSerialize((meshtastic_MeshPacket *)&mp_decoded);
if (jsonString.length() != 0) {
std::string topicJson = jsonTopic + channelId + "/" + owner.id;
std::string topicJson;
if (mp.pki_encrypted) {
topicJson = jsonTopic + "PKI/" + owner.id;
} else {
topicJson = jsonTopic + channelId + "/" + owner.id;
}
LOG_INFO("JSON publish message to %s, %u bytes: %s\n", topicJson.c_str(), jsonString.length(),
jsonString.c_str());
publish(topicJson.c_str(), jsonString.c_str(), false);

View File

@@ -122,8 +122,6 @@
#define HW_VENDOR meshtastic_HardwareModel_HELTEC_WIRELESS_PAPER
#elif defined(TLORA_T3S3_V1)
#define HW_VENDOR meshtastic_HardwareModel_TLORA_T3_S3
#elif defined(TLORA_T3S3_EPAPER)
#define HW_VENDOR meshtastic_HardwareModel_TLORA_T3_S3
#elif defined(CDEBYTE_EORA_S3)
#define HW_VENDOR meshtastic_HardwareModel_CDEBYTE_EORA_S3
#elif defined(BETAFPV_2400_TX)

View File

@@ -1,15 +0,0 @@
# About extra_variants
This directory tree is designed to solve two problems.
- The ESP32 arduino/platformio project doesn't support the nice "if initVariant() is found, call that after init" behavior of the nrf52 builds (they use initVariant() internally).
- Over the years a lot of 'board specific' init code has been added to init() in main.cpp. It would be great to have a general/clean mechanism to allow developers to specify board specific/unique code in a clean fashion without mucking in main.
So we are borrowing the initVariant() ideas here (by using weak gcc references). You can now define lateInitVariant() if your board needs it.
If you'd like a board specific variant to be run, add the variant.cpp file to an appropriately named
subdirectory and check for \_VARIANT_boardname in the cpp file (so that your code is only built for your board).
You'll need to define \_VARIANT_boardname in your corresponding variant.h file.
See existing boards for examples.
This approach has no added runtime cost.

View File

@@ -1,34 +0,0 @@
#include "configuration.h"
#ifdef _VARIANT_HELTEC_WIRELESS_TRACKER
#include "GPS.h"
#include "GpioLogic.h"
#include "graphics/TFTDisplay.h"
// Heltec tracker specific init
void lateInitVariant()
{
// LOG_DEBUG("Heltec tracker initVariant\n");
#ifdef VEXT_ENABLE
GpioPin *hwEnable = new GpioHwPin(VEXT_ENABLE);
GpioVirtPin *virtGpsEnable = gps ? gps->enablePin : new GpioVirtPin();
// On this board we are actually using the backlightEnable signal to already be controlling a physical enable to the
// display controller. But we'd _ALSO_ like to have that signal drive a virtual GPIO. So nest it as needed.
GpioVirtPin *virtScreenEnable = new GpioVirtPin();
if (TFTDisplay::backlightEnable) {
GpioPin *physScreenEnable = TFTDisplay::backlightEnable;
GpioPin *splitter = new GpioSplitter(virtScreenEnable, physScreenEnable);
TFTDisplay::backlightEnable = splitter;
// Assume screen is initially powered
splitter->set(true);
}
// If either the GPS or the screen is on, turn on the external power regulator
new GpioBinaryTransformer(virtGpsEnable, virtScreenEnable, hwEnable, GpioBinaryTransformer::Or);
#endif
}
#endif

View File

@@ -67,8 +67,6 @@
#define HW_VENDOR meshtastic_HardwareModel_TRACKER_T1000_E
#elif defined(ME25LS01_4Y10TD)
#define HW_VENDOR meshtastic_HardwareModel_ME25LS01_4Y10TD
#elif defined(MS24SF1)
#define HW_VENDOR meshtastic_HardwareModel_MS24SF1
#elif defined(PRIVATE_HW) || defined(FEATHER_DIY)
#define HW_VENDOR meshtastic_HardwareModel_PRIVATE_HW
#else

View File

@@ -7,6 +7,7 @@
#include <Utility.h>
#include <assert.h>
#include <time.h>
#include "PortduinoGlue.h"
#include "linux/gpio/LinuxGPIOPin.h"
@@ -369,7 +370,6 @@ void portduinoSetup()
exit(EXIT_FAILURE);
}
}
return;
}

View File

@@ -29,6 +29,4 @@
#define HW_VENDOR meshtastic_HardwareModel_SENSELORA_RP2040
#elif defined(RP2040_LORA)
#define HW_VENDOR meshtastic_HardwareModel_RP2040_LORA
#elif defined(RP2040_FEATHER_RFM95)
#define HW_VENDOR meshtastic_HardwareModel_RP2040_FEATHER_RFM95
#endif

View File

@@ -76,13 +76,6 @@ std::string MeshPacketSerializer::JsonSerialize(const meshtastic_MeshPacket *mp,
msgPayload["wind_direction"] = new JSONValue((uint)decoded->variant.environment_metrics.wind_direction);
msgPayload["wind_gust"] = new JSONValue(decoded->variant.environment_metrics.wind_gust);
msgPayload["wind_lull"] = new JSONValue(decoded->variant.environment_metrics.wind_lull);
} else if (decoded->which_variant == meshtastic_Telemetry_air_quality_metrics_tag) {
msgPayload["pm10"] = new JSONValue((unsigned int)decoded->variant.air_quality_metrics.pm10_standard);
msgPayload["pm25"] = new JSONValue((unsigned int)decoded->variant.air_quality_metrics.pm25_standard);
msgPayload["pm100"] = new JSONValue((unsigned int)decoded->variant.air_quality_metrics.pm100_standard);
msgPayload["pm10_e"] = new JSONValue((unsigned int)decoded->variant.air_quality_metrics.pm10_environmental);
msgPayload["pm25_e"] = new JSONValue((unsigned int)decoded->variant.air_quality_metrics.pm25_environmental);
msgPayload["pm100_e"] = new JSONValue((unsigned int)decoded->variant.air_quality_metrics.pm100_environmental);
} else if (decoded->which_variant == meshtastic_Telemetry_power_metrics_tag) {
msgPayload["voltage_ch1"] = new JSONValue(decoded->variant.power_metrics.ch1_voltage);
msgPayload["current_ch1"] = new JSONValue(decoded->variant.power_metrics.ch1_current);

Some files were not shown because too many files have changed in this diff Show More