ascii: discard stray bytes outside the frame#15
Open
andig wants to merge 2 commits into
Open
Conversation
Some serial adapters (e.g. the FTDI based ABL Confcab) inject stray bytes such as NUL before, after or in between the Modbus ASCII frame. These broke framing and LRC verification, causing timeouts. Extract the frame from the raw response by skipping to the start character, keeping only hexadecimal digits and stopping at the terminating CRLF. The read loop now also detects the CRLF anywhere in the buffer so trailing junk no longer delays the read.
premultiply
reviewed
Jun 6, 2026
|
|
||
| // isHexDigit reports whether b is an ASCII hexadecimal digit (0-9, A-F, a-f). | ||
| func isHexDigit(b byte) bool { | ||
| return b >= '0' && b <= '9' || b >= 'A' && b <= 'F' || b >= 'a' && b <= 'f' |
Member
There was a problem hiding this comment.
only 0-9 or A-F (uppercase) is allowed inside a frame between the delimiters.
Other chars inside should instantly break as framing error.
Member
Author
There was a problem hiding this comment.
would be simpler to just suggest the actual change ;)
Member
There was a problem hiding this comment.
Yes, but I am currently at mobile phone.
Other chars inside should instantly break as framing error.
Is that also implemented and tested regarding data inside a frame?
andig
commented
Jun 6, 2026
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Problem
Some serial adapters insert stray bytes around Modbus ASCII frames. The FTDI FT2232H based ABL Confcab adapter (used to talk to ABL eMH1 wallboxes) wraps each response in NUL (
0x00) bytes before and after the frame. The ASCII driver assumed the received buffer is exactly:…<CR><LF>, so these extra bytes broke:aduResponse[0]was0x00, not:)…which surfaced as timeouts when reading from the wallbox. Users have had to run an external proxy to clean the stream.
Reported in evcc-io/evcc discussion #16328.
Fix
Per @premultiply: ignore everything outside the frame. A valid frame starts with a start character (
:or>), contains only hexadecimal digits and ends with<CR><LF>.extractASCIIFrameskips to the start character, keeps only hex digits, and stops at the terminating CRLF — dropping any stray bytes before, after or interspersed. If no start character is present the input is returned unchanged so verification still reports the original response.bytes.Contains) instead of only at the very end, so trailing junk after CRLF no longer delays the read until timeout.The raw bytes are still logged before sanitization.
Tests
Added
TestExtractASCIIFrame(clean, leading/trailing/surrounding/interspersed NUL,>start, lone LF, no start char, no terminator) andTestASCIIDecodeDirtyFrame(NUL-wrapped frame passesVerify+Decode). All ASCII tests pass;go build ./...andgo vetclean for the package.