mirror of
https://github.com/meshtastic/firmware.git
synced 2025-09-19 00:16:59 +00:00
Merge branch 'master' into esp32-c6
This commit is contained in:
commit
cb1cf055b1
2
.github/workflows/build_stm32.yml
vendored
2
.github/workflows/build_stm32.yml
vendored
@ -13,7 +13,7 @@ jobs:
|
|||||||
steps:
|
steps:
|
||||||
- uses: actions/checkout@v4
|
- uses: actions/checkout@v4
|
||||||
|
|
||||||
- name: Build Raspberry Pi 2040
|
- name: Build STM32WL
|
||||||
id: build
|
id: build
|
||||||
uses: ./.github/actions/build-variant
|
uses: ./.github/actions/build-variant
|
||||||
with:
|
with:
|
||||||
|
2
.github/workflows/main_matrix.yml
vendored
2
.github/workflows/main_matrix.yml
vendored
@ -32,7 +32,7 @@ jobs:
|
|||||||
name: Checkout base
|
name: Checkout base
|
||||||
- id: jsonStep
|
- id: jsonStep
|
||||||
run: |
|
run: |
|
||||||
TARGETS=$(./bin/generate_ci_matrix.py ${{matrix.arch}})
|
TARGETS=$(./bin/generate_ci_matrix.py ${{matrix.arch}} quick)
|
||||||
echo "$TARGETS"
|
echo "$TARGETS"
|
||||||
echo "${{matrix.arch}}=$(jq -cn --argjson environments "$TARGETS" '{board: $environments}')" >> $GITHUB_OUTPUT
|
echo "${{matrix.arch}}=$(jq -cn --argjson environments "$TARGETS" '{board: $environments}')" >> $GITHUB_OUTPUT
|
||||||
outputs:
|
outputs:
|
||||||
|
@ -6,6 +6,7 @@ import configparser
|
|||||||
import json
|
import json
|
||||||
import os
|
import os
|
||||||
import sys
|
import sys
|
||||||
|
import random
|
||||||
|
|
||||||
rootdir = "variants/"
|
rootdir = "variants/"
|
||||||
|
|
||||||
@ -39,5 +40,7 @@ for subdir, dirs, files in os.walk(rootdir):
|
|||||||
"check" in options
|
"check" in options
|
||||||
):
|
):
|
||||||
outlist.append(section)
|
outlist.append(section)
|
||||||
|
if ("quick" in options) & (len(outlist) > 3):
|
||||||
print(json.dumps(outlist))
|
print(json.dumps(random.sample(outlist, 3)))
|
||||||
|
else:
|
||||||
|
print(json.dumps(outlist))
|
||||||
|
@ -88,7 +88,9 @@ monitor_speed = 115200
|
|||||||
monitor_filters = direct
|
monitor_filters = direct
|
||||||
|
|
||||||
lib_deps =
|
lib_deps =
|
||||||
jgromes/RadioLib@~7.0.0
|
;jgromes/RadioLib@~7.0.0
|
||||||
|
;7.0.1pre needed for LR1121 support and SX127x CRC Bugfix
|
||||||
|
https://github.com/jgromes/RadioLib.git#42ae7c92ed584317d7206cfc463ba6260295dbbc
|
||||||
https://github.com/meshtastic/esp8266-oled-ssd1306.git#e16cee124fe26490cb14880c679321ad8ac89c95 ; ESP8266_SSD1306
|
https://github.com/meshtastic/esp8266-oled-ssd1306.git#e16cee124fe26490cb14880c679321ad8ac89c95 ; ESP8266_SSD1306
|
||||||
https://github.com/mathertel/OneButton@~2.6.1 ; OneButton library for non-blocking button debounce
|
https://github.com/mathertel/OneButton@~2.6.1 ; OneButton library for non-blocking button debounce
|
||||||
https://github.com/meshtastic/arduino-fsm.git#7db3702bf0cfe97b783d6c72595e3f38e0b19159
|
https://github.com/meshtastic/arduino-fsm.git#7db3702bf0cfe97b783d6c72595e3f38e0b19159
|
||||||
|
@ -24,7 +24,7 @@
|
|||||||
class SafeFile : public Print
|
class SafeFile : public Print
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
SafeFile(char const *filepath, bool fullAtomic = false);
|
explicit SafeFile(char const *filepath, bool fullAtomic = false);
|
||||||
|
|
||||||
virtual size_t write(uint8_t);
|
virtual size_t write(uint8_t);
|
||||||
virtual size_t write(const uint8_t *buffer, size_t size);
|
virtual size_t write(const uint8_t *buffer, size_t size);
|
||||||
|
@ -406,9 +406,9 @@ int GPS::getACK(uint8_t *buffer, uint16_t size, uint8_t requestedClass, uint8_t
|
|||||||
|
|
||||||
bool GPS::setup()
|
bool GPS::setup()
|
||||||
{
|
{
|
||||||
int msglen = 0;
|
|
||||||
|
|
||||||
if (!didSerialInit) {
|
if (!didSerialInit) {
|
||||||
|
int msglen = 0;
|
||||||
if (tx_gpio && gnssModel == GNSS_MODEL_UNKNOWN) {
|
if (tx_gpio && gnssModel == GNSS_MODEL_UNKNOWN) {
|
||||||
|
|
||||||
// if GPS_BAUDRATE is specified in variant (i.e. not 9600), skip to the specified rate.
|
// if GPS_BAUDRATE is specified in variant (i.e. not 9600), skip to the specified rate.
|
||||||
|
@ -2201,7 +2201,7 @@ void Screen::setFrames(FrameFocus focus)
|
|||||||
|
|
||||||
case FOCUS_PRESERVE:
|
case FOCUS_PRESERVE:
|
||||||
// If we can identify which type of frame "originalPosition" was, can move directly to it in the new frameset
|
// If we can identify which type of frame "originalPosition" was, can move directly to it in the new frameset
|
||||||
FramesetInfo &oldFsi = this->framesetInfo;
|
const FramesetInfo &oldFsi = this->framesetInfo;
|
||||||
if (originalPosition == oldFsi.positions.log)
|
if (originalPosition == oldFsi.positions.log)
|
||||||
ui->switchToFrame(fsi.positions.log);
|
ui->switchToFrame(fsi.positions.log);
|
||||||
else if (originalPosition == oldFsi.positions.settings)
|
else if (originalPosition == oldFsi.positions.settings)
|
||||||
|
@ -976,7 +976,7 @@ void setup()
|
|||||||
|
|
||||||
#if defined(USE_LR1110)
|
#if defined(USE_LR1110)
|
||||||
if (!rIf) {
|
if (!rIf) {
|
||||||
rIf = new LR1110Interface(RadioLibHAL, LR1110_SPI_NSS_PIN, LR1110_IRQ_PIN, LR1110_NRESER_PIN, LR1110_BUSY_PIN);
|
rIf = new LR1110Interface(RadioLibHAL, LR1110_SPI_NSS_PIN, LR1110_IRQ_PIN, LR1110_NRESET_PIN, LR1110_BUSY_PIN);
|
||||||
if (!rIf->init()) {
|
if (!rIf->init()) {
|
||||||
LOG_WARN("Failed to find LR1110 radio\n");
|
LOG_WARN("Failed to find LR1110 radio\n");
|
||||||
delete rIf;
|
delete rIf;
|
||||||
@ -989,7 +989,7 @@ void setup()
|
|||||||
|
|
||||||
#if defined(USE_LR1120)
|
#if defined(USE_LR1120)
|
||||||
if (!rIf) {
|
if (!rIf) {
|
||||||
rIf = new LR1120Interface(RadioLibHAL, LR1120_SPI_NSS_PIN, LR1120_IRQ_PIN, LR1120_NRESER_PIN, LR1120_BUSY_PIN);
|
rIf = new LR1120Interface(RadioLibHAL, LR1120_SPI_NSS_PIN, LR1120_IRQ_PIN, LR1120_NRESET_PIN, LR1120_BUSY_PIN);
|
||||||
if (!rIf->init()) {
|
if (!rIf->init()) {
|
||||||
LOG_WARN("Failed to find LR1120 radio\n");
|
LOG_WARN("Failed to find LR1120 radio\n");
|
||||||
delete rIf;
|
delete rIf;
|
||||||
|
@ -70,8 +70,9 @@ bool CryptoEngine::encryptCurve25519(uint32_t toNode, uint32_t fromNode, uint64_
|
|||||||
long extraNonceTmp = random();
|
long extraNonceTmp = random();
|
||||||
auth = bytesOut + numBytes;
|
auth = bytesOut + numBytes;
|
||||||
extraNonce = (uint32_t *)(auth + 8);
|
extraNonce = (uint32_t *)(auth + 8);
|
||||||
*extraNonce = extraNonceTmp;
|
memcpy(extraNonce, &extraNonceTmp,
|
||||||
LOG_INFO("Random nonce value: %d\n", *extraNonce);
|
4); // do not use dereference on potential non aligned pointers : *extraNonce = extraNonceTmp;
|
||||||
|
LOG_INFO("Random nonce value: %d\n", extraNonceTmp);
|
||||||
meshtastic_NodeInfoLite *node = nodeDB->getMeshNode(toNode);
|
meshtastic_NodeInfoLite *node = nodeDB->getMeshNode(toNode);
|
||||||
if (node->num < 1 || node->user.public_key.size == 0) {
|
if (node->num < 1 || node->user.public_key.size == 0) {
|
||||||
LOG_DEBUG("Node %d or their public_key not found\n", toNode);
|
LOG_DEBUG("Node %d or their public_key not found\n", toNode);
|
||||||
@ -80,14 +81,15 @@ bool CryptoEngine::encryptCurve25519(uint32_t toNode, uint32_t fromNode, uint64_
|
|||||||
if (!crypto->setDHKey(toNode)) {
|
if (!crypto->setDHKey(toNode)) {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
initNonce(fromNode, packetNum, *extraNonce);
|
initNonce(fromNode, packetNum, extraNonceTmp);
|
||||||
|
|
||||||
// Calculate the shared secret with the destination node and encrypt
|
// Calculate the shared secret with the destination node and encrypt
|
||||||
printBytes("Attempting encrypt using nonce: ", nonce, 13);
|
printBytes("Attempting encrypt using nonce: ", nonce, 13);
|
||||||
printBytes("Attempting encrypt using shared_key starting with: ", shared_key, 8);
|
printBytes("Attempting encrypt using shared_key starting with: ", shared_key, 8);
|
||||||
aes_ccm_ae(shared_key, 32, nonce, 8, bytes, numBytes, nullptr, 0, bytesOut,
|
aes_ccm_ae(shared_key, 32, nonce, 8, bytes, numBytes, nullptr, 0, bytesOut,
|
||||||
auth); // this can write up to 15 bytes longer than numbytes past bytesOut
|
auth); // this can write up to 15 bytes longer than numbytes past bytesOut
|
||||||
*extraNonce = extraNonceTmp;
|
memcpy(extraNonce, &extraNonceTmp,
|
||||||
|
4); // do not use dereference on potential non aligned pointers : *extraNonce = extraNonceTmp;
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -100,10 +102,11 @@ bool CryptoEngine::encryptCurve25519(uint32_t toNode, uint32_t fromNode, uint64_
|
|||||||
bool CryptoEngine::decryptCurve25519(uint32_t fromNode, uint64_t packetNum, size_t numBytes, uint8_t *bytes, uint8_t *bytesOut)
|
bool CryptoEngine::decryptCurve25519(uint32_t fromNode, uint64_t packetNum, size_t numBytes, uint8_t *bytes, uint8_t *bytesOut)
|
||||||
{
|
{
|
||||||
uint8_t *auth; // set to last 8 bytes of text?
|
uint8_t *auth; // set to last 8 bytes of text?
|
||||||
uint32_t *extraNonce;
|
uint32_t extraNonce; // pointer was not really used
|
||||||
auth = bytes + numBytes - 12;
|
auth = bytes + numBytes - 12;
|
||||||
extraNonce = (uint32_t *)(auth + 8);
|
#ifndef PIO_UNIT_TESTING
|
||||||
LOG_INFO("Random nonce value: %d\n", *extraNonce);
|
memcpy(&extraNonce, auth + 8, 4); // do not use dereference on potential non aligned pointers : (uint32_t *)(auth + 8);
|
||||||
|
LOG_INFO("Random nonce value: %d\n", extraNonce);
|
||||||
meshtastic_NodeInfoLite *node = nodeDB->getMeshNode(fromNode);
|
meshtastic_NodeInfoLite *node = nodeDB->getMeshNode(fromNode);
|
||||||
|
|
||||||
if (node == nullptr || node->num < 1 || node->user.public_key.size == 0) {
|
if (node == nullptr || node->num < 1 || node->user.public_key.size == 0) {
|
||||||
@ -115,7 +118,8 @@ bool CryptoEngine::decryptCurve25519(uint32_t fromNode, uint64_t packetNum, size
|
|||||||
if (!crypto->setDHKey(fromNode)) {
|
if (!crypto->setDHKey(fromNode)) {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
initNonce(fromNode, packetNum, *extraNonce);
|
#endif
|
||||||
|
initNonce(fromNode, packetNum, extraNonce);
|
||||||
printBytes("Attempting decrypt using nonce: ", nonce, 13);
|
printBytes("Attempting decrypt using nonce: ", nonce, 13);
|
||||||
printBytes("Attempting decrypt using shared_key starting with: ", shared_key, 8);
|
printBytes("Attempting decrypt using shared_key starting with: ", shared_key, 8);
|
||||||
return aes_ccm_ad(shared_key, 32, nonce, 8, bytes, numBytes - 12, nullptr, 0, auth, bytesOut);
|
return aes_ccm_ad(shared_key, 32, nonce, 8, bytes, numBytes - 12, nullptr, 0, auth, bytesOut);
|
||||||
@ -167,12 +171,12 @@ bool CryptoEngine::setDHKey(uint32_t nodeNum)
|
|||||||
void CryptoEngine::hash(uint8_t *bytes, size_t numBytes)
|
void CryptoEngine::hash(uint8_t *bytes, size_t numBytes)
|
||||||
{
|
{
|
||||||
SHA256 hash;
|
SHA256 hash;
|
||||||
size_t posn, len;
|
size_t posn;
|
||||||
uint8_t size = numBytes;
|
uint8_t size = numBytes;
|
||||||
uint8_t inc = 16;
|
uint8_t inc = 16;
|
||||||
hash.reset();
|
hash.reset();
|
||||||
for (posn = 0; posn < size; posn += inc) {
|
for (posn = 0; posn < size; posn += inc) {
|
||||||
len = size - posn;
|
size_t len = size - posn;
|
||||||
if (len > inc)
|
if (len > inc)
|
||||||
len = inc;
|
len = inc;
|
||||||
hash.update(bytes + posn, len);
|
hash.update(bytes + posn, len);
|
||||||
|
@ -108,7 +108,7 @@ template <class T> class ProtobufModule : protected SinglePortModule
|
|||||||
T *decoded = NULL;
|
T *decoded = NULL;
|
||||||
if (mp.which_payload_variant == meshtastic_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));
|
||||||
auto &p = mp.decoded;
|
const meshtastic_Data &p = mp.decoded;
|
||||||
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;
|
||||||
} else {
|
} else {
|
||||||
|
@ -36,8 +36,8 @@ static MemoryDynamic<meshtastic_MeshPacket> staticPool;
|
|||||||
|
|
||||||
Allocator<meshtastic_MeshPacket> &packetPool = staticPool;
|
Allocator<meshtastic_MeshPacket> &packetPool = staticPool;
|
||||||
|
|
||||||
static uint8_t bytes[MAX_LORA_PAYLOAD_LEN + 1];
|
static uint8_t bytes[MAX_LORA_PAYLOAD_LEN + 1] __attribute__ ((__aligned__));
|
||||||
static uint8_t ScratchEncrypted[MAX_LORA_PAYLOAD_LEN + 1];
|
static uint8_t ScratchEncrypted[MAX_LORA_PAYLOAD_LEN + 1] __attribute__ ((__aligned__));
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Constructor
|
* Constructor
|
||||||
|
@ -95,7 +95,7 @@ static void aes_ccm_encr(size_t L, const uint8_t *in, size_t len, uint8_t *out,
|
|||||||
*out++ ^= *in++;
|
*out++ ^= *in++;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
static void aes_ccm_encr_auth(size_t M, uint8_t *x, uint8_t *a, uint8_t *auth)
|
static void aes_ccm_encr_auth(size_t M, const uint8_t *x, uint8_t *a, uint8_t *auth)
|
||||||
{
|
{
|
||||||
size_t i;
|
size_t i;
|
||||||
uint8_t tmp[AES_BLOCK_SIZE];
|
uint8_t tmp[AES_BLOCK_SIZE];
|
||||||
|
@ -339,7 +339,7 @@ int32_t readUTF8(const char *in, int len, int l, int *utf8len)
|
|||||||
/// This is also used for Unicode strings \n
|
/// This is also used for Unicode strings \n
|
||||||
/// This is a crude implementation that is not optimized. Assuming only short strings \n
|
/// This is a crude implementation that is not optimized. Assuming only short strings \n
|
||||||
/// are encoded, this is not much of an issue.
|
/// are encoded, this is not much of an issue.
|
||||||
int matchOccurance(const char *in, int len, int l, char *out, int olen, int *ol, uint8_t *state, const uint8_t usx_hcodes[],
|
int matchOccurance(const char *in, int len, int l, char *out, int olen, int *ol, const uint8_t *state, const uint8_t usx_hcodes[],
|
||||||
const uint8_t usx_hcode_lens[])
|
const uint8_t usx_hcode_lens[])
|
||||||
{
|
{
|
||||||
int j, k;
|
int j, k;
|
||||||
@ -383,7 +383,7 @@ int matchOccurance(const char *in, int len, int l, char *out, int olen, int *ol,
|
|||||||
/// This is also used for Unicode strings \n
|
/// This is also used for Unicode strings \n
|
||||||
/// This is a crude implementation that is not optimized. Assuming only short strings \n
|
/// This is a crude implementation that is not optimized. Assuming only short strings \n
|
||||||
/// are encoded, this is not much of an issue.
|
/// are encoded, this is not much of an issue.
|
||||||
int matchLine(const char *in, int len, int l, char *out, int olen, int *ol, struct us_lnk_lst *prev_lines, uint8_t *state,
|
int matchLine(const char *in, int len, int l, char *out, int olen, int *ol, struct us_lnk_lst *prev_lines, const uint8_t *state,
|
||||||
const uint8_t usx_hcodes[], const uint8_t usx_hcode_lens[])
|
const uint8_t usx_hcodes[], const uint8_t usx_hcode_lens[])
|
||||||
{
|
{
|
||||||
int last_ol = *ol;
|
int last_ol = *ol;
|
||||||
|
@ -60,16 +60,15 @@ char *strnstr(const char *s, const char *find, size_t slen)
|
|||||||
|
|
||||||
void printBytes(const char *label, const uint8_t *p, size_t numbytes)
|
void printBytes(const char *label, const uint8_t *p, size_t numbytes)
|
||||||
{
|
{
|
||||||
char *messageBuffer;
|
|
||||||
int labelSize = strlen(label);
|
int labelSize = strlen(label);
|
||||||
if (labelSize < 100 && numbytes < 64) {
|
if (labelSize < 100 && numbytes < 64) {
|
||||||
messageBuffer = new char[labelSize + (numbytes * 3) + 2];
|
char *messageBuffer = new char[labelSize + (numbytes * 3) + 2];
|
||||||
strncpy(messageBuffer, label, labelSize);
|
strncpy(messageBuffer, label, labelSize);
|
||||||
for (size_t i = 0; i < numbytes; i++)
|
for (size_t i = 0; i < numbytes; i++)
|
||||||
snprintf(messageBuffer + labelSize + i * 3, 4, " %02x", p[i]);
|
snprintf(messageBuffer + labelSize + i * 3, 4, " %02x", p[i]);
|
||||||
strcpy(messageBuffer + labelSize + numbytes * 3, "\n");
|
strcpy(messageBuffer + labelSize + numbytes * 3, "\n");
|
||||||
LOG_DEBUG(messageBuffer);
|
LOG_DEBUG(messageBuffer);
|
||||||
delete messageBuffer;
|
delete[] messageBuffer;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1026,7 +1026,7 @@ bool AdminModule::checkPassKey(meshtastic_AdminMessage *res)
|
|||||||
memcmp(res->session_passkey.bytes, session_passkey, 8) == 0);
|
memcmp(res->session_passkey.bytes, session_passkey, 8) == 0);
|
||||||
}
|
}
|
||||||
|
|
||||||
bool AdminModule::messageIsResponse(meshtastic_AdminMessage *r)
|
bool AdminModule::messageIsResponse(const meshtastic_AdminMessage *r)
|
||||||
{
|
{
|
||||||
if (r->which_payload_variant == meshtastic_AdminMessage_get_channel_response_tag ||
|
if (r->which_payload_variant == meshtastic_AdminMessage_get_channel_response_tag ||
|
||||||
r->which_payload_variant == meshtastic_AdminMessage_get_owner_response_tag ||
|
r->which_payload_variant == meshtastic_AdminMessage_get_owner_response_tag ||
|
||||||
@ -1043,7 +1043,7 @@ bool AdminModule::messageIsResponse(meshtastic_AdminMessage *r)
|
|||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool AdminModule::messageIsRequest(meshtastic_AdminMessage *r)
|
bool AdminModule::messageIsRequest(const meshtastic_AdminMessage *r)
|
||||||
{
|
{
|
||||||
if (r->which_payload_variant == meshtastic_AdminMessage_get_channel_request_tag ||
|
if (r->which_payload_variant == meshtastic_AdminMessage_get_channel_request_tag ||
|
||||||
r->which_payload_variant == meshtastic_AdminMessage_get_owner_request_tag ||
|
r->which_payload_variant == meshtastic_AdminMessage_get_owner_request_tag ||
|
||||||
|
@ -55,8 +55,8 @@ class AdminModule : public ProtobufModule<meshtastic_AdminMessage>, public Obser
|
|||||||
void setPassKey(meshtastic_AdminMessage *res);
|
void setPassKey(meshtastic_AdminMessage *res);
|
||||||
bool checkPassKey(meshtastic_AdminMessage *res);
|
bool checkPassKey(meshtastic_AdminMessage *res);
|
||||||
|
|
||||||
bool messageIsResponse(meshtastic_AdminMessage *r);
|
bool messageIsResponse(const meshtastic_AdminMessage *r);
|
||||||
bool messageIsRequest(meshtastic_AdminMessage *r);
|
bool messageIsRequest(const meshtastic_AdminMessage *r);
|
||||||
};
|
};
|
||||||
|
|
||||||
extern AdminModule *adminModule;
|
extern AdminModule *adminModule;
|
||||||
|
@ -78,16 +78,16 @@ int CannedMessageModule::splitConfiguredMessages()
|
|||||||
int messageIndex = 0;
|
int messageIndex = 0;
|
||||||
int i = 0;
|
int i = 0;
|
||||||
|
|
||||||
String messages = cannedMessageModuleConfig.messages;
|
String canned_messages = cannedMessageModuleConfig.messages;
|
||||||
|
|
||||||
#if defined(T_WATCH_S3) || defined(RAK14014)
|
#if defined(T_WATCH_S3) || defined(RAK14014)
|
||||||
String separator = messages.length() ? "|" : "";
|
String separator = canned_messages.length() ? "|" : "";
|
||||||
|
|
||||||
messages = "[---- Free Text ----]" + separator + messages;
|
canned_messages = "[---- Free Text ----]" + separator + canned_messages;
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
// collect all the message parts
|
// collect all the message parts
|
||||||
strncpy(this->messageStore, messages.c_str(), sizeof(this->messageStore));
|
strncpy(this->messageStore, canned_messages.c_str(), sizeof(this->messageStore));
|
||||||
|
|
||||||
// The first message points to the beginning of the store.
|
// The first message points to the beginning of the store.
|
||||||
this->messages[messageIndex++] = this->messageStore;
|
this->messages[messageIndex++] = this->messageStore;
|
||||||
|
@ -216,7 +216,7 @@ void EnvironmentTelemetryModule::drawFrame(OLEDDisplay *display, OLEDDisplayUiSt
|
|||||||
uint32_t agoSecs = GetTimeSinceMeshPacket(lastMeasurementPacket);
|
uint32_t agoSecs = GetTimeSinceMeshPacket(lastMeasurementPacket);
|
||||||
const char *lastSender = getSenderShortName(*lastMeasurementPacket);
|
const char *lastSender = getSenderShortName(*lastMeasurementPacket);
|
||||||
|
|
||||||
auto &p = lastMeasurementPacket->decoded;
|
const meshtastic_Data &p = lastMeasurementPacket->decoded;
|
||||||
if (!pb_decode_from_bytes(p.payload.bytes, p.payload.size, &meshtastic_Telemetry_msg, &lastMeasurement)) {
|
if (!pb_decode_from_bytes(p.payload.bytes, p.payload.size, &meshtastic_Telemetry_msg, &lastMeasurement)) {
|
||||||
display->drawString(x, y, "Measurement Error");
|
display->drawString(x, y, "Measurement Error");
|
||||||
LOG_ERROR("Unable to decode last packet");
|
LOG_ERROR("Unable to decode last packet");
|
||||||
|
@ -122,7 +122,7 @@ void PowerTelemetryModule::drawFrame(OLEDDisplay *display, OLEDDisplayUiState *s
|
|||||||
uint32_t agoSecs = GetTimeyWimeySinceMeshPacket(lastMeasurementPacket);
|
uint32_t agoSecs = GetTimeyWimeySinceMeshPacket(lastMeasurementPacket);
|
||||||
const char *lastSender = getSenderShortName(*lastMeasurementPacket);
|
const char *lastSender = getSenderShortName(*lastMeasurementPacket);
|
||||||
|
|
||||||
auto &p = lastMeasurementPacket->decoded;
|
const meshtastic_Data &p = lastMeasurementPacket->decoded;
|
||||||
if (!pb_decode_from_bytes(p.payload.bytes, p.payload.size, &meshtastic_Telemetry_msg, &lastMeasurement)) {
|
if (!pb_decode_from_bytes(p.payload.bytes, p.payload.size, &meshtastic_Telemetry_msg, &lastMeasurement)) {
|
||||||
display->setFont(FONT_SMALL);
|
display->setFont(FONT_SMALL);
|
||||||
display->drawString(x, y += _fontHeight(FONT_MEDIUM), "Measurement Error");
|
display->drawString(x, y += _fontHeight(FONT_MEDIUM), "Measurement Error");
|
||||||
|
@ -11,7 +11,7 @@ bool TraceRouteModule::handleReceivedProtobuf(const meshtastic_MeshPacket &mp, m
|
|||||||
|
|
||||||
void TraceRouteModule::alterReceivedProtobuf(meshtastic_MeshPacket &p, meshtastic_RouteDiscovery *r)
|
void TraceRouteModule::alterReceivedProtobuf(meshtastic_MeshPacket &p, meshtastic_RouteDiscovery *r)
|
||||||
{
|
{
|
||||||
auto &incoming = p.decoded;
|
const meshtastic_Data &incoming = p.decoded;
|
||||||
|
|
||||||
// Insert unknown hops if necessary
|
// Insert unknown hops if necessary
|
||||||
insertUnknownHops(p, r, !incoming.request_id);
|
insertUnknownHops(p, r, !incoming.request_id);
|
||||||
|
@ -89,7 +89,7 @@ void WaypointModule::drawFrame(OLEDDisplay *display, OLEDDisplayUiState *state,
|
|||||||
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);
|
||||||
|
|
||||||
// Decode the waypoint
|
// Decode the waypoint
|
||||||
meshtastic_MeshPacket &mp = devicestate.rx_waypoint;
|
const meshtastic_MeshPacket &mp = devicestate.rx_waypoint;
|
||||||
meshtastic_Waypoint wp;
|
meshtastic_Waypoint wp;
|
||||||
memset(&wp, 0, sizeof(wp));
|
memset(&wp, 0, sizeof(wp));
|
||||||
if (!pb_decode_from_bytes(mp.decoded.payload.bytes, mp.decoded.payload.size, &meshtastic_Waypoint_msg, &wp)) {
|
if (!pb_decode_from_bytes(mp.decoded.payload.bytes, mp.decoded.payload.size, &meshtastic_Waypoint_msg, &wp)) {
|
||||||
@ -171,15 +171,15 @@ void WaypointModule::drawFrame(OLEDDisplay *display, OLEDDisplayUiState *state,
|
|||||||
strncpy(distStr, "? km", sizeof(distStr));
|
strncpy(distStr, "? km", sizeof(distStr));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Draw compass circle
|
||||||
|
display->drawCircle(compassX, compassY, compassDiam / 2);
|
||||||
|
|
||||||
// Undo color-inversion, if set prior to drawing header
|
// Undo color-inversion, if set prior to drawing header
|
||||||
// Unsure of expected behavior? For now: copy drawNodeInfo
|
// Unsure of expected behavior? For now: copy drawNodeInfo
|
||||||
if (config.display.displaymode == meshtastic_Config_DisplayConfig_DisplayMode_INVERTED) {
|
if (config.display.displaymode == meshtastic_Config_DisplayConfig_DisplayMode_INVERTED) {
|
||||||
display->setColor(BLACK);
|
display->setColor(BLACK);
|
||||||
}
|
}
|
||||||
|
|
||||||
// Draw compass circle
|
|
||||||
display->drawCircle(compassX, compassY, compassDiam / 2);
|
|
||||||
|
|
||||||
// Must be after distStr is populated
|
// Must be after distStr is populated
|
||||||
screen->drawColumns(display, x, y, fields);
|
screen->drawColumns(display, x, y, fields);
|
||||||
}
|
}
|
||||||
|
@ -184,8 +184,8 @@ void MQTT::onReceive(char *topic, byte *payload, size_t length)
|
|||||||
// PKI messages get accepted even if we can't decrypt
|
// PKI messages get accepted even if we can't decrypt
|
||||||
if (router && p->which_payload_variant == meshtastic_MeshPacket_encrypted_tag &&
|
if (router && p->which_payload_variant == meshtastic_MeshPacket_encrypted_tag &&
|
||||||
strcmp(e.channel_id, "PKI") == 0) {
|
strcmp(e.channel_id, "PKI") == 0) {
|
||||||
meshtastic_NodeInfoLite *tx = nodeDB->getMeshNode(getFrom(p));
|
const meshtastic_NodeInfoLite *tx = nodeDB->getMeshNode(getFrom(p));
|
||||||
meshtastic_NodeInfoLite *rx = nodeDB->getMeshNode(p->to);
|
const meshtastic_NodeInfoLite *rx = nodeDB->getMeshNode(p->to);
|
||||||
// Only accept PKI messages to us, or if we have both the sender and receiver in our nodeDB, as then it's
|
// Only accept PKI messages to us, or if we have both the sender and receiver in our nodeDB, as then it's
|
||||||
// likely they discovered each other via a channel we have downlink enabled for
|
// likely they discovered each other via a channel we have downlink enabled for
|
||||||
if (p->to == nodeDB->getNodeNum() || (tx && tx->has_user && rx && rx->has_user))
|
if (p->to == nodeDB->getNodeNum() || (tx && tx->has_user && rx && rx->has_user))
|
||||||
|
@ -48,11 +48,10 @@ extern "C" void bootloader_util_app_start(uint32_t start_addr);
|
|||||||
|
|
||||||
static uint16_t crc16(const uint8_t *data_p, uint8_t length)
|
static uint16_t crc16(const uint8_t *data_p, uint8_t length)
|
||||||
{
|
{
|
||||||
uint8_t x;
|
|
||||||
uint16_t crc = 0xFFFF;
|
uint16_t crc = 0xFFFF;
|
||||||
|
|
||||||
while (length--) {
|
while (length--) {
|
||||||
x = crc >> 8 ^ *data_p++;
|
uint8_t x = crc >> 8 ^ *data_p++;
|
||||||
x ^= x >> 4;
|
x ^= x >> 4;
|
||||||
crc = (crc << 8) ^ ((uint16_t)(x << 12)) ^ ((uint16_t)(x << 5)) ^ ((uint16_t)x);
|
crc = (crc << 8) ^ ((uint16_t)(x << 12)) ^ ((uint16_t)(x << 5)) ^ ((uint16_t)x);
|
||||||
}
|
}
|
||||||
|
@ -37,14 +37,14 @@
|
|||||||
#define FREE_ARRAY(x) \
|
#define FREE_ARRAY(x) \
|
||||||
{ \
|
{ \
|
||||||
JSONArray::iterator iter; \
|
JSONArray::iterator iter; \
|
||||||
for (iter = x.begin(); iter != x.end(); iter++) { \
|
for (iter = x.begin(); iter != x.end(); ++iter) { \
|
||||||
delete *iter; \
|
delete *iter; \
|
||||||
} \
|
} \
|
||||||
}
|
}
|
||||||
#define FREE_OBJECT(x) \
|
#define FREE_OBJECT(x) \
|
||||||
{ \
|
{ \
|
||||||
JSONObject::iterator iter; \
|
JSONObject::iterator iter; \
|
||||||
for (iter = x.begin(); iter != x.end(); iter++) { \
|
for (iter = x.begin(); iter != x.end(); ++iter) { \
|
||||||
delete (*iter).second; \
|
delete (*iter).second; \
|
||||||
} \
|
} \
|
||||||
}
|
}
|
||||||
@ -430,7 +430,7 @@ JSONValue::JSONValue(const JSONValue &m_source)
|
|||||||
JSONArray source_array = *m_source.array_value;
|
JSONArray source_array = *m_source.array_value;
|
||||||
JSONArray::iterator iter;
|
JSONArray::iterator iter;
|
||||||
array_value = new JSONArray();
|
array_value = new JSONArray();
|
||||||
for (iter = source_array.begin(); iter != source_array.end(); iter++)
|
for (iter = source_array.begin(); iter != source_array.end(); ++iter)
|
||||||
array_value->push_back(new JSONValue(**iter));
|
array_value->push_back(new JSONValue(**iter));
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
@ -439,7 +439,7 @@ JSONValue::JSONValue(const JSONValue &m_source)
|
|||||||
JSONObject source_object = *m_source.object_value;
|
JSONObject source_object = *m_source.object_value;
|
||||||
object_value = new JSONObject();
|
object_value = new JSONObject();
|
||||||
JSONObject::iterator iter;
|
JSONObject::iterator iter;
|
||||||
for (iter = source_object.begin(); iter != source_object.end(); iter++) {
|
for (iter = source_object.begin(); iter != source_object.end(); ++iter) {
|
||||||
std::string name = (*iter).first;
|
std::string name = (*iter).first;
|
||||||
(*object_value)[name] = new JSONValue(*((*iter).second));
|
(*object_value)[name] = new JSONValue(*((*iter).second));
|
||||||
}
|
}
|
||||||
@ -462,12 +462,12 @@ JSONValue::~JSONValue()
|
|||||||
{
|
{
|
||||||
if (type == JSONType_Array) {
|
if (type == JSONType_Array) {
|
||||||
JSONArray::iterator iter;
|
JSONArray::iterator iter;
|
||||||
for (iter = array_value->begin(); iter != array_value->end(); iter++)
|
for (iter = array_value->begin(); iter != array_value->end(); ++iter)
|
||||||
delete *iter;
|
delete *iter;
|
||||||
delete array_value;
|
delete array_value;
|
||||||
} else if (type == JSONType_Object) {
|
} else if (type == JSONType_Object) {
|
||||||
JSONObject::iterator iter;
|
JSONObject::iterator iter;
|
||||||
for (iter = object_value->begin(); iter != object_value->end(); iter++) {
|
for (iter = object_value->begin(); iter != object_value->end(); ++iter) {
|
||||||
delete (*iter).second;
|
delete (*iter).second;
|
||||||
}
|
}
|
||||||
delete object_value;
|
delete object_value;
|
||||||
@ -722,7 +722,7 @@ std::vector<std::string> JSONValue::ObjectKeys() const
|
|||||||
while (iter != object_value->end()) {
|
while (iter != object_value->end()) {
|
||||||
keys.push_back(iter->first);
|
keys.push_back(iter->first);
|
||||||
|
|
||||||
iter++;
|
++iter;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -865,7 +865,7 @@ std::string JSONValue::StringifyString(const std::string &str)
|
|||||||
str_out += chr;
|
str_out += chr;
|
||||||
}
|
}
|
||||||
|
|
||||||
iter++;
|
++iter;
|
||||||
}
|
}
|
||||||
|
|
||||||
str_out += "\"";
|
str_out += "\"";
|
||||||
|
@ -98,7 +98,44 @@ void test_DH25519(void)
|
|||||||
HexToBytes(private_key, "18630f93598637c35da623a74559cf944374a559114c7937811041fc8605564a");
|
HexToBytes(private_key, "18630f93598637c35da623a74559cf944374a559114c7937811041fc8605564a");
|
||||||
crypto->setDHPrivateKey(private_key);
|
crypto->setDHPrivateKey(private_key);
|
||||||
TEST_ASSERT(!crypto->setDHPublicKey(public_key)); // Weak public key results in 0 shared key
|
TEST_ASSERT(!crypto->setDHPublicKey(public_key)); // Weak public key results in 0 shared key
|
||||||
|
|
||||||
|
HexToBytes(public_key, "f7e13a1a067d2f4e1061bf9936fde5be6b0c2494a8f809cbac7f290ef719e91c");
|
||||||
|
HexToBytes(private_key, "10300724f3bea134eb1575245ef26ff9b8ccd59849cd98ce1a59002fe1d5986c");
|
||||||
|
HexToBytes(expected_shared, "24becd5dfed9e9289ba2e15b82b0d54f8e9aacb72f5e4248c58d8d74b451ce76");
|
||||||
|
crypto->setDHPrivateKey(private_key);
|
||||||
|
TEST_ASSERT(crypto->setDHPublicKey(public_key));
|
||||||
|
crypto->hash(crypto->shared_key, 32);
|
||||||
|
TEST_ASSERT_EQUAL_MEMORY(expected_shared, crypto->shared_key, 32);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void test_PKC_Decrypt(void)
|
||||||
|
{
|
||||||
|
uint8_t private_key[32];
|
||||||
|
uint8_t public_key[32];
|
||||||
|
uint8_t expected_shared[32];
|
||||||
|
uint8_t expected_decrypted[32];
|
||||||
|
uint8_t radioBytes[128] __attribute__((__aligned__));
|
||||||
|
uint8_t decrypted[128] __attribute__((__aligned__));
|
||||||
|
uint8_t expected_nonce[16];
|
||||||
|
|
||||||
|
uint32_t fromNode;
|
||||||
|
HexToBytes(public_key, "db18fc50eea47f00251cb784819a3cf5fc361882597f589f0d7ff820e8064457");
|
||||||
|
HexToBytes(private_key, "a00330633e63522f8a4d81ec6d9d1e6617f6c8ffd3a4c698229537d44e522277");
|
||||||
|
HexToBytes(expected_shared, "777b1545c9d6f9a2");
|
||||||
|
HexToBytes(expected_decrypted, "08011204746573744800");
|
||||||
|
HexToBytes(radioBytes, "8c646d7a2909000062d6b2136b00000040df24abfcc30a17a3d9046726099e796a1c036a792b");
|
||||||
|
HexToBytes(expected_nonce, "62d6b213036a792b2909000000");
|
||||||
|
fromNode = 0x0929;
|
||||||
|
crypto->setDHPrivateKey(private_key);
|
||||||
|
TEST_ASSERT(crypto->setDHPublicKey(public_key));
|
||||||
|
crypto->hash(crypto->shared_key, 32);
|
||||||
|
crypto->decryptCurve25519(fromNode, 0x13b2d662, 22, radioBytes + 16, decrypted);
|
||||||
|
TEST_ASSERT_EQUAL_MEMORY(expected_shared, crypto->shared_key, 8);
|
||||||
|
TEST_ASSERT_EQUAL_MEMORY(expected_nonce, crypto->nonce, 13);
|
||||||
|
|
||||||
|
TEST_ASSERT_EQUAL_MEMORY(expected_decrypted, decrypted, 10);
|
||||||
|
}
|
||||||
|
|
||||||
void test_AES_CTR(void)
|
void test_AES_CTR(void)
|
||||||
{
|
{
|
||||||
uint8_t expected[32];
|
uint8_t expected[32];
|
||||||
@ -137,6 +174,7 @@ void setup()
|
|||||||
RUN_TEST(test_ECB_AES256);
|
RUN_TEST(test_ECB_AES256);
|
||||||
RUN_TEST(test_DH25519);
|
RUN_TEST(test_DH25519);
|
||||||
RUN_TEST(test_AES_CTR);
|
RUN_TEST(test_AES_CTR);
|
||||||
|
RUN_TEST(test_PKC_Decrypt);
|
||||||
}
|
}
|
||||||
|
|
||||||
void loop()
|
void loop()
|
||||||
|
@ -94,7 +94,7 @@ extern "C" {
|
|||||||
#define USE_LR1110
|
#define USE_LR1110
|
||||||
|
|
||||||
#define LR1110_IRQ_PIN LORA_DIO1
|
#define LR1110_IRQ_PIN LORA_DIO1
|
||||||
#define LR1110_NRESER_PIN LORA_RESET
|
#define LR1110_NRESET_PIN LORA_RESET
|
||||||
#define LR1110_BUSY_PIN LORA_DIO2
|
#define LR1110_BUSY_PIN LORA_DIO2
|
||||||
#define LR1110_SPI_NSS_PIN LORA_CS
|
#define LR1110_SPI_NSS_PIN LORA_CS
|
||||||
#define LR1110_SPI_SCK_PIN LORA_SCK
|
#define LR1110_SPI_SCK_PIN LORA_SCK
|
||||||
|
@ -117,7 +117,7 @@ static const uint8_t SCK = PIN_SPI_SCK;
|
|||||||
#define USE_LR1110
|
#define USE_LR1110
|
||||||
|
|
||||||
#define LR1110_IRQ_PIN LORA_DIO1
|
#define LR1110_IRQ_PIN LORA_DIO1
|
||||||
#define LR1110_NRESER_PIN LORA_RESET
|
#define LR1110_NRESET_PIN LORA_RESET
|
||||||
#define LR1110_BUSY_PIN LORA_DIO2
|
#define LR1110_BUSY_PIN LORA_DIO2
|
||||||
#define LR1110_SPI_NSS_PIN LORA_CS
|
#define LR1110_SPI_NSS_PIN LORA_CS
|
||||||
#define LR1110_SPI_SCK_PIN LORA_SCK
|
#define LR1110_SPI_SCK_PIN LORA_SCK
|
||||||
|
@ -93,7 +93,7 @@ extern "C" {
|
|||||||
#define USE_LR1110
|
#define USE_LR1110
|
||||||
|
|
||||||
#define LR1110_IRQ_PIN LORA_DIO1
|
#define LR1110_IRQ_PIN LORA_DIO1
|
||||||
#define LR1110_NRESER_PIN LORA_RESET
|
#define LR1110_NRESET_PIN LORA_RESET
|
||||||
#define LR1110_BUSY_PIN LORA_DIO2
|
#define LR1110_BUSY_PIN LORA_DIO2
|
||||||
#define LR1110_SPI_NSS_PIN LORA_CS
|
#define LR1110_SPI_NSS_PIN LORA_CS
|
||||||
#define LR1110_SPI_SCK_PIN LORA_SCK
|
#define LR1110_SPI_SCK_PIN LORA_SCK
|
||||||
|
@ -95,7 +95,7 @@ extern "C" {
|
|||||||
#define USE_LR1110
|
#define USE_LR1110
|
||||||
|
|
||||||
#define LR1110_IRQ_PIN LORA_DIO1
|
#define LR1110_IRQ_PIN LORA_DIO1
|
||||||
#define LR1110_NRESER_PIN LORA_RESET
|
#define LR1110_NRESET_PIN LORA_RESET
|
||||||
#define LR1110_BUSY_PIN LORA_DIO2
|
#define LR1110_BUSY_PIN LORA_DIO2
|
||||||
#define LR1110_SPI_NSS_PIN LORA_CS
|
#define LR1110_SPI_NSS_PIN LORA_CS
|
||||||
#define LR1110_SPI_SCK_PIN LORA_SCK
|
#define LR1110_SPI_SCK_PIN LORA_SCK
|
||||||
|
@ -94,7 +94,7 @@ extern "C" {
|
|||||||
#define USE_LR1110
|
#define USE_LR1110
|
||||||
|
|
||||||
#define LR1110_IRQ_PIN LORA_DIO1
|
#define LR1110_IRQ_PIN LORA_DIO1
|
||||||
#define LR1110_NRESER_PIN LORA_RESET
|
#define LR1110_NRESET_PIN LORA_RESET
|
||||||
#define LR1110_BUSY_PIN LORA_DIO2
|
#define LR1110_BUSY_PIN LORA_DIO2
|
||||||
#define LR1110_SPI_NSS_PIN LORA_CS
|
#define LR1110_SPI_NSS_PIN LORA_CS
|
||||||
#define LR1110_SPI_SCK_PIN LORA_SCK
|
#define LR1110_SPI_SCK_PIN LORA_SCK
|
||||||
|
@ -91,7 +91,7 @@ extern "C" {
|
|||||||
#define USE_LR1110
|
#define USE_LR1110
|
||||||
|
|
||||||
#define LR1110_IRQ_PIN LORA_DIO1
|
#define LR1110_IRQ_PIN LORA_DIO1
|
||||||
#define LR1110_NRESER_PIN LORA_RESET
|
#define LR1110_NRESET_PIN LORA_RESET
|
||||||
#define LR1110_BUSY_PIN LORA_DIO2
|
#define LR1110_BUSY_PIN LORA_DIO2
|
||||||
#define LR1110_SPI_NSS_PIN LORA_CS
|
#define LR1110_SPI_NSS_PIN LORA_CS
|
||||||
#define LR1110_SPI_SCK_PIN LORA_SCK
|
#define LR1110_SPI_SCK_PIN LORA_SCK
|
||||||
|
Loading…
Reference in New Issue
Block a user