httpd: clear upload reset intent when the TCP slot is reused

With UIP_CONF_MAX_CONNECTIONS set to one, a verified upload can leave
reset intent set when its response is never acknowledged. A subsequent
TCP connection reuses that slot, and ACKing its plain GET response can
otherwise trigger reset_chip(). This is sequential slot reuse, not
concurrent HTTP connections.

Store reset intent in the connection appstate and initialize both tstate
and fw_reset_pending on every uip_connected() event, regardless of stale
appstate contents. Reset only after the verified upload response is fully
acknowledged.

Exercise the real HTTP callback for all stale tstate bytes, sequential
slot reuse and a later GET, partial/final ACKs, abort, timeout and CRC
failure. Keep the regression tests in the existing tab-indented style.
This commit is contained in:
avicarmeli committed 2026-10-20 18:47:33 +03:00
1 parent b28ead65dc
commit 491a919105
3 files changed
+122 -8

No files matched your search

+4 -7
View File
@@ -75,9 +75,6 @@ __xdata uint8_t postbody_endpoint;
__xdata uint16_t postbody_start;
__xdata char passwd[21];
// Set when a verified firmware upload awaits its response ACK, after
// which the chip resets to apply the staged image
__xdata uint8_t fw_reset_pending;
__xdata char session_id[SESSION_ID_LENGTH + 1];
__xdata uint8_t authenticated;
__xdata uint32_t now;
@@ -110,7 +107,6 @@ void httpd_init(void) __banked
// Not through uip_conn: it only points at a connection while uIP is
// handling one, and nothing has set it yet at init time.
uip_conns[0].appstate.tstate = TSTATE_CLOSED;
fw_reset_pending = 0; // xdata is not zeroed by the startup code
}
@@ -511,7 +507,7 @@ uint8_t stream_upload(void)
"Content-Type: text/plain\r\n\r\n"
"OK: checksum verified, rebooting\n");
// Reset once the response is fully ACKed
fw_reset_pending = 1;
s->fw_reset_pending = 1;
} else {
print_string("Checksum incorrect! Aborting.\n");
slen = strtox(outbuf, "HTTP/1.1 400 Bad Request\r\nContent-Length: 33\r\n"
@@ -874,9 +870,10 @@ void httpd_appcall(void)
print_byte(s->tstate);
write_char(' ');
#endif
if(uip_connected() && s->tstate == TSTATE_CLOSED) {
if(uip_connected()) {
dbg_string("Connected...\n");
s->tstate = TSTATE_NONE;
s->fw_reset_pending = 0; // explicitly initialize reused XDATA appstate
} else if (uip_closed()) {
dbg_string("Connection closed\n");
s->tstate = TSTATE_CLOSED;
@@ -928,7 +925,7 @@ void httpd_appcall(void)
cont_len -= slen;
cont_addr += slen;
s->tstate = TSTATE_TX;
} else if (fw_reset_pending) {
} else if (s->fw_reset_pending) {
// The upload verdict has been fully ACKed by the client;
// now it is safe to reset and apply the staged image
print_string("Resetting to apply update\n");
+1
View File
@@ -12,6 +12,7 @@
for each TCP connection. */
typedef struct httpd_state {
uint8_t tstate;
uint8_t fw_reset_pending;
} uip_tcp_appstate_t;
/* Finally we define the application function to be called by uIP. */