Files
cms_thermo_active/Thermo.Active.Utils/supportFunctions.cs
T
2020-06-04 15:21:15 +02:00

657 lines
25 KiB
C#

using Newtonsoft.Json;
using Thermo.Active.Model.DTOModels.JobModels;
using System;
using System.Collections.Generic;
using System.Drawing;
using System.Drawing.Imaging;
using System.IO;
using System.IO.Compression;
using System.Linq;
using System.Reflection;
using System.Security.Cryptography;
using System.Text;
using System.Text.RegularExpressions;
using static CMS_CORE_Library.Models.DataStructures;
using static Thermo.Active.Model.Constants;
namespace Thermo.Active.Utils
{
public static class SupportFunctions
{
private static readonly string CMSCONNECT_TOKEN = "59f1qik5PYfiJLiXZ4xZ05pjzx5E9FscQWtj4lmfLKXaF1OAxkvu7ziBzXFBuuVQ";
public static SOFTKEY_TYPE GetSoftKeyType(string type)
{
switch (type)
{
case "softKey_procedure": return SOFTKEY_TYPE.PROCEDURE;
case "softKey_group": return SOFTKEY_TYPE.GROUP;
default: return SOFTKEY_TYPE.TOGGLE;
}
}
public static HEAD_TYPE GetHeadType(string type)
{
switch (type)
{
case "SPINDLE": return HEAD_TYPE.SPINDLE;
case "AWJ": return HEAD_TYPE.AWJ;
default: return HEAD_TYPE.WJ;
}
}
/// <summary>
/// Conversion string --> TACT_PARAM_TYPE
/// </summary>
/// <param name="strValue"></param>
/// <returns></returns>
public static TACT_PARAM_TYPE GetTActParamType(string strValue)
{
TACT_PARAM_TYPE answ = TACT_PARAM_TYPE.ND;
try
{
answ = (TACT_PARAM_TYPE)Enum.Parse(typeof(TACT_PARAM_TYPE), strValue);
}
catch { }
return answ;
}
/// <summary>
/// Conversion string --> TACT_MBLOCK_TYPE
/// </summary>
/// <param name="strValue"></param>
/// <returns></returns>
public static TACT_MBLOCK_TYPE GetTActMB_Type(string strValue)
{
TACT_MBLOCK_TYPE answ = TACT_MBLOCK_TYPE.ND;
try
{
answ = (TACT_MBLOCK_TYPE)Enum.Parse(typeof(TACT_MBLOCK_TYPE), strValue);
}
catch { }
return answ;
}
/// <summary>
/// Conversion string --> TACT_MBLOCK_SECTION
/// </summary>
/// <param name="strValue"></param>
/// <returns></returns>
public static TACT_MBLOCK_SECTION GetTActMB_Section(string strValue)
{
TACT_MBLOCK_SECTION answ = TACT_MBLOCK_SECTION.ND;
try
{
answ = (TACT_MBLOCK_SECTION)Enum.Parse(typeof(TACT_MBLOCK_SECTION), strValue);
}
catch { }
return answ;
}
public static int GetPlcIdFromNcSoftKey(string softKey)
{
switch (softKey)
{
case "auto": return 1;
case "edit": return 2;
case "mdi": return 3;
case "dnc": return 4;
case "ref": return 5;
case "jog": return 6;
case "jogInc": return 7;
case "restart": return 8;
case "teach": return 9;
case "retract": return 10;
case "wcsMcs": return 11;
case "handle": return 12;
case "reset": return 13;
case "blk": return 14;
case "blkDel": return 15;
case "opStop": return 16;
case "dryRun": return 17;
case "prgTest": return 18;
case "manualHandleInterrupt": return 19;
case "teachIn": return 20;
case "incPlane": return 21;
case "plus": return 22;
case "minus": return 23;
case "rapid": return 24;
case "xOne": return 25;
case "xTen": return 26;
case "xHundred": return 27;
case "xThousand": return 28;
case "overstroke": return 30;
case "feedByPass": return 31;
default: return -1;
}
}
public static double ConvertInMinutes(double number, MAINTENANCE_UNIT_OF_MEASURE unit)
{
switch (unit)
{
case MAINTENANCE_UNIT_OF_MEASURE.mm:
return number;
case MAINTENANCE_UNIT_OF_MEASURE.H:
return number * 60;
case MAINTENANCE_UNIT_OF_MEASURE.D:
return number * (24 * 60);
case MAINTENANCE_UNIT_OF_MEASURE.M:
return (30 * number) * (24 * 60);
default:
return number;
}
}
public static double ConvertInUmeas(double number, MAINTENANCE_UNIT_OF_MEASURE unit)
{
switch (unit)
{
case MAINTENANCE_UNIT_OF_MEASURE.mm:
return number;
case MAINTENANCE_UNIT_OF_MEASURE.H:
return number / 60;
case MAINTENANCE_UNIT_OF_MEASURE.D:
return number / (24 / 60);
case MAINTENANCE_UNIT_OF_MEASURE.M:
return (30 / number) / (24 / 60);
default:
return number;
}
}
public static void CopyProperties<TParent, TChild>(TParent parent, TChild child) where TParent : class where TChild : class
{
var parentProperties = parent.GetType().GetProperties();
var childProperties = child.GetType().GetProperties();
foreach (var parentProperty in parentProperties)
{
foreach (var childProperty in childProperties)
{
if (parentProperty.Name == childProperty.Name && parentProperty.PropertyType == childProperty.PropertyType)
{
childProperty.SetValue(child, parentProperty.GetValue(parent));
break;
}
}
}
}
public static int GetNextId(IEnumerable<int> objIds)
{
if (objIds.Count() == 0)
return 1;
return objIds.Max() + 1;
}
public static short GetFirstFreeId(IEnumerable<short> objIds)
{
if (objIds.Count() == 0)
return 1;
List<short> listOfPossibleIds = Enumerable.Range(1, objIds.Max() + 1).Select(x => (short)x).ToList();
IEnumerable<short> res = listOfPossibleIds.Except(objIds).ToList();
if (res.Count() > 0)
return res.First();
else
return 1;
}
public static string GetImageBase64String(string directoryPath, string imageName)
{
string fileName = Path.GetFileNameWithoutExtension(imageName);
foreach (string ext in VALID_IMAGE_EXTENSIONS)
{
if (File.Exists(directoryPath + "\\" + fileName + ext))
{
// Convert image to a base 64 string
return "data:image/" + ext + ";base64," + Convert.ToBase64String(File.ReadAllBytes(directoryPath + "\\" + fileName + ext));
}
}
return "";
}
public static string ExtractBase64ProgIcon(string path)
{
if (!File.Exists(path))
return "";
Image im = Icon.ExtractAssociatedIcon(path)?.ToBitmap();
MemoryStream m = new MemoryStream();
im.Save(m, ImageFormat.Png);
return "data:image/png;base64," + Convert.ToBase64String(m.ToArray());
}
public static DTOJobModel UnpackJobAndReadMetadata(string filePath, int processId)
{
DTOJobModel job = new DTOJobModel();
string jobFolderPath = JOB_TMP_DIRECTORY + "\\" + processId + "\\";
if (!Directory.Exists(jobFolderPath))
Directory.CreateDirectory(jobFolderPath);
// Check if job exists
if (!File.Exists(filePath))
return null;
EmptyFolder(jobFolderPath);
using (ZipArchive zipExtractor = ZipFile.OpenRead(filePath))
{
// Setup main job fields
job.Name = Path.GetFileName(filePath);
job.LastEditTimestamp = new FileInfo(filePath).LastAccessTime;
foreach (ZipArchiveEntry entry in zipExtractor.Entries)
{
// Extract file
entry.ExtractToFile(jobFolderPath + entry.Name, true);
// Get main program content
if (entry.Name.Equals(JOB_MAIN_FILENAME, StringComparison.OrdinalIgnoreCase))
{
using (var reader = new StreamReader(entry.Open()))
job.IsoMainProgram = (reader.ReadToEnd());
}
// Read images
else if (VALID_IMAGE_EXTENSIONS.Contains(Path.GetExtension(entry.Name).ToLower()))
{
var bytes = default(byte[]);
// Populate metadata
using (var memstream = new MemoryStream())
{
entry.Open().CopyTo(memstream);
bytes = memstream.ToArray();
job.Metadata.Generics.Images.Add(new DTOImageParamModel()
{
Name = Path.GetFileNameWithoutExtension(entry.Name),
Base64 = "data:image/" + Path.GetExtension(entry.Name).ToLower().TrimStart('.') + ";base64," + Convert.ToBase64String(bytes)
});
}
}
// Read metadata
else if (entry.Name.Equals(JOB_METADATA_FILENAME, StringComparison.OrdinalIgnoreCase))
{
DTOMetadataFieldsModel metasFromFile = new DTOMetadataFieldsModel();
using (var reader = new StreamReader(entry.Open()))
{
metasFromFile = JsonConvert.DeserializeObject<DTOMetadataFieldsModel>(reader.ReadToEnd());
if (metasFromFile == null)
{
return null;
}
else
{
job.Metadata.Generics.Description = metasFromFile.Description;
job.Metadata.Generics.ExecutionTime = metasFromFile.ExecutionTime;
job.Metadata.Customs = metasFromFile.Customs;
}
}
}
// Consider other file as part program
else
{
job.PartPrograms.Add(jobFolderPath + entry.Name);
}
}
return job;
}
}
public static void EmptyFolder(string path)
{
DirectoryInfo di = new DirectoryInfo(path);
foreach (FileInfo file in di.GetFiles())
file.Delete();
foreach (DirectoryInfo dir in di.GetDirectories())
dir.Delete(true);
}
public static bool IsValidJob(string filePath)
{
if (!File.Exists(filePath))
return false;
try
{
using (var archive = ZipFile.OpenRead(filePath))
{
// Find key files
List<ZipArchiveEntry> files = archive
.Entries
.Where(x => x.FullName == JOB_MAIN_FILENAME || x.FullName == JOB_METADATA_FILENAME)
.ToList();
// if there aren't both
if (files.Count() < 2)
return false;
else
return true;
}
}
catch (Exception)
{
return false;
}
}
public static DTOJobModel ReadExtractedJobMetadata(int processId)
{
string filePath = JOB_TMP_DIRECTORY + "\\" + processId + "\\";
if (!Directory.Exists(filePath))
return null;
// Setup main Fields
DTOJobModel jobData = new DTOJobModel()
{
Name = Path.GetFileName(filePath),
LastEditTimestamp = new FileInfo(filePath).LastAccessTime
};
DirectoryInfo di = new DirectoryInfo(filePath);
foreach (FileInfo file in di.GetFiles())
{
// Get main program content
if (file.Name.Equals(JOB_MAIN_FILENAME, StringComparison.OrdinalIgnoreCase))
{
jobData.IsoMainProgram = (File.ReadAllText(file.FullName));
}
// Get images content without extract files
else if (VALID_IMAGE_EXTENSIONS.Contains(Path.GetExtension(file.Name).ToLower()))
{
byte[] bytes = File.ReadAllBytes(file.FullName);
jobData.Metadata.Generics.Images.Add(new DTOImageParamModel()
{
Name = file.Name,
Base64 = "data:image/" + Path.GetExtension(file.Name).ToLower().TrimStart('.') + ";base64," + Convert.ToBase64String(bytes)
});
}
// Metadata
else if (file.Name.Equals(JOB_METADATA_FILENAME, StringComparison.OrdinalIgnoreCase))
{
DTOMetadataFieldsModel metasFromFile = new DTOMetadataFieldsModel();
metasFromFile = JsonConvert
.DeserializeObject<DTOMetadataFieldsModel>
(File.ReadAllText(file.FullName));
if (metasFromFile == null)
return null;
else
{
jobData.Metadata.Generics.Description = metasFromFile.Description;
jobData.Metadata.Generics.ExecutionTime = metasFromFile.ExecutionTime;
jobData.Metadata.Customs = metasFromFile.Customs;
}
}
}
return jobData;
}
public static SCADA_MEM_TYPE GetMemTypeFromString(string memType)
{
memType = memType.ToUpper();
switch (memType)
{
case "BOOL":
return SCADA_MEM_TYPE.BOOL;
case "BYTE":
return SCADA_MEM_TYPE.BYTE;
case "WORD":
return SCADA_MEM_TYPE.WORD;
case "INT":
return SCADA_MEM_TYPE.INT;
case "REAL":
return SCADA_MEM_TYPE.REAL;
default:
return SCADA_MEM_TYPE.BOOL;
}
}
public static DateTime GetLinkerTime(Assembly assembly, TimeZoneInfo target = null)
{
var filePath = assembly.Location;
const int c_PeHeaderOffset = 60;
const int c_LinkerTimestampOffset = 8;
var buffer = new byte[2048];
using (var stream = new FileStream(filePath, FileMode.Open, FileAccess.Read))
stream.Read(buffer, 0, 2048);
var offset = BitConverter.ToInt32(buffer, c_PeHeaderOffset);
var secondsSince1970 = BitConverter.ToInt32(buffer, offset + c_LinkerTimestampOffset);
var epoch = new DateTime(1970, 1, 1, 0, 0, 0, DateTimeKind.Utc);
var linkTimeUtc = epoch.AddSeconds(secondsSince1970);
var tz = target ?? TimeZoneInfo.Local;
var localTime = TimeZoneInfo.ConvertTimeFromUtc(linkTimeUtc, tz);
return localTime;
}
public static string GetSoftwareVersionAndBuildDate()
{
Version v = Assembly.GetEntryAssembly()?.GetName().Version;
if (v != null)
{
// Get first 2 number of the version
var version = v.ToString().Split('.').Take(3).ToArray();
string betaString = IS_BETA ? " BETA " : " ";
// Get Server version
return $"{string.Join(".", version)}" +
betaString +
$"({GetLinkerTime(Assembly.GetEntryAssembly(), null).ToString("d")}" +
$")";
}
return "";
}
public static Boolean DecodeCMSConnectGatewayLogin(string encryptedString, out string login, out string password)
{
login = "";
password = "";
//Check if is null
if (String.IsNullOrEmpty(encryptedString))
return false;
//Decode it
String decodedLogin = StringCipher.Decrypt(encryptedString, CMSCONNECT_TOKEN);
//Check if contains the Space
if (!decodedLogin.Contains(" "))
return false;
//Split it and check
String[] tempLogin = decodedLogin.Split(' ');
if (tempLogin.Length != 2)
return false;
//Set the variable
login = tempLogin[0];
password = tempLogin[1];
return true;
}
public static Boolean EncodeCMSConnectGatewayLogin(out string encryptedString, string login, string password)
{
encryptedString = "";
//Check if contains the Space
if (String.IsNullOrEmpty(login) || login.Contains(" "))
return false;
//Check if contains the Space
if (String.IsNullOrEmpty(password) || password.Contains(" "))
return false;
encryptedString = StringCipher.Encrypt(login + " " + password, CMSCONNECT_TOKEN);
return true;
}
public static string ConvertIntToAsciiString(int integer)
{
string outputString = "";
for (int i = 3; i >= 0; i--)
{
outputString += (char)((byte)(integer >> (8 * i)));
}
return outputString;
}
public static int ConvertAsciiStringToInt(string asciiString)
{
int number = 0;
for (int i = 1; i <= asciiString.Count(); i++)
number += asciiString[asciiString.Count() - i] << (8 * (i - 1));
return number;
}
public static void ConvertStringMachineNumberIntoNumber(string machineNumber, out bool containsLetters, out int intMachineVal)
{
intMachineVal = 0;
containsLetters = Regex.IsMatch(machineNumber, @".*?[a-zA-Z].*?");
if (string.IsNullOrEmpty(machineNumber))
{
machineNumber = "0000";
}
if (containsLetters)
// Convert ASCII string to a single INT
intMachineVal = SupportFunctions.ConvertAsciiStringToInt(machineNumber);
else
// Convert string of digits to a INT
intMachineVal = int.Parse(machineNumber);
}
//----- Chipher Private Class ---------------------------------
#region Chipher_Private_Class
private static class StringCipher
{
// This constant is used to determine the keysize of the encryption algorithm in bits.
// We divide this by 8 within the code below to get the equivalent number of bytes.
private const int Keysize = 256;
// This constant determines the number of iterations for the password bytes generation function.
private const int DerivationIterations = 1000;
public static string Encrypt(string plainText, string passPhrase)
{
// Salt and IV is randomly generated each time, but is preprended to encrypted cipher text
// so that the same Salt and IV values can be used when decrypting.
var saltStringBytes = Generate256BitsOfRandomEntropy();
var ivStringBytes = Generate256BitsOfRandomEntropy();
var plainTextBytes = Encoding.UTF8.GetBytes(plainText);
using (var password = new Rfc2898DeriveBytes(passPhrase, saltStringBytes, DerivationIterations))
{
var keyBytes = password.GetBytes(Keysize / 8);
using (var symmetricKey = new RijndaelManaged())
{
symmetricKey.BlockSize = 256;
symmetricKey.Mode = CipherMode.CBC;
symmetricKey.Padding = PaddingMode.PKCS7;
using (var encryptor = symmetricKey.CreateEncryptor(keyBytes, ivStringBytes))
{
using (var memoryStream = new MemoryStream())
{
using (var cryptoStream = new CryptoStream(memoryStream, encryptor, CryptoStreamMode.Write))
{
cryptoStream.Write(plainTextBytes, 0, plainTextBytes.Length);
cryptoStream.FlushFinalBlock();
// Create the final bytes as a concatenation of the random salt bytes, the random iv bytes and the cipher bytes.
var cipherTextBytes = saltStringBytes;
cipherTextBytes = cipherTextBytes.Concat(ivStringBytes).ToArray();
cipherTextBytes = cipherTextBytes.Concat(memoryStream.ToArray()).ToArray();
memoryStream.Close();
cryptoStream.Close();
return Convert.ToBase64String(cipherTextBytes);
}
}
}
}
}
}
public static string Decrypt(string cipherText, string passPhrase)
{
// Get the complete stream of bytes that represent:
// [32 bytes of Salt] + [32 bytes of IV] + [n bytes of CipherText]
var cipherTextBytesWithSaltAndIv = Convert.FromBase64String(cipherText);
// Get the saltbytes by extracting the first 32 bytes from the supplied cipherText bytes.
var saltStringBytes = cipherTextBytesWithSaltAndIv.Take(Keysize / 8).ToArray();
// Get the IV bytes by extracting the next 32 bytes from the supplied cipherText bytes.
var ivStringBytes = cipherTextBytesWithSaltAndIv.Skip(Keysize / 8).Take(Keysize / 8).ToArray();
// Get the actual cipher text bytes by removing the first 64 bytes from the cipherText string.
var cipherTextBytes = cipherTextBytesWithSaltAndIv.Skip((Keysize / 8) * 2).Take(cipherTextBytesWithSaltAndIv.Length - ((Keysize / 8) * 2)).ToArray();
using (var password = new Rfc2898DeriveBytes(passPhrase, saltStringBytes, DerivationIterations))
{
var keyBytes = password.GetBytes(Keysize / 8);
using (var symmetricKey = new RijndaelManaged())
{
symmetricKey.BlockSize = 256;
symmetricKey.Mode = CipherMode.CBC;
symmetricKey.Padding = PaddingMode.PKCS7;
using (var decryptor = symmetricKey.CreateDecryptor(keyBytes, ivStringBytes))
{
using (var memoryStream = new MemoryStream(cipherTextBytes))
{
using (var cryptoStream = new CryptoStream(memoryStream, decryptor, CryptoStreamMode.Read))
{
var plainTextBytes = new byte[cipherTextBytes.Length];
var decryptedByteCount = cryptoStream.Read(plainTextBytes, 0, plainTextBytes.Length);
memoryStream.Close();
cryptoStream.Close();
return Encoding.UTF8.GetString(plainTextBytes, 0, decryptedByteCount);
}
}
}
}
}
}
private static byte[] Generate256BitsOfRandomEntropy()
{
var randomBytes = new byte[32]; // 32 Bytes will give us 256 bits.
using (var rngCsp = new RNGCryptoServiceProvider())
{
// Fill the array with cryptographically secure random bytes.
rngCsp.GetBytes(randomBytes);
}
return randomBytes;
}
}
#endregion
}
}