Merge branch 'ripplebiz:main' into t1000e_ui

This commit is contained in:
fdlamotte 2025-03-13 09:44:10 +01:00 committed by GitHub
commit c62f09d92e
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
9 changed files with 264 additions and 111 deletions

View file

@ -46,6 +46,10 @@
#define OFFLINE_QUEUE_SIZE 16 #define OFFLINE_QUEUE_SIZE 16
#endif #endif
#ifndef BLE_NAME_PREFIX
#define BLE_NAME_PREFIX "MeshCore-"
#endif
#include <helpers/BaseChatMesh.h> #include <helpers/BaseChatMesh.h>
#define SEND_TIMEOUT_BASE_MILLIS 500 #define SEND_TIMEOUT_BASE_MILLIS 500
@ -124,11 +128,11 @@ static uint32_t _atoi(const char* sp) {
#define FIRMWARE_VER_CODE 2 #define FIRMWARE_VER_CODE 2
#ifndef FIRMWARE_BUILD_DATE #ifndef FIRMWARE_BUILD_DATE
#define FIRMWARE_BUILD_DATE "9 Mar 2025" #define FIRMWARE_BUILD_DATE "13 Mar 2025"
#endif #endif
#ifndef FIRMWARE_VERSION #ifndef FIRMWARE_VERSION
#define FIRMWARE_VERSION "v1.2.2" #define FIRMWARE_VERSION "v1.3.0"
#endif #endif
#define CMD_APP_START 1 #define CMD_APP_START 1
@ -161,6 +165,8 @@ static uint32_t _atoi(const char* sp) {
#define CMD_HAS_CONNECTION 28 #define CMD_HAS_CONNECTION 28
#define CMD_LOGOUT 29 // 'Disconnect' #define CMD_LOGOUT 29 // 'Disconnect'
#define CMD_GET_CONTACT_BY_KEY 30 #define CMD_GET_CONTACT_BY_KEY 30
#define CMD_GET_CHANNEL 31
#define CMD_SET_CHANNEL 32
#define RESP_CODE_OK 0 #define RESP_CODE_OK 0
#define RESP_CODE_ERR 1 #define RESP_CODE_ERR 1
@ -178,6 +184,8 @@ static uint32_t _atoi(const char* sp) {
#define RESP_CODE_DEVICE_INFO 13 // a reply to CMD_DEVICE_QEURY #define RESP_CODE_DEVICE_INFO 13 // a reply to CMD_DEVICE_QEURY
#define RESP_CODE_PRIVATE_KEY 14 // a reply to CMD_EXPORT_PRIVATE_KEY #define RESP_CODE_PRIVATE_KEY 14 // a reply to CMD_EXPORT_PRIVATE_KEY
#define RESP_CODE_DISABLED 15 #define RESP_CODE_DISABLED 15
// ... _V3 stuff in here
#define RESP_CODE_CHANNEL_INFO 18 // a reply to CMD_GET_CHANNEL
// these are _pushed_ to client app at any time // these are _pushed_ to client app at any time
#define PUSH_CODE_ADVERT 0x80 #define PUSH_CODE_ADVERT 0x80
@ -216,7 +224,6 @@ class MyMesh : public BaseChatMesh {
uint32_t expected_ack_crc; // TODO: keep table of expected ACKs uint32_t expected_ack_crc; // TODO: keep table of expected ACKs
uint32_t pending_login; uint32_t pending_login;
uint32_t pending_status; uint32_t pending_status;
mesh::GroupChannel* _public;
BaseSerialInterface* _serial; BaseSerialInterface* _serial;
unsigned long last_msg_sent; unsigned long last_msg_sent;
ContactsIterator _iter; ContactsIterator _iter;
@ -311,6 +318,58 @@ class MyMesh : public BaseChatMesh {
} }
} }
void loadChannels() {
if (_fs->exists("/channels2")) {
File file = _fs->open("/channels2");
if (file) {
bool full = false;
uint8_t channel_idx = 0;
while (!full) {
ChannelDetails ch;
uint8_t unused[4];
bool success = (file.read(unused, 4) == 4);
success = success && (file.read((uint8_t *) ch.name, 32) == 32);
success = success && (file.read((uint8_t *) ch.channel.secret, 32) == 32);
if (!success) break; // EOF
if (setChannel(channel_idx, ch)) {
channel_idx++;
} else {
full = true;
}
}
file.close();
}
}
}
void saveChannels() {
#if defined(NRF52_PLATFORM)
File file = _fs->open("/channels2", FILE_O_WRITE);
if (file) { file.seek(0); file.truncate(); }
#else
File file = _fs->open("/channels2", "w", true);
#endif
if (file) {
uint8_t channel_idx = 0;
ChannelDetails ch;
uint8_t unused[4];
memset(unused, 0, 4);
while (getChannel(channel_idx, ch)) {
bool success = (file.write(unused, 4) == 4);
success = success && (file.write((uint8_t *) ch.name, 32) == 32);
success = success && (file.write((uint8_t *) ch.channel.secret, 32) == 32);
if (!success) break; // write failed
channel_idx++;
}
file.close();
}
}
int getBlobByKey(const uint8_t key[], int key_len, uint8_t dest_buf[]) override { int getBlobByKey(const uint8_t key[], int key_len, uint8_t dest_buf[]) override {
char path[64]; char path[64];
char fname[18]; char fname[18];
@ -536,7 +595,7 @@ protected:
void onChannelMessageRecv(const mesh::GroupChannel& channel, int in_path_len, uint32_t timestamp, const char *text) override { void onChannelMessageRecv(const mesh::GroupChannel& channel, int in_path_len, uint32_t timestamp, const char *text) override {
int i = 0; int i = 0;
out_frame[i++] = RESP_CODE_CHANNEL_MSG_RECV; out_frame[i++] = RESP_CODE_CHANNEL_MSG_RECV;
out_frame[i++] = 0; // FUTURE: channel_idx (will just be 'public' for now) out_frame[i++] = findChannelIdx(channel);
out_frame[i++] = in_path_len < 0 ? 0xFF : in_path_len; out_frame[i++] = in_path_len < 0 ? 0xFF : in_path_len;
out_frame[i++] = TXT_TYPE_PLAIN; out_frame[i++] = TXT_TYPE_PLAIN;
memcpy(&out_frame[i], &timestamp, 4); i += 4; memcpy(&out_frame[i], &timestamp, 4); i += 4;
@ -713,7 +772,8 @@ public:
_fs->mkdir("/bl"); _fs->mkdir("/bl");
loadContacts(); loadContacts();
_public = addChannel(PUBLIC_GROUP_PSK); // pre-configure Andy's public channel addChannel("Public", PUBLIC_GROUP_PSK); // pre-configure Andy's public channel
loadChannels();
_phy->setFrequency(_prefs.freq); _phy->setFrequency(_prefs.freq);
_phy->setSpreadingFactor(_prefs.sf); _phy->setSpreadingFactor(_prefs.sf);
@ -769,7 +829,9 @@ public:
int i = 0; int i = 0;
out_frame[i++] = RESP_CODE_DEVICE_INFO; out_frame[i++] = RESP_CODE_DEVICE_INFO;
out_frame[i++] = FIRMWARE_VER_CODE; out_frame[i++] = FIRMWARE_VER_CODE;
memset(&out_frame[i], 0, 6); i += 6; // reserved out_frame[i++] = MAX_CONTACTS / 2; // v3+
out_frame[i++] = MAX_GROUP_CHANNELS; // v3+
memset(&out_frame[i], 0, 4); i += 4; // reserved
memset(&out_frame[i], 0, 12); memset(&out_frame[i], 0, 12);
strcpy((char *) &out_frame[i], FIRMWARE_BUILD_DATE); i += 12; strcpy((char *) &out_frame[i], FIRMWARE_BUILD_DATE); i += 12;
StrHelper::strzcpy((char *) &out_frame[i], board.getManufacturerName(), 40); i += 40; StrHelper::strzcpy((char *) &out_frame[i], board.getManufacturerName(), 40); i += 40;
@ -844,12 +906,14 @@ public:
} else if (cmd_frame[0] == CMD_SEND_CHANNEL_TXT_MSG) { // send GroupChannel msg } else if (cmd_frame[0] == CMD_SEND_CHANNEL_TXT_MSG) { // send GroupChannel msg
int i = 1; int i = 1;
uint8_t txt_type = cmd_frame[i++]; // should be TXT_TYPE_PLAIN uint8_t txt_type = cmd_frame[i++]; // should be TXT_TYPE_PLAIN
uint8_t channel_idx = cmd_frame[i++]; // reserved future uint8_t channel_idx = cmd_frame[i++];
uint32_t msg_timestamp; uint32_t msg_timestamp;
memcpy(&msg_timestamp, &cmd_frame[i], 4); i += 4; memcpy(&msg_timestamp, &cmd_frame[i], 4); i += 4;
const char *text = (char *) &cmd_frame[i]; const char *text = (char *) &cmd_frame[i];
if (txt_type == TXT_TYPE_PLAIN && sendGroupMessage(msg_timestamp, *_public, _prefs.node_name, text, len - i)) { // hard-coded to 'public' channel for now ChannelDetails channel;
bool success = getChannel(channel_idx, channel);
if (success && txt_type == TXT_TYPE_PLAIN && sendGroupMessage(msg_timestamp, channel.channel, _prefs.node_name, text, len - i)) {
writeOKFrame(); writeOKFrame();
} else { } else {
writeErrFrame(); writeErrFrame();
@ -1164,6 +1228,33 @@ public:
uint8_t* pub_key = &cmd_frame[1]; uint8_t* pub_key = &cmd_frame[1];
stopConnection(pub_key); stopConnection(pub_key);
writeOKFrame(); writeOKFrame();
} else if (cmd_frame[0] == CMD_GET_CHANNEL && len >= 2) {
uint8_t channel_idx = cmd_frame[1];
ChannelDetails channel;
if (getChannel(channel_idx, channel)) {
int i = 0;
out_frame[i++] = RESP_CODE_CHANNEL_INFO;
out_frame[i++] = channel_idx;
strcpy((char *)&out_frame[i], channel.name); i += 32;
memcpy(&out_frame[i], channel.channel.secret, 16); i += 16; // NOTE: only 128-bit supported
_serial->writeFrame(out_frame, i);
} else {
writeErrFrame();
}
} else if (cmd_frame[0] == CMD_SET_CHANNEL && len >= 2+32+32) {
writeErrFrame(); // not supported (yet)
} else if (cmd_frame[0] == CMD_SET_CHANNEL && len >= 2+32+16) {
uint8_t channel_idx = cmd_frame[1];
ChannelDetails channel;
StrHelper::strncpy(channel.name, (char *) &cmd_frame[2], 32);
memset(channel.channel.secret, 0, sizeof(channel.channel.secret));
memcpy(channel.channel.secret, &cmd_frame[2+32], 16); // NOTE: only 128-bit supported
if (setChannel(channel_idx, channel)) {
saveChannels();
writeOKFrame();
} else {
writeErrFrame();
}
} else { } else {
writeErrFrame(); writeErrFrame();
MESH_DEBUG_PRINTLN("ERROR: unknown command: %02X", cmd_frame[0]); MESH_DEBUG_PRINTLN("ERROR: unknown command: %02X", cmd_frame[0]);
@ -1293,14 +1384,8 @@ void setup() {
the_mesh.begin(InternalFS, trng); the_mesh.begin(InternalFS, trng);
#ifdef BLE_PIN_CODE #ifdef BLE_PIN_CODE
char dev_name[32+10]; char dev_name[32+16];
const char* prefix = sprintf(dev_name, "%s%s", BLE_NAME_PREFIX, the_mesh.getNodeName());
#ifdef BLE_NAME_PREFIX
BLE_NAME_PREFIX;
#else
"MeshCore-";
#endif
sprintf(dev_name, "%s%s", prefix, the_mesh.getNodeName());
serial_interface.begin(dev_name, the_mesh.getBLEPin()); serial_interface.begin(dev_name, the_mesh.getBLEPin());
#else #else
pinMode(WB_IO2, OUTPUT); pinMode(WB_IO2, OUTPUT);
@ -1315,14 +1400,8 @@ void setup() {
WiFi.begin(WIFI_SSID, WIFI_PWD); WiFi.begin(WIFI_SSID, WIFI_PWD);
serial_interface.begin(TCP_PORT); serial_interface.begin(TCP_PORT);
#elif defined(BLE_PIN_CODE) #elif defined(BLE_PIN_CODE)
char dev_name[32+10]; char dev_name[32+16];
const char* prefix = sprintf(dev_name, "%s%s", BLE_NAME_PREFIX, the_mesh.getNodeName());
#ifdef BLE_NAME_PREFIX
BLE_NAME_PREFIX;
#else
"MeshCore-";
#endif
sprintf(dev_name, "%s%s", prefix, the_mesh.getNodeName());
serial_interface.begin(dev_name, the_mesh.getBLEPin()); serial_interface.begin(dev_name, the_mesh.getBLEPin());
#else #else
serial_interface.begin(Serial); serial_interface.begin(Serial);

View file

@ -22,11 +22,11 @@
/* ------------------------------ Config -------------------------------- */ /* ------------------------------ Config -------------------------------- */
#ifndef FIRMWARE_BUILD_DATE #ifndef FIRMWARE_BUILD_DATE
#define FIRMWARE_BUILD_DATE "9 Mar 2025" #define FIRMWARE_BUILD_DATE "13 Mar 2025"
#endif #endif
#ifndef FIRMWARE_VERSION #ifndef FIRMWARE_VERSION
#define FIRMWARE_VERSION "v1.2.2" #define FIRMWARE_VERSION "v1.3.0"
#endif #endif
#ifndef LORA_FREQ #ifndef LORA_FREQ
@ -235,7 +235,9 @@ protected:
} }
bool allowPacketForward(const mesh::Packet* packet) override { bool allowPacketForward(const mesh::Packet* packet) override {
return !_prefs.disable_fwd; if (_prefs.disable_fwd) return false;
if (packet->isRouteFlood() && packet->path_len >= _prefs.flood_max) return false;
return true;
} }
const char* getLogDateTime() override { const char* getLogDateTime() override {
@ -536,6 +538,7 @@ public:
_prefs.cr = LORA_CR; _prefs.cr = LORA_CR;
_prefs.tx_power_dbm = LORA_TX_POWER; _prefs.tx_power_dbm = LORA_TX_POWER;
_prefs.advert_interval = 1; // default to 2 minutes for NEW installs _prefs.advert_interval = 1; // default to 2 minutes for NEW installs
_prefs.flood_max = 64;
} }
CommonCLI* getCLI() { return &_cli; } CommonCLI* getCLI() { return &_cli; }

View file

@ -22,11 +22,11 @@
/* ------------------------------ Config -------------------------------- */ /* ------------------------------ Config -------------------------------- */
#ifndef FIRMWARE_BUILD_DATE #ifndef FIRMWARE_BUILD_DATE
#define FIRMWARE_BUILD_DATE "9 Mar 2025" #define FIRMWARE_BUILD_DATE "13 Mar 2025"
#endif #endif
#ifndef FIRMWARE_VERSION #ifndef FIRMWARE_VERSION
#define FIRMWARE_VERSION "v1.2.2" #define FIRMWARE_VERSION "v1.3.0"
#endif #endif
#ifndef LORA_FREQ #ifndef LORA_FREQ
@ -304,7 +304,9 @@ protected:
} }
bool allowPacketForward(const mesh::Packet* packet) override { bool allowPacketForward(const mesh::Packet* packet) override {
return !_prefs.disable_fwd; if (_prefs.disable_fwd) return false;
if (packet->isRouteFlood() && packet->path_len >= _prefs.flood_max) return false;
return true;
} }
void onAnonDataRecv(mesh::Packet* packet, uint8_t type, const mesh::Identity& sender, uint8_t* data, size_t len) override { void onAnonDataRecv(mesh::Packet* packet, uint8_t type, const mesh::Identity& sender, uint8_t* data, size_t len) override {
@ -568,6 +570,7 @@ public:
_prefs.tx_power_dbm = LORA_TX_POWER; _prefs.tx_power_dbm = LORA_TX_POWER;
_prefs.disable_fwd = 1; _prefs.disable_fwd = 1;
_prefs.advert_interval = 1; // default to 2 minutes for NEW installs _prefs.advert_interval = 1; // default to 2 minutes for NEW installs
_prefs.flood_max = 64;
#ifdef ROOM_PASSWORD #ifdef ROOM_PASSWORD
StrHelper::strncpy(_prefs.guest_password, ROOM_PASSWORD, sizeof(_prefs.guest_password)); StrHelper::strncpy(_prefs.guest_password, ROOM_PASSWORD, sizeof(_prefs.guest_password));
#endif #endif

View file

@ -107,7 +107,7 @@ class MyMesh : public BaseChatMesh, ContactVisitor {
FILESYSTEM* _fs; FILESYSTEM* _fs;
NodePrefs _prefs; NodePrefs _prefs;
uint32_t expected_ack_crc; uint32_t expected_ack_crc;
mesh::GroupChannel* _public; ChannelDetails* _public;
unsigned long last_msg_sent; unsigned long last_msg_sent;
ContactInfo* curr_recipient; ContactInfo* curr_recipient;
char command[512+10]; char command[512+10];
@ -337,7 +337,7 @@ public:
} }
loadContacts(); loadContacts();
_public = addChannel(PUBLIC_GROUP_PSK); // pre-configure Andy's public channel _public = addChannel("Public", PUBLIC_GROUP_PSK); // pre-configure Andy's public channel
} }
void savePrefs() { void savePrefs() {
@ -405,7 +405,7 @@ public:
temp[5 + MAX_TEXT_LEN] = 0; // truncate if too long temp[5 + MAX_TEXT_LEN] = 0; // truncate if too long
int len = strlen((char *) &temp[5]); int len = strlen((char *) &temp[5]);
auto pkt = createGroupDatagram(PAYLOAD_TYPE_GRP_TXT, *_public, temp, 5 + len); auto pkt = createGroupDatagram(PAYLOAD_TYPE_GRP_TXT, _public->channel, temp, 5 + len);
if (pkt) { if (pkt) {
sendFlood(pkt); sendFlood(pkt);
Serial.println(" Sent."); Serial.println(" Sent.");

View file

@ -52,10 +52,10 @@ build_src_filter = ${esp32_base.build_src_filter}
extends = Heltec_lora32_v2 extends = Heltec_lora32_v2
build_flags = build_flags =
${Heltec_lora32_v2.build_flags} ${Heltec_lora32_v2.build_flags}
-D ADVERT_NAME="\"Heltec Repeater\"" -D ADVERT_NAME='"Heltec Repeater"'
-D ADVERT_LAT=-37.0 -D ADVERT_LAT=-37.0
-D ADVERT_LON=145.0 -D ADVERT_LON=145.0
-D ADMIN_PASSWORD="\"password\"" -D ADMIN_PASSWORD='"password"'
; -D MESH_PACKET_LOGGING=1 ; -D MESH_PACKET_LOGGING=1
; -D MESH_DEBUG=1 ; -D MESH_DEBUG=1
build_src_filter = ${Heltec_lora32_v2.build_src_filter} build_src_filter = ${Heltec_lora32_v2.build_src_filter}
@ -80,7 +80,7 @@ extends = Heltec_lora32_v2
build_flags = build_flags =
${Heltec_lora32_v2.build_flags} ${Heltec_lora32_v2.build_flags}
-D MAX_CONTACTS=100 -D MAX_CONTACTS=100
-D MAX_GROUP_CHANNELS=1 -D MAX_GROUP_CHANNELS=8
; NOTE: DO NOT ENABLE --> -D MESH_PACKET_LOGGING=1 ; NOTE: DO NOT ENABLE --> -D MESH_PACKET_LOGGING=1
; NOTE: DO NOT ENABLE --> -D MESH_DEBUG=1 ; NOTE: DO NOT ENABLE --> -D MESH_DEBUG=1
build_src_filter = ${Heltec_lora32_v2.build_src_filter} build_src_filter = ${Heltec_lora32_v2.build_src_filter}
@ -95,7 +95,7 @@ extends = Heltec_lora32_v2
build_flags = build_flags =
${Heltec_lora32_v2.build_flags} ${Heltec_lora32_v2.build_flags}
-D MAX_CONTACTS=100 -D MAX_CONTACTS=100
-D MAX_GROUP_CHANNELS=1 -D MAX_GROUP_CHANNELS=8
-D BLE_PIN_CODE=123456 -D BLE_PIN_CODE=123456
-D BLE_DEBUG_LOGGING=1 -D BLE_DEBUG_LOGGING=1
; -D ENABLE_PRIVATE_KEY_IMPORT=1 ; -D ENABLE_PRIVATE_KEY_IMPORT=1
@ -109,7 +109,6 @@ lib_deps =
${Heltec_lora32_v2.lib_deps} ${Heltec_lora32_v2.lib_deps}
densaugeo/base64 @ ~1.4.0 densaugeo/base64 @ ~1.4.0
; ================ ; ================
[Heltec_lora32_v3] [Heltec_lora32_v3]
extends = esp32_base extends = esp32_base
@ -127,7 +126,7 @@ build_flags =
-D SX126X_DIO2_AS_RF_SWITCH=true -D SX126X_DIO2_AS_RF_SWITCH=true
-D SX126X_DIO3_TCXO_VOLTAGE=1.8 -D SX126X_DIO3_TCXO_VOLTAGE=1.8
-D SX126X_CURRENT_LIMIT=130.0f ; for best TX power! -D SX126X_CURRENT_LIMIT=130.0f ; for best TX power!
-D SX126X_RX_BOOSTED_GAIN=true -D SX126X_RX_BOOSTED_GAIN=1
build_src_filter = ${esp32_base.build_src_filter} build_src_filter = ${esp32_base.build_src_filter}
lib_deps = lib_deps =
${esp32_base.lib_deps} ${esp32_base.lib_deps}
@ -138,10 +137,10 @@ extends = Heltec_lora32_v3
build_flags = build_flags =
${Heltec_lora32_v3.build_flags} ${Heltec_lora32_v3.build_flags}
-D DISPLAY_CLASS=SSD1306Display -D DISPLAY_CLASS=SSD1306Display
-D ADVERT_NAME="\"Heltec Repeater\"" -D ADVERT_NAME='"Heltec Repeater"'
-D ADVERT_LAT=-37.0 -D ADVERT_LAT=-37.0
-D ADVERT_LON=145.0 -D ADVERT_LON=145.0
-D ADMIN_PASSWORD="\"password\"" -D ADMIN_PASSWORD='"password"'
-D MESH_PACKET_LOGGING=1 -D MESH_PACKET_LOGGING=1
; -D MESH_DEBUG=1 ; -D MESH_DEBUG=1
build_src_filter = ${Heltec_lora32_v3.build_src_filter} build_src_filter = ${Heltec_lora32_v3.build_src_filter}
@ -156,12 +155,12 @@ build_src_filter = ${Heltec_lora32_v3.build_src_filter}
build_flags = build_flags =
${Heltec_lora32_v3.build_flags} ${Heltec_lora32_v3.build_flags}
-D DISPLAY_CLASS=SSD1306Display -D DISPLAY_CLASS=SSD1306Display
-D ADVERT_NAME="\"Heltec Room\"" -D ADVERT_NAME='"Heltec Room"'
-D ADVERT_LAT=-37.0 -D ADVERT_LAT=-37.0
-D ADVERT_LON=145.0 -D ADVERT_LON=145.0
-D ADMIN_PASSWORD="\"password\"" -D ADMIN_PASSWORD='"password"'
-D ROOM_PASSWORD="\"hello\"" -D ROOM_PASSWORD='"hello"'
-D MESH_PACKET_LOGGING=1 ; -D MESH_PACKET_LOGGING=1
; -D MESH_DEBUG=1 ; -D MESH_DEBUG=1
[env:Heltec_v3_terminal_chat] [env:Heltec_v3_terminal_chat]
@ -183,7 +182,7 @@ extends = Heltec_lora32_v3
build_flags = build_flags =
${Heltec_lora32_v3.build_flags} ${Heltec_lora32_v3.build_flags}
-D MAX_CONTACTS=100 -D MAX_CONTACTS=100
-D MAX_GROUP_CHANNELS=1 -D MAX_GROUP_CHANNELS=8
-D DISPLAY_CLASS=SSD1306Display -D DISPLAY_CLASS=SSD1306Display
; -D ENABLE_PRIVATE_KEY_IMPORT=1 ; -D ENABLE_PRIVATE_KEY_IMPORT=1
; -D ENABLE_PRIVATE_KEY_EXPORT=1 ; -D ENABLE_PRIVATE_KEY_EXPORT=1
@ -201,7 +200,7 @@ extends = Heltec_lora32_v3
build_flags = build_flags =
${Heltec_lora32_v3.build_flags} ${Heltec_lora32_v3.build_flags}
-D MAX_CONTACTS=100 -D MAX_CONTACTS=100
-D MAX_GROUP_CHANNELS=1 -D MAX_GROUP_CHANNELS=8
-D DISPLAY_CLASS=SSD1306Display -D DISPLAY_CLASS=SSD1306Display
-D BLE_PIN_CODE=0 ; dynamic, random PIN -D BLE_PIN_CODE=0 ; dynamic, random PIN
-D BLE_DEBUG_LOGGING=1 -D BLE_DEBUG_LOGGING=1
@ -222,11 +221,11 @@ extends = Heltec_lora32_v3
build_flags = build_flags =
${Heltec_lora32_v3.build_flags} ${Heltec_lora32_v3.build_flags}
-D MAX_CONTACTS=100 -D MAX_CONTACTS=100
-D MAX_GROUP_CHANNELS=1 -D MAX_GROUP_CHANNELS=8
-D DISPLAY_CLASS=SSD1306Display -D DISPLAY_CLASS=SSD1306Display
-D WIFI_DEBUG_LOGGING=1 -D WIFI_DEBUG_LOGGING=1
-D WIFI_SSID="\"myssid\"" -D WIFI_SSID='"myssid"'
-D WIFI_PWD="\"mypwd\"" -D WIFI_PWD='"mypwd"'
; -D ENABLE_PRIVATE_KEY_IMPORT=1 ; -D ENABLE_PRIVATE_KEY_IMPORT=1
; -D ENABLE_PRIVATE_KEY_EXPORT=1 ; -D ENABLE_PRIVATE_KEY_EXPORT=1
; -D MESH_PACKET_LOGGING=1 ; -D MESH_PACKET_LOGGING=1
@ -243,10 +242,10 @@ lib_deps =
extends = Heltec_lora32_v3 extends = Heltec_lora32_v3
build_flags = build_flags =
${Heltec_lora32_v3.build_flags} ${Heltec_lora32_v3.build_flags}
-D ADVERT_NAME="\"Heltec Repeater\"" -D ADVERT_NAME='"Heltec Repeater"'
-D ADVERT_LAT=-37.0 -D ADVERT_LAT=-37.0
-D ADVERT_LON=145.0 -D ADVERT_LON=145.0
-D ADMIN_PASSWORD="\"password\"" -D ADMIN_PASSWORD='"password"'
-D MESH_PACKET_LOGGING=1 -D MESH_PACKET_LOGGING=1
; -D MESH_DEBUG=1 ; -D MESH_DEBUG=1
build_src_filter = ${Heltec_lora32_v3.build_src_filter} build_src_filter = ${Heltec_lora32_v3.build_src_filter}
@ -258,11 +257,11 @@ build_src_filter = ${Heltec_lora32_v3.build_src_filter}
+<../examples/simple_room_server> +<../examples/simple_room_server>
build_flags = build_flags =
${Heltec_lora32_v3.build_flags} ${Heltec_lora32_v3.build_flags}
-D ADVERT_NAME="\"Heltec Room\"" -D ADVERT_NAME='"Heltec Room"'
-D ADVERT_LAT=-37.0 -D ADVERT_LAT=-37.0
-D ADVERT_LON=145.0 -D ADVERT_LON=145.0
-D ADMIN_PASSWORD="\"password\"" -D ADMIN_PASSWORD='"password"'
-D ROOM_PASSWORD="\"hello\"" -D ROOM_PASSWORD='"hello"'
; -D MESH_PACKET_LOGGING=1 ; -D MESH_PACKET_LOGGING=1
; -D MESH_DEBUG=1 ; -D MESH_DEBUG=1
@ -271,7 +270,7 @@ extends = Heltec_lora32_v3
build_flags = build_flags =
${Heltec_lora32_v3.build_flags} ${Heltec_lora32_v3.build_flags}
-D MAX_CONTACTS=100 -D MAX_CONTACTS=100
-D MAX_GROUP_CHANNELS=1 -D MAX_GROUP_CHANNELS=8
-D BLE_PIN_CODE=123456 -D BLE_PIN_CODE=123456
-D BLE_DEBUG_LOGGING=1 -D BLE_DEBUG_LOGGING=1
; -D ENABLE_PRIVATE_KEY_IMPORT=1 ; -D ENABLE_PRIVATE_KEY_IMPORT=1
@ -312,11 +311,12 @@ build_flags =
${Xiao_esp32_C3.build_flags} ${Xiao_esp32_C3.build_flags}
-D RADIO_CLASS=CustomSX1262 -D RADIO_CLASS=CustomSX1262
-D WRAPPER_CLASS=CustomSX1262Wrapper -D WRAPPER_CLASS=CustomSX1262Wrapper
-D SX126X_RX_BOOSTED_GAIN=1
-D LORA_TX_POWER=22 -D LORA_TX_POWER=22
-D ADVERT_NAME="\"Xiao Repeater\"" -D ADVERT_NAME='"Xiao Repeater"'
-D ADVERT_LAT=-37.0 -D ADVERT_LAT=-37.0
-D ADVERT_LON=145.0 -D ADVERT_LON=145.0
-D ADMIN_PASSWORD="\"password\"" -D ADMIN_PASSWORD='"password"'
; -D MESH_PACKET_LOGGING=1 ; -D MESH_PACKET_LOGGING=1
; -D MESH_DEBUG=1 ; -D MESH_DEBUG=1
@ -329,10 +329,10 @@ build_flags =
-D RADIO_CLASS=CustomSX1268 -D RADIO_CLASS=CustomSX1268
-D WRAPPER_CLASS=CustomSX1268Wrapper -D WRAPPER_CLASS=CustomSX1268Wrapper
-D LORA_TX_POWER=22 -D LORA_TX_POWER=22
-D ADVERT_NAME="\"Xiao Repeater\"" -D ADVERT_NAME='"Xiao Repeater"'
-D ADVERT_LAT=-37.0 -D ADVERT_LAT=-37.0
-D ADVERT_LON=145.0 -D ADVERT_LON=145.0
-D ADMIN_PASSWORD="\"password\"" -D ADMIN_PASSWORD='"password"'
; -D MESH_PACKET_LOGGING=1 ; -D MESH_PACKET_LOGGING=1
; -D MESH_DEBUG=1 ; -D MESH_DEBUG=1
@ -357,6 +357,7 @@ build_flags = ${esp32_base.build_flags}
-D RADIO_CLASS=CustomSX1262 -D RADIO_CLASS=CustomSX1262
-D WRAPPER_CLASS=CustomSX1262Wrapper -D WRAPPER_CLASS=CustomSX1262Wrapper
-D LORA_TX_POWER=22 -D LORA_TX_POWER=22
-D SX126X_RX_BOOSTED_GAIN=1
[env:Xiao_S3_WIO_Repeater] [env:Xiao_S3_WIO_Repeater]
extends = Xiao_S3_WIO extends = Xiao_S3_WIO
@ -364,10 +365,10 @@ build_src_filter = ${Xiao_S3_WIO.build_src_filter}
+<../examples/simple_repeater/main.cpp> +<../examples/simple_repeater/main.cpp>
build_flags = build_flags =
${Xiao_S3_WIO.build_flags} ${Xiao_S3_WIO.build_flags}
-D ADVERT_NAME="\"XiaoS3 Repeater\"" -D ADVERT_NAME='"XiaoS3 Repeater"'
-D ADVERT_LAT=-37.0 -D ADVERT_LAT=-37.0
-D ADVERT_LON=145.0 -D ADVERT_LON=145.0
-D ADMIN_PASSWORD="\"password\"" -D ADMIN_PASSWORD='"password"'
; -D MESH_PACKET_LOGGING=1 ; -D MESH_PACKET_LOGGING=1
; -D MESH_DEBUG=1 ; -D MESH_DEBUG=1
@ -376,7 +377,7 @@ extends = Xiao_S3_WIO
build_flags = build_flags =
${Xiao_S3_WIO.build_flags} ${Xiao_S3_WIO.build_flags}
-D MAX_CONTACTS=100 -D MAX_CONTACTS=100
-D MAX_GROUP_CHANNELS=1 -D MAX_GROUP_CHANNELS=8
; -D MESH_PACKET_LOGGING=1 ; -D MESH_PACKET_LOGGING=1
; -D MESH_DEBUG=1 ; -D MESH_DEBUG=1
build_src_filter = ${Xiao_S3_WIO.build_src_filter} build_src_filter = ${Xiao_S3_WIO.build_src_filter}
@ -390,7 +391,7 @@ extends = Xiao_S3_WIO
build_flags = build_flags =
${Xiao_S3_WIO.build_flags} ${Xiao_S3_WIO.build_flags}
-D MAX_CONTACTS=100 -D MAX_CONTACTS=100
-D MAX_GROUP_CHANNELS=1 -D MAX_GROUP_CHANNELS=8
-D BLE_PIN_CODE=123456 -D BLE_PIN_CODE=123456
; -D BLE_DEBUG_LOGGING=1 ; -D BLE_DEBUG_LOGGING=1
; -D ENABLE_PRIVATE_KEY_IMPORT=1 ; -D ENABLE_PRIVATE_KEY_IMPORT=1
@ -442,10 +443,10 @@ build_src_filter = ${LilyGo_TLora_V2_1_1_6.build_src_filter}
+<../examples/simple_repeater> +<../examples/simple_repeater>
build_flags = build_flags =
${LilyGo_TLora_V2_1_1_6.build_flags} ${LilyGo_TLora_V2_1_1_6.build_flags}
-D ADVERT_NAME="\"TLora-V2.1-1.6 Repeater\"" -D ADVERT_NAME='"TLora-V2.1-1.6 Repeater"'
-D ADVERT_LAT=-37.0 -D ADVERT_LAT=-37.0
-D ADVERT_LON=145.0 -D ADVERT_LON=145.0
-D ADMIN_PASSWORD="\"password\"" -D ADMIN_PASSWORD='"password"'
; -D MESH_PACKET_LOGGING=1 ; -D MESH_PACKET_LOGGING=1
; -D MESH_DEBUG=1 ; -D MESH_DEBUG=1
; -D CORE_DEBUG_LEVEL=3 ; -D CORE_DEBUG_LEVEL=3
@ -455,7 +456,7 @@ extends = LilyGo_TLora_V2_1_1_6
build_flags = build_flags =
${LilyGo_TLora_V2_1_1_6.build_flags} ${LilyGo_TLora_V2_1_1_6.build_flags}
-D MAX_CONTACTS=100 -D MAX_CONTACTS=100
-D MAX_GROUP_CHANNELS=1 -D MAX_GROUP_CHANNELS=8
; -D MESH_PACKET_LOGGING=1 ; -D MESH_PACKET_LOGGING=1
; -D MESH_DEBUG=1 ; -D MESH_DEBUG=1
build_src_filter = ${LilyGo_TLora_V2_1_1_6.build_src_filter} build_src_filter = ${LilyGo_TLora_V2_1_1_6.build_src_filter}
@ -470,7 +471,7 @@ extends = LilyGo_TLora_V2_1_1_6
build_flags = build_flags =
${LilyGo_TLora_V2_1_1_6.build_flags} ${LilyGo_TLora_V2_1_1_6.build_flags}
-D MAX_CONTACTS=100 -D MAX_CONTACTS=100
-D MAX_GROUP_CHANNELS=1 -D MAX_GROUP_CHANNELS=8
; -D ENABLE_PRIVATE_KEY_IMPORT=1 ; -D ENABLE_PRIVATE_KEY_IMPORT=1
; -D ENABLE_PRIVATE_KEY_EXPORT=1 ; -D ENABLE_PRIVATE_KEY_EXPORT=1
; NOTE: DO NOT ENABLE --> -D MESH_PACKET_LOGGING=1 ; NOTE: DO NOT ENABLE --> -D MESH_PACKET_LOGGING=1
@ -487,7 +488,7 @@ extends = LilyGo_TLora_V2_1_1_6
build_flags = build_flags =
${LilyGo_TLora_V2_1_1_6.build_flags} ${LilyGo_TLora_V2_1_1_6.build_flags}
-D MAX_CONTACTS=100 -D MAX_CONTACTS=100
-D MAX_GROUP_CHANNELS=1 -D MAX_GROUP_CHANNELS=8
-D BLE_PIN_CODE=123456 -D BLE_PIN_CODE=123456
; -D BLE_DEBUG_LOGGING=1 ; -D BLE_DEBUG_LOGGING=1
; -D ENABLE_PRIVATE_KEY_IMPORT=1 ; -D ENABLE_PRIVATE_KEY_IMPORT=1
@ -509,11 +510,11 @@ build_src_filter = ${LilyGo_TLora_V2_1_1_6.build_src_filter}
+<../examples/simple_room_server> +<../examples/simple_room_server>
build_flags = build_flags =
${LilyGo_TLora_V2_1_1_6.build_flags} ${LilyGo_TLora_V2_1_1_6.build_flags}
-D ADVERT_NAME="\"TLora-V2.1-1.6 Room\"" -D ADVERT_NAME='"TLora-V2.1-1.6 Room"'
-D ADVERT_LAT=-37.0 -D ADVERT_LAT=-37.0
-D ADVERT_LON=145.0 -D ADVERT_LON=145.0
-D ADMIN_PASSWORD="\"password\"" -D ADMIN_PASSWORD='"password"'
-D ROOM_PASSWORD="\"hello\"" -D ROOM_PASSWORD='"hello"'
; -D MESH_PACKET_LOGGING=1 ; -D MESH_PACKET_LOGGING=1
; -D MESH_DEBUG=1 ; -D MESH_DEBUG=1
@ -538,6 +539,7 @@ build_flags = ${esp32_base.build_flags}
-D RADIO_CLASS=CustomSX1262 -D RADIO_CLASS=CustomSX1262
-D WRAPPER_CLASS=CustomSX1262Wrapper -D WRAPPER_CLASS=CustomSX1262Wrapper
-D LORA_TX_POWER=22 -D LORA_TX_POWER=22
-D SX126X_RX_BOOSTED_GAIN=1
; === LilyGo T3S3 with SX1262 environments === ; === LilyGo T3S3 with SX1262 environments ===
[env:LilyGo_T3S3_sx1262_Repeater] [env:LilyGo_T3S3_sx1262_Repeater]
@ -546,10 +548,10 @@ build_src_filter = ${LilyGo_T3S3_sx1262.build_src_filter}
+<../examples/simple_repeater/main.cpp> +<../examples/simple_repeater/main.cpp>
build_flags = build_flags =
${LilyGo_T3S3_sx1262.build_flags} ${LilyGo_T3S3_sx1262.build_flags}
-D ADVERT_NAME="\"T3S3-1262 Repeater\"" -D ADVERT_NAME='"T3S3-1262 Repeater"'
-D ADVERT_LAT=-37.0 -D ADVERT_LAT=-37.0
-D ADVERT_LON=145.0 -D ADVERT_LON=145.0
-D ADMIN_PASSWORD="\"password\"" -D ADMIN_PASSWORD='"password"'
; -D MESH_PACKET_LOGGING=1 ; -D MESH_PACKET_LOGGING=1
; -D MESH_DEBUG=1 ; -D MESH_DEBUG=1
@ -572,7 +574,7 @@ extends = LilyGo_T3S3_sx1262
build_flags = build_flags =
${LilyGo_T3S3_sx1262.build_flags} ${LilyGo_T3S3_sx1262.build_flags}
-D MAX_CONTACTS=100 -D MAX_CONTACTS=100
-D MAX_GROUP_CHANNELS=1 -D MAX_GROUP_CHANNELS=8
; -D ENABLE_PRIVATE_KEY_IMPORT=1 ; -D ENABLE_PRIVATE_KEY_IMPORT=1
; -D ENABLE_PRIVATE_KEY_EXPORT=1 ; -D ENABLE_PRIVATE_KEY_EXPORT=1
; NOTE: DO NOT ENABLE --> -D MESH_PACKET_LOGGING=1 ; NOTE: DO NOT ENABLE --> -D MESH_PACKET_LOGGING=1
@ -588,7 +590,7 @@ extends = LilyGo_T3S3_sx1262
build_flags = build_flags =
${LilyGo_T3S3_sx1262.build_flags} ${LilyGo_T3S3_sx1262.build_flags}
-D MAX_CONTACTS=100 -D MAX_CONTACTS=100
-D MAX_GROUP_CHANNELS=1 -D MAX_GROUP_CHANNELS=8
-D BLE_PIN_CODE=123456 -D BLE_PIN_CODE=123456
-D BLE_DEBUG_LOGGING=1 -D BLE_DEBUG_LOGGING=1
; -D ENABLE_PRIVATE_KEY_IMPORT=1 ; -D ENABLE_PRIVATE_KEY_IMPORT=1
@ -618,6 +620,9 @@ build_flags =
-D SX126X_DIO2_AS_RF_SWITCH=true -D SX126X_DIO2_AS_RF_SWITCH=true
-D SX126X_DIO3_TCXO_VOLTAGE=1.8 -D SX126X_DIO3_TCXO_VOLTAGE=1.8
-D SX126X_CURRENT_LIMIT=130.0f ; for best TX power! -D SX126X_CURRENT_LIMIT=130.0f ; for best TX power!
; -D SX126X_RX_BOOSTED_GAIN=1 - DO NOT ENABLE THIS!
; https://wiki.uniteng.com/en/meshtastic/station-g2#impact-of-lora-node-dense-areashigh-noise-environments-on-rf-performance
build_src_filter = ${esp32_base.build_src_filter} build_src_filter = ${esp32_base.build_src_filter}
lib_deps = lib_deps =
${esp32_base.lib_deps} ${esp32_base.lib_deps}
@ -626,10 +631,10 @@ lib_deps =
extends = Station_G2 extends = Station_G2
build_flags = build_flags =
${Station_G2.build_flags} ${Station_G2.build_flags}
-D ADVERT_NAME="\"Station G2 Repeater\"" -D ADVERT_NAME='"Station G2 Repeater"'
-D ADVERT_LAT=-37.0 -D ADVERT_LAT=-37.0
-D ADVERT_LON=145.0 -D ADVERT_LON=145.0
-D ADMIN_PASSWORD="\"password\"" -D ADMIN_PASSWORD='"password"'
-D MESH_PACKET_LOGGING=1 -D MESH_PACKET_LOGGING=1
; -D MESH_DEBUG=1 ; -D MESH_DEBUG=1
build_src_filter = ${Station_G2.build_src_filter} build_src_filter = ${Station_G2.build_src_filter}
@ -641,11 +646,11 @@ build_src_filter = ${Station_G2.build_src_filter}
+<../examples/simple_room_server> +<../examples/simple_room_server>
build_flags = build_flags =
${Station_G2.build_flags} ${Station_G2.build_flags}
-D ADVERT_NAME="\"Station G2 Room\"" -D ADVERT_NAME='"Station G2 Room"'
-D ADVERT_LAT=-37.0 -D ADVERT_LAT=-37.0
-D ADVERT_LON=145.0 -D ADVERT_LON=145.0
-D ADMIN_PASSWORD="\"password\"" -D ADMIN_PASSWORD='"password"'
-D ROOM_PASSWORD="\"hello\"" -D ROOM_PASSWORD='"hello"'
; -D MESH_PACKET_LOGGING=1 ; -D MESH_PACKET_LOGGING=1
; -D MESH_DEBUG=1 ; -D MESH_DEBUG=1
@ -677,6 +682,7 @@ build_flags = ${nrf52840_base.build_flags}
-D WRAPPER_CLASS=CustomSX1262Wrapper -D WRAPPER_CLASS=CustomSX1262Wrapper
-D LORA_TX_POWER=22 -D LORA_TX_POWER=22
-D SX126X_CURRENT_LIMIT=130 -D SX126X_CURRENT_LIMIT=130
-D SX126X_RX_BOOSTED_GAIN=1
[env:RAK_4631_Repeater] [env:RAK_4631_Repeater]
extends = rak4631 extends = rak4631
@ -684,10 +690,10 @@ build_src_filter = ${rak4631.build_src_filter}
+<../examples/simple_repeater/main.cpp> +<../examples/simple_repeater/main.cpp>
build_flags = build_flags =
${rak4631.build_flags} ${rak4631.build_flags}
-D ADVERT_NAME="\"RAK4631 Repeater\"" -D ADVERT_NAME='"RAK4631 Repeater"'
-D ADVERT_LAT=-37.0 -D ADVERT_LAT=-37.0
-D ADVERT_LON=145.0 -D ADVERT_LON=145.0
-D ADMIN_PASSWORD="\"password\"" -D ADMIN_PASSWORD='"password"'
; -D MESH_PACKET_LOGGING=1 ; -D MESH_PACKET_LOGGING=1
; -D MESH_DEBUG=1 ; -D MESH_DEBUG=1
@ -697,11 +703,11 @@ build_src_filter = ${rak4631.build_src_filter}
+<../examples/simple_room_server/main.cpp> +<../examples/simple_room_server/main.cpp>
build_flags = build_flags =
${rak4631.build_flags} ${rak4631.build_flags}
-D ADVERT_NAME="\"Test Room\"" -D ADVERT_NAME='"Test Room"'
-D ADVERT_LAT=-37.0 -D ADVERT_LAT=-37.0
-D ADVERT_LON=145.0 -D ADVERT_LON=145.0
-D ADMIN_PASSWORD="\"password\"" -D ADMIN_PASSWORD='"password"'
-D ROOM_PASSWORD="\"hello\"" -D ROOM_PASSWORD='"hello"'
; -D MESH_PACKET_LOGGING=1 ; -D MESH_PACKET_LOGGING=1
; -D MESH_DEBUG=1 ; -D MESH_DEBUG=1
@ -724,7 +730,7 @@ extends = rak4631
build_flags = build_flags =
${rak4631.build_flags} ${rak4631.build_flags}
-D MAX_CONTACTS=100 -D MAX_CONTACTS=100
-D MAX_GROUP_CHANNELS=1 -D MAX_GROUP_CHANNELS=8
; -D ENABLE_PRIVATE_KEY_IMPORT=1 ; -D ENABLE_PRIVATE_KEY_IMPORT=1
; -D ENABLE_PRIVATE_KEY_EXPORT=1 ; -D ENABLE_PRIVATE_KEY_EXPORT=1
; NOTE: DO NOT ENABLE --> -D MESH_PACKET_LOGGING=1 ; NOTE: DO NOT ENABLE --> -D MESH_PACKET_LOGGING=1
@ -740,7 +746,7 @@ extends = rak4631
build_flags = build_flags =
${rak4631.build_flags} ${rak4631.build_flags}
-D MAX_CONTACTS=100 -D MAX_CONTACTS=100
-D MAX_GROUP_CHANNELS=1 -D MAX_GROUP_CHANNELS=8
-D BLE_PIN_CODE=123456 -D BLE_PIN_CODE=123456
-D BLE_DEBUG_LOGGING=1 -D BLE_DEBUG_LOGGING=1
; -D ENABLE_PRIVATE_KEY_IMPORT=1 ; -D ENABLE_PRIVATE_KEY_IMPORT=1
@ -794,7 +800,7 @@ upload_protocol = nrfutil
extends = t1000-e extends = t1000-e
build_flags = ${t1000-e.build_flags} build_flags = ${t1000-e.build_flags}
-D MAX_CONTACTS=100 -D MAX_CONTACTS=100
-D MAX_GROUP_CHANNELS=1 -D MAX_GROUP_CHANNELS=8
-D BLE_PIN_CODE=123456 -D BLE_PIN_CODE=123456
-D BLE_DEBUG_LOGGING=1 -D BLE_DEBUG_LOGGING=1
-D MESH_PACKET_LOGGING=1 -D MESH_PACKET_LOGGING=1
@ -829,6 +835,7 @@ build_flags = ${nrf52840_t114.build_flags}
-D WRAPPER_CLASS=CustomSX1262Wrapper -D WRAPPER_CLASS=CustomSX1262Wrapper
-D LORA_TX_POWER=22 -D LORA_TX_POWER=22
-D SX126X_CURRENT_LIMIT=130 -D SX126X_CURRENT_LIMIT=130
-D SX126X_RX_BOOSTED_GAIN=1
build_src_filter = ${nrf52840_t114.build_src_filter} build_src_filter = ${nrf52840_t114.build_src_filter}
+<helpers/*.cpp> +<helpers/*.cpp>
+<helpers/nrf52/T114Board.cpp> +<helpers/nrf52/T114Board.cpp>
@ -842,10 +849,10 @@ build_src_filter = ${Heltec_t114.build_src_filter}
+<../examples/simple_repeater/main.cpp> +<../examples/simple_repeater/main.cpp>
build_flags = build_flags =
${Heltec_t114.build_flags} ${Heltec_t114.build_flags}
-D ADVERT_NAME="\"Heltec_T114 Repeater\"" -D ADVERT_NAME='"Heltec_T114 Repeater"'
-D ADVERT_LAT=-37.0 -D ADVERT_LAT=-37.0
-D ADVERT_LON=145.0 -D ADVERT_LON=145.0
-D ADMIN_PASSWORD="\"password\"" -D ADMIN_PASSWORD='"password"'
; -D MESH_PACKET_LOGGING=1 ; -D MESH_PACKET_LOGGING=1
; -D MESH_DEBUG=1 ; -D MESH_DEBUG=1
@ -855,11 +862,11 @@ build_src_filter = ${Heltec_t114.build_src_filter}
+<../examples/simple_room_server> +<../examples/simple_room_server>
build_flags = build_flags =
${Heltec_t114.build_flags} ${Heltec_t114.build_flags}
-D ADVERT_NAME="\"Heltec_T114 Room\"" -D ADVERT_NAME='"Heltec_T114 Room"'
-D ADVERT_LAT=-37.0 -D ADVERT_LAT=-37.0
-D ADVERT_LON=145.0 -D ADVERT_LON=145.0
-D ADMIN_PASSWORD="\"password\"" -D ADMIN_PASSWORD='"password"'
-D ROOM_PASSWORD="\"hello\"" -D ROOM_PASSWORD='"hello"'
; -D MESH_PACKET_LOGGING=1 ; -D MESH_PACKET_LOGGING=1
; -D MESH_DEBUG=1 ; -D MESH_DEBUG=1
@ -868,7 +875,7 @@ extends = Heltec_t114
build_flags = build_flags =
${Heltec_t114.build_flags} ${Heltec_t114.build_flags}
-D MAX_CONTACTS=100 -D MAX_CONTACTS=100
-D MAX_GROUP_CHANNELS=1 -D MAX_GROUP_CHANNELS=8
-D BLE_PIN_CODE=123456 -D BLE_PIN_CODE=123456
-D BLE_DEBUG_LOGGING=1 -D BLE_DEBUG_LOGGING=1
; -D ENABLE_PRIVATE_KEY_IMPORT=1 ; -D ENABLE_PRIVATE_KEY_IMPORT=1
@ -904,6 +911,7 @@ build_flags = ${nrf52840_techo.build_flags}
-D WRAPPER_CLASS=CustomSX1262Wrapper -D WRAPPER_CLASS=CustomSX1262Wrapper
-D LORA_TX_POWER=22 -D LORA_TX_POWER=22
-D SX126X_CURRENT_LIMIT=130 -D SX126X_CURRENT_LIMIT=130
-D SX126X_RX_BOOSTED_GAIN=1
build_src_filter = ${nrf52840_techo.build_src_filter} build_src_filter = ${nrf52840_techo.build_src_filter}
+<helpers/*.cpp> +<helpers/*.cpp>
+<helpers/nrf52/TechoBoard.cpp> +<helpers/nrf52/TechoBoard.cpp>
@ -916,10 +924,10 @@ extends = LilyGo_Techo
build_src_filter = ${LilyGo_Techo.build_src_filter} +<../examples/simple_repeater/main.cpp> build_src_filter = ${LilyGo_Techo.build_src_filter} +<../examples/simple_repeater/main.cpp>
build_flags = build_flags =
${LilyGo_Techo.build_flags} ${LilyGo_Techo.build_flags}
-D ADVERT_NAME="\"T-Echo Repeater\"" -D ADVERT_NAME='"T-Echo Repeater"'
-D ADVERT_LAT=-37.0 -D ADVERT_LAT=-37.0
-D ADVERT_LON=145.0 -D ADVERT_LON=145.0
-D ADMIN_PASSWORD="\"password\"" -D ADMIN_PASSWORD='"password"'
; -D MESH_PACKET_LOGGING=1 ; -D MESH_PACKET_LOGGING=1
; -D MESH_DEBUG=1 ; -D MESH_DEBUG=1
@ -928,10 +936,10 @@ extends = LilyGo_Techo
build_src_filter = ${LilyGo_Techo.build_src_filter} +<../examples/simple_room_server/main.cpp> build_src_filter = ${LilyGo_Techo.build_src_filter} +<../examples/simple_room_server/main.cpp>
build_flags = build_flags =
${LilyGo_Techo.build_flags} ${LilyGo_Techo.build_flags}
-D ADVERT_NAME="\"T-Echo Room\"" -D ADVERT_NAME='"T-Echo Room"'
-D ADVERT_LAT=-37.0 -D ADVERT_LAT=-37.0
-D ADVERT_LON=145.0 -D ADVERT_LON=145.0
-D ADMIN_PASSWORD="\"password\"" -D ADMIN_PASSWORD='"password"'
; -D MESH_PACKET_LOGGING=1 ; -D MESH_PACKET_LOGGING=1
; -D MESH_DEBUG=1 ; -D MESH_DEBUG=1
@ -940,7 +948,7 @@ extends = LilyGo_Techo
build_flags = build_flags =
${LilyGo_Techo.build_flags} ${LilyGo_Techo.build_flags}
-D MAX_CONTACTS=100 -D MAX_CONTACTS=100
-D MAX_GROUP_CHANNELS=1 -D MAX_GROUP_CHANNELS=8
-D BLE_PIN_CODE=123456 -D BLE_PIN_CODE=123456
-D BLE_DEBUG_LOGGING=1 -D BLE_DEBUG_LOGGING=1
; -D ENABLE_PRIVATE_KEY_IMPORT=1 ; -D ENABLE_PRIVATE_KEY_IMPORT=1

View file

@ -203,9 +203,9 @@ void BaseChatMesh::onAckRecv(mesh::Packet* packet, uint32_t ack_crc) {
#ifdef MAX_GROUP_CHANNELS #ifdef MAX_GROUP_CHANNELS
int BaseChatMesh::searchChannelsByHash(const uint8_t* hash, mesh::GroupChannel dest[], int max_matches) { int BaseChatMesh::searchChannelsByHash(const uint8_t* hash, mesh::GroupChannel dest[], int max_matches) {
int n = 0; int n = 0;
for (int i = 0; i < num_channels && n < max_matches; i++) { for (int i = 0; i < MAX_GROUP_CHANNELS && n < max_matches; i++) {
if (channels[i].hash[0] == hash[0]) { if (channels[i].channel.hash[0] == hash[0]) {
dest[n++] = channels[i]; dest[n++] = channels[i].channel;
} }
} }
return n; return n;
@ -588,24 +588,61 @@ bool BaseChatMesh::removeContact(ContactInfo& contact) {
#ifdef MAX_GROUP_CHANNELS #ifdef MAX_GROUP_CHANNELS
#include <base64.hpp> #include <base64.hpp>
mesh::GroupChannel* BaseChatMesh::addChannel(const char* psk_base64) { ChannelDetails* BaseChatMesh::addChannel(const char* name, const char* psk_base64) {
if (num_channels < MAX_GROUP_CHANNELS) { if (num_channels < MAX_GROUP_CHANNELS) {
auto dest = &channels[num_channels]; auto dest = &channels[num_channels];
memset(dest->secret, 0, sizeof(dest->secret)); memset(dest->channel.secret, 0, sizeof(dest->channel.secret));
int len = decode_base64((unsigned char *) psk_base64, strlen(psk_base64), dest->secret); int len = decode_base64((unsigned char *) psk_base64, strlen(psk_base64), dest->channel.secret);
if (len == 32 || len == 16) { if (len == 32 || len == 16) {
mesh::Utils::sha256(dest->hash, sizeof(dest->hash), dest->secret, len); mesh::Utils::sha256(dest->channel.hash, sizeof(dest->channel.hash), dest->channel.secret, len);
StrHelper::strncpy(dest->name, name, sizeof(dest->name));
num_channels++; num_channels++;
return dest; return dest;
} }
} }
return NULL; return NULL;
} }
bool BaseChatMesh::getChannel(int idx, ChannelDetails& dest) {
if (idx >= 0 && idx < MAX_GROUP_CHANNELS) {
dest = channels[idx];
return true;
}
return false;
}
bool BaseChatMesh::setChannel(int idx, const ChannelDetails& src) {
static uint8_t zeroes[] = { 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0 };
if (idx >= 0 && idx < MAX_GROUP_CHANNELS) {
channels[idx] = src;
if (memcmp(&src.channel.secret[16], zeroes, 16) == 0) {
mesh::Utils::sha256(channels[idx].channel.hash, sizeof(channels[idx].channel.hash), src.channel.secret, 16); // 128-bit key
} else {
mesh::Utils::sha256(channels[idx].channel.hash, sizeof(channels[idx].channel.hash), src.channel.secret, 32); // 256-bit key
}
return true;
}
return false;
}
int BaseChatMesh::findChannelIdx(const mesh::GroupChannel& ch) {
for (int i = 0; i < MAX_GROUP_CHANNELS; i++) {
if (memcmp(ch.secret, channels[i].channel.secret, sizeof(ch.secret)) == 0) return i;
}
return -1; // not found
}
#else #else
mesh::GroupChannel* BaseChatMesh::addChannel(const char* psk_base64) { ChannelDetails* BaseChatMesh::addChannel(const char* name, const char* psk_base64) {
return NULL; // not supported return NULL; // not supported
} }
bool BaseChatMesh::getChannel(int idx, ChannelDetails& dest) {
return false;
}
bool BaseChatMesh::setChannel(int idx, const ChannelDetails& src) {
return false;
}
int BaseChatMesh::findChannelIdx(const mesh::GroupChannel& ch) {
return -1; // not found
}
#endif #endif
ContactsIterator BaseChatMesh::startContactsIterator() { ContactsIterator BaseChatMesh::startContactsIterator() {

View file

@ -61,6 +61,11 @@ struct ConnectionInfo {
uint32_t expected_ack; uint32_t expected_ack;
}; };
struct ChannelDetails {
mesh::GroupChannel channel;
char name[32];
};
/** /**
* \brief abstract Mesh class for common 'chat' client * \brief abstract Mesh class for common 'chat' client
*/ */
@ -74,8 +79,8 @@ class BaseChatMesh : public mesh::Mesh {
int matching_peer_indexes[MAX_SEARCH_RESULTS]; int matching_peer_indexes[MAX_SEARCH_RESULTS];
unsigned long txt_send_timeout; unsigned long txt_send_timeout;
#ifdef MAX_GROUP_CHANNELS #ifdef MAX_GROUP_CHANNELS
mesh::GroupChannel channels[MAX_GROUP_CHANNELS]; ChannelDetails channels[MAX_GROUP_CHANNELS];
int num_channels; int num_channels; // only for addChannel()
#endif #endif
mesh::Packet* _pendingLoopback; mesh::Packet* _pendingLoopback;
uint8_t temp_buf[MAX_TRANS_UNIT]; uint8_t temp_buf[MAX_TRANS_UNIT];
@ -89,6 +94,7 @@ protected:
{ {
num_contacts = 0; num_contacts = 0;
#ifdef MAX_GROUP_CHANNELS #ifdef MAX_GROUP_CHANNELS
memset(channels, 0, sizeof(channels));
num_channels = 0; num_channels = 0;
#endif #endif
txt_send_timeout = 0; txt_send_timeout = 0;
@ -151,7 +157,10 @@ public:
bool addContact(const ContactInfo& contact); bool addContact(const ContactInfo& contact);
int getNumContacts() const { return num_contacts; } int getNumContacts() const { return num_contacts; }
ContactsIterator startContactsIterator(); ContactsIterator startContactsIterator();
mesh::GroupChannel* addChannel(const char* psk_base64); ChannelDetails* addChannel(const char* name, const char* psk_base64);
bool getChannel(int idx, ChannelDetails& dest);
bool setChannel(int idx, const ChannelDetails& src);
int findChannelIdx(const mesh::GroupChannel& ch);
void loop(); void loop();
}; };

View file

@ -41,6 +41,7 @@ void CommonCLI::loadPrefs(FILESYSTEM* fs) {
file.read((uint8_t *) &_prefs->reserved2, sizeof(_prefs->reserved2)); // 115 file.read((uint8_t *) &_prefs->reserved2, sizeof(_prefs->reserved2)); // 115
file.read((uint8_t *) &_prefs->bw, sizeof(_prefs->bw)); // 116 file.read((uint8_t *) &_prefs->bw, sizeof(_prefs->bw)); // 116
file.read(pad, 4); // 120 file.read(pad, 4); // 120
file.read((uint8_t *) &_prefs->flood_max, sizeof(_prefs->flood_max)); // 124
// sanitise bad pref values // sanitise bad pref values
_prefs->rx_delay_base = constrain(_prefs->rx_delay_base, 0, 20.0f); _prefs->rx_delay_base = constrain(_prefs->rx_delay_base, 0, 20.0f);
@ -91,6 +92,7 @@ void CommonCLI::savePrefs(FILESYSTEM* fs) {
file.write((uint8_t *) &_prefs->reserved2, sizeof(_prefs->reserved2)); // 115 file.write((uint8_t *) &_prefs->reserved2, sizeof(_prefs->reserved2)); // 115
file.write((uint8_t *) &_prefs->bw, sizeof(_prefs->bw)); // 116 file.write((uint8_t *) &_prefs->bw, sizeof(_prefs->bw)); // 116
file.write(pad, 4); // 120 file.write(pad, 4); // 120
file.write((uint8_t *) &_prefs->flood_max, sizeof(_prefs->flood_max)); // 124
file.close(); file.close();
} }
@ -176,6 +178,8 @@ void CommonCLI::handleCommand(uint32_t sender_timestamp, const char* command, ch
sprintf(reply, "> %s", StrHelper::ftoa(_prefs->rx_delay_base)); sprintf(reply, "> %s", StrHelper::ftoa(_prefs->rx_delay_base));
} else if (memcmp(config, "txdelay", 7) == 0) { } else if (memcmp(config, "txdelay", 7) == 0) {
sprintf(reply, "> %s", StrHelper::ftoa(_prefs->tx_delay_factor)); sprintf(reply, "> %s", StrHelper::ftoa(_prefs->tx_delay_factor));
} else if (memcmp(config, "flood.max", 9) == 0) {
sprintf(reply, "> %d", (uint32_t)_prefs->flood_max);
} else if (memcmp(config, "direct.txdelay", 14) == 0) { } else if (memcmp(config, "direct.txdelay", 14) == 0) {
sprintf(reply, "> %s", StrHelper::ftoa(_prefs->direct_tx_delay_factor)); sprintf(reply, "> %s", StrHelper::ftoa(_prefs->direct_tx_delay_factor));
} else if (memcmp(config, "tx", 2) == 0 && (config[2] == 0 || config[2] == ' ')) { } else if (memcmp(config, "tx", 2) == 0 && (config[2] == 0 || config[2] == ' ')) {
@ -262,6 +266,15 @@ void CommonCLI::handleCommand(uint32_t sender_timestamp, const char* command, ch
} else { } else {
strcpy(reply, "Error, cannot be negative"); strcpy(reply, "Error, cannot be negative");
} }
} else if (memcmp(config, "flood.max ", 10) == 0) {
uint8_t m = atoi(&config[10]);
if (m <= 64) {
_prefs->flood_max = m;
savePrefs();
strcpy(reply, "OK");
} else {
strcpy(reply, "Error, max 64");
}
} else if (memcmp(config, "direct.txdelay ", 15) == 0) { } else if (memcmp(config, "direct.txdelay ", 15) == 0) {
float f = atof(&config[15]); float f = atof(&config[15]);
if (f >= 0) { if (f >= 0) {

View file

@ -23,6 +23,7 @@ struct NodePrefs { // persisted to file
uint8_t reserved1; uint8_t reserved1;
uint8_t reserved2; uint8_t reserved2;
float bw; float bw;
uint8_t flood_max;
}; };
class CommonCLICallbacks { class CommonCLICallbacks {