Keep RAK4631 Full OTA images within the application region
This commit is contained in:
1 parent
c563c40c66
commit
8e8c603eb5
2 files changed
+44
-29
No files matched your search
@@ -775,11 +775,11 @@ bool MyMesh::handleMeshtextCommand(const char* command, char* reply, size_t capa
|
||||
ChannelDetails channel;
|
||||
if (!nextToken(nodeinfo_args, index_text, sizeof(index_text)) || !endTokens(nodeinfo_args)
|
||||
|| !mesh::cli::parseUnsignedIntegerStrict(index_text, index) || index >= MAX_GROUP_CHANNELS) {
|
||||
snprintf(reply, capacity, "Error: use send mt.nodeinfo <channel slot>");
|
||||
mesh::cli::formatError(reply, capacity, "use send mt.nodeinfo <channel slot>");
|
||||
} else if (!getChannelForSave(index, channel) || !isMeshtextChannel(channel)) {
|
||||
snprintf(reply, capacity, "Error: configured Meshtext channel required");
|
||||
mesh::cli::formatError(reply, capacity, "configured Meshtext channel required");
|
||||
} else if (!sendMeshtextNodeInfo(channel)) {
|
||||
snprintf(reply, capacity, "Error: NodeInfo not queued; check get mt.status, TX mode or pending TX");
|
||||
mesh::cli::formatError(reply, capacity, "NodeInfo not queued; check get mt.status, TX mode or pending TX");
|
||||
} else {
|
||||
snprintf(reply, capacity, "OK - NodeInfo queued on Meshtext channel %lu; no GPS",
|
||||
(unsigned long)index);
|
||||
@@ -794,19 +794,19 @@ bool MyMesh::handleMeshtextCommand(const char* command, char* reply, size_t capa
|
||||
char index_text[12]; uint32_t index = 0;
|
||||
if (!nextToken(cursor, index_text, sizeof(index_text))
|
||||
|| !mesh::cli::parseUnsignedIntegerStrict(index_text, index) || index >= MAX_GROUP_CHANNELS) {
|
||||
snprintf(reply, capacity, "Error: invalid channel slot"); return true;
|
||||
mesh::cli::formatError(reply, capacity, "invalid channel slot"); return true;
|
||||
}
|
||||
ChannelDetails previous{}, channel{};
|
||||
if (!getChannelForSave(index, previous)) {
|
||||
snprintf(reply, capacity, "Error: channel slot unavailable"); return true;
|
||||
mesh::cli::formatError(reply, capacity, "channel slot unavailable"); return true;
|
||||
}
|
||||
if (channel_get || channel_delete) {
|
||||
if (!endTokens(cursor) || !previous.name[0] || !isMeshtextChannel(previous)) {
|
||||
snprintf(reply, capacity, "Error: Meshtext channel not found or extra arguments"); return true;
|
||||
mesh::cli::formatError(reply, capacity, "Meshtext channel not found or extra arguments"); return true;
|
||||
}
|
||||
if (channel_get) {
|
||||
mesh::mt::Channel wire;
|
||||
if (!describe(previous, wire)) snprintf(reply, capacity, "Error: invalid Meshtext channel");
|
||||
if (!describe(previous, wire)) mesh::cli::formatError(reply, capacity, "invalid Meshtext channel");
|
||||
else snprintf(reply, capacity, "> %lu %s; wire=%s; AES-%u; key not displayed",
|
||||
(unsigned long)index, previous.name, wire.name, unsigned(wire.key_length * 8));
|
||||
return true;
|
||||
@@ -816,24 +816,24 @@ bool MyMesh::handleMeshtextCommand(const char* command, char* reply, size_t capa
|
||||
if (!nextToken(cursor, channel.name, sizeof(channel.name))
|
||||
|| !nextToken(cursor, key_text, sizeof(key_text)) || !endTokens(cursor)
|
||||
|| !isMeshtextChannel(channel)) {
|
||||
snprintf(reply, capacity, "Error: use set mt.channel <slot> <mt-name> <32/64 hex digits|AQ==>"); return true;
|
||||
mesh::cli::formatError(reply, capacity, "use set mt.channel <slot> <mt-name> <32/64 hex digits|AQ==>"); return true;
|
||||
}
|
||||
if (!strcmp(key_text, "AQ==")) memcpy(channel.channel.secret, mesh::mt::DefaultPsk, 16);
|
||||
else {
|
||||
const size_t digits = strlen(key_text);
|
||||
if ((digits != 32 && digits != 64)
|
||||
|| !mesh::Utils::fromHex(channel.channel.secret, digits / 2, key_text)) {
|
||||
snprintf(reply, capacity, "Error: key must be 32/64 hex digits or AQ=="); return true;
|
||||
mesh::cli::formatError(reply, capacity, "key must be 32/64 hex digits or AQ=="); return true;
|
||||
}
|
||||
}
|
||||
if (!validateMeshtextChannelChange(index, channel)) {
|
||||
snprintf(reply, capacity, "Error: conflicting Meshtext preset, region, manual radio2 or busy owner"); return true;
|
||||
mesh::cli::formatError(reply, capacity, "conflicting Meshtext preset, region, manual radio2 or busy owner"); return true;
|
||||
}
|
||||
}
|
||||
if (!setChannel(index, channel)) snprintf(reply, capacity, "Error: invalid Meshtext channel");
|
||||
if (!setChannel(index, channel)) mesh::cli::formatError(reply, capacity, "invalid Meshtext channel");
|
||||
else if (!saveChannels()) {
|
||||
setChannel(index, previous);
|
||||
snprintf(reply, capacity, "Error: channel not saved; previous channel restored");
|
||||
mesh::cli::formatError(reply, capacity, "channel not saved; previous channel restored");
|
||||
} else {
|
||||
_mt_seen.clear(); _mt_profile_dirty = true;
|
||||
refreshMeshtextProfile();
|
||||
@@ -848,7 +848,7 @@ bool MyMesh::handleMeshtextCommand(const char* command, char* reply, size_t capa
|
||||
if (!mesh::mt::parsePreset(preset_value, preset)
|
||||
|| !mesh::mt::modemConfig(meshtextRegion(), preset, requested, _mt_slot)
|
||||
|| !_radio->supportsMeshtext() || !_radio->validateProfile(requested)) {
|
||||
snprintf(reply, capacity, "Error: invalid Meshtext preset/region/slot; use set mt.region first"); return true;
|
||||
mesh::cli::formatError(reply, capacity, "invalid Meshtext preset/region/slot; use set mt.region first"); return true;
|
||||
}
|
||||
// Explicit provisioning for custom private names. This is a manual saved
|
||||
// radio2 choice, not an automatic alias owner, so deletion cannot undo it.
|
||||
@@ -896,16 +896,16 @@ bool MyMesh::handleMeshtextCommand(const char* command, char* reply, size_t capa
|
||||
if (rebroadcast_value) {
|
||||
if (!strcmp(rebroadcast_value, "on")) rebroadcast = 1;
|
||||
else if (!strcmp(rebroadcast_value, "off")) rebroadcast = 0;
|
||||
else { snprintf(reply, capacity, "Error: use set mt.rebroadcast on|off"); return true; }
|
||||
else { mesh::cli::formatError(reply, capacity, "use set mt.rebroadcast on|off"); return true; }
|
||||
}
|
||||
if (region_value && !mesh::mt::parseRegion(region_value, region)) {
|
||||
snprintf(reply, capacity, "Error: use set mt.region auto|us|eu868|eu433|anz"); return true;
|
||||
mesh::cli::formatError(reply, capacity, "use set mt.region auto|us|eu868|eu433|anz"); return true;
|
||||
}
|
||||
if (slot_value && (!mesh::cli::parseUnsignedIntegerStrict(slot_value, slot) || slot > 1024)) {
|
||||
snprintf(reply, capacity, "Error: mt.slot must be 0 (preset default) or 1..1024"); return true;
|
||||
mesh::cli::formatError(reply, capacity, "mt.slot must be 0 (preset default) or 1..1024"); return true;
|
||||
}
|
||||
if (hops_value && (!mesh::cli::parseUnsignedIntegerStrict(hops_value, hops) || hops > 7)) {
|
||||
snprintf(reply, capacity, "Error: mt.hops must be 0..7"); return true;
|
||||
mesh::cli::formatError(reply, capacity, "mt.hops must be 0..7"); return true;
|
||||
}
|
||||
if (node_value) {
|
||||
if (!strcmp(node_value, "default")) node_override = 0;
|
||||
@@ -913,23 +913,23 @@ bool MyMesh::handleMeshtextCommand(const char* command, char* reply, size_t capa
|
||||
if (*node_value == '!') ++node_value;
|
||||
uint8_t bytes[4];
|
||||
if (strlen(node_value) != 8 || !mesh::Utils::fromHex(bytes, sizeof(bytes), node_value)) {
|
||||
snprintf(reply, capacity, "Error: use set mt.node !<8 hex digits>|default"); return true;
|
||||
mesh::cli::formatError(reply, capacity, "use set mt.node !<8 hex digits>|default"); return true;
|
||||
}
|
||||
node_override = (uint32_t(bytes[0]) << 24) | (uint32_t(bytes[1]) << 16)
|
||||
| (uint32_t(bytes[2]) << 8) | uint32_t(bytes[3]);
|
||||
if (!node_override || !validNodeOverride(node_override)) {
|
||||
snprintf(reply, capacity, "Error: mt.node IDs 0..3 and ffffffff are reserved; use default to reset"); return true;
|
||||
mesh::cli::formatError(reply, capacity, "mt.node IDs 0..3 and ffffffff are reserved; use default to reset"); return true;
|
||||
}
|
||||
}
|
||||
}
|
||||
if (short_name_value) {
|
||||
short_name = !strcmp(short_name_value, "default") ? "" : short_name_value;
|
||||
if ((!*short_name && strcmp(short_name_value, "default")) || !validShortName(short_name)) {
|
||||
snprintf(reply, capacity, "Error: mt.shortname must be 1..4 UTF-8 characters (no spaces/control/colon), or default"); return true;
|
||||
mesh::cli::formatError(reply, capacity, "mt.shortname must be 1..4 UTF-8 characters (no spaces/control/colon), or default"); return true;
|
||||
}
|
||||
}
|
||||
if (!saveMeshtextSettings(region, slot, hops, short_name, node_override, rebroadcast))
|
||||
snprintf(reply, capacity, "Error: Meshtext settings not saved (pending TX or storage error)");
|
||||
mesh::cli::formatError(reply, capacity, "Meshtext settings not saved (pending TX or storage error)");
|
||||
else if (rebroadcast_value)
|
||||
snprintf(reply, capacity, "OK - mt.rebroadcast=%s; extra wait=5 packet airtimes", rebroadcast ? "on" : "off");
|
||||
else if (node_value)
|
||||
|
||||
@@ -199,6 +199,16 @@ private:
|
||||
}
|
||||
}
|
||||
|
||||
void clearHash(const uint8_t* hash) {
|
||||
uint8_t* sp = _hashes;
|
||||
for (int i = 0; i < MAX_PACKET_HASHES; i++, sp += MAX_HASH_SIZE) {
|
||||
if (memcmp(hash, sp, MAX_HASH_SIZE) == 0) {
|
||||
memset(sp, 0, MAX_HASH_SIZE);
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
int8_t weightedSnrX4RoundUp(int8_t curr_snr_x4, int8_t new_snr_x4) const {
|
||||
// Keep existing SNR heavier than a single new sample: 75% existing + 25% new.
|
||||
int32_t weighted_sum = ((int32_t)curr_snr_x4 * 3) + (int32_t)new_snr_x4;
|
||||
@@ -433,17 +443,22 @@ public:
|
||||
return;
|
||||
}
|
||||
|
||||
uint8_t* sp = _hashes;
|
||||
for (int i = 0; i < MAX_PACKET_HASHES; i++, sp += MAX_HASH_SIZE) {
|
||||
if (memcmp(key.hash, sp, MAX_HASH_SIZE) == 0) {
|
||||
memset(sp, 0, MAX_HASH_SIZE);
|
||||
break;
|
||||
}
|
||||
}
|
||||
clearHash(key.hash);
|
||||
}
|
||||
|
||||
void clear(const mesh::Packet* packet) override {
|
||||
clearSeenKey(seenKey(*packet));
|
||||
// Packet callers do not need a retained token. Keep this path direct so
|
||||
// small targets avoid its initialization and return-value overhead.
|
||||
if (isDedicatedAckPacket(packet)) {
|
||||
uint8_t hash[MAX_HASH_SIZE];
|
||||
packet->calculatePacketHash(hash);
|
||||
clearAckHash(hash);
|
||||
return;
|
||||
}
|
||||
|
||||
uint8_t hash[MAX_HASH_SIZE];
|
||||
packet->calculatePacketHash(hash);
|
||||
clearHash(hash);
|
||||
}
|
||||
|
||||
uint32_t getNumDirectDups() const { return _direct_dups; }
|
||||
|
||||
Reference in new issue
Block a user