diff --git a/Autosar-Configurator.csproj b/Autosar-Configurator.csproj
index fa6a0cd..a0a4a19 100644
--- a/Autosar-Configurator.csproj
+++ b/Autosar-Configurator.csproj
@@ -29,13 +29,20 @@
+
+
+
+
-
- lib\EcucBaseCore.dll
+
+ lib\Autosar.dll
+
+
+ lib\XObjectsCore.dll
diff --git a/EcucBase/EcucBase.cs b/EcucBase/EcucBase.cs
new file mode 100644
index 0000000..0ae99d4
--- /dev/null
+++ b/EcucBase/EcucBase.cs
@@ -0,0 +1,643 @@
+/*
+ * This file is a part of Autosar Configurator for ECU GUI based
+ * configuration, checking and code generation.
+ *
+ * Copyright (C) 2021-2022 DJS Studio E-mail:DD-Silence@sina.cn
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+
+ * You should have received a copy of the GNU General Public License
+ * along with this program. If not, see .
+ */
+
+using Autosar;
+using Ecuc.EcucBase.EData;
+using Ecuc.EcucBase.EInstance;
+using System.ComponentModel;
+using System.Runtime.CompilerServices;
+using System.Runtime.InteropServices;
+
+namespace Ecuc.EcucBase.EBase
+{
+ ///
+ /// INotifyPropertyChanged abstaract to avoid type property name
+ ///
+ public class NotifyPropertyChangedBase : INotifyPropertyChanged
+ {
+ public event PropertyChangedEventHandler? PropertyChanged;
+
+ public void RaisePropertyChanged([CallerMemberName] string propertyName = "")
+ {
+ PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(propertyName));
+ }
+ }
+
+ ///
+ /// Asr Class represent a single arxml file
+ ///
+ public class Asr
+ {
+ ///
+ /// File name of arxml file.
+ ///
+ private string FileName { get; } = "";
+ ///
+ /// Whether arxml model is modified or not.
+ ///
+ private bool isDirty = false;
+ ///
+ /// Converted data model of arxml file.
+ ///
+ public AUTOSAR? Model { get; } = null;
+ ///
+ /// Packages of Autosar in arxml file.
+ ///
+ public List ArPackages { get; } = new List();
+ ///
+ /// ECUC modules in arxml file.
+ ///
+ public List Modules { get; } = new List();
+ ///
+ /// Dictionary between Autosar path and converted model.
+ ///
+ public Dictionary AsrPathModelDict { get; } = new Dictionary();
+
+ ///
+ /// Whether arxml model is modified or not.
+ ///
+ public bool IsDirty
+ {
+ get
+ {
+ return isDirty;
+ }
+ set
+ {
+ if (value != IsDirty)
+ {
+ isDirty = value;
+ // dirty from true to false shall tranfer to all modules
+ if (value == false)
+ {
+ foreach (var module in Modules)
+ {
+ module.IsDirty = false;
+ }
+ }
+ }
+ }
+ }
+
+ ///
+ /// Initialze Asr from filename.
+ /// File will be converted to data model. All Autosar packages will be extracted.
+ /// Autosar path dictionary will be generated.
+ ///
+ /// Filename of file want to be converted.
+ public Asr(string filename)
+ {
+ FileName = filename;
+ Model = AUTOSAR.Load(filename);
+
+ if (Model != null)
+ {
+ // get all autosar packages
+ FindAllArPackage();
+ // iterate all elements to generate Autosar path dictionary
+ CreateAsrPath();
+ }
+ }
+
+ ///
+ /// Iterate all ARPACKAGE and ARPACKAGES tag to get all Autosar package from Model.
+ /// ARPACKAGES tag can have ARPACKAGE member and ARPACKAGE tag can have ARPACKAGES member.
+ /// All ARPACKAGES and ARPACKAGE tag shall be checked to find all Autosar packages.
+ ///
+ private void FindAllArPackage()
+ {
+ if (Model == null)
+ {
+ return;
+ }
+
+ var query = from package in Model.ARPACKAGES.ARPACKAGE
+ select package;
+ query.ToList().ForEach(x =>
+ {
+ if (x.ARPACKAGES != null)
+ {
+ // Tag ARPACKAGE has ARPACKAGES member, step deeper.
+ FindAllArPackage(x);
+ }
+ // Tag ARPACKAGE has no ARPACKAGES member, get it.
+ ArPackages.Add(x);
+ });
+ }
+
+ ///
+ /// Iterate all ARPACKAGE and ARPACKAGES tag to get all Autosar package from ARPACKAGE.
+ ///
+ /// Autosar package to be checked
+ private void FindAllArPackage(ARPACKAGE arPackage)
+ {
+ var query = from package in arPackage.ARPACKAGES.ARPACKAGE
+ select package;
+ query.ToList().ForEach(x =>
+ {
+ if (x.ARPACKAGES != null)
+ {
+ // Tag ARPACKAGE has ARPACKAGES member, step deeper.
+ FindAllArPackage(x);
+ }
+ // Tag ARPACKAGE has no ARPACKAGES member, get it.
+ ArPackages.Add(x);
+ });
+ }
+
+ ///
+ /// Iterate all tag in Model to genereate Autosar path dictionary.
+ /// Any tag has SHORTNAME member can be treated as a dictionary.
+ /// SHORTNAME with seperator "/" from top can idenfify tags in Model.
+ /// as directory path in file system.
+ ///
+ private void CreateAsrPath()
+ {
+ string asrPath = "";
+ if (Model != null)
+ {
+ // start from top with ARPACKAGES tag
+ CreateAsrPath(Model.ARPACKAGES, asrPath);
+ }
+ }
+
+ ///
+ /// Iterate all tag in model to genereate Autosar path dictionary.
+ /// Any tag has SHORTNAME member can be treated as a dictionary.
+ /// SHORTNAME with seperator "/" from top can idenfify tags in Model.
+ ///
+ /// model to be checked
+ /// current Autosar path
+ private void CreateAsrPath(object model, string asrPath)
+ {
+ // Reflect all properties to get SHORTNAME in model
+ foreach (var prop in model.GetType().GetProperties())
+ {
+ if (prop.Name == "SHORTNAME")
+ {
+ // Property with member "SHORTNAME"
+ if (prop.GetValue(model) is IDENTIFIER identifier)
+ {
+ // It is an IDENTIFIER instance, generate new path and put it into dictionary
+ asrPath += $"/{identifier.TypedValue}";
+ AsrPathModelDict.Add(asrPath, model);
+ }
+ }
+ }
+
+ // Reflect all properties to decide it is needed to check deeper
+ foreach (var prop in model.GetType().GetProperties())
+ {
+ if ((prop.PropertyType.Namespace == "Autosar") || (prop.PropertyType.Namespace == "System.Collections.Generic"))
+ {
+ // Property with namespace "Autosar" or it is a Generic Collection instance
+ var v = prop.GetValue(model);
+ if ((v != null) && (prop.Name != "SHORTNAME"))
+ {
+ // Property is not null and not "SHORTNAME"
+ if (v is IEnumerable valueList)
+ {
+ // Property is a Generic Collection instance, check each member deeper
+ foreach (var v2 in valueList)
+ {
+ CreateAsrPath(v2, asrPath);
+ }
+ }
+ else
+ {
+ // Property is not Generic Collection instance, check it deeper
+ CreateAsrPath(v, asrPath);
+ }
+ }
+ }
+ }
+ }
+
+ ///
+ /// Save model to file.
+ /// After save, all module shall make IsDirty to false.
+ ///
+ public void Save()
+ {
+ if (FileName != "" && Model != null)
+ {
+ Model.Save(FileName);
+ IsDirty = false;
+ }
+ }
+ }
+
+ ///
+ /// Ecuc solve action handler delegate to invalid data.
+ ///
+ /// Ecuc data to solve invalid.
+ public delegate void EcucSolveHandler(EcucData data, object? param);
+
+ ///
+ /// Ecuc solve class.
+ ///
+ public class EcucSolve
+ {
+ ///
+ /// Description of solve.
+ ///
+ public string Description { get; }
+ ///
+ /// Handler to solve invalid data.
+ ///
+ public EcucSolveHandler Handler { get; set; }
+ ///
+ /// Ecuc valid this solve belong to.
+ ///
+ public EcucValid Valid { get; }
+
+ ///
+ /// Paramter for solve opearation.
+ ///
+ private readonly object? parameter;
+
+ ///
+ /// Initialize Ecuc solve class.
+ ///
+ /// Description of invalid solve.
+ /// Handler of invalid solve.
+ /// Ecuc valid this solve belong to.
+ /// Parameter for solve operation.
+ public EcucSolve(string desc, EcucSolveHandler handler, EcucValid valid, object? param = null)
+ {
+ Description = desc;
+ Handler = handler;
+ Valid = valid;
+ parameter = param;
+ }
+
+ ///
+ /// Solve the valid problem.
+ ///
+ public void Solve()
+ {
+ // Only solve Ecuc valid with data
+ if (Valid.Data != null)
+ {
+ try
+ {
+ // Use handler to solve problem
+ Handler(Valid.Data, parameter);
+ // Change valid to true
+ Valid.UpdateValidStatus(true);
+ }
+ catch
+ {
+ Console.WriteLine($"Solve {Description} failed");
+ }
+ }
+ }
+ }
+
+ ///
+ /// Ecuc valid class.
+ /// Describe valid status, invalid reason and solve actions.
+ ///
+ public class EcucValid : NotifyPropertyChangedBase
+ {
+ ///
+ /// Valid status.
+ ///
+ private bool valid;
+ ///
+ /// Invalid reason.
+ ///
+ private string invalidReason;
+
+ ///
+ /// Instance of this valid belong to.
+ ///
+ public IEcucInstanceBase Instance { get; }
+
+ ///
+ /// Data of this valid belong to.
+ ///
+ public EcucData? Data { get; private set; }
+
+ ///
+ /// Solves to solve problem.
+ ///
+ public List Solves { get; private set; } = new();
+
+ ///
+ /// Valid status.
+ ///
+ public bool ValidStatus
+ {
+ get
+ {
+ return valid;
+ }
+ }
+
+ ///
+ /// Invalid reason.
+ ///
+ public string InvalidReason
+ {
+ get
+ {
+ return invalidReason;
+ }
+ }
+
+ ///
+ /// Recursice valid from this level to bottom.
+ ///
+ public List ValidRecursive
+ {
+ get
+ {
+ var result = new List();
+ // Module asks containers
+ if (Instance is EcucInstanceModule instanceModule)
+ {
+ foreach (var container in instanceModule.Containers)
+ {
+ if (container.Valid.ValidRecursive.Count > 0)
+ {
+ result.AddRange(container.Valid.ValidRecursive);
+ }
+ }
+ }
+
+ // Container asks containers, parameters and references
+ if (Instance is EcucInstanceContainer instanceContainer)
+ {
+ foreach (var container in instanceContainer.Containers)
+ {
+ if (container.Valid.ValidRecursive.Count > 0)
+ {
+ result.AddRange(container.Valid.ValidRecursive);
+ }
+ }
+ foreach (var para in instanceContainer.Paras)
+ {
+ if (para.Valid.ValidRecursive.Count > 0)
+ {
+ result.AddRange(para.Valid.ValidRecursive);
+ }
+ }
+ foreach (var reference in instanceContainer.Refs)
+ {
+ if (reference.Valid.ValidRecursive.Count > 0)
+ {
+ result.AddRange(reference.Valid.ValidRecursive);
+ }
+ }
+ }
+
+ if (valid == false)
+ {
+ // If self valid is false, add self
+ result.Add(this);
+ }
+ return result;
+ }
+ }
+
+ ///
+ /// Valid infomation.
+ ///
+ public string Info
+ {
+ get
+ {
+ return Instance switch
+ {
+ IEcucInstanceModule module => $"{module.AsrPath}: {InvalidReason}",
+ IEcucInstanceParam param => $"{Instance.BswmdPathShort}@{param.Parent.AsrPath}: {InvalidReason}",
+ IEcucInstanceReference reference => $"{Instance.BswmdPathShort}@{reference.Parent.AsrPath}: {InvalidReason}",
+ _ => throw new Exception($"Invalid instance type {Instance.GetType()}"),
+ };
+ }
+ }
+
+ ///
+ /// Initialize Ecuc valid class.
+ ///
+ /// Instance of this valid belong to.
+ /// Valid status.
+ /// Invalid reason.
+ public EcucValid(IEcucInstanceBase instance, bool v = true, string vReason = "")
+ {
+ Instance = instance;
+ valid = v;
+ if (v == false)
+ {
+ invalidReason = vReason;
+ }
+ else
+ {
+ // ignore vReason when valid status is true
+ invalidReason = "";
+ }
+ }
+
+ ///
+ /// Change data of this valid belong to.
+ ///
+ /// Data of this valid belong to.
+ public void UpdateData(EcucData data)
+ {
+ Data = data;
+ }
+
+ ///
+ /// Change valid status and invalid reason.
+ ///
+ /// Valid status.
+ /// Invalid status.
+ public void UpdateValidStatus(bool v, string vReason = "")
+ {
+ if (v == true)
+ {
+ if (valid == false)
+ {
+ // Valid status from false to true
+ valid = true;
+ invalidReason = "";
+ RaisePropertyChanged("Valid");
+ }
+ }
+ else
+ {
+ if (valid == true)
+ {
+ // Valid status from true to false
+ valid = false;
+ invalidReason = vReason;
+ RaisePropertyChanged("Valid");
+ }
+ else
+ {
+ // Valid status from false to false
+ if (invalidReason != vReason)
+ {
+ invalidReason = vReason;
+ RaisePropertyChanged("Valid");
+ }
+ }
+ }
+ }
+
+ ///
+ /// Add solve to valid.
+ ///
+ /// Descrption of solve.
+ /// Handler of solve.
+ /// Parameter of solve operation.
+ public void UpdateSolve(string desc, EcucSolveHandler handler, object? param = null)
+ {
+ Solves.Add(new EcucSolve(desc, handler, this, param));
+ }
+
+ ///
+ /// Change solves of valid.
+ ///
+ /// Solves to change.
+ public void UpdateSolve(List solves)
+ {
+ Solves = solves;
+ }
+
+ ///
+ /// Clear all solves.
+ ///
+ public void ClearSolve()
+ {
+ Solves.Clear();
+ }
+
+ ///
+ /// Execute solver.
+ ///
+ ///
+ public void Solve(int index)
+ {
+ if (Data != null)
+ {
+ if (index < Solves.Count && index >= 0)
+ {
+ // Run handler and update status
+ Solves[index].Solve();
+ UpdateValidStatus(true);
+ }
+ }
+ }
+ }
+
+ public class EcucIdRangeCheck
+ {
+ readonly SortedDictionary> IdDict = new();
+
+ public void Add(Int64 id, EcucData data)
+ {
+ try
+ {
+ if (!IdDict.ContainsKey(id))
+ {
+ IdDict.Add(id, new());
+ }
+ IdDict[id].Add(data);
+ }
+ catch
+ {
+ Console.WriteLine($"Id range add fail when add data with id {id}");
+ }
+ }
+
+ public void Check()
+ {
+ Int64 expected = 0;
+ Int64 suggested = 0;
+
+ foreach (var pair in IdDict)
+ {
+ if (pair.Key < 0)
+ {
+ Console.WriteLine($"Id is negtive.");
+ foreach (var data in pair.Value)
+ {
+ data.UpdateValidStatus(false, $"Id is negtive.");
+ data.ClearValidSolve();
+ data.UpdateValidSolve($"Rearrange Id to {suggested}", IdRerangeHandler, suggested);
+ suggested++;
+ }
+ }
+ else if (pair.Value.Count > 1)
+ {
+ Console.WriteLine($"Id is not unique ({pair.Key}).");
+ foreach (var data in pair.Value)
+ {
+ data.UpdateValidStatus(false, $"Id is not unique.");
+ data.ClearValidSolve();
+ data.UpdateValidSolve($"Rearrange Id to {suggested}", IdRerangeHandler, suggested);
+ suggested++;
+ }
+ }
+ else if (pair.Key != expected)
+ {
+ Console.WriteLine($"Id is not consecutive.");
+ foreach (var data in pair.Value)
+ {
+ data.UpdateValidStatus(false, $"Id is not consecutive.");
+ data.ClearValidSolve();
+ data.UpdateValidSolve($"Rearrange Id to {suggested}", IdRerangeHandler, suggested);
+ suggested++;
+ }
+ }
+ else
+ {
+ foreach (var data in pair.Value)
+ {
+ if (expected != suggested)
+ {
+ Console.WriteLine($"Id shall be re-arranged.");
+ data.UpdateValidStatus(false, $"Id shall be re-arranged.");
+ data.ClearValidSolve();
+ data.UpdateValidSolve($"Rearrange Id to {suggested}", IdRerangeHandler, suggested);
+ }
+ else
+ {
+ data.UpdateValidStatus(true);
+ data.ClearValidSolve();
+ }
+ expected++;
+ suggested++;
+ }
+ }
+ }
+ }
+
+ private void IdRerangeHandler(EcucData data, object? idSuggest)
+ {
+ if (idSuggest is Int64 id)
+ {
+ data.Value = id.ToString();
+ }
+ }
+ }
+}
diff --git a/EcucBase/EcucBswmd.cs b/EcucBase/EcucBswmd.cs
new file mode 100644
index 0000000..cc584b2
--- /dev/null
+++ b/EcucBase/EcucBswmd.cs
@@ -0,0 +1,1836 @@
+/*
+ * This file is a part of Autosar Configurator for ECU GUI based
+ * configuration, checking and code generation.
+ *
+ * Copyright (C) 2021-2022 DJS Studio E-mail:DD-Silence@sina.cn
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+
+ * You should have received a copy of the GNU General Public License
+ * along with this program. If not, see .
+ */
+
+using Ecuc.EcucBase.EBase;
+using Autosar;
+using System.Numerics;
+
+namespace Ecuc.EcucBase.EBswmd
+{
+ ///
+ /// ECU Configuration BSW Module Description (EcucBswmd) interface.
+ /// Base interface of all kind of BSW Module Description interface.
+ ///
+ public interface IEcucBswmdBase
+ {
+ ///
+ /// Model of EcucBswmd.
+ ///
+ IArEcucBswmdBase Model { get; }
+ ///
+ /// Manager of this class..
+ ///
+ EcucBswmdManager Manager { get; }
+ ///
+ /// ShortName of EcucBswmd module.
+ ///
+ string ShortName { get; }
+ ///
+ /// Description of EcucBswmd module.
+ ///
+ string Desc { get; }
+ ///
+ /// Trace of EcucBswmd module.
+ ///
+ string Trace { get; }
+ ///
+ /// Smallest quantity of EcucBswmd can exist in Bswmd module.
+ ///
+ uint Lower { get; }
+ ///
+ /// Biggest quantity of EcucBswmd can exist in Bswmd module.
+ ///
+ uint Upper { get; }
+ ///
+ /// Autosar path of refined module from standard.
+ ///
+ string RefinedPath { get; }
+ ///
+ /// Autosar path of Bswmd module.
+ ///
+ string AsrPath { get; }
+ ///
+ /// Short form of AsrPath.
+ ///
+ string AsrPathShort { get; }
+ ///
+ /// Whether this is a multiply EcucBswmd.
+ /// Multiply means biggest quantity can be more than 1
+ ///
+ bool IsMultiply { get; }
+ ///
+ /// Whether this is a single EcucBswmd.
+ /// Single means biggest quantity can only be 1
+ ///
+ bool IsSingle { get; }
+ ///
+ /// Whether this is a single EcucBswmd.
+ /// Single means biggest quantity can only be 1
+ ///
+ bool IsRequired { get; }
+
+ ///
+ /// Get EcucBswmd from BswmdPath.
+ /// BswmdPath is Autosar path of EcucBswmd.
+ /// It usually comes from EcucInstance DEFINITION-REF tag.
+ ///
+ /// BswmdPath of EcucBswmd to be got.
+ /// If bswmdPath is "", this will be returned.
+ /// EcucBswmd has Autosar path of bswmdPath
+ /// Can not find EcucBswmd has Autosar path of bswmdPath
+ IEcucBswmdBase GetBswmdFromBswmdPath(string bswmdPath);
+ }
+
+ public class EcucBswmdBase : IEcucBswmdBase
+ {
+ ///
+ /// Model of EcucBswmd
+ ///
+ public IArEcucBswmdBase Model { get; protected set; }
+ ///
+ /// Root data model of EcucBswmd.
+ ///
+ public EcucBswmdManager Manager { get; protected set; }
+
+ ///
+ /// ShortName of EcucBswmd module.
+ ///
+ public string ShortName => Model.SHORTNAME.TypedValue;
+
+ ///
+ /// Description of EcucBswmd module.
+ ///
+ public string Desc
+ {
+ get
+ {
+ var result = "";
+
+ try
+ {
+ foreach (var d in Model.DESC.L2)
+ {
+ result += d.Untyped.Value;
+ }
+ foreach (var p in Model.INTRODUCTION.P)
+ {
+ result += $"{Environment.NewLine}{p.Untyped.Value}";
+ }
+ }
+ catch
+ {
+ result = "";
+ }
+
+ return result;
+ }
+ }
+
+ ///
+ /// Trace of EcucBswmd module.
+ ///
+ public string Trace
+ {
+ get
+ {
+ var result = "";
+
+ try
+ {
+ foreach (var t in Model.INTRODUCTION.TRACE)
+ {
+ foreach (var l4 in t.LONGNAME.L4)
+ {
+ result += $"{l4.Untyped.Value} ";
+ }
+ }
+ }
+ catch
+ {
+ result = "";
+ }
+
+ return result;
+ }
+ }
+
+ ///
+ /// Smallest quantity of EcucBswmd can exist in Bswmd module.
+ ///
+ public uint Lower => uint.Parse(Model.LOWERMULTIPLICITY.Untyped.Value);
+
+ ///
+ /// Biggest quantity of EcucBswmd can exist in Bswmd module.
+ ///
+ public uint Upper
+ {
+ get
+ {
+ if (Model.UPPERMULTIPLICITYINFINITE != null)
+ {
+ return uint.MaxValue;
+ }
+ else
+ {
+ try
+ {
+ return uint.Parse(Model.UPPERMULTIPLICITY.Untyped.Value);
+ }
+ catch
+ {
+ return uint.MaxValue;
+ }
+ }
+ }
+ }
+
+ ///
+ /// Autosar path of refined module from standard.
+ ///
+ public string RefinedPath { get; protected set; }
+
+ ///
+ /// Autosar path of Bswmd module.
+ ///
+ public string AsrPath
+ {
+ get
+ {
+ try
+ {
+ return Manager.AsrRawAsrPathDict[Model];
+ }
+ catch
+ {
+ throw new Exception($"Can not find Autosar model {Model}");
+ }
+ }
+ }
+
+ ///
+ /// Short form of AsrPath.
+ ///
+ public string AsrPathShort
+ {
+ get
+ {
+ var parts = AsrPath.Split('/');
+ if (parts.Length > 0)
+ {
+ return parts[^1];
+ }
+ return "";
+ }
+ }
+
+ ///
+ /// Whether this is a multiply EcucBswmd.
+ /// Multiply means biggest quantity can be more than 1
+ ///
+ public bool IsMultiply => Upper > 1;
+
+ ///
+ /// Whether this is a single EcucBswmd.
+ /// Single means biggest quantity can only be 1
+ ///
+ public bool IsSingle => Upper == 1;
+
+ ///
+ /// Whether this is a single EcucBswmd.
+ /// Single means biggest quantity can only be 1
+ ///
+ public bool IsRequired => Lower != 0;
+
+ ///
+ /// Get EcucBswmd from BswmdPath.
+ /// BswmdPath is Autosar path of EcucBswmd.
+ /// It usually comes from EcucInstance DEFINITION-REF tag.
+ ///
+ /// BswmdPath of EcucBswmd to be got.
+ /// If bswmdPath is "", this will be returned.
+ /// EcucBswmd has Autosar path of bswmdPath
+ /// Can not find EcucBswmd has Autosar path of bswmdPath
+ public IEcucBswmdBase GetBswmdFromBswmdPath(string bswmdPath)
+ {
+ if (bswmdPath == "")
+ {
+ // bswmdPath is "", return this
+ return this;
+ }
+ else
+ {
+ try
+ {
+ // get EcucBswmd from Root
+ return Manager.AsrPathBswmdDict[bswmdPath];
+ }
+ catch
+ {
+ throw new Exception($"Can not find bswmd with path {bswmdPath}");
+ }
+ }
+ }
+
+ public EcucBswmdBase(IArEcucBswmdBase model, EcucBswmdManager manager)
+ {
+ Model = model;
+ Manager = manager;
+ RefinedPath = "";
+ }
+ }
+
+ ///
+ /// Bswmd module interface
+ /// Base interface of all kind of Bswmd class with Containers member.
+ ///
+ public interface IEcucBswmdModule : IEcucBswmdBase
+ {
+ ///
+ /// Containers in EcucBswmd.
+ ///
+ List Containers { get; }
+ }
+
+ ///
+ /// Bswmd container interface
+ /// Base interface of all kind of Bswmd class with Containers, Parameters and References member.
+ ///
+ public interface IEcucBswmdContainer : IEcucBswmdModule
+ {
+ ///
+ /// Parent EcucBswmd.
+ /// Parent shall be EcucBswmd with Containers member.
+ ///
+ IEcucBswmdModule Parent { get; }
+ ///
+ /// Parameters in EcucBswmd.
+ ///
+ List Paras { get; }
+ ///
+ /// References in EcucBswmd.
+ ///
+ List Refs { get; }
+ }
+
+ ///
+ /// Bswmd parameter interface
+ /// Base interface of all kind of Bswmd parameter in Bswmd container.
+ ///
+ public interface IEcucBswmdParam : IEcucBswmdBase
+ {
+ ///
+ /// Parent EcucBswmd.
+ /// Parent shall be EcucBswmd with Containers member.
+ ///
+ public IEcucBswmdModule Parent { get; }
+ }
+
+ ///
+ /// Bswmd reference interface
+ /// Base interface of all kind of Bswmd reference in Bswmd container.
+ ///
+ public interface IEcucBswmdReference : IEcucBswmdBase
+ {
+ ///
+ /// Parent EcucBswmd.
+ /// Parent shall be EcucBswmd with Containers member.
+ ///
+ public IEcucBswmdModule Parent { get; }
+ }
+
+ ///
+ /// EcucBswmd top level manager of several arxml files.
+ /// EcucBswmd elements in several arxml files are combined.
+ ///
+ public class EcucBswmdManager
+ {
+ ///
+ /// Several Asr from several arxml files.
+ ///
+ private readonly List Autosars = new();
+ ///
+ /// EcucBswmd moudles converted from several arxml files.
+ ///
+ public List EcucModules { get; } = new();
+ ///
+ /// Data model to Autosar path dictionary.
+ ///
+ public Dictionary AsrRawAsrPathDict = new();
+ ///
+ /// Autosar path to EcucBswmd dictionary.
+ ///
+ public Dictionary AsrPathBswmdDict = new();
+
+ ///
+ /// Initialize EcucBswmd from several arxml files.
+ ///
+ /// File names of arxml files.
+ public EcucBswmdManager(string[] fileNames)
+ {
+ InitMultiple(fileNames);
+ }
+
+ ///
+ /// Internal procees of Initialization of EcucBswmd from serveral arxml files.
+ ///
+ ///
+ private void InitMultiple(string[] fileNames)
+ {
+ // create one task for each arxml file.
+ var tasks1 = new Task[fileNames.Length];
+ // step 1 to convert arxml file to Asr
+ for (int i = 0; i < fileNames.Length; i++)
+ {
+ tasks1[i] = InitMultipleSingleStep1(fileNames[i]);
+ }
+ Task.WaitAll(tasks1);
+
+ // create one task for each Asr data model.
+ var tasks2 = new Task[Autosars.Count];
+ // step 2 to collect all Autosar path.
+ for (int i = 0; i < Autosars.Count; i++)
+ {
+ tasks2[i] = InitMultipleSingleStep2(Autosars[i]);
+ }
+ Task.WaitAll(tasks2);
+
+ // create one task for each Asr data model.
+ var tasks3 = new Task[Autosars.Count];
+ // step 3 to extract EcucBswmd module.
+ for (int i = 0; i < Autosars.Count; i++)
+ {
+ tasks3[i] = InitMultipleSingleStep3(Autosars[i]);
+ }
+ Task.WaitAll(tasks3);
+ }
+
+ ///
+ /// Step 1 to convert arxml file to Asr
+ ///
+ /// Arxml file name
+ ///
+ private Task InitMultipleSingleStep1(string fileName)
+ {
+ return Task.Run(() =>
+ {
+ var autosar = new Asr(fileName);
+
+ Monitor.Enter(Autosars);
+ try
+ {
+ // collect all Asr data model.
+ Autosars.Add(autosar);
+ }
+ finally
+ {
+ Monitor.Exit(Autosars);
+ }
+
+ List arPackages = new();
+ foreach (var package in autosar.ArPackages)
+ {
+ // collect all ArPackages.
+ arPackages.Add(package);
+ }
+ });
+ }
+
+ ///
+ /// Step 2 to collect all Autosar path.
+ ///
+ /// Asr data model
+ ///
+ private Task InitMultipleSingleStep2(Asr ar)
+ {
+ return Task.Run(() =>
+ {
+ Monitor.Enter(AsrRawAsrPathDict);
+ try
+ {
+ // exchange value and key
+ foreach (var value in ar.AsrPathModelDict)
+ {
+ AsrRawAsrPathDict[value.Value] = value.Key;
+ }
+ }
+ finally
+ {
+ Monitor.Exit(AsrRawAsrPathDict);
+ }
+ });
+ }
+
+ ///
+ /// Step 3 to extract EcucBswmd module.
+ ///
+ /// Asr data model
+ ///
+ private Task InitMultipleSingleStep3(Asr ar)
+ {
+ return Task.Run(() =>
+ {
+ // filter arPackages which has ECUCMODULEDEF member.
+ var query = from package in ar.ArPackages
+ where package.ELEMENTS?.ECUCMODULEDEF != null
+ from ecucModule in package.ELEMENTS.ECUCMODULEDEF
+ select ecucModule;
+
+ Monitor.Enter(EcucModules);
+ try
+ {
+ // convert EcucBswmd module from tag ECUCMODULEDEF
+ query.ToList().ForEach(x => EcucModules.Add(new EcucBswmdModule(x, this, ar)));
+ }
+ finally
+ {
+ Monitor.Exit(EcucModules);
+ }
+ });
+ }
+
+ ///
+ /// Index EcucBswmd module by short name.
+ ///
+ /// Short name of targeted EcucBswmd module
+ /// EcucBswmd module with shortName
+ /// Can not find EcucBswmd module with shortName
+ public EcucBswmdModule this[string shortName]
+ {
+ get
+ {
+ var query = from module in EcucModules
+ where module.ShortName == shortName
+ select module;
+
+ var result = query.ToList();
+ if (result.Count > 0)
+ {
+ return result[0];
+ }
+ else
+ {
+ throw new Exception($"Can not find bswmd module {shortName}");
+ }
+ }
+ }
+
+ ///
+ /// Get EcucBswmd from BswmdPath.
+ /// BswmdPath is Autosar path of EcucBswmd.
+ /// It usually comes from EcucInstance DEFINITION-REF tag.
+ ///
+ /// BswmdPath of EcucBswmd to be got.
+ /// If bswmdPath is "", this will be returned.
+ /// EcucBswmd has Autosar path of bswmdPath
+ /// Can not find EcucBswmd has Autosar path of bswmdPath
+ public IEcucBswmdBase GetBswmdFromBswmdPath(string bswmdPath)
+ {
+ try
+ {
+ return AsrPathBswmdDict[bswmdPath];
+ }
+ catch
+ {
+ throw new Exception($"Can not find bswmd path {bswmdPath}");
+ }
+ }
+ }
+
+ ///
+ /// EcucBswmd module class.
+ /// EcucBswmd module class represent module of ECUCMODULEDEF tag.
+ ///
+ public class EcucBswmdModule : EcucBswmdBase, IEcucBswmdModule
+ {
+ ///
+ /// Containers of EcucBswmd module.
+ ///
+ public List Containers { get; } = new();
+ ///
+ /// Parent Autosar data model.
+ ///
+ public Asr Parent { get; }
+
+ ///
+ /// Local unpacked model
+ ///
+ public ECUCMODULEDEF ModelLocal
+ {
+ get
+ {
+ if (Model is ECUCMODULEDEF modelLocal)
+ {
+ return modelLocal;
+ }
+ else
+ {
+ throw new Exception("Invalid model type");
+ }
+ }
+ }
+
+ ///
+ /// Initialize EcucBswmd module class.
+ ///
+ /// Data model converted from arxml file.
+ /// Manager of this class.
+ /// Autosar data model which contain this EcucBswmd module.
+ public EcucBswmdModule(ECUCMODULEDEF model, EcucBswmdManager manager, Asr parent)
+ : base(model, manager)
+ {
+ Parent = parent;
+ if (ModelLocal.REFINEDMODULEDEFREF != null)
+ {
+ RefinedPath = ModelLocal.REFINEDMODULEDEFREF.Untyped.Value;
+ }
+ else
+ {
+ RefinedPath = "";
+ }
+
+ // Register this to manager
+ Monitor.Enter(Manager.AsrPathBswmdDict);
+ try
+ {
+ Manager.AsrPathBswmdDict[AsrPath] = this;
+ if (RefinedPath != "")
+ {
+ Manager.AsrPathBswmdDict[RefinedPath] = this;
+ }
+ }
+ finally
+ {
+ Monitor.Exit(Manager.AsrPathBswmdDict);
+ }
+
+ // Collect all containers
+ if (ModelLocal.CONTAINERS != null)
+ {
+ if (ModelLocal.CONTAINERS.ECUCPARAMCONFCONTAINERDEF != null)
+ {
+ // parameter container case
+ foreach (var container in ModelLocal.CONTAINERS.ECUCPARAMCONFCONTAINERDEF)
+ {
+ Containers.Add(new EcucBswmdContainer(container, Manager, this, RefinedPath));
+ }
+ }
+
+ if (ModelLocal.CONTAINERS.ECUCCHOICECONTAINERDEF != null)
+ {
+ // choice container case
+ foreach (var container in ModelLocal.CONTAINERS.ECUCCHOICECONTAINERDEF)
+ {
+ Containers.Add(new EcucBswmdChoiceContainer(container, Manager, this, RefinedPath));
+ }
+ }
+ }
+ }
+ }
+
+ ///
+ /// EcucBswmd container class.
+ /// EcucBswmd container class represent tag ECUCPARAMCONFCONTAINERDEF.
+ ///
+ public class EcucBswmdContainer : EcucBswmdBase, IEcucBswmdContainer
+ {
+ ///
+ /// Containers of EcucBswmd container.
+ ///
+ public List Containers { get; } = new();
+ ///
+ /// Parameters of EcucBswmd container.
+ ///
+ public List Paras { get; } = new();
+ ///
+ /// References of EcucBswmd container.
+ ///
+ public List Refs { get; } = new();
+ ///
+ /// Parent EcucBswmd module.
+ ///
+ public IEcucBswmdModule Parent { get; }
+
+ ///
+ /// Local unpacked model
+ ///
+ public ECUCPARAMCONFCONTAINERDEF ModelLocal
+ {
+ get
+ {
+ if (Model is ECUCPARAMCONFCONTAINERDEF modelLocal)
+ {
+ return modelLocal;
+ }
+ else
+ {
+ throw new Exception("Invalid model type");
+ }
+ }
+ }
+
+ ///
+ /// Initialize EcucBswmd container.
+ ///
+ /// Data model convert from arxml.
+ /// Manager of this class.
+ /// Parent EcucBswmd module or container
+ public EcucBswmdContainer(ECUCPARAMCONFCONTAINERDEF model, EcucBswmdManager manager, IEcucBswmdModule parent, string refinedPath)
+ : base(model, manager)
+ {
+ Parent = parent;
+ if (refinedPath == "")
+ {
+ RefinedPath = "";
+ }
+ else
+ {
+ RefinedPath = $"{refinedPath}/{AsrPathShort}";
+ }
+
+ // Register this to manager
+ Monitor.Enter(Manager.AsrPathBswmdDict);
+ try
+ {
+ Manager.AsrPathBswmdDict[AsrPath] = this;
+ if (RefinedPath != "")
+ {
+ Manager.AsrPathBswmdDict[RefinedPath] = this;
+ }
+ }
+ finally
+ {
+ Monitor.Exit(Manager.AsrPathBswmdDict);
+ }
+
+ // Parse EcucBswmd container
+ if (ModelLocal.SUBCONTAINERS != null)
+ {
+ if (ModelLocal.SUBCONTAINERS != null)
+ {
+ if (ModelLocal.SUBCONTAINERS.ECUCPARAMCONFCONTAINERDEF != null)
+ {
+ foreach (var container in ModelLocal.SUBCONTAINERS.ECUCPARAMCONFCONTAINERDEF)
+ {
+ Containers.Add(new EcucBswmdContainer(container, Manager, this, RefinedPath));
+ }
+ }
+
+ if (ModelLocal.SUBCONTAINERS.ECUCCHOICECONTAINERDEF != null)
+ {
+ foreach (var container in ModelLocal.SUBCONTAINERS.ECUCCHOICECONTAINERDEF)
+ {
+ Containers.Add(new EcucBswmdChoiceContainer(container, Manager, this, RefinedPath));
+ }
+ }
+ }
+ }
+
+ // Parse EcucBswmd parameter
+ if (ModelLocal.PARAMETERS != null)
+ {
+ if (ModelLocal.PARAMETERS.ECUCENUMERATIONPARAMDEF != null)
+ {
+ foreach (var para in ModelLocal.PARAMETERS.ECUCENUMERATIONPARAMDEF)
+ {
+ Paras.Add(new EcucBswmdEnumerationPara(para, Manager, this, RefinedPath));
+ }
+ }
+
+ if (ModelLocal.PARAMETERS.ECUCINTEGERPARAMDEF != null)
+ {
+ foreach (var para in ModelLocal.PARAMETERS.ECUCINTEGERPARAMDEF)
+ {
+ Paras.Add(new EcucBswmdIntegerPara(para, Manager, this, RefinedPath));
+ }
+ }
+
+ if (ModelLocal.PARAMETERS.ECUCBOOLEANPARAMDEF != null)
+ {
+ foreach (var para in ModelLocal.PARAMETERS.ECUCBOOLEANPARAMDEF)
+ {
+ Paras.Add(new EcucBswmdBooleanPara(para, Manager, this, RefinedPath));
+ }
+ }
+
+ if (ModelLocal.PARAMETERS.ECUCFLOATPARAMDEF != null)
+ {
+ foreach (var para in ModelLocal.PARAMETERS.ECUCFLOATPARAMDEF)
+ {
+ Paras.Add(new EcucBswmdFloatPara(para, Manager, this, RefinedPath));
+ }
+ }
+
+ if (ModelLocal.PARAMETERS.ECUCSTRINGPARAMDEF != null)
+ {
+ foreach (var para in ModelLocal.PARAMETERS.ECUCSTRINGPARAMDEF)
+ {
+ Paras.Add(new EcucBswmdStringPara(para, Manager, this, RefinedPath));
+ }
+ }
+
+ if (ModelLocal.PARAMETERS.ECUCFUNCTIONNAMEDEF != null)
+ {
+ foreach (var para in ModelLocal.PARAMETERS.ECUCFUNCTIONNAMEDEF)
+ {
+ Paras.Add(new EcucBswmdFunctionNamePara(para, Manager, this, RefinedPath));
+ }
+ }
+ }
+
+ // Parse EcucBswmd reference
+ if (ModelLocal.REFERENCES != null)
+ {
+ if (ModelLocal.REFERENCES.ECUCREFERENCEDEF != null)
+ {
+ foreach (var reference in ModelLocal.REFERENCES.ECUCREFERENCEDEF)
+ {
+ Refs.Add(new EcucBswmdRef(reference, Manager, this, RefinedPath));
+ }
+ }
+
+ if (ModelLocal.REFERENCES.ECUCFOREIGNREFERENCEDEF != null)
+ {
+ foreach (var reference in ModelLocal.REFERENCES.ECUCFOREIGNREFERENCEDEF)
+ {
+ Refs.Add(new EcucBswmdForeignRef(reference, Manager, this, RefinedPath));
+ }
+ }
+
+ if (ModelLocal.REFERENCES.ECUCSYMBOLICNAMEREFERENCEDEF != null)
+ {
+ foreach (var reference in ModelLocal.REFERENCES.ECUCSYMBOLICNAMEREFERENCEDEF)
+ {
+ Refs.Add(new EcucBswmdSymbolicNameRef(reference, Manager, this, RefinedPath));
+ }
+ }
+
+ if (ModelLocal.REFERENCES.ECUCCHOICEREFERENCEDEF != null)
+ {
+ foreach (var reference in ModelLocal.REFERENCES.ECUCCHOICEREFERENCEDEF)
+ {
+ Refs.Add(new EcucBswmdChoiceRef(reference, Manager, this, RefinedPath));
+ }
+ }
+ }
+ }
+ }
+
+ ///
+ /// EcucBswmd choice container.
+ /// Choice container contains several option containers.
+ /// Only one of choice containers can exist in parent container.
+ ///
+ public class EcucBswmdChoiceContainer : EcucBswmdBase, IEcucBswmdContainer
+ {
+ ///
+ /// Containers of EcucBswmd container.
+ ///
+ public List Containers { get; } = new();
+ ///
+ /// Parameters of EcucBswmd container.
+ ///
+ public List Paras { get; } = new();
+ ///
+ /// References of EcucBswmd container.
+ ///
+ public List Refs { get; } = new();
+ ///
+ /// Parent EcucBswmd module.
+ ///
+ public IEcucBswmdModule Parent { get; }
+
+ ///
+ /// Unpacked EcucBswmd choice container.
+ ///
+ public ECUCCHOICECONTAINERDEF ModelLocal
+ {
+ get
+ {
+ if (Model is ECUCCHOICECONTAINERDEF modelLocal)
+ {
+ return modelLocal;
+ }
+ else
+ {
+ throw new Exception("Invalid model type");
+ }
+ }
+ }
+
+ ///
+ /// Initialize EcucBswmd choice container.
+ ///
+ /// Model data converted from arxml.
+ /// Manager of this class.
+ /// Parent EcucBswmd module or container.
+ public EcucBswmdChoiceContainer(ECUCCHOICECONTAINERDEF model, EcucBswmdManager manager, IEcucBswmdModule parent, string refinedPath)
+ : base(model, manager)
+ {
+ Parent = parent;
+ if (refinedPath == "")
+ {
+ RefinedPath = "";
+ }
+ else
+ {
+ RefinedPath = $"{refinedPath}/{AsrPathShort}";
+ }
+
+ // Register this to manager
+ Monitor.Enter(Manager.AsrPathBswmdDict);
+ try
+ {
+ Manager.AsrPathBswmdDict[AsrPath] = this;
+ if (refinedPath != "")
+ {
+ Manager.AsrPathBswmdDict[RefinedPath] = this;
+ }
+ }
+ finally
+ {
+ Monitor.Exit(Manager.AsrPathBswmdDict);
+ }
+
+ // Parse children of EcucBswmd container
+ foreach (var choice in ModelLocal.CHOICES.ECUCPARAMCONFCONTAINERDEF)
+ {
+ if (refinedPath == "")
+ {
+ Containers.Add(new EcucBswmdContainer(choice, Manager, this, refinedPath));
+ }
+ else
+ {
+ Containers.Add(new EcucBswmdContainer(choice, Manager, this, $"{refinedPath}/{AsrPathShort}"));
+ }
+ }
+ }
+ }
+
+ ///
+ /// EcucBswmd parameter of enumeration.
+ /// Enumeration parameter with several candidate value.
+ /// Only oen candidate is chosen as value.
+ ///
+ public class EcucBswmdEnumerationPara : EcucBswmdBase, IEcucBswmdParam
+ {
+ ///
+ /// Candidate strings.
+ ///
+ public List Candidate { get; set; } = new();
+ ///
+ /// Default string.
+ /// Default string shall one of candidate.
+ ///
+ public string Default { get; }
+ ///
+ /// Parent EcucBswmd module.
+ ///
+ public IEcucBswmdModule Parent { get; }
+
+ ///
+ /// Unpacked EcucBswmd choice container.
+ ///
+ public ECUCENUMERATIONPARAMDEF ModelLocal
+ {
+ get
+ {
+ if (Model is ECUCENUMERATIONPARAMDEF modelLocal)
+ {
+ return modelLocal;
+ }
+ else
+ {
+ throw new Exception("Invalid model type");
+ }
+ }
+ }
+
+ ///
+ /// Initi
+ ///
+ /// Data model converted from arxml.
+ /// Manager of this class.
+ /// Parent EcucBswmd container.
+ public EcucBswmdEnumerationPara(ECUCENUMERATIONPARAMDEF model, EcucBswmdManager manager, IEcucBswmdModule parent, string refinedPath)
+ : base(model, manager)
+ {
+ Parent = parent;
+ if (refinedPath == "")
+ {
+ RefinedPath = "";
+ }
+ else
+ {
+ RefinedPath = $"{refinedPath}/{AsrPathShort}";
+ }
+
+ // Register this to manager
+ Monitor.Enter(Manager.AsrPathBswmdDict);
+ try
+ {
+ Manager.AsrPathBswmdDict[AsrPath] = this;
+ if (refinedPath != "")
+ {
+ Manager.AsrPathBswmdDict[RefinedPath] = this;
+ }
+ }
+ finally
+ {
+ Monitor.Exit(Manager.AsrPathBswmdDict);
+ }
+
+ // Parse all candidate values
+ foreach (var literal in ModelLocal.LITERALS.ECUCENUMERATIONLITERALDEF)
+ {
+ Candidate.Add(literal.SHORTNAME.TypedValue);
+ }
+
+ // Parse default value
+ var value = ModelLocal.DEFAULTVALUE;
+ if (value != null)
+ {
+ Default = value.Untyped.Value;
+ }
+ else
+ {
+ if (Candidate.Count > 0)
+ {
+ Default = Candidate[0];
+ }
+ else
+ {
+ Default = "";
+ }
+ }
+ }
+ }
+
+ ///
+ /// EcucBswmd parameter of integer class.
+ ///
+ public class EcucBswmdIntegerPara : EcucBswmdBase, IEcucBswmdParam
+ {
+ ///
+ /// Minimun value of integer.
+ ///
+ public BigInteger Min { get; }
+ ///
+ /// Maxinum value of integer.
+ ///
+ public BigInteger? Max { get; }
+ ///
+ /// Default value of integer.
+ ///
+ public BigInteger Default { get; }
+ ///
+ /// Format of data displayed.
+ /// HEX for 16 digital representation, DEC for 10 digital representation.
+ ///
+ public string Format { get; }
+ ///
+ /// Parent EcucBswmd module.
+ ///
+ public IEcucBswmdModule Parent { get; }
+
+ ///
+ /// Unpacked EcucBswmd choice container.
+ ///
+ public ECUCINTEGERPARAMDEF ModelLocal
+ {
+ get
+ {
+ if (Model is ECUCINTEGERPARAMDEF modelLocal)
+ {
+ return modelLocal;
+ }
+ else
+ {
+ throw new Exception("Invalid model type");
+ }
+ }
+ }
+
+ ///
+ /// Initialize EcucBswmd parameter of integer.
+ ///
+ /// Data model converted from arxml.
+ /// Manager of this class.
+ /// Parent EcucBswmd container.
+ public EcucBswmdIntegerPara(ECUCINTEGERPARAMDEF model, EcucBswmdManager manager, IEcucBswmdModule parent, string refinedPath)
+ : base(model, manager)
+ {
+ Parent = parent;
+ if (refinedPath == "")
+ {
+ RefinedPath = "";
+ }
+ else
+ {
+ RefinedPath = $"{refinedPath}/{AsrPathShort}";
+ }
+
+ // Register this to manager
+ Monitor.Enter(Manager.AsrPathBswmdDict);
+ try
+ {
+ Manager.AsrPathBswmdDict[AsrPath] = this;
+ if (refinedPath != "")
+ {
+ Manager.AsrPathBswmdDict[RefinedPath] = this;
+ }
+ }
+ finally
+ {
+ Monitor.Exit(Manager.AsrPathBswmdDict);
+ }
+
+ // Parse mininum value
+ try
+ {
+ Min = BigInteger.Parse(ModelLocal.MIN.Untyped.Value);
+ }
+ catch
+ {
+ Min = 0;
+ }
+
+ // Parse maximun value if exist
+ if (ModelLocal.MAX == null)
+ {
+ Max = null;
+ }
+ else if (ModelLocal.MAX.Untyped.Value == "*")
+ {
+ Max = null;
+ }
+ else
+ {
+ Max = BigInteger.Parse(ModelLocal.MAX.Untyped.Value);
+ }
+
+ // Parse default value
+ var value = ModelLocal.DEFAULTVALUE;
+ if (value != null)
+ {
+ if (value.Untyped.Value == "")
+ {
+ Default = Min;
+ }
+ else
+ {
+ Default = BigInteger.Parse(value.Untyped.Value);
+ }
+ }
+ else
+ {
+ Default = Min;
+ }
+
+ // Parse format
+ var format = ModelLocal.ADMINDATA;
+ if (format != null)
+ {
+ var formats = format.SDGS.SDG;
+ foreach (var f in formats)
+ {
+ if (f.GID == "DV:Display")
+ {
+ var formats2 = f.SD;
+ foreach (var f2 in formats2)
+ {
+ if (f2.GID == "DV:DefaultFormat")
+ {
+ Format = f2.Untyped.Value;
+ }
+ }
+ }
+ }
+ }
+
+ // Check format at last
+ if (Format == null)
+ {
+ Format = "";
+ }
+ }
+ }
+
+ ///
+ /// EcucBswmd parameter of boolean.
+ ///
+ public class EcucBswmdBooleanPara : EcucBswmdBase, IEcucBswmdParam
+ {
+ ///
+ /// Default value.
+ /// false or true
+ ///
+ public bool Default { get; }
+ ///
+ /// Parent EcucBswmd module.
+ ///
+ public IEcucBswmdModule Parent { get; }
+
+ ///
+ /// Unpacked EcucBswmd choice container.
+ ///
+ public ECUCBOOLEANPARAMDEF ModelLocal
+ {
+ get
+ {
+ if (Model is ECUCBOOLEANPARAMDEF modelLocal)
+ {
+ return modelLocal;
+ }
+ else
+ {
+ throw new Exception("Invalid model type");
+ }
+ }
+ }
+
+ ///
+ /// Initialize EcucBswmd boolean parameter.
+ ///
+ /// Model data converted form arxml.
+ /// Manager of this class.
+ /// Parent EcucBswmd container.
+ public EcucBswmdBooleanPara(ECUCBOOLEANPARAMDEF model, EcucBswmdManager manager, IEcucBswmdModule parent, string refinedPath)
+ : base(model, manager)
+ {
+ Parent = parent;
+ if (refinedPath == "")
+ {
+ RefinedPath = "";
+ }
+ else
+ {
+ RefinedPath = $"{refinedPath}/{AsrPathShort}";
+ }
+
+ // Register this to manager
+ Monitor.Enter(Manager.AsrPathBswmdDict);
+ try
+ {
+ Manager.AsrPathBswmdDict[AsrPath] = this;
+ if (refinedPath != "")
+ {
+ Manager.AsrPathBswmdDict[RefinedPath] = this;
+ }
+ }
+ finally
+ {
+ Monitor.Exit(Manager.AsrPathBswmdDict);
+ }
+
+ // Parse default value
+ var value = ModelLocal.DEFAULTVALUE;
+ try
+ {
+ if (value.Untyped.Value == "1")
+ {
+ Default = true;
+ }
+ else if (value.Untyped.Value == "0")
+ {
+ Default = false;
+ }
+ else
+ {
+ Default = bool.Parse(value.Untyped.Value);
+ }
+ }
+ catch
+ {
+ Default = false;
+ }
+ }
+ }
+
+ ///
+ /// EcucBswmd parameter of float.
+ ///
+ public class EcucBswmdFloatPara : EcucBswmdBase, IEcucBswmdParam
+ {
+ ///
+ /// Default value.
+ ///
+ public double Default { get; }
+ ///
+ /// Parent EcucBswmd module.
+ ///
+ public IEcucBswmdModule Parent { get; }
+
+ ///
+ /// Unpacked EcucBswmd choice container.
+ ///
+ public ECUCFLOATPARAMDEF ModelLocal
+ {
+ get
+ {
+ if (Model is ECUCFLOATPARAMDEF modelLocal)
+ {
+ return modelLocal;
+ }
+ else
+ {
+ throw new Exception("Invalid model type");
+ }
+ }
+ }
+
+ ///
+ /// Initialize EcucBswmd float parameter.
+ ///
+ /// Model data converted from arxml.
+ /// Manager of this class.
+ /// Parent EcucBswmd container.
+ public EcucBswmdFloatPara(ECUCFLOATPARAMDEF model, EcucBswmdManager manager, IEcucBswmdModule parent, string refinedPath)
+ : base(model, manager)
+ {
+ Parent = parent;
+ if (refinedPath == "")
+ {
+ RefinedPath = "";
+ }
+ else
+ {
+ RefinedPath = $"{refinedPath}/{AsrPathShort}";
+ }
+
+ // Register this to manager
+ Monitor.Enter(Manager.AsrPathBswmdDict);
+ try
+ {
+ Manager.AsrPathBswmdDict[AsrPath] = this;
+ if (refinedPath != "")
+ {
+ Manager.AsrPathBswmdDict[RefinedPath] = this;
+ }
+ }
+ finally
+ {
+ Monitor.Exit(Manager.AsrPathBswmdDict);
+ }
+
+ // Parse default value
+ var value = ModelLocal.DEFAULTVALUE;
+ try
+ {
+ Default = double.Parse(value.Untyped.Value);
+ }
+ catch
+ {
+ Default = 0.0f;
+ }
+ }
+ }
+
+ ///
+ /// EcucBswmd parameter of string.
+ ///
+ public class EcucBswmdStringPara : EcucBswmdBase, IEcucBswmdParam
+ {
+ ///
+ /// Default value.
+ ///
+ public List Default { get; } = new();
+ ///
+ /// Parent EcucBswmd module.
+ ///
+ public IEcucBswmdModule Parent { get; }
+
+ ///
+ /// Unpacked EcucBswmd choice container.
+ ///
+ public ECUCSTRINGPARAMDEF ModelLocal
+ {
+ get
+ {
+ if (Model is ECUCSTRINGPARAMDEF modelLocal)
+ {
+ return modelLocal;
+ }
+ else
+ {
+ throw new Exception("Invalid model type");
+ }
+ }
+ }
+
+ ///
+ ///
+ ///
+ /// Model data converted from arxml.
+ /// Manager of this class.
+ /// Parent EcucBswmd container.
+ public EcucBswmdStringPara(ECUCSTRINGPARAMDEF model, EcucBswmdManager manager, IEcucBswmdModule parent, string refinedPath)
+ : base(model, manager)
+ {
+ Parent = parent;
+ if (refinedPath == "")
+ {
+ RefinedPath = "";
+ }
+ else
+ {
+ RefinedPath = $"{refinedPath}/{AsrPathShort}";
+ }
+
+ // Register this to manager.
+ Monitor.Enter(Manager.AsrPathBswmdDict);
+ try
+ {
+ Manager.AsrPathBswmdDict[AsrPath] = this;
+ if (refinedPath != "")
+ {
+ Manager.AsrPathBswmdDict[RefinedPath] = this;
+ }
+ }
+ finally
+ {
+ Monitor.Exit(Manager.AsrPathBswmdDict);
+ }
+
+ // Parse default strings
+ if (ModelLocal.ECUCSTRINGPARAMDEFVARIANTS != null)
+ {
+ foreach (var variant in ModelLocal.ECUCSTRINGPARAMDEFVARIANTS.ECUCSTRINGPARAMDEFCONDITIONAL)
+ {
+ if (variant.DEFAULTVALUE != null)
+ {
+ Default.Add(variant.DEFAULTVALUE.Untyped.Value);
+ }
+ }
+ }
+ }
+ }
+
+ ///
+ /// EcucBswmd paramter of function name.
+ ///
+ public class EcucBswmdFunctionNamePara : EcucBswmdBase, IEcucBswmdParam
+ {
+ ///
+ /// Default value.
+ ///
+ public List Default { get; } = new();
+ ///
+ /// Parent EcucBswmd module.
+ ///
+ public IEcucBswmdModule Parent { get; }
+
+ ///
+ /// Unpacked EcucBswmd choice container.
+ ///
+ public ECUCFUNCTIONNAMEDEF ModelLocal
+ {
+ get
+ {
+ if (Model is ECUCFUNCTIONNAMEDEF modelLocal)
+ {
+ return modelLocal;
+ }
+ else
+ {
+ throw new Exception("Invalid model type");
+ }
+ }
+ }
+
+ ///
+ /// Initialize EcucBswmd function name parameter.
+ ///
+ /// Model data converted from arxml.
+ /// Manager of this class.
+ /// Parent of EcucBswmd container.
+ public EcucBswmdFunctionNamePara(ECUCFUNCTIONNAMEDEF model, EcucBswmdManager manager, IEcucBswmdModule parent, string refinedPath)
+ : base(model, manager)
+ {
+ Parent = parent;
+ if (refinedPath == "")
+ {
+ RefinedPath = "";
+ }
+ else
+ {
+ RefinedPath = $"{refinedPath}/{AsrPathShort}";
+ }
+
+ // Register this to manager.
+ Monitor.Enter(Manager.AsrPathBswmdDict);
+ try
+ {
+ Manager.AsrPathBswmdDict[AsrPath] = this;
+ if (refinedPath != "")
+ {
+ Manager.AsrPathBswmdDict[RefinedPath] = this;
+ }
+ }
+ finally
+ {
+ Monitor.Exit(Manager.AsrPathBswmdDict);
+ }
+
+ // Parese default values.
+ if (ModelLocal.ECUCFUNCTIONNAMEDEFVARIANTS != null)
+ {
+ foreach (var variant in ModelLocal.ECUCFUNCTIONNAMEDEFVARIANTS.ECUCFUNCTIONNAMEDEFCONDITIONAL)
+ {
+ if (variant.DEFAULTVALUE != null)
+ {
+ Default.Add(variant.DEFAULTVALUE.Untyped.Value);
+ }
+ }
+ }
+
+ if (Default.Count == 0)
+ {
+ Default.Add("");
+ }
+ }
+ }
+
+ ///
+ /// EcucBsemd reference.
+ ///
+ public class EcucBswmdRef : EcucBswmdBase, IEcucBswmdReference
+ {
+ ///
+ /// Parent EcucBswmd module.
+ ///
+ public IEcucBswmdModule Parent { get; }
+
+ ///
+ /// Unpacked EcucBswmd choice container.
+ ///
+ public ECUCREFERENCEDEF ModelLocal
+ {
+ get
+ {
+ if (Model is ECUCREFERENCEDEF modelLocal)
+ {
+ return modelLocal;
+ }
+ else
+ {
+ throw new Exception("Invalid model type");
+ }
+ }
+ }
+
+ ///
+ /// Reference desitination Bswmd path.
+ ///
+ public string DestPath
+ {
+ get
+ {
+ return ModelLocal.DESTINATIONREF.TypedValue;
+ }
+ }
+
+ ///
+ /// Reference desitination tag.
+ ///
+ public string Dest
+ {
+ get
+ {
+ return ModelLocal.DESTINATIONREF.DEST;
+ }
+ }
+
+ ///
+ /// Initialize EcucBswmd reference.
+ ///
+ /// Data model converted from arxml.
+ /// Manager of this class.
+ /// Parent EcucBswmd container.
+ public EcucBswmdRef(ECUCREFERENCEDEF model, EcucBswmdManager manager, IEcucBswmdModule parent, string refinedPath)
+ : base(model, manager)
+ {
+ Parent = parent;
+ if (refinedPath == "")
+ {
+ RefinedPath = "";
+ }
+ else
+ {
+ RefinedPath = $"{refinedPath}/{AsrPathShort}";
+ }
+
+ // Register this to manager.
+ Monitor.Enter(Manager.AsrPathBswmdDict);
+ try
+ {
+ Manager.AsrPathBswmdDict[AsrPath] = this;
+ if (refinedPath != "")
+ {
+ Manager.AsrPathBswmdDict[RefinedPath] = this;
+ }
+ }
+ finally
+ {
+ Monitor.Exit(Manager.AsrPathBswmdDict);
+ }
+ }
+ }
+
+ ///
+ /// EcucBswmd reference from tag other than Ecuc tags.
+ ///
+ public class EcucBswmdForeignRef : EcucBswmdBase, IEcucBswmdReference
+ {
+ ///
+ /// Parent EcucBswmd module.
+ ///
+ public IEcucBswmdModule Parent { get; }
+
+ ///
+ /// Unpacked EcucBswmd choice container.
+ ///
+ public ECUCFOREIGNREFERENCEDEF ModelLocal
+ {
+ get
+ {
+ if (Model is ECUCFOREIGNREFERENCEDEF modelLocal)
+ {
+ return modelLocal;
+ }
+ else
+ {
+ throw new Exception("Invalid model type");
+ }
+ }
+ }
+
+ ///
+ /// Reference desitination tag.
+ ///
+ public string DestType
+ {
+ get
+ {
+ return ModelLocal.DESTINATIONTYPE.TypedValue;
+ }
+ }
+
+ ///
+ /// Initialize
+ ///
+ /// Model data converted from arxml.
+ /// Manager of this class.
+ /// Parent EcucBswmd container.
+ public EcucBswmdForeignRef(ECUCFOREIGNREFERENCEDEF model, EcucBswmdManager manager, IEcucBswmdModule parent, string refinedPath)
+ : base(model, manager)
+ {
+ Parent = parent;
+ if (refinedPath == "")
+ {
+ RefinedPath = "";
+ }
+ else
+ {
+ RefinedPath = $"{refinedPath}/{AsrPathShort}";
+ }
+
+ // Register this to manager.
+ Monitor.Enter(Manager.AsrPathBswmdDict);
+ try
+ {
+ Manager.AsrPathBswmdDict[AsrPath] = this;
+ if (refinedPath != "")
+ {
+ Manager.AsrPathBswmdDict[RefinedPath] = this;
+ }
+ }
+ finally
+ {
+ Monitor.Exit(Manager.AsrPathBswmdDict);
+ }
+ }
+ }
+
+ ///
+ /// EcucBswmd reference of symbolic name.
+ ///
+ public class EcucBswmdSymbolicNameRef : EcucBswmdBase, IEcucBswmdReference
+ {
+ ///
+ /// Parent EcucBswmd module.
+ ///
+ public IEcucBswmdModule Parent { get; }
+
+ ///
+ /// Unpacked EcucBswmd choice container.
+ ///
+ public ECUCSYMBOLICNAMEREFERENCEDEF ModelLocal
+ {
+ get
+ {
+ if (Model is ECUCSYMBOLICNAMEREFERENCEDEF modelLocal)
+ {
+ return modelLocal;
+ }
+ else
+ {
+ throw new Exception("Invalid model type");
+ }
+ }
+ }
+
+ ///
+ /// Reference desitination tag.
+ ///
+ public string Dest
+ {
+ get
+ {
+ return ModelLocal.DESTINATIONREF.DEST;
+ }
+ }
+
+ ///
+ /// Reference desitination desitination tag.
+ ///
+ public string DestPath
+ {
+ get
+ {
+ return ModelLocal.DESTINATIONREF.TypedValue;
+ }
+ }
+
+ ///
+ /// Initialize EcucBswmd symbolic name.
+ ///
+ /// Model data converted from arxml.
+ /// Manager of this class.
+ /// Parent EcucBswmd container.
+ public EcucBswmdSymbolicNameRef(ECUCSYMBOLICNAMEREFERENCEDEF model, EcucBswmdManager manager, IEcucBswmdModule parent, string refinedPath)
+ : base(model, manager)
+ {
+ Parent = parent;
+ if (refinedPath == "")
+ {
+ RefinedPath = "";
+ }
+ else
+ {
+ RefinedPath = $"{refinedPath}/{AsrPathShort}";
+ }
+
+ // Register this to manager.
+ Monitor.Enter(Manager.AsrPathBswmdDict);
+ try
+ {
+ Manager.AsrPathBswmdDict[AsrPath] = this;
+ if (refinedPath != "")
+ {
+ Manager.AsrPathBswmdDict[RefinedPath] = this;
+ }
+ }
+ finally
+ {
+ Monitor.Exit(Manager.AsrPathBswmdDict);
+ }
+ }
+ }
+
+ ///
+ /// EcucBswmd reference of choice reference.
+ ///
+ public class EcucBswmdChoiceRef : EcucBswmdBase, IEcucBswmdReference
+ {
+ ///
+ /// Parent EcucBswmd module.
+ ///
+ public IEcucBswmdModule Parent { get; }
+
+ ///
+ /// Unpacked EcucBswmd choice container.
+ ///
+ public ECUCCHOICEREFERENCEDEF ModelLocal
+ {
+ get
+ {
+ if (Model is ECUCCHOICEREFERENCEDEF modelLocal)
+ {
+ return modelLocal;
+ }
+ else
+ {
+ throw new Exception("Invalid model type");
+ }
+ }
+ }
+
+ ///
+ /// Parse choices reference.
+ ///
+ public Dictionary Choices
+ {
+ get
+ {
+ var result = new Dictionary();
+ foreach (var destRef in ModelLocal.DESTINATIONREFS.DESTINATIONREF)
+ {
+ result[destRef.TypedValue] = destRef.DEST;
+ }
+ return result;
+ }
+ }
+
+ ///
+ /// Initialize EcucBswmd reference of choices.
+ ///
+ /// Model data from converted arxml.
+ /// Manager of this class.
+ /// Parent EcucBswmd container.
+ public EcucBswmdChoiceRef(ECUCCHOICEREFERENCEDEF model, EcucBswmdManager manager, IEcucBswmdModule parent, string refinedPath)
+ : base(model, manager)
+ {
+ Parent = parent;
+ if (refinedPath == "")
+ {
+ RefinedPath = "";
+ }
+ else
+ {
+ RefinedPath = $"{refinedPath}/{AsrPathShort}";
+ }
+
+ // Register this to manager.
+ Monitor.Enter(Manager.AsrPathBswmdDict);
+ try
+ {
+ Manager.AsrPathBswmdDict[AsrPath] = this;
+ if (refinedPath != "")
+ {
+ Manager.AsrPathBswmdDict[RefinedPath] = this;
+ }
+ }
+ finally
+ {
+ Monitor.Exit(Manager.AsrPathBswmdDict);
+ }
+ }
+ }
+}
diff --git a/EcucBase/EcucData.cs b/EcucBase/EcucData.cs
new file mode 100644
index 0000000..0bf5dde
--- /dev/null
+++ b/EcucBase/EcucData.cs
@@ -0,0 +1,2249 @@
+/*
+ * This file is a part of Autosar Configurator for ECU GUI based
+ * configuration, checking and code generation.
+ *
+ * Copyright (C) 2021-2022 DJS Studio E-mail:DD-Silence@sina.cn
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+
+ * You should have received a copy of the GNU General Public License
+ * along with this program. If not, see .
+ */
+
+using Ecuc.EcucBase.EBase;
+using Ecuc.EcucBase.EBswmd;
+using Ecuc.EcucBase.EInstance;
+using System.ComponentModel;
+using System.Numerics;
+
+namespace Ecuc.EcucBase.EData
+{
+ ///
+ /// EcucData multiply status.
+ /// Multiply status is calculated from quantity in instance, lower and upper
+ /// in bswmd. It is represent as int, every status occupy one bit. Several
+ /// status can exist at same time.
+ ///
+ public class EcucDataMultiplyStatus
+ {
+ ///
+ /// Status enumeration
+ ///
+ public enum StatusType
+ {
+ ///
+ /// Fatal error happen during calculation or EcucBswmd upper is 0.
+ ///
+ Invalid = 0,
+ ///
+ /// The quantity is 0.
+ ///
+ Empty = 1,
+ ///
+ /// The quantity is less than lower.
+ ///
+ Lack = 2,
+ ///
+ /// The quantity is same as lower.
+ ///
+ OkLower = 4,
+ ///
+ /// The quantity is bigger than lower and smaller than upper.
+ ///
+ OkMiddle = 8,
+ ///
+ /// The quantity is same as upper.
+ ///
+ OkUpper = 16,
+ ///
+ /// The quantity is bigger than upper.
+ ///
+ Overflow = 32,
+ }
+
+ ///
+ /// Status.
+ ///
+ public StatusType Status { get; }
+
+ ///
+ /// Initialize class by status enumeration.
+ ///
+ ///
+ public EcucDataMultiplyStatus(StatusType status)
+ {
+ Status = status;
+ }
+
+ ///
+ /// Helper property to get whether invalid.
+ ///
+ public bool Invalid => Status == StatusType.Invalid;
+ ///
+ /// Helper property to get whether empty.
+ ///
+ public bool Empty => (Status & StatusType.Empty) == StatusType.Empty;
+ ///
+ /// Helper property to get whether lack.
+ ///
+ public bool Lack => (Status & StatusType.Lack) == StatusType.Lack;
+ ///
+ /// Helper property to get whether okLower.
+ ///
+ public bool OkLower => (Status & StatusType.OkLower) == StatusType.OkLower;
+ ///
+ /// Helper property to get whether okMiddle.
+ ///
+ public bool OkMiddle => (Status & StatusType.OkMiddle) == StatusType.OkMiddle;
+ ///
+ /// Helper property to get whether okUpper.
+ ///
+ public bool OkUpper => (Status & StatusType.OkUpper) == StatusType.OkUpper;
+ ///
+ /// Helper property to get whether overflow.
+ ///
+ public bool Overflow => (Status & StatusType.Overflow) == StatusType.Overflow;
+
+ ///
+ /// Helper property to get whether can add more.
+ ///
+ public bool CanAdd => !OkUpper && !Overflow && !Invalid;
+ ///
+ /// Helper property to get whether can remove one.
+ ///
+ public bool CanRemove => !Lack && !OkLower && !Invalid;
+ ///
+ /// Helper property to get whether ok.
+ ///
+ public bool Ok => OkLower || OkMiddle || OkUpper;
+ ///
+ /// Helper property to get whether not ok.
+ ///
+ public bool NotOk => !Ok;
+ }
+
+ ///
+ /// Ecuc data class.
+ /// Ecuc data integrate EcucInstance and EcucBswmd. From EcucData, quantity of instance
+ /// can be evalutaed. Add and Remove operation can also be evaluated by MultiplyStatus.
+ ///
+ public class EcucData : NotifyPropertyChangedBase
+ {
+ ///
+ /// EcucInstance.
+ ///
+ private IEcucInstanceBase Instance { get; }
+ ///
+ /// EcucBswmd.
+ ///
+ private IEcucBswmdBase Bswmd { get; }
+
+ ///
+ /// Whether data is invalid.
+ ///
+ public bool ValidStatus
+ {
+ get
+ {
+ return Instance.Valid.ValidRecursive.Count == 0;
+ }
+ }
+
+ ///
+ /// Whether data is invalid.
+ ///
+ public string ValidInfo
+ {
+ get
+ {
+ string result = "";
+ foreach (var v in Instance.Valid.ValidRecursive)
+ {
+ result += $"{v.Info}{Environment.NewLine}";
+ }
+ return result;
+ }
+ }
+
+ ///
+ /// Whether data is invalid.
+ ///
+ public List ValidRecursive
+ {
+ get
+ {
+ return Instance.Valid.ValidRecursive;
+ }
+ }
+
+ ///
+ /// Short form of AsrPath
+ ///
+ public string AsrPathShort
+ {
+ get
+ {
+ var parts = AsrPath.Split('/');
+ if (parts.Length > 0)
+ {
+ return parts[^1];
+ }
+ return "";
+ }
+ }
+
+ ///
+ /// Autosar path of EcucInstance as moudle or container.
+ ///
+ public string AsrPath
+ {
+ get
+ {
+ return InstanceAsModule.AsrPath;
+ }
+ }
+
+ ///
+ /// EcucInstance class type.
+ ///
+ public Type InstanceType
+ {
+ get
+ {
+ return Instance.GetType();
+ }
+ }
+
+ ///
+ /// EcucBswmd class type.
+ ///
+ public Type BswmdType
+ {
+ get
+ {
+ return Bswmd.GetType();
+ }
+ }
+
+ ///
+ /// EcucBswmd description.
+ ///
+ public string Desc
+ {
+ get
+ {
+ return Bswmd.Desc;
+ }
+ }
+
+ ///
+ /// EcucBswmd trace.
+ ///
+ public string Trace
+ {
+ get
+ {
+ return Bswmd.Trace;
+ }
+ }
+
+ ///
+ /// EcucBswmd smallest quantity.
+ ///
+ public uint Lower
+ {
+ get
+ {
+ return Bswmd.Lower;
+ }
+ }
+
+ ///
+ /// EcucBswmd biggest quantity.
+ ///
+ public uint Upper
+ {
+ get
+ {
+ return Bswmd.Upper;
+ }
+ }
+
+ ///
+ /// EcucInstance as IEcucInstanceModule.
+ ///
+ private IEcucInstanceModule InstanceAsModule
+ {
+ get
+ {
+ if (Instance is IEcucInstanceModule container)
+ {
+ return container;
+ }
+ else
+ {
+ throw new Exception("Instance of ecuc data is not module kind");
+ }
+ }
+ }
+
+ ///
+ /// EcucBswmd as IEcucBswmdModule.
+ ///
+ private IEcucBswmdModule BswmdAsModule
+ {
+ get
+ {
+ if (Bswmd is IEcucBswmdModule container)
+ {
+ return container;
+ }
+ else
+ {
+ throw new Exception("Bswmd of ecuc data is not module kind");
+ }
+ }
+ }
+
+ ///
+ /// EcucInstance as IEcucInstanceContainer.
+ ///
+ private IEcucInstanceContainer InstanceAsContainer
+ {
+ get
+ {
+ if (Instance is IEcucInstanceContainer container)
+ {
+ return container;
+ }
+ else
+ {
+ throw new Exception("Instance of ecuc data is not container kind");
+ }
+ }
+ }
+
+ ///
+ /// EcucBswmd as IEcucBswmdContainer.
+ ///
+ private IEcucBswmdContainer BswmdAsContainer
+ {
+ get
+ {
+ if (Bswmd is IEcucBswmdContainer container)
+ {
+ return container;
+ }
+ else
+ {
+ throw new Exception("Bswmd of ecuc data is not container kind");
+ }
+ }
+ }
+
+ ///
+ /// EcucBswmd path as well as EcucInstance BswmdPath.
+ ///
+ public string BswmdPath
+ {
+ get
+ {
+ return Bswmd.AsrPath;
+ }
+ }
+
+ ///
+ /// Short form of BswmdPath.
+ ///
+ public string BswmdPathShort
+ {
+ get
+ {
+ return Bswmd.AsrPathShort;
+ }
+ }
+
+ ///
+ /// Continers in EcucInstance
+ ///
+ public List Containers
+ {
+ get
+ {
+ return InstanceAsModule.Containers;
+ }
+ }
+
+ ///
+ /// Parameters in EcucInstance
+ ///
+ public List Paras
+ {
+ get
+ {
+ return InstanceAsContainer.Paras;
+ }
+ }
+
+ ///
+ /// References in EcucInstance
+ ///
+ public List Refs
+ {
+ get
+ {
+ return InstanceAsContainer.Refs;
+ }
+ }
+
+ ///
+ /// Continers in EcucBswmd
+ ///
+ public List BswmdContainers
+ {
+ get
+ {
+ return BswmdAsModule.Containers;
+ }
+ }
+
+ ///
+ /// Parameters in EcucBswmd
+ ///
+ public List BswmdParas
+ {
+ get
+ {
+ return BswmdAsContainer.Paras;
+ }
+ }
+
+ ///
+ /// References in EcucBswmd
+ ///
+ public List BswmdRefs
+ {
+ get
+ {
+ return BswmdAsContainer.Refs;
+ }
+ }
+
+ ///
+ /// The reference point to Autosar path
+ ///
+ public List Usage
+ {
+ get
+ {
+ try
+ {
+ return Instance.GetReferenceByAsrPath(AsrPath);
+ }
+ catch
+ {
+ return new List();
+ }
+ }
+ }
+
+ ///
+ /// Get EcucBswmd from BswmdPath.
+ ///
+ ///
+ ///
+ public IEcucBswmdBase GetBswmdFromBswmdPath(string bswmdPath)
+ {
+ return Bswmd.GetBswmdFromBswmdPath(bswmdPath);
+ }
+
+ ///
+ /// Sort containers in EcucInstance according to IEcucBswmdModule
+ ///
+ public Dictionary SortedContainers
+ {
+ get
+ {
+ var result = new Dictionary();
+ // Iterate bswmd containers in bswmd container
+ foreach (var bswmdSubContainer in BswmdAsModule.Containers)
+ {
+ result[bswmdSubContainer] = new EcucDataList();
+ // Find containers according to bswmd
+ var instanceContainters = InstanceAsModule.FindContainerByBswmd(bswmdSubContainer.AsrPath);
+ // Pack each container to EcucData and then to EcucDataList
+ foreach (var instanceContainter in instanceContainters)
+ {
+ result[bswmdSubContainer].Add(new EcucData(instanceContainter, bswmdSubContainer));
+ }
+ }
+ return result;
+ }
+ }
+
+ ///
+ /// Sort parameters in EcucInstance according to IEcucBswmdParam
+ ///
+ public Dictionary SortedParas
+ {
+ get
+ {
+ var result = new Dictionary();
+ // Iterate bswmd parameters in bswmd container
+ foreach (var bswmdPara in BswmdAsContainer.Paras)
+ {
+ result[bswmdPara] = new EcucDataList();
+ // Find parameters according to bswmd
+ var instanceParas = InstanceAsContainer.FindParaByBswmd(bswmdPara.AsrPath);
+ // Pack each parameter to EcucData and then to EcucDataList
+ foreach (var instancePara in instanceParas)
+ {
+ result[bswmdPara].Add(new EcucData(instancePara, bswmdPara));
+ }
+ }
+ return result;
+ }
+ }
+
+ ///
+ /// Sort references in EcucInstance according to IEcucBswmdReference
+ ///
+ public Dictionary SortedRefs
+ {
+ get
+ {
+ var result = new Dictionary();
+ // Iterate bswmd references in bswmd container
+ foreach (var bswmdRef in BswmdAsContainer.Refs)
+ {
+ result[bswmdRef] = new EcucDataList();
+ // Find references according to bswmd
+ var instanceRefs = InstanceAsContainer.FindRefByBswmd(bswmdRef.AsrPath);
+ // Pack each reference to EcucData and then to EcucDataList
+ foreach (var instanceRef in instanceRefs)
+ {
+ result[bswmdRef].Add(new EcucData(instanceRef, bswmdRef));
+ }
+ }
+ return result;
+ }
+ }
+
+ ///
+ /// Value of EcucData.
+ /// For IEcucInstanceModule, ShortName will be returned.
+ /// For IEcucInstanceParam, Parameter value will be returned.
+ /// For IEcucInstanceReference, Reference valueRef will be returned.
+ ///
+ public string Value
+ {
+ get
+ {
+ switch (Instance)
+ {
+ // For IEcucInstanceModule, ShortName will be returned
+ case IEcucInstanceModule instanceContainer:
+ return instanceContainer.AsrPathShort;
+
+ // For IEcucInstanceParam, further handle is needed
+ case IEcucInstanceParam instancePara:
+ switch (Instance)
+ {
+ // For EcucInstanceNumericalParamValue
+ case EcucInstanceNumericalParamValue:
+ switch (Bswmd)
+ {
+ case EcucBswmdIntegerPara bswmdInteger:
+ // For EcucBswmdIntegerPara
+ switch (bswmdInteger.Format)
+ {
+ // Hex format, 10 base string to integer and then to 16 base string
+ case "HEX":
+ try
+ {
+ return $"0x{Convert.ToInt64(instancePara.Value, 10):X}";
+ }
+ catch
+ {
+ throw new Exception($"Invalid format of value {instancePara.Value}");
+ }
+
+ // Dec format
+ default:
+ return instancePara.Value;
+ }
+
+ case EcucBswmdBooleanPara:
+ // For EcucBswmdBooleanPara
+ if (instancePara.Value == "0")
+ {
+ return "false";
+ }
+ else
+ {
+ return "true";
+ }
+
+ // For others, no need to change
+ default:
+ return instancePara.Value;
+ }
+
+ // For others, no need to change
+ default:
+ return instancePara.Value;
+ }
+
+ // For IEcucInstanceReference, ValueRef will be returned
+ case IEcucInstanceReference instanceRef:
+ return instanceRef.ValueRef;
+
+ default:
+ throw new Exception("invalid instance type");
+ }
+ }
+ set
+ {
+ switch (Instance)
+ {
+ case IEcucInstanceModule instanceContainer:
+ instanceContainer.ShortName = value;
+ break;
+
+ case IEcucInstanceParam instancePara:
+ switch (Instance)
+ {
+ case EcucInstanceNumericalParamValue:
+ switch (Bswmd)
+ {
+ case EcucBswmdIntegerPara bswmdInteger:
+ switch (bswmdInteger.Format)
+ {
+ case "HEX":
+ try
+ {
+ instancePara.Value = Convert.ToInt64(value, 16).ToString();
+ }
+ catch
+ {
+ throw new Exception($"invalid format of value {value}");
+ }
+ break;
+
+ default:
+ instancePara.Value = value;
+ break;
+ }
+ break;
+
+ default:
+ instancePara.Value = value;
+ break;
+ }
+ break;
+
+ default:
+ instancePara.Value = value;
+ break;
+ }
+ break;
+
+ case IEcucInstanceReference instanceRef:
+ instanceRef.ValueRef = value;
+ break;
+
+ default:
+ break;
+ }
+ RaisePropertyChanged();
+ }
+ }
+
+ ///
+ /// Value of EcucData convert to Int64.
+ /// For IEcucInstanceParam, Parameter value with will be returned.
+ ///
+ public Int64 ValueAsInt
+ {
+ get
+ {
+ if (Instance is EcucInstanceNumericalParamValue instancePara && Bswmd is EcucBswmdIntegerPara)
+ {
+ try
+ {
+ return Convert.ToInt64(instancePara.Value, 10);
+ }
+ catch
+ {
+ throw new Exception($"Invalid format of value {instancePara.Value}");
+ }
+ }
+ throw new Exception($"Instance can not convert to integer.");
+ }
+ set
+ {
+ if (Instance is EcucInstanceNumericalParamValue instancePara && Bswmd is EcucBswmdIntegerPara bswmdInteger)
+ {
+ switch (bswmdInteger.Format)
+ {
+ case "HEX":
+ try
+ {
+ instancePara.Value = Convert.ToString(value, 16);
+ }
+ catch
+ {
+ throw new Exception($"invalid format of value {value}");
+ }
+ break;
+
+ default:
+ instancePara.Value = Convert.ToString(value, 10);
+ break;
+ }
+ }
+ RaisePropertyChanged();
+ }
+ }
+
+ public string ValueShort
+ {
+ get
+ {
+ var parts = Value.Split('/');
+ if (parts.Length > 0)
+ {
+ return parts[^1];
+ }
+ return "";
+ }
+ set
+ {
+ var parts = Value.Split('/');
+ parts[^1] = value;
+ Value = string.Join("/", parts);
+ RaisePropertyChanged();
+ }
+ }
+
+ public EcucData(IEcucInstanceBase instance, IEcucBswmdBase bswmd)
+ {
+ Instance = instance;
+ Bswmd = bswmd;
+
+ Instance.PropertyChanged += PropertyChangedEventHandler;
+ }
+
+ public EcucData(EcucInstanceManager isntanceManager, EcucBswmdManager bswmdManager, string name)
+ {
+ var instanceModule = isntanceManager[name];
+ if (instanceModule == null)
+ {
+ throw new Exception($"Can not get instance with name {name}");
+ }
+ var bswmdModule = bswmdManager.GetBswmdFromBswmdPath(instanceModule.BswmdPath);
+ if (bswmdModule == null)
+ {
+ throw new Exception($"Can not get bswmd with path {instanceModule.BswmdPath}");
+ }
+ Instance = instanceModule;
+ Bswmd = bswmdModule;
+ }
+
+ public EcucDataList this[string key]
+ {
+ get
+ {
+ var result = new EcucDataList();
+ if (Bswmd != null)
+ {
+ var bswmdGet = Bswmd.GetBswmdFromBswmdPath($"{Instance.BswmdPath}/{key}");
+ switch (bswmdGet)
+ {
+ case IEcucBswmdModule:
+ {
+ if (Instance is IEcucInstanceModule instanceContainer && Bswmd is IEcucBswmdModule bswmdContainer)
+ {
+ var query = from container in instanceContainer.Containers
+ where container.BswmdPathShort == key
+ select container;
+
+ query.ToList().ForEach(x => result.Add(new EcucData(x, bswmdGet)));
+ }
+ }
+ break;
+
+ case IEcucBswmdParam:
+ {
+ if (Instance is IEcucInstanceContainer instanceOtherContainer && Bswmd is IEcucBswmdContainer bswmdOtherContainer)
+ {
+ var query = from para in instanceOtherContainer.Paras
+ where para.BswmdPathShort == key
+ select para;
+
+ query.ToList().ForEach(x => result.Add(new EcucData(x, bswmdGet)));
+ }
+ }
+ break;
+
+ case IEcucBswmdReference:
+ {
+ if (Instance is IEcucInstanceContainer instanceOtherContainer && Bswmd is IEcucBswmdContainer bswmdOtherContainer)
+ {
+ var query = from reference in instanceOtherContainer.Refs
+ where reference.BswmdPathShort == key
+ select reference;
+
+ query.ToList().ForEach(x => result.Add(new EcucData(x, bswmdGet)));
+ }
+ }
+ break;
+
+ default:
+ break;
+ }
+ }
+ return result;
+ }
+ }
+
+ public EcucDataList this[string key, string name]
+ {
+ get
+ {
+ var result = new EcucDataList();
+ if (Bswmd != null)
+ {
+ var bswmdGet = Bswmd.GetBswmdFromBswmdPath($"{Instance.BswmdPath}/{key}");
+ switch (bswmdGet)
+ {
+ case IEcucBswmdModule:
+ {
+ if (Instance is IEcucInstanceModule instanceContainer && Bswmd is IEcucBswmdModule bswmdContainer)
+ {
+ var query = from container in instanceContainer.Containers
+ where container.BswmdPathShort == key
+ where container.ShortName == name
+ select container;
+
+ query.ToList().ForEach(x => result.Add(new EcucData(x, bswmdGet)));
+ }
+ }
+ break;
+
+ case IEcucBswmdParam:
+ {
+ if (Instance is IEcucInstanceContainer instanceOtherContainer && Bswmd is IEcucBswmdContainer bswmdOtherContainer)
+ {
+ var query = from para in instanceOtherContainer.Paras
+ where para.BswmdPathShort == key
+ select para;
+
+ query.ToList().ForEach(x => result.Add(new EcucData(x, bswmdGet)));
+ }
+ }
+ break;
+
+ case IEcucBswmdReference:
+ {
+ if (Instance is IEcucInstanceContainer instanceOtherContainer && Bswmd is IEcucBswmdContainer bswmdOtherContainer)
+ {
+ var query = from reference in instanceOtherContainer.Refs
+ where reference.BswmdPathShort == key
+ where reference.ValueRefShort == name
+ select reference;
+
+ query.ToList().ForEach(x => result.Add(new EcucData(x, bswmdGet)));
+ }
+ }
+ break;
+
+ default:
+ break;
+ }
+ }
+ return result;
+ }
+ }
+
+ public delegate bool FilterFunc(EcucData data);
+ public EcucDataList this[string key, FilterFunc func]
+ {
+ get
+ {
+ var result = new EcucDataList();
+ if (Bswmd != null)
+ {
+ var bswmdGet = Bswmd.GetBswmdFromBswmdPath($"{Instance.BswmdPath}/{key}");
+ switch (bswmdGet)
+ {
+ case IEcucBswmdModule:
+ {
+ if (Instance is IEcucInstanceModule instanceContainer && Bswmd is IEcucBswmdModule bswmdContainer)
+ {
+ var query = from container in instanceContainer.Containers
+ where container.BswmdPathShort == key
+ where func(new EcucData(container, bswmdGet))
+ select container;
+
+ query.ToList().ForEach(x => result.Add(new EcucData(x, bswmdGet)));
+ }
+ }
+ break;
+
+ case IEcucBswmdParam:
+ {
+ if (Instance is IEcucInstanceContainer instanceOtherContainer && Bswmd is IEcucBswmdContainer bswmdOtherContainer)
+ {
+ var query = from para in instanceOtherContainer.Paras
+ where para.BswmdPathShort == key
+ where func(new EcucData(para, bswmdGet))
+ select para;
+
+ query.ToList().ForEach(x => result.Add(new EcucData(x, bswmdGet)));
+ }
+ }
+ break;
+
+ case IEcucBswmdReference:
+ {
+ if (Instance is IEcucInstanceContainer instanceOtherContainer && Bswmd is IEcucBswmdContainer bswmdOtherContainer)
+ {
+ var query = from reference in instanceOtherContainer.Refs
+ where reference.BswmdPathShort == key
+ where func(new EcucData(reference, bswmdGet))
+ select reference;
+
+ query.ToList().ForEach(x => result.Add(new EcucData(x, bswmdGet)));
+ }
+ }
+ break;
+
+ default:
+ break;
+ }
+ }
+ return result;
+ }
+ }
+
+ private string RecommendedName(string bswmdPathShort)
+ {
+ if (Bswmd is IEcucBswmdModule bswmd && Instance is IEcucInstanceModule instance)
+ {
+ foreach (var bswmdSubContainer in bswmd.Containers)
+ {
+ if (bswmdSubContainer.AsrPathShort == bswmdPathShort)
+ {
+ var instances = instance.FindContainerByBswmd(bswmdSubContainer.AsrPath);
+ bool okFlag = true;
+ var recommendedName = bswmdSubContainer.AsrPathShort;
+
+ foreach (var container in instances)
+ {
+ if (container.ShortName == recommendedName)
+ {
+ okFlag = false;
+ break;
+ }
+ }
+
+ if (okFlag == true)
+ {
+ return recommendedName;
+ }
+
+ for (int i = 0; i < 999; i++)
+ {
+ okFlag = true;
+ recommendedName = $"{bswmdSubContainer.AsrPathShort}_{i:D3}";
+ foreach (var container in instances)
+ {
+ if (container.ShortName == recommendedName)
+ {
+ okFlag = false;
+ break;
+ }
+ }
+
+ if (okFlag == true)
+ {
+ return recommendedName;
+ }
+ }
+ }
+ }
+ throw new Exception("Fail to find recommended name due to every candidate is used");
+ }
+ else
+ {
+ throw new Exception("Fail to find recommended name due to wrong Bswmd or Instance type");
+ }
+ }
+
+ public EcucData AddContainer(string bswmdPathShort)
+ {
+ return AddContainer(bswmdPathShort, RecommendedName(bswmdPathShort));
+ }
+
+ public EcucData AddContainer(string bswmdPathShort, string shortName)
+ {
+ if (Bswmd is IEcucBswmdModule bswmdContainerContainer && Instance is IEcucInstanceModule instanceContainerContainer)
+ {
+ foreach (var bswmd in bswmdContainerContainer.Containers)
+ {
+ if (bswmd.AsrPathShort == bswmdPathShort)
+ {
+ if (GetMultiplyStatus(bswmd.AsrPath).CanAdd == true)
+ {
+ switch (bswmd)
+ {
+ case EcucBswmdContainer:
+ {
+ var instance = instanceContainerContainer.AddContainer(bswmdPathShort, shortName);
+ RaisePropertyChanged();
+ return new EcucData(instance, bswmd);
+ }
+
+ case EcucBswmdChoiceContainer:
+ {
+ var instance = instanceContainerContainer.AddContainer(bswmdPathShort, shortName);
+ RaisePropertyChanged();
+ return new EcucData(instance, bswmd);
+ }
+
+ default:
+ throw new NotImplementedException();
+ }
+ }
+ else
+ {
+ throw new Exception($"Can not add container due to upper limit");
+ }
+ }
+ }
+ throw new Exception($"Unexpected bswmd path {bswmdPathShort}");
+ }
+ else
+ {
+ throw new Exception($"Unexpected bswmd type {Bswmd.GetType()} or instance type {Instance.GetType()}");
+ }
+ }
+
+ public int DelContainer(string bswmdPathShort)
+ {
+ if (Bswmd is IEcucBswmdModule bswmdContainerContainer && Instance is IEcucInstanceModule instanceContainerContainer)
+ {
+ foreach (var bswmd in bswmdContainerContainer.Containers)
+ {
+ if (bswmd.AsrPathShort == bswmdPathShort)
+ {
+ if (bswmd.IsRequired == false)
+ {
+ RaisePropertyChanged();
+ return instanceContainerContainer.DelContainer(bswmd.AsrPath);
+ }
+ else
+ {
+ throw new Exception($"Can not delete container due to this is a required container");
+ }
+ }
+ }
+ throw new Exception($"Can not delete container due to invalid path {bswmdPathShort}");
+ }
+ else
+ {
+ throw new Exception($"Unexpected bswmd type {Bswmd.GetType()} or instance type {Instance.GetType()}");
+ }
+ }
+
+ public int DelContainer(string bswmdPathShort, string shortName)
+ {
+ if (Bswmd is IEcucBswmdModule bswmdContainerContainer && Instance is IEcucInstanceModule instanceContainerContainer)
+ {
+ foreach (var bswmd in bswmdContainerContainer.Containers)
+ {
+ if (bswmd.AsrPathShort == bswmdPathShort)
+ {
+ if (GetMultiplyStatus(bswmd.AsrPath).CanRemove == true)
+ {
+ RaisePropertyChanged();
+ return instanceContainerContainer.DelContainer(bswmd.AsrPath, shortName);
+ }
+ else
+ {
+ throw new Exception($"Can not delete container due to lower limit");
+ }
+ }
+ }
+ throw new Exception($"Can not delete container due to invalid path {bswmdPathShort}");
+ }
+ else
+ {
+ throw new Exception($"Unexpected bswmd type {Bswmd.GetType()} or instance type {Instance.GetType()}");
+ }
+ }
+
+ public EcucData AddContainerWithRequiredField(string bswmdPathShort)
+ {
+ return AddContainerWithRequiredField(bswmdPathShort, RecommendedName(bswmdPathShort));
+ }
+
+ public EcucData AddContainerWithRequiredField(string bswmdPathShort, string shortName)
+ {
+ if (Bswmd is IEcucBswmdModule bswmdContainerContainer && Instance is IEcucInstanceModule instanceContainerContainer)
+ {
+ foreach (var bswmd in bswmdContainerContainer.Containers)
+ {
+ if (bswmd.AsrPathShort == bswmdPathShort)
+ {
+ if (GetMultiplyStatus(bswmd.AsrPath).CanAdd == true)
+ {
+
+ switch (bswmd)
+ {
+ case EcucBswmdContainer:
+ case EcucBswmdChoiceContainer:
+ var instance = instanceContainerContainer.AddContainer(bswmdPathShort, shortName);
+ var dataNew = new EcucData(instance, bswmd);
+ if (bswmd is EcucBswmdContainer bswmdContainer)
+ {
+ foreach (var bswmd2 in bswmdContainer.Containers)
+ {
+ if (bswmd2.IsRequired == true)
+ {
+ dataNew.AddContainerWithRequiredField(bswmd2.AsrPathShort, bswmd2.AsrPathShort);
+ }
+ }
+ foreach (var bswmd3 in bswmdContainer.Paras)
+ {
+ if (bswmd3.IsRequired == true)
+ {
+ switch (bswmd3)
+ {
+ case EcucBswmdEnumerationPara bswmdEnum:
+ dataNew.AddPara(bswmdEnum.AsrPathShort, bswmdEnum.Default);
+ break;
+
+ case EcucBswmdIntegerPara bswmdIntegert:
+ dataNew.AddPara(bswmdIntegert.AsrPathShort, bswmdIntegert.Default.ToString());
+ break;
+
+ case EcucBswmdBooleanPara bswmdBoolean:
+ dataNew.AddPara(bswmdBoolean.AsrPathShort, bswmdBoolean.Default.ToString());
+ break;
+
+ case EcucBswmdFloatPara bswmdFloat:
+ dataNew.AddPara(bswmdFloat.AsrPathShort, bswmdFloat.Default.ToString());
+ break;
+
+ case EcucBswmdStringPara bswmdString:
+ if (bswmdString.Default.Count > 0)
+ {
+ dataNew.AddPara(bswmdString.AsrPathShort, bswmdString.Default[0]);
+ }
+ else
+ {
+ dataNew.AddPara(bswmdString.AsrPathShort, "");
+ }
+ break;
+
+ case EcucBswmdFunctionNamePara bswmdFunction:
+ dataNew.AddPara(bswmdFunction.AsrPathShort, bswmdFunction.Default[0]);
+ break;
+
+ default:
+ throw new NotImplementedException();
+ }
+ }
+ }
+ }
+ RaisePropertyChanged();
+ return dataNew;
+
+ default:
+ throw new NotImplementedException();
+ }
+ }
+ else
+ {
+ throw new Exception($"Can not add container due to upper limit");
+ }
+ }
+ }
+ throw new Exception($"Unexpected bswmd path {bswmdPathShort}");
+ }
+ else
+ {
+ throw new Exception($"Unexpected bswmd type {Bswmd.GetType()} or instance type {Instance.GetType()}");
+ }
+ }
+
+ public List ContainerChain(Dictionary chain)
+ {
+ var result = new List();
+
+ if (Instance is IEcucInstanceModule instanceContainerContainer)
+ {
+ EcucData data = this;
+ foreach (var kvp in chain)
+ {
+ try
+ {
+ var instanceBase = instanceContainerContainer.GetInstanceFromAsrPath($"{instanceContainerContainer.AsrPath}/{kvp.Value}");
+ if (instanceBase.BswmdPath == $"{Bswmd.AsrPath}/{kvp.Key}")
+ {
+ var bswmd = Bswmd.GetBswmdFromBswmdPath(instanceBase.BswmdPath);
+ if (bswmd != null)
+ {
+ data = new EcucData(instanceBase, bswmd);
+ result.Add(data);
+ }
+ }
+ }
+ catch (Exception ex)
+ {
+ Console.WriteLine(ex.Message);
+ data = data.AddContainer(kvp.Key, kvp.Value);
+ result.Add(data);
+ }
+ }
+ }
+ return result;
+ }
+
+ public EcucData AddPara(string bswmdPathShort, string value)
+ {
+ if (Bswmd is IEcucBswmdContainer bswmdContainerContainer && Instance is IEcucInstanceContainer instanceContainerContainer)
+ {
+ foreach (var bswmd in bswmdContainerContainer.Paras)
+ {
+ if (bswmd.AsrPathShort == bswmdPathShort)
+ {
+ if (GetMultiplyStatus(bswmd.AsrPath).CanAdd == true)
+ {
+ if (instanceContainerContainer is EcucInstanceContainer instanceContainer)
+ {
+ switch (bswmd)
+ {
+ case EcucBswmdEnumerationPara bswmdEnum:
+ if (bswmdEnum.Candidate.Count > 0)
+ {
+ if (bswmdEnum.Candidate.Contains(value) == true)
+ {
+ var textualPara = instanceContainer.AddTextualPara(bswmdPathShort, value, "ECUC-ENUMERATION-PARAM-DEF");
+ RaisePropertyChanged();
+ return new EcucData(textualPara, bswmd);
+ }
+ else
+ {
+ throw new Exception($"Can not add Enumerate Parameter {bswmdPathShort} due to value {value} not in candidate");
+ }
+ }
+ else
+ {
+ var textualPara = instanceContainer.AddTextualPara(bswmdPathShort, value, "ECUC-ENUMERATION-PARAM-DEF");
+ RaisePropertyChanged();
+ return new EcucData(textualPara, bswmd);
+ }
+
+ case EcucBswmdIntegerPara bswmdIntegert:
+ if (BigInteger.TryParse(value, out BigInteger integer) == true)
+ {
+ if (bswmdIntegert.Max != null)
+ {
+ if (integer <= bswmdIntegert.Max && integer >= bswmdIntegert.Min)
+ {
+ var numericalPara = instanceContainer.AddNumericalPara(bswmdPathShort, value, "ECUC-INTEGER-PARAM-DEF");
+ RaisePropertyChanged();
+ return new EcucData(numericalPara, bswmd);
+ }
+ else
+ {
+ throw new Exception($"Can not add integer parameter {bswmdPathShort} due to beyond range, Max is {bswmdIntegert.Max}, Min is {bswmdIntegert.Min}, Value is {value}");
+ }
+ }
+ else
+ {
+ if (integer >= bswmdIntegert.Min)
+ {
+ var numericalPara = instanceContainer.AddNumericalPara(bswmdPathShort, value, "ECUC-INTEGER-PARAM-DEF");
+ RaisePropertyChanged();
+ return new EcucData(numericalPara, bswmd);
+ }
+ else
+ {
+ throw new Exception($"Can not add integer parameter {bswmdPathShort} due to beyond range, Min is {bswmdIntegert.Min}, Value is {value}");
+ }
+ }
+ }
+ else
+ {
+ throw new Exception($"Can not add Integer Parameter {bswmdPathShort} due to can not convert value {value}");
+ }
+
+ case EcucBswmdBooleanPara:
+ if (bool.TryParse(value, out _) == true)
+ {
+ var numericalPara = instanceContainer.AddNumericalPara(bswmdPathShort, value, "ECUC-BOOLEAN-PARAM-DEF");
+ RaisePropertyChanged();
+ return new EcucData(numericalPara, bswmd);
+ }
+ else
+ {
+ throw new Exception($"Can not add boolean parameter {bswmdPathShort} dut to can not convert {value} to boolean");
+ }
+
+ case EcucBswmdFloatPara:
+ if (Double.TryParse(value, out _) == true)
+ {
+ var numericalPara = instanceContainer.AddNumericalPara(bswmdPathShort, value, "ECUC-FLOAT-PARAM-DEF");
+ RaisePropertyChanged();
+ return new EcucData(numericalPara, bswmd);
+ }
+ else
+ {
+ throw new Exception($"Can not add float parameter {bswmdPathShort} dut to can not convert {value} to float");
+ }
+
+ case EcucBswmdStringPara:
+ {
+ var textualPara = instanceContainer.AddTextualPara(bswmdPathShort, value, "ECUC-STRING-PARAM-DEF");
+ RaisePropertyChanged();
+ return new EcucData(textualPara, bswmd);
+ }
+
+ case EcucBswmdFunctionNamePara:
+ {
+ var textualPara = instanceContainer.AddTextualPara(bswmdPathShort, value, "ECUC-FUNCTION-NAME-DEF");
+ RaisePropertyChanged();
+ return new EcucData(textualPara, bswmd);
+ }
+
+ default:
+ throw new NotImplementedException();
+ }
+ }
+ else
+ {
+ throw new Exception($"Unexpected instance type {Instance.GetType()}");
+ }
+ }
+ else
+ {
+ throw new Exception($"Can not add container due to upper limit");
+ }
+ }
+ }
+ throw new Exception($"Unexpected bswmd path {bswmdPathShort}");
+ }
+ else
+ {
+ throw new Exception($"Unexpected bswmd type {Bswmd.GetType()} or instance type {Instance.GetType()}");
+ }
+ }
+
+ public EcucData AddPara(string bswmdPathShort)
+ {
+ if (Bswmd is IEcucBswmdContainer bswmdContainerContainer && Instance is IEcucInstanceContainer instanceContainerContainer)
+ {
+ foreach (var bswmd in bswmdContainerContainer.Paras)
+ {
+ if (bswmd.AsrPathShort == bswmdPathShort)
+ {
+ if (GetMultiplyStatus(bswmd.AsrPath).CanAdd == true)
+ {
+ if (instanceContainerContainer is EcucInstanceContainer instanceContainer)
+ {
+ switch (bswmd)
+ {
+ case EcucBswmdEnumerationPara bswmdEnum:
+ {
+ var textualPara = instanceContainer.AddTextualPara(bswmdPathShort, bswmdEnum.Default, "ECUC-ENUMERATION-PARAM-DEF");
+ RaisePropertyChanged();
+ return new EcucData(textualPara, bswmd);
+ }
+
+ case EcucBswmdIntegerPara bswmdIntegert:
+ {
+ var numericalPara = instanceContainer.AddNumericalPara(bswmdPathShort, bswmdIntegert.Default.ToString(), "ECUC-INTEGER-PARAM-DEF");
+ RaisePropertyChanged();
+ return new EcucData(numericalPara, bswmd);
+ }
+
+ case EcucBswmdBooleanPara BswmdBoolean:
+ {
+ var numericalPara = instanceContainer.AddNumericalPara(bswmdPathShort, BswmdBoolean.Default.ToString(), "ECUC-BOOLEAN-PARAM-DEF");
+ RaisePropertyChanged();
+ return new EcucData(numericalPara, bswmd);
+ }
+
+ case EcucBswmdFloatPara BswmdFloat:
+ {
+ var numericalPara = instanceContainer.AddNumericalPara(bswmdPathShort, BswmdFloat.Default.ToString(), "ECUC-FLOAT-PARAM-DEF");
+ RaisePropertyChanged();
+ return new EcucData(numericalPara, bswmd);
+ }
+
+ case EcucBswmdStringPara BswmdString:
+ {
+ var textualPara = instanceContainer.AddTextualPara(bswmdPathShort, BswmdString.Default[0], "ECUC-STRING-PARAM-DEF");
+ RaisePropertyChanged();
+ return new EcucData(textualPara, bswmd);
+ }
+
+ case EcucBswmdFunctionNamePara BswmdFunction:
+ {
+ var textualPara = instanceContainer.AddTextualPara(bswmdPathShort, BswmdFunction.Default[0], "ECUC-FUNCTION-NAME-DEF");
+ RaisePropertyChanged();
+ return new EcucData(textualPara, bswmd);
+ }
+
+ default:
+ throw new NotImplementedException();
+ }
+ }
+ else
+ {
+ throw new Exception($"Unexpected instance type {Instance.GetType()}");
+ }
+ }
+ else
+ {
+ throw new Exception($"Can not add container due to upper limit");
+ }
+ }
+ }
+ throw new Exception($"Unexpected bswmd path {bswmdPathShort}");
+ }
+ else
+ {
+ throw new Exception($"Unexpected bswmd type {Bswmd.GetType()} or instance type {Instance.GetType()}");
+ }
+ }
+
+ public List ParaChain(Dictionary chain)
+ {
+ var result = new List();
+
+ foreach (var kvp in chain)
+ {
+ result.Add(AddPara(kvp.Key, kvp.Value));
+ }
+ return result;
+ }
+
+ public void DelPara(string bswmdPathShort, string value)
+ {
+ if (Bswmd is IEcucBswmdContainer bswmdOtherContainer && Instance is IEcucInstanceContainer instanceOtherContainer)
+ {
+ foreach (var bswmd in bswmdOtherContainer.Paras)
+ {
+ if (bswmd.AsrPathShort == bswmdPathShort)
+ {
+ if (GetMultiplyStatus(bswmd.AsrPath).CanRemove == true)
+ {
+ if (instanceOtherContainer is EcucInstanceContainer instanceContainer)
+ {
+ switch (bswmd)
+ {
+ case EcucBswmdEnumerationPara:
+ instanceContainer.DelTextualPara(bswmdPathShort, value);
+ break;
+
+ case EcucBswmdIntegerPara:
+ instanceContainer.DelNumericalPara(bswmdPathShort, value);
+ break;
+
+ case EcucBswmdBooleanPara:
+ instanceContainer.DelNumericalPara(bswmdPathShort, value);
+ break;
+
+ case EcucBswmdFloatPara:
+ instanceContainer.DelNumericalPara(bswmdPathShort, value);
+ break;
+
+ case EcucBswmdStringPara:
+ instanceContainer.DelTextualPara(bswmdPathShort, value);
+ break;
+
+ case EcucBswmdFunctionNamePara:
+ instanceContainer.DelTextualPara(bswmdPathShort, value);
+ break;
+
+ default:
+ throw new NotImplementedException();
+ }
+ }
+ else
+ {
+ throw new Exception($"Unexpected instance type {Instance.GetType()}");
+ }
+ }
+ }
+ }
+ RaisePropertyChanged();
+ }
+ }
+
+ public void DelPara(string bswmdPath)
+ {
+ if (Bswmd is IEcucBswmdContainer bswmdOtherContainer && Instance is IEcucInstanceContainer instanceOtherContainer)
+ {
+ foreach (var bswmd in bswmdOtherContainer.Paras)
+ {
+ if (bswmd.AsrPathShort == bswmdPath)
+ {
+ if (bswmd.IsRequired == false)
+ {
+ if (instanceOtherContainer is EcucInstanceContainer instanceContainer)
+ {
+ switch (bswmd)
+ {
+ case EcucBswmdEnumerationPara:
+ instanceContainer.DelTextualPara(bswmdPath);
+ break;
+
+ case EcucBswmdIntegerPara:
+ instanceContainer.DelNumericalPara(bswmdPath);
+ break;
+
+ case EcucBswmdBooleanPara:
+ instanceContainer.DelNumericalPara(bswmdPath);
+ break;
+
+ case EcucBswmdFloatPara:
+ instanceContainer.DelNumericalPara(bswmdPath);
+ break;
+
+ case EcucBswmdStringPara:
+ instanceContainer.DelTextualPara(bswmdPath);
+ break;
+
+ case EcucBswmdFunctionNamePara:
+ instanceContainer.DelTextualPara(bswmdPath);
+ break;
+
+ default:
+ throw new NotImplementedException();
+ }
+ }
+ else
+ {
+ throw new Exception($"Unexpected instance type {Instance.GetType()}");
+ }
+ }
+ }
+ }
+ RaisePropertyChanged();
+ }
+ }
+
+ public EcucData AddRef(string bswmdPathShort, string value, string typ = "")
+ {
+ if (Bswmd is IEcucBswmdContainer bswmdOtherContainer && Instance is IEcucInstanceContainer instanceOtherContainer)
+ {
+ foreach (var bswmd in bswmdOtherContainer.Refs)
+ {
+ if (bswmd.AsrPathShort == bswmdPathShort)
+ {
+ if (GetMultiplyStatus(bswmd.AsrPath).CanAdd == true)
+ {
+ if (instanceOtherContainer is EcucInstanceContainer instanceContainer)
+ {
+ switch (bswmd)
+ {
+ case EcucBswmdRef bswmdRef:
+ {
+ var reference = instanceContainer.AddReference(bswmdPathShort, "ECUC-REFERENCE-DEF", value, bswmdRef.Dest);
+ RaisePropertyChanged();
+ return new EcucData(reference, bswmd);
+ }
+
+ case EcucBswmdForeignRef bswmdForeign:
+ {
+ var reference = instanceContainer.AddReference(bswmdPathShort, "ECUC-FOREIGN-REFERENCE-DEF", value, bswmdForeign.DestType);
+ RaisePropertyChanged();
+ return new EcucData(reference, bswmd);
+ }
+
+ case EcucBswmdSymbolicNameRef bswmdSymbolic:
+ {
+ var reference = instanceContainer.AddReference(bswmdPathShort, "ECUC-SYMBOLIC-NAME-REFERENCE-DEF", value, bswmdSymbolic.Dest);
+ RaisePropertyChanged();
+ return new EcucData(reference, bswmd);
+ }
+
+ case EcucBswmdChoiceRef bswmdChoice:
+ {
+ foreach (var choice in bswmdChoice.Choices)
+ {
+ if (typ == choice.Key)
+ {
+ var reference = instanceContainer.AddReference(bswmdPathShort, choice.Value, value, choice.Key);
+ RaisePropertyChanged();
+ return new EcucData(reference, bswmd);
+ }
+ }
+ throw new Exception($"Unexpected input type {typ}");
+ }
+
+ default:
+ throw new NotImplementedException();
+ }
+ }
+ else
+ {
+ throw new Exception($"Unexpected instance type {Instance.GetType()}");
+ }
+ }
+ else
+ {
+ throw new Exception($"Can not add container due to upper limit");
+ }
+ }
+ }
+ throw new Exception($"Unexpected bswmd path {bswmdPathShort}");
+ }
+ else
+ {
+ throw new Exception($"Unexpected bswmd type {Bswmd.GetType()} or instance type {Instance.GetType()}");
+ }
+ }
+
+ public List RefChain(Dictionary chain)
+ {
+ var result = new List();
+
+ foreach (var kvp in chain)
+ {
+ result.Add(AddRef(kvp.Key, kvp.Value));
+ }
+ return result;
+ }
+
+ public EcucData DeRef()
+ {
+ if (Instance is EcucInstanceReferenceValue instanceRef)
+ {
+ var referenced = Instance.GetInstanceFromAsrPath(instanceRef.ValueRef);
+
+ if (referenced != null)
+ {
+ var bswmd = Bswmd.GetBswmdFromBswmdPath(referenced.BswmdPath);
+ if (bswmd != null)
+ {
+ return new EcucData(referenced, bswmd);
+ }
+ }
+ }
+ throw new Exception($"Can not dereference");
+ }
+
+ public void DelRef(string bswmdPathShort, string valueRef)
+ {
+ if (Bswmd is IEcucBswmdContainer bswmdOtherContainer && Instance is IEcucInstanceContainer instanceOtherContainer)
+ {
+ foreach (var bswmd in bswmdOtherContainer.Refs)
+ {
+ if (bswmd.AsrPathShort == bswmdPathShort)
+ {
+ if (GetMultiplyStatus(bswmd.AsrPath).CanRemove == true)
+ {
+ if (instanceOtherContainer is EcucInstanceContainer instanceContainer)
+ {
+ switch (bswmd)
+ {
+ case EcucBswmdRef:
+ instanceContainer.DelReference(bswmdPathShort, valueRef);
+ break;
+
+
+ case EcucBswmdForeignRef:
+ instanceContainer.DelReference(bswmdPathShort, valueRef);
+ break;
+
+
+ case EcucBswmdSymbolicNameRef:
+ instanceContainer.DelReference(bswmdPathShort, valueRef);
+ break;
+
+ case EcucBswmdChoiceRef:
+ instanceContainer.DelReference(bswmdPathShort, valueRef);
+ break;
+
+ default:
+ throw new NotImplementedException();
+ };
+ }
+ else
+ {
+ throw new Exception($"Unexpected instance type {Instance.GetType()}");
+ }
+ }
+ else
+ {
+ throw new Exception($"Can not delete container due to lower limit");
+ }
+ }
+ }
+ RaisePropertyChanged();
+ }
+ else
+ {
+ throw new Exception($"Unexpected bswmd type {Bswmd.GetType()} or instance type {Instance.GetType()}");
+ }
+ }
+
+ public void DelRef(string bswmdPath)
+ {
+ if (Bswmd is IEcucBswmdContainer bswmdOtherContainer && Instance is IEcucInstanceContainer instanceOtherContainer)
+ {
+ foreach (var bswmd in bswmdOtherContainer.Refs)
+ {
+ if (bswmd.AsrPathShort == bswmdPath)
+ {
+ if (bswmd.IsRequired == false)
+ {
+ if (instanceOtherContainer is EcucInstanceContainer instanceContainer)
+ {
+ switch (bswmd)
+ {
+ case EcucBswmdRef:
+ instanceContainer.DelReference(bswmdPath);
+ break;
+
+
+ case EcucBswmdForeignRef:
+ instanceContainer.DelReference(bswmdPath);
+ break;
+
+
+ case EcucBswmdSymbolicNameRef:
+ instanceContainer.DelReference(bswmdPath);
+ break;
+
+ case EcucBswmdChoiceRef:
+ instanceContainer.DelReference(bswmdPath);
+ break;
+
+ default:
+ throw new NotImplementedException();
+ };
+ }
+ else
+ {
+ throw new Exception($"Unexpected instance type {Instance.GetType()}");
+ }
+ }
+ else
+ {
+ throw new Exception($"Can not delete container due to lower limit");
+ }
+ }
+ }
+ RaisePropertyChanged();
+ }
+ else
+ {
+ throw new Exception($"Unexpected bswmd type {Bswmd.GetType()} or instance type {Instance.GetType()}");
+ }
+ }
+
+ public EcucDataMultiplyStatus GetMultiplyStatus(string bswmdPath)
+ {
+ EcucDataMultiplyStatus.StatusType result = EcucDataMultiplyStatus.StatusType.Invalid;
+ try
+ {
+ var bswmd = Bswmd.GetBswmdFromBswmdPath(bswmdPath);
+ int count = 0;
+
+ switch (bswmd)
+ {
+ case IEcucBswmdModule:
+ {
+ var instances = InstanceAsModule.FindContainerByBswmd(bswmdPath);
+ count = instances.Count;
+ }
+ break;
+
+ case IEcucBswmdParam:
+ {
+ var instances = InstanceAsContainer.FindParaByBswmd(bswmdPath);
+ count = instances.Count;
+ }
+ break;
+
+ case IEcucBswmdReference:
+ {
+ var instances = InstanceAsContainer.FindRefByBswmd(bswmdPath);
+ count = instances.Count;
+ }
+ break;
+
+ default:
+ break;
+ }
+
+ if (count == 0)
+ {
+ result |= EcucDataMultiplyStatus.StatusType.Empty;
+ }
+
+ if (count == bswmd.Upper)
+ {
+ result |= EcucDataMultiplyStatus.StatusType.OkUpper;
+ }
+
+ if (count < bswmd.Lower)
+ {
+ result |= EcucDataMultiplyStatus.StatusType.Lack;
+ }
+ else if (count == bswmd.Lower)
+ {
+ result |= EcucDataMultiplyStatus.StatusType.OkLower;
+ }
+ else if (count < bswmd.Upper)
+ {
+ result |= EcucDataMultiplyStatus.StatusType.OkMiddle;
+ }
+ else
+ {
+ result |= EcucDataMultiplyStatus.StatusType.Overflow;
+ }
+ }
+ catch
+ {
+ result = EcucDataMultiplyStatus.StatusType.Invalid;
+ }
+
+ return new EcucDataMultiplyStatus(result);
+ }
+
+ void PropertyChangedEventHandler(object? sender, PropertyChangedEventArgs e)
+ {
+ if (e.PropertyName == "Valid")
+ {
+ RaisePropertyChanged(nameof(ValidStatus));
+ }
+ }
+
+ public void UpdateValidStatus(bool v, string vReason = "")
+ {
+ Instance.Valid.UpdateData(this);
+ Instance.Valid.UpdateValidStatus(v, vReason);
+ }
+
+ public void UpdateValidSolve(string desc, EcucSolveHandler handler, object? param=null)
+ {
+ Instance.Valid.UpdateSolve(desc, handler, param);
+ }
+
+ public void UpdateValidSolve(List solves)
+ {
+ Instance.Valid.UpdateSolve(solves);
+ }
+
+ public void ClearValidSolve()
+ {
+ Instance.Valid.ClearSolve();
+ }
+ }
+
+ public class EcucDataList : List
+ {
+ ///
+ /// Wheter data is valid.
+ ///
+ public bool ValidStatus
+ {
+ get
+ {
+ // iterate all data in datas checking Invalid
+ foreach (var data in this)
+ {
+ if (data.ValidStatus == false)
+ {
+ return false;
+ }
+ }
+ return true;
+ }
+ }
+
+ public string ValidInfo
+ {
+ get
+ {
+ string result = "";
+ foreach (var data in this)
+ {
+ result += data.ValidInfo;
+ }
+ return result;
+ }
+ }
+
+ public List AsrPath
+ {
+ get
+ {
+ var result = new List();
+ foreach (var data in this)
+ {
+ result.Add(data.AsrPath);
+ }
+ return result;
+ }
+ }
+
+ public List AsrPathShort
+ {
+ get
+ {
+ var result = new List();
+ foreach (var data in this)
+ {
+ result.Add(data.AsrPathShort);
+ }
+ return result;
+ }
+ }
+
+ public EcucDataList this[string key]
+ {
+ get
+ {
+ var result = new EcucDataList();
+ foreach (var data in this)
+ {
+ var bswmdGet = data.GetBswmdFromBswmdPath($"{data.BswmdPath}/{key}");
+ switch (bswmdGet)
+ {
+ case IEcucBswmdModule:
+ {
+ var query = from container in data.Containers
+ where container.BswmdPathShort == key
+ select container;
+
+ query.ToList().ForEach(x => result.Add(new EcucData(x, bswmdGet)));
+ }
+ break;
+
+ case IEcucBswmdParam:
+ {
+ var query = from para in data.Paras
+ where para.BswmdPathShort == key
+ select para;
+
+ query.ToList().ForEach(x => result.Add(new EcucData(x, bswmdGet)));
+ }
+ break;
+
+ case IEcucBswmdReference:
+ {
+ var query = from reference in data.Refs
+ where reference.BswmdPathShort == key
+ select reference;
+
+ query.ToList().ForEach(x => result.Add(new EcucData(x, bswmdGet)));
+ }
+ break;
+
+ default:
+ break;
+ }
+ }
+
+ return result;
+ }
+ }
+
+ public EcucDataList this[string key, string name]
+ {
+ get
+ {
+ var result = new EcucDataList();
+ foreach (var data in this)
+ {
+ var bswmdGet = data.GetBswmdFromBswmdPath($"{data.BswmdPath}/{key}");
+ switch (bswmdGet)
+ {
+ case IEcucBswmdModule:
+ {
+ var query = from container in data.Containers
+ where container.BswmdPathShort == key
+ where container.ShortName == name
+ select container;
+
+ query.ToList().ForEach(x => result.Add(new EcucData(x, bswmdGet)));
+ }
+ break;
+
+ case IEcucBswmdParam:
+ {
+ var query = from para in data.Paras
+ where para.BswmdPathShort == key
+ where para.Value == name
+ select para;
+
+ query.ToList().ForEach(x => result.Add(new EcucData(x, bswmdGet)));
+ }
+ break;
+
+ case IEcucBswmdReference:
+ {
+ var query = from reference in data.Refs
+ where reference.BswmdPathShort == key
+ where reference.ValueRefShort == name
+ select reference;
+
+ query.ToList().ForEach(x => result.Add(new EcucData(x, bswmdGet)));
+ }
+ break;
+
+ default:
+ break;
+ }
+ }
+
+ return result;
+ }
+ }
+
+ public delegate bool SearchFunc(EcucData data);
+ public EcucDataList this[string key, SearchFunc func]
+ {
+ get
+ {
+ var result = new EcucDataList();
+ foreach (var data in this)
+ {
+ var bswmdGet = data.GetBswmdFromBswmdPath($"{data.BswmdPath}/{key}");
+ switch (bswmdGet)
+ {
+ case IEcucBswmdModule:
+ {
+ var query = from container in data.Containers
+ where container.BswmdPathShort == key
+ where func(new EcucData(container, bswmdGet))
+ select container;
+
+ query.ToList().ForEach(x => result.Add(new EcucData(x, bswmdGet)));
+ }
+ break;
+
+ case IEcucBswmdParam:
+ {
+ var query = from para in data.Paras
+ where para.BswmdPathShort == key
+ where func(new EcucData(para, bswmdGet))
+ select para;
+
+ query.ToList().ForEach(x => result.Add(new EcucData(x, bswmdGet)));
+ }
+ break;
+
+ case IEcucBswmdReference:
+ {
+ var query = from reference in data.Refs
+ where reference.BswmdPathShort == key
+ where func(new EcucData(reference, bswmdGet))
+ select reference;
+
+ query.ToList().ForEach(x => result.Add(new EcucData(x, bswmdGet)));
+ }
+ break;
+
+ default:
+ break;
+ }
+ }
+
+ return result;
+ }
+ }
+
+ public EcucDataList()
+ {
+
+ }
+
+ public EcucDataList(List datas)
+ {
+ foreach (var data in datas)
+ {
+ Add(data);
+ }
+ }
+
+ public List Value
+ {
+ get
+ {
+ var result = new List();
+ foreach (var data in this)
+ {
+ result.Add(data.Value);
+ }
+ return result;
+ }
+ set
+ {
+ if (value != null)
+ {
+ if (value.Count == Count)
+ {
+ for (int i = 0; i < Count; i++)
+ {
+ this[i].Value = value[i];
+ }
+ }
+ }
+ }
+ }
+
+ public bool ValueSingleEqual(string value)
+ {
+ if (Value.Count == 1)
+ {
+ return Value[0] == value;
+ }
+ return false;
+ }
+
+ public EcucData First
+ {
+ get
+ {
+ if (Count > 0)
+ {
+ return this[0];
+ }
+ else
+ {
+ throw new Exception($"There is no data inside");
+ }
+ }
+ }
+
+ public string FirstValue
+ {
+ get
+ {
+ if (Count > 0)
+ {
+ return this[0].Value;
+ }
+ else
+ {
+ throw new Exception($"There is no text inside");
+ }
+ }
+ set
+ {
+ if (value != null)
+ {
+ if (Count > 0)
+ {
+ this[0].Value = value;
+ }
+ }
+ }
+ }
+
+ public Int64 FirstValueAsInt
+ {
+ get
+ {
+ if (Count > 0)
+ {
+ return this[0].ValueAsInt;
+ }
+ else
+ {
+ throw new Exception($"There is no integer inside");
+ }
+ }
+ set
+ {
+ if (Count > 0)
+ {
+ this[0].ValueAsInt = value;
+ }
+ }
+ }
+
+ public EcucDataList DeRef()
+ {
+ var result = new EcucDataList();
+
+ foreach (var data in this)
+ {
+ var referenced = data.DeRef();
+
+ if (referenced != null)
+ {
+ result.Add(referenced);
+ }
+ }
+ return result;
+ }
+
+ public EcucDataMultiplyStatus GetMultiplyStatus(IEcucBswmdBase bswmd)
+ {
+ EcucDataMultiplyStatus.StatusType result = EcucDataMultiplyStatus.StatusType.Invalid;
+
+ try
+ {
+ if (bswmd.Upper == 0)
+ {
+ result = EcucDataMultiplyStatus.StatusType.Invalid;
+ }
+ else
+ {
+ if (Count == 0)
+ {
+ result |= EcucDataMultiplyStatus.StatusType.Empty;
+ }
+
+ if (Count == bswmd.Upper)
+ {
+ result |= EcucDataMultiplyStatus.StatusType.OkUpper;
+ }
+
+ if (Count < bswmd.Lower)
+ {
+ result |= EcucDataMultiplyStatus.StatusType.Lack;
+ }
+ else if (Count == bswmd.Lower)
+ {
+ result |= EcucDataMultiplyStatus.StatusType.OkLower;
+ }
+ else if (Count < bswmd.Upper)
+ {
+ result |= EcucDataMultiplyStatus.StatusType.OkMiddle;
+ }
+ else if (Count > bswmd.Upper)
+ {
+ result |= EcucDataMultiplyStatus.StatusType.Overflow;
+ }
+ }
+ }
+ catch
+ {
+ result = EcucDataMultiplyStatus.StatusType.Invalid;
+ }
+
+ return new EcucDataMultiplyStatus(result);
+ }
+ }
+}
diff --git a/EcucBase/EcucInstance.cs b/EcucBase/EcucInstance.cs
new file mode 100644
index 0000000..c98cece
--- /dev/null
+++ b/EcucBase/EcucInstance.cs
@@ -0,0 +1,2166 @@
+/*
+ * This file is a part of Autosar Configurator for ECU GUI based
+ * configuration, checking and code generation.
+ *
+ * Copyright (C) 2021-2022 DJS Studio E-mail:DD-Silence@sina.cn
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+
+ * You should have received a copy of the GNU General Public License
+ * along with this program. If not, see .
+ */
+
+using Ecuc.EcucBase.EBase;
+using Autosar;
+using System.ComponentModel;
+
+namespace Ecuc.EcucBase.EInstance
+{
+ public class CommentGroup
+ {
+ public SDG Model { get; }
+
+ public string Name
+ {
+ get
+ {
+ return Model.Untyped.Value;
+ }
+ }
+
+ public CommentGroupList Groups
+ {
+ get
+ {
+ return new CommentGroupList(Model.SDG1);
+ }
+ }
+
+ public Dictionary Data
+ {
+ get
+ {
+ var result = new Dictionary();
+
+ foreach (var sd in Model.SD)
+ {
+ result[sd.GID] = sd.Untyped.Value;
+ }
+ return result;
+ }
+ }
+
+ public Dictionary Ref
+ {
+ get
+ {
+ var result = new Dictionary();
+
+ foreach (var sd in Model.SDXREF)
+ {
+ result[sd.Untyped.Value] = sd.DEST;
+ }
+ return result;
+ }
+ }
+
+ public CommentGroup(SDG model)
+ {
+ Model = model;
+ }
+
+ public CommentGroup this[string name]
+ {
+ get
+ {
+ try
+ {
+ return Groups[name];
+ }
+ catch
+ {
+ throw new Exception($"Fail to get comment {name}");
+ }
+ }
+ set
+ {
+ Groups[name] = value;
+ }
+ }
+
+ public string GetCommentByName(string name)
+ {
+ try
+ {
+ return Data[name];
+ }
+ catch
+ {
+ throw new Exception($"Can not get comment {name}");
+ }
+ }
+
+ public void SetCommentByName(string name, string value)
+ {
+ var sdNew = new SD
+ {
+ GID = name
+ };
+ sdNew.Untyped.Value = value;
+ Model.SD.Add(sdNew);
+ }
+ }
+
+ public class CommentGroupList : List
+ {
+ public IList Model { get; }
+
+ public CommentGroupList()
+ {
+ Model = new List();
+ }
+
+ public CommentGroupList(IList model)
+ {
+ Model = model;
+ foreach (var m in Model)
+ {
+ Add(new CommentGroup(m));
+ }
+ }
+
+ public CommentGroup this[string name]
+ {
+ get
+ {
+ foreach (var sdg in Model)
+ {
+ if (sdg.GID == name)
+ {
+ return new CommentGroup(sdg);
+ }
+ }
+ throw new Exception($"Fail to get comment group {name}");
+ }
+ set
+ {
+ if (value == null)
+ {
+ return;
+ }
+
+ foreach (var sdg in Model)
+ {
+ if (sdg.GID == name)
+ {
+ return;
+ }
+ }
+
+ Add(value);
+ }
+ }
+ }
+
+ public interface IEcucInstanceBase : INotifyPropertyChanged
+ {
+ string BswmdPath { get; }
+ string BswmdPathShort
+ {
+ get
+ {
+ var parts = BswmdPath.Split('/');
+ if (parts.Length > 0)
+ {
+ return parts[^1];
+ }
+ return "";
+ }
+ }
+
+ EcucInstanceManager Manager { get; }
+
+ IEcucInstanceBase GetInstanceFromAsrPath(string path)
+ {
+ try
+ {
+ return Manager.AsrPathInstanceDict[path];
+ }
+ catch
+ {
+ throw new Exception($"Can not get isntance from {path}");
+ }
+ }
+
+ List GetReferenceByAsrPath(string path)
+ {
+ try
+ {
+ return Manager.InstanceReferenceDict[path];
+ }
+ catch
+ {
+ throw new Exception($"Can not get reference from {path}");
+ }
+ }
+
+ bool IsDirty { get; set; }
+ EcucValid Valid { get; }
+ }
+
+ public interface IEcucInstanceModule : IEcucInstanceBase
+ {
+ string ShortName { get; set; }
+ string AsrPath { get; }
+ string AsrPathShort { get; }
+ List Containers { get; }
+ CommentGroupList Comment { get; set; }
+
+ EcucInstanceContainer AddContainer(string path, string shortName);
+ int DelContainer(string path, string shortName);
+ int DelContainer(string path);
+ void DelContainer();
+ void UpdateAsrPathShort(string newName);
+ void UpdateAsrPathPrefix(string newName);
+
+ List FindContainerByBswmd(string bswmdPath)
+ {
+ if (bswmdPath == "")
+ {
+ return Containers;
+ }
+ else
+ {
+ var query = from container in Containers
+ where container.BswmdPath == bswmdPath
+ select container;
+
+ return query.ToList();
+ }
+ }
+ }
+
+ public interface IEcucInstanceContainer : IEcucInstanceModule
+ {
+ List Paras { get; }
+ List Refs { get; }
+ IEcucInstanceModule Parent { get; }
+
+ List FindParaByBswmd(string bswmdPath)
+ {
+ var query = from para in Paras
+ where para.BswmdPath == bswmdPath
+ select para;
+
+ return query.ToList();
+ }
+
+ List FindRefByBswmd(string bswmdPath)
+ {
+ var query = from reference in Refs
+ where reference.BswmdPath == bswmdPath
+ select reference;
+
+ return query.ToList();
+ }
+ }
+
+ public interface IEcucInstanceParam : IEcucInstanceBase
+ {
+ IEcucInstanceModule Parent { get; }
+ string Value { get; set; }
+ public List Comment { get; set; }
+ }
+
+ public interface IEcucInstanceReference : IEcucInstanceBase
+ {
+ IEcucInstanceModule Parent { get; }
+ string ValueRef { get; set; }
+ string ValueRefShort
+ {
+ get
+ {
+ var parts = ValueRef.Split('/');
+ if (parts.Length > 0)
+ {
+ return parts[^1];
+ }
+ return "";
+ }
+ set
+ {
+ var ValueRefOld = ValueRef;
+ var parts = ValueRef.Split('/');
+ if (parts.Length > 0)
+ {
+ if (parts[^1] != value)
+ {
+ parts[^1] = value;
+ ValueRef = string.Join("/", parts);
+ Manager.InstanceReferenceDict[ValueRef] = Manager.InstanceReferenceDict[ValueRefOld];
+ Manager.InstanceReferenceDict.Remove(ValueRefOld);
+ }
+ }
+ }
+ }
+ public List Comment { get; set; }
+ }
+
+ public class EcucInstanceManager
+ {
+ private readonly List Autosars = new();
+ public List EcucModules { get; } = new();
+ public Dictionary AsrRawAsrPathDict = new();
+ public Dictionary AsrPathAsrRawDict = new();
+ public Dictionary> BswmdPathInstanceDict = new();
+ public Dictionary AsrPathInstanceDict = new();
+ public Dictionary> InstanceReferenceDict = new();
+ public Dictionary FileAsrRawDict = new();
+ private bool isDirty = false;
+
+ public bool IsDirty
+ {
+ get
+ {
+ return isDirty;
+ }
+ set
+ {
+ if (value != IsDirty)
+ {
+ isDirty = value;
+ }
+ }
+ }
+
+ public EcucInstanceManager(string content)
+ {
+ InitSingle(content);
+ }
+
+ public EcucInstanceManager(string[] fileNames)
+ {
+ InitMultiple(fileNames);
+ var query = from module in EcucModules
+ orderby module.ShortName ascending
+ select module;
+ EcucModules = query.ToList();
+ }
+
+ private void InitSingle(string content)
+ {
+ var autosar = new Asr(content);
+ Autosars.Add(autosar);
+ List arPackages = new();
+ foreach (var package in autosar.ArPackages)
+ {
+ arPackages.Add(package);
+ }
+
+ foreach (var value in autosar.AsrPathModelDict)
+ {
+ AsrPathAsrRawDict[value.Key] = value.Value;
+ AsrRawAsrPathDict[value.Value] = value.Key;
+ }
+
+ Monitor.Enter(EcucModules);
+ try
+ {
+ var query = from package in arPackages
+ where package.ELEMENTS?.ECUCMODULECONFIGURATIONVALUES != null
+ from ecucModuleValue in package.ELEMENTS.ECUCMODULECONFIGURATIONVALUES
+ select ecucModuleValue;
+
+ query.ToList().ForEach(x => EcucModules.Add(new EcucInstanceModule(x, this, autosar)));
+ }
+ finally
+ {
+ Monitor.Exit(EcucModules);
+ }
+ }
+
+ private void InitMultiple(string[] fileNames)
+ {
+ var tasks = new Task[fileNames.Length];
+
+ for (int i = 0; i < fileNames.Length; i++)
+ {
+ tasks[i] = InitMultipleSingleStep1(fileNames[i]);
+ }
+ Task.WaitAll(tasks);
+
+ tasks = new Task[Autosars.Count];
+ for (int i = 0; i < Autosars.Count; i++)
+ {
+ tasks[i] = InitMultipleSingleStep2(Autosars[i]);
+ }
+ Task.WaitAll(tasks);
+
+ for (int i = 0; i < Autosars.Count; i++)
+ {
+ tasks[i] = InitMultipleSingleStep3(Autosars[i]);
+ }
+ Task.WaitAll(tasks);
+ }
+
+ private Task InitMultipleSingleStep1(string fileName)
+ {
+ return Task.Run(() =>
+ {
+ var autosar = new Asr(fileName);
+ Monitor.Enter(Autosars);
+ try
+ {
+ Autosars.Add(autosar);
+ }
+ finally
+ {
+ Monitor.Exit(Autosars);
+ }
+ });
+ }
+
+ private Task InitMultipleSingleStep2(Asr ar)
+ {
+ return Task.Run(() =>
+ {
+ Monitor.Enter(AsrRawAsrPathDict);
+ try
+ {
+ foreach (var value in ar.AsrPathModelDict)
+ {
+ if (AsrPathAsrRawDict.ContainsKey(value.Key) == false)
+ {
+ AsrPathAsrRawDict[value.Key] = value.Value;
+ AsrRawAsrPathDict[value.Value] = value.Key;
+ }
+ }
+ }
+ finally
+ {
+ Monitor.Exit(AsrRawAsrPathDict);
+ }
+ });
+ }
+
+ private Task InitMultipleSingleStep3(Asr ar)
+ {
+ return Task.Run(() =>
+ {
+ Monitor.Enter(EcucModules);
+ try
+ {
+ var query = from package in ar.ArPackages
+ where package.ELEMENTS.ECUCMODULECONFIGURATIONVALUES != null
+ from ecucModuleValue in package.ELEMENTS.ECUCMODULECONFIGURATIONVALUES
+ select ecucModuleValue;
+
+ query.ToList().ForEach(x =>
+ {
+ var module = new EcucInstanceModule(x, this, ar);
+ EcucModules.Add(module);
+ ar.Modules.Add(module);
+ });
+ }
+ finally
+ {
+ Monitor.Exit(EcucModules);
+ }
+ });
+ }
+
+ public List GetInstancesByBswmdPath(string bswmdPath)
+ {
+ var result = new List();
+
+ if (BswmdPathInstanceDict.ContainsKey(bswmdPath))
+ {
+ result = BswmdPathInstanceDict[bswmdPath];
+ }
+ return result;
+ }
+
+ public IEcucInstanceBase GetInstanceByAsrPath(string path)
+ {
+ try
+ {
+ return AsrPathInstanceDict[path];
+ }
+ catch
+ {
+ throw new Exception($"Can not get isntance from {path}");
+ }
+ }
+
+ public List GetReferenceByAsrPath(string path)
+ {
+ try
+ {
+ return InstanceReferenceDict[path];
+ }
+ catch
+ {
+ throw new Exception($"Can not get reference from {path}");
+ }
+ }
+
+ public EcucInstanceModule? this[string name]
+ {
+ get
+ {
+ var query = from module in EcucModules
+ where module.ShortName == name
+ select module;
+
+ var result = query.ToList();
+ if (result.Count > 0)
+ {
+ return result[0];
+ }
+ else
+ {
+ return null;
+ }
+ }
+ }
+
+ public void Save()
+ {
+ var query = from asr in Autosars
+ where asr.IsDirty == true
+ select asr;
+
+ var result = query.ToList();
+
+ var tasks = new Task[result.Count];
+
+ for (int i = 0; i < result.Count; i++)
+ {
+ tasks[i] = SaveSingle(result[i]);
+ }
+ Task.WaitAll(tasks);
+ }
+
+ private static Task SaveSingle(Asr asr)
+ {
+ return Task.Run(() =>
+ {
+ asr.Save();
+ });
+ }
+
+ ///
+ /// Add object with name to dictionary.
+ ///
+ ///
+ ///
+ public void AddAsrPath(string name, object model)
+ {
+ AsrPathAsrRawDict[name] = model;
+ AsrRawAsrPathDict[model] = name;
+ if (model is IEcucInstanceBase instance)
+ {
+ AsrPathInstanceDict[name] = instance;
+ }
+ }
+
+ public void RemoveAsrPath(string name, object model)
+ {
+ AsrPathAsrRawDict.Remove(name);
+ AsrRawAsrPathDict.Remove(model);
+ }
+ }
+
+ public class EcucInstanceModule : NotifyPropertyChangedBase, IEcucInstanceModule
+ {
+ private ECUCMODULECONFIGURATIONVALUES Model { get; }
+ public EcucInstanceManager Manager { get; }
+ public Asr Parent { get; }
+ public EcucValid Valid { get; set; }
+
+ private bool isDirty = false;
+
+ public bool IsDirty
+ {
+ get
+ {
+ return isDirty;
+ }
+ set
+ {
+ if (value != IsDirty)
+ {
+ isDirty = value;
+
+ if (isDirty == true)
+ {
+ Parent.IsDirty = true;
+ }
+ else
+ {
+ foreach (var container in Containers)
+ {
+ container.IsDirty = false;
+ }
+ }
+ }
+ }
+ }
+
+ public CommentGroupList Comment
+ {
+ get
+ {
+ if (Model.ADMINDATA == null)
+ {
+ return new CommentGroupList();
+ }
+
+ if (Model.ADMINDATA.SDGS == null)
+ {
+ return new CommentGroupList();
+ }
+
+ return new CommentGroupList(Model.ADMINDATA.SDGS.SDG);
+ }
+ set
+ {
+ if (value == null)
+ {
+ return;
+ }
+
+ if (value.Count == 0)
+ {
+ return;
+ }
+
+ if (Model.ADMINDATA == null)
+ {
+ Model.ADMINDATA = new ADMINDATA();
+ }
+
+ if (Model.ADMINDATA.SDGS == null)
+ {
+ Model.ADMINDATA.SDGS = new ADMINDATA.SDGSLocalType();
+ }
+
+ foreach (var item in value)
+ {
+ Model.ADMINDATA.SDGS.SDG.Add(item.Model);
+ }
+ }
+ }
+
+ public string BswmdPath
+ {
+ get
+ {
+ return Model.DEFINITIONREF.TypedValue;
+ }
+ }
+
+ public string ShortName
+ {
+ get
+ {
+ return Model.SHORTNAME.TypedValue;
+ }
+ set
+ {
+ if (value != null)
+ {
+ if (ShortName != value)
+ {
+ // cache old autosar path
+ var asrPathOld = AsrPath;
+ var parts = asrPathOld.Split('/');
+ if (parts.Length > 0)
+ {
+ // add new path to dict
+ UpdateAsrPathShort(value);
+ // autosar model modify
+ Model.SHORTNAME.TypedValue = value;
+ }
+ }
+ }
+ }
+ }
+
+ public string AsrPath
+ {
+ get
+ {
+ return Manager.AsrRawAsrPathDict[Model];
+ }
+ }
+
+ public string AsrPathShort
+ {
+ get
+ {
+ var parts = AsrPath.Split('/');
+ if (parts.Length > 0)
+ {
+ return parts[^1];
+ }
+ return "";
+ }
+ }
+
+ public List Containers { get; } = new List();
+
+ public EcucInstanceModule(ECUCMODULECONFIGURATIONVALUES model, EcucInstanceManager manager, Asr parent)
+ {
+ Model = model;
+ Manager = manager;
+ Parent = parent;
+ Valid = new EcucValid(this);
+ Valid.PropertyChanged += ValidChangedEventHandler;
+
+ Monitor.Enter(Manager.BswmdPathInstanceDict);
+ try
+ {
+ if (Manager.BswmdPathInstanceDict.ContainsKey(BswmdPath))
+ {
+ Manager.BswmdPathInstanceDict[BswmdPath].Add(this);
+ }
+ else
+ {
+ Manager.BswmdPathInstanceDict[BswmdPath] = new List() { this };
+ }
+ }
+ finally
+ {
+ Monitor.Exit(Manager.BswmdPathInstanceDict);
+ }
+
+ Monitor.Enter(Manager.AsrPathInstanceDict);
+ try
+ {
+ Manager.AsrPathInstanceDict[AsrPath] = this;
+ }
+ finally
+ {
+ Monitor.Exit(Manager.AsrPathInstanceDict);
+ }
+
+ if (Model.CONTAINERS != null)
+ {
+ if (Model.CONTAINERS.ECUCCONTAINERVALUE != null)
+ {
+ foreach (ECUCCONTAINERVALUE container in Model.CONTAINERS.ECUCCONTAINERVALUE)
+ {
+ Containers.Add(new EcucInstanceContainer(container, Manager, this));
+ }
+ }
+ }
+ }
+
+ public EcucInstanceContainer AddContainer(string path, string shortName)
+ {
+ var model = new ECUCCONTAINERVALUE
+ {
+ DEFINITIONREF = new ECUCCONTAINERVALUE.DEFINITIONREFLocalType
+ {
+ DEST = "ECUC-PARAM-CONF-CONTAINER-DEF",
+ TypedValue = $"{BswmdPath}/{path}"
+ },
+ SHORTNAME = new IDENTIFIER
+ {
+ TypedValue = shortName
+ },
+ UUID = Guid.NewGuid().ToString()
+ };
+
+ if (Manager.AsrPathAsrRawDict.ContainsKey($"{AsrPath}/{shortName}") == false)
+ {
+ if (Model.CONTAINERS == null)
+ {
+ Model.CONTAINERS = new ECUCMODULECONFIGURATIONVALUES.CONTAINERSLocalType();
+ }
+ Model.CONTAINERS.ECUCCONTAINERVALUE.Add(model);
+ Manager.AddAsrPath($"{AsrPath}/{shortName}", model);
+ var newContainer = new EcucInstanceContainer(model, Manager, this);
+ Containers.Add(newContainer);
+ IsDirty = true;
+ return newContainer;
+ }
+ else
+ {
+ throw new Exception($"Find duplicate container {shortName} when add continer");
+ }
+ }
+
+ public int DelContainer(string path, string shortName)
+ {
+ foreach (var container in Containers)
+ {
+ if (container.BswmdPath == path && container.ShortName == shortName)
+ {
+ if (container is EcucInstanceContainer instanceContainer)
+ {
+ Manager.RemoveAsrPath(instanceContainer.AsrPath, instanceContainer);
+ Model.CONTAINERS.ECUCCONTAINERVALUE.Remove(instanceContainer.Model);
+ IsDirty = true;
+
+ if (container.Containers.Count > 0)
+ {
+ if (container is EcucInstanceContainer instanceContainer2)
+ {
+ instanceContainer2.DelContainer();
+ }
+ }
+ }
+ }
+ }
+
+ Containers.RemoveAll(x => x.BswmdPath == path && x.ShortName == shortName);
+ return Containers.FindAll(x => x.BswmdPath == path).Count;
+ }
+
+ public int DelContainer(string path)
+ {
+ foreach (var container in Containers)
+ {
+ if (container.BswmdPathShort == path)
+ {
+ if (container is EcucInstanceContainer instanceContainer)
+ {
+ Manager.RemoveAsrPath(instanceContainer.AsrPath, instanceContainer);
+ Model.CONTAINERS.ECUCCONTAINERVALUE.Remove(instanceContainer.Model);
+ IsDirty = true;
+
+ if (container.Containers.Count > 0)
+ {
+ if (container is EcucInstanceContainer instanceContainer2)
+ {
+ instanceContainer2.DelContainer();
+ }
+ }
+ }
+ }
+ }
+
+ Containers.RemoveAll(x => x.BswmdPath == path);
+ return Containers.FindAll(x => x.BswmdPath == path).Count;
+ }
+
+ public void DelContainer()
+ {
+ foreach (var container in Containers)
+ {
+ if (container is EcucInstanceContainer instanceContainer)
+ {
+ Manager.RemoveAsrPath(instanceContainer.AsrPath, instanceContainer);
+ Model.CONTAINERS.ECUCCONTAINERVALUE.Remove(instanceContainer.Model);
+ IsDirty = true;
+
+ if (container.Containers.Count > 0)
+ {
+ if (container is EcucInstanceContainer instanceContainer2)
+ {
+ instanceContainer2.DelContainer();
+ }
+ }
+ }
+ }
+ Containers.RemoveAll(x => x.BswmdPath != "");
+ }
+
+ ///
+ /// Update autosar path dictionary of container
+ ///
+ /// New short name of container
+ public void UpdateAsrPathShort(string newName)
+ {
+ // Construct new autosar path
+ var asrPathOld = AsrPath;
+ var parts = AsrPath.Split("/");
+ parts[^1] = newName;
+ var asrPathNew = string.Join("/", parts);
+
+ // Check name duplication
+ if (Manager.AsrPathAsrRawDict.ContainsKey(asrPathNew))
+ {
+ throw new Exception($"Already have continer with name {newName}");
+ }
+
+ // Update AsrPathAsrRawDict
+ Manager.AsrPathAsrRawDict[asrPathNew] = Manager.AsrPathAsrRawDict[asrPathOld];
+ Manager.AsrPathAsrRawDict.Remove(asrPathOld);
+ // Update AsrRawAsrPathDict
+ Manager.AsrRawAsrPathDict[Model] = asrPathNew;
+ // Update AsrPathInstanceDict
+ Manager.AsrPathInstanceDict[asrPathNew] = Manager.AsrPathInstanceDict[asrPathOld];
+ Manager.AsrPathInstanceDict.Remove(asrPathOld);
+
+ // Updata InstanceReferenceDict, change all reference point to container
+ try
+ {
+ var usage = (this as IEcucInstanceBase).GetReferenceByAsrPath(asrPathOld);
+ foreach (var u in usage)
+ {
+ u.ValueRef = asrPathNew;
+ }
+ }
+ catch
+ {
+
+ }
+
+ foreach (var continer in Containers)
+ {
+ continer.UpdateAsrPathPrefix(asrPathNew);
+ }
+ }
+
+ ///
+ /// Update autosar path prefix of container.
+ /// The prefix may be changed by parent container shortname changed.
+ ///
+ /// New short name of container
+ public void UpdateAsrPathPrefix(string newName)
+ {
+ // Construct new autosar path
+ var asrPathOld = AsrPath;
+ var parts = AsrPath.Split("/");
+ var asrPathNew = $"{newName}/{parts[^1]}";
+
+ // Check name duplication
+ if (Manager.AsrPathAsrRawDict.ContainsKey(asrPathNew))
+ {
+ throw new Exception($"Already have continer with name {newName}");
+ }
+
+ // Update AsrPathAsrRawDict
+ Manager.AsrPathAsrRawDict[asrPathNew] = Manager.AsrPathAsrRawDict[asrPathOld];
+ Manager.AsrPathAsrRawDict.Remove(asrPathOld);
+ // Update AsrRawAsrPathDict
+ Manager.AsrRawAsrPathDict[Model] = asrPathNew;
+ // Update AsrPathInstanceDict
+ Manager.AsrPathInstanceDict[asrPathNew] = Manager.AsrPathInstanceDict[asrPathOld];
+ Manager.AsrPathInstanceDict.Remove(asrPathOld);
+
+ // Updata InstanceReferenceDict, change all reference point to container
+ try
+ {
+ var usage = (this as IEcucInstanceBase).GetReferenceByAsrPath(asrPathOld);
+ foreach (var u in usage)
+ {
+ u.ValueRef = asrPathNew;
+ }
+ }
+ catch
+ {
+
+ }
+
+ foreach (var continer in Containers)
+ {
+ continer.UpdateAsrPathPrefix(asrPathNew);
+ }
+ }
+
+ private void ValidChangedEventHandler(object? sender, PropertyChangedEventArgs e)
+ {
+ RaisePropertyChanged(nameof(Valid));
+ }
+ }
+
+ public class EcucInstanceContainer : NotifyPropertyChangedBase, IEcucInstanceContainer
+ {
+ public ECUCCONTAINERVALUE Model { get; }
+ public EcucInstanceManager Manager { get; }
+ public IEcucInstanceModule Parent { get; }
+ public EcucValid Valid { get; set; }
+
+ private bool isDirty = false;
+
+ public bool IsDirty
+ {
+ get
+ {
+ return isDirty;
+ }
+ set
+ {
+ if (value != IsDirty)
+ {
+ isDirty = value;
+ if (value == true)
+ {
+ Parent.IsDirty = true;
+ }
+ else
+ {
+ foreach (var container in Containers)
+ {
+ container.IsDirty = false;
+ }
+ }
+ }
+ }
+ }
+
+ public CommentGroupList Comment
+ {
+ get
+ {
+ if (Model.ADMINDATA == null)
+ {
+ return new CommentGroupList();
+ }
+
+ if (Model.ADMINDATA.SDGS == null)
+ {
+ return new CommentGroupList();
+ }
+
+ return new CommentGroupList(Model.ADMINDATA.SDGS.SDG);
+ }
+ set
+ {
+ if (value == null)
+ {
+ return;
+ }
+
+ if (value.Count == 0)
+ {
+ return;
+ }
+
+ if (Model.ADMINDATA == null)
+ {
+ Model.ADMINDATA = new ADMINDATA();
+ }
+
+ if (Model.ADMINDATA.SDGS == null)
+ {
+ Model.ADMINDATA.SDGS = new ADMINDATA.SDGSLocalType();
+ }
+
+ foreach (var item in value)
+ {
+ Model.ADMINDATA.SDGS.SDG.Add(item.Model);
+ }
+ }
+ }
+
+ public string BswmdPath
+ {
+ get
+ {
+ return Model.DEFINITIONREF.TypedValue;
+ }
+ }
+
+ public string ShortName
+ {
+ get
+ {
+ return Model.SHORTNAME.TypedValue;
+ }
+ set
+ {
+ if (value != null)
+ {
+ if (ShortName != value)
+ {
+ // cache old autosar path
+ var asrPathOld = AsrPath;
+ var parts = asrPathOld.Split('/');
+ if (parts.Length > 0)
+ {
+ // add new path to dict
+ UpdateAsrPathShort(value);
+ // autosar model modify
+ Model.SHORTNAME.TypedValue = value;
+ }
+ }
+ }
+ }
+ }
+
+ public string AsrPath
+ {
+ get
+ {
+ return Manager.AsrRawAsrPathDict[Model];
+ }
+ }
+
+ public string AsrPathShort
+ {
+ get
+ {
+ var parts = AsrPath.Split('/');
+ if (parts.Length > 0)
+ {
+ return parts[^1];
+ }
+ return "";
+ }
+ }
+
+ public List Containers { get; } = new();
+ public List Paras { get; } = new();
+ public List Refs { get; } = new();
+
+ public EcucInstanceContainer(ECUCCONTAINERVALUE model, EcucInstanceManager manager, IEcucInstanceModule parent)
+ {
+ Model = model;
+ Manager = manager;
+ Parent = parent;
+ Valid = new EcucValid(this);
+ Valid.PropertyChanged += ValidChangedEventHandler;
+
+ Monitor.Enter(Manager.BswmdPathInstanceDict);
+ try
+ {
+ if (Manager.BswmdPathInstanceDict.ContainsKey(BswmdPath))
+ {
+ Manager.BswmdPathInstanceDict[BswmdPath].Add(this);
+ }
+ else
+ {
+ Manager.BswmdPathInstanceDict[BswmdPath] = new List() { this };
+ }
+ }
+ finally
+ {
+ Monitor.Exit(Manager.BswmdPathInstanceDict);
+ }
+
+ Monitor.Enter(Manager.AsrPathInstanceDict);
+ try
+ {
+ Manager.AsrPathInstanceDict[AsrPath] = this;
+ }
+ finally
+ {
+ Monitor.Exit(Manager.AsrPathInstanceDict);
+ }
+
+ if (Model.SUBCONTAINERS != null)
+ {
+ if (Model.SUBCONTAINERS.ECUCCONTAINERVALUE != null)
+ {
+ foreach (ECUCCONTAINERVALUE container in Model.SUBCONTAINERS.ECUCCONTAINERVALUE)
+ {
+ Containers.Add(new EcucInstanceContainer(container, Manager, this));
+ }
+ }
+ }
+
+ if (Model.PARAMETERVALUES != null)
+ {
+ if (Model.PARAMETERVALUES.ECUCTEXTUALPARAMVALUE != null)
+ {
+ foreach (ECUCTEXTUALPARAMVALUE para in Model.PARAMETERVALUES.ECUCTEXTUALPARAMVALUE)
+ {
+ Paras.Add(new EcucInstanceTextualParamValue(para, Manager, this));
+ }
+ }
+
+ if (Model.PARAMETERVALUES.ECUCNUMERICALPARAMVALUE != null)
+ {
+ foreach (ECUCNUMERICALPARAMVALUE para in Model.PARAMETERVALUES.ECUCNUMERICALPARAMVALUE)
+ {
+ Paras.Add(new EcucInstanceNumericalParamValue(para, Manager, this));
+ }
+ }
+ }
+
+ if (Model.REFERENCEVALUES != null)
+ {
+ if (Model.REFERENCEVALUES.ECUCREFERENCEVALUE != null)
+ {
+ foreach (ECUCREFERENCEVALUE reference in Model.REFERENCEVALUES.ECUCREFERENCEVALUE)
+ {
+ Refs.Add(new EcucInstanceReferenceValue(reference, Manager, this));
+ }
+ }
+ }
+ }
+
+ public EcucInstanceContainer AddContainer(string path, string shortName)
+ {
+ var model = new ECUCCONTAINERVALUE
+ {
+ DEFINITIONREF = new ECUCCONTAINERVALUE.DEFINITIONREFLocalType
+ {
+ DEST = "ECUC-PARAM-CONF-CONTAINER-DEF",
+ TypedValue = $"{BswmdPath}/{path}"
+ },
+ SHORTNAME = new IDENTIFIER
+ {
+ TypedValue = shortName
+ },
+ UUID = Guid.NewGuid().ToString()
+ };
+
+ if (Manager.AsrPathAsrRawDict.ContainsKey($"{AsrPath}/{shortName}") == false)
+ {
+ if (Model.SUBCONTAINERS == null)
+ {
+ Model.SUBCONTAINERS = new ECUCCONTAINERVALUE.SUBCONTAINERSLocalType();
+ }
+ Model.SUBCONTAINERS.ECUCCONTAINERVALUE.Add(model);
+ Manager.AsrPathAsrRawDict[$"{AsrPath}/{shortName}"] = model;
+ Manager.AsrRawAsrPathDict[model] = $"{AsrPath}/{shortName}";
+ var newContainer = new EcucInstanceContainer(model, Manager, this);
+ Containers.Add(newContainer);
+ IsDirty = true;
+ return newContainer;
+ }
+ else
+ {
+ throw new Exception($"Find duplicate container {shortName} when add continer");
+ }
+ }
+
+ public int DelContainer(string path, string shortName)
+ {
+ foreach (var container in Containers)
+ {
+ if (container.BswmdPath == path && container.ShortName == shortName)
+ {
+ if (container is EcucInstanceContainer instanceContainer)
+ {
+ Manager.AsrPathAsrRawDict.Remove(instanceContainer.AsrPath);
+ Manager.AsrRawAsrPathDict.Remove(instanceContainer);
+ Model.SUBCONTAINERS.ECUCCONTAINERVALUE.Remove(instanceContainer.Model);
+ IsDirty = true;
+
+ if (container.Containers.Count > 0)
+ {
+ if (container is EcucInstanceContainer instanceContainer2)
+ {
+ instanceContainer2.DelContainer();
+ }
+ }
+ }
+ }
+ }
+
+ Containers.RemoveAll(x => x.BswmdPath == path && x.ShortName == shortName);
+ return Containers.FindAll(x => x.BswmdPath == path).Count;
+ }
+
+ public int DelContainer(string path)
+ {
+ foreach (var container in Containers)
+ {
+ if (container.BswmdPathShort == path)
+ {
+ if (container is EcucInstanceContainer instanceContainer)
+ {
+ Manager.AsrPathAsrRawDict.Remove(instanceContainer.AsrPath);
+ Manager.AsrRawAsrPathDict.Remove(instanceContainer);
+ Model.SUBCONTAINERS.ECUCCONTAINERVALUE.Remove(instanceContainer.Model);
+ IsDirty = true;
+
+ if (container.Containers.Count > 0)
+ {
+ if (container is EcucInstanceContainer instanceContainer2)
+ {
+ instanceContainer2.DelContainer();
+ }
+ }
+ }
+ }
+ }
+
+ Containers.RemoveAll(x => x.BswmdPath == path);
+ return Containers.FindAll(x => x.BswmdPath == path).Count;
+ }
+
+ public void DelContainer()
+ {
+ foreach (var container in Containers)
+ {
+ if (container is EcucInstanceContainer instanceContainer)
+ {
+ Manager.AsrPathAsrRawDict.Remove(instanceContainer.AsrPath);
+ Manager.AsrRawAsrPathDict.Remove(instanceContainer);
+ Model.SUBCONTAINERS.ECUCCONTAINERVALUE.Remove(instanceContainer.Model);
+ IsDirty = true;
+
+ if (container.Containers.Count > 0)
+ {
+ if (container is EcucInstanceContainer instanceContainer2)
+ {
+ instanceContainer2.DelContainer();
+ }
+ }
+ }
+ }
+ Containers.RemoveAll(x => x.BswmdPath != "");
+ }
+
+ public EcucInstanceTextualParamValue AddTextualPara(string path, string value, string dest)
+ {
+ var paraNew = new EcucInstanceTextualParamValue($"{BswmdPath}/{path}", dest, value, Manager, this);
+
+ if (Model.PARAMETERVALUES == null)
+ {
+ Model.PARAMETERVALUES = new ECUCCONTAINERVALUE.PARAMETERVALUESLocalType();
+ }
+ Model.PARAMETERVALUES.ECUCTEXTUALPARAMVALUE.Add(paraNew.Model);
+ Paras.Add(paraNew);
+ paraNew.IsDirty = true;
+ return paraNew;
+ }
+
+ public void DelTextualPara(string path, string value)
+ {
+ var query = from para in Paras
+ where para.BswmdPathShort == path && para.Value == value
+ select para;
+
+ foreach (var para in query.ToList())
+ {
+ if (para is EcucInstanceTextualParamValue textualPara)
+ {
+ Model.PARAMETERVALUES.ECUCTEXTUALPARAMVALUE.Remove(textualPara.Model);
+ Manager.BswmdPathInstanceDict[para.BswmdPath].Remove(para);
+ Paras.Remove(para);
+ IsDirty = true;
+ }
+ }
+ }
+
+ public void DelTextualPara(string path)
+ {
+ var query = from para in Paras
+ where para.BswmdPathShort == path
+ select para;
+
+ foreach (var para in query.ToList())
+ {
+ if (para is EcucInstanceTextualParamValue textualPara)
+ {
+ Model.PARAMETERVALUES.ECUCTEXTUALPARAMVALUE.Remove(textualPara.Model);
+ Manager.BswmdPathInstanceDict[para.BswmdPath].Remove(para);
+ Paras.Remove(para);
+ IsDirty = true;
+ }
+ }
+ }
+
+ public EcucInstanceNumericalParamValue AddNumericalPara(string path, string value, string dest)
+ {
+ var paraNew = new EcucInstanceNumericalParamValue($"{BswmdPath}/{path}", dest, value, Manager, this);
+ if (Model.PARAMETERVALUES == null)
+ {
+ Model.PARAMETERVALUES = new ECUCCONTAINERVALUE.PARAMETERVALUESLocalType();
+ }
+ Model.PARAMETERVALUES.ECUCNUMERICALPARAMVALUE.Add(paraNew.Model);
+ Paras.Add(paraNew);
+ paraNew.IsDirty = true;
+ return paraNew;
+ }
+
+ public void DelNumericalPara(string path, string value)
+ {
+ var query = from para in Paras
+ where para.BswmdPathShort == path && para.Value == value
+ select para;
+
+ foreach (var para in query.ToList())
+ {
+ if (para is EcucInstanceNumericalParamValue numericalPara)
+ {
+ Model.PARAMETERVALUES.ECUCNUMERICALPARAMVALUE.Remove(numericalPara.Model);
+ Manager.BswmdPathInstanceDict[para.BswmdPath].Remove(para);
+ Paras.Remove(para);
+ IsDirty = true;
+ }
+ }
+ }
+
+ public void DelNumericalPara(string path)
+ {
+ var query = from para in Paras
+ where para.BswmdPathShort == path
+ select para;
+
+ foreach (var para in query.ToList())
+ {
+ if (para is EcucInstanceNumericalParamValue numericalPara)
+ {
+ Model.PARAMETERVALUES.ECUCNUMERICALPARAMVALUE.Remove(numericalPara.Model);
+ Manager.BswmdPathInstanceDict[para.BswmdPath].Remove(para);
+ Paras.Remove(para);
+ IsDirty = true;
+ }
+ }
+ }
+
+ public EcucInstanceReferenceValue AddReference(string path, string defDest, string valueRef, string valueDest)
+ {
+ var refNew = new EcucInstanceReferenceValue($"{BswmdPath}/{path}", defDest, valueRef, valueDest, Manager, this);
+ if (Model.REFERENCEVALUES == null)
+ {
+ Model.REFERENCEVALUES = new ECUCCONTAINERVALUE.REFERENCEVALUESLocalType();
+ }
+ Model.REFERENCEVALUES.ECUCREFERENCEVALUE.Add(refNew.Model);
+ refNew.IsDirty = true;
+ Refs.Add(refNew);
+ return refNew;
+ }
+
+ public void DelReference(string path, string valueRef)
+ {
+ var query = from reference in Refs
+ where reference.BswmdPathShort == path && reference.ValueRef == valueRef
+ select reference;
+
+ foreach (var reference in query.ToList())
+ {
+ if (reference is EcucInstanceReferenceValue instanceReference)
+ {
+ Model.REFERENCEVALUES.ECUCREFERENCEVALUE.Remove(instanceReference.Model);
+ Refs.Remove(instanceReference);
+ IsDirty = true;
+ }
+ }
+ }
+
+ public void DelReference(string path)
+ {
+ var query = from reference in Refs
+ where reference.BswmdPathShort == path
+ select reference;
+
+ foreach (var reference in query.ToList())
+ {
+ if (reference is EcucInstanceReferenceValue instanceReference)
+ {
+ Model.REFERENCEVALUES.ECUCREFERENCEVALUE.Remove(instanceReference.Model);
+ Refs.Remove(instanceReference);
+ IsDirty = true;
+ }
+ }
+ }
+
+ ///
+ /// Update autosar path dictionary of container
+ ///
+ /// New short name of container
+ public void UpdateAsrPathShort(string newName)
+ {
+ // Construct new autosar path
+ var asrPathOld = AsrPath;
+ var parts = AsrPath.Split("/");
+ parts[^1] = newName;
+ var asrPathNew = string.Join("/", parts);
+
+ // Check name duplication
+ if (Manager.AsrPathAsrRawDict.ContainsKey(asrPathNew))
+ {
+ throw new Exception($"Already have continer with name {newName}");
+ }
+
+ // Update AsrPathAsrRawDict
+ Manager.AsrPathAsrRawDict[asrPathNew] = Manager.AsrPathAsrRawDict[asrPathOld];
+ Manager.AsrPathAsrRawDict.Remove(asrPathOld);
+ // Update AsrRawAsrPathDict
+ Manager.AsrRawAsrPathDict[Model] = asrPathNew;
+ // Update AsrPathInstanceDict
+ Manager.AsrPathInstanceDict[asrPathNew] = Manager.AsrPathInstanceDict[asrPathOld];
+ Manager.AsrPathInstanceDict.Remove(asrPathOld);
+
+ // Updata InstanceReferenceDict, change all reference point to container
+ try
+ {
+ var usage = (this as IEcucInstanceBase).GetReferenceByAsrPath(asrPathOld);
+ foreach (var u in usage)
+ {
+ u.ValueRef = asrPathNew;
+ }
+ Manager.InstanceReferenceDict[asrPathNew] = Manager.InstanceReferenceDict[asrPathOld];
+ Manager.InstanceReferenceDict.Remove(asrPathOld);
+ }
+ catch
+ {
+
+ }
+
+ foreach (var continer in Containers)
+ {
+ continer.UpdateAsrPathPrefix(asrPathNew);
+ }
+ }
+
+ ///
+ /// Update autosar path prefix of container.
+ /// The prefix may be changed by parent container shortname changed.
+ ///
+ /// New short name of container
+ public void UpdateAsrPathPrefix(string newName)
+ {
+ // Construct new autosar path
+ var asrPathOld = AsrPath;
+ var parts = AsrPath.Split("/");
+ var asrPathNew = $"{newName}/{parts[^1]}";
+
+ // Check name duplication
+ if (Manager.AsrPathAsrRawDict.ContainsKey(asrPathNew))
+ {
+ throw new Exception($"Already have continer with name {newName}");
+ }
+
+ // Update AsrPathAsrRawDict
+ Manager.AsrPathAsrRawDict[asrPathNew] = Manager.AsrPathAsrRawDict[asrPathOld];
+ Manager.AsrPathAsrRawDict.Remove(asrPathOld);
+ // Update AsrRawAsrPathDict
+ Manager.AsrRawAsrPathDict[Model] = asrPathNew;
+ // Update AsrPathInstanceDict
+ Manager.AsrPathInstanceDict[asrPathNew] = Manager.AsrPathInstanceDict[asrPathOld];
+ Manager.AsrPathInstanceDict.Remove(asrPathOld);
+
+ // Updata InstanceReferenceDict, change all reference point to container
+ try
+ {
+ var usage = (this as IEcucInstanceBase).GetReferenceByAsrPath(asrPathOld);
+ foreach (var u in usage)
+ {
+ u.ValueRef = asrPathNew;
+ }
+ Manager.InstanceReferenceDict[asrPathNew] = Manager.InstanceReferenceDict[asrPathOld];
+ Manager.InstanceReferenceDict.Remove(asrPathOld);
+ }
+ catch
+ {
+
+ }
+
+ foreach (var continer in Containers)
+ {
+ continer.UpdateAsrPathPrefix(asrPathNew);
+ }
+ }
+
+ private void ValidChangedEventHandler(object? sender, PropertyChangedEventArgs e)
+ {
+ Parent.Valid.RaisePropertyChanged(nameof(Valid));
+ RaisePropertyChanged(nameof(Valid));
+ }
+ }
+
+ public class EcucInstanceTextualParamValue : NotifyPropertyChangedBase, IEcucInstanceParam
+ {
+ public ECUCTEXTUALPARAMVALUE Model { get; }
+ public EcucInstanceManager Manager { get; }
+ public IEcucInstanceModule Parent { get; }
+ public EcucValid Valid { get; set; }
+
+ private bool isDirty = false;
+
+ public bool IsDirty
+ {
+ get
+ {
+ return isDirty;
+ }
+ set
+ {
+ if (value != IsDirty)
+ {
+ isDirty = value;
+ if (value == true)
+ {
+ Parent.IsDirty = true;
+ }
+ }
+ }
+ }
+
+ public string BswmdPath
+ {
+ get
+ {
+ return Model.DEFINITIONREF.TypedValue;
+ }
+ set
+ {
+ if (value == null)
+ {
+ return;
+ }
+ if (BswmdPath == value)
+ {
+ return;
+ }
+ Model.DEFINITIONREF.TypedValue = value;
+ }
+ }
+
+ public string Value
+ {
+ get
+ {
+ try
+ {
+ return Model.VALUE.TypedValue;
+ }
+ catch
+ {
+ return "";
+ }
+ }
+ set
+ {
+ if (value == null)
+ {
+ return;
+ }
+ if (Value == value)
+ {
+ return;
+ }
+ Model.VALUE.TypedValue = value;
+ IsDirty = true;
+ }
+ }
+
+ public string Dest
+ {
+ get
+ {
+ return Model.DEFINITIONREF.DEST;
+ }
+ set
+ {
+ if (value == null)
+ {
+ return;
+ }
+ if (Dest == value)
+ {
+ return;
+ }
+ Model.DEFINITIONREF.DEST = value;
+ }
+ }
+
+ public List Comment
+ {
+ get
+ {
+ var result = new List();
+ foreach (var anno in Model.ANNOTATIONS.ANNOTATION)
+ {
+ result.Add(anno.ANNOTATIONORIGIN.TypedValue);
+ }
+ return result;
+ }
+ set
+ {
+ Model.ANNOTATIONS.ANNOTATION = new List();
+ foreach (var comment in value)
+ {
+ Model.ANNOTATIONS.ANNOTATION.Add
+ (
+ new ANNOTATION
+ {
+ ANNOTATIONORIGIN = new STRING
+ {
+ TypedValue = comment
+ }
+ }
+ );
+ }
+ }
+ }
+
+ public EcucInstanceTextualParamValue(string bswmdPath, string dest, string value, EcucInstanceManager manager, IEcucInstanceModule parent)
+ {
+ Model = new ECUCTEXTUALPARAMVALUE
+ {
+ VALUE = new VERBATIMSTRING
+ {
+ TypedValue = value
+ },
+ DEFINITIONREF = new ECUCTEXTUALPARAMVALUE.DEFINITIONREFLocalType
+ {
+ TypedValue = bswmdPath,
+ DEST = dest
+ },
+ };
+ Manager = manager;
+ Parent = parent;
+ IsDirty = parent.IsDirty;
+ Valid = new EcucValid(this);
+ Valid.PropertyChanged += ValidChangedEventHandler;
+
+ Register();
+ }
+
+ public EcucInstanceTextualParamValue(ECUCTEXTUALPARAMVALUE model, EcucInstanceManager manager, IEcucInstanceModule parent)
+ {
+ Model = model;
+ Manager = manager;
+ Parent = parent;
+ IsDirty = parent.IsDirty;
+ Valid = new EcucValid(this);
+ Valid.PropertyChanged += ValidChangedEventHandler;
+
+ Register();
+ }
+
+ private void Register()
+ {
+ Monitor.Enter(Manager.BswmdPathInstanceDict);
+ try
+ {
+ if (Manager.BswmdPathInstanceDict.ContainsKey(BswmdPath))
+ {
+ Manager.BswmdPathInstanceDict[BswmdPath].Add(this);
+ }
+ else
+ {
+ Manager.BswmdPathInstanceDict[BswmdPath] = new List() { this };
+ }
+ }
+ finally
+ {
+ Monitor.Exit(Manager.BswmdPathInstanceDict);
+ }
+ }
+
+ private void ValidChangedEventHandler(object? sender, PropertyChangedEventArgs e)
+ {
+ Parent.Valid.RaisePropertyChanged(nameof(Valid));
+ RaisePropertyChanged(nameof(Valid));
+ }
+ }
+
+ public class EcucInstanceNumericalParamValue : NotifyPropertyChangedBase, IEcucInstanceParam
+ {
+ public ECUCNUMERICALPARAMVALUE Model { get; }
+ public EcucInstanceManager Manager { get; }
+ public IEcucInstanceModule Parent { get; }
+ public EcucValid Valid { get; set; }
+
+ private bool isDirty = false;
+
+ public bool IsDirty
+ {
+ get
+ {
+ return isDirty;
+ }
+ set
+ {
+ if (value != IsDirty)
+ {
+ isDirty = value;
+ if (value == true)
+ {
+ Parent.IsDirty = true;
+ }
+ }
+ }
+ }
+
+ public string BswmdPath
+ {
+ get
+ {
+ return Model.DEFINITIONREF.TypedValue;
+ }
+ set
+ {
+ if (value == null)
+ {
+ return;
+ }
+ if (BswmdPath == value)
+ {
+ return;
+ }
+ Model.DEFINITIONREF.TypedValue = value;
+ }
+ }
+
+ public string Value
+ {
+ get
+ {
+ try
+ {
+ return Model.VALUE.Untyped.Value;
+ }
+ catch
+ {
+ return "0";
+ }
+ }
+ set
+ {
+ if (value == null)
+ {
+ return;
+ }
+ if (Value == value)
+ {
+ return;
+ }
+ Model.VALUE.Untyped.Value = value;
+ IsDirty = true;
+ }
+ }
+
+ public string Dest
+ {
+ get
+ {
+ return Model.DEFINITIONREF.DEST;
+ }
+ set
+ {
+ if (value == null)
+ {
+ return;
+ }
+ if (Dest == value)
+ {
+ return;
+ }
+ Model.DEFINITIONREF.DEST = value;
+ }
+ }
+
+ public List Comment
+ {
+ get
+ {
+ var result = new List();
+ foreach (var anno in Model.ANNOTATIONS.ANNOTATION)
+ {
+ result.Add(anno.ANNOTATIONORIGIN.TypedValue);
+ }
+ return result;
+ }
+ set
+ {
+ Model.ANNOTATIONS.ANNOTATION = new List();
+ foreach (var comment in value)
+ {
+ Model.ANNOTATIONS.ANNOTATION.Add
+ (
+ new ANNOTATION
+ {
+ ANNOTATIONORIGIN = new STRING
+ {
+ TypedValue = comment
+ }
+ }
+ );
+ }
+ }
+ }
+
+ public EcucInstanceNumericalParamValue(string bswmdPath, string dest, string value, EcucInstanceManager manager, IEcucInstanceModule parent)
+ {
+ Model = new ECUCNUMERICALPARAMVALUE
+ {
+ VALUE = new NUMERICALVALUEVARIATIONPOINT(),
+ DEFINITIONREF = new ECUCNUMERICALPARAMVALUE.DEFINITIONREFLocalType
+ {
+ TypedValue = bswmdPath,
+ DEST = dest
+ }
+ };
+ Model.VALUE.Untyped.Value = value;
+ Manager = manager;
+ Parent = parent;
+ IsDirty = parent.IsDirty;
+ Valid = new EcucValid(this);
+ Valid.PropertyChanged += ValidChangedEventHandler;
+
+ Register();
+ }
+
+ public EcucInstanceNumericalParamValue(ECUCNUMERICALPARAMVALUE model, EcucInstanceManager manager, IEcucInstanceModule parent)
+ {
+ Model = model;
+ Manager = manager;
+ Parent = parent;
+ IsDirty = parent.IsDirty;
+ Valid = new EcucValid(this);
+ Valid.PropertyChanged += ValidChangedEventHandler;
+
+ Register();
+ }
+
+ private void Register()
+ {
+ Monitor.Enter(Manager.BswmdPathInstanceDict);
+ try
+ {
+ if (Manager.BswmdPathInstanceDict.ContainsKey(BswmdPath))
+ {
+ Manager.BswmdPathInstanceDict[BswmdPath].Add(this);
+ }
+ else
+ {
+ Manager.BswmdPathInstanceDict[BswmdPath] = new List() { this };
+ }
+ }
+ finally
+ {
+ Monitor.Exit(Manager.BswmdPathInstanceDict);
+ }
+ }
+
+ private void ValidChangedEventHandler(object? sender, PropertyChangedEventArgs e)
+ {
+ Parent.Valid.RaisePropertyChanged(nameof(Valid));
+ RaisePropertyChanged(nameof(Valid));
+ }
+ }
+
+ public class EcucInstanceReferenceValue : NotifyPropertyChangedBase, IEcucInstanceReference
+ {
+ public ECUCREFERENCEVALUE Model { get; }
+ public EcucInstanceManager Manager { get; }
+ public IEcucInstanceModule Parent { get; }
+ public EcucValid Valid { get; set; }
+
+ private bool isDirty = false;
+
+ public bool IsDirty
+ {
+ get
+ {
+ return isDirty;
+ }
+ set
+ {
+ if (value != IsDirty)
+ {
+ isDirty = value;
+ if (value == true)
+ {
+ Parent.IsDirty = true;
+ }
+ }
+ }
+ }
+
+ public string BswmdPath
+ {
+ get
+ {
+ return Model.DEFINITIONREF.TypedValue;
+ }
+ }
+
+ public string DefDest
+ {
+ get
+ {
+ return Model.VALUEREF.DEST;
+ }
+ set
+ {
+ if (value == null)
+ {
+ return;
+ }
+ if (DefDest == value)
+ {
+ return;
+ }
+
+ Model.VALUEREF.DEST = value;
+ }
+ }
+
+ public string ValueRef
+ {
+ get
+ {
+ if (Model.VALUEREF != null)
+ {
+ return Model.VALUEREF.TypedValue;
+ }
+ else
+ {
+ return "";
+ }
+ }
+ set
+ {
+ if (value == null)
+ {
+ return;
+ }
+ if (ValueRef == value)
+ {
+ return;
+ }
+
+ Model.VALUEREF.TypedValue = value;
+ IsDirty = true;
+ }
+ }
+
+ public string ValueDest
+ {
+ get
+ {
+ return Model.VALUEREF.DEST;
+ }
+ set
+ {
+ if (value == null)
+ {
+ return;
+ }
+ if (ValueDest == value)
+ {
+ return;
+ }
+
+ Model.VALUEREF.DEST = value;
+ }
+ }
+
+ public List Comment
+ {
+ get
+ {
+ var result = new List();
+ foreach (var anno in Model.ANNOTATIONS.ANNOTATION)
+ {
+ result.Add(anno.ANNOTATIONORIGIN.TypedValue);
+ }
+ return result;
+ }
+ set
+ {
+ Model.ANNOTATIONS.ANNOTATION = new List();
+ foreach (var comment in value)
+ {
+ Model.ANNOTATIONS.ANNOTATION.Add
+ (
+ new ANNOTATION
+ {
+ ANNOTATIONORIGIN = new STRING
+ {
+ TypedValue = comment
+ }
+ }
+ );
+ }
+ }
+ }
+
+ public EcucInstanceReferenceValue(string bswmdPath, string defDest, string valueRef, string valueDest, EcucInstanceManager manager, IEcucInstanceModule parent)
+ {
+ valueDest = valueDest switch
+ {
+ "ECUC-PARAM-CONF-CONTAINER-DEF" => "ECUC-CONTAINER-VALUE",
+ "ECUC-ENUMERATION-PARAM-DEF" => "ECUC-TEXTUAL-PARAM-VALUE",
+ "ECUC-INTEGER-PARAM-DEF" => "ECUC-NUMERICAL-PARAM-VALUE",
+ "ECUC-BOOLEAN-PARAM-DEF" => "ECUC-NUMERICAL-PARAM-VALUE",
+ "ECUC-FLOAT-PARAM-DEF" => "ECUC-NUMERICAL-PARAM-VALUE",
+ "ECUC-STRING-PARAM-DEF" => "ECUC-TEXTUAL-PARAM-VALUE",
+ "ECUC-FUNCTION-NAME-DEF" => "ECUC-TEXTUAL-PARAM-VALUE",
+ "ECUC-REFERENCE-DEF" => "ECUC-REFERENCE-VALUE",
+ "ECUC-FOREIGN-REFERENCE-DEF" => "ECUC-REFERENCE-VALUE",
+ "ECUC-SYMBOLIC-NAME-REFERENCE-DEF" => "ECUC-REFERENCE-VALUE",
+ _ => throw new NotImplementedException(),
+ };
+ Model = new ECUCREFERENCEVALUE
+ {
+ DEFINITIONREF = new ECUCREFERENCEVALUE.DEFINITIONREFLocalType
+ {
+ TypedValue = bswmdPath,
+ DEST = defDest
+ },
+ VALUEREF = new ECUCREFERENCEVALUE.VALUEREFLocalType
+ {
+ TypedValue = valueRef,
+ DEST = valueDest
+ }
+ };
+ Manager = manager;
+ Parent = parent;
+ IsDirty = parent.IsDirty;
+ Valid = new EcucValid(this);
+ Valid.PropertyChanged += ValidChangedEventHandler;
+
+ Register();
+ }
+
+ public EcucInstanceReferenceValue(ECUCREFERENCEVALUE model, EcucInstanceManager manager, IEcucInstanceModule parent)
+ {
+ Model = model;
+ Manager = manager;
+ Parent = parent;
+ IsDirty = parent.IsDirty;
+ Valid = new EcucValid(this);
+ Valid.PropertyChanged += ValidChangedEventHandler;
+
+ Register();
+ }
+
+ private void Register()
+ {
+ Monitor.Enter(Manager.BswmdPathInstanceDict);
+ try
+ {
+ if (Manager.BswmdPathInstanceDict.ContainsKey(BswmdPath))
+ {
+ Manager.BswmdPathInstanceDict[BswmdPath].Add(this);
+ }
+ else
+ {
+ Manager.BswmdPathInstanceDict[BswmdPath] = new List() { this };
+ }
+ }
+ finally
+ {
+ Monitor.Exit(Manager.BswmdPathInstanceDict);
+ }
+
+ Monitor.Enter(Manager.InstanceReferenceDict);
+ try
+ {
+ if (Manager.InstanceReferenceDict.ContainsKey(ValueRef))
+ {
+ Manager.InstanceReferenceDict[ValueRef].Add(this);
+ }
+ else
+ {
+ Manager.InstanceReferenceDict[ValueRef] = new List() { this };
+ }
+ }
+ finally
+ {
+ Monitor.Exit(Manager.InstanceReferenceDict);
+ }
+ }
+
+ private void ValidChangedEventHandler(object? sender, PropertyChangedEventArgs e)
+ {
+ Parent.Valid.RaisePropertyChanged(nameof(Valid));
+ RaisePropertyChanged(nameof(Valid));
+ }
+ }
+}
diff --git a/EcucBase/EcucPdu.cs b/EcucBase/EcucPdu.cs
new file mode 100644
index 0000000..c854efe
--- /dev/null
+++ b/EcucBase/EcucPdu.cs
@@ -0,0 +1,558 @@
+/*
+ * This file is a part of Autosar Configurator for ECU GUI based
+ * configuration, checking and code generation.
+ *
+ * Copyright (C) 2021-2022 DJS Studio E-mail:DD-Silence@sina.cn
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+
+ * You should have received a copy of the GNU General Public License
+ * along with this program. If not, see .
+ */
+
+using Ecuc.EcucBase.EBswmd;
+using Ecuc.EcucBase.EData;
+using Ecuc.EcucBase.EInstance;
+
+namespace Ecuc.EcucBase.EPdu
+{
+ public enum EcucPduType
+ {
+ CanIfRx = 0,
+ CanIfTx,
+ ComRx,
+ ComTx,
+ SecOCRx,
+ SecOCTx,
+ CanTpNSduRx,
+ CanTpNSduTx,
+ CanTpNPduRx,
+ CanTpNPduTx,
+ CanTpFcNPduRx,
+ CanTpFcNPduTx,
+ EcucPdu
+ }
+
+ public class EcucPdu
+ {
+ EcucBswmdManager BswmdManager { get; }
+ EcucInstanceManager InstanceManager { get; }
+
+ public EcucPdu(EcucBswmdManager bswmdManager, EcucInstanceManager instanceManager)
+ {
+ BswmdManager = bswmdManager;
+ InstanceManager = instanceManager;
+ }
+
+ private static bool FilterFuncComRx(EcucData data)
+ {
+ return data["ComIPduDirection"].ValueSingleEqual("RECEIVE");
+ }
+
+ private static bool FilterFuncComTx(EcucData data)
+ {
+ return data["ComIPduDirection"].ValueSingleEqual("SEND");
+ }
+
+ public EcucDataList GetPdusByType(EcucPduType typ)
+ {
+ switch (typ)
+ {
+ case EcucPduType.CanIfRx:
+ {
+ var instanceModule = InstanceManager["CanIf"];
+ if (instanceModule == null)
+ {
+ return new EcucDataList();
+ }
+ var bswmdModule = BswmdManager.GetBswmdFromBswmdPath(instanceModule.BswmdPath);
+ if (bswmdModule == null)
+ {
+ return new EcucDataList();
+ }
+ var data = new EcucData(instanceModule, bswmdModule);
+ return data["CanIfInitCfg"]["CanIfRxPduCfg"];
+ }
+
+ case EcucPduType.CanIfTx:
+ {
+ var instanceModule = InstanceManager["CanIf"];
+ if (instanceModule == null)
+ {
+ return new EcucDataList();
+ }
+ var bswmdModule = BswmdManager.GetBswmdFromBswmdPath(instanceModule.BswmdPath);
+ if (bswmdModule == null)
+ {
+ return new EcucDataList();
+ }
+ var data = new EcucData(instanceModule, bswmdModule);
+ return data["CanIfInitCfg"]["CanIfTxPduCfg"];
+ }
+
+ case EcucPduType.ComRx:
+ {
+ var instanceModule = InstanceManager["Com"];
+ if (instanceModule == null)
+ {
+ return new EcucDataList();
+ }
+ var bswmdModule = BswmdManager.GetBswmdFromBswmdPath(instanceModule.BswmdPath);
+ if (bswmdModule == null)
+ {
+ return new EcucDataList();
+ }
+ var data = new EcucData(instanceModule, bswmdModule);
+ return data["ComConfig"]["ComIPdu", x => FilterFuncComRx(x)];
+ }
+
+ case EcucPduType.ComTx:
+ {
+ var instanceModule = InstanceManager["Com"];
+ if (instanceModule == null)
+ {
+ return new EcucDataList();
+ }
+ var bswmdModule = BswmdManager.GetBswmdFromBswmdPath(instanceModule.BswmdPath);
+ if (bswmdModule == null)
+ {
+ return new EcucDataList();
+ }
+ var data = new EcucData(instanceModule, bswmdModule);
+ return data["ComConfig"]["ComIPdu", x => FilterFuncComTx(x)];
+ }
+
+ case EcucPduType.SecOCRx:
+ {
+ var instanceModule = InstanceManager["SecOC"];
+ if (instanceModule == null)
+ {
+ return new EcucDataList();
+ }
+ var bswmdModule = BswmdManager.GetBswmdFromBswmdPath(instanceModule.BswmdPath);
+ if (bswmdModule == null)
+ {
+ return new EcucDataList();
+ }
+ var data = new EcucData(instanceModule, bswmdModule);
+ return data["SecOCRxPduProcessing"]["SecOCRxAuthenticPduLayer"];
+ }
+
+ case EcucPduType.SecOCTx:
+ {
+ var instanceModule = InstanceManager["SecOC"];
+ if (instanceModule == null)
+ {
+ return new EcucDataList();
+ }
+ var bswmdModule = BswmdManager.GetBswmdFromBswmdPath(instanceModule.BswmdPath);
+ if (bswmdModule == null)
+ {
+ return new EcucDataList();
+ }
+ var data = new EcucData(instanceModule, bswmdModule);
+ return data["SecOCRxPduProcessing"]["SecOCTxAuthenticPduLayer"];
+ }
+
+ case EcucPduType.CanTpNSduRx:
+ {
+ var instanceModule = InstanceManager["CanTp"];
+ if (instanceModule == null)
+ {
+ return new EcucDataList();
+ }
+ var bswmdModule = BswmdManager.GetBswmdFromBswmdPath(instanceModule.BswmdPath);
+ if (bswmdModule == null)
+ {
+ return new EcucDataList();
+ }
+ var data = new EcucData(instanceModule, bswmdModule);
+ return data["CanTpConfig"]["CanTpChannel"]["CanTpRxNSdu"];
+ }
+
+ case EcucPduType.CanTpNSduTx:
+ {
+ var instanceModule = InstanceManager["CanTp"];
+ if (instanceModule == null)
+ {
+ return new EcucDataList();
+ }
+ var bswmdModule = BswmdManager.GetBswmdFromBswmdPath(instanceModule.BswmdPath);
+ if (bswmdModule == null)
+ {
+ return new EcucDataList();
+ }
+ var data = new EcucData(instanceModule, bswmdModule);
+ return data["CanTpConfig"]["CanTpChannel"]["CanTpTxNSdu"];
+ }
+
+ case EcucPduType.CanTpNPduRx:
+ {
+ var instanceModule = InstanceManager["CanTp"];
+ if (instanceModule == null)
+ {
+ return new EcucDataList();
+ }
+ var bswmdModule = BswmdManager.GetBswmdFromBswmdPath(instanceModule.BswmdPath);
+ if (bswmdModule == null)
+ {
+ return new EcucDataList();
+ }
+ var data = new EcucData(instanceModule, bswmdModule);
+ return data["CanTpConfig"]["CanTpChannel"]["CanTpRxNSdu"]["CanTpRxNPdu"];
+ }
+
+ case EcucPduType.CanTpNPduTx:
+ {
+ var instanceModule = InstanceManager["CanTp"];
+ if (instanceModule == null)
+ {
+ return new EcucDataList();
+ }
+ var bswmdModule = BswmdManager.GetBswmdFromBswmdPath(instanceModule.BswmdPath);
+ if (bswmdModule == null)
+ {
+ return new EcucDataList();
+ }
+ var data = new EcucData(instanceModule, bswmdModule);
+ return data["CanTpConfig"]["CanTpChannel"]["CanTpTxNSdu"]["CanTpTxNPdu"];
+ }
+
+ case EcucPduType.CanTpFcNPduRx:
+ {
+ var instanceModule = InstanceManager["CanTp"];
+ if (instanceModule == null)
+ {
+ return new EcucDataList();
+ }
+ var bswmdModule = BswmdManager.GetBswmdFromBswmdPath(instanceModule.BswmdPath);
+ if (bswmdModule == null)
+ {
+ return new EcucDataList();
+ }
+ var data = new EcucData(instanceModule, bswmdModule);
+ return data["CanTpConfig"]["CanTpChannel"]["CanTpRxNSdu"]["CanTpTxFcNPdu"];
+ }
+
+ case EcucPduType.CanTpFcNPduTx:
+ {
+ var instanceModule = InstanceManager["CanTp"];
+ if (instanceModule == null)
+ {
+ return new EcucDataList();
+ }
+ var bswmdModule = BswmdManager.GetBswmdFromBswmdPath(instanceModule.BswmdPath);
+ if (bswmdModule == null)
+ {
+ return new EcucDataList();
+ }
+ var data = new EcucData(instanceModule, bswmdModule);
+ return data["CanTpConfig"]["CanTpChannel"]["CanTpTxNSdu"]["CanTpRxFcNPdu"];
+ }
+
+ case EcucPduType.EcucPdu:
+ {
+ var instanceModule = InstanceManager["SecOc"];
+ if (instanceModule == null)
+ {
+ return new EcucDataList();
+ }
+ var bswmdModule = BswmdManager.GetBswmdFromBswmdPath(instanceModule.BswmdPath);
+ if (bswmdModule == null)
+ {
+ return new EcucDataList();
+ }
+ var data = new EcucData(instanceModule, bswmdModule);
+ return data["EcucPduCollection"]["Pdu"];
+ }
+
+ default:
+ return new EcucDataList();
+ }
+ }
+
+ static private bool FilterShortNameFunc(EcucData data, string name)
+ {
+ return data.Value.StartsWith(name);
+ }
+
+ private static bool FilterShortNameFuncComRx(EcucData data, string name)
+ {
+ return data.Value.StartsWith(name) && data["ComIPduDirection"].ValueSingleEqual("RECEIVE");
+ }
+
+ private static bool FilterShortNameFuncComTx(EcucData data, string name)
+ {
+ return data.Value.StartsWith(name) && data["ComIPduDirection"].ValueSingleEqual("SEND");
+ }
+
+ public EcucDataList GetPduByTypeAndName(EcucPduType typ, string name)
+ {
+ switch (typ)
+ {
+ case EcucPduType.CanIfRx:
+ {
+ var instanceModule = InstanceManager["CanIf"];
+ if (instanceModule == null)
+ {
+ return new EcucDataList(); ;
+ }
+ var bswmdModule = BswmdManager.GetBswmdFromBswmdPath(instanceModule.BswmdPath);
+ if (bswmdModule == null)
+ {
+ return new EcucDataList();
+ }
+ var data = new EcucData(instanceModule, bswmdModule);
+ return data["CanIfInitCfg"]["CanIfRxPduCfg", x => FilterShortNameFunc(x, name)];
+ }
+
+ case EcucPduType.CanIfTx:
+ {
+ var instanceModule = InstanceManager["CanIf"];
+ if (instanceModule == null)
+ {
+ return new EcucDataList();
+ }
+ var bswmdModule = BswmdManager.GetBswmdFromBswmdPath(instanceModule.BswmdPath);
+ if (bswmdModule == null)
+ {
+ return new EcucDataList();
+ }
+ var data = new EcucData(instanceModule, bswmdModule);
+ return data["CanIfInitCfg"]["CanIfTxPduCfg", x => FilterShortNameFunc(x, name)];
+ }
+
+ case EcucPduType.ComRx:
+ {
+ var instanceModule = InstanceManager["Com"];
+ if (instanceModule == null)
+ {
+ return new EcucDataList();
+ }
+ var bswmdModule = BswmdManager.GetBswmdFromBswmdPath(instanceModule.BswmdPath);
+ if (bswmdModule == null)
+ {
+ return new EcucDataList();
+ }
+ var data = new EcucData(instanceModule, bswmdModule);
+ return data["ComConfig"]["ComIPdu", x => FilterShortNameFuncComRx(x, name)];
+ }
+
+ case EcucPduType.ComTx:
+ {
+ var instanceModule = InstanceManager["Com"];
+ if (instanceModule == null)
+ {
+ return new EcucDataList();
+ }
+ var bswmdModule = BswmdManager.GetBswmdFromBswmdPath(instanceModule.BswmdPath);
+ if (bswmdModule == null)
+ {
+ return new EcucDataList();
+ }
+ var data = new EcucData(instanceModule, bswmdModule);
+ return data["ComConfig"]["ComIPdu", x => FilterShortNameFuncComTx(x, name)];
+ }
+
+ case EcucPduType.SecOCRx:
+ {
+ var instanceModule = InstanceManager["SecOC"];
+ if (instanceModule == null)
+ {
+ return new EcucDataList();
+ }
+ var bswmdModule = BswmdManager.GetBswmdFromBswmdPath(instanceModule.BswmdPath);
+ if (bswmdModule == null)
+ {
+ return new EcucDataList();
+ }
+ var data = new EcucData(instanceModule, bswmdModule);
+ return data["SecOCRxPduProcessing"]["SecOCRxAuthenticPduLayer", x => FilterShortNameFunc(x, name)];
+ }
+
+ case EcucPduType.SecOCTx:
+ {
+ var instanceModule = InstanceManager["SecOC"];
+ if (instanceModule == null)
+ {
+ return new EcucDataList();
+ }
+ var bswmdModule = BswmdManager.GetBswmdFromBswmdPath(instanceModule.BswmdPath);
+ if (bswmdModule == null)
+ {
+ return new EcucDataList();
+ }
+ var data = new EcucData(instanceModule, bswmdModule);
+ return data["SecOCRxPduProcessing"]["SecOCTxAuthenticPduLayer", x => FilterShortNameFunc(x, name)];
+ }
+
+ case EcucPduType.CanTpNSduRx:
+ {
+ var instanceModule = InstanceManager["CanTp"];
+ if (instanceModule == null)
+ {
+ return new EcucDataList();
+ }
+ var bswmdModule = BswmdManager.GetBswmdFromBswmdPath(instanceModule.BswmdPath);
+ if (bswmdModule == null)
+ {
+ return new EcucDataList();
+ }
+ var data = new EcucData(instanceModule, bswmdModule);
+ return data["CanTpConfig"]["CanTpChannel"]["CanTpRxNSdu", x => FilterShortNameFunc(x, name)];
+ }
+
+ case EcucPduType.CanTpNSduTx:
+ {
+ var instanceModule = InstanceManager["CanTp"];
+ if (instanceModule == null)
+ {
+ return new EcucDataList();
+ }
+ var bswmdModule = BswmdManager.GetBswmdFromBswmdPath(instanceModule.BswmdPath);
+ if (bswmdModule == null)
+ {
+ return new EcucDataList();
+ }
+ var data = new EcucData(instanceModule, bswmdModule);
+ return data["CanTpConfig"]["CanTpChannel"]["CanTpTxNSdu", x => FilterShortNameFunc(x, name)];
+ }
+
+ case EcucPduType.CanTpNPduRx:
+ {
+ var instanceModule = InstanceManager["CanTp"];
+ if (instanceModule == null)
+ {
+ return new EcucDataList();
+ }
+ var bswmdModule = BswmdManager.GetBswmdFromBswmdPath(instanceModule.BswmdPath);
+ if (bswmdModule == null)
+ {
+ return new EcucDataList();
+ }
+ var data = new EcucData(instanceModule, bswmdModule);
+ return data["CanTpConfig"]["CanTpChannel"]["CanTpRxNSdu"]["CanTpRxNPdu", x => FilterShortNameFunc(x, name)];
+ }
+
+ case EcucPduType.CanTpNPduTx:
+ {
+ var instanceModule = InstanceManager["CanTp"];
+ if (instanceModule == null)
+ {
+ return new EcucDataList();
+ }
+ var bswmdModule = BswmdManager.GetBswmdFromBswmdPath(instanceModule.BswmdPath);
+ if (bswmdModule == null)
+ {
+ return new EcucDataList();
+ }
+ var data = new EcucData(instanceModule, bswmdModule);
+ return data["CanTpConfig"]["CanTpChannel"]["CanTpTxNSdu"]["CanTpTxNPdu", x => FilterShortNameFunc(x, name)];
+ }
+
+ case EcucPduType.CanTpFcNPduRx:
+ {
+ var instanceModule = InstanceManager["CanTp"];
+ if (instanceModule == null)
+ {
+ return new EcucDataList();
+ }
+ var bswmdModule = BswmdManager.GetBswmdFromBswmdPath(instanceModule.BswmdPath);
+ if (bswmdModule == null)
+ {
+ return new EcucDataList();
+ }
+ var data = new EcucData(instanceModule, bswmdModule);
+ return data["CanTpConfig"]["CanTpChannel"]["CanTpRxNSdu"]["CanTpTxFcNPdu", x => FilterShortNameFunc(x, name)];
+ }
+
+ case EcucPduType.CanTpFcNPduTx:
+ {
+ var instanceModule = InstanceManager["CanTp"];
+ if (instanceModule == null)
+ {
+ return new EcucDataList();
+ }
+ var bswmdModule = BswmdManager.GetBswmdFromBswmdPath(instanceModule.BswmdPath);
+ if (bswmdModule == null)
+ {
+ return new EcucDataList();
+ }
+ var data = new EcucData(instanceModule, bswmdModule);
+ return data["CanTpConfig"]["CanTpChannel"]["CanTpTxNSdu"]["CanTpRxFcNPdu", x => FilterShortNameFunc(x, name)];
+ }
+
+ case EcucPduType.EcucPdu:
+ {
+ var instanceModule = InstanceManager["SecOc"];
+ if (instanceModule == null)
+ {
+ return new EcucDataList();
+ }
+ var bswmdModule = BswmdManager.GetBswmdFromBswmdPath(instanceModule.BswmdPath);
+ if (bswmdModule == null)
+ {
+ return new EcucDataList();
+ }
+ var data = new EcucData(instanceModule, bswmdModule);
+ return data["EcucPduCollection"]["Pdu", x => FilterShortNameFunc(x, name)];
+ }
+
+
+ default:
+ return new EcucDataList();
+ }
+ }
+ }
+
+ public class EcucPduResult
+ {
+ public EcucDataList Datas { get; }
+ private EcucPduType Typ { get; }
+
+ public EcucDataList Reference
+ {
+ get
+ {
+ return Typ switch
+ {
+ EcucPduType.CanIfRx => Datas["CanIfRxPduRef"],
+ EcucPduType.CanIfTx => Datas["CanIfTxPduRef"],
+ EcucPduType.ComRx => Datas["ComPduIdRef"],
+ EcucPduType.ComTx => Datas["ComPduIdRef"],
+ EcucPduType.SecOCRx => Datas["SecOCRxAuthenticLayerPduRef"],
+ EcucPduType.SecOCTx => Datas["SecOCTxAuthenticLayerPduRef"],
+ EcucPduType.CanTpNSduRx => Datas["CanTpRxNSduRef"],
+ EcucPduType.CanTpNSduTx => Datas["CanTpTxNSduRef"],
+ EcucPduType.CanTpNPduRx => Datas["CanTpRxNPduRef"],
+ EcucPduType.CanTpNPduTx => Datas["CanTpTxNPduRef"],
+ EcucPduType.CanTpFcNPduRx => Datas["CanTpRxFcNPduRef"],
+ EcucPduType.CanTpFcNPduTx => Datas["CanTpTxFcNPduRef"],
+ _ => new EcucDataList(),
+ };
+ }
+ }
+
+ public EcucDataList DeReference
+ {
+ get
+ {
+ return Reference.DeRef();
+ }
+ }
+
+ public EcucPduResult(EcucDataList datas, EcucPduType typ)
+ {
+ Datas = datas;
+ Typ = typ;
+ }
+ }
+}
diff --git a/EcucUi/Main.Designer.cs b/EcucUi/Main.Designer.cs
index 81aaf4a..6fb2f6e 100644
--- a/EcucUi/Main.Designer.cs
+++ b/EcucUi/Main.Designer.cs
@@ -335,7 +335,7 @@ private void InitializeComponent()
this.MainMenuStrip = this.menuStrip1;
this.Margin = new System.Windows.Forms.Padding(4);
this.Name = "WdMain";
- this.Text = "Autosar Configurator V1.1";
+ this.Text = "Autosar Configurator V1.2";
this.FormClosing += new System.Windows.Forms.FormClosingEventHandler(this.WdMain_FormClosing);
this.Load += new System.EventHandler(this.WdMain_Load);
this.splitContainer1.Panel1.ResumeLayout(false);
diff --git a/lib/EcucBaseCore.dll b/lib/EcucBaseCore.dll
deleted file mode 100644
index 98ce277..0000000
Binary files a/lib/EcucBaseCore.dll and /dev/null differ