diff --git a/S7.Net/Protocol/ConnectionRequest.cs b/S7.Net/Protocol/ConnectionRequest.cs index 9c6c5bb..19b441c 100644 --- a/S7.Net/Protocol/ConnectionRequest.cs +++ b/S7.Net/Protocol/ConnectionRequest.cs @@ -6,7 +6,7 @@ namespace S7.Net.Protocol { public static byte[] GetCOTPConnectionRequest(CpuType cpu, Int16 rack, Int16 slot) { - var tsapPair = GetDefaultTsapPair(cpu, rack, slot); + var tsapPair = TsapPair.GetDefaultTsapPair(cpu, rack, slot); byte[] bSend1 = { 3, 0, 0, 22, //TPKT @@ -28,56 +28,5 @@ namespace S7.Net.Protocol return bSend1; } - - /// - /// Builds a that can be used to connect to a PLC using the default connection - /// addresses. - /// - /// - /// The remote TSAP is constructed using new Tsap(0x03, (byte) ((rack << 5) | slot)). - /// - /// The CPU type of the PLC. - /// The rack of the PLC's network card. - /// The slot of the PLC's network card. - /// A TSAP pair that matches the given parameters. - /// The is invalid. - /// - /// -or- - /// - /// The parameter is greater than 15. - /// - /// -or- - /// - /// The parameter is greater than 15. - public static TsapPair GetDefaultTsapPair(CpuType cpuType, int rack, int slot) - { - if (rack > 0x0F) throw InvalidRackOrSlot(rack, nameof(rack)); - if (slot > 0x0F) throw InvalidRackOrSlot(slot, nameof(slot)); - - switch (cpuType) - { - case CpuType.S7200: - return new TsapPair(new Tsap(0x10, 0x00), new Tsap(0x10, 0x00)); - case CpuType.Logo0BA8: - // The actual values are probably on a per-project basis - return new TsapPair(new Tsap(0x01, 0x00), new Tsap(0x01, 0x02)); - case CpuType.S7200Smart: - case CpuType.S71200: - case CpuType.S71500: - case CpuType.S7300: - case CpuType.S7400: - // Testing with S7 1500 shows only the remote TSAP needs to match. This might differ for other - // PLC types. - return new TsapPair(new Tsap(0x01, 0x00), new Tsap(0x03, (byte) ((rack << 5) | slot))); - default: - throw new ArgumentOutOfRangeException(nameof(cpuType), "Invalid CPU Type specified"); - } - } - - private static ArgumentOutOfRangeException InvalidRackOrSlot(int value, string name) - { - return new ArgumentOutOfRangeException(name, - $"Invalid {name} value specified (decimal: {value}, hexadecimal: {value:X}), maximum value is 15 (decimal) or 0x0F (hexadecimal)."); - } } } diff --git a/S7.Net/Protocol/TsapPair.cs b/S7.Net/Protocol/TsapPair.cs index 0869b23..4a329d3 100644 --- a/S7.Net/Protocol/TsapPair.cs +++ b/S7.Net/Protocol/TsapPair.cs @@ -1,4 +1,6 @@ -namespace S7.Net.Protocol +using System; + +namespace S7.Net.Protocol { /// /// Implements a pair of TSAP addresses used to connect to a PLC. @@ -26,5 +28,69 @@ Local = local; Remote = remote; } + + /// + /// Builds a that can be used to connect to a PLC using the default connection + /// addresses. + /// + /// + /// The remote TSAP is constructed using new Tsap(0x03, (byte) ((rack << 5) | slot)). + /// + /// The CPU type of the PLC. + /// The rack of the PLC's network card. + /// The slot of the PLC's network card. + /// A TSAP pair that matches the given parameters. + /// The is invalid. + /// + /// -or- + /// + /// The parameter is less than 0. + /// + /// -or- + /// + /// The parameter is greater than 15. + /// + /// -or- + /// + /// The parameter is less than 0. + /// + /// -or- + /// + /// The parameter is greater than 15. + public static TsapPair GetDefaultTsapPair(CpuType cpuType, int rack, int slot) + { + if (rack < 0) throw InvalidRackOrSlot(rack, nameof(rack), "minimum", 0); + if (rack > 0x0F) throw InvalidRackOrSlot(rack, nameof(rack), "maximum", 0x0F); + + if (slot < 0) throw InvalidRackOrSlot(slot, nameof(slot), "minimum", 0); + if (slot > 0x0F) throw InvalidRackOrSlot(slot, nameof(slot), "maximum", 0x0F); + + switch (cpuType) + { + case CpuType.S7200: + return new TsapPair(new Tsap(0x10, 0x00), new Tsap(0x10, 0x00)); + case CpuType.Logo0BA8: + // The actual values are probably on a per-project basis + return new TsapPair(new Tsap(0x01, 0x00), new Tsap(0x01, 0x02)); + case CpuType.S7200Smart: + case CpuType.S71200: + case CpuType.S71500: + case CpuType.S7300: + case CpuType.S7400: + // Testing with S7 1500 shows only the remote TSAP needs to match. This might differ for other + // PLC types. + return new TsapPair(new Tsap(0x01, 0x00), new Tsap(0x03, (byte) ((rack << 5) | slot))); + default: + throw new ArgumentOutOfRangeException(nameof(cpuType), "Invalid CPU Type specified"); + } + } + + private static ArgumentOutOfRangeException InvalidRackOrSlot(int value, string name, string extrema, + int extremaValue) + { + return new ArgumentOutOfRangeException(name, + $"Invalid {name} value specified (decimal: {value}, hexadecimal: {value:X}), {extrema} value " + + $"is {extremaValue} (decimal) or {extremaValue:X} (hexadecimal)."); + } } } \ No newline at end of file