|
|
@ -14,57 +14,65 @@ static uint32_t _atoi(const char* sp) { |
|
|
} |
|
|
} |
|
|
|
|
|
|
|
|
void CommonCLI::loadPrefs(FILESYSTEM* fs) { |
|
|
void CommonCLI::loadPrefs(FILESYSTEM* fs) { |
|
|
if (fs->exists("/node_prefs")) { |
|
|
if (fs->exists("/com_prefs")) { |
|
|
File file = fs->open("/node_prefs"); |
|
|
loadPrefsInt(fs, "/com_prefs"); // new filename
|
|
|
if (file) { |
|
|
} else if (fs->exists("/node_prefs")) { |
|
|
uint8_t pad[8]; |
|
|
loadPrefsInt(fs, "/node_prefs"); |
|
|
|
|
|
savePrefs(fs); // save to new filename
|
|
|
|
|
|
fs->remove("/node_prefs"); // remove old
|
|
|
|
|
|
} |
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
file.read((uint8_t *) &_prefs->airtime_factor, sizeof(_prefs->airtime_factor)); // 0
|
|
|
void CommonCLI::loadPrefsInt(FILESYSTEM* fs, const char* filename) { |
|
|
file.read((uint8_t *) &_prefs->node_name, sizeof(_prefs->node_name)); // 4
|
|
|
File file = fs->open(filename); |
|
|
file.read(pad, 4); // 36
|
|
|
if (file) { |
|
|
file.read((uint8_t *) &_prefs->node_lat, sizeof(_prefs->node_lat)); // 40
|
|
|
uint8_t pad[8]; |
|
|
file.read((uint8_t *) &_prefs->node_lon, sizeof(_prefs->node_lon)); // 48
|
|
|
|
|
|
file.read((uint8_t *) &_prefs->password[0], sizeof(_prefs->password)); // 56
|
|
|
|
|
|
file.read((uint8_t *) &_prefs->freq, sizeof(_prefs->freq)); // 72
|
|
|
|
|
|
file.read((uint8_t *) &_prefs->tx_power_dbm, sizeof(_prefs->tx_power_dbm)); // 76
|
|
|
|
|
|
file.read((uint8_t *) &_prefs->disable_fwd, sizeof(_prefs->disable_fwd)); // 77
|
|
|
|
|
|
file.read((uint8_t *) &_prefs->advert_interval, sizeof(_prefs->advert_interval)); // 78
|
|
|
|
|
|
file.read((uint8_t *) &_prefs->unused, sizeof(_prefs->unused)); // 79
|
|
|
|
|
|
file.read((uint8_t *) &_prefs->rx_delay_base, sizeof(_prefs->rx_delay_base)); // 80
|
|
|
|
|
|
file.read((uint8_t *) &_prefs->tx_delay_factor, sizeof(_prefs->tx_delay_factor)); // 84
|
|
|
|
|
|
file.read((uint8_t *) &_prefs->guest_password[0], sizeof(_prefs->guest_password)); // 88
|
|
|
|
|
|
file.read((uint8_t *) &_prefs->direct_tx_delay_factor, sizeof(_prefs->direct_tx_delay_factor)); // 104
|
|
|
|
|
|
file.read(pad, 4); // 108
|
|
|
|
|
|
file.read((uint8_t *) &_prefs->sf, sizeof(_prefs->sf)); // 112
|
|
|
|
|
|
file.read((uint8_t *) &_prefs->cr, sizeof(_prefs->cr)); // 113
|
|
|
|
|
|
file.read((uint8_t *) &_prefs->reserved1, sizeof(_prefs->reserved1)); // 114
|
|
|
|
|
|
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
|
|
|
file.read((uint8_t *) &_prefs->airtime_factor, sizeof(_prefs->airtime_factor)); // 0
|
|
|
_prefs->rx_delay_base = constrain(_prefs->rx_delay_base, 0, 20.0f); |
|
|
file.read((uint8_t *) &_prefs->node_name, sizeof(_prefs->node_name)); // 4
|
|
|
_prefs->tx_delay_factor = constrain(_prefs->tx_delay_factor, 0, 2.0f); |
|
|
file.read(pad, 4); // 36
|
|
|
_prefs->direct_tx_delay_factor = constrain(_prefs->direct_tx_delay_factor, 0, 2.0f); |
|
|
file.read((uint8_t *) &_prefs->node_lat, sizeof(_prefs->node_lat)); // 40
|
|
|
_prefs->airtime_factor = constrain(_prefs->airtime_factor, 0, 9.0f); |
|
|
file.read((uint8_t *) &_prefs->node_lon, sizeof(_prefs->node_lon)); // 48
|
|
|
_prefs->freq = constrain(_prefs->freq, 400.0f, 2500.0f); |
|
|
file.read((uint8_t *) &_prefs->password[0], sizeof(_prefs->password)); // 56
|
|
|
_prefs->bw = constrain(_prefs->bw, 62.5f, 500.0f); |
|
|
file.read((uint8_t *) &_prefs->freq, sizeof(_prefs->freq)); // 72
|
|
|
_prefs->sf = constrain(_prefs->sf, 7, 12); |
|
|
file.read((uint8_t *) &_prefs->tx_power_dbm, sizeof(_prefs->tx_power_dbm)); // 76
|
|
|
_prefs->cr = constrain(_prefs->cr, 5, 8); |
|
|
file.read((uint8_t *) &_prefs->disable_fwd, sizeof(_prefs->disable_fwd)); // 77
|
|
|
_prefs->tx_power_dbm = constrain(_prefs->tx_power_dbm, 1, 30); |
|
|
file.read((uint8_t *) &_prefs->advert_interval, sizeof(_prefs->advert_interval)); // 78
|
|
|
|
|
|
file.read((uint8_t *) &_prefs->flood_advert_interval, sizeof(_prefs->flood_advert_interval)); // 79
|
|
|
|
|
|
file.read((uint8_t *) &_prefs->rx_delay_base, sizeof(_prefs->rx_delay_base)); // 80
|
|
|
|
|
|
file.read((uint8_t *) &_prefs->tx_delay_factor, sizeof(_prefs->tx_delay_factor)); // 84
|
|
|
|
|
|
file.read((uint8_t *) &_prefs->guest_password[0], sizeof(_prefs->guest_password)); // 88
|
|
|
|
|
|
file.read((uint8_t *) &_prefs->direct_tx_delay_factor, sizeof(_prefs->direct_tx_delay_factor)); // 104
|
|
|
|
|
|
file.read(pad, 4); // 108
|
|
|
|
|
|
file.read((uint8_t *) &_prefs->sf, sizeof(_prefs->sf)); // 112
|
|
|
|
|
|
file.read((uint8_t *) &_prefs->cr, sizeof(_prefs->cr)); // 113
|
|
|
|
|
|
file.read((uint8_t *) &_prefs->allow_read_only, sizeof(_prefs->allow_read_only)); // 114
|
|
|
|
|
|
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
|
|
|
|
|
|
|
|
|
file.close(); |
|
|
// sanitise bad pref values
|
|
|
} |
|
|
_prefs->rx_delay_base = constrain(_prefs->rx_delay_base, 0, 20.0f); |
|
|
|
|
|
_prefs->tx_delay_factor = constrain(_prefs->tx_delay_factor, 0, 2.0f); |
|
|
|
|
|
_prefs->direct_tx_delay_factor = constrain(_prefs->direct_tx_delay_factor, 0, 2.0f); |
|
|
|
|
|
_prefs->airtime_factor = constrain(_prefs->airtime_factor, 0, 9.0f); |
|
|
|
|
|
_prefs->freq = constrain(_prefs->freq, 400.0f, 2500.0f); |
|
|
|
|
|
_prefs->bw = constrain(_prefs->bw, 62.5f, 500.0f); |
|
|
|
|
|
_prefs->sf = constrain(_prefs->sf, 7, 12); |
|
|
|
|
|
_prefs->cr = constrain(_prefs->cr, 5, 8); |
|
|
|
|
|
_prefs->tx_power_dbm = constrain(_prefs->tx_power_dbm, 1, 30); |
|
|
|
|
|
|
|
|
|
|
|
file.close(); |
|
|
} |
|
|
} |
|
|
} |
|
|
} |
|
|
|
|
|
|
|
|
void CommonCLI::savePrefs(FILESYSTEM* fs) { |
|
|
void CommonCLI::savePrefs(FILESYSTEM* fs) { |
|
|
#if defined(NRF52_PLATFORM) |
|
|
#if defined(NRF52_PLATFORM) |
|
|
File file = fs->open("/node_prefs", FILE_O_WRITE); |
|
|
File file = fs->open("/com_prefs", FILE_O_WRITE); |
|
|
if (file) { file.seek(0); file.truncate(); } |
|
|
if (file) { file.seek(0); file.truncate(); } |
|
|
#else |
|
|
#else |
|
|
File file = fs->open("/node_prefs", "w", true); |
|
|
File file = fs->open("/com_prefs", "w", true); |
|
|
#endif |
|
|
#endif |
|
|
if (file) { |
|
|
if (file) { |
|
|
uint8_t pad[8]; |
|
|
uint8_t pad[8]; |
|
|
@ -80,7 +88,7 @@ void CommonCLI::savePrefs(FILESYSTEM* fs) { |
|
|
file.write((uint8_t *) &_prefs->tx_power_dbm, sizeof(_prefs->tx_power_dbm)); // 76
|
|
|
file.write((uint8_t *) &_prefs->tx_power_dbm, sizeof(_prefs->tx_power_dbm)); // 76
|
|
|
file.write((uint8_t *) &_prefs->disable_fwd, sizeof(_prefs->disable_fwd)); // 77
|
|
|
file.write((uint8_t *) &_prefs->disable_fwd, sizeof(_prefs->disable_fwd)); // 77
|
|
|
file.write((uint8_t *) &_prefs->advert_interval, sizeof(_prefs->advert_interval)); // 78
|
|
|
file.write((uint8_t *) &_prefs->advert_interval, sizeof(_prefs->advert_interval)); // 78
|
|
|
file.write((uint8_t *) &_prefs->unused, sizeof(_prefs->unused)); // 79
|
|
|
file.write((uint8_t *) &_prefs->flood_advert_interval, sizeof(_prefs->flood_advert_interval)); // 79
|
|
|
file.write((uint8_t *) &_prefs->rx_delay_base, sizeof(_prefs->rx_delay_base)); // 80
|
|
|
file.write((uint8_t *) &_prefs->rx_delay_base, sizeof(_prefs->rx_delay_base)); // 80
|
|
|
file.write((uint8_t *) &_prefs->tx_delay_factor, sizeof(_prefs->tx_delay_factor)); // 84
|
|
|
file.write((uint8_t *) &_prefs->tx_delay_factor, sizeof(_prefs->tx_delay_factor)); // 84
|
|
|
file.write((uint8_t *) &_prefs->guest_password[0], sizeof(_prefs->guest_password)); // 88
|
|
|
file.write((uint8_t *) &_prefs->guest_password[0], sizeof(_prefs->guest_password)); // 88
|
|
|
@ -88,7 +96,7 @@ void CommonCLI::savePrefs(FILESYSTEM* fs) { |
|
|
file.write(pad, 4); // 108
|
|
|
file.write(pad, 4); // 108
|
|
|
file.write((uint8_t *) &_prefs->sf, sizeof(_prefs->sf)); // 112
|
|
|
file.write((uint8_t *) &_prefs->sf, sizeof(_prefs->sf)); // 112
|
|
|
file.write((uint8_t *) &_prefs->cr, sizeof(_prefs->cr)); // 113
|
|
|
file.write((uint8_t *) &_prefs->cr, sizeof(_prefs->cr)); // 113
|
|
|
file.write((uint8_t *) &_prefs->reserved1, sizeof(_prefs->reserved1)); // 114
|
|
|
file.write((uint8_t *) &_prefs->allow_read_only, sizeof(_prefs->allow_read_only)); // 114
|
|
|
file.write((uint8_t *) &_prefs->reserved2, sizeof(_prefs->reserved2)); // 115
|
|
|
file.write((uint8_t *) &_prefs->reserved2, sizeof(_prefs->reserved2)); // 115
|
|
|
file.write((uint8_t *) &_prefs->bw, sizeof(_prefs->bw)); // 116
|
|
|
file.write((uint8_t *) &_prefs->bw, sizeof(_prefs->bw)); // 116
|
|
|
file.write(pad, 4); // 120
|
|
|
file.write(pad, 4); // 120
|
|
|
@ -155,6 +163,10 @@ void CommonCLI::handleCommand(uint32_t sender_timestamp, const char* command, ch |
|
|
const char* config = &command[4]; |
|
|
const char* config = &command[4]; |
|
|
if (memcmp(config, "af", 2) == 0) { |
|
|
if (memcmp(config, "af", 2) == 0) { |
|
|
sprintf(reply, "> %s", StrHelper::ftoa(_prefs->airtime_factor)); |
|
|
sprintf(reply, "> %s", StrHelper::ftoa(_prefs->airtime_factor)); |
|
|
|
|
|
} else if (memcmp(config, "allow.read.only", 15) == 0) { |
|
|
|
|
|
sprintf(reply, "> %s", _prefs->allow_read_only ? "on" : "off"); |
|
|
|
|
|
} else if (memcmp(config, "flood.advert.interval", 21) == 0) { |
|
|
|
|
|
sprintf(reply, "> %d", ((uint32_t) _prefs->flood_advert_interval)); |
|
|
} else if (memcmp(config, "advert.interval", 15) == 0) { |
|
|
} else if (memcmp(config, "advert.interval", 15) == 0) { |
|
|
sprintf(reply, "> %d", ((uint32_t) _prefs->advert_interval) * 2); |
|
|
sprintf(reply, "> %d", ((uint32_t) _prefs->advert_interval) * 2); |
|
|
} else if (memcmp(config, "guest.password", 14) == 0) { |
|
|
} else if (memcmp(config, "guest.password", 14) == 0) { |
|
|
@ -193,6 +205,22 @@ void CommonCLI::handleCommand(uint32_t sender_timestamp, const char* command, ch |
|
|
_prefs->airtime_factor = atof(&config[3]); |
|
|
_prefs->airtime_factor = atof(&config[3]); |
|
|
savePrefs(); |
|
|
savePrefs(); |
|
|
strcpy(reply, "OK"); |
|
|
strcpy(reply, "OK"); |
|
|
|
|
|
} else if (memcmp(config, "allow.read.only ", 16) == 0) { |
|
|
|
|
|
_prefs->allow_read_only = memcmp(&config[16], "on", 2) == 0; |
|
|
|
|
|
savePrefs(); |
|
|
|
|
|
strcpy(reply, "OK"); |
|
|
|
|
|
} else if (memcmp(config, "flood.advert.interval ", 22) == 0) { |
|
|
|
|
|
int hours = _atoi(&config[22]); |
|
|
|
|
|
if (hours > 0 && hours < 3) { |
|
|
|
|
|
sprintf(reply, "Error: min is 3 hours"); |
|
|
|
|
|
} else if (hours > 48) { |
|
|
|
|
|
strcpy(reply, "Error: max is 48 hours"); |
|
|
|
|
|
} else { |
|
|
|
|
|
_prefs->flood_advert_interval = (uint8_t)(hours); |
|
|
|
|
|
_callbacks->updateFloodAdvertTimer(); |
|
|
|
|
|
savePrefs(); |
|
|
|
|
|
strcpy(reply, "OK"); |
|
|
|
|
|
} |
|
|
} else if (memcmp(config, "advert.interval ", 16) == 0) { |
|
|
} else if (memcmp(config, "advert.interval ", 16) == 0) { |
|
|
int mins = _atoi(&config[16]); |
|
|
int mins = _atoi(&config[16]); |
|
|
if (mins > 0 && mins < MIN_LOCAL_ADVERT_INTERVAL) { |
|
|
if (mins > 0 && mins < MIN_LOCAL_ADVERT_INTERVAL) { |
|
|
|