Validate beacon power without stranding saved settings
This commit is contained in:
1 parent
adbeb2d007
commit
d5cc73c43d
15 files changed
+662
-7
No files matched your search
+57
@@ -57,6 +57,62 @@ void put32(uint8_t* bytes, uint32_t value) {
|
||||
}
|
||||
void fixCrc(std::vector<uint8_t>& bytes) { put32(bytes.data() + bytes.size() - 4, crc(bytes.data(), bytes.size() - 4)); }
|
||||
|
||||
void structuralStorage() {
|
||||
Fixture mc; mc.mc(1, "Old");
|
||||
Fixture mt; mt.mt();
|
||||
for (unsigned fault = 0; fault < 15; ++fault) {
|
||||
Fixture f;
|
||||
f.fs.files = fault >= 12 ? mt.fs.files : mc.fs.files;
|
||||
auto& bytes = f.fs.files.at("/beacons");
|
||||
uint8_t* record = bytes.data() + 8;
|
||||
switch (fault) {
|
||||
case 0: record[10] = 255; break; // Invalid SF.
|
||||
case 1: record[11] = 4; break; // Invalid coding rate.
|
||||
case 2: {
|
||||
const float bw = 123;
|
||||
std::memcpy(record + 4, &bw, 4); break;
|
||||
}
|
||||
case 3: record[8] = 7; record[9] = 0; break;
|
||||
case 4: { // Valid tuple, but its long preamble overflows safe airtime.
|
||||
const float bw = 7.8f;
|
||||
std::memcpy(record + 4, &bw, 4);
|
||||
record[10] = 12; record[8] = 248; record[9] = 255; break;
|
||||
}
|
||||
case 5: put32(record, 0x7fc00000U); break; // NaN frequency.
|
||||
case 6: record[17] = 255; break; // Malformed UTF-8.
|
||||
case 7: record[17] = '\n'; break;
|
||||
case 8: record[21] = 'X'; break; // Hidden bytes after the terminator.
|
||||
case 9: record[16] = 0; break; // Disabled records must be all zero.
|
||||
case 10: record[12] = uint8_t(mesh::RadioProfileProtocol::Ethernet); break;
|
||||
case 11: record[15] = 8; break;
|
||||
case 12: record[14] = 255; break; // Invalid MT preset.
|
||||
case 13: record[8] = 32; record[9] = 0; break; // MT preamble is fixed.
|
||||
case 14: bytes[6] = 0; break; // MT requires durable ID initialization.
|
||||
}
|
||||
fixCrc(bytes);
|
||||
const auto original = f.fs.files;
|
||||
f.manager.begin(&f.fs, &f.mesh, &f.clock, f.name);
|
||||
f.cmd("get beacon", false);
|
||||
f.cmd("set beacon.interval 12", false);
|
||||
f.cmd("delete beacon all", false);
|
||||
f.tick(48 * H);
|
||||
assert(f.mesh.attempts == 0 && f.fs.files == original);
|
||||
}
|
||||
// Neither a future schema nor a read error may fall back to an older image.
|
||||
for (bool unreadable : {false, true}) {
|
||||
Fixture f;
|
||||
f.fs.files = mc.fs.files;
|
||||
f.fs.files["/beacons.bak"] = f.fs.files.at("/beacons");
|
||||
if (unreadable) f.fs.fail_read_open = true;
|
||||
else f.fs.files.at("/beacons")[4] = 2;
|
||||
const auto original = f.fs.files;
|
||||
f.manager.begin(&f.fs, &f.mesh, &f.clock, f.name);
|
||||
f.cmd("get beacon", false);
|
||||
f.tick(48 * H);
|
||||
assert(f.mesh.attempts == 0 && f.fs.files == original);
|
||||
}
|
||||
}
|
||||
|
||||
void commands() {
|
||||
Fixture f;
|
||||
assert(!f.mesh.wake_enabled && f.fs.files.empty());
|
||||
@@ -407,6 +463,7 @@ int main(int argc, char** argv) {
|
||||
else if (!std::strcmp(argv[1], "schedule")) schedule();
|
||||
else if (!std::strcmp(argv[1], "rolling")) rolling();
|
||||
else if (!std::strcmp(argv[1], "storage")) storage();
|
||||
else if (!std::strcmp(argv[1], "structural_storage")) structuralStorage();
|
||||
else if (!std::strcmp(argv[1], "ids")) ids();
|
||||
else if (!std::strcmp(argv[1], "mutations")) mutations();
|
||||
else if (!std::strcmp(argv[1], "stale_backup")) staleBackup();
|
||||
|
||||
Reference in new issue
Block a user