/// <summary> /// Get HDLC frame for data. /// </summary> /// <param name="settings">DLMS settings.</param> /// <param name="frame">Frame ID. If zero new is generated.</param> /// <param name="data">Data to add.</param> /// <returns>HDLC frames.</returns> 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(); }