Browse Source

delete global using and third code

master
jkpete 4 months ago
parent
commit
9bdac289ec
  1. 3
      EGFramework.csproj
  2. 2
      Example/UsingTest/Script/EGSaveTest.cs
  3. 6
      addons/EGFramework/Module/SaveTools/EGByteSave.cs
  4. 4
      addons/EGFramework/Module/SaveTools/EGCsvSave.cs
  5. 4
      addons/EGFramework/Module/SaveTools/EGJsonSave.cs
  6. 1
      addons/EGFramework/Module/SaveTools/EGSqlite.cs
  7. 2937
      addons/EGFramework/Third_Part_SourceCode/BacNetPlugin/BACnetClient.cs
  8. 158
      addons/EGFramework/Third_Part_SourceCode/BacNetPlugin/BacnetAsyncResult.cs
  9. 69
      addons/EGFramework/Third_Part_SourceCode/BacNetPlugin/Base/BaCnetCalendarEntry.cs
  10. 84
      addons/EGFramework/Third_Part_SourceCode/BacNetPlugin/Base/BacnetAbortReason.cs
  11. 196
      addons/EGFramework/Third_Part_SourceCode/BacNetPlugin/Base/BacnetAddress.cs
  12. 13
      addons/EGFramework/Third_Part_SourceCode/BacNetPlugin/Base/BacnetAddressTypes.cs
  13. 65
      addons/EGFramework/Third_Part_SourceCode/BacNetPlugin/Base/BacnetApplicationTags.cs
  14. 10
      addons/EGFramework/Third_Part_SourceCode/BacNetPlugin/Base/BacnetBinaryPv.cs
  15. 91
      addons/EGFramework/Third_Part_SourceCode/BacNetPlugin/Base/BacnetBitString.cs
  16. 18
      addons/EGFramework/Third_Part_SourceCode/BacNetPlugin/Base/BacnetBvlcFunctions.cs
  17. 12
      addons/EGFramework/Third_Part_SourceCode/BacNetPlugin/Base/BacnetBvlcResults.cs
  18. 18
      addons/EGFramework/Third_Part_SourceCode/BacNetPlugin/Base/BacnetBvlcV6Functions.cs
  19. 10
      addons/EGFramework/Third_Part_SourceCode/BacNetPlugin/Base/BacnetBvlcV6Results.cs
  20. 15
      addons/EGFramework/Third_Part_SourceCode/BacNetPlugin/Base/BacnetCOVSubscription.cs
  21. 13
      addons/EGFramework/Third_Part_SourceCode/BacNetPlugin/Base/BacnetCharacterStringEncodings.cs
  22. 47
      addons/EGFramework/Third_Part_SourceCode/BacNetPlugin/Base/BacnetConfirmedServices.cs
  23. 125
      addons/EGFramework/Third_Part_SourceCode/BacNetPlugin/Base/BacnetDate.cs
  24. 53
      addons/EGFramework/Third_Part_SourceCode/BacNetPlugin/Base/BacnetDateRange.cs
  25. 104
      addons/EGFramework/Third_Part_SourceCode/BacNetPlugin/Base/BacnetDeviceObjectPropertyReference.cs
  26. 11
      addons/EGFramework/Third_Part_SourceCode/BacNetPlugin/Base/BacnetDeviceStatus.cs
  27. 22
      addons/EGFramework/Third_Part_SourceCode/BacNetPlugin/Base/BacnetError.cs
  28. 21
      addons/EGFramework/Third_Part_SourceCode/BacNetPlugin/Base/BacnetErrorClasses.cs
  29. 246
      addons/EGFramework/Third_Part_SourceCode/BacNetPlugin/Base/BacnetErrorCodes.cs
  30. 140
      addons/EGFramework/Third_Part_SourceCode/BacNetPlugin/Base/BacnetEventNotificationData.cs
  31. 20
      addons/EGFramework/Third_Part_SourceCode/BacNetPlugin/Base/BacnetGenericTime.cs
  32. 12
      addons/EGFramework/Third_Part_SourceCode/BacNetPlugin/Base/BacnetGetEventInformationData.cs
  33. 143
      addons/EGFramework/Third_Part_SourceCode/BacNetPlugin/Base/BacnetLogRecord.cs
  34. 11
      addons/EGFramework/Third_Part_SourceCode/BacNetPlugin/Base/BacnetMaxAdpu.cs
  35. 13
      addons/EGFramework/Third_Part_SourceCode/BacNetPlugin/Base/BacnetMaxSegments.cs
  36. 23
      addons/EGFramework/Third_Part_SourceCode/BacNetPlugin/Base/BacnetMstpFrameTypes.cs
  37. 31
      addons/EGFramework/Third_Part_SourceCode/BacNetPlugin/Base/BacnetNetworkMessageTypes.cs
  38. 17
      addons/EGFramework/Third_Part_SourceCode/BacNetPlugin/Base/BacnetNodeTypes.cs
  39. 14
      addons/EGFramework/Third_Part_SourceCode/BacNetPlugin/Base/BacnetNpduControls.cs
  40. 7
      addons/EGFramework/Third_Part_SourceCode/BacNetPlugin/Base/BacnetObjectDescription.cs
  41. 82
      addons/EGFramework/Third_Part_SourceCode/BacNetPlugin/Base/BacnetObjectId.cs
  42. 82
      addons/EGFramework/Third_Part_SourceCode/BacNetPlugin/Base/BacnetObjectTypes.cs
  43. 22
      addons/EGFramework/Third_Part_SourceCode/BacNetPlugin/Base/BacnetPduTypes.cs
  44. 7
      addons/EGFramework/Third_Part_SourceCode/BacNetPlugin/Base/BacnetPolarity.cs
  45. 18
      addons/EGFramework/Third_Part_SourceCode/BacNetPlugin/Base/BacnetProgramError.cs
  46. 11
      addons/EGFramework/Third_Part_SourceCode/BacNetPlugin/Base/BacnetProgramRequest.cs
  47. 11
      addons/EGFramework/Third_Part_SourceCode/BacNetPlugin/Base/BacnetProgramState.cs
  48. 577
      addons/EGFramework/Third_Part_SourceCode/BacNetPlugin/Base/BacnetPropertyIds.cs
  49. 23
      addons/EGFramework/Third_Part_SourceCode/BacNetPlugin/Base/BacnetPropertyReference.cs
  50. 48
      addons/EGFramework/Third_Part_SourceCode/BacNetPlugin/Base/BacnetPropertyState.cs
  51. 13
      addons/EGFramework/Third_Part_SourceCode/BacNetPlugin/Base/BacnetPropertyValue.cs
  52. 9
      addons/EGFramework/Third_Part_SourceCode/BacNetPlugin/Base/BacnetPtpDisconnectReasons.cs
  53. 24
      addons/EGFramework/Third_Part_SourceCode/BacNetPlugin/Base/BacnetPtpFrameTypes.cs
  54. 13
      addons/EGFramework/Third_Part_SourceCode/BacNetPlugin/Base/BacnetReadAccessResult.cs
  55. 40
      addons/EGFramework/Third_Part_SourceCode/BacNetPlugin/Base/BacnetReadAccessSpecification.cs
  56. 9
      addons/EGFramework/Third_Part_SourceCode/BacNetPlugin/Base/BacnetReadRangeRequestTypes.cs
  57. 14
      addons/EGFramework/Third_Part_SourceCode/BacNetPlugin/Base/BacnetReinitializedStates.cs
  58. 84
      addons/EGFramework/Third_Part_SourceCode/BacNetPlugin/Base/BacnetRejectReason.cs
  59. 27
      addons/EGFramework/Third_Part_SourceCode/BacNetPlugin/Base/BacnetReliability.cs
  60. 14
      addons/EGFramework/Third_Part_SourceCode/BacNetPlugin/Base/BacnetRestartReason.cs
  61. 10
      addons/EGFramework/Third_Part_SourceCode/BacNetPlugin/Base/BacnetResultFlags.cs
  62. 9
      addons/EGFramework/Third_Part_SourceCode/BacNetPlugin/Base/BacnetSegmentations.cs
  63. 62
      addons/EGFramework/Third_Part_SourceCode/BacNetPlugin/Base/BacnetServicesSupported.cs
  64. 10
      addons/EGFramework/Third_Part_SourceCode/BacNetPlugin/Base/BacnetStatusFlags.cs
  65. 9
      addons/EGFramework/Third_Part_SourceCode/BacNetPlugin/Base/BacnetTimestampTags.cs
  66. 18
      addons/EGFramework/Third_Part_SourceCode/BacNetPlugin/Base/BacnetTrendLogValueType.cs
  67. 30
      addons/EGFramework/Third_Part_SourceCode/BacNetPlugin/Base/BacnetUnconfirmedServices.cs
  68. 311
      addons/EGFramework/Third_Part_SourceCode/BacNetPlugin/Base/BacnetUnitsId.cs
  69. 89
      addons/EGFramework/Third_Part_SourceCode/BacNetPlugin/Base/BacnetValue.cs
  70. 22
      addons/EGFramework/Third_Part_SourceCode/BacNetPlugin/Base/BacnetWritePriority.cs
  71. 71
      addons/EGFramework/Third_Part_SourceCode/BacNetPlugin/Base/BacnetweekNDay.cs
  72. 84
      addons/EGFramework/Third_Part_SourceCode/BacNetPlugin/Base/DeviceReportingRecipient.cs
  73. 10
      addons/EGFramework/Third_Part_SourceCode/BacNetPlugin/Base/Enums/BacnetBackupState.cs
  74. 7
      addons/EGFramework/Third_Part_SourceCode/BacNetPlugin/Base/Enums/BacnetCOVTypes.cs
  75. 8
      addons/EGFramework/Third_Part_SourceCode/BacNetPlugin/Base/Enums/BacnetEventEnable.cs
  76. 11
      addons/EGFramework/Third_Part_SourceCode/BacNetPlugin/Base/Enums/BacnetEventStates.cs
  77. 40
      addons/EGFramework/Third_Part_SourceCode/BacNetPlugin/Base/Enums/BacnetEventTypes.cs
  78. 7
      addons/EGFramework/Third_Part_SourceCode/BacNetPlugin/Base/Enums/BacnetFileAccessMethod.cs
  79. 30
      addons/EGFramework/Third_Part_SourceCode/BacNetPlugin/Base/Enums/BacnetLifeSafetyModes.cs
  80. 23
      addons/EGFramework/Third_Part_SourceCode/BacNetPlugin/Base/Enums/BacnetLifeSafetyOperations.cs
  81. 39
      addons/EGFramework/Third_Part_SourceCode/BacNetPlugin/Base/Enums/BacnetLifeSafetyStates.cs
  82. 7
      addons/EGFramework/Third_Part_SourceCode/BacNetPlugin/Base/Enums/BacnetLimitEnable.cs
  83. 8
      addons/EGFramework/Third_Part_SourceCode/BacNetPlugin/Base/Enums/BacnetNotifyTypes.cs
  84. 21
      addons/EGFramework/Third_Part_SourceCode/BacNetPlugin/GlobalUsings.cs
  85. 64
      addons/EGFramework/Third_Part_SourceCode/BacNetPlugin/Helpers/BacnetValuesExtensions.cs
  86. 217
      addons/EGFramework/Third_Part_SourceCode/BacNetPlugin/Serialize/APDU.cs
  87. 2486
      addons/EGFramework/Third_Part_SourceCode/BacNetPlugin/Serialize/ASN1.cs
  88. 416
      addons/EGFramework/Third_Part_SourceCode/BacNetPlugin/Serialize/BVLC.cs
  89. 117
      addons/EGFramework/Third_Part_SourceCode/BacNetPlugin/Serialize/EncodeBuffer.cs
  90. 8
      addons/EGFramework/Third_Part_SourceCode/BacNetPlugin/Serialize/EncodeResult.cs
  91. 107
      addons/EGFramework/Third_Part_SourceCode/BacNetPlugin/Serialize/MSTP.cs
  92. 134
      addons/EGFramework/Third_Part_SourceCode/BacNetPlugin/Serialize/NPDU.cs
  93. 67
      addons/EGFramework/Third_Part_SourceCode/BacNetPlugin/Serialize/PTP.cs
  94. 2664
      addons/EGFramework/Third_Part_SourceCode/BacNetPlugin/Serialize/Services.cs
  95. 459
      addons/EGFramework/Third_Part_SourceCode/BacNetPlugin/Storage/DeviceStorage.cs
  96. 18
      addons/EGFramework/Third_Part_SourceCode/BacNetPlugin/Storage/Object.cs
  97. 127
      addons/EGFramework/Third_Part_SourceCode/BacNetPlugin/Storage/Property.cs
  98. 351
      addons/EGFramework/Third_Part_SourceCode/BacNetPlugin/Transport/BVLCV6.cs
  99. 465
      addons/EGFramework/Third_Part_SourceCode/BacNetPlugin/Transport/BacnetIpUdpProtocolTransport.cs
  100. 362
      addons/EGFramework/Third_Part_SourceCode/BacNetPlugin/Transport/BacnetIpV6UdpProtocolTransport.cs
  101. Some files were not shown because too many files have changed in this diff Show More

3
EGFramework.csproj

@ -13,9 +13,8 @@ @@ -13,9 +13,8 @@
<PackageReference Include="WebDav.Client" Version="2.8.0" />
<PackageReference Include="MQTTnet" Version="4.3.3.952" />
<PackageReference Include="Makaretu.Dns.Multicast" Version="0.27.0" />
<PackageReference Include="PacketDotNet" Version="0.19.3" />
<PackageReference Include="SharpPcap" Version="4.5.0" />
<PackageReference Include="Microsoft.Extensions.Configuration.Ini" Version="8.0.0" />
<PackageReference Include="LiteDB" Version="5.0.21" />
<PackageReference Include="BACnet" Version="2.0.4" />
</ItemGroup>
</Project>

2
Example/UsingTest/Script/EGSaveTest.cs

@ -1,3 +1,5 @@ @@ -1,3 +1,5 @@
using System.Collections.Generic;
using System.Linq;
using Godot;
using LiteDB;

6
addons/EGFramework/Module/SaveTools/EGByteSave.cs

