Merge branch 'dev'

This commit is contained in:
Scott Powell
2025-03-30 19:18:35 +11:00
46 changed files with 955 additions and 145 deletions

View File

@@ -7,9 +7,6 @@
#include <SPIFFS.h> #include <SPIFFS.h>
#endif #endif
#define RADIOLIB_STATIC_ONLY 1
#include <RadioLib.h>
#include <helpers/RadioLibWrappers.h>
#include <helpers/ArduinoHelpers.h> #include <helpers/ArduinoHelpers.h>
#include <helpers/StaticPoolPacketManager.h> #include <helpers/StaticPoolPacketManager.h>
#include <helpers/SimpleMeshTables.h> #include <helpers/SimpleMeshTables.h>
@@ -89,11 +86,11 @@ static uint32_t _atoi(const char* sp) {
#define FIRMWARE_VER_CODE 3 #define FIRMWARE_VER_CODE 3
#ifndef FIRMWARE_BUILD_DATE #ifndef FIRMWARE_BUILD_DATE
#define FIRMWARE_BUILD_DATE "25 Mar 2025" #define FIRMWARE_BUILD_DATE "30 Mar 2025"
#endif #endif
#ifndef FIRMWARE_VERSION #ifndef FIRMWARE_VERSION
#define FIRMWARE_VERSION "v1.4.1" #define FIRMWARE_VERSION "v1.4.2"
#endif #endif
#define CMD_APP_START 1 #define CMD_APP_START 1
@@ -197,7 +194,6 @@ struct NodePrefs { // persisted to file
class MyMesh : public BaseChatMesh { class MyMesh : public BaseChatMesh {
FILESYSTEM* _fs; FILESYSTEM* _fs;
RADIO_CLASS* _phy;
IdentityStore* _identity_store; IdentityStore* _identity_store;
NodePrefs _prefs; NodePrefs _prefs;
uint32_t pending_login; uint32_t pending_login;
@@ -229,9 +225,9 @@ class MyMesh : public BaseChatMesh {
AckTableEntry expected_ack_table[EXPECTED_ACK_TABLE_SIZE]; // circular table AckTableEntry expected_ack_table[EXPECTED_ACK_TABLE_SIZE]; // circular table
int next_ack_idx; int next_ack_idx;
void loadMainIdentity(mesh::RNG& trng) { void loadMainIdentity() {
if (!_identity_store->load("_main", self_id)) { if (!_identity_store->load("_main", self_id)) {
self_id = mesh::LocalIdentity(&trng); // create new random identity self_id = radio_new_identity(); // create new random identity
saveMainIdentity(self_id); saveMainIdentity(self_id);
} }
} }
@@ -488,7 +484,7 @@ protected:
} }
void logRxRaw(float snr, float rssi, const uint8_t raw[], int len) override { void logRxRaw(float snr, float rssi, const uint8_t raw[], int len) override {
if (_serial->isConnected()) { if (_serial->isConnected() && len+3 <= MAX_FRAME_SIZE) {
int i = 0; int i = 0;
out_frame[i++] = PUSH_CODE_LOG_RX_DATA; out_frame[i++] = PUSH_CODE_LOG_RX_DATA;
out_frame[i++] = (int8_t)(snr * 4); out_frame[i++] = (int8_t)(snr * 4);
@@ -709,8 +705,8 @@ protected:
public: public:
MyMesh(RADIO_CLASS& phy, RadioLibWrapper& rw, mesh::RNG& rng, mesh::RTCClock& rtc, SimpleMeshTables& tables) MyMesh(mesh::Radio& radio, mesh::RNG& rng, mesh::RTCClock& rtc, SimpleMeshTables& tables)
: BaseChatMesh(rw, *new ArduinoMillis(), rng, rtc, *new StaticPoolPacketManager(16), tables), _serial(NULL), _phy(&phy) : BaseChatMesh(radio, *new ArduinoMillis(), rng, rtc, *new StaticPoolPacketManager(16), tables), _serial(NULL)
{ {
_iter_started = false; _iter_started = false;
offline_queue_len = 0; offline_queue_len = 0;
@@ -767,7 +763,7 @@ public:
} }
} }
void begin(FILESYSTEM& fs, mesh::RNG& trng, bool has_display) { void begin(FILESYSTEM& fs, bool has_display) {
_fs = &fs; _fs = &fs;
BaseChatMesh::begin(); BaseChatMesh::begin();
@@ -778,7 +774,7 @@ public:
_identity_store = new IdentityStore(fs, "/identity"); _identity_store = new IdentityStore(fs, "/identity");
#endif #endif
loadMainIdentity(trng); loadMainIdentity();
// load persisted prefs // load persisted prefs
if (_fs->exists("/new_prefs")) { if (_fs->exists("/new_prefs")) {
@@ -793,7 +789,8 @@ public:
if (_prefs.ble_pin == 0) { if (_prefs.ble_pin == 0) {
#ifdef HAS_UI #ifdef HAS_UI
if (has_display) { if (has_display) {
_active_ble_pin = trng.nextInt(100000, 999999); // random pin each session StdRNG rng;
_active_ble_pin = rng.nextInt(100000, 999999); // random pin each session
} else { } else {
_active_ble_pin = BLE_PIN_CODE; // otherwise static pin _active_ble_pin = BLE_PIN_CODE; // otherwise static pin
} }
@@ -814,11 +811,8 @@ public:
addChannel("Public", PUBLIC_GROUP_PSK); // pre-configure Andy's public channel addChannel("Public", PUBLIC_GROUP_PSK); // pre-configure Andy's public channel
loadChannels(); loadChannels();
_phy->setFrequency(_prefs.freq); radio_set_params(_prefs.freq, _prefs.bw, _prefs.sf, _prefs.cr);
_phy->setSpreadingFactor(_prefs.sf); radio_set_tx_power(_prefs.tx_power_dbm);
_phy->setBandwidth(_prefs.bw);
_phy->setCodingRate(_prefs.cr);
_phy->setOutputPower(_prefs.tx_power_dbm);
} }
const char* getNodeName() { return _prefs.node_name; } const char* getNodeName() { return _prefs.node_name; }
@@ -1153,10 +1147,7 @@ public:
_prefs.bw = (float)bw / 1000.0; _prefs.bw = (float)bw / 1000.0;
savePrefs(); savePrefs();
_phy->setFrequency(_prefs.freq); radio_set_params(_prefs.freq, _prefs.bw, _prefs.sf, _prefs.cr);
_phy->setSpreadingFactor(_prefs.sf);
_phy->setBandwidth(_prefs.bw);
_phy->setCodingRate(_prefs.cr);
MESH_DEBUG_PRINTLN("OK: CMD_SET_RADIO_PARAMS: f=%d, bw=%d, sf=%d, cr=%d", freq, bw, (uint32_t)sf, (uint32_t)cr); MESH_DEBUG_PRINTLN("OK: CMD_SET_RADIO_PARAMS: f=%d, bw=%d, sf=%d, cr=%d", freq, bw, (uint32_t)sf, (uint32_t)cr);
writeOKFrame(); writeOKFrame();
@@ -1170,7 +1161,7 @@ public:
} else { } else {
_prefs.tx_power_dbm = cmd_frame[1]; _prefs.tx_power_dbm = cmd_frame[1];
savePrefs(); savePrefs();
_phy->setOutputPower(_prefs.tx_power_dbm); radio_set_tx_power(_prefs.tx_power_dbm);
writeOKFrame(); writeOKFrame();
} }
} else if (cmd_frame[0] == CMD_SET_TUNING_PARAMS) { } else if (cmd_frame[0] == CMD_SET_TUNING_PARAMS) {
@@ -1431,7 +1422,7 @@ public:
StdRNG fast_rng; StdRNG fast_rng;
SimpleMeshTables tables; SimpleMeshTables tables;
MyMesh the_mesh(radio, *new WRAPPER_CLASS(radio, board), fast_rng, *new VolatileRTCClock(), tables); MyMesh the_mesh(radio_driver, fast_rng, *new VolatileRTCClock(), tables); // TODO: test with 'rtc_clock' in target.cpp
void halt() { void halt() {
while (1) ; while (1) ;
@@ -1444,9 +1435,7 @@ void setup() {
if (!radio_init()) { halt(); } if (!radio_init()) { halt(); }
fast_rng.begin(radio.random(0x7FFFFFFF)); fast_rng.begin(radio_get_rng_seed());
RadioNoiseListener trng(radio);
#ifdef HAS_UI #ifdef HAS_UI
DisplayDriver* disp = NULL; DisplayDriver* disp = NULL;
@@ -1459,7 +1448,7 @@ void setup() {
#if defined(NRF52_PLATFORM) #if defined(NRF52_PLATFORM)
InternalFS.begin(); InternalFS.begin();
the_mesh.begin(InternalFS, trng, the_mesh.begin(InternalFS,
#ifdef HAS_UI #ifdef HAS_UI
disp != NULL disp != NULL
#else #else
@@ -1477,7 +1466,7 @@ void setup() {
the_mesh.startInterface(serial_interface); the_mesh.startInterface(serial_interface);
#elif defined(ESP32) #elif defined(ESP32)
SPIFFS.begin(true); SPIFFS.begin(true);
the_mesh.begin(SPIFFS, trng, the_mesh.begin(SPIFFS,
#ifdef HAS_UI #ifdef HAS_UI
disp != NULL disp != NULL
#else #else

View File

@@ -7,13 +7,10 @@
#include <SPIFFS.h> #include <SPIFFS.h>
#endif #endif
#define RADIOLIB_STATIC_ONLY 1
#include <RadioLib.h>
#include <helpers/ArduinoHelpers.h> #include <helpers/ArduinoHelpers.h>
#include <helpers/StaticPoolPacketManager.h> #include <helpers/StaticPoolPacketManager.h>
#include <helpers/SimpleMeshTables.h> #include <helpers/SimpleMeshTables.h>
#include <helpers/IdentityStore.h> #include <helpers/IdentityStore.h>
#include <helpers/AutoDiscoverRTCClock.h>
#include <helpers/AdvertDataHelpers.h> #include <helpers/AdvertDataHelpers.h>
#include <helpers/TxtDataHelpers.h> #include <helpers/TxtDataHelpers.h>
#include <helpers/CommonCLI.h> #include <helpers/CommonCLI.h>
@@ -23,11 +20,11 @@
/* ------------------------------ Config -------------------------------- */ /* ------------------------------ Config -------------------------------- */
#ifndef FIRMWARE_BUILD_DATE #ifndef FIRMWARE_BUILD_DATE
#define FIRMWARE_BUILD_DATE "25 Mar 2025" #define FIRMWARE_BUILD_DATE "30 Mar 2025"
#endif #endif
#ifndef FIRMWARE_VERSION #ifndef FIRMWARE_VERSION
#define FIRMWARE_VERSION "v1.4.1" #define FIRMWARE_VERSION "v1.4.2"
#endif #endif
#ifndef LORA_FREQ #ifndef LORA_FREQ
@@ -69,6 +66,8 @@
static UITask ui_task(display); static UITask ui_task(display);
#endif #endif
#define FIRMWARE_ROLE "repeater"
#define PACKET_LOG_FILE "/packet_log" #define PACKET_LOG_FILE "/packet_log"
/* ------------------------------ Code -------------------------------- */ /* ------------------------------ Code -------------------------------- */
@@ -108,10 +107,7 @@ struct ClientInfo {
#define CLI_REPLY_DELAY_MILLIS 1500 #define CLI_REPLY_DELAY_MILLIS 1500
class MyMesh : public mesh::Mesh, public CommonCLICallbacks { class MyMesh : public mesh::Mesh, public CommonCLICallbacks {
RadioLibWrapper* my_radio;
FILESYSTEM* _fs; FILESYSTEM* _fs;
RADIO_CLASS* _phy;
mesh::MainBoard* _board;
unsigned long next_local_advert, next_flood_advert; unsigned long next_local_advert, next_flood_advert;
bool _logging; bool _logging;
NodePrefs _prefs; NodePrefs _prefs;
@@ -147,9 +143,9 @@ class MyMesh : public mesh::Mesh, public CommonCLICallbacks {
stats.batt_milli_volts = board.getBattMilliVolts(); stats.batt_milli_volts = board.getBattMilliVolts();
stats.curr_tx_queue_len = _mgr->getOutboundCount(); stats.curr_tx_queue_len = _mgr->getOutboundCount();
stats.curr_free_queue_len = _mgr->getFreeCount(); stats.curr_free_queue_len = _mgr->getFreeCount();
stats.last_rssi = (int16_t) my_radio->getLastRSSI(); stats.last_rssi = (int16_t) radio_driver.getLastRSSI();
stats.n_packets_recv = my_radio->getPacketsRecv(); stats.n_packets_recv = radio_driver.getPacketsRecv();
stats.n_packets_sent = my_radio->getPacketsSent(); stats.n_packets_sent = radio_driver.getPacketsSent();
stats.total_air_time_secs = getTotalAirTime() / 1000; stats.total_air_time_secs = getTotalAirTime() / 1000;
stats.total_up_time_secs = _ms->getMillis() / 1000; stats.total_up_time_secs = _ms->getMillis() / 1000;
stats.n_sent_flood = getNumSentFlood(); stats.n_sent_flood = getNumSentFlood();
@@ -157,7 +153,7 @@ class MyMesh : public mesh::Mesh, public CommonCLICallbacks {
stats.n_recv_flood = getNumRecvFlood(); stats.n_recv_flood = getNumRecvFlood();
stats.n_recv_direct = getNumRecvDirect(); stats.n_recv_direct = getNumRecvDirect();
stats.n_full_events = getNumFullEvents(); stats.n_full_events = getNumFullEvents();
stats.last_snr = (int16_t)(my_radio->getLastSNR() * 4); stats.last_snr = (int16_t)(radio_driver.getLastSNR() * 4);
stats.n_direct_dups = ((SimpleMeshTables *)getTables())->getNumDirectDups(); stats.n_direct_dups = ((SimpleMeshTables *)getTables())->getNumDirectDups();
stats.n_flood_dups = ((SimpleMeshTables *)getTables())->getNumFloodDups(); stats.n_flood_dups = ((SimpleMeshTables *)getTables())->getNumFloodDups();
@@ -474,11 +470,10 @@ protected:
} }
public: public:
MyMesh(RADIO_CLASS& phy, mesh::MainBoard& board, RadioLibWrapper& radio, mesh::MillisecondClock& ms, mesh::RNG& rng, mesh::RTCClock& rtc, SimpleMeshTables& tables) MyMesh(mesh::MainBoard& board, mesh::Radio& radio, mesh::MillisecondClock& ms, mesh::RNG& rng, mesh::RTCClock& rtc, mesh::MeshTables& tables)
: mesh::Mesh(radio, ms, rng, rtc, *new StaticPoolPacketManager(32), tables), : mesh::Mesh(radio, ms, rng, rtc, *new StaticPoolPacketManager(32), tables),
_phy(&phy), _board(&board), _cli(board, this, &_prefs, this) _cli(board, this, &_prefs, this)
{ {
my_radio = &radio;
memset(known_clients, 0, sizeof(known_clients)); memset(known_clients, 0, sizeof(known_clients));
next_local_advert = next_flood_advert = 0; next_local_advert = next_flood_advert = 0;
_logging = false; _logging = false;
@@ -510,11 +505,8 @@ public:
// load persisted prefs // load persisted prefs
_cli.loadPrefs(_fs); _cli.loadPrefs(_fs);
_phy->setFrequency(_prefs.freq); radio_set_params(_prefs.freq, _prefs.bw, _prefs.sf, _prefs.cr);
_phy->setSpreadingFactor(_prefs.sf); radio_set_tx_power(_prefs.tx_power_dbm);
_phy->setBandwidth(_prefs.bw);
_phy->setCodingRate(_prefs.cr);
_phy->setOutputPower(_prefs.tx_power_dbm);
updateAdvertTimer(); updateAdvertTimer();
updateFloodAdvertTimer(); updateFloodAdvertTimer();
@@ -522,6 +514,7 @@ public:
const char* getFirmwareVer() override { return FIRMWARE_VERSION; } const char* getFirmwareVer() override { return FIRMWARE_VERSION; }
const char* getBuildDate() override { return FIRMWARE_BUILD_DATE; } const char* getBuildDate() override { return FIRMWARE_BUILD_DATE; }
const char* getRole() override { return FIRMWARE_ROLE; }
const char* getNodeName() { return _prefs.node_name; } const char* getNodeName() { return _prefs.node_name; }
void savePrefs() override { void savePrefs() override {
@@ -582,7 +575,7 @@ public:
} }
void setTxPower(uint8_t power_dbm) override { void setTxPower(uint8_t power_dbm) override {
_phy->setOutputPower(power_dbm); radio_set_tx_power(power_dbm);
} }
void loop() { void loop() {
@@ -609,14 +602,7 @@ public:
StdRNG fast_rng; StdRNG fast_rng;
SimpleMeshTables tables; SimpleMeshTables tables;
#ifdef ESP32 MyMesh the_mesh(board, radio_driver, *new ArduinoMillis(), fast_rng, rtc_clock, tables);
ESP32RTCClock fallback_clock;
#else
VolatileRTCClock fallback_clock;
#endif
AutoDiscoverRTCClock rtc_clock(fallback_clock);
MyMesh the_mesh(radio, board, *new WRAPPER_CLASS(radio, board), *new ArduinoMillis(), fast_rng, rtc_clock, tables);
void halt() { void halt() {
while (1) ; while (1) ;
@@ -629,14 +615,10 @@ void setup() {
delay(1000); delay(1000);
board.begin(); board.begin();
#ifdef ESP32
fallback_clock.begin();
#endif
rtc_clock.begin(Wire);
if (!radio_init()) { halt(); } if (!radio_init()) { halt(); }
fast_rng.begin(radio.random(0x7FFFFFFF)); fast_rng.begin(radio_get_rng_seed());
FILESYSTEM* fs; FILESYSTEM* fs;
#if defined(NRF52_PLATFORM) #if defined(NRF52_PLATFORM)
@@ -652,8 +634,7 @@ void setup() {
#endif #endif
if (!store.load("_main", the_mesh.self_id)) { if (!store.load("_main", the_mesh.self_id)) {
MESH_DEBUG_PRINTLN("Generating new keypair"); MESH_DEBUG_PRINTLN("Generating new keypair");
RadioNoiseListener rng(radio); the_mesh.self_id = radio_new_identity(); // create new random identity
the_mesh.self_id = mesh::LocalIdentity(&rng); // create new random identity
store.save("_main", the_mesh.self_id); store.save("_main", the_mesh.self_id);
} }

View File

@@ -7,13 +7,10 @@
#include <SPIFFS.h> #include <SPIFFS.h>
#endif #endif
#define RADIOLIB_STATIC_ONLY 1
#include <RadioLib.h>
#include <helpers/ArduinoHelpers.h> #include <helpers/ArduinoHelpers.h>
#include <helpers/StaticPoolPacketManager.h> #include <helpers/StaticPoolPacketManager.h>
#include <helpers/SimpleMeshTables.h> #include <helpers/SimpleMeshTables.h>
#include <helpers/IdentityStore.h> #include <helpers/IdentityStore.h>
#include <helpers/AutoDiscoverRTCClock.h>
#include <helpers/AdvertDataHelpers.h> #include <helpers/AdvertDataHelpers.h>
#include <helpers/TxtDataHelpers.h> #include <helpers/TxtDataHelpers.h>
#include <helpers/CommonCLI.h> #include <helpers/CommonCLI.h>
@@ -23,11 +20,11 @@
/* ------------------------------ Config -------------------------------- */ /* ------------------------------ Config -------------------------------- */
#ifndef FIRMWARE_BUILD_DATE #ifndef FIRMWARE_BUILD_DATE
#define FIRMWARE_BUILD_DATE "25 Mar 2025" #define FIRMWARE_BUILD_DATE "30 Mar 2025"
#endif #endif
#ifndef FIRMWARE_VERSION #ifndef FIRMWARE_VERSION
#define FIRMWARE_VERSION "v1.4.1" #define FIRMWARE_VERSION "v1.4.2"
#endif #endif
#ifndef LORA_FREQ #ifndef LORA_FREQ
@@ -77,6 +74,10 @@
static UITask ui_task(display); static UITask ui_task(display);
#endif #endif
#define FIRMWARE_ROLE "room_server"
#define PACKET_LOG_FILE "/packet_log"
/* ------------------------------ Code -------------------------------- */ /* ------------------------------ Code -------------------------------- */
enum RoomPermission { enum RoomPermission {
@@ -141,11 +142,9 @@ struct ServerStats {
}; };
class MyMesh : public mesh::Mesh, public CommonCLICallbacks { class MyMesh : public mesh::Mesh, public CommonCLICallbacks {
RadioLibWrapper* my_radio;
FILESYSTEM* _fs; FILESYSTEM* _fs;
RADIO_CLASS* _phy;
mesh::MainBoard* _board;
unsigned long next_local_advert, next_flood_advert; unsigned long next_local_advert, next_flood_advert;
bool _logging;
NodePrefs _prefs; NodePrefs _prefs;
CommonCLI _cli; CommonCLI _cli;
uint8_t reply_data[MAX_PACKET_PAYLOAD]; uint8_t reply_data[MAX_PACKET_PAYLOAD];
@@ -257,6 +256,14 @@ class MyMesh : public mesh::Mesh, public CommonCLICallbacks {
return createAdvert(self_id, app_data, app_data_len); return createAdvert(self_id, app_data, app_data_len);
} }
File openAppend(const char* fname) {
#if defined(NRF52_PLATFORM)
return _fs->open(fname, FILE_O_WRITE);
#else
return _fs->open(fname, "a", true);
#endif
}
protected: protected:
float getAirtimeBudgetFactor() const override { float getAirtimeBudgetFactor() const override {
return _prefs.airtime_factor; return _prefs.airtime_factor;
@@ -271,6 +278,55 @@ protected:
#endif #endif
} }
void logRx(mesh::Packet* pkt, int len, float score) override {
if (_logging) {
File f = openAppend(PACKET_LOG_FILE);
if (f) {
f.print(getLogDateTime());
f.printf(": RX, len=%d (type=%d, route=%s, payload_len=%d) SNR=%d RSSI=%d score=%d",
len, pkt->getPayloadType(), pkt->isRouteDirect() ? "D" : "F", pkt->payload_len,
(int)_radio->getLastSNR(), (int)_radio->getLastRSSI(), (int)(score*1000));
if (pkt->getPayloadType() == PAYLOAD_TYPE_PATH || pkt->getPayloadType() == PAYLOAD_TYPE_REQ
|| pkt->getPayloadType() == PAYLOAD_TYPE_RESPONSE || pkt->getPayloadType() == PAYLOAD_TYPE_TXT_MSG) {
f.printf(" [%02X -> %02X]\n", (uint32_t)pkt->payload[1], (uint32_t)pkt->payload[0]);
} else {
f.printf("\n");
}
f.close();
}
}
}
void logTx(mesh::Packet* pkt, int len) override {
if (_logging) {
File f = openAppend(PACKET_LOG_FILE);
if (f) {
f.print(getLogDateTime());
f.printf(": TX, len=%d (type=%d, route=%s, payload_len=%d)",
len, pkt->getPayloadType(), pkt->isRouteDirect() ? "D" : "F", pkt->payload_len);
if (pkt->getPayloadType() == PAYLOAD_TYPE_PATH || pkt->getPayloadType() == PAYLOAD_TYPE_REQ
|| pkt->getPayloadType() == PAYLOAD_TYPE_RESPONSE || pkt->getPayloadType() == PAYLOAD_TYPE_TXT_MSG) {
f.printf(" [%02X -> %02X]\n", (uint32_t)pkt->payload[1], (uint32_t)pkt->payload[0]);
} else {
f.printf("\n");
}
f.close();
}
}
}
void logTxFail(mesh::Packet* pkt, int len) override {
if (_logging) {
File f = openAppend(PACKET_LOG_FILE);
if (f) {
f.print(getLogDateTime());
f.printf(": TX FAIL!, len=%d (type=%d, route=%s, payload_len=%d)\n",
len, pkt->getPayloadType(), pkt->isRouteDirect() ? "D" : "F", pkt->payload_len);
f.close();
}
}
}
int calcRxDelay(float score, uint32_t air_time) const override { int calcRxDelay(float score, uint32_t air_time) const override {
if (_prefs.rx_delay_base <= 0.0f) return 0; if (_prefs.rx_delay_base <= 0.0f) return 0;
return (int) ((pow(_prefs.rx_delay_base, 0.85f - score) - 1.0) * air_time); return (int) ((pow(_prefs.rx_delay_base, 0.85f - score) - 1.0) * air_time);
@@ -524,9 +580,9 @@ protected:
stats.batt_milli_volts = board.getBattMilliVolts(); stats.batt_milli_volts = board.getBattMilliVolts();
stats.curr_tx_queue_len = _mgr->getOutboundCount(); stats.curr_tx_queue_len = _mgr->getOutboundCount();
stats.curr_free_queue_len = _mgr->getFreeCount(); stats.curr_free_queue_len = _mgr->getFreeCount();
stats.last_rssi = (int16_t) my_radio->getLastRSSI(); stats.last_rssi = (int16_t) radio_driver.getLastRSSI();
stats.n_packets_recv = my_radio->getPacketsRecv(); stats.n_packets_recv = radio_driver.getPacketsRecv();
stats.n_packets_sent = my_radio->getPacketsSent(); stats.n_packets_sent = radio_driver.getPacketsSent();
stats.total_air_time_secs = getTotalAirTime() / 1000; stats.total_air_time_secs = getTotalAirTime() / 1000;
stats.total_up_time_secs = _ms->getMillis() / 1000; stats.total_up_time_secs = _ms->getMillis() / 1000;
stats.n_sent_flood = getNumSentFlood(); stats.n_sent_flood = getNumSentFlood();
@@ -534,7 +590,7 @@ protected:
stats.n_recv_flood = getNumRecvFlood(); stats.n_recv_flood = getNumRecvFlood();
stats.n_recv_direct = getNumRecvDirect(); stats.n_recv_direct = getNumRecvDirect();
stats.n_full_events = getNumFullEvents(); stats.n_full_events = getNumFullEvents();
stats.last_snr = (int16_t)(my_radio->getLastSNR() * 4); stats.last_snr = (int16_t)(radio_driver.getLastSNR() * 4);
stats.n_direct_dups = ((SimpleMeshTables *)getTables())->getNumDirectDups(); stats.n_direct_dups = ((SimpleMeshTables *)getTables())->getNumDirectDups();
stats.n_flood_dups = ((SimpleMeshTables *)getTables())->getNumFloodDups(); stats.n_flood_dups = ((SimpleMeshTables *)getTables())->getNumFloodDups();
stats.n_posted = _num_posted; stats.n_posted = _num_posted;
@@ -593,12 +649,12 @@ protected:
} }
public: public:
MyMesh(RADIO_CLASS& phy, mesh::MainBoard& board, RadioLibWrapper& radio, mesh::MillisecondClock& ms, mesh::RNG& rng, mesh::RTCClock& rtc, mesh::MeshTables& tables) MyMesh(mesh::MainBoard& board, mesh::Radio& radio, mesh::MillisecondClock& ms, mesh::RNG& rng, mesh::RTCClock& rtc, mesh::MeshTables& tables)
: mesh::Mesh(radio, ms, rng, rtc, *new StaticPoolPacketManager(32), tables), : mesh::Mesh(radio, ms, rng, rtc, *new StaticPoolPacketManager(32), tables),
_phy(&phy), _board(&board), _cli(board, this, &_prefs, this) _cli(board, this, &_prefs, this)
{ {
my_radio = &radio;
next_local_advert = next_flood_advert = 0; next_local_advert = next_flood_advert = 0;
_logging = false;
// defaults // defaults
memset(&_prefs, 0, sizeof(_prefs)); memset(&_prefs, 0, sizeof(_prefs));
@@ -638,17 +694,16 @@ public:
// load persisted prefs // load persisted prefs
_cli.loadPrefs(_fs); _cli.loadPrefs(_fs);
_phy->setFrequency(_prefs.freq); radio_set_params(_prefs.freq, _prefs.bw, _prefs.sf, _prefs.cr);
_phy->setSpreadingFactor(_prefs.sf); radio_set_tx_power(_prefs.tx_power_dbm);
_phy->setBandwidth(_prefs.bw);
_phy->setCodingRate(_prefs.cr);
_phy->setOutputPower(_prefs.tx_power_dbm);
updateAdvertTimer(); updateAdvertTimer();
updateFloodAdvertTimer();
} }
const char* getFirmwareVer() override { return FIRMWARE_VERSION; } const char* getFirmwareVer() override { return FIRMWARE_VERSION; }
const char* getBuildDate() override { return FIRMWARE_BUILD_DATE; } const char* getBuildDate() override { return FIRMWARE_BUILD_DATE; }
const char* getRole() override { return FIRMWARE_ROLE; }
const char* getNodeName() { return _prefs.node_name; } const char* getNodeName() { return _prefs.node_name; }
void savePrefs() override { void savePrefs() override {
@@ -690,12 +745,26 @@ public:
} }
} }
void setLoggingOn(bool enable) override { /* no-op */ } void setLoggingOn(bool enable) override { _logging = enable; }
void eraseLogFile() override { /* no-op */ }
void dumpLogFile() override { /* no-op */ } void eraseLogFile() override {
_fs->remove(PACKET_LOG_FILE);
}
void dumpLogFile() override {
File f = _fs->open(PACKET_LOG_FILE);
if (f) {
while (f.available()) {
int c = f.read();
if (c < 0) break;
Serial.print((char)c);
}
f.close();
}
}
void setTxPower(uint8_t power_dbm) override { void setTxPower(uint8_t power_dbm) override {
_phy->setOutputPower(power_dbm); radio_set_tx_power(power_dbm);
} }
void loop() { void loop() {
@@ -756,15 +825,7 @@ public:
StdRNG fast_rng; StdRNG fast_rng;
SimpleMeshTables tables; SimpleMeshTables tables;
MyMesh the_mesh(board, radio_driver, *new ArduinoMillis(), fast_rng, rtc_clock, tables);
#ifdef ESP32
ESP32RTCClock fallback_clock;
#else
VolatileRTCClock fallback_clock;
#endif
AutoDiscoverRTCClock rtc_clock(fallback_clock);
MyMesh the_mesh(radio, board, *new WRAPPER_CLASS(radio, board), *new ArduinoMillis(), fast_rng, rtc_clock, tables);
void halt() { void halt() {
while (1) ; while (1) ;
@@ -777,14 +838,10 @@ void setup() {
delay(1000); delay(1000);
board.begin(); board.begin();
#ifdef ESP32
fallback_clock.begin();
#endif
rtc_clock.begin(Wire);
if (!radio_init()) { halt(); } if (!radio_init()) { halt(); }
fast_rng.begin(radio.random(0x7FFFFFFF)); fast_rng.begin(radio_get_rng_seed());
FILESYSTEM* fs; FILESYSTEM* fs;
#if defined(NRF52_PLATFORM) #if defined(NRF52_PLATFORM)
@@ -799,8 +856,7 @@ void setup() {
#error "need to define filesystem" #error "need to define filesystem"
#endif #endif
if (!store.load("_main", the_mesh.self_id)) { if (!store.load("_main", the_mesh.self_id)) {
RadioNoiseListener rng(radio); the_mesh.self_id = radio_new_identity(); // create new random identity
the_mesh.self_id = mesh::LocalIdentity(&rng); // create new random identity
store.save("_main", the_mesh.self_id); store.save("_main", the_mesh.self_id);
} }

View File

@@ -7,9 +7,6 @@
#include <SPIFFS.h> #include <SPIFFS.h>
#endif #endif
#define RADIOLIB_STATIC_ONLY 1
#include <RadioLib.h>
#include <helpers/RadioLibWrappers.h>
#include <helpers/ArduinoHelpers.h> #include <helpers/ArduinoHelpers.h>
#include <helpers/StaticPoolPacketManager.h> #include <helpers/StaticPoolPacketManager.h>
#include <helpers/SimpleMeshTables.h> #include <helpers/SimpleMeshTables.h>
@@ -193,6 +190,10 @@ protected:
return 0; // disable rxdelay return 0; // disable rxdelay
} }
bool allowPacketForward(const mesh::Packet* packet) override {
return true;
}
void onDiscoveredContact(ContactInfo& contact, bool is_new) override { void onDiscoveredContact(ContactInfo& contact, bool is_new) override {
// TODO: if not in favs, prompt to add as fav(?) // TODO: if not in favs, prompt to add as fav(?)
@@ -262,8 +263,7 @@ protected:
} }
public: public:
MyMesh(mesh::Radio& radio, StdRNG& rng, mesh::RTCClock& rtc, SimpleMeshTables& tables)
MyMesh(RadioLibWrapper& radio, mesh::RNG& rng, mesh::RTCClock& rtc, SimpleMeshTables& tables)
: BaseChatMesh(radio, *new ArduinoMillis(), rng, rtc, *new StaticPoolPacketManager(16), tables) : BaseChatMesh(radio, *new ArduinoMillis(), rng, rtc, *new StaticPoolPacketManager(16), tables)
{ {
// defaults // defaults
@@ -291,6 +291,14 @@ public:
IdentityStore store(fs, "/identity"); IdentityStore store(fs, "/identity");
#endif #endif
if (!store.load("_main", self_id, _prefs.node_name, sizeof(_prefs.node_name))) { // legacy: node_name was from identity file if (!store.load("_main", self_id, _prefs.node_name, sizeof(_prefs.node_name))) { // legacy: node_name was from identity file
// Need way to get some entropy to seed RNG
Serial.println("Press ENTER to generate key:");
char c = 0;
while (c != '\n') { // wait for ENTER to be pressed
if (Serial.available()) c = Serial.read();
}
((StdRNG *)getRNG())->begin(millis());
self_id = mesh::LocalIdentity(getRNG()); // create new random identity self_id = mesh::LocalIdentity(getRNG()); // create new random identity
store.save("_main", self_id); store.save("_main", self_id);
} }
@@ -325,6 +333,8 @@ public:
Serial.println("===== MeshCore Chat Terminal ====="); Serial.println("===== MeshCore Chat Terminal =====");
Serial.println(); Serial.println();
Serial.printf("WELCOME %s\n", _prefs.node_name); Serial.printf("WELCOME %s\n", _prefs.node_name);
mesh::Utils::printHex(Serial, self_id.pub_key, PUB_KEY_SIZE);
Serial.println();
Serial.println(" (enter 'help' for basic commands)"); Serial.println(" (enter 'help' for basic commands)");
Serial.println(); Serial.println();
} }
@@ -513,7 +523,7 @@ public:
StdRNG fast_rng; StdRNG fast_rng;
SimpleMeshTables tables; SimpleMeshTables tables;
MyMesh the_mesh(*new WRAPPER_CLASS(radio, board), fast_rng, *new VolatileRTCClock(), tables); MyMesh the_mesh(radio_driver, fast_rng, *new VolatileRTCClock(), tables); // TODO: test with 'rtc_clock' in target.cpp
void halt() { void halt() {
while (1) ; while (1) ;
@@ -526,7 +536,7 @@ void setup() {
if (!radio_init()) { halt(); } if (!radio_init()) { halt(); }
fast_rng.begin(radio.random(0x7FFFFFFF)); fast_rng.begin(radio_get_rng_seed());
#if defined(NRF52_PLATFORM) #if defined(NRF52_PLATFORM)
InternalFS.begin(); InternalFS.begin();
@@ -538,12 +548,8 @@ void setup() {
#error "need to define filesystem" #error "need to define filesystem"
#endif #endif
if (LORA_FREQ != the_mesh.getFreqPref()) { radio_set_params(the_mesh.getFreqPref(), LORA_BW, LORA_SF, LORA_CR);
radio.setFrequency(the_mesh.getFreqPref()); radio_set_tx_power(the_mesh.getTxPowerPref());
}
if (LORA_TX_POWER != the_mesh.getTxPowerPref()) {
radio.setOutputPower(the_mesh.getTxPowerPref());
}
the_mesh.showWelcome(); the_mesh.showWelcome();

View File

@@ -29,6 +29,9 @@ int Dispatcher::calcRxDelay(float score, uint32_t air_time) const {
uint32_t Dispatcher::getCADFailRetryDelay() const { uint32_t Dispatcher::getCADFailRetryDelay() const {
return 200; return 200;
} }
uint32_t Dispatcher::getCADFailMaxDuration() const {
return 4000; // 4 seconds
}
void Dispatcher::loop() { void Dispatcher::loop() {
if (outbound) { // waiting for outbound send to be completed if (outbound) { // waiting for outbound send to be completed
@@ -185,9 +188,20 @@ void Dispatcher::checkSend() {
if (_mgr->getOutboundCount() == 0) return; // nothing waiting to send if (_mgr->getOutboundCount() == 0) return; // nothing waiting to send
if (!millisHasNowPassed(next_tx_time)) return; // still in 'radio silence' phase (from airtime budget setting) if (!millisHasNowPassed(next_tx_time)) return; // still in 'radio silence' phase (from airtime budget setting)
if (_radio->isReceiving()) { // LBT - check if radio is currently mid-receive, or if channel activity if (_radio->isReceiving()) { // LBT - check if radio is currently mid-receive, or if channel activity
next_tx_time = futureMillis(getCADFailRetryDelay()); if (cad_busy_start == 0) {
return; cad_busy_start = _ms->getMillis(); // record when CAD busy state started
}
if (_ms->getMillis() - cad_busy_start > getCADFailMaxDuration()) {
MESH_DEBUG_PRINTLN("%s Dispatcher::checkSend(): CAD busy max duration reached!", getLogDateTime());
// channel activity has gone on too long... (Radio might be in a bad state)
// force the pending transmit below...
} else {
next_tx_time = futureMillis(getCADFailRetryDelay());
return;
}
} }
cad_busy_start = 0; // reset busy state
outbound = _mgr->getNextOutbound(_ms->getMillis()); outbound = _mgr->getNextOutbound(_ms->getMillis());
if (outbound) { if (outbound) {

View File

@@ -98,6 +98,7 @@ class Dispatcher {
Packet* outbound; // current outbound packet Packet* outbound; // current outbound packet
unsigned long outbound_expiry, outbound_start, total_air_time; unsigned long outbound_expiry, outbound_start, total_air_time;
unsigned long next_tx_time; unsigned long next_tx_time;
unsigned long cad_busy_start;
uint32_t n_sent_flood, n_sent_direct; uint32_t n_sent_flood, n_sent_direct;
uint32_t n_recv_flood, n_recv_direct; uint32_t n_recv_flood, n_recv_direct;
uint32_t n_full_events; uint32_t n_full_events;
@@ -113,6 +114,7 @@ protected:
: _radio(&radio), _ms(&ms), _mgr(&mgr) : _radio(&radio), _ms(&ms), _mgr(&mgr)
{ {
outbound = NULL; total_air_time = 0; next_tx_time = 0; outbound = NULL; total_air_time = 0; next_tx_time = 0;
cad_busy_start = 0;
} }
virtual DispatcherAction onRecvPacket(Packet* pkt) = 0; virtual DispatcherAction onRecvPacket(Packet* pkt) = 0;
@@ -127,6 +129,7 @@ protected:
virtual float getAirtimeBudgetFactor() const; virtual float getAirtimeBudgetFactor() const;
virtual int calcRxDelay(float score, uint32_t air_time) const; virtual int calcRxDelay(float score, uint32_t air_time) const;
virtual uint32_t getCADFailRetryDelay() const; virtual uint32_t getCADFailRetryDelay() const;
virtual uint32_t getCADFailMaxDuration() const;
public: public:
void begin(); void begin();

View File

@@ -198,6 +198,11 @@ void CommonCLI::handleCommand(uint32_t sender_timestamp, const char* command, ch
sprintf(reply, "> %d", (uint32_t) _prefs->tx_power_dbm); sprintf(reply, "> %d", (uint32_t) _prefs->tx_power_dbm);
} else if (memcmp(config, "freq", 4) == 0) { } else if (memcmp(config, "freq", 4) == 0) {
sprintf(reply, "> %s", StrHelper::ftoa(_prefs->freq)); sprintf(reply, "> %s", StrHelper::ftoa(_prefs->freq));
} else if (memcmp(config, "public.key", 10) == 0) {
strcpy(reply, "> ");
mesh::Utils::toHex(&reply[2], _mesh->self_id.pub_key, PUB_KEY_SIZE);
} else if (memcmp(config, "role", 4) == 0) {
sprintf(reply, "> %s", _callbacks->getRole());
} else { } else {
sprintf(reply, "??: %s", config); sprintf(reply, "??: %s", config);
} }

View File

@@ -31,6 +31,7 @@ public:
virtual void savePrefs() = 0; virtual void savePrefs() = 0;
virtual const char* getFirmwareVer() = 0; virtual const char* getFirmwareVer() = 0;
virtual const char* getBuildDate() = 0; virtual const char* getBuildDate() = 0;
virtual const char* getRole() = 0;
virtual bool formatFileSystem() = 0; virtual bool formatFileSystem() = 0;
virtual void sendSelfAdvertisement(int delay_millis) = 0; virtual void sendSelfAdvertisement(int delay_millis) = 0;
virtual void updateAdvertTimer() = 0; virtual void updateAdvertTimer() = 0;

View File

@@ -3,6 +3,7 @@
#include <RadioLib.h> #include <RadioLib.h>
#define SX126X_IRQ_HEADER_VALID 0b0000010000 // 4 4 valid LoRa header received #define SX126X_IRQ_HEADER_VALID 0b0000010000 // 4 4 valid LoRa header received
#define SX126X_IRQ_PREAMBLE_DETECTED 0x04
class CustomLLCC68 : public LLCC68 { class CustomLLCC68 : public LLCC68 {
public: public:
@@ -10,7 +11,7 @@ class CustomLLCC68 : public LLCC68 {
bool isReceiving() { bool isReceiving() {
uint16_t irq = getIrqFlags(); uint16_t irq = getIrqFlags();
bool hasPreamble = (irq & SX126X_IRQ_HEADER_VALID); bool detected = (irq & SX126X_IRQ_HEADER_VALID) || (irq & SX126X_IRQ_PREAMBLE_DETECTED);
return hasPreamble; return detected;
} }
}; };

View File

@@ -11,7 +11,7 @@ class CustomLR1110 : public LR1110 {
bool isReceiving() { bool isReceiving() {
uint16_t irq = getIrqStatus(); uint16_t irq = getIrqStatus();
bool hasPreamble = ((irq & LR1110_IRQ_HEADER_VALID) && (irq & LR1110_IRQ_HAS_PREAMBLE)); bool detected = ((irq & LR1110_IRQ_HEADER_VALID) || (irq & LR1110_IRQ_HAS_PREAMBLE));
return hasPreamble; return detected;
} }
}; };

View File

@@ -3,6 +3,7 @@
#include <RadioLib.h> #include <RadioLib.h>
#define SX126X_IRQ_HEADER_VALID 0b0000010000 // 4 4 valid LoRa header received #define SX126X_IRQ_HEADER_VALID 0b0000010000 // 4 4 valid LoRa header received
#define SX126X_IRQ_PREAMBLE_DETECTED 0x04
class CustomSX1262 : public SX1262 { class CustomSX1262 : public SX1262 {
public: public:
@@ -10,7 +11,7 @@ class CustomSX1262 : public SX1262 {
bool isReceiving() { bool isReceiving() {
uint16_t irq = getIrqFlags(); uint16_t irq = getIrqFlags();
bool hasPreamble = (irq & SX126X_IRQ_HEADER_VALID); bool detected = (irq & SX126X_IRQ_HEADER_VALID) || (irq & SX126X_IRQ_PREAMBLE_DETECTED);
return hasPreamble; return detected;
} }
}; };

View File

@@ -3,6 +3,7 @@
#include <RadioLib.h> #include <RadioLib.h>
#define SX126X_IRQ_HEADER_VALID 0b0000010000 // 4 4 valid LoRa header received #define SX126X_IRQ_HEADER_VALID 0b0000010000 // 4 4 valid LoRa header received
#define SX126X_IRQ_PREAMBLE_DETECTED 0x04
class CustomSX1268 : public SX1268 { class CustomSX1268 : public SX1268 {
public: public:
@@ -10,7 +11,7 @@ class CustomSX1268 : public SX1268 {
bool isReceiving() { bool isReceiving() {
uint16_t irq = getIrqFlags(); uint16_t irq = getIrqFlags();
bool hasPreamble = (irq & SX126X_IRQ_HEADER_VALID); bool detected = (irq & SX126X_IRQ_HEADER_VALID) || (irq & SX126X_IRQ_PREAMBLE_DETECTED);
return hasPreamble; return detected;
} }
}; };

View File

@@ -34,7 +34,9 @@ public:
#endif #endif
#if defined(PIN_BOARD_SDA) && defined(PIN_BOARD_SCL) #if defined(PIN_BOARD_SDA) && defined(PIN_BOARD_SCL)
#if PIN_BOARD_SDA >= 0 && PIN_BOARD_SCL >= 0
Wire.begin(PIN_BOARD_SDA, PIN_BOARD_SCL); Wire.begin(PIN_BOARD_SDA, PIN_BOARD_SCL);
#endif
#else #else
Wire.begin(); Wire.begin();
#endif #endif

View File

@@ -0,0 +1,103 @@
#include "ESPNOWRadio.h"
#include <esp_now.h>
#include <WiFi.h>
#include <esp_wifi.h>
static uint8_t broadcastAddress[] = {0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF};
static esp_now_peer_info_t peerInfo;
static bool is_send_complete = false;
static esp_err_t last_send_result;
static uint8_t rx_buf[256];
static uint8_t last_rx_len = 0;
// callback when data is sent
static void OnDataSent(const uint8_t *mac_addr, esp_now_send_status_t status) {
is_send_complete = true;
ESPNOW_DEBUG_PRINTLN("Send Status: %d", (int)status);
}
static void OnDataRecv(const uint8_t *mac, const uint8_t *data, int len) {
ESPNOW_DEBUG_PRINTLN("Recv: len = %d", len);
memcpy(rx_buf, data, len);
last_rx_len = len;
}
void ESPNOWRadio::begin() {
// Set device as a Wi-Fi Station
WiFi.mode(WIFI_STA);
// Long Range mode
esp_wifi_set_protocol(WIFI_IF_STA, WIFI_PROTOCOL_LR);
// Init ESP-NOW
if (esp_now_init() != ESP_OK) {
ESPNOW_DEBUG_PRINTLN("Error initializing ESP-NOW");
return;
}
esp_wifi_set_max_tx_power(80); // should be 20dBm
esp_now_register_send_cb(OnDataSent);
esp_now_register_recv_cb(OnDataRecv);
// Register peer
memcpy(peerInfo.peer_addr, broadcastAddress, 6);
peerInfo.channel = 0;
peerInfo.encrypt = false;
// Add peer
if (esp_now_add_peer(&peerInfo) == ESP_OK) {
ESPNOW_DEBUG_PRINTLN("init success");
} else {
// ESPNOW_DEBUG_PRINTLN("Failed to add peer");
}
}
void ESPNOWRadio::setTxPower(uint8_t dbm) {
esp_wifi_set_max_tx_power(dbm * 4);
}
uint32_t ESPNOWRadio::intID() {
uint8_t mac[8];
memset(mac, 0, sizeof(mac));
esp_efuse_mac_get_default(mac);
uint32_t n, m;
memcpy(&n, &mac[0], 4);
memcpy(&m, &mac[4], 4);
return n + m;
}
void ESPNOWRadio::startSendRaw(const uint8_t* bytes, int len) {
// Send message via ESP-NOW
is_send_complete = false;
esp_err_t result = esp_now_send(broadcastAddress, bytes, len);
if (result == ESP_OK) {
ESPNOW_DEBUG_PRINTLN("Send success");
} else {
last_send_result = result;
is_send_complete = true;
ESPNOW_DEBUG_PRINTLN("Send failed: %d", result);
}
}
bool ESPNOWRadio::isSendComplete() {
return is_send_complete;
}
void ESPNOWRadio::onSendFinished() {
}
float ESPNOWRadio::getLastRSSI() const { return 0; }
float ESPNOWRadio::getLastSNR() const { return 0; }
int ESPNOWRadio::recvRaw(uint8_t* bytes, int sz) {
int len = last_rx_len;
if (last_rx_len > 0) {
memcpy(bytes, rx_buf, last_rx_len);
last_rx_len = 0;
}
return len;
}
uint32_t ESPNOWRadio::getEstAirtimeFor(int len_bytes) {
return 4; // Fast AF
}

View File

@@ -0,0 +1,36 @@
#pragma once
#include <Mesh.h>
class ESPNOWRadio : public mesh::Radio {
protected:
uint32_t n_recv, n_sent;
public:
ESPNOWRadio() { n_recv = n_sent = 0; }
void begin() override;
int recvRaw(uint8_t* bytes, int sz) override;
uint32_t getEstAirtimeFor(int len_bytes) override;
void startSendRaw(const uint8_t* bytes, int len) override;
bool isSendComplete() override;
void onSendFinished() override;
uint32_t getPacketsRecv() const { return n_recv; }
uint32_t getPacketsSent() const { return n_sent; }
virtual float getLastRSSI() const override;
virtual float getLastSNR() const override;
float packetScore(float snr, int packet_len) override { return 0; }
uint32_t intID();
void setTxPower(uint8_t dbm);
};
#if ESPNOW_DEBUG_LOGGING && ARDUINO
#include <Arduino.h>
#define ESPNOW_DEBUG_PRINT(F, ...) Serial.printf("ESP-Now: " F, ##__VA_ARGS__)
#define ESPNOW_DEBUG_PRINTLN(F, ...) Serial.printf("ESP-Now: " F "\n", ##__VA_ARGS__)
#else
#define ESPNOW_DEBUG_PRINT(...) {}
#define ESPNOW_DEBUG_PRINTLN(...) {}
#endif

View File

@@ -1,5 +1,5 @@
#include <Arduino.h> #include <Arduino.h>
#include "faketecBoard.h" #include "FaketecBoard.h"
#include <bluefruit.h> #include <bluefruit.h>
#include <Wire.h> #include <Wire.h>

View File

@@ -0,0 +1,83 @@
; ----------- Generic ESP32-C3 ------------
[Generic_ESPNOW]
extends = esp32_base
board = esp32-c3-devkitm-1
;board = esp32-s3-devkitm-1
build_flags =
${esp32_base.build_flags}
-I variants/generic_espnow
; -D ESP32_CPU_FREQ=80
-D PIN_BOARD_SDA=-1
-D PIN_BOARD_SCL=-1
; -D P_LORA_TX_LED=8
-D PIN_USER_BTN=0
; -D ARDUINO_USB_MODE=1
; -D ARDUINO_USB_CDC_ON_BOOT=1
; -D ESPNOW_DEBUG_LOGGING=1
; -D MESH_PACKET_LOGGING=1
; -D MESH_DEBUG=1
build_src_filter = ${esp32_base.build_src_filter}
+<helpers/esp32/ESPNowRadio.cpp>
+<../variants/generic_espnow>
[env:Generic_ESPNOW_terminal_chat]
extends = Generic_ESPNOW
build_flags =
${Generic_ESPNOW.build_flags}
-D MAX_CONTACTS=100
-D MAX_GROUP_CHANNELS=1
build_src_filter = ${Generic_ESPNOW.build_src_filter}
+<../examples/simple_secure_chat/main.cpp>
lib_deps =
${Generic_ESPNOW.lib_deps}
densaugeo/base64 @ ~1.4.0
[env:Generic_ESPNOW_repeatr]
extends = Generic_ESPNOW
build_flags =
${Generic_ESPNOW.build_flags}
-D ADVERT_NAME='"ESPNOW Repeater"'
-D ADVERT_LAT=-37.0
-D ADVERT_LON=145.0
-D ADMIN_PASSWORD='"password"'
build_src_filter = ${Generic_ESPNOW.build_src_filter}
+<../examples/simple_repeater/main.cpp>
lib_deps =
${Generic_ESPNOW.lib_deps}
${esp32_ota.lib_deps}
densaugeo/base64 @ ~1.4.0
[env:Generic_ESPNOW_comp_radio_usb]
extends = Generic_ESPNOW
build_flags =
${Generic_ESPNOW.build_flags}
-D MAX_CONTACTS=100
-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
; NOTE: DO NOT ENABLE --> -D MESH_DEBUG=1
; NOTE: DO NOT ENABLE --> -D ESPNOW_DEBUG_LOGGING=1
build_src_filter = ${Generic_ESPNOW.build_src_filter}
+<../examples/companion_radio/main.cpp>
lib_deps =
${Generic_ESPNOW.lib_deps}
densaugeo/base64 @ ~1.4.0
[env:Generic_ESPNOW_room_svr]
extends = Generic_ESPNOW
build_flags =
${Generic_ESPNOW.build_flags}
-D ADVERT_NAME='"Heltec Room"'
-D ADVERT_LAT=-37.0
-D ADVERT_LON=145.0
-D ADMIN_PASSWORD='"password"'
-D ROOM_PASSWORD='"hello"'
build_src_filter = ${Generic_ESPNOW.build_src_filter}
+<../examples/simple_room_server/main.cpp>
lib_deps =
${Generic_ESPNOW.lib_deps}
${esp32_ota.lib_deps}

View File

@@ -0,0 +1,33 @@
#include <Arduino.h>
#include "target.h"
#include <helpers/ArduinoHelpers.h>
ESP32Board board;
ESPNOWRadio radio_driver;
ESP32RTCClock rtc_clock;
bool radio_init() {
rtc_clock.begin();
// NOTE: radio_driver.begin() is called by Dispatcher::begin(), so not needed here
return true; // success
}
uint32_t radio_get_rng_seed() {
return millis() + radio_driver.intID(); // TODO: where to get some entropy?
}
void radio_set_params(float freq, float bw, uint8_t sf, uint8_t cr) {
// no-op
}
void radio_set_tx_power(uint8_t dbm) {
radio_driver.setTxPower(dbm);
}
mesh::LocalIdentity radio_new_identity() {
StdRNG rng; // TODO: need stronger True-RNG here
return mesh::LocalIdentity(&rng); // create new random identity
}

View File

@@ -0,0 +1,14 @@
#pragma once
#include <helpers/ESP32Board.h>
#include <helpers/esp32/ESPNOWRadio.h>
extern ESP32Board board;
extern ESPNOWRadio radio_driver;
extern ESP32RTCClock rtc_clock;
bool radio_init();
uint32_t radio_get_rng_seed();
void radio_set_params(float freq, float bw, uint8_t sf, uint8_t cr);
void radio_set_tx_power(uint8_t dbm);
mesh::LocalIdentity radio_new_identity();

View File

@@ -10,11 +10,19 @@ HeltecV2Board board;
RADIO_CLASS radio = new Module(P_LORA_NSS, P_LORA_DIO_1, P_LORA_RESET, P_LORA_BUSY); RADIO_CLASS radio = new Module(P_LORA_NSS, P_LORA_DIO_1, P_LORA_RESET, P_LORA_BUSY);
#endif #endif
WRAPPER_CLASS radio_driver(radio, board);
ESP32RTCClock fallback_clock;
AutoDiscoverRTCClock rtc_clock(fallback_clock);
#ifndef LORA_CR #ifndef LORA_CR
#define LORA_CR 5 #define LORA_CR 5
#endif #endif
bool radio_init() { bool radio_init() {
fallback_clock.begin();
rtc_clock.begin(Wire);
#if defined(P_LORA_SCLK) #if defined(P_LORA_SCLK)
spi.begin(P_LORA_SCLK, P_LORA_MISO, P_LORA_MOSI); spi.begin(P_LORA_SCLK, P_LORA_MISO, P_LORA_MOSI);
#endif #endif
@@ -29,3 +37,23 @@ bool radio_init() {
return true; // success return true; // success
} }
uint32_t radio_get_rng_seed() {
return radio.random(0x7FFFFFFF);
}
void radio_set_params(float freq, float bw, uint8_t sf, uint8_t cr) {
radio.setFrequency(freq);
radio.setSpreadingFactor(sf);
radio.setBandwidth(bw);
radio.setCodingRate(cr);
}
void radio_set_tx_power(uint8_t dbm) {
radio.setOutputPower(dbm);
}
mesh::LocalIdentity radio_new_identity() {
RadioNoiseListener rng(radio);
return mesh::LocalIdentity(&rng); // create new random identity
}

View File

@@ -1,9 +1,18 @@
#pragma once #pragma once
#define RADIOLIB_STATIC_ONLY 1
#include <RadioLib.h>
#include <helpers/RadioLibWrappers.h>
#include <helpers/HeltecV2Board.h> #include <helpers/HeltecV2Board.h>
#include <helpers/CustomSX1276Wrapper.h> #include <helpers/CustomSX1276Wrapper.h>
#include <helpers/AutoDiscoverRTCClock.h>
extern HeltecV2Board board; extern HeltecV2Board board;
extern RADIO_CLASS radio; extern WRAPPER_CLASS radio_driver;
extern AutoDiscoverRTCClock rtc_clock;
bool radio_init(); bool radio_init();
uint32_t radio_get_rng_seed();
void radio_set_params(float freq, float bw, uint8_t sf, uint8_t cr);
void radio_set_tx_power(uint8_t dbm);
mesh::LocalIdentity radio_new_identity();

View File

@@ -10,11 +10,19 @@ HeltecV3Board board;
RADIO_CLASS radio = new Module(P_LORA_NSS, P_LORA_DIO_1, P_LORA_RESET, P_LORA_BUSY); RADIO_CLASS radio = new Module(P_LORA_NSS, P_LORA_DIO_1, P_LORA_RESET, P_LORA_BUSY);
#endif #endif
WRAPPER_CLASS radio_driver(radio, board);
ESP32RTCClock fallback_clock;
AutoDiscoverRTCClock rtc_clock(fallback_clock);
#ifndef LORA_CR #ifndef LORA_CR
#define LORA_CR 5 #define LORA_CR 5
#endif #endif
bool radio_init() { bool radio_init() {
fallback_clock.begin();
rtc_clock.begin(Wire);
#ifdef SX126X_DIO3_TCXO_VOLTAGE #ifdef SX126X_DIO3_TCXO_VOLTAGE
float tcxo = SX126X_DIO3_TCXO_VOLTAGE; float tcxo = SX126X_DIO3_TCXO_VOLTAGE;
#else #else
@@ -45,3 +53,23 @@ bool radio_init() {
return true; // success return true; // success
} }
uint32_t radio_get_rng_seed() {
return radio.random(0x7FFFFFFF);
}
void radio_set_params(float freq, float bw, uint8_t sf, uint8_t cr) {
radio.setFrequency(freq);
radio.setSpreadingFactor(sf);
radio.setBandwidth(bw);
radio.setCodingRate(cr);
}
void radio_set_tx_power(uint8_t dbm) {
radio.setOutputPower(dbm);
}
mesh::LocalIdentity radio_new_identity() {
RadioNoiseListener rng(radio);
return mesh::LocalIdentity(&rng); // create new random identity
}

View File

@@ -1,9 +1,18 @@
#pragma once #pragma once
#define RADIOLIB_STATIC_ONLY 1
#include <RadioLib.h>
#include <helpers/RadioLibWrappers.h>
#include <helpers/HeltecV3Board.h> #include <helpers/HeltecV3Board.h>
#include <helpers/CustomSX1262Wrapper.h> #include <helpers/CustomSX1262Wrapper.h>
#include <helpers/AutoDiscoverRTCClock.h>
extern HeltecV3Board board; extern HeltecV3Board board;
extern RADIO_CLASS radio; extern WRAPPER_CLASS radio_driver;
extern AutoDiscoverRTCClock rtc_clock;
bool radio_init(); bool radio_init();
uint32_t radio_get_rng_seed();
void radio_set_params(float freq, float bw, uint8_t sf, uint8_t cr);
void radio_set_tx_power(uint8_t dbm);
mesh::LocalIdentity radio_new_identity();

View File

@@ -10,11 +10,19 @@ ESP32Board board;
RADIO_CLASS radio = new Module(P_LORA_NSS, P_LORA_DIO_1, P_LORA_RESET, P_LORA_BUSY); RADIO_CLASS radio = new Module(P_LORA_NSS, P_LORA_DIO_1, P_LORA_RESET, P_LORA_BUSY);
#endif #endif
WRAPPER_CLASS radio_driver(radio, board);
ESP32RTCClock fallback_clock;
AutoDiscoverRTCClock rtc_clock(fallback_clock);
#ifndef LORA_CR #ifndef LORA_CR
#define LORA_CR 5 #define LORA_CR 5
#endif #endif
bool radio_init() { bool radio_init() {
fallback_clock.begin();
rtc_clock.begin(Wire);
#ifdef SX126X_DIO3_TCXO_VOLTAGE #ifdef SX126X_DIO3_TCXO_VOLTAGE
float tcxo = SX126X_DIO3_TCXO_VOLTAGE; float tcxo = SX126X_DIO3_TCXO_VOLTAGE;
#else #else
@@ -45,3 +53,23 @@ bool radio_init() {
return true; // success return true; // success
} }
uint32_t radio_get_rng_seed() {
return radio.random(0x7FFFFFFF);
}
void radio_set_params(float freq, float bw, uint8_t sf, uint8_t cr) {
radio.setFrequency(freq);
radio.setSpreadingFactor(sf);
radio.setBandwidth(bw);
radio.setCodingRate(cr);
}
void radio_set_tx_power(uint8_t dbm) {
radio.setOutputPower(dbm);
}
mesh::LocalIdentity radio_new_identity() {
RadioNoiseListener rng(radio);
return mesh::LocalIdentity(&rng); // create new random identity
}

View File

@@ -1,9 +1,18 @@
#pragma once #pragma once
#define RADIOLIB_STATIC_ONLY 1
#include <RadioLib.h>
#include <helpers/RadioLibWrappers.h>
#include <helpers/ESP32Board.h> #include <helpers/ESP32Board.h>
#include <helpers/CustomSX1262Wrapper.h> #include <helpers/CustomSX1262Wrapper.h>
#include <helpers/AutoDiscoverRTCClock.h>
extern ESP32Board board; extern ESP32Board board;
extern RADIO_CLASS radio; extern WRAPPER_CLASS radio_driver;
extern AutoDiscoverRTCClock rtc_clock;
bool radio_init(); bool radio_init();
uint32_t radio_get_rng_seed();
void radio_set_params(float freq, float bw, uint8_t sf, uint8_t cr);
void radio_set_tx_power(uint8_t dbm);
mesh::LocalIdentity radio_new_identity();

View File

@@ -10,11 +10,19 @@ TBeamBoard board;
RADIO_CLASS radio = new Module(P_LORA_NSS, P_LORA_DIO_1, P_LORA_RESET, P_LORA_BUSY); RADIO_CLASS radio = new Module(P_LORA_NSS, P_LORA_DIO_1, P_LORA_RESET, P_LORA_BUSY);
#endif #endif
WRAPPER_CLASS radio_driver(radio, board);
ESP32RTCClock fallback_clock;
AutoDiscoverRTCClock rtc_clock(fallback_clock);
#ifndef LORA_CR #ifndef LORA_CR
#define LORA_CR 5 #define LORA_CR 5
#endif #endif
bool radio_init() { bool radio_init() {
fallback_clock.begin();
rtc_clock.begin(Wire);
#if defined(P_LORA_SCLK) #if defined(P_LORA_SCLK)
spi.begin(P_LORA_SCLK, P_LORA_MISO, P_LORA_MOSI); spi.begin(P_LORA_SCLK, P_LORA_MISO, P_LORA_MOSI);
#endif #endif
@@ -29,3 +37,23 @@ bool radio_init() {
return true; // success return true; // success
} }
uint32_t radio_get_rng_seed() {
return radio.random(0x7FFFFFFF);
}
void radio_set_params(float freq, float bw, uint8_t sf, uint8_t cr) {
radio.setFrequency(freq);
radio.setSpreadingFactor(sf);
radio.setBandwidth(bw);
radio.setCodingRate(cr);
}
void radio_set_tx_power(uint8_t dbm) {
radio.setOutputPower(dbm);
}
mesh::LocalIdentity radio_new_identity() {
RadioNoiseListener rng(radio);
return mesh::LocalIdentity(&rng); // create new random identity
}

View File

@@ -1,9 +1,18 @@
#pragma once #pragma once
#define RADIOLIB_STATIC_ONLY 1
#include <RadioLib.h>
#include <helpers/RadioLibWrappers.h>
#include <helpers/TBeamBoard.h> #include <helpers/TBeamBoard.h>
#include <helpers/CustomSX1276Wrapper.h> #include <helpers/CustomSX1276Wrapper.h>
#include <helpers/AutoDiscoverRTCClock.h>
extern TBeamBoard board; extern TBeamBoard board;
extern RADIO_CLASS radio; extern WRAPPER_CLASS radio_driver;
extern AutoDiscoverRTCClock rtc_clock;
bool radio_init(); bool radio_init();
uint32_t radio_get_rng_seed();
void radio_set_params(float freq, float bw, uint8_t sf, uint8_t cr);
void radio_set_tx_power(uint8_t dbm);
mesh::LocalIdentity radio_new_identity();

View File

@@ -6,11 +6,19 @@ LilyGoTLoraBoard board;
static SPIClass spi; static SPIClass spi;
RADIO_CLASS radio = new Module(P_LORA_NSS, P_LORA_DIO_0, P_LORA_RESET, P_LORA_DIO_1, spi); RADIO_CLASS radio = new Module(P_LORA_NSS, P_LORA_DIO_0, P_LORA_RESET, P_LORA_DIO_1, spi);
WRAPPER_CLASS radio_driver(radio, board);
ESP32RTCClock fallback_clock;
AutoDiscoverRTCClock rtc_clock(fallback_clock);
#ifndef LORA_CR #ifndef LORA_CR
#define LORA_CR 5 #define LORA_CR 5
#endif #endif
bool radio_init() { bool radio_init() {
fallback_clock.begin();
rtc_clock.begin(Wire);
spi.begin(P_LORA_SCLK, P_LORA_MISO, P_LORA_MOSI); spi.begin(P_LORA_SCLK, P_LORA_MISO, P_LORA_MOSI);
int status = radio.begin(LORA_FREQ, LORA_BW, LORA_SF, LORA_CR, RADIOLIB_SX126X_SYNC_WORD_PRIVATE, LORA_TX_POWER, 8); int status = radio.begin(LORA_FREQ, LORA_BW, LORA_SF, LORA_CR, RADIOLIB_SX126X_SYNC_WORD_PRIVATE, LORA_TX_POWER, 8);
if (status != RADIOLIB_ERR_NONE) { if (status != RADIOLIB_ERR_NONE) {
@@ -23,3 +31,23 @@ bool radio_init() {
return true; // success return true; // success
} }
uint32_t radio_get_rng_seed() {
return radio.random(0x7FFFFFFF);
}
void radio_set_params(float freq, float bw, uint8_t sf, uint8_t cr) {
radio.setFrequency(freq);
radio.setSpreadingFactor(sf);
radio.setBandwidth(bw);
radio.setCodingRate(cr);
}
void radio_set_tx_power(uint8_t dbm) {
radio.setOutputPower(dbm);
}
mesh::LocalIdentity radio_new_identity() {
RadioNoiseListener rng(radio);
return mesh::LocalIdentity(&rng); // create new random identity
}

View File

@@ -1,9 +1,18 @@
#pragma once #pragma once
#define RADIOLIB_STATIC_ONLY 1
#include <RadioLib.h>
#include <helpers/RadioLibWrappers.h>
#include <helpers/LilyGoTLoraBoard.h> #include <helpers/LilyGoTLoraBoard.h>
#include <helpers/CustomSX1276Wrapper.h> #include <helpers/CustomSX1276Wrapper.h>
#include <helpers/AutoDiscoverRTCClock.h>
extern LilyGoTLoraBoard board; extern LilyGoTLoraBoard board;
extern RADIO_CLASS radio; extern WRAPPER_CLASS radio_driver;
extern AutoDiscoverRTCClock rtc_clock;
bool radio_init(); bool radio_init();
uint32_t radio_get_rng_seed();
void radio_set_params(float freq, float bw, uint8_t sf, uint8_t cr);
void radio_set_tx_power(uint8_t dbm);
mesh::LocalIdentity radio_new_identity();

View File

@@ -1,15 +1,23 @@
#include <Arduino.h> #include <Arduino.h>
#include "target.h" #include "target.h"
#include <helpers/ArduinoHelpers.h>
FaketecBoard board; FaketecBoard board;
RADIO_CLASS radio = new Module(P_LORA_NSS, P_LORA_DIO_1, P_LORA_RESET, P_LORA_BUSY, SPI); RADIO_CLASS radio = new Module(P_LORA_NSS, P_LORA_DIO_1, P_LORA_RESET, P_LORA_BUSY, SPI);
WRAPPER_CLASS radio_driver(radio, board);
VolatileRTCClock fallback_clock;
AutoDiscoverRTCClock rtc_clock(fallback_clock);
#ifndef LORA_CR #ifndef LORA_CR
#define LORA_CR 5 #define LORA_CR 5
#endif #endif
bool radio_init() { bool radio_init() {
rtc_clock.begin(Wire);
#ifdef SX126X_DIO3_TCXO_VOLTAGE #ifdef SX126X_DIO3_TCXO_VOLTAGE
float tcxo = SX126X_DIO3_TCXO_VOLTAGE; float tcxo = SX126X_DIO3_TCXO_VOLTAGE;
#else #else
@@ -44,3 +52,23 @@ bool radio_init() {
return true; // success return true; // success
} }
uint32_t radio_get_rng_seed() {
return radio.random(0x7FFFFFFF);
}
void radio_set_params(float freq, float bw, uint8_t sf, uint8_t cr) {
radio.setFrequency(freq);
radio.setSpreadingFactor(sf);
radio.setBandwidth(bw);
radio.setCodingRate(cr);
}
void radio_set_tx_power(uint8_t dbm) {
radio.setOutputPower(dbm);
}
mesh::LocalIdentity radio_new_identity() {
RadioNoiseListener rng(radio);
return mesh::LocalIdentity(&rng); // create new random identity
}

View File

@@ -1,10 +1,19 @@
#pragma once #pragma once
#define RADIOLIB_STATIC_ONLY 1
#include <RadioLib.h>
#include <helpers/RadioLibWrappers.h>
#include <helpers/nrf52/FaketecBoard.h> #include <helpers/nrf52/FaketecBoard.h>
#include <helpers/CustomSX1262Wrapper.h> #include <helpers/CustomSX1262Wrapper.h>
#include <helpers/CustomLLCC68Wrapper.h> #include <helpers/CustomLLCC68Wrapper.h>
#include <helpers/AutoDiscoverRTCClock.h>
extern FaketecBoard board; extern FaketecBoard board;
extern RADIO_CLASS radio; extern WRAPPER_CLASS radio_driver;
extern AutoDiscoverRTCClock rtc_clock;
bool radio_init(); bool radio_init();
uint32_t radio_get_rng_seed();
void radio_set_params(float freq, float bw, uint8_t sf, uint8_t cr);
void radio_set_tx_power(uint8_t dbm);
mesh::LocalIdentity radio_new_identity();

View File

@@ -1,15 +1,23 @@
#include <Arduino.h> #include <Arduino.h>
#include "target.h" #include "target.h"
#include <helpers/ArduinoHelpers.h>
RAK4631Board board; RAK4631Board board;
RADIO_CLASS radio = new Module(P_LORA_NSS, P_LORA_DIO_1, P_LORA_RESET, P_LORA_BUSY, SPI); RADIO_CLASS radio = new Module(P_LORA_NSS, P_LORA_DIO_1, P_LORA_RESET, P_LORA_BUSY, SPI);
WRAPPER_CLASS radio_driver(radio, board);
VolatileRTCClock fallback_clock;
AutoDiscoverRTCClock rtc_clock(fallback_clock);
#ifndef LORA_CR #ifndef LORA_CR
#define LORA_CR 5 #define LORA_CR 5
#endif #endif
bool radio_init() { bool radio_init() {
rtc_clock.begin(Wire);
#ifdef SX126X_DIO3_TCXO_VOLTAGE #ifdef SX126X_DIO3_TCXO_VOLTAGE
float tcxo = SX126X_DIO3_TCXO_VOLTAGE; float tcxo = SX126X_DIO3_TCXO_VOLTAGE;
#else #else
@@ -39,3 +47,23 @@ bool radio_init() {
return true; // success return true; // success
} }
uint32_t radio_get_rng_seed() {
return radio.random(0x7FFFFFFF);
}
void radio_set_params(float freq, float bw, uint8_t sf, uint8_t cr) {
radio.setFrequency(freq);
radio.setSpreadingFactor(sf);
radio.setBandwidth(bw);
radio.setCodingRate(cr);
}
void radio_set_tx_power(uint8_t dbm) {
radio.setOutputPower(dbm);
}
mesh::LocalIdentity radio_new_identity() {
RadioNoiseListener rng(radio);
return mesh::LocalIdentity(&rng); // create new random identity
}

View File

@@ -1,9 +1,18 @@
#pragma once #pragma once
#define RADIOLIB_STATIC_ONLY 1
#include <RadioLib.h>
#include <helpers/RadioLibWrappers.h>
#include <helpers/nrf52/RAK4631Board.h> #include <helpers/nrf52/RAK4631Board.h>
#include <helpers/CustomSX1262Wrapper.h> #include <helpers/CustomSX1262Wrapper.h>
#include <helpers/AutoDiscoverRTCClock.h>
extern RAK4631Board board; extern RAK4631Board board;
extern RADIO_CLASS radio; extern WRAPPER_CLASS radio_driver;
extern AutoDiscoverRTCClock rtc_clock;
bool radio_init(); bool radio_init();
uint32_t radio_get_rng_seed();
void radio_set_params(float freq, float bw, uint8_t sf, uint8_t cr);
void radio_set_tx_power(uint8_t dbm);
mesh::LocalIdentity radio_new_identity();

View File

@@ -10,11 +10,19 @@ StationG2Board board;
RADIO_CLASS radio = new Module(P_LORA_NSS, P_LORA_DIO_1, P_LORA_RESET, P_LORA_BUSY); RADIO_CLASS radio = new Module(P_LORA_NSS, P_LORA_DIO_1, P_LORA_RESET, P_LORA_BUSY);
#endif #endif
WRAPPER_CLASS radio_driver(radio, board);
ESP32RTCClock fallback_clock;
AutoDiscoverRTCClock rtc_clock(fallback_clock);
#ifndef LORA_CR #ifndef LORA_CR
#define LORA_CR 5 #define LORA_CR 5
#endif #endif
bool radio_init() { bool radio_init() {
fallback_clock.begin();
rtc_clock.begin(Wire);
#ifdef SX126X_DIO3_TCXO_VOLTAGE #ifdef SX126X_DIO3_TCXO_VOLTAGE
float tcxo = SX126X_DIO3_TCXO_VOLTAGE; float tcxo = SX126X_DIO3_TCXO_VOLTAGE;
#else #else
@@ -45,3 +53,23 @@ bool radio_init() {
return true; // success return true; // success
} }
uint32_t radio_get_rng_seed() {
return radio.random(0x7FFFFFFF);
}
void radio_set_params(float freq, float bw, uint8_t sf, uint8_t cr) {
radio.setFrequency(freq);
radio.setSpreadingFactor(sf);
radio.setBandwidth(bw);
radio.setCodingRate(cr);
}
void radio_set_tx_power(uint8_t dbm) {
radio.setOutputPower(dbm);
}
mesh::LocalIdentity radio_new_identity() {
RadioNoiseListener rng(radio);
return mesh::LocalIdentity(&rng); // create new random identity
}

View File

@@ -1,9 +1,18 @@
#pragma once #pragma once
#define RADIOLIB_STATIC_ONLY 1
#include <RadioLib.h>
#include <helpers/RadioLibWrappers.h>
#include <helpers/StationG2Board.h> #include <helpers/StationG2Board.h>
#include <helpers/CustomSX1262Wrapper.h> #include <helpers/CustomSX1262Wrapper.h>
#include <helpers/AutoDiscoverRTCClock.h>
extern StationG2Board board; extern StationG2Board board;
extern RADIO_CLASS radio; extern WRAPPER_CLASS radio_driver;
extern AutoDiscoverRTCClock rtc_clock;
bool radio_init(); bool radio_init();
uint32_t radio_get_rng_seed();
void radio_set_params(float freq, float bw, uint8_t sf, uint8_t cr);
void radio_set_tx_power(uint8_t dbm);
mesh::LocalIdentity radio_new_identity();

View File

@@ -1,10 +1,16 @@
#include <Arduino.h> #include <Arduino.h>
#include "target.h" #include "target.h"
#include <helpers/ArduinoHelpers.h>
T1000eBoard board; T1000eBoard board;
RADIO_CLASS radio = new Module(P_LORA_NSS, P_LORA_DIO_1, P_LORA_RESET, P_LORA_BUSY, SPI); RADIO_CLASS radio = new Module(P_LORA_NSS, P_LORA_DIO_1, P_LORA_RESET, P_LORA_BUSY, SPI);
WRAPPER_CLASS radio_driver(radio, board);
VolatileRTCClock fallback_clock;
AutoDiscoverRTCClock rtc_clock(fallback_clock);
#ifndef LORA_CR #ifndef LORA_CR
#define LORA_CR 5 #define LORA_CR 5
#endif #endif
@@ -32,6 +38,8 @@ static const Module::RfSwitchMode_t rfswitch_table[] = {
#endif #endif
bool radio_init() { bool radio_init() {
rtc_clock.begin(Wire);
#ifdef LR11X0_DIO3_TCXO_VOLTAGE #ifdef LR11X0_DIO3_TCXO_VOLTAGE
float tcxo = LR11X0_DIO3_TCXO_VOLTAGE; float tcxo = LR11X0_DIO3_TCXO_VOLTAGE;
#else #else
@@ -58,3 +66,23 @@ bool radio_init() {
return true; // success return true; // success
} }
uint32_t radio_get_rng_seed() {
return radio.random(0x7FFFFFFF);
}
void radio_set_params(float freq, float bw, uint8_t sf, uint8_t cr) {
radio.setFrequency(freq);
radio.setSpreadingFactor(sf);
radio.setBandwidth(bw);
radio.setCodingRate(cr);
}
void radio_set_tx_power(uint8_t dbm) {
radio.setOutputPower(dbm);
}
mesh::LocalIdentity radio_new_identity() {
RadioNoiseListener rng(radio);
return mesh::LocalIdentity(&rng); // create new random identity
}

View File

@@ -1,9 +1,18 @@
#pragma once #pragma once
#define RADIOLIB_STATIC_ONLY 1
#include <RadioLib.h>
#include <helpers/RadioLibWrappers.h>
#include <helpers/nrf52/T1000eBoard.h> #include <helpers/nrf52/T1000eBoard.h>
#include <helpers/CustomLR1110Wrapper.h> #include <helpers/CustomLR1110Wrapper.h>
#include <helpers/AutoDiscoverRTCClock.h>
extern T1000eBoard board; extern T1000eBoard board;
extern RADIO_CLASS radio; extern WRAPPER_CLASS radio_driver;
extern AutoDiscoverRTCClock rtc_clock;
bool radio_init(); bool radio_init();
uint32_t radio_get_rng_seed();
void radio_set_params(float freq, float bw, uint8_t sf, uint8_t cr);
void radio_set_tx_power(uint8_t dbm);
mesh::LocalIdentity radio_new_identity();

View File

@@ -1,15 +1,23 @@
#include <Arduino.h> #include <Arduino.h>
#include "target.h" #include "target.h"
#include <helpers/ArduinoHelpers.h>
T114Board board; T114Board board;
RADIO_CLASS radio = new Module(P_LORA_NSS, P_LORA_DIO_1, P_LORA_RESET, P_LORA_BUSY, SPI); RADIO_CLASS radio = new Module(P_LORA_NSS, P_LORA_DIO_1, P_LORA_RESET, P_LORA_BUSY, SPI);
WRAPPER_CLASS radio_driver(radio, board);
VolatileRTCClock fallback_clock;
AutoDiscoverRTCClock rtc_clock(fallback_clock);
#ifndef LORA_CR #ifndef LORA_CR
#define LORA_CR 5 #define LORA_CR 5
#endif #endif
bool radio_init() { bool radio_init() {
rtc_clock.begin(Wire);
#ifdef SX126X_DIO3_TCXO_VOLTAGE #ifdef SX126X_DIO3_TCXO_VOLTAGE
float tcxo = SX126X_DIO3_TCXO_VOLTAGE; float tcxo = SX126X_DIO3_TCXO_VOLTAGE;
#else #else
@@ -39,3 +47,23 @@ bool radio_init() {
return true; // success return true; // success
} }
uint32_t radio_get_rng_seed() {
return radio.random(0x7FFFFFFF);
}
void radio_set_params(float freq, float bw, uint8_t sf, uint8_t cr) {
radio.setFrequency(freq);
radio.setSpreadingFactor(sf);
radio.setBandwidth(bw);
radio.setCodingRate(cr);
}
void radio_set_tx_power(uint8_t dbm) {
radio.setOutputPower(dbm);
}
mesh::LocalIdentity radio_new_identity() {
RadioNoiseListener rng(radio);
return mesh::LocalIdentity(&rng); // create new random identity
}

View File

@@ -1,9 +1,18 @@
#pragma once #pragma once
#define RADIOLIB_STATIC_ONLY 1
#include <RadioLib.h>
#include <helpers/RadioLibWrappers.h>
#include <helpers/nrf52/T114Board.h> #include <helpers/nrf52/T114Board.h>
#include <helpers/CustomSX1262Wrapper.h> #include <helpers/CustomSX1262Wrapper.h>
#include <helpers/AutoDiscoverRTCClock.h>
extern T114Board board; extern T114Board board;
extern RADIO_CLASS radio; extern WRAPPER_CLASS radio_driver;
extern AutoDiscoverRTCClock rtc_clock;
bool radio_init(); bool radio_init();
uint32_t radio_get_rng_seed();
void radio_set_params(float freq, float bw, uint8_t sf, uint8_t cr);
void radio_set_tx_power(uint8_t dbm);
mesh::LocalIdentity radio_new_identity();

View File

@@ -1,15 +1,23 @@
#include <Arduino.h> #include <Arduino.h>
#include "target.h" #include "target.h"
#include <helpers/ArduinoHelpers.h>
TechoBoard board; TechoBoard board;
RADIO_CLASS radio = new Module(P_LORA_NSS, P_LORA_DIO_1, P_LORA_RESET, P_LORA_BUSY, SPI); RADIO_CLASS radio = new Module(P_LORA_NSS, P_LORA_DIO_1, P_LORA_RESET, P_LORA_BUSY, SPI);
WRAPPER_CLASS radio_driver(radio, board);
VolatileRTCClock fallback_clock;
AutoDiscoverRTCClock rtc_clock(fallback_clock);
#ifndef LORA_CR #ifndef LORA_CR
#define LORA_CR 5 #define LORA_CR 5
#endif #endif
bool radio_init() { bool radio_init() {
rtc_clock.begin(Wire);
#ifdef SX126X_DIO3_TCXO_VOLTAGE #ifdef SX126X_DIO3_TCXO_VOLTAGE
float tcxo = SX126X_DIO3_TCXO_VOLTAGE; float tcxo = SX126X_DIO3_TCXO_VOLTAGE;
#else #else
@@ -39,3 +47,23 @@ bool radio_init() {
return true; // success return true; // success
} }
uint32_t radio_get_rng_seed() {
return radio.random(0x7FFFFFFF);
}
void radio_set_params(float freq, float bw, uint8_t sf, uint8_t cr) {
radio.setFrequency(freq);
radio.setSpreadingFactor(sf);
radio.setBandwidth(bw);
radio.setCodingRate(cr);
}
void radio_set_tx_power(uint8_t dbm) {
radio.setOutputPower(dbm);
}
mesh::LocalIdentity radio_new_identity() {
RadioNoiseListener rng(radio);
return mesh::LocalIdentity(&rng); // create new random identity
}

View File

@@ -1,9 +1,18 @@
#pragma once #pragma once
#define RADIOLIB_STATIC_ONLY 1
#include <RadioLib.h>
#include <helpers/RadioLibWrappers.h>
#include <helpers/nrf52/TechoBoard.h> #include <helpers/nrf52/TechoBoard.h>
#include <helpers/CustomSX1262Wrapper.h> #include <helpers/CustomSX1262Wrapper.h>
#include <helpers/AutoDiscoverRTCClock.h>
extern TechoBoard board; extern TechoBoard board;
extern RADIO_CLASS radio; extern WRAPPER_CLASS radio_driver;
extern AutoDiscoverRTCClock rtc_clock;
bool radio_init(); bool radio_init();
uint32_t radio_get_rng_seed();
void radio_set_params(float freq, float bw, uint8_t sf, uint8_t cr);
void radio_set_tx_power(uint8_t dbm);
mesh::LocalIdentity radio_new_identity();

View File

@@ -10,11 +10,19 @@ XiaoC3Board board;
RADIO_CLASS radio = new Module(P_LORA_NSS, P_LORA_DIO_1, P_LORA_RESET, P_LORA_BUSY); RADIO_CLASS radio = new Module(P_LORA_NSS, P_LORA_DIO_1, P_LORA_RESET, P_LORA_BUSY);
#endif #endif
WRAPPER_CLASS radio_driver(radio, board);
ESP32RTCClock fallback_clock;
AutoDiscoverRTCClock rtc_clock(fallback_clock);
#ifndef LORA_CR #ifndef LORA_CR
#define LORA_CR 5 #define LORA_CR 5
#endif #endif
bool radio_init() { bool radio_init() {
fallback_clock.begin();
rtc_clock.begin(Wire);
#ifdef SX126X_DIO3_TCXO_VOLTAGE #ifdef SX126X_DIO3_TCXO_VOLTAGE
float tcxo = SX126X_DIO3_TCXO_VOLTAGE; float tcxo = SX126X_DIO3_TCXO_VOLTAGE;
#else #else
@@ -45,3 +53,23 @@ bool radio_init() {
return true; // success return true; // success
} }
uint32_t radio_get_rng_seed() {
return radio.random(0x7FFFFFFF);
}
void radio_set_params(float freq, float bw, uint8_t sf, uint8_t cr) {
radio.setFrequency(freq);
radio.setSpreadingFactor(sf);
radio.setBandwidth(bw);
radio.setCodingRate(cr);
}
void radio_set_tx_power(uint8_t dbm) {
radio.setOutputPower(dbm);
}
mesh::LocalIdentity radio_new_identity() {
RadioNoiseListener rng(radio);
return mesh::LocalIdentity(&rng); // create new random identity
}

View File

@@ -1,10 +1,19 @@
#pragma once #pragma once
#define RADIOLIB_STATIC_ONLY 1
#include <RadioLib.h>
#include <helpers/RadioLibWrappers.h>
#include <helpers/XiaoC3Board.h> #include <helpers/XiaoC3Board.h>
#include <helpers/CustomSX1262Wrapper.h> #include <helpers/CustomSX1262Wrapper.h>
#include <helpers/CustomSX1268Wrapper.h> #include <helpers/CustomSX1268Wrapper.h>
#include <helpers/AutoDiscoverRTCClock.h>
extern XiaoC3Board board; extern XiaoC3Board board;
extern RADIO_CLASS radio; extern WRAPPER_CLASS radio_driver;
extern AutoDiscoverRTCClock rtc_clock;
bool radio_init(); bool radio_init();
uint32_t radio_get_rng_seed();
void radio_set_params(float freq, float bw, uint8_t sf, uint8_t cr);
void radio_set_tx_power(uint8_t dbm);
mesh::LocalIdentity radio_new_identity();

View File

@@ -10,11 +10,19 @@ ESP32Board board;
RADIO_CLASS radio = new Module(P_LORA_NSS, P_LORA_DIO_1, P_LORA_RESET, P_LORA_BUSY); RADIO_CLASS radio = new Module(P_LORA_NSS, P_LORA_DIO_1, P_LORA_RESET, P_LORA_BUSY);
#endif #endif
WRAPPER_CLASS radio_driver(radio, board);
ESP32RTCClock fallback_clock;
AutoDiscoverRTCClock rtc_clock(fallback_clock);
#ifndef LORA_CR #ifndef LORA_CR
#define LORA_CR 5 #define LORA_CR 5
#endif #endif
bool radio_init() { bool radio_init() {
fallback_clock.begin();
rtc_clock.begin(Wire);
#ifdef SX126X_DIO3_TCXO_VOLTAGE #ifdef SX126X_DIO3_TCXO_VOLTAGE
float tcxo = SX126X_DIO3_TCXO_VOLTAGE; float tcxo = SX126X_DIO3_TCXO_VOLTAGE;
#else #else
@@ -45,3 +53,23 @@ bool radio_init() {
return true; // success return true; // success
} }
uint32_t radio_get_rng_seed() {
return radio.random(0x7FFFFFFF);
}
void radio_set_params(float freq, float bw, uint8_t sf, uint8_t cr) {
radio.setFrequency(freq);
radio.setSpreadingFactor(sf);
radio.setBandwidth(bw);
radio.setCodingRate(cr);
}
void radio_set_tx_power(uint8_t dbm) {
radio.setOutputPower(dbm);
}
mesh::LocalIdentity radio_new_identity() {
RadioNoiseListener rng(radio);
return mesh::LocalIdentity(&rng); // create new random identity
}

View File

@@ -1,9 +1,18 @@
#pragma once #pragma once
#define RADIOLIB_STATIC_ONLY 1
#include <RadioLib.h>
#include <helpers/RadioLibWrappers.h>
#include <helpers/ESP32Board.h> #include <helpers/ESP32Board.h>
#include <helpers/CustomSX1262Wrapper.h> #include <helpers/CustomSX1262Wrapper.h>
#include <helpers/AutoDiscoverRTCClock.h>
extern ESP32Board board; extern ESP32Board board;
extern RADIO_CLASS radio; extern WRAPPER_CLASS radio_driver;
extern AutoDiscoverRTCClock rtc_clock;
bool radio_init(); bool radio_init();
uint32_t radio_get_rng_seed();
void radio_set_params(float freq, float bw, uint8_t sf, uint8_t cr);
void radio_set_tx_power(uint8_t dbm);
mesh::LocalIdentity radio_new_identity();