diff --git a/.devcontainer/Dockerfile b/.devcontainer/Dockerfile deleted file mode 100644 index e44b86089..000000000 --- a/.devcontainer/Dockerfile +++ /dev/null @@ -1,11 +0,0 @@ -# See here for image contents: https://github.com/microsoft/vscode-dev-containers/tree/v0.162.0/containers/ubuntu/.devcontainer/base.Dockerfile - -# [Choice] Ubuntu version: bionic, focal -ARG VARIANT="focal" -FROM mcr.microsoft.com/vscode/devcontainers/base:0-${VARIANT} - -# [Optional] Uncomment this section to install additional OS packages. -RUN apt-get update && export DEBIAN_FRONTEND=noninteractive \ - && apt-get -y install python3-distutils python3-pip -RUN pip3 install platformio meshtastic adafruit-nrfutil -RUN wget https://github.com/protocolbuffers/protobuf/releases/download/v3.15.8/protoc-3.15.8-linux-x86_64.zip -O /tmp/protoc.zip && cd /tmp && unzip protoc.zip && chmod a+x bin/protoc && cp bin/protoc /usr/local/bin diff --git a/.devcontainer/devcontainer.json b/.devcontainer/devcontainer.json deleted file mode 100644 index e0a284e88..000000000 --- a/.devcontainer/devcontainer.json +++ /dev/null @@ -1,32 +0,0 @@ -// For format details, see https://aka.ms/devcontainer.json. For config options, see the README at: -// https://github.com/microsoft/vscode-dev-containers/tree/v0.162.0/containers/ubuntu -{ - "name": "Ubuntu", - "build": { - "dockerfile": "Dockerfile", - // Update 'VARIANT' to pick an Ubuntu version: focal, bionic - "args": { "VARIANT": "focal" } - }, - - // Set *default* container specific settings.json values on container create. - "settings": { - "terminal.integrated.shell.linux": "/bin/bash" - }, - - // Add the IDs of extensions you want installed when the container is created. - "extensions": [ - "platformio.platformio-ide", - "xaver.clang-format" - ], - - // Use 'forwardPorts' to make a list of ports inside the container available locally. - // "forwardPorts": [], - - // Use 'postCreateCommand' to run commands after the container is created. - // "postCreateCommand": "uname -a", - - // Comment out connect as root instead. More info: https://aka.ms/vscode-remote/containers/non-root. - "remoteUser": "vscode", - - "postCreateCommand": "git submodule update --init" -} \ No newline at end of file diff --git a/.github/workflows/main_matrix.yml b/.github/workflows/main_matrix.yml index 8e7331a40..4c23011ac 100644 --- a/.github/workflows/main_matrix.yml +++ b/.github/workflows/main_matrix.yml @@ -1,4 +1,4 @@ -name: Continuous Integration +name: CI on: # # Triggers the workflow on push but only for the master branch push: diff --git a/.github/workflows/update_protobufs.yml b/.github/workflows/update_protobufs.yml index 2791f65e1..59e4d94bc 100644 --- a/.github/workflows/update_protobufs.yml +++ b/.github/workflows/update_protobufs.yml @@ -13,7 +13,7 @@ jobs: - name: Update submodule run: | - git submodule update --remote proto + git submodule update --remote protobufs - name: Download nanopb run: | @@ -29,5 +29,5 @@ jobs: uses: peter-evans/create-pull-request@v3 with: add-paths: | - proto + protobufs src/mesh diff --git a/.gitmodules b/.gitmodules index 59efcedd3..489f01bea 100644 --- a/.gitmodules +++ b/.gitmodules @@ -1,6 +1,3 @@ -[submodule "proto"] - path = proto +[submodule "protobufs"] + path = protobufs url = https://github.com/meshtastic/Meshtastic-protobufs.git -[submodule "design"] - path = design - url = https://github.com/meshtastic/meshtastic-design.git diff --git a/.vscode/settings.json b/.vscode/settings.json index 4a61ccd24..c2bc7b28c 100644 --- a/.vscode/settings.json +++ b/.vscode/settings.json @@ -73,10 +73,5 @@ "cmake.configureOnOpen": true, "protoc": { "compile_on_save": false, - "compile_all_path": "/home/kevinh/development/meshtastic/meshtastic-esp32/proto", - "options": [ - "--java_out=/tmp", - "-I=/home/kevinh/development/meshtastic/meshtastic-esp32/proto" - ] } } \ No newline at end of file diff --git a/Dockerfile b/Dockerfile deleted file mode 100644 index 146ff8878..000000000 --- a/Dockerfile +++ /dev/null @@ -1,16 +0,0 @@ -FROM ubuntu -MAINTAINER Kevin Hester - -RUN apt-get update -RUN DEBIAN_FRONTEND=noninteractive TZ=Etc/UTC apt-get -y install wget python3 g++ zip python3-venv git vim -RUN wget https://raw.githubusercontent.com/platformio/platformio-core-installer/master/get-platformio.py -O get-platformio.py; chmod +x get-platformio.py -RUN python3 get-platformio.py -RUN git clone https://github.com/meshtastic/Meshtastic-device.git -RUN cd Meshtastic-device; git submodule update --init --recursive -# only build the simulator -RUN sed -i 's/^BOARDS_ESP32.*/BOARDS_ESP32=""/' Meshtastic-device/bin/build-all.sh -RUN sed -i 's/^BOARDS_NRF52.*/BOARDS_NRF52=""/' Meshtastic-device/bin/build-all.sh -RUN sed -i 's/echo "Building Filesystem.*/exit/' Meshtastic-device/bin/build-all.sh -RUN . ~/.platformio/penv/bin/activate; cd Meshtastic-device; ./bin/build-all.sh - -CMD ["/Meshtastic-device/release/latest/bins/universal/meshtasticd_linux_amd64"] diff --git a/README.md b/README.md index 4876607e4..39aebf9d7 100644 --- a/README.md +++ b/README.md @@ -1,23 +1,18 @@ -# Meshtastic-device -[![Open in Visual Studio Code](https://open.vscode.dev/badges/open-in-vscode.svg)](https://open.vscode.dev/meshtastic/Meshtastic-device) -[![Continuous Integration](https://github.com/meshtastic/Meshtastic-device/actions/workflows/main_matrix.yml/badge.svg)](https://github.com/meshtastic/Meshtastic-device/actions/workflows/main_matrix.yml) -![GitHub all releases](https://img.shields.io/github/downloads/meshtastic/meshtastic-device/total) +# Meshtastic Firmware + +![GitHub release downloads](https://img.shields.io/github/downloads/meshtastic/meshtastic-device/total) +[![CI](https://img.shields.io/github/workflow/status/meshtastic/Meshtastic-device/CI?label=actions&logo=github&color=yellow)](https://github.com/meshtastic/repo/actions/workflows/main_matrix.yml) [![CLA assistant](https://cla-assistant.io/readme/badge/meshtastic/Meshtastic-device)](https://cla-assistant.io/meshtastic/Meshtastic-device) -[![Fiscal Contributors](https://opencollective.com/meshtastic/tiers/badge.svg)](https://opencollective.com/meshtastic/) +[![Fiscal Contributors](https://opencollective.com/meshtastic/tiers/badge.svg?label=Fiscal%20Contributors&color=deeppink)](https://opencollective.com/meshtastic/) +[![Vercel](https://img.shields.io/static/v1?label=Powered%20by&message=Vercel&style=flat&logo=vercel&color=000000)](https://vercel.com?utm_source=meshtastic&utm_campaign=oss) -## This repository contains the device firmware used in the [Meshtastic](https://meshtastic.org) project. +## Overview -Update Instructions +This repository contains the device firmware for the Meshtastic project. -[Using Meshtastic Flasher](https://meshtastic.org/docs/getting-started/meshtastic-flasher) -Manual Method - -[For ESP32 devices click here](https://meshtastic.org/docs/getting-started/flashing-esp32) - -[For nRF52 devices click here](https://meshtastic.org/docs/getting-started/flashing-nrf52) - -For developer information and specific building instructions, please see the [developer documentation](https://meshtastic.org/docs/developers) +**[Building Instructions](https://meshtastic.org/docs/developers/Firmware/build)** +**[Flashing Instructions](https://meshtastic.org/docs/getting-started/flashing-firmware/)** ## Stats diff --git a/bin/regen-protos.bat b/bin/regen-protos.bat index 39e1f3507..158991414 100644 --- a/bin/regen-protos.bat +++ b/bin/regen-protos.bat @@ -1 +1 @@ -cd proto && ..\nanopb-0.4.5\generator-bin\protoc.exe --nanopb_out=-v:..\src\mesh\generated -I=..\proto *.proto +cd protobufs && ..\nanopb-0.4.5\generator-bin\protoc.exe --nanopb_out=-v:..\src\mesh\generated -I=..\protobufs *.proto diff --git a/bin/regen-protos.sh b/bin/regen-protos.sh index 9f3e33127..0f46d270b 100755 --- a/bin/regen-protos.sh +++ b/bin/regen-protos.sh @@ -7,8 +7,8 @@ echo "meshtastic-device root directory if the following step fails, you should d echo "prebuilt binaries for your computer into nanopb-0.4.5" # the nanopb tool seems to require that the .options file be in the current directory! -cd proto -../nanopb-0.4.5/generator-bin/protoc --nanopb_out=-v:../src/mesh/generated -I=../proto *.proto +cd protobufs +../nanopb-0.4.5/generator-bin/protoc --nanopb_out=-v:../src/mesh/generated -I=../protobufs *.proto #echo "Regenerating protobuf documentation - if you see an error message" #echo "you can ignore it unless doing a new protobuf release to github." diff --git a/design b/design deleted file mode 160000 index 73ba05cee..000000000 --- a/design +++ /dev/null @@ -1 +0,0 @@ -Subproject commit 73ba05ceef8beff81eb546a0b9e8ecad03a1216d diff --git a/platformio.ini b/platformio.ini index bb051e5e2..392f996ea 100644 --- a/platformio.ini +++ b/platformio.ini @@ -35,6 +35,7 @@ build_flags = -Wno-missing-field-initializers -Isrc -Isrc/mesh -Isrc/gps -Isrc/buzz -Wl,-Map,.pio/build/output.map -DUSE_THREAD_NAMES -DTINYGPS_OPTION_NO_CUSTOM_FIELDS + -DPB_ENABLE_MALLOC=1 monitor_speed = 921600 @@ -43,13 +44,12 @@ lib_deps = mathertel/OneButton@^2.0.3 ; OneButton library for non-blocking button debounce 1202 ; CRC32, explicitly needed because dependency is missing in the ble ota update lib https://github.com/meshtastic/arduino-fsm.git - https://github.com/meshtastic/SparkFun_Ublox_Arduino_Library.git#31015a55e630a2df77d9d714669c621a5bf355ad https://github.com/meshtastic/RadioLib.git#5582ac30578ff3f53f20630a00b2a8a4b8f92c74 https://github.com/meshtastic/TinyGPSPlus.git https://github.com/meshtastic/AXP202X_Library.git#8404abb6d4b486748636bc6ad72d2a47baaf5460 Wire ; explicitly needed here because the AXP202 library forgets to add it SPI - https://github.com/geeksville/ArduinoThread.git#72921ac222eed6f526ba1682023cee290d9aa1b3 + https://github.com/meshtastic/ArduinoThread.git#72921ac222eed6f526ba1682023cee290d9aa1b3 PubSubClient nanopb/Nanopb@^0.4.6 meshtastic/json11@^1.0.2 @@ -65,11 +65,12 @@ lib_deps = ${env.lib_deps} build_flags = ${env.build_flags} -Os # -DRADIOLIB_GODMODE -src_filter = ${env.src_filter} - +build_src_filter = ${env.build_src_filter} - ; Common libs for environmental measurements (not included in native / portduino) [environmental] lib_deps = + adafruit/Adafruit BusIO@^1.11.4 adafruit/DHT sensor library@^1.4.1 adafruit/Adafruit Unified Sensor@^1.1.4 paulstoffregen/OneWire@^2.3.5 @@ -82,8 +83,8 @@ lib_deps = [esp32_base] extends = arduino_base platform = espressif32@3.5.0 -src_filter = - ${arduino_base.src_filter} - +build_src_filter = + ${arduino_base.build_src_filter} - upload_speed = 921600 debug_init_break = tbreak setup # Remove -DMYNEWT_VAL_BLE_HS_LOG_LVL=LOG_LEVEL_CRITICAL for low level BLE logging. @@ -130,8 +131,8 @@ build_type = debug ; I'm debugging with ICE a lot now build_flags = ${arduino_base.build_flags} -Wno-unused-variable -Isrc/nrf52 -src_filter = - ${arduino_base.src_filter} - - - - - - +build_src_filter = + ${arduino_base.build_src_filter} - - - - - - lib_ignore = BluetoothOTA diff --git a/proto b/proto deleted file mode 160000 index a578453b3..000000000 --- a/proto +++ /dev/null @@ -1 +0,0 @@ -Subproject commit a578453b3c17794b61fb6cf4470ecaac8287d6d2 diff --git a/protobufs b/protobufs new file mode 160000 index 000000000..98a888f86 --- /dev/null +++ b/protobufs @@ -0,0 +1 @@ +Subproject commit 98a888f863a750464cd44526568af20c7bf12227 diff --git a/src/ButtonThread.h b/src/ButtonThread.h index 3a6f67a72..49243a93d 100644 --- a/src/ButtonThread.h +++ b/src/ButtonThread.h @@ -1,10 +1,10 @@ -#include "configuration.h" -#include "concurrency/OSThread.h" #include "PowerFSM.h" #include "RadioLibInterface.h" +#include "buzz.h" +#include "concurrency/OSThread.h" +#include "configuration.h" #include "graphics/Screen.h" #include "power.h" -#include "buzz.h" #include #ifndef NO_ESP32 @@ -78,14 +78,9 @@ class ButtonThread : public concurrency::OSThread #ifdef BUTTON_PIN_TOUCH userButtonTouch = OneButton(BUTTON_PIN_TOUCH, true, true); -#ifdef INPUT_PULLUP_SENSE - // Some platforms (nrf52) have a SENSE variant which allows wake from sleep - override what OneButton did - pinMode(BUTTON_PIN_TOUCH, INPUT_PULLUP_SENSE); -#endif userButtonTouch.attachClick(touchPressed); wakeOnIrq(BUTTON_PIN_TOUCH, FALLING); #endif - } protected: @@ -114,16 +109,17 @@ class ButtonThread : public concurrency::OSThread private: static void touchPressed() - { + { screen->forceDisplay(); - DEBUG_MSG("touch press!\n"); + DEBUG_MSG("touch press!\n"); } - + static void userButtonPressed() { // DEBUG_MSG("press!\n"); #ifdef BUTTON_PIN - if ((BUTTON_PIN != radioConfig.preferences.inputbroker_pin_press) || !radioConfig.preferences.canned_message_module_enabled) { + if ((BUTTON_PIN != moduleConfig.canned_message.inputbroker_pin_press) || + !moduleConfig.canned_message.enabled) { powerFSM.trigger(EVENT_PRESS); } #endif @@ -144,7 +140,7 @@ class ButtonThread : public concurrency::OSThread #elif NRF52_SERIES // Do actual shutdown when button released, otherwise the button release // may wake the board immediatedly. - if ((!shutdown_on_long_stop) && (millis() > 30 * 1000)) { + if ((!shutdown_on_long_stop) && (millis() > 30 * 1000)) { screen->startShutdownScreen(); DEBUG_MSG("Shutdown from long press"); playBeep(); @@ -163,7 +159,7 @@ class ButtonThread : public concurrency::OSThread #ifndef NO_ESP32 disablePin(); #elif defined(HAS_EINK) - digitalWrite(PIN_EINK_EN,digitalRead(PIN_EINK_EN) == LOW); + digitalWrite(PIN_EINK_EN, digitalRead(PIN_EINK_EN) == LOW); #endif } @@ -177,7 +173,6 @@ class ButtonThread : public concurrency::OSThread #endif } - static void userButtonPressedLongStart() { if (millis() > 30 * 1000) { @@ -188,7 +183,7 @@ class ButtonThread : public concurrency::OSThread static void userButtonPressedLongStop() { - if (millis() > 30 * 1000){ + if (millis() > 30 * 1000) { DEBUG_MSG("Long press stop!\n"); longPressTime = 0; if (shutdown_on_long_stop) { @@ -200,4 +195,4 @@ class ButtonThread : public concurrency::OSThread } }; -} +} // namespace concurrency diff --git a/src/GPSStatus.h b/src/GPSStatus.h index a15e385a8..95f5f53e7 100644 --- a/src/GPSStatus.h +++ b/src/GPSStatus.h @@ -1,7 +1,7 @@ #pragma once +#include "NodeDB.h" #include "Status.h" #include "configuration.h" -#include "NodeDB.h" #include extern NodeDB nodeDB; @@ -17,8 +17,8 @@ class GPSStatus : public Status CallbackObserver statusObserver = CallbackObserver(this, &GPSStatus::updateStatus); - bool hasLock = false; // default to false, until we complete our first read - bool isConnected = false; // Do we have a GPS we are talking to + bool hasLock = false; // default to false, until we complete our first read + bool isConnected = false; // Do we have a GPS we are talking to Position p = Position_init_default; @@ -42,8 +42,7 @@ class GPSStatus : public Status } // preferred method - GPSStatus(bool hasLock, bool isConnected, const Position& pos) - : Status() + GPSStatus(bool hasLock, bool isConnected, const Position &pos) : Status() { this->hasLock = hasLock; this->isConnected = isConnected; @@ -61,8 +60,9 @@ class GPSStatus : public Status bool getIsConnected() const { return isConnected; } - int32_t getLatitude() const { - if (radioConfig.preferences.fixed_position){ + int32_t getLatitude() const + { + if (config.position.fixed_position) { #ifdef GPS_EXTRAVERBOSE DEBUG_MSG("WARNING: Using fixed latitude\n"); #endif @@ -73,8 +73,9 @@ class GPSStatus : public Status } } - int32_t getLongitude() const { - if (radioConfig.preferences.fixed_position){ + int32_t getLongitude() const + { + if (config.position.fixed_position) { #ifdef GPS_EXTRAVERBOSE DEBUG_MSG("WARNING: Using fixed longitude\n"); #endif @@ -85,8 +86,9 @@ class GPSStatus : public Status } } - int32_t getAltitude() const { - if (radioConfig.preferences.fixed_position){ + int32_t getAltitude() const + { + if (config.position.fixed_position) { #ifdef GPS_EXTRAVERBOSE DEBUG_MSG("WARNING: Using fixed altitude\n"); #endif @@ -106,17 +108,12 @@ class GPSStatus : public Status bool matches(const GPSStatus *newStatus) const { #ifdef GPS_EXTRAVERBOSE - DEBUG_MSG("GPSStatus.match() new pos@%x to old pos@%x\n", - newStatus->p.pos_timestamp, p.pos_timestamp); + DEBUG_MSG("GPSStatus.match() new pos@%x to old pos@%x\n", newStatus->p.pos_timestamp, p.pos_timestamp); #endif - return (newStatus->hasLock != hasLock || - newStatus->isConnected != isConnected || - newStatus->p.latitude_i != p.latitude_i || - newStatus->p.longitude_i != p.longitude_i || - newStatus->p.altitude != p.altitude || - newStatus->p.altitude_hae != p.altitude_hae || - newStatus->p.PDOP != p.PDOP || - newStatus->p.ground_track != p.ground_track || + return (newStatus->hasLock != hasLock || newStatus->isConnected != isConnected || + newStatus->p.latitude_i != p.latitude_i || newStatus->p.longitude_i != p.longitude_i || + newStatus->p.altitude != p.altitude || newStatus->p.altitude_hae != p.altitude_hae || + newStatus->p.PDOP != p.PDOP || newStatus->p.ground_track != p.ground_track || newStatus->p.sats_in_view != p.sats_in_view); } @@ -125,8 +122,7 @@ class GPSStatus : public Status // Only update the status if values have actually changed bool isDirty = matches(newStatus); - if (isDirty && p.pos_timestamp && - (newStatus->p.pos_timestamp == p.pos_timestamp)) { + if (isDirty && p.pos_timestamp && (newStatus->p.pos_timestamp == p.pos_timestamp)) { // We can NEVER be in two locations at the same time! (also PR #886) DEBUG_MSG("BUG!! positional timestamp unchanged from prev solution\n"); } @@ -140,11 +136,9 @@ class GPSStatus : public Status if (isDirty) { if (hasLock) { // In debug logs, identify position by @timestamp:stage (stage 3 = notify) - DEBUG_MSG("New GPS pos@%x:3 lat=%f, lon=%f, alt=%d, pdop=%.2f, track=%.2f, sats=%d\n", - p.pos_timestamp, - p.latitude_i * 1e-7, p.longitude_i * 1e-7, - p.altitude, p.PDOP * 1e-2, p.ground_track * 1e-5, - p.sats_in_view); + DEBUG_MSG("New GPS pos@%x:3 lat=%f, lon=%f, alt=%d, pdop=%.2f, track=%.2f, sats=%d\n", p.pos_timestamp, + p.latitude_i * 1e-7, p.longitude_i * 1e-7, p.altitude, p.PDOP * 1e-2, p.ground_track * 1e-5, + p.sats_in_view); } else DEBUG_MSG("No GPS lock\n"); onNewStatus.notifyObservers(this); diff --git a/src/Power.cpp b/src/Power.cpp index 6c5301f15..feb7930ad 100644 --- a/src/Power.cpp +++ b/src/Power.cpp @@ -1,7 +1,7 @@ -#include "configuration.h" #include "power.h" #include "NodeDB.h" #include "PowerFSM.h" +#include "configuration.h" #include "main.h" #include "sleep.h" #include "utils.h" @@ -13,27 +13,28 @@ AXP20X_Class axp; #else -// Copy of the base class defined in axp20x.h. +// Copy of the base class defined in axp20x.h. // I'd rather not inlude axp20x.h as it brings Wire dependency. -class HasBatteryLevel { -public: - /** - * Battery state of charge, from 0 to 100 or -1 for unknown - */ - virtual int getBattPercentage() { return -1; } +class HasBatteryLevel +{ + public: + /** + * Battery state of charge, from 0 to 100 or -1 for unknown + */ + virtual int getBattPercentage() { return -1; } - /** - * The raw voltage of the battery or NAN if unknown - */ - virtual float getBattVoltage() { return NAN; } + /** + * The raw voltage of the battery or NAN if unknown + */ + virtual float getBattVoltage() { return NAN; } - /** - * return true if there is a battery installed in this unit - */ - virtual bool isBatteryConnect() { return false; } + /** + * return true if there is a battery installed in this unit + */ + virtual bool isBatteryConnect() { return false; } - virtual bool isVBUSPlug() { return false; } - virtual bool isChargeing() { return false; } + virtual bool isVBUSPlug() { return false; } + virtual bool isChargeing() { return false; } }; #endif @@ -99,24 +100,24 @@ class AnalogBatteryLevel : public HasBatteryLevel #ifndef ADC_MULTIPLIER #define ADC_MULTIPLIER 2.0 -#endif - // Override variant or default ADC_MULTIPLIER if we have the override pref - float operativeAdcMultiplier = radioConfig.preferences.adc_multiplier_override > 0 ? - radioConfig.preferences.adc_multiplier_override : - ADC_MULTIPLIER; +#endif #ifdef BATTERY_PIN - // Do not call analogRead() often. + // Override variant or default ADC_MULTIPLIER if we have the override pref + float operativeAdcMultiplier = config.power.adc_multiplier_override > 0 + ? config.power.adc_multiplier_override + : ADC_MULTIPLIER; + // Do not call analogRead() often. const uint32_t min_read_interval = 5000; if (millis() - last_read_time_ms > min_read_interval) { last_read_time_ms = millis(); uint32_t raw = analogRead(BATTERY_PIN); float scaled; - #ifndef VBAT_RAW_TO_SCALED +#ifndef VBAT_RAW_TO_SCALED scaled = 1000.0 * operativeAdcMultiplier * (AREF_VOLTAGE / 1024.0) * raw; - #else - scaled = VBAT_RAW_TO_SCALED(raw); //defined in variant.h - #endif +#else + scaled = VBAT_RAW_TO_SCALED(raw); // defined in variant.h +#endif // DEBUG_MSG("battery gpio %d raw val=%u scaled=%u\n", BATTERY_PIN, raw, (uint32_t)(scaled)); last_read_value = scaled; return scaled; @@ -153,7 +154,8 @@ class AnalogBatteryLevel : public HasBatteryLevel AnalogBatteryLevel analogLevel; -Power::Power() : OSThread("Power") { +Power::Power() : OSThread("Power") +{ statusHandler = {}; low_voltage_counter = 0; } @@ -172,7 +174,7 @@ bool Power::analogInit() #endif #ifdef NRF52_SERIES #ifdef VBAT_AR_INTERNAL - analogReference(VBAT_AR_INTERNAL); + analogReference(VBAT_AR_INTERNAL); #else analogReference(AR_INTERNAL); // 3.6V #endif @@ -181,9 +183,10 @@ bool Power::analogInit() #ifndef BATTERY_SENSE_RESOLUTION_BITS #define BATTERY_SENSE_RESOLUTION_BITS 10 #endif - + // adcStart(BATTERY_PIN); - analogReadResolution(BATTERY_SENSE_RESOLUTION_BITS); // Default of 12 is not very linear. Recommended to use 10 or 11 depending on needed resolution. + analogReadResolution(BATTERY_SENSE_RESOLUTION_BITS); // Default of 12 is not very linear. Recommended to use 10 or 11 + // depending on needed resolution. batteryLevel = &analogLevel; return true; #else @@ -246,24 +249,23 @@ void Power::readPowerStatus() powerStatus2.getIsCharging(), powerStatus2.getBatteryVoltageMv(), powerStatus2.getBatteryChargePercent()); newStatus.notifyObservers(&powerStatus2); - - // If we have a battery at all and it is less than 10% full, force deep sleep if we have more than 3 low readings in a row - // Supect fluctuating voltage on the RAK4631 to force it to deep sleep even if battery is at 85% after only a few days - #ifdef NRF52_SERIES - if (powerStatus2.getHasBattery() && !powerStatus2.getHasUSB()){ - if (batteryLevel->getBattVoltage() < MIN_BAT_MILLIVOLTS){ +// If we have a battery at all and it is less than 10% full, force deep sleep if we have more than 3 low readings in a row +// Supect fluctuating voltage on the RAK4631 to force it to deep sleep even if battery is at 85% after only a few days +#ifdef NRF52_SERIES + if (powerStatus2.getHasBattery() && !powerStatus2.getHasUSB()) { + if (batteryLevel->getBattVoltage() < MIN_BAT_MILLIVOLTS) { low_voltage_counter++; - if (low_voltage_counter>3) + if (low_voltage_counter > 3) powerFSM.trigger(EVENT_LOW_BATTERY); } else { low_voltage_counter = 0; } } - #else +#else // If we have a battery at all and it is less than 10% full, force deep sleep if (powerStatus2.getHasBattery() && !powerStatus2.getHasUSB() && batteryLevel->getBattVoltage() < MIN_BAT_MILLIVOLTS) powerFSM.trigger(EVENT_LOW_BATTERY); - #endif +#endif } else { // No power sensing on this board - tell everyone else we have no idea what is happening const PowerStatus powerStatus3 = PowerStatus(OptUnknown, OptUnknown, OptUnknown, -1, -1); @@ -355,40 +357,58 @@ bool Power::axp192Init() DEBUG_MSG("DCDC3: %s\n", axp.isDCDC3Enable() ? "ENABLE" : "DISABLE"); DEBUG_MSG("Exten: %s\n", axp.isExtenEnable() ? "ENABLE" : "DISABLE"); - if (radioConfig.preferences.charge_current == ChargeCurrent_MAUnset) { + switch (config.power.charge_current) { + case Config_PowerConfig_ChargeCurrent_MAUnset: axp.setChargeControlCur(AXP1XX_CHARGE_CUR_450MA); - } else if (radioConfig.preferences.charge_current == ChargeCurrent_MA100) { + break; + case Config_PowerConfig_ChargeCurrent_MA100: axp.setChargeControlCur(AXP1XX_CHARGE_CUR_100MA); - } else if (radioConfig.preferences.charge_current == ChargeCurrent_MA190) { + break; + case Config_PowerConfig_ChargeCurrent_MA190: axp.setChargeControlCur(AXP1XX_CHARGE_CUR_190MA); - } else if (radioConfig.preferences.charge_current == ChargeCurrent_MA280) { + break; + case Config_PowerConfig_ChargeCurrent_MA280: axp.setChargeControlCur(AXP1XX_CHARGE_CUR_280MA); - } else if (radioConfig.preferences.charge_current == ChargeCurrent_MA360) { + break; + case Config_PowerConfig_ChargeCurrent_MA360: axp.setChargeControlCur(AXP1XX_CHARGE_CUR_360MA); - } else if (radioConfig.preferences.charge_current == ChargeCurrent_MA450) { + break; + case Config_PowerConfig_ChargeCurrent_MA450: axp.setChargeControlCur(AXP1XX_CHARGE_CUR_450MA); - } else if (radioConfig.preferences.charge_current == ChargeCurrent_MA550) { + break; + case Config_PowerConfig_ChargeCurrent_MA550: axp.setChargeControlCur(AXP1XX_CHARGE_CUR_550MA); - } else if (radioConfig.preferences.charge_current == ChargeCurrent_MA630) { + break; + case Config_PowerConfig_ChargeCurrent_MA630: axp.setChargeControlCur(AXP1XX_CHARGE_CUR_630MA); - } else if (radioConfig.preferences.charge_current == ChargeCurrent_MA700) { + break; + case Config_PowerConfig_ChargeCurrent_MA700: axp.setChargeControlCur(AXP1XX_CHARGE_CUR_700MA); - } else if (radioConfig.preferences.charge_current == ChargeCurrent_MA780) { + break; + case Config_PowerConfig_ChargeCurrent_MA780: axp.setChargeControlCur(AXP1XX_CHARGE_CUR_780MA); - } else if (radioConfig.preferences.charge_current == ChargeCurrent_MA880) { + break; + case Config_PowerConfig_ChargeCurrent_MA880: axp.setChargeControlCur(AXP1XX_CHARGE_CUR_880MA); - } else if (radioConfig.preferences.charge_current == ChargeCurrent_MA960) { + break; + case Config_PowerConfig_ChargeCurrent_MA960: axp.setChargeControlCur(AXP1XX_CHARGE_CUR_960MA); - } else if (radioConfig.preferences.charge_current == ChargeCurrent_MA1000) { + break; + case Config_PowerConfig_ChargeCurrent_MA1000: axp.setChargeControlCur(AXP1XX_CHARGE_CUR_1000MA); - } else if (radioConfig.preferences.charge_current == ChargeCurrent_MA1080) { + break; + case Config_PowerConfig_ChargeCurrent_MA1080: axp.setChargeControlCur(AXP1XX_CHARGE_CUR_1080MA); - } else if (radioConfig.preferences.charge_current == ChargeCurrent_MA1160) { + break; + case Config_PowerConfig_ChargeCurrent_MA1160: axp.setChargeControlCur(AXP1XX_CHARGE_CUR_1160MA); - } else if (radioConfig.preferences.charge_current == ChargeCurrent_MA1240) { + break; + case Config_PowerConfig_ChargeCurrent_MA1240: axp.setChargeControlCur(AXP1XX_CHARGE_CUR_1240MA); - } else if (radioConfig.preferences.charge_current == ChargeCurrent_MA1320) { + break; + case Config_PowerConfig_ChargeCurrent_MA1320: axp.setChargeControlCur(AXP1XX_CHARGE_CUR_1320MA); + break; } #if 0 diff --git a/src/PowerFSM.cpp b/src/PowerFSM.cpp index a6fd758ac..1bfc58694 100644 --- a/src/PowerFSM.cpp +++ b/src/PowerFSM.cpp @@ -12,15 +12,15 @@ static bool isPowered() { // Completely circumvents the battery / power sensing logic and assumes constant power source - if (radioConfig.preferences.is_always_powered) { + if (config.power.is_always_powered) { return true; } - bool isRouter = (radioConfig.preferences.role == Role_Router ? 1 : 0); + bool isRouter = (config.device.role == Config_DeviceConfig_Role_Router ? 1 : 0); // If we are not a router and we already have AC power go to POWER state after init, otherwise go to ON // We assume routers might be powered all the time, but from a low current (solar) source - bool isLowPower = radioConfig.preferences.is_low_power || isRouter; + bool isLowPower = config.power.is_low_power || isRouter; /* To determine if we're externally powered, assumptions 1) If we're powered up and there's no battery, we must be getting power externally. (because we'd be dead otherwise) @@ -34,7 +34,7 @@ static void sdsEnter() { DEBUG_MSG("Enter state: SDS\n"); // FIXME - make sure GPS and LORA radio are off first - because we want close to zero current draw - doDeepSleep(getPref_sds_secs() * 1000LL); + doDeepSleep(config.power.sds_secs ? config.power.sds_secs : default_sds_secs * 1000LL); } extern Power *power; @@ -51,7 +51,8 @@ static uint32_t secsSlept; static void lsEnter() { - DEBUG_MSG("lsEnter begin, ls_secs=%u\n", getPref_ls_secs()); + DEBUG_MSG("lsEnter begin, ls_secs=%u\n", + config.power.ls_secs ? config.power.ls_secs : default_ls_secs); screen->setOn(false); secsSlept = 0; // How long have we been sleeping this time @@ -65,7 +66,7 @@ static void lsIdle() #ifndef NO_ESP32 // Do we have more sleeping to do? - if (secsSlept < getPref_ls_secs()) { + if (secsSlept < config.power.ls_secs ? config.power.ls_secs : default_ls_secs * 1000) { // Briefly come out of sleep long enough to blink the led once every few seconds uint32_t sleepTime = 30; @@ -78,7 +79,7 @@ static void lsIdle() case ESP_SLEEP_WAKEUP_TIMER: // Normal case: timer expired, we should just go back to sleep ASAP - setLed(true); // briefly turn on led + setLed(true); // briefly turn on led wakeCause2 = doLightSleep(1); // leave led on for 1ms secsSlept += sleepTime; @@ -238,7 +239,7 @@ Fsm powerFSM(&stateBOOT); void PowerFSM_setup() { - bool isRouter = (radioConfig.preferences.role == Role_Router ? 1 : 0); + bool isRouter = (config.device.role == Config_DeviceConfig_Role_Router ? 1 : 0); bool hasPower = isPowered(); DEBUG_MSG("PowerFSM init, USB power=%d\n", hasPower); @@ -332,7 +333,10 @@ void PowerFSM_setup() powerFSM.add_transition(&stateDARK, &stateON, EVENT_FIRMWARE_UPDATE, NULL, "Got firmware update"); powerFSM.add_transition(&stateON, &stateON, EVENT_FIRMWARE_UPDATE, NULL, "Got firmware update"); - powerFSM.add_timed_transition(&stateON, &stateDARK, getPref_screen_on_secs() * 1000, NULL, "Screen-on timeout"); + powerFSM.add_timed_transition(&stateON, &stateDARK, + config.display.screen_on_secs ? config.display.screen_on_secs + : 60 * 1000, + NULL, "Screen-on timeout"); // On most boards we use light-sleep to be our main state, but on NRF52 we just stay in DARK State *lowPowerState = &stateLS; @@ -343,13 +347,21 @@ void PowerFSM_setup() // We never enter light-sleep or NB states on NRF52 (because the CPU uses so little power normally) // See: https://github.com/meshtastic/Meshtastic-device/issues/1071 - if (isRouter || radioConfig.preferences.is_power_saving) { + if (isRouter || config.power.is_power_saving) { // I don't think this transition is correct, turning off for now - @geeksville // powerFSM.add_timed_transition(&stateDARK, &stateNB, getPref_phone_timeout_secs() * 1000, NULL, "Phone timeout"); - powerFSM.add_timed_transition(&stateNB, &stateLS, getPref_min_wake_secs() * 1000, NULL, "Min wake timeout"); - powerFSM.add_timed_transition(&stateDARK, &stateLS, getPref_wait_bluetooth_secs() * 1000, NULL, "Bluetooth timeout"); - meshSds = getPref_mesh_sds_timeout_secs(); + powerFSM.add_timed_transition(&stateNB, &stateLS, + config.power.min_wake_secs ? config.power.min_wake_secs + : default_min_wake_secs * 1000, + NULL, "Min wake timeout"); + powerFSM.add_timed_transition(&stateDARK, &stateLS, + config.power.wait_bluetooth_secs + ? config.power.wait_bluetooth_secs + : default_wait_bluetooth_secs * 1000, + NULL, "Bluetooth timeout"); + meshSds = config.power.mesh_sds_timeout_secs ? config.power.mesh_sds_timeout_secs + : default_mesh_sds_timeout_secs; } else { diff --git a/src/PowerFSMThread.h b/src/PowerFSMThread.h index 00f31e9c3..36bee834d 100644 --- a/src/PowerFSMThread.h +++ b/src/PowerFSMThread.h @@ -1,9 +1,9 @@ -#include "configuration.h" -#include "concurrency/OSThread.h" -#include "main.h" -#include "PowerFSM.h" -#include "power.h" #include "NodeDB.h" +#include "PowerFSM.h" +#include "concurrency/OSThread.h" +#include "configuration.h" +#include "main.h" +#include "power.h" namespace concurrency { @@ -26,13 +26,16 @@ class PowerFSMThread : public OSThread if (powerStatus->getHasUSB()) { timeLastPowered = millis(); - } else if (radioConfig.preferences.on_battery_shutdown_after_secs > 0 && - millis() > timeLastPowered + (1000 * radioConfig.preferences.on_battery_shutdown_after_secs)) { //shutdown after 30 minutes unpowered + } else if (config.power.on_battery_shutdown_after_secs > 0 && + millis() > + timeLastPowered + + (1000 * + config.power.on_battery_shutdown_after_secs)) { // shutdown after 30 minutes unpowered powerFSM.trigger(EVENT_SHUTDOWN); } - + return 10; } }; -} \ No newline at end of file +} // namespace concurrency \ No newline at end of file diff --git a/src/SerialConsole.cpp b/src/SerialConsole.cpp index 7aa19dba4..76926bb4e 100644 --- a/src/SerialConsole.cpp +++ b/src/SerialConsole.cpp @@ -1,7 +1,7 @@ -#include "configuration.h" #include "SerialConsole.h" #include "NodeDB.h" #include "PowerFSM.h" +#include "configuration.h" #define Port Serial @@ -45,7 +45,9 @@ SerialConsole::SerialConsole() : StreamAPI(&Port), RedirectablePrint(&Port) bool SerialConsole::checkIsConnected() { uint32_t now = millis(); - return (now - lastContactMsec) < getPref_phone_timeout_secs() * 1000UL; + return (now - lastContactMsec) < config.power.phone_timeout_secs + ? config.power.phone_timeout_secs + : default_phone_timeout_secs * 1000UL; } /** @@ -55,10 +57,9 @@ bool SerialConsole::checkIsConnected() bool SerialConsole::handleToRadio(const uint8_t *buf, size_t len) { // Turn off debug serial printing once the API is activated, because other threads could print and corrupt packets - if (!radioConfig.preferences.debug_log_enabled) + if (!config.device.debug_log_enabled) setDestination(&noopPrint); canWrite = true; return StreamAPI::handleToRadio(buf, len); } - diff --git a/src/buzz/buzz.cpp b/src/buzz/buzz.cpp index a667df004..3253684d1 100644 --- a/src/buzz/buzz.cpp +++ b/src/buzz/buzz.cpp @@ -1,10 +1,6 @@ #include "buzz.h" #include "configuration.h" -#ifdef NRF52_SERIES -#include "variant.h" -#endif - #ifndef PIN_BUZZER // Noop methods for boards w/o buzzer @@ -12,8 +8,13 @@ void playBeep(){}; void playStartMelody(){}; void playShutdownMelody(){}; +#else +#ifdef M5STACK +#include "Speaker.h" +TONE Tone; #else #include "Tone.h" +#endif extern "C" void delay(uint32_t dwMs); @@ -42,13 +43,26 @@ const int DURATION_1_4 = 250; // 1/4 note void playTones(const ToneDuration *tone_durations, int size) { for (int i = 0; i < size; i++) { const auto &tone_duration = tone_durations[i]; +#ifdef M5STACK + Tone.tone(tone_duration.frequency_khz); + delay(tone_duration.duration_ms); + Tone.mute(); +#else tone(PIN_BUZZER, tone_duration.frequency_khz, tone_duration.duration_ms); +#endif // to distinguish the notes, set a minimum time between them. delay(1.3 * tone_duration.duration_ms); } } +#ifdef M5STACK +void playBeep() { + ToneDuration melody[] = {{NOTE_B3, DURATION_1_4}}; + playTones(melody, sizeof(melody) / sizeof(ToneDuration)); +} +#else void playBeep() { tone(PIN_BUZZER, NOTE_B3, DURATION_1_4); } +#endif void playStartMelody() { ToneDuration melody[] = {{NOTE_B3, DURATION_1_4}, diff --git a/src/configuration.h b/src/configuration.h index 3e1e680f1..16262d97f 100644 --- a/src/configuration.h +++ b/src/configuration.h @@ -107,10 +107,6 @@ along with this program. If not, see . #define GPS_TX_PIN 12 #endif -#ifndef TTGO_T_ECHO -#define GPS_UBLOX -#endif - // ----------------------------------------------------------------------------- // LoRa SPI // ----------------------------------------------------------------------------- @@ -125,6 +121,10 @@ along with this program. If not, see . #endif +#ifndef TTGO_T_ECHO +#define GPS_UBLOX +#endif + // // Standard definitions for !ESP32 targets // @@ -269,6 +269,10 @@ along with this program. If not, see . #define HW_VENDOR HardwareModel_NRF52840_PCA10059 +#elif defined(M5STACK) + +#define HW_VENDOR HardwareModel_M5STACK + #elif NRF52_SERIES #define HW_VENDOR HardwareModel_NRF52_UNKNOWN diff --git a/src/debug/i2cScan.h b/src/debug/i2cScan.h index 4bfd2adf8..ba5636ea9 100644 --- a/src/debug/i2cScan.h +++ b/src/debug/i2cScan.h @@ -34,6 +34,7 @@ uint8_t oled_probe(byte addr) void scanI2Cdevice(void) { byte err, addr; + uint8_t r = 0x00; int nDevices = 0; for (addr = 1; addr < 127; addr++) { Wire.beginTransmission(addr); @@ -72,7 +73,22 @@ void scanI2Cdevice(void) #endif if (addr == CARDKB_ADDR) { cardkb_found = addr; - DEBUG_MSG("m5 cardKB found\n"); + // Do we have the RAK14006 instead? + Wire.beginTransmission(addr); + Wire.write(0x04); // SENSOR_GET_VERSION + Wire.endTransmission(); + delay(20); + Wire.requestFrom((int)addr, 1); + if (Wire.available()) { + r = Wire.read(); + } + if (r == 0x02) { // KEYPAD_VERSION + DEBUG_MSG("RAK14004 found\n"); + kb_model = 0x02; + } else { + DEBUG_MSG("m5 cardKB found\n"); + kb_model = 0x00; + } } if (addr == FACESKB_ADDR) { faceskb_found = addr; diff --git a/src/esp32/ESP32Bluetooth.cpp b/src/esp32/ESP32Bluetooth.cpp index 1816e7f6d..5ed46f119 100644 --- a/src/esp32/ESP32Bluetooth.cpp +++ b/src/esp32/ESP32Bluetooth.cpp @@ -23,9 +23,6 @@ // proccess at once // static uint8_t trBytes[_max(_max(_max(_max(ToRadio_size, RadioConfig_size), User_size), MyNodeInfo_size), FromRadio_size)]; static uint8_t fromRadioBytes[FromRadio_size]; -static uint8_t toRadioBytes[ToRadio_size]; - -static bool bleConnected; NimBLECharacteristic *FromNumCharacteristic; NimBLEServer *bleServer; diff --git a/src/gps/GPS.cpp b/src/gps/GPS.cpp index 45e3eb1a1..0536e5a11 100644 --- a/src/gps/GPS.cpp +++ b/src/gps/GPS.cpp @@ -1,7 +1,7 @@ -#include "configuration.h" #include "GPS.h" #include "NodeDB.h" #include "RTC.h" +#include "configuration.h" #include "sleep.h" #include @@ -22,6 +22,43 @@ GPS *gps; /// only init that port once. static bool didSerialInit; +bool GPS::getACK(uint8_t c, uint8_t i) { + uint8_t b; + uint8_t ack = 0; + const uint8_t ackP[2] = {c, i}; + uint8_t buf[10] = {0xB5, 0x62, 0x05, 0x01, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00}; + unsigned long startTime = millis(); + + for (int j = 2; j < 6; j++) { + buf[8] += buf[j]; + buf[9] += buf[8]; + } + + for (int j = 0; j < 2; j++) { + buf[6 + j] = ackP[j]; + buf[8] += buf[6 + j]; + buf[9] += buf[8]; + } + + while (1) { + if (ack > 9) { + return true; + } + if (millis() - startTime > 1000) { + return false; + } + if (_serial_gps->available()) { + b = _serial_gps->read(); + if (b == buf[ack]) { + ack++; + } + else { + ack = 0; + } + } + } +} + bool GPS::setupGPS() { if (_serial_gps && !didSerialInit) { @@ -37,13 +74,17 @@ bool GPS::setupGPS() _serial_gps->setRxBufferSize(2048); // the default is 256 #endif #ifdef TTGO_T_ECHO - // Switch to 4800 baud, then close and reopen port - _serial_gps->write("$PCAS01,0*1C\r\n"); - delay(250); + // Switch to 9600 baud, then close and reopen port _serial_gps->end(); delay(250); _serial_gps->begin(4800); delay(250); + _serial_gps->write("$PCAS01,1*1D\r\n"); + delay(250); + _serial_gps->end(); + delay(250); + _serial_gps->begin(9600); + delay(250); // Initialize the L76K Chip, use GPS + GLONASS _serial_gps->write("$PCAS04,5*1C\r\n"); delay(250); @@ -53,57 +94,62 @@ bool GPS::setupGPS() // Switch to Vehicle Mode, since SoftRF enables Aviation < 2g _serial_gps->write("$PCAS11,3*1E\r\n"); delay(250); - #endif #ifdef GPS_UBLOX - // Set the UART port to output NMEA only - byte _message_nmea[] = {0xB5, 0x62, 0x06, 0x00, 0x14, 0x00, - 0x01, 0x00, 0x00, 0x00, 0xC0, 0x08, 0x00, 0x00, 0x80, 0x25, 0x00, 0x00, 0x07, 0x00, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x91, 0xAF}; - _serial_gps->write(_message_nmea,sizeof(_message_nmea)); delay(250); + // Set the UART port to output NMEA only + byte _message_nmea[] = {0xB5, 0x62, 0x06, 0x00, 0x14, 0x00, 0x01, 0x00, 0x00, 0x00, 0xC0, 0x08, 0x00, 0x00, + 0x80, 0x25, 0x00, 0x00, 0x07, 0x00, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x91, 0xAF}; + _serial_gps->write(_message_nmea, sizeof(_message_nmea)); + if (!getACK(0x06, 0x00)) { + DEBUG_MSG("WARNING: Unable to enable NMEA Mode.\n"); + return true; + } // disable GGL - byte _message_GGL[] = {0xB5, 0x62, 0x06, 0x01, 0x08, 0x00, - 0xF0, 0x01, 0x01, 0x00, 0x01, 0x01, 0x01, 0x01, - 0x05,0x3A}; - _serial_gps->write(_message_GGL,sizeof(_message_GGL)); - delay(250); + byte _message_GGL[] = {0xB5, 0x62, 0x06, 0x01, 0x08, 0x00, 0xF0, 0x01, 0x01, 0x00, 0x01, 0x01, 0x01, 0x01, 0x05, 0x3A}; + _serial_gps->write(_message_GGL, sizeof(_message_GGL)); + if (!getACK(0x06, 0x01)) { + DEBUG_MSG("WARNING: Unable to disable NMEA GGL.\n"); + return true; + } // disable GSA - byte _message_GSA[] = {0xB5, 0x62, 0x06, 0x01, 0x08, 0x00, - 0xF0, 0x02, 0x01, 0x00, 0x01, 0x01, 0x01, 0x01, - 0x06,0x41}; - _serial_gps->write(_message_GSA,sizeof(_message_GSA)); - delay(250); + byte _message_GSA[] = {0xB5, 0x62, 0x06, 0x01, 0x08, 0x00, 0xF0, 0x02, 0x01, 0x00, 0x01, 0x01, 0x01, 0x01, 0x06, 0x41}; + _serial_gps->write(_message_GSA, sizeof(_message_GSA)); + if (!getACK(0x06, 0x01)) { + DEBUG_MSG("WARNING: Unable to disable NMEA GSA.\n"); + return true; + } // disable GSV - byte _message_GSV[] = {0xB5, 0x62, 0x06, 0x01, 0x08, 0x00, - 0xF0, 0x03, 0x01, 0x00, 0x01, 0x01, 0x01, 0x01, - 0x07,0x48}; - _serial_gps->write(_message_GSV,sizeof(_message_GSV)); - delay(250); + byte _message_GSV[] = {0xB5, 0x62, 0x06, 0x01, 0x08, 0x00, 0xF0, 0x03, 0x01, 0x00, 0x01, 0x01, 0x01, 0x01, 0x07, 0x48}; + _serial_gps->write(_message_GSV, sizeof(_message_GSV)); + if (!getACK(0x06, 0x01)) { + DEBUG_MSG("WARNING: Unable to disable NMEA GSV.\n"); + return true; + } // disable VTG - byte _message_VTG[] = {0xB5, 0x62, 0x06, 0x01, 0x08, 0x00, - 0xF0, 0x05, 0x01, 0x00, 0x01, 0x01, 0x01, 0x01, - 0x09,0x56}; - _serial_gps->write(_message_VTG,sizeof(_message_VTG)); - delay(250); + byte _message_VTG[] = {0xB5, 0x62, 0x06, 0x01, 0x08, 0x00, 0xF0, 0x05, 0x01, 0x00, 0x01, 0x01, 0x01, 0x01, 0x09, 0x56}; + _serial_gps->write(_message_VTG, sizeof(_message_VTG)); + if (!getACK(0x06, 0x01)) { + DEBUG_MSG("WARNING: Unable to disable NMEA VTG.\n"); + return true; + } // enable RMC - byte _message_RMC[] = {0xB5, 0x62, 0x06, 0x01, 0x08, 0x00, - 0xF0, 0x04, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, - 0x09,0x54}; - _serial_gps->write(_message_RMC,sizeof(_message_RMC)); - delay(250); + byte _message_RMC[] = {0xB5, 0x62, 0x06, 0x01, 0x08, 0x00, 0xF0, 0x04, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x09, 0x54}; + _serial_gps->write(_message_RMC, sizeof(_message_RMC)); + if (!getACK(0x06, 0x01)) { + DEBUG_MSG("WARNING: Unable to enable NMEA RMC.\n"); + return true; + } // enable GGA - byte _message_GGA[] = {0xB5, 0x62, 0x06, 0x01, 0x08, 0x00, - 0xF0, 0x00, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, - 0x05, 0x38}; - _serial_gps->write(_message_GGA,sizeof(_message_GGA)); - delay(250); + byte _message_GGA[] = {0xB5, 0x62, 0x06, 0x01, 0x08, 0x00, 0xF0, 0x00, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x05, 0x38}; + _serial_gps->write(_message_GGA, sizeof(_message_GGA)); + if (!getACK(0x06, 0x01)) DEBUG_MSG("WARNING: Unable to enable NMEA GGA.\n"); #endif } @@ -143,7 +189,15 @@ GPS::~GPS() notifyDeepSleepObserver.unobserve(¬ifyDeepSleep); } -bool GPS::hasLock() { return hasValidLocation; } +bool GPS::hasLock() +{ + return hasValidLocation; +} + +bool GPS::hasFlow() +{ + return hasGPS; +} // Allow defining the polarity of the WAKE output. default is active high #ifndef GPS_WAKE_ACTIVE @@ -213,14 +267,16 @@ void GPS::setAwake(bool on) */ uint32_t GPS::getWakeTime() const { - uint32_t t = radioConfig.preferences.gps_attempt_time; + uint32_t t = config.position.gps_attempt_time; if (t == UINT32_MAX) return t; // already maxint if (t == 0) - t = (radioConfig.preferences.role == Role_Router) ? 5 * 60 : 15 * 60; // Allow up to 15 mins for each attempt (probably will be much - // less if we can find sats) or less if a router + t = (config.device.role == Config_DeviceConfig_Role_Router) + ? 5 * 60 + : 15 * 60; // Allow up to 15 mins for each attempt (probably will be much + // less if we can find sats) or less if a router t *= 1000; // msecs @@ -231,18 +287,18 @@ uint32_t GPS::getWakeTime() const */ uint32_t GPS::getSleepTime() const { - uint32_t t = radioConfig.preferences.gps_update_interval; - bool gps_disabled = radioConfig.preferences.gps_disabled; - bool loc_share_disabled = radioConfig.preferences.location_share_disabled; + uint32_t t = config.position.gps_update_interval; + bool gps_disabled = config.position.gps_disabled; - if (gps_disabled || loc_share_disabled) + if (gps_disabled) t = UINT32_MAX; // Sleep forever now if (t == UINT32_MAX) return t; // already maxint - if (t == 0) // default - unset in preferences - t = (radioConfig.preferences.role == Role_Router) ? 24 * 60 * 60 : 2 * 60; // 2 mins or once per day for routers + if (t == 0) // default - unset in preferences + t = (config.device.role == Config_DeviceConfig_Role_Router) ? 24 * 60 * 60 + : 2 * 60; // 2 mins or once per day for routers t *= 1000; @@ -255,12 +311,10 @@ void GPS::publishUpdate() shouldPublish = false; // In debug logs, identify position by @timestamp:stage (stage 2 = publish) - DEBUG_MSG("publishing pos@%x:2, hasVal=%d, GPSlock=%d\n", - p.pos_timestamp, hasValidLocation, hasLock()); + DEBUG_MSG("publishing pos@%x:2, hasVal=%d, GPSlock=%d\n", p.pos_timestamp, hasValidLocation, hasLock()); // Notify any status instances that are observing us - const meshtastic::GPSStatus status = - meshtastic::GPSStatus(hasValidLocation, isConnected(), p); + const meshtastic::GPSStatus status = meshtastic::GPSStatus(hasValidLocation, isConnected(), p); newStatus.notifyObservers(&status); } } @@ -270,6 +324,15 @@ int32_t GPS::runOnce() if (whileIdle()) { // if we have received valid NMEA claim we are connected setConnected(); + } else { +#ifdef GPS_UBLOX + // reset the GPS on next bootup + if(devicestate.did_gps_reset && (millis() > 60000) && !hasFlow()) { + DEBUG_MSG("GPS is not communicating, trying factory reset on next bootup.\n"); + devicestate.did_gps_reset = false; + nodeDB.saveToDisk(); + } +#endif } // If we are overdue for an update, turn on the GPS and at least publish the current status @@ -379,7 +442,7 @@ GPS *createGps() #ifdef NO_GPS return nullptr; #else - if (!radioConfig.preferences.gps_disabled){ + if (!config.position.gps_disabled) { #ifdef GPS_ALTITUDE_HAE DEBUG_MSG("Using HAE altitude model\n"); #else diff --git a/src/gps/GPS.h b/src/gps/GPS.h index 999f88bfa..e6256d3c9 100644 --- a/src/gps/GPS.h +++ b/src/gps/GPS.h @@ -57,6 +57,9 @@ class GPS : private concurrency::OSThread /// Returns true if we have acquired GPS lock. virtual bool hasLock(); + /// Returns true if there's valid data flow with the chip. + virtual bool hasFlow(); + /// Return true if we are connected to a GPS bool isConnected() const { return hasGPS; } @@ -135,6 +138,8 @@ class GPS : private concurrency::OSThread */ uint32_t getSleepTime() const; + bool getACK(uint8_t c, uint8_t i); + /** * Tell users we have new GPS readings */ diff --git a/src/gps/NMEAGPS.cpp b/src/gps/NMEAGPS.cpp index 8a8181f3b..363eb8263 100644 --- a/src/gps/NMEAGPS.cpp +++ b/src/gps/NMEAGPS.cpp @@ -17,6 +17,19 @@ static int32_t toDegInt(RawDegrees d) return r; } +bool NMEAGPS::factoryReset() +{ +#ifdef GPS_UBLOX + // Factory Reset + byte _message_reset[] = {0xB5, 0x62, 0x06, 0x09, 0x0D, 0x00, 0xFF, + 0xFB, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0xFF, 0xFF, 0x00, 0x00, 0x17, 0x2B, 0x7E}; + _serial_gps->write(_message_reset,sizeof(_message_reset)); + delay(1000); +#endif + return true; +} + bool NMEAGPS::setupGPS() { GPS::setupGPS(); @@ -222,6 +235,10 @@ bool NMEAGPS::hasLock() return false; } +bool NMEAGPS::hasFlow() +{ + return reader.passedChecksum() > 0; +} bool NMEAGPS::whileIdle() { diff --git a/src/gps/NMEAGPS.h b/src/gps/NMEAGPS.h index 6133925dd..c97be08ce 100644 --- a/src/gps/NMEAGPS.h +++ b/src/gps/NMEAGPS.h @@ -25,6 +25,8 @@ class NMEAGPS : public GPS public: virtual bool setupGPS() override; + virtual bool factoryReset() override; + protected: /** Subclasses should look for serial rx characters here and feed it to their GPS parser * @@ -49,4 +51,6 @@ class NMEAGPS : public GPS virtual bool lookForLocation() override; virtual bool hasLock() override; + + virtual bool hasFlow() override; }; diff --git a/src/gps/RTC.cpp b/src/gps/RTC.cpp index 335dbe37d..04e7043e5 100644 --- a/src/gps/RTC.cpp +++ b/src/gps/RTC.cpp @@ -120,7 +120,7 @@ bool perhapsSetRTC(RTCQuality q, const struct timeval *tv) #endif // nrf52 doesn't have a readable RTC (yet - software not written) -#if defined(PORTDUINO) || !defined(NO_ESP32) || defined(RV3028_RTC) +#if defined(PORTDUINO) || !defined(NO_ESP32) || defined(RV3028_RTC) || defined(PCF8563_RTC) readFromRTC(); #endif diff --git a/src/graphics/Screen.cpp b/src/graphics/Screen.cpp index 136964006..dc1b0108a 100644 --- a/src/graphics/Screen.cpp +++ b/src/graphics/Screen.cpp @@ -20,6 +20,7 @@ along with this program. If not, see . */ #include "configuration.h" +#ifndef NO_SCREEN #include #include "GPS.h" @@ -31,8 +32,8 @@ along with this program. If not, see . #include "graphics/images.h" #include "main.h" #include "mesh-pb-constants.h" -#include "mesh/generated/deviceonly.pb.h" #include "mesh/Channels.h" +#include "mesh/generated/deviceonly.pb.h" #include "modules/TextMessageModule.h" #include "sleep.h" #include "target_specific.h" @@ -93,7 +94,7 @@ static uint16_t displayWidth, displayHeight; #define SCREEN_WIDTH displayWidth #define SCREEN_HEIGHT displayHeight -#ifdef HAS_EINK +#if defined(HAS_EINK) || defined(ILI9341_DRIVER) // The screen is bigger so use bigger fonts #define FONT_SMALL ArialMT_Plain_16 #define FONT_MEDIUM ArialMT_Plain_24 @@ -162,21 +163,22 @@ static void drawOEMIconScreen(const char *upperMsg, OLEDDisplay *display, OLEDDi // needs to be drawn relative to x and y // draw centered icon left to right and centered above the one line of app text - display->drawXbm(x + (SCREEN_WIDTH - oemStore.oem_icon_width) / 2, y + (SCREEN_HEIGHT - FONT_HEIGHT_MEDIUM - oemStore.oem_icon_height) / 2 + 2, - oemStore.oem_icon_width, oemStore.oem_icon_height, (const uint8_t *)oemStore.oem_icon_bits.bytes); + display->drawXbm(x + (SCREEN_WIDTH - oemStore.oem_icon_width) / 2, + y + (SCREEN_HEIGHT - FONT_HEIGHT_MEDIUM - oemStore.oem_icon_height) / 2 + 2, oemStore.oem_icon_width, + oemStore.oem_icon_height, (const uint8_t *)oemStore.oem_icon_bits.bytes); - switch(oemStore.oem_font){ - case 0: - display->setFont(FONT_SMALL); + switch (oemStore.oem_font) { + case 0: + display->setFont(FONT_SMALL); break; - case 2: - display->setFont(FONT_LARGE); + case 2: + display->setFont(FONT_LARGE); break; - default: - display->setFont(FONT_MEDIUM); + default: + display->setFont(FONT_MEDIUM); break; } - + display->setTextAlignment(TEXT_ALIGN_LEFT); const char *title = oemStore.oem_text; display->drawString(x + getStringCenteredX(title), y + SCREEN_HEIGHT - FONT_HEIGHT_MEDIUM, title); @@ -351,8 +353,8 @@ static void drawCriticalFaultFrame(OLEDDisplay *display, OLEDDisplayUiState *sta // Ignore messages orginating from phone (from the current node 0x0) unless range test or store and forward module are enabled static bool shouldDrawMessage(const MeshPacket *packet) { - return packet->from != 0 && !radioConfig.preferences.range_test_module_enabled && - !radioConfig.preferences.store_forward_module_enabled; + return packet->from != 0 && !moduleConfig.range_test.enabled && + !moduleConfig.store_forward.enabled; } /// Draw the last text message we received @@ -466,7 +468,7 @@ static void drawNodes(OLEDDisplay *display, int16_t x, int16_t y, NodeStatus *no // Draw GPS status summary static void drawGPS(OLEDDisplay *display, int16_t x, int16_t y, const GPSStatus *gps) { - if (radioConfig.preferences.fixed_position) { + if (config.position.fixed_position) { // GPS coordinates are currently fixed display->drawString(x - 1, y - 2, "Fixed GPS"); return; @@ -505,10 +507,10 @@ static void drawGPS(OLEDDisplay *display, int16_t x, int16_t y, const GPSStatus static void drawGPSAltitude(OLEDDisplay *display, int16_t x, int16_t y, const GPSStatus *gps) { String displayLine = ""; - if (!gps->getIsConnected() && !radioConfig.preferences.fixed_position) { + if (!gps->getIsConnected() && !config.position.fixed_position) { // displayLine = "No GPS Module"; // display->drawString(x + (SCREEN_WIDTH - (display->getStringWidth(displayLine))) / 2, y, displayLine); - } else if (!gps->getHasLock() && !radioConfig.preferences.fixed_position) { + } else if (!gps->getHasLock() && !config.position.fixed_position) { // displayLine = "No GPS Lock"; // display->drawString(x + (SCREEN_WIDTH - (display->getStringWidth(displayLine))) / 2, y, displayLine); } else { @@ -521,32 +523,32 @@ static void drawGPSAltitude(OLEDDisplay *display, int16_t x, int16_t y, const GP // Draw GPS status coordinates static void drawGPScoordinates(OLEDDisplay *display, int16_t x, int16_t y, const GPSStatus *gps) { - auto gpsFormat = radioConfig.preferences.gps_format; + auto gpsFormat = config.display.gps_format; String displayLine = ""; - if (!gps->getIsConnected() && !radioConfig.preferences.fixed_position) { + if (!gps->getIsConnected() && !config.position.fixed_position) { displayLine = "No GPS Module"; display->drawString(x + (SCREEN_WIDTH - (display->getStringWidth(displayLine))) / 2, y, displayLine); - } else if (!gps->getHasLock() && !radioConfig.preferences.fixed_position) { + } else if (!gps->getHasLock() && !config.position.fixed_position) { displayLine = "No GPS Lock"; display->drawString(x + (SCREEN_WIDTH - (display->getStringWidth(displayLine))) / 2, y, displayLine); } else { - if (gpsFormat != GpsCoordinateFormat_GpsFormatDMS) { + if (gpsFormat != Config_DisplayConfig_GpsCoordinateFormat_GpsFormatDMS) { char coordinateLine[22]; geoCoord.updateCoords(int32_t(gps->getLatitude()), int32_t(gps->getLongitude()), int32_t(gps->getAltitude())); - if (gpsFormat == GpsCoordinateFormat_GpsFormatDec) { // Decimal Degrees + if (gpsFormat == Config_DisplayConfig_GpsCoordinateFormat_GpsFormatDec) { // Decimal Degrees sprintf(coordinateLine, "%f %f", geoCoord.getLatitude() * 1e-7, geoCoord.getLongitude() * 1e-7); - } else if (gpsFormat == GpsCoordinateFormat_GpsFormatUTM) { // Universal Transverse Mercator + } else if (gpsFormat == Config_DisplayConfig_GpsCoordinateFormat_GpsFormatUTM) { // Universal Transverse Mercator sprintf(coordinateLine, "%2i%1c %06u %07u", geoCoord.getUTMZone(), geoCoord.getUTMBand(), geoCoord.getUTMEasting(), geoCoord.getUTMNorthing()); - } else if (gpsFormat == GpsCoordinateFormat_GpsFormatMGRS) { // Military Grid Reference System + } else if (gpsFormat == Config_DisplayConfig_GpsCoordinateFormat_GpsFormatMGRS) { // Military Grid Reference System sprintf(coordinateLine, "%2i%1c %1c%1c %05u %05u", geoCoord.getMGRSZone(), geoCoord.getMGRSBand(), geoCoord.getMGRSEast100k(), geoCoord.getMGRSNorth100k(), geoCoord.getMGRSEasting(), geoCoord.getMGRSNorthing()); - } else if (gpsFormat == GpsCoordinateFormat_GpsFormatOLC) { // Open Location Code + } else if (gpsFormat == Config_DisplayConfig_GpsCoordinateFormat_GpsFormatOLC) { // Open Location Code geoCoord.getOLCCode(coordinateLine); - } else if (gpsFormat == GpsCoordinateFormat_GpsFormatOSGR) { // Ordnance Survey Grid Reference + } else if (gpsFormat == Config_DisplayConfig_GpsCoordinateFormat_GpsFormatOSGR) { // Ordnance Survey Grid Reference if (geoCoord.getOSGRE100k() == 'I' || geoCoord.getOSGRN100k() == 'I') // OSGR is only valid around the UK region sprintf(coordinateLine, "%s", "Out of Boundary"); else @@ -555,7 +557,7 @@ static void drawGPScoordinates(OLEDDisplay *display, int16_t x, int16_t y, const } // If fixed position, display text "Fixed GPS" alternating with the coordinates. - if (radioConfig.preferences.fixed_position) { + if (config.position.fixed_position) { if ((millis() / 10000) % 2) { display->drawString(x + (SCREEN_WIDTH - (display->getStringWidth(coordinateLine))) / 2, y, coordinateLine); } else { @@ -816,7 +818,8 @@ void _screen_header() #endif // #ifdef RAK4630 -// Screen::Screen(uint8_t address, int sda, int scl) : OSThread("Screen"), cmdQueue(32), dispdev(address, sda, scl), dispdev_oled(address, sda, scl), ui(&dispdev) +// Screen::Screen(uint8_t address, int sda, int scl) : OSThread("Screen"), cmdQueue(32), dispdev(address, sda, scl), +// dispdev_oled(address, sda, scl), ui(&dispdev) // { // address_found = address; // cmdQueue.setReader(this); @@ -976,7 +979,7 @@ int32_t Screen::runOnce() } // If we have an OEM Boot screen, toggle after 2,5 seconds - if(strlen(oemStore.oem_text) > 0){ + if (strlen(oemStore.oem_text) > 0) { static bool showingOEMBootScreen = true; if (showingOEMBootScreen && (millis() > (2500 + serialSinceMsec))) { DEBUG_MSG("Switch to OEM screen...\n"); @@ -991,7 +994,7 @@ int32_t Screen::runOnce() } #ifndef DISABLE_WELCOME_UNSET - if (showingNormalScreen && radioConfig.preferences.region == RegionCode_Unset) { + if (showingNormalScreen && config.lora.region == Config_LoRaConfig_RegionCode_Unset) { setWelcomeFrames(); } #endif @@ -1064,8 +1067,8 @@ int32_t Screen::runOnce() // standard screen switching is stopped. if (showingNormalScreen) { // standard screen loop handling here - if (radioConfig.preferences.auto_screen_carousel_secs > 0 && - (millis() - lastScreenTransition) > (radioConfig.preferences.auto_screen_carousel_secs * 1000)) { + if (config.display.auto_screen_carousel_secs > 0 && + (millis() - lastScreenTransition) > (config.display.auto_screen_carousel_secs * 1000)) { DEBUG_MSG("LastScreenTransition exceeded %ums transitioning to next frame\n", (millis() - lastScreenTransition)); handleOnPress(); } @@ -1340,8 +1343,8 @@ void DebugInfo::drawFrame(OLEDDisplay *display, OLEDDisplayUiState *state, int16 void DebugInfo::drawFrameWiFi(OLEDDisplay *display, OLEDDisplayUiState *state, int16_t x, int16_t y) { #ifdef HAS_WIFI - const char *wifiName = radioConfig.preferences.wifi_ssid; - const char *wifiPsw = radioConfig.preferences.wifi_password; + const char *wifiName = config.wifi.ssid; + const char *wifiPsw = config.wifi.psk; displayedNodeNum = 0; // Not currently showing a node pane @@ -1352,7 +1355,7 @@ void DebugInfo::drawFrameWiFi(OLEDDisplay *display, OLEDDisplayUiState *state, i if (isSoftAPForced()) { display->drawString(x, y, String("WiFi: Software AP (Admin)")); - } else if (radioConfig.preferences.wifi_ap_mode) { + } else if (config.wifi.ap_mode) { display->drawString(x, y, String("WiFi: Software AP")); } else if (WiFi.status() != WL_CONNECTED) { display->drawString(x, y, String("WiFi: Not Connected")); @@ -1375,8 +1378,8 @@ void DebugInfo::drawFrameWiFi(OLEDDisplay *display, OLEDDisplayUiState *state, i - WL_NO_SHIELD: assigned when no WiFi shield is present; */ - if (WiFi.status() == WL_CONNECTED || isSoftAPForced() || radioConfig.preferences.wifi_ap_mode) { - if (radioConfig.preferences.wifi_ap_mode || isSoftAPForced()) { + if (WiFi.status() == WL_CONNECTED || isSoftAPForced() || config.wifi.ap_mode) { + if (config.wifi.ap_mode || isSoftAPForced()) { display->drawString(x, y + FONT_HEIGHT_SMALL * 1, "IP: " + String(WiFi.softAPIP().toString().c_str())); // Number of connections to the AP. Default max for the esp32 is 4 @@ -1468,7 +1471,7 @@ void DebugInfo::drawFrameWiFi(OLEDDisplay *display, OLEDDisplayUiState *state, i } } else { - if (radioConfig.preferences.wifi_ap_mode) { + if (config.wifi.ap_mode) { if ((millis() / 10000) % 2) { display->drawString(x, y + FONT_HEIGHT_SMALL * 2, "SSID: " + String(wifiName)); } else { @@ -1515,22 +1518,31 @@ void DebugInfo::drawFrameSettings(OLEDDisplay *display, OLEDDisplayUiState *stat auto mode = ""; - if (channels.getPrimary().modem_config == 0) { - mode = "VLongSlow"; - } else if (channels.getPrimary().modem_config == 1) { - mode = "LongSlow"; - } else if (channels.getPrimary().modem_config == 2) { - mode = "LongFast"; - } else if (channels.getPrimary().modem_config == 3) { - mode = "MidSlow"; - } else if (channels.getPrimary().modem_config == 4) { - mode = "MidFast"; - } else if (channels.getPrimary().modem_config == 5) { + switch (config.lora.modem_preset) { + case Config_LoRaConfig_ModemPreset_ShortSlow: mode = "ShortSlow"; - } else if (channels.getPrimary().modem_config == 6) { + break; + case Config_LoRaConfig_ModemPreset_ShortFast: mode = "ShortFast"; - } else { + break; + case Config_LoRaConfig_ModemPreset_MidSlow: + mode = "MediumSlow"; + break; + case Config_LoRaConfig_ModemPreset_MidFast: + mode = "MediumFast"; + break; + case Config_LoRaConfig_ModemPreset_LongFast: + mode = "LongFast"; + break; + case Config_LoRaConfig_ModemPreset_LongSlow: + mode = "LongSlow"; + break; + case Config_LoRaConfig_ModemPreset_VLongSlow: + mode = "VLongSlow"; + break; + default: mode = "Custom"; + break; } display->drawString(x + SCREEN_WIDTH - display->getStringWidth(mode), y, mode); @@ -1583,7 +1595,8 @@ void DebugInfo::drawFrameSettings(OLEDDisplay *display, OLEDDisplayUiState *stat display->drawString(x + SCREEN_WIDTH - display->getStringWidth(chUtil), y + FONT_HEIGHT_SMALL * 1, chUtil); // Line 3 - if (radioConfig.preferences.gps_format != GpsCoordinateFormat_GpsFormatDMS) // if DMS then don't draw altitude + if (config.display.gps_format != + Config_DisplayConfig_GpsCoordinateFormat_GpsFormatDMS) // if DMS then don't draw altitude drawGPSAltitude(display, x, y + FONT_HEIGHT_SMALL * 2, gpsStatus); // Line 4 @@ -1652,3 +1665,4 @@ int Screen::handleUIFrameEvent(const UIFrameEvent *event) } } // namespace graphics +#endif // NO_SCREEN \ No newline at end of file diff --git a/src/graphics/Screen.h b/src/graphics/Screen.h index 259598b80..0073e034b 100644 --- a/src/graphics/Screen.h +++ b/src/graphics/Screen.h @@ -1,6 +1,7 @@ #pragma once #ifdef NO_SCREEN +#include "power.h" namespace graphics { // Noop class for boards without screen. @@ -15,6 +16,8 @@ class Screen void adjustBrightness(){} void doDeepSleep() {} void forceDisplay() {} + void startBluetoothPinScreen(uint32_t pin) {} + void stopBluetoothPinScreen() {} }; } @@ -310,7 +313,7 @@ class Screen : public concurrency::OSThread SH1106Wire dispdev; #elif defined(USE_SSD1306) SSD1306Wire dispdev; -#elif defined(ST7735_CS) +#elif defined(ST7735_CS) || defined(ILI9341_DRIVER) TFTDisplay dispdev; #elif defined(HAS_EINK) EInkDisplay dispdev; diff --git a/src/graphics/TFTDisplay.cpp b/src/graphics/TFTDisplay.cpp index 21534edd3..dec496313 100644 --- a/src/graphics/TFTDisplay.cpp +++ b/src/graphics/TFTDisplay.cpp @@ -1,6 +1,6 @@ #include "configuration.h" -#ifdef ST7735_CS +#if defined(ST7735_CS) || defined(ILI9341_DRIVER) #include "SPILock.h" #include "TFTDisplay.h" #include @@ -10,7 +10,11 @@ static TFT_eSPI tft = TFT_eSPI(); // Invoke library, pins defined in User_Setup. TFTDisplay::TFTDisplay(uint8_t address, int sda, int scl) { - setGeometry(GEOMETRY_RAWMODE, 160, 80); +#ifdef SCREEN_ROTATE + setGeometry(GEOMETRY_RAWMODE, TFT_HEIGHT, TFT_WIDTH); +#else + setGeometry(GEOMETRY_RAWMODE, TFT_WIDTH, TFT_HEIGHT); +#endif } // Write the buffer to the display memory @@ -20,12 +24,10 @@ void TFTDisplay::display(void) // FIXME - only draw bits have changed (use backbuf similar to the other displays) // tft.drawBitmap(0, 0, buffer, 128, 64, TFT_YELLOW, TFT_BLACK); - for (uint8_t y = 0; y < displayHeight; y++) { - for (uint8_t x = 0; x < displayWidth; x++) { - + for (uint16_t y = 0; y < displayHeight; y++) { + for (uint16_t x = 0; x < displayWidth; x++) { // get src pixel in the page based ordering the OLED lib uses FIXME, super inefficent - auto b = buffer[x + (y / 8) * displayWidth]; - auto isset = b & (1 << (y & 7)); + auto isset = buffer[x + (y / 8) * displayWidth] & (1 << (y & 7)); tft.drawPixel(x, y, isset ? TFT_WHITE : TFT_BLACK); } } @@ -38,21 +40,34 @@ void TFTDisplay::sendCommand(uint8_t com) // Drop all commands to device (we just update the buffer) } +void TFTDisplay::setDetected(uint8_t detected) +{ + (void)detected; +} + // Connect to the display bool TFTDisplay::connect() { + concurrency::LockGuard g(spiLock); DEBUG_MSG("Doing TFT init\n"); +#ifdef TFT_BL + digitalWrite(TFT_BL, HIGH); + pinMode(TFT_BL, OUTPUT); +#endif + #ifdef ST7735_BACKLIGHT_EN digitalWrite(ST7735_BACKLIGHT_EN, HIGH); pinMode(ST7735_BACKLIGHT_EN, OUTPUT); #endif - tft.init(); +#ifdef M5STACK + tft.setRotation(1); // M5Stack has the TFT in landscape +#else tft.setRotation(3); // Orient horizontal and wide underneath the silkscreen name label +#endif tft.fillScreen(TFT_BLACK); // tft.drawRect(0, 0, 40, 10, TFT_PURPLE); // wide rectangle in upper left - return true; } diff --git a/src/graphics/TFTDisplay.h b/src/graphics/TFTDisplay.h index c21f190ce..c9749d9a8 100644 --- a/src/graphics/TFTDisplay.h +++ b/src/graphics/TFTDisplay.h @@ -22,6 +22,12 @@ class TFTDisplay : public OLEDDisplay // Write the buffer to the display memory virtual void display(void) override; + + /** + * shim to make the abstraction happy + * + */ + void setDetected(uint8_t detected); protected: // the header size of the buffer used, e.g. for the SPI command header diff --git a/src/input/RotaryEncoderInterruptBase.cpp b/src/input/RotaryEncoderInterruptBase.cpp index 290e8fb3e..1cda39a79 100644 --- a/src/input/RotaryEncoderInterruptBase.cpp +++ b/src/input/RotaryEncoderInterruptBase.cpp @@ -1,17 +1,14 @@ -#include "configuration.h" #include "RotaryEncoderInterruptBase.h" +#include "configuration.h" -RotaryEncoderInterruptBase::RotaryEncoderInterruptBase( - const char *name) : - concurrency::OSThread(name) +RotaryEncoderInterruptBase::RotaryEncoderInterruptBase(const char *name) : concurrency::OSThread(name) { this->_originName = name; } void RotaryEncoderInterruptBase::init( - uint8_t pinA, uint8_t pinB, uint8_t pinPress, - char eventCw, char eventCcw, char eventPressed, -// std::function onIntA, std::function onIntB, std::function onIntPress) : + uint8_t pinA, uint8_t pinB, uint8_t pinPress, char eventCw, char eventCcw, char eventPressed, + // std::function onIntA, std::function onIntB, std::function onIntPress) : void (*onIntA)(), void (*onIntB)(), void (*onIntPress)()) { this->_pinA = pinA; @@ -24,42 +21,34 @@ void RotaryEncoderInterruptBase::init( pinMode(this->_pinA, INPUT_PULLUP); pinMode(this->_pinB, INPUT_PULLUP); -// attachInterrupt(pinPress, onIntPress, RISING); + // attachInterrupt(pinPress, onIntPress, RISING); attachInterrupt(pinPress, onIntPress, RISING); attachInterrupt(this->_pinA, onIntA, CHANGE); attachInterrupt(this->_pinB, onIntB, CHANGE); this->rotaryLevelA = digitalRead(this->_pinA); this->rotaryLevelB = digitalRead(this->_pinB); - DEBUG_MSG("Rotary initialized (%d, %d, %d)\n", - this->_pinA, this->_pinB, pinPress); + DEBUG_MSG("Rotary initialized (%d, %d, %d)\n", this->_pinA, this->_pinB, pinPress); } - int32_t RotaryEncoderInterruptBase::runOnce() { InputEvent e; - e.inputEvent = InputEventChar_KEY_NONE; + e.inputEvent = ModuleConfig_CannedMessageConfig_InputEventChar_KEY_NONE; e.source = this->_originName; - if (this->action == ROTARY_ACTION_PRESSED) - { + if (this->action == ROTARY_ACTION_PRESSED) { DEBUG_MSG("Rotary event Press\n"); e.inputEvent = this->_eventPressed; - } - else if (this->action == ROTARY_ACTION_CW) - { + } else if (this->action == ROTARY_ACTION_CW) { DEBUG_MSG("Rotary event CW\n"); e.inputEvent = this->_eventCw; - } - else if (this->action == ROTARY_ACTION_CCW) - { + } else if (this->action == ROTARY_ACTION_CCW) { DEBUG_MSG("Rotary event CCW\n"); e.inputEvent = this->_eventCcw; } - if (e.inputEvent != InputEventChar_KEY_NONE) - { + if (e.inputEvent != ModuleConfig_CannedMessageConfig_InputEventChar_KEY_NONE) { this->notifyObservers(&e); } @@ -68,7 +57,6 @@ int32_t RotaryEncoderInterruptBase::runOnce() return 30000; // TODO: technically this can be MAX_INT } - void RotaryEncoderInterruptBase::intPressHandler() { this->action = ROTARY_ACTION_PRESSED; @@ -79,66 +67,47 @@ void RotaryEncoderInterruptBase::intAHandler() { // CW rotation (at least on most common rotary encoders) int currentLevelA = digitalRead(this->_pinA); - if (this->rotaryLevelA == currentLevelA) - { + if (this->rotaryLevelA == currentLevelA) { return; } this->rotaryLevelA = currentLevelA; - this->rotaryStateCCW = intHandler( - currentLevelA == HIGH, - this->rotaryLevelB, - ROTARY_ACTION_CCW, - this->rotaryStateCCW); + this->rotaryStateCCW = intHandler(currentLevelA == HIGH, this->rotaryLevelB, ROTARY_ACTION_CCW, this->rotaryStateCCW); } void RotaryEncoderInterruptBase::intBHandler() { // CW rotation (at least on most common rotary encoders) int currentLevelB = digitalRead(this->_pinB); - if (this->rotaryLevelB == currentLevelB) - { + if (this->rotaryLevelB == currentLevelB) { return; } this->rotaryLevelB = currentLevelB; - this->rotaryStateCW = intHandler( - currentLevelB == HIGH, - this->rotaryLevelA, - ROTARY_ACTION_CW, - this->rotaryStateCW); + this->rotaryStateCW = intHandler(currentLevelB == HIGH, this->rotaryLevelA, ROTARY_ACTION_CW, this->rotaryStateCW); } /** * @brief Rotary action implementation. * We assume, the following pin setup: * A --|| - * GND --||]======== + * GND --||]======== * B --|| - * + * * @return The new state for rotary pin. */ -RotaryEncoderInterruptBaseStateType RotaryEncoderInterruptBase::intHandler( - bool actualPinRaising, - int otherPinLevel, - RotaryEncoderInterruptBaseActionType action, - RotaryEncoderInterruptBaseStateType state) +RotaryEncoderInterruptBaseStateType RotaryEncoderInterruptBase::intHandler(bool actualPinRaising, int otherPinLevel, + RotaryEncoderInterruptBaseActionType action, + RotaryEncoderInterruptBaseStateType state) { - RotaryEncoderInterruptBaseStateType newState = - state; - if (actualPinRaising && (otherPinLevel == LOW)) - { - if (state == ROTARY_EVENT_CLEARED) - { + RotaryEncoderInterruptBaseStateType newState = state; + if (actualPinRaising && (otherPinLevel == LOW)) { + if (state == ROTARY_EVENT_CLEARED) { newState = ROTARY_EVENT_OCCURRED; - if ((this->action != ROTARY_ACTION_PRESSED) - && (this->action != action)) - { + if ((this->action != ROTARY_ACTION_PRESSED) && (this->action != action)) { this->action = action; DEBUG_MSG("Rotary action\n"); } } - } - else if (!actualPinRaising && (otherPinLevel == HIGH)) - { + } else if (!actualPinRaising && (otherPinLevel == HIGH)) { // Logic to prevent bouncing. newState = ROTARY_EVENT_CLEARED; } diff --git a/src/input/RotaryEncoderInterruptBase.h b/src/input/RotaryEncoderInterruptBase.h index 58e7b80e8..2965790fd 100644 --- a/src/input/RotaryEncoderInterruptBase.h +++ b/src/input/RotaryEncoderInterruptBase.h @@ -1,45 +1,28 @@ #pragma once -#include "SinglePortModule.h" // TODO: what header file to include? #include "InputBroker.h" +#include "SinglePortModule.h" // TODO: what header file to include? -enum RotaryEncoderInterruptBaseStateType -{ - ROTARY_EVENT_OCCURRED, - ROTARY_EVENT_CLEARED -}; +enum RotaryEncoderInterruptBaseStateType { ROTARY_EVENT_OCCURRED, ROTARY_EVENT_CLEARED }; -enum RotaryEncoderInterruptBaseActionType -{ - ROTARY_ACTION_NONE, - ROTARY_ACTION_PRESSED, - ROTARY_ACTION_CW, - ROTARY_ACTION_CCW -}; +enum RotaryEncoderInterruptBaseActionType { ROTARY_ACTION_NONE, ROTARY_ACTION_PRESSED, ROTARY_ACTION_CW, ROTARY_ACTION_CCW }; -class RotaryEncoderInterruptBase : - public Observable, - private concurrency::OSThread +class RotaryEncoderInterruptBase : public Observable, private concurrency::OSThread { public: - explicit RotaryEncoderInterruptBase( - const char *name); - void init( - uint8_t pinA, uint8_t pinB, uint8_t pinPress, - char eventCw, char eventCcw, char eventPressed, -// std::function onIntA, std::function onIntB, std::function onIntPress); - void (*onIntA)(), void (*onIntB)(), void (*onIntPress)()); + explicit RotaryEncoderInterruptBase(const char *name); + void init(uint8_t pinA, uint8_t pinB, uint8_t pinPress, char eventCw, char eventCcw, char eventPressed, + // std::function onIntA, std::function onIntB, std::function onIntPress); + void (*onIntA)(), void (*onIntB)(), void (*onIntPress)()); void intPressHandler(); void intAHandler(); void intBHandler(); protected: virtual int32_t runOnce() override; - RotaryEncoderInterruptBaseStateType intHandler( - bool actualPinRaising, - int otherPinLevel, - RotaryEncoderInterruptBaseActionType action, - RotaryEncoderInterruptBaseStateType state); + RotaryEncoderInterruptBaseStateType intHandler(bool actualPinRaising, int otherPinLevel, + RotaryEncoderInterruptBaseActionType action, + RotaryEncoderInterruptBaseStateType state); volatile RotaryEncoderInterruptBaseStateType rotaryStateCW = ROTARY_EVENT_CLEARED; volatile RotaryEncoderInterruptBaseStateType rotaryStateCCW = ROTARY_EVENT_CLEARED; @@ -50,8 +33,8 @@ class RotaryEncoderInterruptBase : private: uint8_t _pinA = 0; uint8_t _pinB = 0; - char _eventCw = InputEventChar_KEY_NONE; - char _eventCcw = InputEventChar_KEY_NONE; - char _eventPressed = InputEventChar_KEY_NONE; + char _eventCw = ModuleConfig_CannedMessageConfig_InputEventChar_KEY_NONE; + char _eventCcw = ModuleConfig_CannedMessageConfig_InputEventChar_KEY_NONE; + char _eventPressed = ModuleConfig_CannedMessageConfig_InputEventChar_KEY_NONE; const char *_originName; }; diff --git a/src/input/RotaryEncoderInterruptImpl1.cpp b/src/input/RotaryEncoderInterruptImpl1.cpp index dcc26b052..bc897deef 100644 --- a/src/input/RotaryEncoderInterruptImpl1.cpp +++ b/src/input/RotaryEncoderInterruptImpl1.cpp @@ -3,37 +3,26 @@ RotaryEncoderInterruptImpl1 *rotaryEncoderInterruptImpl1; -RotaryEncoderInterruptImpl1::RotaryEncoderInterruptImpl1() : - RotaryEncoderInterruptBase( - "rotEnc1") -{ -} +RotaryEncoderInterruptImpl1::RotaryEncoderInterruptImpl1() : RotaryEncoderInterruptBase("rotEnc1") {} void RotaryEncoderInterruptImpl1::init() { - if (!radioConfig.preferences.rotary1_enabled) - { + if (!moduleConfig.canned_message.rotary1_enabled) { // Input device is disabled. return; } - uint8_t pinA = radioConfig.preferences.inputbroker_pin_a; - uint8_t pinB = radioConfig.preferences.inputbroker_pin_b; - uint8_t pinPress = radioConfig.preferences.inputbroker_pin_press; - char eventCw = - static_cast(radioConfig.preferences.inputbroker_event_cw); - char eventCcw = - static_cast(radioConfig.preferences.inputbroker_event_ccw); - char eventPressed = - static_cast(radioConfig.preferences.inputbroker_event_press); + uint8_t pinA = moduleConfig.canned_message.inputbroker_pin_a; + uint8_t pinB = moduleConfig.canned_message.inputbroker_pin_b; + uint8_t pinPress = moduleConfig.canned_message.inputbroker_pin_press; + char eventCw = static_cast(moduleConfig.canned_message.inputbroker_event_cw); + char eventCcw = static_cast(moduleConfig.canned_message.inputbroker_event_ccw); + char eventPressed = static_cast(moduleConfig.canned_message.inputbroker_event_press); - //radioConfig.preferences.ext_notification_module_output - RotaryEncoderInterruptBase::init( - pinA, pinB, pinPress, - eventCw, eventCcw, eventPressed, - RotaryEncoderInterruptImpl1::handleIntA, - RotaryEncoderInterruptImpl1::handleIntB, - RotaryEncoderInterruptImpl1::handleIntPressed); + // moduleConfig.canned_message.ext_notification_module_output + RotaryEncoderInterruptBase::init(pinA, pinB, pinPress, eventCw, eventCcw, eventPressed, + RotaryEncoderInterruptImpl1::handleIntA, RotaryEncoderInterruptImpl1::handleIntB, + RotaryEncoderInterruptImpl1::handleIntPressed); inputBroker->registerSource(this); } diff --git a/src/input/UpDownInterruptBase.h b/src/input/UpDownInterruptBase.h index 5e1231b40..b6382ff71 100644 --- a/src/input/UpDownInterruptBase.h +++ b/src/input/UpDownInterruptBase.h @@ -1,18 +1,14 @@ #pragma once -#include "SinglePortModule.h" // TODO: what header file to include? #include "InputBroker.h" +#include "SinglePortModule.h" // TODO: what header file to include? -class UpDownInterruptBase : - public Observable +class UpDownInterruptBase : public Observable { public: - explicit UpDownInterruptBase( - const char *name); - void init( - uint8_t pinDown, uint8_t pinUp, uint8_t pinPress, - char eventDown, char eventUp, char eventPressed, - void (*onIntDown)(), void (*onIntUp)(), void (*onIntPress)()); + explicit UpDownInterruptBase(const char *name); + void init(uint8_t pinDown, uint8_t pinUp, uint8_t pinPress, char eventDown, char eventUp, char eventPressed, + void (*onIntDown)(), void (*onIntUp)(), void (*onIntPress)()); void intPressHandler(); void intDownHandler(); void intUpHandler(); @@ -20,8 +16,8 @@ class UpDownInterruptBase : private: uint8_t _pinDown = 0; uint8_t _pinUp = 0; - char _eventDown = InputEventChar_KEY_NONE; - char _eventUp = InputEventChar_KEY_NONE; - char _eventPressed = InputEventChar_KEY_NONE; + char _eventDown = ModuleConfig_CannedMessageConfig_InputEventChar_KEY_NONE; + char _eventUp = ModuleConfig_CannedMessageConfig_InputEventChar_KEY_NONE; + char _eventPressed = ModuleConfig_CannedMessageConfig_InputEventChar_KEY_NONE; const char *_originName; }; diff --git a/src/input/UpDownInterruptImpl1.cpp b/src/input/UpDownInterruptImpl1.cpp index 4d8916fb1..fc04a8628 100644 --- a/src/input/UpDownInterruptImpl1.cpp +++ b/src/input/UpDownInterruptImpl1.cpp @@ -3,38 +3,26 @@ UpDownInterruptImpl1 *upDownInterruptImpl1; -UpDownInterruptImpl1::UpDownInterruptImpl1() : - UpDownInterruptBase( - "upDown1") -{ -} +UpDownInterruptImpl1::UpDownInterruptImpl1() : UpDownInterruptBase("upDown1") {} void UpDownInterruptImpl1::init() { - if (!radioConfig.preferences.updown1_enabled) - { + if (!moduleConfig.canned_message.updown1_enabled) { // Input device is disabled. return; } - uint8_t pinUp = radioConfig.preferences.inputbroker_pin_a; - uint8_t pinDown = radioConfig.preferences.inputbroker_pin_b; - uint8_t pinPress = radioConfig.preferences.inputbroker_pin_press; + uint8_t pinUp = moduleConfig.canned_message.inputbroker_pin_a; + uint8_t pinDown = moduleConfig.canned_message.inputbroker_pin_b; + uint8_t pinPress = moduleConfig.canned_message.inputbroker_pin_press; - char eventDown = - static_cast(InputEventChar_KEY_DOWN); - char eventUp = - static_cast(InputEventChar_KEY_UP); - char eventPressed = - static_cast(InputEventChar_KEY_SELECT); + char eventDown = static_cast(ModuleConfig_CannedMessageConfig_InputEventChar_KEY_DOWN); + char eventUp = static_cast(ModuleConfig_CannedMessageConfig_InputEventChar_KEY_UP); + char eventPressed = static_cast(ModuleConfig_CannedMessageConfig_InputEventChar_KEY_SELECT); - UpDownInterruptBase::init( - pinDown, pinUp, pinPress, - eventDown, eventUp, eventPressed, - UpDownInterruptImpl1::handleIntDown, - UpDownInterruptImpl1::handleIntUp, - UpDownInterruptImpl1::handleIntPressed); + UpDownInterruptBase::init(pinDown, pinUp, pinPress, eventDown, eventUp, eventPressed, UpDownInterruptImpl1::handleIntDown, + UpDownInterruptImpl1::handleIntUp, UpDownInterruptImpl1::handleIntPressed); inputBroker->registerSource(this); } diff --git a/src/input/kbI2cBase.cpp b/src/input/kbI2cBase.cpp index 62719efee..6a00e5a9a 100644 --- a/src/input/kbI2cBase.cpp +++ b/src/input/kbI2cBase.cpp @@ -1,5 +1,5 @@ -#include "configuration.h" #include "kbI2cBase.h" +#include "configuration.h" #include KbI2cBase::KbI2cBase(const char *name) : concurrency::OSThread(name) @@ -10,40 +10,39 @@ KbI2cBase::KbI2cBase(const char *name) : concurrency::OSThread(name) int32_t KbI2cBase::runOnce() { InputEvent e; - e.inputEvent = InputEventChar_KEY_NONE; + e.inputEvent = ModuleConfig_CannedMessageConfig_InputEventChar_KEY_NONE; e.source = this->_originName; Wire.requestFrom(CARDKB_ADDR, 1); - - while(Wire.available()) { + + while (Wire.available()) { char c = Wire.read(); - switch(c) { + switch (c) { case 0x1b: // ESC - e.inputEvent = InputEventChar_KEY_CANCEL; + e.inputEvent = ModuleConfig_CannedMessageConfig_InputEventChar_KEY_CANCEL; break; case 0x08: // Back - e.inputEvent = InputEventChar_KEY_BACK; + e.inputEvent = ModuleConfig_CannedMessageConfig_InputEventChar_KEY_BACK; break; case 0xb5: // Up - e.inputEvent = InputEventChar_KEY_UP; + e.inputEvent = ModuleConfig_CannedMessageConfig_InputEventChar_KEY_UP; break; case 0xb6: // Down - e.inputEvent = InputEventChar_KEY_DOWN; + e.inputEvent = ModuleConfig_CannedMessageConfig_InputEventChar_KEY_DOWN; break; case 0xb4: // Left - e.inputEvent = InputEventChar_KEY_LEFT; + e.inputEvent = ModuleConfig_CannedMessageConfig_InputEventChar_KEY_LEFT; break; case 0xb7: // Right - e.inputEvent = InputEventChar_KEY_RIGHT; + e.inputEvent = ModuleConfig_CannedMessageConfig_InputEventChar_KEY_RIGHT; break; case 0x0d: // Enter - e.inputEvent = InputEventChar_KEY_SELECT; + e.inputEvent = ModuleConfig_CannedMessageConfig_InputEventChar_KEY_SELECT; break; } } - if (e.inputEvent != InputEventChar_KEY_NONE) - { + if (e.inputEvent != ModuleConfig_CannedMessageConfig_InputEventChar_KEY_NONE) { this->notifyObservers(&e); } return 500; diff --git a/src/main.cpp b/src/main.cpp index 9eb1f314d..6e1ff9151 100644 --- a/src/main.cpp +++ b/src/main.cpp @@ -1,4 +1,3 @@ -#include "configuration.h" #include "GPS.h" #include "MeshRadio.h" #include "MeshService.h" @@ -6,6 +5,7 @@ #include "PowerFSM.h" #include "airtime.h" #include "buzz.h" +#include "configuration.h" #include "error.h" #include "power.h" // #include "rom/rtc.h" @@ -17,28 +17,28 @@ #include "SPILock.h" #include "concurrency/OSThread.h" #include "concurrency/Periodic.h" +#include "debug/axpDebug.h" +#include "debug/einkScan.h" +#include "debug/i2cScan.h" #include "graphics/Screen.h" #include "main.h" #include "modules/Modules.h" -#include "sleep.h" #include "shutdown.h" +#include "sleep.h" #include "target_specific.h" -#include "debug/i2cScan.h" -#include "debug/einkScan.h" -#include "debug/axpDebug.h" #include // #include #include "mesh/http/WiFiAPClient.h" #ifndef NO_ESP32 - #include "mesh/http/WebServer.h" +#include "mesh/http/WebServer.h" - #ifdef USE_NEW_ESP32_BLUETOOTH - #include "esp32/ESP32Bluetooth.h" - #else - #include "nimble/BluetoothUtil.h" - #endif +#ifdef USE_NEW_ESP32_BLUETOOTH +#include "esp32/ESP32Bluetooth.h" +#else +#include "nimble/BluetoothUtil.h" +#endif #endif @@ -47,10 +47,10 @@ #include "mqtt/MQTT.h" #endif +#include "LLCC68Interface.h" #include "RF95Interface.h" #include "SX1262Interface.h" #include "SX1268Interface.h" -#include "LLCC68Interface.h" #include "ButtonThread.h" #include "PowerFSMThread.h" @@ -75,6 +75,8 @@ uint8_t screen_model; // The I2C address of the cardkb or RAK14004 (if found) uint8_t cardkb_found; +// 0x02 for RAK14004 and 0x00 for cardkb +uint8_t kb_model; // The I2C address of the Faces Keyboard (if found) uint8_t faceskb_found; @@ -133,7 +135,8 @@ RadioInterface *rIf = NULL; /** * Some platforms (nrf52) might provide an alterate version that supresses calling delay from sleep. */ -__attribute__ ((weak, noinline)) bool loopCanSleep() { +__attribute__((weak, noinline)) bool loopCanSleep() +{ return true; } @@ -152,18 +155,18 @@ void setup() #endif #ifdef DEBUG_PORT - if (!radioConfig.preferences.serial_disabled) { + if (!config.device.serial_disabled) { consoleInit(); // Set serial baud rate and init our mesh console } #endif - + serialSinceMsec = millis(); DEBUG_MSG("\n\n//\\ E S H T /\\ S T / C\n\n"); initDeepSleep(); - // Testing this fix für erratic T-Echo boot behaviour + // Testing this fix für erratic T-Echo boot behaviour #if defined(TTGO_T_ECHO) && defined(PIN_EINK_PWR_ON) pinMode(PIN_EINK_PWR_ON, OUTPUT); digitalWrite(PIN_EINK_PWR_ON, HIGH); @@ -208,7 +211,7 @@ void setup() fsInit(); - //router = new DSRRouter(); + // router = new DSRRouter(); router = new ReliableRouter(); #ifdef I2C_SDA @@ -301,7 +304,7 @@ void setup() // Don't call screen setup until after nodedb is setup (because we need // the current region name) -#if defined(ST7735_CS) || defined(HAS_EINK) +#if defined(ST7735_CS) || defined(HAS_EINK) || defined(ILI9341_DRIVER) screen->setup(); #else if (screen_found) @@ -314,6 +317,7 @@ void setup() // ONCE we will factory reset the GPS for bug #327 if (gps && !devicestate.did_gps_reset) { + DEBUG_MSG("GPS FactoryReset requested\n"); if (gps->factoryReset()) { // If we don't succeed try again next time devicestate.did_gps_reset = true; nodeDB.saveToDisk(); @@ -414,14 +418,12 @@ void setup() if (!rIf) RECORD_CRITICALERROR(CriticalErrorCode_NoRadio); - else{ + else { router->addInterface(rIf); // Calculate and save the bit rate to myNodeInfo // TODO: This needs to be added what ever method changes the channel from the phone. - myNodeInfo.bitrate = (float(Constants_DATA_PAYLOAD_LEN) / - (float(rIf->getPacketTime(Constants_DATA_PAYLOAD_LEN))) - ) * 1000; + myNodeInfo.bitrate = (float(Constants_DATA_PAYLOAD_LEN) / (float(rIf->getPacketTime(Constants_DATA_PAYLOAD_LEN)))) * 1000; DEBUG_MSG("myNodeInfo.bitrate = %f bytes / sec\n", myNodeInfo.bitrate); } @@ -433,7 +435,7 @@ void setup() setCPUFast(false); // 80MHz is fine for our slow peripherals } -uint32_t rebootAtMsec; // If not zero we will reboot at this time (used to reboot shortly after the update completes) +uint32_t rebootAtMsec; // If not zero we will reboot at this time (used to reboot shortly after the update completes) uint32_t shutdownAtMsec; // If not zero we will shutdown at this time (used to shutdown from python or mobile client) // If a thread does something that might need for it to be rescheduled ASAP it can set this flag diff --git a/src/main.h b/src/main.h index de79435bb..bb262a58b 100644 --- a/src/main.h +++ b/src/main.h @@ -8,6 +8,7 @@ extern uint8_t screen_found; extern uint8_t screen_model; extern uint8_t cardkb_found; +extern uint8_t kb_model; extern uint8_t faceskb_found; extern uint8_t rtc_found; diff --git a/src/mesh/Channels.cpp b/src/mesh/Channels.cpp index 2c6c6900d..c48dbd079 100644 --- a/src/mesh/Channels.cpp +++ b/src/mesh/Channels.cpp @@ -1,7 +1,7 @@ -#include "configuration.h" #include "Channels.h" #include "CryptoEngine.h" #include "NodeDB.h" +#include "configuration.h" #include @@ -83,10 +83,11 @@ void Channels::initDefaultChannel(ChannelIndex chIndex) { Channel &ch = getByIndex(chIndex); ChannelSettings &channelSettings = ch.settings; + Config_LoRaConfig &loraConfig = config.lora; - channelSettings.modem_config = ChannelSettings_ModemConfig_LongFast; // Default to Long Range & Fast + loraConfig.modem_preset = Config_LoRaConfig_ModemPreset_LongFast; // Default to Long Range & Fast - channelSettings.tx_power = 0; // default + loraConfig.tx_power = 0; // default uint8_t defaultpskIndex = 1; channelSettings.psk.bytes[0] = defaultpskIndex; channelSettings.psk.size = 1; @@ -206,32 +207,32 @@ const char *Channels::getName(size_t chIndex) const ChannelSettings &channelSettings = getByIndex(chIndex).settings; const char *channelName = channelSettings.name; if (!*channelName) { // emptystring - // Per mesh.proto spec, if bandwidth is specified we must ignore modemConfig enum, we assume that in that case + // Per mesh.proto spec, if bandwidth is specified we must ignore modemPreset enum, we assume that in that case // the app fucked up and forgot to set channelSettings.name - if (channelSettings.bandwidth != 0) + if (config.lora.bandwidth != 0) channelName = "Unset"; else - switch (channelSettings.modem_config) { - case ChannelSettings_ModemConfig_ShortSlow: + switch (config.lora.modem_preset) { + case Config_LoRaConfig_ModemPreset_ShortSlow: channelName = "ShortSlow"; break; - case ChannelSettings_ModemConfig_ShortFast: + case Config_LoRaConfig_ModemPreset_ShortFast: channelName = "ShortFast"; break; - case ChannelSettings_ModemConfig_MidSlow: + case Config_LoRaConfig_ModemPreset_MidSlow: channelName = "MediumSlow"; break; - case ChannelSettings_ModemConfig_MidFast: + case Config_LoRaConfig_ModemPreset_MidFast: channelName = "MediumFast"; break; - case ChannelSettings_ModemConfig_LongFast: + case Config_LoRaConfig_ModemPreset_LongFast: channelName = "LongFast"; break; - case ChannelSettings_ModemConfig_LongSlow: + case Config_LoRaConfig_ModemPreset_LongSlow: channelName = "LongSlow"; break; - case ChannelSettings_ModemConfig_VLongSlow: + case Config_LoRaConfig_ModemPreset_VLongSlow: channelName = "VLongSlow"; break; default: diff --git a/src/mesh/FloodingRouter.cpp b/src/mesh/FloodingRouter.cpp index de43a0ad1..e01863de1 100644 --- a/src/mesh/FloodingRouter.cpp +++ b/src/mesh/FloodingRouter.cpp @@ -32,7 +32,7 @@ void FloodingRouter::sniffReceived(const MeshPacket *p, const Routing *c) if ((p->to == NODENUM_BROADCAST) && (p->hop_limit > 0) && (getFrom(p) != getNodeNum())) { if (p->id != 0) { - if (radioConfig.preferences.role != Role_ClientMute) { + if (config.device.role != Config_DeviceConfig_Role_ClientMute) { MeshPacket *tosend = packetPool.allocCopy(*p); // keep a copy because we will be sending it tosend->hop_limit--; // bump down the hop count diff --git a/src/mesh/MeshRadio.h b/src/mesh/MeshRadio.h index 1b1437123..961d62192 100644 --- a/src/mesh/MeshRadio.h +++ b/src/mesh/MeshRadio.h @@ -7,7 +7,7 @@ // Map from old region names to new region enums struct RegionInfo { - RegionCode code; + Config_LoRaConfig_RegionCode code; float freqStart; float freqEnd; float dutyCycle; diff --git a/src/mesh/MeshService.cpp b/src/mesh/MeshService.cpp index 6fe8cd38d..035578d24 100644 --- a/src/mesh/MeshService.cpp +++ b/src/mesh/MeshService.cpp @@ -181,7 +181,8 @@ void MeshService::sendNetworkPing(NodeNum dest, bool wantReplies) } } -void MeshService::sendToPhone(MeshPacket *p) { +void MeshService::sendToPhone(MeshPacket *p) +{ if (toPhoneQueue.numFree() == 0) { DEBUG_MSG("NOTE: tophone queue is full, discarding oldest\n"); MeshPacket *d = toPhoneQueue.dequeuePtr(0); @@ -235,7 +236,7 @@ int MeshService::onGPSChanged(const meshtastic::GPSStatus *newStatus) #ifdef GPS_EXTRAVERBOSE DEBUG_MSG("onGPSchanged() - lost validLocation\n"); #endif - if (radioConfig.preferences.fixed_position) { + if (config.position.fixed_position) { DEBUG_MSG("WARNING: Using fixed position\n"); pos = node->position; } @@ -247,8 +248,8 @@ int MeshService::onGPSChanged(const meshtastic::GPSStatus *newStatus) pos.time = getValidTime(RTCQualityGPS); // In debug logs, identify position by @timestamp:stage (stage 4 = nodeDB) - DEBUG_MSG("onGPSChanged() pos@%x, time=%u, lat=%d, lon=%d, alt=%d\n", - pos.pos_timestamp, pos.time, pos.latitude_i, pos.longitude_i, pos.altitude); + DEBUG_MSG("onGPSChanged() pos@%x, time=%u, lat=%d, lon=%d, alt=%d\n", pos.pos_timestamp, pos.time, pos.latitude_i, + pos.longitude_i, pos.altitude); // Update our current position in the local DB nodeDB.updatePosition(nodeDB.getNodeNum(), pos, RX_SRC_LOCAL); diff --git a/src/mesh/NodeDB.cpp b/src/mesh/NodeDB.cpp index 660280fcb..d804aa8e1 100644 --- a/src/mesh/NodeDB.cpp +++ b/src/mesh/NodeDB.cpp @@ -34,7 +34,8 @@ NodeDB nodeDB; // we have plenty of ram so statically alloc this tempbuf (for now) EXT_RAM_ATTR DeviceState devicestate; MyNodeInfo &myNodeInfo = devicestate.my_node; -RadioConfig radioConfig; +LocalConfig config; +LocalModuleConfig moduleConfig; ChannelFile channelFile; /** The current change # for radio settings. Starts at 0 on boot and any time the radio settings @@ -86,8 +87,8 @@ bool NodeDB::resetRadioConfig() radioGeneration++; - radioConfig.has_preferences = true; - if (radioConfig.preferences.factory_reset) { + // radioConfig.has_preferences = true; + if (config.device.factory_reset) { DEBUG_MSG("Performing factory reset!\n"); installDefaultDeviceState(); #ifndef NO_ESP32 @@ -95,7 +96,7 @@ bool NodeDB::resetRadioConfig() nvs_flash_erase(); #endif #ifdef NRF52_SERIES - // first, remove the "/prefs" (this removes most prefs) + // first, remove the "/prefs" (this removes most prefs) FSCom.rmdir_r("/prefs"); // second, install default state (this will deal with the duplicate mac address issue) installDefaultDeviceState(); @@ -125,11 +126,11 @@ bool NodeDB::resetRadioConfig() DEBUG_MSG("***** DEVELOPMENT MODE - DO NOT RELEASE *****\n"); // Sleep quite frequently to stress test the BLE comms, broadcast position every 6 mins - radioConfig.preferences.screen_on_secs = 10; - radioConfig.preferences.wait_bluetooth_secs = 10; - radioConfig.preferences.position_broadcast_secs = 6 * 60; - radioConfig.preferences.ls_secs = 60; - radioConfig.preferences.region = RegionCode_TW; + config.display.screen_on_secs = 10; + config.power.wait_bluetooth_secs = 10; + config.position.position_broadcast_secs = 6 * 60; + config.power.ls_secs = 60; + config.lora.region = Config_LoRaConfig_RegionCode_TW; // Enter super deep sleep soon and stay there not very long // radioConfig.preferences.mesh_sds_timeout_secs = 10; @@ -142,30 +143,43 @@ bool NodeDB::resetRadioConfig() return didFactoryReset; } -void NodeDB::installDefaultRadioConfig() +void NodeDB::installDefaultConfig() { - memset(&radioConfig, 0, sizeof(radioConfig)); - radioConfig.has_preferences = true; + memset(&config, 0, sizeof(LocalConfig)); + config.lora.region = Config_LoRaConfig_RegionCode_Unset; + config.lora.modem_preset = Config_LoRaConfig_ModemPreset_LongFast; resetRadioConfig(); - - // for backward compat, default position flags are BAT+ALT+MSL (0x23 = 35) - radioConfig.preferences.position_flags = (PositionFlags_POS_BATTERY | - PositionFlags_POS_ALTITUDE | PositionFlags_POS_ALT_MSL); - + strncpy(config.device.ntp_server, "0.pool.ntp.org", 32); + // for backward compat, default position flags are ALT+MSL + config.position.position_flags = + (Config_PositionConfig_PositionFlags_POS_ALTITUDE | Config_PositionConfig_PositionFlags_POS_ALT_MSL); } +void NodeDB::installDefaultModuleConfig() +{ + memset(&moduleConfig, 0, sizeof(ModuleConfig)); +} + +// void NodeDB::installDefaultRadioConfig() +// { +// memset(&radioConfig, 0, sizeof(radioConfig)); +// radioConfig.has_preferences = true; +// resetRadioConfig(); + +// // for backward compat, default position flags are BAT+ALT+MSL (0x23 = 35) +// config.position.position_flags = +// (Config_PositionConfig_PositionFlags_POS_BATTERY | Config_PositionConfig_PositionFlags_POS_ALTITUDE | +// Config_PositionConfig_PositionFlags_POS_ALT_MSL); +// } + void NodeDB::installDefaultChannels() { - memset(&channelFile, 0, sizeof(channelFile)); + memset(&channelFile, 0, sizeof(ChannelFile)); } void NodeDB::installDefaultDeviceState() { - // We try to preserve the region setting because it will really bum users out if we discard it - String oldRegion = myNodeInfo.region; - RegionCode oldRegionCode = radioConfig.preferences.region; - - memset(&devicestate, 0, sizeof(devicestate)); + memset(&devicestate, 0, sizeof(DeviceState)); *numNodes = 0; // Forget node DB @@ -192,14 +206,8 @@ void NodeDB::installDefaultDeviceState() sprintf(owner.id, "!%08x", getNodeNum()); // Default node ID now based on nodenum memcpy(owner.macaddr, ourMacAddr, sizeof(owner.macaddr)); - // Restore region if possible - if (oldRegionCode != RegionCode_Unset) - radioConfig.preferences.region = oldRegionCode; - if (oldRegion.length()) // If the old style region was set, try to keep it up-to-date - strcpy(myNodeInfo.region, oldRegion.c_str()); - installDefaultChannels(); - installDefaultRadioConfig(); + installDefaultConfig(); } void NodeDB::init() @@ -241,14 +249,14 @@ void NodeDB::init() DEBUG_MSG("Number of Device Reboots: %d\n", myNodeInfo.reboot_count); /* The ESP32 has a wifi radio. This will need to be modified at some point so - * the test isn't so simplistic. - */ + * the test isn't so simplistic. + */ myNodeInfo.has_wifi = true; #endif resetRadioConfig(); // If bogus settings got saved, then fix them - DEBUG_MSG("region=%d, NODENUM=0x%x, dbsize=%d\n", radioConfig.preferences.region, myNodeInfo.my_node_num, *numNodes); + DEBUG_MSG("region=%d, NODENUM=0x%x, dbsize=%d\n", config.lora.region, myNodeInfo.my_node_num, *numNodes); } // We reserve a few nodenums for future use @@ -279,7 +287,8 @@ void NodeDB::pickNewNodeNum() } static const char *preffile = "/prefs/db.proto"; -static const char *radiofile = "/prefs/radio.proto"; +static const char *configfile = "/prefs/config.proto"; +static const char *moduleConfigfile = "/prefs/module.proto"; static const char *channelfile = "/prefs/channels.proto"; /** Load a protobuf from a file, return true for success */ @@ -328,8 +337,12 @@ void NodeDB::loadFromDisk() } } - if (!loadProto(radiofile, RadioConfig_size, sizeof(RadioConfig), RadioConfig_fields, &radioConfig)) { - installDefaultRadioConfig(); // Our in RAM copy might now be corrupt + if (!loadProto(configfile, LocalConfig_size, sizeof(LocalConfig), LocalConfig_fields, &config)) { + installDefaultConfig(); // Our in RAM copy might now be corrupt + } + + if (!loadProto(moduleConfigfile, ModuleConfig_size, sizeof(ModuleConfig), ModuleConfig_fields, &moduleConfig)) { + installDefaultModuleConfig(); // Our in RAM copy might now be corrupt } if (!loadProto(channelfile, ChannelFile_size, sizeof(ChannelFile), ChannelFile_fields, &channelFile)) { @@ -359,7 +372,7 @@ bool saveProto(const char *filename, size_t protoSize, size_t objSize, const pb_ f.close(); // brief window of risk here ;-) - if (!FSCom.remove(filename)) + if (FSCom.exists(filename) && !FSCom.remove(filename)) DEBUG_MSG("Warning: Can't remove old pref file\n"); if (!FSCom.rename(filenameTmp.c_str(), filename)) DEBUG_MSG("Error: can't rename new pref file\n"); @@ -389,7 +402,15 @@ void NodeDB::saveToDisk() FSCom.mkdir("/prefs"); #endif saveProto(preffile, DeviceState_size, sizeof(devicestate), DeviceState_fields, &devicestate); - saveProto(radiofile, RadioConfig_size, sizeof(RadioConfig), RadioConfig_fields, &radioConfig); + // save all config segments + config.has_device = true; + config.has_display = true; + config.has_lora = true; + config.has_position = true; + config.has_power = true; + config.has_wifi = true; + saveProto(configfile, LocalConfig_size, sizeof(LocalConfig), LocalConfig_fields, &config); + saveProto(moduleConfigfile, Module_Config_size, sizeof(ModuleConfig), ModuleConfig_fields, &moduleConfig); saveChannelsToDisk(); } else { @@ -417,7 +438,7 @@ uint32_t sinceLastSeen(const NodeInfo *n) return delta; } -#define NUM_ONLINE_SECS (60 & 60 * 2) // 2 hrs to consider someone offline +#define NUM_ONLINE_SECS (60 * 60 * 2) // 2 hrs to consider someone offline size_t NodeDB::getNumOnlineNodes() { @@ -444,12 +465,11 @@ void NodeDB::updatePosition(uint32_t nodeId, const Position &p, RxSource src) if (src == RX_SRC_LOCAL) { // Local packet, fully authoritative - DEBUG_MSG("updatePosition LOCAL pos@%x, time=%u, latI=%d, lonI=%d, alt=%d\n", - p.pos_timestamp, p.time, p.latitude_i, p.longitude_i, p.altitude); + DEBUG_MSG("updatePosition LOCAL pos@%x, time=%u, latI=%d, lonI=%d, alt=%d\n", p.pos_timestamp, p.time, p.latitude_i, + p.longitude_i, p.altitude); info->position = p; - } else if ((p.time > 0) && !p.latitude_i && !p.longitude_i && !p.pos_timestamp && - !p.location_source) { + } else if ((p.time > 0) && !p.latitude_i && !p.longitude_i && !p.pos_timestamp && !p.location_source) { // FIXME SPECIAL TIME SETTING PACKET FROM EUD TO RADIO // (stop-gap fix for issue #900) DEBUG_MSG("updatePosition SPECIAL time setting time=%u\n", p.time); @@ -461,8 +481,7 @@ void NodeDB::updatePosition(uint32_t nodeId, const Position &p, RxSource src) // recorded based on the packet rxTime // // FIXME perhaps handle RX_SRC_USER separately? - DEBUG_MSG("updatePosition REMOTE node=0x%x time=%u, latI=%d, lonI=%d\n", - nodeId, p.time, p.latitude_i, p.longitude_i); + DEBUG_MSG("updatePosition REMOTE node=0x%x time=%u, latI=%d, lonI=%d\n", nodeId, p.time, p.latitude_i, p.longitude_i); // First, back up fields that we want to protect from overwrite uint32_t tmp_time = info->position.time; @@ -471,7 +490,7 @@ void NodeDB::updatePosition(uint32_t nodeId, const Position &p, RxSource src) info->position = p; // Last, restore any fields that may have been overwritten - if (! info->position.time) + if (!info->position.time) info->position.time = tmp_time; } info->has_position = true; @@ -479,7 +498,6 @@ void NodeDB::updatePosition(uint32_t nodeId, const Position &p, RxSource src) notifyObservers(true); // Force an update whether or not our node counts have changed } - /** Update telemetry info for this node based on received metrics * We only care about device telemetry here */ @@ -591,7 +609,7 @@ void recordCriticalError(CriticalErrorCode code, uint32_t address, const char *f // Print error to screen and serial port String lcd = String("Critical error ") + code + "!\n"; screen->print(lcd.c_str()); - if(filename) + if (filename) DEBUG_MSG("NOTE! Recording critical error %d at %s:%lx\n", code, filename, address); else DEBUG_MSG("NOTE! Recording critical error %d, address=%lx\n", code, address); diff --git a/src/mesh/NodeDB.h b/src/mesh/NodeDB.h index 4cea56068..e2ec49a9f 100644 --- a/src/mesh/NodeDB.h +++ b/src/mesh/NodeDB.h @@ -11,7 +11,8 @@ extern DeviceState devicestate; extern ChannelFile channelFile; extern MyNodeInfo &myNodeInfo; -extern RadioConfig radioConfig; +extern LocalConfig config; +extern LocalModuleConfig moduleConfig; extern User &owner; /// Given a node, return how many seconds in the past (vs now) that we last heard from it @@ -63,7 +64,7 @@ class NodeDB /** Update telemetry info for this node based on received metrics */ - void updateTelemetry(uint32_t nodeId, const Telemetry &t, RxSource src = RX_SRC_RADIO); + void updateTelemetry(uint32_t nodeId, const Telemetry &t, RxSource src = RX_SRC_RADIO); /** Update user info for this node based on received user data */ @@ -122,7 +123,8 @@ class NodeDB void loadFromDisk(); /// Reinit device state from scratch (not loading from disk) - void installDefaultDeviceState(), installDefaultRadioConfig(), installDefaultChannels(); + void installDefaultDeviceState(), installDefaultChannels(), installDefaultConfig(), + installDefaultModuleConfig(); }; /** @@ -146,7 +148,7 @@ extern NodeDB nodeDB; prefs.ls_secs = oneday prefs.position_broadcast_secs = 12 hours # send either position or owner every 12hrs - + # get a new GPS position once per day prefs.gps_update_interval = oneday @@ -159,33 +161,27 @@ extern NodeDB nodeDB; // Our delay functions check for this for times that should never expire #define NODE_DELAY_FOREVER 0xffffffff -#define IF_ROUTER(routerVal, normalVal) ((radioConfig.preferences.role == Role_Router) ? (routerVal) : (normalVal)) +#define IF_ROUTER(routerVal, normalVal) ((config.device.role == Config_DeviceConfig_Role_Router) ? (routerVal) : (normalVal)) -#define PREF_GET(name, defaultVal) \ - inline uint32_t getPref_##name() { return radioConfig.preferences.name ? radioConfig.preferences.name : (defaultVal); } - -PREF_GET(position_broadcast_secs, IF_ROUTER(12 * 60 * 60, 15 * 60)) -// Defaulting Telemetry to the same as position interval for now -PREF_GET(telemetry_module_device_update_interval, IF_ROUTER(12 * 60 * 60, 15 * 60)) -PREF_GET(telemetry_module_environment_update_interval, IF_ROUTER(12 * 60 * 60, 15 * 60)) +#define default_broadcast_interval_secs IF_ROUTER(12 * 60 * 60, 15 * 60) +#define default_wait_bluetooth_secs IF_ROUTER(1, 60) +#define default_mesh_sds_timeout_secs IF_ROUTER(NODE_DELAY_FOREVER, 2 * 60 * 60) +#define default_sds_secs 365 * 24 * 60 * 60 +#define default_ls_secs IF_ROUTER(24 * 60 * 60, 5 * 60) +#define default_phone_timeout_secs 15 * 60 +#define default_min_wake_secs 10 -// Each time we wake into the DARK state allow 1 minute to send and receive BLE packets to the phone -PREF_GET(wait_bluetooth_secs, IF_ROUTER(1, 60)) +inline uint32_t getIntervalOrDefaultMs(uint32_t interval) +{ + if (interval > 0) + return interval * 1000; + return default_broadcast_interval_secs * 1000; +} -PREF_GET(screen_on_secs, 60) -PREF_GET(mesh_sds_timeout_secs, IF_ROUTER(NODE_DELAY_FOREVER, 2 * 60 * 60)) -PREF_GET(sds_secs, 365 * 24 * 60 * 60) - -// We default to sleeping (with bluetooth off for 5 minutes at a time). This seems to be a good tradeoff between -// latency for the user sending messages and power savings because of not having to run (expensive) ESP32 bluetooth -PREF_GET(ls_secs, IF_ROUTER(24 * 60 * 60, 5 * 60)) - -PREF_GET(phone_timeout_secs, 15 * 60) -PREF_GET(min_wake_secs, 10) - -/** The current change # for radio settings. Starts at 0 on boot and any time the radio settings +/** The current change # for radio settings. Starts at 0 on boot and any time the radio settings * might have changed is incremented. Allows others to detect they might now be on a new channel. */ extern uint32_t radioGeneration; +#define Module_Config_size (ModuleConfig_CannedMessageConfig_size + ModuleConfig_ExternalNotificationConfig_size + ModuleConfig_MQTTConfig_size + ModuleConfig_RangeTestConfig_size + ModuleConfig_SerialConfig_size + ModuleConfig_StoreForwardConfig_size + ModuleConfig_TelemetryConfig_size + ModuleConfig_size) \ No newline at end of file diff --git a/src/mesh/PhoneAPI.cpp b/src/mesh/PhoneAPI.cpp index 033ef4906..cc40ff728 100644 --- a/src/mesh/PhoneAPI.cpp +++ b/src/mesh/PhoneAPI.cpp @@ -179,6 +179,9 @@ size_t PhoneAPI::getFromRadio(uint8_t *buf) // Encapsulate as a FromRadio packet fromRadioScratch.which_payloadVariant = FromRadio_packet_tag; fromRadioScratch.packet = *packetForPhone; + + // TODO: Remove with compression rework + fromRadioScratch.packet.decoded.which_payloadVariant = Data_payload_tag; } releasePhonePacket(); break; diff --git a/src/mesh/RadioInterface.cpp b/src/mesh/RadioInterface.cpp index e4b816b5b..111831518 100644 --- a/src/mesh/RadioInterface.cpp +++ b/src/mesh/RadioInterface.cpp @@ -13,7 +13,8 @@ #define RDEF(name, freq_start, freq_end, duty_cycle, spacing, power_limit, audio_permitted, frequency_switching) \ { \ - RegionCode_##name, freq_start, freq_end, duty_cycle, spacing, power_limit, audio_permitted, frequency_switching, #name \ + Config_LoRaConfig_RegionCode_##name, freq_start, freq_end, duty_cycle, spacing, power_limit, audio_permitted, \ + frequency_switching, #name \ } const RegionInfo regions[] = { @@ -76,15 +77,15 @@ const RegionInfo regions[] = { */ RDEF(IN, 865.0f, 867.0f, 100, 0, 30, true, false), - /* - https://rrf.rsm.govt.nz/smart-web/smart/page/-smart/domain/licence/LicenceSummary.wdk?id=219752 - https://iotalliance.org.nz/wp-content/uploads/sites/4/2019/05/IoT-Spectrum-in-NZ-Briefing-Paper.pdf - */ + /* + https://rrf.rsm.govt.nz/smart-web/smart/page/-smart/domain/licence/LicenceSummary.wdk?id=219752 + https://iotalliance.org.nz/wp-content/uploads/sites/4/2019/05/IoT-Spectrum-in-NZ-Briefing-Paper.pdf + */ RDEF(NZ865, 864.0f, 868.0f, 100, 0, 0, true, false), - /* - https://lora-alliance.org/wp-content/uploads/2020/11/lorawan_regional_parameters_v1.0.3reva_0.pdf - */ + /* + https://lora-alliance.org/wp-content/uploads/2020/11/lorawan_regional_parameters_v1.0.3reva_0.pdf + */ RDEF(TH, 920.0f, 925.0f, 100, 0, 16, true, false), /* @@ -99,10 +100,10 @@ const RegionInfo *myRegion; void initRegion() { const RegionInfo *r = regions; - for (; r->code != RegionCode_Unset && r->code != radioConfig.preferences.region; r++) + for (; r->code != Config_LoRaConfig_RegionCode_Unset && r->code != config.lora.region; r++) ; myRegion = r; - DEBUG_MSG("Wanted region %d, using %s\n", radioConfig.preferences.region, r->name); + DEBUG_MSG("Wanted region %d, using %s\n", config.lora.region, r->name); } /** @@ -159,9 +160,15 @@ uint32_t RadioInterface::getPacketTime(MeshPacket *p) uint32_t RadioInterface::getRetransmissionMsec(const MeshPacket *p) { assert(shortPacketMsec); // Better be non zero - - // was 20 and 22 secs respectively, but now with shortPacketMsec as 2269, this should give the same range - return random(9 * shortPacketMsec, 10 * shortPacketMsec); + static uint8_t bytes[MAX_RHPACKETLEN]; + size_t numbytes = pb_encode_to_bytes(bytes, sizeof(bytes), Data_fields, &p->decoded); + uint32_t packetAirtime = getPacketTime(numbytes + sizeof(PacketHeader)); + uint32_t tCADmsec = 2 * (1 << sf) / bw; // duration of CAD is roughly 2 symbols according to SX127x datasheet + /* Make sure enough time has elapsed for this packet to be sent and an ACK is received. + * Right now we have to wait until another node floods the same packet, as that is our implicit ACK. + * TODO: Revise when want_ack will be used (right now it is always set to 0 afterwards). + */ + return 2*packetAirtime + 2*MIN_TX_WAIT_MSEC + shortPacketMsec + shortPacketMsec*2 + PROCESSING_TIME_MSEC + 2*tCADmsec; } /** The delay to use when we want to send something but the ether is busy */ @@ -183,7 +190,6 @@ uint32_t RadioInterface::getTxDelayMsec() return random((MIN_TX_WAIT_MSEC), (MIN_TX_WAIT_MSEC + shortPacketMsec)); } - /** The delay to use when we want to send something but the ether is busy */ uint32_t RadioInterface::getTxDelayMsecWeighted(float snr) { @@ -202,7 +208,8 @@ uint32_t RadioInterface::getTxDelayMsecWeighted(float snr) // low SNR = Short Delay uint32_t delay = 0; - if (radioConfig.preferences.role == Role_Router || radioConfig.preferences.role == Role_RouterClient) { + if (config.device.role == Config_DeviceConfig_Role_Router || + config.device.role == Config_DeviceConfig_Role_RouterClient) { delay = map(snr, SNR_MIN, SNR_MAX, MIN_TX_WAIT_MSEC, (MIN_TX_WAIT_MSEC + (shortPacketMsec / 2))); DEBUG_MSG("rx_snr found in packet. As a router, setting tx delay:%d\n", delay); } else { @@ -210,7 +217,6 @@ uint32_t RadioInterface::getTxDelayMsecWeighted(float snr) DEBUG_MSG("rx_snr found in packet. Setting tx delay:%d\n", delay); } - return delay; } @@ -351,41 +357,41 @@ void RadioInterface::applyModemConfig() { // Set up default configuration // No Sync Words in LORA mode - + Config_LoRaConfig &loraConfig = config.lora; auto channelSettings = channels.getPrimary(); - if (channelSettings.spread_factor == 0) { - switch (channelSettings.modem_config) { - case ChannelSettings_ModemConfig_ShortFast: + if (loraConfig.spread_factor == 0) { + switch (loraConfig.modem_preset) { + case Config_LoRaConfig_ModemPreset_ShortFast: bw = 250; cr = 8; sf = 7; break; - case ChannelSettings_ModemConfig_ShortSlow: + case Config_LoRaConfig_ModemPreset_ShortSlow: bw = 250; cr = 8; sf = 8; break; - case ChannelSettings_ModemConfig_MidFast: + case Config_LoRaConfig_ModemPreset_MidFast: bw = 250; cr = 8; sf = 9; break; - case ChannelSettings_ModemConfig_MidSlow: + case Config_LoRaConfig_ModemPreset_MidSlow: bw = 250; cr = 8; sf = 10; break; - case ChannelSettings_ModemConfig_LongFast: + case Config_LoRaConfig_ModemPreset_LongFast: bw = 250; cr = 8; sf = 11; break; - case ChannelSettings_ModemConfig_LongSlow: + case Config_LoRaConfig_ModemPreset_LongSlow: bw = 125; cr = 8; sf = 12; break; - case ChannelSettings_ModemConfig_VLongSlow: + case Config_LoRaConfig_ModemPreset_VLongSlow: bw = 31.25; cr = 8; sf = 12; @@ -394,9 +400,9 @@ void RadioInterface::applyModemConfig() assert(0); // Unknown enum } } else { - sf = channelSettings.spread_factor; - cr = channelSettings.coding_rate; - bw = channelSettings.bandwidth; + sf = loraConfig.spread_factor; + cr = loraConfig.coding_rate; + bw = loraConfig.bandwidth; if (bw == 31) // This parameter is not an integer bw = 31.25; @@ -404,7 +410,7 @@ void RadioInterface::applyModemConfig() bw = 62.5; } - power = channelSettings.tx_power; + power = loraConfig.tx_power; shortPacketMsec = getPacketTime(sizeof(PacketHeader)); assert(myRegion); // Should have been found in init @@ -419,7 +425,7 @@ void RadioInterface::applyModemConfig() saveChannelNum(channel_num); saveFreq(freq); - DEBUG_MSG("Set radio: name=%s, config=%u, ch=%d, power=%d\n", channelName, channelSettings.modem_config, channel_num, power); + DEBUG_MSG("Set radio: name=%s, config=%u, ch=%d, power=%d\n", channelName, loraConfig.modem_preset, channel_num, power); DEBUG_MSG("Radio myRegion->freqStart / myRegion->freqEnd: %f -> %f (%f mhz)\n", myRegion->freqStart, myRegion->freqEnd, myRegion->freqEnd - myRegion->freqStart); DEBUG_MSG("Radio myRegion->numChannels: %d\n", numChannels); diff --git a/src/mesh/RadioInterface.h b/src/mesh/RadioInterface.h index af05bf1a0..c5ff642c9 100644 --- a/src/mesh/RadioInterface.h +++ b/src/mesh/RadioInterface.h @@ -63,6 +63,8 @@ class RadioInterface uint8_t cr = 7; uint16_t preambleLength = 32; // 8 is default, but we use longer to increase the amount of sleep time when receiving + const uint32_t MIN_TX_WAIT_MSEC = 100; // minimum time to wait before transmitting after sensing the channel in ms + const uint32_t PROCESSING_TIME_MSEC = 4500; // time to construct, process and construct a packet again (empirically determined) MeshPacket *sendingPacket = NULL; // The packet we are currently sending uint32_t lastTxStart = 0L; diff --git a/src/mesh/RadioLibInterface.cpp b/src/mesh/RadioLibInterface.cpp index a0058893a..c0007ade0 100644 --- a/src/mesh/RadioLibInterface.cpp +++ b/src/mesh/RadioLibInterface.cpp @@ -93,8 +93,8 @@ bool RadioLibInterface::canSendImmediately() /// bluetooth comms code. If the txmit queue is empty it might return an error ErrorCode RadioLibInterface::send(MeshPacket *p) { - if (radioConfig.preferences.region != RegionCode_Unset) { - if (disabled || radioConfig.preferences.is_lora_tx_disabled) { + if (config.lora.region != Config_LoRaConfig_RegionCode_Unset) { + if (disabled || config.lora.tx_disabled) { DEBUG_MSG("send - lora_tx_disabled\n"); packetPool.release(p); return ERRNO_DISABLED; @@ -121,7 +121,7 @@ ErrorCode RadioLibInterface::send(MeshPacket *p) // set (random) transmit delay to let others reconfigure their radio, // to avoid collisions and implement timing-based flooding // DEBUG_MSG("Set random delay before transmitting.\n"); - setTransmitDelay(); + setTransmitDelay(); return res; #else @@ -154,10 +154,10 @@ bool RadioLibInterface::cancelSending(NodeNum from, PacketId id) /** radio helper thread callback. We never immediately transmit after any operation (either rx or tx). Instead we should start receiving and -wait a random delay of 100ms to 100ms+shortPacketMsec to make sure we are not stomping on someone else. The 100ms delay at the beginning ensures all -possible listeners have had time to finish processing the previous packet and now have their radio in RX state. The up to 100ms+shortPacketMsec -random delay gives a chance for all possible senders to have high odds of detecting that someone else started transmitting first -and then they will wait until that packet finishes. +wait a random delay of 100ms to 100ms+shortPacketMsec to make sure we are not stomping on someone else. The 100ms delay at the +beginning ensures all possible listeners have had time to finish processing the previous packet and now have their radio in RX +state. The up to 100ms+shortPacketMsec random delay gives a chance for all possible senders to have high odds of detecting that +someone else started transmitting first and then they will wait until that packet finishes. NOTE: the large flood rebroadcast delay might still be needed even with this approach. Because we might not be able to hear other transmitters that we are potentially stomping on. Requires further thought. @@ -215,7 +215,7 @@ void RadioLibInterface::onNotify(uint32_t notification) void RadioLibInterface::setTransmitDelay() { MeshPacket *p = txQueue.getFront(); - // We want all sending/receiving to be done by our daemon thread. + // We want all sending/receiving to be done by our daemon thread. // We use a delay here because this packet might have been sent in response to a packet we just received. // So we want to make sure the other side has had a chance to reconfigure its radio. @@ -345,7 +345,7 @@ void RadioLibInterface::handleReceiveInterrupt() void RadioLibInterface::startSend(MeshPacket *txp) { printPacket("Starting low level send", txp); - if (disabled || radioConfig.preferences.is_lora_tx_disabled) { + if (disabled || config.lora.tx_disabled) { DEBUG_MSG("startSend is dropping tx packet because we are disabled\n"); packetPool.release(txp); } else { diff --git a/src/mesh/ReliableRouter.cpp b/src/mesh/ReliableRouter.cpp index ee513bae0..a23adfa7d 100644 --- a/src/mesh/ReliableRouter.cpp +++ b/src/mesh/ReliableRouter.cpp @@ -1,7 +1,7 @@ -#include "configuration.h" #include "ReliableRouter.h" #include "MeshModule.h" #include "MeshTypes.h" +#include "configuration.h" #include "mesh-pb-constants.h" // ReliableRouter::ReliableRouter() {} @@ -14,11 +14,11 @@ ErrorCode ReliableRouter::send(MeshPacket *p) { if (p->want_ack) { // If someone asks for acks on broadcast, we need the hop limit to be at least one, so that first node that receives our - // message will rebroadcast. But asking for hop_limit 0 in that context means the client app has no preference on hop counts - // and we want this message to get through the whole mesh, so use the default. + // message will rebroadcast. But asking for hop_limit 0 in that context means the client app has no preference on hop + // counts and we want this message to get through the whole mesh, so use the default. if (p->to == NODENUM_BROADCAST && p->hop_limit == 0) { - if (radioConfig.preferences.hop_limit && radioConfig.preferences.hop_limit <= HOP_MAX) { - p->hop_limit = (radioConfig.preferences.hop_limit >= HOP_MAX) ? HOP_MAX : radioConfig.preferences.hop_limit; + if (config.lora.hop_limit && config.lora.hop_limit <= HOP_MAX) { + p->hop_limit = (config.lora.hop_limit >= HOP_MAX) ? HOP_MAX : config.lora.hop_limit; } else { p->hop_limit = HOP_RELIABLE; } @@ -41,9 +41,9 @@ bool ReliableRouter::shouldFilterReceived(MeshPacket *p) // If this is the first time we saw this, cancel any retransmissions we have queued up and generate an internal ack for // the original sending process. - // FIXME - we might want to turn off this "optimization", it does save lots of airtime but it assumes that once we've heard one - // one adjacent node hear our packet that a) probably other adjacent nodes heard it and b) we can trust those nodes to reach - // our destination. Both of which might be incorrect. + // FIXME - we might want to turn off this "optimization", it does save lots of airtime but it assumes that once we've + // heard one one adjacent node hear our packet that a) probably other adjacent nodes heard it and b) we can trust those + // nodes to reach our destination. Both of which might be incorrect. auto key = GlobalPacketId(getFrom(p), p->id); auto old = findPendingPacket(key); if (old) { @@ -53,8 +53,7 @@ bool ReliableRouter::shouldFilterReceived(MeshPacket *p) sendAckNak(Routing_Error_NONE, getFrom(p), p->id, old->packet->channel); stopRetransmission(key); - } - else { + } else { DEBUG_MSG("didn't find pending packet\n"); } } @@ -151,7 +150,7 @@ bool ReliableRouter::stopRetransmission(GlobalPacketId key) if (old) { auto numErased = pending.erase(key); assert(numErased == 1); - packetPool.release(old->packet); + cancelSending(getFrom(old->packet), old->packet->id); return true; } else return false; diff --git a/src/mesh/Router.cpp b/src/mesh/Router.cpp index 68e53a507..87e319d83 100644 --- a/src/mesh/Router.cpp +++ b/src/mesh/Router.cpp @@ -118,8 +118,8 @@ MeshPacket *Router::allocForSending() p->which_payloadVariant = MeshPacket_decoded_tag; // Assume payload is decoded at start. p->from = nodeDB.getNodeNum(); p->to = NODENUM_BROADCAST; - if (radioConfig.preferences.hop_limit && radioConfig.preferences.hop_limit <= HOP_MAX) { - p->hop_limit = (radioConfig.preferences.hop_limit >= HOP_MAX) ? HOP_MAX : radioConfig.preferences.hop_limit; + if (config.lora.hop_limit && config.lora.hop_limit <= HOP_MAX) { + p->hop_limit = (config.lora.hop_limit >= HOP_MAX) ? HOP_MAX : config.lora.hop_limit; } else { p->hop_limit = HOP_RELIABLE; } @@ -227,7 +227,7 @@ ErrorCode Router::send(MeshPacket *p) */ bool shouldActuallyEncrypt = true; - if (*radioConfig.preferences.mqtt_server && !radioConfig.preferences.mqtt_encryption_enabled) { + if (*moduleConfig.mqtt.address && !moduleConfig.mqtt.encryption_enabled) { shouldActuallyEncrypt = false; } @@ -304,13 +304,11 @@ bool perhapsDecode(MeshPacket *p) p->which_payloadVariant = MeshPacket_decoded_tag; // change type to decoded p->channel = chIndex; // change to store the index instead of the hash - // Decompress if needed. jm if (p->decoded.which_payloadVariant == Data_payload_compressed_tag) { // Decompress the file } - printPacket("decoded message", p); return true; } @@ -361,10 +359,10 @@ Routing_Error perhapsEncode(MeshPacket *p) } else { DEBUG_MSG("Compressing message.\n"); // Copy the compressed data into the meshpacket - //p->decoded.payload_compressed.size = compressed_len; - //memcpy(p->decoded.payload_compressed.bytes, compressed_out, compressed_len); + // p->decoded.payload_compressed.size = compressed_len; + // memcpy(p->decoded.payload_compressed.bytes, compressed_out, compressed_len); - //p->decoded.which_payloadVariant = Data_payload_compressed_tag; + // p->decoded.which_payloadVariant = Data_payload_compressed_tag; } if (0) { @@ -437,8 +435,8 @@ void Router::handleReceived(MeshPacket *p, RxSource src) void Router::perhapsHandleReceived(MeshPacket *p) { - assert(radioConfig.has_preferences); - bool ignore = is_in_repeated(radioConfig.preferences.ignore_incoming, p->from); + // assert(radioConfig.has_preferences); + bool ignore = is_in_repeated(config.lora.ignore_incoming, p->from); if (ignore) DEBUG_MSG("Ignoring incoming message, 0x%x is in our ignore list\n", p->from); diff --git a/src/mesh/generated/admin.pb.c b/src/mesh/generated/admin.pb.c index 688cba334..2cb76d756 100644 --- a/src/mesh/generated/admin.pb.c +++ b/src/mesh/generated/admin.pb.c @@ -6,7 +6,9 @@ #error Regenerate this file with the current version of nanopb generator. #endif -PB_BIND(AdminMessage, AdminMessage, 2) +PB_BIND(AdminMessage, AdminMessage, AUTO) + + diff --git a/src/mesh/generated/admin.pb.h b/src/mesh/generated/admin.pb.h index bd33f7b90..ce80a3b0e 100644 --- a/src/mesh/generated/admin.pb.h +++ b/src/mesh/generated/admin.pb.h @@ -5,30 +5,56 @@ #define PB_ADMIN_PB_H_INCLUDED #include #include "channel.pb.h" +#include "config.pb.h" #include "mesh.pb.h" -#include "radioconfig.pb.h" +#include "module_config.pb.h" #if PB_PROTO_HEADER_VERSION != 40 #error Regenerate this file with the current version of nanopb generator. #endif +/* Enum definitions */ +typedef enum _AdminMessage_ConfigType { + AdminMessage_ConfigType_DEVICE_CONFIG = 0, + AdminMessage_ConfigType_POSITION_CONFIG = 1, + AdminMessage_ConfigType_POWER_CONFIG = 2, + AdminMessage_ConfigType_WIFI_CONFIG = 3, + AdminMessage_ConfigType_DISPLAY_CONFIG = 4, + AdminMessage_ConfigType_LORA_CONFIG = 5 +} AdminMessage_ConfigType; + +typedef enum _AdminMessage_ModuleConfigType { + AdminMessage_ModuleConfigType_MQTT_CONFIG = 0, + AdminMessage_ModuleConfigType_SERIAL_CONFIG = 1, + AdminMessage_ModuleConfigType_EXTNOTIF_CONFIG = 2, + AdminMessage_ModuleConfigType_STOREFORWARD_CONFIG = 3, + AdminMessage_ModuleConfigType_RANGETEST_CONFIG = 4, + AdminMessage_ModuleConfigType_TELEMETRY_CONFIG = 5, + AdminMessage_ModuleConfigType_CANNEDMSG_CONFIG = 6 +} AdminMessage_ModuleConfigType; + /* Struct definitions */ /* This message is handled by the Admin module and is responsible for all settings/channel read/write operations. This message is used to do settings operations to both remote AND local nodes. (Prior to 1.2 these operations were done via special ToRadio operations) */ typedef struct _AdminMessage { - /* Set the radio provisioning for this node */ + /* Set the owner for this node */ pb_size_t which_variant; union { - RadioConfig set_radio; User set_owner; Channel set_channel; - bool get_radio_request; - RadioConfig get_radio_response; uint32_t get_channel_request; Channel get_channel_response; bool get_owner_request; User get_owner_response; + AdminMessage_ConfigType get_config_request; + Config get_config_response; + Config set_config; + bool confirm_set_config; + AdminMessage_ModuleConfigType get_module_config_request; + ModuleConfig get_module_config_response; + ModuleConfig set_module_config; + bool confirm_set_module_config; bool confirm_set_channel; bool confirm_set_radio; bool exit_simulator; @@ -50,24 +76,39 @@ typedef struct _AdminMessage { } AdminMessage; +/* Helper constants for enums */ +#define _AdminMessage_ConfigType_MIN AdminMessage_ConfigType_DEVICE_CONFIG +#define _AdminMessage_ConfigType_MAX AdminMessage_ConfigType_LORA_CONFIG +#define _AdminMessage_ConfigType_ARRAYSIZE ((AdminMessage_ConfigType)(AdminMessage_ConfigType_LORA_CONFIG+1)) + +#define _AdminMessage_ModuleConfigType_MIN AdminMessage_ModuleConfigType_MQTT_CONFIG +#define _AdminMessage_ModuleConfigType_MAX AdminMessage_ModuleConfigType_CANNEDMSG_CONFIG +#define _AdminMessage_ModuleConfigType_ARRAYSIZE ((AdminMessage_ModuleConfigType)(AdminMessage_ModuleConfigType_CANNEDMSG_CONFIG+1)) + + #ifdef __cplusplus extern "C" { #endif /* Initializer values for message structs */ -#define AdminMessage_init_default {0, {RadioConfig_init_default}} -#define AdminMessage_init_zero {0, {RadioConfig_init_zero}} +#define AdminMessage_init_default {0, {User_init_default}} +#define AdminMessage_init_zero {0, {User_init_zero}} /* Field tags (for use in manual encoding/decoding) */ -#define AdminMessage_set_radio_tag 1 #define AdminMessage_set_owner_tag 2 #define AdminMessage_set_channel_tag 3 -#define AdminMessage_get_radio_request_tag 4 -#define AdminMessage_get_radio_response_tag 5 #define AdminMessage_get_channel_request_tag 6 #define AdminMessage_get_channel_response_tag 7 #define AdminMessage_get_owner_request_tag 8 #define AdminMessage_get_owner_response_tag 9 +#define AdminMessage_get_config_request_tag 10 +#define AdminMessage_get_config_response_tag 11 +#define AdminMessage_set_config_tag 12 +#define AdminMessage_confirm_set_config_tag 13 +#define AdminMessage_get_module_config_request_tag 14 +#define AdminMessage_get_module_config_response_tag 15 +#define AdminMessage_set_module_config_tag 16 +#define AdminMessage_confirm_set_module_config_tag 17 #define AdminMessage_confirm_set_channel_tag 32 #define AdminMessage_confirm_set_radio_tag 33 #define AdminMessage_exit_simulator_tag 34 @@ -88,15 +129,20 @@ extern "C" { /* Struct field encoding specification for nanopb */ #define AdminMessage_FIELDLIST(X, a) \ -X(a, STATIC, ONEOF, MESSAGE, (variant,set_radio,set_radio), 1) \ X(a, STATIC, ONEOF, MESSAGE, (variant,set_owner,set_owner), 2) \ X(a, STATIC, ONEOF, MESSAGE, (variant,set_channel,set_channel), 3) \ -X(a, STATIC, ONEOF, BOOL, (variant,get_radio_request,get_radio_request), 4) \ -X(a, STATIC, ONEOF, MESSAGE, (variant,get_radio_response,get_radio_response), 5) \ X(a, STATIC, ONEOF, UINT32, (variant,get_channel_request,get_channel_request), 6) \ X(a, STATIC, ONEOF, MESSAGE, (variant,get_channel_response,get_channel_response), 7) \ X(a, STATIC, ONEOF, BOOL, (variant,get_owner_request,get_owner_request), 8) \ X(a, STATIC, ONEOF, MESSAGE, (variant,get_owner_response,get_owner_response), 9) \ +X(a, STATIC, ONEOF, UENUM, (variant,get_config_request,get_config_request), 10) \ +X(a, STATIC, ONEOF, MESSAGE, (variant,get_config_response,get_config_response), 11) \ +X(a, STATIC, ONEOF, MESSAGE, (variant,set_config,set_config), 12) \ +X(a, STATIC, ONEOF, BOOL, (variant,confirm_set_config,confirm_set_config), 13) \ +X(a, STATIC, ONEOF, UENUM, (variant,get_module_config_request,get_module_config_request), 14) \ +X(a, STATIC, ONEOF, MESSAGE, (variant,get_module_config_response,get_module_config_response), 15) \ +X(a, STATIC, ONEOF, MESSAGE, (variant,set_module_config,set_module_config), 16) \ +X(a, STATIC, ONEOF, BOOL, (variant,confirm_set_module_config,confirm_set_module_config), 17) \ X(a, STATIC, ONEOF, BOOL, (variant,confirm_set_channel,confirm_set_channel), 32) \ X(a, STATIC, ONEOF, BOOL, (variant,confirm_set_radio,confirm_set_radio), 33) \ X(a, STATIC, ONEOF, BOOL, (variant,exit_simulator,exit_simulator), 34) \ @@ -116,12 +162,14 @@ X(a, STATIC, ONEOF, STRING, (variant,set_canned_message_module_part4,set_ X(a, STATIC, ONEOF, INT32, (variant,shutdown_seconds,shutdown_seconds), 51) #define AdminMessage_CALLBACK NULL #define AdminMessage_DEFAULT NULL -#define AdminMessage_variant_set_radio_MSGTYPE RadioConfig #define AdminMessage_variant_set_owner_MSGTYPE User #define AdminMessage_variant_set_channel_MSGTYPE Channel -#define AdminMessage_variant_get_radio_response_MSGTYPE RadioConfig #define AdminMessage_variant_get_channel_response_MSGTYPE Channel #define AdminMessage_variant_get_owner_response_MSGTYPE User +#define AdminMessage_variant_get_config_response_MSGTYPE Config +#define AdminMessage_variant_set_config_MSGTYPE Config +#define AdminMessage_variant_get_module_config_response_MSGTYPE ModuleConfig +#define AdminMessage_variant_set_module_config_MSGTYPE ModuleConfig extern const pb_msgdesc_t AdminMessage_msg; @@ -129,7 +177,7 @@ extern const pb_msgdesc_t AdminMessage_msg; #define AdminMessage_fields &AdminMessage_msg /* Maximum encoded size of messages (where known) */ -#define AdminMessage_size 598 +#define AdminMessage_size 204 #ifdef __cplusplus } /* extern "C" */ diff --git a/src/mesh/generated/apponly.pb.c b/src/mesh/generated/apponly.pb.c index 6e02c499c..7580a3551 100644 --- a/src/mesh/generated/apponly.pb.c +++ b/src/mesh/generated/apponly.pb.c @@ -6,7 +6,7 @@ #error Regenerate this file with the current version of nanopb generator. #endif -PB_BIND(ChannelSet, ChannelSet, AUTO) +PB_BIND(ChannelSet, ChannelSet, 2) diff --git a/src/mesh/generated/apponly.pb.h b/src/mesh/generated/apponly.pb.h index 49b9f75fd..2a908c963 100644 --- a/src/mesh/generated/apponly.pb.h +++ b/src/mesh/generated/apponly.pb.h @@ -18,7 +18,8 @@ This abstraction is used only on the the 'app side' of the world (ie python, javascript and android etc) to show a group of Channels as a (long) URL */ typedef struct _ChannelSet { /* TODO: REPLACE */ - pb_callback_t settings; + pb_size_t settings_count; + ChannelSettings settings[8]; } ChannelSet; @@ -27,16 +28,16 @@ extern "C" { #endif /* Initializer values for message structs */ -#define ChannelSet_init_default {{{NULL}, NULL}} -#define ChannelSet_init_zero {{{NULL}, NULL}} +#define ChannelSet_init_default {0, {ChannelSettings_init_default, ChannelSettings_init_default, ChannelSettings_init_default, ChannelSettings_init_default, ChannelSettings_init_default, ChannelSettings_init_default, ChannelSettings_init_default, ChannelSettings_init_default}} +#define ChannelSet_init_zero {0, {ChannelSettings_init_zero, ChannelSettings_init_zero, ChannelSettings_init_zero, ChannelSettings_init_zero, ChannelSettings_init_zero, ChannelSettings_init_zero, ChannelSettings_init_zero, ChannelSettings_init_zero}} /* Field tags (for use in manual encoding/decoding) */ #define ChannelSet_settings_tag 1 /* Struct field encoding specification for nanopb */ #define ChannelSet_FIELDLIST(X, a) \ -X(a, CALLBACK, REPEATED, MESSAGE, settings, 1) -#define ChannelSet_CALLBACK pb_default_field_callback +X(a, STATIC, REPEATED, MESSAGE, settings, 1) +#define ChannelSet_CALLBACK NULL #define ChannelSet_DEFAULT NULL #define ChannelSet_settings_MSGTYPE ChannelSettings @@ -46,7 +47,7 @@ extern const pb_msgdesc_t ChannelSet_msg; #define ChannelSet_fields &ChannelSet_msg /* Maximum encoded size of messages (where known) */ -/* ChannelSet_size depends on runtime parameters */ +#define ChannelSet_size 504 #ifdef __cplusplus } /* extern "C" */ diff --git a/src/mesh/generated/channel.pb.c b/src/mesh/generated/channel.pb.c index 6244818fb..0e1dc031d 100644 --- a/src/mesh/generated/channel.pb.c +++ b/src/mesh/generated/channel.pb.c @@ -14,4 +14,3 @@ PB_BIND(Channel, Channel, AUTO) - diff --git a/src/mesh/generated/channel.pb.h b/src/mesh/generated/channel.pb.h index 6a9bc8a20..9f43e668e 100644 --- a/src/mesh/generated/channel.pb.h +++ b/src/mesh/generated/channel.pb.h @@ -10,16 +10,6 @@ #endif /* Enum definitions */ -typedef enum _ChannelSettings_ModemConfig { - ChannelSettings_ModemConfig_VLongSlow = 0, - ChannelSettings_ModemConfig_LongSlow = 1, - ChannelSettings_ModemConfig_LongFast = 2, - ChannelSettings_ModemConfig_MidSlow = 3, - ChannelSettings_ModemConfig_MidFast = 4, - ChannelSettings_ModemConfig_ShortSlow = 5, - ChannelSettings_ModemConfig_ShortFast = 6 -} ChannelSettings_ModemConfig; - typedef enum _Channel_Role { Channel_Role_DISABLED = 0, Channel_Role_PRIMARY = 1, @@ -48,28 +38,6 @@ typedef PB_BYTES_ARRAY_T(32) ChannelSettings_psk_t; FIXME: explain how apps use channels for security. explain how remote settings and remote gpio are managed as an example */ typedef struct _ChannelSettings { - /* If zero then, use default max legal continuous power (ie. something that won't - burn out the radio hardware) - In most cases you should use zero here. - Units are in dBm. */ - int8_t tx_power; - /* Note: This is the 'old' mechanism for specifying channel parameters. - Either modem_config or bandwidth/spreading/coding will be specified - NOT BOTH. - As a heuristic: If bandwidth is specified, do not use modem_config. - Because protobufs take ZERO space when the value is zero this works out nicely. - This value is replaced by bandwidth/spread_factor/coding_rate. - If you'd like to experiment with other options add them to MeshRadio.cpp in the device code. */ - ChannelSettings_ModemConfig modem_config; - /* Bandwidth in MHz - Certain bandwidth numbers are 'special' and will be converted to the - appropriate floating point value: 31 -> 31.25MHz */ - ChannelSettings_psk_t psk; - /* A number from 7 to 12. - Indicates number of chirps per symbol as 1< + +#if PB_PROTO_HEADER_VERSION != 40 +#error Regenerate this file with the current version of nanopb generator. +#endif + +/* Enum definitions */ +typedef enum _Config_DeviceConfig_Role { + Config_DeviceConfig_Role_Client = 0, + Config_DeviceConfig_Role_ClientMute = 1, + Config_DeviceConfig_Role_Router = 2, + Config_DeviceConfig_Role_RouterClient = 3 +} Config_DeviceConfig_Role; + +typedef enum _Config_PositionConfig_PositionFlags { + Config_PositionConfig_PositionFlags_POS_UNDEFINED = 0, + Config_PositionConfig_PositionFlags_POS_ALTITUDE = 1, + Config_PositionConfig_PositionFlags_POS_ALT_MSL = 2, + Config_PositionConfig_PositionFlags_POS_GEO_SEP = 4, + Config_PositionConfig_PositionFlags_POS_DOP = 8, + Config_PositionConfig_PositionFlags_POS_HVDOP = 16, + Config_PositionConfig_PositionFlags_POS_SATINVIEW = 32, + Config_PositionConfig_PositionFlags_POS_SEQ_NOS = 64, + Config_PositionConfig_PositionFlags_POS_TIMESTAMP = 128 +} Config_PositionConfig_PositionFlags; + +typedef enum _Config_PowerConfig_ChargeCurrent { + Config_PowerConfig_ChargeCurrent_MAUnset = 0, + Config_PowerConfig_ChargeCurrent_MA100 = 1, + Config_PowerConfig_ChargeCurrent_MA190 = 2, + Config_PowerConfig_ChargeCurrent_MA280 = 3, + Config_PowerConfig_ChargeCurrent_MA360 = 4, + Config_PowerConfig_ChargeCurrent_MA450 = 5, + Config_PowerConfig_ChargeCurrent_MA550 = 6, + Config_PowerConfig_ChargeCurrent_MA630 = 7, + Config_PowerConfig_ChargeCurrent_MA700 = 8, + Config_PowerConfig_ChargeCurrent_MA780 = 9, + Config_PowerConfig_ChargeCurrent_MA880 = 10, + Config_PowerConfig_ChargeCurrent_MA960 = 11, + Config_PowerConfig_ChargeCurrent_MA1000 = 12, + Config_PowerConfig_ChargeCurrent_MA1080 = 13, + Config_PowerConfig_ChargeCurrent_MA1160 = 14, + Config_PowerConfig_ChargeCurrent_MA1240 = 15, + Config_PowerConfig_ChargeCurrent_MA1320 = 16 +} Config_PowerConfig_ChargeCurrent; + +typedef enum _Config_DisplayConfig_GpsCoordinateFormat { + Config_DisplayConfig_GpsCoordinateFormat_GpsFormatDec = 0, + Config_DisplayConfig_GpsCoordinateFormat_GpsFormatDMS = 1, + Config_DisplayConfig_GpsCoordinateFormat_GpsFormatUTM = 2, + Config_DisplayConfig_GpsCoordinateFormat_GpsFormatMGRS = 3, + Config_DisplayConfig_GpsCoordinateFormat_GpsFormatOLC = 4, + Config_DisplayConfig_GpsCoordinateFormat_GpsFormatOSGR = 5 +} Config_DisplayConfig_GpsCoordinateFormat; + +typedef enum _Config_LoRaConfig_RegionCode { + Config_LoRaConfig_RegionCode_Unset = 0, + Config_LoRaConfig_RegionCode_US = 1, + Config_LoRaConfig_RegionCode_EU433 = 2, + Config_LoRaConfig_RegionCode_EU868 = 3, + Config_LoRaConfig_RegionCode_CN = 4, + Config_LoRaConfig_RegionCode_JP = 5, + Config_LoRaConfig_RegionCode_ANZ = 6, + Config_LoRaConfig_RegionCode_KR = 7, + Config_LoRaConfig_RegionCode_TW = 8, + Config_LoRaConfig_RegionCode_RU = 9, + Config_LoRaConfig_RegionCode_IN = 10, + Config_LoRaConfig_RegionCode_NZ865 = 11, + Config_LoRaConfig_RegionCode_TH = 12 +} Config_LoRaConfig_RegionCode; + +typedef enum _Config_LoRaConfig_ModemPreset { + Config_LoRaConfig_ModemPreset_VLongSlow = 0, + Config_LoRaConfig_ModemPreset_LongSlow = 1, + Config_LoRaConfig_ModemPreset_LongFast = 2, + Config_LoRaConfig_ModemPreset_MidSlow = 3, + Config_LoRaConfig_ModemPreset_MidFast = 4, + Config_LoRaConfig_ModemPreset_ShortSlow = 5, + Config_LoRaConfig_ModemPreset_ShortFast = 6 +} Config_LoRaConfig_ModemPreset; + +/* Struct definitions */ +typedef struct _Config_DeviceConfig { + Config_DeviceConfig_Role role; + bool serial_disabled; + bool factory_reset; + bool debug_log_enabled; + char ntp_server[33]; +} Config_DeviceConfig; + +typedef struct _Config_DisplayConfig { + uint32_t screen_on_secs; + Config_DisplayConfig_GpsCoordinateFormat gps_format; + uint32_t auto_screen_carousel_secs; +} Config_DisplayConfig; + +typedef struct _Config_LoRaConfig { + int32_t tx_power; + Config_LoRaConfig_ModemPreset modem_preset; + uint32_t bandwidth; + uint32_t spread_factor; + uint32_t coding_rate; + float frequency_offset; + Config_LoRaConfig_RegionCode region; + uint32_t hop_limit; + bool tx_disabled; + pb_size_t ignore_incoming_count; + uint32_t ignore_incoming[3]; +} Config_LoRaConfig; + +typedef struct _Config_PositionConfig { + uint32_t position_broadcast_secs; + bool position_broadcast_smart_disabled; + bool fixed_position; + bool gps_disabled; + uint32_t gps_update_interval; + uint32_t gps_attempt_time; + bool gps_accept_2d; + uint32_t gps_max_dop; + uint32_t position_flags; +} Config_PositionConfig; + +typedef struct _Config_PowerConfig { + Config_PowerConfig_ChargeCurrent charge_current; + bool is_low_power; + bool is_always_powered; + uint32_t on_battery_shutdown_after_secs; + bool is_power_saving; + float adc_multiplier_override; + uint32_t wait_bluetooth_secs; + uint32_t phone_timeout_secs; + uint32_t mesh_sds_timeout_secs; + uint32_t sds_secs; + uint32_t ls_secs; + uint32_t min_wake_secs; +} Config_PowerConfig; + +typedef struct _Config_WiFiConfig { + char ssid[33]; + char psk[64]; + bool ap_mode; + bool ap_hidden; +} Config_WiFiConfig; + +typedef struct _Config { + /* TODO: REPLACE */ + pb_size_t which_payloadVariant; + union { + Config_DeviceConfig device; + Config_PositionConfig position; + Config_PowerConfig power; + Config_WiFiConfig wifi; + Config_DisplayConfig display; + Config_LoRaConfig lora; + } payloadVariant; +} Config; + + +/* Helper constants for enums */ +#define _Config_DeviceConfig_Role_MIN Config_DeviceConfig_Role_Client +#define _Config_DeviceConfig_Role_MAX Config_DeviceConfig_Role_RouterClient +#define _Config_DeviceConfig_Role_ARRAYSIZE ((Config_DeviceConfig_Role)(Config_DeviceConfig_Role_RouterClient+1)) + +#define _Config_PositionConfig_PositionFlags_MIN Config_PositionConfig_PositionFlags_POS_UNDEFINED +#define _Config_PositionConfig_PositionFlags_MAX Config_PositionConfig_PositionFlags_POS_TIMESTAMP +#define _Config_PositionConfig_PositionFlags_ARRAYSIZE ((Config_PositionConfig_PositionFlags)(Config_PositionConfig_PositionFlags_POS_TIMESTAMP+1)) + +#define _Config_PowerConfig_ChargeCurrent_MIN Config_PowerConfig_ChargeCurrent_MAUnset +#define _Config_PowerConfig_ChargeCurrent_MAX Config_PowerConfig_ChargeCurrent_MA1320 +#define _Config_PowerConfig_ChargeCurrent_ARRAYSIZE ((Config_PowerConfig_ChargeCurrent)(Config_PowerConfig_ChargeCurrent_MA1320+1)) + +#define _Config_DisplayConfig_GpsCoordinateFormat_MIN Config_DisplayConfig_GpsCoordinateFormat_GpsFormatDec +#define _Config_DisplayConfig_GpsCoordinateFormat_MAX Config_DisplayConfig_GpsCoordinateFormat_GpsFormatOSGR +#define _Config_DisplayConfig_GpsCoordinateFormat_ARRAYSIZE ((Config_DisplayConfig_GpsCoordinateFormat)(Config_DisplayConfig_GpsCoordinateFormat_GpsFormatOSGR+1)) + +#define _Config_LoRaConfig_RegionCode_MIN Config_LoRaConfig_RegionCode_Unset +#define _Config_LoRaConfig_RegionCode_MAX Config_LoRaConfig_RegionCode_TH +#define _Config_LoRaConfig_RegionCode_ARRAYSIZE ((Config_LoRaConfig_RegionCode)(Config_LoRaConfig_RegionCode_TH+1)) + +#define _Config_LoRaConfig_ModemPreset_MIN Config_LoRaConfig_ModemPreset_VLongSlow +#define _Config_LoRaConfig_ModemPreset_MAX Config_LoRaConfig_ModemPreset_ShortFast +#define _Config_LoRaConfig_ModemPreset_ARRAYSIZE ((Config_LoRaConfig_ModemPreset)(Config_LoRaConfig_ModemPreset_ShortFast+1)) + + +#ifdef __cplusplus +extern "C" { +#endif + +/* Initializer values for message structs */ +#define Config_init_default {0, {Config_DeviceConfig_init_default}} +#define Config_DeviceConfig_init_default {_Config_DeviceConfig_Role_MIN, 0, 0, 0, ""} +#define Config_PositionConfig_init_default {0, 0, 0, 0, 0, 0, 0, 0, 0} +#define Config_PowerConfig_init_default {_Config_PowerConfig_ChargeCurrent_MIN, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0} +#define Config_WiFiConfig_init_default {"", "", 0, 0} +#define Config_DisplayConfig_init_default {0, _Config_DisplayConfig_GpsCoordinateFormat_MIN, 0} +#define Config_LoRaConfig_init_default {0, _Config_LoRaConfig_ModemPreset_MIN, 0, 0, 0, 0, _Config_LoRaConfig_RegionCode_MIN, 0, 0, 0, {0, 0, 0}} +#define Config_init_zero {0, {Config_DeviceConfig_init_zero}} +#define Config_DeviceConfig_init_zero {_Config_DeviceConfig_Role_MIN, 0, 0, 0, ""} +#define Config_PositionConfig_init_zero {0, 0, 0, 0, 0, 0, 0, 0, 0} +#define Config_PowerConfig_init_zero {_Config_PowerConfig_ChargeCurrent_MIN, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0} +#define Config_WiFiConfig_init_zero {"", "", 0, 0} +#define Config_DisplayConfig_init_zero {0, _Config_DisplayConfig_GpsCoordinateFormat_MIN, 0} +#define Config_LoRaConfig_init_zero {0, _Config_LoRaConfig_ModemPreset_MIN, 0, 0, 0, 0, _Config_LoRaConfig_RegionCode_MIN, 0, 0, 0, {0, 0, 0}} + +/* Field tags (for use in manual encoding/decoding) */ +#define Config_DeviceConfig_role_tag 1 +#define Config_DeviceConfig_serial_disabled_tag 2 +#define Config_DeviceConfig_factory_reset_tag 3 +#define Config_DeviceConfig_debug_log_enabled_tag 4 +#define Config_DeviceConfig_ntp_server_tag 5 +#define Config_DisplayConfig_screen_on_secs_tag 1 +#define Config_DisplayConfig_gps_format_tag 2 +#define Config_DisplayConfig_auto_screen_carousel_secs_tag 3 +#define Config_LoRaConfig_tx_power_tag 1 +#define Config_LoRaConfig_modem_preset_tag 2 +#define Config_LoRaConfig_bandwidth_tag 3 +#define Config_LoRaConfig_spread_factor_tag 4 +#define Config_LoRaConfig_coding_rate_tag 5 +#define Config_LoRaConfig_frequency_offset_tag 6 +#define Config_LoRaConfig_region_tag 7 +#define Config_LoRaConfig_hop_limit_tag 8 +#define Config_LoRaConfig_tx_disabled_tag 9 +#define Config_LoRaConfig_ignore_incoming_tag 103 +#define Config_PositionConfig_position_broadcast_secs_tag 1 +#define Config_PositionConfig_position_broadcast_smart_disabled_tag 2 +#define Config_PositionConfig_fixed_position_tag 3 +#define Config_PositionConfig_gps_disabled_tag 5 +#define Config_PositionConfig_gps_update_interval_tag 6 +#define Config_PositionConfig_gps_attempt_time_tag 7 +#define Config_PositionConfig_gps_accept_2d_tag 8 +#define Config_PositionConfig_gps_max_dop_tag 9 +#define Config_PositionConfig_position_flags_tag 10 +#define Config_PowerConfig_charge_current_tag 1 +#define Config_PowerConfig_is_low_power_tag 2 +#define Config_PowerConfig_is_always_powered_tag 3 +#define Config_PowerConfig_on_battery_shutdown_after_secs_tag 4 +#define Config_PowerConfig_is_power_saving_tag 5 +#define Config_PowerConfig_adc_multiplier_override_tag 6 +#define Config_PowerConfig_wait_bluetooth_secs_tag 7 +#define Config_PowerConfig_phone_timeout_secs_tag 8 +#define Config_PowerConfig_mesh_sds_timeout_secs_tag 9 +#define Config_PowerConfig_sds_secs_tag 10 +#define Config_PowerConfig_ls_secs_tag 11 +#define Config_PowerConfig_min_wake_secs_tag 12 +#define Config_WiFiConfig_ssid_tag 1 +#define Config_WiFiConfig_psk_tag 2 +#define Config_WiFiConfig_ap_mode_tag 3 +#define Config_WiFiConfig_ap_hidden_tag 4 +#define Config_device_tag 1 +#define Config_position_tag 2 +#define Config_power_tag 3 +#define Config_wifi_tag 4 +#define Config_display_tag 5 +#define Config_lora_tag 6 + +/* Struct field encoding specification for nanopb */ +#define Config_FIELDLIST(X, a) \ +X(a, STATIC, ONEOF, MESSAGE, (payloadVariant,device,payloadVariant.device), 1) \ +X(a, STATIC, ONEOF, MESSAGE, (payloadVariant,position,payloadVariant.position), 2) \ +X(a, STATIC, ONEOF, MESSAGE, (payloadVariant,power,payloadVariant.power), 3) \ +X(a, STATIC, ONEOF, MESSAGE, (payloadVariant,wifi,payloadVariant.wifi), 4) \ +X(a, STATIC, ONEOF, MESSAGE, (payloadVariant,display,payloadVariant.display), 5) \ +X(a, STATIC, ONEOF, MESSAGE, (payloadVariant,lora,payloadVariant.lora), 6) +#define Config_CALLBACK NULL +#define Config_DEFAULT NULL +#define Config_payloadVariant_device_MSGTYPE Config_DeviceConfig +#define Config_payloadVariant_position_MSGTYPE Config_PositionConfig +#define Config_payloadVariant_power_MSGTYPE Config_PowerConfig +#define Config_payloadVariant_wifi_MSGTYPE Config_WiFiConfig +#define Config_payloadVariant_display_MSGTYPE Config_DisplayConfig +#define Config_payloadVariant_lora_MSGTYPE Config_LoRaConfig + +#define Config_DeviceConfig_FIELDLIST(X, a) \ +X(a, STATIC, SINGULAR, UENUM, role, 1) \ +X(a, STATIC, SINGULAR, BOOL, serial_disabled, 2) \ +X(a, STATIC, SINGULAR, BOOL, factory_reset, 3) \ +X(a, STATIC, SINGULAR, BOOL, debug_log_enabled, 4) \ +X(a, STATIC, SINGULAR, STRING, ntp_server, 5) +#define Config_DeviceConfig_CALLBACK NULL +#define Config_DeviceConfig_DEFAULT NULL + +#define Config_PositionConfig_FIELDLIST(X, a) \ +X(a, STATIC, SINGULAR, UINT32, position_broadcast_secs, 1) \ +X(a, STATIC, SINGULAR, BOOL, position_broadcast_smart_disabled, 2) \ +X(a, STATIC, SINGULAR, BOOL, fixed_position, 3) \ +X(a, STATIC, SINGULAR, BOOL, gps_disabled, 5) \ +X(a, STATIC, SINGULAR, UINT32, gps_update_interval, 6) \ +X(a, STATIC, SINGULAR, UINT32, gps_attempt_time, 7) \ +X(a, STATIC, SINGULAR, BOOL, gps_accept_2d, 8) \ +X(a, STATIC, SINGULAR, UINT32, gps_max_dop, 9) \ +X(a, STATIC, SINGULAR, UINT32, position_flags, 10) +#define Config_PositionConfig_CALLBACK NULL +#define Config_PositionConfig_DEFAULT NULL + +#define Config_PowerConfig_FIELDLIST(X, a) \ +X(a, STATIC, SINGULAR, UENUM, charge_current, 1) \ +X(a, STATIC, SINGULAR, BOOL, is_low_power, 2) \ +X(a, STATIC, SINGULAR, BOOL, is_always_powered, 3) \ +X(a, STATIC, SINGULAR, UINT32, on_battery_shutdown_after_secs, 4) \ +X(a, STATIC, SINGULAR, BOOL, is_power_saving, 5) \ +X(a, STATIC, SINGULAR, FLOAT, adc_multiplier_override, 6) \ +X(a, STATIC, SINGULAR, UINT32, wait_bluetooth_secs, 7) \ +X(a, STATIC, SINGULAR, UINT32, phone_timeout_secs, 8) \ +X(a, STATIC, SINGULAR, UINT32, mesh_sds_timeout_secs, 9) \ +X(a, STATIC, SINGULAR, UINT32, sds_secs, 10) \ +X(a, STATIC, SINGULAR, UINT32, ls_secs, 11) \ +X(a, STATIC, SINGULAR, UINT32, min_wake_secs, 12) +#define Config_PowerConfig_CALLBACK NULL +#define Config_PowerConfig_DEFAULT NULL + +#define Config_WiFiConfig_FIELDLIST(X, a) \ +X(a, STATIC, SINGULAR, STRING, ssid, 1) \ +X(a, STATIC, SINGULAR, STRING, psk, 2) \ +X(a, STATIC, SINGULAR, BOOL, ap_mode, 3) \ +X(a, STATIC, SINGULAR, BOOL, ap_hidden, 4) +#define Config_WiFiConfig_CALLBACK NULL +#define Config_WiFiConfig_DEFAULT NULL + +#define Config_DisplayConfig_FIELDLIST(X, a) \ +X(a, STATIC, SINGULAR, UINT32, screen_on_secs, 1) \ +X(a, STATIC, SINGULAR, UENUM, gps_format, 2) \ +X(a, STATIC, SINGULAR, UINT32, auto_screen_carousel_secs, 3) +#define Config_DisplayConfig_CALLBACK NULL +#define Config_DisplayConfig_DEFAULT NULL + +#define Config_LoRaConfig_FIELDLIST(X, a) \ +X(a, STATIC, SINGULAR, INT32, tx_power, 1) \ +X(a, STATIC, SINGULAR, UENUM, modem_preset, 2) \ +X(a, STATIC, SINGULAR, UINT32, bandwidth, 3) \ +X(a, STATIC, SINGULAR, UINT32, spread_factor, 4) \ +X(a, STATIC, SINGULAR, UINT32, coding_rate, 5) \ +X(a, STATIC, SINGULAR, FLOAT, frequency_offset, 6) \ +X(a, STATIC, SINGULAR, UENUM, region, 7) \ +X(a, STATIC, SINGULAR, UINT32, hop_limit, 8) \ +X(a, STATIC, SINGULAR, BOOL, tx_disabled, 9) \ +X(a, STATIC, REPEATED, UINT32, ignore_incoming, 103) +#define Config_LoRaConfig_CALLBACK NULL +#define Config_LoRaConfig_DEFAULT NULL + +extern const pb_msgdesc_t Config_msg; +extern const pb_msgdesc_t Config_DeviceConfig_msg; +extern const pb_msgdesc_t Config_PositionConfig_msg; +extern const pb_msgdesc_t Config_PowerConfig_msg; +extern const pb_msgdesc_t Config_WiFiConfig_msg; +extern const pb_msgdesc_t Config_DisplayConfig_msg; +extern const pb_msgdesc_t Config_LoRaConfig_msg; + +/* Defines for backwards compatibility with code written before nanopb-0.4.0 */ +#define Config_fields &Config_msg +#define Config_DeviceConfig_fields &Config_DeviceConfig_msg +#define Config_PositionConfig_fields &Config_PositionConfig_msg +#define Config_PowerConfig_fields &Config_PowerConfig_msg +#define Config_WiFiConfig_fields &Config_WiFiConfig_msg +#define Config_DisplayConfig_fields &Config_DisplayConfig_msg +#define Config_LoRaConfig_fields &Config_LoRaConfig_msg + +/* Maximum encoded size of messages (where known) */ +#define Config_DeviceConfig_size 42 +#define Config_DisplayConfig_size 14 +#define Config_LoRaConfig_size 67 +#define Config_PositionConfig_size 38 +#define Config_PowerConfig_size 55 +#define Config_WiFiConfig_size 103 +#define Config_size 105 + +#ifdef __cplusplus +} /* extern "C" */ +#endif + +#endif diff --git a/src/mesh/generated/deviceonly.pb.c b/src/mesh/generated/deviceonly.pb.c index 76aba1aef..33a2ee793 100644 --- a/src/mesh/generated/deviceonly.pb.c +++ b/src/mesh/generated/deviceonly.pb.c @@ -15,5 +15,11 @@ PB_BIND(ChannelFile, ChannelFile, 2) PB_BIND(OEMStore, OEMStore, 2) +PB_BIND(LocalConfig, LocalConfig, 2) + + +PB_BIND(LocalModuleConfig, LocalModuleConfig, 2) + + diff --git a/src/mesh/generated/deviceonly.pb.h b/src/mesh/generated/deviceonly.pb.h index a8df04eae..7fc35424a 100644 --- a/src/mesh/generated/deviceonly.pb.h +++ b/src/mesh/generated/deviceonly.pb.h @@ -5,7 +5,9 @@ #define PB_DEVICEONLY_PB_H_INCLUDED #include #include "channel.pb.h" +#include "config.pb.h" #include "mesh.pb.h" +#include "module_config.pb.h" #if PB_PROTO_HEADER_VERSION != 40 #error Regenerate this file with the current version of nanopb generator. @@ -64,6 +66,51 @@ typedef struct _DeviceState { bool did_gps_reset; } DeviceState; +typedef struct _LocalConfig { + /* TODO: REPLACE */ + bool has_device; + Config_DeviceConfig device; + /* TODO: REPLACE */ + bool has_position; + Config_PositionConfig position; + /* TODO: REPLACE */ + bool has_power; + Config_PowerConfig power; + /* TODO: REPLACE */ + bool has_wifi; + Config_WiFiConfig wifi; + /* TODO: REPLACE */ + bool has_display; + Config_DisplayConfig display; + /* TODO: REPLACE */ + bool has_lora; + Config_LoRaConfig lora; +} LocalConfig; + +typedef struct _LocalModuleConfig { + /* TODO: REPLACE */ + bool has_mqtt; + ModuleConfig_MQTTConfig mqtt; + /* TODO: REPLACE */ + bool has_serial; + ModuleConfig_SerialConfig serial; + /* TODO: REPLACE */ + bool has_external_notification; + ModuleConfig_ExternalNotificationConfig external_notification; + /* TODO: REPLACE */ + bool has_store_forward; + ModuleConfig_StoreForwardConfig store_forward; + /* TODO: REPLACE */ + bool has_range_test; + ModuleConfig_RangeTestConfig range_test; + /* TODO: REPLACE */ + bool has_telemetry; + ModuleConfig_TelemetryConfig telemetry; + /* TODO: REPLACE */ + bool has_canned_message; + ModuleConfig_CannedMessageConfig canned_message; +} LocalModuleConfig; + typedef PB_BYTES_ARRAY_T(2048) OEMStore_oem_icon_bits_t; /* This can be used for customizing the firmware distribution. If populated, show a secondary bootup screen with cuatom logo and text for 2.5 seconds. */ @@ -95,9 +142,13 @@ extern "C" { #define DeviceState_init_default {false, MyNodeInfo_init_default, false, User_init_default, 0, {NodeInfo_init_default, NodeInfo_init_default, NodeInfo_init_default, NodeInfo_init_default, NodeInfo_init_default, NodeInfo_init_default, NodeInfo_init_default, NodeInfo_init_default, NodeInfo_init_default, NodeInfo_init_default, NodeInfo_init_default, NodeInfo_init_default, NodeInfo_init_default, NodeInfo_init_default, NodeInfo_init_default, NodeInfo_init_default, NodeInfo_init_default, NodeInfo_init_default, NodeInfo_init_default, NodeInfo_init_default, NodeInfo_init_default, NodeInfo_init_default, NodeInfo_init_default, NodeInfo_init_default, NodeInfo_init_default, NodeInfo_init_default, NodeInfo_init_default, NodeInfo_init_default, NodeInfo_init_default, NodeInfo_init_default, NodeInfo_init_default, NodeInfo_init_default, NodeInfo_init_default, NodeInfo_init_default, NodeInfo_init_default, NodeInfo_init_default, NodeInfo_init_default, NodeInfo_init_default, NodeInfo_init_default, NodeInfo_init_default, NodeInfo_init_default, NodeInfo_init_default, NodeInfo_init_default, NodeInfo_init_default, NodeInfo_init_default, NodeInfo_init_default, NodeInfo_init_default, NodeInfo_init_default, NodeInfo_init_default, NodeInfo_init_default, NodeInfo_init_default, NodeInfo_init_default, NodeInfo_init_default, NodeInfo_init_default, NodeInfo_init_default, NodeInfo_init_default, NodeInfo_init_default, NodeInfo_init_default, NodeInfo_init_default, NodeInfo_init_default, NodeInfo_init_default, NodeInfo_init_default, NodeInfo_init_default, NodeInfo_init_default}, 0, {MeshPacket_init_default}, false, MeshPacket_init_default, 0, 0, 0} #define ChannelFile_init_default {0, {Channel_init_default, Channel_init_default, Channel_init_default, Channel_init_default, Channel_init_default, Channel_init_default, Channel_init_default, Channel_init_default}} #define OEMStore_init_default {0, 0, {0, {0}}, _ScreenFonts_MIN, ""} +#define LocalConfig_init_default {false, Config_DeviceConfig_init_default, false, Config_PositionConfig_init_default, false, Config_PowerConfig_init_default, false, Config_WiFiConfig_init_default, false, Config_DisplayConfig_init_default, false, Config_LoRaConfig_init_default} +#define LocalModuleConfig_init_default {false, ModuleConfig_MQTTConfig_init_default, false, ModuleConfig_SerialConfig_init_default, false, ModuleConfig_ExternalNotificationConfig_init_default, false, ModuleConfig_StoreForwardConfig_init_default, false, ModuleConfig_RangeTestConfig_init_default, false, ModuleConfig_TelemetryConfig_init_default, false, ModuleConfig_CannedMessageConfig_init_default} #define DeviceState_init_zero {false, MyNodeInfo_init_zero, false, User_init_zero, 0, {NodeInfo_init_zero, NodeInfo_init_zero, NodeInfo_init_zero, NodeInfo_init_zero, NodeInfo_init_zero, NodeInfo_init_zero, NodeInfo_init_zero, NodeInfo_init_zero, NodeInfo_init_zero, NodeInfo_init_zero, NodeInfo_init_zero, NodeInfo_init_zero, NodeInfo_init_zero, NodeInfo_init_zero, NodeInfo_init_zero, NodeInfo_init_zero, NodeInfo_init_zero, NodeInfo_init_zero, NodeInfo_init_zero, NodeInfo_init_zero, NodeInfo_init_zero, NodeInfo_init_zero, NodeInfo_init_zero, NodeInfo_init_zero, NodeInfo_init_zero, NodeInfo_init_zero, NodeInfo_init_zero, NodeInfo_init_zero, NodeInfo_init_zero, NodeInfo_init_zero, NodeInfo_init_zero, NodeInfo_init_zero, NodeInfo_init_zero, NodeInfo_init_zero, NodeInfo_init_zero, NodeInfo_init_zero, NodeInfo_init_zero, NodeInfo_init_zero, NodeInfo_init_zero, NodeInfo_init_zero, NodeInfo_init_zero, NodeInfo_init_zero, NodeInfo_init_zero, NodeInfo_init_zero, NodeInfo_init_zero, NodeInfo_init_zero, NodeInfo_init_zero, NodeInfo_init_zero, NodeInfo_init_zero, NodeInfo_init_zero, NodeInfo_init_zero, NodeInfo_init_zero, NodeInfo_init_zero, NodeInfo_init_zero, NodeInfo_init_zero, NodeInfo_init_zero, NodeInfo_init_zero, NodeInfo_init_zero, NodeInfo_init_zero, NodeInfo_init_zero, NodeInfo_init_zero, NodeInfo_init_zero, NodeInfo_init_zero, NodeInfo_init_zero}, 0, {MeshPacket_init_zero}, false, MeshPacket_init_zero, 0, 0, 0} #define ChannelFile_init_zero {0, {Channel_init_zero, Channel_init_zero, Channel_init_zero, Channel_init_zero, Channel_init_zero, Channel_init_zero, Channel_init_zero, Channel_init_zero}} #define OEMStore_init_zero {0, 0, {0, {0}}, _ScreenFonts_MIN, ""} +#define LocalConfig_init_zero {false, Config_DeviceConfig_init_zero, false, Config_PositionConfig_init_zero, false, Config_PowerConfig_init_zero, false, Config_WiFiConfig_init_zero, false, Config_DisplayConfig_init_zero, false, Config_LoRaConfig_init_zero} +#define LocalModuleConfig_init_zero {false, ModuleConfig_MQTTConfig_init_zero, false, ModuleConfig_SerialConfig_init_zero, false, ModuleConfig_ExternalNotificationConfig_init_zero, false, ModuleConfig_StoreForwardConfig_init_zero, false, ModuleConfig_RangeTestConfig_init_zero, false, ModuleConfig_TelemetryConfig_init_zero, false, ModuleConfig_CannedMessageConfig_init_zero} /* Field tags (for use in manual encoding/decoding) */ #define ChannelFile_channels_tag 1 @@ -109,6 +160,19 @@ extern "C" { #define DeviceState_version_tag 8 #define DeviceState_no_save_tag 9 #define DeviceState_did_gps_reset_tag 11 +#define LocalConfig_device_tag 1 +#define LocalConfig_position_tag 2 +#define LocalConfig_power_tag 3 +#define LocalConfig_wifi_tag 4 +#define LocalConfig_display_tag 5 +#define LocalConfig_lora_tag 6 +#define LocalModuleConfig_mqtt_tag 1 +#define LocalModuleConfig_serial_tag 2 +#define LocalModuleConfig_external_notification_tag 3 +#define LocalModuleConfig_store_forward_tag 4 +#define LocalModuleConfig_range_test_tag 5 +#define LocalModuleConfig_telemetry_tag 6 +#define LocalModuleConfig_canned_message_tag 7 #define OEMStore_oem_icon_width_tag 1 #define OEMStore_oem_icon_height_tag 2 #define OEMStore_oem_icon_bits_tag 3 @@ -148,18 +212,58 @@ X(a, STATIC, SINGULAR, STRING, oem_text, 5) #define OEMStore_CALLBACK NULL #define OEMStore_DEFAULT NULL +#define LocalConfig_FIELDLIST(X, a) \ +X(a, STATIC, OPTIONAL, MESSAGE, device, 1) \ +X(a, STATIC, OPTIONAL, MESSAGE, position, 2) \ +X(a, STATIC, OPTIONAL, MESSAGE, power, 3) \ +X(a, STATIC, OPTIONAL, MESSAGE, wifi, 4) \ +X(a, STATIC, OPTIONAL, MESSAGE, display, 5) \ +X(a, STATIC, OPTIONAL, MESSAGE, lora, 6) +#define LocalConfig_CALLBACK NULL +#define LocalConfig_DEFAULT NULL +#define LocalConfig_device_MSGTYPE Config_DeviceConfig +#define LocalConfig_position_MSGTYPE Config_PositionConfig +#define LocalConfig_power_MSGTYPE Config_PowerConfig +#define LocalConfig_wifi_MSGTYPE Config_WiFiConfig +#define LocalConfig_display_MSGTYPE Config_DisplayConfig +#define LocalConfig_lora_MSGTYPE Config_LoRaConfig + +#define LocalModuleConfig_FIELDLIST(X, a) \ +X(a, STATIC, OPTIONAL, MESSAGE, mqtt, 1) \ +X(a, STATIC, OPTIONAL, MESSAGE, serial, 2) \ +X(a, STATIC, OPTIONAL, MESSAGE, external_notification, 3) \ +X(a, STATIC, OPTIONAL, MESSAGE, store_forward, 4) \ +X(a, STATIC, OPTIONAL, MESSAGE, range_test, 5) \ +X(a, STATIC, OPTIONAL, MESSAGE, telemetry, 6) \ +X(a, STATIC, OPTIONAL, MESSAGE, canned_message, 7) +#define LocalModuleConfig_CALLBACK NULL +#define LocalModuleConfig_DEFAULT NULL +#define LocalModuleConfig_mqtt_MSGTYPE ModuleConfig_MQTTConfig +#define LocalModuleConfig_serial_MSGTYPE ModuleConfig_SerialConfig +#define LocalModuleConfig_external_notification_MSGTYPE ModuleConfig_ExternalNotificationConfig +#define LocalModuleConfig_store_forward_MSGTYPE ModuleConfig_StoreForwardConfig +#define LocalModuleConfig_range_test_MSGTYPE ModuleConfig_RangeTestConfig +#define LocalModuleConfig_telemetry_MSGTYPE ModuleConfig_TelemetryConfig +#define LocalModuleConfig_canned_message_MSGTYPE ModuleConfig_CannedMessageConfig + extern const pb_msgdesc_t DeviceState_msg; extern const pb_msgdesc_t ChannelFile_msg; extern const pb_msgdesc_t OEMStore_msg; +extern const pb_msgdesc_t LocalConfig_msg; +extern const pb_msgdesc_t LocalModuleConfig_msg; /* Defines for backwards compatibility with code written before nanopb-0.4.0 */ #define DeviceState_fields &DeviceState_msg #define ChannelFile_fields &ChannelFile_msg #define OEMStore_fields &OEMStore_msg +#define LocalConfig_fields &LocalConfig_msg +#define LocalModuleConfig_fields &LocalModuleConfig_msg /* Maximum encoded size of messages (where known) */ -#define ChannelFile_size 832 -#define DeviceState_size 19327 +#define ChannelFile_size 624 +#define DeviceState_size 19184 +#define LocalConfig_size 331 +#define LocalModuleConfig_size 282 #define OEMStore_size 2106 #ifdef __cplusplus diff --git a/src/mesh/generated/mesh.pb.c b/src/mesh/generated/mesh.pb.c index 37fdda6eb..8aa1f540a 100644 --- a/src/mesh/generated/mesh.pb.c +++ b/src/mesh/generated/mesh.pb.c @@ -45,6 +45,8 @@ PB_BIND(ToRadio, ToRadio, 2) PB_BIND(ToRadio_PeerInfo, ToRadio_PeerInfo, AUTO) +PB_BIND(Compressed, Compressed, AUTO) + diff --git a/src/mesh/generated/mesh.pb.h b/src/mesh/generated/mesh.pb.h index 8ce6fc803..bc784d697 100644 --- a/src/mesh/generated/mesh.pb.h +++ b/src/mesh/generated/mesh.pb.h @@ -65,45 +65,14 @@ typedef enum _HardwareModel { HardwareModel_NANO_G1 = 41, /* nRF52840 Dongle : https://www.nordicsemi.com/Products/Development-hardware/nrf52840-dongle/ */ HardwareModel_NRF52840_PCA10059 = 42, + /* Custom Disaster Radio esp32 v3 device https://github.com/sudomesh/disaster-radio/tree/master/hardware/board_esp32_v3 */ + HardwareModel_DR_DEV = 43, + /* M5 esp32 based MCU modules with enclosure, TFT and LORA Shields. All Variants (Basic, Core, Fire, Core2, Paper) https://m5stack.com/ */ + HardwareModel_M5STACK = 44, /* Reserved ID For developing private Ports. These will show up in live traffic sparsely, so we can use a high number. Keep it within 8 bits. */ HardwareModel_PRIVATE_HW = 255 } HardwareModel; -/* The team colors are based on the names of "friendly teams" in ATAK: - https://github.com/deptofdefense/AndroidTacticalAssaultKit-CIV/blob/master/atak/ATAK/app/src/main/assets/filters/team_filters.xml */ -typedef enum _Team { - /* the default (unset) is "achromatic" (unaffiliated) */ - Team_CLEAR = 0, - /* TODO: REPLACE */ - Team_CYAN = 1, - /* TODO: REPLACE */ - Team_WHITE = 2, - /* TODO: REPLACE */ - Team_YELLOW = 3, - /* TODO: REPLACE */ - Team_ORANGE = 4, - /* TODO: REPLACE */ - Team_MAGENTA = 5, - /* TODO: REPLACE */ - Team_RED = 6, - /* TODO: REPLACE */ - Team_MAROON = 7, - /* TODO: REPLACE */ - Team_PURPLE = 8, - /* TODO: REPLACE */ - Team_DARK_BLUE = 9, - /* TODO: REPLACE */ - Team_BLUE = 10, - /* TODO: REPLACE */ - Team_TEAL = 11, - /* TODO: REPLACE */ - Team_GREEN = 12, - /* TODO: REPLACE */ - Team_DARK_GREEN = 13, - /* TODO: REPLACE */ - Team_BROWN = 14 -} Team; - /* Shared constants between device and phone */ typedef enum _Constants { /* First enum must be zero, and we are just using this enum to @@ -164,18 +133,17 @@ typedef enum _Position_LocSource { Position_LocSource_LOCSRC_GPS_EXTERNAL = 3 } Position_LocSource; -/* The team colors are based on the names of "friendly teams" in ATAK: - https://github.com/deptofdefense/AndroidTacticalAssaultKit-CIV/blob/master/atak/ATAK/app/src/main/assets/filters/team_filters.xml */ +/* Shared constants between device and phone */ typedef enum _Position_AltSource { - /* the default (unset) is "achromatic" (unaffiliated) */ + /* First enum must be zero, and we are just using this enum to + pass int constants between two very different environments */ Position_AltSource_ALTSRC_UNSPECIFIED = 0, - /* TODO: REPLACE */ + /* From mesh.options + note: this payload length is ONLY the bytes that are sent inside of the Data protobuf (excluding protobuf overhead). The 16 byte header is + outside of this envelope */ Position_AltSource_ALTSRC_MANUAL_ENTRY = 1, - /* TODO: REPLACE */ Position_AltSource_ALTSRC_GPS_INTERNAL = 2, - /* TODO: REPLACE */ Position_AltSource_ALTSRC_GPS_EXTERNAL = 3, - /* TODO: REPLACE */ Position_AltSource_ALTSRC_BAROMETRIC = 4 } Position_AltSource; @@ -232,14 +200,15 @@ typedef enum _MeshPacket_Priority { MeshPacket_Priority_MAX = 127 } MeshPacket_Priority; -/* The team colors are based on the names of "friendly teams" in ATAK: - https://github.com/deptofdefense/AndroidTacticalAssaultKit-CIV/blob/master/atak/ATAK/app/src/main/assets/filters/team_filters.xml */ +/* Shared constants between device and phone */ typedef enum _MeshPacket_Delayed { - /* the default (unset) is "achromatic" (unaffiliated) */ + /* First enum must be zero, and we are just using this enum to + pass int constants between two very different environments */ MeshPacket_Delayed_NO_DELAY = 0, - /* TODO: REPLACE */ + /* From mesh.options + note: this payload length is ONLY the bytes that are sent inside of the Data protobuf (excluding protobuf overhead). The 16 byte header is + outside of this envelope */ MeshPacket_Delayed_DELAYED_BROADCAST = 1, - /* TODO: REPLACE */ MeshPacket_Delayed_DELAYED_DIRECT = 2 } MeshPacket_Delayed; @@ -266,6 +235,12 @@ typedef enum _LogRecord_Level { } LogRecord_Level; /* Struct definitions */ +typedef PB_BYTES_ARRAY_T(237) Compressed_data_t; +typedef struct _Compressed { + PortNum portnum; + Compressed_data_t data; +} Compressed; + /* Location of a waypoint to associate with a message */ typedef struct _Location { /* Id of the location */ @@ -307,14 +282,6 @@ typedef struct _MyNodeInfo { Not the same as UserPreferences.location_sharing */ bool has_gps; /* The maximum number of 'software' channels that can be set on this node. */ - char region[12]; - /* Deprecated! ONLY USED IN DEVICE CODE (for upgrading old 1.0 firmwares) DO NOT READ ELSEWHERE. - The region code for my radio (US, CN, etc...) - Note: This string is deprecated. - The 1.0 builds populate it based on the flashed firmware name. - But for newer builds this string will be unpopulated (missing/null). - For those builds you should instead look at the new read/write region enum in UserSettings - The format of this string was 1.0-US or 1.0-CN etc.. Or empty string if unset. */ char firmware_version[18]; /* 0.0.5 etc... */ CriticalErrorCode error_code; @@ -432,8 +399,11 @@ typedef struct _RouteDiscovery { uint32_t route[8]; } RouteDiscovery; +/* Compressed message payload */ typedef struct _ToRadio_PeerInfo { + /* PortNum to determine the how to handle the compressed payload. */ uint32_t app_version; + /* Compressed data. */ bool mqtt_gateway; } ToRadio_PeerInfo; @@ -480,12 +450,6 @@ typedef struct _User { If this user is a licensed operator, set this flag. Also, "long_name" should be their licence number. */ bool is_licensed; - /* Participants in the same network can self-group into different teams. - Short-term this can be used to visually differentiate them on the map; - in the longer term it could also help users to semi-automatically - select or ignore messages according to team affiliation. - In total, 14 teams are defined (encoded in 4 bits) */ - Team team; /* Transmit power at antenna connector, in decibel-milliwatt An optional self-reported value useful in network planning, discovery and positioning - along with ant_gain_dbi and ant_azimuth below */ @@ -697,10 +661,6 @@ typedef struct _ToRadio { #define _HardwareModel_MAX HardwareModel_PRIVATE_HW #define _HardwareModel_ARRAYSIZE ((HardwareModel)(HardwareModel_PRIVATE_HW+1)) -#define _Team_MIN Team_CLEAR -#define _Team_MAX Team_BROWN -#define _Team_ARRAYSIZE ((Team)(Team_BROWN+1)) - #define _Constants_MIN Constants_Unused #define _Constants_MAX Constants_DATA_PAYLOAD_LEN #define _Constants_ARRAYSIZE ((Constants)(Constants_DATA_PAYLOAD_LEN+1)) @@ -740,33 +700,37 @@ extern "C" { /* Initializer values for message structs */ #define Position_init_default {0, 0, 0, 0, _Position_LocSource_MIN, _Position_AltSource_MIN, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0} -#define User_init_default {"", "", "", {0}, _HardwareModel_MIN, 0, _Team_MIN, 0, 0, 0} +#define User_init_default {"", "", "", {0}, _HardwareModel_MIN, 0, 0, 0, 0} #define RouteDiscovery_init_default {0, {0, 0, 0, 0, 0, 0, 0, 0}} #define Routing_init_default {0, {RouteDiscovery_init_default}} #define Data_init_default {_PortNum_MIN, 0, {{0, {0}}}, 0, 0, 0, 0, 0, 0, false, Location_init_default} #define Location_init_default {0, 0, 0, 0, 0} #define MeshPacket_init_default {0, 0, 0, 0, {Data_init_default}, 0, 0, 0, 0, 0, _MeshPacket_Priority_MIN, 0, _MeshPacket_Delayed_MIN} #define NodeInfo_init_default {0, false, User_init_default, false, Position_init_default, 0, 0, false, DeviceMetrics_init_default} -#define MyNodeInfo_init_default {0, 0, "", "", _CriticalErrorCode_MIN, 0, 0, 0, 0, 0, 0, 0, 0, {0, 0, 0, 0, 0, 0, 0, 0}, 0, {0, 0, 0, 0, 0, 0, 0, 0}, 0, 0, 0} +#define MyNodeInfo_init_default {0, 0, "", _CriticalErrorCode_MIN, 0, 0, 0, 0, 0, 0, 0, 0, {0, 0, 0, 0, 0, 0, 0, 0}, 0, {0, 0, 0, 0, 0, 0, 0, 0}, 0, 0, 0} #define LogRecord_init_default {"", 0, "", _LogRecord_Level_MIN} #define FromRadio_init_default {0, 0, {MyNodeInfo_init_default}} #define ToRadio_init_default {0, {MeshPacket_init_default}} #define ToRadio_PeerInfo_init_default {0, 0} +#define Compressed_init_default {_PortNum_MIN, {0, {0}}} #define Position_init_zero {0, 0, 0, 0, _Position_LocSource_MIN, _Position_AltSource_MIN, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0} -#define User_init_zero {"", "", "", {0}, _HardwareModel_MIN, 0, _Team_MIN, 0, 0, 0} +#define User_init_zero {"", "", "", {0}, _HardwareModel_MIN, 0, 0, 0, 0} #define RouteDiscovery_init_zero {0, {0, 0, 0, 0, 0, 0, 0, 0}} #define Routing_init_zero {0, {RouteDiscovery_init_zero}} #define Data_init_zero {_PortNum_MIN, 0, {{0, {0}}}, 0, 0, 0, 0, 0, 0, false, Location_init_zero} #define Location_init_zero {0, 0, 0, 0, 0} #define MeshPacket_init_zero {0, 0, 0, 0, {Data_init_zero}, 0, 0, 0, 0, 0, _MeshPacket_Priority_MIN, 0, _MeshPacket_Delayed_MIN} #define NodeInfo_init_zero {0, false, User_init_zero, false, Position_init_zero, 0, 0, false, DeviceMetrics_init_zero} -#define MyNodeInfo_init_zero {0, 0, "", "", _CriticalErrorCode_MIN, 0, 0, 0, 0, 0, 0, 0, 0, {0, 0, 0, 0, 0, 0, 0, 0}, 0, {0, 0, 0, 0, 0, 0, 0, 0}, 0, 0, 0} +#define MyNodeInfo_init_zero {0, 0, "", _CriticalErrorCode_MIN, 0, 0, 0, 0, 0, 0, 0, 0, {0, 0, 0, 0, 0, 0, 0, 0}, 0, {0, 0, 0, 0, 0, 0, 0, 0}, 0, 0, 0} #define LogRecord_init_zero {"", 0, "", _LogRecord_Level_MIN} #define FromRadio_init_zero {0, 0, {MyNodeInfo_init_zero}} #define ToRadio_init_zero {0, {MeshPacket_init_zero}} #define ToRadio_PeerInfo_init_zero {0, 0} +#define Compressed_init_zero {_PortNum_MIN, {0, {0}}} /* Field tags (for use in manual encoding/decoding) */ +#define Compressed_portnum_tag 1 +#define Compressed_data_tag 2 #define Location_id_tag 1 #define Location_latitude_i_tag 2 #define Location_longitude_i_tag 3 @@ -778,7 +742,6 @@ extern "C" { #define LogRecord_level_tag 4 #define MyNodeInfo_my_node_num_tag 1 #define MyNodeInfo_has_gps_tag 2 -#define MyNodeInfo_region_tag 4 #define MyNodeInfo_firmware_version_tag 6 #define MyNodeInfo_error_code_tag 7 #define MyNodeInfo_error_address_tag 8 @@ -824,7 +787,6 @@ extern "C" { #define User_macaddr_tag 4 #define User_hw_model_tag 6 #define User_is_licensed_tag 7 -#define User_team_tag 8 #define User_tx_power_dbm_tag 10 #define User_ant_gain_dbi_tag 11 #define User_ant_azimuth_tag 12 @@ -906,7 +868,6 @@ X(a, STATIC, SINGULAR, STRING, short_name, 3) \ X(a, STATIC, SINGULAR, FIXED_LENGTH_BYTES, macaddr, 4) \ X(a, STATIC, SINGULAR, UENUM, hw_model, 6) \ X(a, STATIC, SINGULAR, BOOL, is_licensed, 7) \ -X(a, STATIC, SINGULAR, UENUM, team, 8) \ X(a, STATIC, SINGULAR, UINT32, tx_power_dbm, 10) \ X(a, STATIC, SINGULAR, UINT32, ant_gain_dbi, 11) \ X(a, STATIC, SINGULAR, UINT32, ant_azimuth, 12) @@ -985,7 +946,6 @@ X(a, STATIC, OPTIONAL, MESSAGE, device_metrics, 6) #define MyNodeInfo_FIELDLIST(X, a) \ X(a, STATIC, SINGULAR, UINT32, my_node_num, 1) \ X(a, STATIC, SINGULAR, BOOL, has_gps, 2) \ -X(a, STATIC, SINGULAR, STRING, region, 4) \ X(a, STATIC, SINGULAR, STRING, firmware_version, 6) \ X(a, STATIC, SINGULAR, UENUM, error_code, 7) \ X(a, STATIC, SINGULAR, UINT32, error_address, 8) \ @@ -1042,6 +1002,12 @@ X(a, STATIC, SINGULAR, BOOL, mqtt_gateway, 2) #define ToRadio_PeerInfo_CALLBACK NULL #define ToRadio_PeerInfo_DEFAULT NULL +#define Compressed_FIELDLIST(X, a) \ +X(a, STATIC, SINGULAR, UENUM, portnum, 1) \ +X(a, STATIC, SINGULAR, BYTES, data, 2) +#define Compressed_CALLBACK NULL +#define Compressed_DEFAULT NULL + extern const pb_msgdesc_t Position_msg; extern const pb_msgdesc_t User_msg; extern const pb_msgdesc_t RouteDiscovery_msg; @@ -1055,6 +1021,7 @@ extern const pb_msgdesc_t LogRecord_msg; extern const pb_msgdesc_t FromRadio_msg; extern const pb_msgdesc_t ToRadio_msg; extern const pb_msgdesc_t ToRadio_PeerInfo_msg; +extern const pb_msgdesc_t Compressed_msg; /* Defines for backwards compatibility with code written before nanopb-0.4.0 */ #define Position_fields &Position_msg @@ -1070,21 +1037,23 @@ extern const pb_msgdesc_t ToRadio_PeerInfo_msg; #define FromRadio_fields &FromRadio_msg #define ToRadio_fields &ToRadio_msg #define ToRadio_PeerInfo_fields &ToRadio_PeerInfo_msg +#define Compressed_fields &Compressed_msg /* Maximum encoded size of messages (where known) */ +#define Compressed_size 243 #define Data_size 296 #define FromRadio_size 356 #define Location_size 24 #define LogRecord_size 81 #define MeshPacket_size 347 -#define MyNodeInfo_size 210 -#define NodeInfo_size 283 +#define MyNodeInfo_size 197 +#define NodeInfo_size 281 #define Position_size 142 #define RouteDiscovery_size 40 #define Routing_size 42 #define ToRadio_PeerInfo_size 8 #define ToRadio_size 350 -#define User_size 97 +#define User_size 95 #ifdef __cplusplus } /* extern "C" */ diff --git a/src/mesh/generated/module_config.pb.c b/src/mesh/generated/module_config.pb.c new file mode 100644 index 000000000..75ab73420 --- /dev/null +++ b/src/mesh/generated/module_config.pb.c @@ -0,0 +1,36 @@ +/* Automatically generated nanopb constant definitions */ +/* Generated by nanopb-0.4.5 */ + +#include "module_config.pb.h" +#if PB_PROTO_HEADER_VERSION != 40 +#error Regenerate this file with the current version of nanopb generator. +#endif + +PB_BIND(ModuleConfig, ModuleConfig, AUTO) + + +PB_BIND(ModuleConfig_MQTTConfig, ModuleConfig_MQTTConfig, AUTO) + + +PB_BIND(ModuleConfig_SerialConfig, ModuleConfig_SerialConfig, AUTO) + + +PB_BIND(ModuleConfig_ExternalNotificationConfig, ModuleConfig_ExternalNotificationConfig, AUTO) + + +PB_BIND(ModuleConfig_StoreForwardConfig, ModuleConfig_StoreForwardConfig, AUTO) + + +PB_BIND(ModuleConfig_RangeTestConfig, ModuleConfig_RangeTestConfig, AUTO) + + +PB_BIND(ModuleConfig_TelemetryConfig, ModuleConfig_TelemetryConfig, AUTO) + + +PB_BIND(ModuleConfig_CannedMessageConfig, ModuleConfig_CannedMessageConfig, AUTO) + + + + + + diff --git a/src/mesh/generated/module_config.pb.h b/src/mesh/generated/module_config.pb.h new file mode 100644 index 000000000..9ec763e6f --- /dev/null +++ b/src/mesh/generated/module_config.pb.h @@ -0,0 +1,351 @@ +/* Automatically generated nanopb header */ +/* Generated by nanopb-0.4.5 */ + +#ifndef PB_MODULE_CONFIG_PB_H_INCLUDED +#define PB_MODULE_CONFIG_PB_H_INCLUDED +#include +#include "telemetry.pb.h" + +#if PB_PROTO_HEADER_VERSION != 40 +#error Regenerate this file with the current version of nanopb generator. +#endif + +/* Enum definitions */ +typedef enum _ModuleConfig_SerialConfig_Serial_Baud { + ModuleConfig_SerialConfig_Serial_Baud_BAUD_Default = 0, + ModuleConfig_SerialConfig_Serial_Baud_BAUD_2400 = 1, + ModuleConfig_SerialConfig_Serial_Baud_BAUD_4800 = 2, + ModuleConfig_SerialConfig_Serial_Baud_BAUD_9600 = 3, + ModuleConfig_SerialConfig_Serial_Baud_BAUD_19200 = 4, + ModuleConfig_SerialConfig_Serial_Baud_BAUD_38400 = 5, + ModuleConfig_SerialConfig_Serial_Baud_BAUD_57600 = 6, + ModuleConfig_SerialConfig_Serial_Baud_BAUD_115200 = 7, + ModuleConfig_SerialConfig_Serial_Baud_BAUD_230400 = 8, + ModuleConfig_SerialConfig_Serial_Baud_BAUD_460800 = 9, + ModuleConfig_SerialConfig_Serial_Baud_BAUD_576000 = 10, + ModuleConfig_SerialConfig_Serial_Baud_BAUD_921600 = 11, + ModuleConfig_SerialConfig_Serial_Baud_BAUD_110 = 12, + ModuleConfig_SerialConfig_Serial_Baud_BAUD_300 = 13, + ModuleConfig_SerialConfig_Serial_Baud_BAUD_600 = 14, + ModuleConfig_SerialConfig_Serial_Baud_BAUD_1200 = 15 +} ModuleConfig_SerialConfig_Serial_Baud; + +typedef enum _ModuleConfig_SerialConfig_Serial_Mode { + ModuleConfig_SerialConfig_Serial_Mode_MODE_Default = 0, + ModuleConfig_SerialConfig_Serial_Mode_MODE_SIMPLE = 1, + ModuleConfig_SerialConfig_Serial_Mode_MODE_PROTO = 2 +} ModuleConfig_SerialConfig_Serial_Mode; + +typedef enum _ModuleConfig_CannedMessageConfig_InputEventChar { + ModuleConfig_CannedMessageConfig_InputEventChar_KEY_NONE = 0, + ModuleConfig_CannedMessageConfig_InputEventChar_KEY_UP = 17, + ModuleConfig_CannedMessageConfig_InputEventChar_KEY_DOWN = 18, + ModuleConfig_CannedMessageConfig_InputEventChar_KEY_LEFT = 19, + ModuleConfig_CannedMessageConfig_InputEventChar_KEY_RIGHT = 20, + ModuleConfig_CannedMessageConfig_InputEventChar_KEY_SELECT = 10, + ModuleConfig_CannedMessageConfig_InputEventChar_KEY_BACK = 27, + ModuleConfig_CannedMessageConfig_InputEventChar_KEY_CANCEL = 24 +} ModuleConfig_CannedMessageConfig_InputEventChar; + +/* Struct definitions */ +typedef struct _ModuleConfig_CannedMessageConfig { + bool rotary1_enabled; + uint32_t inputbroker_pin_a; + uint32_t inputbroker_pin_b; + uint32_t inputbroker_pin_press; + ModuleConfig_CannedMessageConfig_InputEventChar inputbroker_event_cw; + ModuleConfig_CannedMessageConfig_InputEventChar inputbroker_event_ccw; + ModuleConfig_CannedMessageConfig_InputEventChar inputbroker_event_press; + bool updown1_enabled; + bool enabled; + char allow_input_source[16]; + bool send_bell; +} ModuleConfig_CannedMessageConfig; + +typedef struct _ModuleConfig_ExternalNotificationConfig { + bool enabled; + uint32_t output_ms; + uint32_t output; + bool active; + bool alert_message; + bool alert_bell; +} ModuleConfig_ExternalNotificationConfig; + +typedef struct _ModuleConfig_MQTTConfig { + bool disabled; + char address[32]; + char username[32]; + char password[32]; + bool encryption_enabled; +} ModuleConfig_MQTTConfig; + +typedef struct _ModuleConfig_RangeTestConfig { + bool enabled; + uint32_t sender; + bool save; +} ModuleConfig_RangeTestConfig; + +typedef struct _ModuleConfig_SerialConfig { + bool enabled; + bool echo; + uint32_t rxd; + uint32_t txd; + ModuleConfig_SerialConfig_Serial_Baud baud; + uint32_t timeout; + ModuleConfig_SerialConfig_Serial_Mode mode; +} ModuleConfig_SerialConfig; + +typedef struct _ModuleConfig_StoreForwardConfig { + bool enabled; + bool heartbeat; + uint32_t records; + uint32_t history_return_max; + uint32_t history_return_window; +} ModuleConfig_StoreForwardConfig; + +typedef struct _ModuleConfig_TelemetryConfig { + uint32_t device_update_interval; + uint32_t environment_update_interval; + bool environment_measurement_enabled; + bool environment_screen_enabled; + uint32_t environment_read_error_count_threshold; + uint32_t environment_recovery_interval; + bool environment_display_fahrenheit; + TelemetrySensorType environment_sensor_type; + uint32_t environment_sensor_pin; +} ModuleConfig_TelemetryConfig; + +/* TODO: REPLACE */ +typedef struct _ModuleConfig { + /* TODO: REPLACE */ + pb_size_t which_payloadVariant; + union { + ModuleConfig_MQTTConfig mqtt; + ModuleConfig_SerialConfig serial; + ModuleConfig_ExternalNotificationConfig external_notification; + ModuleConfig_StoreForwardConfig store_forward; + ModuleConfig_RangeTestConfig range_test; + ModuleConfig_TelemetryConfig telemetry; + ModuleConfig_CannedMessageConfig canned_message; + } payloadVariant; +} ModuleConfig; + + +/* Helper constants for enums */ +#define _ModuleConfig_SerialConfig_Serial_Baud_MIN ModuleConfig_SerialConfig_Serial_Baud_BAUD_Default +#define _ModuleConfig_SerialConfig_Serial_Baud_MAX ModuleConfig_SerialConfig_Serial_Baud_BAUD_1200 +#define _ModuleConfig_SerialConfig_Serial_Baud_ARRAYSIZE ((ModuleConfig_SerialConfig_Serial_Baud)(ModuleConfig_SerialConfig_Serial_Baud_BAUD_1200+1)) + +#define _ModuleConfig_SerialConfig_Serial_Mode_MIN ModuleConfig_SerialConfig_Serial_Mode_MODE_Default +#define _ModuleConfig_SerialConfig_Serial_Mode_MAX ModuleConfig_SerialConfig_Serial_Mode_MODE_PROTO +#define _ModuleConfig_SerialConfig_Serial_Mode_ARRAYSIZE ((ModuleConfig_SerialConfig_Serial_Mode)(ModuleConfig_SerialConfig_Serial_Mode_MODE_PROTO+1)) + +#define _ModuleConfig_CannedMessageConfig_InputEventChar_MIN ModuleConfig_CannedMessageConfig_InputEventChar_KEY_NONE +#define _ModuleConfig_CannedMessageConfig_InputEventChar_MAX ModuleConfig_CannedMessageConfig_InputEventChar_KEY_BACK +#define _ModuleConfig_CannedMessageConfig_InputEventChar_ARRAYSIZE ((ModuleConfig_CannedMessageConfig_InputEventChar)(ModuleConfig_CannedMessageConfig_InputEventChar_KEY_BACK+1)) + + +#ifdef __cplusplus +extern "C" { +#endif + +/* Initializer values for message structs */ +#define ModuleConfig_init_default {0, {ModuleConfig_MQTTConfig_init_default}} +#define ModuleConfig_MQTTConfig_init_default {0, "", "", "", 0} +#define ModuleConfig_SerialConfig_init_default {0, 0, 0, 0, _ModuleConfig_SerialConfig_Serial_Baud_MIN, 0, _ModuleConfig_SerialConfig_Serial_Mode_MIN} +#define ModuleConfig_ExternalNotificationConfig_init_default {0, 0, 0, 0, 0, 0} +#define ModuleConfig_StoreForwardConfig_init_default {0, 0, 0, 0, 0} +#define ModuleConfig_RangeTestConfig_init_default {0, 0, 0} +#define ModuleConfig_TelemetryConfig_init_default {0, 0, 0, 0, 0, 0, 0, _TelemetrySensorType_MIN, 0} +#define ModuleConfig_CannedMessageConfig_init_default {0, 0, 0, 0, _ModuleConfig_CannedMessageConfig_InputEventChar_MIN, _ModuleConfig_CannedMessageConfig_InputEventChar_MIN, _ModuleConfig_CannedMessageConfig_InputEventChar_MIN, 0, 0, "", 0} +#define ModuleConfig_init_zero {0, {ModuleConfig_MQTTConfig_init_zero}} +#define ModuleConfig_MQTTConfig_init_zero {0, "", "", "", 0} +#define ModuleConfig_SerialConfig_init_zero {0, 0, 0, 0, _ModuleConfig_SerialConfig_Serial_Baud_MIN, 0, _ModuleConfig_SerialConfig_Serial_Mode_MIN} +#define ModuleConfig_ExternalNotificationConfig_init_zero {0, 0, 0, 0, 0, 0} +#define ModuleConfig_StoreForwardConfig_init_zero {0, 0, 0, 0, 0} +#define ModuleConfig_RangeTestConfig_init_zero {0, 0, 0} +#define ModuleConfig_TelemetryConfig_init_zero {0, 0, 0, 0, 0, 0, 0, _TelemetrySensorType_MIN, 0} +#define ModuleConfig_CannedMessageConfig_init_zero {0, 0, 0, 0, _ModuleConfig_CannedMessageConfig_InputEventChar_MIN, _ModuleConfig_CannedMessageConfig_InputEventChar_MIN, _ModuleConfig_CannedMessageConfig_InputEventChar_MIN, 0, 0, "", 0} + +/* Field tags (for use in manual encoding/decoding) */ +#define ModuleConfig_CannedMessageConfig_rotary1_enabled_tag 1 +#define ModuleConfig_CannedMessageConfig_inputbroker_pin_a_tag 2 +#define ModuleConfig_CannedMessageConfig_inputbroker_pin_b_tag 3 +#define ModuleConfig_CannedMessageConfig_inputbroker_pin_press_tag 4 +#define ModuleConfig_CannedMessageConfig_inputbroker_event_cw_tag 5 +#define ModuleConfig_CannedMessageConfig_inputbroker_event_ccw_tag 6 +#define ModuleConfig_CannedMessageConfig_inputbroker_event_press_tag 7 +#define ModuleConfig_CannedMessageConfig_updown1_enabled_tag 8 +#define ModuleConfig_CannedMessageConfig_enabled_tag 9 +#define ModuleConfig_CannedMessageConfig_allow_input_source_tag 10 +#define ModuleConfig_CannedMessageConfig_send_bell_tag 11 +#define ModuleConfig_ExternalNotificationConfig_enabled_tag 1 +#define ModuleConfig_ExternalNotificationConfig_output_ms_tag 2 +#define ModuleConfig_ExternalNotificationConfig_output_tag 3 +#define ModuleConfig_ExternalNotificationConfig_active_tag 4 +#define ModuleConfig_ExternalNotificationConfig_alert_message_tag 5 +#define ModuleConfig_ExternalNotificationConfig_alert_bell_tag 6 +#define ModuleConfig_MQTTConfig_disabled_tag 1 +#define ModuleConfig_MQTTConfig_address_tag 2 +#define ModuleConfig_MQTTConfig_username_tag 3 +#define ModuleConfig_MQTTConfig_password_tag 4 +#define ModuleConfig_MQTTConfig_encryption_enabled_tag 5 +#define ModuleConfig_RangeTestConfig_enabled_tag 1 +#define ModuleConfig_RangeTestConfig_sender_tag 2 +#define ModuleConfig_RangeTestConfig_save_tag 3 +#define ModuleConfig_SerialConfig_enabled_tag 1 +#define ModuleConfig_SerialConfig_echo_tag 2 +#define ModuleConfig_SerialConfig_rxd_tag 3 +#define ModuleConfig_SerialConfig_txd_tag 4 +#define ModuleConfig_SerialConfig_baud_tag 5 +#define ModuleConfig_SerialConfig_timeout_tag 6 +#define ModuleConfig_SerialConfig_mode_tag 7 +#define ModuleConfig_StoreForwardConfig_enabled_tag 1 +#define ModuleConfig_StoreForwardConfig_heartbeat_tag 2 +#define ModuleConfig_StoreForwardConfig_records_tag 3 +#define ModuleConfig_StoreForwardConfig_history_return_max_tag 4 +#define ModuleConfig_StoreForwardConfig_history_return_window_tag 5 +#define ModuleConfig_TelemetryConfig_device_update_interval_tag 1 +#define ModuleConfig_TelemetryConfig_environment_update_interval_tag 2 +#define ModuleConfig_TelemetryConfig_environment_measurement_enabled_tag 3 +#define ModuleConfig_TelemetryConfig_environment_screen_enabled_tag 4 +#define ModuleConfig_TelemetryConfig_environment_read_error_count_threshold_tag 5 +#define ModuleConfig_TelemetryConfig_environment_recovery_interval_tag 6 +#define ModuleConfig_TelemetryConfig_environment_display_fahrenheit_tag 7 +#define ModuleConfig_TelemetryConfig_environment_sensor_type_tag 8 +#define ModuleConfig_TelemetryConfig_environment_sensor_pin_tag 9 +#define ModuleConfig_mqtt_tag 1 +#define ModuleConfig_serial_tag 2 +#define ModuleConfig_external_notification_tag 3 +#define ModuleConfig_store_forward_tag 4 +#define ModuleConfig_range_test_tag 5 +#define ModuleConfig_telemetry_tag 6 +#define ModuleConfig_canned_message_tag 7 + +/* Struct field encoding specification for nanopb */ +#define ModuleConfig_FIELDLIST(X, a) \ +X(a, STATIC, ONEOF, MESSAGE, (payloadVariant,mqtt,payloadVariant.mqtt), 1) \ +X(a, STATIC, ONEOF, MESSAGE, (payloadVariant,serial,payloadVariant.serial), 2) \ +X(a, STATIC, ONEOF, MESSAGE, (payloadVariant,external_notification,payloadVariant.external_notification), 3) \ +X(a, STATIC, ONEOF, MESSAGE, (payloadVariant,store_forward,payloadVariant.store_forward), 4) \ +X(a, STATIC, ONEOF, MESSAGE, (payloadVariant,range_test,payloadVariant.range_test), 5) \ +X(a, STATIC, ONEOF, MESSAGE, (payloadVariant,telemetry,payloadVariant.telemetry), 6) \ +X(a, STATIC, ONEOF, MESSAGE, (payloadVariant,canned_message,payloadVariant.canned_message), 7) +#define ModuleConfig_CALLBACK NULL +#define ModuleConfig_DEFAULT NULL +#define ModuleConfig_payloadVariant_mqtt_MSGTYPE ModuleConfig_MQTTConfig +#define ModuleConfig_payloadVariant_serial_MSGTYPE ModuleConfig_SerialConfig +#define ModuleConfig_payloadVariant_external_notification_MSGTYPE ModuleConfig_ExternalNotificationConfig +#define ModuleConfig_payloadVariant_store_forward_MSGTYPE ModuleConfig_StoreForwardConfig +#define ModuleConfig_payloadVariant_range_test_MSGTYPE ModuleConfig_RangeTestConfig +#define ModuleConfig_payloadVariant_telemetry_MSGTYPE ModuleConfig_TelemetryConfig +#define ModuleConfig_payloadVariant_canned_message_MSGTYPE ModuleConfig_CannedMessageConfig + +#define ModuleConfig_MQTTConfig_FIELDLIST(X, a) \ +X(a, STATIC, SINGULAR, BOOL, disabled, 1) \ +X(a, STATIC, SINGULAR, STRING, address, 2) \ +X(a, STATIC, SINGULAR, STRING, username, 3) \ +X(a, STATIC, SINGULAR, STRING, password, 4) \ +X(a, STATIC, SINGULAR, BOOL, encryption_enabled, 5) +#define ModuleConfig_MQTTConfig_CALLBACK NULL +#define ModuleConfig_MQTTConfig_DEFAULT NULL + +#define ModuleConfig_SerialConfig_FIELDLIST(X, a) \ +X(a, STATIC, SINGULAR, BOOL, enabled, 1) \ +X(a, STATIC, SINGULAR, BOOL, echo, 2) \ +X(a, STATIC, SINGULAR, UINT32, rxd, 3) \ +X(a, STATIC, SINGULAR, UINT32, txd, 4) \ +X(a, STATIC, SINGULAR, UENUM, baud, 5) \ +X(a, STATIC, SINGULAR, UINT32, timeout, 6) \ +X(a, STATIC, SINGULAR, UENUM, mode, 7) +#define ModuleConfig_SerialConfig_CALLBACK NULL +#define ModuleConfig_SerialConfig_DEFAULT NULL + +#define ModuleConfig_ExternalNotificationConfig_FIELDLIST(X, a) \ +X(a, STATIC, SINGULAR, BOOL, enabled, 1) \ +X(a, STATIC, SINGULAR, UINT32, output_ms, 2) \ +X(a, STATIC, SINGULAR, UINT32, output, 3) \ +X(a, STATIC, SINGULAR, BOOL, active, 4) \ +X(a, STATIC, SINGULAR, BOOL, alert_message, 5) \ +X(a, STATIC, SINGULAR, BOOL, alert_bell, 6) +#define ModuleConfig_ExternalNotificationConfig_CALLBACK NULL +#define ModuleConfig_ExternalNotificationConfig_DEFAULT NULL + +#define ModuleConfig_StoreForwardConfig_FIELDLIST(X, a) \ +X(a, STATIC, SINGULAR, BOOL, enabled, 1) \ +X(a, STATIC, SINGULAR, BOOL, heartbeat, 2) \ +X(a, STATIC, SINGULAR, UINT32, records, 3) \ +X(a, STATIC, SINGULAR, UINT32, history_return_max, 4) \ +X(a, STATIC, SINGULAR, UINT32, history_return_window, 5) +#define ModuleConfig_StoreForwardConfig_CALLBACK NULL +#define ModuleConfig_StoreForwardConfig_DEFAULT NULL + +#define ModuleConfig_RangeTestConfig_FIELDLIST(X, a) \ +X(a, STATIC, SINGULAR, BOOL, enabled, 1) \ +X(a, STATIC, SINGULAR, UINT32, sender, 2) \ +X(a, STATIC, SINGULAR, BOOL, save, 3) +#define ModuleConfig_RangeTestConfig_CALLBACK NULL +#define ModuleConfig_RangeTestConfig_DEFAULT NULL + +#define ModuleConfig_TelemetryConfig_FIELDLIST(X, a) \ +X(a, STATIC, SINGULAR, UINT32, device_update_interval, 1) \ +X(a, STATIC, SINGULAR, UINT32, environment_update_interval, 2) \ +X(a, STATIC, SINGULAR, BOOL, environment_measurement_enabled, 3) \ +X(a, STATIC, SINGULAR, BOOL, environment_screen_enabled, 4) \ +X(a, STATIC, SINGULAR, UINT32, environment_read_error_count_threshold, 5) \ +X(a, STATIC, SINGULAR, UINT32, environment_recovery_interval, 6) \ +X(a, STATIC, SINGULAR, BOOL, environment_display_fahrenheit, 7) \ +X(a, STATIC, SINGULAR, UENUM, environment_sensor_type, 8) \ +X(a, STATIC, SINGULAR, UINT32, environment_sensor_pin, 9) +#define ModuleConfig_TelemetryConfig_CALLBACK NULL +#define ModuleConfig_TelemetryConfig_DEFAULT NULL + +#define ModuleConfig_CannedMessageConfig_FIELDLIST(X, a) \ +X(a, STATIC, SINGULAR, BOOL, rotary1_enabled, 1) \ +X(a, STATIC, SINGULAR, UINT32, inputbroker_pin_a, 2) \ +X(a, STATIC, SINGULAR, UINT32, inputbroker_pin_b, 3) \ +X(a, STATIC, SINGULAR, UINT32, inputbroker_pin_press, 4) \ +X(a, STATIC, SINGULAR, UENUM, inputbroker_event_cw, 5) \ +X(a, STATIC, SINGULAR, UENUM, inputbroker_event_ccw, 6) \ +X(a, STATIC, SINGULAR, UENUM, inputbroker_event_press, 7) \ +X(a, STATIC, SINGULAR, BOOL, updown1_enabled, 8) \ +X(a, STATIC, SINGULAR, BOOL, enabled, 9) \ +X(a, STATIC, SINGULAR, STRING, allow_input_source, 10) \ +X(a, STATIC, SINGULAR, BOOL, send_bell, 11) +#define ModuleConfig_CannedMessageConfig_CALLBACK NULL +#define ModuleConfig_CannedMessageConfig_DEFAULT NULL + +extern const pb_msgdesc_t ModuleConfig_msg; +extern const pb_msgdesc_t ModuleConfig_MQTTConfig_msg; +extern const pb_msgdesc_t ModuleConfig_SerialConfig_msg; +extern const pb_msgdesc_t ModuleConfig_ExternalNotificationConfig_msg; +extern const pb_msgdesc_t ModuleConfig_StoreForwardConfig_msg; +extern const pb_msgdesc_t ModuleConfig_RangeTestConfig_msg; +extern const pb_msgdesc_t ModuleConfig_TelemetryConfig_msg; +extern const pb_msgdesc_t ModuleConfig_CannedMessageConfig_msg; + +/* Defines for backwards compatibility with code written before nanopb-0.4.0 */ +#define ModuleConfig_fields &ModuleConfig_msg +#define ModuleConfig_MQTTConfig_fields &ModuleConfig_MQTTConfig_msg +#define ModuleConfig_SerialConfig_fields &ModuleConfig_SerialConfig_msg +#define ModuleConfig_ExternalNotificationConfig_fields &ModuleConfig_ExternalNotificationConfig_msg +#define ModuleConfig_StoreForwardConfig_fields &ModuleConfig_StoreForwardConfig_msg +#define ModuleConfig_RangeTestConfig_fields &ModuleConfig_RangeTestConfig_msg +#define ModuleConfig_TelemetryConfig_fields &ModuleConfig_TelemetryConfig_msg +#define ModuleConfig_CannedMessageConfig_fields &ModuleConfig_CannedMessageConfig_msg + +/* Maximum encoded size of messages (where known) */ +#define ModuleConfig_CannedMessageConfig_size 49 +#define ModuleConfig_ExternalNotificationConfig_size 20 +#define ModuleConfig_MQTTConfig_size 103 +#define ModuleConfig_RangeTestConfig_size 10 +#define ModuleConfig_SerialConfig_size 26 +#define ModuleConfig_StoreForwardConfig_size 22 +#define ModuleConfig_TelemetryConfig_size 38 +#define ModuleConfig_size 105 + +#ifdef __cplusplus +} /* extern "C" */ +#endif + +#endif diff --git a/src/mesh/generated/portnums.pb.h b/src/mesh/generated/portnums.pb.h index 47cfbe16d..f824ce769 100644 --- a/src/mesh/generated/portnums.pb.h +++ b/src/mesh/generated/portnums.pb.h @@ -29,8 +29,7 @@ typedef enum _PortNum { PortNum_UNKNOWN_APP = 0, /* A simple UTF-8 text message, which even the little micros in the mesh can understand and show on their screen eventually in some circumstances - even signal might send messages in this form (see below) - Formerly called CLEAR_TEXT */ + even signal might send messages in this form (see below) */ PortNum_TEXT_MESSAGE_APP = 1, /* Reserved for built-in GPIO/example app. See remote_hardware.proto/HardwareMessage for details on the message sent/received to this port number */ @@ -70,6 +69,8 @@ typedef enum _PortNum { Maintained by Github user a-f-G-U-C (a Meshtastic contributor) Project files at https://github.com/a-f-G-U-C/Meshtastic-ZPS */ PortNum_ZPS_APP = 68, + /* Compressed payloads. */ + PortNum_COMPRESSION_APP = 69, /* Private applications should use portnums >= 256. To simplify initial development and testing you can use "PRIVATE_APP" in your code without needing to rebuild protobuf files (via [regen-protos.sh](https://github.com/meshtastic/Meshtastic-device/blob/master/bin/regen-protos.sh)) */ diff --git a/src/mesh/generated/radioconfig.pb.c b/src/mesh/generated/radioconfig.pb.c deleted file mode 100644 index 47b4f3903..000000000 --- a/src/mesh/generated/radioconfig.pb.c +++ /dev/null @@ -1,24 +0,0 @@ -/* Automatically generated nanopb constant definitions */ -/* Generated by nanopb-0.4.5 */ - -#include "radioconfig.pb.h" -#if PB_PROTO_HEADER_VERSION != 40 -#error Regenerate this file with the current version of nanopb generator. -#endif - -PB_BIND(RadioConfig, RadioConfig, 2) - - -PB_BIND(RadioConfig_UserPreferences, RadioConfig_UserPreferences, 2) - - - - - - - - - - - - diff --git a/src/mesh/generated/radioconfig.pb.h b/src/mesh/generated/radioconfig.pb.h deleted file mode 100644 index b6a50bb90..000000000 --- a/src/mesh/generated/radioconfig.pb.h +++ /dev/null @@ -1,606 +0,0 @@ -/* Automatically generated nanopb header */ -/* Generated by nanopb-0.4.5 */ - -#ifndef PB_RADIOCONFIG_PB_H_INCLUDED -#define PB_RADIOCONFIG_PB_H_INCLUDED -#include - -#if PB_PROTO_HEADER_VERSION != 40 -#error Regenerate this file with the current version of nanopb generator. -#endif - -/* Enum definitions */ -/* The frequency/regulatory region the user has selected. - Note: In 1.0 builds (which must still be supported by the android app for a - long time) this field will be unpopulated. - If firmware is ever upgraded from an old 1.0ish build, the old - MyNodeInfo.region string will be used to set UserPreferences.region and the - old value will be no longer set. */ -typedef enum _RegionCode { - /* TODO: REPLACE */ - RegionCode_Unset = 0, - /* TODO: REPLACE */ - RegionCode_US = 1, - /* TODO: REPLACE */ - RegionCode_EU433 = 2, - /* TODO: REPLACE */ - RegionCode_EU868 = 3, - /* TODO: REPLACE */ - RegionCode_CN = 4, - /* TODO: REPLACE */ - RegionCode_JP = 5, - /* TODO: REPLACE */ - RegionCode_ANZ = 6, - /* TODO: REPLACE */ - RegionCode_KR = 7, - /* TODO: REPLACE */ - RegionCode_TW = 8, - /* TODO: REPLACE */ - RegionCode_RU = 9, - /* TODO: REPLACE */ - RegionCode_IN = 10, - /* TODO: REPLACE */ - RegionCode_NZ865 = 11, - /* TODO: REPLACE */ - RegionCode_TH = 12 -} RegionCode; - -/* Defines the device's role on the Mesh network - unset - Behave normally. - Router - Functions as a router */ -typedef enum _Role { - /* Client device role */ - Role_Client = 0, - /* ClientMute device role - This is like the client but packets will not hop over this node. Would be - useful if you want to save power by not contributing to the mesh. */ - Role_ClientMute = 1, - /* Router device role. - Uses an agressive algirithem for the flood networking so packets will - prefer to be routed over this node. Also assume that this will be generally - unattended and so will turn off the wifi/ble radio as well as the oled screen. */ - Role_Router = 2, - /* RouterClient device role - Uses an agressive algirithem for the flood networking so packets will - prefer to be routed over this node. Similiar power management as a regular - client, so the RouterClient can be used as both a Router and a Client. Useful - as a well placed base station that you could also use to send messages. */ - Role_RouterClient = 3 -} Role; - -/* Sets the charge control current of devices with a battery charger that can be - configured. This is passed into the axp power management chip like on the tbeam. */ -typedef enum _ChargeCurrent { - /* TODO: REPLACE */ - ChargeCurrent_MAUnset = 0, - /* TODO: REPLACE */ - ChargeCurrent_MA100 = 1, - /* TODO: REPLACE */ - ChargeCurrent_MA190 = 2, - /* TODO: REPLACE */ - ChargeCurrent_MA280 = 3, - /* TODO: REPLACE */ - ChargeCurrent_MA360 = 4, - /* TODO: REPLACE */ - ChargeCurrent_MA450 = 5, - /* TODO: REPLACE */ - ChargeCurrent_MA550 = 6, - /* TODO: REPLACE */ - ChargeCurrent_MA630 = 7, - /* TODO: REPLACE */ - ChargeCurrent_MA700 = 8, - /* TODO: REPLACE */ - ChargeCurrent_MA780 = 9, - /* TODO: REPLACE */ - ChargeCurrent_MA880 = 10, - /* TODO: REPLACE */ - ChargeCurrent_MA960 = 11, - /* TODO: REPLACE */ - ChargeCurrent_MA1000 = 12, - /* TODO: REPLACE */ - ChargeCurrent_MA1080 = 13, - /* TODO: REPLACE */ - ChargeCurrent_MA1160 = 14, - /* TODO: REPLACE */ - ChargeCurrent_MA1240 = 15, - /* TODO: REPLACE */ - ChargeCurrent_MA1320 = 16 -} ChargeCurrent; - -/* How the GPS coordinates are displayed on the OLED screen. */ -typedef enum _GpsCoordinateFormat { - /* GPS coordinates are displayed in the normal decimal degrees format: - DD.DDDDDD DDD.DDDDDD */ - GpsCoordinateFormat_GpsFormatDec = 0, - /* GPS coordinates are displayed in the degrees minutes seconds format: - DD°MM'SS"C DDD°MM'SS"C, where C is the compass point representing the locations quadrant */ - GpsCoordinateFormat_GpsFormatDMS = 1, - /* GPS coordinates are displayed in Universal Transverse Mercator format: - ZZB EEEEEE NNNNNNN, where Z is zone, B is band, E is easting, N is northing */ - GpsCoordinateFormat_GpsFormatUTM = 2, - /* GPS coordinates are displayed in Military Grid Reference System format: - ZZB CD EEEEE NNNNN, where Z is zone, B is band, C is the east 100k square, D is the north 100k square, - E is easting, N is northing */ - GpsCoordinateFormat_GpsFormatMGRS = 3, - /* GPS coordinates are displayed in Open Location Code (aka Plus Codes). */ - GpsCoordinateFormat_GpsFormatOLC = 4, - /* GPS coordinates are displayed in Ordnance Survey Grid Reference (the National Grid System of the UK). - Format: AB EEEEE NNNNN, where A is the east 100k square, B is the north 100k square, E is the easting, - N is the northing */ - GpsCoordinateFormat_GpsFormatOSGR = 5 -} GpsCoordinateFormat; - -/* Bit field of boolean configuration options, indicating which optional - fields to include when assembling POSITION messages - Longitude and latitude are always included (also time if GPS-synced) - NOTE: the more fields are included, the larger the message will be - - leading to longer airtime and a higher risk of packet loss */ -typedef enum _PositionFlags { - /* Required for compilation */ - PositionFlags_POS_UNDEFINED = 0, - /* Include an altitude value (if available) */ - PositionFlags_POS_ALTITUDE = 1, - /* Altitude value is MSL */ - PositionFlags_POS_ALT_MSL = 2, - /* Include geoidal separation */ - PositionFlags_POS_GEO_SEP = 4, - /* Include the DOP value ; PDOP used by default, see below */ - PositionFlags_POS_DOP = 8, - /* If POS_DOP set, send separate HDOP / VDOP values instead of PDOP */ - PositionFlags_POS_HVDOP = 16, - /* Include battery level */ - PositionFlags_POS_BATTERY = 32, - /* Include number of "satellites in view" */ - PositionFlags_POS_SATINVIEW = 64, - /* Include a sequence number incremented per packet */ - PositionFlags_POS_SEQ_NOS = 128, - /* Include positional timestamp (from GPS solution) */ - PositionFlags_POS_TIMESTAMP = 256 -} PositionFlags; - -/* TODO: REPLACE */ -typedef enum _InputEventChar { - /* TODO: REPLACE */ - InputEventChar_KEY_NONE = 0, - /* TODO: REPLACE */ - InputEventChar_KEY_UP = 17, - /* TODO: REPLACE */ - InputEventChar_KEY_DOWN = 18, - /* TODO: REPLACE */ - InputEventChar_KEY_LEFT = 19, - /* TODO: REPLACE */ - InputEventChar_KEY_RIGHT = 20, - /* '\n' */ - InputEventChar_KEY_SELECT = 10, - /* TODO: REPLACE */ - InputEventChar_KEY_BACK = 27, - /* TODO: REPLACE */ - InputEventChar_KEY_CANCEL = 24 -} InputEventChar; - -/* The frequency/regulatory region the user has selected. - Note: In 1.0 builds (which must still be supported by the android app for a - long time) this field will be unpopulated. - If firmware is ever upgraded from an old 1.0ish build, the old - MyNodeInfo.region string will be used to set UserPreferences.region and the - old value will be no longer set. */ -typedef enum _RadioConfig_UserPreferences_Serial_Baud { - /* TODO: REPLACE */ - RadioConfig_UserPreferences_Serial_Baud_BAUD_Default = 0, - /* TODO: REPLACE */ - RadioConfig_UserPreferences_Serial_Baud_BAUD_2400 = 1, - /* TODO: REPLACE */ - RadioConfig_UserPreferences_Serial_Baud_BAUD_4800 = 2, - /* TODO: REPLACE */ - RadioConfig_UserPreferences_Serial_Baud_BAUD_9600 = 3, - /* TODO: REPLACE */ - RadioConfig_UserPreferences_Serial_Baud_BAUD_19200 = 4, - /* TODO: REPLACE */ - RadioConfig_UserPreferences_Serial_Baud_BAUD_38400 = 5, - /* TODO: REPLACE */ - RadioConfig_UserPreferences_Serial_Baud_BAUD_57600 = 6, - /* TODO: REPLACE */ - RadioConfig_UserPreferences_Serial_Baud_BAUD_115200 = 7, - /* TODO: REPLACE */ - RadioConfig_UserPreferences_Serial_Baud_BAUD_230400 = 8, - /* TODO: REPLACE */ - RadioConfig_UserPreferences_Serial_Baud_BAUD_460800 = 9, - /* TODO: REPLACE */ - RadioConfig_UserPreferences_Serial_Baud_BAUD_576000 = 10, - /* TODO: REPLACE */ - RadioConfig_UserPreferences_Serial_Baud_BAUD_921600 = 11, - /* TODO: REPLACE */ - RadioConfig_UserPreferences_Serial_Baud_BAUD_110 = 12, - RadioConfig_UserPreferences_Serial_Baud_BAUD_300 = 13, - RadioConfig_UserPreferences_Serial_Baud_BAUD_600 = 14, - RadioConfig_UserPreferences_Serial_Baud_BAUD_1200 = 15 -} RadioConfig_UserPreferences_Serial_Baud; - -/* Defines the device's role on the Mesh network - unset - Behave normally. - Router - Functions as a router */ -typedef enum _RadioConfig_UserPreferences_Serial_Mode { - /* Client device role */ - RadioConfig_UserPreferences_Serial_Mode_MODE_Default = 0, - /* ClientMute device role - This is like the client but packets will not hop over this node. Would be - useful if you want to save power by not contributing to the mesh. */ - RadioConfig_UserPreferences_Serial_Mode_MODE_SIMPLE = 1, - /* Router device role. - Uses an agressive algirithem for the flood networking so packets will - prefer to be routed over this node. Also assume that this will be generally - unattended and so will turn off the wifi/ble radio as well as the oled screen. */ - RadioConfig_UserPreferences_Serial_Mode_MODE_PROTO = 2 -} RadioConfig_UserPreferences_Serial_Mode; - -/* Sets the charge control current of devices with a battery charger that can be - configured. This is passed into the axp power management chip like on the tbeam. */ -typedef enum _RadioConfig_UserPreferences_TelemetrySensorType { - /* TODO: REPLACE */ - RadioConfig_UserPreferences_TelemetrySensorType_None = 0, - /* TODO: REPLACE */ - RadioConfig_UserPreferences_TelemetrySensorType_DHT11 = 1, - /* TODO: REPLACE */ - RadioConfig_UserPreferences_TelemetrySensorType_DS18B20 = 2, - /* TODO: REPLACE */ - RadioConfig_UserPreferences_TelemetrySensorType_DHT12 = 3, - /* TODO: REPLACE */ - RadioConfig_UserPreferences_TelemetrySensorType_DHT21 = 4, - /* TODO: REPLACE */ - RadioConfig_UserPreferences_TelemetrySensorType_DHT22 = 5, - /* TODO: REPLACE */ - RadioConfig_UserPreferences_TelemetrySensorType_BME280 = 6, - /* TODO: REPLACE */ - RadioConfig_UserPreferences_TelemetrySensorType_BME680 = 7, - /* TODO: REPLACE */ - RadioConfig_UserPreferences_TelemetrySensorType_MCP9808 = 8, - /* TODO: REPLACE */ - RadioConfig_UserPreferences_TelemetrySensorType_SHTC3 = 9 -} RadioConfig_UserPreferences_TelemetrySensorType; - -/* Struct definitions */ -typedef struct _RadioConfig_UserPreferences { - uint32_t position_broadcast_secs; - uint32_t wait_bluetooth_secs; - uint32_t screen_on_secs; - uint32_t phone_timeout_secs; - uint32_t mesh_sds_timeout_secs; - uint32_t sds_secs; - uint32_t ls_secs; - uint32_t min_wake_secs; - char wifi_ssid[33]; - char wifi_password[64]; - bool wifi_ap_mode; - RegionCode region; - ChargeCurrent charge_current; - bool position_broadcast_smart_disabled; - Role role; - bool location_share_disabled; - bool gps_disabled; - uint32_t gps_update_interval; - uint32_t gps_attempt_time; - bool is_low_power; - bool fixed_position; - bool serial_disabled; - float frequency_offset; - char mqtt_server[32]; - bool mqtt_disabled; - GpsCoordinateFormat gps_format; - bool gps_accept_2d; - uint32_t gps_max_dop; - bool factory_reset; - bool debug_log_enabled; - pb_size_t ignore_incoming_count; - uint32_t ignore_incoming[3]; - bool serial_module_enabled; - bool serial_module_echo; - uint32_t serial_module_rxd; - uint32_t serial_module_txd; - uint32_t serial_module_timeout; - RadioConfig_UserPreferences_Serial_Mode serial_module_mode; - bool ext_notification_module_enabled; - uint32_t ext_notification_module_output_ms; - uint32_t ext_notification_module_output; - bool ext_notification_module_active; - bool ext_notification_module_alert_message; - bool ext_notification_module_alert_bell; - bool range_test_module_enabled; - uint32_t range_test_module_sender; - bool range_test_module_save; - uint32_t store_forward_module_records; - uint32_t store_forward_module_history_return_max; - uint32_t store_forward_module_history_return_window; - bool telemetry_module_environment_measurement_enabled; - bool telemetry_module_environment_screen_enabled; - uint32_t telemetry_module_environment_read_error_count_threshold; - uint32_t telemetry_module_device_update_interval; - uint32_t telemetry_module_environment_recovery_interval; - bool telemetry_module_environment_display_fahrenheit; - RadioConfig_UserPreferences_TelemetrySensorType telemetry_module_environment_sensor_type; - uint32_t telemetry_module_environment_sensor_pin; - bool store_forward_module_enabled; - bool store_forward_module_heartbeat; - uint32_t position_flags; - bool is_always_powered; - uint32_t auto_screen_carousel_secs; - uint32_t on_battery_shutdown_after_secs; - uint32_t hop_limit; - char mqtt_username[32]; - char mqtt_password[32]; - bool is_lora_tx_disabled; - bool is_power_saving; - bool rotary1_enabled; - uint32_t inputbroker_pin_a; - uint32_t inputbroker_pin_b; - uint32_t inputbroker_pin_press; - InputEventChar inputbroker_event_cw; - InputEventChar inputbroker_event_ccw; - InputEventChar inputbroker_event_press; - bool updown1_enabled; - bool canned_message_module_enabled; - char canned_message_module_allow_input_source[16]; - bool canned_message_module_send_bell; - bool mqtt_encryption_enabled; - float adc_multiplier_override; - RadioConfig_UserPreferences_Serial_Baud serial_module_baud; - uint32_t telemetry_module_environment_update_interval; -} RadioConfig_UserPreferences; - -/* The entire set of user settable/readable settings for our radio device. - Includes both the current channel settings and any preferences the user has - set for behavior of their node */ -typedef struct _RadioConfig { - /* TODO: REPLACE */ - bool has_preferences; - RadioConfig_UserPreferences preferences; -} RadioConfig; - - -/* Helper constants for enums */ -#define _RegionCode_MIN RegionCode_Unset -#define _RegionCode_MAX RegionCode_TH -#define _RegionCode_ARRAYSIZE ((RegionCode)(RegionCode_TH+1)) - -#define _Role_MIN Role_Client -#define _Role_MAX Role_RouterClient -#define _Role_ARRAYSIZE ((Role)(Role_RouterClient+1)) - -#define _ChargeCurrent_MIN ChargeCurrent_MAUnset -#define _ChargeCurrent_MAX ChargeCurrent_MA1320 -#define _ChargeCurrent_ARRAYSIZE ((ChargeCurrent)(ChargeCurrent_MA1320+1)) - -#define _GpsCoordinateFormat_MIN GpsCoordinateFormat_GpsFormatDec -#define _GpsCoordinateFormat_MAX GpsCoordinateFormat_GpsFormatOSGR -#define _GpsCoordinateFormat_ARRAYSIZE ((GpsCoordinateFormat)(GpsCoordinateFormat_GpsFormatOSGR+1)) - -#define _PositionFlags_MIN PositionFlags_POS_UNDEFINED -#define _PositionFlags_MAX PositionFlags_POS_TIMESTAMP -#define _PositionFlags_ARRAYSIZE ((PositionFlags)(PositionFlags_POS_TIMESTAMP+1)) - -#define _InputEventChar_MIN InputEventChar_KEY_NONE -#define _InputEventChar_MAX InputEventChar_KEY_BACK -#define _InputEventChar_ARRAYSIZE ((InputEventChar)(InputEventChar_KEY_BACK+1)) - -#define _RadioConfig_UserPreferences_Serial_Baud_MIN RadioConfig_UserPreferences_Serial_Baud_BAUD_Default -#define _RadioConfig_UserPreferences_Serial_Baud_MAX RadioConfig_UserPreferences_Serial_Baud_BAUD_1200 -#define _RadioConfig_UserPreferences_Serial_Baud_ARRAYSIZE ((RadioConfig_UserPreferences_Serial_Baud)(RadioConfig_UserPreferences_Serial_Baud_BAUD_1200+1)) - -#define _RadioConfig_UserPreferences_Serial_Mode_MIN RadioConfig_UserPreferences_Serial_Mode_MODE_Default -#define _RadioConfig_UserPreferences_Serial_Mode_MAX RadioConfig_UserPreferences_Serial_Mode_MODE_PROTO -#define _RadioConfig_UserPreferences_Serial_Mode_ARRAYSIZE ((RadioConfig_UserPreferences_Serial_Mode)(RadioConfig_UserPreferences_Serial_Mode_MODE_PROTO+1)) - -#define _RadioConfig_UserPreferences_TelemetrySensorType_MIN RadioConfig_UserPreferences_TelemetrySensorType_None -#define _RadioConfig_UserPreferences_TelemetrySensorType_MAX RadioConfig_UserPreferences_TelemetrySensorType_SHTC3 -#define _RadioConfig_UserPreferences_TelemetrySensorType_ARRAYSIZE ((RadioConfig_UserPreferences_TelemetrySensorType)(RadioConfig_UserPreferences_TelemetrySensorType_SHTC3+1)) - - -#ifdef __cplusplus -extern "C" { -#endif - -/* Initializer values for message structs */ -#define RadioConfig_init_default {false, RadioConfig_UserPreferences_init_default} -#define RadioConfig_UserPreferences_init_default {0, 0, 0, 0, 0, 0, 0, 0, "", "", 0, _RegionCode_MIN, _ChargeCurrent_MIN, 0, _Role_MIN, 0, 0, 0, 0, 0, 0, 0, 0, "", 0, _GpsCoordinateFormat_MIN, 0, 0, 0, 0, 0, {0, 0, 0}, 0, 0, 0, 0, 0, _RadioConfig_UserPreferences_Serial_Mode_MIN, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, _RadioConfig_UserPreferences_TelemetrySensorType_MIN, 0, 0, 0, 0, 0, 0, 0, 0, "", "", 0, 0, 0, 0, 0, 0, _InputEventChar_MIN, _InputEventChar_MIN, _InputEventChar_MIN, 0, 0, "", 0, 0, 0, _RadioConfig_UserPreferences_Serial_Baud_MIN, 0} -#define RadioConfig_init_zero {false, RadioConfig_UserPreferences_init_zero} -#define RadioConfig_UserPreferences_init_zero {0, 0, 0, 0, 0, 0, 0, 0, "", "", 0, _RegionCode_MIN, _ChargeCurrent_MIN, 0, _Role_MIN, 0, 0, 0, 0, 0, 0, 0, 0, "", 0, _GpsCoordinateFormat_MIN, 0, 0, 0, 0, 0, {0, 0, 0}, 0, 0, 0, 0, 0, _RadioConfig_UserPreferences_Serial_Mode_MIN, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, _RadioConfig_UserPreferences_TelemetrySensorType_MIN, 0, 0, 0, 0, 0, 0, 0, 0, "", "", 0, 0, 0, 0, 0, 0, _InputEventChar_MIN, _InputEventChar_MIN, _InputEventChar_MIN, 0, 0, "", 0, 0, 0, _RadioConfig_UserPreferences_Serial_Baud_MIN, 0} - -/* Field tags (for use in manual encoding/decoding) */ -#define RadioConfig_UserPreferences_position_broadcast_secs_tag 1 -#define RadioConfig_UserPreferences_wait_bluetooth_secs_tag 4 -#define RadioConfig_UserPreferences_screen_on_secs_tag 5 -#define RadioConfig_UserPreferences_phone_timeout_secs_tag 6 -#define RadioConfig_UserPreferences_mesh_sds_timeout_secs_tag 8 -#define RadioConfig_UserPreferences_sds_secs_tag 9 -#define RadioConfig_UserPreferences_ls_secs_tag 10 -#define RadioConfig_UserPreferences_min_wake_secs_tag 11 -#define RadioConfig_UserPreferences_wifi_ssid_tag 12 -#define RadioConfig_UserPreferences_wifi_password_tag 13 -#define RadioConfig_UserPreferences_wifi_ap_mode_tag 14 -#define RadioConfig_UserPreferences_region_tag 15 -#define RadioConfig_UserPreferences_charge_current_tag 16 -#define RadioConfig_UserPreferences_position_broadcast_smart_disabled_tag 17 -#define RadioConfig_UserPreferences_role_tag 18 -#define RadioConfig_UserPreferences_location_share_disabled_tag 32 -#define RadioConfig_UserPreferences_gps_disabled_tag 33 -#define RadioConfig_UserPreferences_gps_update_interval_tag 34 -#define RadioConfig_UserPreferences_gps_attempt_time_tag 36 -#define RadioConfig_UserPreferences_is_low_power_tag 38 -#define RadioConfig_UserPreferences_fixed_position_tag 39 -#define RadioConfig_UserPreferences_serial_disabled_tag 40 -#define RadioConfig_UserPreferences_frequency_offset_tag 41 -#define RadioConfig_UserPreferences_mqtt_server_tag 42 -#define RadioConfig_UserPreferences_mqtt_disabled_tag 43 -#define RadioConfig_UserPreferences_gps_format_tag 44 -#define RadioConfig_UserPreferences_gps_accept_2d_tag 45 -#define RadioConfig_UserPreferences_gps_max_dop_tag 46 -#define RadioConfig_UserPreferences_factory_reset_tag 100 -#define RadioConfig_UserPreferences_debug_log_enabled_tag 101 -#define RadioConfig_UserPreferences_ignore_incoming_tag 103 -#define RadioConfig_UserPreferences_serial_module_enabled_tag 120 -#define RadioConfig_UserPreferences_serial_module_echo_tag 121 -#define RadioConfig_UserPreferences_serial_module_rxd_tag 122 -#define RadioConfig_UserPreferences_serial_module_txd_tag 123 -#define RadioConfig_UserPreferences_serial_module_timeout_tag 124 -#define RadioConfig_UserPreferences_serial_module_mode_tag 125 -#define RadioConfig_UserPreferences_ext_notification_module_enabled_tag 126 -#define RadioConfig_UserPreferences_ext_notification_module_output_ms_tag 127 -#define RadioConfig_UserPreferences_ext_notification_module_output_tag 128 -#define RadioConfig_UserPreferences_ext_notification_module_active_tag 129 -#define RadioConfig_UserPreferences_ext_notification_module_alert_message_tag 130 -#define RadioConfig_UserPreferences_ext_notification_module_alert_bell_tag 131 -#define RadioConfig_UserPreferences_range_test_module_enabled_tag 132 -#define RadioConfig_UserPreferences_range_test_module_sender_tag 133 -#define RadioConfig_UserPreferences_range_test_module_save_tag 134 -#define RadioConfig_UserPreferences_store_forward_module_records_tag 137 -#define RadioConfig_UserPreferences_store_forward_module_history_return_max_tag 138 -#define RadioConfig_UserPreferences_store_forward_module_history_return_window_tag 139 -#define RadioConfig_UserPreferences_telemetry_module_environment_measurement_enabled_tag 140 -#define RadioConfig_UserPreferences_telemetry_module_environment_screen_enabled_tag 141 -#define RadioConfig_UserPreferences_telemetry_module_environment_read_error_count_threshold_tag 142 -#define RadioConfig_UserPreferences_telemetry_module_device_update_interval_tag 143 -#define RadioConfig_UserPreferences_telemetry_module_environment_recovery_interval_tag 144 -#define RadioConfig_UserPreferences_telemetry_module_environment_display_fahrenheit_tag 145 -#define RadioConfig_UserPreferences_telemetry_module_environment_sensor_type_tag 146 -#define RadioConfig_UserPreferences_telemetry_module_environment_sensor_pin_tag 147 -#define RadioConfig_UserPreferences_store_forward_module_enabled_tag 148 -#define RadioConfig_UserPreferences_store_forward_module_heartbeat_tag 149 -#define RadioConfig_UserPreferences_position_flags_tag 150 -#define RadioConfig_UserPreferences_is_always_powered_tag 151 -#define RadioConfig_UserPreferences_auto_screen_carousel_secs_tag 152 -#define RadioConfig_UserPreferences_on_battery_shutdown_after_secs_tag 153 -#define RadioConfig_UserPreferences_hop_limit_tag 154 -#define RadioConfig_UserPreferences_mqtt_username_tag 155 -#define RadioConfig_UserPreferences_mqtt_password_tag 156 -#define RadioConfig_UserPreferences_is_lora_tx_disabled_tag 157 -#define RadioConfig_UserPreferences_is_power_saving_tag 158 -#define RadioConfig_UserPreferences_rotary1_enabled_tag 160 -#define RadioConfig_UserPreferences_inputbroker_pin_a_tag 161 -#define RadioConfig_UserPreferences_inputbroker_pin_b_tag 162 -#define RadioConfig_UserPreferences_inputbroker_pin_press_tag 163 -#define RadioConfig_UserPreferences_inputbroker_event_cw_tag 164 -#define RadioConfig_UserPreferences_inputbroker_event_ccw_tag 165 -#define RadioConfig_UserPreferences_inputbroker_event_press_tag 166 -#define RadioConfig_UserPreferences_updown1_enabled_tag 167 -#define RadioConfig_UserPreferences_canned_message_module_enabled_tag 170 -#define RadioConfig_UserPreferences_canned_message_module_allow_input_source_tag 171 -#define RadioConfig_UserPreferences_canned_message_module_send_bell_tag 173 -#define RadioConfig_UserPreferences_mqtt_encryption_enabled_tag 174 -#define RadioConfig_UserPreferences_adc_multiplier_override_tag 175 -#define RadioConfig_UserPreferences_serial_module_baud_tag 176 -#define RadioConfig_UserPreferences_telemetry_module_environment_update_interval_tag 177 -#define RadioConfig_preferences_tag 1 - -/* Struct field encoding specification for nanopb */ -#define RadioConfig_FIELDLIST(X, a) \ -X(a, STATIC, OPTIONAL, MESSAGE, preferences, 1) -#define RadioConfig_CALLBACK NULL -#define RadioConfig_DEFAULT NULL -#define RadioConfig_preferences_MSGTYPE RadioConfig_UserPreferences - -#define RadioConfig_UserPreferences_FIELDLIST(X, a) \ -X(a, STATIC, SINGULAR, UINT32, position_broadcast_secs, 1) \ -X(a, STATIC, SINGULAR, UINT32, wait_bluetooth_secs, 4) \ -X(a, STATIC, SINGULAR, UINT32, screen_on_secs, 5) \ -X(a, STATIC, SINGULAR, UINT32, phone_timeout_secs, 6) \ -X(a, STATIC, SINGULAR, UINT32, mesh_sds_timeout_secs, 8) \ -X(a, STATIC, SINGULAR, UINT32, sds_secs, 9) \ -X(a, STATIC, SINGULAR, UINT32, ls_secs, 10) \ -X(a, STATIC, SINGULAR, UINT32, min_wake_secs, 11) \ -X(a, STATIC, SINGULAR, STRING, wifi_ssid, 12) \ -X(a, STATIC, SINGULAR, STRING, wifi_password, 13) \ -X(a, STATIC, SINGULAR, BOOL, wifi_ap_mode, 14) \ -X(a, STATIC, SINGULAR, UENUM, region, 15) \ -X(a, STATIC, SINGULAR, UENUM, charge_current, 16) \ -X(a, STATIC, SINGULAR, BOOL, position_broadcast_smart_disabled, 17) \ -X(a, STATIC, SINGULAR, UENUM, role, 18) \ -X(a, STATIC, SINGULAR, BOOL, location_share_disabled, 32) \ -X(a, STATIC, SINGULAR, BOOL, gps_disabled, 33) \ -X(a, STATIC, SINGULAR, UINT32, gps_update_interval, 34) \ -X(a, STATIC, SINGULAR, UINT32, gps_attempt_time, 36) \ -X(a, STATIC, SINGULAR, BOOL, is_low_power, 38) \ -X(a, STATIC, SINGULAR, BOOL, fixed_position, 39) \ -X(a, STATIC, SINGULAR, BOOL, serial_disabled, 40) \ -X(a, STATIC, SINGULAR, FLOAT, frequency_offset, 41) \ -X(a, STATIC, SINGULAR, STRING, mqtt_server, 42) \ -X(a, STATIC, SINGULAR, BOOL, mqtt_disabled, 43) \ -X(a, STATIC, SINGULAR, UENUM, gps_format, 44) \ -X(a, STATIC, SINGULAR, BOOL, gps_accept_2d, 45) \ -X(a, STATIC, SINGULAR, UINT32, gps_max_dop, 46) \ -X(a, STATIC, SINGULAR, BOOL, factory_reset, 100) \ -X(a, STATIC, SINGULAR, BOOL, debug_log_enabled, 101) \ -X(a, STATIC, REPEATED, UINT32, ignore_incoming, 103) \ -X(a, STATIC, SINGULAR, BOOL, serial_module_enabled, 120) \ -X(a, STATIC, SINGULAR, BOOL, serial_module_echo, 121) \ -X(a, STATIC, SINGULAR, UINT32, serial_module_rxd, 122) \ -X(a, STATIC, SINGULAR, UINT32, serial_module_txd, 123) \ -X(a, STATIC, SINGULAR, UINT32, serial_module_timeout, 124) \ -X(a, STATIC, SINGULAR, UENUM, serial_module_mode, 125) \ -X(a, STATIC, SINGULAR, BOOL, ext_notification_module_enabled, 126) \ -X(a, STATIC, SINGULAR, UINT32, ext_notification_module_output_ms, 127) \ -X(a, STATIC, SINGULAR, UINT32, ext_notification_module_output, 128) \ -X(a, STATIC, SINGULAR, BOOL, ext_notification_module_active, 129) \ -X(a, STATIC, SINGULAR, BOOL, ext_notification_module_alert_message, 130) \ -X(a, STATIC, SINGULAR, BOOL, ext_notification_module_alert_bell, 131) \ -X(a, STATIC, SINGULAR, BOOL, range_test_module_enabled, 132) \ -X(a, STATIC, SINGULAR, UINT32, range_test_module_sender, 133) \ -X(a, STATIC, SINGULAR, BOOL, range_test_module_save, 134) \ -X(a, STATIC, SINGULAR, UINT32, store_forward_module_records, 137) \ -X(a, STATIC, SINGULAR, UINT32, store_forward_module_history_return_max, 138) \ -X(a, STATIC, SINGULAR, UINT32, store_forward_module_history_return_window, 139) \ -X(a, STATIC, SINGULAR, BOOL, telemetry_module_environment_measurement_enabled, 140) \ -X(a, STATIC, SINGULAR, BOOL, telemetry_module_environment_screen_enabled, 141) \ -X(a, STATIC, SINGULAR, UINT32, telemetry_module_environment_read_error_count_threshold, 142) \ -X(a, STATIC, SINGULAR, UINT32, telemetry_module_device_update_interval, 143) \ -X(a, STATIC, SINGULAR, UINT32, telemetry_module_environment_recovery_interval, 144) \ -X(a, STATIC, SINGULAR, BOOL, telemetry_module_environment_display_fahrenheit, 145) \ -X(a, STATIC, SINGULAR, UENUM, telemetry_module_environment_sensor_type, 146) \ -X(a, STATIC, SINGULAR, UINT32, telemetry_module_environment_sensor_pin, 147) \ -X(a, STATIC, SINGULAR, BOOL, store_forward_module_enabled, 148) \ -X(a, STATIC, SINGULAR, BOOL, store_forward_module_heartbeat, 149) \ -X(a, STATIC, SINGULAR, UINT32, position_flags, 150) \ -X(a, STATIC, SINGULAR, BOOL, is_always_powered, 151) \ -X(a, STATIC, SINGULAR, UINT32, auto_screen_carousel_secs, 152) \ -X(a, STATIC, SINGULAR, UINT32, on_battery_shutdown_after_secs, 153) \ -X(a, STATIC, SINGULAR, UINT32, hop_limit, 154) \ -X(a, STATIC, SINGULAR, STRING, mqtt_username, 155) \ -X(a, STATIC, SINGULAR, STRING, mqtt_password, 156) \ -X(a, STATIC, SINGULAR, BOOL, is_lora_tx_disabled, 157) \ -X(a, STATIC, SINGULAR, BOOL, is_power_saving, 158) \ -X(a, STATIC, SINGULAR, BOOL, rotary1_enabled, 160) \ -X(a, STATIC, SINGULAR, UINT32, inputbroker_pin_a, 161) \ -X(a, STATIC, SINGULAR, UINT32, inputbroker_pin_b, 162) \ -X(a, STATIC, SINGULAR, UINT32, inputbroker_pin_press, 163) \ -X(a, STATIC, SINGULAR, UENUM, inputbroker_event_cw, 164) \ -X(a, STATIC, SINGULAR, UENUM, inputbroker_event_ccw, 165) \ -X(a, STATIC, SINGULAR, UENUM, inputbroker_event_press, 166) \ -X(a, STATIC, SINGULAR, BOOL, updown1_enabled, 167) \ -X(a, STATIC, SINGULAR, BOOL, canned_message_module_enabled, 170) \ -X(a, STATIC, SINGULAR, STRING, canned_message_module_allow_input_source, 171) \ -X(a, STATIC, SINGULAR, BOOL, canned_message_module_send_bell, 173) \ -X(a, STATIC, SINGULAR, BOOL, mqtt_encryption_enabled, 174) \ -X(a, STATIC, SINGULAR, FLOAT, adc_multiplier_override, 175) \ -X(a, STATIC, SINGULAR, UENUM, serial_module_baud, 176) \ -X(a, STATIC, SINGULAR, UINT32, telemetry_module_environment_update_interval, 177) -#define RadioConfig_UserPreferences_CALLBACK NULL -#define RadioConfig_UserPreferences_DEFAULT NULL - -extern const pb_msgdesc_t RadioConfig_msg; -extern const pb_msgdesc_t RadioConfig_UserPreferences_msg; - -/* Defines for backwards compatibility with code written before nanopb-0.4.0 */ -#define RadioConfig_fields &RadioConfig_msg -#define RadioConfig_UserPreferences_fields &RadioConfig_UserPreferences_msg - -/* Maximum encoded size of messages (where known) */ -#define RadioConfig_UserPreferences_size 592 -#define RadioConfig_size 595 - -#ifdef __cplusplus -} /* extern "C" */ -#endif - -#endif diff --git a/src/mesh/generated/telemetry.pb.c b/src/mesh/generated/telemetry.pb.c index 674a2f84d..a2d812cad 100644 --- a/src/mesh/generated/telemetry.pb.c +++ b/src/mesh/generated/telemetry.pb.c @@ -16,3 +16,4 @@ PB_BIND(Telemetry, Telemetry, AUTO) + diff --git a/src/mesh/generated/telemetry.pb.h b/src/mesh/generated/telemetry.pb.h index b3bf3df1d..6c9db655c 100644 --- a/src/mesh/generated/telemetry.pb.h +++ b/src/mesh/generated/telemetry.pb.h @@ -9,6 +9,31 @@ #error Regenerate this file with the current version of nanopb generator. #endif +/* Enum definitions */ +/* TODO: REPLACE */ +typedef enum _TelemetrySensorType { + /* No external telemetry sensor */ + TelemetrySensorType_NotSet = 0, + /* TODO: REPLACE */ + TelemetrySensorType_DHT11 = 1, + /* TODO: REPLACE */ + TelemetrySensorType_DS18B20 = 2, + /* TODO: REPLACE */ + TelemetrySensorType_DHT12 = 3, + /* TODO: REPLACE */ + TelemetrySensorType_DHT21 = 4, + /* TODO: REPLACE */ + TelemetrySensorType_DHT22 = 5, + /* TODO: REPLACE */ + TelemetrySensorType_BME280 = 6, + /* TODO: REPLACE */ + TelemetrySensorType_BME680 = 7, + /* TODO: REPLACE */ + TelemetrySensorType_MCP9808 = 8, + /* TODO: REPLACE */ + TelemetrySensorType_SHTC3 = 9 +} TelemetrySensorType; + /* Struct definitions */ /* Key native device metrics such as battery level */ typedef struct _DeviceMetrics { @@ -55,6 +80,12 @@ typedef struct _Telemetry { } Telemetry; +/* Helper constants for enums */ +#define _TelemetrySensorType_MIN TelemetrySensorType_NotSet +#define _TelemetrySensorType_MAX TelemetrySensorType_SHTC3 +#define _TelemetrySensorType_ARRAYSIZE ((TelemetrySensorType)(TelemetrySensorType_SHTC3+1)) + + #ifdef __cplusplus extern "C" { #endif diff --git a/src/mesh/http/ContentHandler.cpp b/src/mesh/http/ContentHandler.cpp index ba78b4ea5..c451afe91 100644 --- a/src/mesh/http/ContentHandler.cpp +++ b/src/mesh/http/ContentHandler.cpp @@ -67,8 +67,6 @@ char contentTypes[][2][32] = {{".txt", "text/plain"}, {".html", "text/html"} // Our API to handle messages to and from the radio. HttpAPI webAPI; - - void registerHandlers(HTTPServer *insecureServer, HTTPSServer *secureServer) { @@ -85,9 +83,9 @@ void registerHandlers(HTTPServer *insecureServer, HTTPSServer *secureServer) ResourceNode *nodeAdmin = new ResourceNode("/admin", "GET", &handleAdmin); ResourceNode *nodeAdminSettings = new ResourceNode("/admin/settings", "GET", &handleAdminSettings); ResourceNode *nodeAdminSettingsApply = new ResourceNode("/admin/settings/apply", "POST", &handleAdminSettingsApply); -// ResourceNode *nodeAdminFs = new ResourceNode("/admin/fs", "GET", &handleFs); -// ResourceNode *nodeUpdateFs = new ResourceNode("/admin/fs/update", "POST", &handleUpdateFs); -// ResourceNode *nodeDeleteFs = new ResourceNode("/admin/fs/delete", "GET", &handleDeleteFsContent); + // ResourceNode *nodeAdminFs = new ResourceNode("/admin/fs", "GET", &handleFs); + // ResourceNode *nodeUpdateFs = new ResourceNode("/admin/fs/update", "POST", &handleUpdateFs); + // ResourceNode *nodeDeleteFs = new ResourceNode("/admin/fs/delete", "GET", &handleDeleteFsContent); ResourceNode *nodeRestart = new ResourceNode("/restart", "POST", &handleRestart); ResourceNode *nodeFormUpload = new ResourceNode("/upload", "POST", &handleFormUpload); @@ -98,7 +96,6 @@ void registerHandlers(HTTPServer *insecureServer, HTTPSServer *secureServer) ResourceNode *nodeJsonFsBrowseStatic = new ResourceNode("/json/fs/browse/static", "GET", &handleFsBrowseStatic); ResourceNode *nodeJsonDelete = new ResourceNode("/json/fs/delete/static", "DELETE", &handleFsDeleteStatic); - ResourceNode *nodeRoot = new ResourceNode("/*", "GET", &handleStatic); // Secure nodes @@ -114,10 +111,10 @@ void registerHandlers(HTTPServer *insecureServer, HTTPSServer *secureServer) secureServer->registerNode(nodeJsonFsBrowseStatic); secureServer->registerNode(nodeJsonDelete); secureServer->registerNode(nodeJsonReport); -// secureServer->registerNode(nodeUpdateFs); -// secureServer->registerNode(nodeDeleteFs); + // secureServer->registerNode(nodeUpdateFs); + // secureServer->registerNode(nodeDeleteFs); secureServer->registerNode(nodeAdmin); -// secureServer->registerNode(nodeAdminFs); + // secureServer->registerNode(nodeAdminFs); secureServer->registerNode(nodeAdminSettings); secureServer->registerNode(nodeAdminSettingsApply); secureServer->registerNode(nodeRoot); // This has to be last @@ -135,10 +132,10 @@ void registerHandlers(HTTPServer *insecureServer, HTTPSServer *secureServer) insecureServer->registerNode(nodeJsonFsBrowseStatic); insecureServer->registerNode(nodeJsonDelete); insecureServer->registerNode(nodeJsonReport); -// insecureServer->registerNode(nodeUpdateFs); -// insecureServer->registerNode(nodeDeleteFs); + // insecureServer->registerNode(nodeUpdateFs); + // insecureServer->registerNode(nodeDeleteFs); insecureServer->registerNode(nodeAdmin); -// insecureServer->registerNode(nodeAdminFs); + // insecureServer->registerNode(nodeAdminFs); insecureServer->registerNode(nodeAdminSettings); insecureServer->registerNode(nodeAdminSettingsApply); insecureServer->registerNode(nodeRoot); // This has to be last @@ -227,19 +224,19 @@ void handleAPIv1ToRadio(HTTPRequest *req, HTTPResponse *res) DEBUG_MSG("webAPI handleAPIv1ToRadio\n"); } -void htmlDeleteDir(const char * dirname) +void htmlDeleteDir(const char *dirname) { File root = FSCom.open(dirname); - if(!root){ + if (!root) { return; } - if(!root.isDirectory()){ + if (!root.isDirectory()) { return; } File file = root.openNextFile(); - while(file){ - if(file.isDirectory() && !String(file.name()).endsWith(".")) { + while (file) { + if (file.isDirectory() && !String(file.name()).endsWith(".")) { htmlDeleteDir(file.name()); file.close(); } else { @@ -247,32 +244,32 @@ void htmlDeleteDir(const char * dirname) file.close(); DEBUG_MSG(" %s\n", fileName.c_str()); FSCom.remove(fileName); - } file = root.openNextFile(); } root.close(); } -std::vector>* htmlListDir(std::vector> *fileList, const char *dirname, uint8_t levels) +std::vector> *htmlListDir(std::vector> *fileList, const char *dirname, + uint8_t levels) { File root = FSCom.open(dirname); - if(!root){ + if (!root) { return NULL; } - if(!root.isDirectory()){ + if (!root.isDirectory()) { return NULL; } // iterate over the file list File file = root.openNextFile(); - while(file){ - if(file.isDirectory() && !String(file.name()).endsWith(".")) { - if(levels){ - htmlListDir(fileList, file.name(), levels -1); + while (file) { + if (file.isDirectory() && !String(file.name()).endsWith(".")) { + if (levels) { + htmlListDir(fileList, file.name(), levels - 1); } - } else { - std::map thisFileMap; + } else { + std::map thisFileMap; thisFileMap[strdup("size")] = strdup(String(file.size()).c_str()); thisFileMap[strdup("name")] = strdup(String(file.name()).substring(1).c_str()); if (String(file.name()).substring(1).endsWith(".gz")) { @@ -305,9 +302,7 @@ void handleFsBrowseStatic(HTTPRequest *req, HTTPResponse *res) {"free", String(FSCom.totalBytes() - FSCom.usedBytes()).c_str()}, }; - Json jsonObjInner = Json::object{{"files", Json(*fileList)}, - {"filesystem", filesystemObj} - }; + Json jsonObjInner = Json::object{{"files", Json(*fileList)}, {"filesystem", filesystemObj}}; Json jsonObjOuter = Json::object{{"data", jsonObjInner}, {"status", "ok"}}; @@ -365,7 +360,7 @@ void handleStatic(HTTPRequest *req, HTTPResponse *res) filename = "/static/index.html"; filenameGzip = "/static/index.html.gz"; } - + if (FSCom.exists(filename.c_str())) { file = FSCom.open(filename.c_str()); if (!file.available()) { @@ -615,31 +610,28 @@ void handleReport(HTTPRequest *req, HTTPResponse *res) // data->wifi String ipStr; - if (radioConfig.preferences.wifi_ap_mode || isSoftAPForced()) { + if (config.wifi.ap_mode || isSoftAPForced()) { ipStr = String(WiFi.softAPIP().toString()); } else { ipStr = String(WiFi.localIP().toString()); } - Json jsonObjWifi = Json::object{ - {"rssi", String(WiFi.RSSI())}, - {"ip", ipStr.c_str()} - }; + Json jsonObjWifi = Json::object{{"rssi", String(WiFi.RSSI())}, {"ip", ipStr.c_str()}}; // data->memory Json jsonObjMemory = Json::object{{"heap_total", Json(int(ESP.getHeapSize()))}, - {"heap_free", Json(int(ESP.getFreeHeap()))}, - {"psram_total", Json(int(ESP.getPsramSize()))}, - {"psram_free", Json(int(ESP.getFreePsram()))}, - {"fs_total", String(FSCom.totalBytes()).c_str()}, - {"fs_used", String(FSCom.usedBytes()).c_str()}, - {"fs_free", String(FSCom.totalBytes() - FSCom.usedBytes()).c_str()}}; + {"heap_free", Json(int(ESP.getFreeHeap()))}, + {"psram_total", Json(int(ESP.getPsramSize()))}, + {"psram_free", Json(int(ESP.getFreePsram()))}, + {"fs_total", String(FSCom.totalBytes()).c_str()}, + {"fs_used", String(FSCom.usedBytes()).c_str()}, + {"fs_free", String(FSCom.totalBytes() - FSCom.usedBytes()).c_str()}}; // data->power Json jsonObjPower = Json::object{{"battery_percent", Json(powerStatus->getBatteryChargePercent())}, - {"battery_voltage_mv", Json(powerStatus->getBatteryVoltageMv())}, - {"has_battery", BoolToString(powerStatus->getHasBattery())}, - {"has_usb", BoolToString(powerStatus->getHasUSB())}, - {"is_charging", BoolToString(powerStatus->getIsCharging())}}; + {"battery_voltage_mv", Json(powerStatus->getBatteryVoltageMv())}, + {"has_battery", BoolToString(powerStatus->getHasBattery())}, + {"has_usb", BoolToString(powerStatus->getHasUSB())}, + {"is_charging", BoolToString(powerStatus->getIsCharging())}}; // data->device Json jsonObjDevice = Json::object{{"reboot_counter", Json(int(myNodeInfo.reboot_count))}}; @@ -681,7 +673,6 @@ void handleHotspot(HTTPRequest *req, HTTPResponse *res) res->println("\n"); } - void handleDeleteFsContent(HTTPRequest *req, HTTPResponse *res) { res->setHeader("Content-Type", "text/html"); @@ -723,7 +714,8 @@ void handleAdminSettings(HTTPRequest *req, HTTPResponse *res) res->println("Set?Settingcurrent valuenew value\n"); res->println("WiFi SSIDfalse\n"); res->println("WiFi Passwordfalse\n"); - res->println("Smart Position Updatefalse\n"); + res->println( + "Smart Position Updatefalse\n"); res->println("is_always_poweredfalse\n"); res->println("is_always_poweredfalse\n"); res->println("\n"); @@ -745,7 +737,6 @@ void handleAdminSettingsApply(HTTPRequest *req, HTTPResponse *res) res->println("Settings Applied. Please wait.\n"); } - void handleFs(HTTPRequest *req, HTTPResponse *res) { res->setHeader("Content-Type", "text/html"); @@ -798,7 +789,9 @@ void handleBlinkLED(HTTPRequest *req, HTTPResponse *res) count = count - 1; } } else { +#ifndef NO_SCREEN screen->blink(); +#endif } Json jsonObjOuter = Json::object{{"status", "ok"}}; diff --git a/src/mesh/http/WebServer.cpp b/src/mesh/http/WebServer.cpp index 1f376390b..271adc6c2 100644 --- a/src/mesh/http/WebServer.cpp +++ b/src/mesh/http/WebServer.cpp @@ -152,10 +152,11 @@ void createSSLCert() yield(); esp_task_wdt_reset(); - +#ifndef NO_SCREEN if (millis() / 1000 >= 3) { screen->setSSLFrames(); } +#endif } runLoop = false; } else { diff --git a/src/mesh/http/WiFiAPClient.cpp b/src/mesh/http/WiFiAPClient.cpp index be07acc53..85f8d2a99 100644 --- a/src/mesh/http/WiFiAPClient.cpp +++ b/src/mesh/http/WiFiAPClient.cpp @@ -28,7 +28,7 @@ DNSServer dnsServer; WiFiUDP ntpUDP; #ifndef DISABLE_NTP -NTPClient timeClient(ntpUDP, "0.pool.ntp.org"); +NTPClient timeClient(ntpUDP, config.device.ntp_server); #endif uint8_t wifiDisconnectReason = 0; @@ -59,10 +59,11 @@ static WifiSleepObserver wifiSleepObserver; static int32_t reconnectWiFi() { - const char *wifiName = radioConfig.preferences.wifi_ssid; - const char *wifiPsw = radioConfig.preferences.wifi_password; + const char *wifiName = config.wifi.ssid; + const char *wifiPsw = config.wifi.psk; - if (radioConfig.has_preferences && needReconnect && !WiFi.isConnected()) { + if (needReconnect && !WiFi.isConnected()) { + // if (radioConfig.has_preferences && needReconnect && !WiFi.isConnected()) { if (!*wifiPsw) // Treat empty password as no password wifiPsw = NULL; @@ -79,7 +80,6 @@ static int32_t reconnectWiFi() } #ifndef DISABLE_NTP - // if (*wifiName) { if (WiFi.isConnected()) { DEBUG_MSG("Updating NTP time\n"); if (timeClient.update()) { @@ -97,7 +97,7 @@ static int32_t reconnectWiFi() } #endif - return 30 * 1000; // every 30 seconds + return 43200 * 1000; // every 12 hours } static Periodic *wifiReconnect; @@ -114,7 +114,7 @@ bool isWifiAvailable() return true; } - const char *wifiName = radioConfig.preferences.wifi_ssid; + const char *wifiName = config.wifi.ssid; if (*wifiName) { return true; @@ -184,16 +184,14 @@ bool initWifi(bool forceSoftAP) { forcedSoftAP = forceSoftAP; - // strcpy(radioConfig.preferences.wifi_ssid, "meshtastic"); - // strcpy(radioConfig.preferences.wifi_password, "meshtastic!"); - - if ((radioConfig.has_preferences && radioConfig.preferences.wifi_ssid[0]) || forceSoftAP) { - const char *wifiName = radioConfig.preferences.wifi_ssid; - const char *wifiPsw = radioConfig.preferences.wifi_password; + if ((config.wifi.ssid[0]) || forceSoftAP) { + // if ((radioConfig.has_preferences && config.wifi.ssid[0]) || forceSoftAP) { + const char *wifiName = config.wifi.ssid; + const char *wifiPsw = config.wifi.psk; if (forceSoftAP) { DEBUG_MSG("WiFi ... Forced AP Mode\n"); - } else if (radioConfig.preferences.wifi_ap_mode) { + } else if (config.wifi.ap_mode) { DEBUG_MSG("WiFi ... AP Mode\n"); } else { DEBUG_MSG("WiFi ... Client Mode\n"); @@ -205,7 +203,7 @@ bool initWifi(bool forceSoftAP) wifiPsw = NULL; if (*wifiName || forceSoftAP) { - if (radioConfig.preferences.wifi_ap_mode || forceSoftAP) { + if (config.wifi.ap_mode || forceSoftAP) { IPAddress apIP(192, 168, 42, 1); WiFi.onEvent(WiFiEvent); @@ -218,6 +216,17 @@ bool initWifi(bool forceSoftAP) DEBUG_MSG("Starting (Forced) WIFI AP: ssid=%s, ok=%d\n", softAPssid, ok); } else { + + // If AP is configured to be hidden hidden + if (config.wifi.ap_hidden) { + + // The configurations on softAP are from the espresif library + int ok = WiFi.softAP(wifiName, wifiPsw, 1, 1, 4); + DEBUG_MSG("Starting hiddem WIFI AP: ssid=%s, ok=%d\n", wifiName, ok); + } else { + int ok = WiFi.softAP(wifiName, wifiPsw); + DEBUG_MSG("Starting WIFI AP: ssid=%s, ok=%d\n", wifiName, ok); + } int ok = WiFi.softAP(wifiName, wifiPsw); DEBUG_MSG("Starting WIFI AP: ssid=%s, ok=%d\n", wifiName, ok); } @@ -364,7 +373,7 @@ static void WiFiEvent(WiFiEvent_t event) void handleDNSResponse() { - if (radioConfig.preferences.wifi_ap_mode || isSoftAPForced()) { + if (config.wifi.ap_mode || isSoftAPForced()) { dnsServer.processNextRequest(); } } diff --git a/src/modules/AdminModule.cpp b/src/modules/AdminModule.cpp index 32f89da2f..decce0291 100644 --- a/src/modules/AdminModule.cpp +++ b/src/modules/AdminModule.cpp @@ -1,9 +1,9 @@ -#include "configuration.h" #include "AdminModule.h" #include "Channels.h" #include "MeshService.h" #include "NodeDB.h" #include "Router.h" +#include "configuration.h" #include "main.h" #ifdef PORTDUINO @@ -13,89 +13,57 @@ AdminModule *adminModule; /// A special reserved string to indicate strings we can not share with external nodes. We will use this 'reserved' word instead. -/// Also, to make setting work correctly, if someone tries to set a string to this reserved value we assume they don't really want a change. +/// Also, to make setting work correctly, if someone tries to set a string to this reserved value we assume they don't really want +/// a change. static const char *secretReserved = "sekrit"; /// If buf is !empty, change it to secret -static void hideSecret(char *buf) { - if(*buf) { +static void hideSecret(char *buf) +{ + if (*buf) { strcpy(buf, secretReserved); } } /// If buf is the reserved secret word, replace the buffer with currentVal -static void writeSecret(char *buf, const char *currentVal) { - if(strcmp(buf, secretReserved) == 0) { +static void writeSecret(char *buf, const char *currentVal) +{ + if (strcmp(buf, secretReserved) == 0) { strcpy(buf, currentVal); } } -void AdminModule::handleGetChannel(const MeshPacket &req, uint32_t channelIndex) -{ - if (req.decoded.want_response) { - // We create the reply here - AdminMessage r = AdminMessage_init_default; - r.get_channel_response = channels.getByIndex(channelIndex); - r.which_variant = AdminMessage_get_channel_response_tag; - myReply = allocDataProtobuf(r); - } -} - -void AdminModule::handleGetRadio(const MeshPacket &req) -{ - if (req.decoded.want_response) { - // We create the reply here - AdminMessage r = AdminMessage_init_default; - r.get_radio_response = radioConfig; - - // NOTE: The phone app needs to know the ls_secs & phone_timeout value so it can properly expect sleep behavior. - // So even if we internally use 0 to represent 'use default' we still need to send the value we are - // using to the app (so that even old phone apps work with new device loads). - r.get_radio_response.preferences.ls_secs = getPref_ls_secs(); - r.get_radio_response.preferences.phone_timeout_secs = getPref_phone_timeout_secs(); - // hideSecret(r.get_radio_response.preferences.wifi_ssid); // hmm - leave public for now, because only minimally private and useful for users to know current provisioning) - hideSecret(r.get_radio_response.preferences.wifi_password); - - r.which_variant = AdminMessage_get_radio_response_tag; - myReply = allocDataProtobuf(r); - } -} - -void AdminModule::handleGetOwner(const MeshPacket &req) -{ - if (req.decoded.want_response) { - // We create the reply here - AdminMessage r = AdminMessage_init_default; - r.get_owner_response = owner; - - r.which_variant = AdminMessage_get_owner_response_tag; - myReply = allocDataProtobuf(r); - } -} - +/** + * @brief Handle recieved protobuf message + * + * @param mp Recieved MeshPacket + * @param r Decoded AdminMessage + * @return bool + */ bool AdminModule::handleReceivedProtobuf(const MeshPacket &mp, AdminMessage *r) { // if handled == false, then let others look at this message also if they want bool handled = false; - assert(r); + switch (r->which_variant) { - case AdminMessage_set_owner_tag: - DEBUG_MSG("Client is setting owner\n"); - handleSetOwner(r->set_owner); + + /** + * Getters + */ + case AdminMessage_get_owner_request_tag: + DEBUG_MSG("Client is getting owner\n"); + handleGetOwner(mp); break; - case AdminMessage_set_radio_tag: - DEBUG_MSG("Client is setting radio\n"); - handleSetRadio(r->set_radio); + case AdminMessage_get_config_request_tag: + DEBUG_MSG("Client is getting config\n"); + handleGetConfig(mp, r->get_channel_request); break; - case AdminMessage_set_channel_tag: - DEBUG_MSG("Client is setting channel %d\n", r->set_channel.index); - if (r->set_channel.index < 0 || r->set_channel.index >= (int)MAX_NUM_CHANNELS) - myReply = allocErrorResponse(Routing_Error_BAD_REQUEST, &mp); - else - handleSetChannel(r->set_channel); + case AdminMessage_get_module_config_request_tag: + DEBUG_MSG("Client is getting module config\n"); + handleGetModuleConfig(mp, r->get_module_config_request); break; case AdminMessage_get_channel_request_tag: { @@ -108,16 +76,35 @@ bool AdminModule::handleReceivedProtobuf(const MeshPacket &mp, AdminMessage *r) break; } - case AdminMessage_get_radio_request_tag: - DEBUG_MSG("Client is getting radio\n"); - handleGetRadio(mp); + /** + * Setters + */ + case AdminMessage_set_owner_tag: + DEBUG_MSG("Client is setting owner\n"); + handleSetOwner(r->set_owner); break; - case AdminMessage_get_owner_request_tag: - DEBUG_MSG("Client is getting owner\n"); - handleGetOwner(mp); + case AdminMessage_set_config_tag: + DEBUG_MSG("Client is setting the config\n"); + handleSetConfig(r->set_config); break; + case AdminMessage_set_module_config_tag: + DEBUG_MSG("Client is setting the module config\n"); + handleSetModuleConfig(r->set_module_config); + break; + + case AdminMessage_set_channel_tag: + DEBUG_MSG("Client is setting channel %d\n", r->set_channel.index); + if (r->set_channel.index < 0 || r->set_channel.index >= (int)MAX_NUM_CHANNELS) + myReply = allocErrorResponse(Routing_Error_BAD_REQUEST, &mp); + else + handleSetChannel(r->set_channel); + break; + + /** + * Other + */ case AdminMessage_reboot_seconds_tag: { int32_t s = r->reboot_seconds; DEBUG_MSG("Rebooting in %d seconds\n", s); @@ -139,19 +126,14 @@ bool AdminModule::handleReceivedProtobuf(const MeshPacket &mp, AdminMessage *r) #endif default: - AdminMessage response = AdminMessage_init_default; - AdminMessageHandleResult handleResult = MeshModule::handleAdminMessageForAllPlugins(mp, r, &response); + AdminMessage res = AdminMessage_init_default; + AdminMessageHandleResult handleResult = MeshModule::handleAdminMessageForAllPlugins(mp, r, &res); - if (handleResult == AdminMessageHandleResult::HANDLED_WITH_RESPONSE) - { - myReply = allocDataProtobuf(response); - } - else if (mp.decoded.want_response) - { + if (handleResult == AdminMessageHandleResult::HANDLED_WITH_RESPONSE) { + myReply = allocDataProtobuf(res); + } else if (mp.decoded.want_response) { DEBUG_MSG("We did not responded to a request that wanted a respond. req.variant=%d\n", r->which_variant); - } - else if (handleResult != AdminMessageHandleResult::HANDLED) - { + } else if (handleResult != AdminMessageHandleResult::HANDLED) { // Probably a message sent by us or sent to our local node. FIXME, we should avoid scanning these messages DEBUG_MSG("Ignoring nonrelevant admin %d\n", r->which_variant); } @@ -160,6 +142,10 @@ bool AdminModule::handleReceivedProtobuf(const MeshPacket &mp, AdminMessage *r) return handled; } +/** + * Setter methods + */ + void AdminModule::handleSetOwner(const User &o) { int changed = 0; @@ -181,35 +167,219 @@ void AdminModule::handleSetOwner(const User &o) owner.is_licensed = o.is_licensed; } - if ((!changed || o.team) && (owner.team != o.team)) { - changed = 1; - owner.team = o.team; - } - if (changed) // If nothing really changed, don't broadcast on the network or write to flash service.reloadOwner(); } +void AdminModule::handleSetConfig(const Config &c) +{ + switch (c.which_payloadVariant) { + case Config_device_tag: + DEBUG_MSG("Setting config: Device\n"); + config.device = c.payloadVariant.device; + break; + case Config_position_tag: + DEBUG_MSG("Setting config: Position\n"); + config.position = c.payloadVariant.position; + break; + case Config_power_tag: + DEBUG_MSG("Setting config: Power\n"); + config.power = c.payloadVariant.power; + break; + case Config_wifi_tag: + DEBUG_MSG("Setting config: WiFi\n"); + config.wifi = c.payloadVariant.wifi; + break; + case Config_display_tag: + DEBUG_MSG("Setting config: Display\n"); + config.display = c.payloadVariant.display; + break; + case Config_lora_tag: + DEBUG_MSG("Setting config: LoRa\n"); + config.lora = c.payloadVariant.lora; + break; + } + + service.reloadConfig(); +} + +void AdminModule::handleSetModuleConfig(const ModuleConfig &c) +{ + switch (c.which_payloadVariant) { + case ModuleConfig_mqtt_tag: + DEBUG_MSG("Setting module config: MQTT\n"); + moduleConfig.mqtt = c.payloadVariant.mqtt; + break; + case ModuleConfig_serial_tag: + DEBUG_MSG("Setting module config: Serial\n"); + moduleConfig.serial = c.payloadVariant.serial; + break; + case ModuleConfig_external_notification_tag: + DEBUG_MSG("Setting module config: External Notification\n"); + moduleConfig.external_notification = c.payloadVariant.external_notification; + break; + case ModuleConfig_store_forward_tag: + DEBUG_MSG("Setting module config: Store & Forward\n"); + moduleConfig.store_forward = c.payloadVariant.store_forward; + break; + case ModuleConfig_range_test_tag: + DEBUG_MSG("Setting module config: Range Test\n"); + moduleConfig.range_test = c.payloadVariant.range_test; + break; + case ModuleConfig_telemetry_tag: + DEBUG_MSG("Setting module config: Telemetry\n"); + moduleConfig.telemetry = c.payloadVariant.telemetry; + break; + case ModuleConfig_canned_message_tag: + DEBUG_MSG("Setting module config: Canned Message\n"); + moduleConfig.canned_message = c.payloadVariant.canned_message; + break; + } + + service.reloadConfig(); +} + void AdminModule::handleSetChannel(const Channel &cc) { channels.setChannel(cc); + channels.onConfigChanged(); // tell the radios about this change + nodeDB.saveChannelsToDisk(); +} - // Just update and save the channels - no need to update the radio for ! primary channel changes - if (cc.index == 0) { - // FIXME, this updates the user preferences also, which isn't needed - we really just want to notify on configChanged - service.reloadConfig(); - } else { - channels.onConfigChanged(); // tell the radios about this change - nodeDB.saveChannelsToDisk(); +/** + * Getters + */ + +void AdminModule::handleGetOwner(const MeshPacket &req) +{ + if (req.decoded.want_response) { + // We create the reply here + AdminMessage res = AdminMessage_init_default; + res.get_owner_response = owner; + + res.which_variant = AdminMessage_get_owner_response_tag; + myReply = allocDataProtobuf(res); } } -void AdminModule::handleSetRadio(RadioConfig &r) +void AdminModule::handleGetConfig(const MeshPacket &req, const uint32_t configType) { - writeSecret(r.preferences.wifi_password, radioConfig.preferences.wifi_password); - radioConfig = r; + AdminMessage res = AdminMessage_init_default; - service.reloadConfig(); + if (req.decoded.want_response) { + switch (configType) { + case AdminMessage_ConfigType_DEVICE_CONFIG: + DEBUG_MSG("Getting config: Device\n"); + res.get_config_response.which_payloadVariant = Config_device_tag; + res.get_config_response.payloadVariant.device = config.device; + break; + case AdminMessage_ConfigType_POSITION_CONFIG: + DEBUG_MSG("Getting config: Position\n"); + res.get_config_response.which_payloadVariant = Config_position_tag; + res.get_config_response.payloadVariant.position = config.position; + break; + case AdminMessage_ConfigType_POWER_CONFIG: + DEBUG_MSG("Getting config: Power\n"); + res.get_config_response.which_payloadVariant = Config_power_tag; + res.get_config_response.payloadVariant.power = config.power; + break; + case AdminMessage_ConfigType_WIFI_CONFIG: + DEBUG_MSG("Getting config: WiFi\n"); + res.get_config_response.which_payloadVariant = Config_wifi_tag; + res.get_config_response.payloadVariant.wifi = config.wifi; + writeSecret(res.get_config_response.payloadVariant.wifi.psk, config.wifi.psk); + break; + case AdminMessage_ConfigType_DISPLAY_CONFIG: + DEBUG_MSG("Getting config: Display\n"); + res.get_config_response.which_payloadVariant = Config_display_tag; + res.get_config_response.payloadVariant.display = config.display; + break; + case AdminMessage_ConfigType_LORA_CONFIG: + DEBUG_MSG("Getting config: LoRa\n"); + res.get_config_response.which_payloadVariant = Config_lora_tag; + res.get_config_response.payloadVariant.lora = config.lora; + break; + } + + // NOTE: The phone app needs to know the ls_secs & phone_timeout value so it can properly expect sleep behavior. + // So even if we internally use 0 to represent 'use default' we still need to send the value we are + // using to the app (so that even old phone apps work with new device loads). + // r.get_radio_response.preferences.ls_secs = getPref_ls_secs(); + // r.get_radio_response.preferences.phone_timeout_secs = getPref_phone_timeout_secs(); + // hideSecret(r.get_radio_response.preferences.wifi_ssid); // hmm - leave public for now, because only minimally private + // and useful for users to know current provisioning) hideSecret(r.get_radio_response.preferences.wifi_password); + // r.get_config_response.which_payloadVariant = Config_ModuleConfig_telemetry_tag; + res.which_variant = AdminMessage_get_config_response_tag; + myReply = allocDataProtobuf(res); + } +} + +void AdminModule::handleGetModuleConfig(const MeshPacket &req, const uint32_t configType) +{ + AdminMessage res = AdminMessage_init_default; + + if (req.decoded.want_response) { + switch (configType) { + case AdminMessage_ModuleConfigType_MQTT_CONFIG: + DEBUG_MSG("Getting module config: MQTT\n"); + res.get_module_config_response.which_payloadVariant = ModuleConfig_mqtt_tag; + res.get_module_config_response.payloadVariant.mqtt = moduleConfig.mqtt; + break; + case AdminMessage_ModuleConfigType_SERIAL_CONFIG: + DEBUG_MSG("Getting module config: Serial\n"); + res.get_module_config_response.which_payloadVariant = ModuleConfig_serial_tag; + res.get_module_config_response.payloadVariant.serial = moduleConfig.serial; + break; + case AdminMessage_ModuleConfigType_EXTNOTIF_CONFIG: + DEBUG_MSG("Getting module config: External Notification\n"); + res.get_module_config_response.which_payloadVariant = ModuleConfig_external_notification_tag; + res.get_module_config_response.payloadVariant.external_notification = + moduleConfig.external_notification; + break; + case AdminMessage_ModuleConfigType_STOREFORWARD_CONFIG: + DEBUG_MSG("Getting module config: Store & Forward\n"); + res.get_module_config_response.which_payloadVariant = ModuleConfig_store_forward_tag; + res.get_module_config_response.payloadVariant.store_forward = moduleConfig.store_forward; + break; + case AdminMessage_ModuleConfigType_RANGETEST_CONFIG: + DEBUG_MSG("Getting module config: Range Test\n"); + res.get_module_config_response.which_payloadVariant = ModuleConfig_range_test_tag; + res.get_module_config_response.payloadVariant.range_test = moduleConfig.range_test; + break; + case AdminMessage_ModuleConfigType_TELEMETRY_CONFIG: + DEBUG_MSG("Getting module config: Telemetry\n"); + res.get_module_config_response.which_payloadVariant = ModuleConfig_telemetry_tag; + res.get_module_config_response.payloadVariant.telemetry = moduleConfig.telemetry; + break; + case AdminMessage_ModuleConfigType_CANNEDMSG_CONFIG: + DEBUG_MSG("Getting module config: Canned Message\n"); + res.get_module_config_response.which_payloadVariant = ModuleConfig_canned_message_tag; + res.get_module_config_response.payloadVariant.canned_message = moduleConfig.canned_message; + break; + } + + // NOTE: The phone app needs to know the ls_secs & phone_timeout value so it can properly expect sleep behavior. + // So even if we internally use 0 to represent 'use default' we still need to send the value we are + // using to the app (so that even old phone apps work with new device loads). + // r.get_radio_response.preferences.ls_secs = getPref_ls_secs(); + // r.get_radio_response.preferences.phone_timeout_secs = getPref_phone_timeout_secs(); + // hideSecret(r.get_radio_response.preferences.wifi_ssid); // hmm - leave public for now, because only minimally private + // and useful for users to know current provisioning) hideSecret(r.get_radio_response.preferences.wifi_password); + // r.get_config_response.which_payloadVariant = Config_ModuleConfig_telemetry_tag; + res.which_variant = AdminMessage_get_module_config_response_tag; + myReply = allocDataProtobuf(res); + } +} + +void AdminModule::handleGetChannel(const MeshPacket &req, uint32_t channelIndex) +{ + if (req.decoded.want_response) { + // We create the reply here + AdminMessage r = AdminMessage_init_default; + r.get_channel_response = channels.getByIndex(channelIndex); + r.which_variant = AdminMessage_get_channel_response_tag; + myReply = allocDataProtobuf(r); + } } AdminModule::AdminModule() : ProtobufModule("Admin", PortNum_ADMIN_APP, AdminMessage_fields) diff --git a/src/modules/AdminModule.h b/src/modules/AdminModule.h index dfe1e6c07..a6a02fd52 100644 --- a/src/modules/AdminModule.h +++ b/src/modules/AdminModule.h @@ -20,13 +20,22 @@ class AdminModule : public ProtobufModule virtual bool handleReceivedProtobuf(const MeshPacket &mp, AdminMessage *p) override; private: + /** + * Getters + */ + void handleGetOwner(const MeshPacket &req); + void handleGetConfig(const MeshPacket &req, uint32_t configType); + void handleGetModuleConfig(const MeshPacket &req, uint32_t configType); + void handleGetChannel(const MeshPacket &req, uint32_t channelIndex); + + /** + * Setters + */ void handleSetOwner(const User &o); void handleSetChannel(const Channel &cc); - void handleSetRadio(RadioConfig &r); - - void handleGetChannel(const MeshPacket &req, uint32_t channelIndex); - void handleGetRadio(const MeshPacket &req); - void handleGetOwner(const MeshPacket &req); + void handleSetConfig(const Config &c); + void handleSetModuleConfig(const ModuleConfig &c); + void handleSetChannel(); }; extern AdminModule *adminModule; diff --git a/src/modules/CannedMessageModule.cpp b/src/modules/CannedMessageModule.cpp index aa52cf6cd..6d7064c25 100644 --- a/src/modules/CannedMessageModule.cpp +++ b/src/modules/CannedMessageModule.cpp @@ -1,8 +1,9 @@ #include "configuration.h" +#ifndef NO_SCREEN #include "CannedMessageModule.h" -#include "PowerFSM.h" // neede for button bypass -#include "MeshService.h" #include "FSCommon.h" +#include "MeshService.h" +#include "PowerFSM.h" // neede for button bypass #include "mesh/generated/cannedmessages.pb.h" // TODO: reuse defined from Screen.cpp @@ -21,22 +22,18 @@ CannedMessageModule *cannedMessageModule; // TODO: move it into NodeDB.h! extern bool loadProto(const char *filename, size_t protoSize, size_t objSize, const pb_msgdesc_t *fields, void *dest_struct); -extern bool saveProto(const char *filename, size_t protoSize, size_t objSize, const pb_msgdesc_t *fields, const void *dest_struct); +extern bool saveProto(const char *filename, size_t protoSize, size_t objSize, const pb_msgdesc_t *fields, + const void *dest_struct); CannedMessageModule::CannedMessageModule() - : SinglePortModule("canned", PortNum_TEXT_MESSAGE_APP), - concurrency::OSThread("CannedMessageModule") + : SinglePortModule("canned", PortNum_TEXT_MESSAGE_APP), concurrency::OSThread("CannedMessageModule") { - if (radioConfig.preferences.canned_message_module_enabled) - { + if (moduleConfig.canned_message.enabled) { this->loadProtoForModule(); - if(this->splitConfiguredMessages() <= 0) - { + if (this->splitConfiguredMessages() <= 0) { DEBUG_MSG("CannedMessageModule: No messages are configured. Module is disabled\n"); this->runState = CANNED_MESSAGE_RUN_STATE_DISABLED; - } - else - { + } else { DEBUG_MSG("CannedMessageModule is enabled\n"); this->inputObserver.observe(inputBroker); } @@ -55,57 +52,38 @@ int CannedMessageModule::splitConfiguredMessages() int i = 0; // collect all the message parts - strcpy( - this->messageStore, - cannedMessageModuleConfig.messagesPart1); - strcat( - this->messageStore, - cannedMessageModuleConfig.messagesPart2); - strcat( - this->messageStore, - cannedMessageModuleConfig.messagesPart3); - strcat( - this->messageStore, - cannedMessageModuleConfig.messagesPart4); + strcpy(this->messageStore, cannedMessageModuleConfig.messagesPart1); + strcat(this->messageStore, cannedMessageModuleConfig.messagesPart2); + strcat(this->messageStore, cannedMessageModuleConfig.messagesPart3); + strcat(this->messageStore, cannedMessageModuleConfig.messagesPart4); // The first message points to the beginning of the store. - this->messages[messageIndex++] = - this->messageStore; - int upTo = - strlen(this->messageStore) - 1; + this->messages[messageIndex++] = this->messageStore; + int upTo = strlen(this->messageStore) - 1; - while (i < upTo) - { - if (this->messageStore[i] == '|') - { + while (i < upTo) { + if (this->messageStore[i] == '|') { // Message ending found, replace it with string-end character. this->messageStore[i] = '\0'; - DEBUG_MSG("CannedMessage %d is: '%s'\n", - messageIndex-1, this->messages[messageIndex-1]); + DEBUG_MSG("CannedMessage %d is: '%s'\n", messageIndex - 1, this->messages[messageIndex - 1]); // hit our max messages, bail - if (messageIndex >= CANNED_MESSAGE_MODULE_MESSAGE_MAX_COUNT) - { + if (messageIndex >= CANNED_MESSAGE_MODULE_MESSAGE_MAX_COUNT) { this->messagesCount = messageIndex; return this->messagesCount; } // Next message starts after pipe (|) just found. - this->messages[messageIndex++] = - (this->messageStore + i + 1); + this->messages[messageIndex++] = (this->messageStore + i + 1); } i += 1; } - if (strlen(this->messages[messageIndex-1]) > 0) - { + if (strlen(this->messages[messageIndex - 1]) > 0) { // We have a last message. - DEBUG_MSG("CannedMessage %d is: '%s'\n", - messageIndex-1, this->messages[messageIndex-1]); + DEBUG_MSG("CannedMessage %d is: '%s'\n", messageIndex - 1, this->messages[messageIndex - 1]); this->messagesCount = messageIndex; - } - else - { - this->messagesCount = messageIndex-1; + } else { + this->messagesCount = messageIndex - 1; } return this->messagesCount; @@ -113,11 +91,9 @@ int CannedMessageModule::splitConfiguredMessages() int CannedMessageModule::handleInputEvent(const InputEvent *event) { - if ( - (strlen(radioConfig.preferences.canned_message_module_allow_input_source) > 0) && - (strcmp(radioConfig.preferences.canned_message_module_allow_input_source, event->source) != 0) && - (strcmp(radioConfig.preferences.canned_message_module_allow_input_source, "_any") != 0)) - { + if ((strlen(moduleConfig.canned_message.allow_input_source) > 0) && + (strcmp(moduleConfig.canned_message.allow_input_source, event->source) != 0) && + (strcmp(moduleConfig.canned_message.allow_input_source, "_any") != 0)) { // Event source is not accepted. // Event only accepted if source matches the configured one, or // the configured one is "_any" (or if there is no configured @@ -126,32 +102,28 @@ int CannedMessageModule::handleInputEvent(const InputEvent *event) } bool validEvent = false; - if (event->inputEvent == static_cast(InputEventChar_KEY_UP)) - { + if (event->inputEvent == static_cast(ModuleConfig_CannedMessageConfig_InputEventChar_KEY_UP)) { DEBUG_MSG("Canned message event UP\n"); this->runState = CANNED_MESSAGE_RUN_STATE_ACTION_UP; validEvent = true; } - if (event->inputEvent == static_cast(InputEventChar_KEY_DOWN)) - { + if (event->inputEvent == static_cast(ModuleConfig_CannedMessageConfig_InputEventChar_KEY_DOWN)) { DEBUG_MSG("Canned message event DOWN\n"); this->runState = CANNED_MESSAGE_RUN_STATE_ACTION_DOWN; validEvent = true; } - if (event->inputEvent == static_cast(InputEventChar_KEY_SELECT)) - { + if (event->inputEvent == static_cast(ModuleConfig_CannedMessageConfig_InputEventChar_KEY_SELECT)) { DEBUG_MSG("Canned message event Select\n"); // when inactive, call the onebutton shortpress instead. Activate Module only on up/down if ((this->runState == CANNED_MESSAGE_RUN_STATE_INACTIVE) || (this->runState == CANNED_MESSAGE_RUN_STATE_DISABLED)) { powerFSM.trigger(EVENT_PRESS); - }else{ + } else { this->runState = CANNED_MESSAGE_RUN_STATE_ACTION_SELECT; validEvent = true; } } - if (validEvent) - { + if (validEvent) { // Let runOnce to be called immediately. setIntervalFromNow(0); } @@ -159,90 +131,67 @@ int CannedMessageModule::handleInputEvent(const InputEvent *event) return 0; } -void CannedMessageModule::sendText(NodeNum dest, - const char* message, - bool wantReplies) +void CannedMessageModule::sendText(NodeNum dest, const char *message, bool wantReplies) { MeshPacket *p = allocDataPacket(); p->to = dest; p->want_ack = true; p->decoded.payload.size = strlen(message); memcpy(p->decoded.payload.bytes, message, p->decoded.payload.size); - if (radioConfig.preferences.canned_message_module_send_bell) - { - p->decoded.payload.bytes[p->decoded.payload.size-1] = 7; // Bell character - p->decoded.payload.bytes[p->decoded.payload.size] = '\0'; // Bell character + if (moduleConfig.canned_message.send_bell) { + p->decoded.payload.bytes[p->decoded.payload.size - 1] = 7; // Bell character + p->decoded.payload.bytes[p->decoded.payload.size] = '\0'; // Bell character p->decoded.payload.size++; } - DEBUG_MSG("Sending message id=%d, msg=%.*s\n", - p->id, p->decoded.payload.size, p->decoded.payload.bytes); + DEBUG_MSG("Sending message id=%d, msg=%.*s\n", p->id, p->decoded.payload.size, p->decoded.payload.bytes); service.sendToMesh(p); } int32_t CannedMessageModule::runOnce() { - if ((!radioConfig.preferences.canned_message_module_enabled) - || (this->runState == CANNED_MESSAGE_RUN_STATE_DISABLED) - || (this->runState == CANNED_MESSAGE_RUN_STATE_INACTIVE)) - { + if ((!moduleConfig.canned_message.enabled) || (this->runState == CANNED_MESSAGE_RUN_STATE_DISABLED) || + (this->runState == CANNED_MESSAGE_RUN_STATE_INACTIVE)) { return 30000; // TODO: should return MAX_VAL } DEBUG_MSG("Check status\n"); UIFrameEvent e = {false, true}; - if (this->runState == CANNED_MESSAGE_RUN_STATE_SENDING_ACTIVE) - { + if (this->runState == CANNED_MESSAGE_RUN_STATE_SENDING_ACTIVE) { // TODO: might have some feedback of sendig state this->runState = CANNED_MESSAGE_RUN_STATE_INACTIVE; e.frameChanged = true; this->currentMessageIndex = -1; this->notifyObservers(&e); - } - else if ( - (this->runState == CANNED_MESSAGE_RUN_STATE_ACTIVE) - && (millis() - this->lastTouchMillis) > INACTIVATE_AFTER_MS) - { + } else if ((this->runState == CANNED_MESSAGE_RUN_STATE_ACTIVE) && (millis() - this->lastTouchMillis) > INACTIVATE_AFTER_MS) { // Reset module DEBUG_MSG("Reset due the lack of activity.\n"); e.frameChanged = true; this->currentMessageIndex = -1; this->runState = CANNED_MESSAGE_RUN_STATE_INACTIVE; this->notifyObservers(&e); - } - else if (this->currentMessageIndex == -1) - { + } else if (this->currentMessageIndex == -1) { this->currentMessageIndex = 0; DEBUG_MSG("First touch (%d):%s\n", this->currentMessageIndex, this->getCurrentMessage()); e.frameChanged = true; this->runState = CANNED_MESSAGE_RUN_STATE_ACTIVE; - } - else if (this->runState == CANNED_MESSAGE_RUN_STATE_ACTION_SELECT) - { - sendText( - NODENUM_BROADCAST, - this->messages[this->currentMessageIndex], - true); + } else if (this->runState == CANNED_MESSAGE_RUN_STATE_ACTION_SELECT) { + sendText(NODENUM_BROADCAST, this->messages[this->currentMessageIndex], true); this->runState = CANNED_MESSAGE_RUN_STATE_SENDING_ACTIVE; this->currentMessageIndex = -1; this->notifyObservers(&e); return 2000; - } - else if (this->runState == CANNED_MESSAGE_RUN_STATE_ACTION_UP) - { + } else if (this->runState == CANNED_MESSAGE_RUN_STATE_ACTION_UP) { this->currentMessageIndex = getPrevIndex(); this->runState = CANNED_MESSAGE_RUN_STATE_ACTIVE; DEBUG_MSG("MOVE UP (%d):%s\n", this->currentMessageIndex, this->getCurrentMessage()); - } - else if (this->runState == CANNED_MESSAGE_RUN_STATE_ACTION_DOWN) - { + } else if (this->runState == CANNED_MESSAGE_RUN_STATE_ACTION_DOWN) { this->currentMessageIndex = this->getNextIndex(); this->runState = CANNED_MESSAGE_RUN_STATE_ACTIVE; DEBUG_MSG("MOVE DOWN (%d):%s\n", this->currentMessageIndex, this->getCurrentMessage()); } - if (this->runState == CANNED_MESSAGE_RUN_STATE_ACTIVE) - { + if (this->runState == CANNED_MESSAGE_RUN_STATE_ACTIVE) { this->lastTouchMillis = millis(); this->notifyObservers(&e); return INACTIVATE_AFTER_MS; @@ -251,22 +200,21 @@ int32_t CannedMessageModule::runOnce() return 30000; // TODO: should return MAX_VAL } -const char* CannedMessageModule::getCurrentMessage() +const char *CannedMessageModule::getCurrentMessage() { return this->messages[this->currentMessageIndex]; } -const char* CannedMessageModule::getPrevMessage() +const char *CannedMessageModule::getPrevMessage() { return this->messages[this->getPrevIndex()]; } -const char* CannedMessageModule::getNextMessage() +const char *CannedMessageModule::getNextMessage() { return this->messages[this->getNextIndex()]; } bool CannedMessageModule::shouldDraw() { - if (!radioConfig.preferences.canned_message_module_enabled) - { + if (!moduleConfig.canned_message.enabled) { return false; } return (currentMessageIndex != -1) || (this->runState != CANNED_MESSAGE_RUN_STATE_INACTIVE); @@ -274,47 +222,35 @@ bool CannedMessageModule::shouldDraw() int CannedMessageModule::getNextIndex() { - if (this->currentMessageIndex >= (this->messagesCount -1)) - { + if (this->currentMessageIndex >= (this->messagesCount - 1)) { return 0; - } - else - { + } else { return this->currentMessageIndex + 1; } } int CannedMessageModule::getPrevIndex() { - if (this->currentMessageIndex <= 0) - { + if (this->currentMessageIndex <= 0) { return this->messagesCount - 1; - } - else - { + } else { return this->currentMessageIndex - 1; } } -void CannedMessageModule::drawFrame( - OLEDDisplay *display, OLEDDisplayUiState *state, int16_t x, int16_t y) +void CannedMessageModule::drawFrame(OLEDDisplay *display, OLEDDisplayUiState *state, int16_t x, int16_t y) { displayedNodeNum = 0; // Not currently showing a node pane - if (cannedMessageModule->runState == CANNED_MESSAGE_RUN_STATE_SENDING_ACTIVE) - { + if (cannedMessageModule->runState == CANNED_MESSAGE_RUN_STATE_SENDING_ACTIVE) { display->setTextAlignment(TEXT_ALIGN_CENTER); display->setFont(FONT_MEDIUM); - display->drawString(display->getWidth()/2 + x, 0 + y + 12, "Sending..."); - } - else if (cannedMessageModule->runState == CANNED_MESSAGE_RUN_STATE_DISABLED) - { + display->drawString(display->getWidth() / 2 + x, 0 + y + 12, "Sending..."); + } else if (cannedMessageModule->runState == CANNED_MESSAGE_RUN_STATE_DISABLED) { display->setTextAlignment(TEXT_ALIGN_LEFT); display->setFont(FONT_SMALL); display->drawString(10 + x, 0 + y + 16, "Canned Message\nModule disabled."); - } - else - { + } else { display->setTextAlignment(TEXT_ALIGN_LEFT); display->setFont(FONT_SMALL); display->drawString(0 + x, 0 + y, cannedMessageModule->getPrevMessage()); @@ -327,7 +263,8 @@ void CannedMessageModule::drawFrame( void CannedMessageModule::loadProtoForModule() { - if (!loadProto(cannedMessagesConfigFile, CannedMessageModuleConfig_size, sizeof(cannedMessagesConfigFile), CannedMessageModuleConfig_fields, &cannedMessageModuleConfig)) { + if (!loadProto(cannedMessagesConfigFile, CannedMessageModuleConfig_size, sizeof(cannedMessagesConfigFile), + CannedMessageModuleConfig_fields, &cannedMessageModuleConfig)) { installDefaultCannedMessageModuleConfig(); } } @@ -346,7 +283,8 @@ bool CannedMessageModule::saveProtoForModule() FS.mkdir("/prefs"); #endif - okay &= saveProto(cannedMessagesConfigFile, CannedMessageModuleConfig_size, sizeof(CannedMessageModuleConfig), CannedMessageModuleConfig_fields, &cannedMessageModuleConfig); + okay &= saveProto(cannedMessagesConfigFile, CannedMessageModuleConfig_size, sizeof(CannedMessageModuleConfig), + CannedMessageModuleConfig_fields, &cannedMessageModuleConfig); return okay; } @@ -371,8 +309,8 @@ void CannedMessageModule::installDefaultCannedMessageModuleConfig() * @return AdminMessageHandleResult HANDLED if message was handled * HANDLED_WITH_RESULT if a result is also prepared. */ -AdminMessageHandleResult CannedMessageModule::handleAdminMessageForModule( - const MeshPacket &mp, AdminMessage *request, AdminMessage *response) +AdminMessageHandleResult CannedMessageModule::handleAdminMessageForModule(const MeshPacket &mp, AdminMessage *request, + AdminMessage *response) { AdminMessageHandleResult result; @@ -403,29 +341,25 @@ AdminMessageHandleResult CannedMessageModule::handleAdminMessageForModule( case AdminMessage_set_canned_message_module_part1_tag: DEBUG_MSG("Client is setting radio canned message part 1\n"); - this->handleSetCannedMessageModulePart1( - request->set_canned_message_module_part1); + this->handleSetCannedMessageModulePart1(request->set_canned_message_module_part1); result = AdminMessageHandleResult::HANDLED; break; case AdminMessage_set_canned_message_module_part2_tag: DEBUG_MSG("Client is setting radio canned message part 2\n"); - this->handleSetCannedMessageModulePart2( - request->set_canned_message_module_part2); + this->handleSetCannedMessageModulePart2(request->set_canned_message_module_part2); result = AdminMessageHandleResult::HANDLED; break; case AdminMessage_set_canned_message_module_part3_tag: DEBUG_MSG("Client is setting radio canned message part 3\n"); - this->handleSetCannedMessageModulePart3( - request->set_canned_message_module_part3); + this->handleSetCannedMessageModulePart3(request->set_canned_message_module_part3); result = AdminMessageHandleResult::HANDLED; break; case AdminMessage_set_canned_message_module_part4_tag: DEBUG_MSG("Client is setting radio canned message part 4\n"); - this->handleSetCannedMessageModulePart4( - request->set_canned_message_module_part4); + this->handleSetCannedMessageModulePart4(request->set_canned_message_module_part4); result = AdminMessageHandleResult::HANDLED; break; @@ -436,67 +370,53 @@ AdminMessageHandleResult CannedMessageModule::handleAdminMessageForModule( return result; } -void CannedMessageModule::handleGetCannedMessageModulePart1( - const MeshPacket &req, AdminMessage *response) +void CannedMessageModule::handleGetCannedMessageModulePart1(const MeshPacket &req, AdminMessage *response) { DEBUG_MSG("*** handleGetCannedMessageModulePart1\n"); assert(req.decoded.want_response); response->which_variant = AdminMessage_get_canned_message_module_part1_response_tag; - strcpy( - response->get_canned_message_module_part1_response, - cannedMessageModuleConfig.messagesPart1); + strcpy(response->get_canned_message_module_part1_response, cannedMessageModuleConfig.messagesPart1); } -void CannedMessageModule::handleGetCannedMessageModulePart2( - const MeshPacket &req, AdminMessage *response) +void CannedMessageModule::handleGetCannedMessageModulePart2(const MeshPacket &req, AdminMessage *response) { DEBUG_MSG("*** handleGetCannedMessageModulePart2\n"); assert(req.decoded.want_response); response->which_variant = AdminMessage_get_canned_message_module_part2_response_tag; - strcpy( - response->get_canned_message_module_part2_response, - cannedMessageModuleConfig.messagesPart2); + strcpy(response->get_canned_message_module_part2_response, cannedMessageModuleConfig.messagesPart2); } -void CannedMessageModule::handleGetCannedMessageModulePart3( - const MeshPacket &req, AdminMessage *response) +void CannedMessageModule::handleGetCannedMessageModulePart3(const MeshPacket &req, AdminMessage *response) { DEBUG_MSG("*** handleGetCannedMessageModulePart3\n"); assert(req.decoded.want_response); response->which_variant = AdminMessage_get_canned_message_module_part3_response_tag; - strcpy( - response->get_canned_message_module_part3_response, - cannedMessageModuleConfig.messagesPart3); + strcpy(response->get_canned_message_module_part3_response, cannedMessageModuleConfig.messagesPart3); } -void CannedMessageModule::handleGetCannedMessageModulePart4( - const MeshPacket &req, AdminMessage *response) +void CannedMessageModule::handleGetCannedMessageModulePart4(const MeshPacket &req, AdminMessage *response) { DEBUG_MSG("*** handleGetCannedMessageModulePart4\n"); assert(req.decoded.want_response); response->which_variant = AdminMessage_get_canned_message_module_part4_response_tag; - strcpy( - response->get_canned_message_module_part4_response, - cannedMessageModuleConfig.messagesPart4); + strcpy(response->get_canned_message_module_part4_response, cannedMessageModuleConfig.messagesPart4); } void CannedMessageModule::handleSetCannedMessageModulePart1(const char *from_msg) { int changed = 0; - if (*from_msg) - { + if (*from_msg) { changed |= strcmp(cannedMessageModuleConfig.messagesPart1, from_msg); strcpy(cannedMessageModuleConfig.messagesPart1, from_msg); DEBUG_MSG("*** from_msg.text:%s\n", from_msg); } - if (changed) - { + if (changed) { this->saveProtoForModule(); } } @@ -505,14 +425,12 @@ void CannedMessageModule::handleSetCannedMessageModulePart2(const char *from_msg { int changed = 0; - if (*from_msg) - { + if (*from_msg) { changed |= strcmp(cannedMessageModuleConfig.messagesPart2, from_msg); strcpy(cannedMessageModuleConfig.messagesPart2, from_msg); } - if (changed) - { + if (changed) { this->saveProtoForModule(); } } @@ -521,14 +439,12 @@ void CannedMessageModule::handleSetCannedMessageModulePart3(const char *from_msg { int changed = 0; - if (*from_msg) - { + if (*from_msg) { changed |= strcmp(cannedMessageModuleConfig.messagesPart3, from_msg); strcpy(cannedMessageModuleConfig.messagesPart3, from_msg); } - if (changed) - { + if (changed) { this->saveProtoForModule(); } } @@ -537,14 +453,13 @@ void CannedMessageModule::handleSetCannedMessageModulePart4(const char *from_msg { int changed = 0; - if (*from_msg) - { + if (*from_msg) { changed |= strcmp(cannedMessageModuleConfig.messagesPart4, from_msg); strcpy(cannedMessageModuleConfig.messagesPart4, from_msg); } - if (changed) - { + if (changed) { this->saveProtoForModule(); } } +#endif \ No newline at end of file diff --git a/src/modules/CannedMessageModule.h b/src/modules/CannedMessageModule.h index 9a755c54e..f393882d5 100644 --- a/src/modules/CannedMessageModule.h +++ b/src/modules/CannedMessageModule.h @@ -1,4 +1,6 @@ #pragma once +#ifdef NO_SCREEN +#else #include "ProtobufModule.h" #include "input/InputBroker.h" @@ -84,3 +86,4 @@ class CannedMessageModule : }; extern CannedMessageModule *cannedMessageModule; +#endif \ No newline at end of file diff --git a/src/modules/ExternalNotificationModule.cpp b/src/modules/ExternalNotificationModule.cpp index 7412eb1d3..b9e946823 100644 --- a/src/modules/ExternalNotificationModule.cpp +++ b/src/modules/ExternalNotificationModule.cpp @@ -1,9 +1,9 @@ -#include "configuration.h" #include "ExternalNotificationModule.h" #include "MeshService.h" #include "NodeDB.h" #include "RTC.h" #include "Router.h" +#include "configuration.h" #include //#include @@ -19,26 +19,26 @@ Quick reference: - radioConfig.preferences.ext_notification_module_enabled + moduleConfig.external_notification.enabled 0 = Disabled (Default) 1 = Enabled - radioConfig.preferences.ext_notification_module_active + moduleConfig.external_notification.active 0 = Active Low (Default) 1 = Active High - radioConfig.preferences.ext_notification_module_alert_message + moduleConfig.external_notification.alert_message 0 = Disabled (Default) 1 = Alert when a text message comes - radioConfig.preferences.ext_notification_module_alert_bell + moduleConfig.external_notification.alert_bell 0 = Disabled (Default) 1 = Alert when the bell character is received - radioConfig.preferences.ext_notification_module_output + moduleConfig.external_notification.output GPIO of the output. (Default = 13) - radioConfig.preferences.ext_notification_module_output_ms + moduleConfig.external_notification.output_ms Amount of time in ms for the alert. Default is 1000. */ @@ -59,19 +59,19 @@ int32_t ExternalNotificationModule::runOnce() without having to configure it from the PythonAPI or WebUI. */ - // radioConfig.preferences.ext_notification_module_enabled = 1; - // radioConfig.preferences.ext_notification_module_alert_message = 1; + // moduleConfig.external_notification.enabled = 1; + // moduleConfig.external_notification.alert_message = 1; - // radioConfig.preferences.ext_notification_module_active = 1; - // radioConfig.preferences.ext_notification_module_alert_bell = 1; - // radioConfig.preferences.ext_notification_module_output_ms = 1000; - // radioConfig.preferences.ext_notification_module_output = 13; + // moduleConfig.external_notification.active = 1; + // moduleConfig.external_notification.alert_bell = 1; + // moduleConfig.external_notification.output_ms = 1000; + // moduleConfig.external_notification.output = 13; if (externalCurrentState) { // If the output is turned on, turn it back off after the given period of time. - if (externalTurnedOn + (radioConfig.preferences.ext_notification_module_output_ms - ? radioConfig.preferences.ext_notification_module_output_ms + if (externalTurnedOn + (moduleConfig.external_notification.output_ms + ? moduleConfig.external_notification.output_ms : EXT_NOTIFICATION_MODULE_OUTPUT_MS) < millis()) { DEBUG_MSG("Turning off external notification\n"); @@ -84,59 +84,62 @@ int32_t ExternalNotificationModule::runOnce() void ExternalNotificationModule::setExternalOn() { - #ifdef EXT_NOTIFY_OUT +#ifdef EXT_NOTIFY_OUT externalCurrentState = 1; externalTurnedOn = millis(); - digitalWrite((radioConfig.preferences.ext_notification_module_output ? radioConfig.preferences.ext_notification_module_output - : EXT_NOTIFICATION_MODULE_OUTPUT), - (radioConfig.preferences.ext_notification_module_active ? true : false)); - #endif + digitalWrite((moduleConfig.external_notification.output + ? moduleConfig.external_notification.output + : EXT_NOTIFICATION_MODULE_OUTPUT), + (moduleConfig.external_notification.active ? true : false)); +#endif } void ExternalNotificationModule::setExternalOff() { - #ifdef EXT_NOTIFY_OUT +#ifdef EXT_NOTIFY_OUT externalCurrentState = 0; - digitalWrite((radioConfig.preferences.ext_notification_module_output ? radioConfig.preferences.ext_notification_module_output - : EXT_NOTIFICATION_MODULE_OUTPUT), - (radioConfig.preferences.ext_notification_module_active ? false : true)); - #endif + digitalWrite((moduleConfig.external_notification.output + ? moduleConfig.external_notification.output + : EXT_NOTIFICATION_MODULE_OUTPUT), + (moduleConfig.external_notification.active ? false : true)); +#endif } // -------- ExternalNotificationModule::ExternalNotificationModule() : SinglePortModule("ExternalNotificationModule", PortNum_TEXT_MESSAGE_APP), concurrency::OSThread( - "ExternalNotificationModule") + "ExternalNotificationModule") { // restrict to the admin channel for rx boundChannel = Channels::gpioChannel; #ifndef NO_ESP32 - #ifdef EXT_NOTIFY_OUT +#ifdef EXT_NOTIFY_OUT /* Uncomment the preferences below if you want to use the module without having to configure it from the PythonAPI or WebUI. */ - // radioConfig.preferences.ext_notification_module_enabled = 1; - // radioConfig.preferences.ext_notification_module_alert_message = 1; + // moduleConfig.external_notification.enabled = 1; + // moduleConfig.external_notification.alert_message = 1; - // radioConfig.preferences.ext_notification_module_active = 1; - // radioConfig.preferences.ext_notification_module_alert_bell = 1; - // radioConfig.preferences.ext_notification_module_output_ms = 1000; - // radioConfig.preferences.ext_notification_module_output = 13; + // moduleConfig.external_notification.active = 1; + // moduleConfig.external_notification.alert_bell = 1; + // moduleConfig.external_notification.output_ms = 1000; + // moduleConfig.external_notification.output = 13; - if (radioConfig.preferences.ext_notification_module_enabled) { + if (moduleConfig.external_notification.enabled) { DEBUG_MSG("Initializing External Notification Module\n"); // Set the direction of a pin - pinMode((radioConfig.preferences.ext_notification_module_output ? radioConfig.preferences.ext_notification_module_output - : EXT_NOTIFICATION_MODULE_OUTPUT), + pinMode((moduleConfig.external_notification.output + ? moduleConfig.external_notification.output + : EXT_NOTIFICATION_MODULE_OUTPUT), OUTPUT); // Turn off the pin @@ -145,22 +148,22 @@ ExternalNotificationModule::ExternalNotificationModule() DEBUG_MSG("External Notification Module Disabled\n"); enabled = false; } - #endif +#endif #endif } ProcessMessage ExternalNotificationModule::handleReceived(const MeshPacket &mp) { #ifndef NO_ESP32 - #ifdef EXT_NOTIFY_OUT +#ifdef EXT_NOTIFY_OUT - if (radioConfig.preferences.ext_notification_module_enabled) { + if (moduleConfig.external_notification.enabled) { if (getFrom(&mp) != nodeDB.getNodeNum()) { // TODO: This may be a problem if messages are sent in unicide, but I'm not sure if it will. // Need to know if and how this could be a problem. - if (radioConfig.preferences.ext_notification_module_alert_bell) { + if (moduleConfig.external_notification.alert_bell) { auto &p = mp.decoded; DEBUG_MSG("externalNotificationModule - Notification Bell\n"); for (int i = 0; i < p.payload.size; i++) { @@ -170,7 +173,7 @@ ProcessMessage ExternalNotificationModule::handleReceived(const MeshPacket &mp) } } - if (radioConfig.preferences.ext_notification_module_alert_message) { + if (moduleConfig.external_notification.alert_message) { DEBUG_MSG("externalNotificationModule - Notification Module\n"); setExternalOn(); } @@ -179,7 +182,7 @@ ProcessMessage ExternalNotificationModule::handleReceived(const MeshPacket &mp) } else { DEBUG_MSG("External Notification Module Disabled\n"); } - #endif +#endif #endif diff --git a/src/modules/Modules.cpp b/src/modules/Modules.cpp index 0221418e6..2d308ca43 100644 --- a/src/modules/Modules.cpp +++ b/src/modules/Modules.cpp @@ -47,7 +47,9 @@ void setupModules() cardKbI2cImpl->init(); facesKbI2cImpl = new FacesKbI2cImpl(); facesKbI2cImpl->init(); +#ifndef NO_SCREEN cannedMessageModule = new CannedMessageModule(); +#endif #ifndef PORTDUINO new DeviceTelemetryModule(); new EnvironmentTelemetryModule(); diff --git a/src/modules/NodeInfoModule.cpp b/src/modules/NodeInfoModule.cpp index 4eeac349d..716f6cd19 100644 --- a/src/modules/NodeInfoModule.cpp +++ b/src/modules/NodeInfoModule.cpp @@ -1,9 +1,9 @@ -#include "configuration.h" #include "NodeInfoModule.h" #include "MeshService.h" #include "NodeDB.h" #include "RTC.h" #include "Router.h" +#include "configuration.h" #include "main.h" NodeInfoModule *nodeInfoModule; @@ -19,7 +19,7 @@ bool NodeInfoModule::handleReceivedProtobuf(const MeshPacket &mp, User *pptr) // Show new nodes on LCD screen if (wasBroadcast) { String lcd = String("Joined: ") + p.long_name + "\n"; - if(screen) + if (screen) screen->print(lcd.c_str()); } @@ -69,6 +69,6 @@ int32_t NodeInfoModule::runOnce() DEBUG_MSG("Sending our nodeinfo to mesh (wantReplies=%d)\n", requestReplies); sendOurNodeInfo(NODENUM_BROADCAST, requestReplies); // Send our info (don't request replies) - return getPref_position_broadcast_secs() * 1000; -} - + return config.position.position_broadcast_secs ? config.position.position_broadcast_secs + : default_broadcast_interval_secs * 1000; +} \ No newline at end of file diff --git a/src/modules/PositionModule.cpp b/src/modules/PositionModule.cpp index 750920714..346214f85 100644 --- a/src/modules/PositionModule.cpp +++ b/src/modules/PositionModule.cpp @@ -60,7 +60,7 @@ MeshPacket *PositionModule::allocReply() // configuration of POSITION packet // consider making this a function argument? - uint32_t pos_flags = radioConfig.preferences.position_flags; + uint32_t pos_flags = config.position.position_flags; // Populate a Position struct with ONLY the requested fields Position p = Position_init_default; // Start with an empty structure @@ -70,28 +70,28 @@ MeshPacket *PositionModule::allocReply() p.longitude_i = node->position.longitude_i; p.time = node->position.time; - if (pos_flags & PositionFlags_POS_ALTITUDE) { - if (pos_flags & PositionFlags_POS_ALT_MSL) + if (pos_flags & Config_PositionConfig_PositionFlags_POS_ALTITUDE) { + if (pos_flags & Config_PositionConfig_PositionFlags_POS_ALT_MSL) p.altitude = node->position.altitude; else p.altitude_hae = node->position.altitude_hae; - if (pos_flags & PositionFlags_POS_GEO_SEP) + if (pos_flags & Config_PositionConfig_PositionFlags_POS_GEO_SEP) p.alt_geoid_sep = node->position.alt_geoid_sep; } - if (pos_flags & PositionFlags_POS_DOP) { - if (pos_flags & PositionFlags_POS_HVDOP) { + if (pos_flags & Config_PositionConfig_PositionFlags_POS_DOP) { + if (pos_flags & Config_PositionConfig_PositionFlags_POS_HVDOP) { p.HDOP = node->position.HDOP; p.VDOP = node->position.VDOP; } else p.PDOP = node->position.PDOP; } - if (pos_flags & PositionFlags_POS_SATINVIEW) + if (pos_flags & Config_PositionConfig_PositionFlags_POS_SATINVIEW) p.sats_in_view = node->position.sats_in_view; - if (pos_flags & PositionFlags_POS_TIMESTAMP) + if (pos_flags & Config_PositionConfig_PositionFlags_POS_TIMESTAMP) p.pos_timestamp = node->position.pos_timestamp; // Strip out any time information before sending packets to other nodes - to keep the wire size small (and because other @@ -127,7 +127,9 @@ int32_t PositionModule::runOnce() // We limit our GPS broadcasts to a max rate uint32_t now = millis(); - if (lastGpsSend == 0 || now - lastGpsSend >= getPref_position_broadcast_secs() * 1000) { + if (lastGpsSend == 0 || now - lastGpsSend >= config.position.position_broadcast_secs + ? config.position.position_broadcast_secs + : default_broadcast_interval_secs * 1000) { // Only send packets if the channel is less than 40% utilized. if (airTime->channelUtilizationPercent() < 40) { @@ -149,7 +151,7 @@ int32_t PositionModule::runOnce() DEBUG_MSG("Channel utilization is >50 percent. Skipping this opportunity to send.\n"); } - } else if (!radioConfig.preferences.position_broadcast_smart_disabled) { + } else if (!config.position.position_broadcast_smart_disabled) { // Only send packets if the channel is less than 25% utilized. if (airTime->channelUtilizationPercent() < 25) { diff --git a/src/modules/Telemetry/DeviceTelemetry.cpp b/src/modules/Telemetry/DeviceTelemetry.cpp index 4568521c3..b58441bf7 100644 --- a/src/modules/Telemetry/DeviceTelemetry.cpp +++ b/src/modules/Telemetry/DeviceTelemetry.cpp @@ -1,8 +1,8 @@ #include "DeviceTelemetry.h" #include "../mesh/generated/telemetry.pb.h" -#include "PowerFSM.h" #include "MeshService.h" #include "NodeDB.h" +#include "PowerFSM.h" #include "RTC.h" #include "Router.h" #include "configuration.h" @@ -20,7 +20,8 @@ int32_t DeviceTelemetryModule::runOnce() } sendOurTelemetry(); // OSThread library. Multiply the preference value by 1000 to convert seconds to miliseconds - return (getPref_telemetry_module_device_update_interval() * 1000); + + return getIntervalOrDefaultMs(moduleConfig.telemetry.device_update_interval); #endif } @@ -32,7 +33,7 @@ bool DeviceTelemetryModule::handleReceivedProtobuf(const MeshPacket &mp, Telemet DEBUG_MSG("-----------------------------------------\n"); DEBUG_MSG("Device Telemetry: Received data from %s\n", sender); DEBUG_MSG("Telemetry->time: %i\n", t->time); - DEBUG_MSG("Telemetry->air_util_tx: %f\n", t->variant.device_metrics.air_util_tx ); + DEBUG_MSG("Telemetry->air_util_tx: %f\n", t->variant.device_metrics.air_util_tx); DEBUG_MSG("Telemetry->battery_level: %i\n", t->variant.device_metrics.battery_level); DEBUG_MSG("Telemetry->channel_utilization: %f\n", t->variant.device_metrics.channel_utilization); DEBUG_MSG("Telemetry->voltage: %f\n", t->variant.device_metrics.voltage); diff --git a/src/modules/Telemetry/DeviceTelemetry.h b/src/modules/Telemetry/DeviceTelemetry.h index c224a2c1d..1a10ffcfa 100644 --- a/src/modules/Telemetry/DeviceTelemetry.h +++ b/src/modules/Telemetry/DeviceTelemetry.h @@ -1,5 +1,6 @@ #pragma once #include "../mesh/generated/telemetry.pb.h" +#include "NodeDB.h" #include "ProtobufModule.h" #include #include @@ -8,8 +9,7 @@ class DeviceTelemetryModule : private concurrency::OSThread, public ProtobufModu { public: DeviceTelemetryModule() - : concurrency::OSThread("DeviceTelemetryModule"), - ProtobufModule("DeviceTelemetry", PortNum_TELEMETRY_APP, &Telemetry_msg) + : concurrency::OSThread("DeviceTelemetryModule"), ProtobufModule("DeviceTelemetry", PortNum_TELEMETRY_APP, &Telemetry_msg) { lastMeasurementPacket = nullptr; } diff --git a/src/modules/Telemetry/EnvironmentTelemetry.cpp b/src/modules/Telemetry/EnvironmentTelemetry.cpp index 0257fe311..534819d86 100644 --- a/src/modules/Telemetry/EnvironmentTelemetry.cpp +++ b/src/modules/Telemetry/EnvironmentTelemetry.cpp @@ -1,8 +1,8 @@ #include "EnvironmentTelemetry.h" #include "../mesh/generated/telemetry.pb.h" -#include "PowerFSM.h" #include "MeshService.h" #include "NodeDB.h" +#include "PowerFSM.h" #include "RTC.h" #include "Router.h" #include "configuration.h" @@ -50,17 +50,17 @@ int32_t EnvironmentTelemetryModule::runOnce() without having to configure it from the PythonAPI or WebUI. */ /* - radioConfig.preferences.telemetry_module_environment_measurement_enabled = 1; - radioConfig.preferences.telemetry_module_environment_screen_enabled = 1; - radioConfig.preferences.telemetry_module_environment_read_error_count_threshold = 5; - radioConfig.preferences.telemetry_module_environment_update_interval = 600; - radioConfig.preferences.telemetry_module_environment_recovery_interval = 60; - radioConfig.preferences.telemetry_module_environment_sensor_pin = 13; // If one-wire - radioConfig.preferences.telemetry_module_environment_sensor_type = RadioConfig_UserPreferences_TelemetrySensorType::RadioConfig_UserPreferences_TelemetrySensorType_BME280; + moduleConfig.telemetry.environment_measurement_enabled = 1; + moduleConfig.telemetry.environment_screen_enabled = 1; + moduleConfig.telemetry.environment_read_error_count_threshold = 5; + moduleConfig.telemetry.environment_update_interval = 600; + moduleConfig.telemetry.environment_recovery_interval = 60; + moduleConfig.telemetry.environment_sensor_pin = 13; // If one-wire + moduleConfig.telemetry.environment_sensor_type = TelemetrySensorType::TelemetrySensorType_BME280; */ - - if (!(radioConfig.preferences.telemetry_module_environment_measurement_enabled || - radioConfig.preferences.telemetry_module_environment_screen_enabled)) { + + if (!(moduleConfig.telemetry.environment_measurement_enabled || + moduleConfig.telemetry.environment_screen_enabled)) { // If this module is not enabled, and the user doesn't want the display screen don't waste any OSThread time on it return (INT32_MAX); } @@ -69,83 +69,81 @@ int32_t EnvironmentTelemetryModule::runOnce() // This is the first time the OSThread library has called this function, so do some setup firstTime = 0; - if (radioConfig.preferences.telemetry_module_environment_measurement_enabled) { + if (moduleConfig.telemetry.environment_measurement_enabled) { DEBUG_MSG("Environment Telemetry: Initializing\n"); // it's possible to have this module enabled, only for displaying values on the screen. // therefore, we should only enable the sensor loop if measurement is also enabled - switch (radioConfig.preferences.telemetry_module_environment_sensor_type) { + switch (moduleConfig.telemetry.environment_sensor_type) { - case RadioConfig_UserPreferences_TelemetrySensorType_DHT11: - case RadioConfig_UserPreferences_TelemetrySensorType_DHT12: - case RadioConfig_UserPreferences_TelemetrySensorType_DHT21: - case RadioConfig_UserPreferences_TelemetrySensorType_DHT22: - return dhtSensor.runOnce(); - case RadioConfig_UserPreferences_TelemetrySensorType_DS18B20: - return dallasSensor.runOnce(); - case RadioConfig_UserPreferences_TelemetrySensorType_BME280: - return bme280Sensor.runOnce(); - case RadioConfig_UserPreferences_TelemetrySensorType_BME680: - return bme680Sensor.runOnce(); - case RadioConfig_UserPreferences_TelemetrySensorType_MCP9808: - return mcp9808Sensor.runOnce(); - default: - DEBUG_MSG("Environment Telemetry: Invalid sensor type selected; Disabling module"); - return (INT32_MAX); - break; + case TelemetrySensorType_DHT11: + case TelemetrySensorType_DHT12: + case TelemetrySensorType_DHT21: + case TelemetrySensorType_DHT22: + return dhtSensor.runOnce(); + case TelemetrySensorType_DS18B20: + return dallasSensor.runOnce(); + case TelemetrySensorType_BME280: + return bme280Sensor.runOnce(); + case TelemetrySensorType_BME680: + return bme680Sensor.runOnce(); + case TelemetrySensorType_MCP9808: + return mcp9808Sensor.runOnce(); + default: + DEBUG_MSG("Environment Telemetry: Invalid sensor type selected; Disabling module"); + return (INT32_MAX); + break; } } return (INT32_MAX); } else { // if we somehow got to a second run of this module with measurement disabled, then just wait forever - if (!radioConfig.preferences.telemetry_module_environment_measurement_enabled) + if (!moduleConfig.telemetry.environment_measurement_enabled) return (INT32_MAX); // this is not the first time OSThread library has called this function // so just do what we intend to do on the interval - if (sensor_read_error_count > radioConfig.preferences.telemetry_module_environment_read_error_count_threshold) { - if (radioConfig.preferences.telemetry_module_environment_recovery_interval > 0) { + if (sensor_read_error_count > moduleConfig.telemetry.environment_read_error_count_threshold) { + if (moduleConfig.telemetry.environment_recovery_interval > 0) { DEBUG_MSG("Environment Telemetry: TEMPORARILY DISABLED; The " "telemetry_module_environment_read_error_count_threshold has been exceed: %d. Will retry reads in " "%d seconds\n", - radioConfig.preferences.telemetry_module_environment_read_error_count_threshold, - radioConfig.preferences.telemetry_module_environment_recovery_interval); + moduleConfig.telemetry.environment_read_error_count_threshold, + moduleConfig.telemetry.environment_recovery_interval); sensor_read_error_count = 0; - return (radioConfig.preferences.telemetry_module_environment_recovery_interval * 1000); + return (moduleConfig.telemetry.environment_recovery_interval * 1000); } DEBUG_MSG("Environment Telemetry: DISABLED; The telemetry_module_environment_read_error_count_threshold has " "been exceed: %d. Reads will not be retried until after device reset\n", - radioConfig.preferences.telemetry_module_environment_read_error_count_threshold); + moduleConfig.telemetry.environment_read_error_count_threshold); return (INT32_MAX); } else if (sensor_read_error_count > 0) { DEBUG_MSG("Environment Telemetry: There have been %d sensor read failures. Will retry %d more times\n", sensor_read_error_count, sensor_read_error_count, sensor_read_error_count, - radioConfig.preferences.telemetry_module_environment_read_error_count_threshold - - sensor_read_error_count); + moduleConfig.telemetry.environment_read_error_count_threshold - sensor_read_error_count); } if (!sendOurTelemetry()) { // if we failed to read the sensor, then try again // as soon as we can according to the maximum polling frequency - switch (radioConfig.preferences.telemetry_module_environment_sensor_type) { - case RadioConfig_UserPreferences_TelemetrySensorType_DHT11: - case RadioConfig_UserPreferences_TelemetrySensorType_DHT12: - case RadioConfig_UserPreferences_TelemetrySensorType_DHT21: - case RadioConfig_UserPreferences_TelemetrySensorType_DHT22: - return (DHT_SENSOR_MINIMUM_WAIT_TIME_BETWEEN_READS); - case RadioConfig_UserPreferences_TelemetrySensorType_DS18B20: - return (DS18B20_SENSOR_MINIMUM_WAIT_TIME_BETWEEN_READS); - case RadioConfig_UserPreferences_TelemetrySensorType_BME280: - case RadioConfig_UserPreferences_TelemetrySensorType_BME680: - return (BME_SENSOR_MINIMUM_WAIT_TIME_BETWEEN_READS); - case RadioConfig_UserPreferences_TelemetrySensorType_MCP9808: - return (MCP_SENSOR_MINIMUM_WAIT_TIME_BETWEEN_READS); - default: - return (DEFAULT_SENSOR_MINIMUM_WAIT_TIME_BETWEEN_READS); + switch (moduleConfig.telemetry.environment_sensor_type) { + case TelemetrySensorType_DHT11: + case TelemetrySensorType_DHT12: + case TelemetrySensorType_DHT21: + case TelemetrySensorType_DHT22: + return (DHT_SENSOR_MINIMUM_WAIT_TIME_BETWEEN_READS); + case TelemetrySensorType_DS18B20: + return (DS18B20_SENSOR_MINIMUM_WAIT_TIME_BETWEEN_READS); + case TelemetrySensorType_BME280: + case TelemetrySensorType_BME680: + return (BME_SENSOR_MINIMUM_WAIT_TIME_BETWEEN_READS); + case TelemetrySensorType_MCP9808: + return (MCP_SENSOR_MINIMUM_WAIT_TIME_BETWEEN_READS); + default: + return (DEFAULT_SENSOR_MINIMUM_WAIT_TIME_BETWEEN_READS); } } } - // OSThread library. Multiply the preference value by 1000 to convert seconds to miliseconds - return (getPref_telemetry_module_environment_update_interval() * 1000); + return getIntervalOrDefaultMs(moduleConfig.telemetry.environment_update_interval); #endif } @@ -163,7 +161,7 @@ uint32_t GetTimeSinceMeshPacket(const MeshPacket *mp) bool EnvironmentTelemetryModule::wantUIFrame() { - return radioConfig.preferences.telemetry_module_environment_screen_enabled; + return moduleConfig.telemetry.environment_screen_enabled; } float EnvironmentTelemetryModule::CelsiusToFahrenheit(float c) @@ -197,13 +195,16 @@ void EnvironmentTelemetryModule::drawFrame(OLEDDisplay *display, OLEDDisplayUiSt display->setFont(FONT_SMALL); String last_temp = String(lastMeasurement.variant.environment_metrics.temperature, 0) + "°C"; - if (radioConfig.preferences.telemetry_module_environment_display_fahrenheit) { + if (moduleConfig.telemetry.environment_display_fahrenheit) { last_temp = String(CelsiusToFahrenheit(lastMeasurement.variant.environment_metrics.temperature), 0) + "°F"; } display->drawString(x, y += fontHeight(FONT_MEDIUM) - 2, "From: " + String(lastSender) + "(" + String(agoSecs) + "s)"); - display->drawString(x, y += fontHeight(FONT_SMALL) - 2, "Temp/Hum: " + last_temp + " / " + String(lastMeasurement.variant.environment_metrics.relative_humidity, 0) + "%"); - if (lastMeasurement.variant.environment_metrics.barometric_pressure != 0) - display->drawString(x, y += fontHeight(FONT_SMALL), "Press: " + String(lastMeasurement.variant.environment_metrics.barometric_pressure, 0) + "hPA"); + display->drawString(x, y += fontHeight(FONT_SMALL) - 2, + "Temp/Hum: " + last_temp + " / " + + String(lastMeasurement.variant.environment_metrics.relative_humidity, 0) + "%"); + if (lastMeasurement.variant.environment_metrics.barometric_pressure != 0) + display->drawString(x, y += fontHeight(FONT_SMALL), + "Press: " + String(lastMeasurement.variant.environment_metrics.barometric_pressure, 0) + "hPA"); } bool EnvironmentTelemetryModule::handleReceivedProtobuf(const MeshPacket &mp, Telemetry *t) @@ -239,33 +240,33 @@ bool EnvironmentTelemetryModule::sendOurTelemetry(NodeNum dest, bool wantReplies m.variant.environment_metrics.relative_humidity = 0; m.variant.environment_metrics.temperature = 0; m.variant.environment_metrics.voltage = 0; - + DEBUG_MSG("-----------------------------------------\n"); DEBUG_MSG("Environment Telemetry: Read data\n"); - switch (radioConfig.preferences.telemetry_module_environment_sensor_type) { - case RadioConfig_UserPreferences_TelemetrySensorType_DS18B20: - if (!dallasSensor.getMeasurement(&m)) - sensor_read_error_count++; - break; - case RadioConfig_UserPreferences_TelemetrySensorType_DHT11: - case RadioConfig_UserPreferences_TelemetrySensorType_DHT12: - case RadioConfig_UserPreferences_TelemetrySensorType_DHT21: - case RadioConfig_UserPreferences_TelemetrySensorType_DHT22: - if (!dhtSensor.getMeasurement(&m)) - sensor_read_error_count++; - break; - case RadioConfig_UserPreferences_TelemetrySensorType_BME280: - bme280Sensor.getMeasurement(&m); - break; - case RadioConfig_UserPreferences_TelemetrySensorType_BME680: - bme680Sensor.getMeasurement(&m); - break; - case RadioConfig_UserPreferences_TelemetrySensorType_MCP9808: - mcp9808Sensor.getMeasurement(&m); - break; - default: - DEBUG_MSG("Environment Telemetry: No external sensor type selected; Only sending internal metrics\n"); + switch (moduleConfig.telemetry.environment_sensor_type) { + case TelemetrySensorType_DS18B20: + if (!dallasSensor.getMeasurement(&m)) + sensor_read_error_count++; + break; + case TelemetrySensorType_DHT11: + case TelemetrySensorType_DHT12: + case TelemetrySensorType_DHT21: + case TelemetrySensorType_DHT22: + if (!dhtSensor.getMeasurement(&m)) + sensor_read_error_count++; + break; + case TelemetrySensorType_BME280: + bme280Sensor.getMeasurement(&m); + break; + case TelemetrySensorType_BME680: + bme680Sensor.getMeasurement(&m); + break; + case TelemetrySensorType_MCP9808: + mcp9808Sensor.getMeasurement(&m); + break; + default: + DEBUG_MSG("Environment Telemetry: No external sensor type selected; Only sending internal metrics\n"); } DEBUG_MSG("Telemetry->time: %i\n", m.time); diff --git a/src/modules/Telemetry/EnvironmentTelemetry.h b/src/modules/Telemetry/EnvironmentTelemetry.h index c1cdc9994..e6e526e3f 100644 --- a/src/modules/Telemetry/EnvironmentTelemetry.h +++ b/src/modules/Telemetry/EnvironmentTelemetry.h @@ -1,5 +1,6 @@ #pragma once #include "../mesh/generated/telemetry.pb.h" +#include "NodeDB.h" #include "ProtobufModule.h" #include #include @@ -14,7 +15,11 @@ class EnvironmentTelemetryModule : private concurrency::OSThread, public Protobu lastMeasurementPacket = nullptr; } virtual bool wantUIFrame() override; +#ifdef NO_SCREEN + void drawFrame(OLEDDisplay *display, OLEDDisplayUiState *state, int16_t x, int16_t y); +#else virtual void drawFrame(OLEDDisplay *display, OLEDDisplayUiState *state, int16_t x, int16_t y) override; +#endif protected: /** Called to handle a particular incoming message diff --git a/src/modules/Telemetry/Sensor/DHTSensor.cpp b/src/modules/Telemetry/Sensor/DHTSensor.cpp index 063adced5..5ccb8b0e1 100644 --- a/src/modules/Telemetry/Sensor/DHTSensor.cpp +++ b/src/modules/Telemetry/Sensor/DHTSensor.cpp @@ -1,31 +1,29 @@ -#include "../mesh/generated/telemetry.pb.h" -#include "configuration.h" +#include "DHTSensor.h" +#include "./mesh/generated/telemetry.pb.h" #include "MeshService.h" #include "TelemetrySensor.h" -#include "DHTSensor.h" +#include "configuration.h" #include -DHTSensor::DHTSensor() : TelemetrySensor {} { -} +DHTSensor::DHTSensor() : TelemetrySensor{} {} -int32_t DHTSensor::runOnce() { - if (RadioConfig_UserPreferences_TelemetrySensorType_DHT11 || - RadioConfig_UserPreferences_TelemetrySensorType_DHT12) { - dht = new DHT(radioConfig.preferences.telemetry_module_environment_sensor_pin, DHT11); - } - else { - dht = new DHT(radioConfig.preferences.telemetry_module_environment_sensor_pin, DHT22); +int32_t DHTSensor::runOnce() +{ + if (TelemetrySensorType_DHT11 || TelemetrySensorType_DHT12) { + dht = new DHT(moduleConfig.telemetry.environment_sensor_pin, DHT11); + } else { + dht = new DHT(moduleConfig.telemetry.environment_sensor_pin, DHT22); } dht->begin(); dht->read(); - DEBUG_MSG("Telemetry: Opened DHT11/DHT12 on pin: %d\n", - radioConfig.preferences.telemetry_module_environment_sensor_pin); + DEBUG_MSG("Telemetry: Opened DHT11/DHT12 on pin: %d\n", moduleConfig.telemetry.environment_sensor_pin); return (DHT_SENSOR_MINIMUM_WAIT_TIME_BETWEEN_READS); } -bool DHTSensor::getMeasurement(Telemetry *measurement) { +bool DHTSensor::getMeasurement(Telemetry *measurement) +{ if (!dht->read(true)) { DEBUG_MSG("Telemetry: FAILED TO READ DATA\n"); return false; @@ -33,4 +31,4 @@ bool DHTSensor::getMeasurement(Telemetry *measurement) { measurement->variant.environment_metrics.relative_humidity = dht->readHumidity(); measurement->variant.environment_metrics.temperature = dht->readTemperature(); return true; -} \ No newline at end of file +} \ No newline at end of file diff --git a/src/modules/Telemetry/Sensor/DallasSensor.cpp b/src/modules/Telemetry/Sensor/DallasSensor.cpp index 1be369d79..23fc57cfb 100644 --- a/src/modules/Telemetry/Sensor/DallasSensor.cpp +++ b/src/modules/Telemetry/Sensor/DallasSensor.cpp @@ -1,31 +1,31 @@ +#include "DallasSensor.h" #include "../mesh/generated/telemetry.pb.h" -#include "configuration.h" #include "MeshService.h" #include "TelemetrySensor.h" -#include "DallasSensor.h" +#include "configuration.h" #include #include -DallasSensor::DallasSensor() : TelemetrySensor {} { -} +DallasSensor::DallasSensor() : TelemetrySensor{} {} -int32_t DallasSensor::runOnce() { - oneWire = new OneWire(radioConfig.preferences.telemetry_module_environment_sensor_pin); +int32_t DallasSensor::runOnce() +{ + oneWire = new OneWire(moduleConfig.telemetry.environment_sensor_pin); ds18b20 = new DS18B20(oneWire); ds18b20->begin(); ds18b20->setResolution(12); ds18b20->requestTemperatures(); - DEBUG_MSG("Telemetry: Opened DS18B20 on pin: %d\n", - radioConfig.preferences.telemetry_module_environment_sensor_pin); + DEBUG_MSG("Telemetry: Opened DS18B20 on pin: %d\n", moduleConfig.telemetry.environment_sensor_pin); return (DS18B20_SENSOR_MINIMUM_WAIT_TIME_BETWEEN_READS); } -bool DallasSensor::getMeasurement(Telemetry *measurement) { +bool DallasSensor::getMeasurement(Telemetry *measurement) +{ if (ds18b20->isConversionComplete()) { measurement->variant.environment_metrics.temperature = ds18b20->getTempC(); measurement->variant.environment_metrics.relative_humidity = 0; ds18b20->requestTemperatures(); return true; - } + } return false; } \ No newline at end of file diff --git a/src/modules/Telemetry/Sensor/TelemetrySensor.h b/src/modules/Telemetry/Sensor/TelemetrySensor.h index 327ef8aaa..d2f38cf60 100644 --- a/src/modules/Telemetry/Sensor/TelemetrySensor.h +++ b/src/modules/Telemetry/Sensor/TelemetrySensor.h @@ -1,12 +1,14 @@ #pragma once #include "../mesh/generated/telemetry.pb.h" +#include "NodeDB.h" #define DEFAULT_SENSOR_MINIMUM_WAIT_TIME_BETWEEN_READS 1000 -class TelemetrySensor { -protected: - TelemetrySensor() { } +class TelemetrySensor +{ + protected: + TelemetrySensor() {} -public: + public: virtual int32_t runOnce() = 0; - virtual bool getMeasurement(Telemetry *measurement) = 0; + virtual bool getMeasurement(Telemetry *measurement) = 0; }; diff --git a/src/modules/esp32/RangeTestModule.cpp b/src/modules/esp32/RangeTestModule.cpp index 3ce06d537..71b1bbb53 100644 --- a/src/modules/esp32/RangeTestModule.cpp +++ b/src/modules/esp32/RangeTestModule.cpp @@ -36,23 +36,23 @@ int32_t RangeTestModule::runOnce() without having to configure it from the PythonAPI or WebUI. */ - // radioConfig.preferences.range_test_module_enabled = 1; - // radioConfig.preferences.range_test_module_sender = 45; - // radioConfig.preferences.range_test_module_save = 1; + // moduleConfig.range_test.enabled = 1; + // moduleConfig.range_test.sender = 45; + // moduleConfig.range_test.save = 1; // Fixed position is useful when testing indoors. // radioConfig.preferences.fixed_position = 1; - uint32_t senderHeartbeat = radioConfig.preferences.range_test_module_sender * 1000; + uint32_t senderHeartbeat = moduleConfig.range_test.sender * 1000; - if (radioConfig.preferences.range_test_module_enabled) { + if (moduleConfig.range_test.enabled) { if (firstTime) { rangeTestModuleRadio = new RangeTestModuleRadio(); firstTime = 0; - if (radioConfig.preferences.range_test_module_sender) { + if (moduleConfig.range_test.sender) { DEBUG_MSG("Initializing Range Test Module -- Sender\n"); return (5000); // Sending first message 5 seconds after initilization. } else { @@ -62,7 +62,7 @@ int32_t RangeTestModule::runOnce() } else { - if (radioConfig.preferences.range_test_module_sender) { + if (moduleConfig.range_test.sender) { // If sender DEBUG_MSG("Range Test Module - Sending heartbeat every %d ms\n", (senderHeartbeat)); @@ -71,7 +71,7 @@ int32_t RangeTestModule::runOnce() DEBUG_MSG("gpsStatus->getHasLock() %d\n", gpsStatus->getHasLock()); DEBUG_MSG("gpsStatus->getDOP() %d\n", gpsStatus->getDOP()); DEBUG_MSG("gpsStatus->getHasLock() %d\n", gpsStatus->getHasLock()); - DEBUG_MSG("pref.fixed_position() %d\n", radioConfig.preferences.fixed_position); + DEBUG_MSG("pref.fixed_position() %d\n", config.position.fixed_position); // Only send packets if the channel is less than 25% utilized. if (airTime->channelUtilizationPercent() < 25) { @@ -131,7 +131,7 @@ ProcessMessage RangeTestModuleRadio::handleReceived(const MeshPacket &mp) { #ifndef NO_ESP32 - if (radioConfig.preferences.range_test_module_enabled) { + if (moduleConfig.range_test.enabled) { /* auto &p = mp.decoded; @@ -141,7 +141,7 @@ ProcessMessage RangeTestModuleRadio::handleReceived(const MeshPacket &mp) if (getFrom(&mp) != nodeDB.getNodeNum()) { - if (radioConfig.preferences.range_test_module_save) { + if (moduleConfig.range_test.save) { appendFile(mp); } diff --git a/src/modules/esp32/SerialModule.cpp b/src/modules/esp32/SerialModule.cpp index 46f778f87..f0bf1666c 100644 --- a/src/modules/esp32/SerialModule.cpp +++ b/src/modules/esp32/SerialModule.cpp @@ -1,9 +1,9 @@ -#include "configuration.h" #include "SerialModule.h" #include "MeshService.h" #include "NodeDB.h" #include "RTC.h" #include "Router.h" +#include "configuration.h" #include #include @@ -20,18 +20,18 @@ Basic Usage: - 1) Enable the module by setting serial_module_enabled to 1. - 2) Set the pins (serial_module_rxd / serial_module_rxd) for your preferred RX and TX GPIO pins. + 1) Enable the module by setting enabled to 1. + 2) Set the pins (rxd / rxd) for your preferred RX and TX GPIO pins. On tbeam, recommend to use: RXD 35 TXD 15 - 3) Set serial_module_timeout to the amount of time to wait before we consider + 3) Set timeout to the amount of time to wait before we consider your packet as "done". 4) (Optional) In SerialModule.h set the port to PortNum_TEXT_MESSAGE_APP if you want to send messages to/from the general text message channel. 5) Connect to your device over the serial interface at 38400 8N1. 6) Send a packet up to 240 bytes in length. This will get relayed over the mesh network. - 7) (Optional) Set serial_module_echo to 1 and any message you send out will be echoed back + 7) (Optional) Set echo to 1 and any message you send out will be echoed back to your device. TODO (in this order): @@ -48,11 +48,11 @@ #define RXD2 16 #define TXD2 17 -#define SERIAL_MODULE_RX_BUFFER 128 -#define SERIAL_MODULE_STRING_MAX Constants_DATA_PAYLOAD_LEN -#define SERIAL_MODULE_TIMEOUT 250 -#define SERIAL_MODULE_BAUD 38400 -#define SERIAL_MODULE_ACK 1 +#define RX_BUFFER 128 +#define STRING_MAX Constants_DATA_PAYLOAD_LEN +#define TIMEOUT 250 +#define BAUD 38400 +#define ACK 1 SerialModule *serialModule; SerialModuleRadio *serialModuleRadio; @@ -76,89 +76,86 @@ int32_t SerialModule::runOnce() without having to configure it from the PythonAPI or WebUI. */ - // radioConfig.preferences.serial_module_enabled = 1; - // radioConfig.preferences.serial_module_rxd = 35; - // radioConfig.preferences.serial_module_txd = 15; - // radioConfig.preferences.serial_module_timeout = 1000; - // radioConfig.preferences.serial_module_echo = 1; + // moduleConfig.serial.enabled = 1; + // moduleConfig.serial.rxd = 35; + // moduleConfig.serial.txd = 15; + // moduleConfig.serial.timeout = 1000; + // moduleConfig.serial.echo = 1; - if (radioConfig.preferences.serial_module_enabled) { + if (moduleConfig.serial.enabled) { if (firstTime) { // Interface with the serial peripheral from in here. DEBUG_MSG("Initializing serial peripheral interface\n"); - + uint32_t baud = 0; - if (radioConfig.preferences.serial_module_baud == RadioConfig_UserPreferences_Serial_Baud_BAUD_Default) { + if (moduleConfig.serial.baud == ModuleConfig_SerialConfig_Serial_Baud_BAUD_Default) { baud = 38400; - - } else if (radioConfig.preferences.serial_module_baud == RadioConfig_UserPreferences_Serial_Baud_BAUD_110) { + + } else if (moduleConfig.serial.baud == ModuleConfig_SerialConfig_Serial_Baud_BAUD_110) { baud = 110; - } else if (radioConfig.preferences.serial_module_baud == RadioConfig_UserPreferences_Serial_Baud_BAUD_300) { + } else if (moduleConfig.serial.baud == ModuleConfig_SerialConfig_Serial_Baud_BAUD_300) { baud = 300; - } else if (radioConfig.preferences.serial_module_baud == RadioConfig_UserPreferences_Serial_Baud_BAUD_600) { + } else if (moduleConfig.serial.baud == ModuleConfig_SerialConfig_Serial_Baud_BAUD_600) { baud = 600; - } else if (radioConfig.preferences.serial_module_baud == RadioConfig_UserPreferences_Serial_Baud_BAUD_1200) { + } else if (moduleConfig.serial.baud == ModuleConfig_SerialConfig_Serial_Baud_BAUD_1200) { baud = 1200; - } else if (radioConfig.preferences.serial_module_baud == RadioConfig_UserPreferences_Serial_Baud_BAUD_2400) { + } else if (moduleConfig.serial.baud == ModuleConfig_SerialConfig_Serial_Baud_BAUD_2400) { baud = 2400; - } else if (radioConfig.preferences.serial_module_baud == RadioConfig_UserPreferences_Serial_Baud_BAUD_4800) { + } else if (moduleConfig.serial.baud == ModuleConfig_SerialConfig_Serial_Baud_BAUD_4800) { baud = 4800; - } else if (radioConfig.preferences.serial_module_baud == RadioConfig_UserPreferences_Serial_Baud_BAUD_9600) { + } else if (moduleConfig.serial.baud == ModuleConfig_SerialConfig_Serial_Baud_BAUD_9600) { baud = 9600; - } else if (radioConfig.preferences.serial_module_baud == RadioConfig_UserPreferences_Serial_Baud_BAUD_19200) { + } else if (moduleConfig.serial.baud == ModuleConfig_SerialConfig_Serial_Baud_BAUD_19200) { baud = 19200; - } else if (radioConfig.preferences.serial_module_baud == RadioConfig_UserPreferences_Serial_Baud_BAUD_38400) { + } else if (moduleConfig.serial.baud == ModuleConfig_SerialConfig_Serial_Baud_BAUD_38400) { baud = 38400; - } else if (radioConfig.preferences.serial_module_baud == RadioConfig_UserPreferences_Serial_Baud_BAUD_57600) { + } else if (moduleConfig.serial.baud == ModuleConfig_SerialConfig_Serial_Baud_BAUD_57600) { baud = 57600; - } else if (radioConfig.preferences.serial_module_baud == RadioConfig_UserPreferences_Serial_Baud_BAUD_115200) { + } else if (moduleConfig.serial.baud == ModuleConfig_SerialConfig_Serial_Baud_BAUD_115200) { baud = 115200; - } else if (radioConfig.preferences.serial_module_baud == RadioConfig_UserPreferences_Serial_Baud_BAUD_230400) { + } else if (moduleConfig.serial.baud == ModuleConfig_SerialConfig_Serial_Baud_BAUD_230400) { baud = 230400; - } else if (radioConfig.preferences.serial_module_baud == RadioConfig_UserPreferences_Serial_Baud_BAUD_460800) { + } else if (moduleConfig.serial.baud == ModuleConfig_SerialConfig_Serial_Baud_BAUD_460800) { baud = 460800; - } else if (radioConfig.preferences.serial_module_baud == RadioConfig_UserPreferences_Serial_Baud_BAUD_576000) { + } else if (moduleConfig.serial.baud == ModuleConfig_SerialConfig_Serial_Baud_BAUD_576000) { baud = 576000; - } else if (radioConfig.preferences.serial_module_baud == RadioConfig_UserPreferences_Serial_Baud_BAUD_921600) { + } else if (moduleConfig.serial.baud == ModuleConfig_SerialConfig_Serial_Baud_BAUD_921600) { baud = 921600; - - } - if (radioConfig.preferences.serial_module_rxd && radioConfig.preferences.serial_module_txd) { - Serial2.begin(baud, SERIAL_8N1, radioConfig.preferences.serial_module_rxd, - radioConfig.preferences.serial_module_txd); + if (moduleConfig.serial.rxd && moduleConfig.serial.txd) { + Serial2.begin(baud, SERIAL_8N1, moduleConfig.serial.rxd, moduleConfig.serial.txd); } else { Serial2.begin(baud, SERIAL_8N1, RXD2, TXD2); } - if (radioConfig.preferences.serial_module_timeout) { + if (moduleConfig.serial.timeout) { Serial2.setTimeout( - radioConfig.preferences.serial_module_timeout); // Number of MS to wait to set the timeout for the string. + moduleConfig.serial.timeout); // Number of MS to wait to set the timeout for the string. } else { - Serial2.setTimeout(SERIAL_MODULE_TIMEOUT); // Number of MS to wait to set the timeout for the string. + Serial2.setTimeout(TIMEOUT); // Number of MS to wait to set the timeout for the string. } - Serial2.setRxBufferSize(SERIAL_MODULE_RX_BUFFER); + Serial2.setRxBufferSize(RX_BUFFER); serialModuleRadio = new SerialModuleRadio(); @@ -202,7 +199,7 @@ void SerialModuleRadio::sendPayload(NodeNum dest, bool wantReplies) p->to = dest; p->decoded.want_response = wantReplies; - p->want_ack = SERIAL_MODULE_ACK; + p->want_ack = ACK; p->decoded.payload.size = strlen(serialStringChar); // You must specify how many bytes are in the reply memcpy(p->decoded.payload.bytes, serialStringChar, p->decoded.payload.size); @@ -214,7 +211,7 @@ ProcessMessage SerialModuleRadio::handleReceived(const MeshPacket &mp) { #ifndef NO_ESP32 - if (radioConfig.preferences.serial_module_enabled) { + if (moduleConfig.serial.enabled) { auto &p = mp.decoded; // DEBUG_MSG("Received text msg self=0x%0x, from=0x%0x, to=0x%0x, id=%d, msg=%.*s\n", @@ -223,10 +220,10 @@ ProcessMessage SerialModuleRadio::handleReceived(const MeshPacket &mp) if (getFrom(&mp) == nodeDB.getNodeNum()) { /* - * If radioConfig.preferences.serial_module_echo is true, then echo the packets that are sent out back to the TX - * of the serial interface. + * If moduleConfig.serial.echo is true, then echo the packets that are sent out + * back to the TX of the serial interface. */ - if (radioConfig.preferences.serial_module_echo) { + if (moduleConfig.serial.echo) { // For some reason, we get the packet back twice when we send out of the radio. // TODO: need to find out why. @@ -240,13 +237,13 @@ ProcessMessage SerialModuleRadio::handleReceived(const MeshPacket &mp) } else { - if (radioConfig.preferences.serial_module_mode == RadioConfig_UserPreferences_Serial_Mode_MODE_Default || radioConfig.preferences.serial_module_mode == RadioConfig_UserPreferences_Serial_Mode_MODE_SIMPLE) { + if (moduleConfig.serial.mode == ModuleConfig_SerialConfig_Serial_Mode_MODE_Default || + moduleConfig.serial.mode == ModuleConfig_SerialConfig_Serial_Mode_MODE_SIMPLE) { // DEBUG_MSG("* * Message came from the mesh\n"); // Serial2.println("* * Message came from the mesh"); Serial2.printf("%s", p.payload.bytes); - } else if (radioConfig.preferences.serial_module_mode == RadioConfig_UserPreferences_Serial_Mode_MODE_PROTO) { - + } else if (moduleConfig.serial.mode == ModuleConfig_SerialConfig_Serial_Mode_MODE_PROTO) { } } diff --git a/src/modules/esp32/StoreForwardModule.cpp b/src/modules/esp32/StoreForwardModule.cpp index a3fc2a3f0..6ba14346e 100644 --- a/src/modules/esp32/StoreForwardModule.cpp +++ b/src/modules/esp32/StoreForwardModule.cpp @@ -19,13 +19,12 @@ int32_t StoreForwardModule::runOnce() #ifndef NO_ESP32 - if (radioConfig.preferences.store_forward_module_enabled) { + if (moduleConfig.store_forward.enabled) { - if (radioConfig.preferences.role == Role_Router) { + if (config.device.role == Config_DeviceConfig_Role_Router) { // Send out the message queue. if (this->busy) { - // Only send packets if the channel is less than 25% utilized. if (airTime->channelUtilizationPercent() < 25) { @@ -43,7 +42,7 @@ int32_t StoreForwardModule::runOnce() } else { this->packetHistoryTXQueue_index++; } - + } else { DEBUG_MSG("Channel utilization is too high. Skipping this opportunity to send and will retry later.\n"); } @@ -243,7 +242,7 @@ void StoreForwardModule::sendMessage(NodeNum dest, char *str) ProcessMessage StoreForwardModule::handleReceived(const MeshPacket &mp) { #ifndef NO_ESP32 - if (radioConfig.preferences.store_forward_module_enabled) { + if (moduleConfig.store_forward.enabled) { DEBUG_MSG("--- S&F Received something\n"); @@ -267,10 +266,11 @@ ProcessMessage StoreForwardModule::handleReceived(const MeshPacket &mp) } } else if ((p.payload.bytes[0] == 'S') && (p.payload.bytes[1] == 'F') && (p.payload.bytes[2] == 'm') && (p.payload.bytes[3] == 0x00)) { - strlcpy(this->routerMessage, "01234567890123456789012345678901234567890123456789012345678901234567890123456789" - "01234567890123456789012345678901234567890123456789012345678901234567890123456789" - "01234567890123456789012345678901234567890123456789012345678901234567890123456", - sizeof(this->routerMessage)); + strlcpy(this->routerMessage, + "01234567890123456789012345678901234567890123456789012345678901234567890123456789" + "01234567890123456789012345678901234567890123456789012345678901234567890123456789" + "01234567890123456789012345678901234567890123456789012345678901234567890123456", + sizeof(this->routerMessage)); storeForwardModule->sendMessage(getFrom(&mp), this->routerMessage); } else { @@ -295,7 +295,7 @@ ProcessMessage StoreForwardModule::handleReceived(const MeshPacket &mp) ProcessMessage StoreForwardModule::handleReceivedProtobuf(const MeshPacket &mp, StoreAndForward *p) { - if (!radioConfig.preferences.store_forward_module_enabled) { + if (!moduleConfig.store_forward.enabled) { // If this module is not enabled in any capacity, don't handle the packet, and allow other modules to consume return ProcessMessage::CONTINUE; } @@ -391,14 +391,14 @@ StoreForwardModule::StoreForwardModule() without having to configure it from the PythonAPI or WebUI. */ - radioConfig.preferences.store_forward_module_enabled = 1; - radioConfig.preferences.is_always_powered = 1; + moduleConfig.store_forward.enabled = 1; + config.power.is_always_powered = 1; } - if (radioConfig.preferences.store_forward_module_enabled) { + if (moduleConfig.store_forward.enabled) { // Router - if (radioConfig.preferences.role == Role_Router) { + if (config.device.role == Config_DeviceConfig_Role_Router) { DEBUG_MSG("Initializing Store & Forward Module - Enabled as Router\n"); if (ESP.getPsramSize()) { if (ESP.getFreePsram() >= 1024 * 1024) { @@ -406,20 +406,20 @@ StoreForwardModule::StoreForwardModule() // Do the startup here // Maximum number of records to return. - if (radioConfig.preferences.store_forward_module_history_return_max) - this->historyReturnMax = radioConfig.preferences.store_forward_module_history_return_max; + if (moduleConfig.store_forward.history_return_max) + this->historyReturnMax = moduleConfig.store_forward.history_return_max; // Maximum time window for records to return (in minutes) - if (radioConfig.preferences.store_forward_module_history_return_window) - this->historyReturnWindow = radioConfig.preferences.store_forward_module_history_return_window; + if (moduleConfig.store_forward.history_return_window) + this->historyReturnWindow = moduleConfig.store_forward.history_return_window; // Maximum number of records to store in memory - if (radioConfig.preferences.store_forward_module_records) - this->records = radioConfig.preferences.store_forward_module_records; + if (moduleConfig.store_forward.records) + this->records = moduleConfig.store_forward.records; // Maximum number of records to store in memory - if (radioConfig.preferences.store_forward_module_heartbeat) - this->heartbeat = radioConfig.preferences.store_forward_module_heartbeat; + if (moduleConfig.store_forward.heartbeat) + this->heartbeat = moduleConfig.store_forward.heartbeat; // Popupate PSRAM with our data structures. this->populatePSRAM(); diff --git a/src/mqtt/MQTT.cpp b/src/mqtt/MQTT.cpp index 6f2841149..4c50ff741 100644 --- a/src/mqtt/MQTT.cpp +++ b/src/mqtt/MQTT.cpp @@ -111,17 +111,18 @@ void MQTT::reconnect() const char *mqttUsername = "meshdev"; const char *mqttPassword = "large4cats"; - if (*radioConfig.preferences.mqtt_server) { - serverAddr = radioConfig.preferences.mqtt_server; // Override the default - mqttUsername = radioConfig.preferences.mqtt_username; // do not use the hardcoded credentials for a custom mqtt server - mqttPassword = radioConfig.preferences.mqtt_password; + if (*moduleConfig.mqtt.address) { + serverAddr = moduleConfig.mqtt.address; // Override the default + mqttUsername = + moduleConfig.mqtt.username; // do not use the hardcoded credentials for a custom mqtt server + mqttPassword = moduleConfig.mqtt.password; } else { // we are using the default server. Use the hardcoded credentials by default, but allow overriding - if (*radioConfig.preferences.mqtt_username && radioConfig.preferences.mqtt_username[0] != '\0') { - mqttUsername = radioConfig.preferences.mqtt_username; + if (*moduleConfig.mqtt.username && moduleConfig.mqtt.username[0] != '\0') { + mqttUsername = moduleConfig.mqtt.username; } - if (*radioConfig.preferences.mqtt_password && radioConfig.preferences.mqtt_password[0] != '\0') { - mqttPassword = radioConfig.preferences.mqtt_password; + if (*moduleConfig.mqtt.password && moduleConfig.mqtt.password[0] != '\0') { + mqttPassword = moduleConfig.mqtt.password; } } @@ -174,7 +175,7 @@ bool MQTT::wantsLink() const { bool hasChannel = false; - if (radioConfig.preferences.mqtt_disabled) { + if (moduleConfig.mqtt.disabled) { // DEBUG_MSG("MQTT disabled...\n"); } else { // No need for link if no channel needed it @@ -254,7 +255,7 @@ String MQTT::downstreamPacketToJson(MeshPacket *mp) { using namespace json11; - // the created jsonObj is immutable after creation, so + // the created jsonObj is immutable after creation, so // we need to do the heavy lifting before assembling it. String msgType; Json msgPayload; @@ -288,8 +289,7 @@ String MQTT::downstreamPacketToJson(MeshPacket *mp) Telemetry *decoded = NULL; if (mp->which_payloadVariant == MeshPacket_decoded_tag) { memset(&scratch, 0, sizeof(scratch)); - if (pb_decode_from_bytes(mp->decoded.payload.bytes, mp->decoded.payload.size, &Telemetry_msg, - &scratch)) { + if (pb_decode_from_bytes(mp->decoded.payload.bytes, mp->decoded.payload.size, &Telemetry_msg, &scratch)) { decoded = &scratch; if (decoded->which_variant == Telemetry_environment_metrics_tag) { msgPayload = Json::object{ diff --git a/src/shutdown.h b/src/shutdown.h index 17ceb75dd..3b703331d 100644 --- a/src/shutdown.h +++ b/src/shutdown.h @@ -1,8 +1,8 @@ +#include "buzz.h" #include "configuration.h" #include "graphics/Screen.h" -#include "power.h" -#include "buzz.h" #include "main.h" +#include "power.h" void powerCommandsCheck() { @@ -30,7 +30,7 @@ void powerCommandsCheck() DEBUG_MSG("Shutting down from admin command\n"); #ifdef TBEAM_V10 if (axp192_found == true) { - setLed(false); + // setLed(false); //TODO: FIXME: this is not working power->shutdown(); } #elif NRF52_SERIES diff --git a/src/sleep.cpp b/src/sleep.cpp index fce4f02a3..849ec33a1 100644 --- a/src/sleep.cpp +++ b/src/sleep.cpp @@ -1,9 +1,9 @@ -#include "configuration.h" #include "sleep.h" #include "GPS.h" #include "MeshRadio.h" #include "MeshService.h" #include "NodeDB.h" +#include "configuration.h" #include "error.h" #include "main.h" #include "target_specific.h" @@ -11,10 +11,10 @@ #ifndef NO_ESP32 #include "esp32/pm.h" #include "esp_pm.h" +#include "mesh/http/WiFiAPClient.h" #include "rom/rtc.h" #include #include -#include "mesh/http/WiFiAPClient.h" #include "nimble/BluetoothUtil.h" @@ -51,25 +51,25 @@ void setCPUFast(bool on) #ifndef NO_ESP32 if (isWifiAvailable()) { - /* - * - * There's a newly introduced bug in the espressif framework where WiFi is - * unstable when the frequency is less than 240mhz. - * - * This mostly impacts WiFi AP mode but we'll bump the frequency for - * all WiFi use cases. - * (Added: Dec 23, 2021 by Jm Casler) - */ + /* + * + * There's a newly introduced bug in the espressif framework where WiFi is + * unstable when the frequency is less than 240mhz. + * + * This mostly impacts WiFi AP mode but we'll bump the frequency for + * all WiFi use cases. + * (Added: Dec 23, 2021 by Jm Casler) + */ DEBUG_MSG("Setting CPU to 240mhz because WiFi is in use.\n"); setCpuFrequencyMhz(240); return; } - // The Heltec LORA32 V1 runs at 26 MHz base frequency and doesn't react well to switching to 80 MHz... - #ifndef ARDUINO_HELTEC_WIFI_LORA_32 - setCpuFrequencyMhz(on ? 240 : 80); - #endif - +// The Heltec LORA32 V1 runs at 26 MHz base frequency and doesn't react well to switching to 80 MHz... +#ifndef ARDUINO_HELTEC_WIFI_LORA_32 + setCpuFrequencyMhz(on ? 240 : 80); +#endif + #endif } @@ -284,12 +284,12 @@ esp_sleep_wakeup_cause_t doLightSleep(uint64_t sleepMsec) // FIXME, use a more r */ void enableModemSleep() { - static esp_pm_config_esp32_t config; // filled with zeros because bss + static esp_pm_config_esp32_t esp32_config; // filled with zeros because bss - config.max_freq_mhz = CONFIG_ESP32_DEFAULT_CPU_FREQ_MHZ; - config.min_freq_mhz = 20; // 10Mhz is minimum recommended - config.light_sleep_enable = false; - int rv = esp_pm_configure(&config); + esp32_config.max_freq_mhz = CONFIG_ESP32_DEFAULT_CPU_FREQ_MHZ; + esp32_config.min_freq_mhz = 20; // 10Mhz is minimum recommended + esp32_config.light_sleep_enable = false; + int rv = esp_pm_configure(&esp32_config); DEBUG_MSG("Sleep request result %x\n", rv); } #endif diff --git a/variants/Dongle_nRF52840-pca10059-v1/platformio.ini b/variants/Dongle_nRF52840-pca10059-v1/platformio.ini index e527dd988..10f31c5e5 100644 --- a/variants/Dongle_nRF52840-pca10059-v1/platformio.ini +++ b/variants/Dongle_nRF52840-pca10059-v1/platformio.ini @@ -2,7 +2,7 @@ extends = nrf52840_base board = nordic_pca10059 build_flags = ${nrf52840_base.build_flags} -Ivariants/Dongle_nRF52840-pca10059-v1 -D NORDIC_PCA10059 -src_filter = ${nrf52_base.src_filter} +<../variants/Dongle_nRF52840-pca10059-v1> +build_src_filter = ${nrf52_base.build_src_filter} +<../variants/Dongle_nRF52840-pca10059-v1> lib_deps = ${nrf52840_base.lib_deps} https://github.com/ZinggJM/GxEPD2.git diff --git a/variants/heltec_v1/variant.h b/variants/heltec_v1/variant.h index 7e1af42d1..9ea07eb0c 100644 --- a/variants/heltec_v1/variant.h +++ b/variants/heltec_v1/variant.h @@ -3,7 +3,7 @@ #undef GPS_RX_PIN #undef GPS_TX_PIN #define GPS_RX_PIN 36 -#define GPS_TX_PIN 34 +#define GPS_TX_PIN 33 #ifndef USE_JTAG // gpio15 is TDO for JTAG, so no I2C on this board while doing jtag #define I2C_SDA 4 // I2C pins for this board @@ -20,8 +20,8 @@ #ifndef USE_JTAG #define LORA_RESET 14 #endif -#define LORA_DIO1 33 // Not really used -#define LORA_DIO2 32 // Not really used +#define LORA_DIO1 35 // Not really used +#define LORA_DIO2 34 // Not really used // ratio of voltage divider = 3.20 (R1=100k, R2=220k) #define ADC_MULTIPLIER 3.2 diff --git a/variants/lora_isp4520/platformio.ini b/variants/lora_isp4520/platformio.ini index 0a946c7a8..fb9fdf913 100644 --- a/variants/lora_isp4520/platformio.ini +++ b/variants/lora_isp4520/platformio.ini @@ -6,7 +6,7 @@ board = lora_isp4520 build_flags = ${nrf52_base.build_flags} -Ivariants/lora_isp4520 # No screen and GPS on the board. We still need RTC.cpp for the RTC clock. -src_filter = ${nrf52_base.src_filter} +<../variants/lora_isp4520> - - + + +build_src_filter = ${nrf52_base.build_src_filter} +<../variants/lora_isp4520> - - + + lib_ignore = ${nrf52_base.lib_ignore} ESP8266_SSD1306 SparkFun Ublox Arduino Library diff --git a/variants/lora_relay_v1/platformio.ini b/variants/lora_relay_v1/platformio.ini index 78b338d9b..312108979 100644 --- a/variants/lora_relay_v1/platformio.ini +++ b/variants/lora_relay_v1/platformio.ini @@ -14,7 +14,7 @@ build_flags = ${nrf52840_base.build_flags} -Ivariants/lora_relay_v1 -DTFT_DC=ST7735_RS -DTFT_RST=ST7735_RESET -DSPI_FREQUENCY=27000000 -src_filter = ${nrf52_base.src_filter} +<../variants/lora_relay_v1> +build_src_filter = ${nrf52_base.build_src_filter} +<../variants/lora_relay_v1> lib_deps = ${nrf52840_base.lib_deps} SparkFun BQ27441 LiPo Fuel Gauge Arduino Library diff --git a/variants/lora_relay_v2/platformio.ini b/variants/lora_relay_v2/platformio.ini index 1a12713c8..f35b14c02 100644 --- a/variants/lora_relay_v2/platformio.ini +++ b/variants/lora_relay_v2/platformio.ini @@ -16,7 +16,7 @@ build_flags = ${nrf52840_base.build_flags} -Ivariants/lora_relay_v2 -DSPI_FREQUENCY=27000000 -DTFT_WR=ST7735_SDA -DTFT_SCLK=ST7735_SCK -src_filter = ${nrf52_base.src_filter} +<../variants/lora_relay_v2> +build_src_filter = ${nrf52_base.build_src_filter} +<../variants/lora_relay_v2> lib_deps = ${nrf52840_base.lib_deps} SparkFun BQ27441 LiPo Fuel Gauge Arduino Library diff --git a/variants/m5stack_core/Speaker.cpp b/variants/m5stack_core/Speaker.cpp new file mode 100644 index 000000000..0aaff1238 --- /dev/null +++ b/variants/m5stack_core/Speaker.cpp @@ -0,0 +1,33 @@ +#include "Speaker.h" + +TONE::TONE(void) { + _volume = 5; + _begun = false; +} + +void TONE::begin() { + _begun = true; + ledcSetup(TONE_PIN_CHANNEL, 0, 13); + ledcAttachPin(PIN_BUZZER, TONE_PIN_CHANNEL); +} + +void TONE::end() { + mute(); + ledcDetachPin(PIN_BUZZER); + _begun = false; +} + +void TONE::tone(uint16_t frequency) { + if(!_begun) begin(); + ledcWriteTone(TONE_PIN_CHANNEL, frequency); + ledcWrite(TONE_PIN_CHANNEL, 0x400 >> _volume); +} + +void TONE::setVolume(uint8_t volume) { + _volume = 11 - volume; +} + +void TONE::mute() { + ledcWriteTone(TONE_PIN_CHANNEL, 0); + digitalWrite(PIN_BUZZER, 0); +} \ No newline at end of file diff --git a/variants/m5stack_core/Speaker.h b/variants/m5stack_core/Speaker.h new file mode 100644 index 000000000..2ab877d9b --- /dev/null +++ b/variants/m5stack_core/Speaker.h @@ -0,0 +1,30 @@ +#ifndef _SPEAKER_H_ + #define _SPEAKER_H_ + + #include "configuration.h" + + #ifdef __cplusplus + extern "C" + { + #endif /* __cplusplus */ + #include "esp32-hal-dac.h" + #ifdef __cplusplus + } + #endif /* __cplusplus */ + + class TONE { + public: + TONE(void); + + void begin(); + void end(); + void mute(); + void tone(uint16_t frequency); + void setVolume(uint8_t volume); + + private: + uint8_t _volume; + bool _begun; + bool speaker_on; + }; +#endif diff --git a/variants/m5stack_core/platformio.ini b/variants/m5stack_core/platformio.ini new file mode 100644 index 000000000..c9227fed9 --- /dev/null +++ b/variants/m5stack_core/platformio.ini @@ -0,0 +1,30 @@ +[env:m5stack-core] +extends = esp32_base +board = m5stack-core-esp32 +upload_port = COM8 +monitor_port = COM8 +monitor_filters = esp32_exception_decoder +build_src_filter = + ${esp32_base.build_src_filter} + +<../variants/m5stack_core> +build_flags = + ${esp32_base.build_flags} -I variants/m5stack_core + -DILI9341_DRIVER + -DM5STACK + -DUSER_SETUP_LOADED + -DTFT_SDA_READ + -DTFT_DRIVER=0x9341 + -DTFT_MISO=19 + -DTFT_MOSI=23 + -DTFT_SCLK=18 + -DTFT_CS=14 + -DTFT_DC=27 + -DTFT_RST=33 + -DTFT_BL=32 + -DSPI_FREQUENCY=40000000 + -DSPI_READ_FREQUENCY=16000000 +lib_ignore = + m5stack-core +lib_deps = + ${esp32_base.lib_deps} + bodmer/TFT_eSPI@^2.4.61 \ No newline at end of file diff --git a/variants/m5stack_core/variant.h b/variants/m5stack_core/variant.h new file mode 100644 index 000000000..0fd294c60 --- /dev/null +++ b/variants/m5stack_core/variant.h @@ -0,0 +1,43 @@ +// #define BUTTON_NEED_PULLUP // if set we need to turn on the internal CPU pullup during sleep + +#define I2C_SDA 21 +#define I2C_SCL 22 + +// #define BUTTON_PIN 39 // 38, 37 +//#define BUTTON_PIN 0 +#define BUTTON_NEED_PULLUP +// #define EXT_NOTIFY_OUT 13 // Default pin to use for Ext Notify Plugin. + +#define BUTTON_PIN 38 + +#define PIN_BUZZER 25 +#define TONE_PIN_CHANNEL 0 + +#undef RF95_SCK +#undef RF95_MISO +#undef RF95_MOSI +#undef RF95_NSS + +#define RF95_SCK 18 +#define RF95_MISO 19 +#define RF95_MOSI 23 +#define RF95_NSS 5 + +#define USE_RF95 +#define LORA_DIO0 36 // a No connect on the SX1262 module +#define LORA_RESET 26 +#define LORA_DIO1 RADIOLIB_NC// Not really used +#define LORA_DIO2 RADIOLIB_NC// Not really used + +// This board has different GPS pins than all other boards +#undef GPS_RX_PIN +#undef GPS_TX_PIN +#define GPS_RX_PIN 16 +#define GPS_TX_PIN 17 + +// Define if screen should be mirrored left to right +#define SCREEN_ROTATE + +// LCD screens are slow, so slowdown the wipe so it looks better +#define SCREEN_TRANSITION_MSECS 1 +#define SCREEN_TRANSITION_FRAMERATE 1 // fps diff --git a/variants/pca10056-rc-clock/platformio.ini b/variants/pca10056-rc-clock/platformio.ini index 2eaa223f8..0dd317816 100644 --- a/variants/pca10056-rc-clock/platformio.ini +++ b/variants/pca10056-rc-clock/platformio.ini @@ -4,4 +4,4 @@ extends = nrf52840_base board = nrf52840_dk_modified # add our variants files to the include and src paths build_flags = ${nrf52_base.build_flags} -Ivariants/pca10056-rc-clock -src_filter = ${nrf52_base.src_filter} +<../variants/pca10056-rc-clock> \ No newline at end of file +build_src_filter = ${nrf52_base.build_src_filter} +<../variants/pca10056-rc-clock> \ No newline at end of file diff --git a/variants/portduino/platformio.ini b/variants/portduino/platformio.ini index dd37c3bc9..375c2c454 100644 --- a/variants/portduino/platformio.ini +++ b/variants/portduino/platformio.ini @@ -1,8 +1,8 @@ ; The Portduino based sim environment on top of any host OS, all hardware will be simulated [env:native] -platform = https://github.com/geeksville/platform-native.git -src_filter = - ${env.src_filter} +platform = https://github.com/meshtastic/platform-native.git +build_src_filter = + ${env.build_src_filter} - - - @@ -19,9 +19,9 @@ lib_deps = ; The Portduino based sim environment on top of a linux OS and touching linux hardware devices [env:linux] -platform = https://github.com/geeksville/platform-native.git -src_filter = - ${env.src_filter} +platform = https://github.com/meshtastic/platform-native.git +build_src_filter = + ${env.build_src_filter} - - - @@ -34,4 +34,4 @@ framework = arduino board = linux_hardware lib_deps = ${arduino_base.lib_deps} - rweather/Crypto \ No newline at end of file + rweather/Crypto diff --git a/variants/ppr1/platformio.ini b/variants/ppr1/platformio.ini index 6592e4718..40ad508f9 100644 --- a/variants/ppr1/platformio.ini +++ b/variants/ppr1/platformio.ini @@ -3,6 +3,6 @@ extends = nrf52_base board = ppr1 build_flags = ${nrf52_base.build_flags} -Ivariants/ppr1 -src_filter = ${nrf52_base.src_filter} +<../variants/ppr1> +build_src_filter = ${nrf52_base.build_src_filter} +<../variants/ppr1> lib_deps = ${arduino_base.lib_deps} \ No newline at end of file diff --git a/variants/rak4631/platformio.ini b/variants/rak4631/platformio.ini index fd9fbcd89..5671aae4d 100644 --- a/variants/rak4631/platformio.ini +++ b/variants/rak4631/platformio.ini @@ -3,7 +3,7 @@ extends = nrf52840_base board = wiscore_rak4631 build_flags = ${nrf52840_base.build_flags} -Ivariants/rak4631 -D RAK_4631 -src_filter = ${nrf52_base.src_filter} +<../variants/rak4631> +build_src_filter = ${nrf52_base.build_src_filter} +<../variants/rak4631> lib_deps = ${nrf52840_base.lib_deps} melopero/Melopero RV3028@^1.1.0 diff --git a/variants/rak4631/variant.h b/variants/rak4631/variant.h index bae5d957a..f1e144324 100644 --- a/variants/rak4631/variant.h +++ b/variants/rak4631/variant.h @@ -201,6 +201,9 @@ static const uint8_t SCK = PIN_SPI_SCK; // RAK12002 RTC Module #define RV3028_RTC (uint8_t) 0b1010010 +// RAK18001 Buzzer in Slot C +#define PIN_BUZZER 21 // IO3 is PWM2 + // Battery // The battery sense is hooked to pin A0 (5) #define BATTERY_PIN PIN_A0 diff --git a/variants/rak4631_epaper/platformio.ini b/variants/rak4631_epaper/platformio.ini index 55f799e25..048860cef 100644 --- a/variants/rak4631_epaper/platformio.ini +++ b/variants/rak4631_epaper/platformio.ini @@ -3,7 +3,7 @@ extends = nrf52840_base board = wiscore_rak4631 build_flags = ${nrf52840_base.build_flags} -Ivariants/rak4631_epaper -D RAK_4631 -src_filter = ${nrf52_base.src_filter} +<../variants/rak4631_epaper> +build_src_filter = ${nrf52_base.build_src_filter} +<../variants/rak4631_epaper> lib_deps = ${nrf52840_base.lib_deps} https://github.com/ZinggJM/GxEPD2.git diff --git a/variants/t-echo/platformio.ini b/variants/t-echo/platformio.ini index fca61584d..0544a69a0 100644 --- a/variants/t-echo/platformio.ini +++ b/variants/t-echo/platformio.ini @@ -9,7 +9,7 @@ upload_protocol = jlink # -DBUSY_PIN=3 -DRST_PIN=2 -DDC_PIN=28 -DCS_PIN=30 # add -DCFG_SYSVIEW if you want to use the Segger systemview tool for OS profiling. build_flags = ${nrf52840_base.build_flags} -Ivariants/t-echo -src_filter = ${nrf52_base.src_filter} +<../variants/t-echo> +build_src_filter = ${nrf52_base.build_src_filter} +<../variants/t-echo> lib_deps = ${nrf52840_base.lib_deps} https://github.com/meshtastic/GxEPD2