mirror of
https://github.com/liquidraver/ZephCore.git
synced 2026-10-15 07:19:56 +00:00
self-limiting handlers fix
This commit is contained in:
@@ -1371,11 +1371,17 @@ void RepeaterMesh::handleCommand(uint32_t sender_timestamp, char* command, char*
|
||||
|
||||
while (*command == ' ') command++;
|
||||
|
||||
uint8_t hdr_used = 0;
|
||||
if (strlen(command) > 4 && command[2] == '|') {
|
||||
memcpy(reply, command, 3);
|
||||
reply += 3;
|
||||
command += 3;
|
||||
hdr_used = 3;
|
||||
}
|
||||
/* Tell the shared CLI how much of the caller's buffer is already spent, so
|
||||
* the self-limiting handlers do not write past temp[5 + CLI_REMOTE_REPLY_SIZE].
|
||||
* Set unconditionally: a stale value would shrink the next reply. */
|
||||
_cli.setReplyHeaderUsed(hdr_used);
|
||||
|
||||
#if IS_ENABLED(CONFIG_ZEPHCORE_REPEATER_UPLINK) && IS_ENABLED(CONFIG_MQTT_LIB)
|
||||
if (handleUplinkCommand(command, reply)) {
|
||||
|
||||
@@ -1030,11 +1030,17 @@ void RoomServerMesh::handleCommand(uint32_t sender_timestamp, char* command, cha
|
||||
|
||||
while (*command == ' ') command++;
|
||||
|
||||
uint8_t hdr_used = 0;
|
||||
if (strlen(command) > 4 && command[2] == '|') {
|
||||
memcpy(reply, command, 3);
|
||||
reply += 3;
|
||||
command += 3;
|
||||
hdr_used = 3;
|
||||
}
|
||||
/* Tell the shared CLI how much of the caller's buffer is already spent, so
|
||||
* the self-limiting handlers do not write past temp[5 + CLI_REMOTE_REPLY_SIZE].
|
||||
* Set unconditionally: a stale value would shrink the next reply. */
|
||||
_cli.setReplyHeaderUsed(hdr_used);
|
||||
|
||||
// ACL commands - supports BOTH formats for app compatibility:
|
||||
// Old Arduino: setperm {pubkey-hex} {permissions} (pubkey is long, perms is short)
|
||||
|
||||
@@ -683,9 +683,15 @@ void CommonCLI::handleCommand(uint32_t sender_timestamp, const char* command, ch
|
||||
} else if (memcmp(config, "tz.offset", 9) == 0) {
|
||||
snprintf(reply, CLI_REPLY_SIZE, "> %d", (int)_prefs->tz_offset);
|
||||
} else if (memcmp(config, "gps diag", 8) == 0) {
|
||||
// What the last module-configuration attempt actually did.
|
||||
/* What the last module-configuration attempt actually did.
|
||||
* Self-limits on the remote path like cad.stats/meshtimesync:
|
||||
* gps_get_diag_report() bounds itself by the length it is
|
||||
* handed, and the full report (long module version + wide
|
||||
* counters + the no-GPS_SAT_DIAG tail) can exceed the
|
||||
* caller's packet buffer. */
|
||||
size_t cap = replyCap(sender_timestamp);
|
||||
reply[0] = '>'; reply[1] = ' ';
|
||||
gps_get_diag_report(reply + 2, CLI_REPLY_SIZE - 2);
|
||||
gps_get_diag_report(reply + 2, cap - 2);
|
||||
} else if (memcmp(config, "gps duty", 8) == 0) {
|
||||
uint32_t s = gps_get_poll_interval_sec(); // now-effective value
|
||||
if (s == 0) strcpy(reply, "> always on (0)");
|
||||
@@ -706,8 +712,7 @@ void CommonCLI::handleCommand(uint32_t sender_timestamp, const char* command, ch
|
||||
/* Runtime state + per-level probe stats live in the radio.
|
||||
* ZephCore-only; must stay ahead of the "cad" prefix match below.
|
||||
* Remote replies get the truncated buffer like meshtimesync. */
|
||||
size_t cap = (sender_timestamp == 0) ? CLI_REPLY_SIZE
|
||||
: CLI_REMOTE_REPLY_SIZE;
|
||||
size_t cap = replyCap(sender_timestamp);
|
||||
int n = snprintf(reply, cap, "> ");
|
||||
if (_callbacks->formatCadStatus(reply + n, (int)cap - n) == 0) {
|
||||
strcpy(reply, "not available");
|
||||
@@ -758,8 +763,7 @@ void CommonCLI::handleCommand(uint32_t sender_timestamp, const char* command, ch
|
||||
/* Only the local USB CLI (sender_timestamp == 0) gets the
|
||||
* full evidence table; remote replies are truncated to the
|
||||
* packet buffer. */
|
||||
size_t cap = (sender_timestamp == 0) ? CLI_REPLY_SIZE
|
||||
: CLI_REMOTE_REPLY_SIZE;
|
||||
size_t cap = replyCap(sender_timestamp);
|
||||
ts->formatStatus(reply, cap, getRTCClock()->getCurrentTime(),
|
||||
(uint32_t)(k_uptime_get() / 1000),
|
||||
_prefs->meshtimesync != 0);
|
||||
|
||||
@@ -134,6 +134,18 @@ class CommonCLI {
|
||||
int64_t _reboot_deadline_ms;
|
||||
static void rebootWorkHandler(struct k_work *work);
|
||||
|
||||
/* Bytes the caller already consumed at the head of the reply buffer before
|
||||
* handing it to us — see setReplyHeaderUsed(). */
|
||||
uint8_t _reply_hdr_used;
|
||||
|
||||
/* Space a handler may write at `reply`, terminator included. Local USB
|
||||
* gets the full buffer; a remote reply rides in the caller's packet buffer
|
||||
* and must also leave room for whatever the caller wrote ahead of us. */
|
||||
size_t replyCap(uint32_t sender_timestamp) const {
|
||||
return (sender_timestamp == 0) ? CLI_REPLY_SIZE
|
||||
: (CLI_REMOTE_REPLY_SIZE - _reply_hdr_used);
|
||||
}
|
||||
|
||||
mesh::RTCClock* getRTCClock() { return _rtc; }
|
||||
void savePrefs();
|
||||
void scheduleReboot(uint8_t type);
|
||||
@@ -142,11 +154,18 @@ public:
|
||||
CommonCLI(mesh::MainBoard& board, mesh::RTCClock& rtc, ClientACL& acl,
|
||||
NodePrefs* prefs, CommonCLICallbacks* callbacks)
|
||||
: _board(&board), _rtc(&rtc), _acl(&acl), _prefs(prefs), _callbacks(callbacks),
|
||||
_pending_reboot(REBOOT_NONE), _reboot_deadline_ms(0)
|
||||
_pending_reboot(REBOOT_NONE), _reboot_deadline_ms(0), _reply_hdr_used(0)
|
||||
{
|
||||
k_work_init_delayable(&_reboot_work, rebootWorkHandler);
|
||||
}
|
||||
|
||||
/* Roles that strip the `XX|` request-tag prefix echo those 3 bytes into the
|
||||
* head of the reply buffer and advance `reply` past them before calling us.
|
||||
* Their buffer is still only 5 + CLI_REMOTE_REPLY_SIZE, so the self-limiting
|
||||
* handlers have to subtract what was already written or they overrun it.
|
||||
* Call this on EVERY dispatch, with 0 when no prefix was stripped. */
|
||||
void setReplyHeaderUsed(uint8_t n) { _reply_hdr_used = n; }
|
||||
|
||||
void handleCommand(uint32_t sender_timestamp, const char* command, char* reply);
|
||||
uint8_t buildAdvertData(uint8_t node_type, uint8_t* app_data);
|
||||
|
||||
|
||||
Reference in New Issue
Block a user