From inspection:
• v1.7.0's INIT decodes the I payload into the same buffer as T output data, so every INIT transiently drives garbage onto layout outputs until the first T message.
- DECODE_CMD routes both SET and INIT into the same DECODE_DATA state (src/CMRI.cpp:200-203).
- DECODE_DATA stores incoming body bytes into _rx_buffer unconditionally — it never consults _rx_packet_type (src/CMRI.cpp:214-224). So after an I frame completes, _rx_buffer[0..n] literally contains NDP dH dL NS CT..., and nothing restores the previous output image (POSTAMBLE_SET at 252-256 just resets parser state).
- get_bit()/get_byte() read _rx_buffer with no packet-type gating (src/CMRI.cpp:103-117).
Between the I frame's ETX and the first subsequent T frame, get_bit(0) returns bit 0 of the NDP byte (e.g. 'M' = 0x4D → bit0 = 1) and the sketch drives that to the pin.
A defensive sketch that only writes outputs when process() returns true can't avoid it: process() returns true for INIT as well (src/CMRI.cpp:90-94), and the bool return can't distinguish INIT from SET.
The observable window here is short - JMRI follows an INIT with an immediate TRANSMIT a few mS later...
pre-v1.7.0 versions didn't have this issue because I bodies never reached DECODE_DATA.
From inspection:
• v1.7.0's INIT decodes the I payload into the same buffer as T output data, so every INIT transiently drives garbage onto layout outputs until the first T message.
Between the I frame's ETX and the first subsequent T frame, get_bit(0) returns bit 0 of the NDP byte (e.g. 'M' = 0x4D → bit0 = 1) and the sketch drives that to the pin.
A defensive sketch that only writes outputs when process() returns true can't avoid it: process() returns true for INIT as well (src/CMRI.cpp:90-94), and the bool return can't distinguish INIT from SET.
The observable window here is short - JMRI follows an INIT with an immediate TRANSMIT a few mS later...
pre-v1.7.0 versions didn't have this issue because I bodies never reached DECODE_DATA.