@ -1,9 +1,7 @@ @@ -1,9 +1,7 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Threading.Tasks;
using System.Runtime.Serialization.Formatters.Binary;
using System.IO;
using System.Linq;
using System.Text;
namespace EGFramework
{

4
addons/EGFramework/Module/SaveTools/EGCsvSave.cs

@ -1,11 +1,11 @@ @@ -1,11 +1,11 @@
using System;
using System.Collections;
using System.Collections.Generic;
using System.Data;
using System.IO;
using System.Linq;
using System.Linq.Expressions;
using System.Threading.Tasks;
using System.Text;
using System.Reflection;
namespace EGFramework
{

4
addons/EGFramework/Module/SaveTools/EGJsonSave.cs

@ -1,8 +1,6 @@ @@ -1,8 +1,6 @@
using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Threading.Tasks;
using System.Text;
using Newtonsoft.Json;
using Newtonsoft.Json.Linq;

1
addons/EGFramework/Module/SaveTools/EGSqlite.cs

@ -1,6 +1,7 @@ @@ -1,6 +1,7 @@
using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using Microsoft.Data.Sqlite;
using Newtonsoft.Json;

2937
addons/EGFramework/Third_Part_SourceCode/BacNetPlugin/BACnetClient.cs

File diff suppressed because it is too large Load Diff

158
addons/EGFramework/Third_Part_SourceCode/BacNetPlugin/BacnetAsyncResult.cs

@ -1,158 +0,0 @@ @@ -1,158 +0,0 @@
namespace System.IO.BACnet;
public class BacnetAsyncResult : IAsyncResult, IDisposable
{
private BacnetClient _comm;
private readonly byte _waitInvokeId;
private Exception _error;
private readonly byte[] _transmitBuffer;
private readonly int _transmitLength;
private readonly bool _waitForTransmit;
private readonly int _transmitTimeout;
private ManualResetEvent _waitHandle;
private readonly BacnetAddress _address;
public bool Segmented { get; private set; }
public byte[] Result { get; private set; }
public object AsyncState { get; set; }
public bool CompletedSynchronously { get; private set; }
public WaitHandle AsyncWaitHandle => _waitHandle;
public bool IsCompleted => _waitHandle.WaitOne(0);
public BacnetAddress Address => _address;
public Exception Error
{
get => _error;
set
{
_error = value;
CompletedSynchronously = true;
_waitHandle.Set();
}
}
public BacnetAsyncResult(BacnetClient comm, BacnetAddress adr, byte invokeId, byte[] transmitBuffer, int transmitLength, bool waitForTransmit, int transmitTimeout)
{
_transmitTimeout = transmitTimeout;
_address = adr;
_waitForTransmit = waitForTransmit;
_transmitBuffer = transmitBuffer;
_transmitLength = transmitLength;
_comm = comm;
_waitInvokeId = invokeId;
_comm.OnComplexAck += OnComplexAck;
_comm.OnError += OnError;
_comm.OnAbort += OnAbort;
_comm.OnReject += OnReject;
_comm.OnSimpleAck += OnSimpleAck;
_comm.OnSegment += OnSegment;
_waitHandle = new ManualResetEvent(false);
}
public void Resend()
{
try
{
if (_comm.Transport.Send(_transmitBuffer, _comm.Transport.HeaderLength, _transmitLength, _address, _waitForTransmit, _transmitTimeout) < 0)
{
Error = new IOException("Write Timeout");
}
}
catch (Exception ex)
{
Error = new Exception($"Write Exception: {ex.Message}");
}
}
private void OnSegment(BacnetClient sender, BacnetAddress adr, BacnetPduTypes type, BacnetConfirmedServices service, byte invokeId, BacnetMaxSegments maxSegments, BacnetMaxAdpu maxAdpu, byte sequenceNumber, byte[] buffer, int offset, int length)
{
if (invokeId != _waitInvokeId || !adr.Equals(_address))
return;
Segmented = true;
_waitHandle.Set();
}
private void OnSimpleAck(BacnetClient sender, BacnetAddress adr, BacnetPduTypes type, BacnetConfirmedServices service, byte invokeId, byte[] data, int dataOffset, int dataLength)
{
if (invokeId != _waitInvokeId || !adr.Equals(_address))
return;
_waitHandle.Set();
}
private void OnAbort(BacnetClient sender, BacnetAddress adr, BacnetPduTypes type, byte invokeId, BacnetAbortReason reason, byte[] buffer, int offset, int length)
{
if (invokeId != _waitInvokeId || !adr.Equals(_address))
return;
Error = new Exception($"Abort from device, reason: {reason}");
}
private void OnReject(BacnetClient sender, BacnetAddress adr, BacnetPduTypes type, byte invokeId, BacnetRejectReason reason, byte[] buffer, int offset, int length)
{
if (invokeId != _waitInvokeId || !adr.Equals(_address))
return;
Error = new Exception($"Reject from device, reason: {reason}");
}
private void OnError(BacnetClient sender, BacnetAddress adr, BacnetPduTypes type, BacnetConfirmedServices service, byte invokeId, BacnetErrorClasses errorClass, BacnetErrorCodes errorCode, byte[] buffer, int offset, int length)
{
if (invokeId != _waitInvokeId || !adr.Equals(_address))
return;
Error = new Exception($"Error from device: {errorClass} - {errorCode}");
}
private void OnComplexAck(BacnetClient sender, BacnetAddress adr, BacnetPduTypes type, BacnetConfirmedServices service, byte invokeId, byte[] buffer, int offset, int length)
{
if (invokeId != _waitInvokeId || !adr.Equals(_address))
return;
Segmented = false;
Result = new byte[length];
if (length > 0)
Array.Copy(buffer, offset, Result, 0, length);
//notify waiter even if segmented
_waitHandle.Set();
}
/// <summary>
/// Will continue waiting until all segments are recieved
/// </summary>
public bool WaitForDone(int timeout)
{
while (true)
{
if (!AsyncWaitHandle.WaitOne(timeout))
return false;
if (Segmented)
_waitHandle.Reset();
else
return true;
}
}
public void Dispose()
{
if (_comm != null)
{
_comm.OnComplexAck -= OnComplexAck;
_comm.OnError -= OnError;
_comm.OnAbort -= OnAbort;
_comm.OnReject -= OnReject;
_comm.OnSimpleAck -= OnSimpleAck;
_comm.OnSegment -= OnSegment;
_comm = null;
}
if (_waitHandle != null)
{
_waitHandle.Dispose();
_waitHandle = null;
}
}
}

69
addons/EGFramework/Third_Part_SourceCode/BacNetPlugin/Base/BaCnetCalendarEntry.cs

@ -1,69 +0,0 @@ @@ -1,69 +0,0 @@
namespace System.IO.BACnet;
public struct BACnetCalendarEntry : ASN1.IEncode, ASN1.IDecode
{
public List<object> Entries; // BacnetDate or BacnetDateRange or BacnetweekNDay
public void Encode(EncodeBuffer buffer)
{
if (Entries == null)
return;
foreach (ASN1.IEncode entry in Entries)
{
if (entry is BacnetDate)
{
ASN1.encode_tag(buffer, 0, true, 4);
entry.Encode(buffer);
}
if (entry is BacnetDateRange)
{
ASN1.encode_opening_tag(buffer, 1);
entry.Encode(buffer);
ASN1.encode_closing_tag(buffer, 1);
}
if (entry is BacnetweekNDay)
{
ASN1.encode_tag(buffer, 2, true, 3);
entry.Encode(buffer);
}
}
}
public int Decode(byte[] buffer, int offset, uint count)
{
var len = 0;
Entries = new List<object>();
while (true)
{
len += ASN1.decode_tag_number(buffer, offset + len, out byte tagNumber);
switch (tagNumber)
{
case 0:
var bdt = new BacnetDate();
len += bdt.Decode(buffer, offset + len, count);
Entries.Add(bdt);
break;
case 1:
var bdr = new BacnetDateRange();
len += bdr.Decode(buffer, offset + len, count);
Entries.Add(bdr);
len++; // closing tag
break;
case 2:
var bwd = new BacnetweekNDay();
len += bwd.Decode(buffer, offset + len, count);
Entries.Add(bwd);
break;
default:
return len - 1; // closing Tag
}
}
}
}

84
addons/EGFramework/Third_Part_SourceCode/BacNetPlugin/Base/BacnetAbortReason.cs

@ -1,84 +0,0 @@ @@ -1,84 +0,0 @@
namespace System.IO.BACnet;
/// <summary>
/// Reason the transaction with the indicated invoke ID is being aborted.
/// </summary>
/// <remarks>
/// Enumerated values 0-63 are reserved for definition by ASHRAE.
/// Enumerated values 64-255 may be used by others.
/// </remarks>
public enum BacnetAbortReason
{
/// <summary>
/// This abort reason is returned for a reason other than any of those previously enumerated.
/// </summary>
OTHER = 0,
/// <summary>
/// A buffer capacity has been exceeded.
/// </summary>
BUFFER_OVERFLOW = 1,
/// <summary>
/// Generated in response to an APDU that is not expected in the present
/// state of the Transaction State Machine.
/// </summary>
INVALID_APDU_IN_THIS_STATE = 2,
/// <summary>
/// The transaction shall be aborted to permit higher priority processing.
/// </summary>
PREEMPTED_BY_HIGHER_PRIORITY_TASK = 3,
/// <summary>
/// Generated in response to an APDU that has its segmentation bit set to TRUE
/// when the receiving device does not support segmentation. It is also generated
/// when a BACnet-ComplexACKPDU is large enough to require segmentation but it
/// cannot be transmitted because either the transmitting device or the receiving
/// device does not support segmentation.
/// </summary>
SEGMENTATION_NOT_SUPPORTED = 4,
/// <summary>
/// The Transaction is aborted due to receipt of a security error.
/// </summary>
SECURITY_ERROR = 5,
/// <summary>
/// The transaction is aborted due to receipt of a PDU secured differently
/// than the original PDU of the transaction.
/// </summary>
INSUFFICIENT_SECURITY = 6,
/// <summary>
/// A device receives a request that is segmented, or receives any segment of
/// a segmented request, where the Proposed Window Size field of the PDU header
/// is either zero or greater than 127.
/// </summary>
WINDOW_SIZE_OUT_OF_RANGE = 7,
/// <summary>
/// A device receives a confirmed request but its application layer has
/// not responded within the published APDU Timeout period.
/// </summary>
APPLICATION_EXCEEDED_REPLY_TIME = 8,
/// <summary>
/// A device receives a request but cannot start processing because it has run
/// out of some internal resource.
/// </summary>
OUT_OF_RESOURCES = 9,
/// <summary>
/// A transaction state machine timer exceeded the timeout applicable for the
/// current state, causing the transaction machine to abort the transaction.
/// </summary>
TSM_TIMEOUT = 10,
/// <summary>
/// An APDU was received from the local application program whose overall
/// size exceeds the maximum transmittable length or exceeds the maximum
/// number of segments accepted by the server.
/// </summary>
APDU_TOO_LONG = 11
}

196
addons/EGFramework/Third_Part_SourceCode/BacNetPlugin/Base/BacnetAddress.cs

@ -1,196 +0,0 @@ @@ -1,196 +0,0 @@
namespace System.IO.BACnet;
public class BacnetAddress : ASN1.IEncode
{
public ushort net;
public byte[] adr;
public byte[] VMac = new byte[3]; // for IP V6, could be integrated also as 3 additional bytes in adr
public BacnetAddressTypes type;
// Modif FC
public BacnetAddress RoutedSource = null;
// DAL
public BacnetAddress RoutedDestination = null;
public BacnetAddress(BacnetAddressTypes addressType, ushort network = 0, byte[] address = null)
{
type = addressType;
net = network;
adr = address;
}
public BacnetAddress(BacnetAddressTypes addressType, string address = null, ushort network = 0)
: this(addressType, network)
{
if (address == null)
return;
switch (type)
{
case BacnetAddressTypes.IP:
adr = new byte[6];
var addressParts = address.Split(':');
var addressBytes = IPAddress.Parse(addressParts[0]).GetAddressBytes();
Array.Copy(addressBytes, adr, addressBytes.Length);
var portBytes = BitConverter.GetBytes(addressParts.Length > 1
? ushort.Parse(addressParts[1])
: (ushort)0xBAC0);
if (BitConverter.IsLittleEndian)
portBytes = portBytes.Reverse().ToArray();
Array.Copy(portBytes, 0, adr, addressBytes.Length, portBytes.Length);
break;
case BacnetAddressTypes.Ethernet:
adr = PhysicalAddress.Parse(address).GetAddressBytes();
break;
default:
throw new NotSupportedException("String format is not supported for address type " + type);
}
}
public override int GetHashCode()
{
// DAL this was originally broken...
var str = Convert.ToBase64String(adr);
return str.GetHashCode();
}
public override string ToString()
{
return ToString(type);
}
public string ToString(BacnetAddressTypes addressType)
{
while (true)
{
switch (addressType)
{
case BacnetAddressTypes.IP:
return adr != null && adr.Length >= 6
? $"{adr[0]}.{adr[1]}.{adr[2]}.{adr[3]}:{(adr[4] << 8) | adr[5]}"
: "0.0.0.0";
case BacnetAddressTypes.MSTP:
return adr != null && adr.Length >= 1
? $"{adr[0]}"
: "-1";
case BacnetAddressTypes.PTP:
return "x";
case BacnetAddressTypes.Ethernet:
return $"{new PhysicalAddress(adr)}";
case BacnetAddressTypes.IPV6:
return adr != null && adr.Length == 18
? $"{new IPAddress(adr.Take(16).ToArray())}:{(adr[16] << 8) | adr[17]}"
: "[::]";
default: // Routed @ are always like this, NPDU do not contains the MAC type, only the lenght
if (adr == null || adr.Length == 0)
return "?";
switch (adr.Length)
{
case 6: // certainly IP, but not sure (Newron System send it for internal usage with 4*0 bytes)
addressType = BacnetAddressTypes.IP;
continue;
case 18: // Not sure it could appears, since NPDU may contains Vmac ?
addressType = BacnetAddressTypes.IPV6;
continue;
case 3:
return $"IPv6 VMac : {adr[0] << 16 | (adr[1] << 8) | adr[2]}";
default:
return string.Join(" ", adr);
}
}
}
}
public string ToString(bool sourceOnly)
{
if (RoutedSource == null)
return ToString();
return sourceOnly
? RoutedSource.ToString()
: $"{RoutedSource} via {ToString()}";
}
public bool HasAddress(IPAddress ipAddress)
{
if (type != BacnetAddressTypes.IP || adr == null || ipAddress == null)
return false;
return adr.Take(4).SequenceEqual(ipAddress.GetAddressBytes());
}
public override bool Equals(object obj)
{
if (obj is not BacnetAddress) return false;
var d = (BacnetAddress)obj;
if (adr == null && d.adr == null) return true;
if (adr == null || d.adr == null) return false;
if (adr.Length != d.adr.Length) return false;
if (adr.Where((t, i) => t != d.adr[i]).Any())
return false;
// Modif FC
if (RoutedSource == null && d.RoutedSource != null)
return false;
// DAL
if (RoutedDestination == null && d.RoutedDestination != null)
return false;
if (d.RoutedSource == null && RoutedSource == null &&
d.RoutedDestination == null && RoutedDestination == null)
return true;
bool rv = RoutedSource?.Equals(d.RoutedSource) ?? false;
rv |= RoutedDestination?.Equals(d.RoutedDestination) ?? false;
return rv;
}
// checked if device is routed by curent equipement
public bool IsMyRouter(BacnetAddress device)
{
if (device.RoutedSource == null || RoutedSource != null)
return false;
if (adr.Length != device.adr.Length)
return false;
return !adr.Where((t, i) => t != device.adr[i]).Any();
}
public void Encode(EncodeBuffer buffer)
{
ASN1.encode_opening_tag(buffer, 1);
ASN1.encode_application_unsigned(buffer, net);
ASN1.encode_application_octet_string(buffer, adr, 0, adr.Length);
ASN1.encode_closing_tag(buffer, 1);
}
public string FullHashString()
{
var hash = $"{(uint)type}.{net}.{string.Concat(adr.Select(a => a.ToString("X2")))}";
if (RoutedSource != null)
hash += $":{RoutedSource.FullHashString()}";
if (RoutedDestination != null)
hash += $":{RoutedDestination.FullHashString()}";
return hash;
}
}

13
addons/EGFramework/Third_Part_SourceCode/BacNetPlugin/Base/BacnetAddressTypes.cs

@ -1,13 +0,0 @@ @@ -1,13 +0,0 @@
namespace System.IO.BACnet;
public enum BacnetAddressTypes
{
None,
IP,
MSTP,
Ethernet,
ArcNet,
LonTalk,
PTP,
IPV6
}

65
addons/EGFramework/Third_Part_SourceCode/BacNetPlugin/Base/BacnetApplicationTags.cs

@ -1,65 +0,0 @@ @@ -1,65 +0,0 @@
namespace System.IO.BACnet;
public enum BacnetApplicationTags
{
BACNET_APPLICATION_TAG_NULL = 0,
BACNET_APPLICATION_TAG_BOOLEAN = 1,
BACNET_APPLICATION_TAG_UNSIGNED_INT = 2,
BACNET_APPLICATION_TAG_SIGNED_INT = 3,
BACNET_APPLICATION_TAG_REAL = 4,
BACNET_APPLICATION_TAG_DOUBLE = 5,
BACNET_APPLICATION_TAG_OCTET_STRING = 6,
BACNET_APPLICATION_TAG_CHARACTER_STRING = 7,
BACNET_APPLICATION_TAG_BIT_STRING = 8,
BACNET_APPLICATION_TAG_ENUMERATED = 9,
BACNET_APPLICATION_TAG_DATE = 10,
BACNET_APPLICATION_TAG_TIME = 11,
BACNET_APPLICATION_TAG_OBJECT_ID = 12,
BACNET_APPLICATION_TAG_RESERVE1 = 13,
BACNET_APPLICATION_TAG_RESERVE2 = 14,
BACNET_APPLICATION_TAG_RESERVE3 = 15,
MAX_BACNET_APPLICATION_TAG = 16,
/* Extra stuff - complex tagged data - not specifically enumerated */
/* Means : "nothing", an empty list, not even a null character */
BACNET_APPLICATION_TAG_EMPTYLIST,
/* BACnetWeeknday */
BACNET_APPLICATION_TAG_WEEKNDAY,
/* BACnetDateRange */
BACNET_APPLICATION_TAG_DATERANGE,
/* BACnetDateTime */
BACNET_APPLICATION_TAG_DATETIME,
/* BACnetTimeStamp */
BACNET_APPLICATION_TAG_TIMESTAMP,
/* Error Class, Error Code */
BACNET_APPLICATION_TAG_ERROR,
/* BACnetDeviceObjectPropertyReference */
BACNET_APPLICATION_TAG_DEVICE_OBJECT_PROPERTY_REFERENCE,
/* BACnetDeviceObjectReference */
BACNET_APPLICATION_TAG_DEVICE_OBJECT_REFERENCE,
/* BACnetObjectPropertyReference */
BACNET_APPLICATION_TAG_OBJECT_PROPERTY_REFERENCE,
/* BACnetDestination (Recipient_List) */
BACNET_APPLICATION_TAG_DESTINATION,
/* BACnetRecipient */
BACNET_APPLICATION_TAG_RECIPIENT,
/* BACnetCOVSubscription */
BACNET_APPLICATION_TAG_COV_SUBSCRIPTION,
/* BACnetCalendarEntry */
BACNET_APPLICATION_TAG_CALENDAR_ENTRY,
/* BACnetWeeklySchedule */
BACNET_APPLICATION_TAG_WEEKLY_SCHEDULE,
/* BACnetSpecialEvent */
BACNET_APPLICATION_TAG_SPECIAL_EVENT,
/* BACnetReadAccessSpecification */
BACNET_APPLICATION_TAG_READ_ACCESS_SPECIFICATION,
/* BACnetReadAccessResult */
BACNET_APPLICATION_TAG_READ_ACCESS_RESULT,
/* BACnetLightingCommand */
BACNET_APPLICATION_TAG_LIGHTING_COMMAND,
BACNET_APPLICATION_TAG_CONTEXT_SPECIFIC_DECODED,
BACNET_APPLICATION_TAG_CONTEXT_SPECIFIC_ENCODED,
/* BACnetLogRecord */
BACNET_APPLICATION_TAG_LOG_RECORD
}

10
addons/EGFramework/Third_Part_SourceCode/BacNetPlugin/Base/BacnetBinaryPv.cs

@ -1,10 +0,0 @@ @@ -1,10 +0,0 @@
namespace System.IO.BACnet.Base;
public enum BacnetBinaryPv : byte
{
MIN_BINARY_PV = 0, /* for validating incoming values */
BINARY_INACTIVE = 0,
BINARY_ACTIVE = 1,
MAX_BINARY_PV = 1, /* for validating incoming values */
BINARY_NULL = 255 /* our homemade way of storing this info */
}

91
addons/EGFramework/Third_Part_SourceCode/BacNetPlugin/Base/BacnetBitString.cs

@ -1,91 +0,0 @@ @@ -1,91 +0,0 @@
namespace System.IO.BACnet;
public struct BacnetBitString
{
public byte bits_used;
public byte[] value;
public byte Length => bits_used;
public bool this[byte bitNumber] => GetBit(bitNumber);
public override string ToString()
{
var ret = "";
for (var i = 0; i < bits_used; i++)
{
ret += ((value[i / 8] & (1 << (i % 8))) > 0 ? "1" : "0");
}
return ret;
}
public void SetBit(byte bitNumber, bool v)
{
var byteNumber = (byte)(bitNumber / 8);
byte bitMask = 1;
if (value == null)
value = new byte[ASN1.MAX_BITSTRING_BYTES];
if (byteNumber < ASN1.MAX_BITSTRING_BYTES)
{
/* set max bits used */
if (bits_used < bitNumber + 1)
bits_used = (byte)(bitNumber + 1);
bitMask = (byte)(bitMask << (bitNumber - byteNumber * 8));
if (v)
value[byteNumber] |= bitMask;
else
value[byteNumber] &= (byte)~bitMask;
}
}
public bool GetBit(byte bitNumber)
{
var byteNumber = (byte)(bitNumber / 8);
if (byteNumber >= ASN1.MAX_BITSTRING_BYTES || bitNumber >= bits_used)
throw new ArgumentOutOfRangeException(nameof(bitNumber));
if (value == null)
return false;
var bitMask = (byte)(1 << (bitNumber - byteNumber * 8));
return (value[byteNumber] & bitMask) > 0;
}
public static BacnetBitString Parse(string str)
{
var ret = new BacnetBitString
{
value = new byte[ASN1.MAX_BITSTRING_BYTES]
};
if (string.IsNullOrEmpty(str))
return ret;
ret.bits_used = (byte)str.Length;
for (var i = 0; i < ret.bits_used; i++)
{
var isSet = str[i] == '1';
if (isSet) ret.value[i / 8] |= (byte)(1 << (i % 8));
}
return ret;
}
public uint ConvertToInt()
{
return value != null
? BitConverter.ToUInt32(value, 0)
: 0;
}
public static BacnetBitString ConvertFromInt(uint value)
{
return new BacnetBitString
{
value = BitConverter.GetBytes(value),
bits_used = (byte)Math.Ceiling(Math.Log(value, 2))
};
}
};

18
addons/EGFramework/Third_Part_SourceCode/BacNetPlugin/Base/BacnetBvlcFunctions.cs

@ -1,18 +0,0 @@ @@ -1,18 +0,0 @@
namespace System.IO.BACnet;
public enum BacnetBvlcFunctions : byte
{
BVLC_RESULT = 0,
BVLC_WRITE_BROADCAST_DISTRIBUTION_TABLE = 1,
BVLC_READ_BROADCAST_DIST_TABLE = 2,
BVLC_READ_BROADCAST_DIST_TABLE_ACK = 3,
BVLC_FORWARDED_NPDU = 4,
BVLC_REGISTER_FOREIGN_DEVICE = 5,
BVLC_READ_FOREIGN_DEVICE_TABLE = 6,
BVLC_READ_FOREIGN_DEVICE_TABLE_ACK = 7,
BVLC_DELETE_FOREIGN_DEVICE_TABLE_ENTRY = 8,
BVLC_DISTRIBUTE_BROADCAST_TO_NETWORK = 9,
BVLC_ORIGINAL_UNICAST_NPDU = 10,
BVLC_ORIGINAL_BROADCAST_NPDU = 11,
MAX_BVLC_FUNCTION = 12
}

12
addons/EGFramework/Third_Part_SourceCode/BacNetPlugin/Base/BacnetBvlcResults.cs

@ -1,12 +0,0 @@ @@ -1,12 +0,0 @@
namespace System.IO.BACnet;
public enum BacnetBvlcResults : ushort
{
BVLC_RESULT_SUCCESSFUL_COMPLETION = 0x0000,
BVLC_RESULT_WRITE_BROADCAST_DISTRIBUTION_TABLE_NAK = 0x0010,
BVLC_RESULT_READ_BROADCAST_DISTRIBUTION_TABLE_NAK = 0x0020,
BVLC_RESULT_REGISTER_FOREIGN_DEVICE_NAK = 0X0030,
BVLC_RESULT_READ_FOREIGN_DEVICE_TABLE_NAK = 0x0040,
BVLC_RESULT_DELETE_FOREIGN_DEVICE_TABLE_ENTRY_NAK = 0x0050,
BVLC_RESULT_DISTRIBUTE_BROADCAST_TO_NETWORK_NAK = 0x0060
}

18
addons/EGFramework/Third_Part_SourceCode/BacNetPlugin/Base/BacnetBvlcV6Functions.cs

@ -1,18 +0,0 @@ @@ -1,18 +0,0 @@
namespace System.IO.BACnet;
public enum BacnetBvlcV6Functions : byte
{
BVLC_RESULT = 0,
BVLC_ORIGINAL_UNICAST_NPDU = 1,
BVLC_ORIGINAL_BROADCAST_NPDU = 2,
BVLC_ADDRESS_RESOLUTION = 3,
BVLC_FORWARDED_ADDRESS_RESOLUTION = 4,
BVLC_ADDRESS_RESOLUTION_ACK = 5,
BVLC_VIRTUAL_ADDRESS_RESOLUTION = 6,
BVLC_VIRTUAL_ADDRESS_RESOLUTION_ACK = 7,
BVLC_FORWARDED_NPDU = 8,
BVLC_REGISTER_FOREIGN_DEVICE = 9,
BVLC_DELETE_FOREIGN_DEVICE_TABLE_ENTRY = 0xA,
BVLC_SECURE_BVLC = 0xB,
BVLC_DISTRIBUTE_BROADCAST_TO_NETWORK = 0xC
}

10
addons/EGFramework/Third_Part_SourceCode/BacNetPlugin/Base/BacnetBvlcV6Results.cs

@ -1,10 +0,0 @@ @@ -1,10 +0,0 @@
namespace System.IO.BACnet;
public enum BacnetBvlcV6Results : ushort
{
SUCCESSFUL_COMPLETION = 0x0000,
ADDRESS_RESOLUTION_NAK = 0x0030,
VIRTUAL_ADDRESS_RESOLUTION_NAK = 0x0060,
REGISTER_FOREIGN_DEVICE_NAK = 0X0090,
DISTRIBUTE_BROADCAST_TO_NETWORK_NAK = 0x00B0
}

15
addons/EGFramework/Third_Part_SourceCode/BacNetPlugin/Base/BacnetCOVSubscription.cs

@ -1,15 +0,0 @@ @@ -1,15 +0,0 @@
namespace System.IO.BACnet;
public struct BacnetCOVSubscription
{
/* BACnetRecipientProcess */
public BacnetAddress Recipient;
public uint subscriptionProcessIdentifier;
/* BACnetObjectPropertyReference */
public BacnetObjectId monitoredObjectIdentifier;
public BacnetPropertyReference monitoredProperty;
/* BACnetCOVSubscription */
public bool IssueConfirmedNotifications;
public uint TimeRemaining;
public float COVIncrement;
}

13
addons/EGFramework/Third_Part_SourceCode/BacNetPlugin/Base/BacnetCharacterStringEncodings.cs

@ -1,13 +0,0 @@ @@ -1,13 +0,0 @@
namespace System.IO.BACnet;
public enum BacnetCharacterStringEncodings
{
CHARACTER_ANSI_X34 = 0, /* deprecated : Addendum 135-2008k */
CHARACTER_UTF8 = 0,
CHARACTER_MS_DBCS = 1,
CHARACTER_JISC_6226 = 2, /* deprecated : Addendum 135-2008k */
CHARACTER_JISX_0208 = 2,
CHARACTER_UCS4 = 3,
CHARACTER_UCS2 = 4,
CHARACTER_ISO8859 = 5
}

47
addons/EGFramework/Third_Part_SourceCode/BacNetPlugin/Base/BacnetConfirmedServices.cs

@ -1,47 +0,0 @@ @@ -1,47 +0,0 @@
namespace System.IO.BACnet;
public enum BacnetConfirmedServices : byte
{
/* Alarm and Event Services */
SERVICE_CONFIRMED_ACKNOWLEDGE_ALARM = 0,
SERVICE_CONFIRMED_COV_NOTIFICATION = 1,
SERVICE_CONFIRMED_EVENT_NOTIFICATION = 2,
SERVICE_CONFIRMED_GET_ALARM_SUMMARY = 3,
SERVICE_CONFIRMED_GET_ENROLLMENT_SUMMARY = 4,
SERVICE_CONFIRMED_GET_EVENT_INFORMATION = 29,
SERVICE_CONFIRMED_SUBSCRIBE_COV = 5,
SERVICE_CONFIRMED_SUBSCRIBE_COV_PROPERTY = 28,
SERVICE_CONFIRMED_LIFE_SAFETY_OPERATION = 27,
/* File Access Services */
SERVICE_CONFIRMED_ATOMIC_READ_FILE = 6,
SERVICE_CONFIRMED_ATOMIC_WRITE_FILE = 7,
/* Object Access Services */
SERVICE_CONFIRMED_ADD_LIST_ELEMENT = 8,
SERVICE_CONFIRMED_REMOVE_LIST_ELEMENT = 9,
SERVICE_CONFIRMED_CREATE_OBJECT = 10,
SERVICE_CONFIRMED_DELETE_OBJECT = 11,
SERVICE_CONFIRMED_READ_PROPERTY = 12,
SERVICE_CONFIRMED_READ_PROP_CONDITIONAL = 13,
SERVICE_CONFIRMED_READ_PROP_MULTIPLE = 14,
SERVICE_CONFIRMED_READ_RANGE = 26,
SERVICE_CONFIRMED_WRITE_PROPERTY = 15,
SERVICE_CONFIRMED_WRITE_PROP_MULTIPLE = 16,
/* Remote Device Management Services */
SERVICE_CONFIRMED_DEVICE_COMMUNICATION_CONTROL = 17,
SERVICE_CONFIRMED_PRIVATE_TRANSFER = 18,
SERVICE_CONFIRMED_TEXT_MESSAGE = 19,
SERVICE_CONFIRMED_REINITIALIZE_DEVICE = 20,
/* Virtual Terminal Services */
SERVICE_CONFIRMED_VT_OPEN = 21,
SERVICE_CONFIRMED_VT_CLOSE = 22,
SERVICE_CONFIRMED_VT_DATA = 23,
/* Security Services */
SERVICE_CONFIRMED_AUTHENTICATE = 24,
SERVICE_CONFIRMED_REQUEST_KEY = 25,
/* Services added after 1995 */
/* readRange (26) see Object Access Services */
/* lifeSafetyOperation (27) see Alarm and Event Services */
/* subscribeCOVProperty (28) see Alarm and Event Services */
/* getEventInformation (29) see Alarm and Event Services */
MAX_BACNET_CONFIRMED_SERVICE = 30
}

125
addons/EGFramework/Third_Part_SourceCode/BacNetPlugin/Base/BacnetDate.cs

@ -1,125 +0,0 @@ @@ -1,125 +0,0 @@
namespace System.IO.BACnet;
public struct BacnetDate : ASN1.IEncode, ASN1.IDecode
{
public byte year; /* 255 any */
public byte month; /* 1=Jan; 255 any, 13 Odd, 14 Even */
public byte day; /* 1..31; 32 last day of the month; 255 any */
public byte wday; /* 1=Monday-7=Sunday, 255 any */
public BacnetDate(byte year, byte month, byte day, byte wday = 255)
{
this.year = year;
this.month = month;
this.day = day;
this.wday = wday;
}
public void Encode(EncodeBuffer buffer)
{
buffer.Add(year);
buffer.Add(month);
buffer.Add(day);
buffer.Add(wday);
}
public int Decode(byte[] buffer, int offset, uint count)
{
year = buffer[offset];
month = buffer[offset + 1];
day = buffer[offset + 2];
wday = buffer[offset + 3];
return 4;
}
public bool IsPeriodic => year == 255 || month > 12 || day == 255;
public bool IsAFittingDate(DateTime date)
{
if (date.Year != year + 1900 && year != 255)
return false;
if (date.Month != month && month != 255 && month != 13 && month != 14)
return false;
if (month == 13 && (date.Month & 1) != 1)
return false;
if (month == 14 && (date.Month & 1) == 1)
return false;
if (date.Day != day && day != 255)
return false;
// day 32 todo
if (wday == 255)
return true;
if (wday == 7 && date.DayOfWeek == 0) // Sunday 7 for Bacnet, 0 for .NET
return true;
if (wday == (int)date.DayOfWeek)
return true;
return false;
}
public DateTime toDateTime() // Not every time possible, too much complex (any month, any year ...)
{
try
{
return IsPeriodic
? new DateTime(1, 1, 1)
: new DateTime(year + 1900, month, day);
}
catch
{
return DateTime.Now; // or anything else why not !
}
}
private static string GetDayName(int day)
{
if (day == 7)
day = 0;
return CultureInfo.CurrentCulture.DateTimeFormat.DayNames[day];
}
public override string ToString()
{
string ret;
if (wday != 255)
ret = GetDayName(wday) + " ";
else
ret = "";
if (day != 255)
ret = ret + day + "/";
else
ret += "**/";
switch (month)
{
case 13:
ret += "odd/";
break;
case 14:
ret += "even/";
break;
case 255:
ret += "**/";
break;
default:
ret = ret + month + "/";
break;
}
if (year != 255)
ret += year + 1900;
else
ret += "****";
return ret;
}
}

53
addons/EGFramework/Third_Part_SourceCode/BacNetPlugin/Base/BacnetDateRange.cs

@ -1,53 +0,0 @@ @@ -1,53 +0,0 @@
namespace System.IO.BACnet;
public struct BacnetDateRange : ASN1.IEncode, ASN1.IDecode
{
public BacnetDate startDate;
public BacnetDate endDate;
public BacnetDateRange(BacnetDate start, BacnetDate end)
{
startDate = start;
endDate = end;
}
public void Encode(EncodeBuffer buffer)
{
ASN1.encode_tag(buffer, (byte)BacnetApplicationTags.BACNET_APPLICATION_TAG_DATE, false, 4);
startDate.Encode(buffer);
ASN1.encode_tag(buffer, (byte)BacnetApplicationTags.BACNET_APPLICATION_TAG_DATE, false, 4);
endDate.Encode(buffer);
}
public int Decode(byte[] buffer, int offset, uint count)
{
var len = 1; // opening tag
len += startDate.Decode(buffer, offset + len, count);
len++;
len += endDate.Decode(buffer, offset + len, count);
return len;
}
public bool IsAFittingDate(DateTime date)
{
date = new DateTime(date.Year, date.Month, date.Day);
return date >= startDate.toDateTime() && date <= endDate.toDateTime();
}
public override string ToString()
{
string ret;
if (startDate.day != 255)
ret = "From " + startDate;
else
ret = "From **/**/**";
if (endDate.day != 255)
ret = ret + " to " + endDate;
else
ret += " to **/**/**";
return ret;
}
};

104
addons/EGFramework/Third_Part_SourceCode/BacNetPlugin/Base/BacnetDeviceObjectPropertyReference.cs

@ -1,104 +0,0 @@ @@ -1,104 +0,0 @@
namespace System.IO.BACnet;
public struct BacnetDeviceObjectPropertyReference : ASN1.IEncode
{
public BacnetObjectId objectIdentifier;
public BacnetPropertyIds propertyIdentifier;
public uint arrayIndex;
public BacnetObjectId deviceIndentifier;
public BacnetDeviceObjectPropertyReference(BacnetObjectId objectIdentifier, BacnetPropertyIds propertyIdentifier, BacnetObjectId? deviceIndentifier = null, uint arrayIndex = ASN1.BACNET_ARRAY_ALL)
{
this.objectIdentifier = objectIdentifier;
this.propertyIdentifier = propertyIdentifier;
this.arrayIndex = arrayIndex;
this.deviceIndentifier = deviceIndentifier ?? new BacnetObjectId(BacnetObjectTypes.MAX_BACNET_OBJECT_TYPE, 0);
}
public void Encode(EncodeBuffer buffer)
{
ASN1.bacapp_encode_device_obj_property_ref(buffer, this);
}
public BacnetObjectId ObjectId
{
get => objectIdentifier;
set => objectIdentifier = value;
}
public int ArrayIndex // shows -1 when it's ASN1.BACNET_ARRAY_ALL
{
get => arrayIndex != ASN1.BACNET_ARRAY_ALL
? (int)arrayIndex
: -1;
set => arrayIndex = value < 0
? ASN1.BACNET_ARRAY_ALL
: (uint)value;
}
public BacnetObjectId? DeviceId // shows null when it's not OBJECT_DEVICE
{
get
{
return deviceIndentifier.type == BacnetObjectTypes.OBJECT_DEVICE
? (BacnetObjectId?)deviceIndentifier
: null;
}
set
{
deviceIndentifier = value ?? new BacnetObjectId();
}
}
public BacnetPropertyIds PropertyId
{
get => propertyIdentifier;
set => propertyIdentifier = value;
}
public static object Parse(string value)
{
var parts = value.Split(new[] { '.' }, StringSplitOptions.RemoveEmptyEntries);
BacnetObjectId? deviceId = null;
BacnetObjectId objectId;
switch (parts.Length)
{
case 2:
objectId = BacnetObjectId.Parse(parts[0]);
break;
case 3:
deviceId = BacnetObjectId.Parse(parts[0]);
objectId = BacnetObjectId.Parse(parts[1]);
break;
default:
throw new ArgumentException("Invalid format", nameof(value));
}
if (!Enum.TryParse(parts.Last(), out BacnetPropertyIds propertyId))
{
if (!uint.TryParse(parts.Last(), out var vendorSpecificPropertyId))
throw new ArgumentException("Invalid format of property id", nameof(value));
propertyId = (BacnetPropertyIds)vendorSpecificPropertyId;
}
return new BacnetDeviceObjectPropertyReference
{
DeviceId = deviceId,
ObjectId = objectId,
PropertyId = propertyId,
ArrayIndex = -1
};
}
public override string ToString()
{
return DeviceId != null
? $"{DeviceId}.{ObjectId}.{PropertyId}"
: $"{ObjectId}.{PropertyId}";
}
}

11
addons/EGFramework/Third_Part_SourceCode/BacNetPlugin/Base/BacnetDeviceStatus.cs

@ -1,11 +0,0 @@ @@ -1,11 +0,0 @@
namespace System.IO.BACnet;
public enum BacnetDeviceStatus : byte
{
OPERATIONAL = 0,
OPERATIONAL_READONLY = 1,
DOWNLOAD_REQUIRED = 2,
DOWNLOAD_IN_PROGRESS = 3,
NON_OPERATIONAL = 4,
BACKUP_IN_PROGRESS = 5
}

22
addons/EGFramework/Third_Part_SourceCode/BacNetPlugin/Base/BacnetError.cs

@ -1,22 +0,0 @@ @@ -1,22 +0,0 @@
namespace System.IO.BACnet;
public struct BacnetError
{
public BacnetErrorClasses error_class;
public BacnetErrorCodes error_code;
public BacnetError(BacnetErrorClasses errorClass, BacnetErrorCodes errorCode)
{
error_class = errorClass;
error_code = errorCode;
}
public BacnetError(uint errorClass, uint errorCode)
{
error_class = (BacnetErrorClasses)errorClass;
error_code = (BacnetErrorCodes)errorCode;
}
public override string ToString()
{
return $"{error_class}: {error_code}";
}
}

21
addons/EGFramework/Third_Part_SourceCode/BacNetPlugin/Base/BacnetErrorClasses.cs

@ -1,21 +0,0 @@ @@ -1,21 +0,0 @@
namespace System.IO.BACnet;
public enum BacnetErrorClasses
{
ERROR_CLASS_DEVICE = 0,
ERROR_CLASS_OBJECT = 1,
ERROR_CLASS_PROPERTY = 2,
ERROR_CLASS_RESOURCES = 3,
ERROR_CLASS_SECURITY = 4,
ERROR_CLASS_SERVICES = 5,
ERROR_CLASS_VT = 6,
ERROR_CLASS_COMMUNICATION = 7,
/* Enumerated values 0-63 are reserved for definition by ASHRAE. */
/* Enumerated values 64-65535 may be used by others subject to */
/* the procedures and constraints described in Clause 23. */
MAX_BACNET_ERROR_CLASS = 8,
/* do the MAX here instead of outside of enum so that
compilers will allocate adequate sized datatype for enum */
ERROR_CLASS_PROPRIETARY_FIRST = 64,
ERROR_CLASS_PROPRIETARY_LAST = 65535
}

246
addons/EGFramework/Third_Part_SourceCode/BacNetPlugin/Base/BacnetErrorCodes.cs

@ -1,246 +0,0 @@ @@ -1,246 +0,0 @@
namespace System.IO.BACnet;
// These are sorted in the order given in Clause 18.
// ERROR, REJECT AND ABORT CODES The Class and Code pairings
// are required to be used in accordance with Clause 18.
public enum BacnetErrorCodes
{
/* valid for all classes */
ERROR_CODE_OTHER = 0,
/* Error Class - Device */
ERROR_CODE_DEVICE_BUSY = 3,
ERROR_CODE_CONFIGURATION_IN_PROGRESS = 2,
ERROR_CODE_OPERATIONAL_PROBLEM = 25,
/* Error Class - Object */
ERROR_CODE_DYNAMIC_CREATION_NOT_SUPPORTED = 4,
ERROR_CODE_NO_OBJECTS_OF_SPECIFIED_TYPE = 17,
ERROR_CODE_OBJECT_DELETION_NOT_PERMITTED = 23,
ERROR_CODE_OBJECT_IDENTIFIER_ALREADY_EXISTS = 24,
ERROR_CODE_READ_ACCESS_DENIED = 27,
ERROR_CODE_UNKNOWN_OBJECT = 31,
ERROR_CODE_UNSUPPORTED_OBJECT_TYPE = 36,
/* Error Class - Property */
ERROR_CODE_CHARACTER_SET_NOT_SUPPORTED = 41,
ERROR_CODE_DATATYPE_NOT_SUPPORTED = 47,
ERROR_CODE_INCONSISTENT_SELECTION_CRITERION = 8,
ERROR_CODE_INVALID_ARRAY_INDEX = 42,
ERROR_CODE_INVALID_DATA_TYPE = 9,
ERROR_CODE_NOT_COV_PROPERTY = 44,
ERROR_CODE_OPTIONAL_FUNCTIONALITY_NOT_SUPPORTED = 45,
ERROR_CODE_PROPERTY_IS_NOT_AN_ARRAY = 50,
/* ERROR_CODE_READ_ACCESS_DENIED = 27, */
ERROR_CODE_UNKNOWN_PROPERTY = 32,
ERROR_CODE_VALUE_OUT_OF_RANGE = 37,
ERROR_CODE_WRITE_ACCESS_DENIED = 40,
/* Error Class - Resources */
ERROR_CODE_NO_SPACE_FOR_OBJECT = 18,
ERROR_CODE_NO_SPACE_TO_ADD_LIST_ELEMENT = 19,
ERROR_CODE_NO_SPACE_TO_WRITE_PROPERTY = 20,
/* Error Class - Security */
ERROR_CODE_AUTHENTICATION_FAILED = 1,
/* ERROR_CODE_CHARACTER_SET_NOT_SUPPORTED = 41, */
ERROR_CODE_INCOMPATIBLE_SECURITY_LEVELS = 6,
ERROR_CODE_INVALID_OPERATOR_NAME = 12,
ERROR_CODE_KEY_GENERATION_ERROR = 15,
ERROR_CODE_PASSWORD_FAILURE = 26,
ERROR_CODE_SECURITY_NOT_SUPPORTED = 28,
ERROR_CODE_TIMEOUT = 30,
/* Error Class - Services */
/* ERROR_CODE_CHARACTER_SET_NOT_SUPPORTED = 41, */
ERROR_CODE_COV_SUBSCRIPTION_FAILED = 43,
ERROR_CODE_DUPLICATE_NAME = 48,
ERROR_CODE_DUPLICATE_OBJECT_ID = 49,
ERROR_CODE_FILE_ACCESS_DENIED = 5,
ERROR_CODE_INCONSISTENT_PARAMETERS = 7,
ERROR_CODE_INVALID_CONFIGURATION_DATA = 46,
ERROR_CODE_INVALID_FILE_ACCESS_METHOD = 10,
ERROR_CODE_INVALID_FILE_START_POSITION = 11,
ERROR_CODE_INVALID_PARAMETER_DATA_TYPE = 13,
ERROR_CODE_INVALID_TIME_STAMP = 14,
ERROR_CODE_MISSING_REQUIRED_PARAMETER = 16,
/* ERROR_CODE_OPTIONAL_FUNCTIONALITY_NOT_SUPPORTED = 45, */
ERROR_CODE_PROPERTY_IS_NOT_A_LIST = 22,
ERROR_CODE_SERVICE_REQUEST_DENIED = 29,
/* Error Class - VT */
ERROR_CODE_UNKNOWN_VT_CLASS = 34,
ERROR_CODE_UNKNOWN_VT_SESSION = 35,
ERROR_CODE_NO_VT_SESSIONS_AVAILABLE = 21,
ERROR_CODE_VT_SESSION_ALREADY_CLOSED = 38,
ERROR_CODE_VT_SESSION_TERMINATION_FAILURE = 39,
/* unused */
ERROR_CODE_RESERVED1 = 33,
/* new error codes from new addenda */
ERROR_CODE_ABORT_BUFFER_OVERFLOW = 51,
ERROR_CODE_ABORT_INVALID_APDU_IN_THIS_STATE = 52,
ERROR_CODE_ABORT_PREEMPTED_BY_HIGHER_PRIORITY_TASK = 53,
ERROR_CODE_ABORT_SEGMENTATION_NOT_SUPPORTED = 54,
ERROR_CODE_ABORT_PROPRIETARY = 55,
ERROR_CODE_ABORT_OTHER = 56,
ERROR_CODE_INVALID_TAG = 57,
ERROR_CODE_NETWORK_DOWN = 58,
ERROR_CODE_REJECT_BUFFER_OVERFLOW = 59,
ERROR_CODE_REJECT_INCONSISTENT_PARAMETERS = 60,
ERROR_CODE_REJECT_INVALID_PARAMETER_DATA_TYPE = 61,
ERROR_CODE_REJECT_INVALID_TAG = 62,
ERROR_CODE_REJECT_MISSING_REQUIRED_PARAMETER = 63,
ERROR_CODE_REJECT_PARAMETER_OUT_OF_RANGE = 64,
ERROR_CODE_REJECT_TOO_MANY_ARGUMENTS = 65,
ERROR_CODE_REJECT_UNDEFINED_ENUMERATION = 66,
ERROR_CODE_REJECT_UNRECOGNIZED_SERVICE = 67,
ERROR_CODE_REJECT_PROPRIETARY = 68,
ERROR_CODE_REJECT_OTHER = 69,
ERROR_CODE_UNKNOWN_DEVICE = 70,
ERROR_CODE_UNKNOWN_ROUTE = 71,
ERROR_CODE_VALUE_NOT_INITIALIZED = 72,
ERROR_CODE_INVALID_EVENT_STATE = 73,
ERROR_CODE_NO_ALARM_CONFIGURED = 74,
ERROR_CODE_LOG_BUFFER_FULL = 75,
ERROR_CODE_LOGGED_VALUE_PURGED = 76,
ERROR_CODE_NO_PROPERTY_SPECIFIED = 77,
ERROR_CODE_NOT_CONFIGURED_FOR_TRIGGERED_LOGGING = 78,
ERROR_CODE_UNKNOWN_SUBSCRIPTION = 79,
ERROR_CODE_PARAMETER_OUT_OF_RANGE = 80,
ERROR_CODE_LIST_ELEMENT_NOT_FOUND = 81,
ERROR_CODE_BUSY = 82,
ERROR_CODE_COMMUNICATION_DISABLED = 83,
ERROR_CODE_SUCCESS = 84,
ERROR_CODE_ACCESS_DENIED = 85,
ERROR_CODE_BAD_DESTINATION_ADDRESS = 86,
ERROR_CODE_BAD_DESTINATION_DEVICE_ID = 87,
ERROR_CODE_BAD_SIGNATURE = 88,
ERROR_CODE_BAD_SOURCE_ADDRESS = 89,
ERROR_CODE_BAD_TIMESTAMP = 90,
ERROR_CODE_CANNOT_USE_KEY = 91,
ERROR_CODE_CANNOT_VERIFY_MESSAGE_ID = 92,
ERROR_CODE_CORRECT_KEY_REVISION = 93,
ERROR_CODE_DESTINATION_DEVICE_ID_REQUIRED = 94,
ERROR_CODE_DUPLICATE_MESSAGE = 95,
ERROR_CODE_ENCRYPTION_NOT_CONFIGURED = 96,
ERROR_CODE_ENCRYPTION_REQUIRED = 97,
ERROR_CODE_INCORRECT_KEY = 98,
ERROR_CODE_INVALID_KEY_DATA = 99,
ERROR_CODE_KEY_UPDATE_IN_PROGRESS = 100,
ERROR_CODE_MALFORMED_MESSAGE = 101,
ERROR_CODE_NOT_KEY_SERVER = 102,
ERROR_CODE_SECURITY_NOT_CONFIGURED = 103,
ERROR_CODE_SOURCE_SECURITY_REQUIRED = 104,
ERROR_CODE_TOO_MANY_KEYS = 105,
ERROR_CODE_UNKNOWN_AUTHENTICATION_TYPE = 106,
ERROR_CODE_UNKNOWN_KEY = 107,
ERROR_CODE_UNKNOWN_KEY_REVISION = 108,
ERROR_CODE_UNKNOWN_SOURCE_MESSAGE = 109,
ERROR_CODE_NOT_ROUTER_TO_DNET = 110,
ERROR_CODE_ROUTER_BUSY = 111,
ERROR_CODE_UNKNOWN_NETWORK_MESSAGE = 112,
ERROR_CODE_MESSAGE_TOO_LONG = 113,
ERROR_CODE_SECURITY_ERROR = 114,
ERROR_CODE_ADDRESSING_ERROR = 115,
ERROR_CODE_WRITE_BDT_FAILED = 116,
ERROR_CODE_READ_BDT_FAILED = 117,
ERROR_CODE_REGISTER_FOREIGN_DEVICE_FAILED = 118,
ERROR_CODE_READ_FDT_FAILED = 119,
ERROR_CODE_DELETE_FDT_ENTRY_FAILED = 120,
ERROR_CODE_DISTRIBUTE_BROADCAST_FAILED = 121,
ERROR_CODE_UNKNOWN_FILE_SIZE = 122,
ERROR_CODE_ABORT_APDU_TOO_LONG = 123,
ERROR_CODE_ABORT_APPLICATION_EXCEEDED_REPLY_TIME = 124,
ERROR_CODE_ABORT_OUT_OF_RESOURCES = 125,
ERROR_CODE_ABORT_TSM_TIMEOUT = 126,
ERROR_CODE_ABORT_WINDOW_SIZE_OUT_OF_RANGE = 127,
ERROR_CODE_FILE_FULL = 128,
ERROR_CODE_INCONSISTENT_CONFIGURATION = 129,
ERROR_CODE_INCONSISTENT_OBJECT_TYPE = 130,
ERROR_CODE_INTERNAL_ERROR = 131,
ERROR_CODE_NOT_CONFIGURED = 132,
ERROR_CODE_OUT_OF_MEMORY = 133,
ERROR_CODE_VALUE_TOO_LONG = 134,
ERROR_CODE_ABORT_INSUFFICIENT_SECURITY = 135,
ERROR_CODE_ABORT_SECURITY_ERROR = 136,
ERROR_CODE_DUPLICATE_ENTRY = 137,
ERROR_CODE_INVALID_VALUE_IN_THIS_STATE = 138,
ERROR_CODE_INVALID_OPERATION_IN_THIS_STATE = 139,
ERROR_CODE_LIST_ITEM_NOT_NUMBERED = 140,
ERROR_CODE_LIST_ITEM_NOT_TIMESTAMPED = 141,
ERROR_CODE_INVALID_DATA_ENCODING = 142,
ERROR_CODE_BVLC_FUNCTION_UNKNOWN = 143,
ERROR_CODE_BVLC_PROPRIETARY_FUNCTION_UNKNOWN = 144,
ERROR_CODE_HEADER_ENCODING_ERROR = 145,
ERROR_CODE_HEADER_NOT_UNDERSTOOD = 146,
ERROR_CODE_MESSAGE_INCOMPLETE = 147,
ERROR_CODE_NOT_A_BACNET_SC_HUB = 148,
ERROR_CODE_PAYLOAD_EXPECTED = 149,
ERROR_CODE_UNEXPECTED_DATA = 150,
ERROR_CODE_NODE_DUPLICATE_VMAC = 151,
ERROR_CODE_HTTP_UNEXPECTED_RESPONSE_CODE = 152,
ERROR_CODE_HTTP_NO_UPGRADE = 153,
ERROR_CODE_HTTP_RESOURCE_NOT_LOCAL = 154,
ERROR_CODE_HTTP_PROXY_AUTHENTICATION_FAILED = 155,
ERROR_CODE_HTTP_RESPONSE_TIMEOUT = 156,
ERROR_CODE_HTTP_RESPONSE_SYNTAX_ERROR = 157,
ERROR_CODE_HTTP_RESPONSE_VALUE_ERROR = 158,
ERROR_CODE_HTTP_RESPONSE_MISSING_HEADER = 159,
ERROR_CODE_HTTP_WEBSOCKET_HEADER_ERROR = 160,
ERROR_CODE_HTTP_UPGRADE_REQUIRED = 161,
ERROR_CODE_HTTP_UPGRADE_ERROR = 162,
ERROR_CODE_HTTP_TEMPORARY_UNAVAILABLE = 163,
ERROR_CODE_HTTP_NOT_A_SERVER = 164,
ERROR_CODE_HTTP_ERROR = 165,
ERROR_CODE_WEBSOCKET_SCHEME_NOT_SUPPORTED = 166,
ERROR_CODE_WEBSOCKET_UNKNOWN_CONTROL_MESSAGE = 167,
ERROR_CODE_WEBSOCKET_CLOSE_ERROR = 168,
ERROR_CODE_WEBSOCKET_CLOSED_BY_PEER = 169,
ERROR_CODE_WEBSOCKET_ENDPOINT_LEAVES = 170,
ERROR_CODE_WEBSOCKET_PROTOCOL_ERROR = 171,
ERROR_CODE_WEBSOCKET_DATA_NOT_ACCEPTED = 172,
ERROR_CODE_WEBSOCKET_CLOSED_ABNORMALLY = 173,
ERROR_CODE_WEBSOCKET_DATA_INCONSISTENT = 174,
ERROR_CODE_WEBSOCKET_DATA_AGAINST_POLICY = 175,
ERROR_CODE_WEBSOCKET_FRAME_TOO_LONG = 176,
ERROR_CODE_WEBSOCKET_EXTENSION_MISSING = 177,
ERROR_CODE_WEBSOCKET_REQUEST_UNAVAILABLE = 178,
ERROR_CODE_WEBSOCKET_ERROR = 179,
ERROR_CODE_TLS_CLIENT_CERTIFICATE_ERROR = 180,
ERROR_CODE_TLS_SERVER_CERTIFICATE_ERROR = 181,
ERROR_CODE_TLS_CLIENT_AUTHENTICATION_FAILED = 182,
ERROR_CODE_TLS_SERVER_AUTHENTICATION_FAILED = 183,
ERROR_CODE_TLS_CLIENT_CERTIFICATE_EXPIRED = 184,
ERROR_CODE_TLS_SERVER_CERTIFICATE_EXPIRED = 185,
ERROR_CODE_TLS_CLIENT_CERTIFICATE_REVOKED = 186,
ERROR_CODE_TLS_SERVER_CERTIFICATE_REVOKED = 187,
ERROR_CODE_TLS_ERROR = 188,
ERROR_CODE_DNS_UNAVAILABLE = 189,
ERROR_CODE_DNS_NAME_RESOLUTION_FAILED = 190,
ERROR_CODE_DNS_RESOLVER_FAILURE = 191,
ERROR_CODE_DNS_ERROR = 192,
ERROR_CODE_TCP_CONNECT_TIMEOUT = 193,
ERROR_CODE_TCP_CONNECTION_REFUSED = 194,
ERROR_CODE_TCP_CLOSED_BY_LOCAL = 195,
ERROR_CODE_TCP_CLOSED_OTHER = 196,
ERROR_CODE_TCP_ERROR = 197,
ERROR_CODE_IP_ADDRESS_NOT_REACHABLE = 198,
ERROR_CODE_IP_ERROR = 199,
ERROR_CODE_CERTIFICATE_EXPIRED = 200,
ERROR_CODE_CERTIFICATE_INVALID = 201,
ERROR_CODE_CERTIFICATE_MALFORMED = 202,
ERROR_CODE_CERTIFICATE_REVOKED = 203,
ERROR_CODE_UNKNOWN_SECURITY_KEY = 204,
ERROR_CODE_REFERENCED_PORT_IN_ERROR = 205,
MAX_BACNET_ERROR_CODE = 206,
ERROR_CODE_RESERVED_MAX = 255,
/* Enumerated values 0-255 are reserved for definition by ASHRAE. */
/* Enumerated values 256-65535 may be used by others subject to */
/* the procedures and constraints described in Clause 23. */
/* do the max range inside of enum so that
compilers will allocate adequate sized datatype for enum
which is used to store decoding */
ERROR_CODE_PROPRIETARY_FIRST = 256,
ERROR_CODE_PROPRIETARY_LAST = 65535
}

140
addons/EGFramework/Third_Part_SourceCode/BacNetPlugin/Base/BacnetEventNotificationData.cs

@ -1,140 +0,0 @@ @@ -1,140 +0,0 @@
namespace System.IO.BACnet;
public struct BacnetEventNotificationData
{
public uint processIdentifier;
public BacnetObjectId initiatingObjectIdentifier;
public BacnetObjectId eventObjectIdentifier;
public BacnetGenericTime timeStamp;
public uint notificationClass;
public byte priority;
public BacnetEventTypes eventType;
public string messageText; /* OPTIONAL - Set to NULL if not being used */
public BacnetNotifyTypes notifyType;
public bool ackRequired;
public BacnetEventStates fromState;
public BacnetEventStates toState;
/*
** Each of these structures in the union maps to a particular eventtype
** Based on BACnetNotificationParameters
*/
/*
** EVENT_CHANGE_OF_BITSTRING
*/
public BacnetBitString changeOfBitstring_referencedBitString;
public BacnetBitString changeOfBitstring_statusFlags;
/*
** EVENT_CHANGE_OF_STATE
*/
public BacnetPropertyState changeOfState_newState;
public BacnetBitString changeOfState_statusFlags;
/*
** EVENT_CHANGE_OF_VALUE
*/
public BacnetBitString changeOfValue_changedBits;
public float changeOfValue_changeValue;
public BacnetCOVTypes? changeOfValue_tag;
public BacnetBitString changeOfValue_statusFlags;
/*
** EVENT_COMMAND_FAILURE
*/
public uint commandFailure_commandValue;
public BacnetBitString commandFailure_statusFlags;
public uint commandFailure_feedbackValue;
/*
** EVENT_FLOATING_LIMIT
*/
public float floatingLimit_referenceValue;
public BacnetBitString floatingLimit_statusFlags;
public float floatingLimit_setPointValue;
public float floatingLimit_errorLimit;
/*
** EVENT_OUT_OF_RANGE
*/
public float outOfRange_exceedingValue;
public BacnetBitString outOfRange_statusFlags;
public float outOfRange_deadband;
public float outOfRange_exceededLimit;
/*
** EVENT_CHANGE_OF_LIFE_SAFETY
*/
public BacnetLifeSafetyStates? changeOfLifeSafety_newState;
public BacnetLifeSafetyModes? changeOfLifeSafety_newMode;
public BacnetBitString changeOfLifeSafety_statusFlags;
public BacnetLifeSafetyOperations? changeOfLifeSafety_operationExpected;
/*
** EVENT_EXTENDED
**
** Not Supported!
*/
/*
** EVENT_BUFFER_READY
*/
public BacnetDeviceObjectPropertyReference bufferReady_bufferProperty;
public uint bufferReady_previousNotification;
public uint bufferReady_currentNotification;
/*
** EVENT_UNSIGNED_RANGE
*/
public uint unsignedRange_exceedingValue;
public BacnetBitString unsignedRange_statusFlags;
public uint unsignedRange_exceededLimit;
/*
** EVENT_EXTENDED
*/
public uint extended_vendorId;
public uint extended_eventType;
public object[] extended_parameters;
public override string ToString()
{
return $"initiatingObject: {initiatingObjectIdentifier}, eventObject: {eventObjectIdentifier}, "
+ $"eventType: {eventType}, notifyType: {notifyType}, timeStamp: {timeStamp}, "
+ $"fromState: {fromState}, toState: {toState}, {GetEventDetails() ?? "no details"}";
}
private string GetEventDetails()
{
switch (eventType)
{
case BacnetEventTypes.EVENT_CHANGE_OF_BITSTRING:
return $"referencedBitString: {changeOfBitstring_referencedBitString}, statusFlags: {changeOfBitstring_statusFlags}";
case BacnetEventTypes.EVENT_CHANGE_OF_STATE:
return $"newState: {changeOfState_newState}, statusFlags: {changeOfState_statusFlags}";
case BacnetEventTypes.EVENT_CHANGE_OF_VALUE:
return $"changedBits: {changeOfValue_changedBits}, changeValue: {changeOfValue_changeValue}, "
+ $"tag: {changeOfValue_tag}, statusFlags: {changeOfValue_statusFlags}";
case BacnetEventTypes.EVENT_FLOATING_LIMIT:
return $"referenceValue: {floatingLimit_referenceValue}, statusFlags: {floatingLimit_statusFlags}, "
+ $"setPointValue: {floatingLimit_setPointValue}, errorLimit: {floatingLimit_errorLimit}";
case BacnetEventTypes.EVENT_OUT_OF_RANGE:
return $"exceedingValue: {outOfRange_exceedingValue}, statusFlags: {outOfRange_statusFlags}, "
+ $"deadband: {outOfRange_deadband}, exceededLimit: {outOfRange_exceededLimit}";
case BacnetEventTypes.EVENT_CHANGE_OF_LIFE_SAFETY:
return $"newState: {changeOfLifeSafety_newState}, newMode: {changeOfLifeSafety_newMode}, "
+
$"statusFlags: {changeOfLifeSafety_statusFlags}, operationExpected: {changeOfLifeSafety_operationExpected}";
case BacnetEventTypes.EVENT_BUFFER_READY:
return $"bufferProperty: {bufferReady_bufferProperty}, previousNotification: {bufferReady_previousNotification}, "
+ $"currentNotification: {bufferReady_currentNotification}";
case BacnetEventTypes.EVENT_UNSIGNED_RANGE:
return $"exceedingValue: {unsignedRange_exceedingValue}, statusFlags: {unsignedRange_statusFlags}, "
+ $"exceededLimit: {unsignedRange_exceededLimit}";
case BacnetEventTypes.EVENT_EXTENDED:
return $"vendorId: {extended_vendorId}, extendedEventType: {extended_eventType}, parameters: [{extended_parameters?.Length ?? 0}]";
default:
return null;
}
}
};

20
addons/EGFramework/Third_Part_SourceCode/BacNetPlugin/Base/BacnetGenericTime.cs

@ -1,20 +0,0 @@ @@ -1,20 +0,0 @@
namespace System.IO.BACnet;
public struct BacnetGenericTime
{
public BacnetTimestampTags Tag;
public DateTime Time;
public ushort Sequence;
public BacnetGenericTime(DateTime time, BacnetTimestampTags tag, ushort sequence = 0)
{
Time = time;
Tag = tag;
Sequence = sequence;
}
public override string ToString()
{
return $"{Time}";
}
}

12
addons/EGFramework/Third_Part_SourceCode/BacNetPlugin/Base/BacnetGetEventInformationData.cs

@ -1,12 +0,0 @@ @@ -1,12 +0,0 @@
namespace System.IO.BACnet;
public struct BacnetGetEventInformationData
{
public BacnetObjectId objectIdentifier;
public BacnetEventStates eventState;
public BacnetBitString acknowledgedTransitions;
public BacnetGenericTime[] eventTimeStamps; //3
public BacnetNotifyTypes notifyType;
public BacnetBitString eventEnable;
public uint[] eventPriorities; //3
}

143
addons/EGFramework/Third_Part_SourceCode/BacNetPlugin/Base/BacnetLogRecord.cs

@ -1,143 +0,0 @@ @@ -1,143 +0,0 @@
namespace System.IO.BACnet;
public struct BacnetLogRecord
{
public DateTime timestamp;
/* logDatum: CHOICE { */
public BacnetTrendLogValueType type;
//private BacnetBitString log_status;
//private bool boolean_value;
//private float real_value;
//private uint enum_value;
//private uint unsigned_value;
//private int signed_value;
//private BacnetBitString bitstring_value;
//private bool null_value;
//private BacnetError failure;
//private float time_change;
private object any_value;
/* } */
public BacnetBitString statusFlags;
public BacnetLogRecord(BacnetTrendLogValueType type, object value, DateTime stamp, uint status)
{
this.type = type;
timestamp = stamp;
statusFlags = BacnetBitString.ConvertFromInt(status);
any_value = null;
Value = value;
}
public object Value
{
get
{
switch (type)
{
case BacnetTrendLogValueType.TL_TYPE_ANY:
return any_value;
case BacnetTrendLogValueType.TL_TYPE_BITS:
return (BacnetBitString)Convert.ChangeType(any_value, typeof(BacnetBitString));
case BacnetTrendLogValueType.TL_TYPE_BOOL:
return (bool)Convert.ChangeType(any_value, typeof(bool));
case BacnetTrendLogValueType.TL_TYPE_DELTA:
return (float)Convert.ChangeType(any_value, typeof(float));
case BacnetTrendLogValueType.TL_TYPE_ENUM:
return (uint)Convert.ChangeType(any_value, typeof(uint));
case BacnetTrendLogValueType.TL_TYPE_ERROR:
if (any_value != null)
return (BacnetError)Convert.ChangeType(any_value, typeof(BacnetError));
else
return new BacnetError(BacnetErrorClasses.ERROR_CLASS_DEVICE, BacnetErrorCodes.ERROR_CODE_ABORT_OTHER);
case BacnetTrendLogValueType.TL_TYPE_NULL:
return null;
case BacnetTrendLogValueType.TL_TYPE_REAL:
return (float)Convert.ChangeType(any_value, typeof(float));
case BacnetTrendLogValueType.TL_TYPE_SIGN:
return (int)Convert.ChangeType(any_value, typeof(int));
case BacnetTrendLogValueType.TL_TYPE_STATUS:
return (BacnetBitString)Convert.ChangeType(any_value, typeof(BacnetBitString));
case BacnetTrendLogValueType.TL_TYPE_UNSIGN:
return (uint)Convert.ChangeType(any_value, typeof(uint));
default:
throw new NotSupportedException();
}
}
set
{
switch (type)
{
case BacnetTrendLogValueType.TL_TYPE_ANY:
any_value = value;
break;
case BacnetTrendLogValueType.TL_TYPE_BITS:
if (value == null) value = new BacnetBitString();
if (value.GetType() != typeof(BacnetBitString))
value = BacnetBitString.ConvertFromInt((uint)Convert.ChangeType(value, typeof(uint)));
any_value = (BacnetBitString)value;
break;
case BacnetTrendLogValueType.TL_TYPE_BOOL:
if (value == null) value = false;
if (value.GetType() != typeof(bool))
value = (bool)Convert.ChangeType(value, typeof(bool));
any_value = (bool)value;
break;
case BacnetTrendLogValueType.TL_TYPE_DELTA:
if (value == null) value = (float)0;
if (value.GetType() != typeof(float))
value = (float)Convert.ChangeType(value, typeof(float));
any_value = (float)value;
break;
case BacnetTrendLogValueType.TL_TYPE_ENUM:
if (value == null) value = (uint)0;
if (value.GetType() != typeof(uint))
value = (uint)Convert.ChangeType(value, typeof(uint));
any_value = (uint)value;
break;
case BacnetTrendLogValueType.TL_TYPE_ERROR:
if (value == null) value = new BacnetError();
if (value.GetType() != typeof(BacnetError))
throw new ArgumentException();
any_value = (BacnetError)value;
break;
case BacnetTrendLogValueType.TL_TYPE_NULL:
if (value != null) throw new ArgumentException();
any_value = value;
break;
case BacnetTrendLogValueType.TL_TYPE_REAL:
if (value == null) value = (float)0;
if (value.GetType() != typeof(float))
value = (float)Convert.ChangeType(value, typeof(float));
any_value = (float)value;
break;
case BacnetTrendLogValueType.TL_TYPE_SIGN:
if (value == null) value = 0;
if (value.GetType() != typeof(int))
value = (int)Convert.ChangeType(value, typeof(int));
any_value = (int)value;
break;
case BacnetTrendLogValueType.TL_TYPE_STATUS:
if (value == null) value = new BacnetBitString();
if (value.GetType() != typeof(BacnetBitString))
value = BacnetBitString.ConvertFromInt((uint)Convert.ChangeType(value, typeof(uint)));
any_value = (BacnetBitString)value;
break;
case BacnetTrendLogValueType.TL_TYPE_UNSIGN:
if (value == null) value = (uint)0;
if (value.GetType() != typeof(uint))
value = (uint)Convert.ChangeType(value, typeof(uint));
any_value = (uint)value;
break;
default:
throw new NotSupportedException();
}
}
}
public T GetValue<T>()
{
return (T)Convert.ChangeType(Value, typeof(T));
}
}

11
addons/EGFramework/Third_Part_SourceCode/BacNetPlugin/Base/BacnetMaxAdpu.cs

@ -1,11 +0,0 @@ @@ -1,11 +0,0 @@
namespace System.IO.BACnet;
public enum BacnetMaxAdpu : byte
{
MAX_APDU50 = 0,
MAX_APDU128 = 1,
MAX_APDU206 = 2,
MAX_APDU480 = 3,
MAX_APDU1024 = 4,
MAX_APDU1476 = 5
}

13
addons/EGFramework/Third_Part_SourceCode/BacNetPlugin/Base/BacnetMaxSegments.cs

@ -1,13 +0,0 @@ @@ -1,13 +0,0 @@
namespace System.IO.BACnet;
public enum BacnetMaxSegments : byte
{
MAX_SEG0 = 0,
MAX_SEG2 = 0x10,
MAX_SEG4 = 0x20,
MAX_SEG8 = 0x30,
MAX_SEG16 = 0x40,
MAX_SEG32 = 0x50,
MAX_SEG64 = 0x60,
MAX_SEG65 = 0x70
}

23
addons/EGFramework/Third_Part_SourceCode/BacNetPlugin/Base/BacnetMstpFrameTypes.cs

@ -1,23 +0,0 @@ @@ -1,23 +0,0 @@
namespace System.IO.BACnet;
/* MS/TP Frame Type */
public enum BacnetMstpFrameTypes : byte
{
/* Frame Types 8 through 127 are reserved by ASHRAE. */
FRAME_TYPE_TOKEN = 0,
FRAME_TYPE_POLL_FOR_MASTER = 1,
FRAME_TYPE_REPLY_TO_POLL_FOR_MASTER = 2,
FRAME_TYPE_TEST_REQUEST = 3,
FRAME_TYPE_TEST_RESPONSE = 4,
FRAME_TYPE_BACNET_DATA_EXPECTING_REPLY = 5,
FRAME_TYPE_BACNET_DATA_NOT_EXPECTING_REPLY = 6,
FRAME_TYPE_REPLY_POSTPONED = 7,
/* Frame Types 128 through 255: Proprietary Frames */
/* These frames are available to vendors as proprietary (non-BACnet) frames. */
/* The first two octets of the Data field shall specify the unique vendor */
/* identification code, most significant octet first, for the type of */
/* vendor-proprietary frame to be conveyed. The length of the data portion */
/* of a Proprietary frame shall be in the range of 2 to 501 octets. */
FRAME_TYPE_PROPRIETARY_MIN = 128,
FRAME_TYPE_PROPRIETARY_MAX = 255
}

31
addons/EGFramework/Third_Part_SourceCode/BacNetPlugin/Base/BacnetNetworkMessageTypes.cs

@ -1,31 +0,0 @@ @@ -1,31 +0,0 @@
namespace System.IO.BACnet;
/*Network Layer Message Type */
/*If Bit 7 of the control octet described in 6.2.2 is 1, */
/* a message type octet shall be present as shown in Figure 6-1. */
/* The following message types are indicated: */
public enum BacnetNetworkMessageTypes : byte
{
NETWORK_MESSAGE_WHO_IS_ROUTER_TO_NETWORK = 0,
NETWORK_MESSAGE_I_AM_ROUTER_TO_NETWORK = 1,
NETWORK_MESSAGE_I_COULD_BE_ROUTER_TO_NETWORK = 2,
NETWORK_MESSAGE_REJECT_MESSAGE_TO_NETWORK = 3,
NETWORK_MESSAGE_ROUTER_BUSY_TO_NETWORK = 4,
NETWORK_MESSAGE_ROUTER_AVAILABLE_TO_NETWORK = 5,
NETWORK_MESSAGE_INIT_RT_TABLE = 6,
NETWORK_MESSAGE_INIT_RT_TABLE_ACK = 7,
NETWORK_MESSAGE_ESTABLISH_CONNECTION_TO_NETWORK = 8,
NETWORK_MESSAGE_DISCONNECT_CONNECTION_TO_NETWORK = 9,
NETWORK_MESSAGE_CHALLENGE_REQUEST = 10,
NETWORK_MESSAGE_SECURITY_PAYLOAD = 11,
NETWORK_MESSAGE_SECURITY_RESPONSE = 12,
NETWORK_MESSAGE_REQUEST_KEY_UPDATE = 13,
NETWORK_MESSAGE_UPDATE_KEY_SET = 14,
NETWORK_MESSAGE_UPDATE_DISTRIBUTION_KEY = 15,
NETWORK_MESSAGE_REQUEST_MASTER_KEY = 16,
NETWORK_MESSAGE_SET_MASTER_KEY = 17,
NETWORK_MESSAGE_WHAT_IS_NETWORK_NUMBER = 18,
NETWORK_MESSAGE_NETWORK_NUMBER_IS = 19
/* X'0A' to X'7F': Reserved for use by ASHRAE, */
/* X'80' to X'FF': Available for vendor proprietary messages */
}

17
addons/EGFramework/Third_Part_SourceCode/BacNetPlugin/Base/BacnetNodeTypes.cs

@ -1,17 +0,0 @@ @@ -1,17 +0,0 @@
namespace System.IO.BACnet;
public enum BacnetNodeTypes
{
NT_UNKNOWN,
NT_SYSTEM,
NT_NETWORK,
NT_DEVICE,
NT_ORGANIZATIONAL,
NT_AREA,
NT_EQUIPMENT,
NT_POINT,
NT_COLLECTION,
NT_PROPERTY,
NT_FUNCTIONAL,
NT_OTHER,
}

14
addons/EGFramework/Third_Part_SourceCode/BacNetPlugin/Base/BacnetNpduControls.cs

@ -1,14 +0,0 @@ @@ -1,14 +0,0 @@
namespace System.IO.BACnet;
[Flags]
public enum BacnetNpduControls : byte
{
PriorityNormalMessage = 0,
PriorityUrgentMessage = 1,
PriorityCriticalMessage = 2,
PriorityLifeSafetyMessage = 3,
ExpectingReply = 4,
SourceSpecified = 8,
DestinationSpecified = 32,
NetworkLayerMessage = 128
}

7
addons/EGFramework/Third_Part_SourceCode/BacNetPlugin/Base/BacnetObjectDescription.cs

@ -1,7 +0,0 @@ @@ -1,7 +0,0 @@
namespace System.IO.BACnet;
public struct BacnetObjectDescription
{
public BacnetObjectTypes typeId;
public List<BacnetPropertyIds> propsId;
}

82
addons/EGFramework/Third_Part_SourceCode/BacNetPlugin/Base/BacnetObjectId.cs

@ -1,82 +0,0 @@ @@ -1,82 +0,0 @@
namespace System.IO.BACnet;
[Serializable]
public struct BacnetObjectId : IComparable<BacnetObjectId>
{
public BacnetObjectTypes type;
public uint instance;
public BacnetObjectTypes Type
{
get => type;
set => type = value;
}
public uint Instance
{
get => instance;
set => instance = value;
}
public BacnetObjectId(BacnetObjectTypes type, uint instance)
{
this.type = type;
this.instance = instance;
}
public override string ToString()
{
return $"{Type}:{Instance}";
}
public override int GetHashCode()
{
return ToString().GetHashCode();
}
public override bool Equals(object obj)
{
return obj != null && obj.ToString().Equals(ToString());
}
public int CompareTo(BacnetObjectId other)
{
if (Type == other.Type)
return Instance.CompareTo(other.Instance);
if (Type == BacnetObjectTypes.OBJECT_DEVICE)
return -1;
if (other.Type == BacnetObjectTypes.OBJECT_DEVICE)
return 1;
// cast to int for comparison otherwise unpredictable behaviour with outbound enum (proprietary type)
return ((int)Type).CompareTo((int)other.Type);
}
public static bool operator ==(BacnetObjectId a, BacnetObjectId b)
{
return a.Equals(b);
}
public static bool operator !=(BacnetObjectId a, BacnetObjectId b)
{
return !(a == b);
}
public static BacnetObjectId Parse(string value)
{
var pattern = new Regex($"(?<{nameof(Type)}>.+):(?<{nameof(Instance)}>.+)");
if (string.IsNullOrEmpty(value) || !pattern.IsMatch(value))
return new BacnetObjectId();
var objectType = (BacnetObjectTypes)Enum.Parse(typeof(BacnetObjectTypes),
pattern.Match(value).Groups[nameof(Type)].Value);
var objectInstance = uint.Parse(pattern.Match(value).Groups[nameof(Instance)].Value);
return new BacnetObjectId(objectType, objectInstance);
}
};

82
addons/EGFramework/Third_Part_SourceCode/BacNetPlugin/Base/BacnetObjectTypes.cs

@ -1,82 +0,0 @@ @@ -1,82 +0,0 @@
namespace System.IO.BACnet;
public enum BacnetObjectTypes : uint
{
OBJECT_ANALOG_INPUT = 0,
OBJECT_ANALOG_OUTPUT = 1,
OBJECT_ANALOG_VALUE = 2,
OBJECT_BINARY_INPUT = 3,
OBJECT_BINARY_OUTPUT = 4,
OBJECT_BINARY_VALUE = 5,
OBJECT_CALENDAR = 6,
OBJECT_COMMAND = 7,
OBJECT_DEVICE = 8,
OBJECT_EVENT_ENROLLMENT = 9,
OBJECT_FILE = 10,
OBJECT_GROUP = 11,
OBJECT_LOOP = 12,
OBJECT_MULTI_STATE_INPUT = 13,
OBJECT_MULTI_STATE_OUTPUT = 14,
OBJECT_NOTIFICATION_CLASS = 15,
OBJECT_PROGRAM = 16,
OBJECT_SCHEDULE = 17,
OBJECT_AVERAGING = 18,
OBJECT_MULTI_STATE_VALUE = 19,
OBJECT_TRENDLOG = 20,
OBJECT_LIFE_SAFETY_POINT = 21,
OBJECT_LIFE_SAFETY_ZONE = 22,
OBJECT_ACCUMULATOR = 23,
OBJECT_PULSE_CONVERTER = 24,
OBJECT_EVENT_LOG = 25,
OBJECT_GLOBAL_GROUP = 26,
OBJECT_TREND_LOG_MULTIPLE = 27,
OBJECT_LOAD_CONTROL = 28,
OBJECT_STRUCTURED_VIEW = 29,
OBJECT_ACCESS_DOOR = 30,
OBJECT_TIMER = 31, /* Addendum 135-2012ay */
OBJECT_ACCESS_CREDENTIAL = 32, /* Addendum 2008-j */
OBJECT_ACCESS_POINT = 33,
OBJECT_ACCESS_RIGHTS = 34,
OBJECT_ACCESS_USER = 35,
OBJECT_ACCESS_ZONE = 36,
OBJECT_CREDENTIAL_DATA_INPUT = 37, /* authentication-factor-input */
OBJECT_NETWORK_SECURITY = 38, /* Addendum 2008-g */
OBJECT_BITSTRING_VALUE = 39, /* Addendum 2008-w */
OBJECT_CHARACTERSTRING_VALUE = 40, /* Addendum 2008-w */
OBJECT_DATE_PATTERN_VALUE = 41, /* Addendum 2008-w */
OBJECT_DATE_VALUE = 42, /* Addendum 2008-w */
OBJECT_DATETIME_PATTERN_VALUE = 43, /* Addendum 2008-w */
OBJECT_DATETIME_VALUE = 44, /* Addendum 2008-w */
OBJECT_INTEGER_VALUE = 45, /* Addendum 2008-w */
OBJECT_LARGE_ANALOG_VALUE = 46, /* Addendum 2008-w */
OBJECT_OCTETSTRING_VALUE = 47, /* Addendum 2008-w */
OBJECT_POSITIVE_INTEGER_VALUE = 48, /* Addendum 2008-w */
OBJECT_TIME_PATTERN_VALUE = 49, /* Addendum 2008-w */
OBJECT_TIME_VALUE = 50, /* Addendum 2008-w */
OBJECT_NOTIFICATION_FORWARDER = 51, /* Addendum 2010-af */
OBJECT_ALERT_ENROLLMENT = 52, /* Addendum 2010-af */
OBJECT_CHANNEL = 53, /* Addendum 2010-aa */
OBJECT_LIGHTING_OUTPUT = 54, /* Addendum 2010-i */
OBJECT_BINARY_LIGHTING_OUTPUT = 55, /* Addendum 135-2012az */
OBJECT_NETWORK_PORT = 56, /* Addendum 135-2012az */
OBJECT_ELEVATOR_GROUP = 57, /* Addendum 135-2012aq */
OBJECT_ESCALATOR = 58, /* Addendum 135-2012aq */
OBJECT_LIFT = 59, /* Addendum 135-2012aq */
OBJECT_STAGING = 60, /* Addendum 135-2016bd */
OBJECT_AUDIT_LOG = 61, /* Addendum 135-2016bi */
OBJECT_AUDIT_REPORTER = 62, /* Addendum 135-2016bi */
OBJECT_COLOR = 63, /* Addendum 135-2020ca */
OBJECT_COLOR_TEMPERATURE = 64, /* Addendum 135-2020ca */
/* Enumerated values 0-127 are reserved for definition by ASHRAE. */
/* Enumerated values 128-1023 may be used by others subject to */
/* the procedures and constraints described in Clause 23. */
/* do the max range inside of enum so that
compilers will allocate adequate sized datatype for enum
which is used to store decoding */
OBJECT_PROPRIETARY_MIN = 128,
OBJECT_PROPRIETARY_MAX = 1023,
MAX_BACNET_OBJECT_TYPE = 1024,
MAX_ASHRAE_OBJECT_TYPE = 65
}

22
addons/EGFramework/Third_Part_SourceCode/BacNetPlugin/Base/BacnetPduTypes.cs

@ -1,22 +0,0 @@ @@ -1,22 +0,0 @@
namespace System.IO.BACnet;
[Flags]
/* note: these are not the real values, */
/* but are shifted left for easy encoding */
public enum BacnetPduTypes : byte
{
PDU_TYPE_CONFIRMED_SERVICE_REQUEST = 0,
SERVER = 1,
NEGATIVE_ACK = 2,
SEGMENTED_RESPONSE_ACCEPTED = 2,
MORE_FOLLOWS = 4,
SEGMENTED_MESSAGE = 8,
PDU_TYPE_UNCONFIRMED_SERVICE_REQUEST = 0x10,
PDU_TYPE_SIMPLE_ACK = 0x20,
PDU_TYPE_COMPLEX_ACK = 0x30,
PDU_TYPE_SEGMENT_ACK = 0x40,
PDU_TYPE_ERROR = 0x50,
PDU_TYPE_REJECT = 0x60,
PDU_TYPE_ABORT = 0x70,
PDU_TYPE_MASK = 0xF0,
}

7
addons/EGFramework/Third_Part_SourceCode/BacNetPlugin/Base/BacnetPolarity.cs

@ -1,7 +0,0 @@ @@ -1,7 +0,0 @@
namespace System.IO.BACnet;
public enum BacnetPolarity : byte
{
POLARITY_NORMAL = 0,
POLARITY_REVERSE = 1
}

18
addons/EGFramework/Third_Part_SourceCode/BacNetPlugin/Base/BacnetProgramError.cs

@ -1,18 +0,0 @@ @@ -1,18 +0,0 @@
namespace System.IO.BACnet.Base;
public enum BacnetProgramError : ushort
{
PROGRAM_ERROR_NORMAL = 0,
PROGRAM_ERROR_LOAD_FAILED = 1,
PROGRAM_ERROR_INTERNAL = 2,
PROGRAM_ERROR_PROGRAM = 3,
PROGRAM_ERROR_OTHER = 4,
/* Enumerated values 0-63 are reserved for definition by ASHRAE. */
/* Enumerated values 64-65535 may be used by others subject to */
/* the procedures and constraints described in Clause 23. */
/* do the max range inside of enum so that
compilers will allocate adequate sized datatype for enum
which is used to store decoding */
PROGRAM_ERROR_PROPRIETARY_MIN = 64,
PROGRAM_ERROR_PROPRIETARY_MAX = 65535
}

11
addons/EGFramework/Third_Part_SourceCode/BacNetPlugin/Base/BacnetProgramRequest.cs

@ -1,11 +0,0 @@ @@ -1,11 +0,0 @@
namespace System.IO.BACnet.Base;
public enum BacnetProgramRequest
{
PROGRAM_REQUEST_READY = 0,
PROGRAM_REQUEST_LOAD = 1,
PROGRAM_REQUEST_RUN = 2,
PROGRAM_REQUEST_HALT = 3,
PROGRAM_REQUEST_RESTART = 4,
PROGRAM_REQUEST_UNLOAD = 5
}

11
addons/EGFramework/Third_Part_SourceCode/BacNetPlugin/Base/BacnetProgramState.cs

@ -1,11 +0,0 @@ @@ -1,11 +0,0 @@
namespace System.IO.BACnet.Base;
public enum BacnetProgramState
{
PROGRAM_STATE_IDLE = 0,
PROGRAM_STATE_LOADING = 1,
PROGRAM_STATE_RUNNING = 2,
PROGRAM_STATE_WAITING = 3,
PROGRAM_STATE_HALTED = 4,
PROGRAM_STATE_UNLOADING = 5
}

577
addons/EGFramework/Third_Part_SourceCode/BacNetPlugin/Base/BacnetPropertyIds.cs

@ -1,577 +0,0 @@ @@ -1,577 +0,0 @@
namespace System.IO.BACnet;
public enum BacnetPropertyIds
{
PROP_ACKED_TRANSITIONS = 0,
PROP_ACK_REQUIRED = 1,
PROP_ACTION = 2,
PROP_ACTION_TEXT = 3,
PROP_ACTIVE_TEXT = 4,
PROP_ACTIVE_VT_SESSIONS = 5,
PROP_ALARM_VALUE = 6,
PROP_ALARM_VALUES = 7,
PROP_ALL = 8,
PROP_ALL_WRITES_SUCCESSFUL = 9,
PROP_APDU_SEGMENT_TIMEOUT = 10,
PROP_APDU_TIMEOUT = 11,
PROP_APPLICATION_SOFTWARE_VERSION = 12,
PROP_ARCHIVE = 13,
PROP_BIAS = 14,
PROP_CHANGE_OF_STATE_COUNT = 15,
PROP_CHANGE_OF_STATE_TIME = 16,
PROP_NOTIFICATION_CLASS = 17,
PROP_BLANK_1 = 18,
PROP_CONTROLLED_VARIABLE_REFERENCE = 19,
PROP_CONTROLLED_VARIABLE_UNITS = 20,
PROP_CONTROLLED_VARIABLE_VALUE = 21,
PROP_COV_INCREMENT = 22,
PROP_DATE_LIST = 23,
PROP_DAYLIGHT_SAVINGS_STATUS = 24,
PROP_DEADBAND = 25,
PROP_DERIVATIVE_CONSTANT = 26,
PROP_DERIVATIVE_CONSTANT_UNITS = 27,
PROP_DESCRIPTION = 28,
PROP_DESCRIPTION_OF_HALT = 29,
PROP_DEVICE_ADDRESS_BINDING = 30,
PROP_DEVICE_TYPE = 31,
PROP_EFFECTIVE_PERIOD = 32,
PROP_ELAPSED_ACTIVE_TIME = 33,
PROP_ERROR_LIMIT = 34,
PROP_EVENT_ENABLE = 35,
PROP_EVENT_STATE = 36,
PROP_EVENT_TYPE = 37,
PROP_EXCEPTION_SCHEDULE = 38,
PROP_FAULT_VALUES = 39,
PROP_FEEDBACK_VALUE = 40,
PROP_FILE_ACCESS_METHOD = 41,
PROP_FILE_SIZE = 42,
PROP_FILE_TYPE = 43,
PROP_FIRMWARE_REVISION = 44,
PROP_HIGH_LIMIT = 45,
PROP_INACTIVE_TEXT = 46,
PROP_IN_PROCESS = 47,
PROP_INSTANCE_OF = 48,
PROP_INTEGRAL_CONSTANT = 49,
PROP_INTEGRAL_CONSTANT_UNITS = 50,
PROP_ISSUE_CONFIRMED_NOTIFICATIONS = 51,
PROP_LIMIT_ENABLE = 52,
PROP_LIST_OF_GROUP_MEMBERS = 53,
PROP_LIST_OF_OBJECT_PROPERTY_REFERENCES = 54,
PROP_LIST_OF_SESSION_KEYS = 55,
PROP_LOCAL_DATE = 56,
PROP_LOCAL_TIME = 57,
PROP_LOCATION = 58,
PROP_LOW_LIMIT = 59,
PROP_MANIPULATED_VARIABLE_REFERENCE = 60,
PROP_MAXIMUM_OUTPUT = 61,
PROP_MAX_APDU_LENGTH_ACCEPTED = 62,
PROP_MAX_INFO_FRAMES = 63,
PROP_MAX_MASTER = 64,
PROP_MAX_PRES_VALUE = 65,
PROP_MINIMUM_OFF_TIME = 66,
PROP_MINIMUM_ON_TIME = 67,
PROP_MINIMUM_OUTPUT = 68,
PROP_MIN_PRES_VALUE = 69,
PROP_MODEL_NAME = 70,
PROP_MODIFICATION_DATE = 71,
PROP_NOTIFY_TYPE = 72,
PROP_NUMBER_OF_APDU_RETRIES = 73,
PROP_NUMBER_OF_STATES = 74,
PROP_OBJECT_IDENTIFIER = 75,
PROP_OBJECT_LIST = 76,
PROP_OBJECT_NAME = 77,
PROP_OBJECT_PROPERTY_REFERENCE = 78,
PROP_OBJECT_TYPE = 79,
PROP_OPTIONAL = 80,
PROP_OUT_OF_SERVICE = 81,
PROP_OUTPUT_UNITS = 82,
PROP_EVENT_PARAMETERS = 83,
PROP_POLARITY = 84,
PROP_PRESENT_VALUE = 85,
PROP_PRIORITY = 86,
PROP_PRIORITY_ARRAY = 87,
PROP_PRIORITY_FOR_WRITING = 88,
PROP_PROCESS_IDENTIFIER = 89,
PROP_PROGRAM_CHANGE = 90,
PROP_PROGRAM_LOCATION = 91,
PROP_PROGRAM_STATE = 92,
PROP_PROPORTIONAL_CONSTANT = 93,
PROP_PROPORTIONAL_CONSTANT_UNITS = 94,
PROP_PROTOCOL_CONFORMANCE_CLASS = 95, /* deleted in version 1 revision 2 */
PROP_PROTOCOL_OBJECT_TYPES_SUPPORTED = 96,
PROP_PROTOCOL_SERVICES_SUPPORTED = 97,
PROP_PROTOCOL_VERSION = 98,
PROP_READ_ONLY = 99,
PROP_REASON_FOR_HALT = 100,
PROP_RECIPIENT = 101,
PROP_RECIPIENT_LIST = 102,
PROP_RELIABILITY = 103,
PROP_RELINQUISH_DEFAULT = 104,
PROP_REQUIRED = 105,
PROP_RESOLUTION = 106,
PROP_SEGMENTATION_SUPPORTED = 107,
PROP_SETPOINT = 108,
PROP_SETPOINT_REFERENCE = 109,
PROP_STATE_TEXT = 110,
PROP_STATUS_FLAGS = 111,
PROP_SYSTEM_STATUS = 112,
PROP_TIME_DELAY = 113,
PROP_TIME_OF_ACTIVE_TIME_RESET = 114,
PROP_TIME_OF_STATE_COUNT_RESET = 115,
PROP_TIME_SYNCHRONIZATION_RECIPIENTS = 116,
PROP_UNITS = 117,
PROP_UPDATE_INTERVAL = 118,
PROP_UTC_OFFSET = 119,
PROP_VENDOR_IDENTIFIER = 120,
PROP_VENDOR_NAME = 121,
PROP_VT_CLASSES_SUPPORTED = 122,
PROP_WEEKLY_SCHEDULE = 123,
PROP_ATTEMPTED_SAMPLES = 124,
PROP_AVERAGE_VALUE = 125,
PROP_BUFFER_SIZE = 126,
PROP_CLIENT_COV_INCREMENT = 127,
PROP_COV_RESUBSCRIPTION_INTERVAL = 128,
PROP_CURRENT_NOTIFY_TIME = 129,
PROP_EVENT_TIME_STAMPS = 130,
PROP_LOG_BUFFER = 131,
PROP_LOG_DEVICE_OBJECT_PROPERTY = 132,
/* The enable property is renamed from log-enable in
Addendum b to ANSI/ASHRAE 135-2004(135b-2) */
PROP_ENABLE = 133,
PROP_LOG_INTERVAL = 134,
PROP_MAXIMUM_VALUE = 135,
PROP_MINIMUM_VALUE = 136,
PROP_NOTIFICATION_THRESHOLD = 137,
PROP_PREVIOUS_NOTIFY_TIME = 138,
PROP_PROTOCOL_REVISION = 139,
PROP_RECORDS_SINCE_NOTIFICATION = 140,
PROP_RECORD_COUNT = 141,
PROP_START_TIME = 142,
PROP_STOP_TIME = 143,
PROP_STOP_WHEN_FULL = 144,
PROP_TOTAL_RECORD_COUNT = 145,
PROP_VALID_SAMPLES = 146,
PROP_WINDOW_INTERVAL = 147,
PROP_WINDOW_SAMPLES = 148,
PROP_MAXIMUM_VALUE_TIMESTAMP = 149,
PROP_MINIMUM_VALUE_TIMESTAMP = 150,
PROP_VARIANCE_VALUE = 151,
PROP_ACTIVE_COV_SUBSCRIPTIONS = 152,
PROP_BACKUP_FAILURE_TIMEOUT = 153,
PROP_CONFIGURATION_FILES = 154,
PROP_DATABASE_REVISION = 155,
PROP_DIRECT_READING = 156,
PROP_LAST_RESTORE_TIME = 157,
PROP_MAINTENANCE_REQUIRED = 158,
PROP_MEMBER_OF = 159,
PROP_MODE = 160,
PROP_OPERATION_EXPECTED = 161,
PROP_SETTING = 162,
PROP_SILENCED = 163,
PROP_TRACKING_VALUE = 164,
PROP_ZONE_MEMBERS = 165,
PROP_LIFE_SAFETY_ALARM_VALUES = 166,
PROP_MAX_SEGMENTS_ACCEPTED = 167,
PROP_PROFILE_NAME = 168,
PROP_AUTO_SLAVE_DISCOVERY = 169,
PROP_MANUAL_SLAVE_ADDRESS_BINDING = 170,
PROP_SLAVE_ADDRESS_BINDING = 171,
PROP_SLAVE_PROXY_ENABLE = 172,
PROP_LAST_NOTIFY_RECORD = 173,
PROP_SCHEDULE_DEFAULT = 174,
PROP_ACCEPTED_MODES = 175,
PROP_ADJUST_VALUE = 176,
PROP_COUNT = 177,
PROP_COUNT_BEFORE_CHANGE = 178,
PROP_COUNT_CHANGE_TIME = 179,
PROP_COV_PERIOD = 180,
PROP_INPUT_REFERENCE = 181,
PROP_LIMIT_MONITORING_INTERVAL = 182,
PROP_LOGGING_OBJECT = 183,
PROP_LOGGING_RECORD = 184,
PROP_PRESCALE = 185,
PROP_PULSE_RATE = 186,
PROP_SCALE = 187,
PROP_SCALE_FACTOR = 188,
PROP_UPDATE_TIME = 189,
PROP_VALUE_BEFORE_CHANGE = 190,
PROP_VALUE_SET = 191,
PROP_VALUE_CHANGE_TIME = 192,
/* enumerations 193-206 are new */
PROP_ALIGN_INTERVALS = 193,
/* enumeration 194 is unassigned */
PROP_INTERVAL_OFFSET = 195,
PROP_LAST_RESTART_REASON = 196,
PROP_LOGGING_TYPE = 197,
/* enumeration 198-201 is unassigned */
PROP_RESTART_NOTIFICATION_RECIPIENTS = 202,
PROP_TIME_OF_DEVICE_RESTART = 203,
PROP_TIME_SYNCHRONIZATION_INTERVAL = 204,
PROP_TRIGGER = 205,
PROP_UTC_TIME_SYNCHRONIZATION_RECIPIENTS = 206,
/* enumerations 207-211 are used in Addendum d to ANSI/ASHRAE 135-2004 */
PROP_NODE_SUBTYPE = 207,
PROP_NODE_TYPE = 208,
PROP_STRUCTURED_OBJECT_LIST = 209,
PROP_SUBORDINATE_ANNOTATIONS = 210,
PROP_SUBORDINATE_LIST = 211,
/* enumerations 212-225 are used in Addendum e to ANSI/ASHRAE 135-2004 */
PROP_ACTUAL_SHED_LEVEL = 212,
PROP_DUTY_WINDOW = 213,
PROP_EXPECTED_SHED_LEVEL = 214,
PROP_FULL_DUTY_BASELINE = 215,
/* enumerations 216-217 are unassigned */
/* enumerations 212-225 are used in Addendum e to ANSI/ASHRAE 135-2004 */
PROP_REQUESTED_SHED_LEVEL = 218,
PROP_SHED_DURATION = 219,
PROP_SHED_LEVEL_DESCRIPTIONS = 220,
PROP_SHED_LEVELS = 221,
PROP_STATE_DESCRIPTION = 222,
/* enumerations 223-225 are unassigned */
/* enumerations 226-235 are used in Addendum f to ANSI/ASHRAE 135-2004 */
PROP_DOOR_ALARM_STATE = 226,
PROP_DOOR_EXTENDED_PULSE_TIME = 227,
PROP_DOOR_MEMBERS = 228,
PROP_DOOR_OPEN_TOO_LONG_TIME = 229,
PROP_DOOR_PULSE_TIME = 230,
PROP_DOOR_STATUS = 231,
PROP_DOOR_UNLOCK_DELAY_TIME = 232,
PROP_LOCK_STATUS = 233,
PROP_MASKED_ALARM_VALUES = 234,
PROP_SECURED_STATUS = 235,
/* enumerations 236-243 are unassigned */
/* enumerations 244-311 are used in Addendum j to ANSI/ASHRAE 135-2004 */
PROP_ABSENTEE_LIMIT = 244,
PROP_ACCESS_ALARM_EVENTS = 245,
PROP_ACCESS_DOORS = 246,
PROP_ACCESS_EVENT = 247,
PROP_ACCESS_EVENT_AUTHENTICATION_FACTOR = 248,
PROP_ACCESS_EVENT_CREDENTIAL = 249,
PROP_ACCESS_EVENT_TIME = 250,
PROP_ACCESS_TRANSACTION_EVENTS = 251,
PROP_ACCOMPANIMENT = 252,
PROP_ACCOMPANIMENT_TIME = 253,
PROP_ACTIVATION_TIME = 254,
PROP_ACTIVE_AUTHENTICATION_POLICY = 255,
PROP_ASSIGNED_ACCESS_RIGHTS = 256,
PROP_AUTHENTICATION_FACTORS = 257,
PROP_AUTHENTICATION_POLICY_LIST = 258,
PROP_AUTHENTICATION_POLICY_NAMES = 259,
PROP_AUTHENTICATION_STATUS = 260,
PROP_AUTHORIZATION_MODE = 261,
PROP_BELONGS_TO = 262,
PROP_CREDENTIAL_DISABLE = 263,
PROP_CREDENTIAL_STATUS = 264,
PROP_CREDENTIALS = 265,
PROP_CREDENTIALS_IN_ZONE = 266,
PROP_DAYS_REMAINING = 267,
PROP_ENTRY_POINTS = 268,
PROP_EXIT_POINTS = 269,
PROP_EXPIRY_TIME = 270,
PROP_EXTENDED_TIME_ENABLE = 271,
PROP_FAILED_ATTEMPT_EVENTS = 272,
PROP_FAILED_ATTEMPTS = 273,
PROP_FAILED_ATTEMPTS_TIME = 274,
PROP_LAST_ACCESS_EVENT = 275,
PROP_LAST_ACCESS_POINT = 276,
PROP_LAST_CREDENTIAL_ADDED = 277,
PROP_LAST_CREDENTIAL_ADDED_TIME = 278,
PROP_LAST_CREDENTIAL_REMOVED = 279,
PROP_LAST_CREDENTIAL_REMOVED_TIME = 280,
PROP_LAST_USE_TIME = 281,
PROP_LOCKOUT = 282,
PROP_LOCKOUT_RELINQUISH_TIME = 283,
PROP_MASTER_EXEMPTION = 284,
PROP_MAX_FAILED_ATTEMPTS = 285,
PROP_MEMBERS = 286,
PROP_MUSTER_POINT = 287,
PROP_NEGATIVE_ACCESS_RULES = 288,
PROP_NUMBER_OF_AUTHENTICATION_POLICIES = 289,
PROP_OCCUPANCY_COUNT = 290,
PROP_OCCUPANCY_COUNT_ADJUST = 291,
PROP_OCCUPANCY_COUNT_ENABLE = 292,
PROP_OCCUPANCY_EXEMPTION = 293,
PROP_OCCUPANCY_LOWER_LIMIT = 294,
PROP_OCCUPANCY_LOWER_LIMIT_ENFORCED = 295,
PROP_OCCUPANCY_STATE = 296,
PROP_OCCUPANCY_UPPER_LIMIT = 297,
PROP_OCCUPANCY_UPPER_LIMIT_ENFORCED = 298,
PROP_PASSBACK_EXEMPTION = 299,
PROP_PASSBACK_MODE = 300,
PROP_PASSBACK_TIMEOUT = 301,
PROP_POSITIVE_ACCESS_RULES = 302,
PROP_REASON_FOR_DISABLE = 303,
PROP_SUPPORTED_FORMATS = 304,
PROP_SUPPORTED_FORMAT_CLASSES = 305,
PROP_THREAT_AUTHORITY = 306,
PROP_THREAT_LEVEL = 307,
PROP_TRACE_FLAG = 308,
PROP_TRANSACTION_NOTIFICATION_CLASS = 309,
PROP_USER_EXTERNAL_IDENTIFIER = 310,
PROP_USER_INFORMATION_REFERENCE = 311,
/* enumerations 312-316 are unassigned */
PROP_USER_NAME = 317,
PROP_USER_TYPE = 318,
PROP_USES_REMAINING = 319,
PROP_ZONE_FROM = 320,
PROP_ZONE_TO = 321,
PROP_ACCESS_EVENT_TAG = 322,
PROP_GLOBAL_IDENTIFIER = 323,
/* enumerations 324-325 are unassigned */
PROP_VERIFICATION_TIME = 326,
PROP_BASE_DEVICE_SECURITY_POLICY = 327,
PROP_DISTRIBUTION_KEY_REVISION = 328,
PROP_DO_NOT_HIDE = 329,
PROP_KEY_SETS = 330,
PROP_LAST_KEY_SERVER = 331,
PROP_NETWORK_ACCESS_SECURITY_POLICIES = 332,
PROP_PACKET_REORDER_TIME = 333,
PROP_SECURITY_PDU_TIMEOUT = 334,
PROP_SECURITY_TIME_WINDOW = 335,
PROP_SUPPORTED_SECURITY_ALGORITHM = 336,
PROP_UPDATE_KEY_SET_TIMEOUT = 337,
PROP_BACKUP_AND_RESTORE_STATE = 338,
PROP_BACKUP_PREPARATION_TIME = 339,
PROP_RESTORE_COMPLETION_TIME = 340,
PROP_RESTORE_PREPARATION_TIME = 341,
/* enumerations 342-344 are defined in Addendum 2008-w */
PROP_BIT_MASK = 342,
PROP_BIT_TEXT = 343,
PROP_IS_UTC = 344,
PROP_GROUP_MEMBERS = 345,
PROP_GROUP_MEMBER_NAMES = 346,
PROP_MEMBER_STATUS_FLAGS = 347,
PROP_REQUESTED_UPDATE_INTERVAL = 348,
PROP_COVU_PERIOD = 349,
PROP_COVU_RECIPIENTS = 350,
PROP_EVENT_MESSAGE_TEXTS = 351,
/* enumerations 352-363 are defined in Addendum 2010-af */
PROP_EVENT_MESSAGE_TEXTS_CONFIG = 352,
PROP_EVENT_DETECTION_ENABLE = 353,
PROP_EVENT_ALGORITHM_INHIBIT = 354,
PROP_EVENT_ALGORITHM_INHIBIT_REF = 355,
PROP_TIME_DELAY_NORMAL = 356,
PROP_RELIABILITY_EVALUATION_INHIBIT = 357,
PROP_FAULT_PARAMETERS = 358,
PROP_FAULT_TYPE = 359,
PROP_LOCAL_FORWARDING_ONLY = 360,
PROP_PROCESS_IDENTIFIER_FILTER = 361,
PROP_SUBSCRIBED_RECIPIENTS = 362,
PROP_PORT_FILTER = 363,
/* enumeration 364 is defined in Addendum 2010-ae */
PROP_AUTHORIZATION_EXEMPTIONS = 364,
/* enumerations 365-370 are defined in Addendum 2010-aa */
PROP_ALLOW_GROUP_DELAY_INHIBIT = 365,
PROP_CHANNEL_NUMBER = 366,
PROP_CONTROL_GROUPS = 367,
PROP_EXECUTION_DELAY = 368,
PROP_LAST_PRIORITY = 369,
PROP_WRITE_STATUS = 370,
/* enumeration 371 is defined in Addendum 2010-ao */
PROP_PROPERTY_LIST = 371,
/* enumeration 372 is defined in Addendum 2010-ak */
PROP_SERIAL_NUMBER = 372,
/* enumerations 373-386 are defined in Addendum 2010-i */
PROP_BLINK_WARN_ENABLE = 373,
PROP_DEFAULT_FADE_TIME = 374,
PROP_DEFAULT_RAMP_RATE = 375,
PROP_DEFAULT_STEP_INCREMENT = 376,
PROP_EGRESS_TIME = 377,
PROP_IN_PROGRESS = 378,
PROP_INSTANTANEOUS_POWER = 379,
PROP_LIGHTING_COMMAND = 380,
PROP_LIGHTING_COMMAND_DEFAULT_PRIORITY = 381,
PROP_MAX_ACTUAL_VALUE = 382,
PROP_MIN_ACTUAL_VALUE = 383,
PROP_POWER = 384,
PROP_TRANSITION = 385,
PROP_EGRESS_ACTIVE = 386,
PROP_INTERFACE_VALUE = 387,
PROP_FAULT_HIGH_LIMIT = 388,
PROP_FAULT_LOW_LIMIT = 389,
PROP_LOW_DIFF_LIMIT = 390,
/* enumerations 391-392 are defined in Addendum 135-2012az */
PROP_STRIKE_COUNT = 391,
PROP_TIME_OF_STRIKE_COUNT_RESET = 392,
/* enumerations 393-398 are defined in Addendum 135-2012ay */
PROP_DEFAULT_TIMEOUT = 393,
PROP_INITIAL_TIMEOUT = 394,
PROP_LAST_STATE_CHANGE = 395,
PROP_STATE_CHANGE_VALUES = 396,
PROP_TIMER_RUNNING = 397,
PROP_TIMER_STATE = 398,
/* enumerations 399-427 are defined in Addendum 2012-ai */
PROP_APDU_LENGTH = 399,
PROP_IP_ADDRESS = 400,
PROP_IP_DEFAULT_GATEWAY = 401,
PROP_IP_DHCP_ENABLE = 402,
PROP_IP_DHCP_LEASE_TIME = 403,
PROP_IP_DHCP_LEASE_TIME_REMAINING = 404,
PROP_IP_DHCP_SERVER = 405,
PROP_IP_DNS_SERVER = 406,
PROP_BACNET_IP_GLOBAL_ADDRESS = 407,
PROP_BACNET_IP_MODE = 408,
PROP_BACNET_IP_MULTICAST_ADDRESS = 409,
PROP_BACNET_IP_NAT_TRAVERSAL = 410,
PROP_IP_SUBNET_MASK = 411,
PROP_BACNET_IP_UDP_PORT = 412,
PROP_BBMD_ACCEPT_FD_REGISTRATIONS = 413,
PROP_BBMD_BROADCAST_DISTRIBUTION_TABLE = 414,
PROP_BBMD_FOREIGN_DEVICE_TABLE = 415,
PROP_CHANGES_PENDING = 416,
PROP_COMMAND = 417,
PROP_FD_BBMD_ADDRESS = 418,
PROP_FD_SUBSCRIPTION_LIFETIME = 419,
PROP_LINK_SPEED = 420,
PROP_LINK_SPEEDS = 421,
PROP_LINK_SPEED_AUTONEGOTIATE = 422,
PROP_MAC_ADDRESS = 423,
PROP_NETWORK_INTERFACE_NAME = 424,
PROP_NETWORK_NUMBER = 425,
PROP_NETWORK_NUMBER_QUALITY = 426,
PROP_NETWORK_TYPE = 427,
PROP_ROUTING_TABLE = 428,
PROP_VIRTUAL_MAC_ADDRESS_TABLE = 429,
// Addendum-135-2012as
PROP_COMMAND_TIME_ARRAY = 430,
PROP_CURRENT_COMMAND_PRIORITY = 431,
PROP_LAST_COMMAND_TIME = 432,
PROP_VALUE_SOURCE = 433,
PROP_VALUE_SOURCE_ARRAY = 434,
PROP_BACNET_IPV6_MODE = 435,
PROP_IPV6_ADDRESS = 436,
PROP_IPV6_PREFIX_LENGTH = 437,
PROP_BACNET_IPV6_UDP_PORT = 438,
PROP_IPV6_DEFAULT_GATEWAY = 439,
PROP_BACNET_IPV6_MULTICAST_ADDRESS = 440,
PROP_IPV6_DNS_SERVER = 441,
PROP_IPV6_AUTO_ADDRESSING_ENABLE = 442,
PROP_IPV6_DHCP_LEASE_TIME = 443,
PROP_IPV6_DHCP_LEASE_TIME_REMAINING = 444,
PROP_IPV6_DHCP_SERVER = 445,
PROP_IPV6_ZONE_INDEX = 446,
PROP_ASSIGNED_LANDING_CALLS = 447,
PROP_CAR_ASSIGNED_DIRECTION = 448,
PROP_CAR_DOOR_COMMAND = 449,
PROP_CAR_DOOR_STATUS = 450,
PROP_CAR_DOOR_TEXT = 451,
PROP_CAR_DOOR_ZONE = 452,
PROP_CAR_DRIVE_STATUS = 453,
PROP_CAR_LOAD = 454,
PROP_CAR_LOAD_UNITS = 455,
PROP_CAR_MODE = 456,
PROP_CAR_MOVING_DIRECTION = 457,
PROP_CAR_POSITION = 458,
PROP_ELEVATOR_GROUP = 459,
PROP_ENERGY_METER = 460,
PROP_ENERGY_METER_REF = 461,
PROP_ESCALATOR_MODE = 462,
PROP_FAULT_SIGNALS = 463,
PROP_FLOOR_TEXT = 464,
PROP_GROUP_ID = 465,
/* value 466 is unassigned */
PROP_GROUP_MODE = 467,
PROP_HIGHER_DECK = 468,
PROP_INSTALLATION_ID = 469,
PROP_LANDING_CALLS = 470,
PROP_LANDING_CALL_CONTROL = 471,
PROP_LANDING_DOOR_STATUS = 472,
PROP_LOWER_DECK = 473,
PROP_MACHINE_ROOM_ID = 474,
PROP_MAKING_CAR_CALL = 475,
PROP_NEXT_STOPPING_FLOOR = 476,
PROP_OPERATION_DIRECTION = 477,
PROP_PASSENGER_ALARM = 478,
PROP_POWER_MODE = 479,
PROP_REGISTERED_CAR_CALL = 480,
PROP_ACTIVE_COV_MULTIPLE_SUBSCRIPTIONS = 481,
PROP_PROTOCOL_LEVEL = 482,
PROP_REFERENCE_PORT = 483,
PROP_DEPLOYED_PROFILE_LOCATION = 484,
PROP_PROFILE_LOCATION = 485,
PROP_TAGS = 486,
PROP_SUBORDINATE_NODE_TYPES = 487,
PROP_SUBORDINATE_TAGS = 488,
PROP_SUBORDINATE_RELATIONSHIPS = 489,
PROP_DEFAULT_SUBORDINATE_RELATIONSHIP = 490,
PROP_REPRESENTS = 491,
PROP_DEFAULT_PRESENT_VALUE = 492,
PROP_PRESENT_STAGE = 493,
PROP_STAGES = 494,
PROP_STAGE_NAMES = 495,
PROP_TARGET_REFERENCES = 496,
PROP_AUDIT_SOURCE_LEVEL = 497,
PROP_AUDIT_LEVEL = 498,
PROP_AUDIT_NOTIFICATION_RECIPIENT = 499,
PROP_AUDIT_PRIORITY_FILTER = 500,
PROP_AUDITABLE_OPERATIONS = 501,
PROP_DELETE_ON_FORWARD = 502,
PROP_MAXIMUM_SEND_DELAY = 503,
PROP_MONITORED_OBJECTS = 504,
PROP_SEND_NOW = 505,
PROP_FLOOR_NUMBER = 506,
PROP_DEVICE_UUID = 507,
/* enumerations 508-511 are defined in Addendum 2020cc */
PROP_ADDITIONAL_REFERENCE_PORTS = 508,
PROP_CERTIFICATE_SIGNING_REQUEST_FILE = 509,
PROP_COMMAND_VALIDATION_RESULT = 510,
PROP_ISSUER_CERTIFICATE_FILES = 511,
/* The special property identifiers all, optional, and required */
/* are reserved for use in the ReadPropertyConditional and */
/* ReadPropertyMultiple services or services not defined in this standard.
*/
/* Enumerated values 0-511 are reserved for definition by ASHRAE. */
/* Enumerated values 512-4194303 may be used by others subject to the */
/* procedures and constraints described in Clause 23. */
PROP_PROPRIETARY_RANGE_MIN = 512,
PROP_PROPRIETARY_RANGE_MAX = 4194303,
/* enumerations 4194304-4194327 are defined in Addendum 2020cc */
PROP_MAX_BVLC_LENGTH_ACCEPTED = 4194304,
PROP_MAX_NPDU_LENGTH_ACCEPTED = 4194305,
PROP_OPERATIONAL_CERTIFICATE_FILE = 4194305,
PROP_CURRENT_HEALTH = 4194307,
PROP_SC_CONNECT_WAIT_TIMEOUT = 4194308,
PROP_SC_DIRECT_CONNECT_ACCEPT_ENABLE = 4194309,
PROP_SC_DIRECT_CONNECT_ACCEPT_URIS = 4194310,
PROP_SC_DIRECT_CONNECT_BINDING = 4194311,
PROP_SC_DIRECT_CONNECT_CONNECTION_STATUS = 4194312,
PROP_SC_DIRECT_CONNECT_INITIATE_ENABLE = 4194313,
PROP_SC_DISCONNECT_WAIT_TIMEOUT = 4194314,
PROP_SC_FAILED_CONNECTION_REQUESTS = 4194315,
PROP_SC_FAILOVER_HUB_CONNECTION_STATUS = 4194316,
PROP_SC_FAILOVER_HUB_URI = 4194317,
PROP_SC_HUB_CONNECTOR_STATE = 4194318,
PROP_SC_HUB_FUNCTION_ACCEPT_URIS = 4194319,
PROP_SC_HUB_FUNCTION_BINDING = 4194320,
PROP_SC_HUB_FUNCTION_CONNECTION_STATUS = 4194321,
PROP_SC_HUB_FUNCTION_ENABLE = 4194322,
PROP_SC_HEARTBEAT_TIMEOUT = 4194323,
PROP_SC_PRIMARY_HUB_CONNECTION_STATUS = 4194324,
PROP_SC_PRIMARY_HUB_URI = 4194325,
PROP_SC_MAXIMUM_RECONNECT_TIME = 4194326,
PROP_SC_MINIMUM_RECONNECT_TIME = 4194327,
/* enumerations 4194328-4194332 are defined in Addendum 2020ca */
PROP_COLOR_OVERRIDE = 4194328,
PROP_COLOR_REFERENCE = 4194329,
PROP_DEFAULT_COLOR = 4194330,
PROP_DEFAULT_COLOR_TEMPERATURE = 4194331,
PROP_OVERRIDE_COLOR_REFERENCE = 4194332,
PROP_COLOR_COMMAND = 4194334,
PROP_HIGH_END_TRIM = 4194335,
PROP_LOW_END_TRIM = 4194336,
PROP_TRIM_FADE_TIME = 4194337,
/* The special property identifiers all, optional, and required */
/* are reserved for use in the ReadPropertyConditional and */
/* ReadPropertyMultiple services or services not defined in this standard. */
/* Enumerated values 0-511 are reserved for definition by ASHRAE. */
/* Enumerated values 512-4194303 may be used by others subject to the */
/* procedures and constraints described in Clause 23. */
/* Enumerated values 4194303-16777215 are reserved
for definition by ASHRAE. */
/* do the max range inside of enum so that
compilers will allocate adequate sized datatype for enum
which is used to store decoding */
MAX_BACNET_PROPERTY_ID = 16777215
}

23
addons/EGFramework/Third_Part_SourceCode/BacNetPlugin/Base/BacnetPropertyReference.cs

@ -1,23 +0,0 @@ @@ -1,23 +0,0 @@
namespace System.IO.BACnet;
public struct BacnetPropertyReference
{
public uint propertyIdentifier;
public uint propertyArrayIndex; /* optional */
public BacnetPropertyReference(uint id, uint arrayIndex)
{
propertyIdentifier = id;
propertyArrayIndex = arrayIndex;
}
public BacnetPropertyIds GetPropertyId()
{
return (BacnetPropertyIds)propertyIdentifier;
}
public override string ToString()
{
return $"{GetPropertyId()}";
}
}

48
addons/EGFramework/Third_Part_SourceCode/BacNetPlugin/Base/BacnetPropertyState.cs

@ -1,48 +0,0 @@ @@ -1,48 +0,0 @@
namespace System.IO.BACnet;
public struct BacnetPropertyState
{
public enum BacnetPropertyStateTypes
{
BOOLEAN_VALUE,
BINARY_VALUE,
EVENT_TYPE,
POLARITY,
PROGRAM_CHANGE,
PROGRAM_STATE,
REASON_FOR_HALT,
RELIABILITY,
STATE,
SYSTEM_STATUS,
UNITS,
UNSIGNED_VALUE,
LIFE_SAFETY_MODE,
LIFE_SAFETY_STATE
}
public struct State
{
public bool boolean_value;
public BacnetBinaryPv binaryValue;
public BacnetEventTypes eventType;
public BacnetPolarity polarity;
public BacnetProgramRequest programChange;
public BacnetProgramState programState;
public BacnetProgramError programError;
public BacnetReliability reliability;
public BacnetEventStates state;
public BacnetDeviceStatus systemStatus;
public BacnetUnitsId units;
public uint unsignedValue;
public BacnetLifeSafetyModes lifeSafetyMode;
public BacnetLifeSafetyStates lifeSafetyState;
}
public BacnetPropertyStateTypes tag;
public State state;
public override string ToString()
{
return $"{tag}:{state}";
}
}

13
addons/EGFramework/Third_Part_SourceCode/BacNetPlugin/Base/BacnetPropertyValue.cs

@ -1,13 +0,0 @@ @@ -1,13 +0,0 @@
namespace System.IO.BACnet;
public struct BacnetPropertyValue
{
public BacnetPropertyReference property;
public IList<BacnetValue> value;
public byte priority;
public override string ToString()
{
return property.ToString();
}
}

9
addons/EGFramework/Third_Part_SourceCode/BacNetPlugin/Base/BacnetPtpDisconnectReasons.cs

@ -1,9 +0,0 @@ @@ -1,9 +0,0 @@
namespace System.IO.BACnet;
public enum BacnetPtpDisconnectReasons : byte
{
PTP_DISCONNECT_NO_MORE_DATA = 0,
PTP_DISCONNECT_PREEMPTED = 1,
PTP_DISCONNECT_INVALID_PASSWORD = 2,
PTP_DISCONNECT_OTHER = 3,
}

24
addons/EGFramework/Third_Part_SourceCode/BacNetPlugin/Base/BacnetPtpFrameTypes.cs

@ -1,24 +0,0 @@ @@ -1,24 +0,0 @@
namespace System.IO.BACnet;
public enum BacnetPtpFrameTypes : byte
{
FRAME_TYPE_HEARTBEAT_XOFF = 0,
FRAME_TYPE_HEARTBEAT_XON = 1,
FRAME_TYPE_DATA0 = 2,
FRAME_TYPE_DATA1 = 3,
FRAME_TYPE_DATA_ACK0_XOFF = 4,
FRAME_TYPE_DATA_ACK1_XOFF = 5,
FRAME_TYPE_DATA_ACK0_XON = 6,
FRAME_TYPE_DATA_ACK1_XON = 7,
FRAME_TYPE_DATA_NAK0_XOFF = 8,
FRAME_TYPE_DATA_NAK1_XOFF = 9,
FRAME_TYPE_DATA_NAK0_XON = 0x0A,
FRAME_TYPE_DATA_NAK1_XON = 0x0B,
FRAME_TYPE_CONNECT_REQUEST = 0x0C,
FRAME_TYPE_CONNECT_RESPONSE = 0x0D,
FRAME_TYPE_DISCONNECT_REQUEST = 0x0E,
FRAME_TYPE_DISCONNECT_RESPONSE = 0x0F,
FRAME_TYPE_TEST_REQUEST = 0x14,
FRAME_TYPE_TEST_RESPONSE = 0x15,
FRAME_TYPE_GREETING = 0xFF //special invention
}

13
addons/EGFramework/Third_Part_SourceCode/BacNetPlugin/Base/BacnetReadAccessResult.cs

@ -1,13 +0,0 @@ @@ -1,13 +0,0 @@
namespace System.IO.BACnet;
public struct BacnetReadAccessResult
{
public BacnetObjectId objectIdentifier;
public IList<BacnetPropertyValue> values;
public BacnetReadAccessResult(BacnetObjectId objectIdentifier, IList<BacnetPropertyValue> values)
{
this.objectIdentifier = objectIdentifier;
this.values = values;
}
}

40
addons/EGFramework/Third_Part_SourceCode/BacNetPlugin/Base/BacnetReadAccessSpecification.cs

@ -1,40 +0,0 @@ @@ -1,40 +0,0 @@
namespace System.IO.BACnet;
public struct BacnetReadAccessSpecification
{
public BacnetObjectId objectIdentifier;
public IList<BacnetPropertyReference> propertyReferences;
public BacnetReadAccessSpecification(BacnetObjectId objectIdentifier, IList<BacnetPropertyReference> propertyReferences)
{
this.objectIdentifier = objectIdentifier;
this.propertyReferences = propertyReferences;
}
public static object Parse(string value)
{
var ret = new BacnetReadAccessSpecification();
if (string.IsNullOrEmpty(value)) return ret;
var tmp = value.Split(':');
if (tmp.Length < 2) return ret;
ret.objectIdentifier.type = (BacnetObjectTypes)Enum.Parse(typeof(BacnetObjectTypes), tmp[0]);
ret.objectIdentifier.instance = uint.Parse(tmp[1]);
var refs = new List<BacnetPropertyReference>();
for (var i = 2; i < tmp.Length; i++)
{
refs.Add(new BacnetPropertyReference
{
propertyArrayIndex = ASN1.BACNET_ARRAY_ALL,
propertyIdentifier = (uint)(BacnetPropertyIds)Enum.Parse(typeof(BacnetPropertyIds), tmp[i])
});
}
ret.propertyReferences = refs;
return ret;
}
public override string ToString()
{
return propertyReferences.Aggregate(objectIdentifier.ToString(), (current, r) =>
$"{current}:{(BacnetPropertyIds)r.propertyIdentifier}");
}
}

9
addons/EGFramework/Third_Part_SourceCode/BacNetPlugin/Base/BacnetReadRangeRequestTypes.cs

@ -1,9 +0,0 @@ @@ -1,9 +0,0 @@
namespace System.IO.BACnet.Serialize;
public enum BacnetReadRangeRequestTypes
{
RR_BY_POSITION = 1,
RR_BY_SEQUENCE = 2,
RR_BY_TIME = 4,
RR_READ_ALL = 8
}

14
addons/EGFramework/Third_Part_SourceCode/BacNetPlugin/Base/BacnetReinitializedStates.cs

@ -1,14 +0,0 @@ @@ -1,14 +0,0 @@
namespace System.IO.BACnet;
public enum BacnetReinitializedStates
{
BACNET_REINIT_COLDSTART = 0,
BACNET_REINIT_WARMSTART = 1,
BACNET_REINIT_STARTBACKUP = 2,
BACNET_REINIT_ENDBACKUP = 3,
BACNET_REINIT_STARTRESTORE = 4,
BACNET_REINIT_ENDRESTORE = 5,
BACNET_REINIT_ABORTRESTORE = 6,
BACNET_REINIT_ACTIVATE_CHANGES = 7,
BACNET_REINIT_IDLE = 255
}

84
addons/EGFramework/Third_Part_SourceCode/BacNetPlugin/Base/BacnetRejectReason.cs

@ -1,84 +0,0 @@ @@ -1,84 +0,0 @@
namespace System.IO.BACnet;
/// <summary>
/// Possible reason for rejecting the PDU.
/// </summary>
/// <remarks>
/// Enumerated values 0-63 are reserved for definition by ASHRAE.
/// Enumerated values 64-255 may be used by others.
/// </remarks>
public enum BacnetRejectReason : byte
{
/// <summary>
/// Generated in response to a confirmed request APDU that contains a syntax error
/// for which an error code has not been explicitly defined.
/// </summary>
OTHER = 0,
/// <summary>
/// A buffer capacity has been exceeded.
/// </summary>
BUFFER_OVERFLOW = 1,
/// <summary>
/// Generated in response to a confirmed request APDU that omits a conditional
/// service argument that should be present or contains a conditional service
/// argument that should not be present. This condition could also elicit
/// a Reject PDU with a Reject Reason of <see cref="INVALID_TAG"/>.
/// </summary>
INCONSISTENT_PARAMETERS = 2,
/// <summary>
/// Generated in response to a confirmed request APDU in which the encoding
/// of one or more of the service parameters does not follow the correct
/// type specification. This condition could also elicit a Reject PDU
/// with a Reject Reason of <see cref="INVALID_TAG"/>.
/// </summary>
INVALID_PARAMETER_DATA_TYPE = 3,
/// <summary>
/// While parsing a message, an invalid tag was encountered. Since an invalid tag
/// could confuse the parsing logic, any of the following Reject Reasons may also
/// be generated in response to a confirmed request containing an invalid tag:
/// <list type="bullet">
/// <item><description><see cref="INCONSISTENT_PARAMETERS"/></description></item>
/// <item><description><see cref="INVALID_PARAMETER_DATA_TYPE"/></description></item>
/// <item><description><see cref="MISSING_REQUIRED_PARAMETER"/></description></item>
/// <item><description><see cref="TOO_MANY_ARGUMENTS"/></description></item>
/// </list>
/// </summary>
INVALID_TAG = 4,
/// <summary>
/// Generated in response to a confirmed request APDU that is missing at least one
/// mandatory service argument. This condition could also elicit a Reject PDU with
/// a Reject Reason of <see cref="INVALID_TAG"/>.
/// </summary>
MISSING_REQUIRED_PARAMETER = 5,
/// <summary>
/// Generated in response to a confirmed request APDU that conveys a parameter
/// whose value is outside the range defined for this service.
/// </summary>
PARAMETER_OUT_OF_RANGE = 6,
/// <summary>
/// Generated in response to a confirmed request APDU in which the total number
/// of service arguments is greater than specified for the service. This condition
/// could also elicit a Reject PDU with a Reject Reason of <see cref="INVALID_TAG"/>.
/// </summary>
TOO_MANY_ARGUMENTS = 7,
/// <summary>
/// Generated in response to a confirmed request APDU in which one or more of
/// the service parameters is decoded as an enumeration that is not defined by
/// the type specification of this parameter.
/// </summary>
UNDEFINED_ENUMERATION = 8,
/// <summary>
/// Generated in response to a confirmed request APDU in which the Service Choice
/// field specifies an unknown or unsupported service
/// </summary>
RECOGNIZED_SERVICE = 9
}

27
addons/EGFramework/Third_Part_SourceCode/BacNetPlugin/Base/BacnetReliability.cs

@ -1,27 +0,0 @@ @@ -1,27 +0,0 @@
namespace System.IO.BACnet;
public enum BacnetReliability : uint
{
RELIABILITY_NO_FAULT_DETECTED = 0,
RELIABILITY_NO_SENSOR = 1,
RELIABILITY_OVER_RANGE = 2,
RELIABILITY_UNDER_RANGE = 3,
RELIABILITY_OPEN_LOOP = 4,
RELIABILITY_SHORTED_LOOP = 5,
RELIABILITY_NO_OUTPUT = 6,
RELIABILITY_UNRELIABLE_OTHER = 7,
RELIABILITY_PROCESS_ERROR = 8,
RELIABILITY_MULTI_STATE_FAULT = 9,
RELIABILITY_CONFIGURATION_ERROR = 10,
RELIABILITY_MEMBER_FAULT = 11,
RELIABILITY_COMMUNICATION_FAILURE = 12,
RELIABILITY_TRIPPED = 13,
/* Enumerated values 0-63 are reserved for definition by ASHRAE. */
/* Enumerated values 64-65535 may be used by others subject to */
/* the procedures and constraints described in Clause 23. */
/* do the max range inside of enum so that
compilers will allocate adequate sized datatype for enum
which is used to store decoding */
RELIABILITY_PROPRIETARY_MIN = 64,
RELIABILITY_PROPRIETARY_MAX = 65535
}

14
addons/EGFramework/Third_Part_SourceCode/BacNetPlugin/Base/BacnetRestartReason.cs

@ -1,14 +0,0 @@ @@ -1,14 +0,0 @@
namespace System.IO.BACnet;
// From Loren Van Spronsen csharp-bacnet
public enum BacnetRestartReason
{
UNKNOWN = 0,
COLD_START = 1,
WARM_START = 2,
DETECTED_POWER_LOST = 3,
DETECTED_POWER_OFF = 4,
HARDWARE_WATCHDOG = 5,
SOFTWARE_WATCHDOG = 6,
SUSPENDED = 7
}

10
addons/EGFramework/Third_Part_SourceCode/BacNetPlugin/Base/BacnetResultFlags.cs

@ -1,10 +0,0 @@ @@ -1,10 +0,0 @@
namespace System.IO.BACnet;
[Flags]
public enum BacnetResultFlags
{
NONE = 0,
FIRST_ITEM = 1,
LAST_ITEM = 2,
MORE_ITEMS = 4,
}

9
addons/EGFramework/Third_Part_SourceCode/BacNetPlugin/Base/BacnetSegmentations.cs

@ -1,9 +0,0 @@ @@ -1,9 +0,0 @@
namespace System.IO.BACnet;
public enum BacnetSegmentations
{
SEGMENTATION_BOTH = 0,
SEGMENTATION_TRANSMIT = 1,
SEGMENTATION_RECEIVE = 2,
SEGMENTATION_NONE = 3,
}

62
addons/EGFramework/Third_Part_SourceCode/BacNetPlugin/Base/BacnetServicesSupported.cs

@ -1,62 +0,0 @@ @@ -1,62 +0,0 @@
namespace System.IO.BACnet;
public enum BacnetServicesSupported
{
/* Alarm and Event Services */
SERVICE_SUPPORTED_ACKNOWLEDGE_ALARM = 0,
SERVICE_SUPPORTED_CONFIRMED_COV_NOTIFICATION = 1,
SERVICE_SUPPORTED_CONFIRMED_EVENT_NOTIFICATION = 2,
SERVICE_SUPPORTED_GET_ALARM_SUMMARY = 3,
SERVICE_SUPPORTED_GET_ENROLLMENT_SUMMARY = 4,
SERVICE_SUPPORTED_GET_EVENT_INFORMATION = 39,
SERVICE_SUPPORTED_SUBSCRIBE_COV = 5,
SERVICE_SUPPORTED_SUBSCRIBE_COV_PROPERTY = 38,
SERVICE_SUPPORTED_LIFE_SAFETY_OPERATION = 37,
SERVICE_SUPPORTED_CONFIRMED_AUDIT_NOTIFICATION = 44,
SERVICE_SUPPORTED_AUDIT_LOG_QUERY = 45,
/* File Access Services */
SERVICE_SUPPORTED_ATOMIC_READ_FILE = 6,
SERVICE_SUPPORTED_ATOMIC_WRITE_FILE = 7,
/* Object Access Services */
SERVICE_SUPPORTED_ADD_LIST_ELEMENT = 8,
SERVICE_SUPPORTED_REMOVE_LIST_ELEMENT = 9,
SERVICE_SUPPORTED_CREATE_OBJECT = 10,
SERVICE_SUPPORTED_DELETE_OBJECT = 11,
SERVICE_SUPPORTED_READ_PROPERTY = 12,
SERVICE_SUPPORTED_READ_PROP_CONDITIONAL = 13,
SERVICE_SUPPORTED_READ_PROP_MULTIPLE = 14,
SERVICE_SUPPORTED_READ_RANGE = 35,
SERVICE_SUPPORTED_WRITE_PROPERTY = 15,
SERVICE_SUPPORTED_WRITE_PROP_MULTIPLE = 16,
SERVICE_SUPPORTED_WRITE_GROUP = 40,
/* Remote Device Management Services */
SERVICE_SUPPORTED_DEVICE_COMMUNICATION_CONTROL = 17,
SERVICE_SUPPORTED_PRIVATE_TRANSFER = 18,
SERVICE_SUPPORTED_TEXT_MESSAGE = 19,
SERVICE_SUPPORTED_REINITIALIZE_DEVICE = 20,
SERVICE_SUPPORTED_WHO_AM_I = 47,
SERVICE_SUPPORTED_YOU_ARE = 48,
/* Virtual Terminal Services */
SERVICE_SUPPORTED_VT_OPEN = 21,
SERVICE_SUPPORTED_VT_CLOSE = 22,
SERVICE_SUPPORTED_VT_DATA = 23,
/* Security Services */
SERVICE_SUPPORTED_AUTHENTICATE = 24,
SERVICE_SUPPORTED_REQUEST_KEY = 25,
/* Unconfirmed Services */
SERVICE_SUPPORTED_I_AM = 26,
SERVICE_SUPPORTED_I_HAVE = 27,
SERVICE_SUPPORTED_UNCONFIRMED_COV_NOTIFICATION = 28,
SERVICE_SUPPORTED_UNCONFIRMED_EVENT_NOTIFICATION = 29,
SERVICE_SUPPORTED_UNCONFIRMED_PRIVATE_TRANSFER = 30,
SERVICE_SUPPORTED_UNCONFIRMED_TEXT_MESSAGE = 31,
SERVICE_SUPPORTED_TIME_SYNCHRONIZATION = 32,
SERVICE_SUPPORTED_UTC_TIME_SYNCHRONIZATION = 36,
SERVICE_SUPPORTED_WHO_HAS = 33,
SERVICE_SUPPORTED_WHO_IS = 34,
SERVICE_SUPPORTED_UNCONFIRMED_AUDIT_NOTIFICATION = 46,
/* Other services to be added as they are defined. */
/* All values in this production are reserved */
/* for definition by ASHRAE. */
MAX_BACNET_SERVICES_SUPPORTED = 47
}

10
addons/EGFramework/Third_Part_SourceCode/BacNetPlugin/Base/BacnetStatusFlags.cs

@ -1,10 +0,0 @@ @@ -1,10 +0,0 @@
namespace System.IO.BACnet;
[Flags]
public enum BacnetStatusFlags
{
STATUS_FLAG_IN_ALARM = 1,
STATUS_FLAG_FAULT = 2,
STATUS_FLAG_OVERRIDDEN = 4,
STATUS_FLAG_OUT_OF_SERVICE = 8
}

9
addons/EGFramework/Third_Part_SourceCode/BacNetPlugin/Base/BacnetTimestampTags.cs

@ -1,9 +0,0 @@ @@ -1,9 +0,0 @@
namespace System.IO.BACnet;
public enum BacnetTimestampTags
{
TIME_STAMP_NONE = -1,
TIME_STAMP_TIME = 0,
TIME_STAMP_SEQUENCE = 1,
TIME_STAMP_DATETIME = 2
}

18
addons/EGFramework/Third_Part_SourceCode/BacNetPlugin/Base/BacnetTrendLogValueType.cs

@ -1,18 +0,0 @@ @@ -1,18 +0,0 @@
namespace System.IO.BACnet;
public enum BacnetTrendLogValueType : byte
{
// Copyright (C) 2009 Peter Mc Shane in Steve Karg Stack, trendlog.h
// Thank's to it's encoding sample, very usefull for this decoding work
TL_TYPE_STATUS = 0,
TL_TYPE_BOOL = 1,
TL_TYPE_REAL = 2,
TL_TYPE_ENUM = 3,
TL_TYPE_UNSIGN = 4,
TL_TYPE_SIGN = 5,
TL_TYPE_BITS = 6,
TL_TYPE_NULL = 7,
TL_TYPE_ERROR = 8,
TL_TYPE_DELTA = 9,
TL_TYPE_ANY = 10
}

30
addons/EGFramework/Third_Part_SourceCode/BacNetPlugin/Base/BacnetUnconfirmedServices.cs

@ -1,30 +0,0 @@ @@ -1,30 +0,0 @@
namespace System.IO.BACnet;
public enum BacnetUnconfirmedServices : byte
{
SERVICE_UNCONFIRMED_I_AM = 0,
SERVICE_UNCONFIRMED_I_HAVE = 1,
SERVICE_UNCONFIRMED_COV_NOTIFICATION = 2,
SERVICE_UNCONFIRMED_EVENT_NOTIFICATION = 3,
SERVICE_UNCONFIRMED_PRIVATE_TRANSFER = 4,
SERVICE_UNCONFIRMED_TEXT_MESSAGE = 5,
SERVICE_UNCONFIRMED_TIME_SYNCHRONIZATION = 6,
SERVICE_UNCONFIRMED_WHO_HAS = 7,
SERVICE_UNCONFIRMED_WHO_IS = 8,
SERVICE_UNCONFIRMED_UTC_TIME_SYNCHRONIZATION = 9,
/* addendum 2010-aa */
SERVICE_UNCONFIRMED_WRITE_GROUP = 10,
/* addendum 2012-aq */
SERVICE_UNCONFIRMED_COV_NOTIFICATION_MULTIPLE = 11,
/* addendum 2016-bi */
SERVICE_UNCONFIRMED_AUDIT_NOTIFICATION = 12,
/* addendum 2016-bz */
SERVICE_UNCONFIRMED_WHO_AM_I = 13,
SERVICE_UNCONFIRMED_YOU_ARE = 14,
/* Other services to be added as they are defined. */
/* All choice values in this production are reserved */
/* for definition by ASHRAE. */
/* Proprietary extensions are made by using the */
/* UnconfirmedPrivateTransfer service. See Clause 23. */
MAX_BACNET_UNCONFIRMED_SERVICE = 15
};

311
addons/EGFramework/Third_Part_SourceCode/BacNetPlugin/Base/BacnetUnitsId.cs

@ -1,311 +0,0 @@ @@ -1,311 +0,0 @@
namespace System.IO.BACnet;
// Add FC : from Karg's Stack
public enum BacnetUnitsId
{
UNITS_METERS_PER_SECOND_PER_SECOND = 166,
/* Area */
UNITS_SQUARE_METERS = 0,
UNITS_SQUARE_CENTIMETERS = 116,
UNITS_SQUARE_FEET = 1,
UNITS_SQUARE_INCHES = 115,
/* Currency */
UNITS_CURRENCY1 = 105,
UNITS_CURRENCY2 = 106,
UNITS_CURRENCY3 = 107,
UNITS_CURRENCY4 = 108,
UNITS_CURRENCY5 = 109,
UNITS_CURRENCY6 = 110,
UNITS_CURRENCY7 = 111,
UNITS_CURRENCY8 = 112,
UNITS_CURRENCY9 = 113,
UNITS_CURRENCY10 = 114,
/* Electrical */
UNITS_MILLIAMPERES = 2,
UNITS_AMPERES = 3,
UNITS_AMPERES_PER_METER = 167,
UNITS_AMPERES_PER_SQUARE_METER = 168,
UNITS_AMPERE_SQUARE_METERS = 169,
UNITS_DECIBELS = 199,
UNITS_DECIBELS_MILLIVOLT = 200,
UNITS_DECIBELS_VOLT = 201,
UNITS_FARADS = 170,
UNITS_HENRYS = 171,
UNITS_OHMS = 4,
UNITS_OHM_METERS = 172,
UNITS_MILLIOHMS = 145,
UNITS_KILOHMS = 122,
UNITS_MEGOHMS = 123,
UNITS_MICROSIEMENS = 190,
UNITS_MILLISIEMENS = 202,
UNITS_SIEMENS = 173, /* 1 mho equals 1 siemens */
UNITS_SIEMENS_PER_METER = 174,
UNITS_TESLAS = 175,
UNITS_VOLTS = 5,
UNITS_MILLIVOLTS = 124,
UNITS_KILOVOLTS = 6,
UNITS_MEGAVOLTS = 7,
UNITS_VOLT_AMPERES = 8,
UNITS_KILOVOLT_AMPERES = 9,
UNITS_MEGAVOLT_AMPERES = 10,
UNITS_VOLT_AMPERES_REACTIVE = 11,
UNITS_KILOVOLT_AMPERES_REACTIVE = 12,
UNITS_MEGAVOLT_AMPERES_REACTIVE = 13,
UNITS_VOLTS_PER_DEGREE_KELVIN = 176,
UNITS_VOLTS_PER_METER = 177,
UNITS_DEGREES_PHASE = 14,
UNITS_POWER_FACTOR = 15,
UNITS_WEBERS = 178,
/* Energy */
UNITS_JOULES = 16,
UNITS_KILOJOULES = 17,
UNITS_KILOJOULES_PER_KILOGRAM = 125,
UNITS_MEGAJOULES = 126,
UNITS_WATT_HOURS = 18,
UNITS_KILOWATT_HOURS = 19,
UNITS_MEGAWATT_HOURS = 146,
UNITS_WATT_HOURS_REACTIVE = 203,
UNITS_KILOWATT_HOURS_REACTIVE = 204,
UNITS_MEGAWATT_HOURS_REACTIVE = 205,
UNITS_BTUS = 20,
UNITS_KILO_BTUS = 147,
UNITS_MEGA_BTUS = 148,
UNITS_THERMS = 21,
UNITS_TON_HOURS = 22,
/* Enthalpy */
UNITS_JOULES_PER_KILOGRAM_DRY_AIR = 23,
UNITS_KILOJOULES_PER_KILOGRAM_DRY_AIR = 149,
UNITS_MEGAJOULES_PER_KILOGRAM_DRY_AIR = 150,
UNITS_BTUS_PER_POUND_DRY_AIR = 24,
UNITS_BTUS_PER_POUND = 117,
/* Entropy */
UNITS_JOULES_PER_DEGREE_KELVIN = 127,
UNITS_KILOJOULES_PER_DEGREE_KELVIN = 151,
UNITS_MEGAJOULES_PER_DEGREE_KELVIN = 152,
UNITS_JOULES_PER_KILOGRAM_DEGREE_KELVIN = 128,
/* Force */
UNITS_NEWTON = 153,
/* Frequency */
UNITS_CYCLES_PER_HOUR = 25,
UNITS_CYCLES_PER_MINUTE = 26,
UNITS_HERTZ = 27,
UNITS_KILOHERTZ = 129,
UNITS_MEGAHERTZ = 130,
UNITS_PER_HOUR = 131,
/* Humidity */
UNITS_GRAMS_OF_WATER_PER_KILOGRAM_DRY_AIR = 28,
UNITS_PERCENT_RELATIVE_HUMIDITY = 29,
/* Length */
UNITS_MICROMETERS = 194,
UNITS_MILLIMETERS = 30,
UNITS_CENTIMETERS = 118,
UNITS_KILOMETERS = 193,
UNITS_METERS = 31,
UNITS_INCHES = 32,
UNITS_FEET = 33,
/* Light */
UNITS_CANDELAS = 179,
UNITS_CANDELAS_PER_SQUARE_METER = 180,
UNITS_WATTS_PER_SQUARE_FOOT = 34,
UNITS_WATTS_PER_SQUARE_METER = 35,
UNITS_LUMENS = 36,
UNITS_LUXES = 37,
UNITS_FOOT_CANDLES = 38,
/* Mass */
UNITS_MILLIGRAMS = 196,
UNITS_GRAMS = 195,
UNITS_KILOGRAMS = 39,
UNITS_POUNDS_MASS = 40,
UNITS_TONS = 41,
/* Mass Flow */
UNITS_GRAMS_PER_SECOND = 154,
UNITS_GRAMS_PER_MINUTE = 155,
UNITS_KILOGRAMS_PER_SECOND = 42,
UNITS_KILOGRAMS_PER_MINUTE = 43,
UNITS_KILOGRAMS_PER_HOUR = 44,
UNITS_POUNDS_MASS_PER_SECOND = 119,
UNITS_POUNDS_MASS_PER_MINUTE = 45,
UNITS_POUNDS_MASS_PER_HOUR = 46,
UNITS_TONS_PER_HOUR = 156,
/* Power */
UNITS_MILLIWATTS = 132,
UNITS_WATTS = 47,
UNITS_KILOWATTS = 48,
UNITS_MEGAWATTS = 49,
UNITS_BTUS_PER_HOUR = 50,
UNITS_KILO_BTUS_PER_HOUR = 157,
UNITS_HORSEPOWER = 51,
UNITS_TONS_REFRIGERATION = 52,
/* Pressure */
UNITS_PASCALS = 53,
UNITS_HECTOPASCALS = 133,
UNITS_KILOPASCALS = 54,
UNITS_MILLIBARS = 134,
UNITS_BARS = 55,
UNITS_POUNDS_FORCE_PER_SQUARE_INCH = 56,
UNITS_MILLIMETERS_OF_WATER = 206,
UNITS_CENTIMETERS_OF_WATER = 57,
UNITS_INCHES_OF_WATER = 58,
UNITS_MILLIMETERS_OF_MERCURY = 59,
UNITS_CENTIMETERS_OF_MERCURY = 60,
UNITS_INCHES_OF_MERCURY = 61,
/* Temperature */
UNITS_DEGREES_CELSIUS = 62,
UNITS_DEGREES_KELVIN = 63,
UNITS_DEGREES_KELVIN_PER_HOUR = 181,
UNITS_DEGREES_KELVIN_PER_MINUTE = 182,
UNITS_DEGREES_FAHRENHEIT = 64,
UNITS_DEGREE_DAYS_CELSIUS = 65,
UNITS_DEGREE_DAYS_FAHRENHEIT = 66,
UNITS_DELTA_DEGREES_FAHRENHEIT = 120,
UNITS_DELTA_DEGREES_KELVIN = 121,
/* Time */
UNITS_YEARS = 67,
UNITS_MONTHS = 68,
UNITS_WEEKS = 69,
UNITS_DAYS = 70,
UNITS_HOURS = 71,
UNITS_MINUTES = 72,
UNITS_SECONDS = 73,
UNITS_HUNDREDTHS_SECONDS = 158,
UNITS_MILLISECONDS = 159,
/* Torque */
UNITS_NEWTON_METERS = 160,
/* Velocity */
UNITS_MILLIMETERS_PER_SECOND = 161,
UNITS_MILLIMETERS_PER_MINUTE = 162,
UNITS_METERS_PER_SECOND = 74,
UNITS_METERS_PER_MINUTE = 163,
UNITS_METERS_PER_HOUR = 164,
UNITS_KILOMETERS_PER_HOUR = 75,
UNITS_FEET_PER_SECOND = 76,
UNITS_FEET_PER_MINUTE = 77,
UNITS_MILES_PER_HOUR = 78,
/* Volume */
UNITS_CUBIC_FEET = 79,
UNITS_CUBIC_METERS = 80,
UNITS_IMPERIAL_GALLONS = 81,
UNITS_MILLILITERS = 197,
UNITS_LITERS = 82,
UNITS_US_GALLONS = 83,
/* Volumetric Flow */
UNITS_CUBIC_FEET_PER_SECOND = 142,
UNITS_CUBIC_FEET_PER_MINUTE = 84,
// One unit in Addendum 135-2012bg
UNITS_MILLION_CUBIC_FEET_PER_MINUTE = 254,
UNITS_CUBIC_FEET_PER_HOUR = 191,
// five units in Addendum 135-2012bg
UNITS_STANDARD_CUBIC_FEET_PER_DAY = 47808,
UNITS_MILLION_STANDARD_CUBIC_FEET_PER_DAY = 47809,
UNITS_THOUSAND_CUBIC_FEET_PER_DAY = 47810,
UNITS_THOUSAND_STANDARD_CUBIC_FEET_PER_DAY = 47811,
UINITS_POUNDS_MASS_PER_DAY = 47812,
UNITS_CUBIC_METERS_PER_SECOND = 85,
UNITS_CUBIC_METERS_PER_MINUTE = 165,
UNITS_CUBIC_METERS_PER_HOUR = 135,
UNITS_IMPERIAL_GALLONS_PER_MINUTE = 86,
UNITS_MILLILITERS_PER_SECOND = 198,
UNITS_LITERS_PER_SECOND = 87,
UNITS_LITERS_PER_MINUTE = 88,
UNITS_LITERS_PER_HOUR = 136,
UNITS_US_GALLONS_PER_MINUTE = 89,
UNITS_US_GALLONS_PER_HOUR = 192,
/* Other */
UNITS_DEGREES_ANGULAR = 90,
UNITS_DEGREES_CELSIUS_PER_HOUR = 91,
UNITS_DEGREES_CELSIUS_PER_MINUTE = 92,
UNITS_DEGREES_FAHRENHEIT_PER_HOUR = 93,
UNITS_DEGREES_FAHRENHEIT_PER_MINUTE = 94,
UNITS_JOULE_SECONDS = 183,
UNITS_KILOGRAMS_PER_CUBIC_METER = 186,
UNITS_KW_HOURS_PER_SQUARE_METER = 137,
UNITS_KW_HOURS_PER_SQUARE_FOOT = 138,
UNITS_MEGAJOULES_PER_SQUARE_METER = 139,
UNITS_MEGAJOULES_PER_SQUARE_FOOT = 140,
UNITS_NO_UNITS = 95,
UNITS_NEWTON_SECONDS = 187,
UNITS_NEWTONS_PER_METER = 188,
UNITS_PARTS_PER_MILLION = 96,
UNITS_PARTS_PER_BILLION = 97,
UNITS_PERCENT = 98,
UNITS_PERCENT_OBSCURATION_PER_FOOT = 143,
UNITS_PERCENT_OBSCURATION_PER_METER = 144,
UNITS_PERCENT_PER_SECOND = 99,
UNITS_PER_MINUTE = 100,
UNITS_PER_SECOND = 101,
UNITS_PSI_PER_DEGREE_FAHRENHEIT = 102,
UNITS_RADIANS = 103,
UNITS_RADIANS_PER_SECOND = 184,
UNITS_REVOLUTIONS_PER_MINUTE = 104,
UNITS_SQUARE_METERS_PER_NEWTON = 185,
UNITS_WATTS_PER_METER_PER_DEGREE_KELVIN = 189,
UNITS_WATTS_PER_SQUARE_METER_DEGREE_KELVIN = 141,
UNITS_PER_MILLE = 207,
UNITS_GRAMS_PER_GRAM = 208,
UNITS_KILOGRAMS_PER_KILOGRAM = 209,
UNITS_GRAMS_PER_KILOGRAM = 210,
UNITS_MILLIGRAMS_PER_GRAM = 211,
UNITS_MILLIGRAMS_PER_KILOGRAM = 212,
UNITS_GRAMS_PER_MILLILITER = 213,
UNITS_GRAMS_PER_LITER = 214,
UNITS_MILLIGRAMS_PER_LITER = 215,
UNITS_MICROGRAMS_PER_LITER = 216,
UNITS_GRAMS_PER_CUBIC_METER = 217,
UNITS_MILLIGRAMS_PER_CUBIC_METER = 218,
UNITS_MICROGRAMS_PER_CUBIC_METER = 219,
UNITS_NANOGRAMS_PER_CUBIC_METER = 220,
UNITS_GRAMS_PER_CUBIC_CENTIMETER = 221,
UNITS_BECQUERELS = 222,
UNITS_KILOBECQUERELS = 223,
UNITS_MEGABECQUERELS = 224,
UNITS_GRAY = 225,
UNITS_MILLIGRAY = 226,
UNITS_MICROGRAY = 227,
UNITS_SIEVERTS = 228,
UNITS_MILLISIEVERTS = 229,
UNITS_MICROSIEVERTS = 230,
UNITS_MICROSIEVERTS_PER_HOUR = 231,
UNITS_DECIBELS_A = 232,
UNITS_NEPHELOMETRIC_TURBIDITY_UNIT = 233,
UNITS_PH = 234,
UNITS_GRAMS_PER_SQUARE_METER = 235,
// Since Addendum 135-2012ar
UNITS_MINUTES_PER_DEGREE_KELVIN = 236,
UNITS_METER_SQUARED_PER_METER = 237,
UNITS_AMPERE_SECONDS = 238,
UNITS_VOLT_AMPERE_HOURS = 239,
UNITS_KILOVOLT_AMPERE_HOURS = 240,
UNITS_MEGAVOLT_AMPERE_HOURS = 241,
UNITS_VOLT_AMPERE_HOURS_REACTIVE = 242,
UNITS_KILOVOLT_AMPERE_HOURS_REACTIVE = 243,
UNITS_MEGAVOLT_AMPERE_HOURS_REACTIVE = 244,
UNITS_VOLT_SQUARE_HOURS = 245,
UNITS_AMPERE_SQUARE_HOURS = 246,
UNITS_JOULE_PER_HOURS = 247,
UNITS_CUBIC_FEET_PER_DAY = 248,
UNITS_CUBIC_METERS_PER_DAY = 249,
UNITS_WATT_HOURS_PER_CUBIC_METER = 250,
UNITS_JOULES_PER_CUBIC_METER = 251,
UNITS_MOLE_PERCENT = 252,
UNITS_PASCAL_SECONDS = 253,
UNITS_MILLION_STANDARD_CUBIC_FEET_PER_MINUTE = 254,
UNITS_RESERVED_RANGE_MAX = 255,
/* Enumerated values 256-47807 may be used by others
subject to the procedures and constraints described in Clause 23. */
UNITS_PROPRIETARY_RANGE_MIN = 256,
UNITS_PROPRIETARY_RANGE_MAX = 47807,
/* Enumerated values 47808-49999 are reserved for definition by ASHRAE. */
UNITS_RESERVED_RANGE_MIN2 = 47808,
UNITS_POUNDS_MASS_PER_DAY = 47812,
/* 47813 - NOT USED */
UNITS_MILLIREMS = 47814,
UNITS_MILLIREMS_PER_HOUR = 47815,
UNITS_RESERVED_RANGE_MAX2 = 49999,
UNITS_PROPRIETARY_RANGE_MIN2 = 50000,
/* Enumerated values 50000-65535 may be used by others
subject to the procedures and constraints described in Clause 23. */
/* do the proprietary range inside of enum so that
compilers will allocate adequate sized datatype for enum
which is used to store decoding */
UNITS_PROPRIETARY_RANGE_MAX2 = 65535
}

89
addons/EGFramework/Third_Part_SourceCode/BacNetPlugin/Base/BacnetValue.cs

@ -1,89 +0,0 @@ @@ -1,89 +0,0 @@
namespace System.IO.BACnet;
public struct BacnetValue
{
public BacnetApplicationTags Tag;
public object Value;
public BacnetValue(BacnetApplicationTags tag, object value)
{
Tag = tag;
Value = value;
}
public BacnetValue(object value)
{
Value = value;
Tag = BacnetApplicationTags.BACNET_APPLICATION_TAG_NULL;
//guess at the tag
if (value != null)
Tag = TagFromType(value.GetType());
}
public BacnetApplicationTags TagFromType(Type t)
{
if (t == typeof(string))
return BacnetApplicationTags.BACNET_APPLICATION_TAG_CHARACTER_STRING;
if (t == typeof(int) || t == typeof(short) || t == typeof(sbyte))
return BacnetApplicationTags.BACNET_APPLICATION_TAG_SIGNED_INT;
if (t == typeof(uint) || t == typeof(ushort) || t == typeof(byte))
return BacnetApplicationTags.BACNET_APPLICATION_TAG_UNSIGNED_INT;
if (t == typeof(bool))
return BacnetApplicationTags.BACNET_APPLICATION_TAG_BOOLEAN;
if (t == typeof(float))
return BacnetApplicationTags.BACNET_APPLICATION_TAG_REAL;
if (t == typeof(double))
return BacnetApplicationTags.BACNET_APPLICATION_TAG_DOUBLE;
if (t == typeof(BacnetBitString))
return BacnetApplicationTags.BACNET_APPLICATION_TAG_BIT_STRING;
if (t == typeof(BacnetObjectId))
return BacnetApplicationTags.BACNET_APPLICATION_TAG_OBJECT_ID;
if (t == typeof(BacnetError))
return BacnetApplicationTags.BACNET_APPLICATION_TAG_ERROR;
if (t == typeof(BacnetDeviceObjectPropertyReference))
return BacnetApplicationTags.BACNET_APPLICATION_TAG_OBJECT_PROPERTY_REFERENCE;
if (t.IsEnum)
return BacnetApplicationTags.BACNET_APPLICATION_TAG_ENUMERATED;
return BacnetApplicationTags.BACNET_APPLICATION_TAG_CONTEXT_SPECIFIC_ENCODED;
}
public T As<T>()
{
if (typeof(T) == typeof(DateTime))
{
switch (Tag)
{
case BacnetApplicationTags.BACNET_APPLICATION_TAG_DATE:
case BacnetApplicationTags.BACNET_APPLICATION_TAG_DATETIME:
case BacnetApplicationTags.BACNET_APPLICATION_TAG_TIME:
case BacnetApplicationTags.BACNET_APPLICATION_TAG_TIMESTAMP:
return (T)Value;
}
}
if (typeof(T) == typeof(TimeSpan) && Tag == BacnetApplicationTags.BACNET_APPLICATION_TAG_TIME)
return (T)(dynamic)((DateTime)Value).TimeOfDay;
if (typeof(T) != typeof(object) && TagFromType(typeof(T)) != Tag)
throw new ArgumentException($"Value with tag {Tag} can't be converted to {typeof(T).Name}");
// ReSharper disable once RedundantCast
// This is needed for casting to enums
return (T)(dynamic)Value;
}
public override string ToString()
{
if (Value == null)
return string.Empty;
if (Value.GetType() != typeof(byte[]))
return Value.ToString();
var tmp = (byte[])Value;
return tmp.Aggregate(string.Empty, (current, b) =>
current + b.ToString("X2"));
}
}

22
addons/EGFramework/Third_Part_SourceCode/BacNetPlugin/Base/BacnetWritePriority.cs

@ -1,22 +0,0 @@ @@ -1,22 +0,0 @@
namespace System.IO.BACnet;
public enum BacnetWritePriority
{
NO_PRIORITY = 0,
MANUAL_LIFE_SAFETY = 1,
AUTOMATIC_LIFE_SAFETY = 2,
UNSPECIFIED_LEVEL_3 = 3,
UNSPECIFIED_LEVEL_4 = 4,
CRITICAL_EQUIPMENT_CONTROL = 5,
MINIMUM_ON_OFF = 6,
UNSPECIFIED_LEVEL_7 = 7,
MANUAL_OPERATOR = 8,
UNSPECIFIED_LEVEL_9 = 9,
UNSPECIFIED_LEVEL_10 = 10,
UNSPECIFIED_LEVEL_11 = 11,
UNSPECIFIED_LEVEL_12 = 12,
UNSPECIFIED_LEVEL_13 = 13,
UNSPECIFIED_LEVEL_14 = 14,
UNSPECIFIED_LEVEL_15 = 15,
LOWEST_AND_DEFAULT = 16
}

71
addons/EGFramework/Third_Part_SourceCode/BacNetPlugin/Base/BacnetweekNDay.cs

@ -1,71 +0,0 @@ @@ -1,71 +0,0 @@
namespace System.IO.BACnet;
public struct BacnetweekNDay : ASN1.IEncode, ASN1.IDecode
{
public byte month; /* 1 January, 13 Odd, 14 Even, 255 Any */
public byte week; /* Don't realy understand ??? 1 for day 1 to 7, 2 for ... what's the objective ? boycott it*/
public byte wday; /* 1=Monday-7=Sunday, 255 any */
public BacnetweekNDay(byte day, byte month, byte week = 255)
{
wday = day;
this.month = month;
this.week = week;
}
public void Encode(EncodeBuffer buffer)
{
buffer.Add(month);
buffer.Add(week);
buffer.Add(wday);
}
public int Decode(byte[] buffer, int offset, uint count)
{
month = buffer[offset++];
week = buffer[offset++];
wday = buffer[offset];
return 3;
}
private static string GetDayName(int day)
{
if (day == 7)
day = 0;
return CultureInfo.CurrentCulture.DateTimeFormat.DayNames[day];
}
public override string ToString()
{
string ret = wday != 255 ? GetDayName(wday) : "Every days";
if (month != 255)
ret += " on " + CultureInfo.CurrentCulture.DateTimeFormat.MonthNames[month - 1];
else
ret += " on every month";
return ret;
}
public bool IsAFittingDate(DateTime date)
{
if (date.Month != month && month != 255 && month != 13 && month != 14)
return false;
if (month == 13 && (date.Month & 1) != 1)
return false;
if (month == 14 && (date.Month & 1) == 1)
return false;
// What about week, too much stupid : boycott it !
if (wday == 255)
return true;
if (wday == 7 && date.DayOfWeek == 0) // Sunday 7 for Bacnet, 0 for .NET
return true;
if (wday == (int)date.DayOfWeek)
return true;
return false;
}
}

84
addons/EGFramework/Third_Part_SourceCode/BacNetPlugin/Base/DeviceReportingRecipient.cs

@ -1,84 +0,0 @@ @@ -1,84 +0,0 @@
namespace System.IO.BACnet;
public struct DeviceReportingRecipient : ASN1.IEncode
{
public BacnetBitString WeekofDay;
public DateTime toTime, fromTime;
public BacnetObjectId Id;
public BacnetAddress adr;
public uint processIdentifier;
public bool Ack_Required;
public BacnetBitString evenType;
public DeviceReportingRecipient(BacnetValue v0, BacnetValue v1, BacnetValue v2, BacnetValue v3, BacnetValue v4, BacnetValue v5, BacnetValue v6)
{
Id = new BacnetObjectId();
adr = null;
WeekofDay = (BacnetBitString)v0.Value;
fromTime = (DateTime)v1.Value;
toTime = (DateTime)v2.Value;
if (v3.Value is BacnetObjectId id)
{
Id = id;
}
else
{
var netdescr = (BacnetValue[])v3.Value;
var s = (ushort)(uint)netdescr[0].Value;
var b = (byte[])netdescr[1].Value;
adr = new BacnetAddress(BacnetAddressTypes.IP, s, b);
}
processIdentifier = (uint)v4.Value;
Ack_Required = (bool)v5.Value;
evenType = (BacnetBitString)v6.Value;
}
public DeviceReportingRecipient(BacnetBitString weekofDay, DateTime fromTime, DateTime toTime, BacnetObjectId id, uint processIdentifier, bool ackRequired, BacnetBitString evenType)
{
adr = null;
WeekofDay = weekofDay;
this.toTime = toTime;
this.fromTime = fromTime;
Id = id;
this.processIdentifier = processIdentifier;
Ack_Required = ackRequired;
this.evenType = evenType;
}
public DeviceReportingRecipient(BacnetBitString weekofDay, DateTime fromTime, DateTime toTime, BacnetAddress adr, uint processIdentifier, bool ackRequired, BacnetBitString evenType)
{
Id = new BacnetObjectId();
WeekofDay = weekofDay;
this.toTime = toTime;
this.fromTime = fromTime;
this.adr = adr;
this.processIdentifier = processIdentifier;
Ack_Required = ackRequired;
this.evenType = evenType;
}
public void Encode(EncodeBuffer buffer)
{
ASN1.bacapp_encode_application_data(buffer, new BacnetValue(WeekofDay));
ASN1.bacapp_encode_application_data(buffer, new BacnetValue(BacnetApplicationTags.BACNET_APPLICATION_TAG_TIME, fromTime));
ASN1.bacapp_encode_application_data(buffer, new BacnetValue(BacnetApplicationTags.BACNET_APPLICATION_TAG_TIME, toTime));
if (adr != null)
{
adr.Encode(buffer);
}
else
{
// BacnetObjectId is context specific encoded
ASN1.encode_context_object_id(buffer, 0, Id.type, Id.instance);
}
ASN1.bacapp_encode_application_data(buffer, new BacnetValue(processIdentifier));
ASN1.bacapp_encode_application_data(buffer, new BacnetValue(Ack_Required));
ASN1.bacapp_encode_application_data(buffer, new BacnetValue(evenType));
}
}

10
addons/EGFramework/Third_Part_SourceCode/BacNetPlugin/Base/Enums/BacnetBackupState.cs

@ -1,10 +0,0 @@ @@ -1,10 +0,0 @@
namespace System.IO.BACnet;
public enum BacnetBackupState
{
IDLE = 0,
PREPARING_FOR_BACKUP = 1,
PREPARING_FOR_RESTORE = 2,
PERFORMING_A_BACKUP = 3,
PERFORMING_A_RESTORE = 4
}

7
addons/EGFramework/Third_Part_SourceCode/BacNetPlugin/Base/Enums/BacnetCOVTypes.cs

@ -1,7 +0,0 @@ @@ -1,7 +0,0 @@
namespace System.IO.BACnet;
public enum BacnetCOVTypes
{
CHANGE_OF_VALUE_BITS,
CHANGE_OF_VALUE_REAL
}

8
addons/EGFramework/Third_Part_SourceCode/BacNetPlugin/Base/Enums/BacnetEventEnable.cs

@ -1,8 +0,0 @@ @@ -1,8 +0,0 @@
namespace System.IO.BACnet;
public enum BacnetEventEnable
{
EVENT_ENABLE_TO_OFFNORMAL = 1,
EVENT_ENABLE_TO_FAULT = 2,
EVENT_ENABLE_TO_NORMAL = 4
}

11
addons/EGFramework/Third_Part_SourceCode/BacNetPlugin/Base/Enums/BacnetEventStates.cs

@ -1,11 +0,0 @@ @@ -1,11 +0,0 @@
namespace System.IO.BACnet;
public enum BacnetEventStates
{
EVENT_STATE_NORMAL = 0,
EVENT_STATE_FAULT = 1,
EVENT_STATE_OFFNORMAL = 2,
EVENT_STATE_HIGH_LIMIT = 3,
EVENT_STATE_LOW_LIMIT = 4,
EVENT_STATE_LIFE_SAFETY_ALARM = 5
}

40
addons/EGFramework/Third_Part_SourceCode/BacNetPlugin/Base/Enums/BacnetEventTypes.cs

@ -1,40 +0,0 @@ @@ -1,40 +0,0 @@
namespace System.IO.BACnet;
public enum BacnetEventTypes
{
EVENT_CHANGE_OF_BITSTRING = 0,
EVENT_CHANGE_OF_STATE = 1,
EVENT_CHANGE_OF_VALUE = 2,
EVENT_COMMAND_FAILURE = 3,
EVENT_FLOATING_LIMIT = 4,
EVENT_OUT_OF_RANGE = 5,
/* complex-event-type (6), -- see comment below */
/* event-buffer-ready (7), -- context tag 7 is deprecated */
EVENT_CHANGE_OF_LIFE_SAFETY = 8,
EVENT_EXTENDED = 9,
EVENT_BUFFER_READY = 10,
EVENT_UNSIGNED_RANGE = 11,
/* -- enumeration value 12 is reserved for future addenda */
EVENT_ACCESS_EVENT = 13,
EVENT_DOUBLE_OUT_OF_RANGE = 14,
EVENT_SIGNED_OUT_OF_RANGE = 15,
EVENT_UNSIGNED_OUT_OF_RANGE = 16,
EVENT_CHANGE_OF_CHARACTERSTRING = 17,
EVENT_CHANGE_OF_STATUS_FLAGS = 18,
EVENT_CHANGE_OF_RELIABILITY = 19,
EVENT_NONE = 20,
EVENT_CHANGE_OF_DISCRETE_VALUE = 21,
EVENT_CHANGE_OF_TIMER = 22,
/* Enumerated values 0-63 are reserved for definition by ASHRAE. */
/* Enumerated values 64-65535 may be used by others subject to */
/* the procedures and constraints described in Clause 23. */
/* It is expected that these enumerated values will correspond to */
/* the use of the complex-event-type CHOICE [6] of the */
/* BACnetNotificationParameters production. */
/* The last enumeration used in this version is 11. */
/* do the max range inside of enum so that
compilers will allocate adequate sized datatype for enum
which is used to store decoding */
EVENT_PROPRIETARY_MIN = 64,
EVENT_PROPRIETARY_MAX = 65535
}

7
addons/EGFramework/Third_Part_SourceCode/BacNetPlugin/Base/Enums/BacnetFileAccessMethod.cs

@ -1,7 +0,0 @@ @@ -1,7 +0,0 @@
namespace System.IO.BACnet;
public enum BacnetFileAccessMethod
{
RECORD_ACCESS = 0,
STREAM_ACCESS = 1
}

30
addons/EGFramework/Third_Part_SourceCode/BacNetPlugin/Base/Enums/BacnetLifeSafetyModes.cs

@ -1,30 +0,0 @@ @@ -1,30 +0,0 @@
namespace System.IO.BACnet;
public enum BacnetLifeSafetyModes
{
MIN_LIFE_SAFETY_MODE = 0,
LIFE_SAFETY_MODE_OFF = 0,
LIFE_SAFETY_MODE_ON = 1,
LIFE_SAFETY_MODE_TEST = 2,
LIFE_SAFETY_MODE_MANNED = 3,
LIFE_SAFETY_MODE_UNMANNED = 4,
LIFE_SAFETY_MODE_ARMED = 5,
LIFE_SAFETY_MODE_DISARMED = 6,
LIFE_SAFETY_MODE_PREARMED = 7,
LIFE_SAFETY_MODE_SLOW = 8,
LIFE_SAFETY_MODE_FAST = 9,
LIFE_SAFETY_MODE_DISCONNECTED = 10,
LIFE_SAFETY_MODE_ENABLED = 11,
LIFE_SAFETY_MODE_DISABLED = 12,
LIFE_SAFETY_MODE_AUTOMATIC_RELEASE_DISABLED = 13,
LIFE_SAFETY_MODE_DEFAULT = 14,
MAX_LIFE_SAFETY_MODE = 15,
/* Enumerated values 0-255 are reserved for definition by ASHRAE. */
/* Enumerated values 256-65535 may be used by others subject to */
/* procedures and constraints described in Clause 23. */
/* do the max range inside of enum so that
compilers will allocate adequate sized datatype for enum
which is used to store decoding */
LIFE_SAFETY_MODE_PROPRIETARY_MIN = 256,
LIFE_SAFETY_MODE_PROPRIETARY_MAX = 65535
}

23
addons/EGFramework/Third_Part_SourceCode/BacNetPlugin/Base/Enums/BacnetLifeSafetyOperations.cs

@ -1,23 +0,0 @@ @@ -1,23 +0,0 @@
namespace System.IO.BACnet;
public enum BacnetLifeSafetyOperations
{
LIFE_SAFETY_OP_NONE = 0,
LIFE_SAFETY_OP_SILENCE = 1,
LIFE_SAFETY_OP_SILENCE_AUDIBLE = 2,
LIFE_SAFETY_OP_SILENCE_VISUAL = 3,
LIFE_SAFETY_OP_RESET = 4,
LIFE_SAFETY_OP_RESET_ALARM = 5,
LIFE_SAFETY_OP_RESET_FAULT = 6,
LIFE_SAFETY_OP_UNSILENCE = 7,
LIFE_SAFETY_OP_UNSILENCE_AUDIBLE = 8,
LIFE_SAFETY_OP_UNSILENCE_VISUAL = 9,
/* Enumerated values 0-63 are reserved for definition by ASHRAE. */
/* Enumerated values 64-65535 may be used by others subject to */
/* procedures and constraints described in Clause 23. */
/* do the max range inside of enum so that
compilers will allocate adequate sized datatype for enum
which is used to store decoding */
LIFE_SAFETY_OP_PROPRIETARY_MIN = 64,
LIFE_SAFETY_OP_PROPRIETARY_MAX = 65535
}

39
addons/EGFramework/Third_Part_SourceCode/BacNetPlugin/Base/Enums/BacnetLifeSafetyStates.cs

@ -1,39 +0,0 @@ @@ -1,39 +0,0 @@
namespace System.IO.BACnet;
public enum BacnetLifeSafetyStates
{
MIN_LIFE_SAFETY_STATE = 0,
LIFE_SAFETY_STATE_QUIET = 0,
LIFE_SAFETY_STATE_PRE_ALARM = 1,
LIFE_SAFETY_STATE_ALARM = 2,
LIFE_SAFETY_STATE_FAULT = 3,
LIFE_SAFETY_STATE_FAULT_PRE_ALARM = 4,
LIFE_SAFETY_STATE_FAULT_ALARM = 5,
LIFE_SAFETY_STATE_NOT_READY = 6,
LIFE_SAFETY_STATE_ACTIVE = 7,
LIFE_SAFETY_STATE_TAMPER = 8,
LIFE_SAFETY_STATE_TEST_ALARM = 9,
LIFE_SAFETY_STATE_TEST_ACTIVE = 10,
LIFE_SAFETY_STATE_TEST_FAULT = 11,
LIFE_SAFETY_STATE_TEST_FAULT_ALARM = 12,
LIFE_SAFETY_STATE_HOLDUP = 13,
LIFE_SAFETY_STATE_DURESS = 14,
LIFE_SAFETY_STATE_TAMPER_ALARM = 15,
LIFE_SAFETY_STATE_ABNORMAL = 16,
LIFE_SAFETY_STATE_EMERGENCY_POWER = 17,
LIFE_SAFETY_STATE_DELAYED = 18,
LIFE_SAFETY_STATE_BLOCKED = 19,
LIFE_SAFETY_STATE_LOCAL_ALARM = 20,
LIFE_SAFETY_STATE_GENERAL_ALARM = 21,
LIFE_SAFETY_STATE_SUPERVISORY = 22,
LIFE_SAFETY_STATE_TEST_SUPERVISORY = 23,
MAX_LIFE_SAFETY_STATE = 24,
/* Enumerated values 0-255 are reserved for definition by ASHRAE. */
/* Enumerated values 256-65535 may be used by others subject to */
/* procedures and constraints described in Clause 23. */
/* do the max range inside of enum so that
compilers will allocate adequate sized datatype for enum
which is used to store decoding */
LIFE_SAFETY_STATE_PROPRIETARY_MIN = 256,
LIFE_SAFETY_STATE_PROPRIETARY_MAX = 65535
}

7
addons/EGFramework/Third_Part_SourceCode/BacNetPlugin/Base/Enums/BacnetLimitEnable.cs

@ -1,7 +0,0 @@ @@ -1,7 +0,0 @@
namespace System.IO.BACnet;
public enum BacnetLimitEnable
{
EVENT_LOW_LIMIT_ENABLE = 1,
EVENT_HIGH_LIMIT_ENABLE = 2
}

8
addons/EGFramework/Third_Part_SourceCode/BacNetPlugin/Base/Enums/BacnetNotifyTypes.cs

@ -1,8 +0,0 @@ @@ -1,8 +0,0 @@
namespace System.IO.BACnet;
public enum BacnetNotifyTypes
{
NOTIFY_ALARM = 0,
NOTIFY_EVENT = 1,
NOTIFY_ACK_NOTIFICATION = 2
}

21
addons/EGFramework/Third_Part_SourceCode/BacNetPlugin/GlobalUsings.cs

@ -1,21 +0,0 @@ @@ -1,21 +0,0 @@
global using Common.Logging;
global using PacketDotNet;
global using SharpPcap;
global using SharpPcap.LibPcap;
global using System.Collections.Generic;
global using System.Globalization;
global using System.IO.BACnet.Base;
global using System.IO.BACnet.Serialize;
global using System.IO.Pipes;
global using System.IO.Ports;
global using System.Linq;
global using System.Net;
global using System.Net.NetworkInformation;
global using System.Net.Sockets;
global using System.Reflection;
global using System.Runtime.InteropServices;
global using System.Text;
global using System.Text.RegularExpressions;
global using System.Threading;
global using System.Threading.Tasks;
global using System.Xml.Serialization;

64
addons/EGFramework/Third_Part_SourceCode/BacNetPlugin/Helpers/BacnetValuesExtensions.cs

@ -1,64 +0,0 @@ @@ -1,64 +0,0 @@
namespace System.IO.BACnet.Helpers;
public static class BacnetValuesExtensions
{
public static bool Has(this IList<BacnetPropertyValue> propertyValues, BacnetPropertyIds propertyId)
{
if (propertyValues.All(v => v.property.GetPropertyId() != propertyId))
return false;
return propertyValues
.Where(v => v.property.GetPropertyId() == propertyId)
.Any(v => !v.value.HasError());
}
public static bool HasError(this IList<BacnetPropertyValue> propertyValues, BacnetErrorCodes error)
{
return propertyValues
.SelectMany(p => p.value)
.Where(v => v.Tag == BacnetApplicationTags.BACNET_APPLICATION_TAG_ERROR)
.Any(v => v.As<BacnetError>().error_code == error);
}
public static bool HasError(this IList<BacnetPropertyValue> propertyValues)
{
return propertyValues.Any(p => p.value.HasError());
}
public static bool HasError(this IList<BacnetValue> values)
{
return values.Any(v => v.Tag == BacnetApplicationTags.BACNET_APPLICATION_TAG_ERROR);
}
public static object Get(this IList<BacnetPropertyValue> propertyValues, BacnetPropertyIds propertyId)
{
return Get<object>(propertyValues, propertyId);
}
public static T Get<T>(this IList<BacnetPropertyValue> propertyValues, BacnetPropertyIds propertyId)
{
return GetMany<T>(propertyValues, propertyId).FirstOrDefault();
}
public static T[] GetMany<T>(this IList<BacnetPropertyValue> propertyValues, BacnetPropertyIds propertyId)
{
if (!propertyValues.Has(propertyId))
return new T[0];
var property = propertyValues.First(v => v.property.GetPropertyId() == propertyId);
return property.property.propertyArrayIndex == ASN1.BACNET_ARRAY_ALL
? property.value.GetMany<T>()
: new[] { property.value[(int)property.property.propertyArrayIndex].As<T>() };
}
public static T[] GetMany<T>(this IList<BacnetValue> values)
{
return values.Select(v => v.As<T>()).ToArray();
}
public static T Get<T>(this IList<BacnetValue> values)
{
return GetMany<T>(values).FirstOrDefault();
}
}

217
addons/EGFramework/Third_Part_SourceCode/BacNetPlugin/Serialize/APDU.cs

@ -1,217 +0,0 @@ @@ -1,217 +0,0 @@
namespace System.IO.BACnet.Serialize;
public class APDU
{
public static BacnetPduTypes GetDecodedType(byte[] buffer, int offset)
{
return (BacnetPduTypes)buffer[offset];
}
public static void SetDecodedType(byte[] buffer, int offset, BacnetPduTypes type)
{
buffer[offset] = (byte)type;
}
public static int GetDecodedInvokeId(byte[] buffer, int offset)
{
var type = GetDecodedType(buffer, offset);
switch (type & BacnetPduTypes.PDU_TYPE_MASK)
{
case BacnetPduTypes.PDU_TYPE_SIMPLE_ACK:
case BacnetPduTypes.PDU_TYPE_COMPLEX_ACK:
case BacnetPduTypes.PDU_TYPE_ERROR:
case BacnetPduTypes.PDU_TYPE_REJECT:
case BacnetPduTypes.PDU_TYPE_ABORT:
return buffer[offset + 1];
case BacnetPduTypes.PDU_TYPE_CONFIRMED_SERVICE_REQUEST:
return buffer[offset + 2];
default:
return -1;
}
}
public static void EncodeConfirmedServiceRequest(EncodeBuffer buffer, BacnetPduTypes type, BacnetConfirmedServices service, BacnetMaxSegments maxSegments,
BacnetMaxAdpu maxAdpu, byte invokeId, byte sequenceNumber = 0, byte proposedWindowSize = 0)
{
buffer.buffer[buffer.offset++] = (byte)type;
buffer.buffer[buffer.offset++] = (byte)((byte)maxSegments | (byte)maxAdpu);
buffer.buffer[buffer.offset++] = invokeId;
if ((type & BacnetPduTypes.SEGMENTED_MESSAGE) > 0)
{
buffer.buffer[buffer.offset++] = sequenceNumber;
buffer.buffer[buffer.offset++] = proposedWindowSize;
}
buffer.buffer[buffer.offset++] = (byte)service;
}
public static int DecodeConfirmedServiceRequest(byte[] buffer, int offset, out BacnetPduTypes type, out BacnetConfirmedServices service,
out BacnetMaxSegments maxSegments, out BacnetMaxAdpu maxAdpu, out byte invokeId, out byte sequenceNumber, out byte proposedWindowNumber)
{
var orgOffset = offset;
type = (BacnetPduTypes)buffer[offset++];
maxSegments = (BacnetMaxSegments)(buffer[offset] & 0xF0);
maxAdpu = (BacnetMaxAdpu)(buffer[offset++] & 0x0F);
invokeId = buffer[offset++];
sequenceNumber = 0;
proposedWindowNumber = 0;
if ((type & BacnetPduTypes.SEGMENTED_MESSAGE) > 0)
{
sequenceNumber = buffer[offset++];
proposedWindowNumber = buffer[offset++];
}
service = (BacnetConfirmedServices)buffer[offset++];
return offset - orgOffset;
}
public static void EncodeUnconfirmedServiceRequest(EncodeBuffer buffer, BacnetPduTypes type, BacnetUnconfirmedServices service)
{
buffer.buffer[buffer.offset++] = (byte)type;
buffer.buffer[buffer.offset++] = (byte)service;
}
public static int DecodeUnconfirmedServiceRequest(byte[] buffer, int offset, out BacnetPduTypes type, out BacnetUnconfirmedServices service)
{
var orgOffset = offset;
type = (BacnetPduTypes)buffer[offset++];
service = (BacnetUnconfirmedServices)buffer[offset++];
return offset - orgOffset;
}
public static void EncodeSimpleAck(EncodeBuffer buffer, BacnetPduTypes type, BacnetConfirmedServices service, byte invokeId)
{
buffer.buffer[buffer.offset++] = (byte)type;
buffer.buffer[buffer.offset++] = invokeId;
buffer.buffer[buffer.offset++] = (byte)service;
}
public static int DecodeSimpleAck(byte[] buffer, int offset, out BacnetPduTypes type, out BacnetConfirmedServices service, out byte invokeId)
{
var orgOffset = offset;
type = (BacnetPduTypes)buffer[offset++];
invokeId = buffer[offset++];
service = (BacnetConfirmedServices)buffer[offset++];
return offset - orgOffset;
}
public static int EncodeComplexAck(EncodeBuffer buffer, BacnetPduTypes type, BacnetConfirmedServices service, byte invokeId, byte sequenceNumber = 0, byte proposedWindowNumber = 0)
{
var len = 3;
buffer.buffer[buffer.offset++] = (byte)type;
buffer.buffer[buffer.offset++] = invokeId;
if ((type & BacnetPduTypes.SEGMENTED_MESSAGE) > 0)
{
buffer.buffer[buffer.offset++] = sequenceNumber;
buffer.buffer[buffer.offset++] = proposedWindowNumber;
len += 2;
}
buffer.buffer[buffer.offset++] = (byte)service;
return len;
}
public static int DecodeComplexAck(byte[] buffer, int offset, out BacnetPduTypes type, out BacnetConfirmedServices service, out byte invokeId,
out byte sequenceNumber, out byte proposedWindowNumber)
{
var orgOffset = offset;
type = (BacnetPduTypes)buffer[offset++];
invokeId = buffer[offset++];
sequenceNumber = 0;
proposedWindowNumber = 0;
if ((type & BacnetPduTypes.SEGMENTED_MESSAGE) > 0)
{
sequenceNumber = buffer[offset++];
proposedWindowNumber = buffer[offset++];
}
service = (BacnetConfirmedServices)buffer[offset++];
return offset - orgOffset;
}
public static void EncodeSegmentAck(EncodeBuffer buffer, BacnetPduTypes type, byte originalInvokeId, byte sequenceNumber, byte actualWindowSize)
{
buffer.buffer[buffer.offset++] = (byte)type;
buffer.buffer[buffer.offset++] = originalInvokeId;
buffer.buffer[buffer.offset++] = sequenceNumber;
buffer.buffer[buffer.offset++] = actualWindowSize;
}
public static int DecodeSegmentAck(byte[] buffer, int offset, out BacnetPduTypes type, out byte originalInvokeId, out byte sequenceNumber, out byte actualWindowSize)
{
var orgOffset = offset;
type = (BacnetPduTypes)buffer[offset++];
originalInvokeId = buffer[offset++];
sequenceNumber = buffer[offset++];
actualWindowSize = buffer[offset++];
return offset - orgOffset;
}
public static void EncodeError(EncodeBuffer buffer, BacnetPduTypes type, BacnetConfirmedServices service, byte invokeId)
{
buffer.buffer[buffer.offset++] = (byte)type;
buffer.buffer[buffer.offset++] = invokeId;
buffer.buffer[buffer.offset++] = (byte)service;
}
public static int DecodeError(byte[] buffer, int offset, out BacnetPduTypes type, out BacnetConfirmedServices service, out byte invokeId)
{
var orgOffset = offset;
type = (BacnetPduTypes)buffer[offset++];
invokeId = buffer[offset++];
service = (BacnetConfirmedServices)buffer[offset++];
return offset - orgOffset;
}
public static void EncodeAbort(EncodeBuffer buffer, BacnetPduTypes type, byte invokeId, BacnetAbortReason reason)
{
EncodeAbortOrReject(buffer, type, invokeId, reason);
}
public static void EncodeReject(EncodeBuffer buffer, BacnetPduTypes type, byte invokeId, BacnetRejectReason reason)
{
EncodeAbortOrReject(buffer, type, invokeId, reason);
}
private static void EncodeAbortOrReject(EncodeBuffer buffer, BacnetPduTypes type, byte invokeId, dynamic reason)
{
buffer.buffer[buffer.offset++] = (byte)type;
buffer.buffer[buffer.offset++] = invokeId;
buffer.buffer[buffer.offset++] = (byte)reason;
}
public static int DecodeAbort(byte[] buffer, int offset, out BacnetPduTypes type,
out byte invokeId, out BacnetAbortReason reason)
{
return DecodeAbortOrReject(buffer, offset, out type, out invokeId, out reason);
}
public static int DecodeReject(byte[] buffer, int offset, out BacnetPduTypes type,
out byte invokeId, out BacnetRejectReason reason)
{
return DecodeAbortOrReject(buffer, offset, out type, out invokeId, out reason);
}
private static int DecodeAbortOrReject<TReason>(byte[] buffer, int offset,
out BacnetPduTypes type, out byte invokeId, out TReason reason)
{
var orgOffset = offset;
type = (BacnetPduTypes)buffer[offset++];
invokeId = buffer[offset++];
reason = (TReason)(dynamic)buffer[offset++];
return offset - orgOffset;
}
}

2486
addons/EGFramework/Third_Part_SourceCode/BacNetPlugin/Serialize/ASN1.cs

File diff suppressed because it is too large Load Diff

416
addons/EGFramework/Third_Part_SourceCode/BacNetPlugin/Serialize/BVLC.cs

@ -1,416 +0,0 @@ @@ -1,416 +0,0 @@
namespace System.IO.BACnet.Serialize;
// Special thanks to VTS tool (BBMD services not activated but programmed !) and Steve Karg stack
public class BVLC
{
public delegate void BVLCMessageReceiveHandler(IPEndPoint sender, BacnetBvlcFunctions function, BacnetBvlcResults result, object data);
public event BVLCMessageReceiveHandler MessageReceived;
private readonly BacnetIpUdpProtocolTransport _myBbmdTransport;
readonly string _broadcastAdd;
private bool _bbmdFdServiceActivated;
public const byte BVLL_TYPE_BACNET_IP = 0x81;
public const byte BVLC_HEADER_LENGTH = 4;
public const BacnetMaxAdpu BVLC_MAX_APDU = BacnetMaxAdpu.MAX_APDU1476;
// Two lists for optional BBMD activity
readonly List<KeyValuePair<IPEndPoint, DateTime>> _foreignDevices = new();
private readonly List<KeyValuePair<IPEndPoint, IPAddress>> _bbmds = new();
// Contains the rules to accept FRD based on the IP adress
// If empty it's equal to *.*.*.*, everyone allows
private readonly List<Regex> _autorizedFdr = new();
public ILog Log { get; set; } = LogManager.GetLogger<BVLC>();
public BVLC(BacnetIpUdpProtocolTransport transport)
{
_myBbmdTransport = transport;
_broadcastAdd = _myBbmdTransport.GetBroadcastAddress().ToString().Split(':')[0];
}
public string FDList()
{
var sb = new StringBuilder();
lock (_foreignDevices)
{
// remove oldest Device entries (Time expiration > TTL + 30s delay)
_foreignDevices.Remove(_foreignDevices.Find(item => DateTime.Now > item.Value));
foreach (var client in _foreignDevices)
sb.Append($"{client.Key.Address}:{client.Key.Port};");
}
return sb.ToString();
}
public void AddFDRAutorisationRule(Regex ipRule)
{
_autorizedFdr.Add(ipRule);
}
// Used to initiate the BBMD & FD behaviour, if BBMD is null it start the FD activity only
public void AddBBMDPeer(IPEndPoint bbmd, IPAddress mask)
{
_bbmdFdServiceActivated = true;
if (bbmd == null)
return;
lock (_bbmds)
_bbmds.Add(new KeyValuePair<IPEndPoint, IPAddress>(bbmd, mask));
}
// Add a FD to the table or renew it
private void RegisterForeignDevice(IPEndPoint sender, int ttl)
{
lock (_foreignDevices)
{
// remove it, if any
_foreignDevices.Remove(_foreignDevices.Find(item => item.Key.Equals(sender)));
// TTL + 30s grace period
var expiration = DateTime.Now.AddSeconds(ttl + 30);
// add it
if (_autorizedFdr.Count == 0) // No rules, accept all
{
_foreignDevices.Add(new KeyValuePair<IPEndPoint, DateTime>(sender, expiration));
return;
}
foreach (var r in _autorizedFdr)
{
if (r.Match(sender.Address.ToString()).Success)
{
_foreignDevices.Add(new KeyValuePair<IPEndPoint, DateTime>(sender, expiration));
return;
}
}
Log.Info($"Rejected FDR registration, IP : {sender.Address}");
}
}
// Send a Frame to each registered foreign devices, except the original sender
private void SendToFDs(byte[] buffer, int msgLength, IPEndPoint ePsender = null)
{
lock (_foreignDevices)
{
// remove oldest Device entries (Time expiration > TTL + 30s delay)
_foreignDevices.Remove(_foreignDevices.Find(item => DateTime.Now > item.Value));
// Send to all others, except the original sender
foreach (var client in _foreignDevices)
{
if (!client.Key.Equals(ePsender))
_myBbmdTransport.Send(buffer, msgLength, client.Key);
}
}
}
private static IPEndPoint BBMDSentAdd(IPEndPoint bbmd, IPAddress mask)
{
var bm = mask.GetAddressBytes();
var bip = bbmd.Address.GetAddressBytes();
/* annotation in Steve Karg bacnet stack :
The B/IP address to which the Forwarded-NPDU message is
sent is formed by inverting the broadcast distribution
mask in the BDT entry and logically ORing it with the
BBMD address of the same entry. This process
produces either the directed broadcast address of the remote
subnet or the unicast address of the BBMD on that subnet
depending on the contents of the broadcast distribution
mask.
remark from me :
for instance remote BBMD 192.168.0.1 - mask 255.255.255.255
messages are forward directly to 192.168.0.1
remote BBMD 192.168.0.1 - mask 255.255.255.0
messages are forward to 192.168.0.255, ie certainly the local broadcast
address, but these datagrams are generaly destroy by the final IP router
*/
for (var i = 0; i < bm.Length; i++)
bip[i] = (byte)(bip[i] | ~bm[i]);
return new IPEndPoint(new IPAddress(bip), bbmd.Port);
}
// Send a Frame to each registered BBMD except the original sender
private void SendToBbmDs(byte[] buffer, int msgLength)
{
lock (_bbmds)
{
foreach (var e in _bbmds)
{
var endpoint = BBMDSentAdd(e.Key, e.Value);
_myBbmdTransport.Send(buffer, msgLength, endpoint);
}
}
}
private static void First4BytesHeaderEncode(IList<byte> b, BacnetBvlcFunctions function, int msgLength)
{
b[0] = BVLL_TYPE_BACNET_IP;
b[1] = (byte)function;
b[2] = (byte)((msgLength & 0xFF00) >> 8);
b[3] = (byte)((msgLength & 0x00FF) >> 0);
}
private void Forward_NPDU(byte[] buffer, int msgLength, bool toGlobalBroadcast, IPEndPoint ePsender)
{
// Forms the forwarded NPDU from the original one, and send it to all
// orignal - 4 bytes BVLC - NPDU - APDU
// change to - 10 bytes BVLC - NPDU - APDU
// copy, 6 bytes shifted
var b = new byte[msgLength + 6]; // normaly only 'small' frames are present here, so no need to check if it's to big for Udp
Array.Copy(buffer, 0, b, 6, msgLength);
// 10 bytes for the BVLC Header, with the embedded 6 bytes IP:Port of the original sender
First4BytesHeaderEncode(b, BacnetBvlcFunctions.BVLC_FORWARDED_NPDU, msgLength + 6);
BacnetIpUdpProtocolTransport.Convert(ePsender, out var bacSender); // to embbed in the forward BVLC header
for (var i = 0; i < bacSender.adr.Length; i++)
b[4 + i] = bacSender.adr[i];
// To BBMD
SendToBbmDs(b, msgLength + 6);
// To FD, except the sender
SendToFDs(b, msgLength + 6, ePsender);
// Broadcast if required
if (toGlobalBroadcast)
_myBbmdTransport.Send(b, msgLength + 6, new IPEndPoint(IPAddress.Parse(_broadcastAdd), _myBbmdTransport.SharedPort));
}
// Send ack or nack
private void SendResult(IPEndPoint sender, BacnetBvlcResults resultCode)
{
var b = new byte[6];
First4BytesHeaderEncode(b, BacnetBvlcFunctions.BVLC_RESULT, 6);
b[4] = (byte)(((ushort)resultCode & 0xFF00) >> 8);
b[5] = (byte)((ushort)resultCode & 0xFF);
_myBbmdTransport.Send(b, 6, sender);
}
public void SendRegisterAsForeignDevice(IPEndPoint bbmd, short ttl)
{
var b = new byte[6];
First4BytesHeaderEncode(b, BacnetBvlcFunctions.BVLC_REGISTER_FOREIGN_DEVICE, 6);
b[4] = (byte)((ttl & 0xFF00) >> 8);
b[5] = (byte)(ttl & 0xFF);
_myBbmdTransport.Send(b, 6, bbmd);
}
public void SendReadBroadCastTable(IPEndPoint bbmd)
{
var b = new byte[4];
First4BytesHeaderEncode(b, BacnetBvlcFunctions.BVLC_READ_BROADCAST_DIST_TABLE, 4);
_myBbmdTransport.Send(b, 4, bbmd);
}
public void SendReadFDRTable(IPEndPoint bbmd)
{
var b = new byte[4];
First4BytesHeaderEncode(b, BacnetBvlcFunctions.BVLC_READ_FOREIGN_DEVICE_TABLE, 4);
_myBbmdTransport.Send(b, 4, bbmd);
}
public void SendWriteBroadCastTable(IPEndPoint bbmd, List<Tuple<IPEndPoint, IPAddress>> entries)
{
var b = new byte[4 + 10 * entries.Count];
First4BytesHeaderEncode(b, BacnetBvlcFunctions.BVLC_WRITE_BROADCAST_DISTRIBUTION_TABLE, 4 + 10 * entries.Count);
for (var i = 0; i < entries.Count; i++)
{
Array.Copy(entries[i].Item1.Address.GetAddressBytes(), 0, b, 4 + i * 10, 4);
b[8 + i * 10] = (byte)(entries[i].Item1.Port >> 8);
b[9 + i * 10] = (byte)(entries[i].Item1.Port & 0xFF);
Array.Copy(entries[i].Item2.GetAddressBytes(), 0, b, 10 + i * 10, 4);
}
_myBbmdTransport.Send(b, 4 + 10 * entries.Count, bbmd);
}
public void SendDeleteForeignDeviceEntry(IPEndPoint bbmd, IPEndPoint foreignDevice)
{
var b = new byte[4 + 6];
First4BytesHeaderEncode(b, BacnetBvlcFunctions.BVLC_READ_FOREIGN_DEVICE_TABLE, 4 + 6);
Array.Copy(foreignDevice.Address.GetAddressBytes(), 0, b, 4, 4);
b[8] = (byte)(foreignDevice.Port >> 8);
b[9] = (byte)(foreignDevice.Port & 0xFF);
_myBbmdTransport.Send(b, 4 + 6, bbmd);
}
public void SendRemoteWhois(byte[] buffer, IPEndPoint bbmd, int msgLength)
{
Encode(buffer, 0, BacnetBvlcFunctions.BVLC_DISTRIBUTE_BROADCAST_TO_NETWORK, msgLength);
_myBbmdTransport.Send(buffer, msgLength, bbmd);
}
// Encode is called by internal services if the BBMD is also an active device
public int Encode(byte[] buffer, int offset, BacnetBvlcFunctions function, int msgLength)
{
// offset always 0, we are the first after udp
// do the job
First4BytesHeaderEncode(buffer, function, msgLength);
// optional BBMD service
if (_bbmdFdServiceActivated && function == BacnetBvlcFunctions.BVLC_ORIGINAL_BROADCAST_NPDU)
{
var me = _myBbmdTransport.LocalEndPoint;
// just sometime working, enable to get the local ep, always 0.0.0.0 if the socket is open with
// System.Net.IPAddress.Any
// So in this case don't send a bad message
if (me.Address.ToString() != "0.0.0.0")
Forward_NPDU(buffer, msgLength, false, me); // send to all BBMDs and FDs
}
return 4; // ready to send
}
// Decode is called each time an Udp Frame is received
public int Decode(byte[] buffer, int offset, out BacnetBvlcFunctions function, out int msgLength, IPEndPoint sender)
{
// offset always 0, we are the first after udp
// and a previous test by the caller guaranteed at least 4 bytes into the buffer
function = (BacnetBvlcFunctions)buffer[1];
msgLength = (buffer[2] << 8) | (buffer[3] << 0);
if (buffer[0] != BVLL_TYPE_BACNET_IP || buffer.Length != msgLength) return -1;
switch (function)
{
case BacnetBvlcFunctions.BVLC_RESULT:
var resultCode = (buffer[4] << 8) + buffer[5];
MessageReceived?.Invoke(sender, function, (BacnetBvlcResults)resultCode, null);
return 0; // not for the upper layers
case BacnetBvlcFunctions.BVLC_ORIGINAL_UNICAST_NPDU:
return 4; // only for the upper layers
case BacnetBvlcFunctions.BVLC_ORIGINAL_BROADCAST_NPDU: // Normaly received in an IP local or global broadcast packet
// Send to FDs & BBMDs, not broadcast or it will be made twice !
if (_bbmdFdServiceActivated)
Forward_NPDU(buffer, msgLength, false, sender);
return 4; // also for the upper layers
case BacnetBvlcFunctions.BVLC_FORWARDED_NPDU: // Sent only by a BBMD, broadcast on it network, or broadcast demand by one of it's FDs
if (_bbmdFdServiceActivated && msgLength >= 10)
{
bool ret;
lock (_bbmds)
ret = _bbmds.Exists(items => items.Key.Address.Equals(sender.Address)); // verify sender (@ not Port!) presence in the table
if (ret) // message from a know BBMD address, sent to all FDs and broadcast
{
SendToFDs(buffer, msgLength); // send without modification
// Assume all BVLC_FORWARDED_NPDU are directly sent to me in the
// unicast mode and not by the way of the local broadcast address
// ie my mask must be 255.255.255.255 in the others BBMD tables
// If not, it's not really a big problem, devices on the local net will
// receive two times the message (after all it's just WhoIs, Iam, ...)
_myBbmdTransport.Send(buffer, msgLength, new IPEndPoint(IPAddress.Parse(_broadcastAdd), _myBbmdTransport.SharedPort));
}
}
return 10; // also for the upper layers
case BacnetBvlcFunctions.BVLC_DISTRIBUTE_BROADCAST_TO_NETWORK: // Sent by a Foreign Device, not a BBMD
if (_bbmdFdServiceActivated)
{
// Send to FDs except the sender, BBMDs and broadcast
lock (_foreignDevices)
{
if (_foreignDevices.Exists(item => item.Key.Equals(sender))) // verify previous registration
Forward_NPDU(buffer, msgLength, true, sender);
else
SendResult(sender, BacnetBvlcResults.BVLC_RESULT_DISTRIBUTE_BROADCAST_TO_NETWORK_NAK);
}
}
return 0; // not for the upper layers
case BacnetBvlcFunctions.BVLC_REGISTER_FOREIGN_DEVICE:
if (_bbmdFdServiceActivated && msgLength == 6)
{
var ttl = (buffer[4] << 8) + buffer[5]; // unit is second
RegisterForeignDevice(sender, ttl);
SendResult(sender, BacnetBvlcResults.BVLC_RESULT_SUCCESSFUL_COMPLETION); // ack
}
return 0; // not for the upper layers
// We don't care about Read/Write operation in the BBMD/FDR tables (who realy use it ?)
case BacnetBvlcFunctions.BVLC_READ_FOREIGN_DEVICE_TABLE:
SendResult(sender, BacnetBvlcResults.BVLC_RESULT_READ_FOREIGN_DEVICE_TABLE_NAK);
return 0;
case BacnetBvlcFunctions.BVLC_DELETE_FOREIGN_DEVICE_TABLE_ENTRY:
SendResult(sender, BacnetBvlcResults.BVLC_RESULT_DELETE_FOREIGN_DEVICE_TABLE_ENTRY_NAK);
return 0;
case BacnetBvlcFunctions.BVLC_READ_BROADCAST_DIST_TABLE:
SendResult(sender, BacnetBvlcResults.BVLC_RESULT_READ_BROADCAST_DISTRIBUTION_TABLE_NAK);
return 0;
case BacnetBvlcFunctions.BVLC_WRITE_BROADCAST_DISTRIBUTION_TABLE:
case BacnetBvlcFunctions.BVLC_READ_BROADCAST_DIST_TABLE_ACK:
{
var nbEntries = (msgLength - 4) / 10;
var entries = new List<Tuple<IPEndPoint, IPAddress>>();
for (var i = 0; i < nbEntries; i++)
{
long add = BitConverter.ToInt32(buffer, 4 + i * 10);
Array.Reverse(buffer, 8 + i * 10, 2);
var port = BitConverter.ToUInt16(buffer, 8 + i * 10);
// new IPAddress(long) with 255.255.255.255 (ie -1) not OK
var mask = new byte[4];
Array.Copy(buffer, 10 + i * 10, mask, 0, 4);
var entry = Tuple.Create(new IPEndPoint(new IPAddress(add), port), new IPAddress(mask));
entries.Add(entry);
}
if (MessageReceived != null && function == BacnetBvlcFunctions.BVLC_READ_BROADCAST_DIST_TABLE_ACK)
MessageReceived(sender, function, BacnetBvlcResults.BVLC_RESULT_SUCCESSFUL_COMPLETION, entries);
// Today we don't accept it
if (function == BacnetBvlcFunctions.BVLC_WRITE_BROADCAST_DISTRIBUTION_TABLE)
SendResult(sender, BacnetBvlcResults.BVLC_RESULT_WRITE_BROADCAST_DISTRIBUTION_TABLE_NAK);
return 0;
}
case BacnetBvlcFunctions.BVLC_READ_FOREIGN_DEVICE_TABLE_ACK:
{
var nbEntries = (msgLength - 4) / 10;
var entries = new List<Tuple<IPEndPoint, ushort, ushort>>();
for (var i = 0; i < nbEntries; i++)
{
long add = BitConverter.ToInt32(buffer, 4 + i * 10);
Array.Reverse(buffer, 8 + i * 10, 2);
var port = BitConverter.ToUInt16(buffer, 8 + i * 10);
Array.Reverse(buffer, 10 + i * 10, 2);
var ttl = BitConverter.ToUInt16(buffer, 10 + i * 10);
Array.Reverse(buffer, 12 + i * 10, 2);
var remainTtl = BitConverter.ToUInt16(buffer, 12 + i * 10);
var entry = Tuple.Create(new IPEndPoint(new IPAddress(add), port), ttl, remainTtl);
entries.Add(entry);
}
MessageReceived?.Invoke(sender, function, BacnetBvlcResults.BVLC_RESULT_SUCCESSFUL_COMPLETION, entries);
return 0;
}
// error encoding function or experimental one
default:
return -1;
}
}
}

117
addons/EGFramework/Third_Part_SourceCode/BacNetPlugin/Serialize/EncodeBuffer.cs

@ -1,117 +0,0 @@ @@ -1,117 +0,0 @@
namespace System.IO.BACnet.Serialize;
public class EncodeBuffer
{
public byte[] buffer; //buffer to serialize into
public int offset; //offset in buffer ... will go beyond max_offset (so that you may count what's needed)
public int max_offset; //don't write beyond this offset
public int serialize_counter; //used with 'min_limit'
public int min_limit; //don't write before this limit (used for segmentation)
public EncodeResult result;
public bool expandable;
public EncodeBuffer()
{
expandable = true;
buffer = new byte[128];
max_offset = buffer.Length - 1;
}
public EncodeBuffer(byte[] buffer, int offset)
{
if (buffer == null) buffer = new byte[0];
expandable = false;
this.buffer = buffer;
this.offset = offset;
max_offset = buffer.Length;
}
public void Increment()
{
if (offset < max_offset)
{
if (serialize_counter >= min_limit)
offset++;
serialize_counter++;
}
else
{
if (serialize_counter >= min_limit)
offset++;
}
}
public void Add(byte b)
{
if (offset < max_offset)
{
if (serialize_counter >= min_limit)
buffer[offset] = b;
}
else
{
if (expandable)
{
Array.Resize(ref buffer, buffer.Length * 2);
max_offset = buffer.Length - 1;
if (serialize_counter >= min_limit)
buffer[offset] = b;
}
else
result |= EncodeResult.NotEnoughBuffer;
}
Increment();
}
public void Add(byte[] buffer, int count)
{
for (var i = 0; i < count; i++)
Add(buffer[i]);
}
public int GetDiff(EncodeBuffer buffer)
{
var diff = Math.Abs(buffer.offset - offset);
diff = Math.Max(Math.Abs(buffer.serialize_counter - serialize_counter), diff);
return diff;
}
public EncodeBuffer Copy()
{
return new EncodeBuffer
{
buffer = buffer,
max_offset = max_offset,
min_limit = min_limit,
offset = offset,
result = result,
serialize_counter = serialize_counter,
expandable = expandable
};
}
public byte[] ToArray()
{
var ret = new byte[offset];
Array.Copy(buffer, 0, ret, 0, ret.Length);
return ret;
}
public void Reset(int newOffset)
{
offset = newOffset;
serialize_counter = 0;
result = EncodeResult.Good;
}
public override string ToString()
{
return offset + " - " + serialize_counter;
}
public int GetLength()
{
return Math.Min(offset, max_offset);
}
}

8
addons/EGFramework/Third_Part_SourceCode/BacNetPlugin/Serialize/EncodeResult.cs

@ -1,8 +0,0 @@ @@ -1,8 +0,0 @@
namespace System.IO.BACnet.Serialize;
[Flags]
public enum EncodeResult
{
Good = 0,
NotEnoughBuffer = 1
}

107
addons/EGFramework/Third_Part_SourceCode/BacNetPlugin/Serialize/MSTP.cs

@ -1,107 +0,0 @@ @@ -1,107 +0,0 @@
namespace System.IO.BACnet.Serialize;
public class MSTP
{
public const byte MSTP_PREAMBLE1 = 0x55;
public const byte MSTP_PREAMBLE2 = 0xFF;
public const BacnetMaxAdpu MSTP_MAX_APDU = BacnetMaxAdpu.MAX_APDU480;
public const byte MSTP_HEADER_LENGTH = 8;
public static byte CRC_Calc_Header(byte dataValue, byte crcValue)
{
var crc = (ushort)(crcValue ^ dataValue);
/* Exclusive OR the terms in the table (top down) */
crc = (ushort)(crc ^ (crc << 1) ^ (crc << 2) ^ (crc << 3) ^ (crc << 4) ^ (crc << 5) ^ (crc << 6) ^ (crc << 7));
/* Combine bits shifted out left hand end */
return (byte)((crc & 0xfe) ^ ((crc >> 8) & 1));
}
public static byte CRC_Calc_Header(byte[] buffer, int offset, int length)
{
byte crc = 0xff;
for (var i = offset; i < offset + length; i++)
crc = CRC_Calc_Header(buffer[i], crc);
return (byte)~crc;
}
public static ushort CRC_Calc_Data(byte dataValue, ushort crcValue)
{
var crcLow = (ushort)((crcValue & 0xff) ^ dataValue);
/* Exclusive OR the terms in the table (top down) */
return (ushort)((crcValue >> 8) ^ (crcLow << 8) ^ (crcLow << 3)
^ (crcLow << 12) ^ (crcLow >> 4)
^ (crcLow & 0x0f) ^ ((crcLow & 0x0f) << 7));
}
public static ushort CRC_Calc_Data(byte[] buffer, int offset, int length)
{
ushort crc = 0xffff;
for (var i = offset; i < offset + length; i++)
crc = CRC_Calc_Data(buffer[i], crc);
return (ushort)~crc;
}
public static int Encode(byte[] buffer, int offset, BacnetMstpFrameTypes frameType, byte destinationAddress, byte sourceAddress, int msgLength)
{
buffer[offset + 0] = MSTP_PREAMBLE1;
buffer[offset + 1] = MSTP_PREAMBLE2;
buffer[offset + 2] = (byte)frameType;
buffer[offset + 3] = destinationAddress;
buffer[offset + 4] = sourceAddress;
buffer[offset + 5] = (byte)((msgLength & 0xFF00) >> 8);
buffer[offset + 6] = (byte)((msgLength & 0x00FF) >> 0);
buffer[offset + 7] = CRC_Calc_Header(buffer, offset + 2, 5);
if (msgLength > 0)
{
//calculate data crc
var dataCrc = CRC_Calc_Data(buffer, offset + 8, msgLength);
buffer[offset + 8 + msgLength + 0] = (byte)(dataCrc & 0xFF); //LSB first!
buffer[offset + 8 + msgLength + 1] = (byte)(dataCrc >> 8);
}
//optional pad (0xFF)
return MSTP_HEADER_LENGTH + msgLength + (msgLength > 0 ? 2 : 0);
}
public static int Decode(byte[] buffer, int offset, int maxLength, out BacnetMstpFrameTypes frameType, out byte destinationAddress, out byte sourceAddress, out int msgLength)
{
if (maxLength < MSTP_HEADER_LENGTH) //not enough data
{
frameType = BacnetMstpFrameTypes.FRAME_TYPE_BACNET_DATA_EXPECTING_REPLY; // don't care
destinationAddress = sourceAddress = 0; // don't care
msgLength = 0;
return -1;
}
frameType = (BacnetMstpFrameTypes)buffer[offset + 2];
destinationAddress = buffer[offset + 3];
sourceAddress = buffer[offset + 4];
msgLength = (buffer[offset + 5] << 8) | (buffer[offset + 6] << 0);
var crcHeader = buffer[offset + 7];
ushort crcData = 0;
if (msgLength > 0)
{
if (offset + 8 + msgLength + 1 >= buffer.Length)
return -1;
crcData = (ushort)((buffer[offset + 8 + msgLength + 1] << 8) | (buffer[offset + 8 + msgLength + 0] << 0));
}
if (buffer[offset + 0] != MSTP_PREAMBLE1)
return -1;
if (buffer[offset + 1] != MSTP_PREAMBLE2)
return -1;
if (CRC_Calc_Header(buffer, offset + 2, 5) != crcHeader)
return -1;
if (msgLength > 0 && maxLength >= MSTP_HEADER_LENGTH + msgLength + 2 && CRC_Calc_Data(buffer, offset + 8, msgLength) != crcData)
return -1;
return 8 + msgLength + (msgLength > 0 ? 2 : 0);
}
}

134
addons/EGFramework/Third_Part_SourceCode/BacNetPlugin/Serialize/NPDU.cs

@ -1,134 +0,0 @@ @@ -1,134 +0,0 @@
namespace System.IO.BACnet.Serialize;
public class NPDU
{
public const byte BACNET_PROTOCOL_VERSION = 1;
public static BacnetNpduControls DecodeFunction(byte[] buffer, int offset)
{
if (buffer[offset + 0] != BACNET_PROTOCOL_VERSION) return 0;
return (BacnetNpduControls)buffer[offset + 1];
}
public static int Decode(byte[] buffer, int offset, out BacnetNpduControls function, out BacnetAddress destination,
out BacnetAddress source, out byte hopCount, out BacnetNetworkMessageTypes networkMsgType, out ushort vendorId)
{
var orgOffset = offset;
offset++;
function = (BacnetNpduControls)buffer[offset++];
destination = null;
if ((function & BacnetNpduControls.DestinationSpecified) == BacnetNpduControls.DestinationSpecified)
{
destination = new BacnetAddress(BacnetAddressTypes.None, (ushort)((buffer[offset++] << 8) | (buffer[offset++] << 0)), null);
int adrLen = buffer[offset++];
if (adrLen > 0)
{
destination.adr = new byte[adrLen];
for (var i = 0; i < destination.adr.Length; i++)
destination.adr[i] = buffer[offset++];
}
}
source = null;
if ((function & BacnetNpduControls.SourceSpecified) == BacnetNpduControls.SourceSpecified)
{
source = new BacnetAddress(BacnetAddressTypes.None, (ushort)((buffer[offset++] << 8) | (buffer[offset++] << 0)), null);
int adrLen = buffer[offset++];
if (adrLen > 0)
{
source.adr = new byte[adrLen];
for (var i = 0; i < source.adr.Length; i++)
source.adr[i] = buffer[offset++];
}
}
hopCount = 0;
if ((function & BacnetNpduControls.DestinationSpecified) == BacnetNpduControls.DestinationSpecified)
{
hopCount = buffer[offset++];
}
networkMsgType = BacnetNetworkMessageTypes.NETWORK_MESSAGE_WHO_IS_ROUTER_TO_NETWORK;
vendorId = 0;
if (function.HasFlag(BacnetNpduControls.NetworkLayerMessage))
{
networkMsgType = (BacnetNetworkMessageTypes)buffer[offset++];
if ((byte)networkMsgType >= 0x80)
{
vendorId = (ushort)((buffer[offset++] << 8) | (buffer[offset++] << 0));
}
//DAL - this originally made no sense as the higher level code would just ignore network messages
// else if (networkMsgType == BacnetNetworkMessageTypes.NETWORK_MESSAGE_WHO_IS_ROUTER_TO_NETWORK)
// offset += 2; // Don't care about destination network adress
}
if (buffer[orgOffset + 0] != BACNET_PROTOCOL_VERSION)
return -1;
return offset - orgOffset;
}
public static void Encode(EncodeBuffer buffer, BacnetNpduControls function, BacnetAddress destination,
BacnetAddress source, byte hopCount, BacnetNetworkMessageTypes networkMsgType, ushort vendorId)
{
Encode(buffer, function, destination, source, hopCount);
if (function.HasFlag(BacnetNpduControls.NetworkLayerMessage)) // sure it is, otherwise the other Encode is used
{
buffer.buffer[buffer.offset++] = (byte)networkMsgType;
if ((byte)networkMsgType >= 0x80) // who used this ??? sure nobody !
{
buffer.buffer[buffer.offset++] = (byte)((vendorId & 0xFF00) >> 8);
buffer.buffer[buffer.offset++] = (byte)((vendorId & 0x00FF) >> 0);
}
}
}
public static void Encode(EncodeBuffer buffer, BacnetNpduControls function, BacnetAddress destination,
BacnetAddress source = null, byte hopCount = 0xFF)
{
// Modif FC
var hasDestination = destination != null && destination.net > 0; // && destination.net != 0xFFFF;
var hasSource = source != null && source.net > 0 && source.net != 0xFFFF;
buffer.buffer[buffer.offset++] = BACNET_PROTOCOL_VERSION;
buffer.buffer[buffer.offset++] = (byte)(function | (hasDestination ? BacnetNpduControls.DestinationSpecified : 0) | (hasSource ? BacnetNpduControls.SourceSpecified : 0));
if (hasDestination)
{
buffer.buffer[buffer.offset++] = (byte)((destination.net & 0xFF00) >> 8);
buffer.buffer[buffer.offset++] = (byte)((destination.net & 0x00FF) >> 0);
if (destination.net == 0xFFFF) //patch by F. Chaxel
buffer.buffer[buffer.offset++] = 0;
else
{
buffer.buffer[buffer.offset++] = (byte)destination.adr.Length;
if (destination.adr.Length > 0)
{
foreach (var t in destination.adr)
buffer.buffer[buffer.offset++] = t;
}
}
}
if (hasSource)
{
buffer.buffer[buffer.offset++] = (byte)((source.net & 0xFF00) >> 8);
buffer.buffer[buffer.offset++] = (byte)((source.net & 0x00FF) >> 0);
buffer.buffer[buffer.offset++] = (byte)source.adr.Length;
if (source.adr.Length > 0)
{
foreach (var t in source.adr)
buffer.buffer[buffer.offset++] = t;
}
}
if (hasDestination)
{
buffer.buffer[buffer.offset++] = hopCount;
}
}
}

67
addons/EGFramework/Third_Part_SourceCode/BacNetPlugin/Serialize/PTP.cs

@ -1,67 +0,0 @@ @@ -1,67 +0,0 @@
namespace System.IO.BACnet.Serialize;
public class PTP
{
public const byte PTP_PREAMBLE1 = 0x55;
public const byte PTP_PREAMBLE2 = 0xFF;
public const byte PTP_GREETING_PREAMBLE1 = 0x42;
public const byte PTP_GREETING_PREAMBLE2 = 0x41;
public const BacnetMaxAdpu PTP_MAX_APDU = BacnetMaxAdpu.MAX_APDU480;
public const byte PTP_HEADER_LENGTH = 6;
public static int Encode(byte[] buffer, int offset, BacnetPtpFrameTypes frameType, int msgLength)
{
buffer[offset + 0] = PTP_PREAMBLE1;
buffer[offset + 1] = PTP_PREAMBLE2;
buffer[offset + 2] = (byte)frameType;
buffer[offset + 3] = (byte)((msgLength & 0xFF00) >> 8);
buffer[offset + 4] = (byte)((msgLength & 0x00FF) >> 0);
buffer[offset + 5] = MSTP.CRC_Calc_Header(buffer, offset + 2, 3);
if (msgLength > 0)
{
//calculate data crc
var dataCrc = MSTP.CRC_Calc_Data(buffer, offset + 6, msgLength);
buffer[offset + 6 + msgLength + 0] = (byte)(dataCrc & 0xFF); //LSB first!
buffer[offset + 6 + msgLength + 1] = (byte)(dataCrc >> 8);
}
return PTP_HEADER_LENGTH + msgLength + (msgLength > 0 ? 2 : 0);
}
public static int Decode(byte[] buffer, int offset, int maxLength, out BacnetPtpFrameTypes frameType, out int msgLength)
{
if (maxLength < PTP_HEADER_LENGTH) // not enough data
{
frameType = BacnetPtpFrameTypes.FRAME_TYPE_CONNECT_REQUEST; // don't care
msgLength = 0;
return -1; //not enough data
}
frameType = (BacnetPtpFrameTypes)buffer[offset + 2];
msgLength = (buffer[offset + 3] << 8) | (buffer[offset + 4] << 0);
var crcHeader = buffer[offset + 5];
ushort crcData = 0;
if (msgLength > 0)
{
if (offset + 6 + msgLength + 1 >= buffer.Length)
return -1;
crcData = (ushort)((buffer[offset + 6 + msgLength + 1] << 8) | (buffer[offset + 6 + msgLength + 0] << 0));
}
if (buffer[offset + 0] != PTP_PREAMBLE1)
return -1;
if (buffer[offset + 1] != PTP_PREAMBLE2)
return -1;
if (MSTP.CRC_Calc_Header(buffer, offset + 2, 3) != crcHeader)
return -1;
if (msgLength > 0 && maxLength >= PTP_HEADER_LENGTH + msgLength + 2 && MSTP.CRC_Calc_Data(buffer, offset + 6, msgLength) != crcData)
return -1;
return 8 + msgLength + (msgLength > 0 ? 2 : 0);
}
}

2664
addons/EGFramework/Third_Part_SourceCode/BacNetPlugin/Serialize/Services.cs

File diff suppressed because it is too large Load Diff

459
addons/EGFramework/Third_Part_SourceCode/BacNetPlugin/Storage/DeviceStorage.cs

@ -1,459 +0,0 @@ @@ -1,459 +0,0 @@
/**************************************************************************
* MIT License
*
* Copyright (C) 2014 Morten Kvistgaard <mk@pch-engineering.dk>
*
* Permission is hereby granted, free of charge, to any person obtaining
* a copy of this software and associated documentation files (the
* "Software"), to deal in the Software without restriction, including
* without limitation the rights to use, copy, modify, merge, publish,
* distribute, sublicense, and/or sell copies of the Software, and to
* permit persons to whom the Software is furnished to do so, subject to
* the following conditions:
*
* The above copyright notice and this permission notice shall be included
* in all copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
* IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
* CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
*
*********************************************************************/
namespace System.IO.BACnet.Storage;
/// <summary>
/// This is a basic example of a BACNet storage. This one is XML based. It has no fancy optimizing or anything.
/// </summary>
[Serializable]
public class DeviceStorage
{
[XmlIgnore]
public uint DeviceId { get; set; }
public delegate void ChangeOfValueHandler(DeviceStorage sender, BacnetObjectId objectId, BacnetPropertyIds propertyId, uint arrayIndex, IList<BacnetValue> value);
public event ChangeOfValueHandler ChangeOfValue;
public delegate void ReadOverrideHandler(BacnetObjectId objectId, BacnetPropertyIds propertyId, uint arrayIndex, out IList<BacnetValue> value, out ErrorCodes status, out bool handled);
public event ReadOverrideHandler ReadOverride;
public delegate void WriteOverrideHandler(BacnetObjectId objectId, BacnetPropertyIds propertyId, uint arrayIndex, IList<BacnetValue> value, out ErrorCodes status, out bool handled);
public event WriteOverrideHandler WriteOverride;
public Object[] Objects { get; set; }
public DeviceStorage()
{
DeviceId = (uint)new Random().Next();
Objects = new Object[0];
}
public Property FindProperty(BacnetObjectId objectId, BacnetPropertyIds propertyId)
{
//liniear search
var obj = FindObject(objectId);
return FindProperty(obj, propertyId);
}
private static Property FindProperty(Object obj, BacnetPropertyIds propertyId)
{
//liniear search
return obj?.Properties.FirstOrDefault(p => p.Id == propertyId);
}
private Object FindObject(BacnetObjectTypes objectType)
{
//liniear search
return Objects.FirstOrDefault(obj => obj.Type == objectType);
}
public Object FindObject(BacnetObjectId objectId)
{
//liniear search
return Objects.FirstOrDefault(obj => obj.Type == objectId.type && obj.Instance == objectId.instance);
}
public enum ErrorCodes
{
Good = 0,
GenericError = -1,
NotExist = -2,
NotForMe = -3,
WriteAccessDenied = -4,
UnknownObject = -5,
UnknownProperty = -6
}
public int ReadPropertyValue(BacnetObjectId objectId, BacnetPropertyIds propertyId)
{
if (ReadProperty(objectId, propertyId, Serialize.ASN1.BACNET_ARRAY_ALL, out IList<BacnetValue> value) != ErrorCodes.Good)
return 0;
if (value == null || value.Count < 1)
return 0;
return (int)Convert.ChangeType(value[0].Value, typeof(int));
}
public ErrorCodes ReadProperty(BacnetObjectId objectId, BacnetPropertyIds propertyId, uint arrayIndex, out IList<BacnetValue> value)
{
value = new BacnetValue[0];
//wildcard device_id
if (objectId.type == BacnetObjectTypes.OBJECT_DEVICE && objectId.instance >= Serialize.ASN1.BACNET_MAX_INSTANCE)
objectId.instance = DeviceId;
//overrides
if (ReadOverride != null)
{
ReadOverride(objectId, propertyId, arrayIndex, out value, out ErrorCodes status, out bool handled);
if (handled)
return status;
}
//find in storage
var obj = FindObject(objectId);
if (obj == null)
return ErrorCodes.UnknownObject;
//object found now find property
Godot.GD.Print("object "+objectId+"|property "+propertyId);
var p = FindProperty(objectId, propertyId);
if (p == null)
return ErrorCodes.NotExist;
//get value ... check for array index
if (arrayIndex == 0)
{
value = new[] { new BacnetValue(BacnetApplicationTags.BACNET_APPLICATION_TAG_UNSIGNED_INT, (uint)p.BacnetValue.Count) };
}
else if (arrayIndex != Serialize.ASN1.BACNET_ARRAY_ALL)
{
value = new[] { p.BacnetValue[(int)arrayIndex - 1] };
}
else
{
value = p.BacnetValue;
}
Godot.GD.Print("p "+p.BacnetValue.Count());
return ErrorCodes.Good;
}
public void ReadPropertyMultiple(BacnetObjectId objectId, ICollection<BacnetPropertyReference> properties, out IList<BacnetPropertyValue> values)
{
var valuesRet = new List<BacnetPropertyValue>();
foreach (var entry in properties)
{
var newEntry = new BacnetPropertyValue { property = entry };
switch (ReadProperty(objectId, (BacnetPropertyIds)entry.propertyIdentifier, entry.propertyArrayIndex, out newEntry.value))
{
case ErrorCodes.UnknownObject:
newEntry.value = new[]
{
new BacnetValue(BacnetApplicationTags.BACNET_APPLICATION_TAG_ERROR,
new BacnetError(BacnetErrorClasses.ERROR_CLASS_OBJECT, BacnetErrorCodes.ERROR_CODE_UNKNOWN_OBJECT))
};
break;
case ErrorCodes.NotExist:
newEntry.value = new[]
{
new BacnetValue(BacnetApplicationTags.BACNET_APPLICATION_TAG_ERROR,
new BacnetError(BacnetErrorClasses.ERROR_CLASS_PROPERTY, BacnetErrorCodes.ERROR_CODE_UNKNOWN_PROPERTY))
};
break;
}
valuesRet.Add(newEntry);
}
values = valuesRet;
}
public bool ReadPropertyAll(BacnetObjectId objectId, out IList<BacnetPropertyValue> values)
{
//find
var obj = FindObject(objectId);
if (obj == null)
{
values = null;
return false;
}
//build
var propertyValues = new BacnetPropertyValue[obj.Properties.Length];
for (var i = 0; i < obj.Properties.Length; i++)
{
var newEntry = new BacnetPropertyValue
{
property = new BacnetPropertyReference((uint)obj.Properties[i].Id, Serialize.ASN1.BACNET_ARRAY_ALL)
};
if (ReadProperty(objectId, obj.Properties[i].Id, Serialize.ASN1.BACNET_ARRAY_ALL, out newEntry.value) != ErrorCodes.Good)
{
var bacnetError = new BacnetError(BacnetErrorClasses.ERROR_CLASS_OBJECT, BacnetErrorCodes.ERROR_CODE_UNKNOWN_PROPERTY);
newEntry.value = new[] { new BacnetValue(BacnetApplicationTags.BACNET_APPLICATION_TAG_ERROR, bacnetError) };
}
propertyValues[i] = newEntry;
}
values = propertyValues;
return true;
}
public void WritePropertyValue(BacnetObjectId objectId, BacnetPropertyIds propertyId, int value)
{
//get existing type
if (ReadProperty(objectId, propertyId, Serialize.ASN1.BACNET_ARRAY_ALL, out IList<BacnetValue> readValues) != ErrorCodes.Good)
return;
if (readValues == null || readValues.Count == 0)
return;
//write
WriteProperty(objectId, propertyId, Serialize.ASN1.BACNET_ARRAY_ALL, new[]
{
new BacnetValue(readValues[0].Tag, Convert.ChangeType(value, readValues[0].Value.GetType()))
});
}
public void WriteProperty(BacnetObjectId objectId, BacnetPropertyIds propertyId, BacnetValue value)
{
WriteProperty(objectId, propertyId, Serialize.ASN1.BACNET_ARRAY_ALL, new[] { value });
}
public ErrorCodes WriteProperty(BacnetObjectId objectId, BacnetPropertyIds propertyId, uint arrayIndex, IList<BacnetValue> value, bool addIfNotExits = false)
{
//wildcard device_id
if (objectId.type == BacnetObjectTypes.OBJECT_DEVICE && objectId.instance >= Serialize.ASN1.BACNET_MAX_INSTANCE)
objectId.instance = DeviceId;
//overrides
if (WriteOverride != null)
{
WriteOverride(objectId, propertyId, arrayIndex, value, out ErrorCodes status, out bool handled);
if (handled)
return status;
}
//find
var p = FindProperty(objectId, propertyId);
if (p == null)
{
if (!addIfNotExits) return ErrorCodes.NotExist;
//add obj
var obj = FindObject(objectId);
if (obj == null)
{
obj = new Object
{
Type = objectId.type,
Instance = objectId.instance
};
var arr = Objects;
Array.Resize(ref arr, arr.Length + 1);
arr[arr.Length - 1] = obj;
Objects = arr;
}
//add property
p = new Property { Id = propertyId };
var props = obj.Properties;
Array.Resize(ref props, props.Length + 1);
props[props.Length - 1] = p;
obj.Properties = props;
}
//set type if needed
if (p.Tag == BacnetApplicationTags.BACNET_APPLICATION_TAG_NULL && value != null)
{
foreach (var v in value)
{
if (v.Tag == BacnetApplicationTags.BACNET_APPLICATION_TAG_NULL)
continue;
p.Tag = v.Tag;
break;
}
}
//write
p.BacnetValue = value;
//send event ... for subscriptions
ChangeOfValue?.Invoke(this, objectId, propertyId, arrayIndex, value);
return ErrorCodes.Good;
}
// Write PROP_PRESENT_VALUE or PROP_RELINQUISH_DEFAULT in an object with a 16 level PROP_PRIORITY_ARRAY (BACNET_APPLICATION_TAG_NULL)
public ErrorCodes WriteCommandableProperty(BacnetObjectId objectId, BacnetPropertyIds propertyId, BacnetValue value, uint priority)
{
if (propertyId != BacnetPropertyIds.PROP_PRESENT_VALUE)
return ErrorCodes.NotForMe;
var presentvalue = FindProperty(objectId, BacnetPropertyIds.PROP_PRESENT_VALUE);
if (presentvalue == null)
return ErrorCodes.NotForMe;
var relinquish = FindProperty(objectId, BacnetPropertyIds.PROP_RELINQUISH_DEFAULT);
if (relinquish == null)
return ErrorCodes.NotForMe;
var outOfService = FindProperty(objectId, BacnetPropertyIds.PROP_OUT_OF_SERVICE);
if (outOfService == null)
return ErrorCodes.NotForMe;
var array = FindProperty(objectId, BacnetPropertyIds.PROP_PRIORITY_ARRAY);
if (array == null)
return ErrorCodes.NotForMe;
var errorcode = ErrorCodes.GenericError;
try
{
// If PROP_OUT_OF_SERVICE=True, value is accepted as is : http://www.bacnetwiki.com/wiki/index.php?title=Priority_Array
if ((bool)outOfService.BacnetValue[0].Value && propertyId == BacnetPropertyIds.PROP_PRESENT_VALUE)
{
WriteProperty(objectId, BacnetPropertyIds.PROP_PRESENT_VALUE, value);
return ErrorCodes.Good;
}
IList<BacnetValue> valueArray = null;
// Thank's to Steve Karg
// The 135-2016 text:
// 19.2.2 Application Priority Assignments
// All commandable objects within a device shall be configurable to accept writes to all priorities except priority 6
if (priority == 6)
return ErrorCodes.WriteAccessDenied;
// http://www.chipkin.com/changing-the-bacnet-present-value-or-why-the-present-value-doesn%E2%80%99t-change/
// Write Property PROP_PRESENT_VALUE : A value is placed in the PROP_PRIORITY_ARRAY
if (propertyId == BacnetPropertyIds.PROP_PRESENT_VALUE)
{
errorcode = ErrorCodes.Good;
valueArray = array.BacnetValue;
if (value.Value == null)
valueArray[(int)priority - 1] = new BacnetValue(null);
else
valueArray[(int)priority - 1] = value;
array.BacnetValue = valueArray;
}
// Look on the priority Array to find the first value to be set in PROP_PRESENT_VALUE
if (errorcode == ErrorCodes.Good)
{
var done = false;
for (var i = 0; i < 16; i++)
{
if (valueArray[i].Value == null)
continue;
WriteProperty(objectId, BacnetPropertyIds.PROP_PRESENT_VALUE, valueArray[i]);
done = true;
break;
}
if (done == false) // Nothing in the array : PROP_PRESENT_VALUE = PROP_RELINQUISH_DEFAULT
{
var defaultValue = relinquish.BacnetValue;
WriteProperty(objectId, BacnetPropertyIds.PROP_PRESENT_VALUE, defaultValue[0]);
}
}
}
catch
{
errorcode = ErrorCodes.GenericError;
}
return errorcode;
}
public ErrorCodes[] WritePropertyMultiple(BacnetObjectId objectId, ICollection<BacnetPropertyValue> values)
{
return values
.Select(v => WriteProperty(objectId, (BacnetPropertyIds)v.property.propertyIdentifier, v.property.propertyArrayIndex, v.value))
.ToArray();
}
/// <summary>
/// Store the class, as XML file
/// </summary>
/// <param name="path"></param>
public void Save(string path)
{
var s = new XmlSerializer(typeof(DeviceStorage));
using var fs = new FileStream(path, FileMode.Create, FileAccess.Write);
s.Serialize(fs, this);
}
/// <summary>
/// Load XML values into class
/// </summary>
/// <param name="path">Embedded or external file</param>
/// <param name="deviceId">Optional deviceId other than the one in the Xml file</param>
/// <returns></returns>
public static DeviceStorage Load(string path, uint? deviceId = null)
{
StreamReader textStreamReader;
var assembly = Assembly.GetCallingAssembly();
try
{
// check if the xml file is an embedded resource
textStreamReader = new StreamReader(assembly.GetManifestResourceStream(path));
}
catch
{
// if not check the external file
if (!File.Exists(path))
throw new Exception("No AppSettings found");
textStreamReader = new StreamReader(path);
}
var s = new XmlSerializer(typeof(DeviceStorage));
using (textStreamReader)
{
var ret = (DeviceStorage)s.Deserialize(textStreamReader);
//set device_id
var obj = ret.FindObject(BacnetObjectTypes.OBJECT_DEVICE);
if (obj != null)
ret.DeviceId = obj.Instance;
// use the deviceId in the Xml file or another one
if (!deviceId.HasValue)
return ret;
ret.DeviceId = deviceId.Value;
if (obj == null)
return ret;
// change the value
obj.Instance = deviceId.Value;
IList<BacnetValue> val = new[]
{
new BacnetValue(BacnetApplicationTags.BACNET_APPLICATION_TAG_OBJECT_ID, $"OBJECT_DEVICE:{deviceId.Value}")
};
ret.WriteProperty(new BacnetObjectId(BacnetObjectTypes.OBJECT_DEVICE,
Serialize.ASN1.BACNET_MAX_INSTANCE), BacnetPropertyIds.PROP_OBJECT_IDENTIFIER, 1, val, true);
return ret;
}
}
}

18
addons/EGFramework/Third_Part_SourceCode/BacNetPlugin/Storage/Object.cs

@ -1,18 +0,0 @@ @@ -1,18 +0,0 @@
namespace System.IO.BACnet.Storage;
[Serializable]
public class Object
{
[XmlAttribute]
public BacnetObjectTypes Type { get; set; }
[XmlAttribute]
public uint Instance { get; set; }
public Property[] Properties { get; set; }
public Object()
{
Properties = new Property[0];
}
}

127
addons/EGFramework/Third_Part_SourceCode/BacNetPlugin/Storage/Property.cs

@ -1,127 +0,0 @@ @@ -1,127 +0,0 @@
namespace System.IO.BACnet.Storage;
[Serializable]
public class Property
{
[XmlIgnore]
public BacnetPropertyIds Id { get; set; }
[XmlAttribute("Id")]
public string IdText
{
get
{
return Id.ToString();
}
set
{
Id = (BacnetPropertyIds)Enum.Parse(typeof(BacnetPropertyIds), value);
}
}
[XmlAttribute]
public BacnetApplicationTags Tag { get; set; }
[XmlElement]
public string[] Value { get; set; }
public static BacnetValue DeserializeValue(string value, BacnetApplicationTags type)
{
switch (type)
{
case BacnetApplicationTags.BACNET_APPLICATION_TAG_NULL:
return value == ""
? new BacnetValue(type, null)
: new BacnetValue(value);
case BacnetApplicationTags.BACNET_APPLICATION_TAG_BOOLEAN:
return new BacnetValue(type, bool.Parse(value));
case BacnetApplicationTags.BACNET_APPLICATION_TAG_UNSIGNED_INT:
return new BacnetValue(type, uint.Parse(value));
case BacnetApplicationTags.BACNET_APPLICATION_TAG_SIGNED_INT:
return new BacnetValue(type, int.Parse(value));
case BacnetApplicationTags.BACNET_APPLICATION_TAG_REAL:
return new BacnetValue(type, float.Parse(value, CultureInfo.InvariantCulture));
case BacnetApplicationTags.BACNET_APPLICATION_TAG_DOUBLE:
return new BacnetValue(type, double.Parse(value, CultureInfo.InvariantCulture));
case BacnetApplicationTags.BACNET_APPLICATION_TAG_OCTET_STRING:
try
{
return new BacnetValue(type, Convert.FromBase64String(value));
}
catch
{
return new BacnetValue(type, value);
}
case BacnetApplicationTags.BACNET_APPLICATION_TAG_CONTEXT_SPECIFIC_DECODED:
try
{
return new BacnetValue(type, Convert.FromBase64String(value));
}
catch
{
return new BacnetValue(type, value);
}
case BacnetApplicationTags.BACNET_APPLICATION_TAG_CHARACTER_STRING:
return new BacnetValue(type, value);
case BacnetApplicationTags.BACNET_APPLICATION_TAG_BIT_STRING:
return new BacnetValue(type, BacnetBitString.Parse(value));
case BacnetApplicationTags.BACNET_APPLICATION_TAG_ENUMERATED:
return new BacnetValue(type, uint.Parse(value));
case BacnetApplicationTags.BACNET_APPLICATION_TAG_DATE:
return new BacnetValue(type, DateTime.Parse(value));
case BacnetApplicationTags.BACNET_APPLICATION_TAG_TIME:
return new BacnetValue(type, DateTime.Parse(value));
case BacnetApplicationTags.BACNET_APPLICATION_TAG_OBJECT_ID:
return new BacnetValue(type, BacnetObjectId.Parse(value));
case BacnetApplicationTags.BACNET_APPLICATION_TAG_READ_ACCESS_SPECIFICATION:
return new BacnetValue(type, BacnetReadAccessSpecification.Parse(value));
case BacnetApplicationTags.BACNET_APPLICATION_TAG_OBJECT_PROPERTY_REFERENCE:
return new BacnetValue(type, BacnetDeviceObjectPropertyReference.Parse(value));
default:
return new BacnetValue(type, null);
}
}
public static string SerializeValue(BacnetValue value, BacnetApplicationTags type)
{
switch (type)
{
case BacnetApplicationTags.BACNET_APPLICATION_TAG_NULL:
return value.ToString(); // Modif FC
case BacnetApplicationTags.BACNET_APPLICATION_TAG_REAL:
return ((float)value.Value).ToString(CultureInfo.InvariantCulture);
case BacnetApplicationTags.BACNET_APPLICATION_TAG_DOUBLE:
return ((double)value.Value).ToString(CultureInfo.InvariantCulture);
case BacnetApplicationTags.BACNET_APPLICATION_TAG_OCTET_STRING:
return Convert.ToBase64String((byte[])value.Value);
case BacnetApplicationTags.BACNET_APPLICATION_TAG_CONTEXT_SPECIFIC_DECODED:
{
return value.Value is byte[]? Convert.ToBase64String((byte[])value.Value)
: string.Join(";", ((BacnetValue[])value.Value)
.Select(v => SerializeValue(v, v.Tag)));
}
default:
return value.Value.ToString();
}
}
[XmlIgnore]
public IList<BacnetValue> BacnetValue
{
get
{
if (Value == null)
return new BacnetValue[0];
var ret = new BacnetValue[Value.Length];
for (var i = 0; i < ret.Length; i++)
ret[i] = DeserializeValue(Value[i], Tag);
return ret;
}
set
{
Value = value.Select(v => SerializeValue(v, Tag)).ToArray();
}
}
}

351
addons/EGFramework/Third_Part_SourceCode/BacNetPlugin/Transport/BVLCV6.cs

@ -1,351 +0,0 @@ @@ -1,351 +0,0 @@
namespace System.IO.BACnet;
// Only some elements here are really tested
// all FDR, BBMD activities is just a copy/adaptation of my IPv4 code
// Code for V4 working fine, for V6 sure not before a series of tests
public class BVLCV6
{
public const byte BVLL_TYPE_BACNET_IPV6 = 0x82;
public const byte BVLC_HEADER_LENGTH = 10; // Not all the time, could be 7 for bacnet broadcast
public const BacnetMaxAdpu BVLC_MAX_APDU = BacnetMaxAdpu.MAX_APDU1476;
// Contains the rules to accept FRD based on the IP adress
// If empty it's equal to * , everyone allows
private readonly List<Regex> _autorizedFDR = new();
private bool _bbmdFdServiceActivated;
private readonly List<IPEndPoint> _bbmds = new();
private readonly BacnetAddress _broadcastAdd;
// Two lists for optional BBMD activity
private readonly List<KeyValuePair<IPEndPoint, DateTime>> _foreignDevices = new();
private readonly BacnetIpV6UdpProtocolTransport _myTransport;
public bool RandomVmac;
public byte[] VMAC = new byte[3];
public ILog Log { get; set; } = LogManager.GetLogger<BVLCV6>();
public BVLCV6(BacnetIpV6UdpProtocolTransport transport, int vMac)
{
_myTransport = transport;
_broadcastAdd = _myTransport.GetBroadcastAddress();
if (vMac == -1)
{
RandomVmac = true;
new Random().NextBytes(VMAC);
VMAC[0] = (byte)((VMAC[0] & 0x7F) | 0x40); // ensure 01xxxxxx on the High byte
// Open with default interface specified, cannot send it or
// it will generate an uncheckable continuous local loopback
if (!_myTransport.LocalEndPoint.ToString().Contains("[::]"))
SendAddressResolutionRequest(VMAC);
else
RandomVmac = false; // back to false avoiding loop back
}
else // Device Id is the Vmac Id
{
VMAC[0] = (byte)((vMac >> 16) & 0x3F); // ensure the 2 high bits are 0 on the High byte
VMAC[1] = (byte)((vMac >> 8) & 0xFF);
VMAC[2] = (byte)(vMac & 0xFF);
// unicity is guaranteed by the end user !
}
}
public void AddFDRAutorisationRule(Regex ipRule)
{
_autorizedFDR.Add(ipRule);
}
// Used to initiate the BBMD & FD behaviour, if BBMD is null it start the FD activity only
public void AddBBMDPeer(IPEndPoint bbmd)
{
_bbmdFdServiceActivated = true;
if (bbmd == null)
return;
lock (_bbmds)
_bbmds.Add(bbmd);
}
// Add a FD to the table or renew it
private void RegisterForeignDevice(IPEndPoint sender, int ttl)
{
lock (_foreignDevices)
{
// remove it, if any
_foreignDevices.Remove(_foreignDevices.Find(item => item.Key.Equals(sender)));
// TTL + 30s grace period
var Expiration = DateTime.Now.AddSeconds(ttl + 30);
// add it
if (_autorizedFDR.Count == 0) // No rules, accept all
{
_foreignDevices.Add(new KeyValuePair<IPEndPoint, DateTime>(sender, Expiration));
return;
}
if (_autorizedFDR.Any(r => r.Match(sender.Address.ToString()).Success))
{
_foreignDevices.Add(new KeyValuePair<IPEndPoint, DateTime>(sender, Expiration));
return;
}
Log.Info($"Rejected FDR registration, IP : {sender.Address}");
}
}
// Send a Frame to each registered foreign devices, except the original sender
private void SendToFDs(byte[] buffer, int msgLength, IPEndPoint epSender = null)
{
lock (_foreignDevices)
{
// remove oldest Device entries (Time expiration > TTL + 30s delay)
_foreignDevices.Remove(_foreignDevices.Find(item => DateTime.Now > item.Value));
// Send to all others, except the original sender
foreach (var client in _foreignDevices)
{
if (!client.Key.Equals(epSender))
_myTransport.Send(buffer, msgLength, client.Key);
}
}
}
// Send a Frame to each registered BBMD
private void SendToBBMDs(byte[] buffer, int msgLength)
{
lock (_bbmds)
{
foreach (var ep in _bbmds)
{
_myTransport.Send(buffer, msgLength, ep);
}
}
}
// Never tested
private void Forward_NPDU(byte[] buffer, int msgLength, bool toGlobalBroadcast, IPEndPoint epSender, BacnetAddress bacSender)
{
// Forms the forwarded NPDU from the original (broadcast npdu), and send it to all
// copy, 18 bytes shifted (orignal bvlc header : 7 bytes, new one : 25 bytes)
var b = new byte[msgLength + 18];
// normaly only 'small' frames are present here, so no need to check if it's to big for Udp
Array.Copy(buffer, 0, b, 18, msgLength);
// 7 bytes for the BVLC Header, with the embedded 6 bytes IP:Port of the original sender
First7BytesHeaderEncode(b, BacnetBvlcV6Functions.BVLC_FORWARDED_NPDU, msgLength + 18);
// replace my Vmac by the orignal source vMac
Array.Copy(bacSender.VMac, 0, b, 4, 3);
// Add IpV6 endpoint
Array.Copy(bacSender.adr, 0, b, 7, 18);
// Send To BBMD
SendToBBMDs(b, msgLength + 18);
// Send To FD, except the sender
SendToFDs(b, msgLength + 18, epSender);
// Broadcast if required
if (toGlobalBroadcast)
{
BacnetIpV6UdpProtocolTransport.Convert(_broadcastAdd, out IPEndPoint ep);
_myTransport.Send(b, msgLength + 18, ep);
}
}
private void First7BytesHeaderEncode(byte[] b, BacnetBvlcV6Functions function, int msgLength)
{
b[0] = BVLL_TYPE_BACNET_IPV6;
b[1] = (byte)function;
b[2] = (byte)((msgLength & 0xFF00) >> 8);
b[3] = (byte)((msgLength & 0x00FF) >> 0);
Array.Copy(VMAC, 0, b, 4, 3);
}
// Send ack or nack
private void SendResult(IPEndPoint sender, BacnetBvlcV6Results resultCode)
{
var b = new byte[9];
First7BytesHeaderEncode(b, BacnetBvlcV6Functions.BVLC_RESULT, 9);
b[7] = (byte)(((ushort)resultCode & 0xFF00) >> 8);
b[8] = (byte)((ushort)resultCode & 0xFF);
_myTransport.Send(b, 9, sender);
}
public void SendRegisterAsForeignDevice(IPEndPoint bbmd, short ttl)
{
var b = new byte[9];
First7BytesHeaderEncode(b, BacnetBvlcV6Functions.BVLC_REGISTER_FOREIGN_DEVICE, 9);
b[7] = (byte)((ttl & 0xFF00) >> 8);
b[8] = (byte)(ttl & 0xFF);
_myTransport.Send(b, 9, bbmd);
}
public void SendRemoteWhois(byte[] buffer, IPEndPoint bbmd, int msgLength)
{
// 7 bytes for the BVLC Header
First7BytesHeaderEncode(buffer, BacnetBvlcV6Functions.BVLC_DISTRIBUTE_BROADCAST_TO_NETWORK, msgLength);
_myTransport.Send(buffer, msgLength, bbmd);
}
// Send ack
private void SendAddressResolutionAck(IPEndPoint sender, byte[] vMacDest, BacnetBvlcV6Functions function)
{
var b = new byte[10];
First7BytesHeaderEncode(b, function, 10);
Array.Copy(vMacDest, 0, b, 7, 3);
_myTransport.Send(b, 10, sender);
}
// quite the same frame as the previous one
private void SendAddressResolutionRequest(byte[] vMacDest)
{
BacnetIpV6UdpProtocolTransport.Convert(_broadcastAdd, out IPEndPoint ep);
var b = new byte[10];
First7BytesHeaderEncode(b, BacnetBvlcV6Functions.BVLC_ADDRESS_RESOLUTION, 10);
Array.Copy(vMacDest, 0, b, 7, 3);
_myTransport.Send(b, 10, ep);
}
// Encode is called by internal services if the BBMD is also an active device
public int Encode(byte[] buffer, int offset, BacnetBvlcV6Functions function, int msgLength, BacnetAddress address)
{
// offset always 0, we are the first after udp
First7BytesHeaderEncode(buffer, function, msgLength);
// BBMD service
if (function == BacnetBvlcV6Functions.BVLC_ORIGINAL_BROADCAST_NPDU && _bbmdFdServiceActivated)
{
var me = _myTransport.LocalEndPoint;
BacnetIpV6UdpProtocolTransport.Convert(me, out var bacme);
Array.Copy(VMAC, bacme.VMac, 3);
Forward_NPDU(buffer, msgLength, false, me, bacme); // send to all BBMDs and FDs
return 7; // ready to send
}
if (function != BacnetBvlcV6Functions.BVLC_ORIGINAL_UNICAST_NPDU)
return 0; // ?
buffer[7] = address.VMac[0];
buffer[8] = address.VMac[1];
buffer[9] = address.VMac[2];
return 10; // ready to send
}
// Decode is called each time an Udp Frame is received
public int Decode(byte[] buffer, int offset, out BacnetBvlcV6Functions function, out int msgLength,
IPEndPoint sender, BacnetAddress remoteAddress)
{
// offset always 0, we are the first after udp
// and a previous test by the caller guaranteed at least 4 bytes into the buffer
function = (BacnetBvlcV6Functions)buffer[1];
msgLength = (buffer[2] << 8) | (buffer[3] << 0);
if (buffer[0] != BVLL_TYPE_BACNET_IPV6 || buffer.Length != msgLength) return -1;
Array.Copy(buffer, 4, remoteAddress.VMac, 0, 3);
switch (function)
{
case BacnetBvlcV6Functions.BVLC_RESULT:
return 9; // only for the upper layers
case BacnetBvlcV6Functions.BVLC_ORIGINAL_UNICAST_NPDU:
return 10; // only for the upper layers
case BacnetBvlcV6Functions.BVLC_ORIGINAL_BROADCAST_NPDU:
// Send to FDs & BBMDs, not broadcast or it will be made twice !
if (_bbmdFdServiceActivated)
Forward_NPDU(buffer, msgLength, false, sender, remoteAddress);
return 7; // also for the upper layers
case BacnetBvlcV6Functions.BVLC_ADDRESS_RESOLUTION:
// need to verify that the VMAC is mine
if (VMAC[0] == buffer[7] && VMAC[1] == buffer[8] && VMAC[2] == buffer[9])
// coming from myself ? avoid loopback
if (!_myTransport.LocalEndPoint.Equals(sender))
SendAddressResolutionAck(sender, remoteAddress.VMac,
BacnetBvlcV6Functions.BVLC_ADDRESS_RESOLUTION_ACK);
return 0; // not for the upper layers
case BacnetBvlcV6Functions.BVLC_FORWARDED_ADDRESS_RESOLUTION:
// no need to verify the target VMAC, should be OK
SendAddressResolutionAck(sender, remoteAddress.VMac,
BacnetBvlcV6Functions.BVLC_ADDRESS_RESOLUTION_ACK);
return 0; // not for the upper layers
case BacnetBvlcV6Functions.BVLC_ADDRESS_RESOLUTION_ACK: // adresse conflict
if (VMAC[0] == buffer[4] && VMAC[1] == buffer[5] && VMAC[2] == buffer[6] && RandomVmac)
{
new Random().NextBytes(VMAC);
VMAC[0] = (byte)((VMAC[0] & 0x7F) | 0x40);
SendAddressResolutionRequest(VMAC);
}
return 0; // not for the upper layers
case BacnetBvlcV6Functions.BVLC_VIRTUAL_ADDRESS_RESOLUTION:
SendAddressResolutionAck(sender, remoteAddress.VMac,
BacnetBvlcV6Functions.BVLC_VIRTUAL_ADDRESS_RESOLUTION_ACK);
return 0; // not for the upper layers
case BacnetBvlcV6Functions.BVLC_VIRTUAL_ADDRESS_RESOLUTION_ACK:
return 0; // not for the upper layers
case BacnetBvlcV6Functions.BVLC_FORWARDED_NPDU:
if (_myTransport.LocalEndPoint.Equals(sender)) return 0;
// certainly TODO the same code I've put in the IPV4 implementation
if (_bbmdFdServiceActivated && msgLength >= 25)
{
bool ret;
lock (_bbmds)
ret = _bbmds.Exists(items => items.Equals(sender)); // verify sender presence in the table
// avoid also loopback
if (ret) // message from a know BBMD address, sent to all FDs and broadcast
{
SendToFDs(buffer, msgLength); // send without modification
// Assume all BVLC_FORWARDED_NPDU are directly sent to me in the
// unicast mode and not by the way of the multicast address
// If not, it's not really a big problem, devices on the local net will
// receive two times the message (after all it's just WhoIs, Iam, ...)
BacnetIpV6UdpProtocolTransport.Convert(_broadcastAdd, out IPEndPoint ep);
_myTransport.Send(buffer, msgLength, ep);
}
}
return 25; // for the upper layers
case BacnetBvlcV6Functions.BVLC_REGISTER_FOREIGN_DEVICE:
if (_bbmdFdServiceActivated && msgLength == 9)
{
var TTL = (buffer[7] << 8) + buffer[8]; // unit is second
RegisterForeignDevice(sender, TTL);
SendResult(sender, BacnetBvlcV6Results.SUCCESSFUL_COMPLETION); // ack
}
return 0; // not for the upper layers
case BacnetBvlcV6Functions.BVLC_DELETE_FOREIGN_DEVICE_TABLE_ENTRY:
return 0; // not for the upper layers
case BacnetBvlcV6Functions.BVLC_SECURE_BVLC:
return 0; // not for the upper layers
case BacnetBvlcV6Functions.BVLC_DISTRIBUTE_BROADCAST_TO_NETWORK: // Sent by a Foreign Device, not a BBMD
if (_bbmdFdServiceActivated)
{
// Send to FDs except the sender, BBMDs and broadcast
lock (_foreignDevices)
{
if (_foreignDevices.Exists(item => item.Key.Equals(sender))) // verify previous registration
Forward_NPDU(buffer, msgLength, true, sender, remoteAddress);
else
SendResult(sender, BacnetBvlcV6Results.DISTRIBUTE_BROADCAST_TO_NETWORK_NAK);
}
}
return 0; // not for the upper layers
// error encoding function or experimental one
default:
return -1;
}
}
}

465
addons/EGFramework/Third_Part_SourceCode/BacNetPlugin/Transport/BacnetIpUdpProtocolTransport.cs

@ -1,465 +0,0 @@ @@ -1,465 +0,0 @@
/**************************************************************************
* MIT License
*
* Copyright (C) 2014 Morten Kvistgaard <mk@pch-engineering.dk>
*
* Permission is hereby granted, free of charge, to any person obtaining
* a copy of this software and associated documentation files (the
* "Software"), to deal in the Software without restriction, including
* without limitation the rights to use, copy, modify, merge, publish,
* distribute, sublicense, and/or sell copies of the Software, and to
* permit persons to whom the Software is furnished to do so, subject to
* the following conditions:
*
* The above copyright notice and this permission notice shall be included
* in all copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
* IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
* CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
*
*********************************************************************/
namespace System.IO.BACnet;
/// <summary>
/// This is the standard BACNet udp transport
/// </summary>
public class BacnetIpUdpProtocolTransport : BacnetTransportBase
{
private UdpClient _sharedConn;
private UdpClient _exclusiveConn;
private readonly bool _exclusivePort;
private readonly bool _dontFragment;
private readonly string _localEndpoint;
private BacnetAddress _broadcastAddress;
private bool _disposing;
public BVLC Bvlc { get; private set; }
public int SharedPort { get; }
public int ExclusivePort { get; }
// Give 0.0.0.0:xxxx if the socket is open with System.Net.IPAddress.Any
// Today only used by _GetBroadcastAddress method & the bvlc layer class in BBMD mode
// Some more complex solutions could avoid this, that's why this property is virtual
public virtual IPEndPoint LocalEndPoint => (IPEndPoint)_exclusiveConn.Client.LocalEndPoint;
public BacnetIpUdpProtocolTransport(int port, bool useExclusivePort = false, bool dontFragment = false,
int maxPayload = 1472, string localEndpointIp = "")
{
SharedPort = port;
MaxBufferLength = maxPayload;
Type = BacnetAddressTypes.IP;
HeaderLength = BVLC.BVLC_HEADER_LENGTH;
MaxAdpuLength = BVLC.BVLC_MAX_APDU;
_exclusivePort = useExclusivePort;
_dontFragment = dontFragment;
_localEndpoint = localEndpointIp;
}
public BacnetIpUdpProtocolTransport(int sharedPort, int exclusivePort, bool dontFragment = false,
int maxPayload = 1472, string localEndpointIp = "")
: this(sharedPort, false, dontFragment, maxPayload, localEndpointIp)
{
ExclusivePort = exclusivePort;
}
public override bool Equals(object obj)
{
var a = obj as BacnetIpUdpProtocolTransport;
return a?.SharedPort == SharedPort;
}
public override int GetHashCode()
{
return SharedPort.GetHashCode();
}
public override string ToString()
{
return $"Udp:{SharedPort}";
}
private void Open()
{
if (!_exclusivePort)
{
/* We need a shared broadcast "listen" port. This is the 0xBAC0 port */
/* This will enable us to have more than 1 client, on the same machine. Perhaps it's not that important though. */
/* We (might) only recieve the broadcasts on this. Any unicasts to this might be eaten by another local client */
if (_sharedConn == null)
{
_sharedConn = new UdpClient { ExclusiveAddressUse = false };
_sharedConn.Client.SetSocketOption(SocketOptionLevel.Socket, SocketOptionName.ReuseAddress, true);
var ep = new IPEndPoint(IPAddress.Any, SharedPort);
if (!string.IsNullOrEmpty(_localEndpoint)) ep = new IPEndPoint(IPAddress.Parse(_localEndpoint), SharedPort);
DisableConnReset(_sharedConn);
_sharedConn.Client.Bind(ep);
SetDontFragment(_sharedConn, _dontFragment);
Log.Info($"Binded shared {ep} using UDP");
}
/* This is our own exclusive port. We'll recieve everything sent to this. */
/* So this is how we'll present our selves to the world */
if (_exclusiveConn == null)
{
var ep = new IPEndPoint(IPAddress.Any, ExclusivePort);
if (!string.IsNullOrEmpty(_localEndpoint)) ep = new IPEndPoint(IPAddress.Parse(_localEndpoint), ExclusivePort);
_exclusiveConn = new UdpClient(ep);
// Gets the Endpoint : the assigned Udp port number in fact
ep = (IPEndPoint)_exclusiveConn.Client.LocalEndPoint;
// closes the socket
_exclusiveConn.Close();
// Re-opens it with the freeed port number, to be sure it's a real active/server socket
// which cannot be disarmed for listen by .NET for incoming call after a few inactivity
// minutes ... yes it's like this at least on several systems
_exclusiveConn = new UdpClient(ep)
{
EnableBroadcast = true
};
SetDontFragment(_exclusiveConn, _dontFragment);
DisableConnReset(_exclusiveConn);
}
}
else
{
var ep = new IPEndPoint(IPAddress.Any, SharedPort);
if (!string.IsNullOrEmpty(_localEndpoint)) ep = new IPEndPoint(IPAddress.Parse(_localEndpoint), SharedPort);
_exclusiveConn = new UdpClient { ExclusiveAddressUse = true };
DisableConnReset(_exclusiveConn);
_exclusiveConn.Client.Bind(ep);
SetDontFragment(_exclusiveConn, _dontFragment);
_exclusiveConn.EnableBroadcast = true;
Log.Info($"Binded exclusively to {ep} using UDP");
}
Bvlc = new BVLC(this);
}
/// <summary>
/// Prevent exception on setting Don't Fragment on OSX
/// </summary>
/// <remarks>
/// https://github.com/dotnet/runtime/issues/27653
/// </remarks>
/// <param name="client"></param>
/// <param name="dontFragment"></param>
private void SetDontFragment(UdpClient client, bool dontFragment)
{
if (Environment.OSVersion.Platform != PlatformID.MacOSX)
{
try
{
client.DontFragment = dontFragment;
}
catch (SocketException e)
{
Log.WarnFormat("Unable to set DontFragment", e);
}
}
}
/// <summary>
/// Done to prevent exceptions in Socket.BeginReceive()
/// </summary>
/// <remarks>
/// http://microsoft.public.win32.programmer.networks.narkive.com/RlxW2V6m/udp-comms-and-connection-reset-problem
/// </remarks>
private static void DisableConnReset(UdpClient client)
{
if (Environment.OSVersion.Platform == PlatformID.Win32NT)
{
const uint IOC_IN = 0x80000000;
const uint IOC_VENDOR = 0x18000000;
const uint SIO_UDP_CONNRESET = IOC_IN | IOC_VENDOR | 12;
client?.Client.IOControl(unchecked((int)SIO_UDP_CONNRESET),
new[] { System.Convert.ToByte(false) }, null);
}
}
protected void Close()
{
_exclusiveConn.Close();
}
public override void Start()
{
_disposing = false;
Open();
_sharedConn?.BeginReceive(OnReceiveData, _sharedConn);
_exclusiveConn?.BeginReceive(OnReceiveData, _exclusiveConn);
}
private void OnReceiveData(IAsyncResult asyncResult)
{
var connection = (UdpClient)asyncResult.AsyncState;
try
{
IPEndPoint ep = null;
byte[] receiveBuffer;
try
{
receiveBuffer = connection.EndReceive(asyncResult, ref ep);
}
finally
{
if (connection.Client != null && !_disposing)
{
try
{
// BeginReceive ASAP to enable parallel processing (e.g. query additional data while processing a notification)
connection.BeginReceive(OnReceiveData, connection);
}
catch (Exception ex)
{
Log.Error($"Failed to restart data receive. {ex}");
}
}
}
var receiveBufferHex = ConvertToHex(receiveBuffer);
var receivedLength = receiveBuffer.Length;
if (receivedLength == 0) // Empty frame : port scanner maybe
return;
//verify message
Convert(ep, out var remoteAddress);
if (receivedLength < BVLC.BVLC_HEADER_LENGTH)
{
Log.Warn($"Some garbage data got in: {receiveBufferHex}");
return;
}
// Basic Header lenght
var headerLength = Bvlc.Decode(receiveBuffer, 0, out var function, out var _, ep);
if (headerLength == -1)
{
Log.Warn($"Unknow BVLC Header in: {receiveBufferHex}");
return;
}
switch (function)
{
case BacnetBvlcFunctions.BVLC_RESULT:
// response to BVLC_REGISTER_FOREIGN_DEVICE, could be BVLC_DISTRIBUTE_BROADCAST_TO_NETWORK
// but we are not a BBMD, we don't care
Log.Debug("Receive Register as Foreign Device Response");
break;
case BacnetBvlcFunctions.BVLC_FORWARDED_NPDU:
// BVLC_FORWARDED_NPDU frame by a BBMD, change the remote_address to the original one
// stored in the BVLC header, we don't care about the BBMD address
var ip = ((long)receiveBuffer[7] << 24) + ((long)receiveBuffer[6] << 16) +
((long)receiveBuffer[5] << 8) + receiveBuffer[4];
var port = (receiveBuffer[8] << 8) + receiveBuffer[9]; // 0xbac0 maybe
Convert(new IPEndPoint(ip, port), out remoteAddress);
break;
}
if (function != BacnetBvlcFunctions.BVLC_ORIGINAL_UNICAST_NPDU &&
function != BacnetBvlcFunctions.BVLC_ORIGINAL_BROADCAST_NPDU &&
function != BacnetBvlcFunctions.BVLC_FORWARDED_NPDU)
{
Log.Debug($"{function} - ignoring");
return;
}
if (receivedLength <= headerLength)
{
Log.Warn($"Missing data, only header received: {receiveBufferHex}");
return;
}
InvokeMessageRecieved(receiveBuffer, headerLength, receivedLength - headerLength, remoteAddress);
}
catch (ObjectDisposedException)
{
Log.Debug("Connection has been disposed");
}
catch (Exception e)
{
if (connection.Client == null || _disposing)
return;
Log.Error("Exception in OnRecieveData", e);
}
}
public bool SendRegisterAsForeignDevice(IPEndPoint bbmd, short ttl)
{
if (bbmd.AddressFamily != AddressFamily.InterNetwork)
return false;
Bvlc.SendRegisterAsForeignDevice(bbmd, ttl);
return true;
}
public bool SendRemoteWhois(byte[] buffer, IPEndPoint bbmd, int msgLength)
{
if (bbmd.AddressFamily != AddressFamily.InterNetwork)
return false;
Bvlc.SendRemoteWhois(buffer, bbmd, msgLength);
return true;
}
public static string ConvertToHex(byte[] buffer)
{
return BitConverter.ToString(buffer).Replace("-", "");
}
public int Send(byte[] buffer, int dataLength, IPEndPoint ep)
{
// return _exclusiveConn.Send(buffer, data_length, ep);
ThreadPool.QueueUserWorkItem(o =>
{
try
{
_exclusiveConn.Send(buffer, dataLength, ep);
}
catch
{
// not much you can do about at this point
}
}, null);
return dataLength;
}
public override int Send(byte[] buffer, int offset, int dataLength, BacnetAddress address, bool waitForTransmission, int timeout)
{
if (_exclusiveConn == null) return 0;
//add header
var fullLength = dataLength + HeaderLength;
Bvlc.Encode(buffer, offset - BVLC.BVLC_HEADER_LENGTH, address.net == 0xFFFF
? BacnetBvlcFunctions.BVLC_ORIGINAL_BROADCAST_NPDU
: BacnetBvlcFunctions.BVLC_ORIGINAL_UNICAST_NPDU, fullLength);
//create end point
Convert(address, out var ep);
try
{
// broadcasts are transported from our local unicast socket also
return _exclusiveConn.Send(buffer, fullLength, ep);
}
catch
{
return 0;
}
}
public static void Convert(IPEndPoint ep, out BacnetAddress address)
{
var tmp1 = ep.Address.GetAddressBytes();
var tmp2 = BitConverter.GetBytes((ushort)ep.Port);
Array.Reverse(tmp2);
Array.Resize(ref tmp1, tmp1.Length + tmp2.Length);
Array.Copy(tmp2, 0, tmp1, tmp1.Length - tmp2.Length, tmp2.Length);
address = new BacnetAddress(BacnetAddressTypes.IP, 0, tmp1);
}
public static void Convert(BacnetAddress address, out IPEndPoint ep)
{
long ipAddress = BitConverter.ToUInt32(address.adr, 0);
var port = (ushort)((address.adr[4] << 8) | (address.adr[5] << 0));
ep = new IPEndPoint(ipAddress, port);
}
// Get the IPAddress only if one is present
// this could be usefull to find the broadcast address even if the socket is open on the default interface
// removes somes virtual interfaces (certainly not all)
private static UnicastIPAddressInformation GetAddressDefaultInterface()
{
var unicastAddresses = NetworkInterface.GetAllNetworkInterfaces()
.Where(i => i.OperationalStatus == OperationalStatus.Up)
.Where(i => i.NetworkInterfaceType != NetworkInterfaceType.Loopback)
.Where(i => !(i.Name.Contains("VirtualBox") || i.Name.Contains("VMware")))
.SelectMany(i => i.GetIPProperties().UnicastAddresses)
.Where(a => a.Address.AddressFamily == AddressFamily.InterNetwork)
.ToArray();
return unicastAddresses.Length == 1
? unicastAddresses.Single()
: null;
}
// A lot of problems on Mono (Raspberry) to get the correct broadcast @
// so this method is overridable (this allows the implementation of operating system specific code)
// Marc solution http://stackoverflow.com/questions/8119414/how-to-query-the-subnet-masks-using-mono-on-linux for instance
protected virtual BacnetAddress _GetBroadcastAddress()
{
// general broadcast by default if nothing better is found
var ep = new IPEndPoint(IPAddress.Parse("255.255.255.255"), SharedPort);
UnicastIPAddressInformation ipAddr = null;
if (LocalEndPoint.Address.ToString() == "0.0.0.0")
{
ipAddr = GetAddressDefaultInterface();
}
else
{
// restricted local broadcast (directed ... routable)
foreach (var adapter in NetworkInterface.GetAllNetworkInterfaces())
foreach (var ip in adapter.GetIPProperties().UnicastAddresses)
if (LocalEndPoint.Address.Equals(ip.Address))
{
ipAddr = ip;
break;
}
}
if (ipAddr != null)
{
try
{
var strCurrentIP = ipAddr.Address.ToString().Split('.');
var strIPNetMask = ipAddr.IPv4Mask.ToString().Split('.');
var broadcastStr = new StringBuilder();
for (var i = 0; i < 4; i++)
{
broadcastStr.Append(((byte)(int.Parse(strCurrentIP[i]) | ~int.Parse(strIPNetMask[i]))).ToString());
if (i != 3) broadcastStr.Append('.');
}
ep = new IPEndPoint(IPAddress.Parse(broadcastStr.ToString()), SharedPort);
}
catch
{
// on mono IPv4Mask feature not implemented
}
}
Convert(ep, out var broadcast);
broadcast.net = 0xFFFF;
return broadcast;
}
public override BacnetAddress GetBroadcastAddress()
{
return _broadcastAddress ??= _GetBroadcastAddress();
}
public override void Dispose()
{
_disposing = true;
_exclusiveConn?.Close();
_exclusiveConn = null;
_sharedConn?.Close();
_sharedConn = null;
}
}

362
addons/EGFramework/Third_Part_SourceCode/BacNetPlugin/Transport/BacnetIpV6UdpProtocolTransport.cs

@ -1,362 +0,0 @@ @@ -1,362 +0,0 @@
/**************************************************************************
* MIT License
*
* Copyright (C) 2015 Frederic Chaxel <fchaxel@free.fr>
* Morten Kvistgaard <mk@pch-engineering.dk>
* Permission is hereby granted, free of charge, to any person obtaining
* a copy of this software and associated documentation files (the
* "Software"), to deal in the Software without restriction, including
* without limitation the rights to use, copy, modify, merge, publish,
* distribute, sublicense, and/or sell copies of the Software, and to
* permit persons to whom the Software is furnished to do so, subject to
* the following conditions:
*
* The above copyright notice and this permission notice shall be included
* in all copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
* IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
* CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
*
*********************************************************************/
// based on Addendum 135-2012aj-4
namespace System.IO.BACnet;
public class BacnetIpV6UdpProtocolTransport : BacnetTransportBase
{
private readonly bool _exclusivePort;
private readonly string _localEndpoint;
private readonly int _vMac;
private bool _dontFragment;
private UdpClient _exclusiveConn;
private UdpClient _sharedConn;
public BVLCV6 Bvlc { get; private set; }
public int SharedPort { get; }
// Give [::]:xxxx if the socket is open with System.Net.IPAddress.IPv6Any
// Used the bvlc layer class in BBMD mode
// Some more complex solutions could avoid this, that's why this property is virtual
public virtual IPEndPoint LocalEndPoint => (IPEndPoint)_exclusiveConn.Client.LocalEndPoint;
public BacnetIpV6UdpProtocolTransport(int port, int vMac = -1, bool useExclusivePort = false,
bool dontFragment = false, int maxPayload = 1472, string localEndpointIp = "")
{
SharedPort = port;
MaxBufferLength = maxPayload;
Type = BacnetAddressTypes.IPV6;
MaxAdpuLength = BVLCV6.BVLC_MAX_APDU;
// Two frames type, unicast with 10 bytes or broadcast with 7 bytes
// Here it's the biggest header, resize will be done after, if needed
HeaderLength = BVLCV6.BVLC_HEADER_LENGTH;
_exclusivePort = useExclusivePort;
_dontFragment = dontFragment;
_localEndpoint = localEndpointIp;
_vMac = vMac;
}
public override void Start()
{
Open();
_sharedConn?.BeginReceive(OnReceiveData, _sharedConn);
_exclusiveConn?.BeginReceive(OnReceiveData, _exclusiveConn);
}
public override int Send(byte[] buffer, int offset, int dataLength, BacnetAddress address,
bool waitForTransmission, int timeout)
{
if (_exclusiveConn == null) return 0;
//add header
var fullLength = dataLength + HeaderLength;
if (address.net == 0xFFFF)
{
var newBuffer = new byte[fullLength - 3];
Array.Copy(buffer, 3, newBuffer, 0, fullLength - 3);
fullLength -= 3;
buffer = newBuffer;
Bvlc.Encode(buffer, offset - BVLCV6.BVLC_HEADER_LENGTH,
BacnetBvlcV6Functions.BVLC_ORIGINAL_BROADCAST_NPDU, fullLength, address);
}
else
{
Bvlc.Encode(buffer, offset - BVLCV6.BVLC_HEADER_LENGTH, BacnetBvlcV6Functions.BVLC_ORIGINAL_UNICAST_NPDU,
fullLength, address);
}
// create end point
Convert(address, out var ep);
try
{
// send
// multicast are transported from our local unicast socket also
return _exclusiveConn.Send(buffer, fullLength, ep);
}
catch
{
return 0;
}
}
public override BacnetAddress GetBroadcastAddress()
{
// could be FF08, FF05, FF04, FF02
var ep = new IPEndPoint(IPAddress.Parse("[FF0E::BAC0]"), SharedPort);
Convert(ep, out var ret);
ret.net = 0xFFFF;
return ret;
}
public override void Dispose()
{
_exclusiveConn?.Close();
_exclusiveConn = null;
_sharedConn?.Close();
_sharedConn = null;
}
public override bool Equals(object obj)
{
var a = obj as BacnetIpV6UdpProtocolTransport;
return a?.SharedPort == SharedPort;
}
public override int GetHashCode()
{
return SharedPort.GetHashCode();
}
public override string ToString()
{
return "Udp IPv6:" + SharedPort;
}
private void Open()
{
UdpClient multicastListener = null;
if (!_exclusivePort)
{
/* We need a shared multicast "listen" port. This is the 0xBAC0 port */
/* This will enable us to have more than 1 client, on the same machine. Perhaps it's not that important though. */
/* We (might) only receive the multicast on this. Any unicasts to this might be eaten by another local client */
if (_sharedConn == null)
{
_sharedConn = new UdpClient(AddressFamily.InterNetworkV6) { ExclusiveAddressUse = false };
_sharedConn.Client.SetSocketOption(SocketOptionLevel.Socket, SocketOptionName.ReuseAddress, true);
EndPoint ep = new IPEndPoint(IPAddress.IPv6Any, SharedPort);
if (!string.IsNullOrEmpty(_localEndpoint))
ep = new IPEndPoint(IPAddress.Parse(_localEndpoint), SharedPort);
_sharedConn.Client.Bind(ep);
multicastListener = _sharedConn;
}
/* This is our own exclusive port. We'll recieve everything sent to this. */
/* So this is how we'll present our selves to the world */
if (_exclusiveConn == null)
{
EndPoint ep = new IPEndPoint(IPAddress.IPv6Any, 0);
if (!string.IsNullOrEmpty(_localEndpoint)) ep = new IPEndPoint(IPAddress.Parse(_localEndpoint), 0);
_exclusiveConn = new UdpClient((IPEndPoint)ep);
}
}
else
{
EndPoint ep = new IPEndPoint(IPAddress.IPv6Any, SharedPort);
if (!string.IsNullOrEmpty(_localEndpoint))
ep = new IPEndPoint(IPAddress.Parse(_localEndpoint), SharedPort);
_exclusiveConn = new UdpClient(AddressFamily.InterNetworkV6)
{
ExclusiveAddressUse = true
};
_exclusiveConn.Client.Bind((IPEndPoint)ep);
multicastListener = _exclusiveConn;
}
multicastListener.JoinMulticastGroup(IPAddress.Parse("[FF02::BAC0]"));
multicastListener.JoinMulticastGroup(IPAddress.Parse("[FF04::BAC0]"));
multicastListener.JoinMulticastGroup(IPAddress.Parse("[FF05::BAC0]"));
multicastListener.JoinMulticastGroup(IPAddress.Parse("[FF08::BAC0]"));
multicastListener.JoinMulticastGroup(IPAddress.Parse("[FF0E::BAC0]"));
// If this option is enabled Yabe cannot see itself !
// multicastListener.MulticastLoopback = false;
Bvlc = new BVLCV6(this, _vMac);
}
protected void Close()
{
_sharedConn?.BeginReceive(OnReceiveData, _sharedConn);
_exclusiveConn?.BeginReceive(OnReceiveData, _exclusiveConn);
}
private void OnReceiveData(IAsyncResult asyncResult)
{
var conn = (UdpClient)asyncResult.AsyncState;
try
{
var ep = new IPEndPoint(IPAddress.Any, 0);
byte[] localBuffer;
int rx;
try
{
localBuffer = conn.EndReceive(asyncResult, ref ep);
rx = localBuffer.Length;
}
catch (Exception) // ICMP port unreachable
{
//restart data receive
conn.BeginReceive(OnReceiveData, conn);
return;
}
if (rx == 0) // Empty frame : port scanner maybe
{
//restart data receive
conn.BeginReceive(OnReceiveData, conn);
return;
}
try
{
//verify message
Convert(ep, out var remoteAddress);
if (rx < BVLCV6.BVLC_HEADER_LENGTH - 3)
{
Log.Warn("Some garbage data got in");
}
else
{
// Basic Header lenght
var headerLength = Bvlc.Decode(localBuffer, 0, out var function, out _, ep, remoteAddress);
switch (headerLength)
{
case 0:
return;
case -1:
Log.Debug("Unknow BVLC Header");
return;
}
// response to BVLC_REGISTER_FOREIGN_DEVICE (could be BVLC_DISTRIBUTE_BROADCAST_TO_NETWORK ... but we are not a BBMD, don't care)
if (function == BacnetBvlcV6Functions.BVLC_RESULT)
{
Log.Debug("Receive Register as Foreign Device Response");
}
// a BVLC_FORWARDED_NPDU frame by a BBMD, change the remote_address to the original one (stored in the BVLC header)
// we don't care about the BBMD address
if (function == BacnetBvlcV6Functions.BVLC_FORWARDED_NPDU)
{
Array.Copy(localBuffer, 7, remoteAddress.adr, 0, 18);
}
if (function != BacnetBvlcV6Functions.BVLC_ORIGINAL_UNICAST_NPDU &&
function != BacnetBvlcV6Functions.BVLC_ORIGINAL_BROADCAST_NPDU &&
function != BacnetBvlcV6Functions.BVLC_FORWARDED_NPDU)
return;
if (rx > headerLength)
InvokeMessageRecieved(localBuffer, headerLength, rx - headerLength, remoteAddress);
}
}
catch (Exception ex)
{
Log.Error("Exception in udp recieve", ex);
}
finally
{
//restart data receive
conn.BeginReceive(OnReceiveData, conn);
}
}
catch (Exception ex)
{
//restart data receive
if (conn.Client != null)
{
Log.Error("Exception in Ip OnRecieveData", ex);
conn.BeginReceive(OnReceiveData, conn);
}
}
}
public static string ConvertToHex(byte[] buffer, int length)
{
var ret = "";
for (var i = 0; i < length; i++)
ret += buffer[i].ToString("X2");
return ret;
}
// Modif FC : used for BBMD communication
public int Send(byte[] buffer, int dataLength, IPEndPoint ep)
{
try
{
// return _exclusiveConn.Send(buffer, data_length, ep);
ThreadPool.QueueUserWorkItem(o => _exclusiveConn.Send(buffer, dataLength, ep), null);
return dataLength;
}
catch
{
return 0;
}
}
public bool SendRegisterAsForeignDevice(IPEndPoint bbmd, short ttl)
{
if (bbmd.AddressFamily != AddressFamily.InterNetworkV6)
return false;
Bvlc.SendRegisterAsForeignDevice(bbmd, ttl);
return true;
}
public bool SendRemoteWhois(byte[] buffer, IPEndPoint bbmd, int msgLength)
{
if (bbmd.AddressFamily != AddressFamily.InterNetworkV6)
return false;
// This message was build using the default (10) header lenght, but it's smaller (7)
var newBuffer = new byte[msgLength - 3];
Array.Copy(buffer, 3, newBuffer, 0, msgLength - 3);
msgLength -= 3;
Bvlc.SendRemoteWhois(newBuffer, bbmd, msgLength);
return true;
}
public static void Convert(IPEndPoint ep, out BacnetAddress address)
{
var tmp1 = ep.Address.GetAddressBytes();
var tmp2 = BitConverter.GetBytes((ushort)ep.Port);
Array.Reverse(tmp2);
Array.Resize(ref tmp1, tmp1.Length + tmp2.Length);
Array.Copy(tmp2, 0, tmp1, tmp1.Length - tmp2.Length, tmp2.Length);
address = new BacnetAddress(BacnetAddressTypes.IPV6, 0, tmp1);
}
public static void Convert(BacnetAddress address, out IPEndPoint ep)
{
var port = (ushort)((address.adr[16] << 8) | (address.adr[17] << 0));
var ipv6 = new byte[16];
Array.Copy(address.adr, ipv6, 16);
ep = new IPEndPoint(new IPAddress(ipv6), port);
}
}

Some files were not shown because too many files have changed in this diff Show More

Loading…
Cancel
Save