438 lines
16 KiB
C#
438 lines
16 KiB
C#
using System;
|
|
using System.Collections.Generic;
|
|
using System.Data.SqlClient;
|
|
using System.IO;
|
|
using System.Linq;
|
|
using System.Runtime.Serialization.Formatters.Binary;
|
|
using System.Text;
|
|
using System.Xml;
|
|
using System.Xml.Schema;
|
|
using System.Xml.Serialization;
|
|
using DASFactoryDb.Config;
|
|
using DTS.Common.Interface.DASFactory;
|
|
using DTS.Common.Interface.DASFactory.Config;
|
|
using DTS.Common.Utilities.Logging;
|
|
|
|
namespace DTS.DASLib.Service
|
|
{
|
|
/// <summary>
|
|
/// Each IDASCommunication will have an instance of this class. It provides information
|
|
/// about the configuration of the DAS as a whole with regards to the current test/event.
|
|
/// The ConfigData object in an IDASCommunication will contain arrays representing the
|
|
/// specific modules and channels therein, of which the configurations may be set and
|
|
/// retrieved through the ConfigurationData object.
|
|
/// </summary>
|
|
[Serializable]
|
|
[XmlInclude(typeof(DASChannel))]
|
|
[XmlInclude(typeof(InputDASChannel))]
|
|
[XmlInclude(typeof(AnalogInputDASChannel))]
|
|
//[XmlInclude(typeof(DigitalInputDASChannel))]
|
|
[XmlInclude(typeof(OutputDASChannel))]
|
|
[XmlInclude(typeof(AnalogOutputDASChannel))]
|
|
[XmlInclude(typeof(DigitalOutputDASChannel))]
|
|
public class ConfigurationData : IConfigurationData, IXmlSerializable
|
|
{
|
|
/// <summary>
|
|
/// Array of Module objects in the DAS.
|
|
/// </summary>
|
|
public IDASModule[] Modules { get; set; }
|
|
|
|
/// <summary>
|
|
/// EID's for the whole DAS.
|
|
/// </summary>
|
|
[XmlIgnore]
|
|
public IEID[] IDs { get; set; }
|
|
|
|
/// <summary>
|
|
/// The ID of the current test/event.
|
|
/// </summary>
|
|
public string TestID { get; set; }
|
|
public string TestSetupUniqueId { get; set; }
|
|
|
|
/// <summary>
|
|
/// The ID of an instance of a test run, for the purpose
|
|
/// of identifying where to download data.
|
|
/// </summary>
|
|
public string InstanceID { get; set; }
|
|
|
|
/// <summary>
|
|
/// A description of the current test/event.
|
|
/// </summary>
|
|
public string Description { get; set; }
|
|
[XmlIgnore()]
|
|
public bool ClearSetup { get; set; } = false;
|
|
/// <summary>
|
|
/// Counts how many channels are configured. If a channel's
|
|
/// 'IsConfigured' property is 'true' it is configured.
|
|
/// </summary>
|
|
/// <returns>Number of configured channels</returns>
|
|
public int NumberOfConfiguredChannels()
|
|
{
|
|
if (Modules == null || Modules.Length == 0)
|
|
return 0;
|
|
return Modules.Sum(module => module.NumberOfConfiguredChannels());
|
|
}
|
|
|
|
/// <summary>
|
|
/// Count how many channels we have (regardless if they are configured or not).
|
|
/// </summary>
|
|
/// <returns>Total number of channels</returns>
|
|
public int NumberOfChannels()
|
|
{
|
|
if (Modules == null || Modules.Length == 0)
|
|
return 0;
|
|
return Modules.Sum(module => module.NumberOfChannels());
|
|
}
|
|
|
|
/// <summary>
|
|
/// Count how many downloadable channels (i.e. not UART, StreamOut, etc.) we have (regardless if they are configured or not).
|
|
/// </summary>
|
|
/// <returns>Total number of downloadable channels</returns>
|
|
public int NumberOfDownloadChannels()
|
|
{
|
|
if (Modules == null || Modules.Length == 0)
|
|
return 0;
|
|
return Modules.Where(module => !module.IsStreamOut() && !module.IsUart()).Sum(module => module.NumberOfChannels());
|
|
}
|
|
public ConfigurationData()
|
|
{
|
|
Modules = null;
|
|
IDs = null;
|
|
TestID = "";
|
|
TestSetupUniqueId = null;
|
|
Description = "Default Test ID";
|
|
InstanceID = null;
|
|
}
|
|
public int[] DisplayOrder { get; set; } = new int[] { -1 };
|
|
public int DasDisplayOrder { get; set; } = -1;
|
|
|
|
public int GetDisplayOrder(uint channelIdx)
|
|
{
|
|
if (channelIdx >= DisplayOrder.Length) { return -1; }
|
|
else { return DisplayOrder[channelIdx]; }
|
|
}
|
|
|
|
#region Serialization functions
|
|
|
|
/// <summary>
|
|
/// Serialize configuration data to a file
|
|
/// </summary>
|
|
/// <param name="file">File name to write to</param>
|
|
/// <param name="config">The configuration to serialize</param>
|
|
public static void Serialize(string file, ConfigurationData config)
|
|
{
|
|
System.Xml.Serialization.XmlSerializer xs = new System.Xml.Serialization.XmlSerializer(config.GetType());
|
|
|
|
StreamWriter writer = File.CreateText(file);
|
|
|
|
xs.Serialize(writer, config);
|
|
|
|
writer.Flush();
|
|
writer.Close();
|
|
}
|
|
|
|
/// <summary>
|
|
/// Serialize configuration data to a string
|
|
/// </summary>
|
|
/// <param name="config">The configuration to serialize</param>
|
|
/// <returns>The serialized data in XML form</returns>
|
|
public static string Serialize(ConfigurationData config)
|
|
{
|
|
System.Xml.Serialization.XmlSerializer xs = new System.Xml.Serialization.XmlSerializer(config.GetType());
|
|
|
|
StringWriter writer = new StringWriter();
|
|
System.Xml.XmlWriterSettings xmlsettings = new System.Xml.XmlWriterSettings();
|
|
xmlsettings.NewLineChars = "";
|
|
System.Xml.XmlWriter xmlwriter = System.Xml.XmlWriter.Create(writer, xmlsettings);
|
|
|
|
try
|
|
{
|
|
xs.Serialize(xmlwriter, config);
|
|
}
|
|
catch (Exception ex)
|
|
{
|
|
APILogger.Log(ex); // Maybe useful for forensics?
|
|
APILogger.Log($"Current writer buffer:{writer.ToString()}");
|
|
|
|
// http://manuscript.dts.local/f/cases/26802/Fail-on-serialization-error-for-XML-config-data
|
|
writer.Flush();
|
|
writer.Close();
|
|
throw;
|
|
}
|
|
|
|
writer.Flush();
|
|
writer.Close();
|
|
var xmlStr = writer.ToString();
|
|
return xmlStr;
|
|
}
|
|
|
|
/// <summary>
|
|
/// Serialize configuration data to a binary block
|
|
/// </summary>
|
|
/// <param name="config">The configuration to serialize</param>
|
|
/// <returns>The serialized data in binary form</returns>
|
|
public static byte[] SerializeBin(ConfigurationData config)
|
|
{
|
|
BinaryFormatter bf = new BinaryFormatter();
|
|
byte[] bytes;
|
|
using (MemoryStream ms = new MemoryStream())
|
|
{
|
|
bf.Serialize(ms, config);
|
|
ms.Seek(0, 0);
|
|
bytes = ms.ToArray();
|
|
}
|
|
return bytes;
|
|
}
|
|
|
|
/// <summary>
|
|
/// Deserialize an XML string into a new configuration object
|
|
/// </summary>
|
|
/// <param name="SerializedText">The XML data</param>
|
|
/// <returns>A new configuration object</returns>
|
|
public static ConfigurationData DeserializeFromString(string SerializedText)
|
|
{
|
|
if (string.IsNullOrEmpty(SerializedText)) { return null; }
|
|
|
|
XmlSerializer xs = new System.Xml.Serialization.XmlSerializer(typeof(ConfigurationData));
|
|
|
|
StringReader reader = new StringReader(SerializedText);
|
|
try
|
|
{
|
|
ConfigurationData config = (ConfigurationData)xs.Deserialize(reader);
|
|
return config;
|
|
}
|
|
catch (Exception ex)
|
|
{
|
|
APILogger.Log("Failed to read config", ex);
|
|
}
|
|
finally
|
|
{
|
|
reader.Close();
|
|
}
|
|
return null;
|
|
}
|
|
|
|
/// <summary>
|
|
/// Deserialize from an XML file to a configuration object
|
|
/// </summary>
|
|
/// <param name="file">The file name to read from</param>
|
|
/// <returns>A new configuration object</returns>
|
|
public static ConfigurationData Deserialize(string file)
|
|
{
|
|
var xs = new XmlSerializer(typeof(ConfigurationData));
|
|
|
|
if (File.Exists(file))
|
|
{
|
|
APILogger.Log("reading 67 ", file);
|
|
using (StreamReader reader = File.OpenText(file))
|
|
{
|
|
var c = (ConfigurationData)xs.Deserialize(reader);
|
|
reader.Close();
|
|
return c;
|
|
}
|
|
|
|
}
|
|
else
|
|
{
|
|
return new ConfigurationData();
|
|
}
|
|
}
|
|
|
|
public virtual void WriteXml(XmlWriter writer)
|
|
{
|
|
//writer.WriteStartElement("ConfigurationData");
|
|
// <ConfigurationData xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsd="http://www.w3.org/2001/XMLSchema">
|
|
writer.WriteAttributeString("xmlns", "xsi", null, "http://www.w3.org/2001/XMLSchema-instance");
|
|
writer.WriteAttributeString("xmlns", "xsd", null, "http://www.w3.org/2001/XMLSchema");
|
|
|
|
|
|
// Modules
|
|
writer.WriteStartElement("Modules");
|
|
if (Modules != null)
|
|
{
|
|
foreach (var module in Modules)
|
|
{
|
|
module.WriteXml(writer);
|
|
}
|
|
}
|
|
writer.WriteEndElement();
|
|
|
|
// TestID
|
|
XMLHelper.PutString(writer, "TestID", TestID);
|
|
|
|
// Description
|
|
XMLHelper.PutString(writer, "Description", Description);
|
|
|
|
// TestSetupUniqueId
|
|
XMLHelper.PutString(writer, "TestSetupUniqueId", TestSetupUniqueId);
|
|
|
|
// InstanceID
|
|
XMLHelper.PutString(writer, "InstanceID", InstanceID);
|
|
|
|
XMLHelper.PutString(writer, "UDPReceiveAddress", UDPReceiveAddress);
|
|
//writer.WriteEndElement();
|
|
}
|
|
|
|
private void DumpXml(XmlReader reader)
|
|
{
|
|
using (var writer = new StreamWriter("xmldump.txt"))
|
|
{
|
|
while (reader.Read())
|
|
{
|
|
string n, t, v;
|
|
try
|
|
{
|
|
n = reader.Name;
|
|
if (string.IsNullOrEmpty(n))
|
|
{
|
|
n = "<null>";
|
|
}
|
|
}
|
|
catch
|
|
{
|
|
n = "<no-name>";
|
|
}
|
|
try
|
|
{
|
|
t = reader.NodeType.ToString();
|
|
if (string.IsNullOrEmpty(t))
|
|
{
|
|
t = "<null>";
|
|
}
|
|
}
|
|
catch
|
|
{
|
|
t = "<no-type>";
|
|
}
|
|
try
|
|
{
|
|
v = reader.Value;
|
|
if (string.IsNullOrEmpty(v))
|
|
{
|
|
v = "<null>";
|
|
}
|
|
}
|
|
catch
|
|
{
|
|
v = "<no-value>";
|
|
}
|
|
writer.WriteLine("Name: " + n + " Type: " + t + " Value: " + v);
|
|
}
|
|
}
|
|
}
|
|
private const string CONFIG_START_TAG = "ConfigurationData";
|
|
private const string MODULES_START_TAG = "Modules";
|
|
private const string DASMODULE_START_TAG = "DASModule";
|
|
private const string TESTID_START_TAG = "TestID";
|
|
private const string DESCRIPTION_START_TAG = "Description";
|
|
|
|
private List<string> KNOWN_STARTING_TAGS = new List<string>(new[] { CONFIG_START_TAG, MODULES_START_TAG, DASMODULE_START_TAG, TESTID_START_TAG, DESCRIPTION_START_TAG });
|
|
|
|
private void ReadModules(XmlReader reader)
|
|
{
|
|
var myModules = new List<DASModule>();
|
|
var keepGoing = reader.ReadToFollowing(DASMODULE_START_TAG);
|
|
while (keepGoing)
|
|
{
|
|
var deserializedModule = new DASModule();
|
|
deserializedModule.ReadXml(reader);
|
|
myModules.Add(deserializedModule);
|
|
|
|
if (reader.Name == MODULES_START_TAG && reader.NodeType == XmlNodeType.EndElement)
|
|
{
|
|
keepGoing = false;
|
|
}
|
|
else
|
|
{
|
|
keepGoing = reader.Name == DASMODULE_START_TAG && reader.NodeType == XmlNodeType.Element || reader.ReadToFollowing(DASMODULE_START_TAG);
|
|
}
|
|
}
|
|
Modules = myModules.ToArray();
|
|
}
|
|
public virtual void ReadXml(XmlReader reader)
|
|
{
|
|
// it must be an Element
|
|
if (reader.NodeType != XmlNodeType.Element)
|
|
{
|
|
throw new XmlException("ConfigurationData.ReadXml: Unknown input: " + reader.NodeType.ToString());
|
|
}
|
|
|
|
// remove our start tag
|
|
if (reader.Name == CONFIG_START_TAG)
|
|
{
|
|
reader.Read();
|
|
}
|
|
else
|
|
{
|
|
while (reader.Name != CONFIG_START_TAG)
|
|
{
|
|
reader.Read();
|
|
}
|
|
}
|
|
|
|
// try to find our data
|
|
do
|
|
{
|
|
if (reader.NodeType != XmlNodeType.Element) { continue; }
|
|
switch (reader.Name)
|
|
{
|
|
case "Modules": // DASModule[]
|
|
ReadModules(reader);
|
|
break;
|
|
case "TestID":
|
|
TestID = XMLHelper.GetString(reader);
|
|
break;
|
|
case "Description":
|
|
Description = XMLHelper.GetString(reader);
|
|
break;
|
|
case "TestSetupUniqueId":
|
|
TestSetupUniqueId = XMLHelper.GetString(reader);
|
|
break;
|
|
case "InstanceID":
|
|
InstanceID = XMLHelper.GetString(reader);
|
|
break;
|
|
case "UDPReceiveAddress":
|
|
UDPReceiveAddress = XMLHelper.GetString(reader);
|
|
break;
|
|
default:
|
|
break;
|
|
//throw new XmlException("ConfigurationData.ReadXml: Unknown tag: " + reader.Name);
|
|
//return;
|
|
}
|
|
} while (reader.Read());
|
|
|
|
// we're going to end with an EndElement, so clean up
|
|
if (reader.NodeType == XmlNodeType.EndElement)
|
|
{
|
|
reader.Read();
|
|
}
|
|
}
|
|
|
|
public XmlSchema GetSchema()
|
|
{
|
|
return null;
|
|
}
|
|
|
|
#endregion
|
|
|
|
public const int DIAGNOSTIC_FILESTORE = 0;
|
|
public const int EVENT_FILE_STORE = 1;
|
|
/// <summary>
|
|
/// writes the current configuration to the db if available
|
|
/// </summary>
|
|
public static void SetConfiguration(IDASCommunication das, string xml, int fileStore)
|
|
{
|
|
if (!DASFactoryDb.DbWrapper.Connected) { return; }
|
|
try
|
|
{
|
|
Config.SetConfiguration(das.RecordId, xml, fileStore);
|
|
}
|
|
catch (Exception ex)
|
|
{
|
|
APILogger.Log(ex);
|
|
}
|
|
}
|
|
public string UDPReceiveAddress { get; set; } = "UDP://239.1.2.10:8401";
|
|
}
|
|
}
|