Merge branch 'ripplebiz:main' into faketec-support

This commit is contained in:
oltaco
2025-03-13 16:22:02 +11:00
committed by GitHub
9 changed files with 264 additions and 111 deletions

View File

@@ -46,6 +46,10 @@
#define OFFLINE_QUEUE_SIZE 16
#endif
#ifndef BLE_NAME_PREFIX
#define BLE_NAME_PREFIX "MeshCore-"
#endif
#include <helpers/BaseChatMesh.h>
#define SEND_TIMEOUT_BASE_MILLIS 500
@@ -124,11 +128,11 @@ static uint32_t _atoi(const char* sp) {
#define FIRMWARE_VER_CODE 2
#ifndef FIRMWARE_BUILD_DATE
#define FIRMWARE_BUILD_DATE "9 Mar 2025"
#define FIRMWARE_BUILD_DATE "13 Mar 2025"
#endif
#ifndef FIRMWARE_VERSION
#define FIRMWARE_VERSION "v1.2.2"
#define FIRMWARE_VERSION "v1.3.0"
#endif
#define CMD_APP_START 1
@@ -161,6 +165,8 @@ static uint32_t _atoi(const char* sp) {
#define CMD_HAS_CONNECTION 28
#define CMD_LOGOUT 29 // 'Disconnect'
#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_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_PRIVATE_KEY 14 // a reply to CMD_EXPORT_PRIVATE_KEY
#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
#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 pending_login;
uint32_t pending_status;
mesh::GroupChannel* _public;
BaseSerialInterface* _serial;
unsigned long last_msg_sent;
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 {
char path[64];
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 {
int i = 0;
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++] = TXT_TYPE_PLAIN;
memcpy(&out_frame[i], &timestamp, 4); i += 4;
@@ -713,7 +772,8 @@ public:
_fs->mkdir("/bl");
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->setSpreadingFactor(_prefs.sf);
@@ -769,7 +829,9 @@ public:
int i = 0;
out_frame[i++] = RESP_CODE_DEVICE_INFO;
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);
strcpy((char *) &out_frame[i], FIRMWARE_BUILD_DATE); i += 12;
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
int i = 1;
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;
memcpy(&msg_timestamp, &cmd_frame[i], 4); i += 4;
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();
} else {
writeErrFrame();
@@ -1161,6 +1225,33 @@ public:
uint8_t* pub_key = &cmd_frame[1];
stopConnection(pub_key);
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 {
writeErrFrame();
MESH_DEBUG_PRINTLN("ERROR: unknown command: %02X", cmd_frame[0]);
@@ -1297,14 +1388,8 @@ void setup() {
the_mesh.begin(InternalFS, trng);
#ifdef BLE_PIN_CODE
char dev_name[32+10];
const char* prefix =
#ifdef BLE_NAME_PREFIX
BLE_NAME_PREFIX;
#else
"MeshCore-";
#endif
sprintf(dev_name, "%s%s", prefix, the_mesh.getNodeName());
char dev_name[32+16];
sprintf(dev_name, "%s%s", BLE_NAME_PREFIX, the_mesh.getNodeName());
serial_interface.begin(dev_name, the_mesh.getBLEPin());
#else
#ifdef RAK_4631
@@ -1321,14 +1406,8 @@ void setup() {
WiFi.begin(WIFI_SSID, WIFI_PWD);
serial_interface.begin(TCP_PORT);
#elif defined(BLE_PIN_CODE)
char dev_name[32+10];
const char* prefix =
#ifdef BLE_NAME_PREFIX
BLE_NAME_PREFIX;
#else
"MeshCore-";
#endif
sprintf(dev_name, "%s%s", prefix, the_mesh.getNodeName());
char dev_name[32+16];
sprintf(dev_name, "%s%s", BLE_NAME_PREFIX, the_mesh.getNodeName());
serial_interface.begin(dev_name, the_mesh.getBLEPin());
#else
serial_interface.begin(Serial);

View File

@@ -22,11 +22,11 @@
/* ------------------------------ Config -------------------------------- */
#ifndef FIRMWARE_BUILD_DATE
#define FIRMWARE_BUILD_DATE "9 Mar 2025"
#define FIRMWARE_BUILD_DATE "13 Mar 2025"
#endif
#ifndef FIRMWARE_VERSION
#define FIRMWARE_VERSION "v1.2.2"
#define FIRMWARE_VERSION "v1.3.0"
#endif
#ifndef LORA_FREQ
@@ -239,7 +239,9 @@ protected:
}
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 {
@@ -540,6 +542,7 @@ public:
_prefs.cr = LORA_CR;
_prefs.tx_power_dbm = LORA_TX_POWER;
_prefs.advert_interval = 1; // default to 2 minutes for NEW installs
_prefs.flood_max = 64;
}
CommonCLI* getCLI() { return &_cli; }

View File

@@ -22,11 +22,11 @@
/* ------------------------------ Config -------------------------------- */
#ifndef FIRMWARE_BUILD_DATE
#define FIRMWARE_BUILD_DATE "9 Mar 2025"
#define FIRMWARE_BUILD_DATE "13 Mar 2025"
#endif
#ifndef FIRMWARE_VERSION
#define FIRMWARE_VERSION "v1.2.2"
#define FIRMWARE_VERSION "v1.3.0"
#endif
#ifndef LORA_FREQ
@@ -308,7 +308,9 @@ protected:
}
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 {
@@ -572,6 +574,7 @@ public:
_prefs.tx_power_dbm = LORA_TX_POWER;
_prefs.disable_fwd = 1;
_prefs.advert_interval = 1; // default to 2 minutes for NEW installs
_prefs.flood_max = 64;
#ifdef ROOM_PASSWORD
StrHelper::strncpy(_prefs.guest_password, ROOM_PASSWORD, sizeof(_prefs.guest_password));
#endif

View File

@@ -111,7 +111,7 @@ class MyMesh : public BaseChatMesh, ContactVisitor {
FILESYSTEM* _fs;
NodePrefs _prefs;
uint32_t expected_ack_crc;
mesh::GroupChannel* _public;
ChannelDetails* _public;
unsigned long last_msg_sent;
ContactInfo* curr_recipient;
char command[512+10];
@@ -341,7 +341,7 @@ public:
}
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() {
@@ -409,7 +409,7 @@ public:
temp[5 + MAX_TEXT_LEN] = 0; // truncate if too long
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) {
sendFlood(pkt);
Serial.println(" Sent.");

View File

@@ -52,10 +52,10 @@ build_src_filter = ${esp32_base.build_src_filter}
extends = 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_LON=145.0
-D ADMIN_PASSWORD="\"password\""
-D ADMIN_PASSWORD='"password"'
; -D MESH_PACKET_LOGGING=1
; -D MESH_DEBUG=1
build_src_filter = ${Heltec_lora32_v2.build_src_filter}
@@ -80,7 +80,7 @@ extends = Heltec_lora32_v2
build_flags =
${Heltec_lora32_v2.build_flags}
-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_DEBUG=1
build_src_filter = ${Heltec_lora32_v2.build_src_filter}
@@ -95,7 +95,7 @@ extends = Heltec_lora32_v2
build_flags =
${Heltec_lora32_v2.build_flags}
-D MAX_CONTACTS=100
-D MAX_GROUP_CHANNELS=1
-D MAX_GROUP_CHANNELS=8
-D BLE_PIN_CODE=123456
-D BLE_DEBUG_LOGGING=1
; -D ENABLE_PRIVATE_KEY_IMPORT=1
@@ -109,7 +109,6 @@ lib_deps =
${Heltec_lora32_v2.lib_deps}
densaugeo/base64 @ ~1.4.0
; ================
[Heltec_lora32_v3]
extends = esp32_base
@@ -127,7 +126,7 @@ build_flags =
-D SX126X_DIO2_AS_RF_SWITCH=true
-D SX126X_DIO3_TCXO_VOLTAGE=1.8
-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}
lib_deps =
${esp32_base.lib_deps}
@@ -138,10 +137,10 @@ extends = Heltec_lora32_v3
build_flags =
${Heltec_lora32_v3.build_flags}
-D DISPLAY_CLASS=SSD1306Display
-D ADVERT_NAME="\"Heltec Repeater\""
-D ADVERT_NAME='"Heltec Repeater"'
-D ADVERT_LAT=-37.0
-D ADVERT_LON=145.0
-D ADMIN_PASSWORD="\"password\""
-D ADMIN_PASSWORD='"password"'
-D MESH_PACKET_LOGGING=1
; -D MESH_DEBUG=1
build_src_filter = ${Heltec_lora32_v3.build_src_filter}
@@ -156,12 +155,12 @@ build_src_filter = ${Heltec_lora32_v3.build_src_filter}
build_flags =
${Heltec_lora32_v3.build_flags}
-D DISPLAY_CLASS=SSD1306Display
-D ADVERT_NAME="\"Heltec Room\""
-D ADVERT_NAME='"Heltec Room"'
-D ADVERT_LAT=-37.0
-D ADVERT_LON=145.0
-D ADMIN_PASSWORD="\"password\""
-D ROOM_PASSWORD="\"hello\""
-D MESH_PACKET_LOGGING=1
-D ADMIN_PASSWORD='"password"'
-D ROOM_PASSWORD='"hello"'
; -D MESH_PACKET_LOGGING=1
; -D MESH_DEBUG=1
[env:Heltec_v3_terminal_chat]
@@ -183,7 +182,7 @@ extends = Heltec_lora32_v3
build_flags =
${Heltec_lora32_v3.build_flags}
-D MAX_CONTACTS=100
-D MAX_GROUP_CHANNELS=1
-D MAX_GROUP_CHANNELS=8
-D DISPLAY_CLASS=SSD1306Display
; -D ENABLE_PRIVATE_KEY_IMPORT=1
; -D ENABLE_PRIVATE_KEY_EXPORT=1
@@ -201,7 +200,7 @@ extends = Heltec_lora32_v3
build_flags =
${Heltec_lora32_v3.build_flags}
-D MAX_CONTACTS=100
-D MAX_GROUP_CHANNELS=1
-D MAX_GROUP_CHANNELS=8
-D DISPLAY_CLASS=SSD1306Display
-D BLE_PIN_CODE=0 ; dynamic, random PIN
-D BLE_DEBUG_LOGGING=1
@@ -222,11 +221,11 @@ extends = Heltec_lora32_v3
build_flags =
${Heltec_lora32_v3.build_flags}
-D MAX_CONTACTS=100
-D MAX_GROUP_CHANNELS=1
-D MAX_GROUP_CHANNELS=8
-D DISPLAY_CLASS=SSD1306Display
-D WIFI_DEBUG_LOGGING=1
-D WIFI_SSID="\"myssid\""
-D WIFI_PWD="\"mypwd\""
-D WIFI_SSID='"myssid"'
-D WIFI_PWD='"mypwd"'
; -D ENABLE_PRIVATE_KEY_IMPORT=1
; -D ENABLE_PRIVATE_KEY_EXPORT=1
; -D MESH_PACKET_LOGGING=1
@@ -243,10 +242,10 @@ lib_deps =
extends = 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_LON=145.0
-D ADMIN_PASSWORD="\"password\""
-D ADMIN_PASSWORD='"password"'
-D MESH_PACKET_LOGGING=1
; -D MESH_DEBUG=1
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>
build_flags =
${Heltec_lora32_v3.build_flags}
-D ADVERT_NAME="\"Heltec Room\""
-D ADVERT_NAME='"Heltec Room"'
-D ADVERT_LAT=-37.0
-D ADVERT_LON=145.0
-D ADMIN_PASSWORD="\"password\""
-D ROOM_PASSWORD="\"hello\""
-D ADMIN_PASSWORD='"password"'
-D ROOM_PASSWORD='"hello"'
; -D MESH_PACKET_LOGGING=1
; -D MESH_DEBUG=1
@@ -271,7 +270,7 @@ extends = Heltec_lora32_v3
build_flags =
${Heltec_lora32_v3.build_flags}
-D MAX_CONTACTS=100
-D MAX_GROUP_CHANNELS=1
-D MAX_GROUP_CHANNELS=8
-D BLE_PIN_CODE=123456
-D BLE_DEBUG_LOGGING=1
; -D ENABLE_PRIVATE_KEY_IMPORT=1
@@ -312,11 +311,12 @@ build_flags =
${Xiao_esp32_C3.build_flags}
-D RADIO_CLASS=CustomSX1262
-D WRAPPER_CLASS=CustomSX1262Wrapper
-D SX126X_RX_BOOSTED_GAIN=1
-D LORA_TX_POWER=22
-D ADVERT_NAME="\"Xiao Repeater\""
-D ADVERT_NAME='"Xiao Repeater"'
-D ADVERT_LAT=-37.0
-D ADVERT_LON=145.0
-D ADMIN_PASSWORD="\"password\""
-D ADMIN_PASSWORD='"password"'
; -D MESH_PACKET_LOGGING=1
; -D MESH_DEBUG=1
@@ -329,10 +329,10 @@ build_flags =
-D RADIO_CLASS=CustomSX1268
-D WRAPPER_CLASS=CustomSX1268Wrapper
-D LORA_TX_POWER=22
-D ADVERT_NAME="\"Xiao Repeater\""
-D ADVERT_NAME='"Xiao Repeater"'
-D ADVERT_LAT=-37.0
-D ADVERT_LON=145.0
-D ADMIN_PASSWORD="\"password\""
-D ADMIN_PASSWORD='"password"'
; -D MESH_PACKET_LOGGING=1
; -D MESH_DEBUG=1
@@ -357,6 +357,7 @@ build_flags = ${esp32_base.build_flags}
-D RADIO_CLASS=CustomSX1262
-D WRAPPER_CLASS=CustomSX1262Wrapper
-D LORA_TX_POWER=22
-D SX126X_RX_BOOSTED_GAIN=1
[env:Xiao_S3_WIO_Repeater]
extends = Xiao_S3_WIO
@@ -364,10 +365,10 @@ build_src_filter = ${Xiao_S3_WIO.build_src_filter}
+<../examples/simple_repeater/main.cpp>
build_flags =
${Xiao_S3_WIO.build_flags}
-D ADVERT_NAME="\"XiaoS3 Repeater\""
-D ADVERT_NAME='"XiaoS3 Repeater"'
-D ADVERT_LAT=-37.0
-D ADVERT_LON=145.0
-D ADMIN_PASSWORD="\"password\""
-D ADMIN_PASSWORD='"password"'
; -D MESH_PACKET_LOGGING=1
; -D MESH_DEBUG=1
@@ -376,7 +377,7 @@ extends = Xiao_S3_WIO
build_flags =
${Xiao_S3_WIO.build_flags}
-D MAX_CONTACTS=100
-D MAX_GROUP_CHANNELS=1
-D MAX_GROUP_CHANNELS=8
; -D MESH_PACKET_LOGGING=1
; -D MESH_DEBUG=1
build_src_filter = ${Xiao_S3_WIO.build_src_filter}
@@ -390,7 +391,7 @@ extends = Xiao_S3_WIO
build_flags =
${Xiao_S3_WIO.build_flags}
-D MAX_CONTACTS=100
-D MAX_GROUP_CHANNELS=1
-D MAX_GROUP_CHANNELS=8
-D BLE_PIN_CODE=123456
; -D BLE_DEBUG_LOGGING=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>
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_LON=145.0
-D ADMIN_PASSWORD="\"password\""
-D ADMIN_PASSWORD='"password"'
; -D MESH_PACKET_LOGGING=1
; -D MESH_DEBUG=1
; -D CORE_DEBUG_LEVEL=3
@@ -455,7 +456,7 @@ extends = LilyGo_TLora_V2_1_1_6
build_flags =
${LilyGo_TLora_V2_1_1_6.build_flags}
-D MAX_CONTACTS=100
-D MAX_GROUP_CHANNELS=1
-D MAX_GROUP_CHANNELS=8
; -D MESH_PACKET_LOGGING=1
; -D MESH_DEBUG=1
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 =
${LilyGo_TLora_V2_1_1_6.build_flags}
-D MAX_CONTACTS=100
-D MAX_GROUP_CHANNELS=1
-D MAX_GROUP_CHANNELS=8
; -D ENABLE_PRIVATE_KEY_IMPORT=1
; -D ENABLE_PRIVATE_KEY_EXPORT=1
; NOTE: DO NOT ENABLE --> -D MESH_PACKET_LOGGING=1
@@ -487,7 +488,7 @@ extends = LilyGo_TLora_V2_1_1_6
build_flags =
${LilyGo_TLora_V2_1_1_6.build_flags}
-D MAX_CONTACTS=100
-D MAX_GROUP_CHANNELS=1
-D MAX_GROUP_CHANNELS=8
-D BLE_PIN_CODE=123456
; -D BLE_DEBUG_LOGGING=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>
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_LON=145.0
-D ADMIN_PASSWORD="\"password\""
-D ROOM_PASSWORD="\"hello\""
-D ADMIN_PASSWORD='"password"'
-D ROOM_PASSWORD='"hello"'
; -D MESH_PACKET_LOGGING=1
; -D MESH_DEBUG=1
@@ -538,6 +539,7 @@ build_flags = ${esp32_base.build_flags}
-D RADIO_CLASS=CustomSX1262
-D WRAPPER_CLASS=CustomSX1262Wrapper
-D LORA_TX_POWER=22
-D SX126X_RX_BOOSTED_GAIN=1
; === LilyGo T3S3 with SX1262 environments ===
[env:LilyGo_T3S3_sx1262_Repeater]
@@ -546,10 +548,10 @@ build_src_filter = ${LilyGo_T3S3_sx1262.build_src_filter}
+<../examples/simple_repeater/main.cpp>
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_LON=145.0
-D ADMIN_PASSWORD="\"password\""
-D ADMIN_PASSWORD='"password"'
; -D MESH_PACKET_LOGGING=1
; -D MESH_DEBUG=1
@@ -572,7 +574,7 @@ extends = LilyGo_T3S3_sx1262
build_flags =
${LilyGo_T3S3_sx1262.build_flags}
-D MAX_CONTACTS=100
-D MAX_GROUP_CHANNELS=1
-D MAX_GROUP_CHANNELS=8
; -D ENABLE_PRIVATE_KEY_IMPORT=1
; -D ENABLE_PRIVATE_KEY_EXPORT=1
; NOTE: DO NOT ENABLE --> -D MESH_PACKET_LOGGING=1
@@ -588,7 +590,7 @@ extends = LilyGo_T3S3_sx1262
build_flags =
${LilyGo_T3S3_sx1262.build_flags}
-D MAX_CONTACTS=100
-D MAX_GROUP_CHANNELS=1
-D MAX_GROUP_CHANNELS=8
-D BLE_PIN_CODE=123456
-D BLE_DEBUG_LOGGING=1
; -D ENABLE_PRIVATE_KEY_IMPORT=1
@@ -618,6 +620,9 @@ build_flags =
-D SX126X_DIO2_AS_RF_SWITCH=true
-D SX126X_DIO3_TCXO_VOLTAGE=1.8
-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}
lib_deps =
${esp32_base.lib_deps}
@@ -626,10 +631,10 @@ lib_deps =
extends = 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_LON=145.0
-D ADMIN_PASSWORD="\"password\""
-D ADMIN_PASSWORD='"password"'
-D MESH_PACKET_LOGGING=1
; -D MESH_DEBUG=1
build_src_filter = ${Station_G2.build_src_filter}
@@ -641,11 +646,11 @@ build_src_filter = ${Station_G2.build_src_filter}
+<../examples/simple_room_server>
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_LON=145.0
-D ADMIN_PASSWORD="\"password\""
-D ROOM_PASSWORD="\"hello\""
-D ADMIN_PASSWORD='"password"'
-D ROOM_PASSWORD='"hello"'
; -D MESH_PACKET_LOGGING=1
; -D MESH_DEBUG=1
@@ -677,6 +682,7 @@ build_flags = ${nrf52840_base.build_flags}
-D WRAPPER_CLASS=CustomSX1262Wrapper
-D LORA_TX_POWER=22
-D SX126X_CURRENT_LIMIT=130
-D SX126X_RX_BOOSTED_GAIN=1
[env:RAK_4631_Repeater]
extends = rak4631
@@ -684,10 +690,10 @@ build_src_filter = ${rak4631.build_src_filter}
+<../examples/simple_repeater/main.cpp>
build_flags =
${rak4631.build_flags}
-D ADVERT_NAME="\"RAK4631 Repeater\""
-D ADVERT_NAME='"RAK4631 Repeater"'
-D ADVERT_LAT=-37.0
-D ADVERT_LON=145.0
-D ADMIN_PASSWORD="\"password\""
-D ADMIN_PASSWORD='"password"'
; -D MESH_PACKET_LOGGING=1
; -D MESH_DEBUG=1
@@ -697,11 +703,11 @@ build_src_filter = ${rak4631.build_src_filter}
+<../examples/simple_room_server/main.cpp>
build_flags =
${rak4631.build_flags}
-D ADVERT_NAME="\"Test Room\""
-D ADVERT_NAME='"Test Room"'
-D ADVERT_LAT=-37.0
-D ADVERT_LON=145.0
-D ADMIN_PASSWORD="\"password\""
-D ROOM_PASSWORD="\"hello\""
-D ADMIN_PASSWORD='"password"'
-D ROOM_PASSWORD='"hello"'
; -D MESH_PACKET_LOGGING=1
; -D MESH_DEBUG=1
@@ -724,7 +730,7 @@ extends = rak4631
build_flags =
${rak4631.build_flags}
-D MAX_CONTACTS=100
-D MAX_GROUP_CHANNELS=1
-D MAX_GROUP_CHANNELS=8
; -D ENABLE_PRIVATE_KEY_IMPORT=1
; -D ENABLE_PRIVATE_KEY_EXPORT=1
; NOTE: DO NOT ENABLE --> -D MESH_PACKET_LOGGING=1
@@ -740,7 +746,7 @@ extends = rak4631
build_flags =
${rak4631.build_flags}
-D MAX_CONTACTS=100
-D MAX_GROUP_CHANNELS=1
-D MAX_GROUP_CHANNELS=8
-D BLE_PIN_CODE=123456
-D BLE_DEBUG_LOGGING=1
; -D ENABLE_PRIVATE_KEY_IMPORT=1
@@ -792,7 +798,7 @@ upload_protocol = nrfutil
extends = t1000-e
build_flags = ${t1000-e.build_flags}
-D MAX_CONTACTS=100
-D MAX_GROUP_CHANNELS=1
-D MAX_GROUP_CHANNELS=8
-D BLE_PIN_CODE=123456
-D BLE_DEBUG_LOGGING=1
-D MESH_PACKET_LOGGING=1
@@ -826,6 +832,7 @@ build_flags = ${nrf52840_t114.build_flags}
-D WRAPPER_CLASS=CustomSX1262Wrapper
-D LORA_TX_POWER=22
-D SX126X_CURRENT_LIMIT=130
-D SX126X_RX_BOOSTED_GAIN=1
build_src_filter = ${nrf52840_t114.build_src_filter}
+<helpers/*.cpp>
+<helpers/nrf52/T114Board.cpp>
@@ -839,10 +846,10 @@ build_src_filter = ${Heltec_t114.build_src_filter}
+<../examples/simple_repeater/main.cpp>
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_LON=145.0
-D ADMIN_PASSWORD="\"password\""
-D ADMIN_PASSWORD='"password"'
; -D MESH_PACKET_LOGGING=1
; -D MESH_DEBUG=1
@@ -852,11 +859,11 @@ build_src_filter = ${Heltec_t114.build_src_filter}
+<../examples/simple_room_server>
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_LON=145.0
-D ADMIN_PASSWORD="\"password\""
-D ROOM_PASSWORD="\"hello\""
-D ADMIN_PASSWORD='"password"'
-D ROOM_PASSWORD='"hello"'
; -D MESH_PACKET_LOGGING=1
; -D MESH_DEBUG=1
@@ -865,7 +872,7 @@ extends = Heltec_t114
build_flags =
${Heltec_t114.build_flags}
-D MAX_CONTACTS=100
-D MAX_GROUP_CHANNELS=1
-D MAX_GROUP_CHANNELS=8
-D BLE_PIN_CODE=123456
-D BLE_DEBUG_LOGGING=1
; -D ENABLE_PRIVATE_KEY_IMPORT=1
@@ -901,6 +908,7 @@ build_flags = ${nrf52840_techo.build_flags}
-D WRAPPER_CLASS=CustomSX1262Wrapper
-D LORA_TX_POWER=22
-D SX126X_CURRENT_LIMIT=130
-D SX126X_RX_BOOSTED_GAIN=1
build_src_filter = ${nrf52840_techo.build_src_filter}
+<helpers/*.cpp>
+<helpers/nrf52/TechoBoard.cpp>
@@ -913,10 +921,10 @@ extends = LilyGo_Techo
build_src_filter = ${LilyGo_Techo.build_src_filter} +<../examples/simple_repeater/main.cpp>
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_LON=145.0
-D ADMIN_PASSWORD="\"password\""
-D ADMIN_PASSWORD='"password"'
; -D MESH_PACKET_LOGGING=1
; -D MESH_DEBUG=1
@@ -925,10 +933,10 @@ extends = LilyGo_Techo
build_src_filter = ${LilyGo_Techo.build_src_filter} +<../examples/simple_room_server/main.cpp>
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_LON=145.0
-D ADMIN_PASSWORD="\"password\""
-D ADMIN_PASSWORD='"password"'
; -D MESH_PACKET_LOGGING=1
; -D MESH_DEBUG=1
@@ -937,7 +945,7 @@ extends = LilyGo_Techo
build_flags =
${LilyGo_Techo.build_flags}
-D MAX_CONTACTS=100
-D MAX_GROUP_CHANNELS=1
-D MAX_GROUP_CHANNELS=8
-D BLE_PIN_CODE=123456
-D BLE_DEBUG_LOGGING=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
int BaseChatMesh::searchChannelsByHash(const uint8_t* hash, mesh::GroupChannel dest[], int max_matches) {
int n = 0;
for (int i = 0; i < num_channels && n < max_matches; i++) {
if (channels[i].hash[0] == hash[0]) {
dest[n++] = channels[i];
for (int i = 0; i < MAX_GROUP_CHANNELS && n < max_matches; i++) {
if (channels[i].channel.hash[0] == hash[0]) {
dest[n++] = channels[i].channel;
}
}
return n;
@@ -588,24 +588,61 @@ bool BaseChatMesh::removeContact(ContactInfo& contact) {
#ifdef MAX_GROUP_CHANNELS
#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) {
auto dest = &channels[num_channels];
memset(dest->secret, 0, sizeof(dest->secret));
int len = decode_base64((unsigned char *) psk_base64, strlen(psk_base64), dest->secret);
memset(dest->channel.secret, 0, sizeof(dest->channel.secret));
int len = decode_base64((unsigned char *) psk_base64, strlen(psk_base64), dest->channel.secret);
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++;
return dest;
}
}
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
mesh::GroupChannel* BaseChatMesh::addChannel(const char* psk_base64) {
ChannelDetails* BaseChatMesh::addChannel(const char* name, const char* psk_base64) {
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
ContactsIterator BaseChatMesh::startContactsIterator() {

View File

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

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->bw, sizeof(_prefs->bw)); // 116
file.read(pad, 4); // 120
file.read((uint8_t *) &_prefs->flood_max, sizeof(_prefs->flood_max)); // 124
// sanitise bad pref values
_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->bw, sizeof(_prefs->bw)); // 116
file.write(pad, 4); // 120
file.write((uint8_t *) &_prefs->flood_max, sizeof(_prefs->flood_max)); // 124
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));
} else if (memcmp(config, "txdelay", 7) == 0) {
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) {
sprintf(reply, "> %s", StrHelper::ftoa(_prefs->direct_tx_delay_factor));
} 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 {
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) {
float f = atof(&config[15]);
if (f >= 0) {

View File

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