Fix stray control bytes tearing down the ASTM connection#79
Merged
Conversation
5918546 to
7a7d64d
Compare
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.
Description of the issue/feature this PR addresses
Follow-up to #77 (chunked-frame reassembly). Raising inside an asyncio protocol's
data_received()is fatal -- it drops the connection. Several ASTM handlers raised on input that instruments legitimately send, so a single stray byte forced a disconnect/reconnect even when framing was fine:on_eot()raisedInvalidStatewhen an<EOT>arrived outside a transfer, but instruments emit stray<EOT>(and<EOT>/<ENQ>bursts) between sessions and while establishing.on_ack()/on_nak()raisedNotAcceptedon any<ACK>/<NAK>; as the receiver we should ignore these.Observed live against an Abbott ARCHITECT ci4100: after #77 made frames reassemble correctly,
<EOT>/<ENQ>bursts between sessions still crashed the connection repeatedly (disconnect + reconnect churn).Current behavior before PR
A stray
<EOT>outside a transfer, or any<ACK>/<NAK>, raises insidedata_received()and tears down the connection, forcing a reconnect. One unexpected byte can interrupt an otherwise healthy link.Desired behavior after PR is merged
Stray/unexpected control bytes are non-fatal:
on_eot()outside a transfer and unexpectedon_ack()/on_nak()log-and-ignore, and the unit-dispatch loop wrapshandle_data()intry/exceptso no single byte can drop the link. The stray-<EOT>branch does not callreset_session_state()(that would clear the buffer mid-dispatch and drop bytes following the EOT in the same read). Adds tests for stray<EOT>,<EOT>/<ENQ>bursts, an<EOT>+<ENQ>in one read, and unexpected<ACK>/<NAK>.--
I confirm I have tested this PR thoroughly and coded it according to PEP8
and Plone's Python styleguide standards.