mirror of
https://github.com/meshtastic/firmware.git
synced 2025-12-15 23:32:34 +00:00
Compare commits
20 Commits
v2.1.15.cd
...
v2.1.17.7c
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
7ca2e818df | ||
|
|
f02923435b | ||
|
|
eb0a96a79e | ||
|
|
9e2b86b92c | ||
|
|
d0cf70c8b3 | ||
|
|
44a906dd01 | ||
|
|
ccb682bbb8 | ||
|
|
e677a02273 | ||
|
|
47168d5063 | ||
|
|
5591b9b9f5 | ||
|
|
a2c5b92840 | ||
|
|
685d27f566 | ||
|
|
f71869215d | ||
|
|
81f80546b4 | ||
|
|
44a54278b3 | ||
|
|
194833d77f | ||
|
|
207d421fca | ||
|
|
fb14487f2f | ||
|
|
365a91f3d9 | ||
|
|
5edc872c31 |
2
.github/ISSUE_TEMPLATE/Bug Report.yml
vendored
2
.github/ISSUE_TEMPLATE/Bug Report.yml
vendored
@@ -40,10 +40,12 @@ body:
|
||||
- T-Echo
|
||||
- Rak4631
|
||||
- Rak11200
|
||||
- Rak11310
|
||||
- Heltec v1
|
||||
- Heltec v2
|
||||
- Heltec v2.1
|
||||
- Heltec V3
|
||||
- Raspberry Pi Pico (W)
|
||||
- Relay v1
|
||||
- Relay v2
|
||||
- DIY
|
||||
|
||||
5
.github/pull_request_template.md
vendored
5
.github/pull_request_template.md
vendored
@@ -7,7 +7,8 @@
|
||||
is appreciated." This will allow other devs to potentially save you time by not accidentially duplicating work etc...
|
||||
- Please do not check in files that don't have real changes
|
||||
- Please do not reformat lines that you didn't have to change the code on
|
||||
- We recommend using the [Visual Studio Code](https://platformio.org/install/ide?install=vscode) editor and the 'clang-format' extension,
|
||||
because automatically follows our indentation rules and it's auto reformatting will not cause spurious changes to lines.
|
||||
- We recommend using the [Visual Studio Code](https://platformio.org/install/ide?install=vscode) editor along with the ['Trunk Check' extension](https://marketplace.visualstudio.com/items?itemName=trunk.io) (WSL2 is required on windows),
|
||||
because it automatically follows our indentation rules and its auto reformatting will not cause spurious changes to lines.
|
||||
- If your PR fixes a bug, mention "fixes #bugnum" somewhere in your pull request description.
|
||||
- If your other co-developers have comments on your PR please tweak as needed.
|
||||
- Please also enable "Allow edits by maintainers".
|
||||
|
||||
4
.github/workflows/main_matrix.yml
vendored
4
.github/workflows/main_matrix.yml
vendored
@@ -150,12 +150,14 @@ jobs:
|
||||
release/device-*.bat
|
||||
|
||||
- name: Docker login
|
||||
if: ${{ github.event_name != 'pull_request_target' && github.event_name != 'pull_request' }}
|
||||
uses: docker/login-action@v2
|
||||
with:
|
||||
username: meshtastic
|
||||
password: ${{ secrets.DOCKER_TOKEN }}
|
||||
|
||||
- name: Docker setup
|
||||
if: ${{ github.event_name != 'pull_request_target' && github.event_name != 'pull_request' }}
|
||||
uses: docker/setup-buildx-action@v2
|
||||
|
||||
- name: Docker build and push tagged versions
|
||||
@@ -168,7 +170,7 @@ jobs:
|
||||
tags: meshtastic/device-simulator:${{ steps.version.outputs.version }}
|
||||
|
||||
- name: Docker build and push
|
||||
if: github.ref == 'refs/heads/master'
|
||||
if: ${{ github.ref == 'refs/heads/master' && github.event_name != 'pull_request_target' && github.event_name != 'pull_request' }}
|
||||
uses: docker/build-push-action@v3
|
||||
with:
|
||||
context: .
|
||||
|
||||
@@ -37,7 +37,7 @@ lib_deps =
|
||||
${environmental_base.lib_deps}
|
||||
https://github.com/meshtastic/esp32_https_server.git#23665b3adc080a311dcbb586ed5941b5f94d6ea2
|
||||
h2zero/NimBLE-Arduino@^1.4.0
|
||||
jgromes/RadioLib@^6.0.0
|
||||
jgromes/RadioLib@^6.1.0
|
||||
https://github.com/lewisxhe/XPowersLib.git#84b7373faea3118b6c37954d52f98b8a337148d6
|
||||
https://github.com/meshtastic/ESP32_Codec2.git#633326c78ac251c059ab3a8c430fcdf25b41672f
|
||||
|
||||
@@ -55,4 +55,4 @@ lib_ignore =
|
||||
|
||||
; customize the partition table
|
||||
; http://docs.platformio.org/en/latest/platforms/espressif32.html#partition-tables
|
||||
board_build.partitions = partition-table.csv
|
||||
board_build.partitions = partition-table.csv
|
||||
@@ -13,8 +13,7 @@ build_src_filter =
|
||||
|
||||
lib_deps=
|
||||
${arduino_base.lib_deps}
|
||||
jgromes/RadioLib@^6.0.0
|
||||
jgromes/RadioLib@^6.1.0
|
||||
|
||||
lib_ignore =
|
||||
BluetoothOTA
|
||||
|
||||
BluetoothOTA
|
||||
@@ -22,7 +22,7 @@ lib_deps =
|
||||
${env.lib_deps}
|
||||
${networking_base.lib_deps}
|
||||
rweather/Crypto@^0.4.0
|
||||
jgromes/RadioLib@^6.0.0
|
||||
jgromes/RadioLib@6.1.0
|
||||
|
||||
build_flags =
|
||||
${arduino_base.build_flags}
|
||||
|
||||
@@ -2,7 +2,7 @@
|
||||
[rp2040_base]
|
||||
platform = https://github.com/maxgerhardt/platform-raspberrypi.git#0c33219f53faa035e188925ea1324f472e8b93d2
|
||||
extends = arduino_base
|
||||
platform_packages = framework-arduinopico@https://github.com/earlephilhower/arduino-pico.git#3.2.1
|
||||
platform_packages = framework-arduinopico@https://github.com/earlephilhower/arduino-pico.git#3.2.2
|
||||
|
||||
board_build.core = earlephilhower
|
||||
board_build.filesystem_size = 0.5m
|
||||
@@ -20,5 +20,5 @@ lib_ignore =
|
||||
lib_deps =
|
||||
${arduino_base.lib_deps}
|
||||
${environmental_base.lib_deps}
|
||||
jgromes/RadioLib@^6.0.0
|
||||
jgromes/RadioLib@^6.1.0
|
||||
https://github.com/kokke/tiny-AES-c.git#f06ac37fc31dfdaca2e0d9bec83f90d5663c319b
|
||||
@@ -20,10 +20,10 @@ upload_protocol = stlink
|
||||
|
||||
lib_deps =
|
||||
${env.lib_deps}
|
||||
jgromes/RadioLib@^6.0.0
|
||||
jgromes/RadioLib@^6.1.0
|
||||
https://github.com/kokke/tiny-AES-c.git#f06ac37fc31dfdaca2e0d9bec83f90d5663c319b
|
||||
https://github.com/littlefs-project/littlefs.git#v2.5.1
|
||||
https://github.com/stm32duino/STM32FreeRTOS.git#10.3.1
|
||||
|
||||
lib_ignore =
|
||||
https://github.com/mathertel/OneButton#2.1.0
|
||||
https://github.com/mathertel/OneButton#2.1.0
|
||||
@@ -56,6 +56,12 @@ build_flags = -Wno-missing-field-initializers
|
||||
-DRADIOLIB_EXCLUDE_MORSE
|
||||
-DRADIOLIB_EXCLUDE_RTTY
|
||||
-DRADIOLIB_EXCLUDE_SSTV
|
||||
-DRADIOLIB_EXCLUDE_AX25
|
||||
-DRADIOLIB_EXCLUDE_DIRECT_RECEIVE
|
||||
-DRADIOLIB_EXCLUDE_BELL
|
||||
-DRADIOLIB_EXCLUDE_PAGER
|
||||
-DRADIOLIB_EXCLUDE_FSK4
|
||||
-DRADIOLIB_EXCLUDE_APRS
|
||||
|
||||
monitor_speed = 115200
|
||||
|
||||
|
||||
Submodule protobufs updated: 8d17bb2452...e4396fd499
@@ -157,7 +157,7 @@ class ButtonThread : public concurrency::OSThread
|
||||
digitalWrite(PIN_EINK_EN, digitalRead(PIN_EINK_EN) == LOW);
|
||||
#endif
|
||||
screen->print("Sent ad-hoc ping\n");
|
||||
service.refreshMyNodeInfo();
|
||||
service.refreshLocalMeshNode();
|
||||
service.sendNetworkPing(NODENUM_BROADCAST, true);
|
||||
}
|
||||
|
||||
@@ -196,4 +196,4 @@ class ButtonThread : public concurrency::OSThread
|
||||
}
|
||||
};
|
||||
|
||||
} // namespace concurrency
|
||||
} // namespace concurrency
|
||||
@@ -55,7 +55,7 @@ class GPSStatus : public Status
|
||||
#ifdef GPS_EXTRAVERBOSE
|
||||
LOG_WARN("Using fixed latitude\n");
|
||||
#endif
|
||||
meshtastic_NodeInfo *node = nodeDB.getNode(nodeDB.getNodeNum());
|
||||
meshtastic_NodeInfoLite *node = nodeDB.getMeshNode(nodeDB.getNodeNum());
|
||||
return node->position.latitude_i;
|
||||
} else {
|
||||
return p.latitude_i;
|
||||
@@ -68,7 +68,7 @@ class GPSStatus : public Status
|
||||
#ifdef GPS_EXTRAVERBOSE
|
||||
LOG_WARN("Using fixed longitude\n");
|
||||
#endif
|
||||
meshtastic_NodeInfo *node = nodeDB.getNode(nodeDB.getNodeNum());
|
||||
meshtastic_NodeInfoLite *node = nodeDB.getMeshNode(nodeDB.getNodeNum());
|
||||
return node->position.longitude_i;
|
||||
} else {
|
||||
return p.longitude_i;
|
||||
@@ -81,7 +81,7 @@ class GPSStatus : public Status
|
||||
#ifdef GPS_EXTRAVERBOSE
|
||||
LOG_WARN("Using fixed altitude\n");
|
||||
#endif
|
||||
meshtastic_NodeInfo *node = nodeDB.getNode(nodeDB.getNodeNum());
|
||||
meshtastic_NodeInfoLite *node = nodeDB.getMeshNode(nodeDB.getNodeNum());
|
||||
return node->position.altitude;
|
||||
} else {
|
||||
return p.altitude;
|
||||
@@ -149,4 +149,4 @@ class GPSStatus : public Status
|
||||
|
||||
} // namespace meshtastic
|
||||
|
||||
extern meshtastic::GPSStatus *gpsStatus;
|
||||
extern meshtastic::GPSStatus *gpsStatus;
|
||||
@@ -6,20 +6,22 @@ AirTime *airTime = NULL;
|
||||
|
||||
// Don't read out of this directly. Use the helper functions.
|
||||
|
||||
uint32_t air_period_tx[PERIODS_TO_LOG];
|
||||
uint32_t air_period_rx[PERIODS_TO_LOG];
|
||||
|
||||
void AirTime::logAirtime(reportTypes reportType, uint32_t airtime_ms)
|
||||
{
|
||||
|
||||
if (reportType == TX_LOG) {
|
||||
LOG_DEBUG("AirTime - Packet transmitted : %ums\n", airtime_ms);
|
||||
this->airtimes.periodTX[0] = this->airtimes.periodTX[0] + airtime_ms;
|
||||
myNodeInfo.air_period_tx[0] = myNodeInfo.air_period_tx[0] + airtime_ms;
|
||||
air_period_tx[0] = air_period_tx[0] + airtime_ms;
|
||||
|
||||
this->utilizationTX[this->getPeriodUtilHour()] = this->utilizationTX[this->getPeriodUtilHour()] + airtime_ms;
|
||||
|
||||
} else if (reportType == RX_LOG) {
|
||||
LOG_DEBUG("AirTime - Packet received : %ums\n", airtime_ms);
|
||||
this->airtimes.periodRX[0] = this->airtimes.periodRX[0] + airtime_ms;
|
||||
myNodeInfo.air_period_rx[0] = myNodeInfo.air_period_rx[0] + airtime_ms;
|
||||
air_period_rx[0] = air_period_rx[0] + airtime_ms;
|
||||
} else if (reportType == RX_ALL_LOG) {
|
||||
LOG_DEBUG("AirTime - Packet received (noise?) : %ums\n", airtime_ms);
|
||||
this->airtimes.periodRX_ALL[0] = this->airtimes.periodRX_ALL[0] + airtime_ms;
|
||||
@@ -55,16 +57,16 @@ void AirTime::airtimeRotatePeriod()
|
||||
this->airtimes.periodRX[i + 1] = this->airtimes.periodRX[i];
|
||||
this->airtimes.periodRX_ALL[i + 1] = this->airtimes.periodRX_ALL[i];
|
||||
|
||||
myNodeInfo.air_period_tx[i + 1] = this->airtimes.periodTX[i];
|
||||
myNodeInfo.air_period_rx[i + 1] = this->airtimes.periodRX[i];
|
||||
air_period_tx[i + 1] = this->airtimes.periodTX[i];
|
||||
air_period_rx[i + 1] = this->airtimes.periodRX[i];
|
||||
}
|
||||
|
||||
this->airtimes.periodTX[0] = 0;
|
||||
this->airtimes.periodRX[0] = 0;
|
||||
this->airtimes.periodRX_ALL[0] = 0;
|
||||
|
||||
myNodeInfo.air_period_tx[0] = 0;
|
||||
myNodeInfo.air_period_rx[0] = 0;
|
||||
air_period_tx[0] = 0;
|
||||
air_period_rx[0] = 0;
|
||||
|
||||
this->airtimes.lastPeriodIndex = this->currentPeriodIndex();
|
||||
}
|
||||
@@ -179,18 +181,17 @@ int32_t AirTime::runOnce()
|
||||
}
|
||||
|
||||
// Init airtime windows to all 0
|
||||
for (int i = 0; i < myNodeInfo.air_period_rx_count; i++) {
|
||||
for (int i = 0; i < PERIODS_TO_LOG; i++) {
|
||||
this->airtimes.periodTX[i] = 0;
|
||||
this->airtimes.periodRX[i] = 0;
|
||||
this->airtimes.periodRX_ALL[i] = 0;
|
||||
|
||||
// myNodeInfo.air_period_tx[i] = 0;
|
||||
// myNodeInfo.air_period_rx[i] = 0;
|
||||
// air_period_tx[i] = 0;
|
||||
// air_period_rx[i] = 0;
|
||||
}
|
||||
|
||||
firstTime = false;
|
||||
lastUtilPeriod = utilPeriod;
|
||||
|
||||
} else {
|
||||
this->airtimeRotatePeriod();
|
||||
|
||||
@@ -206,12 +207,6 @@ int32_t AirTime::runOnce()
|
||||
|
||||
this->utilizationTX[utilPeriodTX] = 0;
|
||||
}
|
||||
|
||||
// Update channel_utilization every second.
|
||||
myNodeInfo.channel_utilization = airTime->channelUtilizationPercent();
|
||||
|
||||
// Update channel_utilization every second.
|
||||
myNodeInfo.air_util_tx = airTime->utilizationTXPercent();
|
||||
}
|
||||
/*
|
||||
LOG_DEBUG("utilPeriodTX %d TX Airtime %3.2f%\n", utilPeriodTX, airTime->utilizationTXPercent());
|
||||
@@ -223,4 +218,4 @@ int32_t AirTime::runOnce()
|
||||
LOG_DEBUG("\n");
|
||||
*/
|
||||
return (1000 * 1);
|
||||
}
|
||||
}
|
||||
@@ -9,4 +9,4 @@
|
||||
|
||||
/// Record an error that should be reported via analytics
|
||||
void recordCriticalError(meshtastic_CriticalErrorCode code = meshtastic_CriticalErrorCode_UNSPECIFIED, uint32_t address = 0,
|
||||
const char *filename = NULL);
|
||||
const char *filename = NULL);
|
||||
@@ -12,7 +12,7 @@
|
||||
#include <freertos/task.h>
|
||||
#endif
|
||||
|
||||
#if defined(ARDUINO_NRF52_ADAFRUIT) || defined(ARDUINO_ARCH_STM32)
|
||||
#if defined(ARDUINO_NRF52_ADAFRUIT) || defined(ARDUINO_ARCH_STM32) || defined(ARDUINO_ARCH_RP2040)
|
||||
#define HAS_FREE_RTOS
|
||||
|
||||
#include <FreeRTOS.h>
|
||||
@@ -44,4 +44,4 @@ typedef uint32_t BaseType_t;
|
||||
|
||||
enum eNotifyAction { eNoAction, eSetValueWithoutOverwrite, eSetValueWithOverwrite };
|
||||
|
||||
#endif
|
||||
#endif
|
||||
@@ -18,7 +18,7 @@
|
||||
* -------------------------------------------
|
||||
*/
|
||||
|
||||
uint32_t printWPL(char *buf, size_t bufsz, const meshtastic_Position &pos, const char *name, bool isCaltopoMode)
|
||||
uint32_t printWPL(char *buf, size_t bufsz, const meshtastic_PositionLite &pos, const char *name, bool isCaltopoMode)
|
||||
{
|
||||
GeoCoord geoCoord(pos.latitude_i, pos.longitude_i, pos.altitude);
|
||||
char type = isCaltopoMode ? 'P' : 'N';
|
||||
@@ -34,6 +34,21 @@ uint32_t printWPL(char *buf, size_t bufsz, const meshtastic_Position &pos, const
|
||||
return len;
|
||||
}
|
||||
|
||||
uint32_t printWPL(char *buf, size_t bufsz, const meshtastic_Position &pos, const char *name, bool isCaltopoMode)
|
||||
{
|
||||
GeoCoord geoCoord(pos.latitude_i, pos.longitude_i, pos.altitude);
|
||||
char type = isCaltopoMode ? 'P' : 'N';
|
||||
uint32_t len = snprintf(buf, bufsz, "$G%cWPL,%02d%07.4f,%c,%03d%07.4f,%c,%s", type, geoCoord.getDMSLatDeg(),
|
||||
(abs(geoCoord.getLatitude()) - geoCoord.getDMSLatDeg() * 1e+7) * 6e-6, geoCoord.getDMSLatCP(),
|
||||
geoCoord.getDMSLonDeg(), (abs(geoCoord.getLongitude()) - geoCoord.getDMSLonDeg() * 1e+7) * 6e-6,
|
||||
geoCoord.getDMSLonCP(), name);
|
||||
uint32_t chk = 0;
|
||||
for (uint32_t i = 1; i < len; i++) {
|
||||
chk ^= buf[i];
|
||||
}
|
||||
len += snprintf(buf + len, bufsz - len, "*%02X\r\n", chk);
|
||||
return len;
|
||||
}
|
||||
/* -------------------------------------------
|
||||
* 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15
|
||||
* | | | | | | | | | | | | | | |
|
||||
|
||||
@@ -4,4 +4,5 @@
|
||||
#include <Arduino.h>
|
||||
|
||||
uint32_t printWPL(char *buf, size_t bufsz, const meshtastic_Position &pos, const char *name, bool isCaltopoMode = false);
|
||||
uint32_t printGGA(char *buf, size_t bufsz, const meshtastic_Position &pos);
|
||||
uint32_t printWPL(char *buf, size_t bufsz, const meshtastic_PositionLite &pos, const char *name, bool isCaltopoMode = false);
|
||||
uint32_t printGGA(char *buf, size_t bufsz, const meshtastic_Position &pos);
|
||||
7
src/graphics/RAKled.h
Normal file
7
src/graphics/RAKled.h
Normal file
@@ -0,0 +1,7 @@
|
||||
#include "main.h"
|
||||
|
||||
#ifdef RAK4630
|
||||
#include <NCP5623.h>
|
||||
extern NCP5623 rgb;
|
||||
|
||||
#endif
|
||||
@@ -27,6 +27,7 @@ along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
#include "GPS.h"
|
||||
#include "MeshService.h"
|
||||
#include "NodeDB.h"
|
||||
#include "error.h"
|
||||
#include "gps/GeoCoord.h"
|
||||
#include "gps/RTC.h"
|
||||
#include "graphics/images.h"
|
||||
@@ -352,7 +353,7 @@ static void drawCriticalFaultFrame(OLEDDisplay *display, OLEDDisplayUiState *sta
|
||||
display->setFont(FONT_MEDIUM);
|
||||
|
||||
char tempBuf[24];
|
||||
snprintf(tempBuf, sizeof(tempBuf), "Critical fault #%d", myNodeInfo.error_code);
|
||||
snprintf(tempBuf, sizeof(tempBuf), "Critical fault #%d", error_code);
|
||||
display->drawString(0 + x, 0 + y, tempBuf);
|
||||
display->setTextAlignment(TEXT_ALIGN_LEFT);
|
||||
display->setFont(FONT_SMALL);
|
||||
@@ -372,7 +373,7 @@ static void drawTextMessageFrame(OLEDDisplay *display, OLEDDisplayUiState *state
|
||||
static char tempBuf[237];
|
||||
|
||||
meshtastic_MeshPacket &mp = devicestate.rx_text_message;
|
||||
meshtastic_NodeInfo *node = nodeDB.getNode(getFrom(&mp));
|
||||
meshtastic_NodeInfoLite *node = nodeDB.getMeshNode(getFrom(&mp));
|
||||
// LOG_DEBUG("drawing text message from 0x%x: %s\n", mp.from,
|
||||
// mp.decoded.variant.data.decoded.bytes);
|
||||
|
||||
@@ -410,7 +411,7 @@ static void drawWaypointFrame(OLEDDisplay *display, OLEDDisplayUiState *state, i
|
||||
static char tempBuf[237];
|
||||
|
||||
meshtastic_MeshPacket &mp = devicestate.rx_waypoint;
|
||||
meshtastic_NodeInfo *node = nodeDB.getNode(getFrom(&mp));
|
||||
meshtastic_NodeInfoLite *node = nodeDB.getMeshNode(getFrom(&mp));
|
||||
|
||||
display->setTextAlignment(TEXT_ALIGN_LEFT);
|
||||
display->setFont(FONT_SMALL);
|
||||
@@ -792,16 +793,16 @@ static void drawNodeInfo(OLEDDisplay *display, OLEDDisplayUiState *state, int16_
|
||||
if (state->currentFrame != prevFrame) {
|
||||
prevFrame = state->currentFrame;
|
||||
|
||||
nodeIndex = (nodeIndex + 1) % nodeDB.getNumNodes();
|
||||
meshtastic_NodeInfo *n = nodeDB.getNodeByIndex(nodeIndex);
|
||||
nodeIndex = (nodeIndex + 1) % nodeDB.getNumMeshNodes();
|
||||
meshtastic_NodeInfoLite *n = nodeDB.getMeshNodeByIndex(nodeIndex);
|
||||
if (n->num == nodeDB.getNodeNum()) {
|
||||
// Don't show our node, just skip to next
|
||||
nodeIndex = (nodeIndex + 1) % nodeDB.getNumNodes();
|
||||
n = nodeDB.getNodeByIndex(nodeIndex);
|
||||
nodeIndex = (nodeIndex + 1) % nodeDB.getNumMeshNodes();
|
||||
n = nodeDB.getMeshNodeByIndex(nodeIndex);
|
||||
}
|
||||
}
|
||||
|
||||
meshtastic_NodeInfo *node = nodeDB.getNodeByIndex(nodeIndex);
|
||||
meshtastic_NodeInfoLite *node = nodeDB.getMeshNodeByIndex(nodeIndex);
|
||||
|
||||
display->setFont(FONT_SMALL);
|
||||
|
||||
@@ -835,7 +836,7 @@ static void drawNodeInfo(OLEDDisplay *display, OLEDDisplayUiState *state, int16_
|
||||
|
||||
static char distStr[20];
|
||||
strncpy(distStr, "? km", sizeof(distStr)); // might not have location data
|
||||
meshtastic_NodeInfo *ourNode = nodeDB.getNode(nodeDB.getNodeNum());
|
||||
meshtastic_NodeInfoLite *ourNode = nodeDB.getMeshNode(nodeDB.getNodeNum());
|
||||
const char *fields[] = {username, distStr, signalStr, lastStr, NULL};
|
||||
int16_t compassX = 0, compassY = 0;
|
||||
|
||||
@@ -850,14 +851,14 @@ static void drawNodeInfo(OLEDDisplay *display, OLEDDisplayUiState *state, int16_
|
||||
bool hasNodeHeading = false;
|
||||
|
||||
if (ourNode && hasValidPosition(ourNode)) {
|
||||
meshtastic_Position &op = ourNode->position;
|
||||
meshtastic_PositionLite &op = ourNode->position;
|
||||
float myHeading = estimatedHeading(DegD(op.latitude_i), DegD(op.longitude_i));
|
||||
drawCompassNorth(display, compassX, compassY, myHeading);
|
||||
|
||||
if (hasValidPosition(node)) {
|
||||
// display direction toward node
|
||||
hasNodeHeading = true;
|
||||
meshtastic_Position &p = node->position;
|
||||
meshtastic_PositionLite &p = node->position;
|
||||
float d =
|
||||
GeoCoord::latLongToMeter(DegD(p.latitude_i), DegD(p.longitude_i), DegD(op.latitude_i), DegD(op.longitude_i));
|
||||
|
||||
@@ -1239,9 +1240,9 @@ void Screen::setFrames()
|
||||
#endif
|
||||
|
||||
// We don't show the node info our our node (if we have it yet - we should)
|
||||
size_t numnodes = nodeDB.getNumNodes();
|
||||
if (numnodes > 0)
|
||||
numnodes--;
|
||||
size_t numMeshNodes = nodeDB.getNumMeshNodes();
|
||||
if (numMeshNodes > 0)
|
||||
numMeshNodes--;
|
||||
|
||||
size_t numframes = 0;
|
||||
|
||||
@@ -1258,7 +1259,7 @@ void Screen::setFrames()
|
||||
LOG_DEBUG("Added modules. numframes: %d\n", numframes);
|
||||
|
||||
// If we have a critical fault, show it first
|
||||
if (myNodeInfo.error_code)
|
||||
if (error_code)
|
||||
normalFrames[numframes++] = drawCriticalFaultFrame;
|
||||
|
||||
// If we have a text message - show it next, unless it's a phone message and we aren't using any special modules
|
||||
@@ -1272,7 +1273,7 @@ void Screen::setFrames()
|
||||
|
||||
// then all the nodes
|
||||
// We only show a few nodes in our scrolling list - because meshes with many nodes would have too many screens
|
||||
size_t numToShow = min(numnodes, 4U);
|
||||
size_t numToShow = min(numMeshNodes, 4U);
|
||||
for (size_t i = 0; i < numToShow; i++)
|
||||
normalFrames[numframes++] = drawNodeInfo;
|
||||
|
||||
@@ -1849,4 +1850,4 @@ int Screen::handleUIFrameEvent(const UIFrameEvent *event)
|
||||
} // namespace graphics
|
||||
#else
|
||||
graphics::Screen::Screen(ScanI2C::DeviceAddress, meshtastic_Config_DisplayConfig_OledType, OLEDDISPLAY_GEOMETRY) {}
|
||||
#endif // HAS_SCREEN
|
||||
#endif // HAS_SCREEN
|
||||
28
src/main.cpp
28
src/main.cpp
@@ -19,6 +19,7 @@
|
||||
#include "detect/ScanI2CTwoWire.h"
|
||||
#include "detect/axpDebug.h"
|
||||
#include "detect/einkScan.h"
|
||||
#include "graphics/RAKled.h"
|
||||
#include "graphics/Screen.h"
|
||||
#include "main.h"
|
||||
#include "mesh/generated/meshtastic/config.pb.h"
|
||||
@@ -263,6 +264,12 @@ void setup()
|
||||
// We need to enable 3.3V periphery in order to scan it
|
||||
pinMode(PIN_3V3_EN, OUTPUT);
|
||||
digitalWrite(PIN_3V3_EN, HIGH);
|
||||
|
||||
#ifndef USE_EINK
|
||||
// RAK-12039 set pin for Air quality sensor
|
||||
pinMode(AQ_SET_PIN, OUTPUT);
|
||||
digitalWrite(AQ_SET_PIN, HIGH);
|
||||
#endif
|
||||
#endif
|
||||
|
||||
// Currently only the tbeam has a PMU
|
||||
@@ -354,6 +361,15 @@ void setup()
|
||||
// Only one supported RGB LED currently
|
||||
rgb_found = i2cScanner->find(ScanI2C::DeviceType::NCP5623);
|
||||
|
||||
// Start the RGB LED at 50%
|
||||
#ifdef RAK4630
|
||||
if (rgb_found.type == ScanI2C::NCP5623) {
|
||||
rgb.begin();
|
||||
rgb.setCurrent(10);
|
||||
rgb.setColor(128, 128, 128);
|
||||
}
|
||||
#endif
|
||||
|
||||
#if !defined(ARCH_PORTDUINO) && !defined(ARCH_STM32WL)
|
||||
auto acc_info = i2cScanner->firstAccelerometer();
|
||||
accelerometer_found = acc_info.type != ScanI2C::DeviceType::NONE ? acc_info.address : accelerometer_found;
|
||||
@@ -667,12 +683,10 @@ void setup()
|
||||
else {
|
||||
router->addInterface(rIf);
|
||||
|
||||
// Calculate and save the bit rate to myNodeInfo
|
||||
// TODO: This needs to be added what ever method changes the channel from the phone.
|
||||
myNodeInfo.bitrate =
|
||||
(float(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 bit rate to debug output
|
||||
LOG_DEBUG("LoRA bitrate = %f bytes / sec\n", (float(meshtastic_Constants_DATA_PAYLOAD_LEN) /
|
||||
(float(rIf->getPacketTime(meshtastic_Constants_DATA_PAYLOAD_LEN)))) *
|
||||
1000);
|
||||
}
|
||||
|
||||
// This must be _after_ service.init because we need our preferences loaded from flash to have proper timeout values
|
||||
@@ -693,7 +707,7 @@ bool runASAP;
|
||||
extern meshtastic_DeviceMetadata getDeviceMetadata()
|
||||
{
|
||||
meshtastic_DeviceMetadata deviceMetadata;
|
||||
strncpy(deviceMetadata.firmware_version, myNodeInfo.firmware_version, 18);
|
||||
strncpy(deviceMetadata.firmware_version, optstr(APP_VERSION), sizeof(deviceMetadata.firmware_version));
|
||||
deviceMetadata.device_state_version = DEVICESTATE_CUR_VER;
|
||||
deviceMetadata.canShutdown = pmu_found || HAS_CPU_SHUTDOWN;
|
||||
deviceMetadata.hasBluetooth = HAS_BLUETOOTH;
|
||||
|
||||
@@ -9,6 +9,7 @@
|
||||
#include "NodeDB.h"
|
||||
#include "PowerFSM.h"
|
||||
#include "RTC.h"
|
||||
#include "TypeConversions.h"
|
||||
#include "main.h"
|
||||
#include "mesh-pb-constants.h"
|
||||
#include "modules/NodeInfoModule.h"
|
||||
@@ -76,7 +77,8 @@ int MeshService::handleFromRadio(const meshtastic_MeshPacket *mp)
|
||||
powerFSM.trigger(EVENT_PACKET_FOR_PHONE); // Possibly keep the node from sleeping
|
||||
|
||||
nodeDB.updateFrom(*mp); // update our DB state based off sniffing every RX packet from the radio
|
||||
if (mp->which_payload_variant == meshtastic_MeshPacket_decoded_tag && !nodeDB.getNode(mp->from)->has_user && nodeInfoModule) {
|
||||
if (mp->which_payload_variant == meshtastic_MeshPacket_decoded_tag && !nodeDB.getMeshNode(mp->from)->has_user &&
|
||||
nodeInfoModule) {
|
||||
LOG_INFO("Heard a node on channel %d we don't know, sending NodeInfo and asking for a response.\n", mp->channel);
|
||||
nodeInfoModule->sendOurNodeInfo(mp->from, true, mp->channel);
|
||||
}
|
||||
@@ -236,7 +238,8 @@ void MeshService::sendToMesh(meshtastic_MeshPacket *p, RxSource src, bool ccToPh
|
||||
|
||||
void MeshService::sendNetworkPing(NodeNum dest, bool wantReplies)
|
||||
{
|
||||
meshtastic_NodeInfo *node = nodeDB.getNode(nodeDB.getNodeNum());
|
||||
meshtastic_NodeInfoLite *node = nodeDB.getMeshNode(nodeDB.getNodeNum());
|
||||
|
||||
assert(node);
|
||||
|
||||
if (hasValidPosition(node)) {
|
||||
@@ -266,9 +269,9 @@ void MeshService::sendToPhone(meshtastic_MeshPacket *p)
|
||||
fromNum++;
|
||||
}
|
||||
|
||||
meshtastic_NodeInfo *MeshService::refreshMyNodeInfo()
|
||||
meshtastic_NodeInfoLite *MeshService::refreshLocalMeshNode()
|
||||
{
|
||||
meshtastic_NodeInfo *node = nodeDB.getNode(nodeDB.getNodeNum());
|
||||
meshtastic_NodeInfoLite *node = nodeDB.getMeshNode(nodeDB.getNodeNum());
|
||||
assert(node);
|
||||
|
||||
// We might not have a position yet for our local node, in that case, at least try to send the time
|
||||
@@ -277,7 +280,7 @@ meshtastic_NodeInfo *MeshService::refreshMyNodeInfo()
|
||||
node->has_position = true;
|
||||
}
|
||||
|
||||
meshtastic_Position &position = node->position;
|
||||
meshtastic_PositionLite &position = node->position;
|
||||
|
||||
// Update our local node info with our time (even if we don't decide to update anyone else)
|
||||
node->last_heard =
|
||||
@@ -293,7 +296,7 @@ meshtastic_NodeInfo *MeshService::refreshMyNodeInfo()
|
||||
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)
|
||||
meshtastic_NodeInfo *node = refreshMyNodeInfo();
|
||||
meshtastic_NodeInfoLite *node = refreshLocalMeshNode();
|
||||
meshtastic_Position pos = meshtastic_Position_init_default;
|
||||
|
||||
if (newStatus->getHasLock()) {
|
||||
@@ -307,12 +310,12 @@ int MeshService::onGPSChanged(const meshtastic::GPSStatus *newStatus)
|
||||
#endif
|
||||
if (config.position.fixed_position) {
|
||||
LOG_WARN("Using fixed position\n");
|
||||
pos = node->position;
|
||||
pos = ConvertToPosition(node->position);
|
||||
}
|
||||
}
|
||||
|
||||
// Finally add a fresh timestamp and battery level reading
|
||||
// I KNOW this is redundant with refreshMyNodeInfo() above, but these are
|
||||
// I KNOW this is redundant with refreshLocalMeshNode() above, but these are
|
||||
// inexpensive nonblocking calls and can be refactored in due course
|
||||
pos.time = getValidTime(RTCQualityGPS);
|
||||
|
||||
@@ -329,4 +332,4 @@ int MeshService::onGPSChanged(const meshtastic::GPSStatus *newStatus)
|
||||
bool MeshService::isToPhoneQueueEmpty()
|
||||
{
|
||||
return toPhoneQueue.isEmpty();
|
||||
}
|
||||
}
|
||||
@@ -98,7 +98,7 @@ class MeshService
|
||||
bool cancelSending(PacketId id);
|
||||
|
||||
/// Pull the latest power and time info into my nodeinfo
|
||||
meshtastic_NodeInfo *refreshMyNodeInfo();
|
||||
meshtastic_NodeInfoLite *refreshLocalMeshNode();
|
||||
|
||||
/// Send a packet to the phone
|
||||
void sendToPhone(meshtastic_MeshPacket *p);
|
||||
@@ -118,4 +118,4 @@ class MeshService
|
||||
ErrorCode sendQueueStatusToPhone(const meshtastic_QueueStatus &qs, ErrorCode res, uint32_t mesh_packet_id);
|
||||
};
|
||||
|
||||
extern MeshService service;
|
||||
extern MeshService service;
|
||||
@@ -11,6 +11,7 @@
|
||||
#include "PowerFSM.h"
|
||||
#include "RTC.h"
|
||||
#include "Router.h"
|
||||
#include "TypeConversions.h"
|
||||
#include "error.h"
|
||||
#include "main.h"
|
||||
#include "mesh-pb-constants.h"
|
||||
@@ -55,10 +56,18 @@ extern void getMacAddr(uint8_t *dmac);
|
||||
* we use !macaddr (no colons).
|
||||
*/
|
||||
meshtastic_User &owner = devicestate.owner;
|
||||
meshtastic_Position localPosition = meshtastic_Position_init_default;
|
||||
meshtastic_CriticalErrorCode error_code =
|
||||
meshtastic_CriticalErrorCode_NONE; // For the error code, only show values from this boot (discard value from flash)
|
||||
uint32_t error_address = 0;
|
||||
|
||||
static uint8_t ourMacAddr[6];
|
||||
|
||||
NodeDB::NodeDB() : nodes(devicestate.node_db), numNodes(&devicestate.node_db_count) {}
|
||||
NodeDB::NodeDB()
|
||||
: nodes(devicestate.node_db), numNodes(&devicestate.node_db_count), meshNodes(devicestate.node_db_lite),
|
||||
numMeshNodes(&devicestate.node_db_lite_count)
|
||||
{
|
||||
}
|
||||
|
||||
/**
|
||||
* Most (but not always) of the time we want to treat packets 'from' the local phone (where from == 0), as if they originated on
|
||||
@@ -216,6 +225,15 @@ void NodeDB::installDefaultModuleConfig()
|
||||
moduleConfig.has_store_forward = true;
|
||||
moduleConfig.has_telemetry = true;
|
||||
moduleConfig.has_external_notification = true;
|
||||
#if defined(RAK4630) || defined(RAK11310)
|
||||
// Default to RAK led pin 2 (blue)
|
||||
moduleConfig.external_notification.enabled = true;
|
||||
moduleConfig.external_notification.output = PIN_LED2;
|
||||
moduleConfig.external_notification.active = true;
|
||||
moduleConfig.external_notification.alert_message = true;
|
||||
moduleConfig.external_notification.output_ms = 1000;
|
||||
moduleConfig.external_notification.nag_timeout = 60;
|
||||
#endif
|
||||
moduleConfig.has_canned_message = true;
|
||||
|
||||
strncpy(moduleConfig.mqtt.address, default_mqtt_address, sizeof(moduleConfig.mqtt.address));
|
||||
@@ -258,6 +276,9 @@ void NodeDB::resetNodes()
|
||||
{
|
||||
devicestate.node_db_count = 0;
|
||||
memset(devicestate.node_db, 0, sizeof(devicestate.node_db));
|
||||
|
||||
devicestate.node_db_lite_count = 0;
|
||||
memset(devicestate.node_db_lite, 0, sizeof(devicestate.node_db_lite));
|
||||
saveDeviceStateToDisk();
|
||||
}
|
||||
|
||||
@@ -272,17 +293,12 @@ void NodeDB::installDefaultDeviceState()
|
||||
devicestate.has_my_node = true;
|
||||
devicestate.has_owner = true;
|
||||
devicestate.node_db_count = 0;
|
||||
devicestate.node_db_lite_count = 0;
|
||||
devicestate.version = DEVICESTATE_CUR_VER;
|
||||
devicestate.receive_queue_count = 0; // Not yet implemented FIXME
|
||||
|
||||
// default to no GPS, until one has been found by probing
|
||||
myNodeInfo.has_gps = false;
|
||||
myNodeInfo.message_timeout_msec = FLOOD_EXPIRE_TIME;
|
||||
generatePacketId(); // FIXME - ugly way to init current_packet_id;
|
||||
|
||||
// Init our blank owner info to reasonable defaults
|
||||
getMacAddr(ourMacAddr);
|
||||
|
||||
// Set default owner name
|
||||
pickNewNodeNum(); // based on macaddr now
|
||||
snprintf(owner.long_name, sizeof(owner.long_name), "Meshtastic %02x%02x", ourMacAddr[4], ourMacAddr[5]);
|
||||
@@ -303,28 +319,34 @@ void NodeDB::init()
|
||||
|
||||
int saveWhat = 0;
|
||||
|
||||
myNodeInfo.max_channels = MAX_NUM_CHANNELS; // tell others the max # of channels we can understand
|
||||
|
||||
myNodeInfo.error_code =
|
||||
meshtastic_CriticalErrorCode_NONE; // For the error code, only show values from this boot (discard value from flash)
|
||||
myNodeInfo.error_address = 0;
|
||||
|
||||
// likewise - we always want the app requirements to come from the running appload
|
||||
myNodeInfo.min_app_version = 20300; // format is Mmmss (where M is 1+the numeric major number. i.e. 20120 means 1.1.20
|
||||
|
||||
myNodeInfo.min_app_version = 20300; // format is Mmmss (where M is 1+the numeric major number. i.e. 20120 means 1.1.20
|
||||
myNodeInfo.max_channels = MAX_NUM_CHANNELS; // tell others the max # of channels we can understand
|
||||
// Note! We do this after loading saved settings, so that if somehow an invalid nodenum was stored in preferences we won't
|
||||
// keep using that nodenum forever. Crummy guess at our nodenum (but we will check against the nodedb to avoid conflicts)
|
||||
strncpy(myNodeInfo.firmware_version, optstr(APP_VERSION), sizeof(myNodeInfo.firmware_version));
|
||||
pickNewNodeNum();
|
||||
|
||||
// Set our board type so we can share it with others
|
||||
owner.hw_model = HW_VENDOR;
|
||||
|
||||
// Include our owner in the node db under our nodenum
|
||||
meshtastic_NodeInfo *info = getOrCreateNode(getNodeNum());
|
||||
meshtastic_NodeInfoLite *info = getOrCreateMeshNode(getNodeNum());
|
||||
info->user = owner;
|
||||
info->has_user = true;
|
||||
|
||||
strncpy(myNodeInfo.firmware_version, optstr(APP_VERSION), sizeof(myNodeInfo.firmware_version));
|
||||
if (*numNodes > 0) {
|
||||
LOG_DEBUG("Legacy NodeDB detected... Migrating to NodeDBLite\n");
|
||||
uint32_t readIndex = 0;
|
||||
const meshtastic_NodeInfo *oldNodeInfo = nodeDB.readNextNodeInfo(readIndex);
|
||||
while (oldNodeInfo != NULL) {
|
||||
migrateToNodeInfoLite(oldNodeInfo);
|
||||
oldNodeInfo = nodeDB.readNextNodeInfo(readIndex);
|
||||
}
|
||||
LOG_DEBUG("Migration complete! Clearing out legacy NodeDB...\n");
|
||||
devicestate.node_db_count = 0;
|
||||
memset(devicestate.node_db, 0, sizeof(devicestate.node_db));
|
||||
}
|
||||
|
||||
#ifdef ARCH_ESP32
|
||||
Preferences preferences;
|
||||
@@ -332,11 +354,6 @@ void NodeDB::init()
|
||||
myNodeInfo.reboot_count = preferences.getUInt("rebootCounter", 0);
|
||||
preferences.end();
|
||||
LOG_DEBUG("Number of Device Reboots: %d\n", myNodeInfo.reboot_count);
|
||||
|
||||
/* The ESP32 has a wifi radio. This will need to be modified at some point so
|
||||
* the test isn't so simplistic.
|
||||
*/
|
||||
myNodeInfo.has_wifi = true;
|
||||
#endif
|
||||
|
||||
resetRadioConfig(); // If bogus settings got saved, then fix them
|
||||
@@ -367,17 +384,19 @@ void NodeDB::pickNewNodeNum()
|
||||
{
|
||||
NodeNum r = myNodeInfo.my_node_num;
|
||||
|
||||
// If we don't have a nodenum at app - pick an initial nodenum based on the macaddr
|
||||
if (r == 0)
|
||||
r = (ourMacAddr[2] << 24) | (ourMacAddr[3] << 16) | (ourMacAddr[4] << 8) | ourMacAddr[5];
|
||||
getMacAddr(ourMacAddr); // Make sure ourMacAddr is set
|
||||
|
||||
// Pick an initial nodenum based on the macaddr
|
||||
r = (ourMacAddr[2] << 24) | (ourMacAddr[3] << 16) | (ourMacAddr[4] << 8) | ourMacAddr[5];
|
||||
|
||||
if (r == NODENUM_BROADCAST || r < NUM_RESERVED)
|
||||
r = NUM_RESERVED; // don't pick a reserved node number
|
||||
|
||||
meshtastic_NodeInfo *found;
|
||||
while ((found = getNode(r)) && memcmp(found->user.macaddr, owner.macaddr, sizeof(owner.macaddr))) {
|
||||
meshtastic_NodeInfoLite *found;
|
||||
while ((found = getMeshNode(r)) && memcmp(found->user.macaddr, owner.macaddr, sizeof(owner.macaddr))) {
|
||||
// FIXME: input for random() is int, so NODENUM_BROADCAST becomes -1
|
||||
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_WARN("NOTE! Our desired nodenum 0x%x is in use, so trying for 0x%x\n", r, n);
|
||||
r = n;
|
||||
}
|
||||
|
||||
@@ -584,7 +603,7 @@ void NodeDB::saveToDisk(int saveWhat)
|
||||
}
|
||||
}
|
||||
|
||||
const meshtastic_NodeInfo *NodeDB::readNextInfo(uint32_t &readIndex)
|
||||
const meshtastic_NodeInfo *NodeDB::readNextNodeInfo(uint32_t &readIndex)
|
||||
{
|
||||
if (readIndex < *numNodes)
|
||||
return &nodes[readIndex++];
|
||||
@@ -592,8 +611,16 @@ const meshtastic_NodeInfo *NodeDB::readNextInfo(uint32_t &readIndex)
|
||||
return NULL;
|
||||
}
|
||||
|
||||
const meshtastic_NodeInfoLite *NodeDB::readNextMeshNode(uint32_t &readIndex)
|
||||
{
|
||||
if (readIndex < *numMeshNodes)
|
||||
return &meshNodes[readIndex++];
|
||||
else
|
||||
return NULL;
|
||||
}
|
||||
|
||||
/// Given a node, return how many seconds in the past (vs now) that we last heard from it
|
||||
uint32_t sinceLastSeen(const meshtastic_NodeInfo *n)
|
||||
uint32_t sinceLastSeen(const meshtastic_NodeInfoLite *n)
|
||||
{
|
||||
uint32_t now = getTime();
|
||||
|
||||
@@ -617,13 +644,13 @@ uint32_t sinceReceived(const meshtastic_MeshPacket *p)
|
||||
|
||||
#define NUM_ONLINE_SECS (60 * 60 * 2) // 2 hrs to consider someone offline
|
||||
|
||||
size_t NodeDB::getNumOnlineNodes()
|
||||
size_t NodeDB::getNumOnlineMeshNodes()
|
||||
{
|
||||
size_t numseen = 0;
|
||||
|
||||
// FIXME this implementation is kinda expensive
|
||||
for (int i = 0; i < *numNodes; i++)
|
||||
if (sinceLastSeen(&nodes[i]) < NUM_ONLINE_SECS)
|
||||
for (int i = 0; i < *numMeshNodes; i++)
|
||||
if (sinceLastSeen(&meshNodes[i]) < NUM_ONLINE_SECS)
|
||||
numseen++;
|
||||
|
||||
return numseen;
|
||||
@@ -635,7 +662,7 @@ size_t NodeDB::getNumOnlineNodes()
|
||||
*/
|
||||
void NodeDB::updatePosition(uint32_t nodeId, const meshtastic_Position &p, RxSource src)
|
||||
{
|
||||
meshtastic_NodeInfo *info = getOrCreateNode(nodeId);
|
||||
meshtastic_NodeInfoLite *info = getOrCreateMeshNode(nodeId);
|
||||
if (!info) {
|
||||
return;
|
||||
}
|
||||
@@ -644,7 +671,9 @@ void NodeDB::updatePosition(uint32_t nodeId, const meshtastic_Position &p, RxSou
|
||||
// Local packet, fully authoritative
|
||||
LOG_INFO("updatePosition LOCAL pos@%x, time=%u, latI=%d, lonI=%d, alt=%d\n", p.timestamp, p.time, p.latitude_i,
|
||||
p.longitude_i, p.altitude);
|
||||
info->position = p;
|
||||
|
||||
info->position = ConvertToPositionLite(p);
|
||||
localPosition = p;
|
||||
} else if ((p.time > 0) && !p.latitude_i && !p.longitude_i && !p.timestamp && !p.location_source) {
|
||||
// FIXME SPECIAL TIME SETTING PACKET FROM EUD TO RADIO
|
||||
// (stop-gap fix for issue #900)
|
||||
@@ -662,7 +691,7 @@ void NodeDB::updatePosition(uint32_t nodeId, const meshtastic_Position &p, RxSou
|
||||
uint32_t tmp_time = info->position.time;
|
||||
|
||||
// Next, update atomically
|
||||
info->position = p;
|
||||
info->position = ConvertToPositionLite(p);
|
||||
|
||||
// Last, restore any fields that may have been overwritten
|
||||
if (!info->position.time)
|
||||
@@ -678,7 +707,7 @@ void NodeDB::updatePosition(uint32_t nodeId, const meshtastic_Position &p, RxSou
|
||||
*/
|
||||
void NodeDB::updateTelemetry(uint32_t nodeId, const meshtastic_Telemetry &t, RxSource src)
|
||||
{
|
||||
meshtastic_NodeInfo *info = getOrCreateNode(nodeId);
|
||||
meshtastic_NodeInfoLite *info = getOrCreateMeshNode(nodeId);
|
||||
// Environment metrics should never go to NodeDb but we'll safegaurd anyway
|
||||
if (!info || t.which_variant != meshtastic_Telemetry_device_metrics_tag) {
|
||||
return;
|
||||
@@ -700,7 +729,7 @@ void NodeDB::updateTelemetry(uint32_t nodeId, const meshtastic_Telemetry &t, RxS
|
||||
*/
|
||||
bool NodeDB::updateUser(uint32_t nodeId, const meshtastic_User &p)
|
||||
{
|
||||
meshtastic_NodeInfo *info = getOrCreateNode(nodeId);
|
||||
meshtastic_NodeInfoLite *info = getOrCreateMeshNode(nodeId);
|
||||
if (!info) {
|
||||
return false;
|
||||
}
|
||||
@@ -733,7 +762,7 @@ void NodeDB::updateFrom(const meshtastic_MeshPacket &mp)
|
||||
if (mp.which_payload_variant == meshtastic_MeshPacket_decoded_tag && mp.from) {
|
||||
LOG_DEBUG("Update DB node 0x%x, rx_time=%u, channel=%d\n", mp.from, mp.rx_time, mp.channel);
|
||||
|
||||
meshtastic_NodeInfo *info = getOrCreateNode(getFrom(&mp));
|
||||
meshtastic_NodeInfoLite *info = getOrCreateMeshNode(getFrom(&mp));
|
||||
if (!info) {
|
||||
return;
|
||||
}
|
||||
@@ -750,9 +779,9 @@ void NodeDB::updateFrom(const meshtastic_MeshPacket &mp)
|
||||
}
|
||||
}
|
||||
|
||||
uint8_t NodeDB::getNodeChannel(NodeNum n)
|
||||
uint8_t NodeDB::getMeshNodeChannel(NodeNum n)
|
||||
{
|
||||
meshtastic_NodeInfo *info = getNode(n);
|
||||
meshtastic_NodeInfoLite *info = getMeshNode(n);
|
||||
if (!info) {
|
||||
return 0; // defaults to PRIMARY
|
||||
}
|
||||
@@ -761,7 +790,7 @@ uint8_t NodeDB::getNodeChannel(NodeNum n)
|
||||
|
||||
/// Find a node in our DB, return null for missing
|
||||
/// NOTE: This function might be called from an ISR
|
||||
meshtastic_NodeInfo *NodeDB::getNode(NodeNum n)
|
||||
meshtastic_NodeInfo *NodeDB::getNodeInfo(NodeNum n)
|
||||
{
|
||||
for (int i = 0; i < *numNodes; i++)
|
||||
if (nodes[i].num == n)
|
||||
@@ -770,38 +799,100 @@ meshtastic_NodeInfo *NodeDB::getNode(NodeNum n)
|
||||
return NULL;
|
||||
}
|
||||
|
||||
/// Find a node in our DB, create an empty NodeInfo if missing
|
||||
meshtastic_NodeInfo *NodeDB::getOrCreateNode(NodeNum n)
|
||||
/// Find a node in our DB, return null for missing
|
||||
/// NOTE: This function might be called from an ISR
|
||||
meshtastic_NodeInfoLite *NodeDB::getMeshNode(NodeNum n)
|
||||
{
|
||||
meshtastic_NodeInfo *info = getNode(n);
|
||||
for (int i = 0; i < *numMeshNodes; i++)
|
||||
if (meshNodes[i].num == n)
|
||||
return &meshNodes[i];
|
||||
|
||||
if (!info) {
|
||||
if ((*numNodes >= MAX_NUM_NODES) || (memGet.getFreeHeap() < meshtastic_NodeInfo_size * 3)) {
|
||||
screen->print("warning: node_db full! erasing oldest entry\n");
|
||||
return NULL;
|
||||
}
|
||||
|
||||
/// Find a node in our DB, create an empty NodeInfo if missing
|
||||
meshtastic_NodeInfoLite *NodeDB::getOrCreateMeshNode(NodeNum n)
|
||||
{
|
||||
meshtastic_NodeInfoLite *lite = getMeshNode(n);
|
||||
|
||||
if (!lite) {
|
||||
if ((*numMeshNodes >= MAX_NUM_NODES) || (memGet.getFreeHeap() < meshtastic_NodeInfoLite_size * 3)) {
|
||||
screen->print("warning: node_db_lite full! erasing oldest entry\n");
|
||||
// look for oldest node and erase it
|
||||
uint32_t oldest = UINT32_MAX;
|
||||
int oldestIndex = -1;
|
||||
for (int i = 0; i < *numNodes; i++) {
|
||||
if (nodes[i].last_heard < oldest) {
|
||||
oldest = nodes[i].last_heard;
|
||||
for (int i = 0; i < *numMeshNodes; i++) {
|
||||
if (meshNodes[i].last_heard < oldest) {
|
||||
oldest = meshNodes[i].last_heard;
|
||||
oldestIndex = i;
|
||||
}
|
||||
}
|
||||
// Shove the remaining nodes down the chain
|
||||
for (int i = oldestIndex; i < *numNodes - 1; i++) {
|
||||
nodes[i] = nodes[i + 1];
|
||||
for (int i = oldestIndex; i < *numMeshNodes - 1; i++) {
|
||||
meshNodes[i] = meshNodes[i + 1];
|
||||
}
|
||||
(*numNodes)--;
|
||||
(*numMeshNodes)--;
|
||||
}
|
||||
// add the node at the end
|
||||
info = &nodes[(*numNodes)++];
|
||||
lite = &meshNodes[(*numMeshNodes)++];
|
||||
|
||||
// everything is missing except the nodenum
|
||||
memset(info, 0, sizeof(*info));
|
||||
info->num = n;
|
||||
memset(lite, 0, sizeof(*lite));
|
||||
lite->num = n;
|
||||
}
|
||||
|
||||
return info;
|
||||
return lite;
|
||||
}
|
||||
|
||||
void NodeDB::migrateToNodeInfoLite(const meshtastic_NodeInfo *node)
|
||||
{
|
||||
meshtastic_NodeInfoLite *lite = getMeshNode(node->num);
|
||||
|
||||
if (!lite) {
|
||||
if ((*numMeshNodes >= MAX_NUM_NODES) || (memGet.getFreeHeap() < meshtastic_NodeInfoLite_size * 3)) {
|
||||
screen->print("warning: node_db_lite full! erasing oldest entry\n");
|
||||
// look for oldest node and erase it
|
||||
uint32_t oldest = UINT32_MAX;
|
||||
int oldestIndex = -1;
|
||||
for (int i = 0; i < *numMeshNodes; i++) {
|
||||
if (meshNodes[i].last_heard < oldest) {
|
||||
oldest = meshNodes[i].last_heard;
|
||||
oldestIndex = i;
|
||||
}
|
||||
}
|
||||
// Shove the remaining nodes down the chain
|
||||
for (int i = oldestIndex; i < *numMeshNodes - 1; i++) {
|
||||
meshNodes[i] = meshNodes[i + 1];
|
||||
}
|
||||
(*numMeshNodes)--;
|
||||
}
|
||||
// add the node at the end
|
||||
lite = &meshNodes[(*numMeshNodes)++];
|
||||
|
||||
// everything is missing except the nodenum
|
||||
memset(lite, 0, sizeof(*lite));
|
||||
lite->num = node->num;
|
||||
lite->snr = node->snr;
|
||||
lite->last_heard = node->last_heard;
|
||||
lite->channel = node->channel;
|
||||
|
||||
if (node->has_position) {
|
||||
lite->has_position = true;
|
||||
lite->position.latitude_i = node->position.latitude_i;
|
||||
lite->position.longitude_i = node->position.longitude_i;
|
||||
lite->position.altitude = node->position.altitude;
|
||||
lite->position.location_source = node->position.location_source;
|
||||
lite->position.time = node->position.time;
|
||||
}
|
||||
if (node->has_user) {
|
||||
lite->has_user = true;
|
||||
lite->user = node->user;
|
||||
}
|
||||
if (node->has_device_metrics) {
|
||||
lite->has_device_metrics = true;
|
||||
lite->device_metrics = node->device_metrics;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/// Record an error that should be reported via analytics
|
||||
@@ -817,9 +908,8 @@ void recordCriticalError(meshtastic_CriticalErrorCode code, uint32_t address, co
|
||||
}
|
||||
|
||||
// Record error to DB
|
||||
myNodeInfo.error_code = code;
|
||||
myNodeInfo.error_address = address;
|
||||
myNodeInfo.error_count++;
|
||||
error_code = code;
|
||||
error_address = address;
|
||||
|
||||
// Currently portuino is mostly used for simulation. Make sue the user notices something really bad happend
|
||||
#ifdef ARCH_PORTDUINO
|
||||
|
||||
@@ -7,6 +7,7 @@
|
||||
#include "MeshTypes.h"
|
||||
#include "NodeStatus.h"
|
||||
#include "mesh-pb-constants.h"
|
||||
#include "mesh/generated/meshtastic/mesh.pb.h" // For CriticalErrorCode
|
||||
|
||||
/*
|
||||
DeviceState versions used to be defined in the .proto file but really only this function cares. So changed to a
|
||||
@@ -28,9 +29,10 @@ extern meshtastic_LocalConfig config;
|
||||
extern meshtastic_LocalModuleConfig moduleConfig;
|
||||
extern meshtastic_OEMStore oemStore;
|
||||
extern meshtastic_User &owner;
|
||||
extern meshtastic_Position localPosition;
|
||||
|
||||
/// Given a node, return how many seconds in the past (vs now) that we last heard from it
|
||||
uint32_t sinceLastSeen(const meshtastic_NodeInfo *n);
|
||||
uint32_t sinceLastSeen(const meshtastic_NodeInfoLite *n);
|
||||
|
||||
/// Given a packet, return how many seconds in the past (vs now) it was received
|
||||
uint32_t sinceReceived(const meshtastic_MeshPacket *p);
|
||||
@@ -46,9 +48,12 @@ class NodeDB
|
||||
meshtastic_NodeInfo *nodes;
|
||||
pb_size_t *numNodes;
|
||||
|
||||
meshtastic_NodeInfoLite *meshNodes;
|
||||
pb_size_t *numMeshNodes;
|
||||
|
||||
public:
|
||||
bool updateGUI = false; // we think the gui should definitely be redrawn, screen will clear this once handled
|
||||
meshtastic_NodeInfo *updateGUIforNode = NULL; // if currently showing this node, we think you should update the GUI
|
||||
meshtastic_NodeInfoLite *updateGUIforNode = NULL; // if currently showing this node, we think you should update the GUI
|
||||
Observable<const meshtastic::NodeStatus *> newStatus;
|
||||
|
||||
/// don't do mesh based algoritm for node id assignment (initially)
|
||||
@@ -89,8 +94,6 @@ class NodeDB
|
||||
/// @return our node number
|
||||
NodeNum getNodeNum() { return myNodeInfo.my_node_num; }
|
||||
|
||||
size_t getNumNodes() { return *numNodes; }
|
||||
|
||||
/// if returns false, that means our node should send a DenyNodeNum response. If true, we think the number is okay for use
|
||||
// bool handleWantNodeNum(NodeNum n);
|
||||
|
||||
@@ -102,26 +105,14 @@ class NodeDB
|
||||
their denial?)
|
||||
*/
|
||||
|
||||
/// Allow the bluetooth layer to read our next nodeinfo record, or NULL if done reading
|
||||
const meshtastic_NodeInfo *readNextInfo(uint32_t &readIndex);
|
||||
|
||||
/// pick a provisional nodenum we hope no one is using
|
||||
void pickNewNodeNum();
|
||||
|
||||
// get channel channel index we heard a nodeNum on, defaults to 0 if not found
|
||||
uint8_t getNodeChannel(NodeNum n);
|
||||
|
||||
/// Find a node in our DB, return null for missing
|
||||
meshtastic_NodeInfo *getNode(NodeNum n);
|
||||
|
||||
meshtastic_NodeInfo *getNodeByIndex(size_t x)
|
||||
{
|
||||
assert(x < *numNodes);
|
||||
return &nodes[x];
|
||||
}
|
||||
uint8_t getMeshNodeChannel(NodeNum n);
|
||||
|
||||
/// Return the number of nodes we've heard from recently (within the last 2 hrs?)
|
||||
size_t getNumOnlineNodes();
|
||||
size_t getNumOnlineMeshNodes();
|
||||
|
||||
void initConfigIntervals(), initModuleConfigIntervals(), resetNodes();
|
||||
|
||||
@@ -132,15 +123,38 @@ class NodeDB
|
||||
|
||||
void installRoleDefaults(meshtastic_Config_DeviceConfig_Role role);
|
||||
|
||||
const meshtastic_NodeInfoLite *readNextMeshNode(uint32_t &readIndex);
|
||||
|
||||
meshtastic_NodeInfoLite *getMeshNodeByIndex(size_t x)
|
||||
{
|
||||
assert(x < *numMeshNodes);
|
||||
return &meshNodes[x];
|
||||
}
|
||||
|
||||
meshtastic_NodeInfoLite *getMeshNode(NodeNum n);
|
||||
size_t getNumMeshNodes() { return *numMeshNodes; }
|
||||
|
||||
private:
|
||||
/// Find a node in our DB, create an empty NodeInfo if missing
|
||||
meshtastic_NodeInfo *getOrCreateNode(NodeNum n);
|
||||
/// Find a node in our DB, create an empty NodeInfoLite if missing
|
||||
meshtastic_NodeInfoLite *getOrCreateMeshNode(NodeNum n);
|
||||
void migrateToNodeInfoLite(const meshtastic_NodeInfo *node);
|
||||
/// Find a node in our DB, return null for missing
|
||||
meshtastic_NodeInfo *getNodeInfo(NodeNum n);
|
||||
/// Allow the bluetooth layer to read our next nodeinfo record, or NULL if done reading
|
||||
const meshtastic_NodeInfo *readNextNodeInfo(uint32_t &readIndex);
|
||||
size_t getNumNodes() { return *numNodes; }
|
||||
|
||||
meshtastic_NodeInfo *getNodeByIndex(size_t x)
|
||||
{
|
||||
assert(x < *numNodes);
|
||||
return &nodes[x];
|
||||
}
|
||||
|
||||
/// Notify observers of changes to the DB
|
||||
void notifyObservers(bool forceUpdate = false)
|
||||
{
|
||||
// Notify observers of the current node state
|
||||
const meshtastic::NodeStatus status = meshtastic::NodeStatus(getNumOnlineNodes(), getNumNodes(), forceUpdate);
|
||||
const meshtastic::NodeStatus status = meshtastic::NodeStatus(getNumOnlineMeshNodes(), getNumMeshNodes(), forceUpdate);
|
||||
newStatus.notifyObservers(&status);
|
||||
}
|
||||
|
||||
@@ -218,12 +232,23 @@ static inline bool hasValidPosition(const meshtastic_NodeInfo *n)
|
||||
{
|
||||
return n->has_position && (n->position.latitude_i != 0 || n->position.longitude_i != 0);
|
||||
}
|
||||
static inline bool hasValidPosition(const meshtastic_NodeInfoLite *n)
|
||||
{
|
||||
return n->has_position && (n->position.latitude_i != 0 || n->position.longitude_i != 0);
|
||||
}
|
||||
|
||||
/** The current change # for radio settings. Starts at 0 on boot and any time the radio settings
|
||||
* might have changed is incremented. Allows others to detect they might now be on a new channel.
|
||||
*/
|
||||
extern uint32_t radioGeneration;
|
||||
|
||||
extern meshtastic_CriticalErrorCode error_code;
|
||||
|
||||
/*
|
||||
* A numeric error address (nonzero if available)
|
||||
*/
|
||||
extern uint32_t error_address;
|
||||
|
||||
#define Module_Config_size \
|
||||
(ModuleConfig_CannedMessageConfig_size + ModuleConfig_ExternalNotificationConfig_size + ModuleConfig_MQTTConfig_size + \
|
||||
ModuleConfig_RangeTestConfig_size + ModuleConfig_SerialConfig_size + ModuleConfig_StoreForwardConfig_size + \
|
||||
|
||||
@@ -5,6 +5,7 @@
|
||||
#include "NodeDB.h"
|
||||
#include "PowerFSM.h"
|
||||
#include "RadioInterface.h"
|
||||
#include "TypeConversions.h"
|
||||
#include "configuration.h"
|
||||
#include "main.h"
|
||||
#include "xmodem.h"
|
||||
@@ -40,7 +41,7 @@ void PhoneAPI::handleStartConfig()
|
||||
state = STATE_SEND_MY_INFO;
|
||||
|
||||
LOG_INFO("Starting API client config\n");
|
||||
nodeInfoForPhone = NULL; // Don't keep returning old nodeinfos
|
||||
nodeInfoForPhone.num = 0; // Don't keep returning old nodeinfos
|
||||
resetReadIndex();
|
||||
}
|
||||
|
||||
@@ -143,25 +144,23 @@ size_t PhoneAPI::getFromRadio(uint8_t *buf)
|
||||
LOG_INFO("getFromRadio=STATE_SEND_MY_INFO\n");
|
||||
// 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.
|
||||
myNodeInfo.has_gps = gps && gps->isConnected(); // Update with latest GPS connect info
|
||||
fromRadioScratch.which_payload_variant = meshtastic_FromRadio_my_info_tag;
|
||||
fromRadioScratch.my_info = myNodeInfo;
|
||||
state = STATE_SEND_NODEINFO;
|
||||
|
||||
service.refreshMyNodeInfo(); // Update my NodeInfo because the client will be asking for it soon.
|
||||
service.refreshLocalMeshNode(); // Update my NodeInfo because the client will be asking for it soon.
|
||||
break;
|
||||
|
||||
case STATE_SEND_NODEINFO: {
|
||||
LOG_INFO("getFromRadio=STATE_SEND_NODEINFO\n");
|
||||
const meshtastic_NodeInfo *info = nodeInfoForPhone;
|
||||
nodeInfoForPhone = NULL; // We just consumed a nodeinfo, will need a new one next time
|
||||
|
||||
if (info) {
|
||||
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);
|
||||
if (nodeInfoForPhone.num != 0) {
|
||||
LOG_INFO("nodeinfo: num=0x%x, lastseen=%u, id=%s, name=%s\n", nodeInfoForPhone.num, nodeInfoForPhone.last_heard,
|
||||
nodeInfoForPhone.user.id, nodeInfoForPhone.user.long_name);
|
||||
fromRadioScratch.which_payload_variant = meshtastic_FromRadio_node_info_tag;
|
||||
fromRadioScratch.node_info = *info;
|
||||
fromRadioScratch.node_info = nodeInfoForPhone;
|
||||
// Stay in current state until done sending nodeinfos
|
||||
nodeInfoForPhone.num = 0; // We just consumed a nodeinfo, will need a new one next time
|
||||
} else {
|
||||
LOG_INFO("Done sending nodeinfos\n");
|
||||
state = STATE_SEND_CHANNELS;
|
||||
@@ -371,8 +370,12 @@ bool PhoneAPI::available()
|
||||
return true;
|
||||
|
||||
case STATE_SEND_NODEINFO:
|
||||
if (!nodeInfoForPhone)
|
||||
nodeInfoForPhone = nodeDB.readNextInfo(readIndex);
|
||||
if (nodeInfoForPhone.num == 0) {
|
||||
auto nextNode = nodeDB.readNextMeshNode(readIndex);
|
||||
if (nextNode) {
|
||||
nodeInfoForPhone = ConvertToNodeInfo(nextNode);
|
||||
}
|
||||
}
|
||||
return true; // Always say we have something, because we might need to advance our state machine
|
||||
|
||||
case STATE_SEND_PACKETS: {
|
||||
@@ -427,4 +430,4 @@ int PhoneAPI::onNotify(uint32_t newValue)
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
@@ -51,7 +51,7 @@ class PhoneAPI
|
||||
meshtastic_QueueStatus *queueStatusPacketForPhone = NULL;
|
||||
|
||||
/// We temporarily keep the nodeInfo here between the call to available and getFromRadio
|
||||
const meshtastic_NodeInfo *nodeInfoForPhone = NULL;
|
||||
meshtastic_NodeInfo nodeInfoForPhone = meshtastic_NodeInfo_init_default;
|
||||
|
||||
meshtastic_ToRadio toRadioScratch = {
|
||||
0}; // this is a static scratch object, any data must be copied elsewhere before returning
|
||||
|
||||
@@ -52,7 +52,7 @@ template <class T> class ProtobufModule : protected SinglePortModule
|
||||
*/
|
||||
const char *getSenderShortName(const meshtastic_MeshPacket &mp)
|
||||
{
|
||||
auto node = nodeDB.getNode(getFrom(&mp));
|
||||
auto node = nodeDB.getMeshNode(getFrom(&mp));
|
||||
const char *sender = (node) ? node->user.short_name : "???";
|
||||
return sender;
|
||||
}
|
||||
@@ -86,4 +86,4 @@ template <class T> class ProtobufModule : protected SinglePortModule
|
||||
|
||||
return handleReceivedProtobuf(mp, decoded) ? ProcessMessage::STOP : ProcessMessage::CONTINUE;
|
||||
}
|
||||
};
|
||||
};
|
||||
@@ -232,7 +232,8 @@ uint32_t RadioInterface::getTxDelayMsecWeighted(float snr)
|
||||
delay = random(0, 2 * CWsize) * slotTimeMsec;
|
||||
LOG_DEBUG("rx_snr found in packet. As a router, setting tx delay:%d\n", delay);
|
||||
} else {
|
||||
delay = random(0, pow(2, CWsize)) * slotTimeMsec;
|
||||
// offset the maximum delay for routers: (2 * CWmax * slotTimeMsec)
|
||||
delay = (2 * CWmax * slotTimeMsec) + random(0, pow(2, CWsize)) * slotTimeMsec;
|
||||
LOG_DEBUG("rx_snr found in packet. Setting tx delay:%d\n", delay);
|
||||
}
|
||||
|
||||
|
||||
@@ -178,7 +178,7 @@ ErrorCode Router::sendLocal(meshtastic_MeshPacket *p, RxSource src)
|
||||
}
|
||||
|
||||
if (!p->channel) { // don't override if a channel was requested
|
||||
p->channel = nodeDB.getNodeChannel(p->to);
|
||||
p->channel = nodeDB.getMeshNodeChannel(p->to);
|
||||
LOG_DEBUG("localSend to channel %d\n", p->channel);
|
||||
}
|
||||
|
||||
@@ -493,4 +493,4 @@ void Router::perhapsHandleReceived(meshtastic_MeshPacket *p)
|
||||
handleReceived(p);
|
||||
|
||||
packetPool.release(p);
|
||||
}
|
||||
}
|
||||
54
src/mesh/TypeConversions.h
Normal file
54
src/mesh/TypeConversions.h
Normal file
@@ -0,0 +1,54 @@
|
||||
#include "mesh/generated/meshtastic/deviceonly.pb.h"
|
||||
#include "mesh/generated/meshtastic/mesh.pb.h"
|
||||
|
||||
inline static meshtastic_NodeInfo ConvertToNodeInfo(const meshtastic_NodeInfoLite *lite)
|
||||
{
|
||||
meshtastic_NodeInfo info = meshtastic_NodeInfo_init_default;
|
||||
|
||||
info.num = lite->num;
|
||||
info.snr = lite->snr;
|
||||
info.last_heard = lite->last_heard;
|
||||
info.channel = lite->channel;
|
||||
|
||||
if (lite->has_position) {
|
||||
info.has_position = true;
|
||||
info.position.latitude_i = lite->position.latitude_i;
|
||||
info.position.longitude_i = lite->position.longitude_i;
|
||||
info.position.altitude = lite->position.altitude;
|
||||
info.position.location_source = lite->position.location_source;
|
||||
info.position.time = lite->position.time;
|
||||
}
|
||||
if (lite->has_user) {
|
||||
info.has_user = true;
|
||||
info.user = lite->user;
|
||||
}
|
||||
if (lite->has_device_metrics) {
|
||||
info.has_device_metrics = true;
|
||||
info.device_metrics = lite->device_metrics;
|
||||
}
|
||||
return info;
|
||||
}
|
||||
|
||||
inline static meshtastic_PositionLite ConvertToPositionLite(meshtastic_Position position)
|
||||
{
|
||||
meshtastic_PositionLite lite = meshtastic_PositionLite_init_default;
|
||||
lite.latitude_i = position.latitude_i;
|
||||
lite.longitude_i = position.longitude_i;
|
||||
lite.altitude = position.altitude;
|
||||
lite.location_source = position.location_source;
|
||||
lite.time = position.time;
|
||||
|
||||
return lite;
|
||||
}
|
||||
|
||||
inline static meshtastic_Position ConvertToPosition(meshtastic_PositionLite lite)
|
||||
{
|
||||
meshtastic_Position position = meshtastic_Position_init_default;
|
||||
position.latitude_i = lite.latitude_i;
|
||||
position.longitude_i = lite.longitude_i;
|
||||
position.altitude = lite.altitude;
|
||||
position.location_source = lite.location_source;
|
||||
position.time = lite.time;
|
||||
|
||||
return position;
|
||||
}
|
||||
@@ -98,6 +98,11 @@ static int32_t reconnectETH()
|
||||
return 5000; // every 5 seconds
|
||||
}
|
||||
|
||||
static uint32_t bigToLittleEndian(uint32_t value)
|
||||
{
|
||||
return ((value >> 24) & 0xFF) | ((value >> 8) & 0xFF00) | ((value << 8) & 0xFF0000) | ((value << 24) & 0xFF000000);
|
||||
}
|
||||
|
||||
// Startup Ethernet
|
||||
bool initEthernet()
|
||||
{
|
||||
@@ -126,7 +131,15 @@ bool initEthernet()
|
||||
status = Ethernet.begin(mac);
|
||||
} else if (config.network.address_mode == meshtastic_Config_NetworkConfig_AddressMode_STATIC) {
|
||||
LOG_INFO("starting Ethernet Static\n");
|
||||
Ethernet.begin(mac, config.network.ipv4_config.ip, config.network.ipv4_config.dns, config.network.ipv4_config.subnet);
|
||||
|
||||
IPAddress ip = IPAddress(bigToLittleEndian(config.network.ipv4_config.ip));
|
||||
IPAddress dns = IPAddress(bigToLittleEndian(config.network.ipv4_config.dns));
|
||||
IPAddress gateway = IPAddress(bigToLittleEndian(config.network.ipv4_config.gateway));
|
||||
IPAddress subnet = IPAddress(bigToLittleEndian(config.network.ipv4_config.subnet));
|
||||
|
||||
Ethernet.begin(mac, ip, dns, gateway, subnet);
|
||||
|
||||
status = 1;
|
||||
} else {
|
||||
LOG_INFO("Ethernet Disabled\n");
|
||||
return false;
|
||||
|
||||
@@ -9,6 +9,12 @@
|
||||
PB_BIND(meshtastic_DeviceState, meshtastic_DeviceState, 4)
|
||||
|
||||
|
||||
PB_BIND(meshtastic_NodeInfoLite, meshtastic_NodeInfoLite, AUTO)
|
||||
|
||||
|
||||
PB_BIND(meshtastic_PositionLite, meshtastic_PositionLite, AUTO)
|
||||
|
||||
|
||||
PB_BIND(meshtastic_ChannelFile, meshtastic_ChannelFile, 2)
|
||||
|
||||
|
||||
|
||||
File diff suppressed because one or more lines are too long
@@ -372,7 +372,8 @@ typedef struct _meshtastic_User {
|
||||
/* A VERY short name, ideally two characters.
|
||||
Suitable for a tiny OLED screen */
|
||||
char short_name[5];
|
||||
/* This is the addr of the radio.
|
||||
/* Deprecated in Meshtastic 2.1.x
|
||||
This is the addr of the radio.
|
||||
Not populated by the phone, but added by the esp32 when broadcasting */
|
||||
pb_byte_t macaddr[6];
|
||||
/* TBEAM, HELTEC, etc...
|
||||
@@ -578,12 +579,15 @@ typedef struct _meshtastic_MyNodeInfo {
|
||||
/* Tells the phone what our node number is, default starting value is
|
||||
lowbyte of macaddr, but it will be fixed if that is already in use */
|
||||
uint32_t my_node_num;
|
||||
/* Note: This flag merely means we detected a hardware GPS in our node.
|
||||
/* Deprecated in 2.1.x (Source from device_metadata)
|
||||
Note: This flag merely means we detected a hardware GPS in our node.
|
||||
Not the same as UserPreferences.location_sharing */
|
||||
bool has_gps;
|
||||
/* The maximum number of 'software' channels that can be set on this node. */
|
||||
/* Deprecated in 2.1.x
|
||||
The maximum number of 'software' channels that can be set on this node. */
|
||||
uint32_t max_channels;
|
||||
/* 0.0.5 etc... */
|
||||
/* Deprecated in 2.1.x (Source from device_metadata)
|
||||
0.0.5 etc... */
|
||||
char firmware_version[18];
|
||||
/* An error message we'd like to report back to the mothership through analytics.
|
||||
It indicates a serious bug occurred on the device, the device coped with it,
|
||||
@@ -600,9 +604,11 @@ typedef struct _meshtastic_MyNodeInfo {
|
||||
/* The total number of reboots this node has ever encountered
|
||||
(well - since the last time we discarded preferences) */
|
||||
uint32_t reboot_count;
|
||||
/* Calculated bitrate of the current channel (in Bytes Per Second) */
|
||||
/* Deprecated in 2.1.x
|
||||
Calculated bitrate of the current channel (in Bytes Per Second) */
|
||||
float bitrate;
|
||||
/* How long before we consider a message abandoned and we can clear our
|
||||
/* Deprecated in 2.1.x
|
||||
How long before we consider a message abandoned and we can clear our
|
||||
caches of any messages in flight Normally quite large to handle the worst case
|
||||
message delivery time, 5 minutes.
|
||||
Formerly called FLOOD_EXPIRE_TIME in the device code */
|
||||
@@ -610,17 +616,22 @@ typedef struct _meshtastic_MyNodeInfo {
|
||||
/* The minimum app version that can talk to this device.
|
||||
Phone/PC apps should compare this to their build number and if too low tell the user they must update their app */
|
||||
uint32_t min_app_version;
|
||||
/* 24 time windows of 1hr each with the airtime transmitted out of the device per hour. */
|
||||
/* Deprecated in 2.1.x (Only used on device to keep track of utilization)
|
||||
24 time windows of 1hr each with the airtime transmitted out of the device per hour. */
|
||||
pb_size_t air_period_tx_count;
|
||||
uint32_t air_period_tx[8];
|
||||
/* 24 time windows of 1hr each with the airtime of valid packets for your mesh. */
|
||||
/* Deprecated in 2.1.x (Only used on device to keep track of utilization)
|
||||
24 time windows of 1hr each with the airtime of valid packets for your mesh. */
|
||||
pb_size_t air_period_rx_count;
|
||||
uint32_t air_period_rx[8];
|
||||
/* Is the device wifi capable? */
|
||||
/* Deprecated in 2.1.x (Source from DeviceMetadata instead)
|
||||
Is the device wifi capable? */
|
||||
bool has_wifi;
|
||||
/* Utilization for the current channel, including well formed TX, RX and malformed RX (aka noise). */
|
||||
/* Deprecated in 2.1.x (Source from DeviceMetrics telemetry payloads)
|
||||
Utilization for the current channel, including well formed TX, RX and malformed RX (aka noise). */
|
||||
float channel_utilization;
|
||||
/* Percent of airtime for transmission used within the last hour. */
|
||||
/* Deprecated in 2.1.x (Source from DeviceMetrics telemetry payloads)
|
||||
Percent of airtime for transmission used within the last hour. */
|
||||
float air_util_tx;
|
||||
} meshtastic_MyNodeInfo;
|
||||
|
||||
|
||||
@@ -305,13 +305,14 @@ int32_t CannedMessageModule::runOnce()
|
||||
switch (this->payload) {
|
||||
case 0xb4: // left
|
||||
if (this->destSelect) {
|
||||
size_t numNodes = nodeDB.getNumNodes();
|
||||
size_t numMeshNodes = nodeDB.getNumMeshNodes();
|
||||
if (this->dest == NODENUM_BROADCAST) {
|
||||
this->dest = nodeDB.getNodeNum();
|
||||
}
|
||||
for (unsigned int i = 0; i < numNodes; i++) {
|
||||
if (nodeDB.getNodeByIndex(i)->num == this->dest) {
|
||||
this->dest = (i > 0) ? nodeDB.getNodeByIndex(i - 1)->num : nodeDB.getNodeByIndex(numNodes - 1)->num;
|
||||
for (unsigned int i = 0; i < numMeshNodes; i++) {
|
||||
if (nodeDB.getMeshNodeByIndex(i)->num == this->dest) {
|
||||
this->dest =
|
||||
(i > 0) ? nodeDB.getMeshNodeByIndex(i - 1)->num : nodeDB.getMeshNodeByIndex(numMeshNodes - 1)->num;
|
||||
break;
|
||||
}
|
||||
}
|
||||
@@ -326,13 +327,14 @@ int32_t CannedMessageModule::runOnce()
|
||||
break;
|
||||
case 0xb7: // right
|
||||
if (this->destSelect) {
|
||||
size_t numNodes = nodeDB.getNumNodes();
|
||||
size_t numMeshNodes = nodeDB.getNumMeshNodes();
|
||||
if (this->dest == NODENUM_BROADCAST) {
|
||||
this->dest = nodeDB.getNodeNum();
|
||||
}
|
||||
for (unsigned int i = 0; i < numNodes; i++) {
|
||||
if (nodeDB.getNodeByIndex(i)->num == this->dest) {
|
||||
this->dest = (i < numNodes - 1) ? nodeDB.getNodeByIndex(i + 1)->num : nodeDB.getNodeByIndex(0)->num;
|
||||
for (unsigned int i = 0; i < numMeshNodes; i++) {
|
||||
if (nodeDB.getMeshNodeByIndex(i)->num == this->dest) {
|
||||
this->dest =
|
||||
(i < numMeshNodes - 1) ? nodeDB.getMeshNodeByIndex(i + 1)->num : nodeDB.getMeshNodeByIndex(0)->num;
|
||||
break;
|
||||
}
|
||||
}
|
||||
@@ -409,7 +411,7 @@ const char *CannedMessageModule::getNodeName(NodeNum node)
|
||||
if (node == NODENUM_BROADCAST) {
|
||||
return "Broadcast";
|
||||
} else {
|
||||
meshtastic_NodeInfo *info = nodeDB.getNode(node);
|
||||
meshtastic_NodeInfoLite *info = nodeDB.getMeshNode(node);
|
||||
if (info != NULL) {
|
||||
return info->user.long_name;
|
||||
} else {
|
||||
|
||||
@@ -11,7 +11,7 @@
|
||||
#include "main.h"
|
||||
|
||||
#ifdef RAK4630
|
||||
#include <NCP5623.h>
|
||||
#include <graphics/RAKled.h>
|
||||
NCP5623 rgb;
|
||||
|
||||
uint8_t red = 0;
|
||||
|
||||
@@ -3,6 +3,7 @@
|
||||
#include "NodeDB.h"
|
||||
#include "RTC.h"
|
||||
#include "Router.h"
|
||||
#include "TypeConversions.h"
|
||||
#include "airtime.h"
|
||||
#include "configuration.h"
|
||||
#include "gps/GeoCoord.h"
|
||||
@@ -56,55 +57,57 @@ bool PositionModule::handleReceivedProtobuf(const meshtastic_MeshPacket &mp, mes
|
||||
|
||||
meshtastic_MeshPacket *PositionModule::allocReply()
|
||||
{
|
||||
meshtastic_NodeInfo *node = service.refreshMyNodeInfo(); // should guarantee there is now a position
|
||||
meshtastic_NodeInfoLite *node = service.refreshLocalMeshNode(); // should guarantee there is now a position
|
||||
assert(node->has_position);
|
||||
|
||||
node->position.seq_number++;
|
||||
|
||||
// configuration of POSITION packet
|
||||
// consider making this a function argument?
|
||||
uint32_t pos_flags = config.position.position_flags;
|
||||
|
||||
// Populate a Position struct with ONLY the requested fields
|
||||
meshtastic_Position p = meshtastic_Position_init_default; // Start with an empty structure
|
||||
if (localPosition.latitude_i == 0 && localPosition.longitude_i == 0) {
|
||||
localPosition = ConvertToPosition(node->position);
|
||||
}
|
||||
localPosition.seq_number++;
|
||||
|
||||
// lat/lon are unconditionally included - IF AVAILABLE!
|
||||
p.latitude_i = node->position.latitude_i;
|
||||
p.longitude_i = node->position.longitude_i;
|
||||
p.time = node->position.time;
|
||||
p.latitude_i = localPosition.latitude_i;
|
||||
p.longitude_i = localPosition.longitude_i;
|
||||
p.time = localPosition.time;
|
||||
|
||||
if (pos_flags & meshtastic_Config_PositionConfig_PositionFlags_ALTITUDE) {
|
||||
if (pos_flags & meshtastic_Config_PositionConfig_PositionFlags_ALTITUDE_MSL)
|
||||
p.altitude = node->position.altitude;
|
||||
p.altitude = localPosition.altitude;
|
||||
else
|
||||
p.altitude_hae = node->position.altitude_hae;
|
||||
p.altitude_hae = localPosition.altitude_hae;
|
||||
|
||||
if (pos_flags & meshtastic_Config_PositionConfig_PositionFlags_GEOIDAL_SEPARATION)
|
||||
p.altitude_geoidal_separation = node->position.altitude_geoidal_separation;
|
||||
p.altitude_geoidal_separation = localPosition.altitude_geoidal_separation;
|
||||
}
|
||||
|
||||
if (pos_flags & meshtastic_Config_PositionConfig_PositionFlags_DOP) {
|
||||
if (pos_flags & meshtastic_Config_PositionConfig_PositionFlags_HVDOP) {
|
||||
p.HDOP = node->position.HDOP;
|
||||
p.VDOP = node->position.VDOP;
|
||||
p.HDOP = localPosition.HDOP;
|
||||
p.VDOP = localPosition.VDOP;
|
||||
} else
|
||||
p.PDOP = node->position.PDOP;
|
||||
p.PDOP = localPosition.PDOP;
|
||||
}
|
||||
|
||||
if (pos_flags & meshtastic_Config_PositionConfig_PositionFlags_SATINVIEW)
|
||||
p.sats_in_view = node->position.sats_in_view;
|
||||
p.sats_in_view = localPosition.sats_in_view;
|
||||
|
||||
if (pos_flags & meshtastic_Config_PositionConfig_PositionFlags_TIMESTAMP)
|
||||
p.timestamp = node->position.timestamp;
|
||||
p.timestamp = localPosition.timestamp;
|
||||
|
||||
if (pos_flags & meshtastic_Config_PositionConfig_PositionFlags_SEQ_NO)
|
||||
p.seq_number = node->position.seq_number;
|
||||
p.seq_number = localPosition.seq_number;
|
||||
|
||||
if (pos_flags & meshtastic_Config_PositionConfig_PositionFlags_HEADING)
|
||||
p.ground_track = node->position.ground_track;
|
||||
p.ground_track = localPosition.ground_track;
|
||||
|
||||
if (pos_flags & meshtastic_Config_PositionConfig_PositionFlags_SPEED)
|
||||
p.ground_speed = node->position.ground_speed;
|
||||
p.ground_speed = localPosition.ground_speed;
|
||||
|
||||
// Strip out any time information before sending packets to other nodes - to keep the wire size small (and because other
|
||||
// nodes shouldn't trust it anyways) Note: we allow a device with a local GPS to include the time, so that gpsless
|
||||
@@ -144,7 +147,7 @@ void PositionModule::sendOurPosition(NodeNum dest, bool wantReplies, uint8_t cha
|
||||
|
||||
int32_t PositionModule::runOnce()
|
||||
{
|
||||
meshtastic_NodeInfo *node = nodeDB.getNode(nodeDB.getNodeNum());
|
||||
meshtastic_NodeInfoLite *node = nodeDB.getMeshNode(nodeDB.getNodeNum());
|
||||
|
||||
// We limit our GPS broadcasts to a max rate
|
||||
uint32_t now = millis();
|
||||
@@ -164,14 +167,14 @@ int32_t PositionModule::runOnce()
|
||||
bool requestReplies = currentGeneration != radioGeneration;
|
||||
currentGeneration = radioGeneration;
|
||||
|
||||
LOG_INFO("Sending pos@%x:6 to mesh (wantReplies=%d)\n", node->position.timestamp, requestReplies);
|
||||
LOG_INFO("Sending pos@%x:6 to mesh (wantReplies=%d)\n", localPosition.timestamp, requestReplies);
|
||||
sendOurPosition(NODENUM_BROADCAST, requestReplies);
|
||||
}
|
||||
}
|
||||
} else if (config.position.position_broadcast_smart_enabled) {
|
||||
// Only send packets if the channel is less than 25% utilized or we're a tracker.
|
||||
if (airTime->isTxAllowedChannelUtil(config.device.role != meshtastic_Config_DeviceConfig_Role_TRACKER)) {
|
||||
meshtastic_NodeInfo *node2 = service.refreshMyNodeInfo(); // should guarantee there is now a position
|
||||
meshtastic_NodeInfoLite *node2 = service.refreshLocalMeshNode(); // should guarantee there is now a position
|
||||
|
||||
if (hasValidPosition(node2)) {
|
||||
// The minimum distance to travel before we are able to send a new position packet.
|
||||
@@ -193,7 +196,7 @@ int32_t PositionModule::runOnce()
|
||||
|
||||
LOG_INFO("Sending smart pos@%x:6 to mesh (distanceTraveled=%fm, minDistanceThreshold=%im, timeElapsed=%ims, "
|
||||
"minTimeInterval=%ims)\n",
|
||||
node2->position.timestamp, abs(distanceTraveledSinceLastSend), distanceTravelThreshold,
|
||||
localPosition.timestamp, abs(distanceTraveledSinceLastSend), distanceTravelThreshold,
|
||||
msSinceLastSend, minimumTimeThreshold);
|
||||
sendOurPosition(NODENUM_BROADCAST, requestReplies);
|
||||
|
||||
@@ -211,4 +214,4 @@ int32_t PositionModule::runOnce()
|
||||
}
|
||||
|
||||
return 5000; // to save power only wake for our callback occasionally
|
||||
}
|
||||
}
|
||||
@@ -138,7 +138,7 @@ ProcessMessage RangeTestModuleRadio::handleReceived(const meshtastic_MeshPacket
|
||||
}
|
||||
|
||||
/*
|
||||
NodeInfo *n = nodeDB.getNode(getFrom(&mp));
|
||||
NodeInfoLite *n = nodeDB.getMeshNode(getFrom(&mp));
|
||||
|
||||
LOG_DEBUG("-----------------------------------------\n");
|
||||
LOG_DEBUG("p.payload.bytes \"%s\"\n", p.payload.bytes);
|
||||
@@ -152,7 +152,6 @@ ProcessMessage RangeTestModuleRadio::handleReceived(const meshtastic_MeshPacket
|
||||
LOG_DEBUG("---- Node Information of Received Packet (mp.from):\n");
|
||||
LOG_DEBUG("n->user.long_name %s\n", n->user.long_name);
|
||||
LOG_DEBUG("n->user.short_name %s\n", n->user.short_name);
|
||||
LOG_DEBUG("n->user.macaddr %X\n", n->user.macaddr);
|
||||
LOG_DEBUG("n->has_position %d\n", n->has_position);
|
||||
LOG_DEBUG("n->position.latitude_i %d\n", n->position.latitude_i);
|
||||
LOG_DEBUG("n->position.longitude_i %d\n", n->position.longitude_i);
|
||||
@@ -178,7 +177,7 @@ bool RangeTestModuleRadio::appendFile(const meshtastic_MeshPacket &mp)
|
||||
#ifdef ARCH_ESP32
|
||||
auto &p = mp.decoded;
|
||||
|
||||
meshtastic_NodeInfo *n = nodeDB.getNode(getFrom(&mp));
|
||||
meshtastic_NodeInfoLite *n = nodeDB.getMeshNode(getFrom(&mp));
|
||||
/*
|
||||
LOG_DEBUG("-----------------------------------------\n");
|
||||
LOG_DEBUG("p.payload.bytes \"%s\"\n", p.payload.bytes);
|
||||
@@ -192,7 +191,6 @@ bool RangeTestModuleRadio::appendFile(const meshtastic_MeshPacket &mp)
|
||||
LOG_DEBUG("---- Node Information of Received Packet (mp.from):\n");
|
||||
LOG_DEBUG("n->user.long_name %s\n", n->user.long_name);
|
||||
LOG_DEBUG("n->user.short_name %s\n", n->user.short_name);
|
||||
LOG_DEBUG("n->user.macaddr %X\n", n->user.macaddr);
|
||||
LOG_DEBUG("n->has_position %d\n", n->has_position);
|
||||
LOG_DEBUG("n->position.latitude_i %d\n", n->position.latitude_i);
|
||||
LOG_DEBUG("n->position.longitude_i %d\n", n->position.longitude_i);
|
||||
@@ -286,4 +284,4 @@ bool RangeTestModuleRadio::appendFile(const meshtastic_MeshPacket &mp)
|
||||
#endif
|
||||
|
||||
return 1;
|
||||
}
|
||||
}
|
||||
@@ -161,18 +161,18 @@ int32_t SerialModule::runOnce()
|
||||
// in NMEA mode send out GGA every 2 seconds, Don't read from Port
|
||||
if (millis() - lastNmeaTime > 2000) {
|
||||
lastNmeaTime = millis();
|
||||
printGGA(outbuf, sizeof(outbuf), nodeDB.getNode(myNodeInfo.my_node_num)->position);
|
||||
printGGA(outbuf, sizeof(outbuf), localPosition);
|
||||
serialPrint->printf("%s", outbuf);
|
||||
}
|
||||
} else if (moduleConfig.serial.mode == meshtastic_ModuleConfig_SerialConfig_Serial_Mode_CALTOPO) {
|
||||
if (millis() - lastNmeaTime > 10000) {
|
||||
lastNmeaTime = millis();
|
||||
uint32_t readIndex = 0;
|
||||
const meshtastic_NodeInfo *tempNodeInfo = nodeDB.readNextInfo(readIndex);
|
||||
const meshtastic_NodeInfoLite *tempNodeInfo = nodeDB.readNextMeshNode(readIndex);
|
||||
while (tempNodeInfo != NULL && tempNodeInfo->has_user && hasValidPosition(tempNodeInfo)) {
|
||||
printWPL(outbuf, sizeof(outbuf), tempNodeInfo->position, tempNodeInfo->user.long_name, true);
|
||||
serialPrint->printf("%s", outbuf);
|
||||
tempNodeInfo = nodeDB.readNextInfo(readIndex);
|
||||
tempNodeInfo = nodeDB.readNextMeshNode(readIndex);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -251,7 +251,7 @@ ProcessMessage SerialModuleRadio::handleReceived(const meshtastic_MeshPacket &mp
|
||||
moduleConfig.serial.mode == meshtastic_ModuleConfig_SerialConfig_Serial_Mode_SIMPLE) {
|
||||
serialPrint->printf("%s", p.payload.bytes);
|
||||
} else if (moduleConfig.serial.mode == meshtastic_ModuleConfig_SerialConfig_Serial_Mode_TEXTMSG) {
|
||||
meshtastic_NodeInfo *node = nodeDB.getNode(getFrom(&mp));
|
||||
meshtastic_NodeInfoLite *node = nodeDB.getMeshNode(getFrom(&mp));
|
||||
String sender = (node && node->has_user) ? node->user.short_name : "???";
|
||||
serialPrint->println();
|
||||
serialPrint->printf("%s: %s", sender, p.payload.bytes);
|
||||
@@ -267,7 +267,7 @@ ProcessMessage SerialModuleRadio::handleReceived(const meshtastic_MeshPacket &mp
|
||||
decoded = &scratch;
|
||||
}
|
||||
// send position packet as WPL to the serial port
|
||||
printWPL(outbuf, sizeof(outbuf), *decoded, nodeDB.getNode(getFrom(&mp))->user.long_name,
|
||||
printWPL(outbuf, sizeof(outbuf), *decoded, nodeDB.getMeshNode(getFrom(&mp))->user.long_name,
|
||||
moduleConfig.serial.mode == meshtastic_ModuleConfig_SerialConfig_Serial_Mode_CALTOPO);
|
||||
serialPrint->printf("%s", outbuf);
|
||||
}
|
||||
@@ -312,4 +312,4 @@ uint32_t SerialModule::getBaudRate()
|
||||
}
|
||||
return BAUD;
|
||||
}
|
||||
#endif
|
||||
#endif
|
||||
@@ -50,14 +50,14 @@ bool DeviceTelemetryModule::sendTelemetry(NodeNum dest, bool phoneOnly)
|
||||
t.time = getTime();
|
||||
t.which_variant = meshtastic_Telemetry_device_metrics_tag;
|
||||
|
||||
t.variant.device_metrics.air_util_tx = myNodeInfo.air_util_tx;
|
||||
t.variant.device_metrics.air_util_tx = airTime->utilizationTXPercent();
|
||||
if (powerStatus->getIsCharging()) {
|
||||
t.variant.device_metrics.battery_level = MAGIC_USB_BATTERY_LEVEL;
|
||||
} else {
|
||||
t.variant.device_metrics.battery_level = powerStatus->getBatteryChargePercent();
|
||||
}
|
||||
|
||||
t.variant.device_metrics.channel_utilization = myNodeInfo.channel_utilization;
|
||||
t.variant.device_metrics.channel_utilization = airTime->channelUtilizationPercent();
|
||||
t.variant.device_metrics.voltage = powerStatus->getBatteryVoltageMv() / 1000.0;
|
||||
|
||||
LOG_INFO("(Sending): air_util_tx=%f, channel_utilization=%f, battery_level=%i, voltage=%f\n",
|
||||
@@ -78,4 +78,4 @@ bool DeviceTelemetryModule::sendTelemetry(NodeNum dest, bool phoneOnly)
|
||||
service.sendToMesh(p, RX_SRC_LOCAL, true);
|
||||
}
|
||||
return true;
|
||||
}
|
||||
}
|
||||
@@ -36,8 +36,6 @@ int32_t StoreForwardModule::runOnce()
|
||||
this->packetHistoryTXQueue_index++;
|
||||
}
|
||||
}
|
||||
LOG_DEBUG("*** SF bitrate = %f bytes / sec\n", myNodeInfo.bitrate);
|
||||
|
||||
} else if ((millis() - lastHeartbeat > (heartbeatInterval * 1000)) && airTime->isTxAllowedChannelUtil(true)) {
|
||||
lastHeartbeat = millis();
|
||||
LOG_INFO("*** Sending heartbeat\n");
|
||||
@@ -266,7 +264,6 @@ ProcessMessage StoreForwardModule::handleReceived(const meshtastic_MeshPacket &m
|
||||
storeForwardModule->historyAdd(mp);
|
||||
LOG_INFO("*** S&F stored. Message history contains %u records now.\n", this->packetHistoryCurrent);
|
||||
}
|
||||
|
||||
} else if (mp.decoded.portnum == meshtastic_PortNum_STORE_FORWARD_APP) {
|
||||
auto &p = mp.decoded;
|
||||
meshtastic_StoreAndForward scratch;
|
||||
|
||||
@@ -172,6 +172,10 @@ void cpuDeepSleep(uint32_t msecToWake)
|
||||
setBluetoothEnable(false);
|
||||
#ifdef RAK4630
|
||||
digitalWrite(PIN_3V3_EN, LOW);
|
||||
#ifndef USE_EINK
|
||||
// RAK-12039 set pin for Air quality sensor
|
||||
digitalWrite(AQ_SET_PIN, LOW);
|
||||
#endif
|
||||
#endif
|
||||
// FIXME, use system off mode with ram retention for key state?
|
||||
// FIXME, use non-init RAM per
|
||||
@@ -197,4 +201,4 @@ void clearBonds()
|
||||
nrf52Bluetooth->setup();
|
||||
}
|
||||
nrf52Bluetooth->clearBonds();
|
||||
}
|
||||
}
|
||||
@@ -14,6 +14,7 @@
|
||||
#undef GPS_SERIAL_NUM
|
||||
|
||||
#define LED_CONN PIN_LED2
|
||||
#define LED_PIN LED_BUILTIN
|
||||
|
||||
#define BUTTON_PIN 9
|
||||
#define BUTTON_NEED_PULLUP
|
||||
|
||||
@@ -258,6 +258,7 @@ SO GPIO 39/TXEN MAY NOT BE DEFINED FOR SUCCESSFUL OPERATION OF THE SX1262 - TG
|
||||
#define PIN_ETHERNET_RESET 21
|
||||
#define PIN_ETHERNET_SS PIN_EINK_CS
|
||||
#define ETH_SPI_PORT SPI1
|
||||
#define AQ_SET_PIN 10
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
@@ -267,4 +268,4 @@ SO GPIO 39/TXEN MAY NOT BE DEFINED FOR SUCCESSFUL OPERATION OF THE SX1262 - TG
|
||||
* Arduino objects - C++ only
|
||||
*----------------------------------------------------------------------------*/
|
||||
|
||||
#endif
|
||||
#endif
|
||||
@@ -1,4 +1,4 @@
|
||||
[VERSION]
|
||||
major = 2
|
||||
minor = 1
|
||||
build = 15
|
||||
build = 17
|
||||
|
||||
Reference in New Issue
Block a user