Skip to content

TCP config writes are silently lost on Linux as well (2.7.11, ESP32-S3) #985

Description

@Simplycissmus

Summary

--set over TCP is silently lost against an ESP32-S3 node on Linux, with 2.7.11 — the
release that contains the #958 fix. #957 concluded the loss was Windows-only ("Same
commands work on Linux"); on this hardware it is not.

Two nodes, two client machines, verified by reading the value back over the other
transport rather than the one the write took.

Setup

One of the nodes has both USB serial and WiFi up, so the same device can be written one
way and read the other. Seeed XIAO ESP32S3, firmware 2.8.0.74578a8 (a build of
develop; I have not tried a release build). Clients: Debian 12 and CachyOS, both with
meshtastic 2.7.11 from PyPI.

write read back over result
--host <ip> --set display.screen_on_secs N serial unchanged, 6 of 6
--host <ip> --set … --wait-to-disconnect 8 serial applied
--port /dev/ttyACM0 --set … TCP applied

A second unit of the same model behaves the same over TCP.

The CLI reports success either way: it prints Set display.screen_on_secs to N,
Writing modified preferences to device and Writing display configuration to device
even when nothing is written. A BrokenPipeError sometimes precedes that and sometimes
does not, so it is not a usable signal — and it also shows up on successful reads, which
is #962.

What differs between the two transports

--debug shows both building the same packet — ADMIN_APP to the node's own number,
pki_encrypted: true, want_ack: true — both obtaining a sessionkey, and both logging
Wrote: display.

The difference is what comes back. Over serial:

ROUTING_APP … request_id: … routing { errorReason: NONE }

Over TCP nothing comes back; the CLI sends disconnect: true and closes first. The
device logs, at that moment:

[E][NetworkClient.cpp:435] write(): fail on fd 52, errno: 104, "Connection reset by peer"

That is the node failing to send the ack above.

Why the #958 fix does not cover this

Raising GRACEFUL_CLOSE_TIMEOUT from 0.25 to 5.0 changes nothing — two further writes,
both lost. _wait_for_reader_exit() returns as soon as the reader exits, and the
disconnect: true sent just before close causes exactly that. The half-close does
happen; the wait is simply over long before the device has applied the admin packet.

One thing worth separating while you are in there: #957 attributes the loss to Winsock
discarding received-but-unread data on RST. The receive buffer that matters here is the
device's, not the client's — the RST arrives at the ESP32. That would explain why a
client-side platform distinction does not hold up.

Ruled out

  • A second client competing for the node's TCP server — same result with our
    once-a-minute telemetry poller stopped.
  • The field or the value — several fields, plain integers, same outcome.
  • One bad node — two units, and two different Linux clients.

Workaround

--wait-to-disconnect 8 makes the write land every time. Useful for anyone scripting
against a node over the network in the meantime.

Activity

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions