mirror of
https://github.com/S7NetPlus/s7netplus.git
synced 2026-02-17 22:38:27 +08:00
Calculate PDU size constraints
This commit is contained in:
@@ -1,5 +1,8 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Net.Sockets;
|
||||
using S7.Net.Types;
|
||||
|
||||
|
||||
namespace S7.Net
|
||||
@@ -178,6 +181,25 @@ namespace S7.Net
|
||||
}
|
||||
}
|
||||
|
||||
private void AssertPduSizeForRead(ICollection<DataItem> 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");
|
||||
|
||||
// 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");
|
||||
}
|
||||
|
||||
private void AssertPduSizeForWrite(ICollection<DataItem> dataItems)
|
||||
{
|
||||
// 12 bytes of header data, 18 bytes of parameter data for each dataItem
|
||||
if (dataItems.Count * 18 + 12 > MaxPDUSize) throw new Exception("Too many vars supplied for write");
|
||||
|
||||
// 12 bytes of header data, 16 bytes of data for each dataItem and the actual data
|
||||
if (GetDataLength(dataItems) + dataItems.Count * 16 + 12 > MaxPDUSize)
|
||||
throw new Exception("Too much data supplied for write");
|
||||
}
|
||||
|
||||
private void ConfigureConnection()
|
||||
{
|
||||
if (tcpClient == null)
|
||||
@@ -189,6 +211,13 @@ namespace S7.Net
|
||||
tcpClient.SendTimeout = WriteTimeout;
|
||||
}
|
||||
|
||||
private int GetDataLength(IEnumerable<DataItem> dataItems)
|
||||
{
|
||||
// Odd length variables are 0-padded
|
||||
return dataItems.Select(di => VarTypeToByteLength(di.VarType, di.Count))
|
||||
.Sum(len => (len & 1) == 1 ? len + 1 : len);
|
||||
}
|
||||
|
||||
#region IDisposable Support
|
||||
private bool disposedValue = false; // To detect redundant calls
|
||||
|
||||
|
||||
@@ -205,15 +205,10 @@ namespace S7.Net
|
||||
/// <param name="dataItems">List of dataitems that contains the list of variables that must be read. Maximum 20 dataitems are accepted.</param>
|
||||
public async Task<List<DataItem>> ReadMultipleVarsAsync(List<DataItem> dataItems)
|
||||
{
|
||||
int cntBytes = dataItems.Sum(dataItem => VarTypeToByteLength(dataItem.VarType, dataItem.Count));
|
||||
|
||||
//TODO: Figure out how to use MaxPDUSize here
|
||||
//Snap7 seems to choke on PDU sizes above 256 even if snap7
|
||||
//replies with bigger PDU size in connection setup.
|
||||
if (dataItems.Count > 20)
|
||||
throw new Exception("Too many vars requested");
|
||||
if (cntBytes > 222)
|
||||
throw new Exception("Too many bytes requested"); // TODO: proper TDU check + split in multiple requests
|
||||
AssertPduSizeForRead(dataItems);
|
||||
|
||||
try
|
||||
{
|
||||
// first create the header
|
||||
@@ -410,6 +405,8 @@ namespace S7.Net
|
||||
/// <returns>Task that completes when response from PLC is parsed.</returns>
|
||||
public async Task WriteAsync(params DataItem[] dataItems)
|
||||
{
|
||||
AssertPduSizeForWrite(dataItems);
|
||||
|
||||
var message = new ByteArray();
|
||||
var length = S7WriteMultiple.CreateRequest(message, dataItems);
|
||||
await stream.WriteAsync(message.Array, 0, length).ConfigureAwait(false);
|
||||
|
||||
@@ -374,6 +374,8 @@ namespace S7.Net
|
||||
/// <param name="dataItems">The DataItem(s) to write to the PLC.</param>
|
||||
public void Write(params DataItem[] dataItems)
|
||||
{
|
||||
AssertPduSizeForWrite(dataItems);
|
||||
|
||||
var message = new ByteArray();
|
||||
var length = S7WriteMultiple.CreateRequest(message, dataItems);
|
||||
stream.Write(message.Array, 0, length);
|
||||
@@ -479,15 +481,10 @@ namespace S7.Net
|
||||
/// <param name="dataItems">List of dataitems that contains the list of variables that must be read. Maximum 20 dataitems are accepted.</param>
|
||||
public void ReadMultipleVars(List<DataItem> dataItems)
|
||||
{
|
||||
int cntBytes = dataItems.Sum(dataItem => VarTypeToByteLength(dataItem.VarType, dataItem.Count));
|
||||
|
||||
//TODO: Figure out how to use MaxPDUSize here
|
||||
//Snap7 seems to choke on PDU sizes above 256 even if snap7
|
||||
//replies with bigger PDU size in connection setup.
|
||||
if (dataItems.Count > 20)
|
||||
throw new Exception("Too many vars requested");
|
||||
if (cntBytes > 222)
|
||||
throw new Exception("Too many bytes requested"); // TODO: proper TDU check + split in multiple requests
|
||||
AssertPduSizeForRead(dataItems);
|
||||
|
||||
try
|
||||
{
|
||||
// first create the header
|
||||
|
||||
Reference in New Issue
Block a user