├── .gitignore ├── LICENSE ├── README.md ├── packages └── repositories.config ├── simulator.sln └── simulator ├── Commons ├── Commons.csproj ├── ILog.cs ├── LogFormatter.cs ├── LogMultiplexer.cs ├── LogToFile.cs ├── Properties │ └── AssemblyInfo.cs ├── SafeConvert.cs └── packages.config ├── DNP3 ├── DNP3Commons │ ├── DNP3Commons.csproj │ ├── EventedOutstationApplication.cs │ ├── GUI │ │ ├── DBListView.Designer.cs │ │ ├── DBListView.cs │ │ ├── MeasurementView.Designer.cs │ │ ├── MeasurementView.cs │ │ ├── MeasurementView.resx │ │ ├── TransparentButton.Designer.cs │ │ ├── TransparentButton.cs │ │ └── TransparentButton.resx │ ├── IMeasurementCache.cs │ ├── InfiniteEnumerable.cs │ ├── ListviewDatabaseAdapter.cs │ ├── MeasActions.cs │ ├── Measurement.cs │ ├── MeasurementCache.cs │ ├── MeasurementCollection.cs │ ├── MeasurementConversion.cs │ ├── MeasurementPoco.cs │ ├── Properties │ │ └── AssemblyInfo.cs │ ├── ProxyCommandHandler.cs │ ├── ProxyLoader.cs │ └── packages.config ├── DNP3PluginAPI │ ├── DNP3PluginAPI.csproj │ ├── IOutstationPluginFactory.cs │ ├── Properties │ │ └── AssemblyInfo.cs │ └── packages.config ├── DNP3Simulator │ ├── ActionNodeFactory.cs │ ├── BundledPlugins │ │ ├── MasterForm.Designer.cs │ │ ├── MasterForm.cs │ │ ├── MasterForm.resx │ │ └── StringCallback.cs │ ├── ChannelNode.cs │ ├── Components │ │ ├── AnalogOutputControl.Designer.cs │ │ ├── AnalogOutputControl.cs │ │ ├── AnalogOutputControl.resx │ │ ├── CROBControl.Designer.cs │ │ ├── CROBControl.cs │ │ ├── CROBControl.resx │ │ ├── ChannelDialog.Designer.cs │ │ ├── ChannelDialog.cs │ │ ├── ChannelDialog.resx │ │ ├── ClassFieldControl.Designer.cs │ │ ├── ClassFieldControl.cs │ │ ├── ClassFieldControl.resx │ │ ├── EventBufferConfigControl.Designer.cs │ │ ├── EventBufferConfigControl.cs │ │ ├── EventBufferConfigControl.resx │ │ ├── EventResponseTypeControl.Designer.cs │ │ ├── EventResponseTypeControl.cs │ │ ├── LinkConfigControl.Designer.cs │ │ ├── LinkConfigControl.cs │ │ ├── LinkConfigControl.resx │ │ ├── LogLevelControl.Designer.cs │ │ ├── LogLevelControl.cs │ │ ├── LogLevelControl.resx │ │ ├── MasterConfigControl.Designer.cs │ │ ├── MasterConfigControl.cs │ │ ├── MasterConfigControl.resx │ │ ├── MasterDialog.Designer.cs │ │ ├── MasterDialog.cs │ │ ├── MasterDialog.resx │ │ ├── MasterScanControl.Designer.cs │ │ ├── MasterScanControl.cs │ │ ├── MasterScanControl.resx │ │ ├── OutstationDialog.Designer.cs │ │ ├── OutstationDialog.cs │ │ ├── OutstationDialog.resx │ │ ├── OutstationModuleDialog.Designer.cs │ │ ├── OutstationModuleDialog.cs │ │ ├── OutstationModuleDialog.resx │ │ ├── ResponseTypeControl.Designer.cs │ │ ├── ResponseTypeControl.cs │ │ ├── ResponseTypeControl.resx │ │ ├── ScanDialog.Designer.cs │ │ ├── ScanDialog.cs │ │ ├── ScanDialog.resx │ │ ├── ScanInfo.cs │ │ ├── StaticResponseTypeControl.Designer.cs │ │ ├── StaticResponseTypeControl.cs │ │ ├── TLSOptionsControl.Designer.cs │ │ ├── TLSOptionsControl.cs │ │ ├── TLSOptionsControl.resx │ │ ├── TemplateControl.Designer.cs │ │ ├── TemplateControl.cs │ │ ├── TemplateControl.resx │ │ ├── TemplateDialog.Designer.cs │ │ ├── TemplateDialog.cs │ │ ├── TemplateDialog.resx │ │ ├── TemplateItemDialog.Designer.cs │ │ ├── TemplateItemDialog.cs │ │ └── TemplateItemDialog.resx │ ├── DNP3Config.cs │ ├── DNP3Module.csproj │ ├── DNP3SimulatorPlugin.cs │ ├── DNP3SimulatorPluginFactory.cs │ ├── ForwardingLogHandler.cs │ ├── IDNP3Config.cs │ ├── MasterNode.cs │ ├── NodeAction.cs │ ├── OutstationNode.cs │ ├── Properties │ │ ├── AssemblyInfo.cs │ │ ├── Resources.Designer.cs │ │ └── Resources.resx │ ├── Resources │ │ ├── add.png │ │ ├── network_monitor.png │ │ ├── satellite_dish.png │ │ ├── satellite_dish_add.png │ │ └── send_container.png │ └── packages.config ├── DefaultOutstationPlugin │ ├── DefaultOutstationPlugin.csproj │ ├── GUI │ │ ├── AnalogValueDialog.Designer.cs │ │ ├── AnalogValueDialog.cs │ │ ├── AnalogValueDialog.resx │ │ ├── BinaryValueDialog.Designer.cs │ │ ├── BinaryValueDialog.cs │ │ ├── BinaryValueDialog.resx │ │ ├── CommandHandlerControl.Designer.cs │ │ ├── CommandHandlerControl.cs │ │ ├── CommandHandlerControl.resx │ │ ├── CounterValueDialog.Designer.cs │ │ ├── CounterValueDialog.cs │ │ ├── CounterValueDialog.resx │ │ ├── DoubleBinaryValueDialog.Designer.cs │ │ ├── DoubleBinaryValueDialog.cs │ │ ├── DoubleBinaryValueDialog.resx │ │ ├── OutstationForm.Designer.cs │ │ ├── OutstationForm.cs │ │ ├── OutstationForm.resx │ │ ├── QualitySelector.Designer.cs │ │ ├── QualitySelector.cs │ │ └── QualitySelector.resx │ ├── OutstationInstance.cs │ ├── Properties │ │ └── AssemblyInfo.cs │ └── packages.config └── RelayOutstationPlugin │ ├── OutstationForm.Designer.cs │ ├── OutstationForm.cs │ ├── OutstationForm.resx │ ├── OutstationInstance.cs │ ├── Properties │ ├── AssemblyInfo.cs │ ├── Resources.Designer.cs │ └── Resources.resx │ ├── RelayOutstationPlugin.csproj │ ├── images │ └── relay.jpg │ └── packages.config ├── Simulator ├── AboutBox.Designer.cs ├── AboutBox.cs ├── AboutBox.resx ├── AboutBox.resx.DSN ├── AboutBox.resx.ND ├── App.config ├── CommTreeView.Designer.cs ├── CommTreeView.cs ├── CommTreeView.cs.DSN ├── CommTreeView.cs.ND ├── CommTreeView.resx ├── MakeNoteDialog.Designer.cs ├── MakeNoteDialog.cs ├── MakeNoteDialog.resx ├── Program.cs ├── Properties │ ├── AssemblyInfo.cs │ ├── DataSources │ │ └── MeasurementPoco.datasource │ ├── Resources.Designer.cs │ ├── Resources.resx │ ├── Settings.Designer.cs │ └── Settings.settings ├── Simulator.csproj ├── Simulator.csproj.user ├── SimulatorForm.Designer.cs ├── SimulatorForm.cs ├── SimulatorForm.cs.DSN ├── SimulatorForm.cs.ND ├── SimulatorForm.resx ├── TreeNodeCallbcks.cs ├── automatak.ico └── resources │ ├── add.png │ ├── folder_diskette.png │ ├── info.png │ ├── opendnp3.png │ └── satellite_dish_add.png ├── SimulatorAPI ├── ISimulatorNode.cs ├── ISimulatorPlugin.cs ├── ISimulatorPluginFactory.cs ├── Metric.cs ├── ModuleAPI.csproj └── Properties │ └── AssemblyInfo.cs ├── SimulatorUI ├── App.config ├── LogControl.Designer.cs ├── LogControl.cs ├── LogControl.resx ├── LogFileControl.Designer.cs ├── LogFileControl.cs ├── LogFileControl.resx ├── LogWindow.Designer.cs ├── LogWindow.cs ├── LogWindow.resx ├── Properties │ ├── AssemblyInfo.cs │ ├── Resources.Designer.cs │ ├── Resources.resx │ ├── Settings.Designer.cs │ └── Settings.settings ├── SimulatorUI.csproj └── resources │ ├── arrow_down.png │ ├── arrow_up.png │ ├── clipboard_diskette.png │ ├── cross.png │ ├── edit_config.png │ ├── folder.png │ ├── folder_diskette.png │ ├── folder_down.png │ ├── gear_pencil.png │ ├── info.png │ ├── log_cross.png │ ├── network_monitor.png │ ├── pause.png │ ├── play.png │ ├── satellite_dish.png │ └── satellite_dish_add.png ├── images ├── add.png ├── arrow_down.png ├── arrow_up.png ├── automatak.ico ├── clipboard_diskette.png ├── clipboard_pencil.png ├── cross.png ├── edit_config.png ├── folder.png ├── folder_diskette.png ├── folder_down.png ├── gear_pencil.png ├── info.png ├── log_cross.png ├── network_monitor.png ├── opendnp3.png ├── pause.png ├── play.png ├── satellite_dish.png ├── satellite_dish_add.png └── send_container.png └── setup32.aip /.gitignore: -------------------------------------------------------------------------------- 1 | /packages/opendnp3* 2 | /*.suo 3 | /**/bin 4 | /**/obj -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | ### Graphical DNP3 Master/Outstation simulator 2 | 3 | Depends on opendnp3 via NuGet: 4 | 5 | [https://www.nuget.org/packages/opendnp3](https://www.nuget.org/packages/opendnp3) -------------------------------------------------------------------------------- /packages/repositories.config: -------------------------------------------------------------------------------- 1 |  2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | -------------------------------------------------------------------------------- /simulator/Commons/Commons.csproj: -------------------------------------------------------------------------------- 1 |  2 | 3 | 4 | 5 | Debug 6 | AnyCPU 7 | {67C09F7A-3DD4-4C02-AA3B-6882FB6EA816} 8 | Library 9 | Properties 10 | Automatak.Simulator.Commons 11 | SimulatorCommons 12 | v4.5 13 | 512 14 | 15 | 16 | true 17 | full 18 | false 19 | bin\Debug\ 20 | DEBUG;TRACE 21 | prompt 22 | 4 23 | 24 | 25 | pdbonly 26 | true 27 | bin\Release\ 28 | TRACE 29 | prompt 30 | 4 31 | 32 | 33 | true 34 | bin\x86\Debug\ 35 | DEBUG;TRACE 36 | full 37 | x86 38 | prompt 39 | MinimumRecommendedRules.ruleset 40 | 41 | 42 | bin\x86\Release\ 43 | TRACE 44 | true 45 | pdbonly 46 | x86 47 | prompt 48 | MinimumRecommendedRules.ruleset 49 | 50 | 51 | 52 | ..\..\packages\opendnp3.2.2.0-M1\lib\net45\DNP3CLRAdapter.dll 53 | True 54 | 55 | 56 | ..\..\packages\opendnp3.2.2.0-M1\lib\net45\DNP3CLRInterface.dll 57 | True 58 | 59 | 60 | 61 | 62 | 63 | 64 | 65 | 66 | 67 | 68 | 69 | 70 | 71 | 72 | 73 | 74 | 75 | 76 | 77 | 78 | 79 | 86 | -------------------------------------------------------------------------------- /simulator/Commons/ILog.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Text; 3 | 4 | namespace Automatak.Simulator.Commons 5 | { 6 | public enum DisplayHint 7 | { 8 | EVENT, 9 | ERROR, 10 | WARNING, 11 | INFO, 12 | ALT1, 13 | ALT2, 14 | ALT3, 15 | }; 16 | 17 | public interface ILog 18 | { 19 | void Log(DisplayHint hint, string message); 20 | 21 | void LogFull(DisplayHint hint, string filter, string alias, string message); 22 | } 23 | 24 | } 25 | -------------------------------------------------------------------------------- /simulator/Commons/LogFormatter.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using System.Linq; 4 | using System.Text; 5 | 6 | namespace Automatak.Simulator.Commons 7 | { 8 | public static class LogFormatter 9 | { 10 | private static string timeFormat = "HH:mm:ss.fff"; 11 | private static string logFormat = " {0,-14}{1,-8}{2,-14}{3}"; 12 | 13 | public static string GetLogString(string filters, string alias, string message) 14 | { 15 | return String.Format(logFormat, DateTime.Now.ToString(timeFormat), filters, alias, message); 16 | } 17 | 18 | public static string GetBareString(string message) 19 | { 20 | return String.Format(" {0}{1}", new String(' ', 36), message); 21 | } 22 | } 23 | 24 | } 25 | -------------------------------------------------------------------------------- /simulator/Commons/LogMultiplexer.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using System.Linq; 4 | using System.Text; 5 | using System.Threading.Tasks; 6 | 7 | namespace Automatak.Simulator.Commons 8 | { 9 | public class LogMultiplexer : ILog 10 | { 11 | readonly IEnumerable logs; 12 | 13 | public LogMultiplexer(params ILog[] logs) 14 | { 15 | this.logs = new List(logs); 16 | } 17 | 18 | void ILog.Log(DisplayHint hint, string message) 19 | { 20 | foreach (var log in logs) 21 | { 22 | log.Log(hint, message); 23 | } 24 | } 25 | 26 | void ILog.LogFull(DisplayHint hint, string filter, string alias, string message) 27 | { 28 | foreach (var log in logs) 29 | { 30 | log.LogFull(hint, filter, alias, message); 31 | } 32 | } 33 | } 34 | } 35 | -------------------------------------------------------------------------------- /simulator/Commons/LogToFile.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using System.Collections.Concurrent; 4 | using System.Linq; 5 | using System.Text; 6 | using System.Threading; 7 | 8 | using System.IO; 9 | 10 | namespace Automatak.Simulator.Commons 11 | { 12 | public class LogToFile : ILog 13 | { 14 | readonly BlockingCollection actions = new BlockingCollection(); 15 | readonly BlockingCollection messages = new BlockingCollection(); 16 | 17 | bool shutdown = false; 18 | bool enabled = false; 19 | readonly Thread thread; 20 | string logFilePath = null; 21 | 22 | public LogToFile() 23 | { 24 | this.thread = new Thread(this.Run); 25 | thread.Start(); 26 | } 27 | 28 | public String LogFilePath 29 | { 30 | set 31 | { 32 | this.actions.Add(() => this.ChangeFilePath(value)); 33 | } 34 | } 35 | 36 | public bool Enabled 37 | { 38 | set 39 | { 40 | this.actions.Add(() => this.ChangeEnabledState(value)); 41 | } 42 | } 43 | 44 | public void Shutdown() 45 | { 46 | this.actions.Add(() => this.shutdown = true); 47 | this.thread.Join(); 48 | } 49 | 50 | void ILog.Log(DisplayHint hint, string message) 51 | { 52 | this.EnqueueMessage(LogFormatter.GetBareString(message)); 53 | } 54 | 55 | void ILog.LogFull(DisplayHint hint, string filter, string alias, string message) 56 | { 57 | this.EnqueueMessage(LogFormatter.GetLogString(filter, alias, message)); 58 | } 59 | 60 | void Run() 61 | { 62 | while (!shutdown) 63 | { 64 | actions.Take().Invoke(); 65 | } 66 | } 67 | 68 | void ChangeFilePath(string path) 69 | { 70 | this.logFilePath = path; 71 | } 72 | 73 | void ChangeEnabledState(bool value) 74 | { 75 | this.enabled = value; 76 | } 77 | 78 | void ReadLogMessages() 79 | { 80 | var lines = GetMessages(); 81 | if(enabled && (logFilePath != null) && lines.Any()) 82 | { 83 | WriteToFile(logFilePath, lines); 84 | } 85 | } 86 | 87 | static bool WriteToFile(string path, IEnumerable lines) 88 | { 89 | try 90 | { 91 | File.AppendAllLines(path, lines); 92 | return true; 93 | } 94 | catch(IOException) 95 | { 96 | return false; 97 | } 98 | } 99 | 100 | IEnumerable GetMessages() 101 | { 102 | if (messages.Count > 0) 103 | { 104 | var list = new List(messages.Count); 105 | string msg; 106 | while (messages.TryTake(out msg)) 107 | { 108 | list.Add(msg); 109 | } 110 | return list; 111 | } 112 | else 113 | { 114 | return Enumerable.Empty(); 115 | } 116 | } 117 | 118 | void EnqueueMessage(string msg) 119 | { 120 | this.messages.Add(msg); 121 | this.actions.Add(() => this.ReadLogMessages()); 122 | } 123 | 124 | 125 | 126 | } 127 | } 128 | -------------------------------------------------------------------------------- /simulator/Commons/Properties/AssemblyInfo.cs: -------------------------------------------------------------------------------- 1 | using System.Reflection; 2 | using System.Runtime.CompilerServices; 3 | using System.Runtime.InteropServices; 4 | 5 | // General Information about an assembly is controlled through the following 6 | // set of attributes. Change these attribute values to modify the information 7 | // associated with an assembly. 8 | [assembly: AssemblyTitle("Commons")] 9 | [assembly: AssemblyDescription("")] 10 | [assembly: AssemblyConfiguration("")] 11 | [assembly: AssemblyCompany("")] 12 | [assembly: AssemblyProduct("Commons")] 13 | [assembly: AssemblyCopyright("Copyright © 2014")] 14 | [assembly: AssemblyTrademark("")] 15 | [assembly: AssemblyCulture("")] 16 | 17 | // Setting ComVisible to false makes the types in this assembly not visible 18 | // to COM components. If you need to access a type in this assembly from 19 | // COM, set the ComVisible attribute to true on that type. 20 | [assembly: ComVisible(false)] 21 | 22 | // The following GUID is for the ID of the typelib if this project is exposed to COM 23 | [assembly: Guid("5e3ac8da-e44f-4963-9ac4-45ff7c880a70")] 24 | 25 | // Version information for an assembly consists of the following four values: 26 | // 27 | // Major Version 28 | // Minor Version 29 | // Build Number 30 | // Revision 31 | // 32 | // You can specify all the values or you can default the Build and Revision Numbers 33 | // by using the '*' as shown below: 34 | // [assembly: AssemblyVersion("1.0.*")] 35 | [assembly: AssemblyVersion("1.0.0.0")] 36 | [assembly: AssemblyFileVersion("1.0.0.0")] 37 | -------------------------------------------------------------------------------- /simulator/Commons/SafeConvert.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using System.Linq; 4 | using System.Text; 5 | using System.Threading.Tasks; 6 | 7 | namespace Automatak.Simulator.Commons 8 | { 9 | public static class SafeConvert 10 | { 11 | public static Int16 ToInt16(Decimal value) 12 | { 13 | if (value > Int16.MaxValue) 14 | { 15 | return Int16.MaxValue; 16 | } 17 | else if (value < Int16.MinValue) 18 | { 19 | return Int16.MinValue; 20 | } 21 | else 22 | { 23 | return Convert.ToInt16(value); 24 | } 25 | } 26 | 27 | public static Int32 ToInt32(Decimal value) 28 | { 29 | if (value > Int32.MaxValue) 30 | { 31 | return Int32.MaxValue; 32 | } 33 | else if (value < Int32.MinValue) 34 | { 35 | return Int32.MinValue; 36 | } 37 | else 38 | { 39 | return Convert.ToInt32(value); 40 | } 41 | } 42 | 43 | public static System.Single ToSingle(Decimal value) 44 | { 45 | return Convert.ToSingle(value); 46 | } 47 | 48 | public static System.Double ToDouble(Decimal value) 49 | { 50 | return Convert.ToDouble(value); 51 | } 52 | } 53 | } 54 | -------------------------------------------------------------------------------- /simulator/Commons/packages.config: -------------------------------------------------------------------------------- 1 |  2 | 3 | 4 | -------------------------------------------------------------------------------- /simulator/DNP3/DNP3Commons/GUI/DBListView.Designer.cs: -------------------------------------------------------------------------------- 1 | namespace Automatak.Simulator.DNP3.Commons 2 | { 3 | partial class DBListView 4 | { 5 | /// 6 | /// Required designer variable. 7 | /// 8 | private System.ComponentModel.IContainer components = null; 9 | 10 | /// 11 | /// Clean up any resources being used. 12 | /// 13 | /// true if managed resources should be disposed; otherwise, false. 14 | protected override void Dispose(bool disposing) 15 | { 16 | if (disposing && (components != null)) 17 | { 18 | components.Dispose(); 19 | } 20 | base.Dispose(disposing); 21 | } 22 | 23 | #region Component Designer generated code 24 | 25 | /// 26 | /// Required method for Designer support - do not modify 27 | /// the contents of this method with the code editor. 28 | /// 29 | private void InitializeComponent() 30 | { 31 | components = new System.ComponentModel.Container(); 32 | } 33 | 34 | #endregion 35 | } 36 | } 37 | -------------------------------------------------------------------------------- /simulator/DNP3/DNP3Commons/GUI/DBListView.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using System.ComponentModel; 4 | using System.Drawing; 5 | using System.Data; 6 | using System.Linq; 7 | using System.Text; 8 | using System.Windows.Forms; 9 | 10 | namespace Automatak.Simulator.DNP3.Commons 11 | { 12 | public partial class DBListView : ListView 13 | { 14 | public DBListView() 15 | { 16 | InitializeComponent(); 17 | 18 | this.SetStyle(ControlStyles.OptimizedDoubleBuffer | ControlStyles.AllPaintingInWmPaint, true); 19 | 20 | //Enable the OnNotifyMessage event so we get a chance to filter out 21 | // Windows messages before they get to the form's WndProc 22 | this.SetStyle(ControlStyles.EnableNotifyMessage, true); 23 | } 24 | 25 | protected override void OnNotifyMessage(Message m) 26 | { 27 | //Filter out the WM_ERASEBKGND message 28 | if (m.Msg != 0x14) 29 | { 30 | base.OnNotifyMessage(m); 31 | } 32 | } 33 | } 34 | } 35 | -------------------------------------------------------------------------------- /simulator/DNP3/DNP3Commons/GUI/MeasurementView.Designer.cs: -------------------------------------------------------------------------------- 1 | namespace Automatak.Simulator.DNP3.Commons 2 | { 3 | partial class MeasurementView 4 | { 5 | /// 6 | /// Required designer variable. 7 | /// 8 | private System.ComponentModel.IContainer components = null; 9 | 10 | /// 11 | /// Clean up any resources being used. 12 | /// 13 | /// true if managed resources should be disposed; otherwise, false. 14 | protected override void Dispose(bool disposing) 15 | { 16 | if (disposing && (components != null)) 17 | { 18 | components.Dispose(); 19 | } 20 | base.Dispose(disposing); 21 | } 22 | 23 | #region Component Designer generated code 24 | 25 | /// 26 | /// Required method for Designer support - do not modify 27 | /// the contents of this method with the code editor. 28 | /// 29 | private void InitializeComponent() 30 | { 31 | this.listView = new Automatak.Simulator.DNP3.Commons.DBListView(); 32 | this.columnHeader1 = ((System.Windows.Forms.ColumnHeader)(new System.Windows.Forms.ColumnHeader())); 33 | this.columnHeader2 = ((System.Windows.Forms.ColumnHeader)(new System.Windows.Forms.ColumnHeader())); 34 | this.columnHeader3 = ((System.Windows.Forms.ColumnHeader)(new System.Windows.Forms.ColumnHeader())); 35 | this.columnHeader4 = ((System.Windows.Forms.ColumnHeader)(new System.Windows.Forms.ColumnHeader())); 36 | this.SuspendLayout(); 37 | // 38 | // listView 39 | // 40 | this.listView.Columns.AddRange(new System.Windows.Forms.ColumnHeader[] { 41 | this.columnHeader1, 42 | this.columnHeader2, 43 | this.columnHeader3, 44 | this.columnHeader4}); 45 | this.listView.Dock = System.Windows.Forms.DockStyle.Fill; 46 | this.listView.FullRowSelect = true; 47 | this.listView.HideSelection = false; 48 | this.listView.Location = new System.Drawing.Point(0, 0); 49 | this.listView.Name = "listView"; 50 | this.listView.Size = new System.Drawing.Size(924, 437); 51 | this.listView.TabIndex = 0; 52 | this.listView.UseCompatibleStateImageBehavior = false; 53 | this.listView.View = System.Windows.Forms.View.Details; 54 | this.listView.ItemSelectionChanged += new System.Windows.Forms.ListViewItemSelectionChangedEventHandler(this.listView_ItemSelectionChanged); 55 | this.listView.SelectedIndexChanged += new System.EventHandler(this.listView_SelectedIndexChanged); 56 | // 57 | // columnHeader1 58 | // 59 | this.columnHeader1.Text = "Index"; 60 | this.columnHeader1.Width = 125; 61 | // 62 | // columnHeader2 63 | // 64 | this.columnHeader2.Text = "Value"; 65 | this.columnHeader2.Width = 143; 66 | // 67 | // columnHeader3 68 | // 69 | this.columnHeader3.Text = "Flags"; 70 | this.columnHeader3.Width = 130; 71 | // 72 | // columnHeader4 73 | // 74 | this.columnHeader4.Text = "Timestamp (UTC)"; 75 | this.columnHeader4.Width = 193; 76 | // 77 | // MeasurementView 78 | // 79 | this.AutoScaleDimensions = new System.Drawing.SizeF(6F, 13F); 80 | this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Font; 81 | this.Controls.Add(this.listView); 82 | this.Name = "MeasurementView"; 83 | this.Size = new System.Drawing.Size(924, 437); 84 | this.ResumeLayout(false); 85 | 86 | } 87 | 88 | #endregion 89 | 90 | private DBListView listView; 91 | private System.Windows.Forms.ColumnHeader columnHeader1; 92 | private System.Windows.Forms.ColumnHeader columnHeader2; 93 | private System.Windows.Forms.ColumnHeader columnHeader3; 94 | private System.Windows.Forms.ColumnHeader columnHeader4; 95 | 96 | } 97 | } 98 | -------------------------------------------------------------------------------- /simulator/DNP3/DNP3Commons/GUI/TransparentButton.Designer.cs: -------------------------------------------------------------------------------- 1 | namespace Automatak.Simulator.DNP3.Commons.GUI 2 | { 3 | partial class TransparentButton 4 | { 5 | /// 6 | /// Required designer variable. 7 | /// 8 | private System.ComponentModel.IContainer components = null; 9 | 10 | /// 11 | /// Clean up any resources being used. 12 | /// 13 | /// true if managed resources should be disposed; otherwise, false. 14 | protected override void Dispose(bool disposing) 15 | { 16 | if (disposing && (components != null)) 17 | { 18 | components.Dispose(); 19 | } 20 | base.Dispose(disposing); 21 | } 22 | 23 | #region Component Designer generated code 24 | 25 | /// 26 | /// Required method for Designer support - do not modify 27 | /// the contents of this method with the code editor. 28 | /// 29 | private void InitializeComponent() 30 | { 31 | this.SuspendLayout(); 32 | // 33 | // TransparentButton 34 | // 35 | this.AutoScaleDimensions = new System.Drawing.SizeF(6F, 13F); 36 | this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Font; 37 | this.Name = "TransparentButton"; 38 | this.Size = new System.Drawing.Size(120, 116); 39 | this.ResumeLayout(false); 40 | 41 | } 42 | 43 | #endregion 44 | } 45 | } 46 | -------------------------------------------------------------------------------- /simulator/DNP3/DNP3Commons/GUI/TransparentButton.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using System.ComponentModel; 4 | using System.Drawing; 5 | using System.Data; 6 | using System.Linq; 7 | using System.Text; 8 | using System.Threading.Tasks; 9 | using System.Windows.Forms; 10 | 11 | namespace Automatak.Simulator.DNP3.Commons.GUI 12 | { 13 | public partial class TransparentButton : UserControl 14 | { 15 | public TransparentButton() 16 | { 17 | InitializeComponent(); 18 | 19 | //this.Cursor = Cursors.Hand; 20 | this.SetStyle(ControlStyles.SupportsTransparentBackColor, true); 21 | this.ForeColor = Color.Transparent; 22 | this.BackColor = Color.Transparent; 23 | } 24 | 25 | protected override CreateParams CreateParams 26 | { 27 | get 28 | { 29 | CreateParams cp = base.CreateParams; 30 | cp.ExStyle |= 0x00000020; // WS_EX_TRANSPARENT 31 | return cp; 32 | } 33 | } 34 | 35 | protected override void OnPaint(PaintEventArgs e) 36 | { 37 | //e.Graphics.FillRectangle(new SolidBrush(this.BackColor), this.ClientRectangle); 38 | } 39 | } 40 | } 41 | -------------------------------------------------------------------------------- /simulator/DNP3/DNP3Commons/IMeasurementCache.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using System.Linq; 4 | using System.Text; 5 | using System.Threading.Tasks; 6 | 7 | namespace Automatak.Simulator.DNP3.Commons 8 | { 9 | public interface IMeasurementCache 10 | { 11 | MeasurementCollection GetCollection(MeasType type); 12 | 13 | MeasurementCollection Binaries 14 | { 15 | get; 16 | } 17 | 18 | MeasurementCollection DoubleBinaries 19 | { 20 | get; 21 | } 22 | 23 | MeasurementCollection Counters 24 | { 25 | get; 26 | } 27 | 28 | MeasurementCollection FrozenCounters 29 | { 30 | get; 31 | } 32 | 33 | MeasurementCollection Analogs 34 | { 35 | get; 36 | } 37 | 38 | MeasurementCollection BinaryOutputStatii 39 | { 40 | get; 41 | } 42 | 43 | MeasurementCollection AnalogOutputStatii 44 | { 45 | get; 46 | } 47 | 48 | MeasurementCollection OctetStrings 49 | { 50 | get; 51 | } 52 | } 53 | } 54 | -------------------------------------------------------------------------------- /simulator/DNP3/DNP3Commons/InfiniteEnumerable.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using System.Linq; 4 | using System.Text; 5 | using System.Threading.Tasks; 6 | 7 | namespace Automatak.Simulator.DNP3.Commons 8 | { 9 | public static class InfiniteEnumerable 10 | { 11 | public static IEnumerable Create(params T[] values) 12 | { 13 | int pos = 0; 14 | if (values.Length == 0) 15 | { 16 | yield break; 17 | } 18 | else 19 | { 20 | while (true) 21 | { 22 | yield return values[pos]; 23 | pos = (pos+1) % values.Length; 24 | } 25 | } 26 | } 27 | 28 | 29 | 30 | } 31 | } 32 | -------------------------------------------------------------------------------- /simulator/DNP3/DNP3Commons/ListviewDatabaseAdapter.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using System.Linq; 4 | using System.Text; 5 | using System.Threading.Tasks; 6 | using System.Windows.Forms; 7 | 8 | using Automatak.DNP3.Interface; 9 | 10 | namespace Automatak.Simulator.DNP3.Commons 11 | { 12 | public class ListviewDatabaseAdapter : IDatabase 13 | { 14 | readonly ListBox listBox; 15 | 16 | ListviewDatabaseAdapter(ListBox listBox) 17 | { 18 | this.listBox = listBox; 19 | } 20 | 21 | public static void Process(IChangeSet changes, ListBox listBox) 22 | { 23 | IDatabase adapter = new ListviewDatabaseAdapter(listBox); 24 | 25 | listBox.SuspendLayout(); 26 | changes.Apply(adapter); 27 | listBox.ResumeLayout(); 28 | } 29 | 30 | void Add(Measurement meas, string label) 31 | { 32 | var text = string.Format("{0} ({1}) - {2} - {3}", label, meas.Index, meas.Value, meas.ShortFlags); 33 | listBox.Items.Add(text); 34 | } 35 | 36 | void IDatabase.Update(Binary update, ushort index, EventMode mode) 37 | { 38 | this.Add(update.ToMeasurement(index, TimestampMode.SYNCHRONIZED), "Binary"); 39 | } 40 | 41 | void IDatabase.Update(DoubleBitBinary update, ushort index, EventMode mode) 42 | { 43 | this.Add(update.ToMeasurement(index, TimestampMode.SYNCHRONIZED), "DoubleBitBinary"); 44 | } 45 | 46 | void IDatabase.Update(Analog update, ushort index, EventMode mode) 47 | { 48 | this.Add(update.ToMeasurement(index, TimestampMode.SYNCHRONIZED), "Analog"); 49 | } 50 | 51 | void IDatabase.Update(Counter update, ushort index, EventMode mode) 52 | { 53 | this.Add(update.ToMeasurement(index, TimestampMode.SYNCHRONIZED), "Counter"); 54 | } 55 | 56 | void IDatabase.Update(FrozenCounter update, ushort index, EventMode mode) 57 | { 58 | this.Add(update.ToMeasurement(index, TimestampMode.SYNCHRONIZED), "FrozenCounter"); 59 | } 60 | 61 | void IDatabase.Update(BinaryOutputStatus update, ushort index, EventMode mode) 62 | { 63 | this.Add(update.ToMeasurement(index, TimestampMode.SYNCHRONIZED), "BinaryOutputStatus"); 64 | } 65 | 66 | void IDatabase.Update(AnalogOutputStatus update, ushort index, EventMode mode) 67 | { 68 | this.Add(update.ToMeasurement(index, TimestampMode.SYNCHRONIZED), "AnalogOutputStatus"); 69 | } 70 | 71 | void IDatabase.Update(TimeAndInterval update, ushort index) 72 | { 73 | this.Add(update.ToMeasurement(index, TimestampMode.SYNCHRONIZED), "TimeAndInterval"); 74 | } 75 | } 76 | } 77 | -------------------------------------------------------------------------------- /simulator/DNP3/DNP3Commons/MeasActions.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using System.Linq; 4 | using System.Text; 5 | using System.Threading.Tasks; 6 | 7 | using Automatak.DNP3.Interface; 8 | 9 | namespace Automatak.Simulator.DNP3.Commons 10 | { 11 | public static class MeasActions 12 | { 13 | public static Action GetBinaryAction(bool value, byte quality, DateTime timestamp, ushort index) 14 | { 15 | return (IDatabase db) => 16 | { 17 | db.Update(new Binary(value, quality, timestamp), index); 18 | }; 19 | } 20 | 21 | public static Action GetDoubleBinaryAction(DoubleBit bits, byte quality, DateTime timestamp, ushort index) 22 | { 23 | return (IDatabase db) => 24 | { 25 | db.Update(new DoubleBitBinary(bits, quality, timestamp), index); 26 | }; 27 | } 28 | 29 | public static Action GetBinaryOutputStatusAction(bool value, byte quality, DateTime timestamp, ushort index) 30 | { 31 | return (IDatabase db) => 32 | { 33 | db.Update(new BinaryOutputStatus(value, quality, timestamp), index); 34 | }; 35 | } 36 | 37 | public static Action GetAnalogAction(double value, byte quality, DateTime timestamp, ushort index) 38 | { 39 | return (IDatabase db) => 40 | { 41 | db.Update(new Analog(value, quality, timestamp), index); 42 | }; 43 | } 44 | 45 | public static Action GetAnalogOutputStatusAction(double value, byte quality, DateTime timestamp, ushort index) 46 | { 47 | return (IDatabase db) => 48 | { 49 | db.Update(new AnalogOutputStatus(value, quality, timestamp), index); 50 | }; 51 | } 52 | 53 | public static Action GetCounterAction(uint value, byte quality, DateTime timestamp, ushort index) 54 | { 55 | return (IDatabase db) => 56 | { 57 | db.Update(new Counter(value, quality, timestamp), index); 58 | }; 59 | } 60 | 61 | public static Action GetFrozenCounterAction(uint value, byte quality, DateTime timestamp, ushort index) 62 | { 63 | return (IDatabase db) => 64 | { 65 | db.Update(new FrozenCounter(value, quality, timestamp), index); 66 | }; 67 | } 68 | } 69 | } 70 | -------------------------------------------------------------------------------- /simulator/DNP3/DNP3Commons/Measurement.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using System.Linq; 4 | using System.Text; 5 | 6 | using Automatak.DNP3.Interface; 7 | 8 | namespace Automatak.Simulator.DNP3.Commons 9 | { 10 | public enum MeasType 11 | { 12 | Binary, 13 | DoubleBitBinary, 14 | Counter, 15 | FrozenCounter, 16 | Analog, 17 | BinaryOutputStatus, 18 | AnalogOutputStatus, 19 | OctetString, 20 | TimeAndInterval 21 | }; 22 | 23 | public class Measurement 24 | { 25 | public Measurement(string displayValue, MeasurementBase meas, TimestampMode tsmode, MeasType type, UInt16 index, IQualityBitInfo info) 26 | { 27 | this.valueAsString = displayValue; 28 | this.timeStamp = (tsmode == TimestampMode.INVALID) ? DateTime.Now : meas.Timestamp; 29 | this.tsmode = tsmode; 30 | this.type = type; 31 | this.index = index; 32 | this.info = info; 33 | this.quality = meas.Quality; 34 | } 35 | 36 | public Measurement(string displayValue, TimestampMode tsmode, MeasType type, UInt16 index, IQualityBitInfo info) 37 | { 38 | this.valueAsString = displayValue; 39 | this.timeStamp = DateTime.Now; 40 | this.tsmode = tsmode; 41 | this.type = type; 42 | this.index = index; 43 | this.info = info; 44 | this.quality = 0; 45 | } 46 | 47 | public ushort Index 48 | { 49 | get 50 | { 51 | return index; 52 | } 53 | } 54 | 55 | public string Value 56 | { 57 | get 58 | { 59 | return valueAsString; 60 | } 61 | } 62 | 63 | public string Flags 64 | { 65 | get 66 | { 67 | if (QualityInfo.CountOf(quality) > 2) 68 | { 69 | return ShortFlags + " - " + String.Join(", ", QualityInfo.GetShortNames(quality, info)); 70 | } 71 | else 72 | { 73 | return ShortFlags + " - " + String.Join(", ", QualityInfo.GetLongNames(quality, info)); 74 | } 75 | } 76 | } 77 | 78 | public string ShortFlags 79 | { 80 | get 81 | { 82 | return "0x" + quality.ToString("X02"); 83 | } 84 | } 85 | 86 | public string Timestamp 87 | { 88 | get 89 | { 90 | var time = timeStamp.ToString("d") + timeStamp.ToString(" HH:mm:ss.fff"); 91 | return String.Format("{0} ({1})", time, GetTimeModeString(tsmode)); 92 | } 93 | } 94 | 95 | private static string GetTimeModeString(TimestampMode mode) 96 | { 97 | switch(mode) 98 | { 99 | case(TimestampMode.INVALID): 100 | return "local timestamp"; 101 | case(TimestampMode.SYNCHRONIZED): 102 | return "synchronized"; 103 | default: 104 | return "unsynchronized"; 105 | } 106 | } 107 | 108 | public MeasType Type 109 | { 110 | get 111 | { 112 | return type; 113 | } 114 | } 115 | 116 | readonly UInt16 index; 117 | readonly string valueAsString; 118 | readonly DateTime timeStamp; 119 | readonly TimestampMode tsmode; 120 | readonly MeasType type; 121 | readonly IQualityBitInfo info; 122 | readonly byte quality; 123 | } 124 | } 125 | -------------------------------------------------------------------------------- /simulator/DNP3/DNP3Commons/MeasurementCollection.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using System.Linq; 4 | using System.Text; 5 | 6 | using System.Collections.ObjectModel; 7 | 8 | namespace Automatak.Simulator.DNP3.Commons 9 | { 10 | public interface IMeasurementObserver 11 | { 12 | void Refresh(IEnumerable rows); 13 | 14 | void Update(Measurement meas); 15 | } 16 | 17 | public class MeasurementCollection 18 | { 19 | private IDictionary map = new SortedDictionary(); 20 | 21 | private IList observers = new List(); 22 | 23 | public void AddObserver(IMeasurementObserver observer) 24 | { 25 | lock (observers) 26 | { 27 | this.observers.Add(observer); 28 | observer.Refresh(map.Values); 29 | } 30 | } 31 | 32 | public void RemoveObserver(IMeasurementObserver observer) 33 | { 34 | lock (observers) 35 | { 36 | this.observers.Remove(observer); 37 | } 38 | } 39 | 40 | public void Update(Measurement meas) 41 | { 42 | lock (observers) 43 | { 44 | map[meas.Index] = meas; 45 | foreach (var o in observers) 46 | { 47 | o.Update(meas); 48 | } 49 | } 50 | } 51 | 52 | public void Update(IEnumerable meas) 53 | { 54 | lock (observers) 55 | { 56 | foreach (var m in meas) 57 | { 58 | map[m.Index] = m; 59 | foreach (var o in observers) 60 | { 61 | o.Update(m); 62 | } 63 | } 64 | } 65 | } 66 | 67 | } 68 | } 69 | -------------------------------------------------------------------------------- /simulator/DNP3/DNP3Commons/MeasurementConversion.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using System.Linq; 4 | using System.Text; 5 | using System.Threading.Tasks; 6 | 7 | using Automatak.DNP3.Interface; 8 | 9 | namespace Automatak.Simulator.DNP3.Commons 10 | { 11 | public static class MeasurementConversion 12 | { 13 | public static Measurement ToMeasurement(this Binary meas, UInt16 index, TimestampMode tsmode) 14 | { 15 | return new Measurement(meas.Value.ToString(), meas, tsmode, MeasType.Binary, index, QualityInfo.binary); 16 | } 17 | 18 | public static Measurement ToMeasurement(this DoubleBitBinary meas, UInt16 index, TimestampMode tsmode) 19 | { 20 | return new Measurement(meas.Value.ToString(), meas, tsmode, MeasType.DoubleBitBinary, index, QualityInfo.doubleBinary); 21 | } 22 | 23 | public static Measurement ToMeasurement(this Counter meas, UInt16 index, TimestampMode tsmode) 24 | { 25 | return new Measurement(meas.Value.ToString(), meas, tsmode, MeasType.Counter, index, QualityInfo.counter); 26 | } 27 | 28 | public static Measurement ToMeasurement(this FrozenCounter meas, UInt16 index, TimestampMode tsmode) 29 | { 30 | return new Measurement(meas.Value.ToString(), meas, tsmode, MeasType.FrozenCounter, index, QualityInfo.counter); 31 | } 32 | 33 | public static Measurement ToMeasurement(this Analog meas, UInt16 index, TimestampMode tsmode) 34 | { 35 | return new Measurement(meas.Value.ToString(), meas, tsmode, MeasType.Analog, index, QualityInfo.analog); 36 | } 37 | 38 | public static Measurement ToMeasurement(this BinaryOutputStatus meas, UInt16 index, TimestampMode tsmode) 39 | { 40 | return new Measurement(meas.Value.ToString(), meas, tsmode, MeasType.BinaryOutputStatus, index, QualityInfo.binaryOutputStatus); 41 | } 42 | 43 | public static Measurement ToMeasurement(this AnalogOutputStatus meas, UInt16 index, TimestampMode tsmode) 44 | { 45 | return new Measurement(meas.Value.ToString(), meas, tsmode, MeasType.AnalogOutputStatus, index, QualityInfo.analog); 46 | } 47 | 48 | public static Measurement ToMeasurement(this TimeAndInterval meas, UInt16 index, TimestampMode tsmode) 49 | { 50 | return new Measurement(meas.ToString(), tsmode, MeasType.TimeAndInterval, index, QualityInfo.octetString); 51 | } 52 | 53 | public static Measurement ToMeasurement(this OctetString meas, UInt16 index, TimestampMode tsmode) 54 | { 55 | return new Measurement(meas.AsString(), tsmode, MeasType.OctetString, index, QualityInfo.octetString); 56 | } 57 | } 58 | } 59 | -------------------------------------------------------------------------------- /simulator/DNP3/DNP3Commons/MeasurementPoco.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using System.Linq; 4 | using System.Text; 5 | 6 | using System.ComponentModel; 7 | 8 | using Automatak.DNP3.Interface; 9 | 10 | namespace Automatak.Simulator.DNP3.Commons 11 | { 12 | class MeasurementPoco : INotifyPropertyChanged 13 | { 14 | public event PropertyChangedEventHandler PropertyChanged; 15 | 16 | private void NotifyPropertyChanged(string name) 17 | { 18 | if (PropertyChanged != null) 19 | { 20 | PropertyChanged(this, new PropertyChangedEventArgs(name)); 21 | } 22 | } 23 | 24 | public MeasurementPoco(int row, string sValue, MeasurementBase meas, UInt16 index, MeasType type) 25 | { 26 | this.sValue = sValue; 27 | this.index = index; 28 | this.flags = meas.Quality.ToString("X2"); 29 | this.timeStamp = meas.Timestamp; 30 | this.row = row; 31 | this.type = type; 32 | } 33 | 34 | public void Update(string sValue, MeasurementBase meas) 35 | { 36 | Value = sValue; 37 | Flags = meas.Quality.ToString("X2"); 38 | TimeStamp = meas.Timestamp; 39 | } 40 | 41 | private UInt16 index; 42 | private string sValue; 43 | private string flags; 44 | private DateTime timeStamp; 45 | private int row; 46 | private MeasType type; 47 | 48 | public void NextRow() 49 | { 50 | ++row; 51 | } 52 | 53 | public UInt16 Index 54 | { 55 | get { return index; } 56 | set { 57 | index = value; 58 | NotifyPropertyChanged("Index"); 59 | } 60 | } 61 | 62 | public string Value 63 | { 64 | get { return sValue; } 65 | set { 66 | sValue = value; 67 | NotifyPropertyChanged("Value"); 68 | } 69 | } 70 | 71 | public string Flags 72 | { 73 | get { return flags; } 74 | set { 75 | flags = value; 76 | NotifyPropertyChanged("Flags"); 77 | } 78 | } 79 | 80 | public DateTime TimeStamp 81 | { 82 | get { return timeStamp; } 83 | set { 84 | timeStamp = value; 85 | NotifyPropertyChanged("TimeStamp"); 86 | } 87 | } 88 | 89 | [Browsable(false)] 90 | public int Row 91 | { 92 | get { return row; } 93 | set { row = value; } 94 | } 95 | 96 | [Browsable(false)] 97 | public MeasType Type 98 | { 99 | get { return type; } 100 | set { type = value; } 101 | } 102 | } 103 | } 104 | -------------------------------------------------------------------------------- /simulator/DNP3/DNP3Commons/Properties/AssemblyInfo.cs: -------------------------------------------------------------------------------- 1 | using System.Reflection; 2 | using System.Runtime.CompilerServices; 3 | using System.Runtime.InteropServices; 4 | 5 | // General Information about an assembly is controlled through the following 6 | // set of attributes. Change these attribute values to modify the information 7 | // associated with an assembly. 8 | [assembly: AssemblyTitle("DNP3Commons")] 9 | [assembly: AssemblyDescription("")] 10 | [assembly: AssemblyConfiguration("")] 11 | [assembly: AssemblyCompany("")] 12 | [assembly: AssemblyProduct("DNP3Commons")] 13 | [assembly: AssemblyCopyright("Copyright © 2015")] 14 | [assembly: AssemblyTrademark("")] 15 | [assembly: AssemblyCulture("")] 16 | 17 | // Setting ComVisible to false makes the types in this assembly not visible 18 | // to COM components. If you need to access a type in this assembly from 19 | // COM, set the ComVisible attribute to true on that type. 20 | [assembly: ComVisible(false)] 21 | 22 | // The following GUID is for the ID of the typelib if this project is exposed to COM 23 | [assembly: Guid("c5bd0cdd-bc01-4699-b1d7-e0ae4ee17a90")] 24 | 25 | // Version information for an assembly consists of the following four values: 26 | // 27 | // Major Version 28 | // Minor Version 29 | // Build Number 30 | // Revision 31 | // 32 | // You can specify all the values or you can default the Build and Revision Numbers 33 | // by using the '*' as shown below: 34 | // [assembly: AssemblyVersion("1.0.*")] 35 | [assembly: AssemblyVersion("1.0.0.0")] 36 | [assembly: AssemblyFileVersion("1.0.0.0")] 37 | -------------------------------------------------------------------------------- /simulator/DNP3/DNP3Commons/ProxyLoader.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using System.Linq; 4 | using System.Text; 5 | using System.Threading.Tasks; 6 | 7 | using Automatak.DNP3.Interface; 8 | 9 | namespace Automatak.Simulator.DNP3.Commons 10 | { 11 | public class ProxyLoader : IMeasurementLoader 12 | { 13 | IEnumerable loaders; 14 | 15 | public ProxyLoader(params IMeasurementLoader[] loaders) 16 | { 17 | this.loaders = new List(loaders); 18 | } 19 | 20 | void IMeasurementLoader.Load(IChangeSet updates) 21 | { 22 | foreach (var loader in loaders) 23 | { 24 | loader.Load(updates); 25 | } 26 | } 27 | } 28 | } 29 | -------------------------------------------------------------------------------- /simulator/DNP3/DNP3Commons/packages.config: -------------------------------------------------------------------------------- 1 |  2 | 3 | 4 | -------------------------------------------------------------------------------- /simulator/DNP3/DNP3PluginAPI/DNP3PluginAPI.csproj: -------------------------------------------------------------------------------- 1 |  2 | 3 | 4 | 5 | Debug 6 | AnyCPU 7 | {A392B2A4-F62E-442C-813E-6B7F4BF63459} 8 | Library 9 | Properties 10 | Automatak.Simulator.DNP3.API 11 | DNP3PluginAPI 12 | v4.5 13 | 512 14 | 15 | 16 | true 17 | full 18 | false 19 | bin\Debug\ 20 | DEBUG;TRACE 21 | prompt 22 | 4 23 | 24 | 25 | pdbonly 26 | true 27 | bin\Release\ 28 | TRACE 29 | prompt 30 | 4 31 | 32 | 33 | true 34 | bin\x86\Debug\ 35 | DEBUG;TRACE 36 | full 37 | x86 38 | prompt 39 | MinimumRecommendedRules.ruleset 40 | 41 | 42 | bin\x86\Release\ 43 | TRACE 44 | true 45 | pdbonly 46 | x86 47 | prompt 48 | MinimumRecommendedRules.ruleset 49 | 50 | 51 | 52 | ..\..\..\packages\opendnp3.2.2.0-M1\lib\net45\DNP3CLRAdapter.dll 53 | True 54 | 55 | 56 | ..\..\..\packages\opendnp3.2.2.0-M1\lib\net45\DNP3CLRInterface.dll 57 | True 58 | 59 | 60 | 61 | 62 | 63 | 64 | 65 | 66 | 67 | 68 | 69 | 70 | 71 | 72 | 73 | {6a19318b-8cc5-4bc8-8e80-412180c420a5} 74 | ModuleAPI 75 | 76 | 77 | 78 | 79 | 80 | 81 | 88 | -------------------------------------------------------------------------------- /simulator/DNP3/DNP3PluginAPI/IOutstationPluginFactory.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using System.Linq; 4 | using System.Text; 5 | using System.Threading.Tasks; 6 | 7 | using Automatak.DNP3.Interface; 8 | using Automatak.Simulator.API; 9 | 10 | namespace Automatak.Simulator.DNP3.API 11 | { 12 | public interface IOutstationModule 13 | { 14 | OutstationStackConfig DefaultConfig 15 | { 16 | get; 17 | } 18 | 19 | bool AllowTemplateEditing 20 | { 21 | get; 22 | } 23 | 24 | string Description 25 | { 26 | get; 27 | } 28 | 29 | string Name 30 | { 31 | get; 32 | } 33 | 34 | string DefaultLogName 35 | { 36 | get; 37 | } 38 | 39 | IOutstationFactory CreateFactory(); 40 | 41 | } 42 | 43 | public interface IOutstationInstance 44 | { 45 | bool HasForm 46 | { 47 | get; 48 | } 49 | 50 | bool ShowFormOnCreation 51 | { 52 | get; 53 | } 54 | 55 | string DisplayName 56 | { 57 | get; 58 | } 59 | 60 | void ShowForm(); 61 | 62 | void Shutdown(); 63 | } 64 | 65 | public interface IOutstationFactory 66 | { 67 | ICommandHandler CommandHandler 68 | { 69 | get; 70 | } 71 | 72 | IOutstationApplication Application 73 | { 74 | get; 75 | } 76 | 77 | IOutstationInstance CreateInstance(IOutstation outstation, string name, OutstationStackConfig config); 78 | } 79 | 80 | 81 | } 82 | -------------------------------------------------------------------------------- /simulator/DNP3/DNP3PluginAPI/Properties/AssemblyInfo.cs: -------------------------------------------------------------------------------- 1 | using System.Reflection; 2 | using System.Runtime.CompilerServices; 3 | using System.Runtime.InteropServices; 4 | 5 | // General Information about an assembly is controlled through the following 6 | // set of attributes. Change these attribute values to modify the information 7 | // associated with an assembly. 8 | [assembly: AssemblyTitle("DNP3PluginAPI")] 9 | [assembly: AssemblyDescription("")] 10 | [assembly: AssemblyConfiguration("")] 11 | [assembly: AssemblyCompany("")] 12 | [assembly: AssemblyProduct("DNP3PluginAPI")] 13 | [assembly: AssemblyCopyright("Copyright © 2015")] 14 | [assembly: AssemblyTrademark("")] 15 | [assembly: AssemblyCulture("")] 16 | 17 | // Setting ComVisible to false makes the types in this assembly not visible 18 | // to COM components. If you need to access a type in this assembly from 19 | // COM, set the ComVisible attribute to true on that type. 20 | [assembly: ComVisible(false)] 21 | 22 | // The following GUID is for the ID of the typelib if this project is exposed to COM 23 | [assembly: Guid("b473e5a9-3579-4899-bf8c-4be3a7bf0d7f")] 24 | 25 | // Version information for an assembly consists of the following four values: 26 | // 27 | // Major Version 28 | // Minor Version 29 | // Build Number 30 | // Revision 31 | // 32 | // You can specify all the values or you can default the Build and Revision Numbers 33 | // by using the '*' as shown below: 34 | // [assembly: AssemblyVersion("1.0.*")] 35 | [assembly: AssemblyVersion("1.0.0.0")] 36 | [assembly: AssemblyFileVersion("1.0.0.0")] 37 | -------------------------------------------------------------------------------- /simulator/DNP3/DNP3PluginAPI/packages.config: -------------------------------------------------------------------------------- 1 |  2 | 3 | 4 | -------------------------------------------------------------------------------- /simulator/DNP3/DNP3Simulator/ActionNodeFactory.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using System.Linq; 4 | using System.Text; 5 | using System.Threading.Tasks; 6 | 7 | using Automatak.Simulator.API; 8 | 9 | namespace Automatak.Simulator.DNP3 10 | { 11 | class ActionNodeFactory : ISimulatorNodeFactory 12 | { 13 | readonly string displayName; 14 | readonly Func factory; 15 | 16 | 17 | public ActionNodeFactory(string displayName, Func factory) 18 | { 19 | this.displayName = displayName; 20 | this.factory = factory; 21 | } 22 | 23 | string ISimulatorNodeFactory.DisplayName 24 | { 25 | get { return displayName; } 26 | } 27 | 28 | ISimulatorNode ISimulatorNodeFactory.Create(ISimulatorNodeCallbacks callbacks) 29 | { 30 | return factory.Invoke(callbacks); 31 | } 32 | } 33 | } 34 | -------------------------------------------------------------------------------- /simulator/DNP3/DNP3Simulator/BundledPlugins/MasterForm.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using System.ComponentModel; 4 | using System.Data; 5 | using System.Drawing; 6 | using System.Linq; 7 | using System.Text; 8 | using System.Windows.Forms; 9 | using System.Threading.Tasks; 10 | 11 | using Automatak.DNP3.Interface; 12 | using Automatak.Simulator.DNP3.Commons; 13 | 14 | namespace Automatak.Simulator.DNP3 15 | { 16 | partial class MasterForm : Form 17 | { 18 | MeasurementCollection activeCollection = null; 19 | 20 | readonly IMaster master; 21 | readonly IMeasurementCache cache; 22 | 23 | public MasterForm(IMaster master, IMeasurementCache cache, String alias) 24 | { 25 | InitializeComponent(); 26 | 27 | this.master = master; 28 | this.cache = cache; 29 | 30 | this.Text = String.Format("DNP3 Master ({0})", alias); 31 | 32 | this.masterScanControl1.Master = master; 33 | 34 | this.comboBoxFunctionCode.DataSource = Enum.GetValues(typeof(FunctionCode)); 35 | } 36 | 37 | void GUIMasterForm_FormClosing(object sender, FormClosingEventArgs e) 38 | { 39 | e.Cancel = true; 40 | this.Hide(); 41 | } 42 | 43 | void GUIMasterForm_Load(object sender, EventArgs e) 44 | { 45 | this.comboBoxTypes.DataSource = null; 46 | this.comboBoxTypes.DataSource = System.Enum.GetValues(typeof(MeasType)); 47 | } 48 | 49 | void comboBoxTypes_SelectedIndexChanged(object sender, EventArgs e) 50 | { 51 | var index = this.comboBoxTypes.SelectedIndex; 52 | if(Enum.IsDefined(typeof(MeasType), index)) 53 | { 54 | MeasType type = (MeasType) Enum.ToObject(typeof(MeasType), index); 55 | var collection = cache.GetCollection(type); 56 | if (collection != null) 57 | { 58 | if (activeCollection != null) 59 | { 60 | activeCollection.RemoveObserver(this.measurementView); 61 | } 62 | 63 | activeCollection = collection; 64 | 65 | collection.AddObserver(this.measurementView); 66 | } 67 | } 68 | } 69 | 70 | private void buttonDirectOperate_Click(object sender, EventArgs e) 71 | { 72 | DoCommandAction(this.crobControl.DirectOperateAction); 73 | } 74 | 75 | private void buttonSelectOperate_Click(object sender, EventArgs e) 76 | { 77 | DoCommandAction(this.crobControl.SelectAndOperateAction); 78 | } 79 | 80 | private void buttonDOAO_Click(object sender, EventArgs e) 81 | { 82 | DoCommandAction(this.analogOutputControl.DirectOperateAction); 83 | } 84 | 85 | private void buttonSBOAO_Click(object sender, EventArgs e) 86 | { 87 | DoCommandAction(this.analogOutputControl.SelectAndOperateAction); 88 | } 89 | 90 | private void DoCommandAction(Func> func) 91 | { 92 | this.toolStripStatusLabel.Text = "Result: ... "; 93 | var task = func(this.master); 94 | task.ContinueWith(cr => 95 | this.BeginInvoke(new Action(() => 96 | this.toolStripStatusLabel.Text += cr.Result.ToString() 97 | )) 98 | ); 99 | 100 | } 101 | 102 | private void buttonSendFunction_Click(object sender, EventArgs e) 103 | { 104 | this.toolStripStatusLabel.Text = "Result: ... "; 105 | var function = (FunctionCode)this.comboBoxFunctionCode.SelectedValue; 106 | 107 | /* TODO 108 | this.master.PerformFunction(function, Enumerable.Empty
(), function.ToString(), callback); 109 | callback.Task.ContinueWith(task => 110 | this.BeginInvoke(new Action(() => 111 | this.toolStripStatusLabel.Text += task.Result.ToString() 112 | )) 113 | ); 114 | * */ 115 | } 116 | 117 | } 118 | } 119 | -------------------------------------------------------------------------------- /simulator/DNP3/DNP3Simulator/BundledPlugins/StringCallback.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using System.Linq; 4 | using System.Text; 5 | using System.Threading.Tasks; 6 | using System.Threading; 7 | 8 | using Automatak.DNP3.Interface; 9 | 10 | namespace Automatak.Simulator.DNP3 11 | { 12 | class StringCallback : ITaskCallback 13 | { 14 | readonly TaskCompletionSource tcs = new TaskCompletionSource(); 15 | 16 | public Task Task 17 | { 18 | get 19 | { 20 | return tcs.Task; 21 | } 22 | } 23 | 24 | void ITaskCallback.OnStart() 25 | { 26 | 27 | } 28 | 29 | void ITaskCallback.OnComplete(TaskCompletion result) 30 | { 31 | tcs.SetResult(result); 32 | } 33 | 34 | void ITaskCallback.OnDestroyed() 35 | { 36 | 37 | } 38 | } 39 | } 40 | -------------------------------------------------------------------------------- /simulator/DNP3/DNP3Simulator/Components/AnalogOutputControl.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using System.ComponentModel; 4 | using System.Drawing; 5 | using System.Data; 6 | using System.Linq; 7 | using System.Text; 8 | using System.Threading.Tasks; 9 | using System.Windows.Forms; 10 | 11 | using Automatak.Simulator.Commons; 12 | using Automatak.DNP3.Interface; 13 | 14 | namespace Automatak.Simulator.DNP3.Components 15 | { 16 | public partial class AnalogOutputControl : UserControl 17 | { 18 | enum AOType 19 | { 20 | Integer16, 21 | Integer32, 22 | Float32, 23 | Double64 24 | }; 25 | 26 | public AnalogOutputControl() 27 | { 28 | InitializeComponent(); 29 | 30 | comboBoxType.DataSource = Enum.GetValues(typeof(AOType)); 31 | } 32 | 33 | public Func> DirectOperateAction 34 | { 35 | get 36 | { 37 | 38 | var index = Convert.ToUInt16(this.numericUpDownIndex.Value); 39 | var value = numericUpDownValue.Value; 40 | var type = (AOType) comboBoxType.SelectedValue; 41 | switch (type) 42 | { 43 | case(AOType.Integer16): 44 | return (ICommandProcessor cp) => cp.DirectOperate(new AnalogOutputInt16(SafeConvert.ToInt16(value)) , index, TaskConfig.Default); 45 | case (AOType.Integer32): 46 | return (ICommandProcessor cp) => cp.DirectOperate(new AnalogOutputInt32(SafeConvert.ToInt32(value)), index, TaskConfig.Default); 47 | case(AOType.Float32): 48 | return (ICommandProcessor cp) => cp.DirectOperate(new AnalogOutputFloat32(SafeConvert.ToSingle(value)), index, TaskConfig.Default); 49 | default: 50 | return (ICommandProcessor cp) => cp.DirectOperate(new AnalogOutputDouble64(SafeConvert.ToDouble(value)), index, TaskConfig.Default); 51 | } 52 | } 53 | } 54 | 55 | public Func> SelectAndOperateAction 56 | { 57 | get 58 | { 59 | 60 | var index = Convert.ToUInt16(this.numericUpDownIndex.Value); 61 | var value = numericUpDownValue.Value; 62 | var type = (AOType)comboBoxType.SelectedValue; 63 | switch (type) 64 | { 65 | case (AOType.Integer16): 66 | return (ICommandProcessor cp) => cp.SelectAndOperate(new AnalogOutputInt16(Convert.ToInt16(value)), index, TaskConfig.Default); 67 | case (AOType.Integer32): 68 | return (ICommandProcessor cp) => cp.SelectAndOperate(new AnalogOutputInt32(Convert.ToInt32(value)), index, TaskConfig.Default); 69 | case (AOType.Float32): 70 | return (ICommandProcessor cp) => cp.SelectAndOperate(new AnalogOutputFloat32(Convert.ToSingle(value)), index, TaskConfig.Default); 71 | default: 72 | return (ICommandProcessor cp) => cp.SelectAndOperate(new AnalogOutputDouble64(Convert.ToDouble(value)), index, TaskConfig.Default); 73 | } 74 | } 75 | } 76 | } 77 | } 78 | -------------------------------------------------------------------------------- /simulator/DNP3/DNP3Simulator/Components/CROBControl.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using System.ComponentModel; 4 | using System.Drawing; 5 | using System.Data; 6 | using System.Linq; 7 | using System.Text; 8 | using System.Threading.Tasks; 9 | using System.Windows.Forms; 10 | 11 | using Automatak.DNP3.Interface; 12 | 13 | namespace Automatak.Simulator.DNP3 14 | { 15 | public partial class CROBControl : UserControl 16 | { 17 | public CROBControl() 18 | { 19 | InitializeComponent(); 20 | 21 | this.comboBoxCode.DataSource = Enum.GetValues(typeof(ControlCode)); 22 | } 23 | 24 | private IndexedValue ControlValue 25 | { 26 | get 27 | { 28 | var code = (ControlCode)this.comboBoxCode.SelectedItem; 29 | var count = Convert.ToByte(this.numericUpDownCount.Value); 30 | var onTime = Convert.ToUInt32(this.numericUpDownOnTime.Value); 31 | var offTime = Convert.ToUInt32(this.numericUpDownOffTime.Value); 32 | var crob = new ControlRelayOutputBlock(code, count, onTime, offTime); 33 | var index = Convert.ToUInt16(this.numericUpDownIndex.Value); 34 | return IndexedValue.From(crob, index); 35 | } 36 | } 37 | 38 | public Func> DirectOperateAction 39 | { 40 | get { 41 | var crob = ControlValue; 42 | return (ICommandProcessor cp) => cp.DirectOperate(crob.Value, crob.Index, TaskConfig.Default); 43 | } 44 | } 45 | 46 | public Func> SelectAndOperateAction 47 | { 48 | get 49 | { 50 | var crob = ControlValue; 51 | return (ICommandProcessor cp) => cp.SelectAndOperate(crob.Value, crob.Index, TaskConfig.Default); 52 | } 53 | } 54 | } 55 | } 56 | -------------------------------------------------------------------------------- /simulator/DNP3/DNP3Simulator/Components/ClassFieldControl.Designer.cs: -------------------------------------------------------------------------------- 1 | namespace Automatak.Simulator.DNP3.Components 2 | { 3 | partial class ClassFieldControl 4 | { 5 | /// 6 | /// Required designer variable. 7 | /// 8 | private System.ComponentModel.IContainer components = null; 9 | 10 | /// 11 | /// Clean up any resources being used. 12 | /// 13 | /// true if managed resources should be disposed; otherwise, false. 14 | protected override void Dispose(bool disposing) 15 | { 16 | if (disposing && (components != null)) 17 | { 18 | components.Dispose(); 19 | } 20 | base.Dispose(disposing); 21 | } 22 | 23 | #region Component Designer generated code 24 | 25 | /// 26 | /// Required method for Designer support - do not modify 27 | /// the contents of this method with the code editor. 28 | /// 29 | private void InitializeComponent() 30 | { 31 | this.checkBoxClass0 = new System.Windows.Forms.CheckBox(); 32 | this.checkBoxClass1 = new System.Windows.Forms.CheckBox(); 33 | this.checkBoxClass2 = new System.Windows.Forms.CheckBox(); 34 | this.checkBoxClass3 = new System.Windows.Forms.CheckBox(); 35 | this.SuspendLayout(); 36 | // 37 | // checkBoxClass0 38 | // 39 | this.checkBoxClass0.AutoSize = true; 40 | this.checkBoxClass0.Location = new System.Drawing.Point(11, 13); 41 | this.checkBoxClass0.Name = "checkBoxClass0"; 42 | this.checkBoxClass0.Size = new System.Drawing.Size(60, 17); 43 | this.checkBoxClass0.TabIndex = 0; 44 | this.checkBoxClass0.Text = "Class 0"; 45 | this.checkBoxClass0.UseVisualStyleBackColor = true; 46 | // 47 | // checkBoxClass1 48 | // 49 | this.checkBoxClass1.AutoSize = true; 50 | this.checkBoxClass1.Location = new System.Drawing.Point(11, 36); 51 | this.checkBoxClass1.Name = "checkBoxClass1"; 52 | this.checkBoxClass1.Size = new System.Drawing.Size(60, 17); 53 | this.checkBoxClass1.TabIndex = 1; 54 | this.checkBoxClass1.Text = "Class 1"; 55 | this.checkBoxClass1.UseVisualStyleBackColor = true; 56 | // 57 | // checkBoxClass2 58 | // 59 | this.checkBoxClass2.AutoSize = true; 60 | this.checkBoxClass2.Location = new System.Drawing.Point(11, 59); 61 | this.checkBoxClass2.Name = "checkBoxClass2"; 62 | this.checkBoxClass2.Size = new System.Drawing.Size(60, 17); 63 | this.checkBoxClass2.TabIndex = 2; 64 | this.checkBoxClass2.Text = "Class 2"; 65 | this.checkBoxClass2.UseVisualStyleBackColor = true; 66 | // 67 | // checkBoxClass3 68 | // 69 | this.checkBoxClass3.AutoSize = true; 70 | this.checkBoxClass3.Location = new System.Drawing.Point(11, 82); 71 | this.checkBoxClass3.Name = "checkBoxClass3"; 72 | this.checkBoxClass3.Size = new System.Drawing.Size(60, 17); 73 | this.checkBoxClass3.TabIndex = 3; 74 | this.checkBoxClass3.Text = "Class 3"; 75 | this.checkBoxClass3.UseVisualStyleBackColor = true; 76 | // 77 | // ClassFieldControl 78 | // 79 | this.AutoScaleDimensions = new System.Drawing.SizeF(6F, 13F); 80 | this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Font; 81 | this.Controls.Add(this.checkBoxClass3); 82 | this.Controls.Add(this.checkBoxClass2); 83 | this.Controls.Add(this.checkBoxClass1); 84 | this.Controls.Add(this.checkBoxClass0); 85 | this.Name = "ClassFieldControl"; 86 | this.Size = new System.Drawing.Size(77, 112); 87 | this.ResumeLayout(false); 88 | this.PerformLayout(); 89 | 90 | } 91 | 92 | #endregion 93 | 94 | private System.Windows.Forms.CheckBox checkBoxClass0; 95 | private System.Windows.Forms.CheckBox checkBoxClass1; 96 | private System.Windows.Forms.CheckBox checkBoxClass2; 97 | private System.Windows.Forms.CheckBox checkBoxClass3; 98 | } 99 | } 100 | -------------------------------------------------------------------------------- /simulator/DNP3/DNP3Simulator/Components/ClassFieldControl.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using System.ComponentModel; 4 | using System.Drawing; 5 | using System.Data; 6 | using System.Linq; 7 | using System.Text; 8 | using System.Threading.Tasks; 9 | using System.Windows.Forms; 10 | 11 | using Automatak.DNP3.Interface; 12 | 13 | namespace Automatak.Simulator.DNP3.Components 14 | { 15 | public partial class ClassFieldControl : UserControl 16 | { 17 | public ClassFieldControl() 18 | { 19 | InitializeComponent(); 20 | } 21 | 22 | public bool AllowClass0 23 | { 24 | set 25 | { 26 | checkBoxClass0.Enabled = value; 27 | if (!value) 28 | { 29 | checkBoxClass0.Checked = false; 30 | } 31 | } 32 | } 33 | 34 | public ClassField ClassFieldValue 35 | { 36 | get 37 | { 38 | var field = new ClassField(); 39 | field.Class0 = checkBoxClass0.Checked; 40 | field.Class1 = checkBoxClass1.Checked; 41 | field.Class2 = checkBoxClass2.Checked; 42 | field.Class3 = checkBoxClass3.Checked; 43 | return field; 44 | } 45 | set 46 | { 47 | checkBoxClass0.Checked = value.Class0; 48 | checkBoxClass1.Checked = value.Class1; 49 | checkBoxClass2.Checked = value.Class2; 50 | checkBoxClass3.Checked = value.Class3; 51 | } 52 | } 53 | } 54 | } 55 | -------------------------------------------------------------------------------- /simulator/DNP3/DNP3Simulator/Components/EventBufferConfigControl.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using System.ComponentModel; 4 | using System.Drawing; 5 | using System.Data; 6 | using System.Linq; 7 | using System.Text; 8 | using System.Threading.Tasks; 9 | using System.Windows.Forms; 10 | 11 | using Automatak.DNP3.Interface; 12 | using Automatak.Simulator.DNP3.Commons; 13 | using Automatak.Simulator.DNP3.API; 14 | 15 | namespace Automatak.Simulator.DNP3.Components 16 | { 17 | public partial class EventBufferConfigControl : UserControl 18 | { 19 | const UInt16 defaultValue = 100; 20 | 21 | static IEnumerable types = new MeasType[] { 22 | MeasType.Binary, 23 | MeasType.DoubleBitBinary, 24 | MeasType.Counter, 25 | MeasType.FrozenCounter, 26 | MeasType.Analog, 27 | MeasType.BinaryOutputStatus, 28 | MeasType.AnalogOutputStatus 29 | }; 30 | 31 | public EventBufferConfigControl() 32 | { 33 | InitializeComponent(); 34 | 35 | foreach (var t in types) 36 | { 37 | listView1.Items.Add(CreateItem(t.ToString())); 38 | } 39 | 40 | this.CheckState(); 41 | } 42 | 43 | public EventBufferConfig Configuration 44 | { 45 | get 46 | { 47 | var config = new EventBufferConfig(); 48 | int i = 0; 49 | foreach (ListViewItem item in listView1.Items) 50 | { 51 | var value = UInt32.Parse(item.SubItems[1].Text); 52 | SetValue(config, i, value); 53 | ++i; 54 | } 55 | 56 | return config; 57 | } 58 | } 59 | 60 | void SetValue(EventBufferConfig config, int index, UInt32 value) 61 | { 62 | switch(index) 63 | { 64 | case(0): 65 | config.maxBinaryEvents = value; 66 | break; 67 | case (1): 68 | config.maxDoubleBinaryEvents = value; 69 | break; 70 | case (2): 71 | config.maxCounterEvents = value; 72 | break; 73 | case (3): 74 | config.maxFrozenCounterEvents = value; 75 | break; 76 | case (4): 77 | config.maxAnalogEvents = value; 78 | break; 79 | case (5): 80 | config.maxBinaryOutputStatusEvents = value; 81 | break; 82 | case (6): 83 | config.maxAnalogOutputStatusEvents = value; 84 | break; 85 | } 86 | } 87 | 88 | void CheckState() 89 | { 90 | if (this.listView1.SelectedItems.Count > 0) 91 | { 92 | this.numericUpDown1.Enabled = true; 93 | } 94 | else 95 | { 96 | this.numericUpDown1.Enabled = false; 97 | } 98 | } 99 | 100 | ListViewItem CreateItem(string value) 101 | { 102 | var strings = new String[] { value, defaultValue.ToString() }; 103 | return new ListViewItem(strings); 104 | } 105 | 106 | private void listView1_SelectedIndexChanged(object sender, EventArgs e) 107 | { 108 | this.CheckState(); 109 | } 110 | 111 | private void numericUpDown1_ValueChanged(object sender, EventArgs e) 112 | { 113 | this.CheckState(); 114 | foreach (ListViewItem item in listView1.SelectedItems) 115 | { 116 | item.SubItems[1].Text = Decimal.ToUInt16(numericUpDown1.Value).ToString(); 117 | } 118 | } 119 | } 120 | } 121 | -------------------------------------------------------------------------------- /simulator/DNP3/DNP3Simulator/Components/EventResponseTypeControl.Designer.cs: -------------------------------------------------------------------------------- 1 | namespace Automatak.Simulator.DNP3.Components 2 | { 3 | partial class EventResponseTypeControl 4 | { 5 | /// 6 | /// Required designer variable. 7 | /// 8 | private System.ComponentModel.IContainer components = null; 9 | 10 | /// 11 | /// Clean up any resources being used. 12 | /// 13 | /// true if managed resources should be disposed; otherwise, false. 14 | protected override void Dispose(bool disposing) 15 | { 16 | if (disposing && (components != null)) 17 | { 18 | components.Dispose(); 19 | } 20 | base.Dispose(disposing); 21 | } 22 | 23 | #region Component Designer generated code 24 | 25 | /// 26 | /// Required method for Designer support - do not modify 27 | /// the contents of this method with the code editor. 28 | /// 29 | private void InitializeComponent() 30 | { 31 | components = new System.ComponentModel.Container(); 32 | this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Font; 33 | } 34 | 35 | #endregion 36 | } 37 | } 38 | -------------------------------------------------------------------------------- /simulator/DNP3/DNP3Simulator/Components/EventResponseTypeControl.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using System.ComponentModel; 4 | using System.Drawing; 5 | using System.Data; 6 | using System.Linq; 7 | using System.Text; 8 | using System.Threading.Tasks; 9 | using System.Windows.Forms; 10 | 11 | using Automatak.DNP3.Interface; 12 | 13 | namespace Automatak.Simulator.DNP3.Components 14 | { 15 | public partial class EventResponseTypeControl : ResponseTypeControl 16 | { 17 | public EventResponseTypeControl() 18 | { 19 | InitializeComponent(); 20 | 21 | this.ComboBoxBinary.DataSource = Enum.GetValues(typeof(EventBinaryVariation)); 22 | this.ComboBoxDoubleBinary.DataSource = Enum.GetValues(typeof(EventDoubleBinaryVariation)); 23 | this.ComboBoxCounter.DataSource = Enum.GetValues(typeof(EventCounterVariation)); 24 | this.ComboBoxFrozenCounter.DataSource = Enum.GetValues(typeof(EventFrozenCounterVariation)); 25 | this.ComboBoxAnalog.DataSource = Enum.GetValues(typeof(EventAnalogVariation)); 26 | this.ComboBoxBinaryOutputStatus.DataSource = Enum.GetValues(typeof(EventBinaryOutputStatusVariation)); 27 | this.ComboBoxAnalogOutputStatus.DataSource = Enum.GetValues(typeof(EventAnalogOutputStatusVariation)); 28 | } 29 | 30 | // TODO remove this 31 | public void Configure(DatabaseTemplate template) 32 | { 33 | foreach (var record in template.binaries) record.eventVariation = (EventBinaryVariation)this.ComboBoxBinary.SelectedItem; 34 | foreach (var record in template.binaryOutputStatii) record.eventVariation = (EventBinaryOutputStatusVariation)this.ComboBoxBinaryOutputStatus.SelectedItem; 35 | foreach (var record in template.doubleBinaries) record.eventVariation = (EventDoubleBinaryVariation)this.ComboBoxDoubleBinary.SelectedItem; 36 | foreach (var record in template.counters) record.eventVariation = (EventCounterVariation)ComboBoxCounter.SelectedItem; 37 | foreach (var record in template.frozenCounters) record.eventVariation = (EventFrozenCounterVariation)ComboBoxCounter.SelectedItem; 38 | foreach (var record in template.analogs) record.eventVariation = (EventAnalogVariation)ComboBoxAnalog.SelectedItem; 39 | foreach (var record in template.analogOutputStatii) record.eventVariation = (EventAnalogOutputStatusVariation)ComboBoxAnalogOutputStatus.SelectedItem; 40 | } 41 | } 42 | } 43 | -------------------------------------------------------------------------------- /simulator/DNP3/DNP3Simulator/Components/LinkConfigControl.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using System.ComponentModel; 4 | using System.Drawing; 5 | using System.Data; 6 | using System.Linq; 7 | using System.Text; 8 | using System.Windows.Forms; 9 | 10 | using Automatak.DNP3.Interface; 11 | 12 | namespace Automatak.Simulator.DNP3.Components 13 | { 14 | public partial class LinkConfigControl : UserControl 15 | { 16 | public LinkConfigControl() 17 | { 18 | InitializeComponent(); 19 | } 20 | 21 | public LinkConfig Configuration 22 | { 23 | get 24 | { 25 | var config = new LinkConfig(isMaster, this.checkBoxConfirmed.Checked); 26 | config.localAddr = Decimal.ToUInt16(this.numericUpDownSource.Value); 27 | config.remoteAddr = Decimal.ToUInt16(this.numericUpDownDest.Value); 28 | config.numRetry = Decimal.ToUInt32(this.numericUpDownRetries.Value); 29 | config.responseTimeout = TimeSpan.FromMilliseconds(Decimal.ToUInt32(this.numericUpDownTimeout.Value)); 30 | config.keepAliveTimeout = TimeSpan.FromMilliseconds(Decimal.ToUInt32(this.numericUpDownKeepAliveTimeout.Value * 1000)); 31 | return config; 32 | } 33 | set 34 | { 35 | this.Configure(value); 36 | 37 | } 38 | } 39 | 40 | private void SetState() 41 | { 42 | this.groupBoxConfirmed.Enabled = this.checkBoxConfirmed.Checked; 43 | } 44 | 45 | private void Configure(LinkConfig config) 46 | { 47 | this.isMaster = config.isMaster; 48 | this.numericUpDownSource.Value = config.localAddr; 49 | this.numericUpDownDest.Value = config.remoteAddr; 50 | this.numericUpDownTimeout.Value = Convert.ToDecimal(config.responseTimeout.TotalMilliseconds); 51 | this.numericUpDownRetries.Value = config.numRetry; 52 | this.checkBoxConfirmed.Checked = config.useConfirms; 53 | this.numericUpDownKeepAliveTimeout.Value = Convert.ToDecimal(config.keepAliveTimeout.TotalMilliseconds); 54 | 55 | this.SetState(); 56 | } 57 | 58 | private bool isMaster = false; 59 | 60 | private void checkBoxConfirmed_CheckedChanged(object sender, EventArgs e) 61 | { 62 | this.SetState(); 63 | } 64 | } 65 | } 66 | -------------------------------------------------------------------------------- /simulator/DNP3/DNP3Simulator/Components/LogLevelControl.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using System.ComponentModel; 4 | using System.Drawing; 5 | using System.Data; 6 | using System.Linq; 7 | using System.Text; 8 | using System.Threading.Tasks; 9 | using System.Windows.Forms; 10 | 11 | using Automatak.DNP3.Interface; 12 | 13 | namespace Automatak.Simulator.DNP3.Components 14 | { 15 | public partial class LogLevelControl : UserControl 16 | { 17 | public LogLevelControl() 18 | { 19 | InitializeComponent(); 20 | } 21 | 22 | public LogFilter Filters 23 | { 24 | get 25 | { 26 | uint flags = LogFilters.EVENT; 27 | 28 | if (checkBoxError.Checked) 29 | { 30 | flags |= LogFilters.ERROR; 31 | } 32 | 33 | if (checkBoxWarn.Checked) 34 | { 35 | flags |= LogFilters.WARNING; 36 | } 37 | 38 | if (checkBoxInfo.Checked) 39 | { 40 | flags |= LogFilters.INFO; 41 | } 42 | 43 | if (checkBoxDebug.Checked) 44 | { 45 | flags |= LogFilters.DEBUG; 46 | } 47 | 48 | if (checkBoxLink.Checked) 49 | { 50 | flags |= (LogFilters.LINK_RX | LogFilters.LINK_TX); 51 | } 52 | 53 | if (checkBoxLinkRaw.Checked) 54 | { 55 | flags |= (LogFilters.LINK_RX_HEX | LogFilters.LINK_TX_HEX); 56 | } 57 | 58 | if (checkBoxTransport.Checked) 59 | { 60 | flags |= (LogFilters.TRANSPORT_RX | LogFilters.TRANSPORT_TX); 61 | } 62 | 63 | if (checkBoxAppHeader.Checked) 64 | { 65 | flags |= (LogFilters.APP_HEADER_RX | LogFilters.APP_HEADER_TX); 66 | flags |= (LogFilters.APP_OBJECT_RX | LogFilters.APP_OBJECT_TX); 67 | } 68 | 69 | return new LogFilter(flags); 70 | } 71 | } 72 | } 73 | } 74 | -------------------------------------------------------------------------------- /simulator/DNP3/DNP3Simulator/Components/MasterConfigControl.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using System.ComponentModel; 4 | using System.Drawing; 5 | using System.Data; 6 | using System.Linq; 7 | using System.Text; 8 | using System.Threading.Tasks; 9 | using System.Windows.Forms; 10 | 11 | using Automatak.DNP3.Interface; 12 | 13 | namespace Automatak.Simulator.DNP3.Components 14 | { 15 | public partial class MasterConfigControl : UserControl 16 | { 17 | public MasterConfigControl() 18 | { 19 | InitializeComponent(); 20 | 21 | this.comboBoxTimeSync.DataSource = Enum.GetValues(typeof(TimeSyncMode)); 22 | this.comboBoxTimeSync.SelectedItem = TimeSyncMode.None; 23 | 24 | this.classFieldControlIntegrity.ClassFieldValue = ClassField.AllClasses; 25 | this.classFieldControlEnableUnsol.ClassFieldValue = ClassField.AllEventClasses; 26 | this.classFieldControlEnableUnsol.AllowClass0 = false; 27 | } 28 | 29 | public MasterConfig Configuration 30 | { 31 | get 32 | { 33 | var config = new MasterConfig(); 34 | config.disableUnsolOnStartup = this.checkBoxDisableUnsolicited.Checked; 35 | config.startupIntegrityClassMask = this.classFieldControlIntegrity.ClassFieldValue; 36 | config.unsolClassMask = this.classFieldControlEnableUnsol.ClassFieldValue; 37 | config.timeSyncMode = (TimeSyncMode)this.comboBoxTimeSync.SelectedItem; 38 | config.integrityOnEventOverflowIIN = this.checkBoxIntegrityOnOverflow.Checked; 39 | config.responseTimeout = TimeSpan.FromMilliseconds(Decimal.ToDouble(this.numericUpDownResponseTimeout.Value)); 40 | config.taskRetryPeriod = TimeSpan.FromMilliseconds(Decimal.ToDouble(this.numericUpDownTaskRetryDelay.Value)); 41 | return config; 42 | } 43 | } 44 | } 45 | } 46 | -------------------------------------------------------------------------------- /simulator/DNP3/DNP3Simulator/Components/MasterDialog.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using System.ComponentModel; 4 | using System.Data; 5 | using System.Drawing; 6 | using System.Linq; 7 | using System.Text; 8 | using System.Windows.Forms; 9 | 10 | using Automatak.DNP3.Interface; 11 | 12 | namespace Automatak.Simulator.DNP3.Components 13 | { 14 | public partial class MasterDialog : Form 15 | { 16 | public MasterDialog() 17 | { 18 | InitializeComponent(); 19 | 20 | this.linkConfigControl.Configuration = new LinkConfig(true, false); 21 | } 22 | 23 | private void buttonADD_Click(object sender, EventArgs e) 24 | { 25 | this.DialogResult = DialogResult.OK; 26 | this.Close(); 27 | } 28 | 29 | public String SelectedAlias 30 | { 31 | get 32 | { 33 | return textBoxID.Text; 34 | } 35 | } 36 | 37 | public MasterStackConfig Configuration 38 | { 39 | get 40 | { 41 | var config = new MasterStackConfig(); 42 | config.link = this.linkConfigControl.Configuration; 43 | config.master = this.masterConfigControl.Configuration; 44 | return config; 45 | } 46 | } 47 | } 48 | } 49 | -------------------------------------------------------------------------------- /simulator/DNP3/DNP3Simulator/Components/MasterScanControl.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using System.ComponentModel; 4 | using System.Drawing; 5 | using System.Data; 6 | using System.Linq; 7 | using System.Text; 8 | using System.Threading.Tasks; 9 | using System.Windows.Forms; 10 | 11 | using Automatak.DNP3.Interface; 12 | 13 | namespace Automatak.Simulator.DNP3.Components 14 | { 15 | public partial class MasterScanControl : UserControl 16 | { 17 | IMaster master = null; 18 | 19 | readonly ICollection scans = new List(); 20 | 21 | public MasterScanControl() 22 | { 23 | InitializeComponent(); 24 | } 25 | 26 | public IMaster Master 27 | { 28 | set 29 | { 30 | this.master = value; 31 | } 32 | } 33 | 34 | private void addScanToolStripMenuItem_Click(object sender, EventArgs e) 35 | { 36 | using (var dialog = new ScanDialog(master)) 37 | { 38 | if (dialog.ShowDialog() == DialogResult.OK) 39 | { 40 | foreach (var scan in dialog.ConfiguredScans) 41 | { 42 | scans.Add(scan); 43 | } 44 | 45 | this.RefreshScanList(); 46 | } 47 | } 48 | } 49 | 50 | private void RefreshScanList() 51 | { 52 | this.listViewScans.SuspendLayout(); 53 | 54 | try 55 | { 56 | this.listViewScans.Items.Clear(); 57 | foreach (var info in scans) 58 | { 59 | var item = new ListViewItem(new string[] { info.description, info.period.ToString() }); 60 | item.ToolTipText = info.details; 61 | item.Tag = info.scan; 62 | this.listViewScans.Items.Add(item); 63 | } 64 | } 65 | finally 66 | { 67 | this.listViewScans.ResumeLayout(); 68 | } 69 | } 70 | 71 | private void listViewScans_MouseDown(object sender, MouseEventArgs e) 72 | { 73 | 74 | if (e.Button != System.Windows.Forms.MouseButtons.Right) 75 | { 76 | return; 77 | } 78 | 79 | ListViewItem choice = null; 80 | 81 | foreach (ListViewItem item in listViewScans.Items) 82 | { 83 | if (item.Bounds.Contains(new Point(e.X, e.Y))) 84 | { 85 | choice = item; 86 | } 87 | } 88 | 89 | 90 | if (choice == null) 91 | { 92 | this.contextMenuStripAdd.Show(listViewScans, e.X, e.Y); 93 | } 94 | else 95 | { 96 | this.GetScanMenu(((IMasterScan)choice.Tag)).Show(listViewScans, e.X, e.Y); 97 | } 98 | } 99 | 100 | ContextMenuStrip GetScanMenu(IMasterScan scan) 101 | { 102 | var menu = new ContextMenuStrip(); 103 | var demand = new ToolStripMenuItem("Demand"); 104 | demand.Click += (object sender, EventArgs e) => { 105 | scan.Demand(); 106 | }; 107 | menu.Items.Add(demand); 108 | return menu; 109 | } 110 | 111 | } 112 | } 113 | -------------------------------------------------------------------------------- /simulator/DNP3/DNP3Simulator/Components/OutstationModuleDialog.Designer.cs: -------------------------------------------------------------------------------- 1 | namespace Automatak.Simulator.DNP3.Components 2 | { 3 | partial class OutstationModuleDialog 4 | { 5 | /// 6 | /// Required designer variable. 7 | /// 8 | private System.ComponentModel.IContainer components = null; 9 | 10 | /// 11 | /// Clean up any resources being used. 12 | /// 13 | /// true if managed resources should be disposed; otherwise, false. 14 | protected override void Dispose(bool disposing) 15 | { 16 | if (disposing && (components != null)) 17 | { 18 | components.Dispose(); 19 | } 20 | base.Dispose(disposing); 21 | } 22 | 23 | #region Windows Form Designer generated code 24 | 25 | /// 26 | /// Required method for Designer support - do not modify 27 | /// the contents of this method with the code editor. 28 | /// 29 | private void InitializeComponent() 30 | { 31 | System.ComponentModel.ComponentResourceManager resources = new System.ComponentModel.ComponentResourceManager(typeof(OutstationModuleDialog)); 32 | this.buttonOK = new System.Windows.Forms.Button(); 33 | this.comboBoxModules = new System.Windows.Forms.ComboBox(); 34 | this.textBoxDesc = new System.Windows.Forms.TextBox(); 35 | this.SuspendLayout(); 36 | // 37 | // buttonOK 38 | // 39 | this.buttonOK.Location = new System.Drawing.Point(25, 153); 40 | this.buttonOK.Name = "buttonOK"; 41 | this.buttonOK.Size = new System.Drawing.Size(290, 44); 42 | this.buttonOK.TabIndex = 0; 43 | this.buttonOK.Text = "Select"; 44 | this.buttonOK.UseVisualStyleBackColor = true; 45 | this.buttonOK.Click += new System.EventHandler(this.buttonOK_Click); 46 | // 47 | // comboBoxModules 48 | // 49 | this.comboBoxModules.DropDownStyle = System.Windows.Forms.ComboBoxStyle.DropDownList; 50 | this.comboBoxModules.FormattingEnabled = true; 51 | this.comboBoxModules.Location = new System.Drawing.Point(25, 25); 52 | this.comboBoxModules.Name = "comboBoxModules"; 53 | this.comboBoxModules.Size = new System.Drawing.Size(290, 21); 54 | this.comboBoxModules.TabIndex = 1; 55 | this.comboBoxModules.SelectedIndexChanged += new System.EventHandler(this.comboBoxModules_SelectedIndexChanged); 56 | // 57 | // textBoxDesc 58 | // 59 | this.textBoxDesc.Location = new System.Drawing.Point(25, 58); 60 | this.textBoxDesc.Multiline = true; 61 | this.textBoxDesc.Name = "textBoxDesc"; 62 | this.textBoxDesc.ReadOnly = true; 63 | this.textBoxDesc.Size = new System.Drawing.Size(290, 83); 64 | this.textBoxDesc.TabIndex = 2; 65 | // 66 | // OutstationModuleDialog 67 | // 68 | this.AutoScaleDimensions = new System.Drawing.SizeF(6F, 13F); 69 | this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Font; 70 | this.ClientSize = new System.Drawing.Size(342, 209); 71 | this.Controls.Add(this.textBoxDesc); 72 | this.Controls.Add(this.comboBoxModules); 73 | this.Controls.Add(this.buttonOK); 74 | this.Icon = ((System.Drawing.Icon)(resources.GetObject("$this.Icon"))); 75 | this.MaximizeBox = false; 76 | this.MinimizeBox = false; 77 | this.Name = "OutstationModuleDialog"; 78 | this.StartPosition = System.Windows.Forms.FormStartPosition.CenterParent; 79 | this.Text = "Choose an outstation plugin"; 80 | this.ResumeLayout(false); 81 | this.PerformLayout(); 82 | 83 | } 84 | 85 | #endregion 86 | 87 | private System.Windows.Forms.Button buttonOK; 88 | private System.Windows.Forms.ComboBox comboBoxModules; 89 | private System.Windows.Forms.TextBox textBoxDesc; 90 | } 91 | } -------------------------------------------------------------------------------- /simulator/DNP3/DNP3Simulator/Components/OutstationModuleDialog.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using System.ComponentModel; 4 | using System.Data; 5 | using System.Drawing; 6 | using System.Linq; 7 | using System.Text; 8 | using System.Threading.Tasks; 9 | using System.Windows.Forms; 10 | 11 | using Automatak.Simulator.DNP3.API; 12 | 13 | namespace Automatak.Simulator.DNP3.Components 14 | { 15 | public partial class OutstationModuleDialog : Form 16 | { 17 | IOutstationModule selectedModule = null; 18 | 19 | public OutstationModuleDialog(IEnumerable modules) 20 | { 21 | InitializeComponent(); 22 | 23 | this.comboBoxModules.DataSource = modules.ToArray(); 24 | this.SelectModule(); 25 | } 26 | 27 | private void buttonOK_Click(object sender, EventArgs e) 28 | { 29 | this.SelectModule(); 30 | this.DialogResult = DialogResult.OK; 31 | this.Close(); 32 | } 33 | 34 | void SelectModule() 35 | { 36 | this.selectedModule = (IOutstationModule)this.comboBoxModules.SelectedItem; 37 | this.textBoxDesc.Text = this.selectedModule.Description; 38 | } 39 | 40 | public IOutstationModule SelectedModule 41 | { 42 | get 43 | { 44 | return selectedModule; 45 | } 46 | } 47 | 48 | private void comboBoxModules_SelectedIndexChanged(object sender, EventArgs e) 49 | { 50 | this.SelectModule(); 51 | } 52 | } 53 | } 54 | -------------------------------------------------------------------------------- /simulator/DNP3/DNP3Simulator/Components/ResponseTypeControl.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using System.ComponentModel; 4 | using System.Drawing; 5 | using System.Data; 6 | using System.Linq; 7 | using System.Text; 8 | using System.Threading.Tasks; 9 | using System.Windows.Forms; 10 | 11 | namespace Automatak.Simulator.DNP3.Components 12 | { 13 | public partial class ResponseTypeControl : UserControl 14 | { 15 | public ResponseTypeControl() 16 | { 17 | InitializeComponent(); 18 | } 19 | 20 | protected ComboBox ComboBoxBinary 21 | { 22 | get 23 | { 24 | return comboBoxBinary; 25 | } 26 | } 27 | 28 | protected ComboBox ComboBoxDoubleBinary 29 | { 30 | get 31 | { 32 | return comboBoxDoubleBinary; 33 | } 34 | } 35 | 36 | protected ComboBox ComboBoxCounter 37 | { 38 | get 39 | { 40 | return comboBoxCounter; 41 | } 42 | } 43 | 44 | protected ComboBox ComboBoxFrozenCounter 45 | { 46 | get 47 | { 48 | return comboBoxFrozenCounter; 49 | } 50 | } 51 | 52 | protected ComboBox ComboBoxAnalog 53 | { 54 | get 55 | { 56 | return comboBoxAnalog; 57 | } 58 | } 59 | 60 | protected ComboBox ComboBoxBinaryOutputStatus 61 | { 62 | get 63 | { 64 | return comboBoxBinaryOutputStatus; 65 | } 66 | } 67 | 68 | protected ComboBox ComboBoxAnalogOutputStatus 69 | { 70 | get 71 | { 72 | return comboBoxAnalogOutputStatus; 73 | } 74 | } 75 | } 76 | } 77 | -------------------------------------------------------------------------------- /simulator/DNP3/DNP3Simulator/Components/ScanDialog.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using System.ComponentModel; 4 | using System.Data; 5 | using System.Drawing; 6 | using System.Linq; 7 | using System.Text; 8 | using System.Threading.Tasks; 9 | using System.Windows.Forms; 10 | 11 | using Automatak.DNP3.Interface; 12 | 13 | namespace Automatak.Simulator.DNP3.Components 14 | { 15 | 16 | 17 | 18 | public partial class ScanDialog : Form 19 | { 20 | readonly IMaster master; 21 | readonly IList scans = new List(); 22 | 23 | public ScanDialog(IMaster master) 24 | { 25 | InitializeComponent(); 26 | 27 | this.master = master; 28 | } 29 | 30 | private void buttonOnce_Click(object sender, EventArgs e) 31 | { 32 | master.Scan(GetClassHeaders(classFieldControlScan.ClassFieldValue), TaskConfig.Default); 33 | } 34 | 35 | private static IEnumerable
GetClassHeaders(ClassField classes) 36 | { 37 | IList
headers = new List
(); 38 | if (classes.Class1) 39 | { 40 | headers.Add(Header.AllObjects(60, 2)); 41 | } 42 | if (classes.Class2) 43 | { 44 | headers.Add(Header.AllObjects(60, 3)); 45 | } 46 | if (classes.Class3) 47 | { 48 | headers.Add(Header.AllObjects(60, 4)); 49 | } 50 | if (classes.Class0) 51 | { 52 | headers.Add(Header.AllObjects(60, 1)); 53 | } 54 | return headers; 55 | } 56 | 57 | private static string DetailedDescription(IEnumerable
headers) 58 | { 59 | return String.Join(", ", headers); 60 | } 61 | 62 | private static string ClassDescription(ClassField classes) 63 | { 64 | ICollection names = new List(); 65 | 66 | if (classes.Class1) names.Add("1"); 67 | if (classes.Class2) names.Add("2"); 68 | if (classes.Class3) names.Add("3"); 69 | if (classes.Class0) names.Add("0"); 70 | 71 | return names.Any() ? String.Format("Class {0}", String.Join("/", names.ToArray())) : "Empty"; 72 | } 73 | 74 | private void buttonBind_Click(object sender, EventArgs e) 75 | { 76 | var period = TimeSpan.FromMilliseconds(Convert.ToDouble(this.numericUpDownPeriod.Value)); 77 | var classes = classFieldControlScan.ClassFieldValue; 78 | var headers = GetClassHeaders(classes); 79 | var info = new ScanInfo(master.AddScan(headers, period, TaskConfig.Default), ClassDescription(classes), period, DetailedDescription(headers)); 80 | this.scans.Add(info); 81 | this.DialogResult = DialogResult.OK; 82 | this.Close(); 83 | } 84 | 85 | public IEnumerable ConfiguredScans 86 | { 87 | get 88 | { 89 | return scans; 90 | } 91 | } 92 | 93 | 94 | } 95 | } 96 | -------------------------------------------------------------------------------- /simulator/DNP3/DNP3Simulator/Components/ScanInfo.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using System.Linq; 4 | using System.Text; 5 | using System.Threading.Tasks; 6 | 7 | using Automatak.DNP3.Interface; 8 | 9 | namespace Automatak.Simulator.DNP3.Components 10 | { 11 | public class ScanInfo 12 | { 13 | public ScanInfo(IMasterScan scan, string description, TimeSpan period, string details) 14 | { 15 | this.scan = scan; 16 | this.description = description; 17 | this.period = period; 18 | this.details = details; 19 | } 20 | 21 | public readonly IMasterScan scan; 22 | public readonly string description; 23 | public readonly TimeSpan period; 24 | public readonly string details; 25 | } 26 | } 27 | -------------------------------------------------------------------------------- /simulator/DNP3/DNP3Simulator/Components/StaticResponseTypeControl.Designer.cs: -------------------------------------------------------------------------------- 1 | namespace Automatak.Simulator.DNP3.Components 2 | { 3 | partial class StaticResponseTypeControl 4 | { 5 | /// 6 | /// Required designer variable. 7 | /// 8 | private System.ComponentModel.IContainer components = null; 9 | 10 | /// 11 | /// Clean up any resources being used. 12 | /// 13 | /// true if managed resources should be disposed; otherwise, false. 14 | protected override void Dispose(bool disposing) 15 | { 16 | if (disposing && (components != null)) 17 | { 18 | components.Dispose(); 19 | } 20 | base.Dispose(disposing); 21 | } 22 | 23 | #region Component Designer generated code 24 | 25 | /// 26 | /// Required method for Designer support - do not modify 27 | /// the contents of this method with the code editor. 28 | /// 29 | private void InitializeComponent() 30 | { 31 | components = new System.ComponentModel.Container(); 32 | this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Font; 33 | } 34 | 35 | #endregion 36 | } 37 | } 38 | -------------------------------------------------------------------------------- /simulator/DNP3/DNP3Simulator/Components/StaticResponseTypeControl.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using System.ComponentModel; 4 | using System.Drawing; 5 | using System.Data; 6 | using System.Linq; 7 | using System.Text; 8 | using System.Threading.Tasks; 9 | using System.Windows.Forms; 10 | 11 | using Automatak.DNP3.Interface; 12 | 13 | namespace Automatak.Simulator.DNP3.Components 14 | { 15 | public partial class StaticResponseTypeControl : ResponseTypeControl 16 | { 17 | public StaticResponseTypeControl() 18 | { 19 | InitializeComponent(); 20 | 21 | this.ComboBoxBinary.DataSource = Enum.GetValues(typeof(StaticBinaryVariation)); 22 | this.ComboBoxDoubleBinary.DataSource = Enum.GetValues(typeof(StaticDoubleBinaryVariation)); 23 | this.ComboBoxCounter.DataSource = Enum.GetValues(typeof(StaticCounterVariation)); 24 | this.ComboBoxFrozenCounter.DataSource = Enum.GetValues(typeof(StaticFrozenCounterVariation)); 25 | this.ComboBoxAnalog.DataSource = Enum.GetValues(typeof(StaticAnalogVariation)); 26 | this.ComboBoxBinaryOutputStatus.DataSource = Enum.GetValues(typeof(StaticBinaryOutputStatusVariation)); 27 | this.ComboBoxAnalogOutputStatus.DataSource = Enum.GetValues(typeof(StaticAnalogOutputStatusVariation)); 28 | } 29 | 30 | // TODO remove this 31 | public void Configure(DatabaseTemplate template) 32 | { 33 | foreach (var record in template.binaries) record.staticVariation = (StaticBinaryVariation)this.ComboBoxBinary.SelectedItem; 34 | foreach (var record in template.binaryOutputStatii) record.staticVariation = (StaticBinaryOutputStatusVariation)this.ComboBoxBinaryOutputStatus.SelectedItem; 35 | foreach (var record in template.doubleBinaries) record.staticVariation = (StaticDoubleBinaryVariation)this.ComboBoxDoubleBinary.SelectedItem; 36 | foreach (var record in template.counters) record.staticVariation = (StaticCounterVariation)ComboBoxCounter.SelectedItem; 37 | foreach (var record in template.frozenCounters) record.staticVariation = (StaticFrozenCounterVariation)ComboBoxCounter.SelectedItem; 38 | foreach (var record in template.analogs) record.staticVariation = (StaticAnalogVariation)ComboBoxAnalog.SelectedItem; 39 | foreach (var record in template.analogOutputStatii) record.staticVariation = (StaticAnalogOutputStatusVariation)ComboBoxAnalogOutputStatus.SelectedItem; 40 | } 41 | } 42 | } 43 | -------------------------------------------------------------------------------- /simulator/DNP3/DNP3Simulator/Components/TLSOptionsControl.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using System.ComponentModel; 4 | using System.Drawing; 5 | using System.Data; 6 | using System.Linq; 7 | using System.Text; 8 | using System.Threading.Tasks; 9 | using System.Windows.Forms; 10 | using System.IO; 11 | 12 | using Automatak.DNP3.Interface; 13 | 14 | namespace Automatak.Simulator.DNP3 15 | { 16 | public partial class TLSOptionsControl : UserControl 17 | { 18 | public TLSOptionsControl() 19 | { 20 | InitializeComponent(); 21 | } 22 | 23 | public TLSConfig Configuration 24 | { 25 | get 26 | { 27 | var config = new TLSConfig( 28 | this.trustedCertTextBox.Text, 29 | this.localCertificateTextBox.Text, 30 | this.privateKeyTextBox.Text, 31 | Convert.ToInt32(this.maxDepthNumericUpDown.Value), 32 | this.checkBoxV1_0.Checked, 33 | this.checkBoxV1_1.Checked, 34 | this.checkBoxV1_2.Checked, 35 | this.cipherListTextBox.Text 36 | ); 37 | 38 | ValidateConfig(config); 39 | 40 | return config; 41 | } 42 | } 43 | 44 | private void ValidateConfig(TLSConfig config) 45 | { 46 | 47 | if (string.IsNullOrWhiteSpace(config.peerCertFilePath) || string.IsNullOrWhiteSpace(Path.GetFullPath(config.peerCertFilePath))) 48 | { 49 | throw new Exception("Invalid Trusted Certificate File Path"); 50 | } 51 | 52 | if (string.IsNullOrWhiteSpace(config.localCertFilePath) || string.IsNullOrWhiteSpace(Path.GetFullPath(config.localCertFilePath))) 53 | { 54 | throw new Exception("Invalid Certificate File Path"); 55 | } 56 | 57 | if (string.IsNullOrWhiteSpace(config.privateKeyFilePath) || string.IsNullOrWhiteSpace(Path.GetFullPath(config.privateKeyFilePath))) 58 | { 59 | throw new Exception("Invalid Private Key File Path"); 60 | } 61 | 62 | if (!(config.allowTLSv10 || config.allowTLSv11 || config.allowTLSv12)) 63 | { 64 | throw new Exception("At least one TLS version must be selected"); 65 | } 66 | } 67 | 68 | private void browseCertButton_Click(object sender, EventArgs e) 69 | { 70 | DialogResult result = openFileDialog.ShowDialog(); 71 | if (result == DialogResult.OK) 72 | { 73 | this.localCertificateTextBox.Text = openFileDialog.FileName; 74 | } 75 | } 76 | 77 | private void browsePrivateKeyButton_Click(object sender, EventArgs e) 78 | { 79 | DialogResult result = openFileDialog.ShowDialog(); 80 | if (result == DialogResult.OK) 81 | { 82 | this.privateKeyTextBox.Text = openFileDialog.FileName; 83 | } 84 | } 85 | 86 | private void browseTrustedCertButton_Click(object sender, EventArgs e) 87 | { 88 | DialogResult result = openFileDialog.ShowDialog(); 89 | if (result == DialogResult.OK) 90 | { 91 | this.trustedCertTextBox.Text = openFileDialog.FileName; 92 | } 93 | } 94 | } 95 | } 96 | -------------------------------------------------------------------------------- /simulator/DNP3/DNP3Simulator/Components/TemplateDialog.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using System.ComponentModel; 4 | using System.Data; 5 | using System.Drawing; 6 | using System.Linq; 7 | using System.Text; 8 | using System.Windows.Forms; 9 | 10 | using Automatak.DNP3.Interface; 11 | 12 | namespace Automatak.Simulator.DNP3.Components 13 | { 14 | partial class TemplateDialog : Form 15 | { 16 | public TemplateDialog(string alias, DatabaseTemplate template) 17 | { 18 | InitializeComponent(); 19 | 20 | this.textBoxAlias.Text = alias; 21 | 22 | Configure(template); 23 | } 24 | 25 | private void buttonADD_Click(object sender, EventArgs e) 26 | { 27 | this.DialogResult = DialogResult.OK; 28 | this.Close(); 29 | } 30 | 31 | public String SelectedAlias 32 | { 33 | get 34 | { 35 | return textBoxAlias.Text; 36 | } 37 | } 38 | 39 | public DatabaseTemplate ConfiguredTemplate 40 | { 41 | get 42 | { 43 | var template = new DatabaseTemplate(0); 44 | 45 | template.binaries = templateControlBinary.GetRecords().Select(rec => new BinaryRecord(rec.index)).ToList(); 46 | template.doubleBinaries = templateControlDoubleBinary.GetRecords().Select(rec => new DoubleBinaryRecord(rec.index)).ToList(); 47 | template.counters = templateControlCounter.GetRecords().Select(rec => new CounterRecord(rec.index)).ToList(); 48 | template.frozenCounters = templateControlFrozenCounter.GetRecords().Select(rec => new FrozenCounterRecord(rec.index)).ToList(); 49 | template.analogs = templateControlAnalog.GetRecords().Select(rec => new AnalogRecord(rec.index)).ToList(); 50 | template.binaryOutputStatii = templateControlBOStatus.GetRecords().Select(rec => new BinaryOutputStatusRecord(rec.index)).ToList(); 51 | template.analogOutputStatii = templateControlAOStatus.GetRecords().Select(rec => new AnalogOutputStatusRecord(rec.index)).ToList(); 52 | 53 | 54 | return template; 55 | } 56 | } 57 | 58 | private void Configure(DatabaseTemplate template) 59 | { 60 | this.templateControlAnalog.SetRecords(template.analogs); 61 | this.templateControlAOStatus.SetRecords(template.analogOutputStatii); 62 | this.templateControlBinary.SetRecords(template.binaries); 63 | this.templateControlBOStatus.SetRecords(template.binaryOutputStatii); 64 | this.templateControlCounter.SetRecords(template.counters); 65 | this.templateControlDoubleBinary.SetRecords(template.doubleBinaries); 66 | this.templateControlFrozenCounter.SetRecords(template.frozenCounters); 67 | } 68 | 69 | } 70 | } 71 | -------------------------------------------------------------------------------- /simulator/DNP3/DNP3Simulator/Components/TemplateItemDialog.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using System.ComponentModel; 4 | using System.Data; 5 | using System.Drawing; 6 | using System.Linq; 7 | using System.Text; 8 | using System.Windows.Forms; 9 | 10 | 11 | using Automatak.DNP3.Interface; 12 | 13 | namespace Automatak.Simulator.DNP3.Components 14 | { 15 | public partial class TemplateItemDialog : Form 16 | { 17 | public TemplateItemDialog() 18 | { 19 | InitializeComponent(); 20 | 21 | this.comboBoxPointClass.DataSource = Enum.GetValues(typeof(PointClass)); 22 | } 23 | 24 | private void buttonSave_Click(object sender, EventArgs e) 25 | { 26 | this.DialogResult = DialogResult.OK; 27 | this.Close(); 28 | } 29 | 30 | public PointClass SelectedPointClass 31 | { 32 | get 33 | { 34 | return (PointClass) comboBoxPointClass.SelectedItem; 35 | } 36 | } 37 | } 38 | } 39 | -------------------------------------------------------------------------------- /simulator/DNP3/DNP3Simulator/DNP3Config.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using System.Linq; 4 | using System.Text; 5 | using System.Threading.Tasks; 6 | 7 | using Automatak.DNP3.Interface; 8 | using Automatak.Simulator.DNP3.API; 9 | 10 | namespace Automatak.Simulator.DNP3 11 | { 12 | class DNP3Config : IDNP3Config 13 | { 14 | readonly IDictionary templates = new Dictionary(); 15 | readonly IEnumerable outstations; 16 | 17 | public DNP3Config(IEnumerable outstations) 18 | { 19 | this.outstations = outstations; 20 | } 21 | 22 | IEnumerable IDNP3Config.OutstationModules 23 | { 24 | get 25 | { 26 | return outstations; 27 | } 28 | } 29 | 30 | IEnumerable> IDNP3Config.Templates 31 | { 32 | get 33 | { 34 | return templates.Select(x => x); 35 | } 36 | } 37 | 38 | void IDNP3Config.AddTemplate(string alias, DatabaseTemplate template) 39 | { 40 | templates[alias] = template; 41 | } 42 | 43 | 44 | bool IDNP3Config.ContainsTemplateId(string alias) 45 | { 46 | return templates.ContainsKey(alias); 47 | } 48 | 49 | 50 | DatabaseTemplate IDNP3Config.GetTemplateMaybeNull(string alias) 51 | { 52 | if (templates.ContainsKey(alias)) 53 | { 54 | return templates[alias]; 55 | } 56 | else 57 | { 58 | return null; 59 | } 60 | } 61 | 62 | 63 | public IEnumerable OutstationModules 64 | { 65 | get { return outstations; } 66 | } 67 | } 68 | } 69 | -------------------------------------------------------------------------------- /simulator/DNP3/DNP3Simulator/DNP3SimulatorPlugin.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using System.Linq; 4 | using System.Text; 5 | using System.Threading.Tasks; 6 | using System.Windows.Forms; 7 | 8 | using Automatak.DNP3.Adapter; 9 | using Automatak.DNP3.Interface; 10 | 11 | using Automatak.Simulator.Commons; 12 | using Automatak.Simulator.API; 13 | using Automatak.Simulator.DNP3.API; 14 | 15 | namespace Automatak.Simulator.DNP3 16 | { 17 | static class IconIndex 18 | { 19 | public const int Channel = 0; 20 | public const int Master = 1; 21 | public const int Outstation = 2; 22 | }; 23 | 24 | 25 | class DNP3SimulatorPlugin : ISimulatorPlugin 26 | { 27 | readonly ImageList imgList = new ImageList(); 28 | readonly ILogHandler logHandler; 29 | readonly IDNP3Manager manager; 30 | 31 | readonly DNP3Config config = new DNP3Config( 32 | new IOutstationModule[]{ 33 | Automatak.Simulator.DNP3.DefaultOutstationPlugin.OutstationModule.Instance, 34 | Automatak.Simulator.DNP3.RelayOutstationPlugin.OutstationModule.Instance 35 | } 36 | ); 37 | 38 | public DNP3SimulatorPlugin(ILog log) 39 | { 40 | this.logHandler = new ForwardingLogHandler(log); 41 | 42 | this.manager = DNP3ManagerFactory.CreateManager(this.logHandler); 43 | 44 | imgList.Images.Add(Properties.Resources.satellite_dish); 45 | imgList.Images.Add(Properties.Resources.network_monitor); 46 | imgList.Images.Add(Properties.Resources.send_container); 47 | 48 | /* 49 | Load outstation plugins here 50 | */ 51 | } 52 | 53 | string ISimulatorPlugin.UniqueId 54 | { 55 | get { return "DNP3"; } 56 | } 57 | 58 | System.Drawing.Image ISimulatorPlugin.PluginImage 59 | { 60 | get { return Properties.Resources.satellite_dish_add; } 61 | } 62 | 63 | 64 | string ISimulatorPlugin.RootDisplayName 65 | { 66 | get { return "DNP3 Channel"; } 67 | } 68 | 69 | 70 | ISimulatorNode ISimulatorPlugin.Create(ISimulatorNodeCallbacks callbacks) 71 | { 72 | using (var dialog = new Components.ChannelDialog()) 73 | { 74 | dialog.ShowDialog(); 75 | if (dialog.DialogResult == DialogResult.OK) 76 | { 77 | var channel = dialog.ChannelAction.Invoke(manager); 78 | return new ChannelNode(config, channel, callbacks, dialog.SelectedAlias); 79 | } 80 | else 81 | { 82 | return null; 83 | } 84 | } 85 | } 86 | 87 | System.Windows.Forms.ImageList ISimulatorPlugin.NodeImageList 88 | { 89 | get { return imgList; } 90 | } 91 | } 92 | } 93 | -------------------------------------------------------------------------------- /simulator/DNP3/DNP3Simulator/DNP3SimulatorPluginFactory.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using System.Linq; 4 | using System.Text; 5 | using System.Threading.Tasks; 6 | 7 | using Automatak.Simulator.Commons; 8 | using Automatak.Simulator.API; 9 | 10 | namespace Automatak.Simulator.DNP3 11 | { 12 | public class DNP3SimulatorPluginFactory : ISimulatorPluginFactory 13 | { 14 | ISimulatorPlugin ISimulatorPluginFactory.Create(ILog log) 15 | { 16 | return new DNP3SimulatorPlugin(log); 17 | } 18 | 19 | public static ISimulatorPluginFactory Instance 20 | { 21 | get 22 | { 23 | return instance; 24 | } 25 | } 26 | 27 | static ISimulatorPluginFactory instance = new DNP3SimulatorPluginFactory(); 28 | 29 | DNP3SimulatorPluginFactory() 30 | {} 31 | } 32 | } 33 | -------------------------------------------------------------------------------- /simulator/DNP3/DNP3Simulator/ForwardingLogHandler.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using System.Linq; 4 | using System.Text; 5 | 6 | using Automatak.Simulator.Commons; 7 | using Automatak.DNP3.Interface; 8 | 9 | namespace Automatak.Simulator.DNP3 10 | { 11 | class ForwardingLogHandler : ILogHandler 12 | { 13 | readonly ILog proxy; 14 | 15 | public ForwardingLogHandler(ILog proxy) 16 | { 17 | this.proxy = proxy; 18 | } 19 | 20 | static bool DisplayTimestamp(LogFilter filter) 21 | { 22 | switch (filter.Flags) 23 | { 24 | case(LogFilters.APP_OBJECT_RX): 25 | case(LogFilters.APP_OBJECT_TX): 26 | case(LogFilters.LINK_RX_HEX): 27 | case(LogFilters.LINK_TX_HEX): 28 | return false; 29 | default: 30 | return true; 31 | } 32 | } 33 | 34 | static DisplayHint GetDisplayHint(LogFilter filter) 35 | { 36 | switch (filter.Flags) 37 | { 38 | case(LogFilters.ERROR): 39 | return DisplayHint.ERROR; 40 | case(LogFilters.WARNING): 41 | return DisplayHint.WARNING; 42 | case (LogFilters.APP_OBJECT_RX): 43 | case (LogFilters.APP_OBJECT_TX): 44 | case (LogFilters.LINK_RX_HEX): 45 | case (LogFilters.LINK_TX_HEX): 46 | return DisplayHint.ALT1; 47 | default: 48 | return DisplayHint.INFO; 49 | } 50 | } 51 | 52 | void ILogHandler.Log(LogEntry entry) 53 | { 54 | var hint = GetDisplayHint(entry.filter); 55 | 56 | if (DisplayTimestamp(entry.filter)) 57 | { 58 | proxy.Log(hint, ""); 59 | proxy.LogFull(hint, LogFilters.GetFilterString(entry.filter.Flags), entry.alias, entry.message); 60 | } 61 | else 62 | { 63 | proxy.Log(hint, entry.message); 64 | } 65 | } 66 | } 67 | } 68 | -------------------------------------------------------------------------------- /simulator/DNP3/DNP3Simulator/IDNP3Config.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using System.Linq; 4 | using System.Text; 5 | using System.Threading.Tasks; 6 | 7 | using Automatak.DNP3.Interface; 8 | using Automatak.Simulator.DNP3.API; 9 | 10 | namespace Automatak.Simulator.DNP3 11 | { 12 | interface IDNP3Config 13 | { 14 | void AddTemplate(string alias, DatabaseTemplate template); 15 | 16 | DatabaseTemplate GetTemplateMaybeNull(string alias); 17 | 18 | IEnumerable> Templates 19 | { 20 | get; 21 | } 22 | 23 | IEnumerable OutstationModules 24 | { 25 | get; 26 | } 27 | 28 | bool ContainsTemplateId(string alias); 29 | 30 | } 31 | } 32 | -------------------------------------------------------------------------------- /simulator/DNP3/DNP3Simulator/MasterNode.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using System.Linq; 4 | using System.Text; 5 | using System.Threading.Tasks; 6 | 7 | using Automatak.DNP3.Interface; 8 | using Automatak.Simulator.API; 9 | using Automatak.Simulator.DNP3.Commons; 10 | 11 | namespace Automatak.Simulator.DNP3 12 | { 13 | class MasterNode : ISimulatorNode 14 | { 15 | readonly MeasurementCache cache; 16 | readonly IMaster master; 17 | readonly ISimulatorNodeCallbacks callbacks; 18 | readonly string alias; 19 | readonly ISimulatorNodeAction openAction; 20 | 21 | MasterForm form = null; 22 | 23 | string ISimulatorNode.Alias 24 | { 25 | get 26 | { 27 | return alias; 28 | } 29 | } 30 | 31 | public MasterNode(MeasurementCache cache, IMaster master, ISimulatorNodeCallbacks callbacks, string alias) 32 | { 33 | this.cache = cache; 34 | this.master = master; 35 | this.callbacks = callbacks; 36 | this.alias = alias; 37 | 38 | this.callbacks.ChangeImage(IconIndex.Master); 39 | 40 | this.openAction = new NodeAction("Open", () => OpenForm()); 41 | } 42 | 43 | void OpenForm() 44 | { 45 | if (form == null) 46 | { 47 | form = new MasterForm(master, cache, alias); 48 | } 49 | 50 | form.Show(); 51 | } 52 | 53 | void ISimulatorNode.Remove() 54 | { 55 | if (form != null) 56 | { 57 | form.Close(); 58 | form.Dispose(); 59 | form = null; 60 | } 61 | master.Shutdown(); 62 | } 63 | 64 | IEnumerable ISimulatorNode.Metrics 65 | { 66 | get 67 | { 68 | var list = new List(); 69 | var stats = master.GetStackStatistics(); 70 | list.Add(new Metric("Num transport rx", stats.NumTransportRx.ToString())); 71 | list.Add(new Metric("Num transport tx", stats.NumTransportTx.ToString())); 72 | list.Add(new Metric("Num transport error rx", stats.NumTransportErrorRx.ToString())); 73 | return list; 74 | } 75 | } 76 | 77 | string ISimulatorNode.DisplayName 78 | { 79 | get { return alias; } 80 | } 81 | 82 | IEnumerable ISimulatorNode.Actions 83 | { 84 | get 85 | { 86 | yield return openAction; 87 | } 88 | } 89 | 90 | IEnumerable ISimulatorNode.Children 91 | { 92 | get { return Enumerable.Empty(); } 93 | } 94 | 95 | /* 96 | Guid ISimulatorNode.UniqueID 97 | { 98 | get { return guid; } 99 | } 100 | * */ 101 | } 102 | } 103 | -------------------------------------------------------------------------------- /simulator/DNP3/DNP3Simulator/NodeAction.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using System.Linq; 4 | using System.Text; 5 | using System.Threading.Tasks; 6 | 7 | using Automatak.Simulator.API; 8 | 9 | namespace Automatak.Simulator.DNP3 10 | { 11 | class NodeAction : ISimulatorNodeAction 12 | { 13 | readonly string displayName; 14 | readonly Action action; 15 | 16 | 17 | public NodeAction(string displayName, Action action) 18 | { 19 | this.displayName = displayName; 20 | this.action = action; 21 | } 22 | 23 | string ISimulatorNodeAction.DisplayName 24 | { 25 | get { return displayName; } 26 | } 27 | 28 | void ISimulatorNodeAction.Invoke() 29 | { 30 | action.Invoke(); 31 | } 32 | } 33 | } 34 | -------------------------------------------------------------------------------- /simulator/DNP3/DNP3Simulator/OutstationNode.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using System.Linq; 4 | using System.Text; 5 | using System.Threading.Tasks; 6 | 7 | using Automatak.DNP3.Interface; 8 | using Automatak.Simulator.DNP3.API; 9 | using Automatak.Simulator.DNP3.Commons; 10 | using Automatak.Simulator.API; 11 | 12 | namespace Automatak.Simulator.DNP3 13 | { 14 | class OutstationNode : ISimulatorNode 15 | { 16 | readonly IOutstation outstation; 17 | readonly IOutstationInstance instance; 18 | readonly ISimulatorNodeCallbacks callbacks; 19 | readonly ISimulatorNodeAction openAction; 20 | 21 | string ISimulatorNode.Alias 22 | { 23 | get 24 | { 25 | return instance.DisplayName; 26 | } 27 | } 28 | 29 | public OutstationNode(IOutstation outstation, IOutstationInstance instance, ISimulatorNodeCallbacks callbacks) 30 | { 31 | this.outstation = outstation; 32 | this.instance = instance; 33 | this.callbacks = callbacks; 34 | 35 | this.openAction = new NodeAction("Open", () => OpenForm()); 36 | 37 | this.callbacks.ChangeImage(IconIndex.Outstation); 38 | } 39 | 40 | void OpenForm() 41 | { 42 | this.instance.ShowForm(); 43 | } 44 | 45 | void ISimulatorNode.Remove() 46 | { 47 | this.instance.Shutdown(); 48 | this.outstation.Shutdown(); 49 | } 50 | 51 | IEnumerable ISimulatorNode.Metrics 52 | { 53 | get 54 | { 55 | var list = new List(); 56 | var stats = outstation.GetStackStatistics(); 57 | list.Add(new Metric("Num transport rx", stats.NumTransportRx.ToString())); 58 | list.Add(new Metric("Num transport tx", stats.NumTransportTx.ToString())); 59 | list.Add(new Metric("Num transport error rx", stats.NumTransportErrorRx.ToString())); 60 | return list; 61 | } 62 | } 63 | 64 | string ISimulatorNode.DisplayName 65 | { 66 | get { return instance.DisplayName; } 67 | } 68 | 69 | IEnumerable ISimulatorNode.Actions 70 | { 71 | get 72 | { 73 | yield return openAction; 74 | } 75 | } 76 | 77 | IEnumerable ISimulatorNode.Children 78 | { 79 | get { return Enumerable.Empty(); } 80 | } 81 | } 82 | } 83 | -------------------------------------------------------------------------------- /simulator/DNP3/DNP3Simulator/Properties/AssemblyInfo.cs: -------------------------------------------------------------------------------- 1 | using System.Reflection; 2 | using System.Runtime.CompilerServices; 3 | using System.Runtime.InteropServices; 4 | 5 | // General Information about an assembly is controlled through the following 6 | // set of attributes. Change these attribute values to modify the information 7 | // associated with an assembly. 8 | [assembly: AssemblyTitle("SimulatorDNP3")] 9 | [assembly: AssemblyDescription("")] 10 | [assembly: AssemblyConfiguration("")] 11 | [assembly: AssemblyCompany("")] 12 | [assembly: AssemblyProduct("SimulatorDNP3")] 13 | [assembly: AssemblyCopyright("Copyright © 2014")] 14 | [assembly: AssemblyTrademark("")] 15 | [assembly: AssemblyCulture("")] 16 | 17 | // Setting ComVisible to false makes the types in this assembly not visible 18 | // to COM components. If you need to access a type in this assembly from 19 | // COM, set the ComVisible attribute to true on that type. 20 | [assembly: ComVisible(false)] 21 | 22 | // The following GUID is for the ID of the typelib if this project is exposed to COM 23 | [assembly: Guid("3c00ed6f-9061-44bd-8195-f8f9f01bf78e")] 24 | 25 | // Version information for an assembly consists of the following four values: 26 | // 27 | // Major Version 28 | // Minor Version 29 | // Build Number 30 | // Revision 31 | // 32 | // You can specify all the values or you can default the Build and Revision Numbers 33 | // by using the '*' as shown below: 34 | // [assembly: AssemblyVersion("1.0.*")] 35 | [assembly: AssemblyVersion("1.0.0.0")] 36 | [assembly: AssemblyFileVersion("1.0.0.0")] 37 | -------------------------------------------------------------------------------- /simulator/DNP3/DNP3Simulator/Resources/add.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/dnp3/dnp3-simulator/10c9dcb61e683e2e80ae6cc4e6a9af6228438d9d/simulator/DNP3/DNP3Simulator/Resources/add.png -------------------------------------------------------------------------------- /simulator/DNP3/DNP3Simulator/Resources/network_monitor.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/dnp3/dnp3-simulator/10c9dcb61e683e2e80ae6cc4e6a9af6228438d9d/simulator/DNP3/DNP3Simulator/Resources/network_monitor.png -------------------------------------------------------------------------------- /simulator/DNP3/DNP3Simulator/Resources/satellite_dish.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/dnp3/dnp3-simulator/10c9dcb61e683e2e80ae6cc4e6a9af6228438d9d/simulator/DNP3/DNP3Simulator/Resources/satellite_dish.png -------------------------------------------------------------------------------- /simulator/DNP3/DNP3Simulator/Resources/satellite_dish_add.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/dnp3/dnp3-simulator/10c9dcb61e683e2e80ae6cc4e6a9af6228438d9d/simulator/DNP3/DNP3Simulator/Resources/satellite_dish_add.png -------------------------------------------------------------------------------- /simulator/DNP3/DNP3Simulator/Resources/send_container.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/dnp3/dnp3-simulator/10c9dcb61e683e2e80ae6cc4e6a9af6228438d9d/simulator/DNP3/DNP3Simulator/Resources/send_container.png -------------------------------------------------------------------------------- /simulator/DNP3/DNP3Simulator/packages.config: -------------------------------------------------------------------------------- 1 |  2 | 3 | 4 | -------------------------------------------------------------------------------- /simulator/DNP3/DefaultOutstationPlugin/GUI/AnalogValueDialog.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using System.ComponentModel; 4 | using System.Data; 5 | using System.Drawing; 6 | using System.Linq; 7 | using System.Text; 8 | using System.Windows.Forms; 9 | 10 | using Automatak.DNP3.Interface; 11 | using Automatak.Simulator.DNP3.API; 12 | using Automatak.Simulator.DNP3.Commons; 13 | 14 | namespace Automatak.Simulator.DNP3.DefaultOutstationPlugin 15 | { 16 | public partial class AnalogValueDialog : Form 17 | { 18 | readonly bool isAnalog; 19 | readonly IEnumerable indices; 20 | 21 | public AnalogValueDialog(bool isAnalog, IEnumerable indices) 22 | { 23 | InitializeComponent(); 24 | 25 | this.isAnalog = isAnalog; 26 | this.indices = indices; 27 | 28 | this.qualitySelector.QualityInfo = QualityInfo.analog; 29 | 30 | this.numericUpDown1.Minimum = Decimal.MinValue; 31 | this.numericUpDown1.Maximum = Decimal.MaxValue; 32 | } 33 | 34 | private void buttonSave_Click(object sender, EventArgs e) 35 | { 36 | this.DialogResult = DialogResult.OK; 37 | this.Close(); 38 | } 39 | 40 | public IEnumerable> SelectedActions 41 | { 42 | get 43 | { 44 | var value = Decimal.ToDouble(numericUpDown1.Value); 45 | var timestamp = DateTime.Now; 46 | var quality = qualitySelector.Quality; 47 | 48 | 49 | if (isAnalog) 50 | { 51 | return indices.Select(i => MeasActions.GetAnalogAction(value, quality, timestamp, i)); 52 | } 53 | else 54 | { 55 | return indices.Select(i => MeasActions.GetAnalogOutputStatusAction(value, quality, timestamp, i)); 56 | } 57 | } 58 | } 59 | 60 | public ChangeSet SelectedChanges 61 | { 62 | get 63 | { 64 | var value = Decimal.ToDouble(numericUpDown1.Value); 65 | var quality = qualitySelector.Quality; 66 | var timestamp = DateTime.Now; 67 | var changes = new ChangeSet(); 68 | if (isAnalog) 69 | { 70 | indices.Each(i => changes.Update(new Analog(value, quality, timestamp), i)); 71 | } 72 | else 73 | { 74 | indices.Each(i => changes.Update(new AnalogOutputStatus(value, quality, timestamp), i)); 75 | } 76 | return changes; 77 | } 78 | } 79 | } 80 | } 81 | -------------------------------------------------------------------------------- /simulator/DNP3/DefaultOutstationPlugin/GUI/BinaryValueDialog.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using System.ComponentModel; 4 | using System.Data; 5 | using System.Drawing; 6 | using System.Linq; 7 | using System.Text; 8 | using System.Windows.Forms; 9 | 10 | using Automatak.DNP3.Interface; 11 | 12 | namespace Automatak.Simulator.DNP3.DefaultOutstationPlugin 13 | { 14 | public partial class BinaryValueDialog : Form 15 | { 16 | readonly bool isBinary; 17 | readonly IEnumerable indices; 18 | 19 | public BinaryValueDialog(bool isBinary, IEnumerable indices) 20 | { 21 | InitializeComponent(); 22 | 23 | this.isBinary = isBinary; 24 | this.indices = indices; 25 | 26 | this.qualitySelector.QualityInfo = isBinary ? QualityInfo.binary : QualityInfo.binaryOutputStatus; 27 | } 28 | 29 | private void buttonSave_Click(object sender, EventArgs e) 30 | { 31 | this.DialogResult = DialogResult.OK; 32 | this.Close(); 33 | } 34 | 35 | public ChangeSet SelectedChanges 36 | { 37 | get 38 | { 39 | var timestamp = DateTime.Now; 40 | var changes = new ChangeSet(); 41 | 42 | if (isBinary) 43 | { 44 | indices.Each(i => changes.Update(new Binary(checkBoxValue.Checked, qualitySelector.Quality, timestamp), i)); 45 | } 46 | else 47 | { 48 | indices.Each(i => changes.Update(new BinaryOutputStatus(checkBoxValue.Checked, qualitySelector.Quality, timestamp), i)); 49 | } 50 | 51 | return changes; 52 | } 53 | } 54 | } 55 | } 56 | -------------------------------------------------------------------------------- /simulator/DNP3/DefaultOutstationPlugin/GUI/CounterValueDialog.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using System.ComponentModel; 4 | using System.Data; 5 | using System.Drawing; 6 | using System.Linq; 7 | using System.Text; 8 | using System.Windows.Forms; 9 | 10 | using Automatak.DNP3.Interface; 11 | 12 | namespace Automatak.Simulator.DNP3.DefaultOutstationPlugin 13 | { 14 | public partial class CounterValueDialog : Form 15 | { 16 | readonly bool isCounter; 17 | readonly IEnumerable indices; 18 | 19 | public CounterValueDialog(bool isCounter, IEnumerable indices) 20 | { 21 | InitializeComponent(); 22 | 23 | this.isCounter = isCounter; 24 | this.indices = indices; 25 | 26 | this.qualitySelector.QualityInfo = QualityInfo.counter; 27 | 28 | this.numericUpDown1.Minimum = 0; 29 | this.numericUpDown1.Maximum = UInt32.MaxValue; 30 | } 31 | 32 | private void buttonSave_Click(object sender, EventArgs e) 33 | { 34 | this.DialogResult = DialogResult.OK; 35 | this.Close(); 36 | } 37 | 38 | public ChangeSet SelectedChanges 39 | { 40 | get 41 | { 42 | var value = Decimal.ToUInt32(numericUpDown1.Value); 43 | var quality = qualitySelector.Quality; 44 | var timestamp = DateTime.Now; 45 | var changes = new ChangeSet(); 46 | if (isCounter) 47 | { 48 | indices.Each(i => changes.Update(new Counter(value, quality, timestamp), i)); 49 | } 50 | else 51 | { 52 | indices.Each(i => changes.Update(new FrozenCounter(value, quality, timestamp), i)); 53 | } 54 | return changes; 55 | } 56 | } 57 | } 58 | } 59 | -------------------------------------------------------------------------------- /simulator/DNP3/DefaultOutstationPlugin/GUI/DoubleBinaryValueDialog.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using System.ComponentModel; 4 | using System.Data; 5 | using System.Drawing; 6 | using System.Linq; 7 | using System.Text; 8 | using System.Windows.Forms; 9 | 10 | using Automatak.DNP3.Interface; 11 | using Automatak.Simulator.DNP3.API; 12 | using Automatak.Simulator.DNP3.Commons; 13 | 14 | namespace Automatak.Simulator.DNP3.DefaultOutstationPlugin 15 | { 16 | public partial class DoubleBinaryValueDialog : Form 17 | { 18 | readonly IEnumerable indices; 19 | 20 | public DoubleBinaryValueDialog(IEnumerable indices) 21 | { 22 | InitializeComponent(); 23 | 24 | this.indices = indices; 25 | 26 | this.qualitySelector.QualityInfo = QualityInfo.doubleBinary; 27 | 28 | this.comboBox1.DataSource = Enum.GetValues(typeof(DoubleBit)); 29 | } 30 | 31 | private void buttonSave_Click(object sender, EventArgs e) 32 | { 33 | this.DialogResult = DialogResult.OK; 34 | this.Close(); 35 | } 36 | 37 | public IEnumerable> SelectedActions 38 | { 39 | get 40 | { 41 | var value = (DoubleBit) comboBox1.SelectedItem; 42 | var quality = qualitySelector.Quality; 43 | var timestamp = DateTime.Now; 44 | 45 | return indices.Select(i => MeasActions.GetDoubleBinaryAction(value, quality, timestamp, i)); 46 | } 47 | } 48 | 49 | public ChangeSet SelectedChanges 50 | { 51 | get 52 | { 53 | var value = (DoubleBit) comboBox1.SelectedItem; 54 | var quality = qualitySelector.Quality; 55 | var timestamp = DateTime.Now; 56 | var changes = new ChangeSet(); 57 | indices.Each(i => changes.Update(new DoubleBitBinary(value, quality, timestamp), i)); 58 | return changes; 59 | } 60 | } 61 | } 62 | } 63 | -------------------------------------------------------------------------------- /simulator/DNP3/DefaultOutstationPlugin/GUI/QualitySelector.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using System.ComponentModel; 4 | using System.Drawing; 5 | using System.Data; 6 | using System.Linq; 7 | using System.Text; 8 | using System.Threading.Tasks; 9 | using System.Windows.Forms; 10 | 11 | using Automatak.DNP3.Interface; 12 | 13 | namespace Automatak.Simulator.DNP3.DefaultOutstationPlugin 14 | { 15 | public partial class QualitySelector : UserControl 16 | { 17 | public QualitySelector() 18 | { 19 | InitializeComponent(); 20 | } 21 | 22 | public IQualityBitInfo QualityInfo 23 | { 24 | set { 25 | this.checkBox0.Text = value.GetLongLabel(0); 26 | this.checkBox1.Text = value.GetLongLabel(1); 27 | this.checkBox2.Text = value.GetLongLabel(2); 28 | this.checkBox3.Text = value.GetLongLabel(3); 29 | this.checkBox4.Text = value.GetLongLabel(4); 30 | this.checkBox5.Text = value.GetLongLabel(5); 31 | this.checkBox6.Text = value.GetLongLabel(6); 32 | this.checkBox7.Text = value.GetLongLabel(7); 33 | } 34 | } 35 | 36 | public byte Quality 37 | { 38 | get 39 | { 40 | byte value = 0; 41 | if (this.checkBox0.Checked) value |= 1 << 0; 42 | if (this.checkBox1.Checked) value |= 1 << 1; 43 | if (this.checkBox2.Checked) value |= 1 << 2; 44 | if (this.checkBox3.Checked) value |= 1 << 3; 45 | if (this.checkBox4.Checked) value |= 1 << 4; 46 | if (this.checkBox5.Checked) value |= 1 << 5; 47 | if (this.checkBox6.Checked) value |= 1 << 6; 48 | if (this.checkBox7.Checked) value |= 1 << 7; 49 | return value; 50 | } 51 | } 52 | } 53 | } 54 | -------------------------------------------------------------------------------- /simulator/DNP3/DefaultOutstationPlugin/OutstationInstance.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using System.Linq; 4 | using System.Text; 5 | using System.Threading.Tasks; 6 | 7 | using Automatak.DNP3.Interface; 8 | using Automatak.Simulator.API; 9 | using Automatak.Simulator.DNP3.API; 10 | using Automatak.Simulator.DNP3.Commons; 11 | 12 | namespace Automatak.Simulator.DNP3.DefaultOutstationPlugin 13 | { 14 | public class OutstationModule : IOutstationModule 15 | { 16 | const string name = "DefaultOutstation"; 17 | 18 | OutstationStackConfig IOutstationModule.DefaultConfig 19 | { 20 | get { 21 | return new OutstationStackConfig(); 22 | } 23 | } 24 | 25 | bool IOutstationModule.AllowTemplateEditing 26 | { 27 | get { return true; } 28 | } 29 | 30 | IOutstationFactory IOutstationModule.CreateFactory() 31 | { 32 | return new OutstationFactory(); 33 | } 34 | 35 | public static IOutstationModule Instance 36 | { 37 | get 38 | { 39 | return instance; 40 | } 41 | } 42 | 43 | private OutstationModule() 44 | {} 45 | 46 | private static OutstationModule instance = new OutstationModule(); 47 | 48 | public override string ToString() 49 | { 50 | return name; 51 | } 52 | 53 | string IOutstationModule.Description 54 | { 55 | get { return "A default outstation simulator that allows database editing and other behaviors"; } 56 | } 57 | 58 | string IOutstationModule.Name 59 | { 60 | get { return name; } 61 | } 62 | 63 | string IOutstationModule.DefaultLogName 64 | { 65 | get { return "outstation"; } 66 | } 67 | } 68 | 69 | 70 | class OutstationFactory : IOutstationFactory 71 | { 72 | private readonly ProxyCommandHandler commandHandler = new ProxyCommandHandler(); 73 | private readonly EventedOutstationApplication application = new EventedOutstationApplication(); 74 | 75 | 76 | ICommandHandler IOutstationFactory.CommandHandler 77 | { 78 | get { return commandHandler; } 79 | } 80 | 81 | IOutstationApplication IOutstationFactory.Application 82 | { 83 | get { return application; } 84 | } 85 | 86 | IOutstationInstance IOutstationFactory.CreateInstance(IOutstation outstation, string name, OutstationStackConfig config) 87 | { 88 | return new OutstationInstance(commandHandler, application, outstation, config, name); 89 | } 90 | } 91 | 92 | 93 | class OutstationInstance : IOutstationInstance 94 | { 95 | readonly ProxyCommandHandler handler; 96 | readonly EventedOutstationApplication application; 97 | readonly IOutstation outstation; 98 | readonly string alias; 99 | readonly MeasurementCache cache; 100 | 101 | OutstationForm form = null; 102 | 103 | public OutstationInstance(ProxyCommandHandler handler, EventedOutstationApplication application, IOutstation outstation, OutstationStackConfig config, string alias) 104 | { 105 | this.handler = handler; 106 | this.application = application; 107 | this.outstation = outstation; 108 | this.alias = alias; 109 | 110 | this.cache = new MeasurementCache(config.databaseTemplate); 111 | } 112 | 113 | string IOutstationInstance.DisplayName 114 | { 115 | get { return alias; } 116 | } 117 | 118 | bool IOutstationInstance.HasForm 119 | { 120 | get { return true; } 121 | } 122 | 123 | bool IOutstationInstance.ShowFormOnCreation 124 | { 125 | get 126 | { 127 | return false; 128 | } 129 | } 130 | 131 | void IOutstationInstance.ShowForm() 132 | { 133 | if(this.form == null) 134 | { 135 | this.form = new OutstationForm(outstation, application, cache, handler, alias); 136 | } 137 | 138 | form.Show(); 139 | } 140 | 141 | void IOutstationInstance.Shutdown() 142 | { 143 | if (form != null) 144 | { 145 | form.Close(); 146 | form.Dispose(); 147 | form = null; 148 | } 149 | } 150 | } 151 | 152 | } 153 | -------------------------------------------------------------------------------- /simulator/DNP3/DefaultOutstationPlugin/Properties/AssemblyInfo.cs: -------------------------------------------------------------------------------- 1 | using System.Reflection; 2 | using System.Runtime.CompilerServices; 3 | using System.Runtime.InteropServices; 4 | 5 | // General Information about an assembly is controlled through the following 6 | // set of attributes. Change these attribute values to modify the information 7 | // associated with an assembly. 8 | [assembly: AssemblyTitle("DefaultOutstationPlugin")] 9 | [assembly: AssemblyDescription("")] 10 | [assembly: AssemblyConfiguration("")] 11 | [assembly: AssemblyCompany("")] 12 | [assembly: AssemblyProduct("DefaultOutstationPlugin")] 13 | [assembly: AssemblyCopyright("Copyright © 2015")] 14 | [assembly: AssemblyTrademark("")] 15 | [assembly: AssemblyCulture("")] 16 | 17 | // Setting ComVisible to false makes the types in this assembly not visible 18 | // to COM components. If you need to access a type in this assembly from 19 | // COM, set the ComVisible attribute to true on that type. 20 | [assembly: ComVisible(false)] 21 | 22 | // The following GUID is for the ID of the typelib if this project is exposed to COM 23 | [assembly: Guid("7b61510a-e374-4ca0-9626-7855f672c091")] 24 | 25 | // Version information for an assembly consists of the following four values: 26 | // 27 | // Major Version 28 | // Minor Version 29 | // Build Number 30 | // Revision 31 | // 32 | // You can specify all the values or you can default the Build and Revision Numbers 33 | // by using the '*' as shown below: 34 | // [assembly: AssemblyVersion("1.0.*")] 35 | [assembly: AssemblyVersion("1.0.0.0")] 36 | [assembly: AssemblyFileVersion("1.0.0.0")] 37 | -------------------------------------------------------------------------------- /simulator/DNP3/DefaultOutstationPlugin/packages.config: -------------------------------------------------------------------------------- 1 |  2 | 3 | 4 | -------------------------------------------------------------------------------- /simulator/DNP3/RelayOutstationPlugin/OutstationInstance.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using System.Linq; 4 | using System.Text; 5 | using System.Threading.Tasks; 6 | 7 | using Automatak.DNP3.Interface; 8 | 9 | using Automatak.Simulator.API; 10 | using Automatak.Simulator.DNP3.API; 11 | using Automatak.Simulator.DNP3.Commons; 12 | 13 | namespace Automatak.Simulator.DNP3.RelayOutstationPlugin 14 | { 15 | public class OutstationModule : IOutstationModule 16 | { 17 | const string name = "Relay Simulator"; 18 | 19 | OutstationStackConfig IOutstationModule.DefaultConfig 20 | { 21 | get 22 | { 23 | var config = new OutstationStackConfig(); 24 | config.databaseTemplate = new DatabaseTemplate(1, 0, 6, 0, 0, 0, 0, 0); 25 | return config; 26 | } 27 | } 28 | 29 | bool IOutstationModule.AllowTemplateEditing 30 | { 31 | get { return false; } 32 | } 33 | 34 | IOutstationFactory IOutstationModule.CreateFactory() 35 | { 36 | return new OutstationFactory(); 37 | } 38 | 39 | public static IOutstationModule Instance 40 | { 41 | get 42 | { 43 | return instance; 44 | } 45 | } 46 | 47 | private OutstationModule() 48 | {} 49 | 50 | private static OutstationModule instance = new OutstationModule(); 51 | 52 | public override string ToString() 53 | { 54 | return name; 55 | } 56 | 57 | string IOutstationModule.Description 58 | { 59 | get { return "A simple relay simulator with a mock front panel. Responds to latch on/off"; } 60 | } 61 | 62 | string IOutstationModule.Name 63 | { 64 | get { return name; } 65 | } 66 | 67 | 68 | string IOutstationModule.DefaultLogName 69 | { 70 | get { return "relay"; } 71 | } 72 | } 73 | 74 | 75 | class OutstationFactory : IOutstationFactory 76 | { 77 | private readonly ProxyCommandHandler commandHandler = new ProxyCommandHandler(); 78 | private readonly EventedOutstationApplication application = new EventedOutstationApplication(); 79 | 80 | 81 | ICommandHandler IOutstationFactory.CommandHandler 82 | { 83 | get { return commandHandler; } 84 | } 85 | 86 | IOutstationApplication IOutstationFactory.Application 87 | { 88 | get { return application; } 89 | } 90 | 91 | IOutstationInstance IOutstationFactory.CreateInstance(IOutstation outstation, string name, OutstationStackConfig config) 92 | { 93 | return new OutstationInstance(commandHandler, application, outstation, config, name); 94 | } 95 | } 96 | 97 | 98 | class OutstationInstance : IOutstationInstance 99 | { 100 | readonly ProxyCommandHandler handler; 101 | readonly EventedOutstationApplication application; 102 | readonly IOutstation outstation; 103 | readonly string alias; 104 | readonly OutstationForm form; 105 | 106 | public OutstationInstance(ProxyCommandHandler handler, EventedOutstationApplication application, IOutstation outstation, OutstationStackConfig config, string alias) 107 | { 108 | this.handler = handler; 109 | this.application = application; 110 | this.outstation = outstation; 111 | this.alias = alias; 112 | 113 | this.form = new OutstationForm(outstation, handler); 114 | } 115 | 116 | string IOutstationInstance.DisplayName 117 | { 118 | get { return alias; } 119 | } 120 | 121 | bool IOutstationInstance.HasForm 122 | { 123 | get { return true; } 124 | } 125 | 126 | bool IOutstationInstance.ShowFormOnCreation 127 | { 128 | get 129 | { 130 | return true; 131 | } 132 | } 133 | 134 | void IOutstationInstance.ShowForm() 135 | { 136 | form.Show(); 137 | } 138 | 139 | void IOutstationInstance.Shutdown() 140 | { 141 | form.Close(); 142 | form.Dispose(); 143 | } 144 | } 145 | 146 | } 147 | -------------------------------------------------------------------------------- /simulator/DNP3/RelayOutstationPlugin/Properties/AssemblyInfo.cs: -------------------------------------------------------------------------------- 1 | using System.Reflection; 2 | using System.Runtime.CompilerServices; 3 | using System.Runtime.InteropServices; 4 | 5 | // General Information about an assembly is controlled through the following 6 | // set of attributes. Change these attribute values to modify the information 7 | // associated with an assembly. 8 | [assembly: AssemblyTitle("RelayOutstationPlugin")] 9 | [assembly: AssemblyDescription("")] 10 | [assembly: AssemblyConfiguration("")] 11 | [assembly: AssemblyCompany("")] 12 | [assembly: AssemblyProduct("RelayOutstationPlugin")] 13 | [assembly: AssemblyCopyright("Copyright © 2015")] 14 | [assembly: AssemblyTrademark("")] 15 | [assembly: AssemblyCulture("")] 16 | 17 | // Setting ComVisible to false makes the types in this assembly not visible 18 | // to COM components. If you need to access a type in this assembly from 19 | // COM, set the ComVisible attribute to true on that type. 20 | [assembly: ComVisible(false)] 21 | 22 | // The following GUID is for the ID of the typelib if this project is exposed to COM 23 | [assembly: Guid("33969f73-217a-482d-b496-ce181435db77")] 24 | 25 | // Version information for an assembly consists of the following four values: 26 | // 27 | // Major Version 28 | // Minor Version 29 | // Build Number 30 | // Revision 31 | // 32 | // You can specify all the values or you can default the Build and Revision Numbers 33 | // by using the '*' as shown below: 34 | // [assembly: AssemblyVersion("1.0.*")] 35 | [assembly: AssemblyVersion("1.0.0.0")] 36 | [assembly: AssemblyFileVersion("1.0.0.0")] 37 | -------------------------------------------------------------------------------- /simulator/DNP3/RelayOutstationPlugin/Properties/Resources.Designer.cs: -------------------------------------------------------------------------------- 1 | //------------------------------------------------------------------------------ 2 | // 3 | // This code was generated by a tool. 4 | // Runtime Version:4.0.30319.34209 5 | // 6 | // Changes to this file may cause incorrect behavior and will be lost if 7 | // the code is regenerated. 8 | // 9 | //------------------------------------------------------------------------------ 10 | 11 | namespace Automatak.Simulator.DNP3.RelayOutstationPlugin.Properties { 12 | using System; 13 | 14 | 15 | /// 16 | /// A strongly-typed resource class, for looking up localized strings, etc. 17 | /// 18 | // This class was auto-generated by the StronglyTypedResourceBuilder 19 | // class via a tool like ResGen or Visual Studio. 20 | // To add or remove a member, edit your .ResX file then rerun ResGen 21 | // with the /str option, or rebuild your VS project. 22 | [global::System.CodeDom.Compiler.GeneratedCodeAttribute("System.Resources.Tools.StronglyTypedResourceBuilder", "4.0.0.0")] 23 | [global::System.Diagnostics.DebuggerNonUserCodeAttribute()] 24 | [global::System.Runtime.CompilerServices.CompilerGeneratedAttribute()] 25 | internal class Resources { 26 | 27 | private static global::System.Resources.ResourceManager resourceMan; 28 | 29 | private static global::System.Globalization.CultureInfo resourceCulture; 30 | 31 | [global::System.Diagnostics.CodeAnalysis.SuppressMessageAttribute("Microsoft.Performance", "CA1811:AvoidUncalledPrivateCode")] 32 | internal Resources() { 33 | } 34 | 35 | /// 36 | /// Returns the cached ResourceManager instance used by this class. 37 | /// 38 | [global::System.ComponentModel.EditorBrowsableAttribute(global::System.ComponentModel.EditorBrowsableState.Advanced)] 39 | internal static global::System.Resources.ResourceManager ResourceManager { 40 | get { 41 | if (object.ReferenceEquals(resourceMan, null)) { 42 | global::System.Resources.ResourceManager temp = new global::System.Resources.ResourceManager("Automatak.Simulator.DNP3.RelayOutstationPlugin.Properties.Resources", typeof(Resources).Assembly); 43 | resourceMan = temp; 44 | } 45 | return resourceMan; 46 | } 47 | } 48 | 49 | /// 50 | /// Overrides the current thread's CurrentUICulture property for all 51 | /// resource lookups using this strongly typed resource class. 52 | /// 53 | [global::System.ComponentModel.EditorBrowsableAttribute(global::System.ComponentModel.EditorBrowsableState.Advanced)] 54 | internal static global::System.Globalization.CultureInfo Culture { 55 | get { 56 | return resourceCulture; 57 | } 58 | set { 59 | resourceCulture = value; 60 | } 61 | } 62 | } 63 | } 64 | -------------------------------------------------------------------------------- /simulator/DNP3/RelayOutstationPlugin/images/relay.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/dnp3/dnp3-simulator/10c9dcb61e683e2e80ae6cc4e6a9af6228438d9d/simulator/DNP3/RelayOutstationPlugin/images/relay.jpg -------------------------------------------------------------------------------- /simulator/DNP3/RelayOutstationPlugin/packages.config: -------------------------------------------------------------------------------- 1 |  2 | 3 | 4 | -------------------------------------------------------------------------------- /simulator/Simulator/AboutBox.Designer.cs: -------------------------------------------------------------------------------- 1 | namespace Automatak.Simulator 2 | { 3 | partial class AboutBox 4 | { 5 | /// 6 | /// Required designer variable. 7 | /// 8 | private System.ComponentModel.IContainer components = null; 9 | 10 | /// 11 | /// Clean up any resources being used. 12 | /// 13 | protected override void Dispose(bool disposing) 14 | { 15 | if (disposing && (components != null)) 16 | { 17 | components.Dispose(); 18 | } 19 | base.Dispose(disposing); 20 | } 21 | 22 | #region Windows Form Designer generated code 23 | 24 | /// 25 | /// Required method for Designer support - do not modify 26 | /// the contents of this method with the code editor. 27 | /// 28 | private void InitializeComponent() 29 | { 30 | System.ComponentModel.ComponentResourceManager resources = new System.ComponentModel.ComponentResourceManager(typeof(AboutBox)); 31 | this.pictureBox = new System.Windows.Forms.PictureBox(); 32 | this.richTextBox1 = new System.Windows.Forms.RichTextBox(); 33 | ((System.ComponentModel.ISupportInitialize)(this.pictureBox)).BeginInit(); 34 | this.SuspendLayout(); 35 | // 36 | // pictureBox 37 | // 38 | this.pictureBox.BackColor = System.Drawing.SystemColors.Control; 39 | this.pictureBox.BackgroundImageLayout = System.Windows.Forms.ImageLayout.Center; 40 | this.pictureBox.Dock = System.Windows.Forms.DockStyle.Top; 41 | this.pictureBox.Image = ((System.Drawing.Image)(resources.GetObject("pictureBox.Image"))); 42 | this.pictureBox.Location = new System.Drawing.Point(20, 20); 43 | this.pictureBox.Name = "pictureBox"; 44 | this.pictureBox.Size = new System.Drawing.Size(522, 119); 45 | this.pictureBox.TabIndex = 0; 46 | this.pictureBox.TabStop = false; 47 | // 48 | // richTextBox1 49 | // 50 | this.richTextBox1.BackColor = System.Drawing.SystemColors.Control; 51 | this.richTextBox1.BorderStyle = System.Windows.Forms.BorderStyle.None; 52 | this.richTextBox1.Cursor = System.Windows.Forms.Cursors.Arrow; 53 | this.richTextBox1.Font = new System.Drawing.Font("Calibri", 12F, System.Drawing.FontStyle.Bold, System.Drawing.GraphicsUnit.Point, ((byte)(0))); 54 | this.richTextBox1.ForeColor = System.Drawing.SystemColors.WindowText; 55 | this.richTextBox1.Location = new System.Drawing.Point(20, 162); 56 | this.richTextBox1.Margin = new System.Windows.Forms.Padding(20); 57 | this.richTextBox1.Name = "richTextBox1"; 58 | this.richTextBox1.ReadOnly = true; 59 | this.richTextBox1.ScrollBars = System.Windows.Forms.RichTextBoxScrollBars.None; 60 | this.richTextBox1.Size = new System.Drawing.Size(522, 314); 61 | this.richTextBox1.TabIndex = 1; 62 | this.richTextBox1.Text = ""; 63 | this.richTextBox1.LinkClicked += new System.Windows.Forms.LinkClickedEventHandler(this.richTextBox1_LinkClicked); 64 | // 65 | // AboutBox 66 | // 67 | this.AutoScaleDimensions = new System.Drawing.SizeF(6F, 13F); 68 | this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Font; 69 | this.BackColor = System.Drawing.SystemColors.Control; 70 | this.ClientSize = new System.Drawing.Size(562, 498); 71 | this.Controls.Add(this.richTextBox1); 72 | this.Controls.Add(this.pictureBox); 73 | this.FormBorderStyle = System.Windows.Forms.FormBorderStyle.FixedDialog; 74 | this.MaximizeBox = false; 75 | this.MinimizeBox = false; 76 | this.Name = "AboutBox"; 77 | this.Padding = new System.Windows.Forms.Padding(20); 78 | this.ShowIcon = false; 79 | this.ShowInTaskbar = false; 80 | this.StartPosition = System.Windows.Forms.FormStartPosition.CenterScreen; 81 | this.Text = "About"; 82 | ((System.ComponentModel.ISupportInitialize)(this.pictureBox)).EndInit(); 83 | this.ResumeLayout(false); 84 | 85 | } 86 | 87 | #endregion 88 | 89 | private System.Windows.Forms.PictureBox pictureBox; 90 | private System.Windows.Forms.RichTextBox richTextBox1; 91 | 92 | } 93 | } 94 | -------------------------------------------------------------------------------- /simulator/Simulator/AboutBox.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using System.ComponentModel; 4 | using System.Drawing; 5 | using System.Linq; 6 | using System.Reflection; 7 | using System.Windows.Forms; 8 | 9 | namespace Automatak.Simulator 10 | { 11 | partial class AboutBox : Form 12 | { 13 | public AboutBox() 14 | { 15 | InitializeComponent(); 16 | 17 | string[] lines = { 18 | 19 | "This software is based on open source components with the following licenses:", 20 | "", 21 | "opendnp3", 22 | "http://www.automatak.com/opendnp3", 23 | "http://www.apache.org/licenses/LICENSE-2.0.html", 24 | "", 25 | "asio", 26 | "http://think-async.com/", 27 | "http://www.boost.org/users/license.html", 28 | "", 29 | "This software is distributed on an \"AS IS\" BASIS", 30 | "WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.", 31 | }; 32 | 33 | 34 | this.richTextBox1.Text = String.Join(Environment.NewLine, lines); 35 | } 36 | 37 | private void button1_Click(object sender, EventArgs e) 38 | { 39 | this.Close(); 40 | } 41 | 42 | private void richTextBox1_LinkClicked(object sender, LinkClickedEventArgs e) 43 | { 44 | System.Diagnostics.Process.Start(e.LinkText); 45 | } 46 | } 47 | } 48 | -------------------------------------------------------------------------------- /simulator/Simulator/AboutBox.resx.DSN: -------------------------------------------------------------------------------- 1 | // This is Database Source Name File for ODBC connection to a company file. 2 | // Do not delete this file yourself. ODBC connection may not 3 | // operate correctly IF you manually delete this file. 4 | [ODBC] 5 | DRIVER=SQL Anywhere 6 | Compress=NO 7 | DisableMultiRowFetch=NO 8 | Debug=NO 9 | Integrated=NO 10 | AutoStop=NO 11 | CommLinks=TCPIP{HOST=fe80::38ed:81d7:5220:e28b%17:10180 12 | ServerName=QB_jadamcrain-PC_21 13 | -------------------------------------------------------------------------------- /simulator/Simulator/AboutBox.resx.ND: -------------------------------------------------------------------------------- 1 | // This is QuickBooks configuration File. It exists while users are connected 2 | // to a company file. Do not delete this file yourself. QuickBooks may not 3 | // operate correctly if you manually delete this file. 4 | [NetConnect] 5 | ServerIp=fe80::38ed:81d7:5220:e28b%17 6 | EngineName=QB_jadamcrain-PC_18 7 | ServerPort=10180 8 | FilePath=C:\Users\jadamcrain\Documents\GitHub\dnp3\dotnet\simulator\Simulator\AboutBox.resx 9 | ServerMode=1 10 | -------------------------------------------------------------------------------- /simulator/Simulator/App.config: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | -------------------------------------------------------------------------------- /simulator/Simulator/CommTreeView.cs.DSN: -------------------------------------------------------------------------------- 1 | // This is Database Source Name File for ODBC connection to a company file. 2 | // Do not delete this file yourself. ODBC connection may not 3 | // operate correctly IF you manually delete this file. 4 | [ODBC] 5 | DRIVER=SQL Anywhere 6 | Compress=NO 7 | DisableMultiRowFetch=NO 8 | Debug=NO 9 | Integrated=NO 10 | AutoStop=NO 11 | CommLinks=TCPIP{HOST=fe80::38ed:81d7:5220:e28b%17:10180 12 | ServerName=QB_jadamcrain-PC_21 13 | -------------------------------------------------------------------------------- /simulator/Simulator/CommTreeView.cs.ND: -------------------------------------------------------------------------------- 1 | // This is QuickBooks configuration File. It exists while users are connected 2 | // to a company file. Do not delete this file yourself. QuickBooks may not 3 | // operate correctly if you manually delete this file. 4 | [NetConnect] 5 | ServerIp=fe80::38ed:81d7:5220:e28b%17 6 | EngineName=QB_jadamcrain-PC_18 7 | ServerPort=10180 8 | FilePath=C:\Users\jadamcrain\Documents\GitHub\dnp3\clr\DNP3TestHarness\CommTreeView.cs 9 | ServerMode=1 10 | -------------------------------------------------------------------------------- /simulator/Simulator/MakeNoteDialog.Designer.cs: -------------------------------------------------------------------------------- 1 | namespace Automatak.Simulator 2 | { 3 | partial class MakeNoteDialog 4 | { 5 | /// 6 | /// Required designer variable. 7 | /// 8 | private System.ComponentModel.IContainer components = null; 9 | 10 | /// 11 | /// Clean up any resources being used. 12 | /// 13 | protected override void Dispose(bool disposing) 14 | { 15 | if (disposing && (components != null)) 16 | { 17 | components.Dispose(); 18 | } 19 | base.Dispose(disposing); 20 | } 21 | 22 | #region Windows Form Designer generated code 23 | 24 | /// 25 | /// Required method for Designer support - do not modify 26 | /// the contents of this method with the code editor. 27 | /// 28 | private void InitializeComponent() 29 | { 30 | this.textBox1 = new System.Windows.Forms.TextBox(); 31 | this.buttonAccept = new System.Windows.Forms.Button(); 32 | this.SuspendLayout(); 33 | // 34 | // textBox1 35 | // 36 | this.textBox1.Anchor = ((System.Windows.Forms.AnchorStyles)((((System.Windows.Forms.AnchorStyles.Top | System.Windows.Forms.AnchorStyles.Bottom) 37 | | System.Windows.Forms.AnchorStyles.Left) 38 | | System.Windows.Forms.AnchorStyles.Right))); 39 | this.textBox1.Location = new System.Drawing.Point(23, 23); 40 | this.textBox1.Multiline = true; 41 | this.textBox1.Name = "textBox1"; 42 | this.textBox1.Size = new System.Drawing.Size(326, 185); 43 | this.textBox1.TabIndex = 0; 44 | // 45 | // buttonAccept 46 | // 47 | this.buttonAccept.Anchor = ((System.Windows.Forms.AnchorStyles)(((System.Windows.Forms.AnchorStyles.Bottom | System.Windows.Forms.AnchorStyles.Left) 48 | | System.Windows.Forms.AnchorStyles.Right))); 49 | this.buttonAccept.Location = new System.Drawing.Point(22, 221); 50 | this.buttonAccept.Name = "buttonAccept"; 51 | this.buttonAccept.Size = new System.Drawing.Size(326, 37); 52 | this.buttonAccept.TabIndex = 1; 53 | this.buttonAccept.Text = "Accept"; 54 | this.buttonAccept.UseVisualStyleBackColor = true; 55 | this.buttonAccept.Click += new System.EventHandler(this.buttonAccept_Click); 56 | // 57 | // MakeNoteDialog 58 | // 59 | this.AutoScaleDimensions = new System.Drawing.SizeF(6F, 13F); 60 | this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Font; 61 | this.BackColor = System.Drawing.SystemColors.Control; 62 | this.ClientSize = new System.Drawing.Size(366, 267); 63 | this.Controls.Add(this.buttonAccept); 64 | this.Controls.Add(this.textBox1); 65 | this.FormBorderStyle = System.Windows.Forms.FormBorderStyle.FixedDialog; 66 | this.MaximizeBox = false; 67 | this.MinimizeBox = false; 68 | this.MinimumSize = new System.Drawing.Size(300, 300); 69 | this.Name = "MakeNoteDialog"; 70 | this.Padding = new System.Windows.Forms.Padding(20); 71 | this.ShowIcon = false; 72 | this.ShowInTaskbar = false; 73 | this.StartPosition = System.Windows.Forms.FormStartPosition.CenterParent; 74 | this.Text = "Log User Message"; 75 | this.ResumeLayout(false); 76 | this.PerformLayout(); 77 | 78 | } 79 | 80 | #endregion 81 | 82 | private System.Windows.Forms.TextBox textBox1; 83 | private System.Windows.Forms.Button buttonAccept; 84 | 85 | 86 | } 87 | } 88 | -------------------------------------------------------------------------------- /simulator/Simulator/MakeNoteDialog.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using System.ComponentModel; 4 | using System.Drawing; 5 | using System.Linq; 6 | using System.Reflection; 7 | using System.Windows.Forms; 8 | 9 | namespace Automatak.Simulator 10 | { 11 | partial class MakeNoteDialog : Form 12 | { 13 | public MakeNoteDialog() 14 | { 15 | InitializeComponent(); 16 | } 17 | 18 | public string[] SelectedLines 19 | { 20 | get 21 | { 22 | return textBox1.Lines; 23 | } 24 | } 25 | 26 | private void buttonAccept_Click(object sender, EventArgs e) 27 | { 28 | this.DialogResult = DialogResult.OK; 29 | this.Close(); 30 | } 31 | } 32 | } 33 | -------------------------------------------------------------------------------- /simulator/Simulator/Program.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using System.Linq; 4 | using System.Threading.Tasks; 5 | using System.Windows.Forms; 6 | 7 | using Automatak.Simulator.API; 8 | using Automatak.Simulator.DNP3; 9 | 10 | namespace Automatak.Simulator 11 | { 12 | static class Program 13 | { 14 | /// 15 | /// The main entry point for the application. 16 | /// 17 | [STAThread] 18 | static void Main(string[] args) 19 | { 20 | var plugins = new List() { DNP3SimulatorPluginFactory.Instance }; 21 | 22 | Application.EnableVisualStyles(); 23 | Application.SetCompatibleTextRenderingDefault(false); 24 | 25 | var splashOnLoad = true; 26 | 27 | if (args.Length >= 1 && args[0] == "-nosplash") 28 | { 29 | splashOnLoad = false; 30 | } 31 | 32 | var form = new SimulatorForm(plugins, splashOnLoad); 33 | Application.Run(form); 34 | } 35 | } 36 | } 37 | -------------------------------------------------------------------------------- /simulator/Simulator/Properties/AssemblyInfo.cs: -------------------------------------------------------------------------------- 1 | using System.Reflection; 2 | using System.Runtime.CompilerServices; 3 | using System.Runtime.InteropServices; 4 | 5 | // General Information about an assembly is controlled through the following 6 | // set of attributes. Change these attribute values to modify the information 7 | // associated with an assembly. 8 | [assembly: AssemblyTitle("DNP3TestHarness")] 9 | [assembly: AssemblyDescription("")] 10 | [assembly: AssemblyConfiguration("")] 11 | [assembly: AssemblyCompany("")] 12 | [assembly: AssemblyProduct("DNP3TestHarness")] 13 | [assembly: AssemblyCopyright("Copyright © 2014")] 14 | [assembly: AssemblyTrademark("")] 15 | [assembly: AssemblyCulture("")] 16 | 17 | // Setting ComVisible to false makes the types in this assembly not visible 18 | // to COM components. If you need to access a type in this assembly from 19 | // COM, set the ComVisible attribute to true on that type. 20 | [assembly: ComVisible(false)] 21 | 22 | // The following GUID is for the ID of the typelib if this project is exposed to COM 23 | [assembly: Guid("5ba0da4e-661a-429c-9060-c3a33f21d0b3")] 24 | 25 | // Version information for an assembly consists of the following four values: 26 | // 27 | // Major Version 28 | // Minor Version 29 | // Build Number 30 | // Revision 31 | // 32 | // You can specify all the values or you can default the Build and Revision Numbers 33 | // by using the '*' as shown below: 34 | // [assembly: AssemblyVersion("1.0.*")] 35 | [assembly: AssemblyVersion("1.0.0.0")] 36 | [assembly: AssemblyFileVersion("1.0.0.0")] 37 | -------------------------------------------------------------------------------- /simulator/Simulator/Properties/DataSources/MeasurementPoco.datasource: -------------------------------------------------------------------------------- 1 |  2 | 8 | 9 | Automatak.DNP3.Simulator.MeasurementPoco, DNP3TestHarness, Version=1.0.0.0, Culture=neutral, PublicKeyToken=null 10 | -------------------------------------------------------------------------------- /simulator/Simulator/Properties/Settings.Designer.cs: -------------------------------------------------------------------------------- 1 | //------------------------------------------------------------------------------ 2 | // 3 | // This code was generated by a tool. 4 | // Runtime Version:4.0.30319.18444 5 | // 6 | // Changes to this file may cause incorrect behavior and will be lost if 7 | // the code is regenerated. 8 | // 9 | //------------------------------------------------------------------------------ 10 | 11 | namespace Automatak.Simulator.Properties { 12 | 13 | 14 | [global::System.Runtime.CompilerServices.CompilerGeneratedAttribute()] 15 | [global::System.CodeDom.Compiler.GeneratedCodeAttribute("Microsoft.VisualStudio.Editors.SettingsDesigner.SettingsSingleFileGenerator", "12.0.0.0")] 16 | internal sealed partial class Settings : global::System.Configuration.ApplicationSettingsBase { 17 | 18 | private static Settings defaultInstance = ((Settings)(global::System.Configuration.ApplicationSettingsBase.Synchronized(new Settings()))); 19 | 20 | public static Settings Default { 21 | get { 22 | return defaultInstance; 23 | } 24 | } 25 | } 26 | } 27 | -------------------------------------------------------------------------------- /simulator/Simulator/Properties/Settings.settings: -------------------------------------------------------------------------------- 1 |  2 | 3 | 4 | 5 | 6 | 7 | 8 | -------------------------------------------------------------------------------- /simulator/Simulator/Simulator.csproj.user: -------------------------------------------------------------------------------- 1 |  2 | 3 | 4 | true 5 | -nosplash 6 | 7 | 8 | true 9 | 10 | -------------------------------------------------------------------------------- /simulator/Simulator/SimulatorForm.cs.DSN: -------------------------------------------------------------------------------- 1 | // This is Database Source Name File for ODBC connection to a company file. 2 | // Do not delete this file yourself. ODBC connection may not 3 | // operate correctly IF you manually delete this file. 4 | [ODBC] 5 | DRIVER=SQL Anywhere 6 | Compress=NO 7 | DisableMultiRowFetch=NO 8 | Debug=NO 9 | Integrated=NO 10 | AutoStop=NO 11 | CommLinks=TCPIP{HOST=fe80::38ed:81d7:5220:e28b%17:10180 12 | ServerName=QB_jadamcrain-PC_21 13 | -------------------------------------------------------------------------------- /simulator/Simulator/SimulatorForm.cs.ND: -------------------------------------------------------------------------------- 1 | // This is QuickBooks configuration File. It exists while users are connected 2 | // to a company file. Do not delete this file yourself. QuickBooks may not 3 | // operate correctly if you manually delete this file. 4 | [NetConnect] 5 | ServerIp=fe80::38ed:81d7:5220:e28b%17 6 | EngineName=QB_jadamcrain-PC_18 7 | ServerPort=10180 8 | FilePath=C:\Users\jadamcrain\Documents\GitHub\dnp3\dotnet\simulator\Simulator\SimulatorForm.cs 9 | ServerMode=1 10 | -------------------------------------------------------------------------------- /simulator/Simulator/TreeNodeCallbcks.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using System.Linq; 4 | using System.Text; 5 | using System.Threading.Tasks; 6 | 7 | using System.Drawing; 8 | using System.Windows.Forms; 9 | 10 | using Automatak.Simulator.API; 11 | 12 | namespace Automatak.Simulator 13 | { 14 | class TreeNodeCallbacks : ISimulatorNodeCallbacks 15 | { 16 | readonly Control control; 17 | 18 | public TreeNodeCallbacks(Control control) 19 | { 20 | this.control = control; 21 | this.defaultColor = node.ForeColor; 22 | } 23 | 24 | public readonly TreeNode node = new TreeNode("temp"); 25 | public readonly Color defaultColor; 26 | 27 | void ISimulatorNodeCallbacks.ChangeState(NodeState state) 28 | { 29 | if (control.InvokeRequired) 30 | { 31 | ISimulatorNodeCallbacks temp = this; 32 | control.BeginInvoke(new Action(() => { temp.ChangeState(state); })); 33 | } 34 | else 35 | { 36 | node.ForeColor = GetForeColor(state); 37 | node.BackColor = GetBackColor(state); 38 | } 39 | } 40 | 41 | void ISimulatorNodeCallbacks.ChangeImage(int index) 42 | { 43 | if (control.InvokeRequired) 44 | { 45 | ISimulatorNodeCallbacks temp = this; 46 | control.BeginInvoke(new Action(() => { temp.ChangeImage(index); })); 47 | } 48 | else 49 | { 50 | node.ImageIndex = index; 51 | node.SelectedImageIndex = index; 52 | } 53 | } 54 | 55 | Color GetForeColor(NodeState state) 56 | { 57 | switch (state) 58 | { 59 | case (NodeState.Active): 60 | return Color.Green; 61 | case (NodeState.Failed): 62 | return Color.Red; 63 | case (NodeState.Waiting): 64 | return Color.White; 65 | default: 66 | return defaultColor; 67 | } 68 | } 69 | 70 | Color GetBackColor(NodeState state) 71 | { 72 | switch (state) 73 | { 74 | case (NodeState.Waiting): 75 | return Color.Black; 76 | default: 77 | return Color.White; 78 | } 79 | } 80 | 81 | } 82 | } 83 | -------------------------------------------------------------------------------- /simulator/Simulator/automatak.ico: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/dnp3/dnp3-simulator/10c9dcb61e683e2e80ae6cc4e6a9af6228438d9d/simulator/Simulator/automatak.ico -------------------------------------------------------------------------------- /simulator/Simulator/resources/add.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/dnp3/dnp3-simulator/10c9dcb61e683e2e80ae6cc4e6a9af6228438d9d/simulator/Simulator/resources/add.png -------------------------------------------------------------------------------- /simulator/Simulator/resources/folder_diskette.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/dnp3/dnp3-simulator/10c9dcb61e683e2e80ae6cc4e6a9af6228438d9d/simulator/Simulator/resources/folder_diskette.png -------------------------------------------------------------------------------- /simulator/Simulator/resources/info.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/dnp3/dnp3-simulator/10c9dcb61e683e2e80ae6cc4e6a9af6228438d9d/simulator/Simulator/resources/info.png -------------------------------------------------------------------------------- /simulator/Simulator/resources/opendnp3.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/dnp3/dnp3-simulator/10c9dcb61e683e2e80ae6cc4e6a9af6228438d9d/simulator/Simulator/resources/opendnp3.png -------------------------------------------------------------------------------- /simulator/Simulator/resources/satellite_dish_add.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/dnp3/dnp3-simulator/10c9dcb61e683e2e80ae6cc4e6a9af6228438d9d/simulator/Simulator/resources/satellite_dish_add.png -------------------------------------------------------------------------------- /simulator/SimulatorAPI/ISimulatorNode.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using System.Linq; 4 | using System.Text; 5 | using System.Threading.Tasks; 6 | 7 | using System.Drawing; 8 | 9 | namespace Automatak.Simulator.API 10 | { 11 | public enum NodeState 12 | { 13 | Inactive, 14 | Waiting, 15 | Active, 16 | Failed 17 | } 18 | 19 | public interface ISimulatorNodeCallbacks 20 | { 21 | 22 | 23 | void ChangeImage(int index); 24 | 25 | void ChangeState(NodeState state); 26 | } 27 | 28 | public interface ISimulatorNodeAction 29 | { 30 | string DisplayName 31 | { 32 | get; 33 | } 34 | 35 | void Invoke(); 36 | } 37 | 38 | public interface ISimulatorNodeFactory 39 | { 40 | string DisplayName 41 | { 42 | get; 43 | } 44 | 45 | ISimulatorNode Create(ISimulatorNodeCallbacks callbacks); 46 | } 47 | 48 | public interface ISimulatorNode 49 | { 50 | void Remove(); 51 | 52 | string Alias 53 | { 54 | get; 55 | } 56 | 57 | IEnumerable Metrics 58 | { 59 | get; 60 | } 61 | 62 | String DisplayName 63 | { 64 | get; 65 | } 66 | 67 | IEnumerable Children 68 | { 69 | get; 70 | } 71 | 72 | IEnumerable Actions 73 | { 74 | get; 75 | } 76 | } 77 | 78 | } 79 | -------------------------------------------------------------------------------- /simulator/SimulatorAPI/ISimulatorPlugin.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using System.Linq; 4 | using System.Text; 5 | using System.Threading.Tasks; 6 | using System.Windows.Forms; 7 | 8 | using System.Drawing; 9 | 10 | namespace Automatak.Simulator.API 11 | { 12 | public interface ISimulatorPlugin 13 | { 14 | Image PluginImage 15 | { 16 | get; 17 | } 18 | 19 | ImageList NodeImageList 20 | { 21 | get; 22 | } 23 | 24 | String RootDisplayName 25 | { 26 | get; 27 | } 28 | 29 | String UniqueId 30 | { 31 | get; 32 | } 33 | 34 | ISimulatorNode Create(ISimulatorNodeCallbacks callbacks); 35 | } 36 | } 37 | -------------------------------------------------------------------------------- /simulator/SimulatorAPI/ISimulatorPluginFactory.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using System.Linq; 4 | using System.Text; 5 | using System.Threading.Tasks; 6 | 7 | using Automatak.Simulator.Commons; 8 | 9 | namespace Automatak.Simulator.API 10 | { 11 | public interface ISimulatorPluginFactory 12 | { 13 | ISimulatorPlugin Create(ILog log); 14 | } 15 | } 16 | -------------------------------------------------------------------------------- /simulator/SimulatorAPI/Metric.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using System.Linq; 4 | using System.Text; 5 | 6 | namespace Automatak.Simulator.API 7 | { 8 | public class Metric 9 | { 10 | readonly String id; 11 | readonly String value; 12 | 13 | public Metric(String id, String value) 14 | { 15 | this.id = id; 16 | this.value = value; 17 | } 18 | 19 | public String Id 20 | { 21 | get 22 | { 23 | return id; 24 | } 25 | } 26 | 27 | public String Value 28 | { 29 | get 30 | { 31 | return value; 32 | } 33 | } 34 | } 35 | } 36 | -------------------------------------------------------------------------------- /simulator/SimulatorAPI/ModuleAPI.csproj: -------------------------------------------------------------------------------- 1 |  2 | 3 | 4 | 5 | Debug 6 | AnyCPU 7 | {6A19318B-8CC5-4BC8-8E80-412180C420A5} 8 | Library 9 | Properties 10 | Automatak.Simulator.API 11 | SimulatorAPI 12 | v4.5 13 | 512 14 | 15 | 16 | 17 | true 18 | full 19 | false 20 | bin\Debug\ 21 | DEBUG;TRACE 22 | prompt 23 | 4 24 | false 25 | 26 | 27 | pdbonly 28 | true 29 | bin\Release\ 30 | TRACE 31 | prompt 32 | 4 33 | false 34 | 35 | 36 | true 37 | bin\x86\Debug\ 38 | DEBUG;TRACE 39 | full 40 | x86 41 | prompt 42 | MinimumRecommendedRules.ruleset 43 | 44 | 45 | bin\x86\Release\ 46 | TRACE 47 | true 48 | pdbonly 49 | x86 50 | prompt 51 | MinimumRecommendedRules.ruleset 52 | 53 | 54 | 55 | 56 | 57 | 58 | 59 | 60 | 61 | 62 | 63 | 64 | 65 | 66 | 67 | Code 68 | 69 | 70 | 71 | 72 | 73 | 74 | 75 | {67c09f7a-3dd4-4c02-aa3b-6882fb6ea816} 76 | Commons 77 | 78 | 79 | 80 | 87 | -------------------------------------------------------------------------------- /simulator/SimulatorAPI/Properties/AssemblyInfo.cs: -------------------------------------------------------------------------------- 1 | using System.Reflection; 2 | using System.Runtime.CompilerServices; 3 | using System.Runtime.InteropServices; 4 | 5 | // General Information about an assembly is controlled through the following 6 | // set of attributes. Change these attribute values to modify the information 7 | // associated with an assembly. 8 | [assembly: AssemblyTitle("DNP3SimulatorAPI")] 9 | [assembly: AssemblyDescription("")] 10 | [assembly: AssemblyConfiguration("")] 11 | [assembly: AssemblyCompany("")] 12 | [assembly: AssemblyProduct("DNP3SimulatorAPI")] 13 | [assembly: AssemblyCopyright("Copyright © 2014")] 14 | [assembly: AssemblyTrademark("")] 15 | [assembly: AssemblyCulture("")] 16 | 17 | // Setting ComVisible to false makes the types in this assembly not visible 18 | // to COM components. If you need to access a type in this assembly from 19 | // COM, set the ComVisible attribute to true on that type. 20 | [assembly: ComVisible(false)] 21 | 22 | // The following GUID is for the ID of the typelib if this project is exposed to COM 23 | [assembly: Guid("9c46a30c-e41d-48bf-abbe-c5a6ecf3b972")] 24 | 25 | // Version information for an assembly consists of the following four values: 26 | // 27 | // Major Version 28 | // Minor Version 29 | // Build Number 30 | // Revision 31 | // 32 | // You can specify all the values or you can default the Build and Revision Numbers 33 | // by using the '*' as shown below: 34 | // [assembly: AssemblyVersion("1.0.*")] 35 | [assembly: AssemblyVersion("1.0.0.0")] 36 | [assembly: AssemblyFileVersion("1.0.0.0")] 37 | -------------------------------------------------------------------------------- /simulator/SimulatorUI/App.config: -------------------------------------------------------------------------------- 1 |  2 | 3 | 4 | 5 | 6 | -------------------------------------------------------------------------------- /simulator/SimulatorUI/LogControl.Designer.cs: -------------------------------------------------------------------------------- 1 | namespace Automatak.Simulator.UI 2 | { 3 | partial class LogControl 4 | { 5 | /// 6 | /// Required designer variable. 7 | /// 8 | private System.ComponentModel.IContainer components = null; 9 | 10 | /// 11 | /// Clean up any resources being used. 12 | /// 13 | /// true if managed resources should be disposed; otherwise, false. 14 | protected override void Dispose(bool disposing) 15 | { 16 | if (disposing && (components != null)) 17 | { 18 | components.Dispose(); 19 | } 20 | base.Dispose(disposing); 21 | } 22 | 23 | #region Component Designer generated code 24 | 25 | /// 26 | /// Required method for Designer support - do not modify 27 | /// the contents of this method with the code editor. 28 | /// 29 | private void InitializeComponent() 30 | { 31 | this.SuspendLayout(); 32 | // 33 | // LogControl 34 | // 35 | this.AutoScaleDimensions = new System.Drawing.SizeF(6F, 13F); 36 | this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Font; 37 | this.AutoScroll = true; 38 | this.AutoScrollMinSize = new System.Drawing.Size(100, 100); 39 | this.BackColor = System.Drawing.SystemColors.ControlLightLight; 40 | this.BorderStyle = System.Windows.Forms.BorderStyle.Fixed3D; 41 | this.DoubleBuffered = true; 42 | this.Margin = new System.Windows.Forms.Padding(0); 43 | this.MinimumSize = new System.Drawing.Size(500, 150); 44 | this.Name = "LogControl"; 45 | this.Size = new System.Drawing.Size(819, 527); 46 | this.ResumeLayout(false); 47 | 48 | } 49 | 50 | #endregion 51 | 52 | 53 | 54 | } 55 | } 56 | -------------------------------------------------------------------------------- /simulator/SimulatorUI/LogFileControl.Designer.cs: -------------------------------------------------------------------------------- 1 | namespace Automatak.Simulator.UI 2 | { 3 | partial class LogFileControl 4 | { 5 | /// 6 | /// Required designer variable. 7 | /// 8 | private System.ComponentModel.IContainer components = null; 9 | 10 | /// 11 | /// Clean up any resources being used. 12 | /// 13 | /// true if managed resources should be disposed; otherwise, false. 14 | protected override void Dispose(bool disposing) 15 | { 16 | if (disposing && (components != null)) 17 | { 18 | components.Dispose(); 19 | } 20 | base.Dispose(disposing); 21 | } 22 | 23 | #region Component Designer generated code 24 | 25 | /// 26 | /// Required method for Designer support - do not modify 27 | /// the contents of this method with the code editor. 28 | /// 29 | private void InitializeComponent() 30 | { 31 | this.components = new System.ComponentModel.Container(); 32 | System.ComponentModel.ComponentResourceManager resources = new System.ComponentModel.ComponentResourceManager(typeof(LogFileControl)); 33 | this.buttonBrowse = new System.Windows.Forms.Button(); 34 | this.imageList = new System.Windows.Forms.ImageList(this.components); 35 | this.buttonStop = new System.Windows.Forms.Button(); 36 | this.SuspendLayout(); 37 | // 38 | // buttonBrowse 39 | // 40 | this.buttonBrowse.AutoSizeMode = System.Windows.Forms.AutoSizeMode.GrowAndShrink; 41 | this.buttonBrowse.ImageAlign = System.Drawing.ContentAlignment.MiddleLeft; 42 | this.buttonBrowse.ImageIndex = 0; 43 | this.buttonBrowse.ImageList = this.imageList; 44 | this.buttonBrowse.Location = new System.Drawing.Point(0, 0); 45 | this.buttonBrowse.Name = "buttonBrowse"; 46 | this.buttonBrowse.Size = new System.Drawing.Size(42, 38); 47 | this.buttonBrowse.TabIndex = 0; 48 | this.buttonBrowse.UseVisualStyleBackColor = true; 49 | this.buttonBrowse.Click += new System.EventHandler(this.buttonBrowse_Click); 50 | // 51 | // imageList 52 | // 53 | this.imageList.ImageStream = ((System.Windows.Forms.ImageListStreamer)(resources.GetObject("imageList.ImageStream"))); 54 | this.imageList.TransparentColor = System.Drawing.Color.Transparent; 55 | this.imageList.Images.SetKeyName(0, "folder.png"); 56 | this.imageList.Images.SetKeyName(1, "cross.png"); 57 | // 58 | // buttonStop 59 | // 60 | this.buttonStop.ImageAlign = System.Drawing.ContentAlignment.MiddleLeft; 61 | this.buttonStop.ImageIndex = 1; 62 | this.buttonStop.ImageList = this.imageList; 63 | this.buttonStop.Location = new System.Drawing.Point(44, 0); 64 | this.buttonStop.Name = "buttonStop"; 65 | this.buttonStop.Size = new System.Drawing.Size(42, 38); 66 | this.buttonStop.TabIndex = 3; 67 | this.buttonStop.UseVisualStyleBackColor = true; 68 | this.buttonStop.Click += new System.EventHandler(this.buttonStop_Click); 69 | // 70 | // LogFileControl 71 | // 72 | this.AutoScaleDimensions = new System.Drawing.SizeF(6F, 13F); 73 | this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Font; 74 | this.AutoSizeMode = System.Windows.Forms.AutoSizeMode.GrowAndShrink; 75 | this.Controls.Add(this.buttonStop); 76 | this.Controls.Add(this.buttonBrowse); 77 | this.Margin = new System.Windows.Forms.Padding(0); 78 | this.Name = "LogFileControl"; 79 | this.Size = new System.Drawing.Size(89, 39); 80 | this.ResumeLayout(false); 81 | 82 | } 83 | 84 | #endregion 85 | 86 | private System.Windows.Forms.Button buttonBrowse; 87 | private System.Windows.Forms.ImageList imageList; 88 | private System.Windows.Forms.Button buttonStop; 89 | } 90 | } 91 | -------------------------------------------------------------------------------- /simulator/SimulatorUI/LogFileControl.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using System.ComponentModel; 4 | using System.Drawing; 5 | using System.Data; 6 | using System.Linq; 7 | using System.Text; 8 | using System.Threading.Tasks; 9 | using System.Windows.Forms; 10 | 11 | using Automatak.Simulator.Commons; 12 | 13 | namespace Automatak.Simulator.UI 14 | { 15 | public partial class LogFileControl : UserControl 16 | { 17 | LogToFile log = null; 18 | bool enabled = false; 19 | 20 | public LogFileControl() 21 | { 22 | InitializeComponent(); 23 | 24 | var tooltip1 = new System.Windows.Forms.ToolTip(); 25 | tooltip1.SetToolTip(this.buttonBrowse, "Browse for a log file"); 26 | 27 | var tooltip2 = new System.Windows.Forms.ToolTip(); 28 | tooltip2.SetToolTip(this.buttonStop, "Stop logging to file"); 29 | 30 | 31 | this.CheckState(); 32 | } 33 | 34 | public LogToFile FileLogger 35 | { 36 | set 37 | { 38 | log = value; 39 | this.CheckState(); 40 | } 41 | } 42 | 43 | void CheckState() 44 | { 45 | if (log == null) 46 | { 47 | this.buttonStop.Enabled = false; 48 | this.buttonBrowse.Enabled = false; 49 | } 50 | else 51 | { 52 | if (enabled) 53 | { 54 | this.buttonStop.Enabled = true; 55 | this.buttonBrowse.Enabled = false; 56 | } 57 | else 58 | { 59 | this.buttonStop.Enabled = false; 60 | this.buttonBrowse.Enabled = true; 61 | } 62 | } 63 | } 64 | 65 | private void buttonBrowse_Click(object sender, EventArgs e) 66 | { 67 | using (var dialog = new OpenFileDialog()) 68 | { 69 | dialog.Title = "Open or create a log file"; 70 | dialog.Multiselect = false; 71 | dialog.Filter = "Text files (*.txt)|*.txt"; 72 | if(dialog.ShowDialog() == DialogResult.OK) 73 | { 74 | this.enabled = true; 75 | log.LogFilePath = dialog.FileName; 76 | log.Enabled = true; 77 | this.CheckState(); 78 | } 79 | } 80 | } 81 | 82 | private void buttonStop_Click(object sender, EventArgs e) 83 | { 84 | this.enabled = false; 85 | log.Enabled = false; 86 | this.CheckState(); 87 | } 88 | 89 | } 90 | } 91 | -------------------------------------------------------------------------------- /simulator/SimulatorUI/Properties/AssemblyInfo.cs: -------------------------------------------------------------------------------- 1 | using System.Reflection; 2 | using System.Runtime.CompilerServices; 3 | using System.Runtime.InteropServices; 4 | 5 | // General Information about an assembly is controlled through the following 6 | // set of attributes. Change these attribute values to modify the information 7 | // associated with an assembly. 8 | [assembly: AssemblyTitle("SimulatorUI")] 9 | [assembly: AssemblyDescription("")] 10 | [assembly: AssemblyConfiguration("")] 11 | [assembly: AssemblyCompany("")] 12 | [assembly: AssemblyProduct("SimulatorUI")] 13 | [assembly: AssemblyCopyright("Copyright © 2014")] 14 | [assembly: AssemblyTrademark("")] 15 | [assembly: AssemblyCulture("")] 16 | 17 | // Setting ComVisible to false makes the types in this assembly not visible 18 | // to COM components. If you need to access a type in this assembly from 19 | // COM, set the ComVisible attribute to true on that type. 20 | [assembly: ComVisible(false)] 21 | 22 | // The following GUID is for the ID of the typelib if this project is exposed to COM 23 | [assembly: Guid("15715a1c-a32b-46e0-bbcb-ea6412c1c5bf")] 24 | 25 | // Version information for an assembly consists of the following four values: 26 | // 27 | // Major Version 28 | // Minor Version 29 | // Build Number 30 | // Revision 31 | // 32 | // You can specify all the values or you can default the Build and Revision Numbers 33 | // by using the '*' as shown below: 34 | // [assembly: AssemblyVersion("1.0.*")] 35 | [assembly: AssemblyVersion("1.0.0.0")] 36 | [assembly: AssemblyFileVersion("1.0.0.0")] 37 | -------------------------------------------------------------------------------- /simulator/SimulatorUI/Properties/Resources.Designer.cs: -------------------------------------------------------------------------------- 1 | //------------------------------------------------------------------------------ 2 | // 3 | // This code was generated by a tool. 4 | // Runtime Version:4.0.30319.18444 5 | // 6 | // Changes to this file may cause incorrect behavior and will be lost if 7 | // the code is regenerated. 8 | // 9 | //------------------------------------------------------------------------------ 10 | 11 | namespace Automatak.Simulator.UI.Properties { 12 | using System; 13 | 14 | 15 | /// 16 | /// A strongly-typed resource class, for looking up localized strings, etc. 17 | /// 18 | // This class was auto-generated by the StronglyTypedResourceBuilder 19 | // class via a tool like ResGen or Visual Studio. 20 | // To add or remove a member, edit your .ResX file then rerun ResGen 21 | // with the /str option, or rebuild your VS project. 22 | [global::System.CodeDom.Compiler.GeneratedCodeAttribute("System.Resources.Tools.StronglyTypedResourceBuilder", "4.0.0.0")] 23 | [global::System.Diagnostics.DebuggerNonUserCodeAttribute()] 24 | [global::System.Runtime.CompilerServices.CompilerGeneratedAttribute()] 25 | internal class Resources { 26 | 27 | private static global::System.Resources.ResourceManager resourceMan; 28 | 29 | private static global::System.Globalization.CultureInfo resourceCulture; 30 | 31 | [global::System.Diagnostics.CodeAnalysis.SuppressMessageAttribute("Microsoft.Performance", "CA1811:AvoidUncalledPrivateCode")] 32 | internal Resources() { 33 | } 34 | 35 | /// 36 | /// Returns the cached ResourceManager instance used by this class. 37 | /// 38 | [global::System.ComponentModel.EditorBrowsableAttribute(global::System.ComponentModel.EditorBrowsableState.Advanced)] 39 | internal static global::System.Resources.ResourceManager ResourceManager { 40 | get { 41 | if (object.ReferenceEquals(resourceMan, null)) { 42 | global::System.Resources.ResourceManager temp = new global::System.Resources.ResourceManager("Automatak.Simulator.UI.Properties.Resources", typeof(Resources).Assembly); 43 | resourceMan = temp; 44 | } 45 | return resourceMan; 46 | } 47 | } 48 | 49 | /// 50 | /// Overrides the current thread's CurrentUICulture property for all 51 | /// resource lookups using this strongly typed resource class. 52 | /// 53 | [global::System.ComponentModel.EditorBrowsableAttribute(global::System.ComponentModel.EditorBrowsableState.Advanced)] 54 | internal static global::System.Globalization.CultureInfo Culture { 55 | get { 56 | return resourceCulture; 57 | } 58 | set { 59 | resourceCulture = value; 60 | } 61 | } 62 | 63 | /// 64 | /// Looks up a localized resource of type System.Drawing.Bitmap. 65 | /// 66 | internal static System.Drawing.Bitmap folder { 67 | get { 68 | object obj = ResourceManager.GetObject("folder", resourceCulture); 69 | return ((System.Drawing.Bitmap)(obj)); 70 | } 71 | } 72 | } 73 | } 74 | -------------------------------------------------------------------------------- /simulator/SimulatorUI/Properties/Settings.Designer.cs: -------------------------------------------------------------------------------- 1 | //------------------------------------------------------------------------------ 2 | // 3 | // This code was generated by a tool. 4 | // Runtime Version:4.0.30319.18444 5 | // 6 | // Changes to this file may cause incorrect behavior and will be lost if 7 | // the code is regenerated. 8 | // 9 | //------------------------------------------------------------------------------ 10 | 11 | namespace Automatak.Simulator.UI.Properties { 12 | 13 | 14 | [global::System.Runtime.CompilerServices.CompilerGeneratedAttribute()] 15 | [global::System.CodeDom.Compiler.GeneratedCodeAttribute("Microsoft.VisualStudio.Editors.SettingsDesigner.SettingsSingleFileGenerator", "12.0.0.0")] 16 | internal sealed partial class Settings : global::System.Configuration.ApplicationSettingsBase { 17 | 18 | private static Settings defaultInstance = ((Settings)(global::System.Configuration.ApplicationSettingsBase.Synchronized(new Settings()))); 19 | 20 | public static Settings Default { 21 | get { 22 | return defaultInstance; 23 | } 24 | } 25 | } 26 | } 27 | -------------------------------------------------------------------------------- /simulator/SimulatorUI/Properties/Settings.settings: -------------------------------------------------------------------------------- 1 |  2 | 3 | 4 | 5 | 6 | 7 | 8 | -------------------------------------------------------------------------------- /simulator/SimulatorUI/resources/arrow_down.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/dnp3/dnp3-simulator/10c9dcb61e683e2e80ae6cc4e6a9af6228438d9d/simulator/SimulatorUI/resources/arrow_down.png -------------------------------------------------------------------------------- /simulator/SimulatorUI/resources/arrow_up.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/dnp3/dnp3-simulator/10c9dcb61e683e2e80ae6cc4e6a9af6228438d9d/simulator/SimulatorUI/resources/arrow_up.png -------------------------------------------------------------------------------- /simulator/SimulatorUI/resources/clipboard_diskette.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/dnp3/dnp3-simulator/10c9dcb61e683e2e80ae6cc4e6a9af6228438d9d/simulator/SimulatorUI/resources/clipboard_diskette.png -------------------------------------------------------------------------------- /simulator/SimulatorUI/resources/cross.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/dnp3/dnp3-simulator/10c9dcb61e683e2e80ae6cc4e6a9af6228438d9d/simulator/SimulatorUI/resources/cross.png -------------------------------------------------------------------------------- /simulator/SimulatorUI/resources/edit_config.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/dnp3/dnp3-simulator/10c9dcb61e683e2e80ae6cc4e6a9af6228438d9d/simulator/SimulatorUI/resources/edit_config.png -------------------------------------------------------------------------------- /simulator/SimulatorUI/resources/folder.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/dnp3/dnp3-simulator/10c9dcb61e683e2e80ae6cc4e6a9af6228438d9d/simulator/SimulatorUI/resources/folder.png -------------------------------------------------------------------------------- /simulator/SimulatorUI/resources/folder_diskette.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/dnp3/dnp3-simulator/10c9dcb61e683e2e80ae6cc4e6a9af6228438d9d/simulator/SimulatorUI/resources/folder_diskette.png -------------------------------------------------------------------------------- /simulator/SimulatorUI/resources/folder_down.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/dnp3/dnp3-simulator/10c9dcb61e683e2e80ae6cc4e6a9af6228438d9d/simulator/SimulatorUI/resources/folder_down.png -------------------------------------------------------------------------------- /simulator/SimulatorUI/resources/gear_pencil.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/dnp3/dnp3-simulator/10c9dcb61e683e2e80ae6cc4e6a9af6228438d9d/simulator/SimulatorUI/resources/gear_pencil.png -------------------------------------------------------------------------------- /simulator/SimulatorUI/resources/info.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/dnp3/dnp3-simulator/10c9dcb61e683e2e80ae6cc4e6a9af6228438d9d/simulator/SimulatorUI/resources/info.png -------------------------------------------------------------------------------- /simulator/SimulatorUI/resources/log_cross.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/dnp3/dnp3-simulator/10c9dcb61e683e2e80ae6cc4e6a9af6228438d9d/simulator/SimulatorUI/resources/log_cross.png -------------------------------------------------------------------------------- /simulator/SimulatorUI/resources/network_monitor.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/dnp3/dnp3-simulator/10c9dcb61e683e2e80ae6cc4e6a9af6228438d9d/simulator/SimulatorUI/resources/network_monitor.png -------------------------------------------------------------------------------- /simulator/SimulatorUI/resources/pause.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/dnp3/dnp3-simulator/10c9dcb61e683e2e80ae6cc4e6a9af6228438d9d/simulator/SimulatorUI/resources/pause.png -------------------------------------------------------------------------------- /simulator/SimulatorUI/resources/play.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/dnp3/dnp3-simulator/10c9dcb61e683e2e80ae6cc4e6a9af6228438d9d/simulator/SimulatorUI/resources/play.png -------------------------------------------------------------------------------- /simulator/SimulatorUI/resources/satellite_dish.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/dnp3/dnp3-simulator/10c9dcb61e683e2e80ae6cc4e6a9af6228438d9d/simulator/SimulatorUI/resources/satellite_dish.png -------------------------------------------------------------------------------- /simulator/SimulatorUI/resources/satellite_dish_add.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/dnp3/dnp3-simulator/10c9dcb61e683e2e80ae6cc4e6a9af6228438d9d/simulator/SimulatorUI/resources/satellite_dish_add.png -------------------------------------------------------------------------------- /simulator/images/add.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/dnp3/dnp3-simulator/10c9dcb61e683e2e80ae6cc4e6a9af6228438d9d/simulator/images/add.png -------------------------------------------------------------------------------- /simulator/images/arrow_down.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/dnp3/dnp3-simulator/10c9dcb61e683e2e80ae6cc4e6a9af6228438d9d/simulator/images/arrow_down.png -------------------------------------------------------------------------------- /simulator/images/arrow_up.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/dnp3/dnp3-simulator/10c9dcb61e683e2e80ae6cc4e6a9af6228438d9d/simulator/images/arrow_up.png -------------------------------------------------------------------------------- /simulator/images/automatak.ico: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/dnp3/dnp3-simulator/10c9dcb61e683e2e80ae6cc4e6a9af6228438d9d/simulator/images/automatak.ico -------------------------------------------------------------------------------- /simulator/images/clipboard_diskette.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/dnp3/dnp3-simulator/10c9dcb61e683e2e80ae6cc4e6a9af6228438d9d/simulator/images/clipboard_diskette.png -------------------------------------------------------------------------------- /simulator/images/clipboard_pencil.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/dnp3/dnp3-simulator/10c9dcb61e683e2e80ae6cc4e6a9af6228438d9d/simulator/images/clipboard_pencil.png -------------------------------------------------------------------------------- /simulator/images/cross.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/dnp3/dnp3-simulator/10c9dcb61e683e2e80ae6cc4e6a9af6228438d9d/simulator/images/cross.png -------------------------------------------------------------------------------- /simulator/images/edit_config.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/dnp3/dnp3-simulator/10c9dcb61e683e2e80ae6cc4e6a9af6228438d9d/simulator/images/edit_config.png -------------------------------------------------------------------------------- /simulator/images/folder.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/dnp3/dnp3-simulator/10c9dcb61e683e2e80ae6cc4e6a9af6228438d9d/simulator/images/folder.png -------------------------------------------------------------------------------- /simulator/images/folder_diskette.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/dnp3/dnp3-simulator/10c9dcb61e683e2e80ae6cc4e6a9af6228438d9d/simulator/images/folder_diskette.png -------------------------------------------------------------------------------- /simulator/images/folder_down.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/dnp3/dnp3-simulator/10c9dcb61e683e2e80ae6cc4e6a9af6228438d9d/simulator/images/folder_down.png -------------------------------------------------------------------------------- /simulator/images/gear_pencil.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/dnp3/dnp3-simulator/10c9dcb61e683e2e80ae6cc4e6a9af6228438d9d/simulator/images/gear_pencil.png -------------------------------------------------------------------------------- /simulator/images/info.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/dnp3/dnp3-simulator/10c9dcb61e683e2e80ae6cc4e6a9af6228438d9d/simulator/images/info.png -------------------------------------------------------------------------------- /simulator/images/log_cross.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/dnp3/dnp3-simulator/10c9dcb61e683e2e80ae6cc4e6a9af6228438d9d/simulator/images/log_cross.png -------------------------------------------------------------------------------- /simulator/images/network_monitor.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/dnp3/dnp3-simulator/10c9dcb61e683e2e80ae6cc4e6a9af6228438d9d/simulator/images/network_monitor.png -------------------------------------------------------------------------------- /simulator/images/opendnp3.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/dnp3/dnp3-simulator/10c9dcb61e683e2e80ae6cc4e6a9af6228438d9d/simulator/images/opendnp3.png -------------------------------------------------------------------------------- /simulator/images/pause.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/dnp3/dnp3-simulator/10c9dcb61e683e2e80ae6cc4e6a9af6228438d9d/simulator/images/pause.png -------------------------------------------------------------------------------- /simulator/images/play.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/dnp3/dnp3-simulator/10c9dcb61e683e2e80ae6cc4e6a9af6228438d9d/simulator/images/play.png -------------------------------------------------------------------------------- /simulator/images/satellite_dish.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/dnp3/dnp3-simulator/10c9dcb61e683e2e80ae6cc4e6a9af6228438d9d/simulator/images/satellite_dish.png -------------------------------------------------------------------------------- /simulator/images/satellite_dish_add.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/dnp3/dnp3-simulator/10c9dcb61e683e2e80ae6cc4e6a9af6228438d9d/simulator/images/satellite_dish_add.png -------------------------------------------------------------------------------- /simulator/images/send_container.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/dnp3/dnp3-simulator/10c9dcb61e683e2e80ae6cc4e6a9af6228438d9d/simulator/images/send_container.png --------------------------------------------------------------------------------