mirror of
https://github.com/MarekZegare4/MeshCore-Solo.git
synced 2026-11-02 19:02:00 +00:00
* new DynamicConfigSerializer
* board/variant KeyValueStore now can write to 'custom' object in Json prefs
This commit is contained in:
@@ -990,7 +990,7 @@ void MyMesh::begin(bool has_display) {
|
|||||||
radio_driver.setTxPower(_prefs.tx_power_dbm);
|
radio_driver.setTxPower(_prefs.tx_power_dbm);
|
||||||
radio_driver.setRxBoostedGainMode(_prefs.rx_boosted_gain);
|
radio_driver.setRxBoostedGainMode(_prefs.rx_boosted_gain);
|
||||||
|
|
||||||
board.attachDynamicPrefs(_prefs.getRadioPrefs());
|
board.attachDynamicPrefs(_prefs.getCustom());
|
||||||
|
|
||||||
MESH_DEBUG_PRINTLN("RX Boosted Gain Mode: %s",
|
MESH_DEBUG_PRINTLN("RX Boosted Gain Mode: %s",
|
||||||
radio_driver.getRxBoostedGainMode() ? "Enabled" : "Disabled");
|
radio_driver.getRxBoostedGainMode() ? "Enabled" : "Disabled");
|
||||||
|
|||||||
@@ -2,6 +2,7 @@
|
|||||||
#include <cstdint> // For uint8_t, uint32_t
|
#include <cstdint> // For uint8_t, uint32_t
|
||||||
#include <helpers/ConfigSerializer.h>
|
#include <helpers/ConfigSerializer.h>
|
||||||
#include <helpers/CommonRadioPrefs.h>
|
#include <helpers/CommonRadioPrefs.h>
|
||||||
|
#include <helpers/DynamicConfigSerializer.h>
|
||||||
|
|
||||||
#define TELEM_MODE_DENY 0
|
#define TELEM_MODE_DENY 0
|
||||||
#define TELEM_MODE_ALLOW_FLAGS 1 // use contact.flags
|
#define TELEM_MODE_ALLOW_FLAGS 1 // use contact.flags
|
||||||
@@ -154,6 +155,8 @@ private:
|
|||||||
};
|
};
|
||||||
CompanionPrefs companion;
|
CompanionPrefs companion;
|
||||||
|
|
||||||
|
DynamicConfigSerializer custom;
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
void structure() override {
|
void structure() override {
|
||||||
def("name", node_name, sizeof(node_name));
|
def("name", node_name, sizeof(node_name));
|
||||||
@@ -165,9 +168,10 @@ protected:
|
|||||||
def("gps", gps);
|
def("gps", gps);
|
||||||
def("repeat", repeat);
|
def("repeat", repeat);
|
||||||
def("comp", companion);
|
def("comp", companion);
|
||||||
|
def("custom", custom);
|
||||||
}
|
}
|
||||||
public:
|
public:
|
||||||
NodePrefs() : radio(this), gps(this), companion(this) {
|
NodePrefs() : radio(this), gps(this), companion(this), custom(&radio) {
|
||||||
node_name[0] = 0;
|
node_name[0] = 0;
|
||||||
default_scope_name[0] = 0;
|
default_scope_name[0] = 0;
|
||||||
memset(default_scope_key, 0, sizeof(default_scope_key));
|
memset(default_scope_key, 0, sizeof(default_scope_key));
|
||||||
@@ -177,6 +181,8 @@ public:
|
|||||||
void setRepeatEn(bool en) { repeat.disable_fwd = en ? 0 : 1; }
|
void setRepeatEn(bool en) { repeat.disable_fwd = en ? 0 : 1; }
|
||||||
|
|
||||||
CommonRadioPrefs* getRadioPrefs() { return &radio; }
|
CommonRadioPrefs* getRadioPrefs() { return &radio; }
|
||||||
|
KeyValueStore* getCustom() { return &custom; }
|
||||||
|
|
||||||
bool isDirty() const override { return ConfigSerializer::isDirty() || radio.isDirty(); }
|
bool isDirty() const override { return ConfigSerializer::isDirty() || radio.isDirty(); }
|
||||||
void clearDirty() override { ConfigSerializer::clearDirty(); radio.clearDirty(); }
|
void clearDirty() override { ConfigSerializer::clearDirty(); radio.clearDirty(); }
|
||||||
};
|
};
|
||||||
|
|||||||
@@ -983,7 +983,7 @@ void MyMesh::begin(FILESYSTEM *fs) {
|
|||||||
MESH_DEBUG_PRINTLN("RX Boosted Gain Mode: %s",
|
MESH_DEBUG_PRINTLN("RX Boosted Gain Mode: %s",
|
||||||
radio_driver.getRxBoostedGainMode() ? "Enabled" : "Disabled");
|
radio_driver.getRxBoostedGainMode() ? "Enabled" : "Disabled");
|
||||||
|
|
||||||
board.attachDynamicPrefs(_prefs.getRadioPrefs());
|
board.attachDynamicPrefs(_prefs.getCustom());
|
||||||
|
|
||||||
updateAdvertTimer();
|
updateAdvertTimer();
|
||||||
updateFloodAdvertTimer();
|
updateFloodAdvertTimer();
|
||||||
|
|||||||
@@ -726,7 +726,7 @@ void MyMesh::begin(FILESYSTEM *fs) {
|
|||||||
radio_driver.setTxPower(_prefs.tx_power_dbm);
|
radio_driver.setTxPower(_prefs.tx_power_dbm);
|
||||||
radio_driver.setRxBoostedGainMode(_prefs.rx_boosted_gain);
|
radio_driver.setRxBoostedGainMode(_prefs.rx_boosted_gain);
|
||||||
|
|
||||||
board.attachDynamicPrefs(_prefs.getRadioPrefs());
|
board.attachDynamicPrefs(_prefs.getCustom());
|
||||||
|
|
||||||
updateAdvertTimer();
|
updateAdvertTimer();
|
||||||
updateFloodAdvertTimer();
|
updateFloodAdvertTimer();
|
||||||
|
|||||||
@@ -772,7 +772,7 @@ void SensorMesh::begin(FILESYSTEM* fs) {
|
|||||||
radio_driver.setParams(_prefs.freq, _prefs.bw, _prefs.sf, _prefs.cr);
|
radio_driver.setParams(_prefs.freq, _prefs.bw, _prefs.sf, _prefs.cr);
|
||||||
radio_driver.setTxPower(_prefs.tx_power_dbm);
|
radio_driver.setTxPower(_prefs.tx_power_dbm);
|
||||||
|
|
||||||
board.attachDynamicPrefs(_prefs.getRadioPrefs());
|
board.attachDynamicPrefs(_prefs.getCustom());
|
||||||
|
|
||||||
updateAdvertTimer();
|
updateAdvertTimer();
|
||||||
updateFloodAdvertTimer();
|
updateFloodAdvertTimer();
|
||||||
|
|||||||
@@ -7,6 +7,7 @@
|
|||||||
#include <helpers/RegionMap.h>
|
#include <helpers/RegionMap.h>
|
||||||
#include <helpers/ConfigSerializer.h>
|
#include <helpers/ConfigSerializer.h>
|
||||||
#include <helpers/CommonRadioPrefs.h>
|
#include <helpers/CommonRadioPrefs.h>
|
||||||
|
#include <helpers/DynamicConfigSerializer.h>
|
||||||
|
|
||||||
#if defined(WITH_RS232_BRIDGE) || defined(WITH_ESPNOW_BRIDGE)
|
#if defined(WITH_RS232_BRIDGE) || defined(WITH_ESPNOW_BRIDGE)
|
||||||
#define WITH_BRIDGE
|
#define WITH_BRIDGE
|
||||||
@@ -202,6 +203,8 @@ private:
|
|||||||
};
|
};
|
||||||
RoomPrefs room;
|
RoomPrefs room;
|
||||||
|
|
||||||
|
DynamicConfigSerializer custom;
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
void structure() override {
|
void structure() override {
|
||||||
def("name", node_name, sizeof(node_name));
|
def("name", node_name, sizeof(node_name));
|
||||||
@@ -218,10 +221,11 @@ protected:
|
|||||||
def("repeat", repeat);
|
def("repeat", repeat);
|
||||||
def("room", room);
|
def("room", room);
|
||||||
def("power", power);
|
def("power", power);
|
||||||
|
def("custom", custom);
|
||||||
}
|
}
|
||||||
|
|
||||||
public:
|
public:
|
||||||
NodePrefs() : ConfigSerializer(), bridge(this), gps(this), radio(this), power(this), repeat(this), room(this) {
|
NodePrefs() : ConfigSerializer(), bridge(this), gps(this), radio(this), power(this), repeat(this), room(this), custom(&radio) {
|
||||||
node_name[0] = 0;
|
node_name[0] = 0;
|
||||||
password[0] = 0;
|
password[0] = 0;
|
||||||
guest_password[0] = 0;
|
guest_password[0] = 0;
|
||||||
@@ -230,6 +234,8 @@ public:
|
|||||||
}
|
}
|
||||||
|
|
||||||
CommonRadioPrefs* getRadioPrefs() { return &radio; }
|
CommonRadioPrefs* getRadioPrefs() { return &radio; }
|
||||||
|
KeyValueStore* getCustom() { return &custom; }
|
||||||
|
|
||||||
bool isDirty() const override { return ConfigSerializer::isDirty() || radio.isDirty(); }
|
bool isDirty() const override { return ConfigSerializer::isDirty() || radio.isDirty(); }
|
||||||
void clearDirty() override { ConfigSerializer::clearDirty(); radio.clearDirty(); }
|
void clearDirty() override { ConfigSerializer::clearDirty(); radio.clearDirty(); }
|
||||||
};
|
};
|
||||||
|
|||||||
@@ -3,25 +3,29 @@
|
|||||||
#include "Utils.h"
|
#include "Utils.h"
|
||||||
#include "target.h"
|
#include "target.h"
|
||||||
|
|
||||||
void CommonRadioPrefs::getByKey(const char* key, char* value, size_t max_len) {
|
bool CommonRadioPrefs::getByKey(const char* key, char* value, size_t max_len) {
|
||||||
if (strcmp(key, "fem_rxgain") == 0) {
|
if (strcmp(key, "fem_rxgain") == 0) {
|
||||||
snprintf(value, max_len, "%d", (uint32_t)getFEMRxGain());
|
snprintf(value, max_len, "%d", (uint32_t)getFEMRxGain());
|
||||||
} else if (strcmp(key, "fem_txgain") == 0) {
|
return true;
|
||||||
|
}
|
||||||
|
if (strcmp(key, "fem_txgain") == 0) {
|
||||||
snprintf(value, max_len, "%d", (uint32_t)getFEMTxGain());
|
snprintf(value, max_len, "%d", (uint32_t)getFEMTxGain());
|
||||||
} else {
|
return true;
|
||||||
MESH_DEBUG_PRINTLN("Error: getBykey() unknown key: %s", key);
|
|
||||||
}
|
}
|
||||||
|
return false;
|
||||||
}
|
}
|
||||||
void CommonRadioPrefs::setByKey(const char* key, const char* value) {
|
bool CommonRadioPrefs::setByKey(const char* key, const char* value) {
|
||||||
if (strcmp(key, "fem_rxgain") == 0) {
|
if (strcmp(key, "fem_rxgain") == 0) {
|
||||||
setFEMRxGain(atoi(value));
|
setFEMRxGain(atoi(value));
|
||||||
markDirty();
|
markDirty();
|
||||||
} else if (strcmp(key, "fem_txgain") == 0) {
|
return true;
|
||||||
|
}
|
||||||
|
if (strcmp(key, "fem_txgain") == 0) {
|
||||||
setFEMTxGain(atoi(value));
|
setFEMTxGain(atoi(value));
|
||||||
markDirty();
|
markDirty();
|
||||||
} else {
|
return true;
|
||||||
MESH_DEBUG_PRINTLN("Error: setBykey() unknown key: %s", key);
|
|
||||||
}
|
}
|
||||||
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool CommonRadioPrefs::handleCommand(const char* command, uint32_t sender_timestamp, char* reply) {
|
bool CommonRadioPrefs::handleCommand(const char* command, uint32_t sender_timestamp, char* reply) {
|
||||||
|
|||||||
@@ -64,6 +64,6 @@ public:
|
|||||||
|
|
||||||
bool handleCommand(const char* command, uint32_t sender_timestamp, char* reply);
|
bool handleCommand(const char* command, uint32_t sender_timestamp, char* reply);
|
||||||
|
|
||||||
void setByKey(const char* key, const char* value) override; // for dynamic key/value access
|
bool setByKey(const char* key, const char* value) override; // for dynamic key/value access
|
||||||
void getByKey(const char* key, char* value, size_t max_len) override;
|
bool getByKey(const char* key, char* value, size_t max_len) override;
|
||||||
};
|
};
|
||||||
|
|||||||
@@ -0,0 +1,83 @@
|
|||||||
|
#include "DynamicConfigSerializer.h"
|
||||||
|
#include <Utils.h>
|
||||||
|
|
||||||
|
#define PROP_SEP_CHAR '|'
|
||||||
|
#define PROP_SEP_STR "|"
|
||||||
|
#define KEY_SEP_CHAR ':'
|
||||||
|
#define KEY_SEP_STR ":"
|
||||||
|
|
||||||
|
bool DynamicConfigSerializer::setByKey(const char* key, const char* value) {
|
||||||
|
if (_fallback && _fallback->setByKey(key, value)) return true;
|
||||||
|
|
||||||
|
// TODO: guard for bad chars (':' or '|')
|
||||||
|
char tmp[MAX_DYNAMIC_CONFG];
|
||||||
|
strcpy(tmp, _config); // make a (modifiable) copy
|
||||||
|
|
||||||
|
const char* parts[8];
|
||||||
|
int n = mesh::Utils::parseTextParts(tmp, parts, 8, PROP_SEP_CHAR);
|
||||||
|
|
||||||
|
// add/replace in _config[]
|
||||||
|
char new_config[MAX_DYNAMIC_CONFG];
|
||||||
|
new_config[0] = 0;
|
||||||
|
|
||||||
|
int keylen = strlen(key);
|
||||||
|
for (int i = 0; i < n; i++) {
|
||||||
|
const char* item = parts[i];
|
||||||
|
if (item[keylen] == KEY_SEP_CHAR && memcmp(item, key, keylen) == 0) {
|
||||||
|
// key exists, so omit old value from this pass (will append new value at end)
|
||||||
|
} else {
|
||||||
|
if (new_config[0]) {
|
||||||
|
strcat(new_config, PROP_SEP_STR);
|
||||||
|
}
|
||||||
|
strcat(new_config, item);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
// now append new key/value (if it fits)
|
||||||
|
if (strlen(new_config) + strlen(key) + strlen(value) + 2 < sizeof(_config)-1) {
|
||||||
|
strcat(new_config, key);
|
||||||
|
strcat(new_config, KEY_SEP_STR);
|
||||||
|
strcat(new_config, value);
|
||||||
|
strcpy(_config, new_config); // commit new serialized string
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
return false; // didn't fit in _config[]
|
||||||
|
}
|
||||||
|
|
||||||
|
bool DynamicConfigSerializer::getByKey(const char* key, char* value, size_t max_len) {
|
||||||
|
if (_fallback && _fallback->getByKey(key, value, max_len)) return true;
|
||||||
|
|
||||||
|
char tmp[MAX_DYNAMIC_CONFG];
|
||||||
|
strcpy(tmp, _config); // make a (modifiable) copy
|
||||||
|
|
||||||
|
const char* parts[8];
|
||||||
|
int n = mesh::Utils::parseTextParts(tmp, parts, 8, PROP_SEP_CHAR);
|
||||||
|
|
||||||
|
int keylen = strlen(key);
|
||||||
|
for (int i = 0; i < n; i++) {
|
||||||
|
const char* item = parts[i];
|
||||||
|
if (item[keylen] == KEY_SEP_CHAR && memcmp(item, key, keylen) == 0) {
|
||||||
|
strncpy(value, &item[keylen+1], max_len);
|
||||||
|
value[max_len] = 0;
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
void DynamicConfigSerializer::structure() {
|
||||||
|
char tmp[MAX_DYNAMIC_CONFG];
|
||||||
|
strcpy(tmp, _config); // make a (modifiable) copy
|
||||||
|
|
||||||
|
const char* parts[8];
|
||||||
|
int n = mesh::Utils::parseTextParts(tmp, parts, 8, PROP_SEP_CHAR);
|
||||||
|
|
||||||
|
// dynamically call def()'s
|
||||||
|
for (int i = 0; i < n; i++) {
|
||||||
|
char* item = (char *) parts[i];
|
||||||
|
char* eq = strchr(item, KEY_SEP_CHAR);
|
||||||
|
if (eq) {
|
||||||
|
*eq = 0; // replace separator with null terminator
|
||||||
|
def(item, eq + 1, MAX_DYNAMIC_CONFG/2); // maximum HALF of total for individual property value
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,20 @@
|
|||||||
|
#include "ConfigSerializer.h"
|
||||||
|
#include "KeyValueStore.h"
|
||||||
|
|
||||||
|
#ifndef MAX_DYNAMIC_CONFG
|
||||||
|
#define MAX_DYNAMIC_CONFG 128
|
||||||
|
#endif
|
||||||
|
|
||||||
|
class DynamicConfigSerializer : public ConfigSerializer, public KeyValueStore {
|
||||||
|
char _config[MAX_DYNAMIC_CONFG];
|
||||||
|
KeyValueStore* _fallback;
|
||||||
|
|
||||||
|
protected:
|
||||||
|
void structure() override;
|
||||||
|
|
||||||
|
public:
|
||||||
|
DynamicConfigSerializer(KeyValueStore* fallback = NULL) : _fallback(fallback) { _config[0] = 0; }
|
||||||
|
|
||||||
|
bool setByKey(const char* key, const char* value) override;
|
||||||
|
bool getByKey(const char* key, char* value, size_t max_len) override;
|
||||||
|
};
|
||||||
@@ -6,6 +6,6 @@ class KeyValueStore {
|
|||||||
protected:
|
protected:
|
||||||
KeyValueStore() { }
|
KeyValueStore() { }
|
||||||
public:
|
public:
|
||||||
virtual void setByKey(const char* key, const char* value) { }
|
virtual bool setByKey(const char* key, const char* value) { return false; }
|
||||||
virtual void getByKey(const char* key, char* value, size_t max_len) { }
|
virtual bool getByKey(const char* key, char* value, size_t max_len) { return false; }
|
||||||
};
|
};
|
||||||
|
|||||||
Reference in New Issue
Block a user