Use CAD cycle, better deep sleep
This commit is contained in:
parent
193dfda32a
commit
b6ce634744
|
@ -1,81 +0,0 @@
|
||||||
#include "mesh.pb.h"
|
|
||||||
// CONFIGURATION:
|
|
||||||
#define REGION RegionCode_EU865 // define your region here. For US, RegionCode_US, CN RegionCode_Cn etc.
|
|
||||||
char MESHTASTIC_NAME[12] = {"Default"}; // Channel Name, but without "-Xy" suffix , e.g. use "Test" instead of "Test-A"
|
|
||||||
#define MESHTASTIC_SPEED 3 // 0 = short range, 1 = medium range, 2 = long range, 3 = very long range
|
|
||||||
#define TX_MAX_POWER 14 // max output power in dB, keep in mind the maximums set by law and the hardware
|
|
||||||
// :CONFIGURATION
|
|
||||||
|
|
||||||
#define RGB_GREEN 0x000300 // receive mode --- not longer used
|
|
||||||
#define RGB_RED 0x030000 // send mode
|
|
||||||
|
|
||||||
#define LORA_PREAMBLE_LENGTH 32 // Same for Tx and Rx
|
|
||||||
#define LORA_SYMBOL_TIMEOUT 0 // Symbols
|
|
||||||
#define RX_TIMEOUT_VALUE 1000
|
|
||||||
#define MAX_PAYLOAD_LENGTH 0xFF // max payload (see \cores\asr650x\device\asr6501_lrwan\radio.c --> MaxPayloadLength)
|
|
||||||
|
|
||||||
/* possible RegionCodes, from mesh.pb.h:
|
|
||||||
typedef enum _RegionCode {
|
|
||||||
RegionCode_Unset = 0,
|
|
||||||
RegionCode_US = 1,
|
|
||||||
RegionCode_EU433 = 2,
|
|
||||||
RegionCode_EU865 = 3,
|
|
||||||
RegionCode_CN = 4,
|
|
||||||
RegionCode_JP = 5,
|
|
||||||
RegionCode_ANZ = 6,
|
|
||||||
RegionCode_KR = 7,
|
|
||||||
RegionCode_TW = 8
|
|
||||||
} RegionCode;
|
|
||||||
*/
|
|
||||||
|
|
||||||
// the PSK is not used for encryption/decryption, you can leave it as it is
|
|
||||||
#define MESHTASTIC_PSK { 0x10, 0xd4, 0xf1, 0xbb, 0x3a, 0x20, 0x29, 0x07, 0x59, 0xf0, 0xbc, 0xff, 0xab, 0xcf, 0x4e, 0x69, 0xbf }
|
|
||||||
#define PSK_NOENCRYPTION { 0x10, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 }
|
|
||||||
|
|
||||||
typedef struct {
|
|
||||||
uint32_t to, from, id;
|
|
||||||
uint8_t flags; // The bottom three bits of flags are used to store hop_limit, bit 4 is the WANT_ACK flag
|
|
||||||
} PacketHeader;
|
|
||||||
|
|
||||||
#define MSG(...) Serial.printf(__VA_ARGS__)
|
|
||||||
//#define DUTY(symbTime) ( (uint32_t)( symbTime * LORA_PREAMBLE_LENGTH / 2 ) )
|
|
||||||
|
|
||||||
void onTxDone( void );
|
|
||||||
void onCadDone( bool ChannelActive );
|
|
||||||
void onRxTimeout( void );
|
|
||||||
void onTxTimeout( void );
|
|
||||||
void onRxDone( uint8_t *payload, uint16_t size, int16_t rssi, int8_t snr );
|
|
||||||
void onCheckRadio(void);
|
|
||||||
void ConfigureRadio( ChannelSettings ChanSet );
|
|
||||||
unsigned long hash(char *str);
|
|
||||||
|
|
||||||
|
|
||||||
// from Meshtastic project: MeshRadio.h , RadioInterface.cpp
|
|
||||||
#define RDEF(name, freq, spacing, num_ch, power_limit) \
|
|
||||||
{ \
|
|
||||||
RegionCode_##name, num_ch, power_limit, freq, spacing, #name \
|
|
||||||
}
|
|
||||||
struct RegionInfo {
|
|
||||||
RegionCode code;
|
|
||||||
uint8_t numChannels;
|
|
||||||
uint8_t powerLimit; // Or zero for not set
|
|
||||||
float freq;
|
|
||||||
float spacing;
|
|
||||||
const char *name; // EU433 etc
|
|
||||||
};
|
|
||||||
|
|
||||||
const RegionInfo regions[] = {
|
|
||||||
RDEF(Unset, 903.08f, 2.16f, 13, 0), // I put it FIRST, so i can use regions[] with RegionCode as index (Unset == 0)
|
|
||||||
RDEF(US, 903.08f, 2.16f, 13, 0),
|
|
||||||
RDEF(EU433, 433.175f, 0.2f, 8, 0),
|
|
||||||
RDEF(EU865, 865.2f, 0.3f, 10, 0),
|
|
||||||
RDEF(CN, 470.0f, 2.0f, 20, 0),
|
|
||||||
RDEF(JP, 920.0f, 0.5f, 10, 13), // See https://github.com/meshtastic/Meshtastic-device/issues/346 power level 13
|
|
||||||
RDEF(ANZ, 916.0f, 0.5f, 20, 0), // AU/NZ channel settings 915-928MHz
|
|
||||||
RDEF(KR, 921.9f, 0.2f, 8, 0), // KR channel settings (KR920-923) Start from TTN download channel
|
|
||||||
// freq. (921.9f is for download, others are for uplink)
|
|
||||||
RDEF(TW, 923.0f, 0.2f, 10, 0) // TW channel settings (AS2 bandplan 923-925MHz)
|
|
||||||
};
|
|
||||||
|
|
||||||
// Bandwidths and CodeRate. Arrays are specific to the Radio.c of the CubeCells
|
|
||||||
const uint32_t TheBandwidths[] = { 125E3, 250E3, 500E3, 62500, 41670, 31250, 20830, 15630, 10420, 7810 };
|
|
|
@ -1,309 +0,0 @@
|
||||||
#include <Arduino.h>
|
|
||||||
#include "config.h"
|
|
||||||
|
|
||||||
// CONFIGURATION:
|
|
||||||
// Change RegionCode, Frequency, Speed in config.h !
|
|
||||||
#define VERBOSE // define to SILENT to turn off serial messages
|
|
||||||
#define NOBLINK // define to NOBLINK to turn off LED signaling
|
|
||||||
#define NO_OLED // define to NO_OLED to turn off display
|
|
||||||
// OLED supported for cubecell_board_Plus (HTCC-AB02) and cubecell_gps (HTCC-AB02S)
|
|
||||||
// :CONFIGURATION
|
|
||||||
|
|
||||||
static MeshPacket thePacket;
|
|
||||||
static ChannelSettings ChanSet;
|
|
||||||
static RadioEvents_t RadioEvents;
|
|
||||||
static TimerEvent_t CheckRadio;
|
|
||||||
static uint32_t lastreceivedID = 0;
|
|
||||||
static uint32_t sleepTime;
|
|
||||||
static bool noTimer;
|
|
||||||
static uint32_t startTime = 0;
|
|
||||||
|
|
||||||
#ifndef NOBLINK
|
|
||||||
#include "CubeCell_NeoPixel.h"
|
|
||||||
CubeCell_NeoPixel LED(1, RGB, NEO_GRB + NEO_KHZ800);
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#ifndef NO_OLED
|
|
||||||
#ifdef CubeCell_BoardPlus
|
|
||||||
#include "cubecell_SH1107Wire.h"
|
|
||||||
SH1107Wire display(0x3c, 500000, I2C_NUM_0,GEOMETRY_128_64,GPIO10 );
|
|
||||||
#endif
|
|
||||||
#ifdef CubeCell_GPS
|
|
||||||
#include "cubecell_SSD1306Wire.h"
|
|
||||||
SSD1306Wire display(0x3c, 500000, I2C_NUM_0,GEOMETRY_128_64,GPIO10 );
|
|
||||||
#endif
|
|
||||||
char str[32];
|
|
||||||
#endif
|
|
||||||
|
|
||||||
void setup() {
|
|
||||||
TimerInit( &CheckRadio, onCheckRadio );
|
|
||||||
#ifndef NO_OLED
|
|
||||||
pinMode(Vext,OUTPUT);
|
|
||||||
digitalWrite(Vext,LOW);
|
|
||||||
#endif
|
|
||||||
#ifndef NOBLINK
|
|
||||||
pinMode(Vext,OUTPUT);
|
|
||||||
digitalWrite(Vext,LOW);
|
|
||||||
delay(100);
|
|
||||||
LED.begin();
|
|
||||||
LED.clear( );
|
|
||||||
LED.show();
|
|
||||||
#endif
|
|
||||||
#ifndef NO_OLED
|
|
||||||
display.init();
|
|
||||||
display.clear();
|
|
||||||
display.setTextAlignment(TEXT_ALIGN_LEFT);
|
|
||||||
display.setFont(ArialMT_Plain_16);
|
|
||||||
display.drawString(0,0,"CC Repeater");
|
|
||||||
display.display();
|
|
||||||
#endif
|
|
||||||
#ifndef SILENT
|
|
||||||
Serial.begin(115200);
|
|
||||||
MSG("\nSetting up Radio:\n");
|
|
||||||
#endif
|
|
||||||
RadioEvents.TxDone = onTxDone;
|
|
||||||
RadioEvents.TxTimeout = onTxTimeout;
|
|
||||||
RadioEvents.RxDone = onRxDone;
|
|
||||||
RadioEvents.RxTimeout = onRxTimeout;
|
|
||||||
RadioEvents.CadDone = onCadDone;
|
|
||||||
Radio.Init( &RadioEvents );
|
|
||||||
Radio.Sleep();
|
|
||||||
memcpy(ChanSet.name, MESHTASTIC_NAME, 12);
|
|
||||||
ChanSet.channel_num = hash( MESHTASTIC_NAME ) % regions[REGION].numChannels; // see config.h
|
|
||||||
ChanSet.tx_power = (regions[REGION].powerLimit == 0) ? TX_MAX_POWER : MIN(regions[REGION].powerLimit, TX_MAX_POWER) ;
|
|
||||||
//ChanSet.psk = MESHTASTIC_PSK;
|
|
||||||
ChanSet.psk = PSK_NOENCRYPTION;
|
|
||||||
/* FYI:
|
|
||||||
"bandwidth":
|
|
||||||
[0: 125 kHz, 1: 250 kHz, 2: 500 kHz, 3: 62.5kHz, 4: 41.67kHz, 5: 31.25kHz, 6: 20.83kHz, 7: 15.63kHz, 8: 10.42kHz, 9: 7.81kHz]
|
|
||||||
"speed":
|
|
||||||
0: ChannelSettings_ModemConfig_Bw125Cr45Sf128 aka short range
|
|
||||||
1: ChannelSettings_ModemConfig_Bw500Cr45Sf128 aka medium range
|
|
||||||
2: ChannelSettings_ModemConfig_Bw31_25Cr48Sf512 aka long range
|
|
||||||
3: ChannelSettings_ModemConfig_Bw125Cr48Sf4096 aka very long range
|
|
||||||
"coding rate":
|
|
||||||
[1: 4/5, 2: 4/6, 3: 4/7, 4: 4/8]
|
|
||||||
*/
|
|
||||||
switch ( MESHTASTIC_SPEED ){
|
|
||||||
case 0: { // short range
|
|
||||||
ChanSet.bandwidth = 0; // 125 kHz
|
|
||||||
ChanSet.coding_rate = 1; // = 4/5
|
|
||||||
ChanSet.spread_factor = 7;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
case 1: { // medium range
|
|
||||||
ChanSet.bandwidth = 2; // 500 kHz
|
|
||||||
ChanSet.coding_rate = 1; // = 4/5
|
|
||||||
ChanSet.spread_factor = 7;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
case 2: { // long range
|
|
||||||
ChanSet.bandwidth = 5; // 31.25 kHz
|
|
||||||
ChanSet.coding_rate = 4; // = 4/8
|
|
||||||
ChanSet.spread_factor = 9;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
case 3: { // very long range
|
|
||||||
ChanSet.bandwidth = 0; // 125 kHz
|
|
||||||
ChanSet.coding_rate = 4; // = 4/8
|
|
||||||
ChanSet.spread_factor = 12;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
default:{ // default setting is very long range
|
|
||||||
ChanSet.bandwidth = 0; // 125 kHz
|
|
||||||
ChanSet.coding_rate = 4; // = 4/8
|
|
||||||
ChanSet.spread_factor = 12;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
sleepTime = floor( 10 * ((1<< ChanSet.spread_factor)*1000 +32) / TheBandwidths[ChanSet.bandwidth] + 0.5 );
|
|
||||||
ConfigureRadio( ChanSet );
|
|
||||||
#ifndef SILENT
|
|
||||||
MSG("..done! Switch to Receive Mode.\n");
|
|
||||||
#endif
|
|
||||||
#ifndef NO_OLED
|
|
||||||
display.drawString(0,32, "Receive Mode..");
|
|
||||||
display.display();
|
|
||||||
#endif
|
|
||||||
Radio.StartCad( 4 ); // length in symbols
|
|
||||||
}
|
|
||||||
|
|
||||||
void onCheckRadio(void)
|
|
||||||
{
|
|
||||||
noTimer=false;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Cycle starts @ 0 symbols. LoRA: CAD for 4 symbols, then (implicitly) Standby MCU: sleep
|
|
||||||
// After 10 LoRa symbols, wake up MCU and check for IRQs from LoRa (including CADdone)
|
|
||||||
// If channel activiy detected, switch to RX mode for 500 symbols, to capture very long packages.
|
|
||||||
// If the package is short, the onRXDone handler will put the LoRa to sleep, so no excess power consumption
|
|
||||||
// Radio.Send() is non-blocking, so if a TX is running we cannot immediatly start a new CAD, so we wait until LoRa is idle
|
|
||||||
|
|
||||||
void loop( )
|
|
||||||
{
|
|
||||||
noTimer = true;
|
|
||||||
TimerSetValue( &CheckRadio, sleepTime ); // MCU sleeps 10 LoRa symbols
|
|
||||||
TimerStart( &CheckRadio ); // onCheckRadio() will set noTimer to false
|
|
||||||
while (noTimer) lowPowerHandler( );
|
|
||||||
|
|
||||||
Radio.IrqProcess(); // handle events from LoRa, if CAD, set SX1262 to receive (onCadDone)
|
|
||||||
|
|
||||||
if ( Radio.GetStatus() == RF_IDLE ) Radio.StartCad( 4 );
|
|
||||||
}
|
|
||||||
|
|
||||||
void onCadDone( bool ChannelActive ){
|
|
||||||
// Rx Time = 500 * symbol time should be longer than receive time for max. packet length
|
|
||||||
(ChannelActive) ? Radio.Rx( sleepTime * 50 ) : Radio.Sleep();
|
|
||||||
}
|
|
||||||
|
|
||||||
void onRxTimeout( void ){
|
|
||||||
Radio.Sleep();
|
|
||||||
}
|
|
||||||
|
|
||||||
void onTxDone( void )
|
|
||||||
{
|
|
||||||
#ifndef NOBLINK
|
|
||||||
LED.clear( );
|
|
||||||
LED.show( );
|
|
||||||
#endif
|
|
||||||
#ifndef SILENT
|
|
||||||
MSG(".done (%ims)! Switch to Receive Mode.\n", millis() - startTime );
|
|
||||||
#endif
|
|
||||||
#ifndef NO_OLED
|
|
||||||
sprintf(str,"..done. RX Mode..");
|
|
||||||
display.drawString(42,53,str);
|
|
||||||
display.display();
|
|
||||||
#endif
|
|
||||||
Radio.Sleep();
|
|
||||||
}
|
|
||||||
|
|
||||||
void onTxTimeout( void )
|
|
||||||
{
|
|
||||||
#ifndef NOBLINK
|
|
||||||
LED.clear( );
|
|
||||||
LED.show( );
|
|
||||||
#endif
|
|
||||||
#ifndef SILENT
|
|
||||||
MSG(".failed (TX Timeout)! Switch to Receive Mode.\n");
|
|
||||||
#endif
|
|
||||||
#ifndef NO_OLED
|
|
||||||
sprintf(str,"..timeout!");
|
|
||||||
display.drawString(42,53,str);
|
|
||||||
display.display();
|
|
||||||
#endif
|
|
||||||
Radio.Sleep();
|
|
||||||
}
|
|
||||||
|
|
||||||
void onRxDone( uint8_t *payload, uint16_t size, int16_t rssi, int8_t snr )
|
|
||||||
{
|
|
||||||
Radio.Sleep();
|
|
||||||
if ( size > MAX_PAYLOAD_LENGTH ) size = MAX_PAYLOAD_LENGTH;
|
|
||||||
if ( !(size > sizeof(PacketHeader)) ) {
|
|
||||||
#ifndef SILENT
|
|
||||||
MSG("\nReceived packet! (Size %i bytes, RSSI %i, SNR %i)\n", size, rssi, snr);
|
|
||||||
MSG("Packet to small (No MeshPacket).\n");
|
|
||||||
#endif
|
|
||||||
#ifndef NOBLINK
|
|
||||||
LED.setPixelColor( 0, RGB_RED ); // send mode
|
|
||||||
LED.show();
|
|
||||||
#endif
|
|
||||||
Radio.Send( payload, size );
|
|
||||||
Radio.Rx( 0 );
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
PacketHeader * h = (PacketHeader *)payload;
|
|
||||||
MeshPacket * p = &thePacket;
|
|
||||||
p->to = h->to;
|
|
||||||
p->from = h->from;
|
|
||||||
p->id = h->id;
|
|
||||||
p->hop_limit = h->flags && 0b00000111;
|
|
||||||
p->want_ack = h->flags && 0b00001000;
|
|
||||||
p->which_payload = MeshPacket_encrypted_tag;
|
|
||||||
p->encrypted.size= size - sizeof(PacketHeader);
|
|
||||||
p->decoded.data.payload.size = p->encrypted.size;
|
|
||||||
memcpy(p->encrypted.bytes, payload + sizeof(PacketHeader), p->encrypted.size);
|
|
||||||
#ifndef SILENT
|
|
||||||
MSG("\nReceived packet! (Size %i bytes, RSSI %i, SNR %i)\n", size, rssi, snr);
|
|
||||||
MSG("TO: %.2X ", p->to);
|
|
||||||
MSG(" FROM: %.2X ", p->from);
|
|
||||||
MSG(" Packet ID: %.2X ", p->id);
|
|
||||||
MSG(" Flags: WANT_ACK="); MSG((p->want_ack) ? "YES " : "NO ");
|
|
||||||
MSG(" HOP_LIMIT=%i\n", p->hop_limit);
|
|
||||||
MSG("Payload:"); for ( int i=0; i < p->encrypted.size; i++ ) MSG(" %.2X", p->encrypted.bytes[i]);
|
|
||||||
MSG("\n");
|
|
||||||
#endif
|
|
||||||
#ifndef NO_OLED
|
|
||||||
display.clear();
|
|
||||||
display.display();
|
|
||||||
display.setFont(ArialMT_Plain_10);
|
|
||||||
sprintf(str,"Size: %i RSSI %i SNR %i", size, rssi, snr);
|
|
||||||
display.drawString(0,0,str);
|
|
||||||
sprintf(str,"%X", p->to);
|
|
||||||
display.drawString(0,11,"TO:");
|
|
||||||
display.drawString(40,11,str);
|
|
||||||
sprintf(str,"%X", p->from);
|
|
||||||
display.drawString(0,22,"FROM:");
|
|
||||||
display.drawString(40,22,str);
|
|
||||||
sprintf(str,"%X", p->id);
|
|
||||||
display.drawString(0,32,"ID:");
|
|
||||||
display.drawString(40,32,str);
|
|
||||||
display.display();
|
|
||||||
#endif
|
|
||||||
if ( !(lastreceivedID == thePacket.id) ){
|
|
||||||
// will repeat package
|
|
||||||
lastreceivedID = thePacket.id;
|
|
||||||
#ifndef NO_OLED
|
|
||||||
sprintf(str,"Sending..");
|
|
||||||
display.drawString(0,53,str);
|
|
||||||
display.display();
|
|
||||||
#endif
|
|
||||||
#ifndef NOBLINK
|
|
||||||
LED.setPixelColor( 0, RGB_RED ); // send mode
|
|
||||||
LED.show();
|
|
||||||
#endif
|
|
||||||
#ifndef SILENT
|
|
||||||
MSG("Sending packet.. (Size: %i)..", size);
|
|
||||||
startTime = millis();
|
|
||||||
#endif
|
|
||||||
Radio.Send( payload, size );
|
|
||||||
}
|
|
||||||
else{
|
|
||||||
#ifndef SILENT
|
|
||||||
MSG("PacketID = last PacketID, will not repeat again.\n");
|
|
||||||
#endif
|
|
||||||
#ifndef NO_OLED
|
|
||||||
sprintf(str,"ID known!");
|
|
||||||
display.drawString(0,53,str);
|
|
||||||
display.display();
|
|
||||||
#endif
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// hash a string into an integer - djb2 by Dan Bernstein. -
|
|
||||||
// http://www.cse.yorku.ca/~oz/hash.html
|
|
||||||
unsigned long hash(char *str)
|
|
||||||
{
|
|
||||||
unsigned long hash = 5381;
|
|
||||||
int c;
|
|
||||||
while ((c = *str++) != 0)
|
|
||||||
hash = ((hash << 5) + hash) + (unsigned char) c; // hash * 33 + c //
|
|
||||||
return hash;
|
|
||||||
}
|
|
||||||
|
|
||||||
void ConfigureRadio( ChannelSettings ChanSet )
|
|
||||||
{
|
|
||||||
uint32_t freq = (regions[REGION].freq + regions[REGION].spacing * ChanSet.channel_num)*1E6;
|
|
||||||
#ifndef SILENT
|
|
||||||
MSG("\nRegion is: %s", regions[REGION].name);
|
|
||||||
MSG(" TX power: %i\n", ChanSet.tx_power);
|
|
||||||
MSG("Setting frequency to %i Hz (meshtastic channel %i) .. \n",freq,ChanSet.channel_num );
|
|
||||||
MSG("Channel name is: '%s' .. \n", ChanSet.name );
|
|
||||||
MSG("Setting bandwidth to index %i (%ikHz)..\n", ChanSet.bandwidth, TheBandwidths[ChanSet.bandwidth] );
|
|
||||||
MSG("Setting CodeRate to index %i (4/%i).. \n", ChanSet.coding_rate, ChanSet.coding_rate + 4 );
|
|
||||||
MSG("Setting SpreadingFactor to %i ..\n",ChanSet.spread_factor);
|
|
||||||
#endif
|
|
||||||
Radio.SetChannel( freq );
|
|
||||||
Radio.SetTxConfig( MODEM_LORA, ChanSet.tx_power ,0 , ChanSet.bandwidth, ChanSet.spread_factor, ChanSet.coding_rate,
|
|
||||||
LORA_PREAMBLE_LENGTH, false, true, false, 0, false, 20000 );
|
|
||||||
Radio.SetRxConfig( MODEM_LORA, ChanSet.bandwidth, ChanSet.spread_factor, ChanSet.coding_rate, 0, LORA_PREAMBLE_LENGTH,
|
|
||||||
LORA_SYMBOL_TIMEOUT, false , 0, true, false, 0, false, true );
|
|
||||||
}
|
|
|
@ -1,652 +0,0 @@
|
||||||
/* Automatically generated nanopb header */
|
|
||||||
/* Generated by nanopb-0.4.1 */
|
|
||||||
|
|
||||||
#ifndef PB_MESH_PB_H_INCLUDED
|
|
||||||
#define PB_MESH_PB_H_INCLUDED
|
|
||||||
#include <pb.h>
|
|
||||||
|
|
||||||
#if PB_PROTO_HEADER_VERSION != 40
|
|
||||||
#error Regenerate this file with the current version of nanopb generator.
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#ifdef __cplusplus
|
|
||||||
extern "C" {
|
|
||||||
#endif
|
|
||||||
|
|
||||||
/* Enum definitions */
|
|
||||||
typedef enum _RouteError {
|
|
||||||
RouteError_NONE = 0,
|
|
||||||
RouteError_NO_ROUTE = 1,
|
|
||||||
RouteError_GOT_NAK = 2,
|
|
||||||
RouteError_TIMEOUT = 3
|
|
||||||
} RouteError;
|
|
||||||
|
|
||||||
typedef enum _Constants {
|
|
||||||
Constants_Unused = 0
|
|
||||||
} Constants;
|
|
||||||
|
|
||||||
typedef enum _RegionCode {
|
|
||||||
RegionCode_Unset = 0,
|
|
||||||
RegionCode_US = 1,
|
|
||||||
RegionCode_EU433 = 2,
|
|
||||||
RegionCode_EU865 = 3,
|
|
||||||
RegionCode_CN = 4,
|
|
||||||
RegionCode_JP = 5,
|
|
||||||
RegionCode_ANZ = 6,
|
|
||||||
RegionCode_KR = 7,
|
|
||||||
RegionCode_TW = 8
|
|
||||||
} RegionCode;
|
|
||||||
|
|
||||||
typedef enum _Data_Type {
|
|
||||||
Data_Type_OPAQUE = 0,
|
|
||||||
Data_Type_CLEAR_TEXT = 1,
|
|
||||||
Data_Type_CLEAR_READACK = 2
|
|
||||||
} Data_Type;
|
|
||||||
|
|
||||||
typedef enum _ChannelSettings_ModemConfig {
|
|
||||||
ChannelSettings_ModemConfig_Bw125Cr45Sf128 = 0,
|
|
||||||
ChannelSettings_ModemConfig_Bw500Cr45Sf128 = 1,
|
|
||||||
ChannelSettings_ModemConfig_Bw31_25Cr48Sf512 = 2,
|
|
||||||
ChannelSettings_ModemConfig_Bw125Cr48Sf4096 = 3
|
|
||||||
} ChannelSettings_ModemConfig;
|
|
||||||
|
|
||||||
/* Struct definitions */
|
|
||||||
typedef PB_BYTES_ARRAY_T(32) ChannelSettings_psk_t;
|
|
||||||
typedef struct _ChannelSettings {
|
|
||||||
int32_t tx_power;
|
|
||||||
ChannelSettings_ModemConfig modem_config;
|
|
||||||
ChannelSettings_psk_t psk;
|
|
||||||
char name[12];
|
|
||||||
uint32_t bandwidth;
|
|
||||||
uint32_t spread_factor;
|
|
||||||
uint32_t coding_rate;
|
|
||||||
uint32_t channel_num;
|
|
||||||
} ChannelSettings;
|
|
||||||
|
|
||||||
typedef PB_BYTES_ARRAY_T(240) Data_payload_t;
|
|
||||||
typedef struct _Data {
|
|
||||||
Data_Type typ;
|
|
||||||
Data_payload_t payload;
|
|
||||||
} Data;
|
|
||||||
|
|
||||||
typedef struct _DebugString {
|
|
||||||
char message[256];
|
|
||||||
} DebugString;
|
|
||||||
|
|
||||||
typedef struct _ManufacturingData {
|
|
||||||
uint32_t fradioFreq;
|
|
||||||
pb_callback_t hw_model;
|
|
||||||
pb_callback_t hw_version;
|
|
||||||
int32_t selftest_result;
|
|
||||||
} ManufacturingData;
|
|
||||||
|
|
||||||
typedef struct _MyNodeInfo {
|
|
||||||
uint32_t my_node_num;
|
|
||||||
bool has_gps;
|
|
||||||
int32_t num_channels;
|
|
||||||
char region[12];
|
|
||||||
char hw_model[16];
|
|
||||||
char firmware_version[12];
|
|
||||||
uint32_t error_code;
|
|
||||||
uint32_t error_address;
|
|
||||||
uint32_t error_count;
|
|
||||||
uint32_t packet_id_bits;
|
|
||||||
uint32_t current_packet_id;
|
|
||||||
uint32_t node_num_bits;
|
|
||||||
uint32_t message_timeout_msec;
|
|
||||||
uint32_t min_app_version;
|
|
||||||
} MyNodeInfo;
|
|
||||||
|
|
||||||
typedef struct _Position {
|
|
||||||
int32_t altitude;
|
|
||||||
int32_t battery_level;
|
|
||||||
int32_t latitude_i;
|
|
||||||
int32_t longitude_i;
|
|
||||||
uint32_t time;
|
|
||||||
} Position;
|
|
||||||
|
|
||||||
typedef struct _RadioConfig_UserPreferences {
|
|
||||||
uint32_t position_broadcast_secs;
|
|
||||||
uint32_t send_owner_interval;
|
|
||||||
uint32_t num_missed_to_fail;
|
|
||||||
uint32_t wait_bluetooth_secs;
|
|
||||||
uint32_t screen_on_secs;
|
|
||||||
uint32_t phone_timeout_secs;
|
|
||||||
uint32_t phone_sds_timeout_sec;
|
|
||||||
uint32_t mesh_sds_timeout_secs;
|
|
||||||
uint32_t sds_secs;
|
|
||||||
uint32_t ls_secs;
|
|
||||||
uint32_t min_wake_secs;
|
|
||||||
char wifi_ssid[33];
|
|
||||||
char wifi_password[64];
|
|
||||||
bool wifi_ap_mode;
|
|
||||||
RegionCode region;
|
|
||||||
bool factory_reset;
|
|
||||||
pb_size_t ignore_incoming_count;
|
|
||||||
uint32_t ignore_incoming[3];
|
|
||||||
} RadioConfig_UserPreferences;
|
|
||||||
|
|
||||||
typedef struct _RouteDiscovery {
|
|
||||||
pb_size_t route_count;
|
|
||||||
int32_t route[8];
|
|
||||||
} RouteDiscovery;
|
|
||||||
|
|
||||||
typedef struct _User {
|
|
||||||
char id[16];
|
|
||||||
char long_name[40];
|
|
||||||
char short_name[5];
|
|
||||||
pb_byte_t macaddr[6];
|
|
||||||
} User;
|
|
||||||
|
|
||||||
typedef struct _NodeInfo {
|
|
||||||
uint32_t num;
|
|
||||||
bool has_user;
|
|
||||||
User user;
|
|
||||||
bool has_position;
|
|
||||||
Position position;
|
|
||||||
uint32_t next_hop;
|
|
||||||
float snr;
|
|
||||||
} NodeInfo;
|
|
||||||
|
|
||||||
typedef struct _RadioConfig {
|
|
||||||
bool has_preferences;
|
|
||||||
RadioConfig_UserPreferences preferences;
|
|
||||||
bool has_channel_settings;
|
|
||||||
ChannelSettings channel_settings;
|
|
||||||
} RadioConfig;
|
|
||||||
|
|
||||||
typedef struct _SubPacket {
|
|
||||||
pb_size_t which_payload;
|
|
||||||
union {
|
|
||||||
Position position;
|
|
||||||
Data data;
|
|
||||||
User user;
|
|
||||||
RouteDiscovery route_request;
|
|
||||||
RouteDiscovery route_reply;
|
|
||||||
RouteError route_error;
|
|
||||||
};
|
|
||||||
uint32_t original_id;
|
|
||||||
bool want_response;
|
|
||||||
uint32_t dest;
|
|
||||||
pb_size_t which_ack;
|
|
||||||
union {
|
|
||||||
uint32_t success_id;
|
|
||||||
uint32_t fail_id;
|
|
||||||
} ack;
|
|
||||||
uint32_t source;
|
|
||||||
} SubPacket;
|
|
||||||
|
|
||||||
typedef PB_BYTES_ARRAY_T(256) MeshPacket_encrypted_t;
|
|
||||||
typedef struct _MeshPacket {
|
|
||||||
uint32_t from;
|
|
||||||
uint32_t to;
|
|
||||||
pb_size_t which_payload;
|
|
||||||
union {
|
|
||||||
SubPacket decoded;
|
|
||||||
MeshPacket_encrypted_t encrypted;
|
|
||||||
};
|
|
||||||
uint32_t id;
|
|
||||||
float rx_snr;
|
|
||||||
uint32_t rx_time;
|
|
||||||
uint32_t hop_limit;
|
|
||||||
bool want_ack;
|
|
||||||
} MeshPacket;
|
|
||||||
|
|
||||||
typedef struct _DeviceState {
|
|
||||||
bool has_radio;
|
|
||||||
RadioConfig radio;
|
|
||||||
bool has_my_node;
|
|
||||||
MyNodeInfo my_node;
|
|
||||||
bool has_owner;
|
|
||||||
User owner;
|
|
||||||
pb_size_t node_db_count;
|
|
||||||
NodeInfo node_db[32];
|
|
||||||
pb_size_t receive_queue_count;
|
|
||||||
MeshPacket receive_queue[1];
|
|
||||||
bool has_rx_text_message;
|
|
||||||
MeshPacket rx_text_message;
|
|
||||||
uint32_t version;
|
|
||||||
bool no_save;
|
|
||||||
bool did_gps_reset;
|
|
||||||
} DeviceState;
|
|
||||||
|
|
||||||
typedef struct _FromRadio {
|
|
||||||
uint32_t num;
|
|
||||||
pb_size_t which_variant;
|
|
||||||
union {
|
|
||||||
MeshPacket packet;
|
|
||||||
MyNodeInfo my_info;
|
|
||||||
NodeInfo node_info;
|
|
||||||
RadioConfig radio;
|
|
||||||
DebugString debug_string;
|
|
||||||
uint32_t config_complete_id;
|
|
||||||
bool rebooted;
|
|
||||||
} variant;
|
|
||||||
} FromRadio;
|
|
||||||
|
|
||||||
typedef struct _ToRadio {
|
|
||||||
pb_size_t which_variant;
|
|
||||||
union {
|
|
||||||
MeshPacket packet;
|
|
||||||
uint32_t want_config_id;
|
|
||||||
RadioConfig set_radio;
|
|
||||||
User set_owner;
|
|
||||||
} variant;
|
|
||||||
} ToRadio;
|
|
||||||
|
|
||||||
|
|
||||||
/* Helper constants for enums */
|
|
||||||
#define _RouteError_MIN RouteError_NONE
|
|
||||||
#define _RouteError_MAX RouteError_TIMEOUT
|
|
||||||
#define _RouteError_ARRAYSIZE ((RouteError)(RouteError_TIMEOUT+1))
|
|
||||||
|
|
||||||
#define _Constants_MIN Constants_Unused
|
|
||||||
#define _Constants_MAX Constants_Unused
|
|
||||||
#define _Constants_ARRAYSIZE ((Constants)(Constants_Unused+1))
|
|
||||||
|
|
||||||
#define _RegionCode_MIN RegionCode_Unset
|
|
||||||
#define _RegionCode_MAX RegionCode_TW
|
|
||||||
#define _RegionCode_ARRAYSIZE ((RegionCode)(RegionCode_TW+1))
|
|
||||||
|
|
||||||
#define _Data_Type_MIN Data_Type_OPAQUE
|
|
||||||
#define _Data_Type_MAX Data_Type_CLEAR_READACK
|
|
||||||
#define _Data_Type_ARRAYSIZE ((Data_Type)(Data_Type_CLEAR_READACK+1))
|
|
||||||
|
|
||||||
#define _ChannelSettings_ModemConfig_MIN ChannelSettings_ModemConfig_Bw125Cr45Sf128
|
|
||||||
#define _ChannelSettings_ModemConfig_MAX ChannelSettings_ModemConfig_Bw125Cr48Sf4096
|
|
||||||
#define _ChannelSettings_ModemConfig_ARRAYSIZE ((ChannelSettings_ModemConfig)(ChannelSettings_ModemConfig_Bw125Cr48Sf4096+1))
|
|
||||||
|
|
||||||
|
|
||||||
/* Initializer values for message structs */
|
|
||||||
#define Position_init_default {0, 0, 0, 0, 0}
|
|
||||||
#define Data_init_default {_Data_Type_MIN, {0, {0}}}
|
|
||||||
#define User_init_default {"", "", "", {0}}
|
|
||||||
#define RouteDiscovery_init_default {0, {0, 0, 0, 0, 0, 0, 0, 0}}
|
|
||||||
#define SubPacket_init_default {0, {Position_init_default}, 0, 0, 0, 0, {0}, 0}
|
|
||||||
#define MeshPacket_init_default {0, 0, 0, {SubPacket_init_default}, 0, 0, 0, 0, 0}
|
|
||||||
#define ChannelSettings_init_default {0, _ChannelSettings_ModemConfig_MIN, {0, {0}}, "", 0, 0, 0, 0}
|
|
||||||
#define RadioConfig_init_default {false, RadioConfig_UserPreferences_init_default, false, ChannelSettings_init_default}
|
|
||||||
#define RadioConfig_UserPreferences_init_default {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, "", "", 0, _RegionCode_MIN, 0, 0, {0, 0, 0}}
|
|
||||||
#define NodeInfo_init_default {0, false, User_init_default, false, Position_init_default, 0, 0}
|
|
||||||
#define MyNodeInfo_init_default {0, 0, 0, "", "", "", 0, 0, 0, 0, 0, 0, 0, 0}
|
|
||||||
#define DeviceState_init_default {false, RadioConfig_init_default, false, MyNodeInfo_init_default, false, User_init_default, 0, {NodeInfo_init_default, NodeInfo_init_default, NodeInfo_init_default, NodeInfo_init_default, NodeInfo_init_default, NodeInfo_init_default, NodeInfo_init_default, NodeInfo_init_default, NodeInfo_init_default, NodeInfo_init_default, NodeInfo_init_default, NodeInfo_init_default, NodeInfo_init_default, NodeInfo_init_default, NodeInfo_init_default, NodeInfo_init_default, NodeInfo_init_default, NodeInfo_init_default, NodeInfo_init_default, NodeInfo_init_default, NodeInfo_init_default, NodeInfo_init_default, NodeInfo_init_default, NodeInfo_init_default, NodeInfo_init_default, NodeInfo_init_default, NodeInfo_init_default, NodeInfo_init_default, NodeInfo_init_default, NodeInfo_init_default, NodeInfo_init_default, NodeInfo_init_default}, 0, {MeshPacket_init_default}, false, MeshPacket_init_default, 0, 0, 0}
|
|
||||||
#define DebugString_init_default {""}
|
|
||||||
#define FromRadio_init_default {0, 0, {MeshPacket_init_default}}
|
|
||||||
#define ToRadio_init_default {0, {MeshPacket_init_default}}
|
|
||||||
#define ManufacturingData_init_default {0, {{NULL}, NULL}, {{NULL}, NULL}, 0}
|
|
||||||
#define Position_init_zero {0, 0, 0, 0, 0}
|
|
||||||
#define Data_init_zero {_Data_Type_MIN, {0, {0}}}
|
|
||||||
#define User_init_zero {"", "", "", {0}}
|
|
||||||
#define RouteDiscovery_init_zero {0, {0, 0, 0, 0, 0, 0, 0, 0}}
|
|
||||||
#define SubPacket_init_zero {0, {Position_init_zero}, 0, 0, 0, 0, {0}, 0}
|
|
||||||
#define MeshPacket_init_zero {0, 0, 0, {SubPacket_init_zero}, 0, 0, 0, 0, 0}
|
|
||||||
#define ChannelSettings_init_zero {0, _ChannelSettings_ModemConfig_MIN, {0, {0}}, "", 0, 0, 0, 0}
|
|
||||||
#define RadioConfig_init_zero {false, RadioConfig_UserPreferences_init_zero, false, ChannelSettings_init_zero}
|
|
||||||
#define RadioConfig_UserPreferences_init_zero {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, "", "", 0, _RegionCode_MIN, 0, 0, {0, 0, 0}}
|
|
||||||
#define NodeInfo_init_zero {0, false, User_init_zero, false, Position_init_zero, 0, 0}
|
|
||||||
#define MyNodeInfo_init_zero {0, 0, 0, "", "", "", 0, 0, 0, 0, 0, 0, 0, 0}
|
|
||||||
#define DeviceState_init_zero {false, RadioConfig_init_zero, false, MyNodeInfo_init_zero, false, User_init_zero, 0, {NodeInfo_init_zero, NodeInfo_init_zero, NodeInfo_init_zero, NodeInfo_init_zero, NodeInfo_init_zero, NodeInfo_init_zero, NodeInfo_init_zero, NodeInfo_init_zero, NodeInfo_init_zero, NodeInfo_init_zero, NodeInfo_init_zero, NodeInfo_init_zero, NodeInfo_init_zero, NodeInfo_init_zero, NodeInfo_init_zero, NodeInfo_init_zero, NodeInfo_init_zero, NodeInfo_init_zero, NodeInfo_init_zero, NodeInfo_init_zero, NodeInfo_init_zero, NodeInfo_init_zero, NodeInfo_init_zero, NodeInfo_init_zero, NodeInfo_init_zero, NodeInfo_init_zero, NodeInfo_init_zero, NodeInfo_init_zero, NodeInfo_init_zero, NodeInfo_init_zero, NodeInfo_init_zero, NodeInfo_init_zero}, 0, {MeshPacket_init_zero}, false, MeshPacket_init_zero, 0, 0, 0}
|
|
||||||
#define DebugString_init_zero {""}
|
|
||||||
#define FromRadio_init_zero {0, 0, {MeshPacket_init_zero}}
|
|
||||||
#define ToRadio_init_zero {0, {MeshPacket_init_zero}}
|
|
||||||
#define ManufacturingData_init_zero {0, {{NULL}, NULL}, {{NULL}, NULL}, 0}
|
|
||||||
|
|
||||||
/* Field tags (for use in manual encoding/decoding) */
|
|
||||||
#define ChannelSettings_tx_power_tag 1
|
|
||||||
#define ChannelSettings_modem_config_tag 3
|
|
||||||
#define ChannelSettings_bandwidth_tag 6
|
|
||||||
#define ChannelSettings_spread_factor_tag 7
|
|
||||||
#define ChannelSettings_coding_rate_tag 8
|
|
||||||
#define ChannelSettings_channel_num_tag 9
|
|
||||||
#define ChannelSettings_psk_tag 4
|
|
||||||
#define ChannelSettings_name_tag 5
|
|
||||||
#define Data_typ_tag 1
|
|
||||||
#define Data_payload_tag 2
|
|
||||||
#define DebugString_message_tag 1
|
|
||||||
#define ManufacturingData_fradioFreq_tag 1
|
|
||||||
#define ManufacturingData_hw_model_tag 2
|
|
||||||
#define ManufacturingData_hw_version_tag 3
|
|
||||||
#define ManufacturingData_selftest_result_tag 4
|
|
||||||
#define MyNodeInfo_my_node_num_tag 1
|
|
||||||
#define MyNodeInfo_has_gps_tag 2
|
|
||||||
#define MyNodeInfo_num_channels_tag 3
|
|
||||||
#define MyNodeInfo_region_tag 4
|
|
||||||
#define MyNodeInfo_hw_model_tag 5
|
|
||||||
#define MyNodeInfo_firmware_version_tag 6
|
|
||||||
#define MyNodeInfo_error_code_tag 7
|
|
||||||
#define MyNodeInfo_error_address_tag 8
|
|
||||||
#define MyNodeInfo_error_count_tag 9
|
|
||||||
#define MyNodeInfo_packet_id_bits_tag 10
|
|
||||||
#define MyNodeInfo_current_packet_id_tag 11
|
|
||||||
#define MyNodeInfo_node_num_bits_tag 12
|
|
||||||
#define MyNodeInfo_message_timeout_msec_tag 13
|
|
||||||
#define MyNodeInfo_min_app_version_tag 14
|
|
||||||
#define Position_latitude_i_tag 7
|
|
||||||
#define Position_longitude_i_tag 8
|
|
||||||
#define Position_altitude_tag 3
|
|
||||||
#define Position_battery_level_tag 4
|
|
||||||
#define Position_time_tag 9
|
|
||||||
#define RadioConfig_UserPreferences_position_broadcast_secs_tag 1
|
|
||||||
#define RadioConfig_UserPreferences_send_owner_interval_tag 2
|
|
||||||
#define RadioConfig_UserPreferences_num_missed_to_fail_tag 3
|
|
||||||
#define RadioConfig_UserPreferences_wait_bluetooth_secs_tag 4
|
|
||||||
#define RadioConfig_UserPreferences_screen_on_secs_tag 5
|
|
||||||
#define RadioConfig_UserPreferences_phone_timeout_secs_tag 6
|
|
||||||
#define RadioConfig_UserPreferences_phone_sds_timeout_sec_tag 7
|
|
||||||
#define RadioConfig_UserPreferences_mesh_sds_timeout_secs_tag 8
|
|
||||||
#define RadioConfig_UserPreferences_sds_secs_tag 9
|
|
||||||
#define RadioConfig_UserPreferences_ls_secs_tag 10
|
|
||||||
#define RadioConfig_UserPreferences_min_wake_secs_tag 11
|
|
||||||
#define RadioConfig_UserPreferences_wifi_ssid_tag 12
|
|
||||||
#define RadioConfig_UserPreferences_wifi_password_tag 13
|
|
||||||
#define RadioConfig_UserPreferences_wifi_ap_mode_tag 14
|
|
||||||
#define RadioConfig_UserPreferences_region_tag 15
|
|
||||||
#define RadioConfig_UserPreferences_factory_reset_tag 100
|
|
||||||
#define RadioConfig_UserPreferences_ignore_incoming_tag 103
|
|
||||||
#define RouteDiscovery_route_tag 2
|
|
||||||
#define User_id_tag 1
|
|
||||||
#define User_long_name_tag 2
|
|
||||||
#define User_short_name_tag 3
|
|
||||||
#define User_macaddr_tag 4
|
|
||||||
#define NodeInfo_num_tag 1
|
|
||||||
#define NodeInfo_user_tag 2
|
|
||||||
#define NodeInfo_position_tag 3
|
|
||||||
#define NodeInfo_snr_tag 7
|
|
||||||
#define NodeInfo_next_hop_tag 5
|
|
||||||
#define RadioConfig_preferences_tag 1
|
|
||||||
#define RadioConfig_channel_settings_tag 2
|
|
||||||
#define SubPacket_position_tag 1
|
|
||||||
#define SubPacket_data_tag 3
|
|
||||||
#define SubPacket_user_tag 4
|
|
||||||
#define SubPacket_route_request_tag 6
|
|
||||||
#define SubPacket_route_reply_tag 7
|
|
||||||
#define SubPacket_route_error_tag 13
|
|
||||||
#define SubPacket_success_id_tag 10
|
|
||||||
#define SubPacket_fail_id_tag 11
|
|
||||||
#define SubPacket_want_response_tag 5
|
|
||||||
#define SubPacket_dest_tag 9
|
|
||||||
#define SubPacket_source_tag 12
|
|
||||||
#define SubPacket_original_id_tag 2
|
|
||||||
#define MeshPacket_decoded_tag 3
|
|
||||||
#define MeshPacket_encrypted_tag 8
|
|
||||||
#define MeshPacket_from_tag 1
|
|
||||||
#define MeshPacket_to_tag 2
|
|
||||||
#define MeshPacket_id_tag 6
|
|
||||||
#define MeshPacket_rx_time_tag 9
|
|
||||||
#define MeshPacket_rx_snr_tag 7
|
|
||||||
#define MeshPacket_hop_limit_tag 10
|
|
||||||
#define MeshPacket_want_ack_tag 11
|
|
||||||
#define DeviceState_radio_tag 1
|
|
||||||
#define DeviceState_my_node_tag 2
|
|
||||||
#define DeviceState_owner_tag 3
|
|
||||||
#define DeviceState_node_db_tag 4
|
|
||||||
#define DeviceState_receive_queue_tag 5
|
|
||||||
#define DeviceState_version_tag 8
|
|
||||||
#define DeviceState_rx_text_message_tag 7
|
|
||||||
#define DeviceState_no_save_tag 9
|
|
||||||
#define DeviceState_did_gps_reset_tag 11
|
|
||||||
#define FromRadio_packet_tag 2
|
|
||||||
#define FromRadio_my_info_tag 3
|
|
||||||
#define FromRadio_node_info_tag 4
|
|
||||||
#define FromRadio_radio_tag 6
|
|
||||||
#define FromRadio_debug_string_tag 7
|
|
||||||
#define FromRadio_config_complete_id_tag 8
|
|
||||||
#define FromRadio_rebooted_tag 9
|
|
||||||
#define FromRadio_num_tag 1
|
|
||||||
#define ToRadio_packet_tag 1
|
|
||||||
#define ToRadio_want_config_id_tag 100
|
|
||||||
#define ToRadio_set_radio_tag 101
|
|
||||||
#define ToRadio_set_owner_tag 102
|
|
||||||
|
|
||||||
/* Struct field encoding specification for nanopb */
|
|
||||||
#define Position_FIELDLIST(X, a) \
|
|
||||||
X(a, STATIC, SINGULAR, INT32, altitude, 3) \
|
|
||||||
X(a, STATIC, SINGULAR, INT32, battery_level, 4) \
|
|
||||||
X(a, STATIC, SINGULAR, SINT32, latitude_i, 7) \
|
|
||||||
X(a, STATIC, SINGULAR, SINT32, longitude_i, 8) \
|
|
||||||
X(a, STATIC, SINGULAR, FIXED32, time, 9)
|
|
||||||
#define Position_CALLBACK NULL
|
|
||||||
#define Position_DEFAULT NULL
|
|
||||||
|
|
||||||
#define Data_FIELDLIST(X, a) \
|
|
||||||
X(a, STATIC, SINGULAR, UENUM, typ, 1) \
|
|
||||||
X(a, STATIC, SINGULAR, BYTES, payload, 2)
|
|
||||||
#define Data_CALLBACK NULL
|
|
||||||
#define Data_DEFAULT NULL
|
|
||||||
|
|
||||||
#define User_FIELDLIST(X, a) \
|
|
||||||
X(a, STATIC, SINGULAR, STRING, id, 1) \
|
|
||||||
X(a, STATIC, SINGULAR, STRING, long_name, 2) \
|
|
||||||
X(a, STATIC, SINGULAR, STRING, short_name, 3) \
|
|
||||||
X(a, STATIC, SINGULAR, FIXED_LENGTH_BYTES, macaddr, 4)
|
|
||||||
#define User_CALLBACK NULL
|
|
||||||
#define User_DEFAULT NULL
|
|
||||||
|
|
||||||
#define RouteDiscovery_FIELDLIST(X, a) \
|
|
||||||
X(a, STATIC, REPEATED, INT32, route, 2)
|
|
||||||
#define RouteDiscovery_CALLBACK NULL
|
|
||||||
#define RouteDiscovery_DEFAULT NULL
|
|
||||||
|
|
||||||
#define SubPacket_FIELDLIST(X, a) \
|
|
||||||
X(a, STATIC, ONEOF, MESSAGE, (payload,position,position), 1) \
|
|
||||||
X(a, STATIC, ONEOF, MESSAGE, (payload,data,data), 3) \
|
|
||||||
X(a, STATIC, ONEOF, MESSAGE, (payload,user,user), 4) \
|
|
||||||
X(a, STATIC, ONEOF, MESSAGE, (payload,route_request,route_request), 6) \
|
|
||||||
X(a, STATIC, ONEOF, MESSAGE, (payload,route_reply,route_reply), 7) \
|
|
||||||
X(a, STATIC, ONEOF, ENUM, (payload,route_error,route_error), 13) \
|
|
||||||
X(a, STATIC, SINGULAR, UINT32, original_id, 2) \
|
|
||||||
X(a, STATIC, SINGULAR, BOOL, want_response, 5) \
|
|
||||||
X(a, STATIC, SINGULAR, UINT32, dest, 9) \
|
|
||||||
X(a, STATIC, ONEOF, UINT32, (ack,success_id,ack.success_id), 10) \
|
|
||||||
X(a, STATIC, ONEOF, UINT32, (ack,fail_id,ack.fail_id), 11) \
|
|
||||||
X(a, STATIC, SINGULAR, UINT32, source, 12)
|
|
||||||
#define SubPacket_CALLBACK NULL
|
|
||||||
#define SubPacket_DEFAULT NULL
|
|
||||||
#define SubPacket_payload_position_MSGTYPE Position
|
|
||||||
#define SubPacket_payload_data_MSGTYPE Data
|
|
||||||
#define SubPacket_payload_user_MSGTYPE User
|
|
||||||
#define SubPacket_payload_route_request_MSGTYPE RouteDiscovery
|
|
||||||
#define SubPacket_payload_route_reply_MSGTYPE RouteDiscovery
|
|
||||||
|
|
||||||
#define MeshPacket_FIELDLIST(X, a) \
|
|
||||||
X(a, STATIC, SINGULAR, UINT32, from, 1) \
|
|
||||||
X(a, STATIC, SINGULAR, UINT32, to, 2) \
|
|
||||||
X(a, STATIC, ONEOF, MESSAGE, (payload,decoded,decoded), 3) \
|
|
||||||
X(a, STATIC, ONEOF, BYTES, (payload,encrypted,encrypted), 8) \
|
|
||||||
X(a, STATIC, SINGULAR, UINT32, id, 6) \
|
|
||||||
X(a, STATIC, SINGULAR, FLOAT, rx_snr, 7) \
|
|
||||||
X(a, STATIC, SINGULAR, FIXED32, rx_time, 9) \
|
|
||||||
X(a, STATIC, SINGULAR, UINT32, hop_limit, 10) \
|
|
||||||
X(a, STATIC, SINGULAR, BOOL, want_ack, 11)
|
|
||||||
#define MeshPacket_CALLBACK NULL
|
|
||||||
#define MeshPacket_DEFAULT NULL
|
|
||||||
#define MeshPacket_payload_decoded_MSGTYPE SubPacket
|
|
||||||
|
|
||||||
#define ChannelSettings_FIELDLIST(X, a) \
|
|
||||||
X(a, STATIC, SINGULAR, INT32, tx_power, 1) \
|
|
||||||
X(a, STATIC, SINGULAR, UENUM, modem_config, 3) \
|
|
||||||
X(a, STATIC, SINGULAR, BYTES, psk, 4) \
|
|
||||||
X(a, STATIC, SINGULAR, STRING, name, 5) \
|
|
||||||
X(a, STATIC, SINGULAR, UINT32, bandwidth, 6) \
|
|
||||||
X(a, STATIC, SINGULAR, UINT32, spread_factor, 7) \
|
|
||||||
X(a, STATIC, SINGULAR, UINT32, coding_rate, 8) \
|
|
||||||
X(a, STATIC, SINGULAR, UINT32, channel_num, 9)
|
|
||||||
#define ChannelSettings_CALLBACK NULL
|
|
||||||
#define ChannelSettings_DEFAULT NULL
|
|
||||||
|
|
||||||
#define RadioConfig_FIELDLIST(X, a) \
|
|
||||||
X(a, STATIC, OPTIONAL, MESSAGE, preferences, 1) \
|
|
||||||
X(a, STATIC, OPTIONAL, MESSAGE, channel_settings, 2)
|
|
||||||
#define RadioConfig_CALLBACK NULL
|
|
||||||
#define RadioConfig_DEFAULT NULL
|
|
||||||
#define RadioConfig_preferences_MSGTYPE RadioConfig_UserPreferences
|
|
||||||
#define RadioConfig_channel_settings_MSGTYPE ChannelSettings
|
|
||||||
|
|
||||||
#define RadioConfig_UserPreferences_FIELDLIST(X, a) \
|
|
||||||
X(a, STATIC, SINGULAR, UINT32, position_broadcast_secs, 1) \
|
|
||||||
X(a, STATIC, SINGULAR, UINT32, send_owner_interval, 2) \
|
|
||||||
X(a, STATIC, SINGULAR, UINT32, num_missed_to_fail, 3) \
|
|
||||||
X(a, STATIC, SINGULAR, UINT32, wait_bluetooth_secs, 4) \
|
|
||||||
X(a, STATIC, SINGULAR, UINT32, screen_on_secs, 5) \
|
|
||||||
X(a, STATIC, SINGULAR, UINT32, phone_timeout_secs, 6) \
|
|
||||||
X(a, STATIC, SINGULAR, UINT32, phone_sds_timeout_sec, 7) \
|
|
||||||
X(a, STATIC, SINGULAR, UINT32, mesh_sds_timeout_secs, 8) \
|
|
||||||
X(a, STATIC, SINGULAR, UINT32, sds_secs, 9) \
|
|
||||||
X(a, STATIC, SINGULAR, UINT32, ls_secs, 10) \
|
|
||||||
X(a, STATIC, SINGULAR, UINT32, min_wake_secs, 11) \
|
|
||||||
X(a, STATIC, SINGULAR, STRING, wifi_ssid, 12) \
|
|
||||||
X(a, STATIC, SINGULAR, STRING, wifi_password, 13) \
|
|
||||||
X(a, STATIC, SINGULAR, BOOL, wifi_ap_mode, 14) \
|
|
||||||
X(a, STATIC, SINGULAR, UENUM, region, 15) \
|
|
||||||
X(a, STATIC, SINGULAR, BOOL, factory_reset, 100) \
|
|
||||||
X(a, STATIC, REPEATED, UINT32, ignore_incoming, 103)
|
|
||||||
#define RadioConfig_UserPreferences_CALLBACK NULL
|
|
||||||
#define RadioConfig_UserPreferences_DEFAULT NULL
|
|
||||||
|
|
||||||
#define NodeInfo_FIELDLIST(X, a) \
|
|
||||||
X(a, STATIC, SINGULAR, UINT32, num, 1) \
|
|
||||||
X(a, STATIC, OPTIONAL, MESSAGE, user, 2) \
|
|
||||||
X(a, STATIC, OPTIONAL, MESSAGE, position, 3) \
|
|
||||||
X(a, STATIC, SINGULAR, UINT32, next_hop, 5) \
|
|
||||||
X(a, STATIC, SINGULAR, FLOAT, snr, 7)
|
|
||||||
#define NodeInfo_CALLBACK NULL
|
|
||||||
#define NodeInfo_DEFAULT NULL
|
|
||||||
#define NodeInfo_user_MSGTYPE User
|
|
||||||
#define NodeInfo_position_MSGTYPE Position
|
|
||||||
|
|
||||||
#define MyNodeInfo_FIELDLIST(X, a) \
|
|
||||||
X(a, STATIC, SINGULAR, UINT32, my_node_num, 1) \
|
|
||||||
X(a, STATIC, SINGULAR, BOOL, has_gps, 2) \
|
|
||||||
X(a, STATIC, SINGULAR, INT32, num_channels, 3) \
|
|
||||||
X(a, STATIC, SINGULAR, STRING, region, 4) \
|
|
||||||
X(a, STATIC, SINGULAR, STRING, hw_model, 5) \
|
|
||||||
X(a, STATIC, SINGULAR, STRING, firmware_version, 6) \
|
|
||||||
X(a, STATIC, SINGULAR, UINT32, error_code, 7) \
|
|
||||||
X(a, STATIC, SINGULAR, UINT32, error_address, 8) \
|
|
||||||
X(a, STATIC, SINGULAR, UINT32, error_count, 9) \
|
|
||||||
X(a, STATIC, SINGULAR, UINT32, packet_id_bits, 10) \
|
|
||||||
X(a, STATIC, SINGULAR, UINT32, current_packet_id, 11) \
|
|
||||||
X(a, STATIC, SINGULAR, UINT32, node_num_bits, 12) \
|
|
||||||
X(a, STATIC, SINGULAR, UINT32, message_timeout_msec, 13) \
|
|
||||||
X(a, STATIC, SINGULAR, UINT32, min_app_version, 14)
|
|
||||||
#define MyNodeInfo_CALLBACK NULL
|
|
||||||
#define MyNodeInfo_DEFAULT NULL
|
|
||||||
|
|
||||||
#define DeviceState_FIELDLIST(X, a) \
|
|
||||||
X(a, STATIC, OPTIONAL, MESSAGE, radio, 1) \
|
|
||||||
X(a, STATIC, OPTIONAL, MESSAGE, my_node, 2) \
|
|
||||||
X(a, STATIC, OPTIONAL, MESSAGE, owner, 3) \
|
|
||||||
X(a, STATIC, REPEATED, MESSAGE, node_db, 4) \
|
|
||||||
X(a, STATIC, REPEATED, MESSAGE, receive_queue, 5) \
|
|
||||||
X(a, STATIC, OPTIONAL, MESSAGE, rx_text_message, 7) \
|
|
||||||
X(a, STATIC, SINGULAR, UINT32, version, 8) \
|
|
||||||
X(a, STATIC, SINGULAR, BOOL, no_save, 9) \
|
|
||||||
X(a, STATIC, SINGULAR, BOOL, did_gps_reset, 11)
|
|
||||||
#define DeviceState_CALLBACK NULL
|
|
||||||
#define DeviceState_DEFAULT NULL
|
|
||||||
#define DeviceState_radio_MSGTYPE RadioConfig
|
|
||||||
#define DeviceState_my_node_MSGTYPE MyNodeInfo
|
|
||||||
#define DeviceState_owner_MSGTYPE User
|
|
||||||
#define DeviceState_node_db_MSGTYPE NodeInfo
|
|
||||||
#define DeviceState_receive_queue_MSGTYPE MeshPacket
|
|
||||||
#define DeviceState_rx_text_message_MSGTYPE MeshPacket
|
|
||||||
|
|
||||||
#define DebugString_FIELDLIST(X, a) \
|
|
||||||
X(a, STATIC, SINGULAR, STRING, message, 1)
|
|
||||||
#define DebugString_CALLBACK NULL
|
|
||||||
#define DebugString_DEFAULT NULL
|
|
||||||
|
|
||||||
#define FromRadio_FIELDLIST(X, a) \
|
|
||||||
X(a, STATIC, SINGULAR, UINT32, num, 1) \
|
|
||||||
X(a, STATIC, ONEOF, MESSAGE, (variant,packet,variant.packet), 2) \
|
|
||||||
X(a, STATIC, ONEOF, MESSAGE, (variant,my_info,variant.my_info), 3) \
|
|
||||||
X(a, STATIC, ONEOF, MESSAGE, (variant,node_info,variant.node_info), 4) \
|
|
||||||
X(a, STATIC, ONEOF, MESSAGE, (variant,radio,variant.radio), 6) \
|
|
||||||
X(a, STATIC, ONEOF, MESSAGE, (variant,debug_string,variant.debug_string), 7) \
|
|
||||||
X(a, STATIC, ONEOF, UINT32, (variant,config_complete_id,variant.config_complete_id), 8) \
|
|
||||||
X(a, STATIC, ONEOF, BOOL, (variant,rebooted,variant.rebooted), 9)
|
|
||||||
#define FromRadio_CALLBACK NULL
|
|
||||||
#define FromRadio_DEFAULT NULL
|
|
||||||
#define FromRadio_variant_packet_MSGTYPE MeshPacket
|
|
||||||
#define FromRadio_variant_my_info_MSGTYPE MyNodeInfo
|
|
||||||
#define FromRadio_variant_node_info_MSGTYPE NodeInfo
|
|
||||||
#define FromRadio_variant_radio_MSGTYPE RadioConfig
|
|
||||||
#define FromRadio_variant_debug_string_MSGTYPE DebugString
|
|
||||||
|
|
||||||
#define ToRadio_FIELDLIST(X, a) \
|
|
||||||
X(a, STATIC, ONEOF, MESSAGE, (variant,packet,variant.packet), 1) \
|
|
||||||
X(a, STATIC, ONEOF, UINT32, (variant,want_config_id,variant.want_config_id), 100) \
|
|
||||||
X(a, STATIC, ONEOF, MESSAGE, (variant,set_radio,variant.set_radio), 101) \
|
|
||||||
X(a, STATIC, ONEOF, MESSAGE, (variant,set_owner,variant.set_owner), 102)
|
|
||||||
#define ToRadio_CALLBACK NULL
|
|
||||||
#define ToRadio_DEFAULT NULL
|
|
||||||
#define ToRadio_variant_packet_MSGTYPE MeshPacket
|
|
||||||
#define ToRadio_variant_set_radio_MSGTYPE RadioConfig
|
|
||||||
#define ToRadio_variant_set_owner_MSGTYPE User
|
|
||||||
|
|
||||||
#define ManufacturingData_FIELDLIST(X, a) \
|
|
||||||
X(a, STATIC, SINGULAR, UINT32, fradioFreq, 1) \
|
|
||||||
X(a, CALLBACK, SINGULAR, STRING, hw_model, 2) \
|
|
||||||
X(a, CALLBACK, SINGULAR, STRING, hw_version, 3) \
|
|
||||||
X(a, STATIC, SINGULAR, SINT32, selftest_result, 4)
|
|
||||||
#define ManufacturingData_CALLBACK pb_default_field_callback
|
|
||||||
#define ManufacturingData_DEFAULT NULL
|
|
||||||
|
|
||||||
extern const pb_msgdesc_t Position_msg;
|
|
||||||
extern const pb_msgdesc_t Data_msg;
|
|
||||||
extern const pb_msgdesc_t User_msg;
|
|
||||||
extern const pb_msgdesc_t RouteDiscovery_msg;
|
|
||||||
extern const pb_msgdesc_t SubPacket_msg;
|
|
||||||
extern const pb_msgdesc_t MeshPacket_msg;
|
|
||||||
extern const pb_msgdesc_t ChannelSettings_msg;
|
|
||||||
extern const pb_msgdesc_t RadioConfig_msg;
|
|
||||||
extern const pb_msgdesc_t RadioConfig_UserPreferences_msg;
|
|
||||||
extern const pb_msgdesc_t NodeInfo_msg;
|
|
||||||
extern const pb_msgdesc_t MyNodeInfo_msg;
|
|
||||||
extern const pb_msgdesc_t DeviceState_msg;
|
|
||||||
extern const pb_msgdesc_t DebugString_msg;
|
|
||||||
extern const pb_msgdesc_t FromRadio_msg;
|
|
||||||
extern const pb_msgdesc_t ToRadio_msg;
|
|
||||||
extern const pb_msgdesc_t ManufacturingData_msg;
|
|
||||||
|
|
||||||
/* Defines for backwards compatibility with code written before nanopb-0.4.0 */
|
|
||||||
#define Position_fields &Position_msg
|
|
||||||
#define Data_fields &Data_msg
|
|
||||||
#define User_fields &User_msg
|
|
||||||
#define RouteDiscovery_fields &RouteDiscovery_msg
|
|
||||||
#define SubPacket_fields &SubPacket_msg
|
|
||||||
#define MeshPacket_fields &MeshPacket_msg
|
|
||||||
#define ChannelSettings_fields &ChannelSettings_msg
|
|
||||||
#define RadioConfig_fields &RadioConfig_msg
|
|
||||||
#define RadioConfig_UserPreferences_fields &RadioConfig_UserPreferences_msg
|
|
||||||
#define NodeInfo_fields &NodeInfo_msg
|
|
||||||
#define MyNodeInfo_fields &MyNodeInfo_msg
|
|
||||||
#define DeviceState_fields &DeviceState_msg
|
|
||||||
#define DebugString_fields &DebugString_msg
|
|
||||||
#define FromRadio_fields &FromRadio_msg
|
|
||||||
#define ToRadio_fields &ToRadio_msg
|
|
||||||
#define ManufacturingData_fields &ManufacturingData_msg
|
|
||||||
|
|
||||||
/* Maximum encoded size of messages (where known) */
|
|
||||||
#define Position_size 39
|
|
||||||
#define Data_size 245
|
|
||||||
#define User_size 72
|
|
||||||
#define RouteDiscovery_size 88
|
|
||||||
#define SubPacket_size 274
|
|
||||||
#define MeshPacket_size 313
|
|
||||||
#define ChannelSettings_size 84
|
|
||||||
#define RadioConfig_size 282
|
|
||||||
#define RadioConfig_UserPreferences_size 193
|
|
||||||
#define NodeInfo_size 132
|
|
||||||
#define MyNodeInfo_size 110
|
|
||||||
#define DeviceState_size 5434
|
|
||||||
#define DebugString_size 258
|
|
||||||
#define FromRadio_size 322
|
|
||||||
#define ToRadio_size 316
|
|
||||||
/* ManufacturingData_size depends on runtime parameters */
|
|
||||||
|
|
||||||
#ifdef __cplusplus
|
|
||||||
} /* extern "C" */
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#endif
|
|
|
@ -7,6 +7,7 @@
|
||||||
;
|
;
|
||||||
; Please visit documentation for the other options and examples
|
; Please visit documentation for the other options and examples
|
||||||
; https://docs.platformio.org/page/projectconf.html
|
; https://docs.platformio.org/page/projectconf.html
|
||||||
|
|
||||||
[platformio]
|
[platformio]
|
||||||
default_envs = cubecell_board
|
default_envs = cubecell_board
|
||||||
|
|
||||||
|
@ -16,6 +17,7 @@ framework = arduino
|
||||||
monitor_speed = 115200
|
monitor_speed = 115200
|
||||||
build_flags = -Os
|
build_flags = -Os
|
||||||
lib_deps = nanopb/Nanopb@^0.4.3
|
lib_deps = nanopb/Nanopb@^0.4.3
|
||||||
|
agdl/Base64 @ ^1.0.0
|
||||||
|
|
||||||
[env]
|
[env]
|
||||||
|
|
||||||
|
@ -23,18 +25,23 @@ lib_deps = nanopb/Nanopb@^0.4.3
|
||||||
extends = common
|
extends = common
|
||||||
board = cubecell_capsule
|
board = cubecell_capsule
|
||||||
|
|
||||||
|
|
||||||
[env:cubecell_capsule_solar_sensor]
|
[env:cubecell_capsule_solar_sensor]
|
||||||
extends = common
|
extends = common
|
||||||
board = cubecell_capsule_solar_sensor
|
board = cubecell_capsule_solar_sensor
|
||||||
|
|
||||||
|
|
||||||
[env:cubecell_board]
|
[env:cubecell_board]
|
||||||
extends = common
|
extends = common
|
||||||
board = cubecell_board
|
board = cubecell_board
|
||||||
|
|
||||||
|
|
||||||
[env:cubecell_board_plus]
|
[env:cubecell_board_plus]
|
||||||
extends = common
|
extends = common
|
||||||
board = cubecell_board_plus
|
board = cubecell_board_plus
|
||||||
|
|
||||||
|
|
||||||
[env:cubecell_gps]
|
[env:cubecell_gps]
|
||||||
extends = common
|
extends = common
|
||||||
board = cubecell_gps
|
board = cubecell_gps
|
||||||
|
|
||||||
|
|
50
src/config.h
50
src/config.h
|
@ -1,11 +1,22 @@
|
||||||
#include "mesh.pb.h"
|
|
||||||
// CONFIGURATION:
|
// CONFIGURATION:
|
||||||
#define REGION RegionCode_EU865 // define your region here. For US, RegionCode_US, CN RegionCode_Cn etc.
|
#define REGION RegionCode_EU865 // define your region here. For US, RegionCode_US, CN RegionCode_Cn etc.
|
||||||
char MESHTASTIC_NAME[12] = {"Default"}; // Channel Name, but without "-Xy" suffix , e.g. use "Test" instead of "Test-A"
|
|
||||||
#define MESHTASTIC_SPEED 3 // 0 = short range, 1 = medium range, 2 = long range, 3 = very long range
|
|
||||||
#define TX_MAX_POWER 14 // max output power in dB, keep in mind the maximums set by law and the hardware
|
#define TX_MAX_POWER 14 // max output power in dB, keep in mind the maximums set by law and the hardware
|
||||||
|
char MeshtasticLink[] = "https://www.meshtastic.org/c/#GAMiENTxuzogKQdZ8Lz_q89Oab8qB0RlZmF1bHQ=" ;
|
||||||
// :CONFIGURATION
|
// :CONFIGURATION
|
||||||
|
|
||||||
|
/* RegionCodes:
|
||||||
|
|
||||||
|
RegionCode_Unset
|
||||||
|
RegionCode_US
|
||||||
|
RegionCode_EU433
|
||||||
|
RegionCode_EU865
|
||||||
|
RegionCode_CN
|
||||||
|
RegionCode_JP
|
||||||
|
RegionCode_ANZ
|
||||||
|
RegionCode_KR
|
||||||
|
RegionCode_TW
|
||||||
|
*/
|
||||||
|
|
||||||
#define RGB_GREEN 0x000300 // receive mode --- not longer used
|
#define RGB_GREEN 0x000300 // receive mode --- not longer used
|
||||||
#define RGB_RED 0x030000 // send mode
|
#define RGB_RED 0x030000 // send mode
|
||||||
|
|
||||||
|
@ -14,23 +25,8 @@ char MESHTASTIC_NAME[12] = {"Default"}; // Channel Name, but without "-Xy" su
|
||||||
#define RX_TIMEOUT_VALUE 1000
|
#define RX_TIMEOUT_VALUE 1000
|
||||||
#define MAX_PAYLOAD_LENGTH 0xFF // max payload (see \cores\asr650x\device\asr6501_lrwan\radio.c --> MaxPayloadLength)
|
#define MAX_PAYLOAD_LENGTH 0xFF // max payload (see \cores\asr650x\device\asr6501_lrwan\radio.c --> MaxPayloadLength)
|
||||||
|
|
||||||
/* possible RegionCodes, from mesh.pb.h:
|
#include "mesh.pb.h"
|
||||||
typedef enum _RegionCode {
|
#include "mesh-pb-constants.h"
|
||||||
RegionCode_Unset = 0,
|
|
||||||
RegionCode_US = 1,
|
|
||||||
RegionCode_EU433 = 2,
|
|
||||||
RegionCode_EU865 = 3,
|
|
||||||
RegionCode_CN = 4,
|
|
||||||
RegionCode_JP = 5,
|
|
||||||
RegionCode_ANZ = 6,
|
|
||||||
RegionCode_KR = 7,
|
|
||||||
RegionCode_TW = 8
|
|
||||||
} RegionCode;
|
|
||||||
*/
|
|
||||||
|
|
||||||
// the PSK is not used for encryption/decryption, you can leave it as it is
|
|
||||||
#define MESHTASTIC_PSK { 0x10, 0xd4, 0xf1, 0xbb, 0x3a, 0x20, 0x29, 0x07, 0x59, 0xf0, 0xbc, 0xff, 0xab, 0xcf, 0x4e, 0x69, 0xbf }
|
|
||||||
#define PSK_NOENCRYPTION { 0x10, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 }
|
|
||||||
|
|
||||||
typedef struct {
|
typedef struct {
|
||||||
uint32_t to, from, id;
|
uint32_t to, from, id;
|
||||||
|
@ -38,15 +34,17 @@ typedef struct {
|
||||||
} PacketHeader;
|
} PacketHeader;
|
||||||
|
|
||||||
#define MSG(...) Serial.printf(__VA_ARGS__)
|
#define MSG(...) Serial.printf(__VA_ARGS__)
|
||||||
//#define DUTY(symbTime) ( (uint32_t)( symbTime * LORA_PREAMBLE_LENGTH / 2 ) )
|
#define LINE( count, c) { for (uint8_t i=0; i<count; i++ ) { Serial.print(c); } Serial.println(); }
|
||||||
|
|
||||||
void onTxDone( void );
|
void onTxDone( void );
|
||||||
|
void onCadDone( bool ChannelActive );
|
||||||
|
void onRxTimeout( void );
|
||||||
void onTxTimeout( void );
|
void onTxTimeout( void );
|
||||||
void onRxDone( uint8_t *payload, uint16_t size, int16_t rssi, int8_t snr );
|
void onRxDone( uint8_t *payload, uint16_t size, int16_t rssi, int8_t snr );
|
||||||
|
void onCheckRadio( void );
|
||||||
void ConfigureRadio( ChannelSettings ChanSet );
|
void ConfigureRadio( ChannelSettings ChanSet );
|
||||||
void setRxCycle(void);
|
void MCU_deepsleep( void );
|
||||||
unsigned long hash(char *str);
|
unsigned long hash( char *str );
|
||||||
|
|
||||||
|
|
||||||
// from Meshtastic project: MeshRadio.h , RadioInterface.cpp
|
// from Meshtastic project: MeshRadio.h , RadioInterface.cpp
|
||||||
#define RDEF(name, freq, spacing, num_ch, power_limit) \
|
#define RDEF(name, freq, spacing, num_ch, power_limit) \
|
||||||
|
@ -75,5 +73,7 @@ const RegionInfo regions[] = {
|
||||||
RDEF(TW, 923.0f, 0.2f, 10, 0) // TW channel settings (AS2 bandplan 923-925MHz)
|
RDEF(TW, 923.0f, 0.2f, 10, 0) // TW channel settings (AS2 bandplan 923-925MHz)
|
||||||
};
|
};
|
||||||
|
|
||||||
// Bandwidths. Array is specific to the Radio.c of the CubeCells
|
// Bandwidths array is specific to the Radio.c of the CubeCell boards
|
||||||
const uint32_t TheBandwidths[] = { 125E3, 250E3, 500E3, 62500, 41670, 31250, 20830, 15630, 10420, 7810 };
|
const uint32_t TheBandwidths[] = { 125E3, 250E3, 500E3, 62500, 41670, 31250, 20830, 15630, 10420, 7810 };
|
||||||
|
|
||||||
|
|
||||||
|
|
128
src/main.cpp
128
src/main.cpp
|
@ -1,5 +1,7 @@
|
||||||
#include <Arduino.h>
|
#include <Arduino.h>
|
||||||
#include "config.h"
|
#include "config.h"
|
||||||
|
#include <Base64.h>
|
||||||
|
#include "cyPm.c"
|
||||||
|
|
||||||
// CONFIGURATION:
|
// CONFIGURATION:
|
||||||
// Change RegionCode, Frequency, Speed in config.h !
|
// Change RegionCode, Frequency, Speed in config.h !
|
||||||
|
@ -12,13 +14,11 @@
|
||||||
static MeshPacket thePacket;
|
static MeshPacket thePacket;
|
||||||
static ChannelSettings ChanSet;
|
static ChannelSettings ChanSet;
|
||||||
static RadioEvents_t RadioEvents;
|
static RadioEvents_t RadioEvents;
|
||||||
|
static TimerEvent_t CheckRadio;
|
||||||
static uint32_t lastreceivedID = 0;
|
static uint32_t lastreceivedID = 0;
|
||||||
static uint32_t startTime = 0;
|
|
||||||
static uint32_t symbolTime;
|
static uint32_t symbolTime;
|
||||||
static uint32_t sleepTime;
|
static uint32_t sendTime;
|
||||||
static uint32_t rxTime;
|
extern uint32_t systime; // global system time count --> millis()
|
||||||
static bool flag_No_Cycle = false;
|
|
||||||
|
|
||||||
|
|
||||||
#ifndef NOBLINK
|
#ifndef NOBLINK
|
||||||
#include "CubeCell_NeoPixel.h"
|
#include "CubeCell_NeoPixel.h"
|
||||||
|
@ -38,6 +38,7 @@ char str[32];
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
void setup() {
|
void setup() {
|
||||||
|
TimerInit( &CheckRadio, onCheckRadio );
|
||||||
#ifndef NO_OLED
|
#ifndef NO_OLED
|
||||||
pinMode(Vext,OUTPUT);
|
pinMode(Vext,OUTPUT);
|
||||||
digitalWrite(Vext,LOW);
|
digitalWrite(Vext,LOW);
|
||||||
|
@ -60,17 +61,24 @@ void setup() {
|
||||||
#endif
|
#endif
|
||||||
#ifndef SILENT
|
#ifndef SILENT
|
||||||
Serial.begin(115200);
|
Serial.begin(115200);
|
||||||
MSG("\n***********************************************************\nSetting up Radio:\n");
|
MSG("\n");
|
||||||
|
LINE(60, "*");
|
||||||
|
MSG("Setting up Radio:\n");
|
||||||
#endif
|
#endif
|
||||||
RadioEvents.TxDone = onTxDone;
|
RadioEvents.TxDone = onTxDone;
|
||||||
RadioEvents.TxTimeout = onTxTimeout;
|
RadioEvents.TxTimeout = onTxTimeout;
|
||||||
RadioEvents.RxDone = onRxDone;
|
RadioEvents.RxDone = onRxDone;
|
||||||
|
RadioEvents.RxTimeout = onRxTimeout;
|
||||||
|
RadioEvents.CadDone = onCadDone;
|
||||||
Radio.Init( &RadioEvents );
|
Radio.Init( &RadioEvents );
|
||||||
memcpy(ChanSet.name, MESHTASTIC_NAME, 12);
|
Radio.Sleep();
|
||||||
ChanSet.channel_num = hash( MESHTASTIC_NAME ) % regions[REGION].numChannels; // see config.h
|
// import Channel Settings from Meshtastic Link (channel name, modem config):
|
||||||
|
char decoded[Base64.decodedLength(&MeshtasticLink[30], sizeof(MeshtasticLink)-30)];
|
||||||
|
Base64.decode(decoded, &MeshtasticLink[30], sizeof(MeshtasticLink)-30);
|
||||||
|
pb_decode_from_bytes((uint8_t *)&decoded[0], sizeof(decoded), ChannelSettings_fields, &ChanSet);
|
||||||
|
// done, populate remaining settings according to channel name and provided modem config
|
||||||
|
ChanSet.channel_num = hash( ChanSet.name ) % regions[REGION].numChannels; // see config.h
|
||||||
ChanSet.tx_power = (regions[REGION].powerLimit == 0) ? TX_MAX_POWER : MIN(regions[REGION].powerLimit, TX_MAX_POWER) ;
|
ChanSet.tx_power = (regions[REGION].powerLimit == 0) ? TX_MAX_POWER : MIN(regions[REGION].powerLimit, TX_MAX_POWER) ;
|
||||||
//ChanSet.psk = MESHTASTIC_PSK;
|
|
||||||
ChanSet.psk = PSK_NOENCRYPTION;
|
|
||||||
/* FYI:
|
/* FYI:
|
||||||
"bandwidth":
|
"bandwidth":
|
||||||
[0: 125 kHz, 1: 250 kHz, 2: 500 kHz, 3: 62.5kHz, 4: 41.67kHz, 5: 31.25kHz, 6: 20.83kHz, 7: 15.63kHz, 8: 10.42kHz, 9: 7.81kHz]
|
[0: 125 kHz, 1: 250 kHz, 2: 500 kHz, 3: 62.5kHz, 4: 41.67kHz, 5: 31.25kHz, 6: 20.83kHz, 7: 15.63kHz, 8: 10.42kHz, 9: 7.81kHz]
|
||||||
|
@ -82,64 +90,79 @@ void setup() {
|
||||||
"coding rate":
|
"coding rate":
|
||||||
[1: 4/5, 2: 4/6, 3: 4/7, 4: 4/8]
|
[1: 4/5, 2: 4/6, 3: 4/7, 4: 4/8]
|
||||||
*/
|
*/
|
||||||
switch ( MESHTASTIC_SPEED ){
|
switch ( (uint8_t)ChanSet.modem_config ){
|
||||||
case 0: { // short range
|
case 0: { // short range
|
||||||
ChanSet.bandwidth = 0; // 125 kHz
|
ChanSet.bandwidth = 0; // 125 kHz
|
||||||
ChanSet.coding_rate = 1; // = 4/5
|
ChanSet.coding_rate = 1; // = 4/5
|
||||||
ChanSet.spread_factor = 7;
|
ChanSet.spread_factor = 7;
|
||||||
symbolTime = 1024; // in micro seconds!
|
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
case 1: { // medium range
|
case 1: { // medium range
|
||||||
ChanSet.bandwidth = 2; // 500 kHz
|
ChanSet.bandwidth = 2; // 500 kHz
|
||||||
ChanSet.coding_rate = 1; // = 4/5
|
ChanSet.coding_rate = 1; // = 4/5
|
||||||
ChanSet.spread_factor = 7;
|
ChanSet.spread_factor = 7;
|
||||||
symbolTime = 256;
|
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
case 2: { // long range
|
case 2: { // long range
|
||||||
ChanSet.bandwidth = 5; // 31.25 kHz
|
ChanSet.bandwidth = 5; // 31.25 kHz
|
||||||
ChanSet.coding_rate = 4; // = 4/8
|
ChanSet.coding_rate = 4; // = 4/8
|
||||||
ChanSet.spread_factor = 9;
|
ChanSet.spread_factor = 9;
|
||||||
symbolTime = 16384;
|
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
case 3: { // very long range
|
case 3: { // very long range
|
||||||
ChanSet.bandwidth = 0; // 125 kHz
|
ChanSet.bandwidth = 0; // 125 kHz
|
||||||
ChanSet.coding_rate = 4; // = 4/8
|
ChanSet.coding_rate = 4; // = 4/8
|
||||||
ChanSet.spread_factor = 12;
|
ChanSet.spread_factor = 12;
|
||||||
symbolTime = 32768;
|
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
default:{ // default setting is very long range
|
default:{ // default setting is very long range
|
||||||
ChanSet.bandwidth = 0; // 125 kHz
|
ChanSet.bandwidth = 0; // 125 kHz
|
||||||
ChanSet.coding_rate = 4; // = 4/8
|
ChanSet.coding_rate = 4; // = 4/8
|
||||||
ChanSet.spread_factor = 12;
|
ChanSet.spread_factor = 12;
|
||||||
symbolTime = 32768;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
symbolTime = ((1<< ChanSet.spread_factor)*1000 +32) *1000 / TheBandwidths[ChanSet.bandwidth]; // in micro seconds!
|
||||||
ConfigureRadio( ChanSet );
|
ConfigureRadio( ChanSet );
|
||||||
#ifndef SILENT
|
#ifndef SILENT
|
||||||
MSG("\n..done! Switch to Receive Mode.\n***********************************************************\n");
|
MSG("\n..done!\n");
|
||||||
|
LINE(60,"*");
|
||||||
#endif
|
#endif
|
||||||
#ifndef NO_OLED
|
#ifndef NO_OLED
|
||||||
display.drawString(0,32, "Receive Mode..");
|
display.drawString(0,32, "Receive Mode..");
|
||||||
display.display();
|
display.display();
|
||||||
#endif
|
#endif
|
||||||
setRxCycle();
|
TimerSetValue( &CheckRadio, symbolTime / 100 ); // MCU sleeps 10 LoRa symbols (in milli seconds)
|
||||||
|
TimerStart( &CheckRadio ); // onCheckRadio() will break deep sleep mode
|
||||||
|
Radio.StartCad( 3 ); // length in symbols
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void onCheckRadio(void)
|
||||||
|
{
|
||||||
|
TimerReset(&CheckRadio);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Cycle starts @ 0 symbols. LoRA: CAD for x symbols, then (implicitly) Standby MCU: sleep
|
||||||
|
// After 10 LoRa symbols, wake up MCU and check for IRQs from LoRa (including CADdone)
|
||||||
|
// If channel activiy detected, switch to RX mode for 500 symbols, to capture very long packages.
|
||||||
|
// If the package is shorter, the onRXDone handler will put the LoRa to sleep, so no excess power consumption
|
||||||
|
// Radio.Send() is non-blocking, so if a TX is running we cannot immediatly start a new CAD. We wait (sleep) until LoRa is idle.
|
||||||
|
|
||||||
void loop( )
|
void loop( )
|
||||||
{
|
{
|
||||||
while ( !(Radio.GetStatus() == RF_IDLE) ) {
|
|
||||||
for (uint8_t i = 0; i<6; i++) lowPowerHandler();
|
MCU_deepsleep( );
|
||||||
Radio.IrqProcess();
|
Radio.IrqProcess(); // handle events from LoRa, if CAD, set SX1262 to receive (onCadDone)
|
||||||
}
|
if ( Radio.GetStatus() == RF_IDLE ) Radio.StartCad( 3 ); // (in symbols)
|
||||||
setRxCycle();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void setRxCycle(void){
|
void onCadDone( bool ChannelActive ){
|
||||||
(flag_No_Cycle) ? Radio.Rx( 0 ) : Radio.SetRxDutyCycle( rxTime, sleepTime );
|
// Rx Time = 500 * symbol time (in ms) should be longer than receive time for max. packet length
|
||||||
|
(ChannelActive) ? Radio.Rx( symbolTime >> 1 ) : Radio.Sleep();
|
||||||
|
}
|
||||||
|
|
||||||
|
void onRxTimeout( void ){
|
||||||
|
Radio.Sleep();
|
||||||
}
|
}
|
||||||
|
|
||||||
void onTxDone( void )
|
void onTxDone( void )
|
||||||
|
@ -149,14 +172,14 @@ void onTxDone( void )
|
||||||
LED.show( );
|
LED.show( );
|
||||||
#endif
|
#endif
|
||||||
#ifndef SILENT
|
#ifndef SILENT
|
||||||
MSG(".done (%ims)! Switch to Receive Mode.\n", millis() - startTime );
|
MSG(".done (%ims)! Switch to Receive Mode.\n", millis() - sendTime );
|
||||||
#endif
|
#endif
|
||||||
#ifndef NO_OLED
|
#ifndef NO_OLED
|
||||||
sprintf(str,"..done. RX Mode..");
|
sprintf(str,"..done. RX Mode..");
|
||||||
display.drawString(42,53,str);
|
display.drawString(42,53,str);
|
||||||
display.display();
|
display.display();
|
||||||
#endif
|
#endif
|
||||||
Radio.Standby();
|
Radio.Sleep();
|
||||||
}
|
}
|
||||||
|
|
||||||
void onTxTimeout( void )
|
void onTxTimeout( void )
|
||||||
|
@ -173,11 +196,12 @@ void onTxTimeout( void )
|
||||||
display.drawString(42,53,str);
|
display.drawString(42,53,str);
|
||||||
display.display();
|
display.display();
|
||||||
#endif
|
#endif
|
||||||
Radio.Standby();
|
Radio.Sleep();
|
||||||
}
|
}
|
||||||
|
|
||||||
void onRxDone( uint8_t *payload, uint16_t size, int16_t rssi, int8_t snr )
|
void onRxDone( uint8_t *payload, uint16_t size, int16_t rssi, int8_t snr )
|
||||||
{
|
{
|
||||||
|
Radio.Sleep();
|
||||||
if ( size > MAX_PAYLOAD_LENGTH ) size = MAX_PAYLOAD_LENGTH;
|
if ( size > MAX_PAYLOAD_LENGTH ) size = MAX_PAYLOAD_LENGTH;
|
||||||
if ( !(size > sizeof(PacketHeader)) ) {
|
if ( !(size > sizeof(PacketHeader)) ) {
|
||||||
#ifndef SILENT
|
#ifndef SILENT
|
||||||
|
@ -189,7 +213,7 @@ void onRxDone( uint8_t *payload, uint16_t size, int16_t rssi, int8_t snr )
|
||||||
LED.show();
|
LED.show();
|
||||||
#endif
|
#endif
|
||||||
Radio.Send( payload, size );
|
Radio.Send( payload, size );
|
||||||
Radio.Standby();
|
Radio.Rx( 0 );
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
PacketHeader * h = (PacketHeader *)payload;
|
PacketHeader * h = (PacketHeader *)payload;
|
||||||
|
@ -243,8 +267,8 @@ void onRxDone( uint8_t *payload, uint16_t size, int16_t rssi, int8_t snr )
|
||||||
LED.show();
|
LED.show();
|
||||||
#endif
|
#endif
|
||||||
#ifndef SILENT
|
#ifndef SILENT
|
||||||
MSG("Sending packet.. (Size: %i)..", size);
|
MSG("Sending packet..");
|
||||||
startTime = millis();
|
sendTime = millis();
|
||||||
#endif
|
#endif
|
||||||
Radio.Send( payload, size );
|
Radio.Send( payload, size );
|
||||||
}
|
}
|
||||||
|
@ -277,36 +301,30 @@ void ConfigureRadio( ChannelSettings ChanSet )
|
||||||
#ifndef SILENT
|
#ifndef SILENT
|
||||||
MSG("\nRegion is: %s", regions[REGION].name);
|
MSG("\nRegion is: %s", regions[REGION].name);
|
||||||
MSG(" TX power: %i\n", ChanSet.tx_power);
|
MSG(" TX power: %i\n", ChanSet.tx_power);
|
||||||
|
MSG("Channel name is: '%s' .. \n", ChanSet.name );
|
||||||
MSG("Setting frequency to %i Hz (meshtastic channel %i) .. \n",freq,ChanSet.channel_num );
|
MSG("Setting frequency to %i Hz (meshtastic channel %i) .. \n",freq,ChanSet.channel_num );
|
||||||
MSG("Channel name is: %s .. \n", ChanSet.name );
|
MSG("Setting bandwidth to index %i (%ikHz)..\n", ChanSet.bandwidth, TheBandwidths[ChanSet.bandwidth] );
|
||||||
MSG("Setting bandwidth to index %i (%ikHz)..\n", ChanSet.bandwidth, TheBandwidths[ChanSet.bandwidth]);
|
MSG("Setting CodeRate to index %i (4/%i).. \n", ChanSet.coding_rate, ChanSet.coding_rate + 4 );
|
||||||
MSG("Setting CodeRate to index %i .. \n", ChanSet.coding_rate);
|
|
||||||
MSG("Setting SpreadingFactor to %i ..\n",ChanSet.spread_factor);
|
MSG("Setting SpreadingFactor to %i ..\n",ChanSet.spread_factor);
|
||||||
|
MSG("Symboltime is %i micro s ..\n", symbolTime );
|
||||||
#endif
|
#endif
|
||||||
Radio.SetChannel( freq );
|
Radio.SetChannel( freq );
|
||||||
Radio.SetTxConfig( MODEM_LORA, ChanSet.tx_power ,0 , ChanSet.bandwidth, ChanSet.spread_factor, ChanSet.coding_rate,
|
Radio.SetTxConfig( MODEM_LORA, ChanSet.tx_power ,0 , ChanSet.bandwidth, ChanSet.spread_factor, ChanSet.coding_rate,
|
||||||
LORA_PREAMBLE_LENGTH, false, true, false, 0, false, 20000 );
|
LORA_PREAMBLE_LENGTH, false, true, false, 0, false, 20000 );
|
||||||
Radio.SetRxConfig( MODEM_LORA, ChanSet.bandwidth, ChanSet.spread_factor, ChanSet.coding_rate, 0, LORA_PREAMBLE_LENGTH,
|
Radio.SetRxConfig( MODEM_LORA, ChanSet.bandwidth, ChanSet.spread_factor, ChanSet.coding_rate, 0, LORA_PREAMBLE_LENGTH,
|
||||||
LORA_SYMBOL_TIMEOUT, false , 0, true, false, 0, false, true );
|
LORA_SYMBOL_TIMEOUT, false , 0, true, false, 0, false, true );
|
||||||
|
}
|
||||||
// SET UP RX_DUTY_CYCLE:
|
|
||||||
#define RXSYMBOLS 8 // Minimum count of symbols to reliably detect a LoRa preamble in rx mode. Should not be lower than 6.
|
void MCU_deepsleep(void)
|
||||||
if ( (LORA_PREAMBLE_LENGTH + 4.5) < (2 * RXSYMBOLS + 1 ) ) // 4.5 symbols are added to the user set preamble by the Sx1262
|
{
|
||||||
{
|
#ifndef SILENT
|
||||||
#ifndef SILENT
|
UART_1_Sleep;
|
||||||
MSG("Short Preamble, will not use RxDutyCycle!\n");
|
#endif
|
||||||
#endif
|
pinMode(P4_1, ANALOG); // SPI0 MISO
|
||||||
flag_No_Cycle = true;
|
CySysPmDeepSleep(); // deep sleep mode
|
||||||
return;
|
systime = (uint32_t)TimerGetCurrentTime();
|
||||||
}
|
pinMode(P4_1, INPUT);
|
||||||
uint32_t preambTime = symbolTime * (LORA_PREAMBLE_LENGTH + 4.5); // micro secs.
|
#ifndef SILENT
|
||||||
rxTime = 2 * RXSYMBOLS * symbolTime;
|
UART_1_Wakeup;
|
||||||
sleepTime = preambTime - rxTime - 1000; // SX1262 needs 500 micro sec for each sleep/wake transition
|
#endif
|
||||||
if (preambTime < (2* rxTime + sleepTime) ) flag_No_Cycle = true;
|
|
||||||
#ifndef SILENT
|
|
||||||
MSG("Will use RxDutyCycle: %s\n", (flag_No_Cycle) ? "YES" : "NO" );
|
|
||||||
MSG("RX time: %u micro s sleep time: %u micro s\n", rxTime, sleepTime);
|
|
||||||
#endif
|
|
||||||
rxTime = (rxTime * 125) >> 3; // * 15.768 micro s (125/8 is 15.768)
|
|
||||||
sleepTime = (sleepTime * 125) >> 3;
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -0,0 +1,76 @@
|
||||||
|
#include "mesh-pb-constants.h"
|
||||||
|
/*#include "FS.h"
|
||||||
|
#include "configuration.h"
|
||||||
|
#include <Arduino.h>*/
|
||||||
|
#include <assert.h>
|
||||||
|
#include <pb_decode.h>
|
||||||
|
#include <pb_encode.h>
|
||||||
|
|
||||||
|
#ifdef ARDUINO_ARCH_NRF52
|
||||||
|
#include "Adafruit_LittleFS.h"
|
||||||
|
using namespace Adafruit_LittleFS_Namespace; // To get File type
|
||||||
|
#endif
|
||||||
|
|
||||||
|
/// helper function for encoding a record as a protobuf, any failures to encode are fatal and we will panic
|
||||||
|
/// returns the encoded packet size
|
||||||
|
size_t pb_encode_to_bytes(uint8_t *destbuf, size_t destbufsize, const pb_msgdesc_t *fields, const void *src_struct)
|
||||||
|
{
|
||||||
|
|
||||||
|
pb_ostream_t stream = pb_ostream_from_buffer(destbuf, destbufsize);
|
||||||
|
if (!pb_encode(&stream, fields, src_struct)) {
|
||||||
|
//MSG("Error: can't encode protobuf %s\n", PB_GET_ERROR(&stream));
|
||||||
|
assert(0); // FIXME - panic
|
||||||
|
} else {
|
||||||
|
return stream.bytes_written;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/// helper function for decoding a record as a protobuf, we will return false if the decoding failed
|
||||||
|
bool pb_decode_from_bytes(const uint8_t *srcbuf, size_t srcbufsize, const pb_msgdesc_t *fields, void *dest_struct)
|
||||||
|
{
|
||||||
|
pb_istream_t stream = pb_istream_from_buffer(srcbuf, srcbufsize);
|
||||||
|
if (!pb_decode(&stream, fields, dest_struct)) {
|
||||||
|
//DEBUG_MSG("Error: can't decode protobuf %s, pb_msgdesc 0x%p\n", PB_GET_ERROR(&stream), fields);
|
||||||
|
return false;
|
||||||
|
} else {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
/*
|
||||||
|
/// Read from an Arduino File
|
||||||
|
bool readcb(pb_istream_t *stream, uint8_t *buf, size_t count)
|
||||||
|
{
|
||||||
|
bool status = false;
|
||||||
|
File *file = (File *)stream->state;
|
||||||
|
|
||||||
|
if (buf == NULL) {
|
||||||
|
while (count-- && file->read() != EOF)
|
||||||
|
;
|
||||||
|
return count == 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
status = (file->read(buf, count) == (int)count);
|
||||||
|
|
||||||
|
if (file->available() == 0)
|
||||||
|
stream->bytes_left = 0;
|
||||||
|
|
||||||
|
return status;
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Write to an arduino file
|
||||||
|
bool writecb(pb_ostream_t *stream, const uint8_t *buf, size_t count)
|
||||||
|
{
|
||||||
|
File *file = (File *)stream->state;
|
||||||
|
// DEBUG_MSG("writing %d bytes to protobuf file\n", count);
|
||||||
|
return file->write(buf, count) == count;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool is_in_helper(uint32_t n, const uint32_t *array, pb_size_t count)
|
||||||
|
{
|
||||||
|
for (pb_size_t i = 0; i < count; i++)
|
||||||
|
if (array[i] == n)
|
||||||
|
return true;
|
||||||
|
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
*/
|
|
@ -0,0 +1,39 @@
|
||||||
|
#pragma once
|
||||||
|
|
||||||
|
#include "mesh.pb.h"
|
||||||
|
|
||||||
|
// this file defines constants which come from mesh.options
|
||||||
|
|
||||||
|
// Tricky macro to let you find the sizeof a type member
|
||||||
|
#define member_size(type, member) sizeof(((type *)0)->member)
|
||||||
|
|
||||||
|
/// max number of packets which can be waiting for delivery to android - note, this value comes from mesh.options protobuf
|
||||||
|
// FIXME - max_count is actually 32 but we save/load this as one long string of preencoded MeshPacket bytes - not a big array in RAM
|
||||||
|
// #define MAX_RX_TOPHONE (member_size(DeviceState, receive_queue) / member_size(DeviceState, receive_queue[0]))
|
||||||
|
#define MAX_RX_TOPHONE 32
|
||||||
|
|
||||||
|
/// max number of nodes allowed in the mesh
|
||||||
|
#define MAX_NUM_NODES (member_size(DeviceState, node_db) / member_size(DeviceState, node_db[0]))
|
||||||
|
|
||||||
|
/// helper function for encoding a record as a protobuf, any failures to encode are fatal and we will panic
|
||||||
|
/// returns the encoded packet size
|
||||||
|
size_t pb_encode_to_bytes(uint8_t *destbuf, size_t destbufsize, const pb_msgdesc_t *fields, const void *src_struct);
|
||||||
|
|
||||||
|
/// helper function for decoding a record as a protobuf, we will return false if the decoding failed
|
||||||
|
bool pb_decode_from_bytes(const uint8_t *srcbuf, size_t srcbufsize, const pb_msgdesc_t *fields, void *dest_struct);
|
||||||
|
|
||||||
|
/// Read from an Arduino File
|
||||||
|
bool readcb(pb_istream_t *stream, uint8_t *buf, size_t count);
|
||||||
|
|
||||||
|
/// Write to an arduino file
|
||||||
|
bool writecb(pb_ostream_t *stream, const uint8_t *buf, size_t count);
|
||||||
|
|
||||||
|
/** is_in_repeated is a macro/function that returns true if a specified word appears in a repeated protobuf array.
|
||||||
|
* It relies on the following naming conventions from nanopb:
|
||||||
|
*
|
||||||
|
* pb_size_t ignore_incoming_count;
|
||||||
|
* uint32_t ignore_incoming[3];
|
||||||
|
*/
|
||||||
|
bool is_in_helper(uint32_t n, const uint32_t *array, pb_size_t count);
|
||||||
|
|
||||||
|
#define is_in_repeated(name, n) is_in_helper(n, name, name##_count)
|
|
@ -0,0 +1,64 @@
|
||||||
|
/* Automatically generated nanopb constant definitions */
|
||||||
|
/* Generated by nanopb-0.4.1 */
|
||||||
|
|
||||||
|
#include "mesh.pb.h"
|
||||||
|
#if PB_PROTO_HEADER_VERSION != 40
|
||||||
|
#error Regenerate this file with the current version of nanopb generator.
|
||||||
|
#endif
|
||||||
|
|
||||||
|
PB_BIND(Position, Position, AUTO)
|
||||||
|
|
||||||
|
|
||||||
|
PB_BIND(Data, Data, AUTO)
|
||||||
|
|
||||||
|
|
||||||
|
PB_BIND(User, User, AUTO)
|
||||||
|
|
||||||
|
|
||||||
|
PB_BIND(RouteDiscovery, RouteDiscovery, AUTO)
|
||||||
|
|
||||||
|
|
||||||
|
PB_BIND(SubPacket, SubPacket, 2)
|
||||||
|
|
||||||
|
|
||||||
|
PB_BIND(MeshPacket, MeshPacket, 2)
|
||||||
|
|
||||||
|
|
||||||
|
PB_BIND(ChannelSettings, ChannelSettings, AUTO)
|
||||||
|
|
||||||
|
|
||||||
|
PB_BIND(RadioConfig, RadioConfig, 2)
|
||||||
|
|
||||||
|
|
||||||
|
PB_BIND(RadioConfig_UserPreferences, RadioConfig_UserPreferences, 2)
|
||||||
|
|
||||||
|
|
||||||
|
PB_BIND(NodeInfo, NodeInfo, AUTO)
|
||||||
|
|
||||||
|
|
||||||
|
PB_BIND(MyNodeInfo, MyNodeInfo, AUTO)
|
||||||
|
|
||||||
|
|
||||||
|
PB_BIND(DeviceState, DeviceState, 2)
|
||||||
|
|
||||||
|
|
||||||
|
PB_BIND(DebugString, DebugString, 2)
|
||||||
|
|
||||||
|
|
||||||
|
PB_BIND(FromRadio, FromRadio, 2)
|
||||||
|
|
||||||
|
|
||||||
|
PB_BIND(ToRadio, ToRadio, 2)
|
||||||
|
|
||||||
|
|
||||||
|
PB_BIND(ManufacturingData, ManufacturingData, AUTO)
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -37,6 +37,19 @@ typedef enum _RegionCode {
|
||||||
RegionCode_TW = 8
|
RegionCode_TW = 8
|
||||||
} RegionCode;
|
} RegionCode;
|
||||||
|
|
||||||
|
typedef enum _GpsOperation {
|
||||||
|
GpsOperation_GpsOpUnset = 0,
|
||||||
|
GpsOperation_GpsOpMobile = 2,
|
||||||
|
GpsOperation_GpsOpTimeOnly = 3,
|
||||||
|
GpsOperation_GpsOpDisabled = 4
|
||||||
|
} GpsOperation;
|
||||||
|
|
||||||
|
typedef enum _LocationSharing {
|
||||||
|
LocationSharing_LocUnset = 0,
|
||||||
|
LocationSharing_LocEnabled = 1,
|
||||||
|
LocationSharing_LocDisabled = 2
|
||||||
|
} LocationSharing;
|
||||||
|
|
||||||
typedef enum _Data_Type {
|
typedef enum _Data_Type {
|
||||||
Data_Type_OPAQUE = 0,
|
Data_Type_OPAQUE = 0,
|
||||||
Data_Type_CLEAR_TEXT = 1,
|
Data_Type_CLEAR_TEXT = 1,
|
||||||
|
@ -121,6 +134,12 @@ typedef struct _RadioConfig_UserPreferences {
|
||||||
char wifi_password[64];
|
char wifi_password[64];
|
||||||
bool wifi_ap_mode;
|
bool wifi_ap_mode;
|
||||||
RegionCode region;
|
RegionCode region;
|
||||||
|
LocationSharing location_share;
|
||||||
|
GpsOperation gps_operation;
|
||||||
|
uint32_t gps_update_interval;
|
||||||
|
uint32_t gps_attempt_time;
|
||||||
|
bool is_router;
|
||||||
|
bool is_low_power;
|
||||||
bool factory_reset;
|
bool factory_reset;
|
||||||
pb_size_t ignore_incoming_count;
|
pb_size_t ignore_incoming_count;
|
||||||
uint32_t ignore_incoming[3];
|
uint32_t ignore_incoming[3];
|
||||||
|
@ -248,6 +267,14 @@ typedef struct _ToRadio {
|
||||||
#define _RegionCode_MAX RegionCode_TW
|
#define _RegionCode_MAX RegionCode_TW
|
||||||
#define _RegionCode_ARRAYSIZE ((RegionCode)(RegionCode_TW+1))
|
#define _RegionCode_ARRAYSIZE ((RegionCode)(RegionCode_TW+1))
|
||||||
|
|
||||||
|
#define _GpsOperation_MIN GpsOperation_GpsOpUnset
|
||||||
|
#define _GpsOperation_MAX GpsOperation_GpsOpDisabled
|
||||||
|
#define _GpsOperation_ARRAYSIZE ((GpsOperation)(GpsOperation_GpsOpDisabled+1))
|
||||||
|
|
||||||
|
#define _LocationSharing_MIN LocationSharing_LocUnset
|
||||||
|
#define _LocationSharing_MAX LocationSharing_LocDisabled
|
||||||
|
#define _LocationSharing_ARRAYSIZE ((LocationSharing)(LocationSharing_LocDisabled+1))
|
||||||
|
|
||||||
#define _Data_Type_MIN Data_Type_OPAQUE
|
#define _Data_Type_MIN Data_Type_OPAQUE
|
||||||
#define _Data_Type_MAX Data_Type_CLEAR_READACK
|
#define _Data_Type_MAX Data_Type_CLEAR_READACK
|
||||||
#define _Data_Type_ARRAYSIZE ((Data_Type)(Data_Type_CLEAR_READACK+1))
|
#define _Data_Type_ARRAYSIZE ((Data_Type)(Data_Type_CLEAR_READACK+1))
|
||||||
|
@ -266,7 +293,7 @@ typedef struct _ToRadio {
|
||||||
#define MeshPacket_init_default {0, 0, 0, {SubPacket_init_default}, 0, 0, 0, 0, 0}
|
#define MeshPacket_init_default {0, 0, 0, {SubPacket_init_default}, 0, 0, 0, 0, 0}
|
||||||
#define ChannelSettings_init_default {0, _ChannelSettings_ModemConfig_MIN, {0, {0}}, "", 0, 0, 0, 0}
|
#define ChannelSettings_init_default {0, _ChannelSettings_ModemConfig_MIN, {0, {0}}, "", 0, 0, 0, 0}
|
||||||
#define RadioConfig_init_default {false, RadioConfig_UserPreferences_init_default, false, ChannelSettings_init_default}
|
#define RadioConfig_init_default {false, RadioConfig_UserPreferences_init_default, false, ChannelSettings_init_default}
|
||||||
#define RadioConfig_UserPreferences_init_default {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, "", "", 0, _RegionCode_MIN, 0, 0, {0, 0, 0}}
|
#define RadioConfig_UserPreferences_init_default {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, "", "", 0, _RegionCode_MIN, _LocationSharing_MIN, _GpsOperation_MIN, 0, 0, 0, 0, 0, 0, {0, 0, 0}}
|
||||||
#define NodeInfo_init_default {0, false, User_init_default, false, Position_init_default, 0, 0}
|
#define NodeInfo_init_default {0, false, User_init_default, false, Position_init_default, 0, 0}
|
||||||
#define MyNodeInfo_init_default {0, 0, 0, "", "", "", 0, 0, 0, 0, 0, 0, 0, 0}
|
#define MyNodeInfo_init_default {0, 0, 0, "", "", "", 0, 0, 0, 0, 0, 0, 0, 0}
|
||||||
#define DeviceState_init_default {false, RadioConfig_init_default, false, MyNodeInfo_init_default, false, User_init_default, 0, {NodeInfo_init_default, NodeInfo_init_default, NodeInfo_init_default, NodeInfo_init_default, NodeInfo_init_default, NodeInfo_init_default, NodeInfo_init_default, NodeInfo_init_default, NodeInfo_init_default, NodeInfo_init_default, NodeInfo_init_default, NodeInfo_init_default, NodeInfo_init_default, NodeInfo_init_default, NodeInfo_init_default, NodeInfo_init_default, NodeInfo_init_default, NodeInfo_init_default, NodeInfo_init_default, NodeInfo_init_default, NodeInfo_init_default, NodeInfo_init_default, NodeInfo_init_default, NodeInfo_init_default, NodeInfo_init_default, NodeInfo_init_default, NodeInfo_init_default, NodeInfo_init_default, NodeInfo_init_default, NodeInfo_init_default, NodeInfo_init_default, NodeInfo_init_default}, 0, {MeshPacket_init_default}, false, MeshPacket_init_default, 0, 0, 0}
|
#define DeviceState_init_default {false, RadioConfig_init_default, false, MyNodeInfo_init_default, false, User_init_default, 0, {NodeInfo_init_default, NodeInfo_init_default, NodeInfo_init_default, NodeInfo_init_default, NodeInfo_init_default, NodeInfo_init_default, NodeInfo_init_default, NodeInfo_init_default, NodeInfo_init_default, NodeInfo_init_default, NodeInfo_init_default, NodeInfo_init_default, NodeInfo_init_default, NodeInfo_init_default, NodeInfo_init_default, NodeInfo_init_default, NodeInfo_init_default, NodeInfo_init_default, NodeInfo_init_default, NodeInfo_init_default, NodeInfo_init_default, NodeInfo_init_default, NodeInfo_init_default, NodeInfo_init_default, NodeInfo_init_default, NodeInfo_init_default, NodeInfo_init_default, NodeInfo_init_default, NodeInfo_init_default, NodeInfo_init_default, NodeInfo_init_default, NodeInfo_init_default}, 0, {MeshPacket_init_default}, false, MeshPacket_init_default, 0, 0, 0}
|
||||||
|
@ -282,7 +309,7 @@ typedef struct _ToRadio {
|
||||||
#define MeshPacket_init_zero {0, 0, 0, {SubPacket_init_zero}, 0, 0, 0, 0, 0}
|
#define MeshPacket_init_zero {0, 0, 0, {SubPacket_init_zero}, 0, 0, 0, 0, 0}
|
||||||
#define ChannelSettings_init_zero {0, _ChannelSettings_ModemConfig_MIN, {0, {0}}, "", 0, 0, 0, 0}
|
#define ChannelSettings_init_zero {0, _ChannelSettings_ModemConfig_MIN, {0, {0}}, "", 0, 0, 0, 0}
|
||||||
#define RadioConfig_init_zero {false, RadioConfig_UserPreferences_init_zero, false, ChannelSettings_init_zero}
|
#define RadioConfig_init_zero {false, RadioConfig_UserPreferences_init_zero, false, ChannelSettings_init_zero}
|
||||||
#define RadioConfig_UserPreferences_init_zero {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, "", "", 0, _RegionCode_MIN, 0, 0, {0, 0, 0}}
|
#define RadioConfig_UserPreferences_init_zero {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, "", "", 0, _RegionCode_MIN, _LocationSharing_MIN, _GpsOperation_MIN, 0, 0, 0, 0, 0, 0, {0, 0, 0}}
|
||||||
#define NodeInfo_init_zero {0, false, User_init_zero, false, Position_init_zero, 0, 0}
|
#define NodeInfo_init_zero {0, false, User_init_zero, false, Position_init_zero, 0, 0}
|
||||||
#define MyNodeInfo_init_zero {0, 0, 0, "", "", "", 0, 0, 0, 0, 0, 0, 0, 0}
|
#define MyNodeInfo_init_zero {0, 0, 0, "", "", "", 0, 0, 0, 0, 0, 0, 0, 0}
|
||||||
#define DeviceState_init_zero {false, RadioConfig_init_zero, false, MyNodeInfo_init_zero, false, User_init_zero, 0, {NodeInfo_init_zero, NodeInfo_init_zero, NodeInfo_init_zero, NodeInfo_init_zero, NodeInfo_init_zero, NodeInfo_init_zero, NodeInfo_init_zero, NodeInfo_init_zero, NodeInfo_init_zero, NodeInfo_init_zero, NodeInfo_init_zero, NodeInfo_init_zero, NodeInfo_init_zero, NodeInfo_init_zero, NodeInfo_init_zero, NodeInfo_init_zero, NodeInfo_init_zero, NodeInfo_init_zero, NodeInfo_init_zero, NodeInfo_init_zero, NodeInfo_init_zero, NodeInfo_init_zero, NodeInfo_init_zero, NodeInfo_init_zero, NodeInfo_init_zero, NodeInfo_init_zero, NodeInfo_init_zero, NodeInfo_init_zero, NodeInfo_init_zero, NodeInfo_init_zero, NodeInfo_init_zero, NodeInfo_init_zero}, 0, {MeshPacket_init_zero}, false, MeshPacket_init_zero, 0, 0, 0}
|
#define DeviceState_init_zero {false, RadioConfig_init_zero, false, MyNodeInfo_init_zero, false, User_init_zero, 0, {NodeInfo_init_zero, NodeInfo_init_zero, NodeInfo_init_zero, NodeInfo_init_zero, NodeInfo_init_zero, NodeInfo_init_zero, NodeInfo_init_zero, NodeInfo_init_zero, NodeInfo_init_zero, NodeInfo_init_zero, NodeInfo_init_zero, NodeInfo_init_zero, NodeInfo_init_zero, NodeInfo_init_zero, NodeInfo_init_zero, NodeInfo_init_zero, NodeInfo_init_zero, NodeInfo_init_zero, NodeInfo_init_zero, NodeInfo_init_zero, NodeInfo_init_zero, NodeInfo_init_zero, NodeInfo_init_zero, NodeInfo_init_zero, NodeInfo_init_zero, NodeInfo_init_zero, NodeInfo_init_zero, NodeInfo_init_zero, NodeInfo_init_zero, NodeInfo_init_zero, NodeInfo_init_zero, NodeInfo_init_zero}, 0, {MeshPacket_init_zero}, false, MeshPacket_init_zero, 0, 0, 0}
|
||||||
|
@ -341,7 +368,13 @@ typedef struct _ToRadio {
|
||||||
#define RadioConfig_UserPreferences_wifi_password_tag 13
|
#define RadioConfig_UserPreferences_wifi_password_tag 13
|
||||||
#define RadioConfig_UserPreferences_wifi_ap_mode_tag 14
|
#define RadioConfig_UserPreferences_wifi_ap_mode_tag 14
|
||||||
#define RadioConfig_UserPreferences_region_tag 15
|
#define RadioConfig_UserPreferences_region_tag 15
|
||||||
|
#define RadioConfig_UserPreferences_is_router_tag 37
|
||||||
|
#define RadioConfig_UserPreferences_is_low_power_tag 38
|
||||||
#define RadioConfig_UserPreferences_factory_reset_tag 100
|
#define RadioConfig_UserPreferences_factory_reset_tag 100
|
||||||
|
#define RadioConfig_UserPreferences_location_share_tag 32
|
||||||
|
#define RadioConfig_UserPreferences_gps_operation_tag 33
|
||||||
|
#define RadioConfig_UserPreferences_gps_update_interval_tag 34
|
||||||
|
#define RadioConfig_UserPreferences_gps_attempt_time_tag 36
|
||||||
#define RadioConfig_UserPreferences_ignore_incoming_tag 103
|
#define RadioConfig_UserPreferences_ignore_incoming_tag 103
|
||||||
#define RouteDiscovery_route_tag 2
|
#define RouteDiscovery_route_tag 2
|
||||||
#define User_id_tag 1
|
#define User_id_tag 1
|
||||||
|
@ -498,6 +531,12 @@ X(a, STATIC, SINGULAR, STRING, wifi_ssid, 12) \
|
||||||
X(a, STATIC, SINGULAR, STRING, wifi_password, 13) \
|
X(a, STATIC, SINGULAR, STRING, wifi_password, 13) \
|
||||||
X(a, STATIC, SINGULAR, BOOL, wifi_ap_mode, 14) \
|
X(a, STATIC, SINGULAR, BOOL, wifi_ap_mode, 14) \
|
||||||
X(a, STATIC, SINGULAR, UENUM, region, 15) \
|
X(a, STATIC, SINGULAR, UENUM, region, 15) \
|
||||||
|
X(a, STATIC, SINGULAR, UENUM, location_share, 32) \
|
||||||
|
X(a, STATIC, SINGULAR, UENUM, gps_operation, 33) \
|
||||||
|
X(a, STATIC, SINGULAR, UINT32, gps_update_interval, 34) \
|
||||||
|
X(a, STATIC, SINGULAR, UINT32, gps_attempt_time, 36) \
|
||||||
|
X(a, STATIC, SINGULAR, BOOL, is_router, 37) \
|
||||||
|
X(a, STATIC, SINGULAR, BOOL, is_low_power, 38) \
|
||||||
X(a, STATIC, SINGULAR, BOOL, factory_reset, 100) \
|
X(a, STATIC, SINGULAR, BOOL, factory_reset, 100) \
|
||||||
X(a, STATIC, REPEATED, UINT32, ignore_incoming, 103)
|
X(a, STATIC, REPEATED, UINT32, ignore_incoming, 103)
|
||||||
#define RadioConfig_UserPreferences_CALLBACK NULL
|
#define RadioConfig_UserPreferences_CALLBACK NULL
|
||||||
|
@ -635,11 +674,11 @@ extern const pb_msgdesc_t ManufacturingData_msg;
|
||||||
#define SubPacket_size 274
|
#define SubPacket_size 274
|
||||||
#define MeshPacket_size 313
|
#define MeshPacket_size 313
|
||||||
#define ChannelSettings_size 84
|
#define ChannelSettings_size 84
|
||||||
#define RadioConfig_size 282
|
#define RadioConfig_size 308
|
||||||
#define RadioConfig_UserPreferences_size 193
|
#define RadioConfig_UserPreferences_size 219
|
||||||
#define NodeInfo_size 132
|
#define NodeInfo_size 132
|
||||||
#define MyNodeInfo_size 110
|
#define MyNodeInfo_size 110
|
||||||
#define DeviceState_size 5434
|
#define DeviceState_size 5460
|
||||||
#define DebugString_size 258
|
#define DebugString_size 258
|
||||||
#define FromRadio_size 322
|
#define FromRadio_size 322
|
||||||
#define ToRadio_size 316
|
#define ToRadio_size 316
|
||||||
|
|
Loading…
Reference in New Issue