Merge branch 'master' into gps-fixedposboot

This commit is contained in:
Ben Meadors
2023-01-21 20:34:41 -06:00
committed by GitHub
318 changed files with 7783 additions and 7862 deletions
+1
View File
@@ -1,3 +1,4 @@
* text=auto eol=lf * text=auto eol=lf
*.{cmd,[cC][mM][dD]} text eol=crlf *.{cmd,[cC][mM][dD]} text eol=crlf
*.{bat,[bB][aA][tT]} text eol=crlf *.{bat,[bB][aA][tT]} text eol=crlf
*.{sh,[sS][hH]} text eol=lf
+5 -4
View File
@@ -8,16 +8,17 @@ plugins:
uri: https://github.com/trunk-io/plugins uri: https://github.com/trunk-io/plugins
lint: lint:
enabled: enabled:
- git-diff-check
- gitleaks@8.15.2
- clang-format@14.0.0
- prettier@2.8.3
disabled:
- shellcheck@0.9.0 - shellcheck@0.9.0
- shfmt@3.5.0 - shfmt@3.5.0
- oxipng@8.0.0 - oxipng@8.0.0
- actionlint@1.6.22 - actionlint@1.6.22
- git-diff-check
- gitleaks@8.15.2
- markdownlint@0.33.0 - markdownlint@0.33.0
- hadolint@2.12.0 - hadolint@2.12.0
- clang-format@14.0.0
- prettier@2.8.3
- svgo@3.0.2 - svgo@3.0.2
runtimes: runtimes:
enabled: enabled:
+3 -3
View File
@@ -1,5 +1,5 @@
cd protobufs && ..\nanopb-0.4.7\generator-bin\protoc.exe --nanopb_out=-v:..\src\mesh\generated -I=..\protobufs ..\protobufs\meshtastic\*.proto cd protobufs && ..\nanopb-0.4.7\generator-bin\protoc.exe --nanopb_out=-v:..\src\mesh\generated -I=..\protobufs ..\protobufs\meshtastic\*.proto
cd ../src/mesh/generated/meshtastic @REM cd ../src/mesh/generated/meshtastic
sed -i 's/#include "meshtastic/#include "./g' * @REM sed -i 's/#include "meshtastic/#include "./g' *
sed -i 's/meshtastic_//g' * @REM sed -i 's/meshtastic_//g' *
+3 -3
View File
@@ -10,10 +10,10 @@ echo "prebuilt binaries for your computer into nanopb-0.4.7"
cd protobufs cd protobufs
../nanopb-0.4.7/generator-bin/protoc --nanopb_out=-v:../src/mesh/generated/ -I=../protobufs meshtastic/*.proto ../nanopb-0.4.7/generator-bin/protoc --nanopb_out=-v:../src/mesh/generated/ -I=../protobufs meshtastic/*.proto
cd ../src/mesh/generated/meshtastic # cd ../src/mesh/generated/meshtastic
sed -i 's/#include "meshtastic/#include "./g' * # sed -i 's/#include "meshtastic/#include "./g' -- *
sed -i 's/meshtastic_//g' * # sed -i 's/meshtastic_//g' -- *
#echo "Regenerating protobuf documentation - if you see an error message" #echo "Regenerating protobuf documentation - if you see an error message"
#echo "you can ignore it unless doing a new protobuf release to github." #echo "you can ignore it unless doing a new protobuf release to github."
+5 -20
View File
@@ -7,12 +7,7 @@
"cpu": "cortex-m4", "cpu": "cortex-m4",
"extra_flags": "-DARDUINO_NRF52840_TTGO_EINK -DNRF52840_XXAA", "extra_flags": "-DARDUINO_NRF52840_TTGO_EINK -DNRF52840_XXAA",
"f_cpu": "64000000L", "f_cpu": "64000000L",
"hwids": [ "hwids": [["0x239A", "0x4405"]],
[
"0x239A",
"0x4405"
]
],
"usb_product": "TTGO_eink", "usb_product": "TTGO_eink",
"mcu": "nrf52840", "mcu": "nrf52840",
"variant": "eink0.1", "variant": "eink0.1",
@@ -30,19 +25,13 @@
"settings_addr": "0xFF000" "settings_addr": "0xFF000"
} }
}, },
"connectivity": [ "connectivity": ["bluetooth"],
"bluetooth"
],
"debug": { "debug": {
"jlink_device": "nRF52840_xxAA", "jlink_device": "nRF52840_xxAA",
"onboard_tools": [ "onboard_tools": ["jlink"],
"jlink"
],
"svd_path": "nrf52840.svd" "svd_path": "nrf52840.svd"
}, },
"frameworks": [ "frameworks": ["arduino"],
"arduino"
],
"name": "TTGO eink (Adafruit BSP)", "name": "TTGO eink (Adafruit BSP)",
"upload": { "upload": {
"maximum_ram_size": 248832, "maximum_ram_size": 248832,
@@ -50,11 +39,7 @@
"require_upload_port": true, "require_upload_port": true,
"speed": 115200, "speed": 115200,
"protocol": "jlink", "protocol": "jlink",
"protocols": [ "protocols": ["jlink", "nrfjprog", "stlink"]
"jlink",
"nrfjprog",
"stlink"
]
}, },
"url": "FIXME", "url": "FIXME",
"vendor": "TTGO" "vendor": "TTGO"
+2 -6
View File
@@ -9,9 +9,7 @@
"product_line": "STM32WLE5xx" "product_line": "STM32WLE5xx"
}, },
"debug": { "debug": {
"default_tools": [ "default_tools": ["stlink"],
"stlink"
],
"jlink_device": "STM32WLE5CC", "jlink_device": "STM32WLE5CC",
"openocd_target": "stm32wlx", "openocd_target": "stm32wlx",
"svd_path": "STM32WLE5_CM4.svd" "svd_path": "STM32WLE5_CM4.svd"
@@ -22,9 +20,7 @@
"maximum_ram_size": 65536, "maximum_ram_size": 65536,
"maximum_size": 262144, "maximum_size": 262144,
"protocol": "cmsis-dap", "protocol": "cmsis-dap",
"protocols": [ "protocols": ["cmsis-dap"]
"cmsis-dap"
]
}, },
"url": "https://www.st.com/en/microcontrollers-microprocessors/stm32wl-series.html", "url": "https://www.st.com/en/microcontrollers-microprocessors/stm32wl-series.html",
"vendor": "ST" "vendor": "ST"
+3 -12
View File
@@ -19,16 +19,12 @@
"sd_fwid": "0x00B7" "sd_fwid": "0x00B7"
} }
}, },
"connectivity": [ "connectivity": ["bluetooth"],
"bluetooth"
],
"debug": { "debug": {
"jlink_device": "nRF52832_xxAA", "jlink_device": "nRF52832_xxAA",
"svd_path": "nrf52.svd" "svd_path": "nrf52.svd"
}, },
"frameworks": [ "frameworks": ["arduino"],
"arduino"
],
"name": "lora ISP4520", "name": "lora ISP4520",
"upload": { "upload": {
"maximum_ram_size": 65536, "maximum_ram_size": 65536,
@@ -36,12 +32,7 @@
"require_upload_port": true, "require_upload_port": true,
"speed": 115200, "speed": 115200,
"protocol": "nrfutil", "protocol": "nrfutil",
"protocols": [ "protocols": ["jlink", "nrfjprog", "nrfutil", "stlink"]
"jlink",
"nrfjprog",
"nrfutil",
"stlink"
]
}, },
"url": "", "url": "",
"vendor": "PsiSoft" "vendor": "PsiSoft"
+7 -28
View File
@@ -8,22 +8,10 @@
"extra_flags": "-DARDUINO_NRF52840_FEATHER -DNRF52840_XXAA", "extra_flags": "-DARDUINO_NRF52840_FEATHER -DNRF52840_XXAA",
"f_cpu": "64000000L", "f_cpu": "64000000L",
"hwids": [ "hwids": [
[ ["0x239A", "0x8029"],
"0x239A", ["0x239A", "0x0029"],
"0x8029" ["0x239A", "0x002A"],
], ["0x239A", "0x802A"]
[
"0x239A",
"0x0029"
],
[
"0x239A",
"0x002A"
],
[
"0x239A",
"0x802A"
]
], ],
"usb_product": "PCA10059", "usb_product": "PCA10059",
"mcu": "nrf52840", "mcu": "nrf52840",
@@ -41,28 +29,19 @@
"settings_addr": "0xFF000" "settings_addr": "0xFF000"
} }
}, },
"connectivity": [ "connectivity": ["bluetooth"],
"bluetooth"
],
"debug": { "debug": {
"jlink_device": "nRF52840_xxAA", "jlink_device": "nRF52840_xxAA",
"svd_path": "nrf52840.svd" "svd_path": "nrf52840.svd"
}, },
"frameworks": [ "frameworks": ["arduino"],
"arduino"
],
"name": "nRF52840 Dongle", "name": "nRF52840 Dongle",
"upload": { "upload": {
"maximum_ram_size": 248832, "maximum_ram_size": 248832,
"maximum_size": 815104, "maximum_size": 815104,
"speed": 115200, "speed": 115200,
"protocol": "nrfutil", "protocol": "nrfutil",
"protocols": [ "protocols": ["jlink", "nrfjprog", "nrfutil", "stlink"],
"jlink",
"nrfjprog",
"nrfutil",
"stlink"
],
"use_1200bps_touch": true, "use_1200bps_touch": true,
"require_upload_port": true, "require_upload_port": true,
"wait_for_upload_port": true "wait_for_upload_port": true
-1
View File
@@ -44,4 +44,3 @@
"url": "https://meshtastic.org/", "url": "https://meshtastic.org/",
"vendor": "Nordic Semi" "vendor": "Nordic Semi"
} }
+5 -21
View File
@@ -7,12 +7,7 @@
"cpu": "cortex-m4", "cpu": "cortex-m4",
"extra_flags": "-DARDUINO_NRF52840_TTGO_EINK -DNRF52840_XXAA", "extra_flags": "-DARDUINO_NRF52840_TTGO_EINK -DNRF52840_XXAA",
"f_cpu": "64000000L", "f_cpu": "64000000L",
"hwids": [ "hwids": [["0x239A", "0x4405"]],
[
"0x239A",
"0x4405"
]
],
"usb_product": "TTGO_eink", "usb_product": "TTGO_eink",
"mcu": "nrf52840", "mcu": "nrf52840",
"variant": "t-echo", "variant": "t-echo",
@@ -30,31 +25,20 @@
"settings_addr": "0xFF000" "settings_addr": "0xFF000"
} }
}, },
"connectivity": [ "connectivity": ["bluetooth"],
"bluetooth"
],
"debug": { "debug": {
"jlink_device": "nRF52840_xxAA", "jlink_device": "nRF52840_xxAA",
"onboard_tools": [ "onboard_tools": ["jlink"],
"jlink"
],
"svd_path": "nrf52840.svd" "svd_path": "nrf52840.svd"
}, },
"frameworks": [ "frameworks": ["arduino"],
"arduino"
],
"name": "TTGO eink (Adafruit BSP)", "name": "TTGO eink (Adafruit BSP)",
"upload": { "upload": {
"maximum_ram_size": 248832, "maximum_ram_size": 248832,
"maximum_size": 815104, "maximum_size": 815104,
"speed": 115200, "speed": 115200,
"protocol": "nrfutil", "protocol": "nrfutil",
"protocols": [ "protocols": ["jlink", "nrfjprog", "nrfutil", "stlink"],
"jlink",
"nrfjprog",
"nrfutil",
"stlink"
],
"use_1200bps_touch": true, "use_1200bps_touch": true,
"require_upload_port": true, "require_upload_port": true,
"wait_for_upload_port": true "wait_for_upload_port": true
+3 -12
View File
@@ -15,24 +15,15 @@
"f_cpu": "240000000L", "f_cpu": "240000000L",
"f_flash": "80000000L", "f_flash": "80000000L",
"flash_mode": "dio", "flash_mode": "dio",
"hwids": [ "hwids": [["0X303A", "0x1001"]],
[
"0X303A",
"0x1001"
]
],
"mcu": "esp32s3", "mcu": "esp32s3",
"variant": "tbeam-s3-core" "variant": "tbeam-s3-core"
}, },
"connectivity": [ "connectivity": ["wifi"],
"wifi"
],
"debug": { "debug": {
"openocd_target": "esp32s3.cfg" "openocd_target": "esp32s3.cfg"
}, },
"frameworks": [ "frameworks": ["arduino"],
"arduino"
],
"name": "LilyGo TBeam-S3-Core", "name": "LilyGo TBeam-S3-Core",
"upload": { "upload": {
"flash_size": "8MB", "flash_size": "8MB",
+3 -13
View File
@@ -14,25 +14,15 @@
"f_cpu": "240000000L", "f_cpu": "240000000L",
"f_flash": "80000000L", "f_flash": "80000000L",
"flash_mode": "dio", "flash_mode": "dio",
"hwids": [ "hwids": [["0X303A", "0x1001"]],
[
"0X303A",
"0x1001"
]
],
"mcu": "esp32s3", "mcu": "esp32s3",
"variant": "tlora-t3s3-v1" "variant": "tlora-t3s3-v1"
}, },
"connectivity": [ "connectivity": ["wifi"],
"wifi"
],
"debug": { "debug": {
"openocd_target": "esp32s3.cfg" "openocd_target": "esp32s3.cfg"
}, },
"frameworks": [ "frameworks": ["arduino", "espidf"],
"arduino",
"espidf"
],
"name": "LilyGo TLora-T3S3-V1", "name": "LilyGo TLora-T3S3-V1",
"upload": { "upload": {
"flash_size": "4MB", "flash_size": "4MB",
+3 -15
View File
@@ -11,26 +11,14 @@
"mcu": "esp32", "mcu": "esp32",
"variant": "WisCore_RAK11200_Board" "variant": "WisCore_RAK11200_Board"
}, },
"connectivity": [ "connectivity": ["wifi", "bluetooth", "ethernet", "can"],
"wifi", "frameworks": ["arduino", "espidf"],
"bluetooth",
"ethernet",
"can"
],
"frameworks": [
"arduino",
"espidf"
],
"name": "WisCore RAK11200 Board", "name": "WisCore RAK11200 Board",
"upload": { "upload": {
"flash_size": "4MB", "flash_size": "4MB",
"maximum_ram_size": 327680, "maximum_ram_size": 327680,
"maximum_size": 4194304, "maximum_size": 4194304,
"protocols": [ "protocols": ["esptool", "espota", "ftdi"],
"esptool",
"espota",
"ftdi"
],
"require_upload_port": true, "require_upload_port": true,
"speed": 460800 "speed": 460800
}, },
+7 -29
View File
@@ -8,22 +8,10 @@
"extra_flags": "-DNRF52832_XXAA -DNRF52", "extra_flags": "-DNRF52832_XXAA -DNRF52",
"f_cpu": "64000000L", "f_cpu": "64000000L",
"hwids": [ "hwids": [
[ ["0x239A", "0x8029"],
"0x239A", ["0x239A", "0x0029"],
"0x8029" ["0x239A", "0x002A"],
], ["0x239A", "0x802A"]
[
"0x239A",
"0x0029"
],
[
"0x239A",
"0x002A"
],
[
"0x239A",
"0x802A"
]
], ],
"usb_product": "Feather nRF52832 Express", "usb_product": "Feather nRF52832 Express",
"mcu": "nrf52832", "mcu": "nrf52832",
@@ -41,17 +29,12 @@
"variant": "nrf52_adafruit_feather" "variant": "nrf52_adafruit_feather"
} }
}, },
"connectivity": [ "connectivity": ["bluetooth"],
"bluetooth"
],
"debug": { "debug": {
"jlink_device": "nRF52832_xxAA", "jlink_device": "nRF52832_xxAA",
"svd_path": "nrf52.svd" "svd_path": "nrf52.svd"
}, },
"frameworks": [ "frameworks": ["arduino", "zephyr"],
"arduino",
"zephyr"
],
"name": "Adafruit Bluefruit nRF52832 Feather", "name": "Adafruit Bluefruit nRF52832 Feather",
"upload": { "upload": {
"maximum_ram_size": 65536, "maximum_ram_size": 65536,
@@ -59,12 +42,7 @@
"require_upload_port": true, "require_upload_port": true,
"speed": 115200, "speed": 115200,
"protocol": "nrfutil", "protocol": "nrfutil",
"protocols": [ "protocols": ["jlink", "nrfjprog", "nrfutil", "stlink"]
"jlink",
"nrfjprog",
"nrfutil",
"stlink"
]
}, },
"url": "https://www.adafruit.com/product/3406", "url": "https://www.adafruit.com/product/3406",
"vendor": "Adafruit" "vendor": "Adafruit"
+7 -28
View File
@@ -8,22 +8,10 @@
"extra_flags": "-DARDUINO_NRF52840_FEATHER -DNRF52840_XXAA", "extra_flags": "-DARDUINO_NRF52840_FEATHER -DNRF52840_XXAA",
"f_cpu": "64000000L", "f_cpu": "64000000L",
"hwids": [ "hwids": [
[ ["0x239A", "0x8029"],
"0x239A", ["0x239A", "0x0029"],
"0x8029" ["0x239A", "0x002A"],
], ["0x239A", "0x802A"]
[
"0x239A",
"0x0029"
],
[
"0x239A",
"0x002A"
],
[
"0x239A",
"0x802A"
]
], ],
"usb_product": "WisCore RAK4631 Board", "usb_product": "WisCore RAK4631 Board",
"mcu": "nrf52840", "mcu": "nrf52840",
@@ -41,28 +29,19 @@
"settings_addr": "0xFF000" "settings_addr": "0xFF000"
} }
}, },
"connectivity": [ "connectivity": ["bluetooth"],
"bluetooth"
],
"debug": { "debug": {
"jlink_device": "nRF52840_xxAA", "jlink_device": "nRF52840_xxAA",
"svd_path": "nrf52840.svd" "svd_path": "nrf52840.svd"
}, },
"frameworks": [ "frameworks": ["arduino"],
"arduino"
],
"name": "WisCore RAK4631 Board", "name": "WisCore RAK4631 Board",
"upload": { "upload": {
"maximum_ram_size": 248832, "maximum_ram_size": 248832,
"maximum_size": 815104, "maximum_size": 815104,
"speed": 115200, "speed": 115200,
"protocol": "nrfutil", "protocol": "nrfutil",
"protocols": [ "protocols": ["jlink", "nrfjprog", "nrfutil", "stlink"],
"jlink",
"nrfjprog",
"nrfutil",
"stlink"
],
"use_1200bps_touch": true, "use_1200bps_touch": true,
"require_upload_port": true, "require_upload_port": true,
"wait_for_upload_port": true "wait_for_upload_port": true
+1 -1
View File
@@ -39,7 +39,7 @@ extra_scripts = bin/platformio-custom.py
; The Radiolib stuff will speed up building considerably. Exclud all the stuff we dont need. ; The Radiolib stuff will speed up building considerably. Exclud all the stuff we dont need.
build_flags = -Wno-missing-field-initializers build_flags = -Wno-missing-field-initializers
-Wno-format -Wno-format
-Isrc -Isrc/mesh -Isrc/gps -Isrc/buzz -Wl,-Map,.pio/build/output.map -Isrc -Isrc/mesh -Isrc/mesh/generated -Isrc/gps -Isrc/buzz -Wl,-Map,.pio/build/output.map
-DUSE_THREAD_NAMES -DUSE_THREAD_NAMES
-DTINYGPS_OPTION_NO_CUSTOM_FIELDS -DTINYGPS_OPTION_NO_CUSTOM_FIELDS
-DPB_ENABLE_MALLOC=1 -DPB_ENABLE_MALLOC=1
+1 -1
View File
@@ -1,5 +1,5 @@
#include "configuration.h"
#include "BluetoothCommon.h" #include "BluetoothCommon.h"
#include "configuration.h"
// NRF52 wants these constants as byte arrays // NRF52 wants these constants as byte arrays
// Generated here https://yupana-engineering.com/online-uuid-to-c-array-converter - but in REVERSE BYTE ORDER // Generated here https://yupana-engineering.com/online-uuid-to-c-array-converter - but in REVERSE BYTE ORDER
+3 -10
View File
@@ -1,17 +1,15 @@
#include "configuration.h"
#include "FSCommon.h" #include "FSCommon.h"
#include "configuration.h"
#ifdef HAS_SDCARD #ifdef HAS_SDCARD
#include <SPI.h>
#include <SD.h> #include <SD.h>
#include <SPI.h>
#ifdef SDCARD_USE_SPI1 #ifdef SDCARD_USE_SPI1
SPIClass SPI1(HSPI); SPIClass SPI1(HSPI);
#define SDHandler SPI1 #define SDHandler SPI1
#endif #endif
#endif // HAS_SDCARD #endif // HAS_SDCARD
bool copyFile(const char *from, const char *to) bool copyFile(const char *from, const char *to)
@@ -168,8 +166,7 @@ void rmDir(const char * dirname)
void fsInit() void fsInit()
{ {
#ifdef FSCom #ifdef FSCom
if (!FSBegin()) if (!FSBegin()) {
{
LOG_ERROR("Filesystem mount Failed.\n"); LOG_ERROR("Filesystem mount Failed.\n");
// assert(0); This auto-formats the partition, so no need to fail here. // assert(0); This auto-formats the partition, so no need to fail here.
} }
@@ -182,7 +179,6 @@ void fsInit()
#endif #endif
} }
void setupSDCard() void setupSDCard()
{ {
#ifdef HAS_SDCARD #ifdef HAS_SDCARD
@@ -214,6 +210,3 @@ void setupSDCard()
LOG_DEBUG("Used space: %llu MB\n", SD.usedBytes() / (1024 * 1024)); LOG_DEBUG("Used space: %llu MB\n", SD.usedBytes() / (1024 * 1024));
#endif #endif
} }
+22 -13
View File
@@ -22,13 +22,13 @@ class GPSStatus : public Status
bool isPowerSaving = false; // Are we in power saving state bool isPowerSaving = false; // Are we in power saving state
Position p = Position_init_default; meshtastic_Position p = meshtastic_Position_init_default;
public: public:
GPSStatus() { statusType = STATUS_TYPE_GPS; } GPSStatus() { statusType = STATUS_TYPE_GPS; }
// preferred method // preferred method
GPSStatus(bool hasLock, bool isConnected, bool isPowerSaving, const Position &pos) : Status() GPSStatus(bool hasLock, bool isConnected, bool isPowerSaving, const meshtastic_Position &pos) : Status()
{ {
this->hasLock = hasLock; this->hasLock = hasLock;
this->isConnected = isConnected; this->isConnected = isConnected;
@@ -55,7 +55,7 @@ class GPSStatus : public Status
#ifdef GPS_EXTRAVERBOSE #ifdef GPS_EXTRAVERBOSE
LOG_WARN("Using fixed latitude\n"); LOG_WARN("Using fixed latitude\n");
#endif #endif
NodeInfo *node = nodeDB.getNode(nodeDB.getNodeNum()); meshtastic_NodeInfo *node = nodeDB.getNode(nodeDB.getNodeNum());
return node->position.latitude_i; return node->position.latitude_i;
} else { } else {
return p.latitude_i; return p.latitude_i;
@@ -68,7 +68,7 @@ class GPSStatus : public Status
#ifdef GPS_EXTRAVERBOSE #ifdef GPS_EXTRAVERBOSE
LOG_WARN("Using fixed longitude\n"); LOG_WARN("Using fixed longitude\n");
#endif #endif
NodeInfo *node = nodeDB.getNode(nodeDB.getNodeNum()); meshtastic_NodeInfo *node = nodeDB.getNode(nodeDB.getNodeNum());
return node->position.longitude_i; return node->position.longitude_i;
} else { } else {
return p.longitude_i; return p.longitude_i;
@@ -81,29 +81,38 @@ class GPSStatus : public Status
#ifdef GPS_EXTRAVERBOSE #ifdef GPS_EXTRAVERBOSE
LOG_WARN("Using fixed altitude\n"); LOG_WARN("Using fixed altitude\n");
#endif #endif
NodeInfo *node = nodeDB.getNode(nodeDB.getNodeNum()); meshtastic_NodeInfo *node = nodeDB.getNode(nodeDB.getNodeNum());
return node->position.altitude; return node->position.altitude;
} else { } else {
return p.altitude; return p.altitude;
} }
} }
uint32_t getDOP() const { return p.PDOP; } uint32_t getDOP() const
{
return p.PDOP;
}
uint32_t getHeading() const { return p.ground_track; } uint32_t getHeading() const
{
return p.ground_track;
}
uint32_t getNumSatellites() const { return p.sats_in_view; } uint32_t getNumSatellites() const
{
return p.sats_in_view;
}
bool matches(const GPSStatus *newStatus) const bool matches(const GPSStatus *newStatus) const
{ {
#ifdef GPS_EXTRAVERBOSE #ifdef GPS_EXTRAVERBOSE
LOG_DEBUG("GPSStatus.match() new pos@%x to old pos@%x\n", newStatus->p.pos_timestamp, p.pos_timestamp); LOG_DEBUG("GPSStatus.match() new pos@%x to old pos@%x\n", newStatus->p.pos_timestamp, p.pos_timestamp);
#endif #endif
return (newStatus->hasLock != hasLock || newStatus->isConnected != isConnected || newStatus->isPowerSaving !=isPowerSaving || return (newStatus->hasLock != hasLock || newStatus->isConnected != isConnected ||
newStatus->p.latitude_i != p.latitude_i || newStatus->p.longitude_i != p.longitude_i || newStatus->isPowerSaving != isPowerSaving || newStatus->p.latitude_i != p.latitude_i ||
newStatus->p.altitude != p.altitude || newStatus->p.altitude_hae != p.altitude_hae || newStatus->p.longitude_i != p.longitude_i || newStatus->p.altitude != p.altitude ||
newStatus->p.PDOP != p.PDOP || newStatus->p.ground_track != p.ground_track || newStatus->p.altitude_hae != p.altitude_hae || newStatus->p.PDOP != p.PDOP ||
newStatus->p.ground_speed != p.ground_speed || newStatus->p.ground_track != p.ground_track || newStatus->p.ground_speed != p.ground_speed ||
newStatus->p.sats_in_view != p.sats_in_view); newStatus->p.sats_in_view != p.sats_in_view);
} }
+14 -29
View File
@@ -1,16 +1,18 @@
#pragma once #pragma once
#include <Arduino.h>
#include "Status.h" #include "Status.h"
#include "configuration.h" #include "configuration.h"
#include <Arduino.h>
namespace meshtastic { namespace meshtastic
{
/// Describes the state of the NodeDB system. /// Describes the state of the NodeDB system.
class NodeStatus : public Status class NodeStatus : public Status
{ {
private: private:
CallbackObserver<NodeStatus, const NodeStatus *> statusObserver = CallbackObserver<NodeStatus, const NodeStatus *>(this, &NodeStatus::updateStatus); CallbackObserver<NodeStatus, const NodeStatus *> statusObserver =
CallbackObserver<NodeStatus, const NodeStatus *>(this, &NodeStatus::updateStatus);
uint8_t numOnline = 0; uint8_t numOnline = 0;
uint8_t numTotal = 0; uint8_t numTotal = 0;
@@ -20,9 +22,7 @@ namespace meshtastic {
public: public:
bool forceUpdate = false; bool forceUpdate = false;
NodeStatus() { NodeStatus() { statusType = STATUS_TYPE_NODE; }
statusType = STATUS_TYPE_NODE;
}
NodeStatus(uint8_t numOnline, uint8_t numTotal, bool forceUpdate = false) : Status() NodeStatus(uint8_t numOnline, uint8_t numTotal, bool forceUpdate = false) : Status()
{ {
this->forceUpdate = forceUpdate; this->forceUpdate = forceUpdate;
@@ -32,34 +32,20 @@ namespace meshtastic {
NodeStatus(const NodeStatus &); NodeStatus(const NodeStatus &);
NodeStatus &operator=(const NodeStatus &); NodeStatus &operator=(const NodeStatus &);
void observe(Observable<const NodeStatus *> *source) void observe(Observable<const NodeStatus *> *source) { statusObserver.observe(source); }
{
statusObserver.observe(source);
}
uint8_t getNumOnline() const uint8_t getNumOnline() const { return numOnline; }
{
return numOnline;
}
uint8_t getNumTotal() const uint8_t getNumTotal() const { return numTotal; }
{
return numTotal;
}
uint8_t getLastNumTotal() const uint8_t getLastNumTotal() const { return lastNumTotal; }
{
return lastNumTotal;
}
bool matches(const NodeStatus *newStatus) const bool matches(const NodeStatus *newStatus) const
{ {
return ( return (newStatus->getNumOnline() != numOnline || newStatus->getNumTotal() != numTotal);
newStatus->getNumOnline() != numOnline ||
newStatus->getNumTotal() != numTotal
);
} }
int updateStatus(const NodeStatus *newStatus) { int updateStatus(const NodeStatus *newStatus)
{
// Only update the status if values have actually changed // Only update the status if values have actually changed
lastNumTotal = numTotal; lastNumTotal = numTotal;
bool isDirty; bool isDirty;
@@ -75,9 +61,8 @@ namespace meshtastic {
} }
return 0; return 0;
} }
}; };
} } // namespace meshtastic
extern meshtastic::NodeStatus *nodeStatus; extern meshtastic::NodeStatus *nodeStatus;
+1 -1
View File
@@ -1,5 +1,5 @@
#include "configuration.h"
#include "OSTimer.h" #include "OSTimer.h"
#include "configuration.h"
/** /**
* Schedule a callback to run. The callback must _not_ block, though it is called from regular thread level (not ISR) * Schedule a callback to run. The callback must _not_ block, though it is called from regular thread level (not ISR)
+1 -2
View File
@@ -1,3 +1,2 @@
#include "configuration.h"
#include "Observer.h" #include "Observer.h"
#include "configuration.h"
+45 -28
View File
@@ -1,16 +1,16 @@
#include "power.h" #include "power.h"
#include "NodeDB.h" #include "NodeDB.h"
#include "PowerFSM.h" #include "PowerFSM.h"
#include "buzz/buzz.h"
#include "configuration.h" #include "configuration.h"
#include "main.h" #include "main.h"
#include "sleep.h" #include "sleep.h"
#include "utils.h" #include "utils.h"
#include "buzz/buzz.h"
#ifdef HAS_PMU #ifdef HAS_PMU
#include "XPowersLibInterface.hpp"
#include "XPowersAXP2101.tpp"
#include "XPowersAXP192.tpp" #include "XPowersAXP192.tpp"
#include "XPowersAXP2101.tpp"
#include "XPowersLibInterface.hpp"
XPowersLibInterface *PMU = NULL; XPowersLibInterface *PMU = NULL;
#else #else
// Copy of the base class defined in axp20x.h. // Copy of the base class defined in axp20x.h.
@@ -108,15 +108,15 @@ class AnalogBatteryLevel : public HasBatteryLevel
#ifdef BATTERY_PIN #ifdef BATTERY_PIN
// Override variant or default ADC_MULTIPLIER if we have the override pref // Override variant or default ADC_MULTIPLIER if we have the override pref
float operativeAdcMultiplier = config.power.adc_multiplier_override > 0 float operativeAdcMultiplier =
? config.power.adc_multiplier_override config.power.adc_multiplier_override > 0 ? config.power.adc_multiplier_override : ADC_MULTIPLIER;
: ADC_MULTIPLIER;
// Do not call analogRead() often. // Do not call analogRead() often.
const uint32_t min_read_interval = 5000; const uint32_t min_read_interval = 5000;
if (millis() - last_read_time_ms > min_read_interval) { if (millis() - last_read_time_ms > min_read_interval) {
last_read_time_ms = millis(); last_read_time_ms = millis();
//Set the number of samples, it has an effect of increasing sensitivity, especially in complex electromagnetic environment. // Set the number of samples, it has an effect of increasing sensitivity, especially in complex electromagnetic
// environment.
uint32_t raw = 0; uint32_t raw = 0;
for (uint32_t i = 0; i < BATTERY_SENSE_SAMPLES; i++) { for (uint32_t i = 0; i < BATTERY_SENSE_SAMPLES; i++) {
raw += analogRead(BATTERY_PIN); raw += analogRead(BATTERY_PIN);
@@ -143,15 +143,24 @@ class AnalogBatteryLevel : public HasBatteryLevel
/** /**
* return true if there is a battery installed in this unit * return true if there is a battery installed in this unit
*/ */
virtual bool isBatteryConnect() override { return getBatteryPercent() != -1; } virtual bool isBatteryConnect() override
{
return getBatteryPercent() != -1;
}
/// If we see a battery voltage higher than physics allows - assume charger is pumping /// If we see a battery voltage higher than physics allows - assume charger is pumping
/// in power /// in power
virtual bool isVbusIn() override { return getBattVoltage() > chargingVolt; } virtual bool isVbusIn() override
{
return getBattVoltage() > chargingVolt;
}
/// Assume charging if we have a battery and external power is connected. /// Assume charging if we have a battery and external power is connected.
/// we can't be smart enough to say 'full'? /// we can't be smart enough to say 'full'?
virtual bool isCharging() override { return isBatteryConnect() && isVbusIn(); } virtual bool isCharging() override
{
return isBatteryConnect() && isVbusIn();
}
private: private:
/// If we see a battery voltage higher than physics allows - assume charger is pumping /// If we see a battery voltage higher than physics allows - assume charger is pumping
@@ -298,7 +307,8 @@ void Power::readPowerStatus()
} }
} }
LOG_DEBUG("\n"); LOG_DEBUG("\n");
LOG_DEBUG("Heap status: %d/%d bytes free (%d), running %d/%d threads\n", ESP.getFreeHeap(), ESP.getHeapSize(), ESP.getFreeHeap() - lastheap, running, concurrency::mainController.size(false)); LOG_DEBUG("Heap status: %d/%d bytes free (%d), running %d/%d threads\n", ESP.getFreeHeap(), ESP.getHeapSize(),
ESP.getFreeHeap() - lastheap, running, concurrency::mainController.size(false));
lastheap = ESP.getFreeHeap(); lastheap = ESP.getFreeHeap();
} }
#endif #endif
@@ -450,7 +460,6 @@ bool Power::axpChipInit()
PMU->setPowerChannelVoltage(XPOWERS_LDO2, 3300); PMU->setPowerChannelVoltage(XPOWERS_LDO2, 3300);
PMU->enablePowerOutput(XPOWERS_LDO2); PMU->enablePowerOutput(XPOWERS_LDO2);
// oled module power channel, // oled module power channel,
// disable it will cause abnormal communication between boot and AXP power supply, // disable it will cause abnormal communication between boot and AXP power supply,
// do not turn it off // do not turn it off
@@ -458,12 +467,10 @@ bool Power::axpChipInit()
// enable oled power // enable oled power
PMU->enablePowerOutput(XPOWERS_DCDC1); PMU->enablePowerOutput(XPOWERS_DCDC1);
// gnss module power channel - now turned on in setGpsPower // gnss module power channel - now turned on in setGpsPower
PMU->setPowerChannelVoltage(XPOWERS_LDO3, 3300); PMU->setPowerChannelVoltage(XPOWERS_LDO3, 3300);
// PMU->enablePowerOutput(XPOWERS_LDO3); // PMU->enablePowerOutput(XPOWERS_LDO3);
// protected oled power source // protected oled power source
PMU->setProtectedChannel(XPOWERS_DCDC1); PMU->setProtectedChannel(XPOWERS_DCDC1);
// protected esp32 power source // protected esp32 power source
@@ -537,7 +544,6 @@ bool Power::axpChipInit()
PMU->setChargeTargetVoltage(XPOWERS_AXP2101_CHG_VOL_4V2); PMU->setChargeTargetVoltage(XPOWERS_AXP2101_CHG_VOL_4V2);
} }
PMU->clearIrqStatus(); PMU->clearIrqStatus();
// TBeam1.1 /T-Beam S3-Core has no external TS detection, // TBeam1.1 /T-Beam S3-Core has no external TS detection,
@@ -550,40 +556,52 @@ bool Power::axpChipInit()
LOG_DEBUG("=======================================================================\n"); LOG_DEBUG("=======================================================================\n");
if (PMU->isChannelAvailable(XPOWERS_DCDC1)) { if (PMU->isChannelAvailable(XPOWERS_DCDC1)) {
LOG_DEBUG("DC1 : %s Voltage:%u mV \n", PMU->isPowerChannelEnable(XPOWERS_DCDC1) ? "+" : "-", PMU->getPowerChannelVoltage(XPOWERS_DCDC1)); LOG_DEBUG("DC1 : %s Voltage:%u mV \n", PMU->isPowerChannelEnable(XPOWERS_DCDC1) ? "+" : "-",
PMU->getPowerChannelVoltage(XPOWERS_DCDC1));
} }
if (PMU->isChannelAvailable(XPOWERS_DCDC2)) { if (PMU->isChannelAvailable(XPOWERS_DCDC2)) {
LOG_DEBUG("DC2 : %s Voltage:%u mV \n", PMU->isPowerChannelEnable(XPOWERS_DCDC2) ? "+" : "-", PMU->getPowerChannelVoltage(XPOWERS_DCDC2)); LOG_DEBUG("DC2 : %s Voltage:%u mV \n", PMU->isPowerChannelEnable(XPOWERS_DCDC2) ? "+" : "-",
PMU->getPowerChannelVoltage(XPOWERS_DCDC2));
} }
if (PMU->isChannelAvailable(XPOWERS_DCDC3)) { if (PMU->isChannelAvailable(XPOWERS_DCDC3)) {
LOG_DEBUG("DC3 : %s Voltage:%u mV \n", PMU->isPowerChannelEnable(XPOWERS_DCDC3) ? "+" : "-", PMU->getPowerChannelVoltage(XPOWERS_DCDC3)); LOG_DEBUG("DC3 : %s Voltage:%u mV \n", PMU->isPowerChannelEnable(XPOWERS_DCDC3) ? "+" : "-",
PMU->getPowerChannelVoltage(XPOWERS_DCDC3));
} }
if (PMU->isChannelAvailable(XPOWERS_DCDC4)) { if (PMU->isChannelAvailable(XPOWERS_DCDC4)) {
LOG_DEBUG("DC4 : %s Voltage:%u mV \n", PMU->isPowerChannelEnable(XPOWERS_DCDC4) ? "+" : "-", PMU->getPowerChannelVoltage(XPOWERS_DCDC4)); LOG_DEBUG("DC4 : %s Voltage:%u mV \n", PMU->isPowerChannelEnable(XPOWERS_DCDC4) ? "+" : "-",
PMU->getPowerChannelVoltage(XPOWERS_DCDC4));
} }
if (PMU->isChannelAvailable(XPOWERS_LDO2)) { if (PMU->isChannelAvailable(XPOWERS_LDO2)) {
LOG_DEBUG("LDO2 : %s Voltage:%u mV \n", PMU->isPowerChannelEnable(XPOWERS_LDO2) ? "+" : "-", PMU->getPowerChannelVoltage(XPOWERS_LDO2)); LOG_DEBUG("LDO2 : %s Voltage:%u mV \n", PMU->isPowerChannelEnable(XPOWERS_LDO2) ? "+" : "-",
PMU->getPowerChannelVoltage(XPOWERS_LDO2));
} }
if (PMU->isChannelAvailable(XPOWERS_LDO3)) { if (PMU->isChannelAvailable(XPOWERS_LDO3)) {
LOG_DEBUG("LDO3 : %s Voltage:%u mV \n", PMU->isPowerChannelEnable(XPOWERS_LDO3) ? "+" : "-", PMU->getPowerChannelVoltage(XPOWERS_LDO3)); LOG_DEBUG("LDO3 : %s Voltage:%u mV \n", PMU->isPowerChannelEnable(XPOWERS_LDO3) ? "+" : "-",
PMU->getPowerChannelVoltage(XPOWERS_LDO3));
} }
if (PMU->isChannelAvailable(XPOWERS_ALDO1)) { if (PMU->isChannelAvailable(XPOWERS_ALDO1)) {
LOG_DEBUG("ALDO1: %s Voltage:%u mV \n", PMU->isPowerChannelEnable(XPOWERS_ALDO1) ? "+" : "-", PMU->getPowerChannelVoltage(XPOWERS_ALDO1)); LOG_DEBUG("ALDO1: %s Voltage:%u mV \n", PMU->isPowerChannelEnable(XPOWERS_ALDO1) ? "+" : "-",
PMU->getPowerChannelVoltage(XPOWERS_ALDO1));
} }
if (PMU->isChannelAvailable(XPOWERS_ALDO2)) { if (PMU->isChannelAvailable(XPOWERS_ALDO2)) {
LOG_DEBUG("ALDO2: %s Voltage:%u mV \n", PMU->isPowerChannelEnable(XPOWERS_ALDO2) ? "+" : "-", PMU->getPowerChannelVoltage(XPOWERS_ALDO2)); LOG_DEBUG("ALDO2: %s Voltage:%u mV \n", PMU->isPowerChannelEnable(XPOWERS_ALDO2) ? "+" : "-",
PMU->getPowerChannelVoltage(XPOWERS_ALDO2));
} }
if (PMU->isChannelAvailable(XPOWERS_ALDO3)) { if (PMU->isChannelAvailable(XPOWERS_ALDO3)) {
LOG_DEBUG("ALDO3: %s Voltage:%u mV \n", PMU->isPowerChannelEnable(XPOWERS_ALDO3) ? "+" : "-", PMU->getPowerChannelVoltage(XPOWERS_ALDO3)); LOG_DEBUG("ALDO3: %s Voltage:%u mV \n", PMU->isPowerChannelEnable(XPOWERS_ALDO3) ? "+" : "-",
PMU->getPowerChannelVoltage(XPOWERS_ALDO3));
} }
if (PMU->isChannelAvailable(XPOWERS_ALDO4)) { if (PMU->isChannelAvailable(XPOWERS_ALDO4)) {
LOG_DEBUG("ALDO4: %s Voltage:%u mV \n", PMU->isPowerChannelEnable(XPOWERS_ALDO4) ? "+" : "-", PMU->getPowerChannelVoltage(XPOWERS_ALDO4)); LOG_DEBUG("ALDO4: %s Voltage:%u mV \n", PMU->isPowerChannelEnable(XPOWERS_ALDO4) ? "+" : "-",
PMU->getPowerChannelVoltage(XPOWERS_ALDO4));
} }
if (PMU->isChannelAvailable(XPOWERS_BLDO1)) { if (PMU->isChannelAvailable(XPOWERS_BLDO1)) {
LOG_DEBUG("BLDO1: %s Voltage:%u mV \n", PMU->isPowerChannelEnable(XPOWERS_BLDO1) ? "+" : "-", PMU->getPowerChannelVoltage(XPOWERS_BLDO1)); LOG_DEBUG("BLDO1: %s Voltage:%u mV \n", PMU->isPowerChannelEnable(XPOWERS_BLDO1) ? "+" : "-",
PMU->getPowerChannelVoltage(XPOWERS_BLDO1));
} }
if (PMU->isChannelAvailable(XPOWERS_BLDO2)) { if (PMU->isChannelAvailable(XPOWERS_BLDO2)) {
LOG_DEBUG("BLDO2: %s Voltage:%u mV \n", PMU->isPowerChannelEnable(XPOWERS_BLDO2) ? "+" : "-", PMU->getPowerChannelVoltage(XPOWERS_BLDO2)); LOG_DEBUG("BLDO2: %s Voltage:%u mV \n", PMU->isPowerChannelEnable(XPOWERS_BLDO2) ? "+" : "-",
PMU->getPowerChannelVoltage(XPOWERS_BLDO2));
} }
LOG_DEBUG("=======================================================================\n"); LOG_DEBUG("=======================================================================\n");
@@ -597,7 +615,6 @@ bool Power::axpChipInit()
PMU->setSysPowerDownVoltage(2600); PMU->setSysPowerDownVoltage(2600);
#endif #endif
#ifdef PMU_IRQ #ifdef PMU_IRQ
uint64_t pmuIrqMask = 0; uint64_t pmuIrqMask = 0;
+19 -10
View File
@@ -16,7 +16,7 @@ static bool isPowered()
return true; return true;
#endif #endif
bool isRouter = (config.device.role == Config_DeviceConfig_Role_ROUTER ? 1 : 0); bool isRouter = (config.device.role == meshtastic_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 // 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 // We assume routers might be powered all the time, but from a low current (solar) source
@@ -199,7 +199,8 @@ static void onEnter()
uint32_t now = millis(); uint32_t now = millis();
if ((now - lastPingMs) > 30 * 1000) { // if more than a minute since our last press, ask node we are looking at to update their state if ((now - lastPingMs) >
30 * 1000) { // if more than a minute since our last press, ask node we are looking at to update their state
if (displayedNodeNum) if (displayedNodeNum)
service.sendNetworkPing(displayedNodeNum, true); // Refresh the currently displayed node service.sendNetworkPing(displayedNodeNum, true); // Refresh the currently displayed node
lastPingMs = now; lastPingMs = now;
@@ -237,7 +238,7 @@ Fsm powerFSM(&stateBOOT);
void PowerFSM_setup() void PowerFSM_setup()
{ {
bool isRouter = (config.device.role == Config_DeviceConfig_Role_ROUTER ? 1 : 0); bool isRouter = (config.device.role == meshtastic_Config_DeviceConfig_Role_ROUTER ? 1 : 0);
bool hasPower = isPowered(); bool hasPower = isPowered();
LOG_INFO("PowerFSM init, USB power=%d\n", hasPower ? 1 : 0); LOG_INFO("PowerFSM init, USB power=%d\n", hasPower ? 1 : 0);
@@ -249,7 +250,8 @@ void PowerFSM_setup()
// We need this transition, because we might not transition if we were waiting to enter light-sleep, because when we wake from // We need this transition, because we might not transition if we were waiting to enter light-sleep, because when we wake from
// light sleep we _always_ transition to NB or dark and // light sleep we _always_ transition to NB or dark and
powerFSM.add_transition(&stateLS, isRouter ? &stateNB : &stateDARK, EVENT_PACKET_FOR_PHONE, NULL, "Received packet, exiting light sleep"); powerFSM.add_transition(&stateLS, isRouter ? &stateNB : &stateDARK, EVENT_PACKET_FOR_PHONE, NULL,
"Received packet, exiting light sleep");
powerFSM.add_transition(&stateNB, &stateNB, EVENT_PACKET_FOR_PHONE, NULL, "Received packet, resetting win wake"); powerFSM.add_transition(&stateNB, &stateNB, EVENT_PACKET_FOR_PHONE, NULL, "Received packet, resetting win wake");
// Handle press events - note: we ignore button presses when in API mode // Handle press events - note: we ignore button presses when in API mode
@@ -258,7 +260,8 @@ void PowerFSM_setup()
powerFSM.add_transition(&stateDARK, &stateON, EVENT_PRESS, NULL, "Press"); powerFSM.add_transition(&stateDARK, &stateON, EVENT_PRESS, NULL, "Press");
powerFSM.add_transition(&statePOWER, &statePOWER, EVENT_PRESS, screenPress, "Press"); powerFSM.add_transition(&statePOWER, &statePOWER, EVENT_PRESS, screenPress, "Press");
powerFSM.add_transition(&stateON, &stateON, EVENT_PRESS, screenPress, "Press"); // reenter On to restart our timers powerFSM.add_transition(&stateON, &stateON, EVENT_PRESS, screenPress, "Press"); // reenter On to restart our timers
powerFSM.add_transition(&stateSERIAL, &stateSERIAL, EVENT_PRESS, screenPress, "Press"); // Allow button to work while in serial API powerFSM.add_transition(&stateSERIAL, &stateSERIAL, EVENT_PRESS, screenPress,
"Press"); // Allow button to work while in serial API
// Handle critically low power battery by forcing deep sleep // Handle critically low power battery by forcing deep sleep
powerFSM.add_transition(&stateBOOT, &stateSDS, EVENT_LOW_BATTERY, NULL, "LowBat"); powerFSM.add_transition(&stateBOOT, &stateSDS, EVENT_LOW_BATTERY, NULL, "LowBat");
@@ -324,7 +327,9 @@ void PowerFSM_setup()
powerFSM.add_transition(&stateDARK, &stateDARK, EVENT_CONTACT_FROM_PHONE, NULL, "Contact from phone"); powerFSM.add_transition(&stateDARK, &stateDARK, EVENT_CONTACT_FROM_PHONE, NULL, "Contact from phone");
powerFSM.add_timed_transition(&stateON, &stateDARK, getConfiguredOrDefaultMs(config.display.screen_on_secs, default_screen_on_secs), NULL, "Screen-on timeout"); powerFSM.add_timed_transition(&stateON, &stateDARK,
getConfiguredOrDefaultMs(config.display.screen_on_secs, default_screen_on_secs), NULL,
"Screen-on timeout");
#ifdef ARCH_ESP32 #ifdef ARCH_ESP32
State *lowPowerState = &stateLS; State *lowPowerState = &stateLS;
@@ -332,14 +337,18 @@ void PowerFSM_setup()
// See: https://github.com/meshtastic/firmware/issues/1071 // See: https://github.com/meshtastic/firmware/issues/1071
if (isRouter || config.power.is_power_saving) { if (isRouter || config.power.is_power_saving) {
powerFSM.add_timed_transition(&stateNB, &stateLS, getConfiguredOrDefaultMs(config.power.min_wake_secs, default_min_wake_secs), NULL, "Min wake timeout"); powerFSM.add_timed_transition(&stateNB, &stateLS,
powerFSM.add_timed_transition(&stateDARK, &stateLS, getConfiguredOrDefaultMs(config.power.wait_bluetooth_secs, default_wait_bluetooth_secs), NULL, "Bluetooth timeout"); getConfiguredOrDefaultMs(config.power.min_wake_secs, default_min_wake_secs), NULL,
"Min wake timeout");
powerFSM.add_timed_transition(&stateDARK, &stateLS,
getConfiguredOrDefaultMs(config.power.wait_bluetooth_secs, default_wait_bluetooth_secs),
NULL, "Bluetooth timeout");
} }
if (config.power.sds_secs != UINT32_MAX) if (config.power.sds_secs != UINT32_MAX)
powerFSM.add_timed_transition(lowPowerState, &stateSDS, getConfiguredOrDefaultMs(config.power.sds_secs), NULL, "mesh timeout"); powerFSM.add_timed_transition(lowPowerState, &stateSDS, getConfiguredOrDefaultMs(config.power.sds_secs), NULL,
"mesh timeout");
#endif #endif
powerFSM.run_machine(); // run one interation of the state machine, so we run our on enter tasks for the initial DARK state powerFSM.run_machine(); // run one interation of the state machine, so we run our on enter tasks for the initial DARK state
} }
+4 -3
View File
@@ -26,9 +26,10 @@ class PowerFSMThread : public OSThread
if (powerStatus->getHasUSB()) { if (powerStatus->getHasUSB()) {
timeLastPowered = millis(); timeLastPowered = millis();
} else if (config.power.on_battery_shutdown_after_secs > 0 && } else if (config.power.on_battery_shutdown_after_secs > 0 && config.power.on_battery_shutdown_after_secs != UINT32_MAX &&
config.power.on_battery_shutdown_after_secs != UINT32_MAX && millis() > (timeLastPowered +
millis() > (timeLastPowered + getConfiguredOrDefaultMs(config.power.on_battery_shutdown_after_secs))) { // shutdown after 30 minutes unpowered getConfiguredOrDefaultMs(
config.power.on_battery_shutdown_after_secs))) { // shutdown after 30 minutes unpowered
powerFSM.trigger(EVENT_SHUTDOWN); powerFSM.trigger(EVENT_SHUTDOWN);
} }
+13 -8
View File
@@ -1,12 +1,12 @@
#include "configuration.h"
#include "RedirectablePrint.h" #include "RedirectablePrint.h"
#include "RTC.h"
#include "NodeDB.h" #include "NodeDB.h"
#include "RTC.h"
#include "concurrency/OSThread.h" #include "concurrency/OSThread.h"
#include "configuration.h"
#include <assert.h> #include <assert.h>
#include <cstring>
#include <sys/time.h> #include <sys/time.h>
#include <time.h> #include <time.h>
#include <cstring>
/** /**
* A printer that doesn't go anywhere * A printer that doesn't go anywhere
@@ -42,7 +42,8 @@ size_t RedirectablePrint::vprintf(const char *format, va_list arg)
size_t len = vsnprintf(printBuf, sizeof(printBuf), format, copy); size_t len = vsnprintf(printBuf, sizeof(printBuf), format, copy);
va_end(copy); va_end(copy);
// If the resulting string is longer than sizeof(printBuf)-1 characters, the remaining characters are still counted for the return value // If the resulting string is longer than sizeof(printBuf)-1 characters, the remaining characters are still counted for the
// return value
if (len > sizeof(printBuf) - 1) { if (len > sizeof(printBuf) - 1) {
len = sizeof(printBuf) - 1; len = sizeof(printBuf) - 1;
@@ -104,7 +105,8 @@ size_t RedirectablePrint::log(const char *logLevel, const char *format, ...)
return r; return r;
} }
void RedirectablePrint::hexDump(const char *logLevel, unsigned char *buf, uint16_t len) { void RedirectablePrint::hexDump(const char *logLevel, unsigned char *buf, uint16_t len)
{
const char alphabet[17] = "0123456789abcdef"; const char alphabet[17] = "0123456789abcdef";
log(logLevel, " +------------------------------------------------+ +----------------+\n"); log(logLevel, " +------------------------------------------------+ +----------------+\n");
log(logLevel, " |.0 .1 .2 .3 .4 .5 .6 .7 .8 .9 .a .b .c .d .e .f | | ASCII |\n"); log(logLevel, " |.0 .1 .2 .3 .4 .5 .6 .7 .8 .9 .a .b .c .d .e .f | | ASCII |\n");
@@ -119,12 +121,15 @@ void RedirectablePrint::hexDump(const char *logLevel, unsigned char *buf, uint16
s[ix++] = alphabet[(c >> 4) & 0x0F]; s[ix++] = alphabet[(c >> 4) & 0x0F];
s[ix++] = alphabet[c & 0x0F]; s[ix++] = alphabet[c & 0x0F];
ix++; ix++;
if (c > 31 && c < 128) s[iy++] = c; if (c > 31 && c < 128)
else s[iy++] = '.'; s[iy++] = c;
else
s[iy++] = '.';
} }
} }
uint8_t index = i / 16; uint8_t index = i / 16;
if (i < 256) log(logLevel, " "); if (i < 256)
log(logLevel, " ");
log(logLevel, "%02x", index); log(logLevel, "%02x", index);
log(logLevel, "."); log(logLevel, ".");
log(logLevel, s); log(logLevel, s);
+1 -1
View File
@@ -1,5 +1,5 @@
#include "configuration.h"
#include "SPILock.h" #include "SPILock.h"
#include "configuration.h"
#include <Arduino.h> #include <Arduino.h>
#include <assert.h> #include <assert.h>
+2 -1
View File
@@ -49,7 +49,8 @@ int32_t SerialConsole::runOnce()
return runOncePart(); return runOncePart();
} }
void SerialConsole::flush() { void SerialConsole::flush()
{
Port.flush(); Port.flush();
} }
-1
View File
@@ -29,7 +29,6 @@ class SerialConsole : public StreamAPI, public RedirectablePrint, private concur
void flush(); void flush();
protected: protected:
/// Check the current underlying physical link to see if the client is currently connected /// Check the current underlying physical link to see if the client is currently connected
virtual bool checkIsConnected() override; virtual bool checkIsConnected() override;
}; };
+10 -26
View File
@@ -8,7 +8,6 @@
#define STATUS_TYPE_GPS 2 #define STATUS_TYPE_GPS 2
#define STATUS_TYPE_NODE 3 #define STATUS_TYPE_NODE 3
namespace meshtastic namespace meshtastic
{ {
@@ -17,7 +16,8 @@ namespace meshtastic
{ {
protected: protected:
// Allows us to observe an Observable // Allows us to observe an Observable
CallbackObserver<Status, const Status *> statusObserver = CallbackObserver<Status, const Status *>(this, &Status::updateStatus); CallbackObserver<Status, const Status *> statusObserver =
CallbackObserver<Status, const Status *>(this, &Status::updateStatus);
bool initialized = false; bool initialized = false;
// Workaround for no typeid support // Workaround for no typeid support
int statusType = 0; int statusType = 0;
@@ -29,9 +29,9 @@ namespace meshtastic
// Enable polymorphism ? // Enable polymorphism ?
virtual ~Status() = default; virtual ~Status() = default;
Status() { Status()
if (!statusType)
{ {
if (!statusType) {
statusType = STATUS_TYPE_BASE; statusType = STATUS_TYPE_BASE;
} }
} }
@@ -41,32 +41,16 @@ namespace meshtastic
Status &operator=(const Status &) = delete; Status &operator=(const Status &) = delete;
// Start observing a source of data // Start observing a source of data
void observe(Observable<const Status *> *source) void observe(Observable<const Status *> *source) { statusObserver.observe(source); }
{
statusObserver.observe(source);
}
// Determines whether or not existing data matches the data in another Status instance // Determines whether or not existing data matches the data in another Status instance
bool matches(const Status *otherStatus) const bool matches(const Status *otherStatus) const { return true; }
{
return true;
}
bool isInitialized() const bool isInitialized() const { return initialized; }
{
return initialized;
}
int getStatusType() const int getStatusType() const { return statusType; }
{
return statusType;
}
// Called when the Observable we're observing generates a new notification // Called when the Observable we're observing generates a new notification
int updateStatus(const Status *newStatus) int updateStatus(const Status *newStatus) { return 0; }
{
return 0;
}
};
}; };
}; // namespace meshtastic
+7 -7
View File
@@ -34,11 +34,13 @@ uint8_t AirTime::currentPeriodIndex()
return ((getSecondsSinceBoot() / SECONDS_PER_PERIOD) % PERIODS_TO_LOG); return ((getSecondsSinceBoot() / SECONDS_PER_PERIOD) % PERIODS_TO_LOG);
} }
uint8_t AirTime::getPeriodUtilMinute() { uint8_t AirTime::getPeriodUtilMinute()
{
return (getSecondsSinceBoot() / 10) % CHANNEL_UTILIZATION_PERIODS; return (getSecondsSinceBoot() / 10) % CHANNEL_UTILIZATION_PERIODS;
} }
uint8_t AirTime::getPeriodUtilHour() { uint8_t AirTime::getPeriodUtilHour()
{
return (getSecondsSinceBoot() / 60) % MINUTES_IN_HOUR; return (getSecondsSinceBoot() / 60) % MINUTES_IN_HOUR;
} }
@@ -128,14 +130,14 @@ bool AirTime::isTxAllowedChannelUtil(bool polite)
} }
} }
bool AirTime::isTxAllowedAirUtil() bool AirTime::isTxAllowedAirUtil()
{ {
if (!config.lora.override_duty_cycle && myRegion->dutyCycle < 100) { if (!config.lora.override_duty_cycle && myRegion->dutyCycle < 100) {
if (utilizationTXPercent() < myRegion->dutyCycle * polite_duty_cycle_percent / 100) { if (utilizationTXPercent() < myRegion->dutyCycle * polite_duty_cycle_percent / 100) {
return true; return true;
} else { } else {
LOG_WARN("Tx air utilization is >%f percent. Skipping this opportunity to send.\n", myRegion->dutyCycle * polite_duty_cycle_percent / 100); LOG_WARN("Tx air utilization is >%f percent. Skipping this opportunity to send.\n",
myRegion->dutyCycle * polite_duty_cycle_percent / 100);
return false; return false;
} }
} }
@@ -155,9 +157,7 @@ uint8_t AirTime::getSilentMinutes(float txPercent, float dutyCycle)
return MINUTES_IN_HOUR; return MINUTES_IN_HOUR;
} }
AirTime::AirTime() : concurrency::OSThread("AirTime"), airtimes({}) {}
AirTime::AirTime() : concurrency::OSThread("AirTime"),airtimes({}) {
}
int32_t AirTime::runOnce() int32_t AirTime::runOnce()
{ {
+1 -2
View File
@@ -1,10 +1,10 @@
#pragma once #pragma once
#include "MeshRadio.h"
#include "concurrency/OSThread.h" #include "concurrency/OSThread.h"
#include "configuration.h" #include "configuration.h"
#include <Arduino.h> #include <Arduino.h>
#include <functional> #include <functional>
#include "MeshRadio.h"
/* /*
TX_LOG - Time on air this device has transmitted TX_LOG - Time on air this device has transmitted
@@ -33,7 +33,6 @@
#define MS_IN_MINUTE (SECONDS_IN_MINUTE * 1000) #define MS_IN_MINUTE (SECONDS_IN_MINUTE * 1000)
#define MS_IN_HOUR (MINUTES_IN_HOUR * SECONDS_IN_MINUTE * 1000) #define MS_IN_HOUR (MINUTES_IN_HOUR * SECONDS_IN_MINUTE * 1000)
enum reportTypes { TX_LOG, RX_LOG, RX_ALL_LOG }; enum reportTypes { TX_LOG, RX_LOG, RX_ALL_LOG };
void logAirtime(reportTypes reportType, uint32_t airtime_ms); void logAirtime(reportTypes reportType, uint32_t airtime_ms);
+11 -12
View File
@@ -1,6 +1,6 @@
#include "buzz.h" #include "buzz.h"
#include "configuration.h"
#include "NodeDB.h" #include "NodeDB.h"
#include "configuration.h"
#if !defined(ARCH_ESP32) && !defined(ARCH_RP2040) && !defined(ARCH_PORTDUINO) #if !defined(ARCH_ESP32) && !defined(ARCH_RP2040) && !defined(ARCH_PORTDUINO)
#include "Tone.h" #include "Tone.h"
@@ -33,7 +33,8 @@ struct ToneDuration {
const int DURATION_1_8 = 125; // 1/8 note const int DURATION_1_8 = 125; // 1/8 note
const int DURATION_1_4 = 250; // 1/4 note const int DURATION_1_4 = 250; // 1/4 note
void playTones(const ToneDuration *tone_durations, int size) { void playTones(const ToneDuration *tone_durations, int size)
{
#ifdef PIN_BUZZER #ifdef PIN_BUZZER
if (!config.device.buzzer_gpio) if (!config.device.buzzer_gpio)
config.device.buzzer_gpio = PIN_BUZZER; config.device.buzzer_gpio = PIN_BUZZER;
@@ -48,22 +49,20 @@ void playTones(const ToneDuration *tone_durations, int size) {
} }
} }
void playBeep()
void playBeep() { {
ToneDuration melody[] = {{NOTE_B3, DURATION_1_4}}; ToneDuration melody[] = {{NOTE_B3, DURATION_1_4}};
playTones(melody, sizeof(melody) / sizeof(ToneDuration)); playTones(melody, sizeof(melody) / sizeof(ToneDuration));
} }
void playStartMelody() { void playStartMelody()
ToneDuration melody[] = {{NOTE_FS3, DURATION_1_8}, {
{NOTE_AS3, DURATION_1_8}, ToneDuration melody[] = {{NOTE_FS3, DURATION_1_8}, {NOTE_AS3, DURATION_1_8}, {NOTE_CS4, DURATION_1_4}};
{NOTE_CS4, DURATION_1_4}};
playTones(melody, sizeof(melody) / sizeof(ToneDuration)); playTones(melody, sizeof(melody) / sizeof(ToneDuration));
} }
void playShutdownMelody() { void playShutdownMelody()
ToneDuration melody[] = {{NOTE_CS4, DURATION_1_8}, {
{NOTE_AS3, DURATION_1_8}, ToneDuration melody[] = {{NOTE_CS4, DURATION_1_8}, {NOTE_AS3, DURATION_1_8}, {NOTE_FS3, DURATION_1_4}};
{NOTE_FS3, DURATION_1_4}};
playTones(melody, sizeof(melody) / sizeof(ToneDuration)); playTones(melody, sizeof(melody) / sizeof(ToneDuration));
} }
+1 -1
View File
@@ -1,5 +1,5 @@
#include "configuration.h"
#include "concurrency/BinarySemaphoreFreeRTOS.h" #include "concurrency/BinarySemaphoreFreeRTOS.h"
#include "configuration.h"
#include <assert.h> #include <assert.h>
#ifdef HAS_FREE_RTOS #ifdef HAS_FREE_RTOS
+5 -13
View File
@@ -1,18 +1,14 @@
#include "configuration.h"
#include "concurrency/BinarySemaphorePosix.h" #include "concurrency/BinarySemaphorePosix.h"
#include "configuration.h"
#ifndef HAS_FREE_RTOS #ifndef HAS_FREE_RTOS
namespace concurrency namespace concurrency
{ {
BinarySemaphorePosix::BinarySemaphorePosix() BinarySemaphorePosix::BinarySemaphorePosix() {}
{
}
BinarySemaphorePosix::~BinarySemaphorePosix() BinarySemaphorePosix::~BinarySemaphorePosix() {}
{
}
/** /**
* Returns false if we timed out * Returns false if we timed out
@@ -23,13 +19,9 @@ bool BinarySemaphorePosix::take(uint32_t msec)
return false; return false;
} }
void BinarySemaphorePosix::give() void BinarySemaphorePosix::give() {}
{
}
IRAM_ATTR void BinarySemaphorePosix::giveFromISR(BaseType_t *pxHigherPriorityTaskWoken) IRAM_ATTR void BinarySemaphorePosix::giveFromISR(BaseType_t *pxHigherPriorityTaskWoken) {}
{
}
} // namespace concurrency } // namespace concurrency
+1 -1
View File
@@ -1,5 +1,5 @@
#include "configuration.h"
#include "concurrency/InterruptableDelay.h" #include "concurrency/InterruptableDelay.h"
#include "configuration.h"
namespace concurrency namespace concurrency
{ {
-1
View File
@@ -2,7 +2,6 @@
#include "../freertosinc.h" #include "../freertosinc.h"
#ifdef HAS_FREE_RTOS #ifdef HAS_FREE_RTOS
#include "concurrency/BinarySemaphoreFreeRTOS.h" #include "concurrency/BinarySemaphoreFreeRTOS.h"
#define BinarySemaphore BinarySemaphoreFreeRTOS #define BinarySemaphore BinarySemaphoreFreeRTOS
+1 -1
View File
@@ -1,5 +1,5 @@
#include "configuration.h"
#include "Lock.h" #include "Lock.h"
#include "configuration.h"
#include <cassert> #include <cassert>
namespace concurrency namespace concurrency
+3 -2
View File
@@ -1,7 +1,8 @@
#include "configuration.h"
#include "LockGuard.h" #include "LockGuard.h"
#include "configuration.h"
namespace concurrency { namespace concurrency
{
LockGuard::LockGuard(Lock *lock) : lock(lock) LockGuard::LockGuard(Lock *lock) : lock(lock)
{ {
+2 -1
View File
@@ -2,7 +2,8 @@
#include "Lock.h" #include "Lock.h"
namespace concurrency { namespace concurrency
{
/** /**
* @brief RAII lock guard * @brief RAII lock guard
+1 -3
View File
@@ -1,5 +1,5 @@
#include "configuration.h"
#include "NotifiedWorkerThread.h" #include "NotifiedWorkerThread.h"
#include "configuration.h"
#include "main.h" #include "main.h"
namespace concurrency namespace concurrency
@@ -80,8 +80,6 @@ void NotifiedWorkerThread::checkNotification()
} }
} }
int32_t NotifiedWorkerThread::runOnce() int32_t NotifiedWorkerThread::runOnce()
{ {
enabled = false; // Only run once per notification enabled = false; // Only run once per notification
+3 -3
View File
@@ -41,9 +41,9 @@ class NotifiedWorkerThread : public OSThread
/// just calls checkNotification() /// just calls checkNotification()
virtual int32_t runOnce() override; virtual int32_t runOnce() override;
/// Sometimes we might want to check notifications independently of when our thread was getting woken up (i.e. if we are about to change /// Sometimes we might want to check notifications independently of when our thread was getting woken up (i.e. if we are about
/// radio transmit/receive modes we want to handle any pending interrupts first). You can call this method and if any notifications are currently /// to change radio transmit/receive modes we want to handle any pending interrupts first). You can call this method and if
/// pending they will be handled immediately. /// any notifications are currently pending they will be handled immediately.
void checkNotification(); void checkNotification();
private: private:
+1 -1
View File
@@ -1,5 +1,5 @@
#include "configuration.h"
#include "OSThread.h" #include "OSThread.h"
#include "configuration.h"
#include <assert.h> #include <assert.h>
namespace concurrency namespace concurrency
+3 -2
View File
@@ -42,7 +42,8 @@ along with this program. If not, see <http://www.gnu.org/licenses/>.
#error APP_VERSION must be set by the build environment #error APP_VERSION must be set by the build environment
#endif #endif
// FIXME: This is still needed by the Bluetooth Stack and needs to be replaced by something better. Remnant of the old versioning system. // FIXME: This is still needed by the Bluetooth Stack and needs to be replaced by something better. Remnant of the old versioning
// system.
#ifndef HW_VERSION #ifndef HW_VERSION
#define HW_VERSION "1.0" #define HW_VERSION "1.0"
#endif #endif
@@ -175,8 +176,8 @@ along with this program. If not, see <http://www.gnu.org/licenses/>.
#define HAS_BLUETOOTH 0 #define HAS_BLUETOOTH 0
#endif #endif
#include "RF95Configuration.h"
#include "DebugConfiguration.h" #include "DebugConfiguration.h"
#include "RF95Configuration.h"
#ifndef HW_VENDOR #ifndef HW_VENDOR
#error HW_VENDOR must be defined #error HW_VENDOR must be defined
+22 -15
View File
@@ -7,41 +7,48 @@
void d_writeCommand(uint8_t c) void d_writeCommand(uint8_t c)
{ {
SPI1.beginTransaction(SPISettings(4000000, MSBFIRST, SPI_MODE0)); SPI1.beginTransaction(SPISettings(4000000, MSBFIRST, SPI_MODE0));
if (PIN_EINK_DC >= 0) digitalWrite(PIN_EINK_DC, LOW); if (PIN_EINK_DC >= 0)
if (PIN_EINK_CS >= 0) digitalWrite(PIN_EINK_CS, LOW); digitalWrite(PIN_EINK_DC, LOW);
if (PIN_EINK_CS >= 0)
digitalWrite(PIN_EINK_CS, LOW);
SPI1.transfer(c); SPI1.transfer(c);
if (PIN_EINK_CS >= 0) digitalWrite(PIN_EINK_CS, HIGH); if (PIN_EINK_CS >= 0)
if (PIN_EINK_DC >= 0) digitalWrite(PIN_EINK_DC, HIGH); digitalWrite(PIN_EINK_CS, HIGH);
if (PIN_EINK_DC >= 0)
digitalWrite(PIN_EINK_DC, HIGH);
SPI1.endTransaction(); SPI1.endTransaction();
} }
void d_writeData(uint8_t d) void d_writeData(uint8_t d)
{ {
SPI1.beginTransaction(SPISettings(4000000, MSBFIRST, SPI_MODE0)); SPI1.beginTransaction(SPISettings(4000000, MSBFIRST, SPI_MODE0));
if (PIN_EINK_CS >= 0) digitalWrite(PIN_EINK_CS, LOW); if (PIN_EINK_CS >= 0)
digitalWrite(PIN_EINK_CS, LOW);
SPI1.transfer(d); SPI1.transfer(d);
if (PIN_EINK_CS >= 0) digitalWrite(PIN_EINK_CS, HIGH); if (PIN_EINK_CS >= 0)
digitalWrite(PIN_EINK_CS, HIGH);
SPI1.endTransaction(); SPI1.endTransaction();
} }
unsigned long d_waitWhileBusy(uint16_t busy_time) unsigned long d_waitWhileBusy(uint16_t busy_time)
{ {
if (PIN_EINK_BUSY >= 0) if (PIN_EINK_BUSY >= 0) {
{
delay(1); // add some margin to become active delay(1); // add some margin to become active
unsigned long start = micros(); unsigned long start = micros();
while (1) while (1) {
{ if (digitalRead(PIN_EINK_BUSY) != HIGH)
if (digitalRead(PIN_EINK_BUSY) != HIGH) break; break;
delay(1); delay(1);
if (digitalRead(PIN_EINK_BUSY) != HIGH) break; if (digitalRead(PIN_EINK_BUSY) != HIGH)
if (micros() - start > 10000000) break; break;
if (micros() - start > 10000000)
break;
} }
unsigned long elapsed = micros() - start; unsigned long elapsed = micros() - start;
(void)start; (void)start;
return elapsed; return elapsed;
} } else
else return busy_time; return busy_time;
} }
void scanEInkDevice(void) void scanEInkDevice(void)
+12 -12
View File
@@ -168,13 +168,13 @@ void scanI2Cdevice()
registerValue = getRegisterValue(addr, 0xD0, 1); // GET_ID registerValue = getRegisterValue(addr, 0xD0, 1); // GET_ID
if (registerValue == 0x61) { if (registerValue == 0x61) {
LOG_INFO("BME-680 sensor found at address 0x%x\n", (uint8_t)addr); LOG_INFO("BME-680 sensor found at address 0x%x\n", (uint8_t)addr);
nodeTelemetrySensorsMap[TelemetrySensorType_BME680] = addr; nodeTelemetrySensorsMap[meshtastic_TelemetrySensorType_BME680] = addr;
} else if (registerValue == 0x60) { } else if (registerValue == 0x60) {
LOG_INFO("BME-280 sensor found at address 0x%x\n", (uint8_t)addr); LOG_INFO("BME-280 sensor found at address 0x%x\n", (uint8_t)addr);
nodeTelemetrySensorsMap[TelemetrySensorType_BME280] = addr; nodeTelemetrySensorsMap[meshtastic_TelemetrySensorType_BME280] = addr;
} else { } else {
LOG_INFO("BMP-280 sensor found at address 0x%x\n", (uint8_t)addr); LOG_INFO("BMP-280 sensor found at address 0x%x\n", (uint8_t)addr);
nodeTelemetrySensorsMap[TelemetrySensorType_BMP280] = addr; nodeTelemetrySensorsMap[meshtastic_TelemetrySensorType_BMP280] = addr;
} }
} }
if (addr == INA_ADDR || addr == INA_ADDR_ALTERNATE) { if (addr == INA_ADDR || addr == INA_ADDR_ALTERNATE) {
@@ -182,41 +182,41 @@ void scanI2Cdevice()
LOG_DEBUG("Register MFG_UID: 0x%x\n", registerValue); LOG_DEBUG("Register MFG_UID: 0x%x\n", registerValue);
if (registerValue == 0x5449) { if (registerValue == 0x5449) {
LOG_INFO("INA260 sensor found at address 0x%x\n", (uint8_t)addr); LOG_INFO("INA260 sensor found at address 0x%x\n", (uint8_t)addr);
nodeTelemetrySensorsMap[TelemetrySensorType_INA260] = addr; nodeTelemetrySensorsMap[meshtastic_TelemetrySensorType_INA260] = addr;
} else { // Assume INA219 if INA260 ID is not found } else { // Assume INA219 if INA260 ID is not found
LOG_INFO("INA219 sensor found at address 0x%x\n", (uint8_t)addr); LOG_INFO("INA219 sensor found at address 0x%x\n", (uint8_t)addr);
nodeTelemetrySensorsMap[TelemetrySensorType_INA219] = addr; nodeTelemetrySensorsMap[meshtastic_TelemetrySensorType_INA219] = addr;
} }
} }
if (addr == MCP9808_ADDR) { if (addr == MCP9808_ADDR) {
nodeTelemetrySensorsMap[TelemetrySensorType_MCP9808] = addr; nodeTelemetrySensorsMap[meshtastic_TelemetrySensorType_MCP9808] = addr;
LOG_INFO("MCP9808 sensor found\n"); LOG_INFO("MCP9808 sensor found\n");
} }
if (addr == SHT31_ADDR) { if (addr == SHT31_ADDR) {
LOG_INFO("SHT31 sensor found\n"); LOG_INFO("SHT31 sensor found\n");
nodeTelemetrySensorsMap[TelemetrySensorType_SHT31] = addr; nodeTelemetrySensorsMap[meshtastic_TelemetrySensorType_SHT31] = addr;
} }
if (addr == SHTC3_ADDR) { if (addr == SHTC3_ADDR) {
LOG_INFO("SHTC3 sensor found\n"); LOG_INFO("SHTC3 sensor found\n");
nodeTelemetrySensorsMap[TelemetrySensorType_SHTC3] = addr; nodeTelemetrySensorsMap[meshtastic_TelemetrySensorType_SHTC3] = addr;
} }
if (addr == LPS22HB_ADDR || addr == LPS22HB_ADDR_ALT) { if (addr == LPS22HB_ADDR || addr == LPS22HB_ADDR_ALT) {
LOG_INFO("LPS22HB sensor found\n"); LOG_INFO("LPS22HB sensor found\n");
nodeTelemetrySensorsMap[TelemetrySensorType_LPS22] = addr; nodeTelemetrySensorsMap[meshtastic_TelemetrySensorType_LPS22] = addr;
} }
// High rate sensors, will be processed internally // High rate sensors, will be processed internally
if (addr == QMC6310_ADDR) { if (addr == QMC6310_ADDR) {
LOG_INFO("QMC6310 Highrate 3-Axis magnetic sensor found\n"); LOG_INFO("QMC6310 Highrate 3-Axis magnetic sensor found\n");
nodeTelemetrySensorsMap[TelemetrySensorType_QMC6310] = addr; nodeTelemetrySensorsMap[meshtastic_TelemetrySensorType_QMC6310] = addr;
} }
if (addr == QMI8658_ADDR) { if (addr == QMI8658_ADDR) {
LOG_INFO("QMI8658 Highrate 6-Axis inertial measurement sensor found\n"); LOG_INFO("QMI8658 Highrate 6-Axis inertial measurement sensor found\n");
nodeTelemetrySensorsMap[TelemetrySensorType_QMI8658] = addr; nodeTelemetrySensorsMap[meshtastic_TelemetrySensorType_QMI8658] = addr;
} }
if (addr == QMC5883L_ADDR) { if (addr == QMC5883L_ADDR) {
LOG_INFO("QMC5883L Highrate 3-Axis magnetic sensor found\n"); LOG_INFO("QMC5883L Highrate 3-Axis magnetic sensor found\n");
nodeTelemetrySensorsMap[TelemetrySensorType_QMC5883L] = addr; nodeTelemetrySensorsMap[meshtastic_TelemetrySensorType_QMC5883L] = addr;
} }
} else if (err == 4) { } else if (err == 4) {
LOG_ERROR("Unknow error at address 0x%x\n", addr); LOG_ERROR("Unknow error at address 0x%x\n", addr);
+1 -1
View File
@@ -8,5 +8,5 @@
#define RECORD_CRITICALERROR(code) recordCriticalError(code, __LINE__, __FILE__) #define RECORD_CRITICALERROR(code) recordCriticalError(code, __LINE__, __FILE__)
/// Record an error that should be reported via analytics /// Record an error that should be reported via analytics
void recordCriticalError(CriticalErrorCode code = CriticalErrorCode_UNSPECIFIED, uint32_t address = 0, void recordCriticalError(meshtastic_CriticalErrorCode code = meshtastic_CriticalErrorCode_UNSPECIFIED, uint32_t address = 0,
const char *filename = NULL); const char *filename = NULL);
+2 -1
View File
@@ -295,6 +295,7 @@ bool GPS::setup()
notifyDeepSleepObserver.observe(&notifyDeepSleep); notifyDeepSleepObserver.observe(&notifyDeepSleep);
notifyGPSSleepObserver.observe(&notifyGPSSleep); notifyGPSSleepObserver.observe(&notifyGPSSleep);
} }
if (config.position.gps_enabled == false && config.position.fixed_position == false) { if (config.position.gps_enabled == false && config.position.fixed_position == false) {
setAwake(false); setAwake(false);
doGPSpowersave(false); doGPSpowersave(false);
@@ -489,7 +490,7 @@ int32_t GPS::runOnce()
if (hasValidLocation) { if (hasValidLocation) {
LOG_DEBUG("hasValidLocation FALLING EDGE (last read: %d)\n", gotLoc); LOG_DEBUG("hasValidLocation FALLING EDGE (last read: %d)\n", gotLoc);
} }
p = Position_init_default; p = meshtastic_Position_init_default;
hasValidLocation = false; hasValidLocation = false;
} }
+1 -1
View File
@@ -54,7 +54,7 @@ class GPS : private concurrency::OSThread
/** If !NULL we will use this serial port to construct our GPS */ /** If !NULL we will use this serial port to construct our GPS */
static HardwareSerial *_serial_gps; static HardwareSerial *_serial_gps;
Position p = Position_init_default; meshtastic_Position p = meshtastic_Position_init_default;
GPS() : concurrency::OSThread("GPS") {} GPS() : concurrency::OSThread("GPS") {}
+76 -41
View File
@@ -1,21 +1,25 @@
#include "GeoCoord.h" #include "GeoCoord.h"
GeoCoord::GeoCoord() { GeoCoord::GeoCoord()
{
_dirty = true; _dirty = true;
} }
GeoCoord::GeoCoord (int32_t lat, int32_t lon, int32_t alt) : _latitude(lat), _longitude(lon), _altitude(alt) { GeoCoord::GeoCoord(int32_t lat, int32_t lon, int32_t alt) : _latitude(lat), _longitude(lon), _altitude(alt)
{
GeoCoord::setCoords(); GeoCoord::setCoords();
} }
GeoCoord::GeoCoord (float lat, float lon, int32_t alt) : _altitude(alt) { GeoCoord::GeoCoord(float lat, float lon, int32_t alt) : _altitude(alt)
{
// Change decimial reprsentation to int32_t. I.e., 12.345 becomes 123450000 // Change decimial reprsentation to int32_t. I.e., 12.345 becomes 123450000
_latitude = int32_t(lat * 1e+7); _latitude = int32_t(lat * 1e+7);
_longitude = int32_t(lon * 1e+7); _longitude = int32_t(lon * 1e+7);
GeoCoord::setCoords(); GeoCoord::setCoords();
} }
GeoCoord::GeoCoord(double lat, double lon, int32_t alt): _altitude(alt) { GeoCoord::GeoCoord(double lat, double lon, int32_t alt) : _altitude(alt)
{
// Change decimial reprsentation to int32_t. I.e., 12.345 becomes 123450000 // Change decimial reprsentation to int32_t. I.e., 12.345 becomes 123450000
_latitude = int32_t(lat * 1e+7); _latitude = int32_t(lat * 1e+7);
_longitude = int32_t(lon * 1e+7); _longitude = int32_t(lon * 1e+7);
@@ -23,7 +27,8 @@ GeoCoord::GeoCoord(double lat, double lon, int32_t alt): _altitude(alt) {
} }
// Initialize all the coordinate systems // Initialize all the coordinate systems
void GeoCoord::setCoords() { void GeoCoord::setCoords()
{
double lat = _latitude * 1e-7; double lat = _latitude * 1e-7;
double lon = _longitude * 1e-7; double lon = _longitude * 1e-7;
GeoCoord::latLongToDMS(lat, lon, _dms); GeoCoord::latLongToDMS(lat, lon, _dms);
@@ -34,7 +39,8 @@ void GeoCoord::setCoords() {
_dirty = false; _dirty = false;
} }
void GeoCoord::updateCoords(int32_t lat, int32_t lon, int32_t alt) { void GeoCoord::updateCoords(int32_t lat, int32_t lon, int32_t alt)
{
// If marked dirty or new coordiantes // If marked dirty or new coordiantes
if (_dirty || _latitude != lat || _longitude != lon || _altitude != alt) { if (_dirty || _latitude != lat || _longitude != lon || _altitude != alt) {
_dirty = true; _dirty = true;
@@ -45,7 +51,8 @@ void GeoCoord::updateCoords(int32_t lat, int32_t lon, int32_t alt) {
} }
} }
void GeoCoord::updateCoords(const double lat, const double lon, const int32_t alt) { void GeoCoord::updateCoords(const double lat, const double lon, const int32_t alt)
{
int32_t iLat = lat * 1e+7; int32_t iLat = lat * 1e+7;
int32_t iLon = lon * 1e+7; int32_t iLon = lon * 1e+7;
// If marked dirty or new coordiantes // If marked dirty or new coordiantes
@@ -56,10 +63,10 @@ void GeoCoord::updateCoords(const double lat, const double lon, const int32_t al
_altitude = alt; _altitude = alt;
setCoords(); setCoords();
} }
} }
void GeoCoord::updateCoords(const float lat, const float lon, const int32_t alt) { void GeoCoord::updateCoords(const float lat, const float lon, const int32_t alt)
{
int32_t iLat = lat * 1e+7; int32_t iLat = lat * 1e+7;
int32_t iLon = lon * 1e+7; int32_t iLon = lon * 1e+7;
// If marked dirty or new coordiantes // If marked dirty or new coordiantes
@@ -76,9 +83,12 @@ void GeoCoord::updateCoords(const float lat, const float lon, const int32_t alt)
* Converts lat long coordinates from decimal degrees to degrees minutes seconds format. * Converts lat long coordinates from decimal degrees to degrees minutes seconds format.
* DD°MM'SS"C DDD°MM'SS"C * DD°MM'SS"C DDD°MM'SS"C
*/ */
void GeoCoord::latLongToDMS(const double lat, const double lon, DMS &dms) { void GeoCoord::latLongToDMS(const double lat, const double lon, DMS &dms)
if (lat < 0) dms.latCP = 'S'; {
else dms.latCP = 'N'; if (lat < 0)
dms.latCP = 'S';
else
dms.latCP = 'N';
double latDeg = lat; double latDeg = lat;
@@ -90,8 +100,10 @@ void GeoCoord::latLongToDMS(const double lat, const double lon, DMS &dms) {
dms.latMin = floor(latMin); dms.latMin = floor(latMin);
dms.latSec = (latMin - dms.latMin) * 60; dms.latSec = (latMin - dms.latMin) * 60;
if (lon < 0) dms.lonCP = 'W'; if (lon < 0)
else dms.lonCP = 'E'; dms.lonCP = 'W';
else
dms.lonCP = 'E';
double lonDeg = lon; double lonDeg = lon;
@@ -108,7 +120,8 @@ void GeoCoord::latLongToDMS(const double lat, const double lon, DMS &dms) {
* Converts lat long coordinates to UTM. * Converts lat long coordinates to UTM.
* based on this: https://github.com/walvok/LatLonToUTM/blob/master/latlon_utm.ino * based on this: https://github.com/walvok/LatLonToUTM/blob/master/latlon_utm.ino
*/ */
void GeoCoord::latLongToUTM(const double lat, const double lon, UTM &utm) { void GeoCoord::latLongToUTM(const double lat, const double lon, UTM &utm)
{
const std::string latBands = "CDEFGHJKLMNPQRSTUVWXX"; const std::string latBands = "CDEFGHJKLMNPQRSTUVWXX";
utm.zone = int((lon + 180) / 6 + 1); utm.zone = int((lon + 180) / 6 + 1);
@@ -124,10 +137,14 @@ void GeoCoord::latLongToUTM(const double lat, const double lon, UTM &utm) {
if (lat >= 56.0 && lat < 64.0 && lonTemp >= 3.0 && lonTemp < 12.0) // Norway if (lat >= 56.0 && lat < 64.0 && lonTemp >= 3.0 && lonTemp < 12.0) // Norway
utm.zone = 32; utm.zone = 32;
if (lat >= 72.0 && lat < 84.0) { // Svalbard if (lat >= 72.0 && lat < 84.0) { // Svalbard
if ( lonTemp >= 0.0 && lonTemp < 9.0 ) utm.zone = 31; if (lonTemp >= 0.0 && lonTemp < 9.0)
else if( lonTemp >= 9.0 && lonTemp < 21.0 ) utm.zone = 33; utm.zone = 31;
else if( lonTemp >= 21.0 && lonTemp < 33.0 ) utm.zone = 35; else if (lonTemp >= 9.0 && lonTemp < 21.0)
else if( lonTemp >= 33.0 && lonTemp < 42.0 ) utm.zone = 37; utm.zone = 33;
else if (lonTemp >= 21.0 && lonTemp < 33.0)
utm.zone = 35;
else if (lonTemp >= 33.0 && lonTemp < 42.0)
utm.zone = 37;
} }
double lonOrigin = (utm.zone - 1) * 6 - 180 + 3; // puts origin in middle of zone double lonOrigin = (utm.zone - 1) * 6 - 180 + 3; // puts origin in middle of zone
@@ -137,21 +154,28 @@ void GeoCoord::latLongToUTM(const double lat, const double lon, UTM &utm) {
double T = tan(latRad) * tan(latRad); double T = tan(latRad) * tan(latRad);
double C = eccPrimeSquared * cos(latRad) * cos(latRad); double C = eccPrimeSquared * cos(latRad) * cos(latRad);
double A = cos(latRad) * (lonRad - lonOriginRad); double A = cos(latRad) * (lonRad - lonOriginRad);
double M = a*((1 - eccSquared/4 - 3*eccSquared*eccSquared/64 - 5*eccSquared*eccSquared*eccSquared/256)*latRad double M =
- (3*eccSquared/8 + 3*eccSquared*eccSquared/32 + 45*eccSquared*eccSquared*eccSquared/1024)*sin(2*latRad) a * ((1 - eccSquared / 4 - 3 * eccSquared * eccSquared / 64 - 5 * eccSquared * eccSquared * eccSquared / 256) * latRad -
+ (15*eccSquared*eccSquared/256 + 45*eccSquared*eccSquared*eccSquared/1024)*sin(4*latRad) (3 * eccSquared / 8 + 3 * eccSquared * eccSquared / 32 + 45 * eccSquared * eccSquared * eccSquared / 1024) *
- (35*eccSquared*eccSquared*eccSquared/3072)*sin(6*latRad)); sin(2 * latRad) +
utm.easting = (double)(k0*N*(A+(1-T+C)*pow(A, 3)/6 + (5-18*T+T*T+72*C-58*eccPrimeSquared)*A*A*A*A*A/120) (15 * eccSquared * eccSquared / 256 + 45 * eccSquared * eccSquared * eccSquared / 1024) * sin(4 * latRad) -
+ 500000.0); (35 * eccSquared * eccSquared * eccSquared / 3072) * sin(6 * latRad));
utm.northing = (double)(k0*(M+N*tan(latRad)*(A*A/2+(5-T+9*C+4*C*C)*A*A*A*A/24 utm.easting = (double)(k0 * N *
+ (61-58*T+T*T+600*C-330*eccPrimeSquared)*A*A*A*A*A*A/720))); (A + (1 - T + C) * pow(A, 3) / 6 +
(5 - 18 * T + T * T + 72 * C - 58 * eccPrimeSquared) * A * A * A * A * A / 120) +
500000.0);
utm.northing =
(double)(k0 * (M + N * tan(latRad) *
(A * A / 2 + (5 - T + 9 * C + 4 * C * C) * A * A * A * A / 24 +
(61 - 58 * T + T * T + 600 * C - 330 * eccPrimeSquared) * A * A * A * A * A * A / 720)));
if (lat < 0) if (lat < 0)
utm.northing += 10000000.0; // 10000000 meter offset for southern hemisphere utm.northing += 10000000.0; // 10000000 meter offset for southern hemisphere
} }
// Converts lat long coordinates to an MGRS. // Converts lat long coordinates to an MGRS.
void GeoCoord::latLongToMGRS(const double lat, const double lon, MGRS &mgrs) { void GeoCoord::latLongToMGRS(const double lat, const double lon, MGRS &mgrs)
{
const std::string e100kLetters[3] = {"ABCDEFGH", "JKLMNPQR", "STUVWXYZ"}; const std::string e100kLetters[3] = {"ABCDEFGH", "JKLMNPQR", "STUVWXYZ"};
const std::string n100kLetters[2] = {"ABCDEFGHJKLMNPQRSTUV", "FGHJKLMNPQRSTUVABCDE"}; const std::string n100kLetters[2] = {"ABCDEFGHJKLMNPQRSTUV", "FGHJKLMNPQRSTUVABCDE"};
UTM utm; UTM utm;
@@ -170,7 +194,8 @@ void GeoCoord::latLongToMGRS(const double lat, const double lon, MGRS &mgrs) {
* Converts lat long coordinates to Ordnance Survey Grid Reference (UK National Grid Ref). * Converts lat long coordinates to Ordnance Survey Grid Reference (UK National Grid Ref).
* Based on: https://www.movable-type.co.uk/scripts/latlong-os-gridref.html * Based on: https://www.movable-type.co.uk/scripts/latlong-os-gridref.html
*/ */
void GeoCoord::latLongToOSGR(const double lat, const double lon, OSGR &osgr) { void GeoCoord::latLongToOSGR(const double lat, const double lon, OSGR &osgr)
{
const char letter[] = "ABCDEFGHJKLMNOPQRSTUVWXYZ"; // No 'I' in OSGR const char letter[] = "ABCDEFGHJKLMNOPQRSTUVWXYZ"; // No 'I' in OSGR
double a = 6377563.396; // Airy 1830 semi-major axis double a = 6377563.396; // Airy 1830 semi-major axis
double b = 6356256.909; // Airy 1830 semi-minor axis double b = 6356256.909; // Airy 1830 semi-minor axis
@@ -211,7 +236,8 @@ void GeoCoord::latLongToOSGR(const double lat, const double lon, OSGR &osgr) {
double deltaLambda = lambda - lambda0; double deltaLambda = lambda - lambda0;
double deltaLambda2 = deltaLambda * deltaLambda; double deltaLambda2 = deltaLambda * deltaLambda;
double northing = I + II*deltaLambda2 + III*deltaLambda2*deltaLambda2 + IIIA*deltaLambda2*deltaLambda2*deltaLambda2; double northing =
I + II * deltaLambda2 + III * deltaLambda2 * deltaLambda2 + IIIA * deltaLambda2 * deltaLambda2 * deltaLambda2;
double easting = e0 + IV * deltaLambda + V * deltaLambda2 * deltaLambda + VI * deltaLambda2 * deltaLambda2 * deltaLambda; double easting = e0 + IV * deltaLambda + V * deltaLambda2 * deltaLambda + VI * deltaLambda2 * deltaLambda2 * deltaLambda;
if (easting < 0 || easting > 700000 || northing < 0 || northing > 1300000) // Check if out of boundaries if (easting < 0 || easting > 700000 || northing < 0 || northing > 1300000) // Check if out of boundaries
@@ -232,7 +258,8 @@ void GeoCoord::latLongToOSGR(const double lat, const double lon, OSGR &osgr) {
* Converts lat long coordinates to Open Location Code. * Converts lat long coordinates to Open Location Code.
* Based on: https://github.com/google/open-location-code/blob/main/c/src/olc.c * Based on: https://github.com/google/open-location-code/blob/main/c/src/olc.c
*/ */
void GeoCoord::latLongToOLC(double lat, double lon, OLC &olc) { void GeoCoord::latLongToOLC(double lat, double lon, OLC &olc)
{
char tempCode[] = "1234567890abc"; char tempCode[] = "1234567890abc";
const char kAlphabet[] = "23456789CFGHJMPQRVWX"; const char kAlphabet[] = "23456789CFGHJMPQRVWX";
double latitude; double latitude;
@@ -304,7 +331,8 @@ void GeoCoord::latLongToOLC(double lat, double lon, OLC &olc) {
} }
// Converts the coordinate in WGS84 datum to the OSGB36 datum. // Converts the coordinate in WGS84 datum to the OSGB36 datum.
void GeoCoord::convertWGS84ToOSGB36(const double lat, const double lon, double &osgb_Latitude, double &osgb_Longitude) { void GeoCoord::convertWGS84ToOSGB36(const double lat, const double lon, double &osgb_Latitude, double &osgb_Longitude)
{
// Convert lat long to cartesian // Convert lat long to cartesian
double phi = toRadians(lat); double phi = toRadians(lat);
double lambda = toRadians(lon); double lambda = toRadians(lon);
@@ -340,7 +368,8 @@ void GeoCoord::convertWGS84ToOSGB36(const double lat, const double lon, double &
double tanBeta = (airyB * osgbZ) / (airyA * p) * (1 + airyEcc2 * airyB / R); double tanBeta = (airyB * osgbZ) / (airyA * p) * (1 + airyEcc2 * airyB / R);
double sinBeta = tanBeta / sqrt(1 + tanBeta * tanBeta); double sinBeta = tanBeta / sqrt(1 + tanBeta * tanBeta);
double cosBeta = sinBeta / tanBeta; double cosBeta = sinBeta / tanBeta;
osgb_Latitude = atan2(osgbZ + airyEcc2*airyB*sinBeta*sinBeta*sinBeta, p - airyEcc*airyA*cosBeta*cosBeta*cosBeta); // leave in radians osgb_Latitude = atan2(osgbZ + airyEcc2 * airyB * sinBeta * sinBeta * sinBeta,
p - airyEcc * airyA * cosBeta * cosBeta * cosBeta); // leave in radians
osgb_Longitude = atan2(osgbY, osgbX); // leave in radians osgb_Longitude = atan2(osgbY, osgbX); // leave in radians
// osgb height = p*cos(osgb.latitude) + osgbZ*sin(osgb.latitude) - // osgb height = p*cos(osgb.latitude) + osgbZ*sin(osgb.latitude) -
//(airyA*airyA/(airyA / sqrt(1 - airyEcc*sin(osgb.latitude)*sin(osgb.latitude)))); // Not used, no OSTN data //(airyA*airyA/(airyA / sqrt(1 - airyEcc*sin(osgb.latitude)*sin(osgb.latitude)))); // Not used, no OSTN data
@@ -399,7 +428,8 @@ float GeoCoord::bearing(double lat1, double lon1, double lat2, double lon2)
* The range in meters * The range in meters
* @return range in radians on a great circle * @return range in radians on a great circle
*/ */
float GeoCoord::rangeMetersToRadians(double range_meters) { float GeoCoord::rangeMetersToRadians(double range_meters)
{
// 1 nm is 1852 meters // 1 nm is 1852 meters
double distance_nm = range_meters * 1852; double distance_nm = range_meters * 1852;
return (PI / (180 * 60)) * distance_nm; return (PI / (180 * 60)) * distance_nm;
@@ -412,20 +442,25 @@ float GeoCoord::rangeMetersToRadians(double range_meters) {
* The range in radians * The range in radians
* @return Range in meters on a great circle * @return Range in meters on a great circle
*/ */
float GeoCoord::rangeRadiansToMeters(double range_radians) { float GeoCoord::rangeRadiansToMeters(double range_radians)
{
double distance_nm = ((180 * 60) / PI) * range_radians; double distance_nm = ((180 * 60) / PI) * range_radians;
// 1 meter is 0.000539957 nm // 1 meter is 0.000539957 nm
return distance_nm * 0.000539957; return distance_nm * 0.000539957;
} }
// Find distance from point to passed in point // Find distance from point to passed in point
int32_t GeoCoord::distanceTo(const GeoCoord& pointB) { int32_t GeoCoord::distanceTo(const GeoCoord &pointB)
return latLongToMeter(this->getLatitude() * 1e-7, this->getLongitude() * 1e-7, pointB.getLatitude() * 1e-7, pointB.getLongitude() * 1e-7); {
return latLongToMeter(this->getLatitude() * 1e-7, this->getLongitude() * 1e-7, pointB.getLatitude() * 1e-7,
pointB.getLongitude() * 1e-7);
} }
// Find bearing from point to passed in point // Find bearing from point to passed in point
int32_t GeoCoord::bearingTo(const GeoCoord& pointB) { int32_t GeoCoord::bearingTo(const GeoCoord &pointB)
return bearing(this->getLatitude() * 1e-7, this->getLongitude() * 1e-7, pointB.getLatitude() * 1e-7, pointB.getLongitude() * 1e-7); {
return bearing(this->getLatitude() * 1e-7, this->getLongitude() * 1e-7, pointB.getLatitude() * 1e-7,
pointB.getLongitude() * 1e-7);
} }
/** /**
@@ -437,7 +472,8 @@ int32_t GeoCoord::bearingTo(const GeoCoord& pointB) {
* range in meters * range in meters
* @return GeoCoord object of point at bearing and range from initial point * @return GeoCoord object of point at bearing and range from initial point
*/ */
std::shared_ptr<GeoCoord> GeoCoord::pointAtDistance(double bearing, double range_meters) { std::shared_ptr<GeoCoord> GeoCoord::pointAtDistance(double bearing, double range_meters)
{
double range_radians = rangeMetersToRadians(range_meters); double range_radians = rangeMetersToRadians(range_meters);
double lat1 = this->getLatitude() * 1e-7; double lat1 = this->getLatitude() * 1e-7;
double lon1 = this->getLongitude() * 1e-7; double lon1 = this->getLongitude() * 1e-7;
@@ -446,5 +482,4 @@ std::shared_ptr<GeoCoord> GeoCoord::pointAtDistance(double bearing, double range
double lon = fmod(lon1 - dlon + PI, 2 * PI) - PI; double lon = fmod(lon1 - dlon + PI, 2 * PI) - PI;
return std::make_shared<GeoCoord>(double(lat), double(lon), this->getAltitude()); return std::make_shared<GeoCoord>(double(lat), double(lon), this->getAltitude());
} }
+11 -13
View File
@@ -1,20 +1,21 @@
#pragma once #pragma once
#include <algorithm> #include <algorithm>
#include <string>
#include <cstring>
#include <cstdint> #include <cstdint>
#include <cstring>
#include <math.h> #include <math.h>
#include <stdint.h>
#include <stdexcept>
#include <memory> #include <memory>
#include <stdexcept>
#include <stdint.h>
#include <string>
#define PI 3.1415926535897932384626433832795 #define PI 3.1415926535897932384626433832795
#define OLC_CODE_LEN 11 #define OLC_CODE_LEN 11
// Helper functions // Helper functions
// Raises a number to an exponent, handling negative exponents. // Raises a number to an exponent, handling negative exponents.
static inline double pow_neg(double base, double exponent) { static inline double pow_neg(double base, double exponent)
{
if (exponent == 0) { if (exponent == 0) {
return 1; return 1;
} else if (exponent > 0) { } else if (exponent > 0) {
@@ -35,8 +36,7 @@ static inline double toDegrees(double r)
// GeoCoord structs/classes // GeoCoord structs/classes
// A struct to hold the data for a DMS coordinate. // A struct to hold the data for a DMS coordinate.
struct DMS struct DMS {
{
uint8_t latDeg; uint8_t latDeg;
uint8_t latMin; uint8_t latMin;
uint32_t latSec; uint32_t latSec;
@@ -48,8 +48,7 @@ struct DMS
}; };
// A struct to hold the data for a UTM coordinate, this is also used when creating an MGRS coordinate. // A struct to hold the data for a UTM coordinate, this is also used when creating an MGRS coordinate.
struct UTM struct UTM {
{
uint8_t zone; uint8_t zone;
char band; char band;
uint32_t easting; uint32_t easting;
@@ -57,8 +56,7 @@ struct UTM
}; };
// A struct to hold the data for a MGRS coordinate. // A struct to hold the data for a MGRS coordinate.
struct MGRS struct MGRS {
{
uint8_t zone; uint8_t zone;
char band; char band;
char east100k; char east100k;
@@ -80,7 +78,8 @@ struct OLC {
char code[OLC_CODE_LEN + 1]; // +1 for null termination char code[OLC_CODE_LEN + 1]; // +1 for null termination
}; };
class GeoCoord { class GeoCoord
{
private: private:
int32_t _latitude = 0; int32_t _latitude = 0;
int32_t _longitude = 0; int32_t _longitude = 0;
@@ -161,4 +160,3 @@ class GeoCoord {
// OLC getter // OLC getter
void getOLCCode(char *code) { strncpy(code, _olc.code, OLC_CODE_LEN + 1); } // +1 for null termination void getOLCCode(char *code) { strncpy(code, _olc.code, OLC_CODE_LEN + 1); } // +1 for null termination
}; };
+11 -15
View File
@@ -1,6 +1,6 @@
#include "configuration.h"
#include "NMEAGPS.h" #include "NMEAGPS.h"
#include "RTC.h" #include "RTC.h"
#include "configuration.h"
#include <TinyGPS++.h> #include <TinyGPS++.h>
@@ -29,9 +29,8 @@ bool NMEAGPS::factoryReset()
// send the UBLOX Factory Reset Command regardless of detect state, something is very wrong, just assume it's UBLOX. // send the UBLOX Factory Reset Command regardless of detect state, something is very wrong, just assume it's UBLOX.
// Factory Reset // Factory Reset
byte _message_reset[] = {0xB5, 0x62, 0x06, 0x09, 0x0D, 0x00, 0xFF, byte _message_reset[] = {0xB5, 0x62, 0x06, 0x09, 0x0D, 0x00, 0xFF, 0xFB, 0x00, 0x00, 0x00,
0xFB, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xFF, 0xFF, 0x00, 0x00, 0x17, 0x2B, 0x7E};
0xFF, 0xFF, 0x00, 0x00, 0x17, 0x2B, 0x7E};
_serial_gps->write(_message_reset, sizeof(_message_reset)); _serial_gps->write(_message_reset, sizeof(_message_reset));
delay(1000); delay(1000);
return true; return true;
@@ -85,7 +84,8 @@ The Unix epoch (or Unix time or POSIX time or Unix timestamp) is the number of s
t.tm_year = d.year() - 1900; t.tm_year = d.year() - 1900;
t.tm_isdst = false; t.tm_isdst = false;
if (t.tm_mon > -1) { if (t.tm_mon > -1) {
LOG_DEBUG("NMEA GPS time %02d-%02d-%02d %02d:%02d:%02d\n", d.year(), d.month(), t.tm_mday, t.tm_hour, t.tm_min, t.tm_sec); LOG_DEBUG("NMEA GPS time %02d-%02d-%02d %02d:%02d:%02d\n", d.year(), d.month(), t.tm_mday, t.tm_hour, t.tm_min,
t.tm_sec);
perhapsSetRTC(RTCQualityGPS, t); perhapsSetRTC(RTCQualityGPS, t);
return true; return true;
} else } else
@@ -117,8 +117,7 @@ bool NMEAGPS::lookForLocation()
return false; return false;
#ifdef GPS_EXTRAVERBOSE #ifdef GPS_EXTRAVERBOSE
LOG_DEBUG("AGE: LOC=%d FIX=%d DATE=%d TIME=%d\n", LOG_DEBUG("AGE: LOC=%d FIX=%d DATE=%d TIME=%d\n", reader.location.age(),
reader.location.age(),
#ifndef TINYGPS_OPTION_NO_CUSTOM_FIELDS #ifndef TINYGPS_OPTION_NO_CUSTOM_FIELDS
gsafixtype.age(), gsafixtype.age(),
#else #else
@@ -134,9 +133,7 @@ bool NMEAGPS::lookForLocation()
#ifndef TINYGPS_OPTION_NO_CUSTOM_FIELDS #ifndef TINYGPS_OPTION_NO_CUSTOM_FIELDS
(gsafixtype.age() < GPS_SOL_EXPIRY_MS) && (gsafixtype.age() < GPS_SOL_EXPIRY_MS) &&
#endif #endif
(reader.time.age() < GPS_SOL_EXPIRY_MS) && (reader.time.age() < GPS_SOL_EXPIRY_MS) && (reader.date.age() < GPS_SOL_EXPIRY_MS))) {
(reader.date.age() < GPS_SOL_EXPIRY_MS)))
{
LOG_WARN("SOME data is TOO OLD: LOC %u, TIME %u, DATE %u\n", reader.location.age(), reader.time.age(), reader.date.age()); LOG_WARN("SOME data is TOO OLD: LOC %u, TIME %u, DATE %u\n", reader.location.age(), reader.time.age(), reader.date.age());
return false; return false;
} }
@@ -162,7 +159,7 @@ bool NMEAGPS::lookForLocation()
return false; return false;
} }
p.location_source = Position_LocSource_LOC_INTERNAL; p.location_source = meshtastic_Position_LocSource_LOC_INTERNAL;
// Dilution of precision (an accuracy metric) is reported in 10^2 units, so we need to scale down when we use it // Dilution of precision (an accuracy metric) is reported in 10^2 units, so we need to scale down when we use it
#ifndef TINYGPS_OPTION_NO_CUSTOM_FIELDS #ifndef TINYGPS_OPTION_NO_CUSTOM_FIELDS
@@ -210,10 +207,10 @@ bool NMEAGPS::lookForLocation()
if (reader.course.isUpdated() && reader.course.isValid()) { if (reader.course.isUpdated() && reader.course.isValid()) {
if (reader.course.value() < 36000) { // sanity check if (reader.course.value() < 36000) { // sanity check
p.ground_track = reader.course.value() * 1e3; // Scale the heading (in degrees * 10^-2) to match the expected degrees * 10^-5 p.ground_track =
reader.course.value() * 1e3; // Scale the heading (in degrees * 10^-2) to match the expected degrees * 10^-5
} else { } else {
LOG_WARN("BOGUS course.value() REJECTED: %d\n", LOG_WARN("BOGUS course.value() REJECTED: %d\n", reader.course.value());
reader.course.value());
} }
} }
@@ -224,7 +221,6 @@ bool NMEAGPS::lookForLocation()
return true; return true;
} }
bool NMEAGPS::hasLock() bool NMEAGPS::hasLock()
{ {
// Using GPGGA fix quality indicator // Using GPGGA fix quality indicator
+15 -33
View File
@@ -16,17 +16,13 @@
* ------------------------------------------- * -------------------------------------------
*/ */
uint32_t printWPL(char *buf, size_t bufsz, const Position &pos, const char *name) uint32_t printWPL(char *buf, size_t bufsz, const meshtastic_Position &pos, const char *name)
{ {
GeoCoord geoCoord(pos.latitude_i, pos.longitude_i, pos.altitude); GeoCoord geoCoord(pos.latitude_i, pos.longitude_i, pos.altitude);
uint32_t len = snprintf(buf, bufsz, "$GNWPL,%02d%07.4f,%c,%03d%07.4f,%c,%s", uint32_t len = snprintf(buf, bufsz, "$GNWPL,%02d%07.4f,%c,%03d%07.4f,%c,%s", geoCoord.getDMSLatDeg(),
geoCoord.getDMSLatDeg(), (abs(geoCoord.getLatitude()) - geoCoord.getDMSLatDeg() * 1e+7) * 6e-6, geoCoord.getDMSLatCP(),
(abs(geoCoord.getLatitude()) - geoCoord.getDMSLatDeg() * 1e+7) * 6e-6, geoCoord.getDMSLonDeg(), (abs(geoCoord.getLongitude()) - geoCoord.getDMSLonDeg() * 1e+7) * 6e-6,
geoCoord.getDMSLatCP(), geoCoord.getDMSLonCP(), name);
geoCoord.getDMSLonDeg(),
(abs(geoCoord.getLongitude()) - geoCoord.getDMSLonDeg() * 1e+7) * 6e-6,
geoCoord.getDMSLonCP(),
name);
uint32_t chk = 0; uint32_t chk = 0;
for (uint32_t i = 1; i < len; i++) { for (uint32_t i = 1; i < len; i++) {
chk ^= buf[i]; chk ^= buf[i];
@@ -51,35 +47,21 @@ uint32_t printWPL(char *buf, size_t bufsz, const Position &pos, const char *name
* 8 Horizontal Dilution of precision (meters) * 8 Horizontal Dilution of precision (meters)
* 9 Antenna Altitude above/below mean-sea-level (geoid) (in meters) * 9 Antenna Altitude above/below mean-sea-level (geoid) (in meters)
* 10 Units of antenna altitude, meters * 10 Units of antenna altitude, meters
* 11 Geoidal separation, the difference between the WGS-84 earth ellipsoid and mean-sea-level (geoid), "-" means mean-sea-level below ellipsoid * 11 Geoidal separation, the difference between the WGS-84 earth ellipsoid and mean-sea-level (geoid), "-" means mean-sea-level
* 12 Units of geoidal separation, meters * below ellipsoid 12 Units of geoidal separation, meters 13 Age of differential GPS data, time in seconds since last SC104 type 1
* 13 Age of differential GPS data, time in seconds since last SC104 type 1 or 9 update, null field when DGPS is not used * or 9 update, null field when DGPS is not used 14 Differential reference station ID, 0000-1023 15 Checksum
* 14 Differential reference station ID, 0000-1023
* 15 Checksum
* ------------------------------------------- * -------------------------------------------
*/ */
uint32_t printGGA(char *buf, size_t bufsz, const Position &pos) uint32_t printGGA(char *buf, size_t bufsz, const meshtastic_Position &pos)
{ {
GeoCoord geoCoord(pos.latitude_i, pos.longitude_i, pos.altitude); GeoCoord geoCoord(pos.latitude_i, pos.longitude_i, pos.altitude);
uint32_t len = snprintf(buf, bufsz, "$GNGGA,%06u.%03u,%02d%07.4f,%c,%03d%07.4f,%c,%u,%02u,%04u,%04d,%c,%04d,%c,%d,%04d", uint32_t len =
pos.time / 1000, snprintf(buf, bufsz, "$GNGGA,%06u.%03u,%02d%07.4f,%c,%03d%07.4f,%c,%u,%02u,%04u,%04d,%c,%04d,%c,%d,%04d", pos.time / 1000,
pos.time % 1000, pos.time % 1000, geoCoord.getDMSLatDeg(), (abs(geoCoord.getLatitude()) - geoCoord.getDMSLatDeg() * 1e+7) * 6e-6,
geoCoord.getDMSLatDeg(), geoCoord.getDMSLatCP(), geoCoord.getDMSLonDeg(),
(abs(geoCoord.getLatitude()) - geoCoord.getDMSLatDeg() * 1e+7) * 6e-6, (abs(geoCoord.getLongitude()) - geoCoord.getDMSLonDeg() * 1e+7) * 6e-6, geoCoord.getDMSLonCP(), pos.fix_type,
geoCoord.getDMSLatCP(), pos.sats_in_view, pos.HDOP, geoCoord.getAltitude(), 'M', pos.altitude_geoidal_separation, 'M', 0, 0);
geoCoord.getDMSLonDeg(),
(abs(geoCoord.getLongitude()) - geoCoord.getDMSLonDeg() * 1e+7) * 6e-6,
geoCoord.getDMSLonCP(),
pos.fix_type,
pos.sats_in_view,
pos.HDOP,
geoCoord.getAltitude(),
'M',
pos.altitude_geoidal_separation,
'M',
0,
0);
uint32_t chk = 0; uint32_t chk = 0;
for (uint32_t i = 1; i < len; i++) { for (uint32_t i = 1; i < len; i++) {
+3 -3
View File
@@ -1,7 +1,7 @@
#pragma once #pragma once
#include <Arduino.h>
#include "main.h" #include "main.h"
#include <Arduino.h>
uint32_t printWPL(char *buf, size_t bufsz, const Position &pos, const char *name); uint32_t printWPL(char *buf, size_t bufsz, const meshtastic_Position &pos, const char *name);
uint32_t printGGA(char *buf, size_t bufsz, const Position &pos); uint32_t printGGA(char *buf, size_t bufsz, const meshtastic_Position &pos);
+5 -4
View File
@@ -91,8 +91,7 @@ bool perhapsSetRTC(RTCQuality q, const struct timeval *tv)
// Every 12 hrs we will slam in a new GPS time, to correct for local RTC clock drift // Every 12 hrs we will slam in a new GPS time, to correct for local RTC clock drift
shouldSet = true; shouldSet = true;
LOG_DEBUG("Reapplying external time to correct clock drift %ld secs\n", tv->tv_sec); LOG_DEBUG("Reapplying external time to correct clock drift %ld secs\n", tv->tv_sec);
} } else
else
shouldSet = false; shouldSet = false;
if (shouldSet) { if (shouldSet) {
@@ -109,7 +108,8 @@ bool perhapsSetRTC(RTCQuality q, const struct timeval *tv)
rtc.initI2C(); rtc.initI2C();
tm *t = localtime(&tv->tv_sec); tm *t = localtime(&tv->tv_sec);
rtc.setTime(t->tm_year + 1900, t->tm_mon + 1, t->tm_wday, t->tm_mday, t->tm_hour, t->tm_min, t->tm_sec); rtc.setTime(t->tm_year + 1900, t->tm_mon + 1, t->tm_wday, t->tm_mday, t->tm_hour, t->tm_min, t->tm_sec);
LOG_DEBUG("RV3028_RTC setTime %02d-%02d-%02d %02d:%02d:%02d %ld\n", t->tm_year + 1900, t->tm_mon + 1, t->tm_mday, t->tm_hour, t->tm_min, t->tm_sec, tv->tv_sec); LOG_DEBUG("RV3028_RTC setTime %02d-%02d-%02d %02d:%02d:%02d %ld\n", t->tm_year + 1900, t->tm_mon + 1, t->tm_mday,
t->tm_hour, t->tm_min, t->tm_sec, tv->tv_sec);
} }
#elif defined(PCF8563_RTC) #elif defined(PCF8563_RTC)
if (rtc_found == PCF8563_RTC) { if (rtc_found == PCF8563_RTC) {
@@ -121,7 +121,8 @@ bool perhapsSetRTC(RTCQuality q, const struct timeval *tv)
#endif #endif
tm *t = localtime(&tv->tv_sec); tm *t = localtime(&tv->tv_sec);
rtc.setDateTime(t->tm_year + 1900, t->tm_mon + 1, t->tm_mday, t->tm_hour, t->tm_min, t->tm_sec); rtc.setDateTime(t->tm_year + 1900, t->tm_mon + 1, t->tm_mday, t->tm_hour, t->tm_min, t->tm_sec);
LOG_DEBUG("PCF8563_RTC setDateTime %02d-%02d-%02d %02d:%02d:%02d %ld\n", t->tm_year + 1900, t->tm_mon + 1, t->tm_mday, t->tm_hour, t->tm_min, t->tm_sec, tv->tv_sec); LOG_DEBUG("PCF8563_RTC setDateTime %02d-%02d-%02d %02d:%02d:%02d %ld\n", t->tm_year + 1900, t->tm_mon + 1, t->tm_mday,
t->tm_hour, t->tm_min, t->tm_sec, tv->tv_sec);
} }
#elif defined(ARCH_ESP32) #elif defined(ARCH_ESP32)
settimeofday(tv, NULL); settimeofday(tv, NULL);
+44 -42
View File
@@ -352,7 +352,7 @@ 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 // 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) static bool shouldDrawMessage(const meshtastic_MeshPacket *packet)
{ {
return packet->from != 0 && !moduleConfig.range_test.enabled && !moduleConfig.store_forward.enabled; return packet->from != 0 && !moduleConfig.range_test.enabled && !moduleConfig.store_forward.enabled;
} }
@@ -365,8 +365,8 @@ static void drawTextMessageFrame(OLEDDisplay *display, OLEDDisplayUiState *state
// the max length of this buffer is much longer than we can possibly print // the max length of this buffer is much longer than we can possibly print
static char tempBuf[237]; static char tempBuf[237];
MeshPacket &mp = devicestate.rx_text_message; meshtastic_MeshPacket &mp = devicestate.rx_text_message;
NodeInfo *node = nodeDB.getNode(getFrom(&mp)); meshtastic_NodeInfo *node = nodeDB.getNode(getFrom(&mp));
// LOG_DEBUG("drawing text message from 0x%x: %s\n", mp.from, // LOG_DEBUG("drawing text message from 0x%x: %s\n", mp.from,
// mp.decoded.variant.data.decoded.bytes); // mp.decoded.variant.data.decoded.bytes);
@@ -375,7 +375,7 @@ static void drawTextMessageFrame(OLEDDisplay *display, OLEDDisplayUiState *state
// be wrapped. Currently only spaces and "-" are allowed for wrapping // be wrapped. Currently only spaces and "-" are allowed for wrapping
display->setTextAlignment(TEXT_ALIGN_LEFT); display->setTextAlignment(TEXT_ALIGN_LEFT);
display->setFont(FONT_SMALL); display->setFont(FONT_SMALL);
if (config.display.displaymode == Config_DisplayConfig_DisplayMode_INVERTED) { if (config.display.displaymode == meshtastic_Config_DisplayConfig_DisplayMode_INVERTED) {
display->fillRect(0 + x, 0 + y, x + display->getWidth(), y + FONT_HEIGHT_SMALL); display->fillRect(0 + x, 0 + y, x + display->getWidth(), y + FONT_HEIGHT_SMALL);
display->setColor(BLACK); display->setColor(BLACK);
} }
@@ -556,7 +556,7 @@ static void drawGPSAltitude(OLEDDisplay *display, int16_t x, int16_t y, const GP
} else { } else {
geoCoord.updateCoords(int32_t(gps->getLatitude()), int32_t(gps->getLongitude()), int32_t(gps->getAltitude())); geoCoord.updateCoords(int32_t(gps->getLatitude()), int32_t(gps->getLongitude()), int32_t(gps->getAltitude()));
displayLine = "Altitude: " + String(geoCoord.getAltitude()) + "m"; displayLine = "Altitude: " + String(geoCoord.getAltitude()) + "m";
if (config.display.units == Config_DisplayConfig_DisplayUnits_IMPERIAL) if (config.display.units == meshtastic_Config_DisplayConfig_DisplayUnits_IMPERIAL)
displayLine = "Altitude: " + String(geoCoord.getAltitude() * METERS_TO_FEET) + "ft"; displayLine = "Altitude: " + String(geoCoord.getAltitude() * METERS_TO_FEET) + "ft";
display->drawString(x + (SCREEN_WIDTH - (display->getStringWidth(displayLine))) / 2, y, displayLine); display->drawString(x + (SCREEN_WIDTH - (display->getStringWidth(displayLine))) / 2, y, displayLine);
} }
@@ -578,21 +578,21 @@ static void drawGPScoordinates(OLEDDisplay *display, int16_t x, int16_t y, const
geoCoord.updateCoords(int32_t(gps->getLatitude()), int32_t(gps->getLongitude()), int32_t(gps->getAltitude())); geoCoord.updateCoords(int32_t(gps->getLatitude()), int32_t(gps->getLongitude()), int32_t(gps->getAltitude()));
if (gpsFormat != Config_DisplayConfig_GpsCoordinateFormat_DMS) { if (gpsFormat != meshtastic_Config_DisplayConfig_GpsCoordinateFormat_DMS) {
char coordinateLine[22]; char coordinateLine[22];
if (gpsFormat == Config_DisplayConfig_GpsCoordinateFormat_DEC) { // Decimal Degrees if (gpsFormat == meshtastic_Config_DisplayConfig_GpsCoordinateFormat_DEC) { // Decimal Degrees
snprintf(coordinateLine, sizeof(coordinateLine), "%f %f", geoCoord.getLatitude() * 1e-7, snprintf(coordinateLine, sizeof(coordinateLine), "%f %f", geoCoord.getLatitude() * 1e-7,
geoCoord.getLongitude() * 1e-7); geoCoord.getLongitude() * 1e-7);
} else if (gpsFormat == Config_DisplayConfig_GpsCoordinateFormat_UTM) { // Universal Transverse Mercator } else if (gpsFormat == meshtastic_Config_DisplayConfig_GpsCoordinateFormat_UTM) { // Universal Transverse Mercator
snprintf(coordinateLine, sizeof(coordinateLine), "%2i%1c %06u %07u", geoCoord.getUTMZone(), geoCoord.getUTMBand(), snprintf(coordinateLine, sizeof(coordinateLine), "%2i%1c %06u %07u", geoCoord.getUTMZone(), geoCoord.getUTMBand(),
geoCoord.getUTMEasting(), geoCoord.getUTMNorthing()); geoCoord.getUTMEasting(), geoCoord.getUTMNorthing());
} else if (gpsFormat == Config_DisplayConfig_GpsCoordinateFormat_MGRS) { // Military Grid Reference System } else if (gpsFormat == meshtastic_Config_DisplayConfig_GpsCoordinateFormat_MGRS) { // Military Grid Reference System
snprintf(coordinateLine, sizeof(coordinateLine), "%2i%1c %1c%1c %05u %05u", geoCoord.getMGRSZone(), snprintf(coordinateLine, sizeof(coordinateLine), "%2i%1c %1c%1c %05u %05u", geoCoord.getMGRSZone(),
geoCoord.getMGRSBand(), geoCoord.getMGRSEast100k(), geoCoord.getMGRSNorth100k(), geoCoord.getMGRSBand(), geoCoord.getMGRSEast100k(), geoCoord.getMGRSNorth100k(),
geoCoord.getMGRSEasting(), geoCoord.getMGRSNorthing()); geoCoord.getMGRSEasting(), geoCoord.getMGRSNorthing());
} else if (gpsFormat == Config_DisplayConfig_GpsCoordinateFormat_OLC) { // Open Location Code } else if (gpsFormat == meshtastic_Config_DisplayConfig_GpsCoordinateFormat_OLC) { // Open Location Code
geoCoord.getOLCCode(coordinateLine); geoCoord.getOLCCode(coordinateLine);
} else if (gpsFormat == Config_DisplayConfig_GpsCoordinateFormat_OSGR) { // Ordnance Survey Grid Reference } else if (gpsFormat == meshtastic_Config_DisplayConfig_GpsCoordinateFormat_OSGR) { // Ordnance Survey Grid Reference
if (geoCoord.getOSGRE100k() == 'I' || geoCoord.getOSGRN100k() == 'I') // OSGR is only valid around the UK region if (geoCoord.getOSGRE100k() == 'I' || geoCoord.getOSGRN100k() == 'I') // OSGR is only valid around the UK region
snprintf(coordinateLine, sizeof(coordinateLine), "%s", "Out of Boundary"); snprintf(coordinateLine, sizeof(coordinateLine), "%s", "Out of Boundary");
else else
@@ -699,7 +699,7 @@ static float estimatedHeading(double lat, double lon)
/// Sometimes we will have Position objects that only have a time, so check for /// Sometimes we will have Position objects that only have a time, so check for
/// valid lat/lon /// valid lat/lon
static bool hasPosition(NodeInfo *n) static bool hasPosition(meshtastic_NodeInfo *n)
{ {
return n->has_position && (n->position.latitude_i != 0 || n->position.longitude_i != 0); return n->has_position && (n->position.latitude_i != 0 || n->position.longitude_i != 0);
} }
@@ -709,7 +709,7 @@ static uint16_t getCompassDiam(OLEDDisplay *display)
uint16_t diam = 0; uint16_t diam = 0;
uint16_t offset = 0; uint16_t offset = 0;
if (config.display.displaymode != Config_DisplayConfig_DisplayMode_DEFAULT) if (config.display.displaymode != meshtastic_Config_DisplayConfig_DisplayMode_DEFAULT)
offset = FONT_HEIGHT_SMALL; offset = FONT_HEIGHT_SMALL;
// get the smaller of the 2 dimensions and subtract 20 // get the smaller of the 2 dimensions and subtract 20
@@ -786,7 +786,7 @@ static void drawNodeInfo(OLEDDisplay *display, OLEDDisplayUiState *state, int16_
prevFrame = state->currentFrame; prevFrame = state->currentFrame;
nodeIndex = (nodeIndex + 1) % nodeDB.getNumNodes(); nodeIndex = (nodeIndex + 1) % nodeDB.getNumNodes();
NodeInfo *n = nodeDB.getNodeByIndex(nodeIndex); meshtastic_NodeInfo *n = nodeDB.getNodeByIndex(nodeIndex);
if (n->num == nodeDB.getNodeNum()) { if (n->num == nodeDB.getNodeNum()) {
// Don't show our node, just skip to next // Don't show our node, just skip to next
nodeIndex = (nodeIndex + 1) % nodeDB.getNumNodes(); nodeIndex = (nodeIndex + 1) % nodeDB.getNumNodes();
@@ -795,14 +795,14 @@ static void drawNodeInfo(OLEDDisplay *display, OLEDDisplayUiState *state, int16_
displayedNodeNum = n->num; displayedNodeNum = n->num;
} }
NodeInfo *node = nodeDB.getNodeByIndex(nodeIndex); meshtastic_NodeInfo *node = nodeDB.getNodeByIndex(nodeIndex);
display->setFont(FONT_SMALL); display->setFont(FONT_SMALL);
// The coordinates define the left starting point of the text // The coordinates define the left starting point of the text
display->setTextAlignment(TEXT_ALIGN_LEFT); display->setTextAlignment(TEXT_ALIGN_LEFT);
if (config.display.displaymode == Config_DisplayConfig_DisplayMode_INVERTED) { if (config.display.displaymode == meshtastic_Config_DisplayConfig_DisplayMode_INVERTED) {
display->fillRect(0 + x, 0 + y, x + display->getWidth(), y + FONT_HEIGHT_SMALL); display->fillRect(0 + x, 0 + y, x + display->getWidth(), y + FONT_HEIGHT_SMALL);
} }
@@ -832,12 +832,12 @@ static void drawNodeInfo(OLEDDisplay *display, OLEDDisplayUiState *state, int16_
static char distStr[20]; static char distStr[20];
strncpy(distStr, "? km", sizeof(distStr)); // might not have location data strncpy(distStr, "? km", sizeof(distStr)); // might not have location data
NodeInfo *ourNode = nodeDB.getNode(nodeDB.getNodeNum()); meshtastic_NodeInfo *ourNode = nodeDB.getNode(nodeDB.getNodeNum());
const char *fields[] = {username, distStr, signalStr, lastStr, NULL}; const char *fields[] = {username, distStr, signalStr, lastStr, NULL};
int16_t compassX = 0, compassY = 0; int16_t compassX = 0, compassY = 0;
// coordinates for the center of the compass/circle // coordinates for the center of the compass/circle
if (config.display.displaymode == Config_DisplayConfig_DisplayMode_DEFAULT) { if (config.display.displaymode == meshtastic_Config_DisplayConfig_DisplayMode_DEFAULT) {
compassX = x + SCREEN_WIDTH - getCompassDiam(display) / 2 - 5; compassX = x + SCREEN_WIDTH - getCompassDiam(display) / 2 - 5;
compassY = y + SCREEN_HEIGHT / 2; compassY = y + SCREEN_HEIGHT / 2;
} else { } else {
@@ -847,18 +847,18 @@ static void drawNodeInfo(OLEDDisplay *display, OLEDDisplayUiState *state, int16_
bool hasNodeHeading = false; bool hasNodeHeading = false;
if (ourNode && hasPosition(ourNode)) { if (ourNode && hasPosition(ourNode)) {
Position &op = ourNode->position; meshtastic_Position &op = ourNode->position;
float myHeading = estimatedHeading(DegD(op.latitude_i), DegD(op.longitude_i)); float myHeading = estimatedHeading(DegD(op.latitude_i), DegD(op.longitude_i));
drawCompassNorth(display, compassX, compassY, myHeading); drawCompassNorth(display, compassX, compassY, myHeading);
if (hasPosition(node)) { if (hasPosition(node)) {
// display direction toward node // display direction toward node
hasNodeHeading = true; hasNodeHeading = true;
Position &p = node->position; meshtastic_Position &p = node->position;
float d = float d =
GeoCoord::latLongToMeter(DegD(p.latitude_i), DegD(p.longitude_i), DegD(op.latitude_i), DegD(op.longitude_i)); GeoCoord::latLongToMeter(DegD(p.latitude_i), DegD(p.longitude_i), DegD(op.latitude_i), DegD(op.longitude_i));
if (config.display.units == Config_DisplayConfig_DisplayUnits_IMPERIAL) { if (config.display.units == meshtastic_Config_DisplayConfig_DisplayUnits_IMPERIAL) {
if (d < (2 * MILES_TO_FEET)) if (d < (2 * MILES_TO_FEET))
snprintf(distStr, sizeof(distStr), "%.0f ft", d * METERS_TO_FEET); snprintf(distStr, sizeof(distStr), "%.0f ft", d * METERS_TO_FEET);
else else
@@ -887,7 +887,7 @@ static void drawNodeInfo(OLEDDisplay *display, OLEDDisplayUiState *state, int16_
} }
display->drawCircle(compassX, compassY, getCompassDiam(display) / 2); display->drawCircle(compassX, compassY, getCompassDiam(display) / 2);
if (config.display.displaymode == Config_DisplayConfig_DisplayMode_INVERTED) { if (config.display.displaymode == meshtastic_Config_DisplayConfig_DisplayMode_INVERTED) {
display->setColor(BLACK); display->setColor(BLACK);
} }
// Must be after distStr is populated // Must be after distStr is populated
@@ -910,7 +910,8 @@ static void drawNodeInfo(OLEDDisplay *display, OLEDDisplayUiState *state, int16_
// #else // #else
Screen::Screen(uint8_t address, int sda, int scl) Screen::Screen(uint8_t address, int sda, int scl)
: OSThread("Screen"), cmdQueue(32), : OSThread("Screen"), cmdQueue(32),
dispdev(address, sda, scl, screen_model == Config_DisplayConfig_OledType_OLED_SH1107 ? GEOMETRY_128_128 : GEOMETRY_128_64), dispdev(address, sda, scl,
screen_model == meshtastic_Config_DisplayConfig_OledType_OLED_SH1107 ? GEOMETRY_128_128 : GEOMETRY_128_64),
ui(&dispdev) ui(&dispdev)
{ {
address_found = address; address_found = address;
@@ -961,8 +962,8 @@ void Screen::setup()
useDisplay = true; useDisplay = true;
#ifdef AutoOLEDWire_h #ifdef AutoOLEDWire_h
if (screen_model == Config_DisplayConfig_OledType_OLED_SH1107) if (screen_model == meshtastic_Config_DisplayConfig_OledType_OLED_SH1107)
screen_model = Config_DisplayConfig_OledType_OLED_SH1106; screen_model = meshtastic_Config_DisplayConfig_OledType_OLED_SH1106;
dispdev.setDetected(screen_model); dispdev.setDetected(screen_model);
#endif #endif
@@ -1084,7 +1085,7 @@ int32_t Screen::runOnce()
} }
#ifndef DISABLE_WELCOME_UNSET #ifndef DISABLE_WELCOME_UNSET
if (showingNormalScreen && config.lora.region == Config_LoRaConfig_RegionCode_UNSET) { if (showingNormalScreen && config.lora.region == meshtastic_Config_LoRaConfig_RegionCode_UNSET) {
setWelcomeFrames(); setWelcomeFrames();
} }
#endif #endif
@@ -1404,7 +1405,7 @@ void DebugInfo::drawFrame(OLEDDisplay *display, OLEDDisplayUiState *state, int16
// The coordinates define the left starting point of the text // The coordinates define the left starting point of the text
display->setTextAlignment(TEXT_ALIGN_LEFT); display->setTextAlignment(TEXT_ALIGN_LEFT);
if (config.display.displaymode == Config_DisplayConfig_DisplayMode_INVERTED) { if (config.display.displaymode == meshtastic_Config_DisplayConfig_DisplayMode_INVERTED) {
display->fillRect(0 + x, 0 + y, x + display->getWidth(), y + FONT_HEIGHT_SMALL); display->fillRect(0 + x, 0 + y, x + display->getWidth(), y + FONT_HEIGHT_SMALL);
display->setColor(BLACK); display->setColor(BLACK);
} }
@@ -1418,20 +1419,20 @@ void DebugInfo::drawFrame(OLEDDisplay *display, OLEDDisplayUiState *state, int16
// Display power status // Display power status
if (powerStatus->getHasBattery()) { if (powerStatus->getHasBattery()) {
if (config.display.displaymode == Config_DisplayConfig_DisplayMode_DEFAULT) { if (config.display.displaymode == meshtastic_Config_DisplayConfig_DisplayMode_DEFAULT) {
drawBattery(display, x, y + 2, imgBattery, powerStatus); drawBattery(display, x, y + 2, imgBattery, powerStatus);
} else { } else {
drawBattery(display, x + 1, y + 3, imgBattery, powerStatus); drawBattery(display, x + 1, y + 3, imgBattery, powerStatus);
} }
} else if (powerStatus->knowsUSB()) { } else if (powerStatus->knowsUSB()) {
if (config.display.displaymode == Config_DisplayConfig_DisplayMode_DEFAULT) { if (config.display.displaymode == meshtastic_Config_DisplayConfig_DisplayMode_DEFAULT) {
display->drawFastImage(x, y + 2, 16, 8, powerStatus->getHasUSB() ? imgUSB : imgPower); display->drawFastImage(x, y + 2, 16, 8, powerStatus->getHasUSB() ? imgUSB : imgPower);
} else { } else {
display->drawFastImage(x + 1, y + 3, 16, 8, powerStatus->getHasUSB() ? imgUSB : imgPower); display->drawFastImage(x + 1, y + 3, 16, 8, powerStatus->getHasUSB() ? imgUSB : imgPower);
} }
} }
// Display nodes status // Display nodes status
if (config.display.displaymode == Config_DisplayConfig_DisplayMode_DEFAULT) { if (config.display.displaymode == meshtastic_Config_DisplayConfig_DisplayMode_DEFAULT) {
drawNodes(display, x + (SCREEN_WIDTH * 0.25), y + 2, nodeStatus); drawNodes(display, x + (SCREEN_WIDTH * 0.25), y + 2, nodeStatus);
} else { } else {
drawNodes(display, x + (SCREEN_WIDTH * 0.25), y + 3, nodeStatus); drawNodes(display, x + (SCREEN_WIDTH * 0.25), y + 3, nodeStatus);
@@ -1444,7 +1445,7 @@ void DebugInfo::drawFrame(OLEDDisplay *display, OLEDDisplayUiState *state, int16
#endif #endif
drawGPSpowerstat(display, x, yPos, gpsStatus); drawGPSpowerstat(display, x, yPos, gpsStatus);
} else { } else {
if (config.display.displaymode == Config_DisplayConfig_DisplayMode_DEFAULT) { if (config.display.displaymode == meshtastic_Config_DisplayConfig_DisplayMode_DEFAULT) {
drawGPS(display, x + (SCREEN_WIDTH * 0.63), y + 2, gpsStatus); drawGPS(display, x + (SCREEN_WIDTH * 0.63), y + 2, gpsStatus);
} else { } else {
drawGPS(display, x + (SCREEN_WIDTH * 0.63), y + 3, gpsStatus); drawGPS(display, x + (SCREEN_WIDTH * 0.63), y + 3, gpsStatus);
@@ -1517,7 +1518,7 @@ void DebugInfo::drawFrameWiFi(OLEDDisplay *display, OLEDDisplayUiState *state, i
// The coordinates define the left starting point of the text // The coordinates define the left starting point of the text
display->setTextAlignment(TEXT_ALIGN_LEFT); display->setTextAlignment(TEXT_ALIGN_LEFT);
if (config.display.displaymode == Config_DisplayConfig_DisplayMode_INVERTED) { if (config.display.displaymode == meshtastic_Config_DisplayConfig_DisplayMode_INVERTED) {
display->fillRect(0 + x, 0 + y, x + display->getWidth(), y + FONT_HEIGHT_SMALL); display->fillRect(0 + x, 0 + y, x + display->getWidth(), y + FONT_HEIGHT_SMALL);
display->setColor(BLACK); display->setColor(BLACK);
} }
@@ -1649,7 +1650,7 @@ void DebugInfo::drawFrameSettings(OLEDDisplay *display, OLEDDisplayUiState *stat
// The coordinates define the left starting point of the text // The coordinates define the left starting point of the text
display->setTextAlignment(TEXT_ALIGN_LEFT); display->setTextAlignment(TEXT_ALIGN_LEFT);
if (config.display.displaymode == Config_DisplayConfig_DisplayMode_INVERTED) { if (config.display.displaymode == meshtastic_Config_DisplayConfig_DisplayMode_INVERTED) {
display->fillRect(0 + x, 0 + y, x + display->getWidth(), y + FONT_HEIGHT_SMALL); display->fillRect(0 + x, 0 + y, x + display->getWidth(), y + FONT_HEIGHT_SMALL);
display->setColor(BLACK); display->setColor(BLACK);
} }
@@ -1676,25 +1677,25 @@ void DebugInfo::drawFrameSettings(OLEDDisplay *display, OLEDDisplayUiState *stat
auto mode = ""; auto mode = "";
switch (config.lora.modem_preset) { switch (config.lora.modem_preset) {
case Config_LoRaConfig_ModemPreset_SHORT_SLOW: case meshtastic_Config_LoRaConfig_ModemPreset_SHORT_SLOW:
mode = "ShortS"; mode = "ShortS";
break; break;
case Config_LoRaConfig_ModemPreset_SHORT_FAST: case meshtastic_Config_LoRaConfig_ModemPreset_SHORT_FAST:
mode = "ShortF"; mode = "ShortF";
break; break;
case Config_LoRaConfig_ModemPreset_MEDIUM_SLOW: case meshtastic_Config_LoRaConfig_ModemPreset_MEDIUM_SLOW:
mode = "MedS"; mode = "MedS";
break; break;
case Config_LoRaConfig_ModemPreset_MEDIUM_FAST: case meshtastic_Config_LoRaConfig_ModemPreset_MEDIUM_FAST:
mode = "MedF"; mode = "MedF";
break; break;
case Config_LoRaConfig_ModemPreset_LONG_SLOW: case meshtastic_Config_LoRaConfig_ModemPreset_LONG_SLOW:
mode = "LongS"; mode = "LongS";
break; break;
case Config_LoRaConfig_ModemPreset_LONG_FAST: case meshtastic_Config_LoRaConfig_ModemPreset_LONG_FAST:
mode = "LongF"; mode = "LongF";
break; break;
case Config_LoRaConfig_ModemPreset_VERY_LONG_SLOW: case meshtastic_Config_LoRaConfig_ModemPreset_VERY_LONG_SLOW:
mode = "VeryL"; mode = "VeryL";
break; break;
default: default:
@@ -1756,7 +1757,8 @@ void DebugInfo::drawFrameSettings(OLEDDisplay *display, OLEDDisplayUiState *stat
display->drawString(x + SCREEN_WIDTH - display->getStringWidth(chUtil), y + FONT_HEIGHT_SMALL * 1, chUtil); display->drawString(x + SCREEN_WIDTH - display->getStringWidth(chUtil), y + FONT_HEIGHT_SMALL * 1, chUtil);
if (config.position.gps_enabled) { if (config.position.gps_enabled) {
// Line 3 // Line 3
if (config.display.gps_format != Config_DisplayConfig_GpsCoordinateFormat_DMS) // if DMS then don't draw altitude if (config.display.gps_format !=
meshtastic_Config_DisplayConfig_GpsCoordinateFormat_DMS) // if DMS then don't draw altitude
drawGPSAltitude(display, x, y + FONT_HEIGHT_SMALL * 2, gpsStatus); drawGPSAltitude(display, x, y + FONT_HEIGHT_SMALL * 2, gpsStatus);
// Line 4 // Line 4
@@ -1804,7 +1806,7 @@ int Screen::handleStatusUpdate(const meshtastic::Status *arg)
return 0; return 0;
} }
int Screen::handleTextMessage(const MeshPacket *packet) int Screen::handleTextMessage(const meshtastic_MeshPacket *packet)
{ {
if (showingNormalScreen) { if (showingNormalScreen) {
setFrames(); // Regen the list of screens (will show new text message) setFrames(); // Regen the list of screens (will show new text message)
+3 -3
View File
@@ -110,8 +110,8 @@ class Screen : public concurrency::OSThread
CallbackObserver<Screen, const meshtastic::Status *>(this, &Screen::handleStatusUpdate); CallbackObserver<Screen, const meshtastic::Status *>(this, &Screen::handleStatusUpdate);
CallbackObserver<Screen, const meshtastic::Status *> nodeStatusObserver = CallbackObserver<Screen, const meshtastic::Status *> nodeStatusObserver =
CallbackObserver<Screen, const meshtastic::Status *>(this, &Screen::handleStatusUpdate); CallbackObserver<Screen, const meshtastic::Status *>(this, &Screen::handleStatusUpdate);
CallbackObserver<Screen, const MeshPacket *> textMessageObserver = CallbackObserver<Screen, const meshtastic_MeshPacket *> textMessageObserver =
CallbackObserver<Screen, const MeshPacket *>(this, &Screen::handleTextMessage); CallbackObserver<Screen, const meshtastic_MeshPacket *>(this, &Screen::handleTextMessage);
CallbackObserver<Screen, const UIFrameEvent *> uiFrameEventObserver = CallbackObserver<Screen, const UIFrameEvent *> uiFrameEventObserver =
CallbackObserver<Screen, const UIFrameEvent *>(this, &Screen::handleUIFrameEvent); CallbackObserver<Screen, const UIFrameEvent *>(this, &Screen::handleUIFrameEvent);
@@ -273,7 +273,7 @@ class Screen : public concurrency::OSThread
DebugInfo *debug_info() { return &debugInfo; } DebugInfo *debug_info() { return &debugInfo; }
int handleStatusUpdate(const meshtastic::Status *arg); int handleStatusUpdate(const meshtastic::Status *arg);
int handleTextMessage(const MeshPacket *arg); int handleTextMessage(const meshtastic_MeshPacket *arg);
int handleUIFrameEvent(const UIFrameEvent *arg); int handleUIFrameEvent(const UIFrameEvent *arg);
/// Used to force (super slow) eink displays to draw critical frames /// Used to force (super slow) eink displays to draw critical frames
+6 -3
View File
@@ -8,7 +8,8 @@ const uint8_t SATELLITE_IMAGE[] PROGMEM = {0x00, 0x08, 0x00, 0x1C, 0x00, 0x0E, 0
const uint8_t imgSatellite[] PROGMEM = {0x70, 0x71, 0x22, 0xFA, 0xFA, 0x22, 0x71, 0x70}; const uint8_t imgSatellite[] PROGMEM = {0x70, 0x71, 0x22, 0xFA, 0xFA, 0x22, 0x71, 0x70};
const uint8_t imgUSB[] PROGMEM = {0x60, 0x60, 0x30, 0x18, 0x18, 0x18, 0x24, 0x42, 0x42, 0x42, 0x42, 0x7E, 0x24, 0x24, 0x24, 0x3C}; const uint8_t imgUSB[] PROGMEM = {0x60, 0x60, 0x30, 0x18, 0x18, 0x18, 0x24, 0x42, 0x42, 0x42, 0x42, 0x7E, 0x24, 0x24, 0x24, 0x3C};
const uint8_t imgPower[] PROGMEM = { 0x40, 0x40, 0x40, 0x58, 0x48, 0x08, 0x08, 0x08, 0x1C, 0x22, 0x22, 0x41, 0x7F, 0x22, 0x22, 0x22 }; const uint8_t imgPower[] PROGMEM = {0x40, 0x40, 0x40, 0x58, 0x48, 0x08, 0x08, 0x08,
0x1C, 0x22, 0x22, 0x41, 0x7F, 0x22, 0x22, 0x22};
const uint8_t imgUser[] PROGMEM = {0x3C, 0x42, 0x99, 0xA5, 0xA5, 0x99, 0x42, 0x3C}; const uint8_t imgUser[] PROGMEM = {0x3C, 0x42, 0x99, 0xA5, 0xA5, 0x99, 0x42, 0x3C};
const uint8_t imgPositionEmpty[] PROGMEM = {0x20, 0x30, 0x28, 0x24, 0x42, 0xFF}; const uint8_t imgPositionEmpty[] PROGMEM = {0x20, 0x30, 0x28, 0x24, 0x42, 0xFF};
const uint8_t imgPositionSolid[] PROGMEM = {0x20, 0x30, 0x38, 0x3C, 0x7E, 0xFF}; const uint8_t imgPositionSolid[] PROGMEM = {0x20, 0x30, 0x38, 0x3C, 0x7E, 0xFF};
@@ -18,8 +19,10 @@ const uint8_t imgQuestionL1[] PROGMEM = { 0xff, 0x01, 0x01, 0x32, 0x7b, 0
const uint8_t imgQuestionL2[] PROGMEM = {0x0f, 0x08, 0x08, 0x08, 0x06, 0x0f, 0x0f, 0x06, 0x08, 0x08, 0x08, 0x0f}; const uint8_t imgQuestionL2[] PROGMEM = {0x0f, 0x08, 0x08, 0x08, 0x06, 0x0f, 0x0f, 0x06, 0x08, 0x08, 0x08, 0x0f};
const uint8_t imgInfoL1[] PROGMEM = {0xff, 0x01, 0x01, 0x01, 0x1e, 0x7f, 0x1e, 0x01, 0x01, 0x01, 0x01, 0xff}; const uint8_t imgInfoL1[] PROGMEM = {0xff, 0x01, 0x01, 0x01, 0x1e, 0x7f, 0x1e, 0x01, 0x01, 0x01, 0x01, 0xff};
const uint8_t imgInfoL2[] PROGMEM = {0x0f, 0x08, 0x08, 0x08, 0x06, 0x0f, 0x0f, 0x06, 0x08, 0x08, 0x08, 0x0f}; const uint8_t imgInfoL2[] PROGMEM = {0x0f, 0x08, 0x08, 0x08, 0x06, 0x0f, 0x0f, 0x06, 0x08, 0x08, 0x08, 0x0f};
const uint8_t imgSFL1[] PROGMEM = { 0xb6, 0x8f, 0x19, 0x11, 0x31, 0xe3, 0xc2, 0x01, 0x01, 0xf9, 0xf9, 0x89, 0x89, 0x89, 0x09, 0xeb}; const uint8_t imgSFL1[] PROGMEM = {0xb6, 0x8f, 0x19, 0x11, 0x31, 0xe3, 0xc2, 0x01,
const uint8_t imgSFL2[] PROGMEM = { 0x0e, 0x09, 0x09, 0x09, 0x09, 0x09, 0x08, 0x08, 0x00, 0x0f, 0x0f, 0x00, 0x08, 0x08, 0x08, 0x0f}; 0x01, 0xf9, 0xf9, 0x89, 0x89, 0x89, 0x09, 0xeb};
const uint8_t imgSFL2[] PROGMEM = {0x0e, 0x09, 0x09, 0x09, 0x09, 0x09, 0x08, 0x08,
0x00, 0x0f, 0x0f, 0x00, 0x08, 0x08, 0x08, 0x0f};
#else #else
const uint8_t imgInfo[] PROGMEM = {0xff, 0x81, 0x00, 0xfb, 0xfb, 0x00, 0x81, 0xff}; const uint8_t imgInfo[] PROGMEM = {0xff, 0x81, 0x00, 0xfb, 0xfb, 0x00, 0x81, 0xff};
const uint8_t imgQuestion[] PROGMEM = {0xbf, 0x41, 0xc0, 0x8b, 0xdb, 0x70, 0xa1, 0xdf}; const uint8_t imgQuestion[] PROGMEM = {0xbf, 0x41, 0xc0, 0x8b, 0xdb, 0x70, 0xa1, 0xdf};
+1 -3
View File
@@ -3,9 +3,7 @@
InputBroker *inputBroker; InputBroker *inputBroker;
InputBroker::InputBroker() InputBroker::InputBroker(){};
{
};
void InputBroker::registerSource(Observable<const InputEvent *> *source) void InputBroker::registerSource(Observable<const InputEvent *> *source)
{ {
+1 -2
View File
@@ -9,8 +9,7 @@ typedef struct _InputEvent {
char inputEvent; char inputEvent;
char kbchar; char kbchar;
} InputEvent; } InputEvent;
class InputBroker : class InputBroker : public Observable<const InputEvent *>
public Observable<const InputEvent *>
{ {
CallbackObserver<InputBroker, const InputEvent *> inputEventObserver = CallbackObserver<InputBroker, const InputEvent *> inputEventObserver =
CallbackObserver<InputBroker, const InputEvent *>(this, &InputBroker::handleInputEvent); CallbackObserver<InputBroker, const InputEvent *>(this, &InputBroker::handleInputEvent);
+2 -2
View File
@@ -34,7 +34,7 @@ void RotaryEncoderInterruptBase::init(
int32_t RotaryEncoderInterruptBase::runOnce() int32_t RotaryEncoderInterruptBase::runOnce()
{ {
InputEvent e; InputEvent e;
e.inputEvent = ModuleConfig_CannedMessageConfig_InputEventChar_NONE; e.inputEvent = meshtastic_ModuleConfig_CannedMessageConfig_InputEventChar_NONE;
e.source = this->_originName; e.source = this->_originName;
if (this->action == ROTARY_ACTION_PRESSED) { if (this->action == ROTARY_ACTION_PRESSED) {
@@ -48,7 +48,7 @@ int32_t RotaryEncoderInterruptBase::runOnce()
e.inputEvent = this->_eventCcw; e.inputEvent = this->_eventCcw;
} }
if (e.inputEvent != ModuleConfig_CannedMessageConfig_InputEventChar_NONE) { if (e.inputEvent != meshtastic_ModuleConfig_CannedMessageConfig_InputEventChar_NONE) {
this->notifyObservers(&e); this->notifyObservers(&e);
} }
+3 -3
View File
@@ -33,8 +33,8 @@ class RotaryEncoderInterruptBase : public Observable<const InputEvent *>, public
private: private:
uint8_t _pinA = 0; uint8_t _pinA = 0;
uint8_t _pinB = 0; uint8_t _pinB = 0;
char _eventCw = ModuleConfig_CannedMessageConfig_InputEventChar_NONE; char _eventCw = meshtastic_ModuleConfig_CannedMessageConfig_InputEventChar_NONE;
char _eventCcw = ModuleConfig_CannedMessageConfig_InputEventChar_NONE; char _eventCcw = meshtastic_ModuleConfig_CannedMessageConfig_InputEventChar_NONE;
char _eventPressed = ModuleConfig_CannedMessageConfig_InputEventChar_NONE; char _eventPressed = meshtastic_ModuleConfig_CannedMessageConfig_InputEventChar_NONE;
const char *_originName; const char *_originName;
}; };
+1 -2
View File
@@ -8,8 +8,7 @@
* to your device as you wish, but you always need to have separate event * to your device as you wish, but you always need to have separate event
* handlers, thus you need to have a RotaryEncoderInterrupt implementation. * handlers, thus you need to have a RotaryEncoderInterrupt implementation.
*/ */
class RotaryEncoderInterruptImpl1 : class RotaryEncoderInterruptImpl1 : public RotaryEncoderInterruptBase
public RotaryEncoderInterruptBase
{ {
public: public:
RotaryEncoderInterruptImpl1(); RotaryEncoderInterruptImpl1();
+4 -8
View File
@@ -1,15 +1,12 @@
#include "configuration.h"
#include "UpDownInterruptBase.h" #include "UpDownInterruptBase.h"
#include "configuration.h"
UpDownInterruptBase::UpDownInterruptBase( UpDownInterruptBase::UpDownInterruptBase(const char *name)
const char *name)
{ {
this->_originName = name; this->_originName = name;
} }
void UpDownInterruptBase::init( void UpDownInterruptBase::init(uint8_t pinDown, uint8_t pinUp, uint8_t pinPress, char eventDown, char eventUp, char eventPressed,
uint8_t pinDown, uint8_t pinUp, uint8_t pinPress,
char eventDown, char eventUp, char eventPressed,
void (*onIntDown)(), void (*onIntUp)(), void (*onIntPress)()) void (*onIntDown)(), void (*onIntUp)(), void (*onIntPress)())
{ {
this->_pinDown = pinDown; this->_pinDown = pinDown;
@@ -26,8 +23,7 @@ void UpDownInterruptBase::init(
attachInterrupt(this->_pinDown, onIntDown, RISING); attachInterrupt(this->_pinDown, onIntDown, RISING);
attachInterrupt(this->_pinUp, onIntUp, RISING); attachInterrupt(this->_pinUp, onIntUp, RISING);
LOG_DEBUG("GPIO initialized (%d, %d, %d)\n", LOG_DEBUG("GPIO initialized (%d, %d, %d)\n", this->_pinDown, this->_pinUp, pinPress);
this->_pinDown, this->_pinUp, pinPress);
} }
void UpDownInterruptBase::intPressHandler() void UpDownInterruptBase::intPressHandler()
+3 -3
View File
@@ -16,8 +16,8 @@ class UpDownInterruptBase : public Observable<const InputEvent *>
private: private:
uint8_t _pinDown = 0; uint8_t _pinDown = 0;
uint8_t _pinUp = 0; uint8_t _pinUp = 0;
char _eventDown = ModuleConfig_CannedMessageConfig_InputEventChar_NONE; char _eventDown = meshtastic_ModuleConfig_CannedMessageConfig_InputEventChar_NONE;
char _eventUp = ModuleConfig_CannedMessageConfig_InputEventChar_NONE; char _eventUp = meshtastic_ModuleConfig_CannedMessageConfig_InputEventChar_NONE;
char _eventPressed = ModuleConfig_CannedMessageConfig_InputEventChar_NONE; char _eventPressed = meshtastic_ModuleConfig_CannedMessageConfig_InputEventChar_NONE;
const char *_originName; const char *_originName;
}; };
+3 -3
View File
@@ -17,9 +17,9 @@ void UpDownInterruptImpl1::init()
uint8_t pinDown = moduleConfig.canned_message.inputbroker_pin_b; uint8_t pinDown = moduleConfig.canned_message.inputbroker_pin_b;
uint8_t pinPress = moduleConfig.canned_message.inputbroker_pin_press; uint8_t pinPress = moduleConfig.canned_message.inputbroker_pin_press;
char eventDown = static_cast<char>(ModuleConfig_CannedMessageConfig_InputEventChar_DOWN); char eventDown = static_cast<char>(meshtastic_ModuleConfig_CannedMessageConfig_InputEventChar_DOWN);
char eventUp = static_cast<char>(ModuleConfig_CannedMessageConfig_InputEventChar_UP); char eventUp = static_cast<char>(meshtastic_ModuleConfig_CannedMessageConfig_InputEventChar_UP);
char eventPressed = static_cast<char>(ModuleConfig_CannedMessageConfig_InputEventChar_SELECT); char eventPressed = static_cast<char>(meshtastic_ModuleConfig_CannedMessageConfig_InputEventChar_SELECT);
UpDownInterruptBase::init(pinDown, pinUp, pinPress, eventDown, eventUp, eventPressed, UpDownInterruptImpl1::handleIntDown, UpDownInterruptBase::init(pinDown, pinUp, pinPress, eventDown, eventUp, eventPressed, UpDownInterruptImpl1::handleIntDown,
UpDownInterruptImpl1::handleIntUp, UpDownInterruptImpl1::handleIntPressed); UpDownInterruptImpl1::handleIntUp, UpDownInterruptImpl1::handleIntPressed);
+1 -2
View File
@@ -1,8 +1,7 @@
#pragma once #pragma once
#include "UpDownInterruptBase.h" #include "UpDownInterruptBase.h"
class UpDownInterruptImpl1 : class UpDownInterruptImpl1 : public UpDownInterruptBase
public UpDownInterruptBase
{ {
public: public:
UpDownInterruptImpl1(); UpDownInterruptImpl1();
+2 -6
View File
@@ -3,15 +3,11 @@
CardKbI2cImpl *cardKbI2cImpl; CardKbI2cImpl *cardKbI2cImpl;
CardKbI2cImpl::CardKbI2cImpl() : CardKbI2cImpl::CardKbI2cImpl() : KbI2cBase("cardKB") {}
KbI2cBase("cardKB")
{
}
void CardKbI2cImpl::init() void CardKbI2cImpl::init()
{ {
if (cardkb_found != CARDKB_ADDR) if (cardkb_found != CARDKB_ADDR) {
{
disable(); disable();
return; return;
} }
+1 -2
View File
@@ -9,8 +9,7 @@
* to your device as you wish, but you always need to have separate event * to your device as you wish, but you always need to have separate event
* handlers, thus you need to have a RotaryEncoderInterrupt implementation. * handlers, thus you need to have a RotaryEncoderInterrupt implementation.
*/ */
class CardKbI2cImpl : class CardKbI2cImpl : public KbI2cBase
public KbI2cBase
{ {
public: public:
CardKbI2cImpl(); CardKbI2cImpl();
+10 -10
View File
@@ -70,35 +70,35 @@ int32_t KbI2cBase::runOnce()
while (Wire.available()) { while (Wire.available()) {
char c = Wire.read(); char c = Wire.read();
InputEvent e; InputEvent e;
e.inputEvent = ModuleConfig_CannedMessageConfig_InputEventChar_NONE; e.inputEvent = meshtastic_ModuleConfig_CannedMessageConfig_InputEventChar_NONE;
e.source = this->_originName; e.source = this->_originName;
switch (c) { switch (c) {
case 0x1b: // ESC case 0x1b: // ESC
e.inputEvent = ModuleConfig_CannedMessageConfig_InputEventChar_CANCEL; e.inputEvent = meshtastic_ModuleConfig_CannedMessageConfig_InputEventChar_CANCEL;
break; break;
case 0x08: // Back case 0x08: // Back
e.inputEvent = ModuleConfig_CannedMessageConfig_InputEventChar_BACK; e.inputEvent = meshtastic_ModuleConfig_CannedMessageConfig_InputEventChar_BACK;
e.kbchar = c; e.kbchar = c;
break; break;
case 0xb5: // Up case 0xb5: // Up
e.inputEvent = ModuleConfig_CannedMessageConfig_InputEventChar_UP; e.inputEvent = meshtastic_ModuleConfig_CannedMessageConfig_InputEventChar_UP;
break; break;
case 0xb6: // Down case 0xb6: // Down
e.inputEvent = ModuleConfig_CannedMessageConfig_InputEventChar_DOWN; e.inputEvent = meshtastic_ModuleConfig_CannedMessageConfig_InputEventChar_DOWN;
break; break;
case 0xb4: // Left case 0xb4: // Left
e.inputEvent = ModuleConfig_CannedMessageConfig_InputEventChar_LEFT; e.inputEvent = meshtastic_ModuleConfig_CannedMessageConfig_InputEventChar_LEFT;
e.kbchar = c; e.kbchar = c;
break; break;
case 0xb7: // Right case 0xb7: // Right
e.inputEvent = ModuleConfig_CannedMessageConfig_InputEventChar_RIGHT; e.inputEvent = meshtastic_ModuleConfig_CannedMessageConfig_InputEventChar_RIGHT;
e.kbchar = c; e.kbchar = c;
break; break;
case 0x0d: // Enter case 0x0d: // Enter
e.inputEvent = ModuleConfig_CannedMessageConfig_InputEventChar_SELECT; e.inputEvent = meshtastic_ModuleConfig_CannedMessageConfig_InputEventChar_SELECT;
break; break;
case 0x00: // nopress case 0x00: // nopress
e.inputEvent = ModuleConfig_CannedMessageConfig_InputEventChar_NONE; e.inputEvent = meshtastic_ModuleConfig_CannedMessageConfig_InputEventChar_NONE;
break; break;
default: // all other keys default: // all other keys
e.inputEvent = ANYKEY; e.inputEvent = ANYKEY;
@@ -106,7 +106,7 @@ int32_t KbI2cBase::runOnce()
break; break;
} }
if (e.inputEvent != ModuleConfig_CannedMessageConfig_InputEventChar_NONE) { if (e.inputEvent != meshtastic_ModuleConfig_CannedMessageConfig_InputEventChar_NONE) {
this->notifyObservers(&e); this->notifyObservers(&e);
} }
} }
+2 -4
View File
@@ -1,11 +1,9 @@
#pragma once #pragma once
#include "SinglePortModule.h" // TODO: what header file to include?
#include "InputBroker.h" #include "InputBroker.h"
#include "SinglePortModule.h" // TODO: what header file to include?
class KbI2cBase : class KbI2cBase : public Observable<const InputEvent *>, public concurrency::OSThread
public Observable<const InputEvent *>,
public concurrency::OSThread
{ {
public: public:
explicit KbI2cBase(const char *name); explicit KbI2cBase(const char *name);
+10 -8
View File
@@ -87,7 +87,7 @@ uint8_t rtc_found;
// Keystore Chips // Keystore Chips
uint8_t keystore_found; uint8_t keystore_found;
#ifndef ARCH_PORTDUINO #if !defined(ARCH_PORTDUINO) && !defined(ARCH_STM32WL)
ATECCX08A atecc; ATECCX08A atecc;
#endif #endif
@@ -98,7 +98,7 @@ uint32_t serialSinceMsec;
bool pmu_found; bool pmu_found;
// Array map of sensor types (as array index) and i2c address as value we'll find in the i2c scan // Array map of sensor types (as array index) and i2c address as value we'll find in the i2c scan
uint8_t nodeTelemetrySensorsMap[_TelemetrySensorType_MAX + 1] = { uint8_t nodeTelemetrySensorsMap[_meshtastic_TelemetrySensorType_MAX + 1] = {
0}; // one is enough, missing elements will be initialized to 0 anyway. 0}; // one is enough, missing elements will be initialized to 0 anyway.
Router *router = NULL; // Users of router don't care what sort of subclass implements that API Router *router = NULL; // Users of router don't care what sort of subclass implements that API
@@ -302,7 +302,7 @@ void setup()
playStartMelody(); playStartMelody();
// fixed screen override? // fixed screen override?
if (config.display.oled != Config_DisplayConfig_OledType_OLED_AUTO) if (config.display.oled != meshtastic_Config_DisplayConfig_OledType_OLED_AUTO)
screen_model = config.display.oled; screen_model = config.display.oled;
#if defined(USE_SH1107) #if defined(USE_SH1107)
@@ -341,7 +341,7 @@ void setup()
// Do this after service.init (because that clears error_code) // Do this after service.init (because that clears error_code)
#ifdef HAS_PMU #ifdef HAS_PMU
if (!pmu_found) if (!pmu_found)
RECORD_CRITICALERROR(CriticalErrorCode_NO_AXP192); // Record a hardware fault for missing hardware RECORD_CRITICALERROR(meshtastic_CriticalErrorCode_NO_AXP192); // Record a hardware fault for missing hardware
#endif #endif
// Don't call screen setup until after nodedb is setup (because we need // Don't call screen setup until after nodedb is setup (because we need
@@ -454,9 +454,9 @@ void setup()
// check if the radio chip matches the selected region // check if the radio chip matches the selected region
if ((config.lora.region == Config_LoRaConfig_RegionCode_LORA_24) && (!rIf->wideLora())) { if ((config.lora.region == meshtastic_Config_LoRaConfig_RegionCode_LORA_24) && (!rIf->wideLora())) {
LOG_WARN("Radio chip does not support 2.4GHz LoRa. Reverting to unset.\n"); LOG_WARN("Radio chip does not support 2.4GHz LoRa. Reverting to unset.\n");
config.lora.region = Config_LoRaConfig_RegionCode_UNSET; config.lora.region = meshtastic_Config_LoRaConfig_RegionCode_UNSET;
nodeDB.saveToDisk(SEGMENT_CONFIG); nodeDB.saveToDisk(SEGMENT_CONFIG);
if (!rIf->reconfigure()) { if (!rIf->reconfigure()) {
LOG_WARN("Reconfigure failed, rebooting\n"); LOG_WARN("Reconfigure failed, rebooting\n");
@@ -490,13 +490,15 @@ void setup()
airTime = new AirTime(); airTime = new AirTime();
if (!rIf) if (!rIf)
RECORD_CRITICALERROR(CriticalErrorCode_NO_RADIO); RECORD_CRITICALERROR(meshtastic_CriticalErrorCode_NO_RADIO);
else { else {
router->addInterface(rIf); router->addInterface(rIf);
// Calculate and save the bit rate to myNodeInfo // Calculate and save the bit rate to myNodeInfo
// TODO: This needs to be added what ever method changes the channel from the phone. // 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(meshtastic_Constants_DATA_PAYLOAD_LEN) / (float(rIf->getPacketTime(meshtastic_Constants_DATA_PAYLOAD_LEN)))) *
1000;
LOG_DEBUG("myNodeInfo.bitrate = %f bytes / sec\n", myNodeInfo.bitrate); LOG_DEBUG("myNodeInfo.bitrate = %f bytes / sec\n", myNodeInfo.bitrate);
} }
+1 -1
View File
@@ -26,7 +26,7 @@ extern bool isUSBPowered;
extern ATECCX08A atecc; extern ATECCX08A atecc;
#endif #endif
extern uint8_t nodeTelemetrySensorsMap[_TelemetrySensorType_MAX + 1]; extern uint8_t nodeTelemetrySensorsMap[_meshtastic_TelemetrySensorType_MAX + 1];
extern int TCPPort; // set by Portduino extern int TCPPort; // set by Portduino
+36 -37
View File
@@ -45,23 +45,23 @@ int16_t Channels::generateHash(ChannelIndex channelNum)
/** /**
* Validate a channel, fixing any errors as needed * Validate a channel, fixing any errors as needed
*/ */
Channel &Channels::fixupChannel(ChannelIndex chIndex) meshtastic_Channel &Channels::fixupChannel(ChannelIndex chIndex)
{ {
Channel &ch = getByIndex(chIndex); meshtastic_Channel &ch = getByIndex(chIndex);
ch.index = chIndex; // Preinit the index so it be ready to share with the phone (we'll never change it later) ch.index = chIndex; // Preinit the index so it be ready to share with the phone (we'll never change it later)
if (!ch.has_settings) { if (!ch.has_settings) {
// No settings! Must disable and skip // No settings! Must disable and skip
ch.role = Channel_Role_DISABLED; ch.role = meshtastic_Channel_Role_DISABLED;
memset(&ch.settings, 0, sizeof(ch.settings)); memset(&ch.settings, 0, sizeof(ch.settings));
ch.has_settings = true; ch.has_settings = true;
} else { } else {
ChannelSettings &channelSettings = ch.settings; meshtastic_ChannelSettings &meshtastic_channelSettings = ch.settings;
// Convert the old string "Default" to our new short representation // Convert the old string "Default" to our new short representation
if (strcmp(channelSettings.name, "Default") == 0) if (strcmp(meshtastic_channelSettings.name, "Default") == 0)
*channelSettings.name = '\0'; *meshtastic_channelSettings.name = '\0';
} }
hashes[chIndex] = generateHash(chIndex); hashes[chIndex] = generateHash(chIndex);
@@ -74,11 +74,11 @@ Channel &Channels::fixupChannel(ChannelIndex chIndex)
*/ */
void Channels::initDefaultChannel(ChannelIndex chIndex) void Channels::initDefaultChannel(ChannelIndex chIndex)
{ {
Channel &ch = getByIndex(chIndex); meshtastic_Channel &ch = getByIndex(chIndex);
ChannelSettings &channelSettings = ch.settings; meshtastic_ChannelSettings &channelSettings = ch.settings;
Config_LoRaConfig &loraConfig = config.lora; meshtastic_Config_LoRaConfig &loraConfig = config.lora;
loraConfig.modem_preset = Config_LoRaConfig_ModemPreset_LONG_FAST; // Default to Long Range & Fast loraConfig.modem_preset = meshtastic_Config_LoRaConfig_ModemPreset_LONG_FAST; // Default to Long Range & Fast
loraConfig.use_preset = true; loraConfig.use_preset = true;
loraConfig.tx_power = 0; // default loraConfig.tx_power = 0; // default
uint8_t defaultpskIndex = 1; uint8_t defaultpskIndex = 1;
@@ -87,25 +87,25 @@ void Channels::initDefaultChannel(ChannelIndex chIndex)
strncpy(channelSettings.name, "", sizeof(channelSettings.name)); strncpy(channelSettings.name, "", sizeof(channelSettings.name));
ch.has_settings = true; ch.has_settings = true;
ch.role = Channel_Role_PRIMARY; ch.role = meshtastic_Channel_Role_PRIMARY;
} }
CryptoKey Channels::getKey(ChannelIndex chIndex) CryptoKey Channels::getKey(ChannelIndex chIndex)
{ {
Channel &ch = getByIndex(chIndex); meshtastic_Channel &ch = getByIndex(chIndex);
const ChannelSettings &channelSettings = ch.settings; const meshtastic_ChannelSettings &channelSettings = ch.settings;
assert(ch.has_settings); assert(ch.has_settings);
CryptoKey k; CryptoKey k;
memset(k.bytes, 0, sizeof(k.bytes)); // In case the user provided a short key, we want to pad the rest with zeros memset(k.bytes, 0, sizeof(k.bytes)); // In case the user provided a short key, we want to pad the rest with zeros
if (ch.role == Channel_Role_DISABLED) { if (ch.role == meshtastic_Channel_Role_DISABLED) {
k.length = -1; // invalid k.length = -1; // invalid
} else { } else {
memcpy(k.bytes, channelSettings.psk.bytes, channelSettings.psk.size); memcpy(k.bytes, channelSettings.psk.bytes, channelSettings.psk.size);
k.length = channelSettings.psk.size; k.length = channelSettings.psk.size;
if (k.length == 0) { if (k.length == 0) {
if (ch.role == Channel_Role_SECONDARY) { if (ch.role == meshtastic_Channel_Role_SECONDARY) {
LOG_DEBUG("Unset PSK for secondary channel %s. using primary key\n", ch.settings.name); LOG_DEBUG("Unset PSK for secondary channel %s. using primary key\n", ch.settings.name);
k = getKey(primaryIndex); k = getKey(primaryIndex);
} else } else
@@ -182,24 +182,24 @@ void Channels::onConfigChanged()
{ {
// Make sure the phone hasn't mucked anything up // Make sure the phone hasn't mucked anything up
for (int i = 0; i < channelFile.channels_count; i++) { for (int i = 0; i < channelFile.channels_count; i++) {
Channel &ch = fixupChannel(i); meshtastic_Channel &ch = fixupChannel(i);
if (ch.role == Channel_Role_PRIMARY) if (ch.role == meshtastic_Channel_Role_PRIMARY)
primaryIndex = i; primaryIndex = i;
} }
} }
Channel &Channels::getByIndex(ChannelIndex chIndex) meshtastic_Channel &Channels::getByIndex(ChannelIndex chIndex)
{ {
// remove this assert cause malformed packets can make our firmware reboot here. // remove this assert cause malformed packets can make our firmware reboot here.
if (chIndex < channelFile.channels_count) { // This should be equal to MAX_NUM_CHANNELS if (chIndex < channelFile.channels_count) { // This should be equal to MAX_NUM_CHANNELS
Channel *ch = channelFile.channels + chIndex; meshtastic_Channel *ch = channelFile.channels + chIndex;
return *ch; return *ch;
} else { } else {
LOG_ERROR("Invalid channel index %d > %d, malformed packet received?\n", chIndex, channelFile.channels_count); LOG_ERROR("Invalid channel index %d > %d, malformed packet received?\n", chIndex, channelFile.channels_count);
static Channel *ch = (Channel *)malloc(sizeof(Channel)); static meshtastic_Channel *ch = (meshtastic_Channel *)malloc(sizeof(meshtastic_Channel));
memset(ch, 0, sizeof(Channel)); memset(ch, 0, sizeof(meshtastic_Channel));
// ch.index -1 means we don't know the channel locally and need to look it up by settings.name // ch.index -1 means we don't know the channel locally and need to look it up by settings.name
// not sure this is handled right everywhere // not sure this is handled right everywhere
ch->index = -1; ch->index = -1;
@@ -207,7 +207,7 @@ Channel &Channels::getByIndex(ChannelIndex chIndex)
} }
} }
Channel &Channels::getByName(const char* chName) meshtastic_Channel &Channels::getByName(const char *chName)
{ {
for (ChannelIndex i = 0; i < getNumChannels(); i++) { for (ChannelIndex i = 0; i < getNumChannels(); i++) {
if (strcasecmp(getGlobalId(i), chName) == 0) { if (strcasecmp(getGlobalId(i), chName) == 0) {
@@ -218,15 +218,15 @@ Channel &Channels::getByName(const char* chName)
return getByIndex(getPrimaryIndex()); return getByIndex(getPrimaryIndex());
} }
void Channels::setChannel(const Channel &c) void Channels::setChannel(const meshtastic_Channel &c)
{ {
Channel &old = getByIndex(c.index); meshtastic_Channel &old = getByIndex(c.index);
// if this is the new primary, demote any existing roles // if this is the new primary, demote any existing roles
if (c.role == Channel_Role_PRIMARY) if (c.role == meshtastic_Channel_Role_PRIMARY)
for (int i = 0; i < getNumChannels(); i++) for (int i = 0; i < getNumChannels(); i++)
if (channelFile.channels[i].role == Channel_Role_PRIMARY) if (channelFile.channels[i].role == meshtastic_Channel_Role_PRIMARY)
channelFile.channels[i].role = Channel_Role_SECONDARY; channelFile.channels[i].role = meshtastic_Channel_Role_SECONDARY;
old = c; // slam in the new settings/role old = c; // slam in the new settings/role
} }
@@ -234,7 +234,7 @@ void Channels::setChannel(const Channel &c)
const char *Channels::getName(size_t chIndex) const char *Channels::getName(size_t chIndex)
{ {
// Convert the short "" representation for Default into a usable string // Convert the short "" representation for Default into a usable string
const ChannelSettings &channelSettings = getByIndex(chIndex).settings; const meshtastic_ChannelSettings &channelSettings = getByIndex(chIndex).settings;
const char *channelName = channelSettings.name; const char *channelName = channelSettings.name;
if (!*channelName) { // emptystring if (!*channelName) { // emptystring
// Per mesh.proto spec, if bandwidth is specified we must ignore modemPreset 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
@@ -242,33 +242,32 @@ const char *Channels::getName(size_t chIndex)
if (config.lora.use_preset) { if (config.lora.use_preset) {
switch (config.lora.modem_preset) { switch (config.lora.modem_preset) {
case Config_LoRaConfig_ModemPreset_SHORT_SLOW: case meshtastic_Config_LoRaConfig_ModemPreset_SHORT_SLOW:
channelName = "ShortSlow"; channelName = "ShortSlow";
break; break;
case Config_LoRaConfig_ModemPreset_SHORT_FAST: case meshtastic_Config_LoRaConfig_ModemPreset_SHORT_FAST:
channelName = "ShortFast"; channelName = "ShortFast";
break; break;
case Config_LoRaConfig_ModemPreset_MEDIUM_SLOW: case meshtastic_Config_LoRaConfig_ModemPreset_MEDIUM_SLOW:
channelName = "MediumSlow"; channelName = "MediumSlow";
break; break;
case Config_LoRaConfig_ModemPreset_MEDIUM_FAST: case meshtastic_Config_LoRaConfig_ModemPreset_MEDIUM_FAST:
channelName = "MediumFast"; channelName = "MediumFast";
break; break;
case Config_LoRaConfig_ModemPreset_LONG_SLOW: case meshtastic_Config_LoRaConfig_ModemPreset_LONG_SLOW:
channelName = "LongSlow"; channelName = "LongSlow";
break; break;
case Config_LoRaConfig_ModemPreset_LONG_FAST: case meshtastic_Config_LoRaConfig_ModemPreset_LONG_FAST:
channelName = "LongFast"; channelName = "LongFast";
break; break;
case Config_LoRaConfig_ModemPreset_VERY_LONG_SLOW: case meshtastic_Config_LoRaConfig_ModemPreset_VERY_LONG_SLOW:
channelName = "VLongSlow"; channelName = "VLongSlow";
break; break;
default: default:
channelName = "Invalid"; channelName = "Invalid";
break; break;
} }
} } else {
else {
channelName = "Custom"; channelName = "Custom";
} }
} }
+5 -6
View File
@@ -29,24 +29,23 @@ class Channels
int16_t hashes[MAX_NUM_CHANNELS] = {}; int16_t hashes[MAX_NUM_CHANNELS] = {};
public: public:
Channels() {} Channels() {}
/// Well known channel names /// Well known channel names
static const char *adminChannel, *gpioChannel, *serialChannel; static const char *adminChannel, *gpioChannel, *serialChannel;
const ChannelSettings &getPrimary() { return getByIndex(getPrimaryIndex()).settings; } const meshtastic_ChannelSettings &getPrimary() { return getByIndex(getPrimaryIndex()).settings; }
/** Return the Channel for a specified index */ /** Return the Channel for a specified index */
Channel &getByIndex(ChannelIndex chIndex); meshtastic_Channel &getByIndex(ChannelIndex chIndex);
/** Return the Channel for a specified name, return primary if not found. */ /** Return the Channel for a specified name, return primary if not found. */
Channel &getByName(const char* chName); meshtastic_Channel &getByName(const char *chName);
/** Using the index inside the channel, update the specified channel's settings and role. If this channel is being promoted /** Using the index inside the channel, update the specified channel's settings and role. If this channel is being promoted
* to be primary, force all other channels to be secondary. * to be primary, force all other channels to be secondary.
*/ */
void setChannel(const Channel &c); void setChannel(const meshtastic_Channel &c);
/** Return a human friendly name for this channel (and expand any short strings as needed) /** Return a human friendly name for this channel (and expand any short strings as needed)
*/ */
@@ -125,7 +124,7 @@ class Channels
/** /**
* Validate a channel, fixing any errors as needed * Validate a channel, fixing any errors as needed
*/ */
Channel &fixupChannel(ChannelIndex chIndex); meshtastic_Channel &fixupChannel(ChannelIndex chIndex);
/** /**
* Write a default channel to the specified channel index * Write a default channel to the specified channel index
+1 -1
View File
@@ -1,5 +1,5 @@
#include "configuration.h"
#include "CryptoEngine.h" #include "CryptoEngine.h"
#include "configuration.h"
void CryptoEngine::setKey(const CryptoKey &k) void CryptoEngine::setKey(const CryptoKey &k)
{ {
+8 -7
View File
@@ -9,7 +9,7 @@ FloodingRouter::FloodingRouter() {}
* later free() the packet to pool. This routine is not allowed to stall. * later free() the packet to pool. This routine is not allowed to stall.
* If the txmit queue is full it might return an error * If the txmit queue is full it might return an error
*/ */
ErrorCode FloodingRouter::send(MeshPacket *p) ErrorCode FloodingRouter::send(meshtastic_MeshPacket *p)
{ {
// Add any messages _we_ send to the seen message list (so we will ignore all retransmissions we see) // Add any messages _we_ send to the seen message list (so we will ignore all retransmissions we see)
wasSeenRecently(p); // FIXME, move this to a sniffSent method wasSeenRecently(p); // FIXME, move this to a sniffSent method
@@ -17,7 +17,7 @@ ErrorCode FloodingRouter::send(MeshPacket *p)
return Router::send(p); return Router::send(p);
} }
bool FloodingRouter::shouldFilterReceived(const MeshPacket *p) bool FloodingRouter::shouldFilterReceived(const meshtastic_MeshPacket *p)
{ {
if (wasSeenRecently(p)) { // Note: this will also add a recent packet record if (wasSeenRecently(p)) { // Note: this will also add a recent packet record
printPacket("Ignoring incoming msg, because we've already seen it", p); printPacket("Ignoring incoming msg, because we've already seen it", p);
@@ -27,9 +27,10 @@ bool FloodingRouter::shouldFilterReceived(const MeshPacket *p)
return Router::shouldFilterReceived(p); return Router::shouldFilterReceived(p);
} }
void FloodingRouter::sniffReceived(const MeshPacket *p, const Routing *c) void FloodingRouter::sniffReceived(const meshtastic_MeshPacket *p, const meshtastic_Routing *c)
{ {
bool isAck = ((c && c->error_reason == Routing_Error_NONE)); // consider only ROUTING_APP message without error as ACK bool isAck =
((c && c->error_reason == meshtastic_Routing_Error_NONE)); // consider only ROUTING_APP message without error as ACK
if (isAck && p->to != getNodeNum()) { if (isAck && p->to != getNodeNum()) {
// do not flood direct message that is ACKed // do not flood direct message that is ACKed
LOG_DEBUG("Receiving an ACK not for me, but don't need to rebroadcast this direct message anymore.\n"); LOG_DEBUG("Receiving an ACK not for me, but don't need to rebroadcast this direct message anymore.\n");
@@ -37,13 +38,13 @@ void FloodingRouter::sniffReceived(const MeshPacket *p, const Routing *c)
} }
if ((p->to != getNodeNum()) && (p->hop_limit > 0) && (getFrom(p) != getNodeNum())) { if ((p->to != getNodeNum()) && (p->hop_limit > 0) && (getFrom(p) != getNodeNum())) {
if (p->id != 0) { if (p->id != 0) {
if (config.device.role != Config_DeviceConfig_Role_CLIENT_MUTE) { if (config.device.role != meshtastic_Config_DeviceConfig_Role_CLIENT_MUTE) {
MeshPacket *tosend = packetPool.allocCopy(*p); // keep a copy because we will be sending it meshtastic_MeshPacket *tosend = packetPool.allocCopy(*p); // keep a copy because we will be sending it
tosend->hop_limit--; // bump down the hop count tosend->hop_limit--; // bump down the hop count
// If it is a traceRoute request, update the route that it went via me // If it is a traceRoute request, update the route that it went via me
if (p->which_payload_variant == MeshPacket_decoded_tag && traceRouteModule->wantPacket(p)) { if (p->which_payload_variant == meshtastic_MeshPacket_decoded_tag && traceRouteModule->wantPacket(p)) {
traceRouteModule->updateRoute(tosend); traceRouteModule->updateRoute(tosend);
} }
+3 -3
View File
@@ -42,7 +42,7 @@ class FloodingRouter : public Router, protected PacketHistory
* later free() the packet to pool. This routine is not allowed to stall. * later free() the packet to pool. This routine is not allowed to stall.
* If the txmit queue is full it might return an error * If the txmit queue is full it might return an error
*/ */
virtual ErrorCode send(MeshPacket *p) override; virtual ErrorCode send(meshtastic_MeshPacket *p) override;
protected: protected:
/** /**
@@ -51,10 +51,10 @@ class FloodingRouter : public Router, protected PacketHistory
* Called immedately on receiption, before any further processing. * Called immedately on receiption, before any further processing.
* @return true to abandon the packet * @return true to abandon the packet
*/ */
virtual bool shouldFilterReceived(const MeshPacket *p) override; virtual bool shouldFilterReceived(const meshtastic_MeshPacket *p) override;
/** /**
* Look for broadcasts we need to rebroadcast * Look for broadcasts we need to rebroadcast
*/ */
virtual void sniffReceived(const MeshPacket *p, const Routing *c) override; virtual void sniffReceived(const meshtastic_MeshPacket *p, const meshtastic_Routing *c) override;
}; };
+3 -3
View File
@@ -1,9 +1,9 @@
#include "SX126xInterface.h"
#include "SX126xInterface.cpp" #include "SX126xInterface.cpp"
#include "SX128xInterface.h" #include "SX126xInterface.h"
#include "SX128xInterface.cpp" #include "SX128xInterface.cpp"
#include "api/ServerAPI.h" #include "SX128xInterface.h"
#include "api/ServerAPI.cpp" #include "api/ServerAPI.cpp"
#include "api/ServerAPI.h"
// We need this declaration for proper linking in derived classes // We need this declaration for proper linking in derived classes
template class SX126xInterface<SX1262>; template class SX126xInterface<SX1262>;
+1 -1
View File
@@ -1,5 +1,5 @@
#include "configuration.h"
#include "LLCC68Interface.h" #include "LLCC68Interface.h"
#include "configuration.h"
#include "error.h" #include "error.h"
LLCC68Interface::LLCC68Interface(RADIOLIB_PIN_TYPE cs, RADIOLIB_PIN_TYPE irq, RADIOLIB_PIN_TYPE rst, RADIOLIB_PIN_TYPE busy, LLCC68Interface::LLCC68Interface(RADIOLIB_PIN_TYPE cs, RADIOLIB_PIN_TYPE irq, RADIOLIB_PIN_TYPE rst, RADIOLIB_PIN_TYPE busy,
+34 -40
View File
@@ -1,20 +1,20 @@
#include "configuration.h"
#include "MeshModule.h" #include "MeshModule.h"
#include "Channels.h" #include "Channels.h"
#include "MeshService.h" #include "MeshService.h"
#include "NodeDB.h" #include "NodeDB.h"
#include "configuration.h"
#include "modules/RoutingModule.h" #include "modules/RoutingModule.h"
#include <assert.h> #include <assert.h>
std::vector<MeshModule *> *MeshModule::modules; std::vector<MeshModule *> *MeshModule::modules;
const MeshPacket *MeshModule::currentRequest; const meshtastic_MeshPacket *MeshModule::currentRequest;
/** /**
* If any of the current chain of modules has already sent a reply, it will be here. This is useful to allow * If any of the current chain of modules has already sent a reply, it will be here. This is useful to allow
* the RoutingPlugin to avoid sending redundant acks * the RoutingPlugin to avoid sending redundant acks
*/ */
MeshPacket *MeshModule::currentReply; meshtastic_MeshPacket *MeshModule::currentReply;
MeshModule::MeshModule(const char *_name) : name(_name) MeshModule::MeshModule(const char *_name) : name(_name)
{ {
@@ -32,21 +32,22 @@ MeshModule::~MeshModule()
assert(0); // FIXME - remove from list of modules once someone needs this feature assert(0); // FIXME - remove from list of modules once someone needs this feature
} }
MeshPacket *MeshModule::allocAckNak(Routing_Error err, NodeNum to, PacketId idFrom, ChannelIndex chIndex) meshtastic_MeshPacket *MeshModule::allocAckNak(meshtastic_Routing_Error err, NodeNum to, PacketId idFrom, ChannelIndex chIndex)
{ {
Routing c = Routing_init_default; meshtastic_Routing c = meshtastic_Routing_init_default;
c.error_reason = err; c.error_reason = err;
c.which_variant = Routing_error_reason_tag; c.which_variant = meshtastic_Routing_error_reason_tag;
// Now that we have moded sendAckNak up one level into the class heirarchy we can no longer assume we are a RoutingPlugin // Now that we have moded sendAckNak up one level into the class heirarchy we can no longer assume we are a RoutingPlugin
// So we manually call pb_encode_to_bytes and specify routing port number // So we manually call pb_encode_to_bytes and specify routing port number
// auto p = allocDataProtobuf(c); // auto p = allocDataProtobuf(c);
MeshPacket *p = router->allocForSending(); meshtastic_MeshPacket *p = router->allocForSending();
p->decoded.portnum = PortNum_ROUTING_APP; p->decoded.portnum = meshtastic_PortNum_ROUTING_APP;
p->decoded.payload.size = pb_encode_to_bytes(p->decoded.payload.bytes, sizeof(p->decoded.payload.bytes), &Routing_msg, &c); p->decoded.payload.size =
pb_encode_to_bytes(p->decoded.payload.bytes, sizeof(p->decoded.payload.bytes), &meshtastic_Routing_msg, &c);
p->priority = MeshPacket_Priority_ACK; p->priority = meshtastic_MeshPacket_Priority_ACK;
p->hop_limit = config.lora.hop_limit; // Flood ACK back to original sender p->hop_limit = config.lora.hop_limit; // Flood ACK back to original sender
p->to = to; p->to = to;
@@ -57,7 +58,7 @@ MeshPacket *MeshModule::allocAckNak(Routing_Error err, NodeNum to, PacketId idFr
return p; return p;
} }
MeshPacket *MeshModule::allocErrorResponse(Routing_Error err, const MeshPacket *p) meshtastic_MeshPacket *MeshModule::allocErrorResponse(meshtastic_Routing_Error err, const meshtastic_MeshPacket *p)
{ {
auto r = allocAckNak(err, getFrom(p), p->id, p->channel); auto r = allocAckNak(err, getFrom(p), p->id, p->channel);
@@ -66,13 +67,13 @@ MeshPacket *MeshModule::allocErrorResponse(Routing_Error err, const MeshPacket *
return r; return r;
} }
void MeshModule::callPlugins(const MeshPacket &mp, RxSource src) void MeshModule::callPlugins(const meshtastic_MeshPacket &mp, RxSource src)
{ {
// LOG_DEBUG("In call modules\n"); // LOG_DEBUG("In call modules\n");
bool moduleFound = false; bool moduleFound = false;
// We now allow **encrypted** packets to pass through the modules // We now allow **encrypted** packets to pass through the modules
bool isDecoded = mp.which_payload_variant == MeshPacket_decoded_tag; bool isDecoded = mp.which_payload_variant == meshtastic_MeshPacket_decoded_tag;
currentReply = NULL; // No reply yet currentReply = NULL; // No reply yet
@@ -101,13 +102,13 @@ void MeshModule::callPlugins(const MeshPacket &mp, RxSource src)
moduleFound = true; moduleFound = true;
/// received channel (or NULL if not decoded) /// received channel (or NULL if not decoded)
Channel *ch = isDecoded ? &channels.getByIndex(mp.channel) : NULL; meshtastic_Channel *ch = isDecoded ? &channels.getByIndex(mp.channel) : NULL;
/// Is the channel this packet arrived on acceptable? (security check) /// Is the channel this packet arrived on acceptable? (security check)
/// Note: we can't know channel names for encrypted packets, so those are NEVER sent to boundChannel modules /// Note: we can't know channel names for encrypted packets, so those are NEVER sent to boundChannel modules
/// Also: if a packet comes in on the local PC interface, we don't check for bound channels, because it is TRUSTED and it needs to /// Also: if a packet comes in on the local PC interface, we don't check for bound channels, because it is TRUSTED and
/// to be able to fetch the initial admin packets without yet knowing any channels. /// it needs to to be able to fetch the initial admin packets without yet knowing any channels.
bool rxChannelOk = !pi.boundChannel || (mp.from == 0) || (strcasecmp(ch->settings.name, pi.boundChannel) == 0); bool rxChannelOk = !pi.boundChannel || (mp.from == 0) || (strcasecmp(ch->settings.name, pi.boundChannel) == 0);
@@ -117,7 +118,7 @@ void MeshModule::callPlugins(const MeshPacket &mp, RxSource src)
if (mp.decoded.want_response) { if (mp.decoded.want_response) {
printPacket("packet on wrong channel, returning error", &mp); printPacket("packet on wrong channel, returning error", &mp);
currentReply = pi.allocErrorResponse(Routing_Error_NOT_AUTHORIZED, &mp); currentReply = pi.allocErrorResponse(meshtastic_Routing_Error_NOT_AUTHORIZED, &mp);
} else } else
printPacket("packet on wrong channel, but can't respond", &mp); printPacket("packet on wrong channel, but can't respond", &mp);
} else { } else {
@@ -170,17 +171,16 @@ void MeshModule::callPlugins(const MeshPacket &mp, RxSource src)
// SECURITY NOTE! I considered sending back a different error code if we didn't find the psk (i.e. !isDecoded) // SECURITY NOTE! I considered sending back a different error code if we didn't find the psk (i.e. !isDecoded)
// but opted NOT TO. Because it is not a good idea to let remote nodes 'probe' to find out which PSKs were "good" vs // but opted NOT TO. Because it is not a good idea to let remote nodes 'probe' to find out which PSKs were "good" vs
// bad. // bad.
routingModule->sendAckNak(Routing_Error_NO_RESPONSE, getFrom(&mp), mp.id, mp.channel); routingModule->sendAckNak(meshtastic_Routing_Error_NO_RESPONSE, getFrom(&mp), mp.id, mp.channel);
} }
} }
if (!moduleFound) if (!moduleFound)
LOG_DEBUG("No modules interested in portnum=%d, src=%s\n", LOG_DEBUG("No modules interested in portnum=%d, src=%s\n", mp.decoded.portnum,
mp.decoded.portnum,
(src == RX_SRC_LOCAL) ? "LOCAL" : "REMOTE"); (src == RX_SRC_LOCAL) ? "LOCAL" : "REMOTE");
} }
MeshPacket *MeshModule::allocReply() meshtastic_MeshPacket *MeshModule::allocReply()
{ {
auto r = myReply; auto r = myReply;
myReply = NULL; // Only use each reply once myReply = NULL; // Only use each reply once
@@ -191,7 +191,7 @@ MeshPacket *MeshModule::allocReply()
* so that subclasses can (optionally) send a response back to the original sender. Implementing this method * so that subclasses can (optionally) send a response back to the original sender. Implementing this method
* is optional * is optional
*/ */
void MeshModule::sendResponse(const MeshPacket &req) void MeshModule::sendResponse(const meshtastic_MeshPacket &req)
{ {
auto r = allocReply(); auto r = allocReply();
if (r) { if (r) {
@@ -206,16 +206,16 @@ void MeshModule::sendResponse(const MeshPacket &req)
/** set the destination and packet parameters of packet p intended as a reply to a particular "to" packet /** set the destination and packet parameters of packet p intended as a reply to a particular "to" packet
* This ensures that if the request packet was sent reliably, the reply is sent that way as well. * This ensures that if the request packet was sent reliably, the reply is sent that way as well.
*/ */
void setReplyTo(MeshPacket *p, const MeshPacket &to) void setReplyTo(meshtastic_MeshPacket *p, const meshtastic_MeshPacket &to)
{ {
assert(p->which_payload_variant == MeshPacket_decoded_tag); // Should already be set by now assert(p->which_payload_variant == meshtastic_MeshPacket_decoded_tag); // Should already be set by now
p->to = getFrom(&to); // Make sure that if we are sending to the local node, we use our local node addr, not 0 p->to = getFrom(&to); // Make sure that if we are sending to the local node, we use our local node addr, not 0
p->channel = to.channel; // Use the same channel that the request came in on p->channel = to.channel; // Use the same channel that the request came in on
// No need for an ack if we are just delivering locally (it just generates an ignored ack) // No need for an ack if we are just delivering locally (it just generates an ignored ack)
p->want_ack = (to.from != 0) ? to.want_ack : false; p->want_ack = (to.from != 0) ? to.want_ack : false;
if (p->priority == MeshPacket_Priority_UNSET) if (p->priority == meshtastic_MeshPacket_Priority_UNSET)
p->priority = MeshPacket_Priority_RELIABLE; p->priority = meshtastic_MeshPacket_Priority_RELIABLE;
p->decoded.request_id = to.id; p->decoded.request_id = to.id;
} }
@@ -235,14 +235,12 @@ std::vector<MeshModule *> MeshModule::GetMeshModulesWithUIFrames()
return modulesWithUIFrames; return modulesWithUIFrames;
} }
void MeshModule::observeUIEvents( void MeshModule::observeUIEvents(Observer<const UIFrameEvent *> *observer)
Observer<const UIFrameEvent *> *observer)
{ {
if (modules) { if (modules) {
for (auto i = modules->begin(); i != modules->end(); ++i) { for (auto i = modules->begin(); i != modules->end(); ++i) {
auto &pi = **i; auto &pi = **i;
Observable<const UIFrameEvent *> *observable = Observable<const UIFrameEvent *> *observable = pi.getUIFrameObservable();
pi.getUIFrameObservable();
if (observable != NULL) { if (observable != NULL) {
LOG_DEBUG("Module wants a UI Frame\n"); LOG_DEBUG("Module wants a UI Frame\n");
observer->observe(observable); observer->observe(observable);
@@ -251,24 +249,20 @@ void MeshModule::observeUIEvents(
} }
} }
AdminMessageHandleResult MeshModule::handleAdminMessageForAllPlugins(const MeshPacket &mp, AdminMessage *request, AdminMessage *response) AdminMessageHandleResult MeshModule::handleAdminMessageForAllPlugins(const meshtastic_MeshPacket &mp,
meshtastic_AdminMessage *request,
meshtastic_AdminMessage *response)
{ {
AdminMessageHandleResult handled = AdminMessageHandleResult::NOT_HANDLED; AdminMessageHandleResult handled = AdminMessageHandleResult::NOT_HANDLED;
if (modules) { if (modules) {
for (auto i = modules->begin(); i != modules->end(); ++i) { for (auto i = modules->begin(); i != modules->end(); ++i) {
auto &pi = **i; auto &pi = **i;
AdminMessageHandleResult h = pi.handleAdminMessageForModule(mp, request, response); AdminMessageHandleResult h = pi.handleAdminMessageForModule(mp, request, response);
if (h == AdminMessageHandleResult::HANDLED_WITH_RESPONSE) if (h == AdminMessageHandleResult::HANDLED_WITH_RESPONSE) {
{
// In case we have a response it always has priority. // In case we have a response it always has priority.
LOG_DEBUG("Reply prepared by module '%s' of variant: %d\n", LOG_DEBUG("Reply prepared by module '%s' of variant: %d\n", pi.name, response->which_payload_variant);
pi.name,
response->which_payload_variant);
handled = h; handled = h;
} } else if ((handled != AdminMessageHandleResult::HANDLED_WITH_RESPONSE) && (h == AdminMessageHandleResult::HANDLED)) {
else if ((handled != AdminMessageHandleResult::HANDLED_WITH_RESPONSE) &&
(h == AdminMessageHandleResult::HANDLED))
{
// In case the message is handled it should be populated, but will not overwrite // In case the message is handled it should be populated, but will not overwrite
// a result with response. // a result with response.
handled = h; handled = h;
+39 -23
View File
@@ -15,8 +15,7 @@
* *
* Use ProcessMessage::STOP to stop further message processing. * Use ProcessMessage::STOP to stop further message processing.
*/ */
enum class ProcessMessage enum class ProcessMessage {
{
CONTINUE = 0, CONTINUE = 0,
STOP = 1, STOP = 1,
}; };
@@ -27,8 +26,7 @@ enum class ProcessMessage
* If response is also prepared for the request, then HANDLED_WITH_RESPONSE * If response is also prepared for the request, then HANDLED_WITH_RESPONSE
* should be returned. * should be returned.
*/ */
enum class AdminMessageHandleResult enum class AdminMessageHandleResult {
{
NOT_HANDLED = 0, NOT_HANDLED = 0,
HANDLED = 1, HANDLED = 1,
HANDLED_WITH_RESPONSE = 2, HANDLED_WITH_RESPONSE = 2,
@@ -66,14 +64,18 @@ class MeshModule
/** For use only by MeshService /** For use only by MeshService
*/ */
static void callPlugins(const MeshPacket &mp, RxSource src = RX_SRC_RADIO); static void callPlugins(const meshtastic_MeshPacket &mp, RxSource src = RX_SRC_RADIO);
static std::vector<MeshModule *> GetMeshModulesWithUIFrames(); static std::vector<MeshModule *> GetMeshModulesWithUIFrames();
static void observeUIEvents(Observer<const UIFrameEvent *> *observer); static void observeUIEvents(Observer<const UIFrameEvent *> *observer);
static AdminMessageHandleResult handleAdminMessageForAllPlugins( static AdminMessageHandleResult handleAdminMessageForAllPlugins(const meshtastic_MeshPacket &mp,
const MeshPacket &mp, AdminMessage *request, AdminMessage *response); meshtastic_AdminMessage *request,
meshtastic_AdminMessage *response);
#if HAS_SCREEN #if HAS_SCREEN
virtual void drawFrame(OLEDDisplay *display, OLEDDisplayUiState *state, int16_t x, int16_t y) { return; } virtual void drawFrame(OLEDDisplay *display, OLEDDisplayUiState *state, int16_t x, int16_t y)
{
return;
}
#endif #endif
protected: protected:
const char *name; const char *name;
@@ -107,12 +109,12 @@ class MeshModule
* Note: this can be static because we are guaranteed to be processing only one * Note: this can be static because we are guaranteed to be processing only one
* plumodulegin at a time. * plumodulegin at a time.
*/ */
static const MeshPacket *currentRequest; static const meshtastic_MeshPacket *currentRequest;
/** /**
* If your handler wants to send a response, simply set currentReply and it will be sent at the end of response handling. * If your handler wants to send a response, simply set currentReply and it will be sent at the end of response handling.
*/ */
MeshPacket *myReply = NULL; meshtastic_MeshPacket *myReply = NULL;
/** /**
* Initialize your module. This setup function is called once after all hardware and mesh protocol layers have * Initialize your module. This setup function is called once after all hardware and mesh protocol layers have
@@ -123,13 +125,17 @@ class MeshModule
/** /**
* @return true if you want to receive the specified portnum * @return true if you want to receive the specified portnum
*/ */
virtual bool wantPacket(const MeshPacket *p) = 0; virtual bool wantPacket(const meshtastic_MeshPacket *p) = 0;
/** Called to handle a particular incoming message /** Called to handle a particular incoming message
@return ProcessMessage::STOP if you've guaranteed you've handled this message and no other handlers should be considered for it @return ProcessMessage::STOP if you've guaranteed you've handled this message and no other handlers should be considered for
it
*/ */
virtual ProcessMessage handleReceived(const MeshPacket &mp) { return ProcessMessage::CONTINUE; } virtual ProcessMessage handleReceived(const meshtastic_MeshPacket &mp)
{
return ProcessMessage::CONTINUE;
}
/** Messages can be received that have the want_response bit set. If set, this callback will be invoked /** Messages can be received that have the want_response bit set. If set, this callback will be invoked
* so that subclasses can (optionally) send a response back to the original sender. * so that subclasses can (optionally) send a response back to the original sender.
@@ -137,18 +143,24 @@ class MeshModule
* Note: most implementers don't need to override this, instead: If while handling a request you have a reply, just set * Note: most implementers don't need to override this, instead: If while handling a request you have a reply, just set
* the protected reply field in this instance. * the protected reply field in this instance.
* */ * */
virtual MeshPacket *allocReply(); virtual meshtastic_MeshPacket *allocReply();
/*** /***
* @return true if you want to be alloced a UI screen frame * @return true if you want to be alloced a UI screen frame
*/ */
virtual bool wantUIFrame() { return false; } virtual bool wantUIFrame()
virtual Observable<const UIFrameEvent *>* getUIFrameObservable() { return NULL; } {
return false;
}
virtual Observable<const UIFrameEvent *> *getUIFrameObservable()
{
return NULL;
}
MeshPacket *allocAckNak(Routing_Error err, NodeNum to, PacketId idFrom, ChannelIndex chIndex); meshtastic_MeshPacket *allocAckNak(meshtastic_Routing_Error err, NodeNum to, PacketId idFrom, ChannelIndex chIndex);
/// Send an error response for the specified packet. /// Send an error response for the specified packet.
MeshPacket *allocErrorResponse(Routing_Error err, const MeshPacket *p); meshtastic_MeshPacket *allocErrorResponse(meshtastic_Routing_Error err, const meshtastic_MeshPacket *p);
/** /**
* @brief An admin message arrived to AdminModule. Module was asked whether it want to handle the request. * @brief An admin message arrived to AdminModule. Module was asked whether it want to handle the request.
@@ -160,15 +172,19 @@ class MeshModule
* HANDLED if message was handled * HANDLED if message was handled
* HANDLED_WITH_RESPONSE if a response is also prepared and to be sent. * HANDLED_WITH_RESPONSE if a response is also prepared and to be sent.
*/ */
virtual AdminMessageHandleResult handleAdminMessageForModule( virtual AdminMessageHandleResult handleAdminMessageForModule(const meshtastic_MeshPacket &mp,
const MeshPacket &mp, AdminMessage *request, AdminMessage *response) { return AdminMessageHandleResult::NOT_HANDLED; }; meshtastic_AdminMessage *request,
meshtastic_AdminMessage *response)
{
return AdminMessageHandleResult::NOT_HANDLED;
};
private: private:
/** /**
* If any of the current chain of modules has already sent a reply, it will be here. This is useful to allow * If any of the current chain of modules has already sent a reply, it will be here. This is useful to allow
* the RoutingModule to avoid sending redundant acks * the RoutingModule to avoid sending redundant acks
*/ */
static MeshPacket *currentReply; static meshtastic_MeshPacket *currentReply;
friend class ReliableRouter; friend class ReliableRouter;
@@ -176,10 +192,10 @@ class MeshModule
* so that subclasses can (optionally) send a response back to the original sender. This method calls allocReply() * so that subclasses can (optionally) send a response back to the original sender. This method calls allocReply()
* to generate the reply message, and if !NULL that message will be delivered to whoever sent req * to generate the reply message, and if !NULL that message will be delivered to whoever sent req
*/ */
void sendResponse(const MeshPacket &req); void sendResponse(const meshtastic_MeshPacket &req);
}; };
/** set the destination and packet parameters of packet p intended as a reply to a particular "to" packet /** set the destination and packet parameters of packet p intended as a reply to a particular "to" packet
* This ensures that if the request packet was sent reliably, the reply is sent that way as well. * This ensures that if the request packet was sent reliably, the reply is sent that way as well.
*/ */
void setReplyTo(MeshPacket *p, const MeshPacket &to); void setReplyTo(meshtastic_MeshPacket *p, const meshtastic_MeshPacket &to);
+16 -13
View File
@@ -1,18 +1,18 @@
#include "configuration.h"
#include "MeshPacketQueue.h" #include "MeshPacketQueue.h"
#include "configuration.h"
#include <assert.h> #include <assert.h>
#include <algorithm> #include <algorithm>
/// @return the priority of the specified packet /// @return the priority of the specified packet
inline uint32_t getPriority(const MeshPacket *p) inline uint32_t getPriority(const meshtastic_MeshPacket *p)
{ {
auto pri = p->priority; auto pri = p->priority;
return pri; return pri;
} }
/// @return "true" if "p1" is ordered before "p2" /// @return "true" if "p1" is ordered before "p2"
bool CompareMeshPacketFunc(const MeshPacket *p1, const MeshPacket *p2) bool CompareMeshPacketFunc(const meshtastic_MeshPacket *p1, const meshtastic_MeshPacket *p2)
{ {
assert(p1 && p2); assert(p1 && p2);
auto p1p = getPriority(p1), p2p = getPriority(p2); auto p1p = getPriority(p1), p2p = getPriority(p2);
@@ -26,27 +26,29 @@ bool CompareMeshPacketFunc(const MeshPacket *p1, const MeshPacket *p2)
MeshPacketQueue::MeshPacketQueue(size_t _maxLen) : maxLen(_maxLen) {} MeshPacketQueue::MeshPacketQueue(size_t _maxLen) : maxLen(_maxLen) {}
bool MeshPacketQueue::empty() { bool MeshPacketQueue::empty()
{
return queue.empty(); return queue.empty();
} }
/** /**
* Some clients might not properly set priority, therefore we fix it here. * Some clients might not properly set priority, therefore we fix it here.
*/ */
void fixPriority(MeshPacket *p) void fixPriority(meshtastic_MeshPacket *p)
{ {
// We might receive acks from other nodes (and since generated remotely, they won't have priority assigned. Check for that // We might receive acks from other nodes (and since generated remotely, they won't have priority assigned. Check for that
// and fix it // and fix it
if (p->priority == MeshPacket_Priority_UNSET) { if (p->priority == meshtastic_MeshPacket_Priority_UNSET) {
// if acks give high priority // if acks give high priority
// if a reliable message give a bit higher default priority // if a reliable message give a bit higher default priority
p->priority = (p->decoded.portnum == PortNum_ROUTING_APP) ? MeshPacket_Priority_ACK : p->priority = (p->decoded.portnum == meshtastic_PortNum_ROUTING_APP)
(p->want_ack ? MeshPacket_Priority_RELIABLE : MeshPacket_Priority_DEFAULT); ? meshtastic_MeshPacket_Priority_ACK
: (p->want_ack ? meshtastic_MeshPacket_Priority_RELIABLE : meshtastic_MeshPacket_Priority_DEFAULT);
} }
} }
/** enqueue a packet, return false if full */ /** enqueue a packet, return false if full */
bool MeshPacketQueue::enqueue(MeshPacket *p) bool MeshPacketQueue::enqueue(meshtastic_MeshPacket *p)
{ {
fixPriority(p); fixPriority(p);
@@ -60,7 +62,7 @@ bool MeshPacketQueue::enqueue(MeshPacket *p)
return true; return true;
} }
MeshPacket *MeshPacketQueue::dequeue() meshtastic_MeshPacket *MeshPacketQueue::dequeue()
{ {
if (empty()) { if (empty()) {
return NULL; return NULL;
@@ -73,7 +75,7 @@ MeshPacket *MeshPacketQueue::dequeue()
return p; return p;
} }
MeshPacket *MeshPacketQueue::getFront() meshtastic_MeshPacket *MeshPacketQueue::getFront()
{ {
if (empty()) { if (empty()) {
return NULL; return NULL;
@@ -84,7 +86,7 @@ MeshPacket *MeshPacketQueue::getFront()
} }
/** Attempt to find and remove a packet from this queue. Returns a pointer to the removed packet, or NULL if not found */ /** Attempt to find and remove a packet from this queue. Returns a pointer to the removed packet, or NULL if not found */
MeshPacket *MeshPacketQueue::remove(NodeNum from, PacketId id) meshtastic_MeshPacket *MeshPacketQueue::remove(NodeNum from, PacketId id)
{ {
for (auto it = queue.begin(); it != queue.end(); it++) { for (auto it = queue.begin(); it != queue.end(); it++) {
auto p = (*it); auto p = (*it);
@@ -99,7 +101,8 @@ MeshPacket *MeshPacketQueue::remove(NodeNum from, PacketId id)
} }
/** Attempt to find and remove a packet from this queue. Returns the packet which was removed from the queue */ /** Attempt to find and remove a packet from this queue. Returns the packet which was removed from the queue */
bool MeshPacketQueue::replaceLowerPriorityPacket(MeshPacket *p) { bool MeshPacketQueue::replaceLowerPriorityPacket(meshtastic_MeshPacket *p)
{
std::sort_heap(queue.begin(), queue.end(), &CompareMeshPacketFunc); // sort ascending based on priority (0 -> 127) std::sort_heap(queue.begin(), queue.end(), &CompareMeshPacketFunc); // sort ascending based on priority (0 -> 127)
// find first packet which does not compare less (in priority) than parameter packet // find first packet which does not compare less (in priority) than parameter packet
+8 -8
View File
@@ -4,23 +4,23 @@
#include <queue> #include <queue>
/** /**
* A priority queue of packets * A priority queue of packets
*/ */
class MeshPacketQueue class MeshPacketQueue
{ {
size_t maxLen; size_t maxLen;
std::vector<MeshPacket *> queue; std::vector<meshtastic_MeshPacket *> queue;
/** Replace a lower priority package in the queue with 'mp' (provided there are lower pri packages). Return true if replaced. */ /** Replace a lower priority package in the queue with 'mp' (provided there are lower pri packages). Return true if replaced.
bool replaceLowerPriorityPacket(MeshPacket *mp); */
bool replaceLowerPriorityPacket(meshtastic_MeshPacket *mp);
public: public:
explicit MeshPacketQueue(size_t _maxLen); explicit MeshPacketQueue(size_t _maxLen);
/** enqueue a packet, return false if full */ /** enqueue a packet, return false if full */
bool enqueue(MeshPacket *p); bool enqueue(meshtastic_MeshPacket *p);
/** return true if the queue is empty */ /** return true if the queue is empty */
bool empty(); bool empty();
@@ -31,10 +31,10 @@ class MeshPacketQueue
/** return total size of the Queue */ /** return total size of the Queue */
size_t getMaxLen() { return maxLen; } size_t getMaxLen() { return maxLen; }
MeshPacket *dequeue(); meshtastic_MeshPacket *dequeue();
MeshPacket *getFront(); meshtastic_MeshPacket *getFront();
/** Attempt to find and remove a packet from this queue. Returns the packet which was removed from the queue */ /** Attempt to find and remove a packet from this queue. Returns the packet which was removed from the queue */
MeshPacket *remove(NodeNum from, PacketId id); meshtastic_MeshPacket *remove(NodeNum from, PacketId id);
}; };
+1 -1
View File
@@ -7,7 +7,7 @@
// Map from old region names to new region enums // Map from old region names to new region enums
struct RegionInfo { struct RegionInfo {
Config_LoRaConfig_RegionCode code; meshtastic_Config_LoRaConfig_RegionCode code;
float freqStart; float freqStart;
float freqEnd; float freqEnd;
float dutyCycle; float dutyCycle;
+27 -26
View File
@@ -2,9 +2,9 @@
#include <assert.h> #include <assert.h>
#include <string> #include <string>
#include "GPS.h"
#include "../concurrency/Periodic.h" #include "../concurrency/Periodic.h"
#include "BluetoothCommon.h" // needed for updateBatteryLevel, FIXME, eventually when we pull mesh out into a lib we shouldn't be whacking bluetooth from here #include "BluetoothCommon.h" // needed for updateBatteryLevel, FIXME, eventually when we pull mesh out into a lib we shouldn't be whacking bluetooth from here
#include "GPS.h"
#include "MeshService.h" #include "MeshService.h"
#include "NodeDB.h" #include "NodeDB.h"
#include "PowerFSM.h" #include "PowerFSM.h"
@@ -51,9 +51,9 @@ FIXME in the initial proof of concept we just skip the entire want/deny flow and
MeshService service; MeshService service;
static MemoryDynamic<QueueStatus> staticQueueStatusPool; static MemoryDynamic<meshtastic_QueueStatus> staticQueueStatusPool;
Allocator<QueueStatus> &queueStatusPool = staticQueueStatusPool; Allocator<meshtastic_QueueStatus> &queueStatusPool = staticQueueStatusPool;
#include "Router.h" #include "Router.h"
@@ -71,14 +71,14 @@ void MeshService::init()
gpsObserver.observe(&gps->newStatus); gpsObserver.observe(&gps->newStatus);
} }
int MeshService::handleFromRadio(const MeshPacket *mp) int MeshService::handleFromRadio(const meshtastic_MeshPacket *mp)
{ {
powerFSM.trigger(EVENT_PACKET_FOR_PHONE); // Possibly keep the node from sleeping powerFSM.trigger(EVENT_PACKET_FOR_PHONE); // Possibly keep the node from sleeping
printPacket("Forwarding to phone", mp); printPacket("Forwarding to phone", mp);
nodeDB.updateFrom(*mp); // update our DB state based off sniffing every RX packet from the radio nodeDB.updateFrom(*mp); // update our DB state based off sniffing every RX packet from the radio
sendToPhone((MeshPacket *)mp); sendToPhone((meshtastic_MeshPacket *)mp);
return 0; return 0;
} }
@@ -87,7 +87,7 @@ int MeshService::handleFromRadio(const MeshPacket *mp)
void MeshService::loop() void MeshService::loop()
{ {
if (lastQueueStatus.free == 0) { // check if there is now free space in TX queue if (lastQueueStatus.free == 0) { // check if there is now free space in TX queue
QueueStatus qs = router->getQueueStatus(); meshtastic_QueueStatus qs = router->getQueueStatus();
if (qs.free != lastQueueStatus.free) if (qs.free != lastQueueStatus.free)
(void)sendQueueStatusToPhone(qs, 0, 0); (void)sendQueueStatusToPhone(qs, 0, 0);
} }
@@ -130,17 +130,18 @@ void MeshService::reloadOwner(bool shouldSave)
* Called by PhoneAPI.handleToRadio. Note: p is a scratch buffer, this function is allowed to write to it but it can not keep a * Called by PhoneAPI.handleToRadio. Note: p is a scratch buffer, this function is allowed to write to it but it can not keep a
* reference * reference
*/ */
void MeshService::handleToRadio(MeshPacket &p) void MeshService::handleToRadio(meshtastic_MeshPacket &p)
{ {
#ifdef ARCH_PORTDUINO #ifdef ARCH_PORTDUINO
// Simulates device is receiving a packet via the LoRa chip // Simulates device is receiving a packet via the LoRa chip
if (p.decoded.portnum == PortNum_SIMULATOR_APP) { if (p.decoded.portnum == meshtastic_PortNum_SIMULATOR_APP) {
// Simulator packet (=Compressed packet) is encapsulated in a MeshPacket, so need to unwrap first // Simulator packet (=Compressed packet) is encapsulated in a MeshPacket, so need to unwrap first
Compressed scratch; meshtastic_Compressed scratch;
Compressed *decoded = NULL; meshtastic_Compressed *decoded = NULL;
if (p.which_payload_variant == MeshPacket_decoded_tag) { if (p.which_payload_variant == meshtastic_MeshPacket_decoded_tag) {
memset(&scratch, 0, sizeof(scratch)); memset(&scratch, 0, sizeof(scratch));
p.decoded.payload.size = pb_decode_from_bytes(p.decoded.payload.bytes, p.decoded.payload.size, &Compressed_msg, &scratch); p.decoded.payload.size =
pb_decode_from_bytes(p.decoded.payload.bytes, p.decoded.payload.size, &meshtastic_Compressed_msg, &scratch);
if (p.decoded.payload.size) { if (p.decoded.payload.size) {
decoded = &scratch; decoded = &scratch;
// Extract the original payload and replace // Extract the original payload and replace
@@ -187,16 +188,16 @@ bool MeshService::cancelSending(PacketId id)
return router->cancelSending(nodeDB.getNodeNum(), id); return router->cancelSending(nodeDB.getNodeNum(), id);
} }
ErrorCode MeshService::sendQueueStatusToPhone(const QueueStatus &qs, ErrorCode res, uint32_t mesh_packet_id) ErrorCode MeshService::sendQueueStatusToPhone(const meshtastic_QueueStatus &qs, ErrorCode res, uint32_t mesh_packet_id)
{ {
QueueStatus *copied = queueStatusPool.allocCopy(qs); meshtastic_QueueStatus *copied = queueStatusPool.allocCopy(qs);
copied->res = res; copied->res = res;
copied->mesh_packet_id = mesh_packet_id; copied->mesh_packet_id = mesh_packet_id;
if (toPhoneQueueStatusQueue.numFree() == 0) { if (toPhoneQueueStatusQueue.numFree() == 0) {
LOG_DEBUG("NOTE: tophone queue status queue is full, discarding oldest\n"); LOG_DEBUG("NOTE: tophone queue status queue is full, discarding oldest\n");
QueueStatus *d = toPhoneQueueStatusQueue.dequeuePtr(0); meshtastic_QueueStatus *d = toPhoneQueueStatusQueue.dequeuePtr(0);
if (d) if (d)
releaseQueueStatusToPool(d); releaseQueueStatusToPool(d);
} }
@@ -209,7 +210,7 @@ ErrorCode MeshService::sendQueueStatusToPhone(const QueueStatus &qs, ErrorCode r
return res ? ERRNO_OK : ERRNO_UNKNOWN; return res ? ERRNO_OK : ERRNO_UNKNOWN;
} }
void MeshService::sendToMesh(MeshPacket *p, RxSource src, bool ccToPhone) void MeshService::sendToMesh(meshtastic_MeshPacket *p, RxSource src, bool ccToPhone)
{ {
uint32_t mesh_packet_id = p->id; uint32_t mesh_packet_id = p->id;
nodeDB.updateFrom(*p); // update our local DB for this packet (because phone might have sent position packets etc...) nodeDB.updateFrom(*p); // update our local DB for this packet (because phone might have sent position packets etc...)
@@ -219,7 +220,7 @@ void MeshService::sendToMesh(MeshPacket *p, RxSource src, bool ccToPhone)
/* NOTE(pboldin): Prepare and send QueueStatus message to the phone as a /* NOTE(pboldin): Prepare and send QueueStatus message to the phone as a
* high-priority message. */ * high-priority message. */
QueueStatus qs = router->getQueueStatus(); meshtastic_QueueStatus qs = router->getQueueStatus();
ErrorCode r = sendQueueStatusToPhone(qs, res, mesh_packet_id); ErrorCode r = sendQueueStatusToPhone(qs, res, mesh_packet_id);
if (r != ERRNO_OK) { if (r != ERRNO_OK) {
LOG_DEBUG("Can't send status to phone"); LOG_DEBUG("Can't send status to phone");
@@ -232,7 +233,7 @@ void MeshService::sendToMesh(MeshPacket *p, RxSource src, bool ccToPhone)
void MeshService::sendNetworkPing(NodeNum dest, bool wantReplies) void MeshService::sendNetworkPing(NodeNum dest, bool wantReplies)
{ {
NodeInfo *node = nodeDB.getNode(nodeDB.getNodeNum()); meshtastic_NodeInfo *node = nodeDB.getNode(nodeDB.getNodeNum());
assert(node); assert(node);
if (node->has_position && (node->position.latitude_i != 0 || node->position.longitude_i != 0)) { if (node->has_position && (node->position.latitude_i != 0 || node->position.longitude_i != 0)) {
@@ -248,24 +249,24 @@ void MeshService::sendNetworkPing(NodeNum dest, bool wantReplies)
} }
} }
void MeshService::sendToPhone(MeshPacket *p) void MeshService::sendToPhone(meshtastic_MeshPacket *p)
{ {
if (toPhoneQueue.numFree() == 0) { if (toPhoneQueue.numFree() == 0) {
LOG_WARN("ToPhone queue is full, discarding oldest\n"); LOG_WARN("ToPhone queue is full, discarding oldest\n");
MeshPacket *d = toPhoneQueue.dequeuePtr(0); meshtastic_MeshPacket *d = toPhoneQueue.dequeuePtr(0);
if (d) if (d)
releaseToPool(d); releaseToPool(d);
} }
MeshPacket *copied = packetPool.allocCopy(*p); meshtastic_MeshPacket *copied = packetPool.allocCopy(*p);
perhapsDecode(copied); perhapsDecode(copied);
assert(toPhoneQueue.enqueue(copied, 0)); assert(toPhoneQueue.enqueue(copied, 0));
fromNum++; fromNum++;
} }
NodeInfo *MeshService::refreshMyNodeInfo() meshtastic_NodeInfo *MeshService::refreshMyNodeInfo()
{ {
NodeInfo *node = nodeDB.getNode(nodeDB.getNodeNum()); meshtastic_NodeInfo *node = nodeDB.getNode(nodeDB.getNodeNum());
assert(node); assert(node);
// We might not have a position yet for our local node, in that case, at least try to send the time // We might not have a position yet for our local node, in that case, at least try to send the time
@@ -274,7 +275,7 @@ NodeInfo *MeshService::refreshMyNodeInfo()
node->has_position = true; node->has_position = true;
} }
Position &position = node->position; meshtastic_Position &position = node->position;
// Update our local node info with our time (even if we don't decide to update anyone else) // Update our local node info with our time (even if we don't decide to update anyone else)
node->last_heard = node->last_heard =
@@ -290,8 +291,8 @@ NodeInfo *MeshService::refreshMyNodeInfo()
int MeshService::onGPSChanged(const meshtastic::GPSStatus *newStatus) int MeshService::onGPSChanged(const meshtastic::GPSStatus *newStatus)
{ {
// Update our local node info with our position (even if we don't decide to update anyone else) // Update our local node info with our position (even if we don't decide to update anyone else)
NodeInfo *node = refreshMyNodeInfo(); meshtastic_NodeInfo *node = refreshMyNodeInfo();
Position pos = Position_init_default; meshtastic_Position pos = meshtastic_Position_init_default;
if (newStatus->getHasLock()) { if (newStatus->getHasLock()) {
// load data from GPS object, will add timestamp + battery further down // load data from GPS object, will add timestamp + battery further down
+14 -14
View File
@@ -14,7 +14,7 @@
#include "../platform/portduino/SimRadio.h" #include "../platform/portduino/SimRadio.h"
#endif #endif
extern Allocator<QueueStatus> &queueStatusPool; extern Allocator<meshtastic_QueueStatus> &queueStatusPool;
/** /**
* Top level app for this service. keeps the mesh, the radio config and the queue of received packets. * Top level app for this service. keeps the mesh, the radio config and the queue of received packets.
@@ -29,13 +29,13 @@ class MeshService
/// FIXME, change to a DropOldestQueue and keep a count of the number of dropped packets to ensure /// FIXME, change to a DropOldestQueue and keep a count of the number of dropped packets to ensure
/// we never hang because android hasn't been there in a while /// we never hang because android hasn't been there in a while
/// FIXME - save this to flash on deep sleep /// FIXME - save this to flash on deep sleep
PointerQueue<MeshPacket> toPhoneQueue; PointerQueue<meshtastic_MeshPacket> toPhoneQueue;
// keep list of QueueStatus packets to be send to the phone // keep list of QueueStatus packets to be send to the phone
PointerQueue<QueueStatus> toPhoneQueueStatusQueue; PointerQueue<meshtastic_QueueStatus> toPhoneQueueStatusQueue;
// This holds the last QueueStatus send // This holds the last QueueStatus send
QueueStatus lastQueueStatus; meshtastic_QueueStatus lastQueueStatus;
/// The current nonce for the newest packet which has been queued for the phone /// The current nonce for the newest packet which has been queued for the phone
uint32_t fromNum = 0; uint32_t fromNum = 0;
@@ -59,23 +59,23 @@ class MeshService
/// Return the next packet destined to the phone. FIXME, somehow use fromNum to allow the phone to retry the /// Return the next packet destined to the phone. FIXME, somehow use fromNum to allow the phone to retry the
/// last few packets if needs to. /// last few packets if needs to.
MeshPacket *getForPhone() { return toPhoneQueue.dequeuePtr(0); } meshtastic_MeshPacket *getForPhone() { return toPhoneQueue.dequeuePtr(0); }
/// Allows the bluetooth handler to free packets after they have been sent /// Allows the bluetooth handler to free packets after they have been sent
void releaseToPool(MeshPacket *p) { packetPool.release(p); } void releaseToPool(meshtastic_MeshPacket *p) { packetPool.release(p); }
/// Return the next QueueStatus packet destined to the phone. /// Return the next QueueStatus packet destined to the phone.
QueueStatus *getQueueStatusForPhone() { return toPhoneQueueStatusQueue.dequeuePtr(0); } meshtastic_QueueStatus *getQueueStatusForPhone() { return toPhoneQueueStatusQueue.dequeuePtr(0); }
// Release QueueStatus packet to pool // Release QueueStatus packet to pool
void releaseQueueStatusToPool(QueueStatus *p) { queueStatusPool.release(p); } void releaseQueueStatusToPool(meshtastic_QueueStatus *p) { queueStatusPool.release(p); }
/** /**
* Given a ToRadio buffer parse it and properly handle it (setup radio, owner or send packet into the mesh) * Given a ToRadio buffer parse it and properly handle it (setup radio, owner or send packet into the mesh)
* Called by PhoneAPI.handleToRadio. Note: p is a scratch buffer, this function is allowed to write to it but it can not keep * Called by PhoneAPI.handleToRadio. Note: p is a scratch buffer, this function is allowed to write to it but it can not keep
* a reference * a reference
*/ */
void handleToRadio(MeshPacket &p); void handleToRadio(meshtastic_MeshPacket &p);
/** The radioConfig object just changed, call this to force the hw to change to the new settings /** The radioConfig object just changed, call this to force the hw to change to the new settings
* @return true if client devices should be sent a new set of radio configs * @return true if client devices should be sent a new set of radio configs
@@ -92,16 +92,16 @@ class MeshService
/// Send a packet into the mesh - note p must have been allocated from packetPool. We will return it to that pool after /// Send a packet into the mesh - note p must have been allocated from packetPool. We will return it to that pool after
/// sending. This is the ONLY function you should use for sending messages into the mesh, because it also updates the nodedb /// sending. This is the ONLY function you should use for sending messages into the mesh, because it also updates the nodedb
/// cache /// cache
void sendToMesh(MeshPacket *p, RxSource src = RX_SRC_LOCAL, bool ccToPhone = false); void sendToMesh(meshtastic_MeshPacket *p, RxSource src = RX_SRC_LOCAL, bool ccToPhone = false);
/** Attempt to cancel a previously sent packet from this _local_ node. Returns true if a packet was found we could cancel */ /** Attempt to cancel a previously sent packet from this _local_ node. Returns true if a packet was found we could cancel */
bool cancelSending(PacketId id); bool cancelSending(PacketId id);
/// Pull the latest power and time info into my nodeinfo /// Pull the latest power and time info into my nodeinfo
NodeInfo *refreshMyNodeInfo(); meshtastic_NodeInfo *refreshMyNodeInfo();
/// Send a packet to the phone /// Send a packet to the phone
void sendToPhone(MeshPacket *p); void sendToPhone(meshtastic_MeshPacket *p);
bool isToPhoneQueueEmpty(); bool isToPhoneQueueEmpty();
@@ -112,10 +112,10 @@ class MeshService
/// Handle a packet that just arrived from the radio. This method does _ReliableRouternot_ free the provided packet. If it /// Handle a packet that just arrived from the radio. This method does _ReliableRouternot_ free the provided packet. If it
/// needs to keep the packet around it makes a copy /// needs to keep the packet around it makes a copy
int handleFromRadio(const MeshPacket *p); int handleFromRadio(const meshtastic_MeshPacket *p);
friend class RoutingModule; friend class RoutingModule;
ErrorCode sendQueueStatusToPhone(const QueueStatus &qs, ErrorCode res, uint32_t mesh_packet_id); ErrorCode sendQueueStatusToPhone(const meshtastic_QueueStatus &qs, ErrorCode res, uint32_t mesh_packet_id);
}; };
extern MeshService service; extern MeshService service;
+2 -2
View File
@@ -39,10 +39,10 @@ enum RxSource {
typedef int ErrorCode; typedef int ErrorCode;
/// Alloc and free packets to our global, ISR safe pool /// Alloc and free packets to our global, ISR safe pool
extern Allocator<MeshPacket> &packetPool; extern Allocator<meshtastic_MeshPacket> &packetPool;
/** /**
* Most (but not always) of the time we want to treat packets 'from' the local phone (where from == 0), as if they originated on * Most (but not always) of the time we want to treat packets 'from' the local phone (where from == 0), as if they originated on
* the local node. If from is zero this function returns our node number instead * the local node. If from is zero this function returns our node number instead
*/ */
NodeNum getFrom(const MeshPacket *p); NodeNum getFrom(const meshtastic_MeshPacket *p);
+55 -48
View File
@@ -13,9 +13,9 @@
#include "error.h" #include "error.h"
#include "main.h" #include "main.h"
#include "mesh-pb-constants.h" #include "mesh-pb-constants.h"
#include <ErriezCRC32.h>
#include <pb_decode.h> #include <pb_decode.h>
#include <pb_encode.h> #include <pb_encode.h>
#include <ErriezCRC32.h>
#ifdef ARCH_ESP32 #ifdef ARCH_ESP32
#include "mesh/http/WiFiAPClient.h" #include "mesh/http/WiFiAPClient.h"
@@ -32,12 +32,12 @@
NodeDB nodeDB; NodeDB nodeDB;
// we have plenty of ram so statically alloc this tempbuf (for now) // we have plenty of ram so statically alloc this tempbuf (for now)
EXT_RAM_ATTR DeviceState devicestate; EXT_RAM_ATTR meshtastic_DeviceState devicestate;
MyNodeInfo &myNodeInfo = devicestate.my_node; meshtastic_MyNodeInfo &myNodeInfo = devicestate.my_node;
LocalConfig config; meshtastic_LocalConfig config;
LocalModuleConfig moduleConfig; meshtastic_LocalModuleConfig moduleConfig;
ChannelFile channelFile; meshtastic_ChannelFile channelFile;
OEMStore oemStore; meshtastic_OEMStore oemStore;
/** 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. * might have changed is incremented. Allows others to detect they might now be on a new channel.
@@ -53,7 +53,7 @@ extern void getMacAddr(uint8_t *dmac);
* But there are some special ids used when we haven't yet been configured by a user. In that case * But there are some special ids used when we haven't yet been configured by a user. In that case
* we use !macaddr (no colons). * we use !macaddr (no colons).
*/ */
User &owner = devicestate.owner; meshtastic_User &owner = devicestate.owner;
static uint8_t ourMacAddr[6]; static uint8_t ourMacAddr[6];
@@ -69,7 +69,7 @@ NodeDB::NodeDB() : nodes(devicestate.node_db), numNodes(&devicestate.node_db_cou
* Most (but not always) of the time we want to treat packets 'from' the local phone (where from == 0), as if they originated on * Most (but not always) of the time we want to treat packets 'from' the local phone (where from == 0), as if they originated on
* the local node. If from is zero this function returns our node number instead * the local node. If from is zero this function returns our node number instead
*/ */
NodeNum getFrom(const MeshPacket *p) NodeNum getFrom(const meshtastic_MeshPacket *p)
{ {
return (p->from == 0) ? nodeDB.getNodeNum() : p->from; return (p->from == 0) ? nodeDB.getNodeNum() : p->from;
} }
@@ -102,7 +102,7 @@ bool NodeDB::resetRadioConfig(bool factory_reset)
config.power.wait_bluetooth_secs = 10; config.power.wait_bluetooth_secs = 10;
config.position.position_broadcast_secs = 6 * 60; config.position.position_broadcast_secs = 6 * 60;
config.power.ls_secs = 60; config.power.ls_secs = 60;
config.lora.region = Config_LoRaConfig_RegionCode_TW; config.lora.region = meshtastic_Config_LoRaConfig_RegionCode_TW;
// Enter super deep sleep soon and stay there not very long // Enter super deep sleep soon and stay there not very long
// radioConfig.preferences.mesh_sds_timeout_secs = 10; // radioConfig.preferences.mesh_sds_timeout_secs = 10;
@@ -151,7 +151,7 @@ bool NodeDB::factoryReset()
void NodeDB::installDefaultConfig() void NodeDB::installDefaultConfig()
{ {
LOG_INFO("Installing default LocalConfig\n"); LOG_INFO("Installing default LocalConfig\n");
memset(&config, 0, sizeof(LocalConfig)); memset(&config, 0, sizeof(meshtastic_LocalConfig));
config.version = DEVICESTATE_CUR_VER; config.version = DEVICESTATE_CUR_VER;
config.has_device = true; config.has_device = true;
config.has_display = true; config.has_display = true;
@@ -160,10 +160,11 @@ void NodeDB::installDefaultConfig()
config.has_power = true; config.has_power = true;
config.has_network = true; config.has_network = true;
config.has_bluetooth = true; config.has_bluetooth = true;
config.lora.tx_enabled = true; // FIXME: maybe false in the future, and setting region to enable it. (unset region forces it off) config.lora.tx_enabled =
true; // FIXME: maybe false in the future, and setting region to enable it. (unset region forces it off)
config.lora.override_duty_cycle = false; config.lora.override_duty_cycle = false;
config.lora.region = Config_LoRaConfig_RegionCode_UNSET; config.lora.region = meshtastic_Config_LoRaConfig_RegionCode_UNSET;
config.lora.modem_preset = Config_LoRaConfig_ModemPreset_LONG_FAST; config.lora.modem_preset = meshtastic_Config_LoRaConfig_ModemPreset_LONG_FAST;
config.lora.hop_limit = HOP_RELIABLE; config.lora.hop_limit = HOP_RELIABLE;
config.position.gps_enabled = true; config.position.gps_enabled = true;
config.position.position_broadcast_smart_enabled = true; config.position.position_broadcast_smart_enabled = true;
@@ -178,9 +179,11 @@ void NodeDB::installDefaultConfig()
#else #else
bool hasScreen = screen_found; bool hasScreen = screen_found;
#endif #endif
config.bluetooth.mode = hasScreen ? Config_BluetoothConfig_PairingMode_RANDOM_PIN : Config_BluetoothConfig_PairingMode_FIXED_PIN; config.bluetooth.mode = hasScreen ? meshtastic_Config_BluetoothConfig_PairingMode_RANDOM_PIN
: meshtastic_Config_BluetoothConfig_PairingMode_FIXED_PIN;
// for backward compat, default position flags are ALT+MSL // for backward compat, default position flags are ALT+MSL
config.position.position_flags = (Config_PositionConfig_PositionFlags_ALTITUDE | Config_PositionConfig_PositionFlags_ALTITUDE_MSL); config.position.position_flags =
(meshtastic_Config_PositionConfig_PositionFlags_ALTITUDE | meshtastic_Config_PositionConfig_PositionFlags_ALTITUDE_MSL);
initConfigIntervals(); initConfigIntervals();
} }
@@ -203,7 +206,7 @@ void NodeDB::initConfigIntervals()
void NodeDB::installDefaultModuleConfig() void NodeDB::installDefaultModuleConfig()
{ {
LOG_INFO("Installing default ModuleConfig\n"); LOG_INFO("Installing default ModuleConfig\n");
memset(&moduleConfig, 0, sizeof(ModuleConfig)); memset(&moduleConfig, 0, sizeof(meshtastic_ModuleConfig));
moduleConfig.version = DEVICESTATE_CUR_VER; moduleConfig.version = DEVICESTATE_CUR_VER;
moduleConfig.has_mqtt = true; moduleConfig.has_mqtt = true;
@@ -230,7 +233,7 @@ void NodeDB::initModuleConfigIntervals()
void NodeDB::installDefaultChannels() void NodeDB::installDefaultChannels()
{ {
LOG_INFO("Installing default ChannelFile\n"); LOG_INFO("Installing default ChannelFile\n");
memset(&channelFile, 0, sizeof(ChannelFile)); memset(&channelFile, 0, sizeof(meshtastic_ChannelFile));
channelFile.version = DEVICESTATE_CUR_VER; channelFile.version = DEVICESTATE_CUR_VER;
} }
@@ -244,7 +247,7 @@ void NodeDB::resetNodes()
void NodeDB::installDefaultDeviceState() void NodeDB::installDefaultDeviceState()
{ {
LOG_INFO("Installing default DeviceState\n"); LOG_INFO("Installing default DeviceState\n");
memset(&devicestate, 0, sizeof(DeviceState)); memset(&devicestate, 0, sizeof(meshtastic_DeviceState));
*numNodes = 0; *numNodes = 0;
@@ -285,7 +288,8 @@ void NodeDB::init()
myNodeInfo.max_channels = MAX_NUM_CHANNELS; // tell others the max # of channels we can understand myNodeInfo.max_channels = MAX_NUM_CHANNELS; // tell others the max # of channels we can understand
myNodeInfo.error_code = CriticalErrorCode_NONE; // For the error code, only show values from this boot (discard value from flash) myNodeInfo.error_code =
meshtastic_CriticalErrorCode_NONE; // For the error code, only show values from this boot (discard value from flash)
myNodeInfo.error_address = 0; myNodeInfo.error_address = 0;
// likewise - we always want the app requirements to come from the running appload // likewise - we always want the app requirements to come from the running appload
@@ -299,7 +303,7 @@ void NodeDB::init()
owner.hw_model = HW_VENDOR; owner.hw_model = HW_VENDOR;
// Include our owner in the node db under our nodenum // Include our owner in the node db under our nodenum
NodeInfo *info = getOrCreateNode(getNodeNum()); meshtastic_NodeInfo *info = getOrCreateNode(getNodeNum());
info->user = owner; info->user = owner;
info->has_user = true; info->has_user = true;
@@ -348,7 +352,7 @@ void NodeDB::pickNewNodeNum()
if (r == NODENUM_BROADCAST || r < NUM_RESERVED) if (r == NODENUM_BROADCAST || r < NUM_RESERVED)
r = NUM_RESERVED; // don't pick a reserved node number r = NUM_RESERVED; // don't pick a reserved node number
NodeInfo *found; meshtastic_NodeInfo *found;
while ((found = getNode(r)) && memcmp(found->user.macaddr, owner.macaddr, sizeof(owner.macaddr))) { while ((found = getNode(r)) && memcmp(found->user.macaddr, owner.macaddr, sizeof(owner.macaddr))) {
NodeNum n = random(NUM_RESERVED, NODENUM_BROADCAST); // try a new random choice NodeNum n = random(NUM_RESERVED, NODENUM_BROADCAST); // try a new random choice
LOG_DEBUG("NOTE! Our desired nodenum 0x%x is in use, so trying for 0x%x\n", r, n); LOG_DEBUG("NOTE! Our desired nodenum 0x%x is in use, so trying for 0x%x\n", r, n);
@@ -364,7 +368,6 @@ static const char *moduleConfigFileName = "/prefs/module.proto";
static const char *channelFileName = "/prefs/channels.proto"; static const char *channelFileName = "/prefs/channels.proto";
static const char *oemConfigFile = "/oem/oem.proto"; static const char *oemConfigFile = "/oem/oem.proto";
/** Load a protobuf from a file, return true for success */ /** Load a protobuf from a file, return true for success */
bool NodeDB::loadProto(const char *filename, size_t protoSize, size_t objSize, const pb_msgdesc_t *fields, void *dest_struct) bool NodeDB::loadProto(const char *filename, size_t protoSize, size_t objSize, const pb_msgdesc_t *fields, void *dest_struct)
{ {
@@ -400,7 +403,8 @@ bool NodeDB::loadProto(const char *filename, size_t protoSize, size_t objSize, c
void NodeDB::loadFromDisk() void NodeDB::loadFromDisk()
{ {
// static DeviceState scratch; We no longer read into a tempbuf because this structure is 15KB of valuable RAM // static DeviceState scratch; We no longer read into a tempbuf because this structure is 15KB of valuable RAM
if (!loadProto(prefFileName, DeviceState_size, sizeof(DeviceState), &DeviceState_msg, &devicestate)) { if (!loadProto(prefFileName, meshtastic_DeviceState_size, sizeof(meshtastic_DeviceState), &meshtastic_DeviceState_msg,
&devicestate)) {
installDefaultDeviceState(); // Our in RAM copy might now be corrupt installDefaultDeviceState(); // Our in RAM copy might now be corrupt
} else { } else {
if (devicestate.version < DEVICESTATE_MIN_VER) { if (devicestate.version < DEVICESTATE_MIN_VER) {
@@ -411,7 +415,8 @@ void NodeDB::loadFromDisk()
} }
} }
if (!loadProto(configFileName, LocalConfig_size, sizeof(LocalConfig), &LocalConfig_msg, &config)) { if (!loadProto(configFileName, meshtastic_LocalConfig_size, sizeof(meshtastic_LocalConfig), &meshtastic_LocalConfig_msg,
&config)) {
installDefaultConfig(); // Our in RAM copy might now be corrupt installDefaultConfig(); // Our in RAM copy might now be corrupt
} else { } else {
if (config.version < DEVICESTATE_MIN_VER) { if (config.version < DEVICESTATE_MIN_VER) {
@@ -422,7 +427,8 @@ void NodeDB::loadFromDisk()
} }
} }
if (!loadProto(moduleConfigFileName, LocalModuleConfig_size, sizeof(LocalModuleConfig), &LocalModuleConfig_msg, &moduleConfig)) { if (!loadProto(moduleConfigFileName, meshtastic_LocalModuleConfig_size, sizeof(meshtastic_LocalModuleConfig),
&meshtastic_LocalModuleConfig_msg, &moduleConfig)) {
installDefaultModuleConfig(); // Our in RAM copy might now be corrupt installDefaultModuleConfig(); // Our in RAM copy might now be corrupt
} else { } else {
if (moduleConfig.version < DEVICESTATE_MIN_VER) { if (moduleConfig.version < DEVICESTATE_MIN_VER) {
@@ -433,7 +439,8 @@ void NodeDB::loadFromDisk()
} }
} }
if (!loadProto(channelFileName, ChannelFile_size, sizeof(ChannelFile), &ChannelFile_msg, &channelFile)) { if (!loadProto(channelFileName, meshtastic_ChannelFile_size, sizeof(meshtastic_ChannelFile), &meshtastic_ChannelFile_msg,
&channelFile)) {
installDefaultChannels(); // Our in RAM copy might now be corrupt installDefaultChannels(); // Our in RAM copy might now be corrupt
} else { } else {
if (channelFile.version < DEVICESTATE_MIN_VER) { if (channelFile.version < DEVICESTATE_MIN_VER) {
@@ -444,7 +451,7 @@ void NodeDB::loadFromDisk()
} }
} }
if (loadProto(oemConfigFile, OEMStore_size, sizeof(OEMStore), &OEMStore_msg, &oemStore)) if (loadProto(oemConfigFile, meshtastic_OEMStore_size, sizeof(meshtastic_OEMStore), &meshtastic_OEMStore_msg, &oemStore))
LOG_INFO("Loaded OEMStore\n"); LOG_INFO("Loaded OEMStore\n");
} }
@@ -497,7 +504,7 @@ void NodeDB::saveChannelsToDisk()
#ifdef FSCom #ifdef FSCom
FSCom.mkdir("/prefs"); FSCom.mkdir("/prefs");
#endif #endif
saveProto(channelFileName, ChannelFile_size, &ChannelFile_msg, &channelFile); saveProto(channelFileName, meshtastic_ChannelFile_size, &meshtastic_ChannelFile_msg, &channelFile);
} }
} }
@@ -507,7 +514,7 @@ void NodeDB::saveDeviceStateToDisk()
#ifdef FSCom #ifdef FSCom
FSCom.mkdir("/prefs"); FSCom.mkdir("/prefs");
#endif #endif
saveProto(prefFileName, DeviceState_size, &DeviceState_msg, &devicestate); saveProto(prefFileName, meshtastic_DeviceState_size, &meshtastic_DeviceState_msg, &devicestate);
} }
} }
@@ -529,7 +536,7 @@ void NodeDB::saveToDisk(int saveWhat)
config.has_power = true; config.has_power = true;
config.has_network = true; config.has_network = true;
config.has_bluetooth = true; config.has_bluetooth = true;
saveProto(configFileName, LocalConfig_size, &LocalConfig_msg, &config); saveProto(configFileName, meshtastic_LocalConfig_size, &meshtastic_LocalConfig_msg, &config);
} }
if (saveWhat & SEGMENT_MODULECONFIG) { if (saveWhat & SEGMENT_MODULECONFIG) {
@@ -540,7 +547,7 @@ void NodeDB::saveToDisk(int saveWhat)
moduleConfig.has_serial = true; moduleConfig.has_serial = true;
moduleConfig.has_store_forward = true; moduleConfig.has_store_forward = true;
moduleConfig.has_telemetry = true; moduleConfig.has_telemetry = true;
saveProto(moduleConfigFileName, LocalModuleConfig_size, &LocalModuleConfig_msg, &moduleConfig); saveProto(moduleConfigFileName, meshtastic_LocalModuleConfig_size, &meshtastic_LocalModuleConfig_msg, &moduleConfig);
} }
if (saveWhat & SEGMENT_CHANNELS) { if (saveWhat & SEGMENT_CHANNELS) {
@@ -551,7 +558,7 @@ void NodeDB::saveToDisk(int saveWhat)
} }
} }
const NodeInfo *NodeDB::readNextInfo() const meshtastic_NodeInfo *NodeDB::readNextInfo()
{ {
if (readPointer < *numNodes) if (readPointer < *numNodes)
return &nodes[readPointer++]; return &nodes[readPointer++];
@@ -560,7 +567,7 @@ const NodeInfo *NodeDB::readNextInfo()
} }
/// Given a node, return how many seconds in the past (vs now) that we last heard from it /// Given a node, return how many seconds in the past (vs now) that we last heard from it
uint32_t sinceLastSeen(const NodeInfo *n) uint32_t sinceLastSeen(const meshtastic_NodeInfo *n)
{ {
uint32_t now = getTime(); uint32_t now = getTime();
@@ -589,9 +596,9 @@ size_t NodeDB::getNumOnlineNodes()
/** Update position info for this node based on received position data /** Update position info for this node based on received position data
*/ */
void NodeDB::updatePosition(uint32_t nodeId, const Position &p, RxSource src) void NodeDB::updatePosition(uint32_t nodeId, const meshtastic_Position &p, RxSource src)
{ {
NodeInfo *info = getOrCreateNode(nodeId); meshtastic_NodeInfo *info = getOrCreateNode(nodeId);
if (!info) { if (!info) {
return; return;
} }
@@ -634,11 +641,11 @@ void NodeDB::updatePosition(uint32_t nodeId, const Position &p, RxSource src)
/** Update telemetry info for this node based on received metrics /** Update telemetry info for this node based on received metrics
* We only care about device telemetry here * We only care about device telemetry here
*/ */
void NodeDB::updateTelemetry(uint32_t nodeId, const Telemetry &t, RxSource src) void NodeDB::updateTelemetry(uint32_t nodeId, const meshtastic_Telemetry &t, RxSource src)
{ {
NodeInfo *info = getOrCreateNode(nodeId); meshtastic_NodeInfo *info = getOrCreateNode(nodeId);
// Environment metrics should never go to NodeDb but we'll safegaurd anyway // Environment metrics should never go to NodeDb but we'll safegaurd anyway
if (!info || t.which_variant != Telemetry_device_metrics_tag) { if (!info || t.which_variant != meshtastic_Telemetry_device_metrics_tag) {
return; return;
} }
@@ -656,9 +663,9 @@ void NodeDB::updateTelemetry(uint32_t nodeId, const Telemetry &t, RxSource src)
/** Update user info for this node based on received user data /** Update user info for this node based on received user data
*/ */
void NodeDB::updateUser(uint32_t nodeId, const User &p) void NodeDB::updateUser(uint32_t nodeId, const meshtastic_User &p)
{ {
NodeInfo *info = getOrCreateNode(nodeId); meshtastic_NodeInfo *info = getOrCreateNode(nodeId);
if (!info) { if (!info) {
return; return;
} }
@@ -685,12 +692,12 @@ void NodeDB::updateUser(uint32_t nodeId, const User &p)
/// given a subpacket sniffed from the network, update our DB state /// given a subpacket sniffed from the network, update our DB state
/// we updateGUI and updateGUIforNode if we think our this change is big enough for a redraw /// we updateGUI and updateGUIforNode if we think our this change is big enough for a redraw
void NodeDB::updateFrom(const MeshPacket &mp) void NodeDB::updateFrom(const meshtastic_MeshPacket &mp)
{ {
if (mp.which_payload_variant == MeshPacket_decoded_tag && mp.from) { if (mp.which_payload_variant == meshtastic_MeshPacket_decoded_tag && mp.from) {
LOG_DEBUG("Update DB node 0x%x, rx_time=%u\n", mp.from, mp.rx_time); LOG_DEBUG("Update DB node 0x%x, rx_time=%u\n", mp.from, mp.rx_time);
NodeInfo *info = getOrCreateNode(getFrom(&mp)); meshtastic_NodeInfo *info = getOrCreateNode(getFrom(&mp));
if (!info) { if (!info) {
return; return;
} }
@@ -705,7 +712,7 @@ void NodeDB::updateFrom(const MeshPacket &mp)
/// Find a node in our DB, return null for missing /// Find a node in our DB, return null for missing
/// NOTE: This function might be called from an ISR /// NOTE: This function might be called from an ISR
NodeInfo *NodeDB::getNode(NodeNum n) meshtastic_NodeInfo *NodeDB::getNode(NodeNum n)
{ {
for (int i = 0; i < *numNodes; i++) for (int i = 0; i < *numNodes; i++)
if (nodes[i].num == n) if (nodes[i].num == n)
@@ -715,9 +722,9 @@ NodeInfo *NodeDB::getNode(NodeNum n)
} }
/// Find a node in our DB, create an empty NodeInfo if missing /// Find a node in our DB, create an empty NodeInfo if missing
NodeInfo *NodeDB::getOrCreateNode(NodeNum n) meshtastic_NodeInfo *NodeDB::getOrCreateNode(NodeNum n)
{ {
NodeInfo *info = getNode(n); meshtastic_NodeInfo *info = getNode(n);
if (!info) { if (!info) {
if (*numNodes >= MAX_NUM_NODES) { if (*numNodes >= MAX_NUM_NODES) {
@@ -749,7 +756,7 @@ NodeInfo *NodeDB::getOrCreateNode(NodeNum n)
} }
/// Record an error that should be reported via analytics /// Record an error that should be reported via analytics
void recordCriticalError(CriticalErrorCode code, uint32_t address, const char *filename) void recordCriticalError(meshtastic_CriticalErrorCode code, uint32_t address, const char *filename)
{ {
// Print error to screen and serial port // Print error to screen and serial port
String lcd = String("Critical error ") + code + "!\n"; String lcd = String("Critical error ") + code + "!\n";
+31 -26
View File
@@ -21,16 +21,16 @@ DeviceState versions used to be defined in the .proto file but really only this
#define DEVICESTATE_CUR_VER 20 #define DEVICESTATE_CUR_VER 20
#define DEVICESTATE_MIN_VER DEVICESTATE_CUR_VER #define DEVICESTATE_MIN_VER DEVICESTATE_CUR_VER
extern DeviceState devicestate; extern meshtastic_DeviceState devicestate;
extern ChannelFile channelFile; extern meshtastic_ChannelFile channelFile;
extern MyNodeInfo &myNodeInfo; extern meshtastic_MyNodeInfo &myNodeInfo;
extern LocalConfig config; extern meshtastic_LocalConfig config;
extern LocalModuleConfig moduleConfig; extern meshtastic_LocalModuleConfig moduleConfig;
extern OEMStore oemStore; extern meshtastic_OEMStore oemStore;
extern User &owner; extern meshtastic_User &owner;
/// Given a node, return how many seconds in the past (vs now) that we last heard from it /// Given a node, return how many seconds in the past (vs now) that we last heard from it
uint32_t sinceLastSeen(const NodeInfo *n); uint32_t sinceLastSeen(const meshtastic_NodeInfo *n);
class NodeDB class NodeDB
{ {
@@ -40,14 +40,14 @@ class NodeDB
// Eventually use a smarter datastructure // Eventually use a smarter datastructure
// HashMap<NodeNum, NodeInfo> nodes; // HashMap<NodeNum, NodeInfo> nodes;
// Note: these two references just point into our static array we serialize to/from disk // Note: these two references just point into our static array we serialize to/from disk
NodeInfo *nodes; meshtastic_NodeInfo *nodes;
pb_size_t *numNodes; pb_size_t *numNodes;
uint32_t readPointer = 0; uint32_t readPointer = 0;
public: public:
bool updateGUI = false; // we think the gui should definitely be redrawn, screen will clear this once handled bool updateGUI = false; // we think the gui should definitely be redrawn, screen will clear this once handled
NodeInfo *updateGUIforNode = NULL; // if currently showing this node, we think you should update the GUI meshtastic_NodeInfo *updateGUIforNode = NULL; // if currently showing this node, we think you should update the GUI
Observable<const meshtastic::NodeStatus *> newStatus; Observable<const meshtastic::NodeStatus *> newStatus;
/// don't do mesh based algoritm for node id assignment (initially) /// don't do mesh based algoritm for node id assignment (initially)
@@ -58,7 +58,8 @@ class NodeDB
void init(); void init();
/// write to flash /// write to flash
void saveToDisk(int saveWhat = SEGMENT_CONFIG | SEGMENT_MODULECONFIG | SEGMENT_DEVICESTATE | SEGMENT_CHANNELS), saveChannelsToDisk(), saveDeviceStateToDisk(); void saveToDisk(int saveWhat = SEGMENT_CONFIG | SEGMENT_MODULECONFIG | SEGMENT_DEVICESTATE | SEGMENT_CHANNELS),
saveChannelsToDisk(), saveDeviceStateToDisk();
/** Reinit radio config if needed, because either: /** Reinit radio config if needed, because either:
* a) sometimes a buggy android app might send us bogus settings or * a) sometimes a buggy android app might send us bogus settings or
@@ -70,19 +71,19 @@ class NodeDB
/// given a subpacket sniffed from the network, update our DB state /// given a subpacket sniffed from the network, update our DB state
/// we updateGUI and updateGUIforNode if we think our this change is big enough for a redraw /// we updateGUI and updateGUIforNode if we think our this change is big enough for a redraw
void updateFrom(const MeshPacket &p); void updateFrom(const meshtastic_MeshPacket &p);
/** Update position info for this node based on received position data /** Update position info for this node based on received position data
*/ */
void updatePosition(uint32_t nodeId, const Position &p, RxSource src = RX_SRC_RADIO); void updatePosition(uint32_t nodeId, const meshtastic_Position &p, RxSource src = RX_SRC_RADIO);
/** Update telemetry info for this node based on received metrics /** 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 meshtastic_Telemetry &t, RxSource src = RX_SRC_RADIO);
/** Update user info for this node based on received user data /** Update user info for this node based on received user data
*/ */
void updateUser(uint32_t nodeId, const User &p); void updateUser(uint32_t nodeId, const meshtastic_User &p);
/// @return our node number /// @return our node number
NodeNum getNodeNum() { return myNodeInfo.my_node_num; } NodeNum getNodeNum() { return myNodeInfo.my_node_num; }
@@ -104,15 +105,15 @@ class NodeDB
void resetReadPointer() { readPointer = 0; } void resetReadPointer() { readPointer = 0; }
/// Allow the bluetooth layer to read our next nodeinfo record, or NULL if done reading /// Allow the bluetooth layer to read our next nodeinfo record, or NULL if done reading
const NodeInfo *readNextInfo(); const meshtastic_NodeInfo *readNextInfo();
/// pick a provisional nodenum we hope no one is using /// pick a provisional nodenum we hope no one is using
void pickNewNodeNum(); void pickNewNodeNum();
/// Find a node in our DB, return null for missing /// Find a node in our DB, return null for missing
NodeInfo *getNode(NodeNum n); meshtastic_NodeInfo *getNode(NodeNum n);
NodeInfo *getNodeByIndex(size_t x) meshtastic_NodeInfo *getNodeByIndex(size_t x)
{ {
assert(x < *numNodes); assert(x < *numNodes);
return &nodes[x]; return &nodes[x];
@@ -130,7 +131,7 @@ class NodeDB
private: private:
/// Find a node in our DB, create an empty NodeInfo if missing /// Find a node in our DB, create an empty NodeInfo if missing
NodeInfo *getOrCreateNode(NodeNum n); meshtastic_NodeInfo *getOrCreateNode(NodeNum n);
/// Notify observers of changes to the DB /// Notify observers of changes to the DB
void notifyObservers(bool forceUpdate = false) void notifyObservers(bool forceUpdate = false)
@@ -140,13 +141,11 @@ class NodeDB
newStatus.notifyObservers(&status); newStatus.notifyObservers(&status);
} }
/// read our db from flash /// read our db from flash
void loadFromDisk(); void loadFromDisk();
/// Reinit device state from scratch (not loading from disk) /// Reinit device state from scratch (not loading from disk)
void installDefaultDeviceState(), installDefaultChannels(), installDefaultConfig(), void installDefaultDeviceState(), installDefaultChannels(), installDefaultConfig(), installDefaultModuleConfig();
installDefaultModuleConfig();
}; };
/** /**
@@ -183,7 +182,8 @@ extern NodeDB nodeDB;
// Our delay functions check for this for times that should never expire // Our delay functions check for this for times that should never expire
#define NODE_DELAY_FOREVER 0xffffffff #define NODE_DELAY_FOREVER 0xffffffff
#define IF_ROUTER(routerVal, normalVal) ((config.device.role == Config_DeviceConfig_Role_ROUTER) ? (routerVal) : (normalVal)) #define IF_ROUTER(routerVal, normalVal) \
((config.device.role == meshtastic_Config_DeviceConfig_Role_ROUTER) ? (routerVal) : (normalVal))
#define ONE_DAY 24 * 60 * 60 #define ONE_DAY 24 * 60 * 60
@@ -203,13 +203,15 @@ extern NodeDB nodeDB;
inline uint32_t getConfiguredOrDefaultMs(uint32_t configuredInterval) inline uint32_t getConfiguredOrDefaultMs(uint32_t configuredInterval)
{ {
if (configuredInterval > 0) return configuredInterval * 1000; if (configuredInterval > 0)
return configuredInterval * 1000;
return default_broadcast_interval_secs * 1000; return default_broadcast_interval_secs * 1000;
} }
inline uint32_t getConfiguredOrDefaultMs(uint32_t configuredInterval, uint32_t defaultInterval) inline uint32_t getConfiguredOrDefaultMs(uint32_t configuredInterval, uint32_t defaultInterval)
{ {
if (configuredInterval > 0) return configuredInterval * 1000; if (configuredInterval > 0)
return configuredInterval * 1000;
return defaultInterval * 1000; return defaultInterval * 1000;
} }
@@ -218,4 +220,7 @@ inline uint32_t getConfiguredOrDefaultMs(uint32_t configuredInterval, uint32_t d
*/ */
extern uint32_t radioGeneration; 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) #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)
+4 -3
View File
@@ -1,5 +1,5 @@
#include "configuration.h"
#include "PacketHistory.h" #include "PacketHistory.h"
#include "configuration.h"
#include "mesh-pb-constants.h" #include "mesh-pb-constants.h"
PacketHistory::PacketHistory() PacketHistory::PacketHistory()
@@ -11,7 +11,7 @@ PacketHistory::PacketHistory()
/** /**
* Update recentBroadcasts and return true if we have already seen this packet * Update recentBroadcasts and return true if we have already seen this packet
*/ */
bool PacketHistory::wasSeenRecently(const MeshPacket *p, bool withUpdate) bool PacketHistory::wasSeenRecently(const meshtastic_MeshPacket *p, bool withUpdate)
{ {
if (p->id == 0) { if (p->id == 0) {
LOG_DEBUG("Ignoring message with zero id\n"); LOG_DEBUG("Ignoring message with zero id\n");
@@ -58,7 +58,8 @@ bool PacketHistory::wasSeenRecently(const MeshPacket *p, bool withUpdate)
/** /**
* Iterate through all recent packets, and remove all older than FLOOD_EXPIRE_TIME * Iterate through all recent packets, and remove all older than FLOOD_EXPIRE_TIME
*/ */
void PacketHistory::clearExpiredRecentPackets() { void PacketHistory::clearExpiredRecentPackets()
{
uint32_t now = millis(); uint32_t now = millis();
LOG_DEBUG("recentPackets size=%ld\n", recentPackets.size()); LOG_DEBUG("recentPackets size=%ld\n", recentPackets.size());
+1 -1
View File
@@ -41,5 +41,5 @@ class PacketHistory
* *
* @param withUpdate if true and not found we add an entry to recentPackets * @param withUpdate if true and not found we add an entry to recentPackets
*/ */
bool wasSeenRecently(const MeshPacket *p, bool withUpdate = true); bool wasSeenRecently(const meshtastic_MeshPacket *p, bool withUpdate = true);
}; };
+53 -53
View File
@@ -80,20 +80,20 @@ bool PhoneAPI::handleToRadio(const uint8_t *buf, size_t bufLength)
// return (lastContactMsec != 0) && // return (lastContactMsec != 0) &&
memset(&toRadioScratch, 0, sizeof(toRadioScratch)); memset(&toRadioScratch, 0, sizeof(toRadioScratch));
if (pb_decode_from_bytes(buf, bufLength, &ToRadio_msg, &toRadioScratch)) { if (pb_decode_from_bytes(buf, bufLength, &meshtastic_ToRadio_msg, &toRadioScratch)) {
switch (toRadioScratch.which_payload_variant) { switch (toRadioScratch.which_payload_variant) {
case ToRadio_packet_tag: case meshtastic_ToRadio_packet_tag:
return handleToRadioPacket(toRadioScratch.packet); return handleToRadioPacket(toRadioScratch.packet);
case ToRadio_want_config_id_tag: case meshtastic_ToRadio_want_config_id_tag:
config_nonce = toRadioScratch.want_config_id; config_nonce = toRadioScratch.want_config_id;
LOG_INFO("Client wants config, nonce=%u\n", config_nonce); LOG_INFO("Client wants config, nonce=%u\n", config_nonce);
handleStartConfig(); handleStartConfig();
break; break;
case ToRadio_disconnect_tag: case meshtastic_ToRadio_disconnect_tag:
LOG_INFO("Disconnecting from phone\n"); LOG_INFO("Disconnecting from phone\n");
close(); close();
break; break;
case ToRadio_xmodemPacket_tag: case meshtastic_ToRadio_xmodemPacket_tag:
LOG_INFO("Got xmodem packet\n"); LOG_INFO("Got xmodem packet\n");
xModem.handlePacket(toRadioScratch.xmodemPacket); xModem.handlePacket(toRadioScratch.xmodemPacket);
break; break;
@@ -143,7 +143,7 @@ size_t PhoneAPI::getFromRadio(uint8_t *buf)
// If the user has specified they don't want our node to share its location, make sure to tell the phone // If the user has specified they don't want our node to share its location, make sure to tell the phone
// app not to send locations on our behalf. // app not to send locations on our behalf.
myNodeInfo.has_gps = gps && gps->isConnected(); // Update with latest GPS connect info myNodeInfo.has_gps = gps && gps->isConnected(); // Update with latest GPS connect info
fromRadioScratch.which_payload_variant = FromRadio_my_info_tag; fromRadioScratch.which_payload_variant = meshtastic_FromRadio_my_info_tag;
fromRadioScratch.my_info = myNodeInfo; fromRadioScratch.my_info = myNodeInfo;
state = STATE_SEND_NODEINFO; state = STATE_SEND_NODEINFO;
@@ -152,13 +152,13 @@ size_t PhoneAPI::getFromRadio(uint8_t *buf)
case STATE_SEND_NODEINFO: { case STATE_SEND_NODEINFO: {
LOG_INFO("getFromRadio=STATE_SEND_NODEINFO\n"); LOG_INFO("getFromRadio=STATE_SEND_NODEINFO\n");
const NodeInfo *info = nodeInfoForPhone; const meshtastic_NodeInfo *info = nodeInfoForPhone;
nodeInfoForPhone = NULL; // We just consumed a nodeinfo, will need a new one next time nodeInfoForPhone = NULL; // We just consumed a nodeinfo, will need a new one next time
if (info) { if (info) {
LOG_INFO("Sending nodeinfo: num=0x%x, lastseen=%u, id=%s, name=%s\n", info->num, info->last_heard, info->user.id, LOG_INFO("Sending nodeinfo: num=0x%x, lastseen=%u, id=%s, name=%s\n", info->num, info->last_heard, info->user.id,
info->user.long_name); info->user.long_name);
fromRadioScratch.which_payload_variant = FromRadio_node_info_tag; fromRadioScratch.which_payload_variant = meshtastic_FromRadio_node_info_tag;
fromRadioScratch.node_info = *info; fromRadioScratch.node_info = *info;
// Stay in current state until done sending nodeinfos // Stay in current state until done sending nodeinfos
} else { } else {
@@ -172,47 +172,47 @@ size_t PhoneAPI::getFromRadio(uint8_t *buf)
case STATE_SEND_CHANNELS: case STATE_SEND_CHANNELS:
LOG_INFO("getFromRadio=STATE_SEND_CHANNELS\n"); LOG_INFO("getFromRadio=STATE_SEND_CHANNELS\n");
fromRadioScratch.which_payload_variant = FromRadio_channel_tag; fromRadioScratch.which_payload_variant = meshtastic_FromRadio_channel_tag;
fromRadioScratch.channel = channels.getByIndex(config_state); fromRadioScratch.channel = channels.getByIndex(config_state);
config_state++; config_state++;
// Advance when we have sent all of our Channels // Advance when we have sent all of our Channels
if (config_state >= MAX_NUM_CHANNELS) { if (config_state >= MAX_NUM_CHANNELS) {
state = STATE_SEND_CONFIG; state = STATE_SEND_CONFIG;
config_state = _AdminMessage_ConfigType_MIN + 1; config_state = _meshtastic_AdminMessage_ConfigType_MIN + 1;
} }
break; break;
case STATE_SEND_CONFIG: case STATE_SEND_CONFIG:
LOG_INFO("getFromRadio=STATE_SEND_CONFIG\n"); LOG_INFO("getFromRadio=STATE_SEND_CONFIG\n");
fromRadioScratch.which_payload_variant = FromRadio_config_tag; fromRadioScratch.which_payload_variant = meshtastic_FromRadio_config_tag;
switch (config_state) { switch (config_state) {
case Config_device_tag: case meshtastic_Config_device_tag:
fromRadioScratch.config.which_payload_variant = Config_device_tag; fromRadioScratch.config.which_payload_variant = meshtastic_Config_device_tag;
fromRadioScratch.config.payload_variant.device = config.device; fromRadioScratch.config.payload_variant.device = config.device;
break; break;
case Config_position_tag: case meshtastic_Config_position_tag:
fromRadioScratch.config.which_payload_variant = Config_position_tag; fromRadioScratch.config.which_payload_variant = meshtastic_Config_position_tag;
fromRadioScratch.config.payload_variant.position = config.position; fromRadioScratch.config.payload_variant.position = config.position;
break; break;
case Config_power_tag: case meshtastic_Config_power_tag:
fromRadioScratch.config.which_payload_variant = Config_power_tag; fromRadioScratch.config.which_payload_variant = meshtastic_Config_power_tag;
fromRadioScratch.config.payload_variant.power = config.power; fromRadioScratch.config.payload_variant.power = config.power;
fromRadioScratch.config.payload_variant.power.ls_secs = default_ls_secs; fromRadioScratch.config.payload_variant.power.ls_secs = default_ls_secs;
break; break;
case Config_network_tag: case meshtastic_Config_network_tag:
fromRadioScratch.config.which_payload_variant = Config_network_tag; fromRadioScratch.config.which_payload_variant = meshtastic_Config_network_tag;
fromRadioScratch.config.payload_variant.network = config.network; fromRadioScratch.config.payload_variant.network = config.network;
break; break;
case Config_display_tag: case meshtastic_Config_display_tag:
fromRadioScratch.config.which_payload_variant = Config_display_tag; fromRadioScratch.config.which_payload_variant = meshtastic_Config_display_tag;
fromRadioScratch.config.payload_variant.display = config.display; fromRadioScratch.config.payload_variant.display = config.display;
break; break;
case Config_lora_tag: case meshtastic_Config_lora_tag:
fromRadioScratch.config.which_payload_variant = Config_lora_tag; fromRadioScratch.config.which_payload_variant = meshtastic_Config_lora_tag;
fromRadioScratch.config.payload_variant.lora = config.lora; fromRadioScratch.config.payload_variant.lora = config.lora;
break; break;
case Config_bluetooth_tag: case meshtastic_Config_bluetooth_tag:
fromRadioScratch.config.which_payload_variant = Config_bluetooth_tag; fromRadioScratch.config.which_payload_variant = meshtastic_Config_bluetooth_tag;
fromRadioScratch.config.payload_variant.bluetooth = config.bluetooth; fromRadioScratch.config.payload_variant.bluetooth = config.bluetooth;
break; break;
default: default:
@@ -224,50 +224,50 @@ size_t PhoneAPI::getFromRadio(uint8_t *buf)
config_state++; config_state++;
// Advance when we have sent all of our config objects // Advance when we have sent all of our config objects
if (config_state > (_AdminMessage_ConfigType_MAX + 1)) { if (config_state > (_meshtastic_AdminMessage_ConfigType_MAX + 1)) {
state = STATE_SEND_MODULECONFIG; state = STATE_SEND_MODULECONFIG;
config_state = _AdminMessage_ModuleConfigType_MIN + 1; config_state = _meshtastic_AdminMessage_ModuleConfigType_MIN + 1;
} }
break; break;
case STATE_SEND_MODULECONFIG: case STATE_SEND_MODULECONFIG:
LOG_INFO("getFromRadio=STATE_SEND_MODULECONFIG\n"); LOG_INFO("getFromRadio=STATE_SEND_MODULECONFIG\n");
fromRadioScratch.which_payload_variant = FromRadio_moduleConfig_tag; fromRadioScratch.which_payload_variant = meshtastic_FromRadio_moduleConfig_tag;
switch (config_state) { switch (config_state) {
case ModuleConfig_mqtt_tag: case meshtastic_ModuleConfig_mqtt_tag:
fromRadioScratch.moduleConfig.which_payload_variant = ModuleConfig_mqtt_tag; fromRadioScratch.moduleConfig.which_payload_variant = meshtastic_ModuleConfig_mqtt_tag;
fromRadioScratch.moduleConfig.payload_variant.mqtt = moduleConfig.mqtt; fromRadioScratch.moduleConfig.payload_variant.mqtt = moduleConfig.mqtt;
break; break;
case ModuleConfig_serial_tag: case meshtastic_ModuleConfig_serial_tag:
fromRadioScratch.moduleConfig.which_payload_variant = ModuleConfig_serial_tag; fromRadioScratch.moduleConfig.which_payload_variant = meshtastic_ModuleConfig_serial_tag;
fromRadioScratch.moduleConfig.payload_variant.serial = moduleConfig.serial; fromRadioScratch.moduleConfig.payload_variant.serial = moduleConfig.serial;
break; break;
case ModuleConfig_external_notification_tag: case meshtastic_ModuleConfig_external_notification_tag:
fromRadioScratch.moduleConfig.which_payload_variant = ModuleConfig_external_notification_tag; fromRadioScratch.moduleConfig.which_payload_variant = meshtastic_ModuleConfig_external_notification_tag;
fromRadioScratch.moduleConfig.payload_variant.external_notification = moduleConfig.external_notification; fromRadioScratch.moduleConfig.payload_variant.external_notification = moduleConfig.external_notification;
break; break;
case ModuleConfig_store_forward_tag: case meshtastic_ModuleConfig_store_forward_tag:
fromRadioScratch.moduleConfig.which_payload_variant = ModuleConfig_store_forward_tag; fromRadioScratch.moduleConfig.which_payload_variant = meshtastic_ModuleConfig_store_forward_tag;
fromRadioScratch.moduleConfig.payload_variant.store_forward = moduleConfig.store_forward; fromRadioScratch.moduleConfig.payload_variant.store_forward = moduleConfig.store_forward;
break; break;
case ModuleConfig_range_test_tag: case meshtastic_ModuleConfig_range_test_tag:
fromRadioScratch.moduleConfig.which_payload_variant = ModuleConfig_range_test_tag; fromRadioScratch.moduleConfig.which_payload_variant = meshtastic_ModuleConfig_range_test_tag;
fromRadioScratch.moduleConfig.payload_variant.range_test = moduleConfig.range_test; fromRadioScratch.moduleConfig.payload_variant.range_test = moduleConfig.range_test;
break; break;
case ModuleConfig_telemetry_tag: case meshtastic_ModuleConfig_telemetry_tag:
fromRadioScratch.moduleConfig.which_payload_variant = ModuleConfig_telemetry_tag; fromRadioScratch.moduleConfig.which_payload_variant = meshtastic_ModuleConfig_telemetry_tag;
fromRadioScratch.moduleConfig.payload_variant.telemetry = moduleConfig.telemetry; fromRadioScratch.moduleConfig.payload_variant.telemetry = moduleConfig.telemetry;
break; break;
case ModuleConfig_canned_message_tag: case meshtastic_ModuleConfig_canned_message_tag:
fromRadioScratch.moduleConfig.which_payload_variant = ModuleConfig_canned_message_tag; fromRadioScratch.moduleConfig.which_payload_variant = meshtastic_ModuleConfig_canned_message_tag;
fromRadioScratch.moduleConfig.payload_variant.canned_message = moduleConfig.canned_message; fromRadioScratch.moduleConfig.payload_variant.canned_message = moduleConfig.canned_message;
break; break;
case ModuleConfig_audio_tag: case meshtastic_ModuleConfig_audio_tag:
fromRadioScratch.moduleConfig.which_payload_variant = ModuleConfig_audio_tag; fromRadioScratch.moduleConfig.which_payload_variant = meshtastic_ModuleConfig_audio_tag;
fromRadioScratch.moduleConfig.payload_variant.audio = moduleConfig.audio; fromRadioScratch.moduleConfig.payload_variant.audio = moduleConfig.audio;
break; break;
case ModuleConfig_remote_hardware_tag: case meshtastic_ModuleConfig_remote_hardware_tag:
fromRadioScratch.moduleConfig.which_payload_variant = ModuleConfig_remote_hardware_tag; fromRadioScratch.moduleConfig.which_payload_variant = meshtastic_ModuleConfig_remote_hardware_tag;
fromRadioScratch.moduleConfig.payload_variant.remote_hardware = moduleConfig.remote_hardware; fromRadioScratch.moduleConfig.payload_variant.remote_hardware = moduleConfig.remote_hardware;
break; break;
default: default:
@@ -276,7 +276,7 @@ size_t PhoneAPI::getFromRadio(uint8_t *buf)
config_state++; config_state++;
// Advance when we have sent all of our ModuleConfig objects // Advance when we have sent all of our ModuleConfig objects
if (config_state > (_AdminMessage_ModuleConfigType_MAX + 1)) { if (config_state > (_meshtastic_AdminMessage_ModuleConfigType_MAX + 1)) {
state = STATE_SEND_COMPLETE_ID; state = STATE_SEND_COMPLETE_ID;
config_state = 0; config_state = 0;
} }
@@ -284,7 +284,7 @@ size_t PhoneAPI::getFromRadio(uint8_t *buf)
case STATE_SEND_COMPLETE_ID: case STATE_SEND_COMPLETE_ID:
LOG_INFO("getFromRadio=STATE_SEND_COMPLETE_ID\n"); LOG_INFO("getFromRadio=STATE_SEND_COMPLETE_ID\n");
fromRadioScratch.which_payload_variant = FromRadio_config_complete_id_tag; fromRadioScratch.which_payload_variant = meshtastic_FromRadio_config_complete_id_tag;
fromRadioScratch.config_complete_id = config_nonce; fromRadioScratch.config_complete_id = config_nonce;
config_nonce = 0; config_nonce = 0;
state = STATE_SEND_PACKETS; state = STATE_SEND_PACKETS;
@@ -294,11 +294,11 @@ size_t PhoneAPI::getFromRadio(uint8_t *buf)
// Do we have a message from the mesh? // Do we have a message from the mesh?
LOG_INFO("getFromRadio=STATE_SEND_PACKETS\n"); LOG_INFO("getFromRadio=STATE_SEND_PACKETS\n");
if (queueStatusPacketForPhone) { if (queueStatusPacketForPhone) {
fromRadioScratch.which_payload_variant = FromRadio_queueStatus_tag; fromRadioScratch.which_payload_variant = meshtastic_FromRadio_queueStatus_tag;
fromRadioScratch.queueStatus = *queueStatusPacketForPhone; fromRadioScratch.queueStatus = *queueStatusPacketForPhone;
releaseQueueStatusPhonePacket(); releaseQueueStatusPhonePacket();
} else if (xmodemPacketForPhone) { } else if (xmodemPacketForPhone) {
fromRadioScratch.which_payload_variant = FromRadio_xmodemPacket_tag; fromRadioScratch.which_payload_variant = meshtastic_FromRadio_xmodemPacket_tag;
fromRadioScratch.xmodemPacket = *xmodemPacketForPhone; fromRadioScratch.xmodemPacket = *xmodemPacketForPhone;
free(xmodemPacketForPhone); free(xmodemPacketForPhone);
xmodemPacketForPhone = NULL; xmodemPacketForPhone = NULL;
@@ -306,7 +306,7 @@ size_t PhoneAPI::getFromRadio(uint8_t *buf)
printPacket("phone downloaded packet", packetForPhone); printPacket("phone downloaded packet", packetForPhone);
// Encapsulate as a FromRadio packet // Encapsulate as a FromRadio packet
fromRadioScratch.which_payload_variant = FromRadio_packet_tag; fromRadioScratch.which_payload_variant = meshtastic_FromRadio_packet_tag;
fromRadioScratch.packet = *packetForPhone; fromRadioScratch.packet = *packetForPhone;
releasePhonePacket(); releasePhonePacket();
} }
@@ -319,7 +319,7 @@ size_t PhoneAPI::getFromRadio(uint8_t *buf)
// Do we have a message from the mesh? // Do we have a message from the mesh?
if (fromRadioScratch.which_payload_variant != 0) { if (fromRadioScratch.which_payload_variant != 0) {
// Encapsulate as a FromRadio packet // Encapsulate as a FromRadio packet
size_t numbytes = pb_encode_to_bytes(buf, FromRadio_size, &FromRadio_msg, &fromRadioScratch); size_t numbytes = pb_encode_to_bytes(buf, meshtastic_FromRadio_size, &meshtastic_FromRadio_msg, &fromRadioScratch);
LOG_DEBUG("encoding toPhone packet to phone variant=%d, %d bytes\n", fromRadioScratch.which_payload_variant, numbytes); LOG_DEBUG("encoding toPhone packet to phone variant=%d, %d bytes\n", fromRadioScratch.which_payload_variant, numbytes);
return numbytes; return numbytes;
@@ -399,7 +399,7 @@ bool PhoneAPI::available()
/** /**
* Handle a packet that the phone wants us to send. It is our responsibility to free the packet to the pool * Handle a packet that the phone wants us to send. It is our responsibility to free the packet to the pool
*/ */
bool PhoneAPI::handleToRadioPacket(MeshPacket &p) bool PhoneAPI::handleToRadioPacket(meshtastic_MeshPacket &p)
{ {
printPacket("PACKET FROM PHONE", &p); printPacket("PACKET FROM PHONE", &p);
service.handleToRadio(p); service.handleToRadio(p);
+8 -7
View File
@@ -41,18 +41,19 @@ class PhoneAPI
/// We temporarily keep the packet here between the call to available and getFromRadio. We will free it after the phone /// We temporarily keep the packet here between the call to available and getFromRadio. We will free it after the phone
/// downloads it /// downloads it
MeshPacket *packetForPhone = NULL; meshtastic_MeshPacket *packetForPhone = NULL;
// file transfer packets destined for phone. Push it to the queue then free it. // file transfer packets destined for phone. Push it to the queue then free it.
XModem *xmodemPacketForPhone = NULL; meshtastic_XModem *xmodemPacketForPhone = NULL;
// Keep QueueStatus packet just as packetForPhone // Keep QueueStatus packet just as packetForPhone
QueueStatus *queueStatusPacketForPhone = NULL; meshtastic_QueueStatus *queueStatusPacketForPhone = NULL;
/// We temporarily keep the nodeInfo here between the call to available and getFromRadio /// We temporarily keep the nodeInfo here between the call to available and getFromRadio
const NodeInfo *nodeInfoForPhone = NULL; const meshtastic_NodeInfo *nodeInfoForPhone = NULL;
ToRadio toRadioScratch = {0}; // this is a static scratch object, any data must be copied elsewhere before returning meshtastic_ToRadio toRadioScratch = {
0}; // this is a static scratch object, any data must be copied elsewhere before returning
/// Use to ensure that clients don't get confused about old messages from the radio /// Use to ensure that clients don't get confused about old messages from the radio
uint32_t config_nonce = 0; uint32_t config_nonce = 0;
@@ -92,7 +93,7 @@ class PhoneAPI
protected: protected:
/// Our fromradio packet while it is being assembled /// Our fromradio packet while it is being assembled
FromRadio fromRadioScratch = {}; meshtastic_FromRadio fromRadioScratch = {};
/** the last msec we heard from the client on the other side of this link */ /** the last msec we heard from the client on the other side of this link */
uint32_t lastContactMsec = 0; uint32_t lastContactMsec = 0;
@@ -128,7 +129,7 @@ class PhoneAPI
* Handle a packet that the phone wants us to send. We can write to it but can not keep a reference to it * Handle a packet that the phone wants us to send. We can write to it but can not keep a reference to it
* @return true true if a packet was queued for sending * @return true true if a packet was queued for sending
*/ */
bool handleToRadioPacket(MeshPacket &p); bool handleToRadioPacket(meshtastic_MeshPacket &p);
/// If the mesh service tells us fromNum has changed, tell the phone /// If the mesh service tells us fromNum has changed, tell the phone
virtual int onNotify(uint32_t newValue) override; virtual int onNotify(uint32_t newValue) override;
+1 -3
View File
@@ -1,4 +1,2 @@
#include "configuration.h"
#include "ProtobufModule.h" #include "ProtobufModule.h"
#include "configuration.h"
+10 -12
View File
@@ -16,31 +16,29 @@ template <class T> class ProtobufModule : protected SinglePortModule
/** Constructor /** Constructor
* name is for debugging output * name is for debugging output
*/ */
ProtobufModule(const char *_name, PortNum _ourPortNum, const pb_msgdesc_t *_fields) ProtobufModule(const char *_name, meshtastic_PortNum _ourPortNum, const pb_msgdesc_t *_fields)
: SinglePortModule(_name, _ourPortNum), fields(_fields) : SinglePortModule(_name, _ourPortNum), fields(_fields)
{ {
} }
protected: protected:
/** /**
* Handle a received message, the data field in the message is already decoded and is provided * Handle a received message, the data field in the message is already decoded and is provided
* *
* In general decoded will always be !NULL. But in some special applications (where you have handling packets * In general decoded will always be !NULL. But in some special applications (where you have handling packets
* for multiple port numbers, decoding will ONLY be attempted for packets where the portnum matches our expected ourPortNum. * for multiple port numbers, decoding will ONLY be attempted for packets where the portnum matches our expected ourPortNum.
*/ */
virtual bool handleReceivedProtobuf(const MeshPacket &mp, T *decoded) = 0; virtual bool handleReceivedProtobuf(const meshtastic_MeshPacket &mp, T *decoded) = 0;
/** /**
* Return a mesh packet which has been preinited with a particular protobuf data payload and port number. * Return a mesh packet which has been preinited with a particular protobuf data payload and port number.
* You can then send this packet (after customizing any of the payload fields you might need) with * You can then send this packet (after customizing any of the payload fields you might need) with
* service.sendToMesh() * service.sendToMesh()
*/ */
MeshPacket *allocDataProtobuf(const T &payload) meshtastic_MeshPacket *allocDataProtobuf(const T &payload)
{ {
// Update our local node info with our position (even if we don't decide to update anyone else) // Update our local node info with our position (even if we don't decide to update anyone else)
MeshPacket *p = allocDataPacket(); meshtastic_MeshPacket *p = allocDataPacket();
p->decoded.payload.size = p->decoded.payload.size =
pb_encode_to_bytes(p->decoded.payload.bytes, sizeof(p->decoded.payload.bytes), fields, &payload); pb_encode_to_bytes(p->decoded.payload.bytes, sizeof(p->decoded.payload.bytes), fields, &payload);
@@ -52,7 +50,7 @@ template <class T> class ProtobufModule : protected SinglePortModule
* Gets the short name from the sender of the mesh packet * Gets the short name from the sender of the mesh packet
* Returns "???" if unknown sender * Returns "???" if unknown sender
*/ */
const char *getSenderShortName(const MeshPacket &mp) const char *getSenderShortName(const meshtastic_MeshPacket &mp)
{ {
auto node = nodeDB.getNode(getFrom(&mp)); auto node = nodeDB.getNode(getFrom(&mp));
const char *sender = (node) ? node->user.short_name : "???"; const char *sender = (node) ? node->user.short_name : "???";
@@ -62,20 +60,20 @@ template <class T> class ProtobufModule : protected SinglePortModule
private: private:
/** Called to handle a particular incoming message /** Called to handle a particular incoming message
@return ProcessMessage::STOP if you've guaranteed you've handled this message and no other handlers should be considered for it @return ProcessMessage::STOP if you've guaranteed you've handled this message and no other handlers should be considered for
it
*/ */
virtual ProcessMessage handleReceived(const MeshPacket &mp) override virtual ProcessMessage handleReceived(const meshtastic_MeshPacket &mp) override
{ {
// FIXME - we currently update position data in the DB only if the message was a broadcast or destined to us // FIXME - we currently update position data in the DB only if the message was a broadcast or destined to us
// it would be better to update even if the message was destined to others. // it would be better to update even if the message was destined to others.
auto &p = mp.decoded; auto &p = mp.decoded;
LOG_INFO("Received %s from=0x%0x, id=0x%x, portnum=%d, payloadlen=%d\n", name, mp.from, mp.id, p.portnum, LOG_INFO("Received %s from=0x%0x, id=0x%x, portnum=%d, payloadlen=%d\n", name, mp.from, mp.id, p.portnum, p.payload.size);
p.payload.size);
T scratch; T scratch;
T *decoded = NULL; T *decoded = NULL;
if (mp.which_payload_variant == MeshPacket_decoded_tag && mp.decoded.portnum == ourPortNum) { if (mp.which_payload_variant == meshtastic_MeshPacket_decoded_tag && mp.decoded.portnum == ourPortNum) {
memset(&scratch, 0, sizeof(scratch)); memset(&scratch, 0, sizeof(scratch));
if (pb_decode_from_bytes(p.payload.bytes, p.payload.size, fields, &scratch)) { if (pb_decode_from_bytes(p.payload.bytes, p.payload.size, fields, &scratch)) {
decoded = &scratch; decoded = &scratch;
+7 -8
View File
@@ -1,7 +1,7 @@
#include "configuration.h"
#include "RF95Interface.h" #include "RF95Interface.h"
#include "MeshRadio.h" // kinda yucky, but we need to know which region we are in #include "MeshRadio.h" // kinda yucky, but we need to know which region we are in
#include "RadioLibRF95.h" #include "RadioLibRF95.h"
#include "configuration.h"
#include "error.h" #include "error.h"
#define MAX_POWER 20 #define MAX_POWER 20
@@ -104,15 +104,15 @@ bool RF95Interface::reconfigure()
// configure publicly accessible settings // configure publicly accessible settings
int err = lora->setSpreadingFactor(sf); int err = lora->setSpreadingFactor(sf);
if (err != RADIOLIB_ERR_NONE) if (err != RADIOLIB_ERR_NONE)
RECORD_CRITICALERROR(CriticalErrorCode_INVALID_RADIO_SETTING); RECORD_CRITICALERROR(meshtastic_CriticalErrorCode_INVALID_RADIO_SETTING);
err = lora->setBandwidth(bw); err = lora->setBandwidth(bw);
if (err != RADIOLIB_ERR_NONE) if (err != RADIOLIB_ERR_NONE)
RECORD_CRITICALERROR(CriticalErrorCode_INVALID_RADIO_SETTING); RECORD_CRITICALERROR(meshtastic_CriticalErrorCode_INVALID_RADIO_SETTING);
err = lora->setCodingRate(cr); err = lora->setCodingRate(cr);
if (err != RADIOLIB_ERR_NONE) if (err != RADIOLIB_ERR_NONE)
RECORD_CRITICALERROR(CriticalErrorCode_INVALID_RADIO_SETTING); RECORD_CRITICALERROR(meshtastic_CriticalErrorCode_INVALID_RADIO_SETTING);
err = lora->setSyncWord(syncWord); err = lora->setSyncWord(syncWord);
assert(err == RADIOLIB_ERR_NONE); assert(err == RADIOLIB_ERR_NONE);
@@ -125,14 +125,14 @@ bool RF95Interface::reconfigure()
err = lora->setFrequency(getFreq()); err = lora->setFrequency(getFreq());
if (err != RADIOLIB_ERR_NONE) if (err != RADIOLIB_ERR_NONE)
RECORD_CRITICALERROR(CriticalErrorCode_INVALID_RADIO_SETTING); RECORD_CRITICALERROR(meshtastic_CriticalErrorCode_INVALID_RADIO_SETTING);
if (power > MAX_POWER) // This chip has lower power limits than some if (power > MAX_POWER) // This chip has lower power limits than some
power = MAX_POWER; power = MAX_POWER;
err = lora->setOutputPower(power); err = lora->setOutputPower(power);
if (err != RADIOLIB_ERR_NONE) if (err != RADIOLIB_ERR_NONE)
RECORD_CRITICALERROR(CriticalErrorCode_INVALID_RADIO_SETTING); RECORD_CRITICALERROR(meshtastic_CriticalErrorCode_INVALID_RADIO_SETTING);
startReceive(); // restart receiving startReceive(); // restart receiving
@@ -142,11 +142,10 @@ bool RF95Interface::reconfigure()
/** /**
* Add SNR data to received messages * Add SNR data to received messages
*/ */
void RF95Interface::addReceiveMetadata(MeshPacket *mp) void RF95Interface::addReceiveMetadata(meshtastic_MeshPacket *mp)
{ {
mp->rx_snr = lora->getSNR(); mp->rx_snr = lora->getSNR();
mp->rx_rssi = lround(lora->getRSSI()); mp->rx_rssi = lround(lora->getRSSI());
} }
void RF95Interface::setStandby() void RF95Interface::setStandby()
+1 -1
View File
@@ -55,7 +55,7 @@ class RF95Interface : public RadioLibInterface
/** /**
* Add SNR data to received messages * Add SNR data to received messages
*/ */
virtual void addReceiveMetadata(MeshPacket *mp) override; virtual void addReceiveMetadata(meshtastic_MeshPacket *mp) override;
virtual void setStandby() override; virtual void setStandby() override;
+28 -27
View File
@@ -13,7 +13,7 @@
#define RDEF(name, freq_start, freq_end, duty_cycle, spacing, power_limit, audio_permitted, frequency_switching, wide_lora) \ #define RDEF(name, freq_start, freq_end, duty_cycle, spacing, power_limit, audio_permitted, frequency_switching, wide_lora) \
{ \ { \
Config_LoRaConfig_RegionCode_##name, freq_start, freq_end, duty_cycle, spacing, power_limit, audio_permitted, \ meshtastic_Config_LoRaConfig_RegionCode_##name, freq_start, freq_end, duty_cycle, spacing, power_limit, audio_permitted, \
frequency_switching, wide_lora, #name \ frequency_switching, wide_lora, #name \
} }
@@ -38,9 +38,9 @@ const RegionInfo regions[] = {
Special Note: Special Note:
The link above describes LoRaWAN's band plan, stating a power limit of 16 dBm. This is their own suggested specification, The link above describes LoRaWAN's band plan, stating a power limit of 16 dBm. This is their own suggested specification,
we do not need to follow it. The European Union regulations clearly state that the power limit for this frequency range is 500 mW, or 27 dBm. we do not need to follow it. The European Union regulations clearly state that the power limit for this frequency range is
It also states that we can use interference avoidance and spectrum access techniques to avoid a duty cycle. 500 mW, or 27 dBm. It also states that we can use interference avoidance and spectrum access techniques to avoid a duty
(Please refer to section 4.21 in the following document) cycle. (Please refer to section 4.21 in the following document)
https://ec.europa.eu/growth/tools-databases/tris/index.cfm/ro/search/?trisaction=search.detail&year=2021&num=528&dLang=EN https://ec.europa.eu/growth/tools-databases/tris/index.cfm/ro/search/?trisaction=search.detail&year=2021&num=528&dLang=EN
*/ */
RDEF(EU_868, 869.4f, 869.65f, 10, 0, 27, false, false, false), RDEF(EU_868, 869.4f, 869.65f, 10, 0, 27, false, false, false),
@@ -127,7 +127,7 @@ static uint8_t bytes[MAX_RHPACKETLEN];
void initRegion() void initRegion()
{ {
const RegionInfo *r = regions; const RegionInfo *r = regions;
for (; r->code != Config_LoRaConfig_RegionCode_UNSET && r->code != config.lora.region; r++) for (; r->code != meshtastic_Config_LoRaConfig_RegionCode_UNSET && r->code != config.lora.region; r++)
; ;
myRegion = r; myRegion = r;
LOG_INFO("Wanted region %d, using %s\n", config.lora.region, r->name); LOG_INFO("Wanted region %d, using %s\n", config.lora.region, r->name);
@@ -175,22 +175,22 @@ uint32_t RadioInterface::getPacketTime(uint32_t pl)
return msecs; return msecs;
} }
uint32_t RadioInterface::getPacketTime(MeshPacket *p) uint32_t RadioInterface::getPacketTime(meshtastic_MeshPacket *p)
{ {
uint32_t pl = 0; uint32_t pl = 0;
if(p->which_payload_variant == MeshPacket_encrypted_tag) { if (p->which_payload_variant == meshtastic_MeshPacket_encrypted_tag) {
pl = p->encrypted.size + sizeof(PacketHeader); pl = p->encrypted.size + sizeof(PacketHeader);
} else { } else {
size_t numbytes = pb_encode_to_bytes(bytes, sizeof(bytes), &Data_msg, &p->decoded); size_t numbytes = pb_encode_to_bytes(bytes, sizeof(bytes), &meshtastic_Data_msg, &p->decoded);
pl = numbytes + sizeof(PacketHeader); pl = numbytes + sizeof(PacketHeader);
} }
return getPacketTime(pl); return getPacketTime(pl);
} }
/** The delay to use for retransmitting dropped packets */ /** The delay to use for retransmitting dropped packets */
uint32_t RadioInterface::getRetransmissionMsec(const MeshPacket *p) uint32_t RadioInterface::getRetransmissionMsec(const meshtastic_MeshPacket *p)
{ {
size_t numbytes = pb_encode_to_bytes(bytes, sizeof(bytes), &Data_msg, &p->decoded); size_t numbytes = pb_encode_to_bytes(bytes, sizeof(bytes), &meshtastic_Data_msg, &p->decoded);
uint32_t packetAirtime = getPacketTime(numbytes + sizeof(PacketHeader)); uint32_t packetAirtime = getPacketTime(numbytes + sizeof(PacketHeader));
// Make sure enough time has elapsed for this packet to be sent and an ACK is received. // Make sure enough time has elapsed for this packet to be sent and an ACK is received.
// LOG_DEBUG("Waiting for flooding message with airtime %d and slotTime is %d\n", packetAirtime, slotTimeMsec); // LOG_DEBUG("Waiting for flooding message with airtime %d and slotTime is %d\n", packetAirtime, slotTimeMsec);
@@ -226,8 +226,8 @@ uint32_t RadioInterface::getTxDelayMsecWeighted(float snr)
uint32_t delay = 0; uint32_t delay = 0;
uint8_t CWsize = map(snr, SNR_MIN, SNR_MAX, CWmin, CWmax); uint8_t CWsize = map(snr, SNR_MIN, SNR_MAX, CWmin, CWmax);
// LOG_DEBUG("rx_snr of %f so setting CWsize to:%d\n", snr, CWsize); // LOG_DEBUG("rx_snr of %f so setting CWsize to:%d\n", snr, CWsize);
if (config.device.role == Config_DeviceConfig_Role_ROUTER || if (config.device.role == meshtastic_Config_DeviceConfig_Role_ROUTER ||
config.device.role == Config_DeviceConfig_Role_ROUTER_CLIENT) { config.device.role == meshtastic_Config_DeviceConfig_Role_ROUTER_CLIENT) {
delay = random(0, 2 * CWsize) * slotTimeMsec; delay = random(0, 2 * CWsize) * slotTimeMsec;
LOG_DEBUG("rx_snr found in packet. As a router, setting tx delay:%d\n", delay); LOG_DEBUG("rx_snr found in packet. As a router, setting tx delay:%d\n", delay);
} else { } else {
@@ -238,11 +238,11 @@ uint32_t RadioInterface::getTxDelayMsecWeighted(float snr)
return delay; return delay;
} }
void printPacket(const char *prefix, const MeshPacket *p) void printPacket(const char *prefix, const meshtastic_MeshPacket *p)
{ {
LOG_DEBUG("%s (id=0x%08x fr=0x%02x to=0x%02x, WantAck=%d, HopLim=%d Ch=0x%x", prefix, p->id, p->from & 0xff, p->to & 0xff, LOG_DEBUG("%s (id=0x%08x fr=0x%02x to=0x%02x, WantAck=%d, HopLim=%d Ch=0x%x", prefix, p->id, p->from & 0xff, p->to & 0xff,
p->want_ack, p->hop_limit, p->channel); p->want_ack, p->hop_limit, p->channel);
if (p->which_payload_variant == MeshPacket_decoded_tag) { if (p->which_payload_variant == meshtastic_MeshPacket_decoded_tag) {
auto &s = p->decoded; auto &s = p->decoded;
LOG_DEBUG(" Portnum=%d", s.portnum); LOG_DEBUG(" Portnum=%d", s.portnum);
@@ -372,26 +372,26 @@ void RadioInterface::applyModemConfig()
{ {
// Set up default configuration // Set up default configuration
// No Sync Words in LORA mode // No Sync Words in LORA mode
Config_LoRaConfig &loraConfig = config.lora; meshtastic_Config_LoRaConfig &loraConfig = config.lora;
if (loraConfig.use_preset) { if (loraConfig.use_preset) {
switch (loraConfig.modem_preset) { switch (loraConfig.modem_preset) {
case Config_LoRaConfig_ModemPreset_SHORT_FAST: case meshtastic_Config_LoRaConfig_ModemPreset_SHORT_FAST:
bw = (myRegion->wideLora) ? 812.5 : 250; bw = (myRegion->wideLora) ? 812.5 : 250;
cr = 8; cr = 8;
sf = 7; sf = 7;
break; break;
case Config_LoRaConfig_ModemPreset_SHORT_SLOW: case meshtastic_Config_LoRaConfig_ModemPreset_SHORT_SLOW:
bw = (myRegion->wideLora) ? 812.5 : 250; bw = (myRegion->wideLora) ? 812.5 : 250;
cr = 8; cr = 8;
sf = 8; sf = 8;
break; break;
case Config_LoRaConfig_ModemPreset_MEDIUM_FAST: case meshtastic_Config_LoRaConfig_ModemPreset_MEDIUM_FAST:
bw = (myRegion->wideLora) ? 812.5 : 250; bw = (myRegion->wideLora) ? 812.5 : 250;
cr = 8; cr = 8;
sf = 9; sf = 9;
break; break;
case Config_LoRaConfig_ModemPreset_MEDIUM_SLOW: case meshtastic_Config_LoRaConfig_ModemPreset_MEDIUM_SLOW:
bw = (myRegion->wideLora) ? 812.5 : 250; bw = (myRegion->wideLora) ? 812.5 : 250;
cr = 8; cr = 8;
sf = 10; sf = 10;
@@ -401,12 +401,12 @@ void RadioInterface::applyModemConfig()
cr = 8; cr = 8;
sf = 11; sf = 11;
break; break;
case Config_LoRaConfig_ModemPreset_LONG_SLOW: case meshtastic_Config_LoRaConfig_ModemPreset_LONG_SLOW:
bw = (myRegion->wideLora) ? 406.25 : 125; bw = (myRegion->wideLora) ? 406.25 : 125;
cr = 8; cr = 8;
sf = 12; sf = 12;
break; break;
case Config_LoRaConfig_ModemPreset_VERY_LONG_SLOW: case meshtastic_Config_LoRaConfig_ModemPreset_VERY_LONG_SLOW:
bw = (myRegion->wideLora) ? 203.125 : 31.25; bw = (myRegion->wideLora) ? 203.125 : 31.25;
cr = 8; cr = 8;
sf = 12; sf = 12;
@@ -459,8 +459,10 @@ void RadioInterface::applyModemConfig()
saveFreq(freq + config.lora.frequency_offset); saveFreq(freq + config.lora.frequency_offset);
LOG_INFO("Radio freq=%.3f, config.lora.frequency_offset=%.3f\n", freq, config.lora.frequency_offset); LOG_INFO("Radio freq=%.3f, config.lora.frequency_offset=%.3f\n", freq, config.lora.frequency_offset);
LOG_INFO("Set radio: region=%s, name=%s, config=%u, ch=%d, power=%d\n", myRegion->name, channelName, loraConfig.modem_preset, channel_num, power); LOG_INFO("Set radio: region=%s, name=%s, config=%u, ch=%d, power=%d\n", myRegion->name, channelName, loraConfig.modem_preset,
LOG_INFO("Radio myRegion->freqStart -> myRegion->freqEnd: %f -> %f (%f mhz)\n", myRegion->freqStart, myRegion->freqEnd, myRegion->freqEnd - myRegion->freqStart); channel_num, power);
LOG_INFO("Radio myRegion->freqStart -> myRegion->freqEnd: %f -> %f (%f mhz)\n", myRegion->freqStart, myRegion->freqEnd,
myRegion->freqEnd - myRegion->freqStart);
LOG_INFO("Radio myRegion->numChannels: %d x %.3fkHz\n", numChannels, bw); LOG_INFO("Radio myRegion->numChannels: %d x %.3fkHz\n", numChannels, bw);
LOG_INFO("Radio channel_num: %d\n", channel_num); LOG_INFO("Radio channel_num: %d\n", channel_num);
LOG_INFO("Radio frequency: %f\n", getFreq()); LOG_INFO("Radio frequency: %f\n", getFreq());
@@ -486,8 +488,7 @@ void RadioInterface::limitPower()
LOG_INFO("Set radio: final power level=%d\n", power); LOG_INFO("Set radio: final power level=%d\n", power);
} }
void RadioInterface::deliverToReceiver(meshtastic_MeshPacket *p)
void RadioInterface::deliverToReceiver(MeshPacket *p)
{ {
if (router) if (router)
router->enqueueReceivedMessage(p); router->enqueueReceivedMessage(p);
@@ -496,12 +497,12 @@ void RadioInterface::deliverToReceiver(MeshPacket *p)
/*** /***
* given a packet set sendingPacket and decode the protobufs into radiobuf. Returns # of payload bytes to send * given a packet set sendingPacket and decode the protobufs into radiobuf. Returns # of payload bytes to send
*/ */
size_t RadioInterface::beginSending(MeshPacket *p) size_t RadioInterface::beginSending(meshtastic_MeshPacket *p)
{ {
assert(!sendingPacket); assert(!sendingPacket);
// LOG_DEBUG("sending queued packet on mesh (txGood=%d,rxGood=%d,rxBad=%d)\n", rf95.txGood(), rf95.rxGood(), rf95.rxBad()); // LOG_DEBUG("sending queued packet on mesh (txGood=%d,rxGood=%d,rxBad=%d)\n", rf95.txGood(), rf95.rxGood(), rf95.rxBad());
assert(p->which_payload_variant == MeshPacket_encrypted_tag); // It should have already been encoded by now assert(p->which_payload_variant == meshtastic_MeshPacket_encrypted_tag); // It should have already been encoded by now
lastTxStart = millis(); lastTxStart = millis();

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