The idea behind this is that if we receive a response which does not conform to the underlying protocol specification (with all the TCP checks in place!), we are in a weird/corrupt state and it is better to just close the connection.
Add support for custom addressing by supplying a TsapPair to the PLC.
CPU, Rack and Slot properties are still present to preserve backwards
compatibility and to support alternate functionality based on the PLC
type.
This helps to avoid deadlocks when using synchronous API which references the async one in applications with a synchronization context, like a GUI.
Should fix#344
- Separate into Connect and EstablishConnection step.
- Remove redundant null checks for returned data.
- Only assing PLC stream object once we fully established a connection, and Close otherwise.
- Replace sync implementation with Async call.
The limit calculations did not match what the send and parsing code expected.
sending request header seems to be 19 byte in general.
Also adjust XML comments somewhat, since max PDU really differs a lot between PLC types, from 240 to 960 afaik.
I don't know what the correct expected connection response size is, so I just added checks for the minimal index access by the current code.
This change will just change NullReferenceExceptions into WrongNumberOfBytesException when the PLC response with not enough data for a connection attempt.
The previous problem of not being able to use a larger chunk size than 200 was that the complete header building code for the async implementation was incorrect. Specifically, it wrote the package size only as a byte instead of a int16, thus restricting the package size to something < 256.
With the sharing of the Header building code in the previous commits, this problem was resolved by accident, and thus the chunk size can be increased to the maximum value allowed by the PDUSize.
Both Synchronous and Asynchronous need to build the same binary data package to write a bytes array. Move that package building out into a common function.
Also use IEnumerable to pass in data instead of converting it to array and back multiple times. Not that happy with the whole ByteArray class, we could probably just use a MemoryStream instead.
This requires reference types that can be null to be annotated by a ? operator, similar to value types.
This gives the advantage that the compiler can warn against any null dereference exceptions, of which this commits elimits a few.
To make the underlying protocol implementation not any more complicated and to eliminate existing problems, and not that precise error reporting, I replaced some return null statements with explicit Exceptions. This lead to the assumption that those core protocoll functions always return non-null objects if they do not throw, making the PLC code simpler.
Adjust some NotConnected tests to look for explicit PlcException instead of NullReferenceException.