Upgrade to Version 0.3.0
This commit is contained in:
parent
9e9ae92849
commit
200893ee84
67
README.md
67
README.md
|
@ -1,7 +1,12 @@
|
||||||
# CubeCellRepeater
|
# CubeCellRepeater
|
||||||
|
|
||||||
This is the code for a simple repeater node for the meshtastic project: https://github.com/meshtastic
|
This is the code for a simple repeater node for the meshtastic project: https://github.com/meshtastic (https://www.meshtastic.org)
|
||||||
|
The Meshtastic project is in no way affiliated with or respnsible for the CubeCellRepeater project.
|
||||||
|
|
||||||
|
To be compatible with meshtastic project, portions of their code was used.
|
||||||
|
(c) Copyright Meshtastic Project (and others).
|
||||||
|
|
||||||
|
Hardware:
|
||||||
The actual node can be one of the LoRa CubeCell nodes by Heltec Automation: https://github.com/HelTecAutomation/ASR650x-Arduino/
|
The actual node can be one of the LoRa CubeCell nodes by Heltec Automation: https://github.com/HelTecAutomation/ASR650x-Arduino/
|
||||||
|
|
||||||
Notes:
|
Notes:
|
||||||
|
@ -9,15 +14,69 @@ Notes:
|
||||||
Intended for use with the platform.io IDE. Serial output speed is 115200.
|
Intended for use with the platform.io IDE. Serial output speed is 115200.
|
||||||
See the provided platformio.ini for built-in environments. Default is cubecell_board.
|
See the provided platformio.ini for built-in environments. Default is cubecell_board.
|
||||||
|
|
||||||
Will repeat packets ONCE with HopLimit reduced by one. To prevent flooding the last repeated packet ID will not be repeated again.
|
Will repeat packets ONCE with HopLimit reduced by one. To prevent flooding the last 64 repeated packets will not be repeated again.
|
||||||
If the HopLimit was already 0, the packet will not be repeated.
|
If the HopLimit was already 0, the packet will not be repeated.
|
||||||
|
|
||||||
Keep in mind that re-sending packets will cause the initial sender to assume that the packet is "received" or at least in the mesh.
|
Keep in mind that re-sending packets will cause the initial sender to assume that the packet is "received" or at least in the mesh.
|
||||||
If no other meshtastic node is in range of either the node or the repeater, the message will still be shown as received.
|
If no other meshtastic node is in range of either the node or the repeater, the message will still be shown as received.
|
||||||
|
|
||||||
Will work with most packets meeting the radio settings, but the serial output is based on the assumption that the node receives meshtastic packets.
|
Will work with most packets meeting the radio settings, but the serial output is based on the assumption that the node receives meshtastic packets.
|
||||||
Minimum size for none-Meshtastic packets is 14 bytes.
|
Minimum size for none-Meshtastic packets is 16 bytes.
|
||||||
|
|
||||||
"#define SILENT" in main.h to stop serial output.
|
"#define SILENT" in main.h to stop serial output.
|
||||||
|
|
||||||
Modifying radio settings for your own radio settings: edit the main.h
|
The node can decode meshtastic packets meeting some requirements:
|
||||||
|
- they key is the default meshtastic key or provided by you (see main.h)
|
||||||
|
- the packets are sent over channel 0, primary channel. This should already be true for all telemetry, node info, traces and DM.
|
||||||
|
|
||||||
|
##Modifying radio settings: edit the main.h
|
||||||
|
|
||||||
|
List of meshtastic-supported regions:
|
||||||
|
/* United States */
|
||||||
|
meshtastic_Config_LoRaConfig_RegionCode_US
|
||||||
|
/* European Union 433mhz */
|
||||||
|
meshtastic_Config_LoRaConfig_RegionCode_EU_433
|
||||||
|
/* European Union 868mhz */
|
||||||
|
meshtastic_Config_LoRaConfig_RegionCode_EU_868 (default)
|
||||||
|
/* China */
|
||||||
|
meshtastic_Config_LoRaConfig_RegionCode_CN
|
||||||
|
/* Japan */
|
||||||
|
meshtastic_Config_LoRaConfig_RegionCode_JP
|
||||||
|
/* Australia / New Zealand */
|
||||||
|
meshtastic_Config_LoRaConfig_RegionCode_ANZ
|
||||||
|
/* Korea */
|
||||||
|
meshtastic_Config_LoRaConfig_RegionCode_KR
|
||||||
|
/* Taiwan */
|
||||||
|
meshtastic_Config_LoRaConfig_RegionCode_TW
|
||||||
|
/* Russia */
|
||||||
|
meshtastic_Config_LoRaConfig_RegionCode_RU
|
||||||
|
/* India */
|
||||||
|
meshtastic_Config_LoRaConfig_RegionCode_IN
|
||||||
|
/* New Zealand 865mhz */
|
||||||
|
meshtastic_Config_LoRaConfig_RegionCode_NZ_865
|
||||||
|
/* Thailand */
|
||||||
|
meshtastic_Config_LoRaConfig_RegionCode_TH
|
||||||
|
/* WLAN Band */
|
||||||
|
meshtastic_Config_LoRaConfig_RegionCode_LORA_24
|
||||||
|
/* Ukraine 433mhz */
|
||||||
|
meshtastic_Config_LoRaConfig_RegionCode_UA_433
|
||||||
|
/* Ukraine 868mhz */
|
||||||
|
meshtastic_Config_LoRaConfig_RegionCode_UA_868
|
||||||
|
/* Malaysia 433mhz */
|
||||||
|
meshtastic_Config_LoRaConfig_RegionCode_MY_433
|
||||||
|
/* Malaysia 919mhz */
|
||||||
|
meshtastic_Config_LoRaConfig_RegionCode_MY_919
|
||||||
|
/* Singapore 923mhz */
|
||||||
|
meshtastic_Config_LoRaConfig_RegionCode_SG_923
|
||||||
|
|
||||||
|
For lora modem settings you should always try the default (LongFast), it's proven to be THE setting to go for.
|
||||||
|
If you want to try other presets, here is the list:
|
||||||
|
|
||||||
|
meshtastic_Config_LoRaConfig_ModemPreset_SHORT_FAST
|
||||||
|
meshtastic_Config_LoRaConfig_ModemPreset_SHORT_SLOW
|
||||||
|
meshtastic_Config_LoRaConfig_ModemPreset_MEDIUM_FAST
|
||||||
|
meshtastic_Config_LoRaConfig_ModemPreset_MEDIUM_SLOW
|
||||||
|
meshtastic_Config_LoRaConfig_ModemPreset_LONG_FAST (default)
|
||||||
|
meshtastic_Config_LoRaConfig_ModemPreset_LONG_MODERATE
|
||||||
|
meshtastic_Config_LoRaConfig_ModemPreset_LONG_SLOW
|
||||||
|
meshtastic_Config_LoRaConfig_ModemPreset_VERY_LONG_SLOW
|
||||||
|
|
|
@ -17,13 +17,32 @@ monitor_speed = 115200
|
||||||
build_flags = -Os
|
build_flags = -Os
|
||||||
-Isrc -Isrc/mesh -Isrc/mesh/generated
|
-Isrc -Isrc/mesh -Isrc/mesh/generated
|
||||||
-D PB_ENABLE_MALLOC=1
|
-D PB_ENABLE_MALLOC=1
|
||||||
-D APP_VERSION=0.01.1
|
-D APP_VERSION=0.3.0
|
||||||
|
-DRADIOLIB_EXCLUDE_CC1101
|
||||||
|
-DRADIOLIB_EXCLUDE_NRF24
|
||||||
|
-DRADIOLIB_EXCLUDE_RF69
|
||||||
|
-DRADIOLIB_EXCLUDE_SX1231
|
||||||
|
-DRADIOLIB_EXCLUDE_SX1233
|
||||||
|
-DRADIOLIB_EXCLUDE_SI443X
|
||||||
|
-DRADIOLIB_EXCLUDE_RFM2X
|
||||||
|
-DRADIOLIB_EXCLUDE_AFSK
|
||||||
|
-DRADIOLIB_EXCLUDE_BELL
|
||||||
|
-DRADIOLIB_EXCLUDE_HELLSCHREIBER
|
||||||
|
-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
|
||||||
|
-DRADIOLIB_EXCLUDE_LORAWAN
|
||||||
|
|
||||||
lib_deps = nanopb/Nanopb
|
lib_deps = nanopb/Nanopb
|
||||||
https://github.com/meshtastic/protobufs.git
|
https://github.com/meshtastic/protobufs.git
|
||||||
jgromes/RadioLib
|
jgromes/RadioLib
|
||||||
https://github.com/kokke/tiny-AES-c.git
|
https://github.com/kokke/tiny-AES-c.git
|
||||||
|
|
||||||
|
|
||||||
check_tool = cppcheck
|
check_tool = cppcheck
|
||||||
build_type = release
|
build_type = release
|
||||||
|
|
||||||
|
@ -33,6 +52,5 @@ platform = heltec-cubecell
|
||||||
board = cubecell_board
|
board = cubecell_board
|
||||||
platform_packages = platformio/toolchain-gccarmnoneeabi@^1.120301.0
|
platform_packages = platformio/toolchain-gccarmnoneeabi@^1.120301.0
|
||||||
build_flags = ${common.build_flags} -Isrc/platform/cubecell
|
build_flags = ${common.build_flags} -Isrc/platform/cubecell
|
||||||
-D CUBECELL=1
|
-D CUBECELL
|
||||||
-D HW_VENDOR=CUBECELL
|
-D HW_VENDOR=CUBECELL
|
||||||
|
|
||||||
|
|
591
src/main.cpp
591
src/main.cpp
|
@ -1,48 +1,43 @@
|
||||||
#include <main.h>
|
#include <main.h>
|
||||||
#include <assert.h>
|
|
||||||
|
|
||||||
typedef struct {
|
|
||||||
uint32_t to, from, id;
|
|
||||||
// The bottom three bits of flags are used to store hop_limit
|
|
||||||
uint8_t flags;
|
|
||||||
uint8_t channel;
|
|
||||||
} PacketHeader;
|
|
||||||
|
|
||||||
void setup() {
|
void setup() {
|
||||||
UART_1_RxWakeDisableInt(); // no wake on UART activity
|
msgID.clear();
|
||||||
memset(idList, 0, MAX_ID_LIST *4);
|
txQueue.clear();
|
||||||
for (uint8_t i = 0; i<(MAX_TX_QUEUE - 1); i++) {
|
|
||||||
txQueue[i].size = 0;
|
|
||||||
}
|
|
||||||
#ifndef SILENT
|
#ifndef SILENT
|
||||||
Serial.begin(115200);
|
Serial.begin(115200);
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
MSG("[INFO][CryptoEngine] Initializing ... ");
|
MSG("[INF][CryptoEngine]Initializing ... ");
|
||||||
memcpy(psk.bytes, mypsk, sizeof(mypsk));
|
memcpy(psk.bytes, mypsk, sizeof(mypsk));
|
||||||
psk.length = sizeof(psk.bytes);
|
psk.length = sizeof(psk.bytes);
|
||||||
crypto->setKey(psk);
|
crypto->setKey(psk);
|
||||||
|
|
||||||
initRegion(); // create regions[] and load myRegion
|
initRegion(); // create regions[] and load myRegion
|
||||||
applyModemConfig(); // apply lora settings
|
applyModemConfig(); // apply lora settings
|
||||||
MSG("[INFO][SX1262] Starting to listen ... ");
|
radio.setDio1Action(ISR_dio1Action);
|
||||||
|
MSG("[INF][SX1262]Starting to listen ...\n");
|
||||||
startReceive();
|
startReceive();
|
||||||
if (state == RADIOLIB_ERR_NONE) {
|
|
||||||
MSG("success!\n\n");
|
|
||||||
} else {
|
|
||||||
MSG("\n[ERROR][SX1262] startReceive() failed, code: %i\n\n ** Full Stop **", state);
|
|
||||||
while (true);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void loop() {
|
void loop() {
|
||||||
|
|
||||||
|
if (dio1) {
|
||||||
|
dio1 = false;
|
||||||
|
static uint16_t irqStatus = radio.getIrqStatus();
|
||||||
|
if (irqStatus & RADIOLIB_SX126X_IRQ_RX_DONE) {
|
||||||
|
PacketReceived = true;
|
||||||
|
}
|
||||||
|
if (irqStatus & RADIOLIB_SX126X_IRQ_TX_DONE) {
|
||||||
|
PacketSent = true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
if (PacketReceived) {
|
if (PacketReceived) {
|
||||||
PacketReceived = false;
|
PacketReceived = false;
|
||||||
const size_t length = radio.getPacketLength();
|
const size_t length = radio.getPacketLength();
|
||||||
state = radio.readData(radiobuf, length);
|
state = radio.readData(radiobuf, length);
|
||||||
PacketHeader* h = (PacketHeader *)radiobuf;
|
PacketHeader* h = (PacketHeader *)radiobuf;
|
||||||
|
|
||||||
//MSG("[RX]");
|
|
||||||
if (state == RADIOLIB_ERR_NONE) {
|
if (state == RADIOLIB_ERR_NONE) {
|
||||||
const int32_t payloadLen = length - sizeof(PacketHeader);
|
const int32_t payloadLen = length - sizeof(PacketHeader);
|
||||||
if (payloadLen < 0) {
|
if (payloadLen < 0) {
|
||||||
|
@ -50,47 +45,17 @@ void loop() {
|
||||||
return; // will not repeat
|
return; // will not repeat
|
||||||
}
|
}
|
||||||
const uint8_t hop_limit = h->flags & PACKET_FLAGS_HOP_MASK;
|
const uint8_t hop_limit = h->flags & PACKET_FLAGS_HOP_MASK;
|
||||||
/*
|
// do not repeat if id is known or hop limit is zero
|
||||||
MSG(" (id=0x%08X) HopLim=%i from=0x%08X to=0x%08X WantAck=%s viaMQTT=%s", h->id,
|
repeatPacket = msgID.add(h->id);
|
||||||
hop_limit, h->from, h->to, (h->flags & PACKET_FLAGS_WANT_ACK_MASK)? "YES":"NO", (h->flags & PACKET_FLAGS_VIA_MQTT_MASK)? "YES":"NO");
|
if (hop_limit == 0) repeatPacket = false;
|
||||||
|
MSG("\n[NEW](id=0x%08X) (HopLim %d) ", h->id, hop_limit);
|
||||||
MSGFLOAT(" SNR=",radio.getSNR() );
|
|
||||||
MSGFLOAT(" RSSI=", radio.getRSSI() );
|
|
||||||
*/
|
|
||||||
repeatPacket = update_idList(h->id);
|
|
||||||
if ( hop_limit == 0) repeatPacket = false; // do not repeat if id is known or hop limit is Zero
|
|
||||||
#ifndef SILENT // print packet:
|
|
||||||
const uint8_t *payload = radiobuf + sizeof(PacketHeader);
|
|
||||||
mp.from = h->from;
|
|
||||||
mp.to = h->to;
|
|
||||||
mp.id = h->id;
|
|
||||||
mp.channel = h->channel;
|
|
||||||
mp.hop_limit = h->flags & PACKET_FLAGS_HOP_MASK;
|
|
||||||
mp.want_ack = h->flags & PACKET_FLAGS_WANT_ACK_MASK;
|
|
||||||
mp.via_mqtt = h->flags & PACKET_FLAGS_VIA_MQTT_MASK;
|
|
||||||
mp.rx_snr = radio.getSNR();
|
|
||||||
mp.rx_rssi = lround(radio.getRSSI());
|
|
||||||
mp.which_payload_variant = meshtastic_MeshPacket_encrypted_tag; // Mark that the payload is still encrypted at this point
|
|
||||||
assert(((uint32_t)payloadLen) <= sizeof(mp.encrypted.bytes));
|
|
||||||
memcpy(mp.encrypted.bytes, payload, payloadLen);
|
|
||||||
mp.encrypted.size = payloadLen;
|
|
||||||
MSG("\n[NEW]");
|
|
||||||
if ( !repeatPacket ){
|
if ( !repeatPacket ){
|
||||||
MSG("(id=0x%08X) no repeat! (HopLim %d)\n", mp.id, mp.hop_limit);
|
MSG("no repeat!\n");
|
||||||
} else {
|
|
||||||
perhapsDecode(&mp); // try to decode and print the result
|
|
||||||
}
|
}
|
||||||
#endif //SILENT
|
else {
|
||||||
|
h->flags -= 1; // decrease hop limit by 1
|
||||||
/* MSG(" repeat=%s\n", (repeatPacket)?"YES":"NO");
|
txQueue.add(radiobuf, length);
|
||||||
MSGFLOAT(" Freq Error=", radio.getFrequencyError());
|
|
||||||
MSG("\n");
|
|
||||||
*/
|
|
||||||
if ( repeatPacket ) {
|
|
||||||
h->flags -= 1; // decrease HopLim by 1
|
|
||||||
enqueueTX(radiobuf, length);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
} else if (state == RADIOLIB_ERR_CRC_MISMATCH) {
|
} else if (state == RADIOLIB_ERR_CRC_MISMATCH) {
|
||||||
MSG(" [ERROR]CRC error!\n");
|
MSG(" [ERROR]CRC error!\n");
|
||||||
} else {
|
} else {
|
||||||
|
@ -98,47 +63,68 @@ void loop() {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (txQueueHasPacket) { // try to repeat packets
|
while (txQueue.hasPackets) {
|
||||||
//const long wait = lround( abs( radio.getSNR() * radio.getRSSI() ));
|
p = txQueue.pop();
|
||||||
long wait = 1000;
|
// if we pop a Nullpointer (empty queue), hasPackets will be false now
|
||||||
radio.startChannelScan(3, 24, 10);
|
if (txQueue.hasPackets) {
|
||||||
for (int i = 1; i < wait; i++) {
|
TimerTime_t now = systime; //RtcGetTimerValue();
|
||||||
|
//try to decode the packet and print it
|
||||||
|
uint32_t wait = maxPacketTimeMsec + abs( radio.getRSSI() * radio.getSNR() ) + random(0, 3*slotTimeMsec);
|
||||||
|
MSG("[INF]wait %i ms before TX\n", wait);
|
||||||
|
while ( (now + wait) > systime ) {
|
||||||
|
// while waiting, we still are in receive mode
|
||||||
|
if (dio1) {
|
||||||
|
MSG("[INF]New packet, no TX\n");
|
||||||
|
return; // new packet arrived, return to handle it
|
||||||
|
}
|
||||||
|
delay(5);
|
||||||
|
}
|
||||||
|
// last check before actually sending the packet
|
||||||
|
radio.startChannelScan(); // RadioLib 6.5 overrides all user params
|
||||||
|
// CAD will activate dio1 at activity or timeout
|
||||||
|
MCU_deepsleep();
|
||||||
if (radio.getChannelScanResult() == RADIOLIB_LORA_DETECTED) {
|
if (radio.getChannelScanResult() == RADIOLIB_LORA_DETECTED) {
|
||||||
clearInterrupts();
|
dio1 = false;
|
||||||
radio.setPacketReceivedAction(ISR_setReceived);
|
startReceive();
|
||||||
radio.startReceive(20000);
|
MSG("[INF]Lora activity, no TX\n");
|
||||||
return; // new packet arrived while waiting!
|
return;
|
||||||
}
|
}
|
||||||
delay(2);
|
dio1 = false;
|
||||||
}
|
if (perhapsSend(&p->buf[0], p->size) ) {
|
||||||
|
perhapsDecode(&p->buf[0], p->size);
|
||||||
uint8_t idx = poptxQueue();
|
PacketSent = true;
|
||||||
if (txQueue[idx].size == 0){
|
// mark packet as "deleted"
|
||||||
txQueueHasPacket = false; // empty Queue, do nothing
|
p->size = 0;
|
||||||
//MSG("[INFO] TX Queue is empty\n");
|
} else {
|
||||||
}
|
// Could not send, resume receiving
|
||||||
else {
|
PacketSent = true;
|
||||||
perhapsSend(&txQueue[idx].buf[0], txQueue[idx].size);
|
|
||||||
txQueue[idx].size = 0;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (PacketSent) {
|
if (PacketSent) {
|
||||||
PacketSent = false;
|
PacketSent = false;
|
||||||
|
radio.finishTransmit();
|
||||||
|
dio1 = false;
|
||||||
startReceive();
|
startReceive();
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
#ifndef SILENT
|
||||||
|
// wait for serial output to conplete
|
||||||
|
delay(10);
|
||||||
|
#endif
|
||||||
|
|
||||||
delay(100); // wait for Serial
|
|
||||||
MCU_deepsleep();
|
MCU_deepsleep();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
void MCU_deepsleep(void) {
|
void MCU_deepsleep(void) {
|
||||||
#ifdef CUBECELL
|
#ifdef CUBECELL
|
||||||
#ifndef SILENT
|
#ifndef SILENT
|
||||||
UART_1_Sleep; // aka USB, if you use UART2 for communication, add UART_2_Sleep / Wakeup
|
UART_1_Sleep; // aka USB, if you use UART2 for communication, add UART_2_Sleep / Wakeup
|
||||||
#endif
|
#endif
|
||||||
pinMode(P4_1, ANALOG); // SPI0 MISO, save power
|
pinMode(P4_1, ANALOG); // SPI0 MISO, save power
|
||||||
CySysPmDeepSleep(); // deep sleep mode
|
CySysPmDeepSleep();
|
||||||
// after sleep, set global time counter, set MISO to input, reactivate UART :
|
// after sleep, set global time counter, set MISO to input, reactivate UART :
|
||||||
systime = (uint32_t)RtcGetTimerValue();
|
systime = (uint32_t)RtcGetTimerValue();
|
||||||
pinMode(P4_1, INPUT);
|
pinMode(P4_1, INPUT);
|
||||||
|
@ -148,240 +134,144 @@ void MCU_deepsleep(void) {
|
||||||
#endif //CUBECELL
|
#endif //CUBECELL
|
||||||
}
|
}
|
||||||
|
|
||||||
void clearInterrupts(void) {
|
|
||||||
radio.clearDio1Action();
|
|
||||||
radio.finishTransmit();
|
|
||||||
}
|
|
||||||
|
|
||||||
void startReceive(){
|
void startReceive(){
|
||||||
clearInterrupts();
|
MSG("[RX]Start receiving ...\n");
|
||||||
radio.setPacketReceivedAction(ISR_setReceived);
|
while (RADIOLIB_ERR_NONE != radio.startReceive(RADIOLIB_SX126X_RX_TIMEOUT_INF, RADIOLIB_SX126X_IRQ_RX_DEFAULT , RADIOLIB_SX126X_IRQ_RX_DONE, 0) )
|
||||||
state=radio.startReceive();
|
{
|
||||||
|
MSG("\n[ERROR][SX1262] startReceive() failed, code: %i\n", state);
|
||||||
|
delay(1000);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
bool update_idList(uint32_t id){
|
bool perhapsSend(uint8_t* buf, size_t size) {
|
||||||
for (uint8_t i=0; i < (MAX_ID_LIST - 1); i++) {
|
|
||||||
//MSG("\nstored: 0x%08X delivered: 0x%08X",idQueue[i-1], id);
|
|
||||||
if (idList[i] == id){
|
|
||||||
return false; // packet ID is known, no Queue update
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// store new ID:
|
|
||||||
uint8_t idx = MAX_ID_LIST;
|
|
||||||
for (uint8_t i=0; i < (MAX_ID_LIST -1); i++){
|
|
||||||
if (idList[i] == 0) {
|
|
||||||
idx = i;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
if (idx == MAX_ID_LIST) {
|
|
||||||
idList[0] = id;
|
|
||||||
idList[1] = 0;
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
idList[idx] = id;
|
|
||||||
if (++idx < MAX_ID_LIST) { idList[idx] = 0; }
|
|
||||||
else { idList[0] = 0; }
|
|
||||||
}
|
|
||||||
return true; // packet ID was not known, Queue was updated
|
|
||||||
}
|
|
||||||
|
|
||||||
void enqueueTX(uint8_t* buf, size_t size){
|
|
||||||
PacketHeader* h = (PacketHeader *)buf;
|
PacketHeader* h = (PacketHeader *)buf;
|
||||||
uint8_t idx = MAX_TX_QUEUE;
|
MSG("\n[TX](id=0x%08X) HopLim=%i ", h->id, (h->flags & PACKET_FLAGS_HOP_MASK));
|
||||||
for (uint8_t i=0; i<(MAX_TX_QUEUE -1); i++) {
|
|
||||||
if (txQueue[i].size == 0) { // search for a free slot
|
|
||||||
idx = i;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
if (idx == MAX_TX_QUEUE) { // no free slot, overwrite oldest packet
|
|
||||||
idx = 0;
|
|
||||||
for (uint8_t i=1; i<(MAX_TX_QUEUE -1); i++) {
|
|
||||||
if (txQueue[idx].packetTime < txQueue[i].packetTime) idx = i;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
txQueue[idx].size = size;
|
|
||||||
MSG("[INF](id=0x%08X) enQueue Index=%i size=%i", h->id, idx, size);
|
|
||||||
txQueue[idx].packetTime = (uint32_t)RtcGetTimerValue();
|
|
||||||
MSG(" Time=%i\n",txQueue[idx].packetTime); //MSG("\n");
|
|
||||||
memcpy(&txQueue[idx].buf[0], buf, size);
|
|
||||||
//MSG(" Copy done!\n");
|
|
||||||
txQueueHasPacket = true;
|
|
||||||
}
|
|
||||||
|
|
||||||
uint8_t poptxQueue(void) {
|
|
||||||
uint8_t idx = MAX_TX_QUEUE;
|
|
||||||
for (uint8_t i=0 ;i < (MAX_TX_QUEUE -1); i++ ){
|
|
||||||
if (txQueue[i].size != 0) {
|
|
||||||
idx = i;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
if (idx == MAX_TX_QUEUE) { // empty Queue
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
for (uint8_t i=idx; i<(MAX_TX_QUEUE -1); i++) {
|
|
||||||
if ( (txQueue[i].size != 0) && (txQueue[idx].packetTime < txQueue[i].packetTime) ) idx = i; // find oldest packet
|
|
||||||
}
|
|
||||||
//MSG("[INFO]POP index=%i\n", idx);
|
|
||||||
return idx;
|
|
||||||
}
|
|
||||||
|
|
||||||
void perhapsSend(uint8_t* buf, size_t size) {
|
|
||||||
PacketHeader* h = (PacketHeader *)buf;
|
|
||||||
//clearInterrupts();
|
|
||||||
//while ( radio.scanChannel() == RADIOLIB_LORA_DETECTED ) delay( (uint32_t)lround( abs(radio.getSNR() + radio.getRSSI() ) ) );
|
|
||||||
MSG("[TX] (id=0x%08X) HopLim=%i ... ", h->id, (h->flags & PACKET_FLAGS_HOP_MASK));
|
|
||||||
clearInterrupts();
|
|
||||||
radio.setPacketSentAction(ISR_setPacketSent);
|
|
||||||
state=radio.startTransmit(buf, size);
|
state=radio.startTransmit(buf, size);
|
||||||
if (state == RADIOLIB_ERR_NONE) {
|
if (state == RADIOLIB_ERR_NONE) {
|
||||||
MSG("OK\n");
|
MSG("starting ... ");
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
MSG("failed, ERR = %i - resume RX", state);
|
MSG("failed, ERR = %i - resume RX\n", state);
|
||||||
PacketSent=true; // do not halt on error
|
return false;
|
||||||
}
|
}
|
||||||
|
delay(10);
|
||||||
|
MCU_deepsleep(); // wait for TX to complete, will wake on any DIO1
|
||||||
|
state = radio.getIrqStatus();
|
||||||
|
(state & RADIOLIB_SX126X_IRQ_TX_DONE) ? MSG("done!\n") : MSG("failed. Returned IRQ=%i\n", state);
|
||||||
|
dio1 = false;
|
||||||
|
return ( state & RADIOLIB_SX126X_IRQ_TX_DONE );
|
||||||
}
|
}
|
||||||
|
|
||||||
static uint8_t bytes[MAX_RHPACKETLEN];
|
bool perhapsDecode(uint8_t* buf, size_t size) {
|
||||||
|
// modified code, (c) Meshtastic https://github.com/meshtastic/firmware
|
||||||
bool perhapsDecode(meshtastic_MeshPacket *p)
|
PacketHeader* h = (PacketHeader *)buf;
|
||||||
{
|
const int32_t len = size - sizeof(PacketHeader);
|
||||||
/* concurrency::LockGuard g(cryptLock);
|
const uint8_t *payload = radiobuf + sizeof(PacketHeader);
|
||||||
|
mp.from = h->from;
|
||||||
if (config.device.role == meshtastic_Config_DeviceConfig_Role_REPEATER &&
|
mp.to = h->to;
|
||||||
config.device.rebroadcast_mode == meshtastic_Config_DeviceConfig_RebroadcastMode_ALL_SKIP_DECODING)
|
mp.id = h->id;
|
||||||
return false;
|
mp.channel = h->channel;
|
||||||
|
mp.hop_limit = h->flags & PACKET_FLAGS_HOP_MASK;
|
||||||
if (config.device.rebroadcast_mode == meshtastic_Config_DeviceConfig_RebroadcastMode_KNOWN_ONLY &&
|
mp.hop_limit += 1;
|
||||||
!nodeDB.getMeshNode(p->from)->has_user) {
|
mp.want_ack = h->flags & PACKET_FLAGS_WANT_ACK_MASK;
|
||||||
LOG_DEBUG("Node 0x%x not in NodeDB. Rebroadcast mode KNOWN_ONLY will ignore packet\n", p->from);
|
mp.via_mqtt = h->flags & PACKET_FLAGS_VIA_MQTT_MASK;
|
||||||
return false;
|
mp.rx_snr = radio.getSNR();
|
||||||
}
|
mp.rx_rssi = lround(radio.getRSSI());
|
||||||
*/
|
mp.which_payload_variant = meshtastic_MeshPacket_encrypted_tag;
|
||||||
if (p->which_payload_variant == meshtastic_MeshPacket_decoded_tag)
|
mp.encrypted.size = 0;
|
||||||
return true; // If packet was already decoded just return
|
static uint8_t scratchbuf[MAX_RHPACKETLEN];
|
||||||
|
assert(len <= sizeof(scratchbuf));
|
||||||
// assert(p->which_payloadVariant == MeshPacket_encrypted_tag);
|
// we have to copy into a scratch buffer, because mp.encrypted is a union with the decoded protobuf
|
||||||
|
memcpy(scratchbuf, buf + sizeof(PacketHeader), len);
|
||||||
// Try to find a channel that works with this hash
|
crypto->decrypt(mp.from, mp.id, len, scratchbuf);
|
||||||
/* for (ChannelIndex chIndex = 0; chIndex < channels.getNumChannels(); chIndex++) {
|
memset(&mp.decoded, 0, sizeof(mp.decoded));
|
||||||
// Try to use this hash/channel pair
|
if (!pb_decode_from_bytes((const uint8_t*)scratchbuf, len, &meshtastic_Data_msg, &mp.decoded)) {
|
||||||
if (channels.decryptForHash(chIndex, p->channel)) { */
|
|
||||||
// Try to decrypt the packet if we can
|
|
||||||
size_t rawSize = p->encrypted.size;
|
|
||||||
assert(rawSize <= sizeof(bytes));
|
|
||||||
memcpy(bytes, p->encrypted.bytes,
|
|
||||||
rawSize); // we have to copy into a scratch buffer, because these bytes are a union with the decoded protobuf
|
|
||||||
crypto->decrypt(p->from, p->id, rawSize, bytes);
|
|
||||||
|
|
||||||
// printBytes("plaintext", bytes, p->encrypted.size);
|
|
||||||
|
|
||||||
// Take those raw bytes and convert them back into a well structured protobuf we can understand
|
|
||||||
memset(&p->decoded, 0, sizeof(p->decoded));
|
|
||||||
if (!pb_decode_from_bytes(bytes, rawSize, &meshtastic_Data_msg, &p->decoded)) {
|
|
||||||
MSG("[ERROR]Invalid protobufs in received mesh packet (bad psk?)!\n");
|
MSG("[ERROR]Invalid protobufs in received mesh packet (bad psk?)!\n");
|
||||||
} else if (p->decoded.portnum == meshtastic_PortNum_UNKNOWN_APP) {
|
} else if (mp.decoded.portnum == meshtastic_PortNum_UNKNOWN_APP) {
|
||||||
MSG("[ERROR]Invalid portnum (bad psk?)!\n");
|
MSG("[ERROR]Invalid portnum (bad psk?)!\n");
|
||||||
} else {
|
} else {
|
||||||
// parsing was successful
|
mp.which_payload_variant = meshtastic_MeshPacket_decoded_tag;
|
||||||
p->which_payload_variant = meshtastic_MeshPacket_decoded_tag; // change type to decoded
|
mp.channel = generateHash(0);
|
||||||
p->channel = generateHash(0); // change to store the index instead of the hash
|
/*
|
||||||
|
if (mp.decoded.portnum == meshtastic_PortNum_TEXT_MESSAGE_COMPRESSED_APP) {
|
||||||
// Decompress if needed. jm
|
|
||||||
if (p->decoded.portnum == meshtastic_PortNum_TEXT_MESSAGE_COMPRESSED_APP) {
|
|
||||||
// Decompress the payload
|
|
||||||
char compressed_in[meshtastic_Constants_DATA_PAYLOAD_LEN] = {};
|
char compressed_in[meshtastic_Constants_DATA_PAYLOAD_LEN] = {};
|
||||||
char decompressed_out[meshtastic_Constants_DATA_PAYLOAD_LEN] = {};
|
char decompressed_out[meshtastic_Constants_DATA_PAYLOAD_LEN] = {};
|
||||||
int decompressed_len;
|
int decompressed_len;
|
||||||
|
memcpy(compressed_in, mp.decoded.payload.bytes, mp.decoded.payload.size);
|
||||||
memcpy(compressed_in, p->decoded.payload.bytes, p->decoded.payload.size);
|
decompressed_len = unishox2_decompress_simple(compressed_in, mp.decoded.payload.size, decompressed_out);
|
||||||
|
memcpy(mp.decoded.payload.bytes, decompressed_out, decompressed_len);
|
||||||
decompressed_len = unishox2_decompress_simple(compressed_in, p->decoded.payload.size, decompressed_out);
|
mp.decoded.portnum = meshtastic_PortNum_TEXT_MESSAGE_APP;
|
||||||
|
|
||||||
// LOG_DEBUG("\n\n**\n\nDecompressed length - %d \n", decompressed_len);
|
|
||||||
|
|
||||||
memcpy(p->decoded.payload.bytes, decompressed_out, decompressed_len);
|
|
||||||
|
|
||||||
// Switch the port from PortNum_TEXT_MESSAGE_COMPRESSED_APP to PortNum_TEXT_MESSAGE_APP
|
|
||||||
p->decoded.portnum = meshtastic_PortNum_TEXT_MESSAGE_APP;
|
|
||||||
}
|
}
|
||||||
|
*/
|
||||||
printPacket("", p);
|
printPacket();
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
//}
|
MSG("[ERROR]No suitable channel found for decoding, hash was 0x%x!\n", mp.channel);
|
||||||
//}
|
|
||||||
|
|
||||||
MSG("[ERROR]No suitable channel found for decoding, hash was 0x%x!\n", p->channel);
|
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
void printPacket(const char *prefix, const meshtastic_MeshPacket *p) {
|
void printPacket(void) {
|
||||||
|
MSG("[INF](id=0x%08X) from=0x%.2X to=0x%.2X, WantAck=%s, HopLim=%d Ch=0x%X",
|
||||||
MSG("%s(id=0x%08X fr=0x%.2X to=0x%.2X, WantAck=%s, HopLim=%d Ch=0x%X", prefix, p->id,
|
mp.id, mp.from, mp.to, (mp.want_ack)? "YES":"NO", mp.hop_limit, mp.channel);
|
||||||
p->from, p->to, (p->want_ack)? "YES":"NO", p->hop_limit, p->channel);
|
if (mp.which_payload_variant == meshtastic_MeshPacket_decoded_tag) {
|
||||||
if (p->which_payload_variant == meshtastic_MeshPacket_decoded_tag) {
|
auto &s = mp.decoded;
|
||||||
auto &s = p->decoded;
|
|
||||||
MSG(" Portnum=%d", s.portnum);
|
MSG(" Portnum=%d", s.portnum);
|
||||||
if (s.want_response)
|
if (s.want_response) MSG(" WANTRESP");
|
||||||
MSG(" WANTRESP");
|
if (s.source != 0) MSG(" source=%08x", s.source);
|
||||||
if (s.source != 0)
|
if (s.dest != 0) MSG(" dest=%08x", s.dest);
|
||||||
MSG(" source=%08x", s.source);
|
if (s.request_id) MSG(" requestId=%0x", s.request_id);
|
||||||
if (s.dest != 0)
|
if (mp.rx_time != 0) MSG(" rxtime=%u", mp.rx_time);
|
||||||
MSG(" dest=%08x", s.dest);
|
if (mp.rx_snr != 0.0) MSGFLOAT(" rxSNR=", mp.rx_snr);
|
||||||
if (s.request_id)
|
if (mp.rx_rssi != 0) MSG(" rxRSSI=%i", mp.rx_rssi);
|
||||||
MSG(" requestId=%0x", s.request_id);
|
if (mp.via_mqtt != 0) MSG(" via MQTT");
|
||||||
if (p->rx_time != 0)
|
if (mp.priority != 0) MSG(" priority=%d", mp.priority);
|
||||||
MSG(" rxtime=%u", p->rx_time);
|
MSG("\nPayload: ");
|
||||||
if (p->rx_snr != 0.0)
|
printVariants();
|
||||||
MSGFLOAT(" rxSNR=", p->rx_snr);
|
|
||||||
if (p->rx_rssi != 0)
|
|
||||||
MSG(" rxRSSI=%i", p->rx_rssi);
|
|
||||||
if (p->via_mqtt != 0)
|
|
||||||
MSG(" via MQTT");
|
|
||||||
if (p->priority != 0)
|
|
||||||
MSG(" priority=%d", p->priority);
|
|
||||||
|
|
||||||
MSG("\nPayload: "); printVariants(p);
|
|
||||||
} else {
|
} else {
|
||||||
MSG(" encrypted!\n");
|
MSG(" encrypted!\n");
|
||||||
}
|
}
|
||||||
//MSG("\n");
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void printVariants(const meshtastic_MeshPacket *p){
|
void printVariants(void){
|
||||||
|
|
||||||
// Make sure we have a decoded packet
|
// Make sure we have a decoded packet
|
||||||
if (p->which_payload_variant != meshtastic_MeshPacket_decoded_tag)
|
if (mp.which_payload_variant != meshtastic_MeshPacket_decoded_tag)
|
||||||
return;
|
return;
|
||||||
|
auto &d = mp.decoded;
|
||||||
auto &mp = p->decoded;
|
|
||||||
|
|
||||||
// TEXT MESSAGE
|
// TEXT MESSAGE
|
||||||
// /modules/TextMessageModule.cpp
|
// /modules/TextMessageModule.cpp
|
||||||
if (mp.portnum == meshtastic_PortNum_TEXT_MESSAGE_APP){
|
if (d.portnum == meshtastic_PortNum_TEXT_MESSAGE_APP){
|
||||||
MSG("\"%.*s\"\n", mp.payload.size, mp.payload.bytes);
|
MSG("TEXT ");
|
||||||
|
MSG("\"%.*s\"\n", d.payload.size, d.payload.bytes);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
// HARDWARE MESSAGE
|
||||||
|
// /modules/RemoteHardwareModule.cpp
|
||||||
|
if (d.portnum == meshtastic_PortNum_REMOTE_HARDWARE_APP){
|
||||||
|
MSG("GPIO ");
|
||||||
|
meshtastic_NodeRemoteHardwarePin pin;
|
||||||
|
if (!pb_decode_from_bytes(d.payload.bytes, d.payload.size, &meshtastic_NodeRemoteHardwarePin_msg, &pin)) {
|
||||||
|
MSG("*** Error ***\n");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
// POSITION MESSAGE
|
// POSITION MESSAGE
|
||||||
// /modules/PositionModule.cpp
|
// /modules/PositionModule.cpp
|
||||||
if (mp.portnum == meshtastic_PortNum_POSITION_APP){
|
if (d.portnum == meshtastic_PortNum_POSITION_APP){
|
||||||
MSG("Position ");
|
MSG("POSITION ");
|
||||||
meshtastic_Position pos;
|
meshtastic_Position pos;
|
||||||
if (!pb_decode_from_bytes(mp.payload.bytes, mp.payload.size, &meshtastic_Position_msg, &pos)) {
|
if (!pb_decode_from_bytes(d.payload.bytes, d.payload.size, &meshtastic_Position_msg, &pos)) {
|
||||||
MSG("*** Error ***\n");
|
MSG("*** Error ***\n");
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
// Log packet size and data fields
|
// Log packet size and data fields
|
||||||
MSG("node=%08x l=%d latI=%d lonI=%d msl=%d hae=%d geo=%d pdop=%d hdop=%d vdop=%d siv=%d fxq=%d fxt=%d pts=%d "
|
MSG("Node=%08X l=%d latI=%d lonI=%d msl=%d hae=%d geo=%d pdop=%d hdop=%d vdop=%d siv=%d fxq=%d fxt=%d pts=%d "
|
||||||
"time=%d\n",
|
"time=%d\n",
|
||||||
p->from, mp.payload.size, pos.latitude_i, pos.longitude_i, pos.altitude, pos.altitude_hae,
|
mp.from, d.payload.size, pos.latitude_i, pos.longitude_i, pos.altitude, pos.altitude_hae,
|
||||||
pos.altitude_geoidal_separation, pos.PDOP, pos.HDOP, pos.VDOP, pos.sats_in_view, pos.fix_quality, pos.fix_type, pos.timestamp,
|
pos.altitude_geoidal_separation, pos.PDOP, pos.HDOP, pos.VDOP, pos.sats_in_view, pos.fix_quality, pos.fix_type, pos.timestamp,
|
||||||
pos.time);
|
pos.time);
|
||||||
return;
|
return;
|
||||||
|
@ -389,10 +279,10 @@ void printVariants(const meshtastic_MeshPacket *p){
|
||||||
|
|
||||||
// NODEINFO MESSAGE
|
// NODEINFO MESSAGE
|
||||||
// /modules/NodeInfoModule.cpp
|
// /modules/NodeInfoModule.cpp
|
||||||
if (mp.portnum == meshtastic_PortNum_NODEINFO_APP){
|
if (d.portnum == meshtastic_PortNum_NODEINFO_APP){
|
||||||
MSG("Node Info: ");
|
MSG("NODE INFO ");
|
||||||
meshtastic_User user;
|
meshtastic_User user;
|
||||||
if (!pb_decode_from_bytes(mp.payload.bytes, mp.payload.size, &meshtastic_User_msg, &user)) {
|
if (!pb_decode_from_bytes(d.payload.bytes, d.payload.size, &meshtastic_User_msg, &user)) {
|
||||||
MSG("*** Error ***\n");
|
MSG("*** Error ***\n");
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
@ -405,14 +295,37 @@ void printVariants(const meshtastic_MeshPacket *p){
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// ROUTING MESSAGE
|
||||||
|
// /modules/RoutingModule.cpp
|
||||||
|
if (d.portnum == meshtastic_PortNum_ROUTING_APP){
|
||||||
|
MSG("ROUTING \n");
|
||||||
|
/*
|
||||||
|
meshtastic_Routing r;
|
||||||
|
if (!pb_decode_from_bytes(d.payload.bytes, d.payload.size, &meshtastic_Routing_msg, &r)) {
|
||||||
|
MSG("*** Error ***\n");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
if (r.which_variant == sizeof(meshtastic_Routing_Error) ) {
|
||||||
|
MSG("RoutingError=%i\n", r.error_reason);
|
||||||
|
} else {
|
||||||
|
MSG("RouteRequest [");
|
||||||
|
for (uint8_t i=0; i < r.route_request.route_count; i++) MSG("0x%X ", r.route_request.route[i]);
|
||||||
|
MSG("] ");
|
||||||
|
MSG("RouteReply [");
|
||||||
|
for (uint8_t i=0; i < r.route_reply.route_count; i++) MSG("0x%X ", r.route_reply.route[i]);
|
||||||
|
MSG("]\n");
|
||||||
|
|
||||||
|
}
|
||||||
|
*/
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
// TELEMETRY
|
// TELEMETRY MESSAGE
|
||||||
if (mp.portnum == meshtastic_PortNum_TELEMETRY_APP){
|
if (d.portnum == meshtastic_PortNum_TELEMETRY_APP){
|
||||||
MSG("Telemetry ");
|
MSG("TELEMETRY");
|
||||||
meshtastic_Telemetry telemetry;
|
meshtastic_Telemetry telemetry;
|
||||||
meshtastic_Telemetry *t = &telemetry;
|
meshtastic_Telemetry *t = &telemetry;
|
||||||
if (!pb_decode_from_bytes(mp.payload.bytes, mp.payload.size, &meshtastic_Telemetry_msg, &telemetry)) {
|
if (!pb_decode_from_bytes(d.payload.bytes, d.payload.size, &meshtastic_Telemetry_msg, &telemetry)) {
|
||||||
MSG("*** Error ***\n");
|
MSG("*** Error ***\n");
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
@ -444,9 +357,9 @@ void printVariants(const meshtastic_MeshPacket *p){
|
||||||
MSGFLOAT("barometric_pressure=", t->variant.environment_metrics.barometric_pressure);
|
MSGFLOAT("barometric_pressure=", t->variant.environment_metrics.barometric_pressure);
|
||||||
MSGFLOAT(", current=", t->variant.environment_metrics.current);
|
MSGFLOAT(", current=", t->variant.environment_metrics.current);
|
||||||
MSGFLOAT(", gas_resistance=",t->variant.environment_metrics.gas_resistance);
|
MSGFLOAT(", gas_resistance=",t->variant.environment_metrics.gas_resistance);
|
||||||
MSGFLOAT(", relative_humidity=",t->variant.environment_metrics.relative_humidity);
|
MSGFLOAT(", rel_humidity=",t->variant.environment_metrics.relative_humidity);
|
||||||
MSGFLOAT(", temperature=", t->variant.environment_metrics.temperature);
|
MSGFLOAT(", temp=", t->variant.environment_metrics.temperature);
|
||||||
MSGFLOAT(", voltage=", t->variant.environment_metrics.voltage);
|
MSGFLOAT(", volt=", t->variant.environment_metrics.voltage);
|
||||||
MSG("\n");
|
MSG("\n");
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
@ -463,11 +376,123 @@ void printVariants(const meshtastic_MeshPacket *p){
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// TRACEROUTE MESSAGE
|
||||||
|
// /modules/TraceRouteModule.cpp
|
||||||
|
if (d.portnum == meshtastic_PortNum_TRACEROUTE_APP){
|
||||||
|
MSG("TRACEROUTE");
|
||||||
|
meshtastic_RouteDiscovery route;
|
||||||
|
if (!pb_decode_from_bytes(d.payload.bytes, d.payload.size, &meshtastic_RouteDiscovery_msg, &route)) {
|
||||||
|
MSG("*** Error ***\n");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
MSG("(seen by %i Nodes", route.route_count);
|
||||||
|
if (route.route_count > 0) {
|
||||||
|
for (uint8_t i=0; i < route.route_count; i++) {
|
||||||
|
MSG(" %08X", route.route[i]);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
MSG(")\n");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
// NEIGHBORINFO MESSAGE
|
||||||
|
// /modules/NeighborInfoModule.cpp
|
||||||
|
if (d.portnum == meshtastic_PortNum_NEIGHBORINFO_APP){
|
||||||
|
MSG("NEIGHBORINFO ");
|
||||||
|
meshtastic_NeighborInfo np;
|
||||||
|
if (!pb_decode_from_bytes(d.payload.bytes, d.payload.size, &meshtastic_NeighborInfo_msg, &np)) {
|
||||||
|
MSG("*** Error ***\n");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
MSG("(last sent by 0x%x) Number of neighbors=%d\n", np.last_sent_by_id, np.neighbors_count);
|
||||||
|
for (uint8_t i = 0; i < np.neighbors_count; i++) {
|
||||||
|
MSG("[0x%X, ", np.neighbors[i].node_id);
|
||||||
|
MSGFLOAT("snr=%.2f]\n", np.neighbors[i].snr);
|
||||||
|
}
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
// ATAK PLUGIN MESSAGE
|
||||||
|
// /modules/AtakPluginModule.cpp
|
||||||
|
if (d.portnum == meshtastic_PortNum_ATAK_PLUGIN){
|
||||||
|
MSG("ATAK \n");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
// No known PortNum:
|
// No known PortNum:
|
||||||
MSG("\"");
|
MSG("\"");
|
||||||
for (uint32_t i=0; i < mp.payload.size; i++){
|
for (uint32_t i=0; i < d.payload.size; i++){
|
||||||
MSG("%X", mp.payload.bytes[i]);
|
MSG("%X", d.payload.bytes[i]);
|
||||||
}
|
}
|
||||||
MSG("\"\n");
|
MSG("\"\n");
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// PacketQueueClass Definitions
|
||||||
|
|
||||||
|
void PacketQueueClass::add(uint8_t* buf, size_t size) {
|
||||||
|
uint8_t idx = MAX_TX_QUEUE;
|
||||||
|
for (uint8_t i=0; i<(MAX_TX_QUEUE -1); i++) {
|
||||||
|
if (Queue[i].size == 0) { // search for a free slot
|
||||||
|
idx = i;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (idx == MAX_TX_QUEUE) { // no free slot, overwrite oldest packet
|
||||||
|
for (uint8_t i=1; i<(MAX_TX_QUEUE -1); i++) {
|
||||||
|
if (Queue[idx].packetTime < Queue[i].packetTime) idx = i;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
Queue[idx].size = size;
|
||||||
|
Queue[idx].packetTime = (uint32_t)RtcGetTimerValue();
|
||||||
|
MSG("enQueue Index=%i Size=%i\n", idx, Queue[idx].size);
|
||||||
|
memcpy(Queue[idx].buf, buf, size);
|
||||||
|
hasPackets = true;
|
||||||
|
}
|
||||||
|
|
||||||
|
Packet_t* PacketQueueClass::pop(void) {
|
||||||
|
uint8_t idx = MAX_TX_QUEUE;
|
||||||
|
for (uint8_t i=0 ;i < (MAX_TX_QUEUE -1); i++ ){
|
||||||
|
if (Queue[i].size != 0) { // first not empty entry
|
||||||
|
idx = i;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (idx == MAX_TX_QUEUE) { // empty Queue
|
||||||
|
hasPackets = false;
|
||||||
|
return (Packet_t*)NULL;
|
||||||
|
}
|
||||||
|
for (uint8_t i=idx; i<(MAX_TX_QUEUE -1); i++) {
|
||||||
|
if ( (Queue[i].size != 0) && (Queue[idx].packetTime < Queue[i].packetTime) ) idx = i; // find oldest packet
|
||||||
|
}
|
||||||
|
return &Queue[idx];
|
||||||
|
}
|
||||||
|
|
||||||
|
void PacketQueueClass::clear(void) {
|
||||||
|
for (uint8_t i = 0; i<(MAX_TX_QUEUE - 1); i++) {
|
||||||
|
Queue[i].size = 0; // mark as "deleted"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// idStoreClass Definitions
|
||||||
|
|
||||||
|
bool idStoreClass::add(uint32_t id) {
|
||||||
|
uint8_t idx = 0;
|
||||||
|
for (uint8_t i = MAX_ID_LIST; i > 0; i--) {
|
||||||
|
if (storage[i] == id){
|
||||||
|
return false; // packet ID is known, no update
|
||||||
|
}
|
||||||
|
if (storage[i] == 0) idx = i;
|
||||||
|
}
|
||||||
|
storage[idx] = id;
|
||||||
|
if (++idx <= MAX_ID_LIST) {
|
||||||
|
storage[idx] = 0;
|
||||||
|
} else {
|
||||||
|
storage[0] = 0;
|
||||||
|
}
|
||||||
|
return true; // new packet ID was added
|
||||||
|
}
|
||||||
|
|
||||||
|
void idStoreClass::clear(void) {
|
||||||
|
memset(this->storage, 0, sizeof(this->storage));
|
||||||
|
}
|
161
src/main.h
161
src/main.h
|
@ -10,28 +10,48 @@
|
||||||
#define CC_MY_LORA_BW 125.0 // use these settings, if not using a modem preset
|
#define CC_MY_LORA_BW 125.0 // use these settings, if not using a modem preset
|
||||||
#define CC_MY_LORA_SF 10
|
#define CC_MY_LORA_SF 10
|
||||||
#define CC_MY_LORA_CR 5
|
#define CC_MY_LORA_CR 5
|
||||||
#define CC_MY_LORA_POWER 0 // 0 = max legal power for region
|
#define CC_MY_LORA_POWER 20 // 0 = max legal power for region
|
||||||
#define CC_MY_LORA_FREQ 0.0 // if you want to override frequency calculation, in MHz (e.g. 869.4)
|
#define CC_MY_LORA_FREQ 0.0 // if you want to override frequency calculation: Freq in MHz (e.g. 869.4)
|
||||||
|
|
||||||
#define CC_MAX_POWER 22 // TX power setting. Maximum for CubeCell is 22, enforced by RadioLib.
|
#define CC_MAX_POWER 22 // TX power setting. Absolute Max for CubeCell is 22, enforced by RadioLib.
|
||||||
|
|
||||||
#define MAX_ID_LIST 32 // number of stored packet IDs to prevent unnecesary repeating
|
#define MAX_ID_LIST 64 // number of stored packet IDs to prevent unnecesary repeating
|
||||||
#define MAX_TX_QUEUE 16 // max number of packets which can be waiting for transmission
|
#define MAX_TX_QUEUE 24 // max number of packets which can be waiting for transmission
|
||||||
#define MAX_RHPACKETLEN 256
|
#define MAX_RHPACKETLEN 256
|
||||||
|
|
||||||
#include <RadioLib.h>
|
|
||||||
#ifdef CUBECELL
|
|
||||||
#include "cyPm.c" // for reliable sleep we use MCU_deepSleep()
|
|
||||||
extern uint32_t systime; // CubeCell global system time count, Millis
|
|
||||||
SX1262 radio = new Module(RADIOLIB_BUILTIN_MODULE);
|
|
||||||
#endif //CUBECELL
|
|
||||||
|
|
||||||
/// 16 bytes of random PSK for our _public_ default channel that all devices power up on (AES128)
|
/// 16 bytes of random PSK for our _public_ default channel that all devices power up on (AES128)
|
||||||
/// Meshtastic default key (AQ==):
|
/// Meshtastic default key (AQ==):
|
||||||
static const uint8_t mypsk[] = {0xd4, 0xf1, 0xbb, 0x3a, 0x20, 0x29, 0x07, 0x59,
|
static const uint8_t mypsk[] = {0xd4, 0xf1, 0xbb, 0x3a, 0x20, 0x29, 0x07, 0x59,
|
||||||
0xf0, 0xbc, 0xff, 0xab, 0xcf, 0x4e, 0x69, 0x01};
|
0xf0, 0xbc, 0xff, 0xab, 0xcf, 0x4e, 0x69, 0x01};
|
||||||
// No Crypto = all zero
|
// No Crypto = all zero
|
||||||
|
|
||||||
|
#ifndef SILENT
|
||||||
|
#define MSG(...) Serial.printf(__VA_ARGS__)
|
||||||
|
#define MSGFLOAT(a,b) Serial.print(a); Serial.print(b)
|
||||||
|
#else
|
||||||
|
#define MSG(...)
|
||||||
|
#define MSGFLOAT(a,b)
|
||||||
|
#endif
|
||||||
|
|
||||||
|
// Heltec borked the Arduino.h
|
||||||
|
#ifdef __cplusplus
|
||||||
|
#undef min
|
||||||
|
#undef max
|
||||||
|
#undef abs
|
||||||
|
#include <algorithm>
|
||||||
|
using std::abs;
|
||||||
|
using std::max;
|
||||||
|
using std::min;
|
||||||
|
#endif /* __cplusplus */
|
||||||
|
|
||||||
|
#include <RadioLib.h>
|
||||||
|
|
||||||
|
#ifdef CUBECELL
|
||||||
|
#include "cyPm.c" // for reliable sleep we use MCU_deepSleep()
|
||||||
|
extern uint32_t systime; // CubeCell global system time count, Millis
|
||||||
|
SX1262 radio = new Module(RADIOLIB_BUILTIN_MODULE);
|
||||||
|
#endif
|
||||||
|
|
||||||
#include <assert.h>
|
#include <assert.h>
|
||||||
#include <pb.h>
|
#include <pb.h>
|
||||||
#include <MeshTypes.h>
|
#include <MeshTypes.h>
|
||||||
|
@ -44,62 +64,82 @@ extern "C"
|
||||||
#include <mesh/compression/unishox2.h>
|
#include <mesh/compression/unishox2.h>
|
||||||
}
|
}
|
||||||
|
|
||||||
CryptoKey psk;
|
|
||||||
meshtastic_MeshPacket mp;
|
|
||||||
|
|
||||||
uint8_t radiobuf[MAX_RHPACKETLEN -1];
|
|
||||||
|
|
||||||
typedef struct {
|
typedef struct {
|
||||||
size_t size;
|
size_t size;
|
||||||
uint8_t buf[MAX_RHPACKETLEN -1];
|
uint8_t buf[MAX_RHPACKETLEN -1];
|
||||||
uint32_t packetTime;
|
uint32_t packetTime;
|
||||||
} Packet_t;
|
} Packet_t;
|
||||||
|
|
||||||
Packet_t txQueue[MAX_TX_QUEUE - 1];
|
typedef struct {
|
||||||
uint32_t idList[MAX_ID_LIST - 1];
|
uint32_t to, from;
|
||||||
|
uint32_t id;
|
||||||
|
uint8_t flags;
|
||||||
|
uint8_t channel;
|
||||||
|
uint8_t next_hop;
|
||||||
|
uint8_t relay_node;
|
||||||
|
} PacketHeader; // see Meshtastic RadioInterface.h
|
||||||
|
|
||||||
|
class PacketQueueClass {
|
||||||
|
private:
|
||||||
|
Packet_t Queue[MAX_TX_QUEUE - 1];
|
||||||
|
public:
|
||||||
|
void clear(void);
|
||||||
|
bool hasPackets = false;
|
||||||
|
void add(uint8_t* buf, size_t size);
|
||||||
|
Packet_t* pop(void);
|
||||||
|
};
|
||||||
|
PacketQueueClass txQueue;
|
||||||
|
|
||||||
|
class idStoreClass {
|
||||||
|
private:
|
||||||
|
uint32_t storage[MAX_ID_LIST];
|
||||||
|
public:
|
||||||
|
void clear(void);
|
||||||
|
// add() returns false if the message id is already known
|
||||||
|
bool add(uint32_t id);
|
||||||
|
};
|
||||||
|
idStoreClass msgID;
|
||||||
|
|
||||||
|
CryptoKey psk;
|
||||||
|
meshtastic_MeshPacket mp;
|
||||||
|
uint8_t radiobuf[MAX_RHPACKETLEN];
|
||||||
bool repeatPacket = false;
|
bool repeatPacket = false;
|
||||||
bool txQueueHasPacket = false;
|
|
||||||
int state = RADIOLIB_ERR_NONE;
|
int state = RADIOLIB_ERR_NONE;
|
||||||
|
Packet_t* p = NULL;
|
||||||
|
|
||||||
void MCU_deepsleep(void);
|
void MCU_deepsleep(void);
|
||||||
void clearInterrupts(void);
|
|
||||||
void startReceive(void);
|
void startReceive(void);
|
||||||
bool update_idList(uint32_t id);
|
bool perhapsSend(uint8_t* buf, size_t size);
|
||||||
void enqueueTX(uint8_t* buf, size_t size);
|
bool perhapsDecode(uint8_t* buf, size_t size);
|
||||||
uint8_t poptxQueue(void);
|
void printPacket(void);
|
||||||
void perhapsSend(uint8_t* buf, size_t size);
|
void printVariants(void);
|
||||||
|
|
||||||
void printVariants(const meshtastic_MeshPacket *p);
|
bool PacketReceived = false;
|
||||||
void printPacket(const char *prefix, const meshtastic_MeshPacket *p);
|
bool PacketSent = false;
|
||||||
bool perhapsDecode(meshtastic_MeshPacket *p);
|
volatile bool dio1 = false;
|
||||||
|
|
||||||
// Flag and ISR for "Received packet" - events
|
void ISR_dio1Action(void) {
|
||||||
volatile bool PacketReceived = false;
|
dio1 = true;
|
||||||
|
|
||||||
void ISR_setReceived(void) {
|
|
||||||
PacketReceived = true;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// Flag and ISR for "Packet sent" - events
|
|
||||||
volatile bool PacketSent = false;
|
|
||||||
|
|
||||||
void ISR_setPacketSent(void) {
|
|
||||||
PacketSent = true;
|
|
||||||
}
|
|
||||||
|
|
||||||
#ifndef SILENT
|
|
||||||
#define MSG(...) Serial.printf(__VA_ARGS__)
|
|
||||||
#define MSGFLOAT(a,b) Serial.print(a); Serial.print(b)
|
|
||||||
#else
|
|
||||||
#define MSG(...)
|
|
||||||
#define MSGFLOAT(a,b)
|
|
||||||
#endif
|
|
||||||
|
|
||||||
|
|
||||||
/**************
|
/**************
|
||||||
* Meshtastic *
|
* Meshtastic * https://github.com/meshtastic/firmware
|
||||||
**************/
|
**************/
|
||||||
|
|
||||||
|
/** Slottime is the minimum time to wait, consisting of:
|
||||||
|
- CAD duration (maximum of SX126x and SX127x);
|
||||||
|
- roundtrip air propagation time (assuming max. 30km between nodes);
|
||||||
|
- Tx/Rx turnaround time (maximum of SX126x and SX127x);
|
||||||
|
- MAC processing time (measured on T-beam) */
|
||||||
|
uint32_t slotTimeMsec; //= 8.5 * pow(2, sf) / bw + 0.2 + 0.4 + 7; --> calculated at applyModemConfig()
|
||||||
|
uint16_t preambleLength = 16; // 8 is default, but we use longer to increase the amount of sleep time when receiving
|
||||||
|
uint32_t preambleTimeMsec = 165; // calculated on startup, this is the default for LongFast
|
||||||
|
uint32_t maxPacketTimeMsec = 3246; // calculated on startup, this is the default for LongFast
|
||||||
|
const uint32_t PROCESSING_TIME_MSEC =
|
||||||
|
4500; // time to construct, process and construct a packet again (empirically determined)
|
||||||
|
const uint8_t CWmin = 2; // minimum CWsize
|
||||||
|
const uint8_t CWmax = 8; // maximum CWsize
|
||||||
|
|
||||||
#define PACKET_FLAGS_HOP_MASK 0x07
|
#define PACKET_FLAGS_HOP_MASK 0x07
|
||||||
#define PACKET_FLAGS_WANT_ACK_MASK 0x08
|
#define PACKET_FLAGS_WANT_ACK_MASK 0x08
|
||||||
#define PACKET_FLAGS_VIA_MQTT_MASK 0x10
|
#define PACKET_FLAGS_VIA_MQTT_MASK 0x10
|
||||||
|
@ -111,8 +151,7 @@ size_t pb_encode_to_bytes(uint8_t *destbuf, size_t destbufsize, const pb_msgdesc
|
||||||
pb_ostream_t stream = pb_ostream_from_buffer(destbuf, destbufsize);
|
pb_ostream_t stream = pb_ostream_from_buffer(destbuf, destbufsize);
|
||||||
if (!pb_encode(&stream, fields, src_struct)) {
|
if (!pb_encode(&stream, fields, src_struct)) {
|
||||||
MSG("[ERROR]Panic: can't encode protobuf reason='%s'\n", PB_GET_ERROR(&stream));
|
MSG("[ERROR]Panic: can't encode protobuf reason='%s'\n", PB_GET_ERROR(&stream));
|
||||||
assert(
|
//assert(0); // If this assert fails it probably means you made a field too large for the max limits specified in mesh.options
|
||||||
0); // If this assert fails it probably means you made a field too large for the max limits specified in mesh.options
|
|
||||||
} else {
|
} else {
|
||||||
return stream.bytes_written;
|
return stream.bytes_written;
|
||||||
}
|
}
|
||||||
|
@ -148,7 +187,9 @@ struct RegionInfo {
|
||||||
bool wideLora;
|
bool wideLora;
|
||||||
const char *name; // EU433 etc
|
const char *name; // EU433 etc
|
||||||
};
|
};
|
||||||
|
|
||||||
const RegionInfo *myRegion;
|
const RegionInfo *myRegion;
|
||||||
|
|
||||||
const RegionInfo regions[] = {
|
const RegionInfo regions[] = {
|
||||||
/*
|
/*
|
||||||
https://link.springer.com/content/pdf/bbm%3A978-1-4842-4357-2%2F1.pdf
|
https://link.springer.com/content/pdf/bbm%3A978-1-4842-4357-2%2F1.pdf
|
||||||
|
@ -269,10 +310,11 @@ const RegionInfo regions[] = {
|
||||||
|
|
||||||
void initRegion()
|
void initRegion()
|
||||||
{
|
{
|
||||||
|
MSG("[INF]Init region List ...");
|
||||||
const RegionInfo *r = regions;
|
const RegionInfo *r = regions;
|
||||||
for (; r->code != meshtastic_Config_LoRaConfig_RegionCode_UNSET && r->code != CC_MY_REGION; r++)
|
for (; r->code != meshtastic_Config_LoRaConfig_RegionCode_UNSET && r->code != CC_MY_REGION; r++) ;
|
||||||
;
|
|
||||||
myRegion = r;
|
myRegion = r;
|
||||||
|
MSG(" done!\n");
|
||||||
}
|
}
|
||||||
|
|
||||||
/** hash a string into an integer
|
/** hash a string into an integer
|
||||||
|
@ -330,10 +372,10 @@ int16_t generateHash(ChannelIndex channelNum)
|
||||||
|
|
||||||
void applyModemConfig()
|
void applyModemConfig()
|
||||||
{
|
{
|
||||||
float bw=0;
|
float bw = 0;
|
||||||
uint8_t sf = 0;
|
uint8_t sf = 0;
|
||||||
uint8_t cr = 0;
|
uint8_t cr = 0;
|
||||||
int8_t power = 0; // 0 = max legal power for region
|
int8_t power = CC_MY_LORA_POWER; // 0 = max legal power for region
|
||||||
float freq = 0;
|
float freq = 0;
|
||||||
|
|
||||||
if (CC_LORA_USE_PRESET) {
|
if (CC_LORA_USE_PRESET) {
|
||||||
|
@ -426,13 +468,12 @@ void applyModemConfig()
|
||||||
channel_num = -1;
|
channel_num = -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
MSG("\nRegion %s (Power Limit is %idb) ",myRegion->name, myRegion->powerLimit);
|
MSG("[INF]Using Region %s freq %d bw %i sf %i cr %i power %i ... ",myRegion->name, lround(freq*1E6), lround(bw*1000), sf, cr, power);
|
||||||
MSG(" freq %d bw %i sf %i cr %i power %i ... ", lround(freq*1E6), lround(bw*1000), sf, cr, power);
|
|
||||||
|
|
||||||
// Syncword is 0x2b, see RadioLibInterface.h
|
// Syncword is 0x2b, see RadioLibInterface.h
|
||||||
// preamble length is 16, see RadioInterface.h
|
// preamble length is 16, see RadioInterface.h
|
||||||
|
|
||||||
int state = radio.begin(freq, bw, sf, cr, 0x2b, power, 16);
|
state = radio.begin(freq, bw, sf, cr, 0x2b, power, 16);
|
||||||
|
|
||||||
if (state == RADIOLIB_ERR_NONE) {
|
if (state == RADIOLIB_ERR_NONE) {
|
||||||
MSG("success!\n");
|
MSG("success!\n");
|
||||||
|
@ -441,4 +482,6 @@ void applyModemConfig()
|
||||||
while (true);
|
while (true);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// used to calculate wait time before repeating a packet
|
||||||
|
slotTimeMsec = 8.5 * pow(2, sf) / bw + 0.2 + 0.4 + 7;
|
||||||
}
|
}
|
|
@ -55,7 +55,7 @@ extern const pb_msgdesc_t meshtastic_ChannelSet_msg;
|
||||||
|
|
||||||
/* Maximum encoded size of messages (where known) */
|
/* Maximum encoded size of messages (where known) */
|
||||||
#define MESHTASTIC_MESHTASTIC_APPONLY_PB_H_MAX_SIZE meshtastic_ChannelSet_size
|
#define MESHTASTIC_MESHTASTIC_APPONLY_PB_H_MAX_SIZE meshtastic_ChannelSet_size
|
||||||
#define meshtastic_ChannelSet_size 658
|
#define meshtastic_ChannelSet_size 674
|
||||||
|
|
||||||
#ifdef __cplusplus
|
#ifdef __cplusplus
|
||||||
} /* extern "C" */
|
} /* extern "C" */
|
||||||
|
|
|
@ -34,6 +34,9 @@ typedef enum _meshtastic_Channel_Role {
|
||||||
typedef struct _meshtastic_ModuleSettings {
|
typedef struct _meshtastic_ModuleSettings {
|
||||||
/* Bits of precision for the location sent in position packets. */
|
/* Bits of precision for the location sent in position packets. */
|
||||||
uint32_t position_precision;
|
uint32_t position_precision;
|
||||||
|
/* Controls whether or not the phone / clients should mute the current channel
|
||||||
|
Useful for noisy public channels you don't necessarily want to disable */
|
||||||
|
bool is_client_muted;
|
||||||
} meshtastic_ModuleSettings;
|
} meshtastic_ModuleSettings;
|
||||||
|
|
||||||
typedef PB_BYTES_ARRAY_T(32) meshtastic_ChannelSettings_psk_t;
|
typedef PB_BYTES_ARRAY_T(32) meshtastic_ChannelSettings_psk_t;
|
||||||
|
@ -126,14 +129,15 @@ extern "C" {
|
||||||
|
|
||||||
/* Initializer values for message structs */
|
/* Initializer values for message structs */
|
||||||
#define meshtastic_ChannelSettings_init_default {0, {0, {0}}, "", 0, 0, 0, false, meshtastic_ModuleSettings_init_default}
|
#define meshtastic_ChannelSettings_init_default {0, {0, {0}}, "", 0, 0, 0, false, meshtastic_ModuleSettings_init_default}
|
||||||
#define meshtastic_ModuleSettings_init_default {0}
|
#define meshtastic_ModuleSettings_init_default {0, 0}
|
||||||
#define meshtastic_Channel_init_default {0, false, meshtastic_ChannelSettings_init_default, _meshtastic_Channel_Role_MIN}
|
#define meshtastic_Channel_init_default {0, false, meshtastic_ChannelSettings_init_default, _meshtastic_Channel_Role_MIN}
|
||||||
#define meshtastic_ChannelSettings_init_zero {0, {0, {0}}, "", 0, 0, 0, false, meshtastic_ModuleSettings_init_zero}
|
#define meshtastic_ChannelSettings_init_zero {0, {0, {0}}, "", 0, 0, 0, false, meshtastic_ModuleSettings_init_zero}
|
||||||
#define meshtastic_ModuleSettings_init_zero {0}
|
#define meshtastic_ModuleSettings_init_zero {0, 0}
|
||||||
#define meshtastic_Channel_init_zero {0, false, meshtastic_ChannelSettings_init_zero, _meshtastic_Channel_Role_MIN}
|
#define meshtastic_Channel_init_zero {0, false, meshtastic_ChannelSettings_init_zero, _meshtastic_Channel_Role_MIN}
|
||||||
|
|
||||||
/* Field tags (for use in manual encoding/decoding) */
|
/* Field tags (for use in manual encoding/decoding) */
|
||||||
#define meshtastic_ModuleSettings_position_precision_tag 1
|
#define meshtastic_ModuleSettings_position_precision_tag 1
|
||||||
|
#define meshtastic_ModuleSettings_is_client_muted_tag 2
|
||||||
#define meshtastic_ChannelSettings_channel_num_tag 1
|
#define meshtastic_ChannelSettings_channel_num_tag 1
|
||||||
#define meshtastic_ChannelSettings_psk_tag 2
|
#define meshtastic_ChannelSettings_psk_tag 2
|
||||||
#define meshtastic_ChannelSettings_name_tag 3
|
#define meshtastic_ChannelSettings_name_tag 3
|
||||||
|
@ -159,7 +163,8 @@ X(a, STATIC, OPTIONAL, MESSAGE, module_settings, 7)
|
||||||
#define meshtastic_ChannelSettings_module_settings_MSGTYPE meshtastic_ModuleSettings
|
#define meshtastic_ChannelSettings_module_settings_MSGTYPE meshtastic_ModuleSettings
|
||||||
|
|
||||||
#define meshtastic_ModuleSettings_FIELDLIST(X, a) \
|
#define meshtastic_ModuleSettings_FIELDLIST(X, a) \
|
||||||
X(a, STATIC, SINGULAR, UINT32, position_precision, 1)
|
X(a, STATIC, SINGULAR, UINT32, position_precision, 1) \
|
||||||
|
X(a, STATIC, SINGULAR, BOOL, is_client_muted, 2)
|
||||||
#define meshtastic_ModuleSettings_CALLBACK NULL
|
#define meshtastic_ModuleSettings_CALLBACK NULL
|
||||||
#define meshtastic_ModuleSettings_DEFAULT NULL
|
#define meshtastic_ModuleSettings_DEFAULT NULL
|
||||||
|
|
||||||
|
@ -182,9 +187,9 @@ extern const pb_msgdesc_t meshtastic_Channel_msg;
|
||||||
|
|
||||||
/* Maximum encoded size of messages (where known) */
|
/* Maximum encoded size of messages (where known) */
|
||||||
#define MESHTASTIC_MESHTASTIC_CHANNEL_PB_H_MAX_SIZE meshtastic_Channel_size
|
#define MESHTASTIC_MESHTASTIC_CHANNEL_PB_H_MAX_SIZE meshtastic_Channel_size
|
||||||
#define meshtastic_ChannelSettings_size 70
|
#define meshtastic_ChannelSettings_size 72
|
||||||
#define meshtastic_Channel_size 85
|
#define meshtastic_Channel_size 87
|
||||||
#define meshtastic_ModuleSettings_size 6
|
#define meshtastic_ModuleSettings_size 8
|
||||||
|
|
||||||
#ifdef __cplusplus
|
#ifdef __cplusplus
|
||||||
} /* extern "C" */
|
} /* extern "C" */
|
||||||
|
|
|
@ -283,6 +283,8 @@ typedef struct _meshtastic_Config_DeviceConfig {
|
||||||
bool disable_triple_click;
|
bool disable_triple_click;
|
||||||
/* POSIX Timezone definition string from https://github.com/nayarsystems/posix_tz_db/blob/master/zones.csv. */
|
/* POSIX Timezone definition string from https://github.com/nayarsystems/posix_tz_db/blob/master/zones.csv. */
|
||||||
char tzdef[65];
|
char tzdef[65];
|
||||||
|
/* If true, disable the default blinking LED (LED_PIN) behavior on the device */
|
||||||
|
bool led_heartbeat_disabled;
|
||||||
} meshtastic_Config_DeviceConfig;
|
} meshtastic_Config_DeviceConfig;
|
||||||
|
|
||||||
/* Position Config */
|
/* Position Config */
|
||||||
|
@ -324,35 +326,30 @@ typedef struct _meshtastic_Config_PositionConfig {
|
||||||
/* Power Config\
|
/* Power Config\
|
||||||
See [Power Config](/docs/settings/config/power) for additional power config details. */
|
See [Power Config](/docs/settings/config/power) for additional power config details. */
|
||||||
typedef struct _meshtastic_Config_PowerConfig {
|
typedef struct _meshtastic_Config_PowerConfig {
|
||||||
/* If set, we are powered from a low-current source (i.e. solar), so even if it looks like we have power flowing in
|
/* Description: Will sleep everything as much as possible, for the tracker and sensor role this will also include the lora radio.
|
||||||
we should try to minimize power consumption as much as possible.
|
Don't use this setting if you want to use your device with the phone apps or are using a device without a user button.
|
||||||
YOU DO NOT NEED TO SET THIS IF YOU'VE set is_router (it is implied in that case).
|
Technical Details: Works for ESP32 devices and NRF52 devices in the Sensor or Tracker roles */
|
||||||
Advanced Option */
|
|
||||||
bool is_power_saving;
|
bool is_power_saving;
|
||||||
/* If non-zero, the device will fully power off this many seconds after external power is removed. */
|
/* Description: If non-zero, the device will fully power off this many seconds after external power is removed. */
|
||||||
uint32_t on_battery_shutdown_after_secs;
|
uint32_t on_battery_shutdown_after_secs;
|
||||||
/* Ratio of voltage divider for battery pin eg. 3.20 (R1=100k, R2=220k)
|
/* Ratio of voltage divider for battery pin eg. 3.20 (R1=100k, R2=220k)
|
||||||
Overrides the ADC_MULTIPLIER defined in variant for battery voltage calculation.
|
Overrides the ADC_MULTIPLIER defined in variant for battery voltage calculation.
|
||||||
Should be set to floating point value between 2 and 4
|
https://meshtastic.org/docs/configuration/radio/power/#adc-multiplier-override
|
||||||
Fixes issues on Heltec v2 */
|
Should be set to floating point value between 2 and 6 */
|
||||||
float adc_multiplier_override;
|
float adc_multiplier_override;
|
||||||
/* Wait Bluetooth Seconds
|
/* Description: The number of seconds for to wait before turning off BLE in No Bluetooth states
|
||||||
The number of seconds for to wait before turning off BLE in No Bluetooth states
|
Technical Details: ESP32 Only 0 for default of 1 minute */
|
||||||
0 for default of 1 minute */
|
|
||||||
uint32_t wait_bluetooth_secs;
|
uint32_t wait_bluetooth_secs;
|
||||||
/* Super Deep Sleep Seconds
|
/* Super Deep Sleep Seconds
|
||||||
While in Light Sleep if mesh_sds_timeout_secs is exceeded we will lower into super deep sleep
|
While in Light Sleep if mesh_sds_timeout_secs is exceeded we will lower into super deep sleep
|
||||||
for this value (default 1 year) or a button press
|
for this value (default 1 year) or a button press
|
||||||
0 for default of one year */
|
0 for default of one year */
|
||||||
uint32_t sds_secs;
|
uint32_t sds_secs;
|
||||||
/* Light Sleep Seconds
|
/* Description: In light sleep the CPU is suspended, LoRa radio is on, BLE is off an GPS is on
|
||||||
In light sleep the CPU is suspended, LoRa radio is on, BLE is off an GPS is on
|
Technical Details: ESP32 Only 0 for default of 300 */
|
||||||
ESP32 Only
|
|
||||||
0 for default of 300 */
|
|
||||||
uint32_t ls_secs;
|
uint32_t ls_secs;
|
||||||
/* Minimum Wake Seconds
|
/* Description: While in light sleep when we receive packets on the LoRa radio we will wake and handle them and stay awake in no BLE mode for this value
|
||||||
While in light sleep when we receive packets on the LoRa radio we will wake and handle them and stay awake in no BLE mode for this value
|
Technical Details: ESP32 Only 0 for default of 10 seconds */
|
||||||
0 for default of 10 seconds */
|
|
||||||
uint32_t min_wake_secs;
|
uint32_t min_wake_secs;
|
||||||
/* I2C address of INA_2XX to use for reading device battery voltage */
|
/* I2C address of INA_2XX to use for reading device battery voltage */
|
||||||
uint8_t device_battery_ina_address;
|
uint8_t device_battery_ina_address;
|
||||||
|
@ -585,7 +582,7 @@ extern "C" {
|
||||||
|
|
||||||
/* Initializer values for message structs */
|
/* Initializer values for message structs */
|
||||||
#define meshtastic_Config_init_default {0, {meshtastic_Config_DeviceConfig_init_default}}
|
#define meshtastic_Config_init_default {0, {meshtastic_Config_DeviceConfig_init_default}}
|
||||||
#define meshtastic_Config_DeviceConfig_init_default {_meshtastic_Config_DeviceConfig_Role_MIN, 0, 0, 0, 0, _meshtastic_Config_DeviceConfig_RebroadcastMode_MIN, 0, 0, 0, 0, ""}
|
#define meshtastic_Config_DeviceConfig_init_default {_meshtastic_Config_DeviceConfig_Role_MIN, 0, 0, 0, 0, _meshtastic_Config_DeviceConfig_RebroadcastMode_MIN, 0, 0, 0, 0, "", 0}
|
||||||
#define meshtastic_Config_PositionConfig_init_default {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, _meshtastic_Config_PositionConfig_GpsMode_MIN}
|
#define meshtastic_Config_PositionConfig_init_default {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, _meshtastic_Config_PositionConfig_GpsMode_MIN}
|
||||||
#define meshtastic_Config_PowerConfig_init_default {0, 0, 0, 0, 0, 0, 0, 0}
|
#define meshtastic_Config_PowerConfig_init_default {0, 0, 0, 0, 0, 0, 0, 0}
|
||||||
#define meshtastic_Config_NetworkConfig_init_default {0, "", "", "", 0, _meshtastic_Config_NetworkConfig_AddressMode_MIN, false, meshtastic_Config_NetworkConfig_IpV4Config_init_default, ""}
|
#define meshtastic_Config_NetworkConfig_init_default {0, "", "", "", 0, _meshtastic_Config_NetworkConfig_AddressMode_MIN, false, meshtastic_Config_NetworkConfig_IpV4Config_init_default, ""}
|
||||||
|
@ -594,7 +591,7 @@ extern "C" {
|
||||||
#define meshtastic_Config_LoRaConfig_init_default {0, _meshtastic_Config_LoRaConfig_ModemPreset_MIN, 0, 0, 0, 0, _meshtastic_Config_LoRaConfig_RegionCode_MIN, 0, 0, 0, 0, 0, 0, 0, 0, {0, 0, 0}, 0}
|
#define meshtastic_Config_LoRaConfig_init_default {0, _meshtastic_Config_LoRaConfig_ModemPreset_MIN, 0, 0, 0, 0, _meshtastic_Config_LoRaConfig_RegionCode_MIN, 0, 0, 0, 0, 0, 0, 0, 0, {0, 0, 0}, 0}
|
||||||
#define meshtastic_Config_BluetoothConfig_init_default {0, _meshtastic_Config_BluetoothConfig_PairingMode_MIN, 0}
|
#define meshtastic_Config_BluetoothConfig_init_default {0, _meshtastic_Config_BluetoothConfig_PairingMode_MIN, 0}
|
||||||
#define meshtastic_Config_init_zero {0, {meshtastic_Config_DeviceConfig_init_zero}}
|
#define meshtastic_Config_init_zero {0, {meshtastic_Config_DeviceConfig_init_zero}}
|
||||||
#define meshtastic_Config_DeviceConfig_init_zero {_meshtastic_Config_DeviceConfig_Role_MIN, 0, 0, 0, 0, _meshtastic_Config_DeviceConfig_RebroadcastMode_MIN, 0, 0, 0, 0, ""}
|
#define meshtastic_Config_DeviceConfig_init_zero {_meshtastic_Config_DeviceConfig_Role_MIN, 0, 0, 0, 0, _meshtastic_Config_DeviceConfig_RebroadcastMode_MIN, 0, 0, 0, 0, "", 0}
|
||||||
#define meshtastic_Config_PositionConfig_init_zero {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, _meshtastic_Config_PositionConfig_GpsMode_MIN}
|
#define meshtastic_Config_PositionConfig_init_zero {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, _meshtastic_Config_PositionConfig_GpsMode_MIN}
|
||||||
#define meshtastic_Config_PowerConfig_init_zero {0, 0, 0, 0, 0, 0, 0, 0}
|
#define meshtastic_Config_PowerConfig_init_zero {0, 0, 0, 0, 0, 0, 0, 0}
|
||||||
#define meshtastic_Config_NetworkConfig_init_zero {0, "", "", "", 0, _meshtastic_Config_NetworkConfig_AddressMode_MIN, false, meshtastic_Config_NetworkConfig_IpV4Config_init_zero, ""}
|
#define meshtastic_Config_NetworkConfig_init_zero {0, "", "", "", 0, _meshtastic_Config_NetworkConfig_AddressMode_MIN, false, meshtastic_Config_NetworkConfig_IpV4Config_init_zero, ""}
|
||||||
|
@ -615,6 +612,7 @@ extern "C" {
|
||||||
#define meshtastic_Config_DeviceConfig_is_managed_tag 9
|
#define meshtastic_Config_DeviceConfig_is_managed_tag 9
|
||||||
#define meshtastic_Config_DeviceConfig_disable_triple_click_tag 10
|
#define meshtastic_Config_DeviceConfig_disable_triple_click_tag 10
|
||||||
#define meshtastic_Config_DeviceConfig_tzdef_tag 11
|
#define meshtastic_Config_DeviceConfig_tzdef_tag 11
|
||||||
|
#define meshtastic_Config_DeviceConfig_led_heartbeat_disabled_tag 12
|
||||||
#define meshtastic_Config_PositionConfig_position_broadcast_secs_tag 1
|
#define meshtastic_Config_PositionConfig_position_broadcast_secs_tag 1
|
||||||
#define meshtastic_Config_PositionConfig_position_broadcast_smart_enabled_tag 2
|
#define meshtastic_Config_PositionConfig_position_broadcast_smart_enabled_tag 2
|
||||||
#define meshtastic_Config_PositionConfig_fixed_position_tag 3
|
#define meshtastic_Config_PositionConfig_fixed_position_tag 3
|
||||||
|
@ -715,7 +713,8 @@ X(a, STATIC, SINGULAR, UINT32, node_info_broadcast_secs, 7) \
|
||||||
X(a, STATIC, SINGULAR, BOOL, double_tap_as_button_press, 8) \
|
X(a, STATIC, SINGULAR, BOOL, double_tap_as_button_press, 8) \
|
||||||
X(a, STATIC, SINGULAR, BOOL, is_managed, 9) \
|
X(a, STATIC, SINGULAR, BOOL, is_managed, 9) \
|
||||||
X(a, STATIC, SINGULAR, BOOL, disable_triple_click, 10) \
|
X(a, STATIC, SINGULAR, BOOL, disable_triple_click, 10) \
|
||||||
X(a, STATIC, SINGULAR, STRING, tzdef, 11)
|
X(a, STATIC, SINGULAR, STRING, tzdef, 11) \
|
||||||
|
X(a, STATIC, SINGULAR, BOOL, led_heartbeat_disabled, 12)
|
||||||
#define meshtastic_Config_DeviceConfig_CALLBACK NULL
|
#define meshtastic_Config_DeviceConfig_CALLBACK NULL
|
||||||
#define meshtastic_Config_DeviceConfig_DEFAULT NULL
|
#define meshtastic_Config_DeviceConfig_DEFAULT NULL
|
||||||
|
|
||||||
|
@ -834,7 +833,7 @@ extern const pb_msgdesc_t meshtastic_Config_BluetoothConfig_msg;
|
||||||
/* Maximum encoded size of messages (where known) */
|
/* Maximum encoded size of messages (where known) */
|
||||||
#define MESHTASTIC_MESHTASTIC_CONFIG_PB_H_MAX_SIZE meshtastic_Config_size
|
#define MESHTASTIC_MESHTASTIC_CONFIG_PB_H_MAX_SIZE meshtastic_Config_size
|
||||||
#define meshtastic_Config_BluetoothConfig_size 10
|
#define meshtastic_Config_BluetoothConfig_size 10
|
||||||
#define meshtastic_Config_DeviceConfig_size 98
|
#define meshtastic_Config_DeviceConfig_size 100
|
||||||
#define meshtastic_Config_DisplayConfig_size 28
|
#define meshtastic_Config_DisplayConfig_size 28
|
||||||
#define meshtastic_Config_LoRaConfig_size 80
|
#define meshtastic_Config_LoRaConfig_size 80
|
||||||
#define meshtastic_Config_NetworkConfig_IpV4Config_size 20
|
#define meshtastic_Config_NetworkConfig_IpV4Config_size 20
|
||||||
|
|
|
@ -306,9 +306,9 @@ extern const pb_msgdesc_t meshtastic_OEMStore_msg;
|
||||||
/* Maximum encoded size of messages (where known) */
|
/* Maximum encoded size of messages (where known) */
|
||||||
/* meshtastic_DeviceState_size depends on runtime parameters */
|
/* meshtastic_DeviceState_size depends on runtime parameters */
|
||||||
#define MESHTASTIC_MESHTASTIC_DEVICEONLY_PB_H_MAX_SIZE meshtastic_OEMStore_size
|
#define MESHTASTIC_MESHTASTIC_DEVICEONLY_PB_H_MAX_SIZE meshtastic_OEMStore_size
|
||||||
#define meshtastic_ChannelFile_size 702
|
#define meshtastic_ChannelFile_size 718
|
||||||
#define meshtastic_NodeInfoLite_size 166
|
#define meshtastic_NodeInfoLite_size 166
|
||||||
#define meshtastic_OEMStore_size 3344
|
#define meshtastic_OEMStore_size 3346
|
||||||
#define meshtastic_PositionLite_size 28
|
#define meshtastic_PositionLite_size 28
|
||||||
|
|
||||||
#ifdef __cplusplus
|
#ifdef __cplusplus
|
||||||
|
|
|
@ -181,7 +181,7 @@ extern const pb_msgdesc_t meshtastic_LocalModuleConfig_msg;
|
||||||
|
|
||||||
/* Maximum encoded size of messages (where known) */
|
/* Maximum encoded size of messages (where known) */
|
||||||
#define MESHTASTIC_MESHTASTIC_LOCALONLY_PB_H_MAX_SIZE meshtastic_LocalModuleConfig_size
|
#define MESHTASTIC_MESHTASTIC_LOCALONLY_PB_H_MAX_SIZE meshtastic_LocalModuleConfig_size
|
||||||
#define meshtastic_LocalConfig_size 535
|
#define meshtastic_LocalConfig_size 537
|
||||||
#define meshtastic_LocalModuleConfig_size 663
|
#define meshtastic_LocalModuleConfig_size 663
|
||||||
|
|
||||||
#ifdef __cplusplus
|
#ifdef __cplusplus
|
||||||
|
|
|
@ -63,6 +63,8 @@ typedef enum _meshtastic_HardwareModel {
|
||||||
meshtastic_HardwareModel_NANO_G2_ULTRA = 18,
|
meshtastic_HardwareModel_NANO_G2_ULTRA = 18,
|
||||||
/* LoRAType device: https://loratype.org/ */
|
/* LoRAType device: https://loratype.org/ */
|
||||||
meshtastic_HardwareModel_LORA_TYPE = 19,
|
meshtastic_HardwareModel_LORA_TYPE = 19,
|
||||||
|
/* wiphone https://www.wiphone.io/ */
|
||||||
|
meshtastic_HardwareModel_WIPHONE = 20,
|
||||||
/* B&Q Consulting Station Edition G1: https://uniteng.com/wiki/doku.php?id=meshtastic:station */
|
/* B&Q Consulting Station Edition G1: https://uniteng.com/wiki/doku.php?id=meshtastic:station */
|
||||||
meshtastic_HardwareModel_STATION_G1 = 25,
|
meshtastic_HardwareModel_STATION_G1 = 25,
|
||||||
/* RAK11310 (RP2040 + SX1262) */
|
/* RAK11310 (RP2040 + SX1262) */
|
||||||
|
@ -146,6 +148,14 @@ typedef enum _meshtastic_HardwareModel {
|
||||||
/* Teledatics TD-LORAC NRF52840 based M.2 LoRA module
|
/* Teledatics TD-LORAC NRF52840 based M.2 LoRA module
|
||||||
Compatible with the TD-WRLS development board */
|
Compatible with the TD-WRLS development board */
|
||||||
meshtastic_HardwareModel_TD_LORAC = 60,
|
meshtastic_HardwareModel_TD_LORAC = 60,
|
||||||
|
/* CDEBYTE EoRa-S3 board using their own MM modules, clone of LILYGO T3S3 */
|
||||||
|
meshtastic_HardwareModel_CDEBYTE_EORA_S3 = 61,
|
||||||
|
/* TWC_MESH_V4
|
||||||
|
Adafruit NRF52840 feather express with SX1262, SSD1306 OLED and NEO6M GPS */
|
||||||
|
meshtastic_HardwareModel_TWC_MESH_V4 = 62,
|
||||||
|
/* NRF52_PROMICRO_DIY
|
||||||
|
Promicro NRF52840 with SX1262/LLCC68, SSD1306 OLED and NEO6M GPS */
|
||||||
|
meshtastic_HardwareModel_NRF52_PROMICRO_DIY = 63,
|
||||||
/* ------------------------------------------------------------------------------------------------------------------------------------------
|
/* ------------------------------------------------------------------------------------------------------------------------------------------
|
||||||
Reserved ID For developing private Ports. These will show up in live traffic sparsely, so we can use a high number. Keep it within 8 bits.
|
Reserved ID For developing private Ports. These will show up in live traffic sparsely, so we can use a high number. Keep it within 8 bits.
|
||||||
------------------------------------------------------------------------------------------------------------------------------------------ */
|
------------------------------------------------------------------------------------------------------------------------------------------ */
|
||||||
|
|
|
@ -43,7 +43,11 @@ typedef enum _meshtastic_TelemetrySensorType {
|
||||||
/* INA3221 3 Channel Voltage / Current Sensor */
|
/* INA3221 3 Channel Voltage / Current Sensor */
|
||||||
meshtastic_TelemetrySensorType_INA3221 = 14,
|
meshtastic_TelemetrySensorType_INA3221 = 14,
|
||||||
/* BMP085/BMP180 High accuracy temperature and pressure (older Version of BMP280) */
|
/* BMP085/BMP180 High accuracy temperature and pressure (older Version of BMP280) */
|
||||||
meshtastic_TelemetrySensorType_BMP085 = 15
|
meshtastic_TelemetrySensorType_BMP085 = 15,
|
||||||
|
/* RCWL-9620 Doppler Radar Distance Sensor, used for water level detection */
|
||||||
|
meshtastic_TelemetrySensorType_RCWL9620 = 16,
|
||||||
|
/* Sensirion High accuracy temperature and humidity */
|
||||||
|
meshtastic_TelemetrySensorType_SHT4X = 17
|
||||||
} meshtastic_TelemetrySensorType;
|
} meshtastic_TelemetrySensorType;
|
||||||
|
|
||||||
/* Struct definitions */
|
/* Struct definitions */
|
||||||
|
@ -78,6 +82,8 @@ typedef struct _meshtastic_EnvironmentMetrics {
|
||||||
/* relative scale IAQ value as measured by Bosch BME680 . value 0-500.
|
/* relative scale IAQ value as measured by Bosch BME680 . value 0-500.
|
||||||
Belongs to Air Quality but is not particle but VOC measurement. Other VOC values can also be put in here. */
|
Belongs to Air Quality but is not particle but VOC measurement. Other VOC values can also be put in here. */
|
||||||
uint16_t iaq;
|
uint16_t iaq;
|
||||||
|
/* RCWL9620 Doppler Radar Distance Sensor, used for water level detection. Float value in mm. */
|
||||||
|
float distance;
|
||||||
} meshtastic_EnvironmentMetrics;
|
} meshtastic_EnvironmentMetrics;
|
||||||
|
|
||||||
/* Power Metrics (voltage / current / etc) */
|
/* Power Metrics (voltage / current / etc) */
|
||||||
|
@ -148,8 +154,8 @@ extern "C" {
|
||||||
|
|
||||||
/* Helper constants for enums */
|
/* Helper constants for enums */
|
||||||
#define _meshtastic_TelemetrySensorType_MIN meshtastic_TelemetrySensorType_SENSOR_UNSET
|
#define _meshtastic_TelemetrySensorType_MIN meshtastic_TelemetrySensorType_SENSOR_UNSET
|
||||||
#define _meshtastic_TelemetrySensorType_MAX meshtastic_TelemetrySensorType_BMP085
|
#define _meshtastic_TelemetrySensorType_MAX meshtastic_TelemetrySensorType_SHT4X
|
||||||
#define _meshtastic_TelemetrySensorType_ARRAYSIZE ((meshtastic_TelemetrySensorType)(meshtastic_TelemetrySensorType_BMP085+1))
|
#define _meshtastic_TelemetrySensorType_ARRAYSIZE ((meshtastic_TelemetrySensorType)(meshtastic_TelemetrySensorType_SHT4X+1))
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
@ -159,12 +165,12 @@ extern "C" {
|
||||||
|
|
||||||
/* Initializer values for message structs */
|
/* Initializer values for message structs */
|
||||||
#define meshtastic_DeviceMetrics_init_default {0, 0, 0, 0, 0}
|
#define meshtastic_DeviceMetrics_init_default {0, 0, 0, 0, 0}
|
||||||
#define meshtastic_EnvironmentMetrics_init_default {0, 0, 0, 0, 0, 0, 0}
|
#define meshtastic_EnvironmentMetrics_init_default {0, 0, 0, 0, 0, 0, 0, 0}
|
||||||
#define meshtastic_PowerMetrics_init_default {0, 0, 0, 0, 0, 0}
|
#define meshtastic_PowerMetrics_init_default {0, 0, 0, 0, 0, 0}
|
||||||
#define meshtastic_AirQualityMetrics_init_default {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}
|
#define meshtastic_AirQualityMetrics_init_default {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}
|
||||||
#define meshtastic_Telemetry_init_default {0, 0, {meshtastic_DeviceMetrics_init_default}}
|
#define meshtastic_Telemetry_init_default {0, 0, {meshtastic_DeviceMetrics_init_default}}
|
||||||
#define meshtastic_DeviceMetrics_init_zero {0, 0, 0, 0, 0}
|
#define meshtastic_DeviceMetrics_init_zero {0, 0, 0, 0, 0}
|
||||||
#define meshtastic_EnvironmentMetrics_init_zero {0, 0, 0, 0, 0, 0, 0}
|
#define meshtastic_EnvironmentMetrics_init_zero {0, 0, 0, 0, 0, 0, 0, 0}
|
||||||
#define meshtastic_PowerMetrics_init_zero {0, 0, 0, 0, 0, 0}
|
#define meshtastic_PowerMetrics_init_zero {0, 0, 0, 0, 0, 0}
|
||||||
#define meshtastic_AirQualityMetrics_init_zero {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}
|
#define meshtastic_AirQualityMetrics_init_zero {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}
|
||||||
#define meshtastic_Telemetry_init_zero {0, 0, {meshtastic_DeviceMetrics_init_zero}}
|
#define meshtastic_Telemetry_init_zero {0, 0, {meshtastic_DeviceMetrics_init_zero}}
|
||||||
|
@ -182,6 +188,7 @@ extern "C" {
|
||||||
#define meshtastic_EnvironmentMetrics_voltage_tag 5
|
#define meshtastic_EnvironmentMetrics_voltage_tag 5
|
||||||
#define meshtastic_EnvironmentMetrics_current_tag 6
|
#define meshtastic_EnvironmentMetrics_current_tag 6
|
||||||
#define meshtastic_EnvironmentMetrics_iaq_tag 7
|
#define meshtastic_EnvironmentMetrics_iaq_tag 7
|
||||||
|
#define meshtastic_EnvironmentMetrics_distance_tag 8
|
||||||
#define meshtastic_PowerMetrics_ch1_voltage_tag 1
|
#define meshtastic_PowerMetrics_ch1_voltage_tag 1
|
||||||
#define meshtastic_PowerMetrics_ch1_current_tag 2
|
#define meshtastic_PowerMetrics_ch1_current_tag 2
|
||||||
#define meshtastic_PowerMetrics_ch2_voltage_tag 3
|
#define meshtastic_PowerMetrics_ch2_voltage_tag 3
|
||||||
|
@ -223,7 +230,8 @@ X(a, STATIC, SINGULAR, FLOAT, barometric_pressure, 3) \
|
||||||
X(a, STATIC, SINGULAR, FLOAT, gas_resistance, 4) \
|
X(a, STATIC, SINGULAR, FLOAT, gas_resistance, 4) \
|
||||||
X(a, STATIC, SINGULAR, FLOAT, voltage, 5) \
|
X(a, STATIC, SINGULAR, FLOAT, voltage, 5) \
|
||||||
X(a, STATIC, SINGULAR, FLOAT, current, 6) \
|
X(a, STATIC, SINGULAR, FLOAT, current, 6) \
|
||||||
X(a, STATIC, SINGULAR, UINT32, iaq, 7)
|
X(a, STATIC, SINGULAR, UINT32, iaq, 7) \
|
||||||
|
X(a, STATIC, SINGULAR, FLOAT, distance, 8)
|
||||||
#define meshtastic_EnvironmentMetrics_CALLBACK NULL
|
#define meshtastic_EnvironmentMetrics_CALLBACK NULL
|
||||||
#define meshtastic_EnvironmentMetrics_DEFAULT NULL
|
#define meshtastic_EnvironmentMetrics_DEFAULT NULL
|
||||||
|
|
||||||
|
@ -283,7 +291,7 @@ extern const pb_msgdesc_t meshtastic_Telemetry_msg;
|
||||||
#define MESHTASTIC_MESHTASTIC_TELEMETRY_PB_H_MAX_SIZE meshtastic_Telemetry_size
|
#define MESHTASTIC_MESHTASTIC_TELEMETRY_PB_H_MAX_SIZE meshtastic_Telemetry_size
|
||||||
#define meshtastic_AirQualityMetrics_size 72
|
#define meshtastic_AirQualityMetrics_size 72
|
||||||
#define meshtastic_DeviceMetrics_size 27
|
#define meshtastic_DeviceMetrics_size 27
|
||||||
#define meshtastic_EnvironmentMetrics_size 34
|
#define meshtastic_EnvironmentMetrics_size 39
|
||||||
#define meshtastic_PowerMetrics_size 30
|
#define meshtastic_PowerMetrics_size 30
|
||||||
#define meshtastic_Telemetry_size 79
|
#define meshtastic_Telemetry_size 79
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue