internal static byte[] GetHdlcFrame(GXDLMSSettings settings, byte frame, GXByteBuffer data)
{
GXByteBuffer bb = new GXByteBuffer();
int frameSize, len = 0;
byte[] primaryAddress, secondaryAddress;
if (settings.IsServer)
{
primaryAddress = GetHdlcAddressBytes(settings.ClientAddress, 0);
secondaryAddress = GetHdlcAddressBytes(settings.ServerAddress, settings.ServerAddressSize);
}
else
{
primaryAddress = GetHdlcAddressBytes(settings.ServerAddress, settings.ServerAddressSize);
secondaryAddress = GetHdlcAddressBytes(settings.ClientAddress, 0);
}
// Add BOP
bb.SetUInt8(GXCommon.HDLCFrameStartEnd);
frameSize = Convert.ToInt32(settings.Limits.MaxInfoTX);
// If no data
if (data == null || data.Size == 0)
{
bb.SetUInt8(0xA0);
}
else if (data.Size - data.Position <= frameSize)
{
// Is last packet.
bb.SetUInt8(0xA0);
len = data.Size - data.Position;
}
else
{
// More data to left.
bb.SetUInt8(0xA8);
len = frameSize;
}
//Frame len.
if (len == 0)
{
bb.SetUInt8((byte)(5 + primaryAddress.Length + secondaryAddress.Length + len));
}
else
{
bb.SetUInt8((byte)(7 + primaryAddress.Length + secondaryAddress.Length + len));
}
// Add primary address.
bb.Set(primaryAddress);
// Add secondary address.
bb.Set(secondaryAddress);
//Add frame ID.
if (frame == 0)
{
frame = settings.NextSend();
}
bb.SetUInt8(frame);
// Add header CRC.
UInt16 crc = GXFCS16.CountFCS16(bb.Data, 1, bb.Size - 1);
bb.SetUInt16(crc);
if (len != 0)
{
//Add data.
bb.Set(data, len);
// Add data CRC.
crc = GXFCS16.CountFCS16(bb.Data, 1, bb.Size - 1);
bb.SetUInt16(crc);
}
// Add EOP
bb.SetUInt8(GXCommon.HDLCFrameStartEnd);
if (data != null)
{
//Remove sent data in server side.
if (settings.IsServer)
{
if (data.Size == data.Position)
{
data.Clear();
}
else
{
data.Move(data.Position, 0, data.Size - data.Position);
data.Position = 0;
}
}
}
return bb.Array();
}