So I tried to read 19 single bytes and got an CliSizeOverPDU error, because the PDU was calculated to be 247 bytes (240 bytes negotiated on a S7 300 PLC)! In the ReadMultiVars-Function the calculation is as follows: 19 byte upfront and then plus 12 bytes for every item regardless of it's length or anything. At the beginning of the function an S7Item byte[] is allocated that is 12 bytes long and for every item the following is done:
Offset += S7Item.Length
When I comment the PDU check my values get read fine without an error so as long as I read max 19 items if i try to read 20 items (20 bytes) I get the error code 5.
So 1: I guess the PDU length calculation in ReadMultiVars for Sharp7 1.0.3 is bugged
and 2: What is the actual formula to calculate how many items I can pack in one telegram or why can't I read 20 items, respectively. I had the problem that I can only read 19 instead of 20 items with Snap7, too. Because my PDU length is always 240 I guess there is a mistake in the formula above.
Any help will be greatly appreciated.
Best Regards
Last edit: Legge 2017-02-03
If you would like to refer to this comment somewhere else in this project, copy and paste the following link:
At the beginning of Snap7 developing process I made many tests with many CPU and noticed that for some CPU the PDU was considered to be the whole TPKT+ISO+S7 Packet, for some others the PDU was only the S7 Packet.
Since there are no official protocol specification I opted for the the most conservative hypothesis.
Pinning this statement, it will be useful in future.
My answer that you linked is not wrong but is a bit incomplete, I forgot to mention the request packet size and this caused confusion in your analysis.
Now let's start The Game ;)
A S7 transaction is composed by two packets : the request, from PC to PLC, and the answer from PLC to PC.
The length of both must be less than or equal to the size of the PDU negotiated during the connection.
For now let shall suppose to work with an S7300 considering the first option.
I attached two pictures of Wireshark.
Picture "Request", the S7 frame of the MultiRead var function is composed by 12 bytes of function header + 12 bytes for each descriptor
item.
If you request 20 items, regardless of their size you need of:
7 + 12 + 20*12 = 259 bytes which is too big for a PDU.
If you request 19 items, your telegram is:
7 + 12 + 19*12 = 247 bytes which can be accepted by some CPU under the 2nd option (7 + 240) but under the 1st option is refused by sharp7.
If you are confident for the 2nd option you could modify the PDU check from:
if (Offset > _PDULength)
return S7Consts.errCliSizeOverPDU;
To:
if (Offset > _PDULength + 7)
return S7Consts.errCliSizeOverPDU;
But I will not do this.
Into the "Answer" picture you will find the explaination of the Payload formula, but it is not enough...
For every item, if the size of the required data is odd, we must add one byte of "padding".
This is handled here:
if (ItemSize % 2 != 0)
ItemSize++;
So, You can transfer at least 20 vars but the request and the answer whole telegram size must not exceed the PDU.
There is no coded formula for this but the library checks that you don't send packets bigger than the PDU and the CPU, from the other side, refuses the incorrect telegrams.
thank you for the detailed answer, it's very much appreciated.
So basically I only did the calculation for the answer telegram, but I have to make a seperate one to ensure the request telegram is small enough, too.
Last edit: Legge 2017-02-04
If you would like to refer to this comment somewhere else in this project, copy and paste the following link:
Hi,
according to this post the formula to calculate how many items one can pack using ReadMultiVars (as long as its max 20 items) is:
So I tried to read 19 single bytes and got an CliSizeOverPDU error, because the PDU was calculated to be 247 bytes (240 bytes negotiated on a S7 300 PLC)! In the ReadMultiVars-Function the calculation is as follows: 19 byte upfront and then plus 12 bytes for every item regardless of it's length or anything. At the beginning of the function an S7Item byte[] is allocated that is 12 bytes long and for every item the following is done:
When I comment the PDU check my values get read fine without an error so as long as I read max 19 items if i try to read 20 items (20 bytes) I get the error code 5.
So 1: I guess the PDU length calculation in ReadMultiVars for Sharp7 1.0.3 is bugged
and 2: What is the actual formula to calculate how many items I can pack in one telegram or why can't I read 20 items, respectively. I had the problem that I can only read 19 instead of 20 items with Snap7, too. Because my PDU length is always 240 I guess there is a mistake in the formula above.
Any help will be greatly appreciated.
Best Regards
Last edit: Legge 2017-02-03
Hi,
At the beginning of Snap7 developing process I made many tests with many CPU and noticed that for some CPU the PDU was considered to be the whole TPKT+ISO+S7 Packet, for some others the PDU was only the S7 Packet.
Since there are no official protocol specification I opted for the the most conservative hypothesis.
Pinning this statement, it will be useful in future.
My answer that you linked is not wrong but is a bit incomplete, I forgot to mention the request packet size and this caused confusion in your analysis.
Now let's start The Game ;)
A S7 transaction is composed by two packets : the request, from PC to PLC, and the answer from PLC to PC.
The length of both must be less than or equal to the size of the PDU negotiated during the connection.
An S7 Packet is composed by:
TPKT - 3 bytes
ISO-COTP - 4 bytes
S7 frame - variable size, conservative option : 233 bytes (=240-7) non conservative option : 240 bytes.
For now let shall suppose to work with an S7300 considering the first option.
I attached two pictures of Wireshark.
Picture "Request", the S7 frame of the MultiRead var function is composed by 12 bytes of function header + 12 bytes for each descriptor
item.
If you request 20 items, regardless of their size you need of:
7 + 12 + 20*12 = 259 bytes which is too big for a PDU.
If you request 19 items, your telegram is:
7 + 12 + 19*12 = 247 bytes which can be accepted by some CPU under the 2nd option (7 + 240) but under the 1st option is refused by sharp7.
If you are confident for the 2nd option you could modify the PDU check from:
if (Offset > _PDULength)
return S7Consts.errCliSizeOverPDU;
To:
if (Offset > _PDULength + 7)
return S7Consts.errCliSizeOverPDU;
But I will not do this.
Into the "Answer" picture you will find the explaination of the Payload formula, but it is not enough...
For every item, if the size of the required data is odd, we must add one byte of "padding".
This is handled here:
if (ItemSize % 2 != 0)
ItemSize++;
So, You can transfer at least 20 vars but the request and the answer whole telegram size must not exceed the PDU.
There is no coded formula for this but the library checks that you don't send packets bigger than the PDU and the CPU, from the other side, refuses the incorrect telegrams.
Hope this helps.
Last edit: Davide Nardella 2017-02-04
Hi,
thank you for the detailed answer, it's very much appreciated.
So basically I only did the calculation for the answer telegram, but I have to make a seperate one to ensure the request telegram is small enough, too.
Last edit: Legge 2017-02-04