From b92242f911d6ac95180916f62632b60868254bb1 Mon Sep 17 00:00:00 2001 From: Serge Camille Date: Tue, 18 Aug 2020 21:35:30 +0200 Subject: [PATCH 1/2] Adjust AssertPduSize checks for Reading multiple DataItems. 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. --- S7.Net/PLC.cs | 6 +++--- S7.Net/PlcAsynchronous.cs | 4 ++-- S7.Net/PlcSynchronous.cs | 6 ++---- 3 files changed, 7 insertions(+), 9 deletions(-) diff --git a/S7.Net/PLC.cs b/S7.Net/PLC.cs index f11e568..58595c7 100644 --- a/S7.Net/PLC.cs +++ b/S7.Net/PLC.cs @@ -183,10 +183,10 @@ namespace S7.Net private void AssertPduSizeForRead(ICollection dataItems) { - // 12 bytes of header data, 12 bytes of parameter data for each dataItem - if ((dataItems.Count + 1) * 12 > MaxPDUSize) throw new Exception("Too many vars requested for read"); + // send request limit: 19 bytes of header data, 12 bytes of parameter data for each dataItem + if (19 + dataItems.Count * 12 > MaxPDUSize) throw new Exception("Too many vars requested for read"); - // 14 bytes of header data, 4 bytes of result data for each dataItem and the actual data + // response limit: 14 bytes of header data, 4 bytes of result data for each dataItem and the actual data if (GetDataLength(dataItems) + dataItems.Count * 4 + 14 > MaxPDUSize) throw new Exception("Too much data requested for read"); } diff --git a/S7.Net/PlcAsynchronous.cs b/S7.Net/PlcAsynchronous.cs index 6a63ddd..c6d7388 100644 --- a/S7.Net/PlcAsynchronous.cs +++ b/S7.Net/PlcAsynchronous.cs @@ -209,9 +209,9 @@ namespace S7.Net /// You have to create and pass a list of DataItems and you obtain in response the same list with the values. /// Values are stored in the property "Value" of the dataItem and are already converted. /// If you don't want the conversion, just create a dataItem of bytes. - /// DataItems must not be more than 20 (protocol restriction) and bytes must not be more than 200 + 22 of header (protocol restriction). + /// The number of DataItems as well as the total size of the requested data can not exceed a certain limit (protocol restriction). /// - /// List of dataitems that contains the list of variables that must be read. Maximum 20 dataitems are accepted. + /// List of dataitems that contains the list of variables that must be read. public async Task> ReadMultipleVarsAsync(List dataItems) { //Snap7 seems to choke on PDU sizes above 256 even if snap7 diff --git a/S7.Net/PlcSynchronous.cs b/S7.Net/PlcSynchronous.cs index 9ae2cc0..bf0a1a3 100644 --- a/S7.Net/PlcSynchronous.cs +++ b/S7.Net/PlcSynchronous.cs @@ -500,13 +500,11 @@ namespace S7.Net /// You have to create and pass a list of DataItems and you obtain in response the same list with the values. /// Values are stored in the property "Value" of the dataItem and are already converted. /// If you don't want the conversion, just create a dataItem of bytes. - /// DataItems must not be more than 20 (protocol restriction) and bytes must not be more than 200 + 22 of header (protocol restriction). + /// The number of DataItems as well as the total size of the requested data can not exceed a certain limit (protocol restriction). /// - /// List of dataitems that contains the list of variables that must be read. Maximum 20 dataitems are accepted. + /// List of dataitems that contains the list of variables that must be read. public void ReadMultipleVars(List dataItems) { - //Snap7 seems to choke on PDU sizes above 256 even if snap7 - //replies with bigger PDU size in connection setup. AssertPduSizeForRead(dataItems); var stream = GetStreamIfAvailable(); From eca2ed64747f001a391c3907f960f9eb6f606f3e Mon Sep 17 00:00:00 2001 From: Serge Camille Date: Fri, 21 Aug 2020 15:48:09 +0200 Subject: [PATCH 2/2] Add required request & response sizes to PDU limit exception messages. --- S7.Net/PLC.cs | 8 +++++--- 1 file changed, 5 insertions(+), 3 deletions(-) diff --git a/S7.Net/PLC.cs b/S7.Net/PLC.cs index 58595c7..e4a7f7f 100644 --- a/S7.Net/PLC.cs +++ b/S7.Net/PLC.cs @@ -184,10 +184,12 @@ namespace S7.Net private void AssertPduSizeForRead(ICollection dataItems) { // send request limit: 19 bytes of header data, 12 bytes of parameter data for each dataItem - if (19 + dataItems.Count * 12 > MaxPDUSize) throw new Exception("Too many vars requested for read"); - + var requiredRequestSize = 19 + dataItems.Count * 12; + if (requiredRequestSize > MaxPDUSize) throw new Exception($"Too many vars requested for read. Request size ({requiredRequestSize}) is larger than protocol limit ({MaxPDUSize})."); + // response limit: 14 bytes of header data, 4 bytes of result data for each dataItem and the actual data - if (GetDataLength(dataItems) + dataItems.Count * 4 + 14 > MaxPDUSize) throw new Exception("Too much data requested for read"); + var requiredResponseSize = GetDataLength(dataItems) + dataItems.Count * 4 + 14; + if (requiredResponseSize > MaxPDUSize) throw new Exception($"Too much data requested for read. Response size ({requiredResponseSize}) is larger than protocol limit ({MaxPDUSize})."); } private void AssertPduSizeForWrite(ICollection dataItems)