├── .gitignore
├── LICENSE
├── ProfinetTools.Gui
├── App.xaml
├── App.xaml.cs
├── GuiModuleCatalog.cs
├── ProfinetTools.Gui.csproj
├── Properties
│ └── AssemblyInfo.cs
├── Resources
│ └── logo.png
├── ViewModelLocator.cs
├── ViewModels
│ ├── AdaptersViewModel.cs
│ ├── DevicesViewModel.cs
│ ├── MainViewModel.cs
│ ├── SettingsViewModel.cs
│ └── ViewModelBase.cs
├── Views
│ ├── AdaptersView.xaml
│ ├── AdaptersView.xaml.cs
│ ├── DevicesView.xaml
│ ├── DevicesView.xaml.cs
│ ├── MainWindow.xaml
│ ├── MainWindow.xaml.cs
│ ├── SettingsView.xaml
│ └── SettingsView.xaml.cs
└── packages.config
├── ProfinetTools.Interfaces
├── Commons
│ ├── IInitializable.cs
│ ├── IInstanceCreator.cs
│ ├── IViewModel.cs
│ ├── IViewModelFactory.cs
│ └── NotifyPropertyChanged.cs
├── Extensions
│ └── DisposableExtensions.cs
├── Models
│ ├── Device.cs
│ └── SaveResult.cs
├── ProfinetTools.Interfaces.csproj
├── Properties
│ └── AssemblyInfo.cs
├── Serialization
│ ├── IProfinetDeserialize.cs
│ └── IProfinetSerialize.cs
├── Services
│ ├── IAdaptersService.cs
│ ├── IDeviceService.cs
│ └── ISettingsService.cs
└── packages.config
├── ProfinetTools.Logic
├── LogicModuleCatalog.cs
├── ProfinetTools.Logic.csproj
├── Properties
│ └── AssemblyInfo.cs
├── Protocols
│ ├── DCP.cs
│ ├── Ethernet.cs
│ ├── RPC.cs
│ ├── RT.cs
│ └── VLAN.cs
├── Services
│ ├── AdaptersService.cs
│ ├── DeviceService.cs
│ └── SettingsService.cs
├── Transport
│ ├── ConnectionInfoEthernet.cs
│ ├── DcpMessageArgs.cs
│ └── ProfinetEthernetTransport.cs
└── packages.config
├── ProfinetTools.Setup
├── Fragments
│ └── Fragments.wxs
├── Paraffin
│ ├── Create.bat
│ ├── Update.bat
│ └── Zen of Paraffin.docx
├── Product.wxs
├── ProfinetTools.Setup.wixproj
└── Resources
│ ├── installer_background.bmp
│ └── logo.ico
├── ProfinetTools.sln
├── ProfinetTools
├── App.config
├── ProfinetTools.csproj
├── Program.cs
├── Properties
│ ├── AssemblyInfo.cs
│ ├── Resources.Designer.cs
│ ├── Resources.resx
│ ├── Settings.Designer.cs
│ └── Settings.settings
└── packages.config
├── README.md
└── docs
└── screenshot.png
/.gitignore:
--------------------------------------------------------------------------------
1 | ## Ignore Visual Studio temporary files, build results, and
2 | ## files generated by popular Visual Studio add-ons.
3 | ##
4 | ## Get latest from https://github.com/github/gitignore/blob/master/VisualStudio.gitignore
5 |
6 | # User-specific files
7 | *.suo
8 | *.user
9 | *.userosscache
10 | *.sln.docstates
11 |
12 | # User-specific files (MonoDevelop/Xamarin Studio)
13 | *.userprefs
14 |
15 | # Build results
16 | [Dd]ebug/
17 | [Dd]ebugPublic/
18 | [Rr]elease/
19 | [Rr]eleases/
20 | x64/
21 | x86/
22 | bld/
23 | [Bb]in/
24 | [Oo]bj/
25 | [Ll]og/
26 |
27 | # Visual Studio 2015 cache/options directory
28 | .vs/
29 | # Uncomment if you have tasks that create the project's static files in wwwroot
30 | #wwwroot/
31 |
32 | # MSTest test Results
33 | [Tt]est[Rr]esult*/
34 | [Bb]uild[Ll]og.*
35 |
36 | # NUNIT
37 | *.VisualState.xml
38 | TestResult.xml
39 |
40 | # Build Results of an ATL Project
41 | [Dd]ebugPS/
42 | [Rr]eleasePS/
43 | dlldata.c
44 |
45 | # .NET Core
46 | project.lock.json
47 | project.fragment.lock.json
48 | artifacts/
49 | **/Properties/launchSettings.json
50 |
51 | *_i.c
52 | *_p.c
53 | *_i.h
54 | *.ilk
55 | *.meta
56 | *.obj
57 | *.pch
58 | *.pdb
59 | *.pgc
60 | *.pgd
61 | *.rsp
62 | *.sbr
63 | *.tlb
64 | *.tli
65 | *.tlh
66 | *.tmp
67 | *.tmp_proj
68 | *.log
69 | *.vspscc
70 | *.vssscc
71 | .builds
72 | *.pidb
73 | *.svclog
74 | *.scc
75 |
76 | # Chutzpah Test files
77 | _Chutzpah*
78 |
79 | # Visual C++ cache files
80 | ipch/
81 | *.aps
82 | *.ncb
83 | *.opendb
84 | *.opensdf
85 | *.sdf
86 | *.cachefile
87 | *.VC.db
88 | *.VC.VC.opendb
89 |
90 | # Visual Studio profiler
91 | *.psess
92 | *.vsp
93 | *.vspx
94 | *.sap
95 |
96 | # TFS 2012 Local Workspace
97 | $tf/
98 |
99 | # Guidance Automation Toolkit
100 | *.gpState
101 |
102 | # ReSharper is a .NET coding add-in
103 | _ReSharper*/
104 | *.[Rr]e[Ss]harper
105 | *.DotSettings.user
106 |
107 | # JustCode is a .NET coding add-in
108 | .JustCode
109 |
110 | # TeamCity is a build add-in
111 | _TeamCity*
112 |
113 | # DotCover is a Code Coverage Tool
114 | *.dotCover
115 |
116 | # Visual Studio code coverage results
117 | *.coverage
118 | *.coveragexml
119 |
120 | # NCrunch
121 | _NCrunch_*
122 | .*crunch*.local.xml
123 | nCrunchTemp_*
124 |
125 | # MightyMoose
126 | *.mm.*
127 | AutoTest.Net/
128 |
129 | # Web workbench (sass)
130 | .sass-cache/
131 |
132 | # Installshield output folder
133 | [Ee]xpress/
134 |
135 | # DocProject is a documentation generator add-in
136 | DocProject/buildhelp/
137 | DocProject/Help/*.HxT
138 | DocProject/Help/*.HxC
139 | DocProject/Help/*.hhc
140 | DocProject/Help/*.hhk
141 | DocProject/Help/*.hhp
142 | DocProject/Help/Html2
143 | DocProject/Help/html
144 |
145 | # Click-Once directory
146 | publish/
147 |
148 | # Publish Web Output
149 | *.[Pp]ublish.xml
150 | *.azurePubxml
151 | # TODO: Comment the next line if you want to checkin your web deploy settings
152 | # but database connection strings (with potential passwords) will be unencrypted
153 | *.pubxml
154 | *.publishproj
155 |
156 | # Microsoft Azure Web App publish settings. Comment the next line if you want to
157 | # checkin your Azure Web App publish settings, but sensitive information contained
158 | # in these scripts will be unencrypted
159 | PublishScripts/
160 |
161 | # NuGet Packages
162 | *.nupkg
163 | # The packages folder can be ignored because of Package Restore
164 | **/packages/*
165 | # except build/, which is used as an MSBuild target.
166 | !**/packages/build/
167 | # Uncomment if necessary however generally it will be regenerated when needed
168 | #!**/packages/repositories.config
169 | # NuGet v3's project.json files produces more ignorable files
170 | *.nuget.props
171 | *.nuget.targets
172 |
173 | # Microsoft Azure Build Output
174 | csx/
175 | *.build.csdef
176 |
177 | # Microsoft Azure Emulator
178 | ecf/
179 | rcf/
180 |
181 | # Windows Store app package directories and files
182 | AppPackages/
183 | BundleArtifacts/
184 | Package.StoreAssociation.xml
185 | _pkginfo.txt
186 |
187 | # Visual Studio cache files
188 | # files ending in .cache can be ignored
189 | *.[Cc]ache
190 | # but keep track of directories ending in .cache
191 | !*.[Cc]ache/
192 |
193 | # Others
194 | ClientBin/
195 | ~$*
196 | *~
197 | *.dbmdl
198 | *.dbproj.schemaview
199 | *.jfm
200 | *.pfx
201 | *.publishsettings
202 | orleans.codegen.cs
203 |
204 | # Since there are multiple workflows, uncomment next line to ignore bower_components
205 | # (https://github.com/github/gitignore/pull/1529#issuecomment-104372622)
206 | #bower_components/
207 |
208 | # RIA/Silverlight projects
209 | Generated_Code/
210 |
211 | # Backup & report files from converting an old project file
212 | # to a newer Visual Studio version. Backup files are not needed,
213 | # because we have git ;-)
214 | _UpgradeReport_Files/
215 | Backup*/
216 | UpgradeLog*.XML
217 | UpgradeLog*.htm
218 |
219 | # SQL Server files
220 | *.mdf
221 | *.ldf
222 | *.ndf
223 |
224 | # Business Intelligence projects
225 | *.rdl.data
226 | *.bim.layout
227 | *.bim_*.settings
228 |
229 | # Microsoft Fakes
230 | FakesAssemblies/
231 |
232 | # GhostDoc plugin setting file
233 | *.GhostDoc.xml
234 |
235 | # Node.js Tools for Visual Studio
236 | .ntvs_analysis.dat
237 | node_modules/
238 |
239 | # Typescript v1 declaration files
240 | typings/
241 |
242 | # Visual Studio 6 build log
243 | *.plg
244 |
245 | # Visual Studio 6 workspace options file
246 | *.opt
247 |
248 | # Visual Studio 6 auto-generated workspace file (contains which files were open etc.)
249 | *.vbw
250 |
251 | # Visual Studio LightSwitch build output
252 | **/*.HTMLClient/GeneratedArtifacts
253 | **/*.DesktopClient/GeneratedArtifacts
254 | **/*.DesktopClient/ModelManifest.xml
255 | **/*.Server/GeneratedArtifacts
256 | **/*.Server/ModelManifest.xml
257 | _Pvt_Extensions
258 |
259 | # Paket dependency manager
260 | .paket/paket.exe
261 | paket-files/
262 |
263 | # FAKE - F# Make
264 | .fake/
265 |
266 | # JetBrains Rider
267 | .idea/
268 | *.sln.iml
269 |
270 | # CodeRush
271 | .cr/
272 |
273 | # Python Tools for Visual Studio (PTVS)
274 | __pycache__/
275 | *.pyc
276 |
277 | # Cake - Uncomment if you are using it
278 | # tools/**
279 | # !tools/packages.config
280 |
281 | # Telerik's JustMock configuration file
282 | *.jmconfig
283 |
284 | # BizTalk build output
285 | *.btp.cs
286 | *.btm.cs
287 | *.odx.cs
288 | *.xsd.cs
289 | /out
290 |
--------------------------------------------------------------------------------
/LICENSE:
--------------------------------------------------------------------------------
1 | MIT License
2 |
3 | Copyright (c) 2018 Federico Barresi
4 |
5 | Permission is hereby granted, free of charge, to any person obtaining a copy
6 | of this software and associated documentation files (the "Software"), to deal
7 | in the Software without restriction, including without limitation the rights
8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9 | copies of the Software, and to permit persons to whom the Software is
10 | furnished to do so, subject to the following conditions:
11 |
12 | The above copyright notice and this permission notice shall be included in all
13 | copies or substantial portions of the Software.
14 |
15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21 | SOFTWARE.
22 |
--------------------------------------------------------------------------------
/ProfinetTools.Gui/App.xaml:
--------------------------------------------------------------------------------
1 |
8 |
9 |
10 |
11 |
12 |
13 |
14 |
--------------------------------------------------------------------------------
/ProfinetTools.Gui/App.xaml.cs:
--------------------------------------------------------------------------------
1 | using System;
2 | using System.Linq;
3 | using System.Windows;
4 |
5 | namespace ProfinetTools.Gui
6 | {
7 | ///
8 | /// Interaktionslogik für App.xaml
9 | ///
10 | public partial class App : Application
11 | {
12 | }
13 | }
14 |
--------------------------------------------------------------------------------
/ProfinetTools.Gui/GuiModuleCatalog.cs:
--------------------------------------------------------------------------------
1 | using System;
2 | using System.Linq;
3 | using Ninject.Modules;
4 |
5 | namespace ProfinetTools.Gui
6 | {
7 | public class GuiModuleCatalog : NinjectModule
8 | {
9 | public override void Load()
10 | {
11 | }
12 | }
13 | }
--------------------------------------------------------------------------------
/ProfinetTools.Gui/ProfinetTools.Gui.csproj:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 | Debug
6 | AnyCPU
7 | {F7D721A7-EB1B-4688-B535-63FCBEB12DAB}
8 | Library
9 | Properties
10 | ProfinetTools.Gui
11 | ProfinetTools.Gui
12 | v4.5.2
13 | 512
14 |
15 |
16 | true
17 | full
18 | false
19 | ..\out\Debug\
20 | DEBUG;TRACE
21 | prompt
22 | 4
23 |
24 |
25 | pdbonly
26 | true
27 | ..\out\Release\
28 | TRACE
29 | prompt
30 | 4
31 |
32 |
33 |
34 | ..\packages\JetBrains.Annotations.10.2.1\lib\net\JetBrains.Annotations.dll
35 |
36 |
37 | ..\packages\Ninject.3.3.4\lib\net45\Ninject.dll
38 |
39 |
40 | ..\packages\PacketDotNet.0.13.0\lib\net\PacketDotNet.dll
41 |
42 |
43 |
44 |
45 | ..\packages\reactiveui-core.7.0.0\lib\Net45\ReactiveUI.dll
46 |
47 |
48 | ..\packages\SharpPcap.4.2.0\lib\net\SharpPcap.dll
49 |
50 |
51 | ..\packages\Splat.1.4.0\lib\Net45\Splat.dll
52 |
53 |
54 |
55 |
56 | ..\packages\Rx-Core.2.2.5\lib\net45\System.Reactive.Core.dll
57 |
58 |
59 | ..\packages\Rx-Interfaces.2.2.5\lib\net45\System.Reactive.Interfaces.dll
60 |
61 |
62 | ..\packages\Rx-Linq.2.2.5\lib\net45\System.Reactive.Linq.dll
63 |
64 |
65 | ..\packages\Rx-PlatformServices.2.2.5\lib\net45\System.Reactive.PlatformServices.dll
66 |
67 |
68 | ..\packages\Rx-XAML.2.2.5\lib\net45\System.Reactive.Windows.Threading.dll
69 |
70 |
71 |
72 |
73 |
74 |
75 |
76 |
77 |
78 |
79 |
80 |
81 |
82 | App.xaml
83 |
84 |
85 |
86 |
87 |
88 |
89 |
90 |
91 |
92 |
93 | AdaptersView.xaml
94 |
95 |
96 | DevicesView.xaml
97 |
98 |
99 | MainWindow.xaml
100 |
101 |
102 | SettingsView.xaml
103 |
104 |
105 |
106 |
107 | MSBuild:Compile
108 | Designer
109 |
110 |
111 | Designer
112 | MSBuild:Compile
113 |
114 |
115 | Designer
116 | MSBuild:Compile
117 |
118 |
119 | MSBuild:Compile
120 | Designer
121 |
122 |
123 | Designer
124 | MSBuild:Compile
125 |
126 |
127 |
128 |
129 |
130 |
131 |
132 | {f23836b7-30f9-4a77-8ea1-8c57b7bc953f}
133 | ProfinetTools.Interfaces
134 |
135 |
136 |
137 |
138 |
139 |
140 |
--------------------------------------------------------------------------------
/ProfinetTools.Gui/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("ProfinetTools.Gui")]
9 | [assembly: AssemblyDescription("")]
10 | [assembly: AssemblyConfiguration("")]
11 | [assembly: AssemblyCompany("")]
12 | [assembly: AssemblyProduct("ProfinetTools.Gui")]
13 | [assembly: AssemblyCopyright("Copyright © 2018")]
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("f7d721a7-eb1b-4688-b535-63fcbeb12dab")]
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 |
--------------------------------------------------------------------------------
/ProfinetTools.Gui/Resources/logo.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/fbarresi/ProfinetTools/0315f0f698efd886809ba177edd7ee8e38b5166f/ProfinetTools.Gui/Resources/logo.png
--------------------------------------------------------------------------------
/ProfinetTools.Gui/ViewModelLocator.cs:
--------------------------------------------------------------------------------
1 | using Ninject;
2 | using Ninject.Parameters;
3 | using ProfinetTools.Interfaces.Commons;
4 | using ProfinetTools.Gui.ViewModels;
5 | using System;
6 | using IInitializable = ProfinetTools.Interfaces.Commons.IInitializable;
7 |
8 | namespace ProfinetTools.Gui
9 | {
10 | public class ViewModelLocator : IViewModelFactory, IInstanceCreator
11 | {
12 | protected readonly IKernel Kernel;
13 |
14 | private static ViewModelLocator s_Instance;
15 |
16 | public ViewModelLocator()
17 | {
18 | Kernel.Bind().To().InSingletonScope();
19 | }
20 |
21 | public ViewModelLocator(IKernel kernel)
22 | {
23 | Kernel = kernel;
24 | kernel.Bind().ToConstant(this);
25 |
26 | Kernel.Bind().To().InSingletonScope();
27 | }
28 |
29 | public static IInstanceCreator DesignInstanceCreator => s_Instance ?? (s_Instance = new ViewModelLocator());
30 |
31 | public static IViewModelFactory DesignViewModelFactory => s_Instance ?? (s_Instance = new ViewModelLocator());
32 |
33 | public MainWindowViewModel MainWindowViewModel => Kernel.Get();
34 |
35 | public T Create()
36 | {
37 | var newObject = Kernel.Get();
38 | InitializeInitialziable(newObject as IInitializable);
39 | return newObject;
40 | }
41 |
42 | public T CreateInstance(ConstructorArgument[] arguments)
43 | {
44 | var vm = Kernel.Get(arguments);
45 | InitializeInitialziable(vm as IInitializable);
46 | return vm;
47 | }
48 |
49 | public TVm CreateViewModel(T model)
50 | {
51 | var vm = Kernel.Get(new ConstructorArgument(@"model", model));
52 | InitializeInitialziable(vm as IInitializable);
53 | return vm;
54 | }
55 |
56 | public TVm CreateViewModel()
57 | {
58 | var vm = Kernel.Get();
59 | InitializeInitialziable(vm as IInitializable);
60 | return vm;
61 | }
62 |
63 | private static void InitializeInitialziable(IInitializable initializable)
64 | {
65 | initializable?.Init();
66 | }
67 | }
68 | }
--------------------------------------------------------------------------------
/ProfinetTools.Gui/ViewModels/AdaptersViewModel.cs:
--------------------------------------------------------------------------------
1 | using System;
2 | using System.Collections.Generic;
3 | using System.Linq;
4 | using ProfinetTools.Interfaces.Extensions;
5 | using ProfinetTools.Interfaces.Services;
6 | using ReactiveUI;
7 | using SharpPcap;
8 |
9 | namespace ProfinetTools.Gui.ViewModels
10 | {
11 | public class AdaptersViewModel : ViewModelBase
12 | {
13 | private readonly IAdaptersService adaptersService;
14 | private ICaptureDevice selectedAdapter;
15 |
16 | public AdaptersViewModel(IAdaptersService adaptersService)
17 | {
18 | this.adaptersService = adaptersService;
19 | }
20 | public override void Init()
21 | {
22 | Adapters = adaptersService.GetAdapters();
23 |
24 | this.WhenAnyValue(model => model.SelectedAdapter)
25 | .Subscribe(adaptersService.SelectAdapter)
26 | .AddDisposableTo(Disposables);
27 |
28 | SelectedAdapter = Adapters.FirstOrDefault(device => device.Description.Contains("Ethernet") && !device.Description.Contains("Virtual"));
29 | }
30 |
31 | public List Adapters { get; set; }
32 |
33 | public ICaptureDevice SelectedAdapter
34 | {
35 | get { return selectedAdapter; }
36 | set
37 | {
38 | if (Equals(value, selectedAdapter)) return;
39 | selectedAdapter = value;
40 | raisePropertyChanged();
41 | }
42 | }
43 | }
44 | }
--------------------------------------------------------------------------------
/ProfinetTools.Gui/ViewModels/DevicesViewModel.cs:
--------------------------------------------------------------------------------
1 | using System;
2 | using System.Collections.Generic;
3 | using System.Linq;
4 | using System.Reactive;
5 | using System.Reactive.Linq;
6 | using System.Reactive.Threading.Tasks;
7 | using System.Threading.Tasks;
8 | using ProfinetTools.Interfaces.Extensions;
9 | using ProfinetTools.Interfaces.Models;
10 | using ProfinetTools.Interfaces.Services;
11 | using ReactiveUI;
12 |
13 | namespace ProfinetTools.Gui.ViewModels
14 | {
15 | public class DevicesViewModel : ViewModelBase
16 | {
17 | private readonly IDeviceService deviceService;
18 | private readonly IAdaptersService adaptersService;
19 | private List devices = new List();
20 | private Device selectedDevice;
21 | public ReactiveUI.ReactiveCommand RefreshCommand { get; set; }
22 |
23 | public DevicesViewModel(IDeviceService deviceService, IAdaptersService adaptersService)
24 | {
25 | this.deviceService = deviceService;
26 | this.adaptersService = adaptersService;
27 | }
28 |
29 | public override void Init()
30 | {
31 | RefreshCommand = ReactiveUI.ReactiveCommand.CreateFromTask(RefreshDevicesList)
32 | .AddDisposableTo(Disposables);
33 |
34 | this.WhenAnyValue(model => model.SelectedDevice)
35 | .Subscribe(deviceService.SelectDevice)
36 | .AddDisposableTo(Disposables)
37 | ;
38 | }
39 |
40 | private async Task RefreshDevicesList()
41 | {
42 | var adapter = await adaptersService.SelectedAdapter.FirstAsync().ToTask();
43 | if(adapter == null) return Unit.Default;
44 |
45 | try
46 | {
47 | Devices = await deviceService.GetDevices(adapter, TimeSpan.FromSeconds(0.5));
48 | }
49 | catch (Exception e)
50 | {
51 | Console.WriteLine(e);
52 | }
53 | return Unit.Default;
54 | }
55 |
56 | public List Devices
57 | {
58 | get { return devices; }
59 | set
60 | {
61 | if (Equals(value, devices)) return;
62 | devices = value;
63 | raisePropertyChanged();
64 | }
65 | }
66 |
67 | public Device SelectedDevice
68 | {
69 | get { return selectedDevice; }
70 | set
71 | {
72 | if (Equals(value, selectedDevice)) return;
73 | selectedDevice = value;
74 | raisePropertyChanged();
75 | }
76 | }
77 | }
78 | }
--------------------------------------------------------------------------------
/ProfinetTools.Gui/ViewModels/MainViewModel.cs:
--------------------------------------------------------------------------------
1 | using System;
2 | using System.Reactive;
3 | using System.Threading.Tasks;
4 | using Microsoft.Win32;
5 | using ProfinetTools.Interfaces.Commons;
6 | using ProfinetTools.Interfaces.Extensions;
7 | using ReactiveUI.Legacy;
8 |
9 | namespace ProfinetTools.Gui.ViewModels
10 | {
11 | public class MainWindowViewModel : ViewModelBase
12 | {
13 | private readonly IViewModelFactory viewModelFactory;
14 |
15 | public MainWindowViewModel(IViewModelFactory viewModelFactory)
16 | {
17 | this.viewModelFactory = viewModelFactory;
18 | }
19 | public override void Init()
20 | {
21 | AdaptersViewModel = viewModelFactory.CreateViewModel();
22 | AdaptersViewModel.Init();
23 | AdaptersViewModel.AddDisposableTo(Disposables);
24 |
25 | DevicesViewModel = viewModelFactory.CreateViewModel();
26 | DevicesViewModel.Init();
27 | DevicesViewModel.AddDisposableTo(Disposables);
28 |
29 | SettingsViewModel = viewModelFactory.CreateViewModel();
30 | SettingsViewModel.Init();
31 | SettingsViewModel.AddDisposableTo(Disposables);
32 | }
33 |
34 | public AdaptersViewModel AdaptersViewModel { get; set; }
35 | public DevicesViewModel DevicesViewModel { get; set; }
36 | public SettingsViewModel SettingsViewModel { get; set; }
37 | }
38 | }
--------------------------------------------------------------------------------
/ProfinetTools.Gui/ViewModels/SettingsViewModel.cs:
--------------------------------------------------------------------------------
1 | using System;
2 | using System.Reactive;
3 | using System.Reactive.Linq;
4 | using System.Reactive.Subjects;
5 | using System.Reactive.Threading.Tasks;
6 | using System.Threading.Tasks;
7 | using System.Windows;
8 | using ProfinetTools.Interfaces.Extensions;
9 | using ProfinetTools.Interfaces.Models;
10 | using ProfinetTools.Interfaces.Services;
11 |
12 | namespace ProfinetTools.Gui.ViewModels
13 | {
14 | public class SettingsViewModel : ViewModelBase
15 | {
16 | private readonly IDeviceService deviceService;
17 | private readonly IAdaptersService adaptersService;
18 | private readonly ISettingsService settingsService;
19 | private Device device1;
20 |
21 | public ReactiveUI.ReactiveCommand SaveCommand { get; set; }
22 | public ReactiveUI.ReactiveCommand ResetCommand { get; set; }
23 |
24 |
25 | public SettingsViewModel(IDeviceService deviceService, IAdaptersService adaptersService, ISettingsService settingsService)
26 | {
27 | this.deviceService = deviceService;
28 | this.adaptersService = adaptersService;
29 | this.settingsService = settingsService;
30 | }
31 |
32 | public override void Init()
33 | {
34 | deviceService.SelectedDevice
35 | .Do(device => Device = device)
36 | .ObserveOnDispatcher()
37 | .Subscribe()
38 | .AddDisposableTo(Disposables);
39 |
40 | SaveCommand = ReactiveUI.ReactiveCommand.CreateFromTask(SaveDeviceSettings)
41 | .AddDisposableTo(Disposables);
42 |
43 | ResetCommand = ReactiveUI.ReactiveCommand.CreateFromTask(ResetDevice)
44 | .AddDisposableTo(Disposables);
45 | }
46 |
47 |
48 | private async Task ResetDevice()
49 | {
50 | var adapter = await adaptersService.SelectedAdapter.FirstAsync().ToTask();
51 | if (adapter == null) return Unit.Default;
52 |
53 | if(Device == null) return Unit.Default;
54 |
55 | var result = await settingsService.FactoryReset(adapter, Device.MAC);
56 | if (!result.Success)
57 | MessageBox.Show("Device refuse: " + result.ErrorMessage, "Device Error", MessageBoxButton.OK, MessageBoxImage.Exclamation);
58 | else
59 | MessageBox.Show("All done!", "Device Info", MessageBoxButton.OK, MessageBoxImage.Information);
60 |
61 |
62 | return Unit.Default;
63 | }
64 |
65 | private async Task SaveDeviceSettings()
66 | {
67 | var adapter = await adaptersService.SelectedAdapter.FirstAsync().ToTask();
68 | if (adapter == null) return Unit.Default;
69 |
70 | if (Device == null || !settingsService.TryParseNetworkConfiguration(Device)) return Unit.Default;
71 |
72 | var result = await settingsService.SendSettings(adapter, Device.MAC, Device);
73 | if (!result.Success)
74 | MessageBox.Show("Device refuse: " + result.ErrorMessage, "Device Error", MessageBoxButton.OK, MessageBoxImage.Exclamation);
75 | else
76 | MessageBox.Show("All done!", "Device Info", MessageBoxButton.OK, MessageBoxImage.Information);
77 |
78 | return Unit.Default;
79 | }
80 |
81 |
82 | public Device Device
83 | {
84 | get { return device1; }
85 | set
86 | {
87 | if (Equals(value, device1)) return;
88 | device1 = value;
89 | raisePropertyChanged();
90 | }
91 | }
92 | }
93 | }
--------------------------------------------------------------------------------
/ProfinetTools.Gui/ViewModels/ViewModelBase.cs:
--------------------------------------------------------------------------------
1 | using System;
2 | using System.Linq;
3 | using System.Reactive.Disposables;
4 | using System.Runtime.CompilerServices;
5 | using JetBrains.Annotations;
6 | using ProfinetTools.Interfaces.Commons;
7 | using ReactiveUI;
8 |
9 | namespace ProfinetTools.Gui.ViewModels
10 | {
11 | public abstract class ViewModelBase : ReactiveObject, IDisposable, IInitializable
12 | {
13 | protected CompositeDisposable Disposables = new CompositeDisposable();
14 | private bool disposed;
15 |
16 | ~ViewModelBase()
17 | {
18 | Dispose(false);
19 | }
20 |
21 | public virtual void Dispose()
22 | {
23 | Dispose(true);
24 | }
25 |
26 | public abstract void Init();
27 |
28 | [System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Usage", "CA2213:DisposableFieldsShouldBeDisposed", MessageId = "Disposables")]
29 | protected virtual void Dispose(bool disposing)
30 | {
31 | if (disposed)
32 | return;
33 |
34 | Disposables?.Dispose();
35 | Disposables = null;
36 |
37 | disposed = true;
38 | }
39 |
40 | [NotifyPropertyChangedInvocator]
41 | // ReSharper disable once InconsistentNaming
42 | protected void raisePropertyChanged([CallerMemberName] string propertyName = "")
43 | {
44 | this.RaisePropertyChanged(propertyName);
45 | }
46 | }
47 | }
--------------------------------------------------------------------------------
/ProfinetTools.Gui/Views/AdaptersView.xaml:
--------------------------------------------------------------------------------
1 |
11 |
12 |
13 |
14 |
15 |
16 |
17 |
18 |
19 |
20 |
21 |
22 |
23 |
--------------------------------------------------------------------------------
/ProfinetTools.Gui/Views/AdaptersView.xaml.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;
7 | using System.Windows.Controls;
8 | using System.Windows.Data;
9 | using System.Windows.Documents;
10 | using System.Windows.Input;
11 | using System.Windows.Media;
12 | using System.Windows.Media.Imaging;
13 | using System.Windows.Navigation;
14 | using System.Windows.Shapes;
15 |
16 | namespace ProfinetTools.Gui.Views
17 | {
18 | ///
19 | /// Interaction logic for AdaptersView.xaml
20 | ///
21 | public partial class AdaptersView : UserControl
22 | {
23 | public AdaptersView()
24 | {
25 | InitializeComponent();
26 | }
27 | }
28 | }
29 |
--------------------------------------------------------------------------------
/ProfinetTools.Gui/Views/DevicesView.xaml:
--------------------------------------------------------------------------------
1 |
11 |
12 |
13 |
14 |
15 |
16 |
17 |
18 |
19 |
20 |
21 |
22 |
23 |
24 |
25 |
26 |
27 |
28 |
29 |
30 |
31 |
32 |
--------------------------------------------------------------------------------
/ProfinetTools.Gui/Views/DevicesView.xaml.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;
7 | using System.Windows.Controls;
8 | using System.Windows.Data;
9 | using System.Windows.Documents;
10 | using System.Windows.Input;
11 | using System.Windows.Media;
12 | using System.Windows.Media.Imaging;
13 | using System.Windows.Navigation;
14 | using System.Windows.Shapes;
15 |
16 | namespace ProfinetTools.Gui.Views
17 | {
18 | ///
19 | /// Interaction logic for DevicesView.xaml
20 | ///
21 | public partial class DevicesView : UserControl
22 | {
23 | public DevicesView()
24 | {
25 | InitializeComponent();
26 | }
27 | }
28 | }
29 |
--------------------------------------------------------------------------------
/ProfinetTools.Gui/Views/MainWindow.xaml:
--------------------------------------------------------------------------------
1 |
12 |
13 |
14 |
15 |
16 |
17 |
18 |
19 |
20 |
21 |
22 |
23 |
--------------------------------------------------------------------------------
/ProfinetTools.Gui/Views/MainWindow.xaml.cs:
--------------------------------------------------------------------------------
1 | using System;
2 | using System.Linq;
3 | using System.Windows;
4 |
5 | namespace ProfinetTools.Gui.Views
6 | {
7 | public partial class MainWindow : Window
8 | {
9 | public MainWindow()
10 | {
11 | InitializeComponent();
12 | }
13 | }
14 | }
15 |
--------------------------------------------------------------------------------
/ProfinetTools.Gui/Views/SettingsView.xaml:
--------------------------------------------------------------------------------
1 |
11 |
12 |
13 |
14 |
15 |
16 |
17 |
18 |
19 |
20 |
21 |
22 |
23 |
24 |
25 |
26 |
27 |
28 |
29 |
30 |
31 |
32 |
33 |
34 |
35 |
36 |
37 |
38 |
39 |
40 |
41 |
42 |
43 |
44 |
45 |
46 |
47 |
48 |
--------------------------------------------------------------------------------
/ProfinetTools.Gui/Views/SettingsView.xaml.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;
7 | using System.Windows.Controls;
8 | using System.Windows.Data;
9 | using System.Windows.Documents;
10 | using System.Windows.Input;
11 | using System.Windows.Media;
12 | using System.Windows.Media.Imaging;
13 | using System.Windows.Navigation;
14 | using System.Windows.Shapes;
15 |
16 | namespace ProfinetTools.Gui.Views
17 | {
18 | ///
19 | /// Interaction logic for SettingsView.xaml
20 | ///
21 | public partial class SettingsView : UserControl
22 | {
23 | public SettingsView()
24 | {
25 | InitializeComponent();
26 | }
27 | }
28 | }
29 |
--------------------------------------------------------------------------------
/ProfinetTools.Gui/packages.config:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
10 |
11 |
12 |
13 |
14 |
15 |
--------------------------------------------------------------------------------
/ProfinetTools.Interfaces/Commons/IInitializable.cs:
--------------------------------------------------------------------------------
1 | using System;
2 | using System.Linq;
3 |
4 | namespace ProfinetTools.Interfaces.Commons
5 | {
6 | public interface IInitializable
7 | {
8 | void Init();
9 | }
10 | }
--------------------------------------------------------------------------------
/ProfinetTools.Interfaces/Commons/IInstanceCreator.cs:
--------------------------------------------------------------------------------
1 | using System;
2 | using System.Linq;
3 | using Ninject.Parameters;
4 |
5 | namespace ProfinetTools.Interfaces.Commons
6 | {
7 | public interface IInstanceCreator
8 | {
9 | T CreateInstance(ConstructorArgument[] arguments);
10 | }
11 | }
--------------------------------------------------------------------------------
/ProfinetTools.Interfaces/Commons/IViewModel.cs:
--------------------------------------------------------------------------------
1 | using System;
2 | using System.Linq;
3 |
4 | namespace ProfinetTools.Interfaces.Commons
5 | {
6 | public interface IViewModel
7 | {
8 | }
9 | }
--------------------------------------------------------------------------------
/ProfinetTools.Interfaces/Commons/IViewModelFactory.cs:
--------------------------------------------------------------------------------
1 | using System;
2 | using System.Linq;
3 |
4 | namespace ProfinetTools.Interfaces.Commons
5 | {
6 | public interface IViewModelFactory
7 | {
8 | T Create();
9 |
10 | TVm CreateViewModel(T model);
11 |
12 | TVm CreateViewModel();
13 | }
14 | }
--------------------------------------------------------------------------------
/ProfinetTools.Interfaces/Commons/NotifyPropertyChanged.cs:
--------------------------------------------------------------------------------
1 | using System.ComponentModel;
2 | using System.Runtime.CompilerServices;
3 | using JetBrains.Annotations;
4 |
5 | namespace ProfinetTools.Interfaces.Commons
6 | {
7 | public abstract class NotifyPropertyChanged : INotifyPropertyChanged
8 | {
9 | public virtual event PropertyChangedEventHandler PropertyChanged;
10 |
11 | [NotifyPropertyChangedInvocator]
12 | protected virtual void raisePropertyChanged([CallerMemberName] string propertyName = null)
13 | {
14 | PropertyChangedEventHandler propertyChanged = this.PropertyChanged;
15 | if (propertyChanged == null)
16 | return;
17 | propertyChanged((object)this, new PropertyChangedEventArgs(propertyName));
18 | }
19 | }
20 | }
--------------------------------------------------------------------------------
/ProfinetTools.Interfaces/Extensions/DisposableExtensions.cs:
--------------------------------------------------------------------------------
1 | using System;
2 | using System.Reactive.Disposables;
3 |
4 | namespace ProfinetTools.Interfaces.Extensions
5 | {
6 | public static class DisposableExtensions
7 | {
8 | public static T AddDisposableTo(this T obj, CompositeDisposable disposables) where T : IDisposable
9 | {
10 | disposables.Add(obj);
11 | return obj;
12 | }
13 | }
14 | }
--------------------------------------------------------------------------------
/ProfinetTools.Interfaces/Models/Device.cs:
--------------------------------------------------------------------------------
1 | using ProfinetTools.Interfaces.Commons;
2 |
3 | namespace ProfinetTools.Interfaces.Models
4 | {
5 | public class Device : NotifyPropertyChanged
6 | {
7 | private string mac;
8 | private string name;
9 | private string type;
10 | private string role;
11 | private string ip;
12 | private string subnetMask;
13 | private string gateway;
14 |
15 | public string MAC
16 | {
17 | get { return mac; }
18 | set
19 | {
20 | if (value == mac) return;
21 | mac = value;
22 | raisePropertyChanged();
23 | }
24 | }
25 |
26 | public string Name
27 | {
28 | get { return name; }
29 | set
30 | {
31 | if (value == name) return;
32 | name = value;
33 | raisePropertyChanged();
34 | }
35 | }
36 |
37 | public string Type
38 | {
39 | get { return type; }
40 | set
41 | {
42 | if (value == type) return;
43 | type = value;
44 | raisePropertyChanged();
45 | }
46 | }
47 |
48 | public string Role
49 | {
50 | get { return role; }
51 | set
52 | {
53 | if (value == role) return;
54 | role = value;
55 | raisePropertyChanged();
56 | }
57 | }
58 |
59 | public string IP
60 | {
61 | get { return ip; }
62 | set
63 | {
64 | if (value == ip) return;
65 | ip = value;
66 | raisePropertyChanged();
67 | }
68 | }
69 |
70 | public string SubnetMask
71 | {
72 | get { return subnetMask; }
73 | set
74 | {
75 | if (value == subnetMask) return;
76 | subnetMask = value;
77 | raisePropertyChanged();
78 | }
79 | }
80 |
81 | public string Gateway
82 | {
83 | get { return gateway; }
84 | set
85 | {
86 | if (value == gateway) return;
87 | gateway = value;
88 | raisePropertyChanged();
89 | }
90 | }
91 | }
92 | }
--------------------------------------------------------------------------------
/ProfinetTools.Interfaces/Models/SaveResult.cs:
--------------------------------------------------------------------------------
1 | namespace ProfinetTools.Interfaces.Models
2 | {
3 | public class SaveResult
4 | {
5 | public SaveResult(bool success, string errorMessage)
6 | {
7 | Success = success;
8 | ErrorMessage = errorMessage;
9 | }
10 |
11 | public bool Success { get; }
12 | public string ErrorMessage { get; }
13 | }
14 | }
--------------------------------------------------------------------------------
/ProfinetTools.Interfaces/ProfinetTools.Interfaces.csproj:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 | Debug
6 | AnyCPU
7 | {F23836B7-30F9-4A77-8EA1-8C57B7BC953F}
8 | Library
9 | Properties
10 | ProfinetTools.Interfaces
11 | ProfinetTools.Interfaces
12 | v4.5.2
13 | 512
14 |
15 |
16 | true
17 | full
18 | false
19 | ..\out\Debug\
20 | DEBUG;TRACE
21 | prompt
22 | 4
23 |
24 |
25 | pdbonly
26 | true
27 | ..\out\Release\
28 | TRACE
29 | prompt
30 | 4
31 |
32 |
33 |
34 | ..\packages\JetBrains.Annotations.10.2.1\lib\net\JetBrains.Annotations.dll
35 |
36 |
37 | ..\packages\Ninject.3.3.4\lib\net45\Ninject.dll
38 |
39 |
40 | ..\packages\PacketDotNet.0.13.0\lib\net\PacketDotNet.dll
41 |
42 |
43 | ..\packages\SharpPcap.4.2.0\lib\net\SharpPcap.dll
44 |
45 |
46 |
47 |
48 | ..\packages\Rx-Core.2.2.5\lib\net45\System.Reactive.Core.dll
49 |
50 |
51 | ..\packages\Rx-Interfaces.2.2.5\lib\net45\System.Reactive.Interfaces.dll
52 |
53 |
54 |
55 |
56 |
57 |
58 |
59 |
60 |
61 |
62 |
63 |
64 |
65 |
66 |
67 |
68 |
69 |
70 |
71 |
72 |
73 |
74 |
75 |
76 |
77 |
78 |
79 |
80 |
--------------------------------------------------------------------------------
/ProfinetTools.Interfaces/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("ProfinetTools.Interfaces")]
9 | [assembly: AssemblyDescription("")]
10 | [assembly: AssemblyConfiguration("")]
11 | [assembly: AssemblyCompany("")]
12 | [assembly: AssemblyProduct("ProfinetTools.Interfaces")]
13 | [assembly: AssemblyCopyright("Copyright © 2018")]
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("f23836b7-30f9-4a77-8ea1-8c57b7bc953f")]
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 |
--------------------------------------------------------------------------------
/ProfinetTools.Interfaces/Serialization/IProfinetDeserialize.cs:
--------------------------------------------------------------------------------
1 | using System;
2 | using System.Linq;
3 |
4 | namespace ProfinetTools.Interfaces.Serialization
5 | {
6 | public interface IProfinetDeserialize //Should be merged with IProfinetSerialize, at some point
7 | {
8 | int Deserialize(System.IO.Stream buffer);
9 | }
10 | }
--------------------------------------------------------------------------------
/ProfinetTools.Interfaces/Serialization/IProfinetSerialize.cs:
--------------------------------------------------------------------------------
1 | using System;
2 | using System.Linq;
3 |
4 | namespace ProfinetTools.Interfaces.Serialization
5 | {
6 | public interface IProfinetSerialize
7 | {
8 | int Serialize(System.IO.Stream buffer);
9 | }
10 | }
--------------------------------------------------------------------------------
/ProfinetTools.Interfaces/Services/IAdaptersService.cs:
--------------------------------------------------------------------------------
1 | using System;
2 | using System.Collections.Generic;
3 | using System.Linq;
4 | using SharpPcap;
5 |
6 | namespace ProfinetTools.Interfaces.Services
7 | {
8 | public interface IAdaptersService
9 | {
10 | List GetAdapters();
11 |
12 | IObservable SelectedAdapter { get; }
13 | void SelectAdapter(ICaptureDevice adapter);
14 | }
15 | }
--------------------------------------------------------------------------------
/ProfinetTools.Interfaces/Services/IDeviceService.cs:
--------------------------------------------------------------------------------
1 | using System;
2 | using System.Collections.Generic;
3 | using System.Linq;
4 | using System.Threading.Tasks;
5 | using ProfinetTools.Interfaces.Models;
6 | using SharpPcap;
7 |
8 | namespace ProfinetTools.Interfaces.Services
9 | {
10 | public interface IDeviceService
11 | {
12 | Task> GetDevices(ICaptureDevice adapter, TimeSpan timeout);
13 | void SelectDevice(Device device);
14 | IObservable SelectedDevice { get; }
15 | }
16 | }
--------------------------------------------------------------------------------
/ProfinetTools.Interfaces/Services/ISettingsService.cs:
--------------------------------------------------------------------------------
1 | using System;
2 | using System.Linq;
3 | using System.Threading.Tasks;
4 | using ProfinetTools.Interfaces.Models;
5 | using SharpPcap;
6 |
7 | namespace ProfinetTools.Interfaces.Services
8 | {
9 | public interface ISettingsService
10 | {
11 | Task FactoryReset(ICaptureDevice adapter, string deviceName);
12 | Task SendSettings(ICaptureDevice adapter, string macAddress, Device newSettings);
13 | bool TryParseNetworkConfiguration(Device device);
14 | }
15 | }
--------------------------------------------------------------------------------
/ProfinetTools.Interfaces/packages.config:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
--------------------------------------------------------------------------------
/ProfinetTools.Logic/LogicModuleCatalog.cs:
--------------------------------------------------------------------------------
1 | using System;
2 | using System.Linq;
3 | using Ninject.Modules;
4 | using ProfinetTools.Interfaces.Services;
5 | using ProfinetTools.Logic.Services;
6 |
7 | namespace ProfinetTools.Logic
8 | {
9 | public class LogicModuleCatalog : NinjectModule
10 | {
11 | public override void Load()
12 | {
13 | Bind().To().InSingletonScope();
14 | Bind().To().InSingletonScope();
15 | Bind().To().InSingletonScope();
16 | }
17 | }
18 | }
--------------------------------------------------------------------------------
/ProfinetTools.Logic/ProfinetTools.Logic.csproj:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 | Debug
6 | AnyCPU
7 | {6696F4A6-C9A5-49F3-8463-16A85BACB6E6}
8 | Library
9 | Properties
10 | ProfinetTools.Logic
11 | ProfinetTools.Logic
12 | v4.5.2
13 | 512
14 |
15 |
16 | true
17 | full
18 | false
19 | ..\out\Debug\
20 | DEBUG;TRACE
21 | prompt
22 | 4
23 |
24 |
25 | pdbonly
26 | true
27 | ..\out\Release\
28 | TRACE
29 | prompt
30 | 4
31 |
32 |
33 |
34 | ..\packages\Ninject.3.3.4\lib\net45\Ninject.dll
35 |
36 |
37 | ..\packages\PacketDotNet.0.13.0\lib\net\PacketDotNet.dll
38 |
39 |
40 | ..\packages\SharpPcap.4.2.0\lib\net\SharpPcap.dll
41 |
42 |
43 |
44 |
45 | ..\packages\Rx-Core.2.2.5\lib\net45\System.Reactive.Core.dll
46 |
47 |
48 | ..\packages\Rx-Interfaces.2.2.5\lib\net45\System.Reactive.Interfaces.dll
49 |
50 |
51 | ..\packages\Rx-Linq.2.2.5\lib\net45\System.Reactive.Linq.dll
52 |
53 |
54 |
55 |
56 |
57 |
58 |
59 |
60 |
61 |
62 |
63 |
64 |
65 |
66 |
67 |
68 |
69 |
70 |
71 |
72 |
73 |
74 |
75 |
76 |
77 |
78 |
79 |
80 | {F23836B7-30F9-4A77-8EA1-8C57B7BC953F}
81 | ProfinetTools.Interfaces
82 |
83 |
84 |
85 |
--------------------------------------------------------------------------------
/ProfinetTools.Logic/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("ProfinetTools.Logic")]
9 | [assembly: AssemblyDescription("")]
10 | [assembly: AssemblyConfiguration("")]
11 | [assembly: AssemblyCompany("")]
12 | [assembly: AssemblyProduct("ProfinetTools.Logic")]
13 | [assembly: AssemblyCopyright("Copyright © 2018")]
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("6696f4a6-c9a5-49f3-8463-16a85bacb6e6")]
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 |
--------------------------------------------------------------------------------
/ProfinetTools.Logic/Protocols/DCP.cs:
--------------------------------------------------------------------------------
1 | using System;
2 | using System.Collections.Generic;
3 | using System.ComponentModel;
4 | using System.Diagnostics;
5 | using System.Linq;
6 | using System.Text;
7 | using ProfinetTools.Interfaces.Serialization;
8 |
9 | namespace ProfinetTools.Logic.Protocols
10 | {
11 | public class DCP
12 | {
13 | [Flags]
14 | public enum ServiceIds : ushort
15 | {
16 | Get_Request = 0x0300,
17 | Get_Response = 0x0301,
18 | Set_Request = 0x0400,
19 | Set_Response = 0x0401,
20 | Identify_Request = 0x0500,
21 | Identify_Response = 0x0501,
22 | Hello_Request = 0x0600,
23 | ServiceIDNotSupported = 0x0004,
24 | }
25 |
26 | public enum BlockOptions : ushort
27 | {
28 | //IP
29 | IP_MACAddress = 0x0101,
30 | IP_IPParameter = 0x0102,
31 | IP_FullIPSuite = 0x0103,
32 |
33 | //DeviceProperties
34 | DeviceProperties_DeviceVendor = 0x0201,
35 | DeviceProperties_NameOfStation = 0x0202,
36 | DeviceProperties_DeviceID = 0x0203,
37 | DeviceProperties_DeviceRole = 0x0204,
38 | DeviceProperties_DeviceOptions = 0x0205,
39 | DeviceProperties_AliasName = 0x0206,
40 | DeviceProperties_DeviceInstance = 0x0207,
41 | DeviceProperties_OEMDeviceID = 0x0208,
42 |
43 | //DHCP
44 | DHCP_HostName = 0x030C,
45 | DHCP_VendorSpecificInformation = 0x032B,
46 | DHCP_ServerIdentifier = 0x0336,
47 | DHCP_ParameterRequestList = 0x0337,
48 | DHCP_ClassIdentifier = 0x033C,
49 | DHCP_DHCPClientIdentifier = 0x033D,
50 | DHCP_FullyQualifiedDomainName = 0x0351,
51 | DHCP_UUIDClientIdentifier = 0x0361,
52 | DHCP_DHCP = 0x03FF,
53 |
54 | //Control
55 | Control_Start = 0x0501,
56 | Control_Stop = 0x0502,
57 | Control_Signal = 0x0503,
58 | Control_Response = 0x0504,
59 | Control_FactoryReset = 0x0505,
60 | Control_ResetToFactory = 0x0506,
61 |
62 | //DeviceInitiative
63 | DeviceInitiative_DeviceInitiative = 0x0601,
64 |
65 | //AllSelector
66 | AllSelector_AllSelector = 0xFFFF,
67 | }
68 |
69 | public enum BlockQualifiers : ushort
70 | {
71 | Temporary = 0,
72 | Permanent = 1,
73 |
74 | ResetApplicationData = 2,
75 | ResetCommunicationParameter = 4,
76 | ResetEngineeringParameter = 6,
77 | ResetAllStoredData = 8,
78 | ResetDevice = 16,
79 | ResetAndRestoreData = 18,
80 | }
81 |
82 | [Flags]
83 | public enum BlockInfo : ushort
84 | {
85 | IpSet = 1,
86 | IpSetViaDhcp = 2,
87 | IpConflict = 0x80,
88 | }
89 |
90 | [Flags]
91 | public enum DeviceRoles : byte
92 | {
93 | Device = 1,
94 | Controller = 2,
95 | Multidevice = 4,
96 | Supervisor = 8,
97 | }
98 |
99 | public enum BlockErrors : byte
100 | {
101 | NoError = 0,
102 | OptionNotSupported = 1,
103 | SuboptionNotSupported = 2,
104 | SuboptionNotSet = 3,
105 | ResourceError = 4,
106 | SetNotPossible = 5,
107 | Busy = 6,
108 | }
109 |
110 | public static int EncodeU32(System.IO.Stream buffer, UInt32 value)
111 | {
112 | buffer.WriteByte((byte)((value & 0xFF000000) >> 24));
113 | buffer.WriteByte((byte)((value & 0x00FF0000) >> 16));
114 | buffer.WriteByte((byte)((value & 0x0000FF00) >> 08));
115 | buffer.WriteByte((byte)((value & 0x000000FF) >> 00));
116 | return 4;
117 | }
118 |
119 | public static int EncodeU16(System.IO.Stream buffer, UInt16 value)
120 | {
121 | buffer.WriteByte((byte)((value & 0xFF00) >> 08));
122 | buffer.WriteByte((byte)((value & 0x00FF) >> 00));
123 | return 2;
124 | }
125 |
126 | public static int EncodeU8(System.IO.Stream buffer, byte value)
127 | {
128 | buffer.WriteByte((byte)value);
129 | return 1;
130 | }
131 |
132 | public static int DecodeU16(System.IO.Stream buffer, out UInt16 value)
133 | {
134 | if (buffer.Position >= buffer.Length)
135 | {
136 | value = 0;
137 | return 0;
138 | }
139 | value = (UInt16)((buffer.ReadByte() << 8) | buffer.ReadByte());
140 | return 2;
141 | }
142 |
143 | public static int DecodeU8(System.IO.Stream buffer, out byte value)
144 | {
145 | if (buffer.Position >= buffer.Length)
146 | {
147 | value = 0;
148 | return 0;
149 | }
150 | value = (byte)buffer.ReadByte();
151 | return 1;
152 | }
153 |
154 | public static int DecodeU32(System.IO.Stream buffer, out UInt32 value)
155 | {
156 | if (buffer.Position >= buffer.Length)
157 | {
158 | value = 0;
159 | return 0;
160 | }
161 | value = (UInt32)((buffer.ReadByte() << 24) | (buffer.ReadByte() << 16) | (buffer.ReadByte() << 8) | buffer.ReadByte());
162 | return 4;
163 | }
164 |
165 | public static int EncodeString(System.IO.Stream buffer, string value)
166 | {
167 | byte[] bytes = Encoding.ASCII.GetBytes(value);
168 | buffer.Write(bytes, 0, bytes.Length);
169 | return bytes.Length;
170 | }
171 |
172 | public static int DecodeString(System.IO.Stream buffer, int length, out string value)
173 | {
174 | byte[] tmp = new byte[length];
175 | buffer.Read(tmp, 0, length);
176 | value = Encoding.ASCII.GetString(tmp);
177 | return tmp.Length;
178 | }
179 |
180 | public static int EncodeOctets(System.IO.Stream buffer, byte[] value)
181 | {
182 | if (value == null || value.Length == 0) return 0;
183 | buffer.Write(value, 0, value.Length);
184 | return value.Length;
185 | }
186 |
187 | public static int DecodeOctets(System.IO.Stream buffer, int length, out byte[] value)
188 | {
189 | if (length <= 0)
190 | {
191 | value = null;
192 | return 0;
193 | }
194 | value = new byte[length];
195 | buffer.Read(value, 0, length);
196 | return value.Length;
197 | }
198 |
199 | public static int EncodeHeader(System.IO.Stream buffer, ServiceIds ServiceID, UInt32 Xid, UInt16 ResponseDelayFactor, UInt16 DCPDataLength)
200 | {
201 | long dummy;
202 | return EncodeHeader(buffer, ServiceID, Xid, ResponseDelayFactor, DCPDataLength, out dummy);
203 | }
204 |
205 | public static int EncodeHeader(System.IO.Stream buffer, ServiceIds ServiceID, UInt32 Xid, UInt16 ResponseDelayFactor, UInt16 DCPDataLength, out long DCPDataLength_pos)
206 | {
207 | EncodeU16(buffer, (ushort)ServiceID);
208 |
209 | //big endian uint32
210 | EncodeU32(buffer, Xid);
211 |
212 | //ResponseDelayFactor, 1 = Allowed value without spread, 2 – 0x1900 = Allowed value with spread
213 | EncodeU16(buffer, ResponseDelayFactor);
214 |
215 | DCPDataLength_pos = buffer.Position;
216 | EncodeU16(buffer, DCPDataLength);
217 |
218 | return 10;
219 | }
220 |
221 | public static void ReEncodeDCPDataLength(System.IO.Stream buffer, long DCPDataLength_pos)
222 | {
223 | long current_pos = buffer.Position;
224 | buffer.Position = DCPDataLength_pos;
225 | EncodeU16(buffer, (ushort)(current_pos - buffer.Position - 2));
226 | buffer.Position = current_pos;
227 | }
228 |
229 | public static int DecodeHeader(System.IO.Stream buffer, out ServiceIds ServiceID, out UInt32 Xid, out UInt16 ResponseDelayFactor, out UInt16 DCPDataLength)
230 | {
231 | ushort val;
232 | DecodeU16(buffer, out val);
233 | ServiceID = (ServiceIds)val;
234 |
235 | //big endian uint32
236 | DecodeU32(buffer, out Xid);
237 |
238 | //ResponseDelayFactor, 1 = Allowed value without spread, 2 – 0x1900 = Allowed value with spread
239 | DecodeU16(buffer, out ResponseDelayFactor);
240 |
241 | DecodeU16(buffer, out DCPDataLength);
242 |
243 | return 10;
244 | }
245 |
246 | public static int EncodeBlock(System.IO.Stream buffer, BlockOptions options, UInt16 DCPBlockLength)
247 | {
248 | long dummy;
249 | return EncodeBlock(buffer, options, DCPBlockLength, out dummy);
250 | }
251 |
252 | public static int EncodeBlock(System.IO.Stream buffer, BlockOptions options, UInt16 DCPBlockLength, out long DCPBlockLength_pos)
253 | {
254 | EncodeU16(buffer, (ushort)options);
255 | DCPBlockLength_pos = buffer.Position;
256 | EncodeU16(buffer, DCPBlockLength);
257 | return 4;
258 | }
259 |
260 | public static int DecodeBlock(System.IO.Stream buffer, out BlockOptions options, out UInt16 DCPBlockLength)
261 | {
262 | ushort opt;
263 | DecodeU16(buffer, out opt);
264 | options = (BlockOptions)opt;
265 | DecodeU16(buffer, out DCPBlockLength);
266 | return 4;
267 | }
268 |
269 | public static int EncodeIdentifyResponse(System.IO.Stream buffer, UInt32 Xid, Dictionary blocks)
270 | {
271 | int ret = 0;
272 | long dcp_data_length_pos;
273 |
274 | //Header
275 | ret += EncodeHeader(buffer, ServiceIds.Identify_Response, Xid, 0, 0, out dcp_data_length_pos);
276 |
277 | //{ IdentifyResBlock, NameOfStationBlockRes,IPParameterBlockRes, DeviceIDBlockRes, DeviceVendorBlockRes,DeviceOptionsBlockRes, DeviceRoleBlockRes, [DeviceInitiativeBlockRes],[DeviceInstanceBlockRes], [OEMDeviceIDBlockRes] }
278 |
279 | foreach (KeyValuePair entry in blocks)
280 | {
281 | ret += EncodeNextBlock(buffer, entry);
282 | }
283 |
284 | //adjust dcp_length
285 | ReEncodeDCPDataLength(buffer, dcp_data_length_pos);
286 |
287 | return ret;
288 | }
289 |
290 | ///
291 | /// This is a helper class for the block options
292 | ///
293 | [TypeConverter(typeof(ExpandableObjectConverter)), Serializable]
294 | public class BlockOptionMeta
295 | {
296 | public string Name { get; set; }
297 | public bool IsReadable { get; set; }
298 | public bool IsWriteable { get; set; }
299 |
300 | [Browsable(false), System.Xml.Serialization.XmlIgnore]
301 | public BlockOptions BlockOption { get; set; }
302 |
303 | public byte Option
304 | {
305 | get
306 | {
307 | return (byte)((((UInt16)BlockOption) & 0xFF00) >> 8);
308 | }
309 | set
310 | {
311 | BlockOption = (BlockOptions)((((UInt16)BlockOption) & 0x00FF) | ((UInt16)value << 8));
312 | }
313 | }
314 |
315 | public byte SubOption
316 | {
317 | get
318 | {
319 | return (byte)((((UInt16)BlockOption) & 0x00FF) >> 0);
320 | }
321 | set
322 | {
323 | BlockOption = (BlockOptions)((((UInt16)BlockOption) & 0xFF00) | ((UInt16)value << 0));
324 | }
325 | }
326 |
327 | private BlockOptionMeta() //For XmlSerializer
328 | {
329 | }
330 |
331 | public BlockOptionMeta(string name, byte option, byte sub_option, bool is_readable, bool is_writeable)
332 | {
333 | this.BlockOption = 0;
334 | this.Name = name;
335 | this.Option = option;
336 | this.SubOption = sub_option;
337 | this.IsReadable = is_readable;
338 | this.IsWriteable = is_writeable;
339 | }
340 |
341 | public BlockOptionMeta(BlockOptions opt)
342 | {
343 | BlockOption = opt;
344 | Name = opt.ToString();
345 | if (opt == BlockOptions.IP_MACAddress ||
346 | opt == BlockOptions.DeviceProperties_DeviceID ||
347 | opt == BlockOptions.DeviceProperties_DeviceVendor ||
348 | opt == BlockOptions.DeviceProperties_DeviceRole ||
349 | opt == BlockOptions.DeviceProperties_DeviceOptions ||
350 | opt == BlockOptions.DeviceProperties_DeviceInstance ||
351 | opt == BlockOptions.DeviceProperties_OEMDeviceID ||
352 | opt == BlockOptions.DeviceInitiative_DeviceInitiative)
353 | {
354 | IsReadable = true;
355 | }
356 | else if (opt == BlockOptions.DeviceProperties_AliasName ||
357 | opt == BlockOptions.Control_Response ||
358 | opt == BlockOptions.AllSelector_AllSelector)
359 | {
360 | //none
361 | }
362 | else if (opt == BlockOptions.Control_Start ||
363 | opt == BlockOptions.Control_Stop ||
364 | opt == BlockOptions.Control_Signal ||
365 | opt == BlockOptions.Control_FactoryReset ||
366 | opt == BlockOptions.Control_ResetToFactory)
367 | {
368 | IsWriteable = true;
369 | }
370 | else
371 | {
372 | //default
373 | IsReadable = true;
374 | IsWriteable = true;
375 | }
376 | }
377 | }
378 |
379 | public class IpAddressConverter : TypeConverter
380 | {
381 | public override bool CanConvertFrom(ITypeDescriptorContext context, Type sourceType)
382 | {
383 | if (sourceType == typeof(string)) return true;
384 | return base.CanConvertFrom(context, sourceType);
385 | }
386 | public override object ConvertFrom(ITypeDescriptorContext context, System.Globalization.CultureInfo culture, object value)
387 | {
388 | if (value is string)
389 | return System.Net.IPAddress.Parse((string)value);
390 | return base.ConvertFrom(context, culture, value);
391 | }
392 | }
393 |
394 | [TypeConverter(typeof(ExpandableObjectConverter))]
395 | public class IpInfo : IProfinetSerialize
396 | {
397 | public BlockInfo Info { get; set; }
398 | [TypeConverter(typeof(IpAddressConverter))]
399 | public System.Net.IPAddress Ip { get; set; }
400 | [TypeConverter(typeof(IpAddressConverter))]
401 | public System.Net.IPAddress SubnetMask { get; set; }
402 | [TypeConverter(typeof(IpAddressConverter))]
403 | public System.Net.IPAddress Gateway { get; set; }
404 | public IpInfo(BlockInfo info, byte[] ip, byte[] subnet, byte[] gateway)
405 | {
406 | Info = info;
407 | Ip = new System.Net.IPAddress(ip);
408 | SubnetMask = new System.Net.IPAddress(subnet);
409 | Gateway = new System.Net.IPAddress(gateway);
410 | }
411 | public override string ToString()
412 | {
413 | return "{" + Ip.ToString() + " - " + SubnetMask.ToString() + " - " + Gateway.ToString() + "}";
414 | }
415 |
416 | public int Serialize(System.IO.Stream buffer)
417 | {
418 | int ret = 0;
419 | byte[] tmp;
420 | tmp = Ip.GetAddressBytes();
421 | buffer.Write(tmp, 0, tmp.Length);
422 | ret += tmp.Length;
423 | tmp = SubnetMask.GetAddressBytes();
424 | buffer.Write(tmp, 0, tmp.Length);
425 | ret += tmp.Length;
426 | tmp = Gateway.GetAddressBytes();
427 | buffer.Write(tmp, 0, tmp.Length);
428 | ret += tmp.Length;
429 | return ret;
430 | }
431 | }
432 |
433 | [TypeConverter(typeof(ExpandableObjectConverter))]
434 | public class DeviceIdInfo : IProfinetSerialize
435 | {
436 | public UInt16 VendorId { get; set; }
437 | public UInt16 DeviceId { get; set; }
438 | public DeviceIdInfo(UInt16 vendor_id, UInt16 device_id)
439 | {
440 | VendorId = vendor_id;
441 | DeviceId = device_id;
442 | }
443 | public override string ToString()
444 | {
445 | return "Vendor 0x" + VendorId.ToString("X") + " - Device 0x" + DeviceId.ToString("X");
446 | }
447 |
448 | public int Serialize(System.IO.Stream buffer)
449 | {
450 | int ret = 0;
451 | ret += EncodeU16(buffer, VendorId);
452 | ret += EncodeU16(buffer, DeviceId);
453 | return ret;
454 | }
455 | public override bool Equals(object obj)
456 | {
457 | if (!(obj is DeviceIdInfo)) return false;
458 | DeviceIdInfo o = (DeviceIdInfo)obj;
459 | return o.DeviceId == DeviceId && o.VendorId == VendorId;
460 | }
461 | public override int GetHashCode()
462 | {
463 | UInt32 tmp = (uint)(VendorId << 16);
464 | tmp |= DeviceId;
465 | return tmp.GetHashCode();
466 | }
467 | }
468 |
469 | [TypeConverter(typeof(ExpandableObjectConverter))]
470 | public class DeviceRoleInfo : IProfinetSerialize
471 | {
472 | public DeviceRoles DeviceRole { get; set; }
473 |
474 | public DeviceRoleInfo(DeviceRoles device_role)
475 | {
476 | DeviceRole = device_role;
477 | }
478 |
479 | public int Serialize(System.IO.Stream buffer)
480 | {
481 | int ret = 0;
482 | ret += EncodeU8(buffer, (byte)DeviceRole);
483 | buffer.WriteByte(0); //padding
484 | ret++;
485 | return ret;
486 | }
487 |
488 | public override string ToString()
489 | {
490 | return DeviceRole.ToString();
491 | }
492 | }
493 |
494 | [TypeConverter(typeof(ExpandableObjectConverter))]
495 | public class ResponseStatus
496 | {
497 | public BlockOptions Option { get; set; }
498 | public BlockErrors Error { get; set; }
499 | public ResponseStatus()
500 | {
501 | }
502 | public ResponseStatus(BlockOptions Option, BlockErrors Error)
503 | {
504 | this.Option = Option;
505 | this.Error = Error;
506 | }
507 | public override string ToString()
508 | {
509 | return Error.ToString();
510 | }
511 | }
512 |
513 | private static int EncodeNextBlock(System.IO.Stream buffer, KeyValuePair block)
514 | {
515 | int ret = 0;
516 | int tmp = 0;
517 | long DCPBlockLength_pos;
518 |
519 | ret += EncodeBlock(buffer, block.Key, 0, out DCPBlockLength_pos);
520 |
521 | //block info
522 | if (block.Value != null) ret += EncodeU16(buffer, 0);
523 | else return ret;
524 |
525 | if (block.Value is ResponseStatus)
526 | {
527 | buffer.Position -= 2;
528 | EncodeU16(buffer, (ushort)((ResponseStatus)block.Value).Option);
529 | tmp += EncodeU8(buffer, (byte)((ResponseStatus)block.Value).Error);
530 | }
531 | else if (block.Value is IProfinetSerialize)
532 | {
533 | tmp += ((IProfinetSerialize)block.Value).Serialize(buffer);
534 | }
535 | else if (block.Value is string)
536 | {
537 | tmp += EncodeString(buffer, (string)block.Value);
538 | }
539 | else if (block.Value is byte[])
540 | {
541 | tmp += EncodeOctets(buffer, (byte[])block.Value);
542 | }
543 | else if (block.Value is BlockOptions[])
544 | {
545 | foreach (BlockOptions b in (BlockOptions[])block.Value)
546 | {
547 | tmp += EncodeU16(buffer, (ushort)b);
548 | }
549 | }
550 | else
551 | {
552 | throw new NotImplementedException();
553 | }
554 |
555 | //adjust length
556 | ReEncodeDCPDataLength(buffer, DCPBlockLength_pos);
557 |
558 | //padding
559 | ret += tmp;
560 | if ((tmp % 2) != 0)
561 | {
562 | buffer.WriteByte(0);
563 | ret++;
564 | }
565 |
566 | return ret;
567 | }
568 |
569 | private static int DecodeNextBlock(System.IO.Stream buffer, ushort dcp_length, out KeyValuePair block)
570 | {
571 | int ret = 0;
572 | BlockOptions options;
573 | UInt16 dcp_block_length;
574 | UInt16 block_info = 0;
575 | UInt16 tmp, tmp2;
576 | string str;
577 | object content;
578 | ResponseStatus set_response;
579 |
580 | if (buffer.Position >= buffer.Length || dcp_length <= 0)
581 | {
582 | block = new KeyValuePair(0, null);
583 | return ret;
584 | }
585 |
586 | ret += DecodeBlock(buffer, out options, out dcp_block_length);
587 | if (dcp_block_length >= 2) ret += DecodeU16(buffer, out block_info);
588 | dcp_block_length -= 2;
589 |
590 | switch (options)
591 | {
592 | case BlockOptions.DeviceProperties_NameOfStation:
593 | ret += DecodeString(buffer, dcp_block_length, out str);
594 | content = str;
595 | break;
596 | case BlockOptions.IP_IPParameter:
597 | byte[] ip, subnet, gateway;
598 | ret += DecodeOctets(buffer, 4, out ip);
599 | ret += DecodeOctets(buffer, 4, out subnet);
600 | ret += DecodeOctets(buffer, 4, out gateway);
601 | content = new IpInfo((BlockInfo)block_info, ip, subnet, gateway); ;
602 | break;
603 | case BlockOptions.DeviceProperties_DeviceID:
604 | ret += DecodeU16(buffer, out tmp);
605 | ret += DecodeU16(buffer, out tmp2);
606 | content = new DeviceIdInfo(tmp, tmp2);
607 | break;
608 | case BlockOptions.DeviceProperties_DeviceOptions:
609 | BlockOptions[] option_list = new BlockOptions[dcp_block_length / 2];
610 | for (int i = 0; i < option_list.Length; i++)
611 | {
612 | ret += DecodeU16(buffer, out tmp);
613 | option_list[i] = (BlockOptions)tmp;
614 | }
615 | content = option_list;
616 | break;
617 | case BlockOptions.DeviceProperties_DeviceRole:
618 | DeviceRoles roles = (DeviceRoles)buffer.ReadByte();
619 | buffer.ReadByte(); //padding
620 | ret += 2;
621 | content = new DeviceRoleInfo(roles);
622 | break;
623 | case BlockOptions.DeviceProperties_DeviceVendor:
624 | ret += DecodeString(buffer, dcp_block_length, out str);
625 | content = str;
626 | break;
627 | case BlockOptions.Control_Response:
628 | set_response = new ResponseStatus();
629 | set_response.Option = (BlockOptions)block_info;
630 | set_response.Error = (BlockErrors)buffer.ReadByte();
631 | ret++;
632 | content = set_response;
633 | break;
634 | default:
635 | byte[] arr;
636 | ret += DecodeOctets(buffer, dcp_block_length, out arr);
637 | content = arr;
638 | break;
639 | }
640 | block = new KeyValuePair(options, content);
641 |
642 | //padding
643 | if ((dcp_block_length % 2) != 0)
644 | {
645 | buffer.ReadByte();
646 | ret++;
647 | }
648 |
649 | return ret;
650 | }
651 |
652 | public static int DecodeAllBlocks(System.IO.Stream buffer, ushort dcp_length, out Dictionary blocks)
653 | {
654 | int ret = 0, r;
655 | KeyValuePair value;
656 | blocks = new Dictionary();
657 | while ((r = DCP.DecodeNextBlock(buffer, (ushort)(dcp_length - ret), out value)) > 0)
658 | {
659 | ret += r;
660 | if (!blocks.ContainsKey(value.Key)) blocks.Add(value.Key, value.Value);
661 | else Trace.TraceError("Multiple blocks in reply: " + value.Key);
662 | }
663 | if (r < 0) return r; //error
664 | else return ret;
665 | }
666 |
667 | public static int EncodeIdentifyRequest(System.IO.Stream buffer, UInt32 Xid)
668 | {
669 | int ret = 0;
670 |
671 | //Header
672 | ret += EncodeHeader(buffer, ServiceIds.Identify_Request, Xid, 1, 4);
673 |
674 | //optional filter (instead of the ALL block)
675 | //[NameOfStationBlock] ^ [AliasNameBlock], IdentifyReqBlock
676 |
677 | //IdentifyReqBlock
678 | /* DeviceRoleBlock ^ DeviceVendorBlock ^ DeviceIDBlock ^
679 | DeviceOptionsBlock ^ OEMDeviceIDBlock ^ MACAddressBlock ^
680 | IPParameterBlock ^ DHCPParameterBlock ^
681 | ManufacturerSpecificParameterBlock */
682 |
683 | //AllSelectorType
684 | ret += EncodeBlock(buffer, BlockOptions.AllSelector_AllSelector, 0);
685 |
686 | return ret;
687 | }
688 |
689 | public static int EncodeSetRequest(System.IO.Stream buffer, UInt32 Xid, BlockOptions options, BlockQualifiers qualifiers, byte[] data)
690 | {
691 | int ret = 0;
692 | int data_length = 0;
693 | bool do_pad = false;
694 |
695 | if (data != null) data_length = data.Length;
696 | if ((data_length % 2) != 0) do_pad = true;
697 |
698 | //The following is modified by F.Chaxel.
699 | //TODO: Test that decode still work
700 |
701 | ret += EncodeHeader(buffer, ServiceIds.Set_Request, Xid, 0, (ushort)(12 + data_length + (do_pad ? 1 : 0)));
702 | ret += EncodeBlock(buffer, options, (ushort)(2 + data_length));
703 |
704 | ret += EncodeU16(buffer, (ushort)0); // Don't care
705 |
706 | //data
707 | EncodeOctets(buffer, data);
708 |
709 | //pad (re-ordered by f.chaxel)
710 | if (do_pad) ret += EncodeU8(buffer, 0);
711 |
712 | //BlockQualifier
713 | ret += EncodeBlock(buffer, BlockOptions.Control_Stop, (ushort)(2));
714 | ret += EncodeU16(buffer, (ushort)qualifiers);
715 |
716 | return ret;
717 | }
718 |
719 | public static int EncodeGetRequest(System.IO.Stream buffer, UInt32 Xid, BlockOptions options)
720 | {
721 | int ret = 0;
722 |
723 | ret += EncodeHeader(buffer, ServiceIds.Get_Request, Xid, 0, 2);
724 | ret += EncodeU16(buffer, (ushort)options);
725 |
726 | return ret;
727 | }
728 |
729 | public static int EncodeHelloRequest(System.IO.Stream buffer, UInt32 Xid)
730 | {
731 | throw new NotImplementedException();
732 | }
733 |
734 | public static int EncodeGetResponse(System.IO.Stream buffer, UInt32 Xid, BlockOptions options, object data)
735 | {
736 | int ret = 0;
737 | long dcp_length;
738 |
739 | ret += EncodeHeader(buffer, ServiceIds.Get_Response, Xid, 0, 0, out dcp_length);
740 | ret += EncodeNextBlock(buffer, new KeyValuePair(options, data));
741 | ReEncodeDCPDataLength(buffer, dcp_length);
742 |
743 | return ret;
744 | }
745 |
746 | public static int EncodeSetResponse(System.IO.Stream buffer, UInt32 Xid, BlockOptions options, BlockErrors status)
747 | {
748 | int ret = 0;
749 | long dcp_length;
750 |
751 | ret += EncodeHeader(buffer, ServiceIds.Set_Response, Xid, 0, 0, out dcp_length);
752 | ret += EncodeNextBlock(buffer, new KeyValuePair(BlockOptions.Control_Response, new ResponseStatus(options, status)));
753 | ReEncodeDCPDataLength(buffer, dcp_length);
754 |
755 | return ret;
756 | }
757 | }
758 | }
759 |
--------------------------------------------------------------------------------
/ProfinetTools.Logic/Protocols/Ethernet.cs:
--------------------------------------------------------------------------------
1 | using System;
2 | using System.Linq;
3 |
4 | namespace ProfinetTools.Logic.Protocols
5 | {
6 | public class Ethernet
7 | {
8 | public enum Type : ushort
9 | {
10 | None = 0,
11 | Loop = 96,
12 | Echo = 512,
13 | IpV4 = 2048,
14 | Arp = 2054,
15 | WakeOnLan = 2114,
16 | ReverseArp = 32821,
17 | AppleTalk = 32923,
18 | AppleTalkArp = 33011,
19 | VLanTaggedFrame = 33024,
20 | NovellInternetworkPacketExchange = 33079,
21 | Novell = 33080,
22 | IpV6 = 34525,
23 | MacControl = 34824,
24 | CobraNet = 34841,
25 | MultiprotocolLabelSwitchingUnicast = 34887,
26 | MultiprotocolLabelSwitchingMulticast = 34888,
27 | PointToPointProtocolOverEthernetDiscoveryStage = 34915,
28 | PointToPointProtocolOverEthernetSessionStage = 34916,
29 | ExtensibleAuthenticationProtocolOverLan = 34958,
30 | HyperScsi = 34970,
31 | AtaOverEthernet = 34978,
32 | EtherCatProtocol = 34980,
33 | ProviderBridging = 34984,
34 | AvbTransportProtocol = 34997,
35 | LLDP = 35020,
36 | SerialRealTimeCommunicationSystemIii = 35021,
37 | CircuitEmulationServicesOverEthernet = 35032,
38 | HomePlug = 35041,
39 | MacSecurity = 35045,
40 | PrecisionTimeProtocol = 35063,
41 | ConnectivityFaultManagementOrOperationsAdministrationManagement = 35074,
42 | FibreChannelOverEthernet = 35078,
43 | FibreChannelOverEthernetInitializationProtocol = 35092,
44 | QInQ = 37120,
45 | VeritasLowLatencyTransport = 51966,
46 | }
47 |
48 | public static int Encode(System.IO.Stream buffer, System.Net.NetworkInformation.PhysicalAddress destination, System.Net.NetworkInformation.PhysicalAddress source, Type type)
49 | {
50 | //destination
51 | DCP.EncodeOctets(buffer, destination.GetAddressBytes());
52 |
53 | //source
54 | DCP.EncodeOctets(buffer, source.GetAddressBytes());
55 |
56 | //type
57 | DCP.EncodeU16(buffer, (ushort)type);
58 |
59 | return 14;
60 | }
61 | }
62 | }
--------------------------------------------------------------------------------
/ProfinetTools.Logic/Protocols/RPC.cs:
--------------------------------------------------------------------------------
1 | using System;
2 | using System.Linq;
3 |
4 | namespace ProfinetTools.Logic.Protocols
5 | {
6 | public class RPC
7 | {
8 | public static Guid UUID_IO_ObjectInstance_XYZ = Guid.Parse("DEA00000-6C97-11D1-8271-000000000000");
9 | public static Guid UUID_IO_DeviceInterface = Guid.Parse("DEA00001-6C97-11D1-8271-00A02442DF7D");
10 | public static Guid UUID_IO_ControllerInterface = Guid.Parse("DEA00002-6C97-11D1-8271-00A02442DF7D");
11 | public static Guid UUID_IO_SupervisorInterface = Guid.Parse("DEA00003-6C97-11D1-8271-00A02442DF7D");
12 | public static Guid UUID_IO_ParameterServerInterface = Guid.Parse("DEA00004-6C97-11D1-8271-00A02442DF7D");
13 | public static Guid UUID_EPMap_Interface = Guid.Parse("E1AF8308-5D1F-11C9-91A4-08002B14A0FA");
14 | public static Guid UUID_EPMap_Object = Guid.Parse("00000000-0000-0000-0000-000000000000");
15 |
16 | public enum PacketTypes : byte
17 | {
18 | Request = 0,
19 | Ping = 1,
20 | Response = 2,
21 | Fault = 3,
22 | Working = 4,
23 | NoCall = 5,
24 | Reject = 6,
25 | Acknowledge = 7,
26 | ConnectionlessCancel = 8,
27 | FragmentAcknowledge = 9,
28 | CancelAcknowledge = 10,
29 | }
30 |
31 | [Flags]
32 | public enum Flags1 : byte
33 | {
34 | LastFragment = 2,
35 | Fragment = 4,
36 | NoFragmentAckRequested = 8,
37 | Maybe = 16,
38 | Idempotent = 32,
39 | Broadcast = 64,
40 | }
41 |
42 | [Flags]
43 | public enum Flags2 : byte
44 | {
45 | CancelPendingAtCallEnd = 2,
46 | }
47 |
48 | [Flags]
49 | public enum Encodings : ushort
50 | {
51 | ASCII = 0x000,
52 | EBCDIC = 0x100,
53 | BigEndian = 0x000,
54 | LittleEndian = 0x1000,
55 | IEEE_float = 0,
56 | VAX_float = 1,
57 | CRAY_float = 2,
58 | IBM_float = 3,
59 | }
60 |
61 | public enum Operations : ushort
62 | {
63 | //IO device
64 | Connect = 0,
65 | Release = 1,
66 | Read = 2,
67 | Write = 3,
68 | Control = 4,
69 | ReadImplicit = 5,
70 |
71 | //Endpoint mapper
72 | Insert = 0,
73 | Delete = 1,
74 | Lookup = 2,
75 | Map = 3,
76 | LookupHandleFree = 4,
77 | InqObject = 5,
78 | MgmtDelete = 6,
79 | }
80 |
81 | public static Guid GenerateObjectInstanceUUID(UInt16 InstanceNo, byte InterfaceNo, UInt16 DeviceId, UInt16 VendorId)
82 | {
83 | byte[] bytes = UUID_IO_ObjectInstance_XYZ.ToByteArray();
84 | UInt32 Data1 = BitConverter.ToUInt32(bytes, 0);
85 | UInt16 Data2 = BitConverter.ToUInt16(bytes, 4);
86 | UInt16 Data3 = BitConverter.ToUInt16(bytes, 6);
87 | byte Data4 = bytes[8];
88 | byte Data5 = bytes[9];
89 | InstanceNo &= 0xFFF;
90 | InstanceNo |= (UInt16)(InterfaceNo << 12);
91 | Guid ret = new Guid(Data1, Data2, Data3, Data4, Data5, (byte)(InstanceNo >> 8), (byte)(InstanceNo & 0xFF), (byte)(DeviceId >> 8), (byte)(DeviceId & 0xFF), (byte)(VendorId >> 8), (byte)(VendorId & 0xFF));
92 | return ret;
93 | }
94 |
95 | public static int EncodeU32(System.IO.Stream buffer, Encodings encoding, UInt32 value)
96 | {
97 | if ((encoding & Encodings.LittleEndian) == Encodings.BigEndian)
98 | {
99 | buffer.WriteByte((byte)((value & 0xFF000000) >> 24));
100 | buffer.WriteByte((byte)((value & 0x00FF0000) >> 16));
101 | buffer.WriteByte((byte)((value & 0x0000FF00) >> 08));
102 | buffer.WriteByte((byte)((value & 0x000000FF) >> 00));
103 | }
104 | else
105 | {
106 | buffer.WriteByte((byte)((value & 0x000000FF) >> 00));
107 | buffer.WriteByte((byte)((value & 0x0000FF00) >> 08));
108 | buffer.WriteByte((byte)((value & 0x00FF0000) >> 16));
109 | buffer.WriteByte((byte)((value & 0xFF000000) >> 24));
110 | }
111 | return 4;
112 | }
113 |
114 | public static int DecodeU32(System.IO.Stream buffer, Encodings encoding, out UInt32 value)
115 | {
116 | if ((encoding & Encodings.LittleEndian) == Encodings.BigEndian)
117 | {
118 | value = (UInt32)((buffer.ReadByte() << 24) | (buffer.ReadByte() << 16) | (buffer.ReadByte() << 8) | (buffer.ReadByte() << 0));
119 | }
120 | else
121 | {
122 | value = (UInt32)((buffer.ReadByte() << 0) | (buffer.ReadByte() << 8) | (buffer.ReadByte() << 16) | (buffer.ReadByte() << 24));
123 | }
124 | return 4;
125 | }
126 |
127 | public static int EncodeU16(System.IO.Stream buffer, Encodings encoding, UInt16 value)
128 | {
129 | if ((encoding & Encodings.LittleEndian) == Encodings.BigEndian)
130 | {
131 | buffer.WriteByte((byte)((value & 0x0000FF00) >> 08));
132 | buffer.WriteByte((byte)((value & 0x000000FF) >> 00));
133 | }
134 | else
135 | {
136 | buffer.WriteByte((byte)((value & 0x000000FF) >> 00));
137 | buffer.WriteByte((byte)((value & 0x0000FF00) >> 08));
138 | }
139 | return 2;
140 | }
141 |
142 | public static int DecodeU16(System.IO.Stream buffer, Encodings encoding, out UInt16 value)
143 | {
144 | if ((encoding & Encodings.LittleEndian) == Encodings.BigEndian)
145 | {
146 | value = (UInt16)((buffer.ReadByte() << 8) | (buffer.ReadByte() << 0));
147 | }
148 | else
149 | {
150 | value = (UInt16)((buffer.ReadByte() << 0) | (buffer.ReadByte() << 8));
151 | }
152 | return 2;
153 | }
154 |
155 | public static int EncodeGuid(System.IO.Stream buffer, Encodings encoding, Guid value)
156 | {
157 | int ret = 0;
158 | byte[] bytes = value.ToByteArray();
159 | UInt32 Data1 = BitConverter.ToUInt32(bytes, 0);
160 | UInt16 Data2 = BitConverter.ToUInt16(bytes, 4);
161 | UInt16 Data3 = BitConverter.ToUInt16(bytes, 6);
162 | byte[] Data4 = new byte[8];
163 | Array.Copy(bytes, 8, Data4, 0, 8);
164 | ret += EncodeU32(buffer, encoding, Data1);
165 | ret += EncodeU16(buffer, encoding, Data2);
166 | ret += EncodeU16(buffer, encoding, Data3);
167 | ret += DCP.EncodeOctets(buffer, Data4);
168 | return ret;
169 | }
170 |
171 | public static int DecodeGuid(System.IO.Stream buffer, Encodings encoding, out Guid value)
172 | {
173 | int ret = 0;
174 | UInt32 Data1;
175 | UInt16 Data2;
176 | UInt16 Data3;
177 | byte[] Data4 = new byte[8];
178 |
179 | ret += DecodeU32(buffer, encoding, out Data1);
180 | ret += DecodeU16(buffer, encoding, out Data2);
181 | ret += DecodeU16(buffer, encoding, out Data3);
182 | buffer.Read(Data4, 0, Data4.Length);
183 | ret += Data4.Length;
184 |
185 | value = new Guid((int)Data1, (short)Data2, (short)Data3, Data4);
186 |
187 | return ret;
188 | }
189 |
190 | public static int EncodeHeader(System.IO.Stream buffer, PacketTypes type, Flags1 flags1, Flags2 flags2, Encodings encoding, UInt16 serial_high_low, Guid object_id, Guid interface_id, Guid activity_id, UInt32 server_boot_time, UInt32 sequence_no, Operations op, UInt16 body_length, UInt16 fragment_no, out long body_length_position)
191 | {
192 | int ret = 0;
193 |
194 | ret += DCP.EncodeU8(buffer, 4); //RPCVersion
195 | ret += DCP.EncodeU8(buffer, (byte)type);
196 | ret += DCP.EncodeU8(buffer, (byte)flags1);
197 | ret += DCP.EncodeU8(buffer, (byte)flags2);
198 | ret += DCP.EncodeU16(buffer, (ushort)encoding);
199 | ret += DCP.EncodeU8(buffer, 0); //pad
200 | ret += DCP.EncodeU8(buffer, (byte)(serial_high_low >> 8));
201 | ret += EncodeGuid(buffer, encoding, object_id);
202 | ret += EncodeGuid(buffer, encoding, interface_id);
203 | ret += EncodeGuid(buffer, encoding, activity_id);
204 | ret += EncodeU32(buffer, encoding, server_boot_time);
205 | ret += EncodeU32(buffer, encoding, 1); //interface version
206 | ret += EncodeU32(buffer, encoding, sequence_no);
207 | ret += EncodeU16(buffer, encoding, (ushort)op);
208 | ret += EncodeU16(buffer, encoding, 0xFFFF); //interface hint
209 | ret += EncodeU16(buffer, encoding, 0xFFFF); //activity hint
210 | body_length_position = buffer.Position;
211 | ret += EncodeU16(buffer, encoding, body_length);
212 | ret += EncodeU16(buffer, encoding, fragment_no);
213 | ret += DCP.EncodeU8(buffer, 0); //authentication protocol
214 | ret += DCP.EncodeU8(buffer, (byte)(serial_high_low & 0xFF));
215 |
216 | return ret;
217 | }
218 |
219 | public static int DecodeHeader(System.IO.Stream buffer, out PacketTypes type, out Flags1 flags1, out Flags2 flags2, out Encodings encoding, out UInt16 serial_high_low, out Guid object_id, out Guid interface_id, out Guid activity_id, out UInt32 server_boot_time, out UInt32 sequence_no, out Operations op, out UInt16 body_length, out UInt16 fragment_no)
220 | {
221 | int ret = 0;
222 | byte tmp1;
223 | UInt16 tmp2;
224 | UInt32 tmp3;
225 |
226 | serial_high_low = 0;
227 |
228 | ret += DCP.DecodeU8(buffer, out tmp1); //RPCVersion
229 | if (tmp1 != 4) throw new Exception("Wrong protocol");
230 | ret += DCP.DecodeU8(buffer, out tmp1);
231 | type = (PacketTypes)tmp1;
232 | ret += DCP.DecodeU8(buffer, out tmp1);
233 | flags1 = (Flags1)tmp1;
234 | ret += DCP.DecodeU8(buffer, out tmp1);
235 | flags2 = (Flags2)tmp1;
236 | ret += DCP.DecodeU16(buffer, out tmp2);
237 | encoding = (Encodings)tmp2;
238 | ret += DCP.DecodeU8(buffer, out tmp1); //pad
239 | ret += DCP.DecodeU8(buffer, out tmp1);
240 | serial_high_low |= (UInt16)(tmp1 << 8);
241 | ret += DecodeGuid(buffer, encoding, out object_id);
242 | ret += DecodeGuid(buffer, encoding, out interface_id);
243 | ret += DecodeGuid(buffer, encoding, out activity_id);
244 | ret += DecodeU32(buffer, encoding, out server_boot_time);
245 | ret += DecodeU32(buffer, encoding, out tmp3); //interface version
246 | if ((tmp3 & 0xFFFF) != 1) throw new Exception("Wrong protocol version");
247 | ret += DecodeU32(buffer, encoding, out sequence_no);
248 | ret += DecodeU16(buffer, encoding, out tmp2);
249 | op = (Operations)tmp2;
250 | ret += DecodeU16(buffer, encoding, out tmp2); //interface hint
251 | ret += DecodeU16(buffer, encoding, out tmp2); //activity hint
252 | ret += DecodeU16(buffer, encoding, out body_length);
253 | ret += DecodeU16(buffer, encoding, out fragment_no);
254 | ret += DCP.DecodeU8(buffer, out tmp1); //authentication protocol
255 | ret += DCP.DecodeU8(buffer, out tmp1);
256 | serial_high_low |= tmp1;
257 |
258 | return ret;
259 | }
260 |
261 | public static void ReEncodeHeaderLength(System.IO.Stream buffer, Encodings encoding, long body_length_position)
262 | {
263 | long current_pos = buffer.Position;
264 | UInt16 actual_length = (UInt16)(buffer.Position - body_length_position - 6);
265 |
266 | buffer.Position = body_length_position;
267 | EncodeU16(buffer, encoding, actual_length);
268 |
269 | buffer.Position = current_pos;
270 | }
271 |
272 | public static int EncodeNDRDataHeader(System.IO.Stream buffer, Encodings encoding, UInt32 ArgsMaximum_or_PNIOStatus, UInt32 ArgsLength, UInt32 MaximumCount, UInt32 Offset, UInt32 ActualCount, out long NDRDataHeader_position)
273 | {
274 | int ret = 0;
275 |
276 | NDRDataHeader_position = buffer.Position;
277 | ret += EncodeU32(buffer, encoding, ArgsMaximum_or_PNIOStatus);
278 | ret += EncodeU32(buffer, encoding, ArgsLength);
279 | ret += EncodeU32(buffer, encoding, MaximumCount);
280 | ret += EncodeU32(buffer, encoding, Offset);
281 | ret += EncodeU32(buffer, encoding, ActualCount);
282 |
283 | return ret;
284 | }
285 |
286 | public static int DecodeNDRDataHeader(System.IO.Stream buffer, Encodings encoding, out UInt32 ArgsMaximum_or_PNIOStatus, out UInt32 ArgsLength, out UInt32 MaximumCount, out UInt32 Offset, out UInt32 ActualCount)
287 | {
288 | int ret = 0;
289 |
290 | ret += DecodeU32(buffer, encoding, out ArgsMaximum_or_PNIOStatus);
291 | ret += DecodeU32(buffer, encoding, out ArgsLength);
292 | ret += DecodeU32(buffer, encoding, out MaximumCount);
293 | ret += DecodeU32(buffer, encoding, out Offset);
294 | ret += DecodeU32(buffer, encoding, out ActualCount);
295 |
296 | return ret;
297 | }
298 |
299 | public static void ReEncodeNDRDataHeaderLength(System.IO.Stream buffer, Encodings encoding, long NDRDataHeader_position, bool re_encode_pniostatus)
300 | {
301 | long current_pos = buffer.Position;
302 | UInt32 actual_length = (UInt32)(buffer.Position - NDRDataHeader_position - 20);
303 |
304 | buffer.Position = NDRDataHeader_position;
305 | if (re_encode_pniostatus) EncodeU32(buffer, encoding, actual_length); //ArgsMaximum/PNIOStatus
306 | else buffer.Position += 4;
307 | EncodeU32(buffer, encoding, actual_length); //ArgsLength
308 | EncodeU32(buffer, encoding, actual_length); //MaximumCount
309 | buffer.Position += 4;
310 | EncodeU32(buffer, encoding, actual_length); //ActualCount
311 |
312 | buffer.Position = current_pos;
313 | }
314 | }
315 | }
--------------------------------------------------------------------------------
/ProfinetTools.Logic/Protocols/RT.cs:
--------------------------------------------------------------------------------
1 | using System;
2 | using System.Linq;
3 |
4 | namespace ProfinetTools.Logic.Protocols
5 | {
6 | public class RT
7 | {
8 | public enum FrameIds : ushort
9 | {
10 | PTCP_RTSyncPDU_With_Follow_Up = 0x20,
11 | PTCP_RTSyncPDU = 0x80,
12 | Alarm_High = 0xFC01,
13 | Alarm_Low = 0xFE01,
14 | DCP_Hello_ReqPDU = 0xFEFC,
15 | DCP_Get_Set_PDU = 0xFEFD,
16 | DCP_Identify_ReqPDU = 0xFEFE,
17 | DCP_Identify_ResPDU = 0xFEFF,
18 | PTCP_AnnouncePDU = 0xFF00,
19 | PTCP_FollowUpPDU = 0xFF20,
20 | PTCP_DelayReqPDU = 0xFF40,
21 | PTCP_DelayResPDU_With_Follow_Up = 0xFF41,
22 | PTCP_DelayFuResPDU_With_Follow_Up = 0xFF42,
23 | PTCP_DelayResPDU = 0xFF43,
24 | RTC_Start = 0xC000,
25 | RTC_End = 0xF7FF,
26 | }
27 |
28 | public const string MulticastMACAdd_Identify_Address = "01-0E-CF-00-00-00";
29 | public const string MulticastMACAdd_Hello_Address = "01-0E-CF-00-00-01";
30 | public const string MulticastMACAdd_Range1_Destination_Address = "01-0E-CF-00-01-01";
31 | public const string MulticastMACAdd_Range1_Invalid_Address = "01-0E-CF-00-01-02";
32 | public const string PTCP_MulticastMACAdd_Range2_Clock_Synchronization_Address = "01-0E-CF-00-04-00";
33 | public const string PTCP_MulticastMACAdd_Range3_Clock_Synchronization_Address = "01-0E-CF-00-04-20";
34 | public const string PTCP_MulticastMACAdd_Range4_Clock_Synchronization_Address = "01-0E-CF-00-04-40";
35 | public const string PTCP_MulticastMACAdd_Range6_Clock_Synchronization_Address = "01-0E-CF-00-04-80";
36 | public const string PTCP_MulticastMACAdd_Range8_Address = "01-80-C2-00-00-0E";
37 | public const string RTC_PDU_RT_CLASS_3_Destination_Address = "01-0E-CF-00-01-01";
38 | public const string RTC_PDU_RT_CLASS_3_Invalid_Address = "01-0E-CF-00-01-02";
39 |
40 | public static int EncodeFrameId(System.IO.Stream buffer, FrameIds value)
41 | {
42 | return DCP.EncodeU16(buffer, (ushort)value);
43 | }
44 |
45 | public static int DecodeFrameId(System.IO.Stream buffer, out FrameIds value)
46 | {
47 | ushort val;
48 | DCP.DecodeU16(buffer, out val);
49 | value = (FrameIds)val;
50 | return 2;
51 | }
52 |
53 | [Flags]
54 | public enum DataStatus : byte
55 | {
56 | State_Primary = 1, /* 0 is Backup */
57 | Redundancy_Backup = 2, /* 0 is Primary */
58 | DataItemValid = 4, /* 0 is invalid */
59 | ProviderState_Run = 1 << 4, /* 0 is stop */
60 | StationProblemIndicator_Normal = 1 << 5, /* 0 is Detected */
61 | Ignore = 1 << 7, /* 0 is Evaluate */
62 | }
63 |
64 | [Flags]
65 | public enum TransferStatus : byte
66 | {
67 | OK = 0,
68 | AlignmentOrFrameChecksumError = 1,
69 | WrongLengthError = 2,
70 | MACReceiveBufferOverflow = 4,
71 | RT_CLASS_3_Error = 8,
72 | }
73 |
74 | [Flags]
75 | public enum IOxS : byte
76 | {
77 | Extension_MoreIOxSOctetFollows = 1,
78 | Instance_DetectedBySubslot = 0 << 5,
79 | Instance_DetectedBySlot = 1 << 5,
80 | Instance_DetectedByIODevice = 2 << 5,
81 | Instance_DetectedByIOController = 3 << 5,
82 | DataState_Good = 1 << 7,
83 | }
84 |
85 | [Flags]
86 | public enum PDUTypes : byte
87 | {
88 | //0x00 Reserved —
89 | Data = 1, //Shall only be used to encode the DATA-RTA-PDU
90 | Nack = 2, //Shall only be used to encode the NACK-RTA-PDU
91 | Ack = 3, //Shall only be used to encode the ACK-RTA-PDU
92 | Err = 4, //Shall only be used to encode the ERR-RTA-PDU
93 | //0x05 – 0x0F Reserved —
94 | Version1 = 1 << 4,
95 | }
96 |
97 | [Flags]
98 | public enum AddFlags : byte
99 | {
100 | WindowSizeOne = 1,
101 | TACK_ImmediateAcknowledge = 1 << 4,
102 | }
103 |
104 | public static int DecodeRTCStatus(System.IO.Stream buffer, out UInt16 CycleCounter, out DataStatus DataStatus, out TransferStatus TransferStatus)
105 | {
106 | int ret = 0;
107 | byte tmp;
108 |
109 | ret += DCP.DecodeU16(buffer, out CycleCounter);
110 | ret += DCP.DecodeU8(buffer, out tmp);
111 | DataStatus = (DataStatus)tmp;
112 | ret += DCP.DecodeU8(buffer, out tmp);
113 | TransferStatus = (TransferStatus)tmp;
114 |
115 | return ret;
116 | }
117 |
118 | public static int EncodeRTCStatus(System.IO.Stream buffer, UInt16 CycleCounter, DataStatus DataStatus, TransferStatus TransferStatus)
119 | {
120 | int ret = 0;
121 |
122 | ret += DCP.EncodeU16(buffer, CycleCounter);
123 | ret += DCP.EncodeU8(buffer, (byte)DataStatus);
124 | ret += DCP.EncodeU8(buffer, (byte)TransferStatus);
125 |
126 | return ret;
127 | }
128 |
129 | public static int DecodeRTAHeader(System.IO.Stream buffer, out UInt16 AlarmDestinationEndpoint, out UInt16 AlarmSourceEndpoint, out PDUTypes PDUType, out AddFlags AddFlags, out UInt16 SendSeqNum, out UInt16 AckSeqNum, out UInt16 VarPartLen)
130 | {
131 | int ret = 0;
132 | byte tmp;
133 |
134 | ret += DCP.DecodeU16(buffer, out AlarmDestinationEndpoint);
135 | ret += DCP.DecodeU16(buffer, out AlarmSourceEndpoint);
136 | ret += DCP.DecodeU8(buffer, out tmp);
137 | PDUType = (PDUTypes)tmp;
138 | ret += DCP.DecodeU8(buffer, out tmp);
139 | AddFlags = (AddFlags)tmp;
140 | ret += DCP.DecodeU16(buffer, out SendSeqNum);
141 | ret += DCP.DecodeU16(buffer, out AckSeqNum);
142 | ret += DCP.DecodeU16(buffer, out VarPartLen);
143 |
144 | return ret;
145 | }
146 | }
147 | }
--------------------------------------------------------------------------------
/ProfinetTools.Logic/Protocols/VLAN.cs:
--------------------------------------------------------------------------------
1 | using System;
2 | using System.Linq;
3 |
4 | namespace ProfinetTools.Logic.Protocols
5 | {
6 | public class VLAN
7 | {
8 | public enum Priorities
9 | {
10 | ///
11 | /// DCP, IP
12 | ///
13 | Priority0 = 0,
14 | ///
15 | /// Low prior RTA_CLASS_1 or RTA_CLASS_UDP
16 | ///
17 | Priority5 = 5,
18 | ///
19 | /// RT_CLASS_UDP, RT_CLASS_1, RT_CLASS_2, RT_CLASS_3, high prior RTA_CLASS_1 or RTA_CLASS_UDP
20 | ///
21 | Priority6 = 6,
22 | ///
23 | /// PTCP-AnnouncePDU
24 | ///
25 | Priority7 = 7,
26 | }
27 |
28 | public enum Type : ushort
29 | {
30 | ///
31 | /// UDP, RPC, SNMP, ICMP
32 | ///
33 | IP = 0x0800,
34 | ARP = 0x0806,
35 | TagControlInformation = 0x8100,
36 | ///
37 | /// RTC, RTA, DCP, PTCP, FRAG
38 | ///
39 | PN = 0x8892,
40 | IEEE_802_1AS = 0x88F7,
41 | LLDP = 0x88CC,
42 | MRP = 0x88E3,
43 | }
44 |
45 | public static int Encode(System.IO.Stream buffer, Priorities priority, Type type)
46 | {
47 | UInt16 tmp = 0;
48 |
49 | //Priority
50 | tmp |= (UInt16)((((UInt16)priority) & 0x7) << 13);
51 |
52 | //CanonicalFormatIdentificator
53 | tmp |= 0 << 12;
54 |
55 | //VLAN_Id
56 | tmp |= 0;
57 |
58 | DCP.EncodeU16(buffer, tmp);
59 | DCP.EncodeU16(buffer, (UInt16)type);
60 |
61 | return 4;
62 | }
63 | }
64 | }
--------------------------------------------------------------------------------
/ProfinetTools.Logic/Services/AdaptersService.cs:
--------------------------------------------------------------------------------
1 | using System;
2 | using System.Collections.Generic;
3 | using System.Reactive.Linq;
4 | using System.Reactive.Subjects;
5 | using ProfinetTools.Interfaces.Services;
6 | using SharpPcap;
7 |
8 | namespace ProfinetTools.Logic.Services
9 | {
10 | public class AdaptersService : IAdaptersService
11 | {
12 | private readonly BehaviorSubject selectedAdapterSubject = new BehaviorSubject(null);
13 | public List GetAdapters()
14 | {
15 | var devices = new List();
16 |
17 | try
18 | {
19 | foreach (ICaptureDevice dev in CaptureDeviceList.Instance)
20 | devices.Add(dev);
21 | }
22 | catch (Exception e)
23 | {
24 | Console.WriteLine(e);
25 | }
26 |
27 | return devices;
28 | }
29 |
30 | public void SelectAdapter(ICaptureDevice adapter)
31 | {
32 | selectedAdapterSubject.OnNext(adapter);
33 | }
34 |
35 | public IObservable SelectedAdapter => selectedAdapterSubject.AsObservable();
36 | }
37 | }
--------------------------------------------------------------------------------
/ProfinetTools.Logic/Services/DeviceService.cs:
--------------------------------------------------------------------------------
1 | using System;
2 | using System.Collections.Generic;
3 | using System.Linq;
4 | using System.Reactive.Disposables;
5 | using System.Reactive.Linq;
6 | using System.Reactive.Subjects;
7 | using System.Threading;
8 | using System.Threading.Tasks;
9 | using ProfinetTools.Interfaces.Extensions;
10 | using ProfinetTools.Interfaces.Models;
11 | using ProfinetTools.Interfaces.Services;
12 | using ProfinetTools.Logic.Protocols;
13 | using ProfinetTools.Logic.Transport;
14 | using SharpPcap;
15 |
16 | namespace ProfinetTools.Logic.Services
17 | {
18 | public class DeviceService : IDeviceService
19 | {
20 | public async Task> GetDevices(ICaptureDevice adapter, TimeSpan timeout)
21 | {
22 | var disposables = new CompositeDisposable();
23 | var transport = new ProfinetEthernetTransport(adapter);
24 | transport.Open();
25 | transport.AddDisposableTo(disposables);
26 |
27 | var devices = new List();
28 |
29 | Observable.FromEventPattern(h => transport.OnDcpMessage += h, h => transport.OnDcpMessage -= h)
30 | .Select(x => ConvertEventToDevice(x.Sender, x.EventArgs))
31 | .Where(device => devices!=null)
32 | .Do(device => devices.Add(device))
33 | .Subscribe()
34 | .AddDisposableTo(disposables)
35 | ;
36 |
37 | transport.SendIdentifyBroadcast();
38 |
39 | await Task.Delay(timeout);
40 |
41 | disposables.Dispose();
42 |
43 | return devices;
44 | }
45 |
46 | private readonly BehaviorSubject selectedDeviceSubject = new BehaviorSubject(null);
47 |
48 | public void SelectDevice(Device device)
49 | {
50 | selectedDeviceSubject.OnNext(device);
51 | }
52 |
53 | public IObservable SelectedDevice => selectedDeviceSubject.AsObservable();
54 |
55 | private Device ConvertEventToDevice(ConnectionInfoEthernet sender, DcpMessageArgs args)
56 | {
57 | try
58 | {
59 | var device = new Device()
60 | {
61 | MAC = sender.Source.ToString(),
62 | Name = (string)args.Blocks[DCP.BlockOptions.DeviceProperties_NameOfStation],
63 | IP = ((DCP.IpInfo)args.Blocks[DCP.BlockOptions.IP_IPParameter]).Ip.ToString(),
64 | SubnetMask = ((DCP.IpInfo)args.Blocks[DCP.BlockOptions.IP_IPParameter]).SubnetMask.ToString(),
65 | Gateway = ((DCP.IpInfo)args.Blocks[DCP.BlockOptions.IP_IPParameter]).Gateway.ToString(),
66 | Type = (string)args.Blocks[DCP.BlockOptions.DeviceProperties_DeviceVendor],
67 | Role = ((DCP.DeviceRoleInfo)args.Blocks[DCP.BlockOptions.DeviceProperties_DeviceRole]).ToString()
68 | };
69 | return device;
70 | }
71 | catch (Exception e)
72 | {
73 | Console.WriteLine(e);
74 | return null;
75 | }
76 | }
77 | }
78 | }
--------------------------------------------------------------------------------
/ProfinetTools.Logic/Services/SettingsService.cs:
--------------------------------------------------------------------------------
1 | using System;
2 | using System.Reactive.Disposables;
3 | using System.Threading.Tasks;
4 | using ProfinetTools.Interfaces.Extensions;
5 | using ProfinetTools.Interfaces.Models;
6 | using ProfinetTools.Interfaces.Services;
7 | using ProfinetTools.Logic.Protocols;
8 | using ProfinetTools.Logic.Transport;
9 | using SharpPcap;
10 |
11 | namespace ProfinetTools.Logic.Services
12 | {
13 | public class SettingsService : ISettingsService
14 | {
15 | private readonly int timeoutInMilliseconds = 3000;
16 | private readonly int retries = 2;
17 |
18 | public bool TryParseNetworkConfiguration(Device device)
19 | {
20 | try
21 | {
22 | System.Net.IPAddress ip = System.Net.IPAddress.Parse(device.IP);
23 | System.Net.IPAddress subnet = System.Net.IPAddress.Parse(device.SubnetMask);
24 | System.Net.IPAddress gateway = System.Net.IPAddress.Parse(device.Gateway);
25 |
26 | return true;
27 | }
28 | catch (Exception e)
29 | {
30 | return false;
31 | }
32 | }
33 |
34 | public Task SendSettings(ICaptureDevice adapter, string macAddress, Device newSettings)
35 | {
36 | var disposables = new CompositeDisposable();
37 | var transport = new ProfinetEthernetTransport(adapter);
38 | transport.Open();
39 | transport.AddDisposableTo(disposables);
40 |
41 |
42 | try
43 | {
44 | System.Net.NetworkInformation.PhysicalAddress deviceAddress = System.Net.NetworkInformation.PhysicalAddress.Parse(macAddress);
45 |
46 | DCP.BlockErrors err = transport.SendSetNameRequest(deviceAddress, timeoutInMilliseconds, retries, newSettings.Name);
47 | if (err != DCP.BlockErrors.NoError) return Task.FromResult(new SaveResult(false, err.ToString()));
48 |
49 | System.Net.IPAddress ip = System.Net.IPAddress.Parse(newSettings.IP);
50 | System.Net.IPAddress subnet = System.Net.IPAddress.Parse(newSettings.SubnetMask);
51 | System.Net.IPAddress gateway = System.Net.IPAddress.Parse(newSettings.Gateway);
52 | err = transport.SendSetIpRequest(deviceAddress, timeoutInMilliseconds, retries, ip, subnet, gateway);
53 | if (err != DCP.BlockErrors.NoError) return Task.FromResult(new SaveResult(false, err.ToString()));
54 |
55 | return Task.FromResult(new SaveResult(true, err.ToString()));
56 | }
57 | catch (Exception e)
58 | {
59 | return Task.FromResult(new SaveResult(false, e.Message));
60 | }
61 | finally
62 | {
63 | disposables.Dispose();
64 | }
65 | }
66 |
67 | public Task FactoryReset(ICaptureDevice adapter, string deviceName)
68 | {
69 | var disposables = new CompositeDisposable();
70 | var transport = new ProfinetEthernetTransport(adapter);
71 | transport.Open();
72 | transport.AddDisposableTo(disposables);
73 |
74 | System.Net.NetworkInformation.PhysicalAddress deviceAddress = System.Net.NetworkInformation.PhysicalAddress.Parse(deviceName);
75 |
76 | try
77 | {
78 | DCP.BlockErrors err = transport.SendSetResetRequest(deviceAddress, timeoutInMilliseconds, retries);
79 | if (err != DCP.BlockErrors.NoError) return Task.FromResult(new SaveResult(false, err.ToString()));
80 |
81 | return Task.FromResult(new SaveResult(false, err.ToString()));
82 | }
83 | catch (Exception e)
84 | {
85 | return Task.FromResult(new SaveResult(false, e.Message));
86 | }
87 | finally
88 | {
89 | disposables.Dispose();
90 | }
91 | }
92 | }
93 | }
--------------------------------------------------------------------------------
/ProfinetTools.Logic/Transport/ConnectionInfoEthernet.cs:
--------------------------------------------------------------------------------
1 | using System;
2 | using System.Net.NetworkInformation;
3 |
4 | namespace ProfinetTools.Logic.Transport
5 | {
6 | public class ConnectionInfoEthernet
7 | {
8 | public ProfinetEthernetTransport Adapter;
9 | public PhysicalAddress Destination;
10 | public PhysicalAddress Source;
11 | public ConnectionInfoEthernet(ProfinetEthernetTransport adapter, PhysicalAddress destination, PhysicalAddress source)
12 | {
13 | Adapter = adapter;
14 | Destination = destination;
15 | Source = source;
16 | }
17 | }
18 | }
--------------------------------------------------------------------------------
/ProfinetTools.Logic/Transport/DcpMessageArgs.cs:
--------------------------------------------------------------------------------
1 | using System;
2 | using System.Collections.Generic;
3 | using System.Linq;
4 | using ProfinetTools.Logic.Protocols;
5 |
6 | namespace ProfinetTools.Logic.Transport
7 | {
8 | public class DcpMessageArgs
9 | {
10 | public DCP.ServiceIds ServiceID { get; }
11 | public uint Xid { get; }
12 | public ushort ResponseDelayFactor { get; }
13 | public Dictionary Blocks { get; }
14 |
15 | public DcpMessageArgs(DCP.ServiceIds serviceID, uint xid, ushort responseDelayFactor, Dictionary blocks)
16 | {
17 | ServiceID = serviceID;
18 | Xid = xid;
19 | ResponseDelayFactor = responseDelayFactor;
20 | Blocks = blocks;
21 | }
22 | }
23 | }
--------------------------------------------------------------------------------
/ProfinetTools.Logic/Transport/ProfinetEthernetTransport.cs:
--------------------------------------------------------------------------------
1 | using System;
2 | using System.Collections.Generic;
3 | using System.Diagnostics;
4 | using System.IO;
5 | using System.Linq;
6 | using System.Net;
7 | using System.Net.NetworkInformation;
8 | using System.Text;
9 | using ProfinetTools.Logic.Protocols;
10 | using SharpPcap;
11 |
12 | namespace ProfinetTools.Logic.Transport
13 | {
14 | public class ProfinetEthernetTransport : IDisposable
15 | {
16 | private ICaptureDevice adapter;
17 | private UInt32 lastXid = 0;
18 | private bool isOpen = false;
19 |
20 | public delegate void OnDcpMessageHandler(ConnectionInfoEthernet sender, DcpMessageArgs args);
21 | public event OnDcpMessageHandler OnDcpMessage;
22 | public delegate void OnAcyclicMessageHandler(ConnectionInfoEthernet sender, UInt16 alarmDestinationEndpoint, UInt16 alarmSourceEndpoint, RT.PDUTypes pduType, RT.AddFlags addFlags, UInt16 sendSeqNum, UInt16 ackSeqNum, UInt16 varPartLen, Stream data);
23 | public event OnAcyclicMessageHandler OnAcyclicMessage;
24 | public delegate void OnCyclicMessageHandler(ConnectionInfoEthernet sender, UInt16 cycleCounter, RT.DataStatus dataStatus, RT.TransferStatus transferStatus, Stream data, int dataLength);
25 | public event OnCyclicMessageHandler OnCyclicMessage;
26 |
27 | public bool IsOpen => isOpen;
28 | public ICaptureDevice Adapter => adapter;
29 |
30 | public ProfinetEthernetTransport(ICaptureDevice adapter)
31 | {
32 | this.adapter = adapter;
33 | this.adapter.OnPacketArrival += new PacketArrivalEventHandler(m_adapter_OnPacketArrival);
34 | }
35 |
36 | ///
37 | /// Will return pcap version. Use this to validate installed pcap library
38 | ///
39 | public static string PcapVersion
40 | {
41 | get
42 | {
43 | try
44 | {
45 | return SharpPcap.Pcap.Version;
46 | }
47 | catch { }
48 | return "";
49 | }
50 | }
51 |
52 | public void Open()
53 | {
54 | if (isOpen) return;
55 | if (adapter is SharpPcap.WinPcap.WinPcapDevice)
56 | ((SharpPcap.WinPcap.WinPcapDevice)adapter).Open(SharpPcap.WinPcap.OpenFlags.MaxResponsiveness | SharpPcap.WinPcap.OpenFlags.NoCaptureLocal, -1);
57 | else
58 | adapter.Open(DeviceMode.Normal);
59 | adapter.Filter = "ether proto 0x8892 or vlan 0";
60 | adapter.StartCapture();
61 | isOpen = true;
62 | System.Threading.Thread.Sleep(50); //let the pcap start up
63 | }
64 |
65 | public void Close()
66 | {
67 | if (!isOpen) return;
68 | try
69 | {
70 | adapter.StopCapture();
71 | }
72 | catch
73 | {
74 | }
75 | isOpen = false;
76 | }
77 |
78 | public void Dispose()
79 | {
80 | if (adapter != null)
81 | {
82 | Close();
83 | adapter.Close();
84 | adapter = null;
85 | }
86 | }
87 |
88 | public static DCP.IpInfo GetPcapIp(SharpPcap.ICaptureDevice pcapDevice)
89 | {
90 | foreach (System.Net.NetworkInformation.NetworkInterface nic in System.Net.NetworkInformation.NetworkInterface.GetAllNetworkInterfaces())
91 | {
92 | PhysicalAddress mac = null;
93 | try
94 | {
95 | mac = nic.GetPhysicalAddress();
96 | }
97 | catch (Exception)
98 | {
99 | //interface have no mac address
100 | }
101 |
102 | if (mac != null && mac.Equals(pcapDevice.MacAddress))
103 | {
104 | IPInterfaceProperties ipp = nic.GetIPProperties();
105 | foreach (var entry in ipp.UnicastAddresses)
106 | {
107 | if (entry.Address.AddressFamily == System.Net.Sockets.AddressFamily.InterNetwork)
108 | {
109 | byte[] gw = new byte[] { 0, 0, 0, 0 };
110 | if (ipp.GatewayAddresses.Count > 0) gw = ipp.GatewayAddresses[0].Address.GetAddressBytes();
111 | return new DCP.IpInfo(DCP.BlockInfo.IpSet, entry.Address.GetAddressBytes(), entry.IPv4Mask.GetAddressBytes(), gw);
112 | }
113 | }
114 | }
115 | }
116 | return null;
117 | }
118 |
119 | public static PhysicalAddress GetDeviceMac(string interfaceIp)
120 | {
121 | IPAddress searchIp = IPAddress.Parse(interfaceIp);
122 | foreach (System.Net.NetworkInformation.NetworkInterface nic in System.Net.NetworkInformation.NetworkInterface.GetAllNetworkInterfaces())
123 | {
124 | PhysicalAddress mac = null;
125 | try
126 | {
127 | mac = nic.GetPhysicalAddress();
128 | }
129 | catch (Exception)
130 | {
131 | //interface have no mac address
132 | continue;
133 | }
134 | foreach (var entry in nic.GetIPProperties().UnicastAddresses)
135 | {
136 | if (searchIp.Equals(entry.Address))
137 | {
138 | return mac;
139 | }
140 | }
141 | }
142 | return null;
143 | }
144 |
145 | public static SharpPcap.ICaptureDevice GetPcapDevice(string localIp)
146 | {
147 | IPAddress searchIp = IPAddress.Parse(localIp);
148 | PhysicalAddress searchMac = null;
149 | Dictionary networks = new Dictionary();
150 |
151 | //search all networks
152 | foreach (System.Net.NetworkInformation.NetworkInterface nic in System.Net.NetworkInformation.NetworkInterface.GetAllNetworkInterfaces())
153 | {
154 | PhysicalAddress mac = null;
155 | try
156 | {
157 | mac = nic.GetPhysicalAddress();
158 | }
159 | catch (Exception)
160 | {
161 | //interface have no mac address
162 | continue;
163 | }
164 | foreach (var entry in nic.GetIPProperties().UnicastAddresses)
165 | {
166 | if (searchIp.Equals(entry.Address))
167 | {
168 | searchMac = mac;
169 | break;
170 | }
171 | }
172 | if (searchMac != null) break;
173 | }
174 |
175 | //validate
176 | if (searchMac == null) return null;
177 |
178 | //search all pcap networks
179 | foreach (SharpPcap.ICaptureDevice dev in SharpPcap.CaptureDeviceList.Instance)
180 | {
181 | try
182 | {
183 | dev.Open();
184 | networks.Add(dev.MacAddress, dev);
185 | dev.Close();
186 | }
187 | catch { }
188 | }
189 |
190 | //find link
191 | if (networks.ContainsKey(searchMac)) return networks[searchMac];
192 | else return null;
193 | }
194 |
195 | public static System.Net.IPAddress GetNetworkAddress(System.Net.IPAddress address, System.Net.IPAddress subnetMask)
196 | {
197 | byte[] ipAdressBytes = address.GetAddressBytes();
198 | byte[] subnetMaskBytes = subnetMask.GetAddressBytes();
199 |
200 | if (ipAdressBytes.Length != subnetMaskBytes.Length)
201 | throw new ArgumentException("Lengths of IP address and subnet mask do not match.");
202 |
203 | byte[] broadcastAddress = new byte[ipAdressBytes.Length];
204 | for (int i = 0; i < broadcastAddress.Length; i++)
205 | broadcastAddress[i] = (byte)(ipAdressBytes[i] & (subnetMaskBytes[i]));
206 | return new System.Net.IPAddress(broadcastAddress);
207 | }
208 |
209 | public static string GetLocalIpAddress(string ipMatch)
210 | {
211 | System.Net.IPAddress target = System.Net.IPAddress.Parse(ipMatch);
212 | foreach (System.Net.NetworkInformation.NetworkInterface nic in System.Net.NetworkInformation.NetworkInterface.GetAllNetworkInterfaces())
213 | {
214 | foreach (var entry in nic.GetIPProperties().UnicastAddresses)
215 | {
216 | if (entry.Address.AddressFamily == System.Net.Sockets.AddressFamily.InterNetwork)
217 | {
218 | if (GetNetworkAddress(entry.Address, entry.IPv4Mask).Equals(GetNetworkAddress(target, entry.IPv4Mask)))
219 | return entry.Address.ToString();
220 | }
221 | }
222 | }
223 | return "";
224 | }
225 |
226 | private void m_adapter_OnProfinetArrival(ConnectionInfoEthernet sender, Stream stream)
227 | {
228 | RT.FrameIds frameID;
229 |
230 | //Real Time
231 | RT.DecodeFrameId(stream, out frameID);
232 | if (frameID == RT.FrameIds.DCP_Identify_ResPDU || frameID == RT.FrameIds.DCP_Identify_ReqPDU || frameID == RT.FrameIds.DCP_Get_Set_PDU || frameID == RT.FrameIds.DCP_Hello_ReqPDU)
233 | {
234 | DCP.ServiceIds serviceID;
235 | uint xid;
236 | ushort responseDelayFactor;
237 | ushort dcpDataLength;
238 | DCP.DecodeHeader(stream, out serviceID, out xid, out responseDelayFactor, out dcpDataLength);
239 | Dictionary blocks;
240 | DCP.DecodeAllBlocks(stream, dcpDataLength, out blocks);
241 | if (OnDcpMessage != null) OnDcpMessage(sender, new DcpMessageArgs(serviceID, xid, responseDelayFactor, blocks));
242 | }
243 | else if (frameID == RT.FrameIds.PTCP_DelayReqPDU)
244 | {
245 | //ignore this for now
246 | }
247 | else if (frameID >= RT.FrameIds.RTC_Start && frameID <= RT.FrameIds.RTC_End)
248 | {
249 | long dataPos = stream.Position;
250 | stream.Position = stream.Length - 4;
251 | UInt16 cycleCounter;
252 | RT.DataStatus dataStatus;
253 | RT.TransferStatus transferStatus;
254 | RT.DecodeRTCStatus(stream, out cycleCounter, out dataStatus, out transferStatus);
255 | stream.Position = dataPos;
256 | if (OnCyclicMessage != null) OnCyclicMessage(sender, cycleCounter, dataStatus, transferStatus, stream, (int)(stream.Length - dataPos - 4));
257 | }
258 | else if (frameID == RT.FrameIds.Alarm_Low || frameID == RT.FrameIds.Alarm_High)
259 | {
260 | UInt16 alarmDestinationEndpoint;
261 | UInt16 alarmSourceEndpoint;
262 | RT.PDUTypes pduType;
263 | RT.AddFlags addFlags;
264 | UInt16 sendSeqNum;
265 | UInt16 ackSeqNum;
266 | UInt16 varPartLen;
267 | RT.DecodeRTAHeader(stream, out alarmDestinationEndpoint, out alarmSourceEndpoint, out pduType, out addFlags, out sendSeqNum, out ackSeqNum, out varPartLen);
268 | if (OnAcyclicMessage != null) OnAcyclicMessage(sender, alarmDestinationEndpoint, alarmSourceEndpoint, pduType, addFlags, sendSeqNum, ackSeqNum, varPartLen, stream);
269 | }
270 | else
271 | {
272 | Trace.TraceWarning("Unclassified RT message");
273 | }
274 | }
275 |
276 | private void m_adapter_OnPacketArrival(object sender, CaptureEventArgs e)
277 | {
278 | if (e.Packet.LinkLayerType != PacketDotNet.LinkLayers.Ethernet) return;
279 | PacketDotNet.Utils.ByteArraySegment bas = new PacketDotNet.Utils.ByteArraySegment(e.Packet.Data);
280 | PacketDotNet.EthernetPacket ethP = new PacketDotNet.EthernetPacket(bas);
281 | if (ethP.Type != (PacketDotNet.EthernetPacketType)0x8892 && ethP.Type != PacketDotNet.EthernetPacketType.VLanTaggedFrame) return;
282 | if (ethP.PayloadPacket != null && ethP.PayloadPacket is PacketDotNet.Ieee8021QPacket)
283 | {
284 | if (((PacketDotNet.Ieee8021QPacket)ethP.PayloadPacket).Type != (PacketDotNet.EthernetPacketType)0x8892) return;
285 | if (((PacketDotNet.Ieee8021QPacket)ethP.PayloadPacket).PayloadData == null)
286 | {
287 | Trace.TraceWarning("Empty vlan package");
288 | return;
289 | }
290 | m_adapter_OnProfinetArrival(new ConnectionInfoEthernet(this, ethP.DestinationHwAddress, ethP.SourceHwAddress), new MemoryStream(((PacketDotNet.Ieee8021QPacket)ethP.PayloadPacket).PayloadData, false));
291 | }
292 | else
293 | {
294 | if (ethP.PayloadData == null)
295 | {
296 | Trace.TraceWarning("Empty ethernet package");
297 | return;
298 | }
299 | m_adapter_OnProfinetArrival(new ConnectionInfoEthernet(this, ethP.DestinationHwAddress, ethP.SourceHwAddress), new MemoryStream(ethP.PayloadData, false));
300 | }
301 | }
302 |
303 | private void Send(MemoryStream stream)
304 | {
305 | byte[] buffer = stream.GetBuffer();
306 | adapter.SendPacket(buffer, (int)stream.Position);
307 | }
308 |
309 | public void SendIdentifyBroadcast()
310 | {
311 | Trace.WriteLine("Sending identify broadcast", null);
312 |
313 | MemoryStream mem = new MemoryStream();
314 |
315 | //ethernet
316 | PhysicalAddress ethernetDestinationHwAddress = PhysicalAddress.Parse(RT.MulticastMACAdd_Identify_Address);
317 | Ethernet.Encode(mem, ethernetDestinationHwAddress, adapter.MacAddress, Ethernet.Type.VLanTaggedFrame);
318 |
319 | //VLAN
320 | VLAN.Encode(mem, VLAN.Priorities.Priority0, VLAN.Type.PN);
321 |
322 | //Profinet Real Time
323 | RT.EncodeFrameId(mem, RT.FrameIds.DCP_Identify_ReqPDU);
324 |
325 | //Profinet DCP
326 | DCP.EncodeIdentifyRequest(mem, ++lastXid);
327 |
328 | //Send
329 | Send(mem);
330 | }
331 |
332 | public void SendIdentifyResponse(PhysicalAddress destination, uint xid, Dictionary blocks)
333 | {
334 | Trace.WriteLine("Sending identify response", null);
335 |
336 | MemoryStream mem = new MemoryStream();
337 |
338 | //ethernet
339 | Ethernet.Encode(mem, destination, adapter.MacAddress, Ethernet.Type.VLanTaggedFrame);
340 |
341 | //VLAN
342 | VLAN.Encode(mem, VLAN.Priorities.Priority0, VLAN.Type.PN);
343 |
344 | //Profinet Real Time
345 | RT.EncodeFrameId(mem, RT.FrameIds.DCP_Identify_ResPDU);
346 |
347 | //Profinet DCP
348 | DCP.EncodeIdentifyResponse(mem, xid, blocks);
349 |
350 | //Send
351 | Send(mem);
352 | }
353 |
354 | public void SendCyclicData(PhysicalAddress destination, UInt16 frameID, UInt16 cycleCounter, byte[] userData)
355 | {
356 | Trace.WriteLine("Sending cyclic data", null);
357 |
358 | MemoryStream mem = new MemoryStream();
359 |
360 | //ethernet
361 | Ethernet.Encode(mem, destination, adapter.MacAddress, (Ethernet.Type)0x8892);
362 |
363 | //Profinet Real Time
364 | RT.EncodeFrameId(mem, (RT.FrameIds)frameID);
365 |
366 | //user data
367 | if (userData == null) userData = new byte[40];
368 | if (userData.Length < 40) Array.Resize(ref userData, 40);
369 | mem.Write(userData, 0, userData.Length);
370 |
371 | //RT footer
372 | RT.EncodeRTCStatus(mem, cycleCounter, RT.DataStatus.DataItemValid |
373 | RT.DataStatus.State_Primary |
374 | RT.DataStatus.ProviderState_Run |
375 | RT.DataStatus.StationProblemIndicator_Normal,
376 | RT.TransferStatus.OK);
377 |
378 | //Send
379 | Send(mem);
380 | }
381 |
382 | public class ProfinetAsyncDcpResult : IAsyncResult, IDisposable
383 | {
384 | private System.Threading.ManualResetEvent mWait = new System.Threading.ManualResetEvent(false);
385 | private uint mXid;
386 | private ProfinetEthernetTransport mConn = null;
387 |
388 | public object AsyncState { get; set; }
389 | public System.Threading.WaitHandle AsyncWaitHandle { get { return mWait; } }
390 | public bool CompletedSynchronously { get; private set; } //always false
391 | public bool IsCompleted { get; private set; }
392 |
393 | public Dictionary Result { get; private set; }
394 |
395 | public ProfinetAsyncDcpResult(ProfinetEthernetTransport conn, MemoryStream message, UInt32 xid)
396 | {
397 | mConn = conn;
398 | conn.OnDcpMessage += new OnDcpMessageHandler(conn_OnDcpMessage);
399 | mXid = xid;
400 | conn.Send(message);
401 | }
402 |
403 | private void conn_OnDcpMessage(ConnectionInfoEthernet sender, DcpMessageArgs args)
404 | {
405 | if (args.Xid == mXid)
406 | {
407 | Result = args.Blocks;
408 | IsCompleted = true;
409 | mWait.Set();
410 | }
411 | }
412 |
413 | public void Dispose()
414 | {
415 | if (mConn != null)
416 | {
417 | mConn.OnDcpMessage -= conn_OnDcpMessage;
418 | mConn = null;
419 | }
420 | }
421 | }
422 |
423 | public IAsyncResult BeginGetRequest(PhysicalAddress destination, DCP.BlockOptions option)
424 | {
425 | Trace.WriteLine("Sending Get " + option.ToString() + " request", null);
426 |
427 | MemoryStream mem = new MemoryStream();
428 |
429 | //ethernet
430 | Ethernet.Encode(mem, destination, adapter.MacAddress, Ethernet.Type.VLanTaggedFrame);
431 |
432 | //VLAN
433 | VLAN.Encode(mem, VLAN.Priorities.Priority0, VLAN.Type.PN);
434 |
435 | //Profinet Real Time
436 | RT.EncodeFrameId(mem, RT.FrameIds.DCP_Get_Set_PDU);
437 |
438 | //Profinet DCP
439 | UInt32 xid = ++lastXid;
440 | DCP.EncodeGetRequest(mem, xid, option);
441 | //start Async
442 | return new ProfinetAsyncDcpResult(this, mem, xid);
443 | }
444 |
445 | public void SendGetResponse(PhysicalAddress destination, uint xid, DCP.BlockOptions option, object data)
446 | {
447 | Trace.WriteLine("Sending Get " + option.ToString() + " response", null);
448 |
449 | MemoryStream mem = new MemoryStream();
450 |
451 | //ethernet
452 | Ethernet.Encode(mem, destination, adapter.MacAddress, Ethernet.Type.VLanTaggedFrame);
453 |
454 | //VLAN
455 | VLAN.Encode(mem, VLAN.Priorities.Priority0, VLAN.Type.PN);
456 |
457 | //Profinet Real Time
458 | RT.EncodeFrameId(mem, RT.FrameIds.DCP_Get_Set_PDU);
459 |
460 | //Profinet DCP
461 | DCP.EncodeGetResponse(mem, xid, option, data);
462 |
463 | //send
464 | Send(mem);
465 | }
466 |
467 | public IAsyncResult BeginSetRequest(PhysicalAddress destination, DCP.BlockOptions option, DCP.BlockQualifiers qualifiers, byte[] data)
468 | {
469 | Trace.WriteLine("Sending Set " + option.ToString() + " request", null);
470 |
471 | MemoryStream mem = new MemoryStream();
472 |
473 | //ethernet
474 | Ethernet.Encode(mem, destination, adapter.MacAddress, Ethernet.Type.VLanTaggedFrame);
475 |
476 | //VLAN
477 | VLAN.Encode(mem, VLAN.Priorities.Priority0, VLAN.Type.PN);
478 |
479 | //Profinet Real Time
480 | RT.EncodeFrameId(mem, RT.FrameIds.DCP_Get_Set_PDU);
481 |
482 | //Profinet DCP
483 | UInt32 xid = ++lastXid;
484 | DCP.EncodeSetRequest(mem, xid, option, qualifiers, data);
485 |
486 | //start Async
487 | return new ProfinetAsyncDcpResult(this, mem, xid);
488 | }
489 |
490 | public void SendSetResponse(PhysicalAddress destination, uint xid, DCP.BlockOptions option, DCP.BlockErrors status)
491 | {
492 | Trace.WriteLine("Sending Set " + option.ToString() + " response", null);
493 |
494 | MemoryStream mem = new MemoryStream();
495 |
496 | //ethernet
497 | Ethernet.Encode(mem, destination, adapter.MacAddress, Ethernet.Type.VLanTaggedFrame);
498 |
499 | //VLAN
500 | VLAN.Encode(mem, VLAN.Priorities.Priority0, VLAN.Type.PN);
501 |
502 | //Profinet Real Time
503 | RT.EncodeFrameId(mem, RT.FrameIds.DCP_Get_Set_PDU);
504 |
505 | //Profinet DCP
506 | DCP.EncodeSetResponse(mem, xid, option, status);
507 |
508 | //Send
509 | Send(mem);
510 | }
511 |
512 | public DCP.BlockErrors EndSetRequest(IAsyncResult result, int timeoutMs)
513 | {
514 | ProfinetAsyncDcpResult r = (ProfinetAsyncDcpResult)result;
515 |
516 | if (result.AsyncWaitHandle.WaitOne(timeoutMs))
517 | {
518 | DCP.BlockErrors ret = r.Result.ContainsKey(DCP.BlockOptions.Control_Response) ? ((DCP.ResponseStatus)r.Result[DCP.BlockOptions.Control_Response]).Error : DCP.BlockErrors.NoError;
519 | r.Dispose();
520 | return ret;
521 | }
522 | else
523 | {
524 | r.Dispose();
525 | throw new TimeoutException("No response received");
526 | }
527 | }
528 |
529 | public Dictionary EndGetRequest(IAsyncResult result, int timeoutMs)
530 | {
531 | ProfinetAsyncDcpResult r = (ProfinetAsyncDcpResult)result;
532 |
533 | if (result.AsyncWaitHandle.WaitOne(timeoutMs))
534 | {
535 | Dictionary ret = r.Result;
536 | r.Dispose();
537 | return ret;
538 | }
539 | else
540 | {
541 | r.Dispose();
542 | throw new TimeoutException("No response received");
543 | }
544 | }
545 |
546 | public IAsyncResult BeginSetSignalRequest(PhysicalAddress destination)
547 | {
548 | return BeginSetRequest(destination, DCP.BlockOptions.Control_Signal, DCP.BlockQualifiers.Temporary, BitConverter.GetBytes((ushort)0x100)); //SignalValue - Flash once
549 | }
550 |
551 | public IAsyncResult BeginSetResetRequest(PhysicalAddress destination)
552 | {
553 | return BeginSetRequest(destination, DCP.BlockOptions.Control_FactoryReset, DCP.BlockQualifiers.Permanent, null);
554 | }
555 |
556 | public IAsyncResult BeginSetNameRequest(PhysicalAddress destination, string name)
557 | {
558 | byte[] bytes = Encoding.ASCII.GetBytes(name);
559 | return BeginSetRequest(destination, DCP.BlockOptions.DeviceProperties_NameOfStation, DCP.BlockQualifiers.Permanent, bytes);
560 | }
561 |
562 | public IAsyncResult BeginSetIpRequest(PhysicalAddress destination, IPAddress ip, IPAddress subnetMask, IPAddress gateway)
563 | {
564 | byte[] bytes = new byte[12];
565 | Array.Copy(ip.GetAddressBytes(), 0, bytes, 0, 4);
566 | Array.Copy(subnetMask.GetAddressBytes(), 0, bytes, 4, 4);
567 | Array.Copy(gateway.GetAddressBytes(), 0, bytes, 8, 4);
568 | return BeginSetRequest(destination, DCP.BlockOptions.IP_IPParameter, DCP.BlockQualifiers.Permanent, bytes);
569 | }
570 |
571 | public IAsyncResult BeginSetIpFullRequest(PhysicalAddress destination, IPAddress ip, IPAddress subnetMask, IPAddress gateway, IPAddress[] dns)
572 | {
573 | byte[] bytes = new byte[28];
574 | Array.Copy(ip.GetAddressBytes(), 0, bytes, 0, 4);
575 | Array.Copy(subnetMask.GetAddressBytes(), 0, bytes, 4, 4);
576 | Array.Copy(gateway.GetAddressBytes(), 0, bytes, 8, 4);
577 | if (dns == null || dns.Length != 4) throw new ArgumentException("dns array length must be 4");
578 | for (int i = 0; i < 4; i++)
579 | Array.Copy(dns[i].GetAddressBytes(), 0, bytes, 12 + i * 4, 4);
580 | return BeginSetRequest(destination, DCP.BlockOptions.IP_FullIPSuite, DCP.BlockQualifiers.Permanent, bytes);
581 | }
582 |
583 | public DCP.BlockErrors SendSetRequest(PhysicalAddress destination, int timeoutMs, int retries, DCP.BlockOptions option, DCP.BlockQualifiers qualifiers, byte[] data)
584 | {
585 | for (int r = 0; r < retries; r++)
586 | {
587 | IAsyncResult asyncResult = BeginSetRequest(destination, option, qualifiers, data);
588 | try
589 | {
590 | return EndSetRequest(asyncResult, timeoutMs);
591 | }
592 | catch (TimeoutException)
593 | {
594 | //continue
595 | }
596 | }
597 | throw new TimeoutException("No response received");
598 | }
599 |
600 | public DCP.BlockErrors SendSetRequest(PhysicalAddress destination, int timeoutMs, int retries, DCP.BlockOptions option, byte[] data)
601 | {
602 | return SendSetRequest(destination, timeoutMs, retries, option, DCP.BlockQualifiers.Permanent, data);
603 | }
604 |
605 | public Dictionary SendGetRequest(PhysicalAddress destination, int timeoutMs, int retries, DCP.BlockOptions option)
606 | {
607 | for (int r = 0; r < retries; r++)
608 | {
609 | IAsyncResult asyncResult = BeginGetRequest(destination, option);
610 | try
611 | {
612 | return EndGetRequest(asyncResult, timeoutMs);
613 | }
614 | catch (TimeoutException)
615 | {
616 | //continue
617 | }
618 | }
619 | throw new TimeoutException("No response received");
620 | }
621 |
622 | public DCP.BlockErrors SendSetSignalRequest(PhysicalAddress destination, int timeoutMs, int retries)
623 | {
624 | for (int r = 0; r < retries; r++)
625 | {
626 | IAsyncResult asyncResult = BeginSetSignalRequest(destination);
627 | try
628 | {
629 | return EndSetRequest(asyncResult, timeoutMs);
630 | }
631 | catch (TimeoutException)
632 | {
633 | //continue
634 | }
635 | }
636 | throw new TimeoutException("No response received");
637 | }
638 |
639 | public DCP.BlockErrors SendSetResetRequest(PhysicalAddress destination, int timeoutMs, int retries)
640 | {
641 | for (int r = 0; r < retries; r++)
642 | {
643 | IAsyncResult asyncResult = BeginSetResetRequest(destination);
644 | try
645 | {
646 | return EndSetRequest(asyncResult, timeoutMs);
647 | }
648 | catch (TimeoutException)
649 | {
650 | //continue
651 | }
652 | }
653 | throw new TimeoutException("No response received");
654 | }
655 |
656 | public DCP.BlockErrors SendSetNameRequest(PhysicalAddress destination, int timeoutMs, int retries, string name)
657 | {
658 | for (int r = 0; r < retries; r++)
659 | {
660 | IAsyncResult asyncResult = BeginSetNameRequest(destination, name);
661 | try
662 | {
663 | return EndSetRequest(asyncResult, timeoutMs);
664 | }
665 | catch (TimeoutException)
666 | {
667 | //continue
668 | }
669 | }
670 | throw new TimeoutException("No response received");
671 | }
672 |
673 | public DCP.BlockErrors SendSetIpFullRequest(PhysicalAddress destination, int timeoutMs, int retries, IPAddress ip, IPAddress subnetMask, IPAddress gateway, IPAddress[] dns)
674 | {
675 | for (int r = 0; r < retries; r++)
676 | {
677 | IAsyncResult asyncResult = BeginSetIpFullRequest(destination, ip, subnetMask, gateway, dns);
678 | try
679 | {
680 | return EndSetRequest(asyncResult, timeoutMs);
681 | }
682 | catch (TimeoutException)
683 | {
684 | //continue
685 | }
686 | }
687 | throw new TimeoutException("No response received");
688 | }
689 |
690 | public DCP.BlockErrors SendSetIpRequest(PhysicalAddress destination, int timeoutMs, int retries, IPAddress ip, IPAddress subnetMask, IPAddress gateway)
691 | {
692 | for (int r = 0; r < retries; r++)
693 | {
694 | IAsyncResult asyncResult = BeginSetIpRequest(destination, ip, subnetMask, gateway);
695 | try
696 | {
697 | return EndSetRequest(asyncResult, timeoutMs);
698 | }
699 | catch (TimeoutException)
700 | {
701 | //continue
702 | }
703 | }
704 | throw new TimeoutException("No response received");
705 | }
706 | }
707 | }
708 |
--------------------------------------------------------------------------------
/ProfinetTools.Logic/packages.config:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
--------------------------------------------------------------------------------
/ProfinetTools.Setup/Fragments/Fragments.wxs:
--------------------------------------------------------------------------------
1 |
2 |
3 |
25 |
26 |
27 |
28 |
29 |
30 |
31 |
32 |
33 |
34 |
35 |
36 |
37 |
38 |
39 |
40 |
41 |
42 |
43 |
44 |
45 |
46 |
47 |
48 |
49 |
50 |
51 |
52 |
53 |
54 |
55 |
56 |
57 |
58 |
59 |
60 |
61 |
62 |
63 |
64 |
65 |
66 |
67 |
68 |
69 |
70 |
71 |
72 |
73 |
74 |
75 |
76 |
77 |
78 |
79 |
80 |
81 |
82 |
83 |
84 |
85 |
86 |
87 |
88 |
89 |
90 |
91 |
92 |
93 |
94 |
95 |
96 |
97 |
98 |
99 |
100 |
101 |
102 |
103 |
104 |
105 |
106 |
107 |
108 |
109 |
110 |
111 |
112 |
113 |
114 |
115 |
116 |
117 |
118 |
119 |
120 |
121 |
122 |
123 |
124 |
125 |
126 |
127 |
128 |
129 |
130 |
131 |
132 |
133 |
134 |
135 |
136 |
137 |
138 |
139 |
140 |
141 |
142 |
143 |
144 |
145 |
146 |
147 |
148 |
149 |
150 |
151 |
152 |
153 |
154 |
155 |
156 |
157 |
158 |
159 |
--------------------------------------------------------------------------------
/ProfinetTools.Setup/Paraffin/Create.bat:
--------------------------------------------------------------------------------
1 | mkdir ..\Fragments
2 | Paraffin.exe -dir ..\..\out\Release ^
3 | -NoRootDirectory ^
4 | -alias $(var.SourcePath) ^
5 | -GroupName ProfinetToolsFragments ..\Fragments\Fragments.wxs ^
6 | -ext .json ^
7 | -ext .sdf ^
8 | -regExExclude "\.vshost\." ^
9 | -regExExclude "\.dll\.conf"
10 |
--------------------------------------------------------------------------------
/ProfinetTools.Setup/Paraffin/Update.bat:
--------------------------------------------------------------------------------
1 | Paraffin.exe -update -verbose ..\Fragments\Fragments.wxs
2 | move /Y ..\Fragments\Fragments.PARAFFIN ..\Fragments\Fragments.wxs
--------------------------------------------------------------------------------
/ProfinetTools.Setup/Paraffin/Zen of Paraffin.docx:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/fbarresi/ProfinetTools/0315f0f698efd886809ba177edd7ee8e38b5166f/ProfinetTools.Setup/Paraffin/Zen of Paraffin.docx
--------------------------------------------------------------------------------
/ProfinetTools.Setup/Product.wxs:
--------------------------------------------------------------------------------
1 |
2 |
3 |
6 |
7 |
8 |
9 |
10 |
13 |
19 |
20 |
24 |
25 |
26 |
31 |
37 |
40 |
41 |
42 |
43 |
44 |
45 |
46 |
47 |
48 | 1
49 | 1
50 |
51 |
52 |
53 |
54 |
55 |
56 |
57 |
58 |
59 |
60 |
61 |
62 |
63 |
64 |
65 |
71 |
72 |
79 |
80 |
81 |
101 |
102 |
103 |
104 |
105 |
106 |
107 |
108 |
109 |
110 |
111 |
112 |
113 |
114 |
115 |
118 |
119 |
121 |
122 |
125 |
126 |
127 |
128 |
130 | NEWPRODUCTFOUND
131 |
132 |
133 |
134 |
135 |
138 |
139 |
141 | NEWPRODUCTFOUND
142 |
143 |
144 |
145 |
146 |
147 |
--------------------------------------------------------------------------------
/ProfinetTools.Setup/ProfinetTools.Setup.wixproj:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 | Debug
5 | x86
6 | 3.10
7 | e6c11d5c-ed2c-43a9-8df9-15d36df77f6f
8 | 2.0
9 | ProfinetTools.Setup
10 | Package
11 | $(MSBuildExtensionsPath32)\Microsoft\WiX\v3.x\Wix.targets
12 | $(MSBuildExtensionsPath)\Microsoft\WiX\v3.x\Wix.targets
13 | $(MSBuildProgramFiles32)
14 | $(ProgramFiles%28x86%29)
15 | $(ProgramFiles) (x86)
16 | $(ProgramFiles)
17 |
18 |
19 | bin\$(Configuration)\
20 | obj\$(Configuration)\
21 | Debug
22 |
23 |
24 | bin\$(Configuration)\
25 | obj\$(Configuration)\
26 | SourcePath=..\out\$(Configuration)
27 | VersionNumber=0.9.9.9;
28 | true
29 |
30 |
31 |
32 |
33 |
34 |
35 |
36 |
37 |
38 |
39 |
40 |
41 |
42 |
43 |
44 |
45 |
46 |
47 |
48 |
49 |
50 |
51 | $(WixExtDir)\WixUtilExtension.dll
52 | WixUtilExtension
53 |
54 |
55 | $(WixExtDir)\WixUIExtension.dll
56 | WixUIExtension
57 |
58 |
59 | $(WixExtDir)\WixNetFxExtension.dll
60 | WixNetFxExtension
61 |
62 |
63 |
64 |
72 |
--------------------------------------------------------------------------------
/ProfinetTools.Setup/Resources/installer_background.bmp:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/fbarresi/ProfinetTools/0315f0f698efd886809ba177edd7ee8e38b5166f/ProfinetTools.Setup/Resources/installer_background.bmp
--------------------------------------------------------------------------------
/ProfinetTools.Setup/Resources/logo.ico:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/fbarresi/ProfinetTools/0315f0f698efd886809ba177edd7ee8e38b5166f/ProfinetTools.Setup/Resources/logo.ico
--------------------------------------------------------------------------------
/ProfinetTools.sln:
--------------------------------------------------------------------------------
1 |
2 | Microsoft Visual Studio Solution File, Format Version 12.00
3 | # Visual Studio 15
4 | VisualStudioVersion = 15.0.27130.2024
5 | MinimumVisualStudioVersion = 10.0.40219.1
6 | Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "ProfinetTools", "ProfinetTools\ProfinetTools.csproj", "{8C9C17B3-A185-4D73-9645-A8871F7B17EC}"
7 | EndProject
8 | Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "ProfinetTools.Gui", "ProfinetTools.Gui\ProfinetTools.Gui.csproj", "{F7D721A7-EB1B-4688-B535-63FCBEB12DAB}"
9 | EndProject
10 | Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "ProfinetTools.Interfaces", "ProfinetTools.Interfaces\ProfinetTools.Interfaces.csproj", "{F23836B7-30F9-4A77-8EA1-8C57B7BC953F}"
11 | EndProject
12 | Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "ProfinetTools.Logic", "ProfinetTools.Logic\ProfinetTools.Logic.csproj", "{6696F4A6-C9A5-49F3-8463-16A85BACB6E6}"
13 | EndProject
14 | Project("{930C7802-8A8C-48F9-8165-68863BCCD9DD}") = "ProfinetTools.Setup", "ProfinetTools.Setup\ProfinetTools.Setup.wixproj", "{E6C11D5C-ED2C-43A9-8DF9-15D36DF77F6F}"
15 | EndProject
16 | Global
17 | GlobalSection(SolutionConfigurationPlatforms) = preSolution
18 | Debug|Any CPU = Debug|Any CPU
19 | Debug|x86 = Debug|x86
20 | Release|Any CPU = Release|Any CPU
21 | Release|x86 = Release|x86
22 | EndGlobalSection
23 | GlobalSection(ProjectConfigurationPlatforms) = postSolution
24 | {8C9C17B3-A185-4D73-9645-A8871F7B17EC}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
25 | {8C9C17B3-A185-4D73-9645-A8871F7B17EC}.Debug|Any CPU.Build.0 = Debug|Any CPU
26 | {8C9C17B3-A185-4D73-9645-A8871F7B17EC}.Debug|x86.ActiveCfg = Debug|Any CPU
27 | {8C9C17B3-A185-4D73-9645-A8871F7B17EC}.Debug|x86.Build.0 = Debug|Any CPU
28 | {8C9C17B3-A185-4D73-9645-A8871F7B17EC}.Release|Any CPU.ActiveCfg = Release|Any CPU
29 | {8C9C17B3-A185-4D73-9645-A8871F7B17EC}.Release|Any CPU.Build.0 = Release|Any CPU
30 | {8C9C17B3-A185-4D73-9645-A8871F7B17EC}.Release|x86.ActiveCfg = Release|Any CPU
31 | {8C9C17B3-A185-4D73-9645-A8871F7B17EC}.Release|x86.Build.0 = Release|Any CPU
32 | {F7D721A7-EB1B-4688-B535-63FCBEB12DAB}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
33 | {F7D721A7-EB1B-4688-B535-63FCBEB12DAB}.Debug|Any CPU.Build.0 = Debug|Any CPU
34 | {F7D721A7-EB1B-4688-B535-63FCBEB12DAB}.Debug|x86.ActiveCfg = Debug|Any CPU
35 | {F7D721A7-EB1B-4688-B535-63FCBEB12DAB}.Debug|x86.Build.0 = Debug|Any CPU
36 | {F7D721A7-EB1B-4688-B535-63FCBEB12DAB}.Release|Any CPU.ActiveCfg = Release|Any CPU
37 | {F7D721A7-EB1B-4688-B535-63FCBEB12DAB}.Release|Any CPU.Build.0 = Release|Any CPU
38 | {F7D721A7-EB1B-4688-B535-63FCBEB12DAB}.Release|x86.ActiveCfg = Release|Any CPU
39 | {F7D721A7-EB1B-4688-B535-63FCBEB12DAB}.Release|x86.Build.0 = Release|Any CPU
40 | {F23836B7-30F9-4A77-8EA1-8C57B7BC953F}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
41 | {F23836B7-30F9-4A77-8EA1-8C57B7BC953F}.Debug|Any CPU.Build.0 = Debug|Any CPU
42 | {F23836B7-30F9-4A77-8EA1-8C57B7BC953F}.Debug|x86.ActiveCfg = Debug|Any CPU
43 | {F23836B7-30F9-4A77-8EA1-8C57B7BC953F}.Debug|x86.Build.0 = Debug|Any CPU
44 | {F23836B7-30F9-4A77-8EA1-8C57B7BC953F}.Release|Any CPU.ActiveCfg = Release|Any CPU
45 | {F23836B7-30F9-4A77-8EA1-8C57B7BC953F}.Release|Any CPU.Build.0 = Release|Any CPU
46 | {F23836B7-30F9-4A77-8EA1-8C57B7BC953F}.Release|x86.ActiveCfg = Release|Any CPU
47 | {F23836B7-30F9-4A77-8EA1-8C57B7BC953F}.Release|x86.Build.0 = Release|Any CPU
48 | {6696F4A6-C9A5-49F3-8463-16A85BACB6E6}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
49 | {6696F4A6-C9A5-49F3-8463-16A85BACB6E6}.Debug|Any CPU.Build.0 = Debug|Any CPU
50 | {6696F4A6-C9A5-49F3-8463-16A85BACB6E6}.Debug|x86.ActiveCfg = Debug|Any CPU
51 | {6696F4A6-C9A5-49F3-8463-16A85BACB6E6}.Debug|x86.Build.0 = Debug|Any CPU
52 | {6696F4A6-C9A5-49F3-8463-16A85BACB6E6}.Release|Any CPU.ActiveCfg = Release|Any CPU
53 | {6696F4A6-C9A5-49F3-8463-16A85BACB6E6}.Release|Any CPU.Build.0 = Release|Any CPU
54 | {6696F4A6-C9A5-49F3-8463-16A85BACB6E6}.Release|x86.ActiveCfg = Release|Any CPU
55 | {6696F4A6-C9A5-49F3-8463-16A85BACB6E6}.Release|x86.Build.0 = Release|Any CPU
56 | {E6C11D5C-ED2C-43A9-8DF9-15D36DF77F6F}.Debug|Any CPU.ActiveCfg = Debug|x86
57 | {E6C11D5C-ED2C-43A9-8DF9-15D36DF77F6F}.Debug|x86.ActiveCfg = Debug|x86
58 | {E6C11D5C-ED2C-43A9-8DF9-15D36DF77F6F}.Debug|x86.Build.0 = Debug|x86
59 | {E6C11D5C-ED2C-43A9-8DF9-15D36DF77F6F}.Release|Any CPU.ActiveCfg = Release|x86
60 | {E6C11D5C-ED2C-43A9-8DF9-15D36DF77F6F}.Release|Any CPU.Build.0 = Release|x86
61 | {E6C11D5C-ED2C-43A9-8DF9-15D36DF77F6F}.Release|x86.ActiveCfg = Release|x86
62 | {E6C11D5C-ED2C-43A9-8DF9-15D36DF77F6F}.Release|x86.Build.0 = Release|x86
63 | EndGlobalSection
64 | GlobalSection(SolutionProperties) = preSolution
65 | HideSolutionNode = FALSE
66 | EndGlobalSection
67 | GlobalSection(ExtensibilityGlobals) = postSolution
68 | SolutionGuid = {83582AD7-A74F-4279-BE1A-C1272663677F}
69 | EndGlobalSection
70 | EndGlobal
71 |
--------------------------------------------------------------------------------
/ProfinetTools/App.config:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
--------------------------------------------------------------------------------
/ProfinetTools/ProfinetTools.csproj:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 | Debug
6 | AnyCPU
7 | {8C9C17B3-A185-4D73-9645-A8871F7B17EC}
8 | WinExe
9 | ProfinetTools
10 | ProfinetTools
11 | v4.5.2
12 | 512
13 | {60dc8134-eba5-43b8-bcc9-bb4bc16c2548};{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}
14 | 4
15 | true
16 |
17 |
18 | AnyCPU
19 | true
20 | full
21 | false
22 | ..\out\Debug\
23 | DEBUG;TRACE
24 | prompt
25 | 4
26 |
27 |
28 | AnyCPU
29 | pdbonly
30 | true
31 | ..\out\Release\
32 | TRACE
33 | prompt
34 | 4
35 |
36 |
37 |
38 | ..\packages\log4net.2.0.12\lib\net45\log4net.dll
39 | True
40 |
41 |
42 | ..\packages\Ninject.3.3.4\lib\net45\Ninject.dll
43 |
44 |
45 |
46 |
47 |
48 |
49 |
50 |
51 |
52 |
53 |
54 |
55 | 4.0
56 |
57 |
58 |
59 |
60 |
61 |
62 |
63 |
64 | Code
65 |
66 |
67 | True
68 | True
69 | Resources.resx
70 |
71 |
72 | True
73 | Settings.settings
74 | True
75 |
76 |
77 | ResXFileCodeGenerator
78 | Resources.Designer.cs
79 |
80 |
81 |
82 | SettingsSingleFileGenerator
83 | Settings.Designer.cs
84 |
85 |
86 |
87 |
88 |
89 |
90 |
91 | {f7d721a7-eb1b-4688-b535-63fcbeb12dab}
92 | ProfinetTools.Gui
93 |
94 |
95 | {f23836b7-30f9-4a77-8ea1-8c57b7bc953f}
96 | ProfinetTools.Interfaces
97 |
98 |
99 | {6696f4a6-c9a5-49f3-8463-16a85bacb6e6}
100 | ProfinetTools.Logic
101 |
102 |
103 |
104 |
--------------------------------------------------------------------------------
/ProfinetTools/Program.cs:
--------------------------------------------------------------------------------
1 | using log4net;
2 | using log4net.Appender;
3 | using log4net.Config;
4 | using log4net.Layout;
5 | using Ninject;
6 | using ProfinetTools.Logic;
7 | using ProfinetTools.Gui;
8 | using ProfinetTools.Gui.ViewModels;
9 | using ProfinetTools.Gui.Views;
10 | using System;
11 | using System.Reflection;
12 | using System.Windows;
13 | using ProfinetTools.Interfaces.Commons;
14 | using App = ProfinetTools.Gui.App;
15 |
16 | namespace ProfinetTools
17 | {
18 | public static class ApplicationExtensions
19 | {
20 | public static void ReplaceViewModelLocator(this Application application, IViewModelFactory viewModelLocator, string locatorKey = "Locator")
21 | {
22 | if (application.Resources.Contains(locatorKey))
23 | application.Resources.Remove(locatorKey);
24 | application.Resources.Add(locatorKey, viewModelLocator);
25 | }
26 | }
27 |
28 | internal class Program
29 | {
30 | private static ILog s_Logger;
31 |
32 | private static Application CreateApplication(IViewModelFactory viewModelLocator)
33 | {
34 | var application = new App();
35 |
36 | application.InitializeComponent();
37 | application.ReplaceViewModelLocator(viewModelLocator);
38 |
39 | return application;
40 | }
41 |
42 | private static void LoadModules(IKernel kernel)
43 | {
44 | kernel.Load();
45 | kernel.Load();
46 | }
47 |
48 | [STAThread]
49 | private static void Main()
50 | {
51 | using (IKernel kernel = new StandardKernel())
52 | {
53 | LoadModules(kernel);
54 |
55 | var x = new ConsoleAppender { Layout = new SimpleLayout() };
56 | BasicConfigurator.Configure(x);
57 |
58 | s_Logger = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType);
59 |
60 | var viewModelFactory = kernel.Get();
61 | var application = CreateApplication(viewModelFactory);
62 |
63 | var mainWindowViewModel = viewModelFactory.CreateViewModel();
64 | s_Logger.Info("Initializing application");
65 |
66 | var mainWindow = kernel.Get();
67 | mainWindow.DataContext = mainWindowViewModel;
68 |
69 | application.Run(mainWindow);
70 | application.Shutdown();
71 | }
72 | }
73 | }
74 | }
--------------------------------------------------------------------------------
/ProfinetTools/Properties/AssemblyInfo.cs:
--------------------------------------------------------------------------------
1 | using System.Reflection;
2 | using System.Resources;
3 | using System.Runtime.CompilerServices;
4 | using System.Runtime.InteropServices;
5 | using System.Windows;
6 |
7 | // General Information about an assembly is controlled through the following
8 | // set of attributes. Change these attribute values to modify the information
9 | // associated with an assembly.
10 | [assembly: AssemblyTitle("ProfinetTools")]
11 | [assembly: AssemblyDescription("")]
12 | [assembly: AssemblyConfiguration("")]
13 | [assembly: AssemblyCompany("")]
14 | [assembly: AssemblyProduct("ProfinetTools")]
15 | [assembly: AssemblyCopyright("Copyright © 2018")]
16 | [assembly: AssemblyTrademark("")]
17 | [assembly: AssemblyCulture("")]
18 |
19 | // Setting ComVisible to false makes the types in this assembly not visible
20 | // to COM components. If you need to access a type in this assembly from
21 | // COM, set the ComVisible attribute to true on that type.
22 | [assembly: ComVisible(false)]
23 |
24 | //In order to begin building localizable applications, set
25 | //CultureYouAreCodingWith in your .csproj file
26 | //inside a . For example, if you are using US english
27 | //in your source files, set the to en-US. Then uncomment
28 | //the NeutralResourceLanguage attribute below. Update the "en-US" in
29 | //the line below to match the UICulture setting in the project file.
30 |
31 | //[assembly: NeutralResourcesLanguage("en-US", UltimateResourceFallbackLocation.Satellite)]
32 |
33 |
34 | [assembly: ThemeInfo(
35 | ResourceDictionaryLocation.None, //where theme specific resource dictionaries are located
36 | //(used if a resource is not found in the page,
37 | // or application resource dictionaries)
38 | ResourceDictionaryLocation.SourceAssembly //where the generic resource dictionary is located
39 | //(used if a resource is not found in the page,
40 | // app, or any theme specific resource dictionaries)
41 | )]
42 |
43 |
44 | // Version information for an assembly consists of the following four values:
45 | //
46 | // Major Version
47 | // Minor Version
48 | // Build Number
49 | // Revision
50 | //
51 | // You can specify all the values or you can default the Build and Revision Numbers
52 | // by using the '*' as shown below:
53 | // [assembly: AssemblyVersion("1.0.*")]
54 | [assembly: AssemblyVersion("1.0.0.0")]
55 | [assembly: AssemblyFileVersion("1.0.0.0")]
56 |
--------------------------------------------------------------------------------
/ProfinetTools/Properties/Resources.Designer.cs:
--------------------------------------------------------------------------------
1 | //------------------------------------------------------------------------------
2 | //
3 | // This code was generated by a tool.
4 | // Runtime Version:4.0.30319.42000
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 ProfinetTools.Properties
12 | {
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 |
28 | private static global::System.Resources.ResourceManager resourceMan;
29 |
30 | private static global::System.Globalization.CultureInfo resourceCulture;
31 |
32 | [global::System.Diagnostics.CodeAnalysis.SuppressMessageAttribute("Microsoft.Performance", "CA1811:AvoidUncalledPrivateCode")]
33 | internal Resources()
34 | {
35 | }
36 |
37 | ///
38 | /// Returns the cached ResourceManager instance used by this class.
39 | ///
40 | [global::System.ComponentModel.EditorBrowsableAttribute(global::System.ComponentModel.EditorBrowsableState.Advanced)]
41 | internal static global::System.Resources.ResourceManager ResourceManager
42 | {
43 | get
44 | {
45 | if ((resourceMan == null))
46 | {
47 | global::System.Resources.ResourceManager temp = new global::System.Resources.ResourceManager("ProfinetTools.Properties.Resources", typeof(Resources).Assembly);
48 | resourceMan = temp;
49 | }
50 | return resourceMan;
51 | }
52 | }
53 |
54 | ///
55 | /// Overrides the current thread's CurrentUICulture property for all
56 | /// resource lookups using this strongly typed resource class.
57 | ///
58 | [global::System.ComponentModel.EditorBrowsableAttribute(global::System.ComponentModel.EditorBrowsableState.Advanced)]
59 | internal static global::System.Globalization.CultureInfo Culture
60 | {
61 | get
62 | {
63 | return resourceCulture;
64 | }
65 | set
66 | {
67 | resourceCulture = value;
68 | }
69 | }
70 | }
71 | }
72 |
--------------------------------------------------------------------------------
/ProfinetTools/Properties/Resources.resx:
--------------------------------------------------------------------------------
1 |
2 |
3 |
62 |
63 |
64 |
65 |
66 |
67 |
68 |
69 |
70 |
71 |
72 |
73 |
74 |
75 |
76 |
77 |
78 |
79 |
80 |
81 |
82 |
83 |
84 |
85 |
86 |
87 |
88 |
89 |
90 |
91 |
92 |
93 |
94 |
95 |
96 |
97 |
98 |
99 |
100 |
101 |
102 |
103 |
104 |
105 |
106 | text/microsoft-resx
107 |
108 |
109 | 2.0
110 |
111 |
112 | System.Resources.ResXResourceReader, System.Windows.Forms, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089
113 |
114 |
115 | System.Resources.ResXResourceWriter, System.Windows.Forms, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089
116 |
117 |
--------------------------------------------------------------------------------
/ProfinetTools/Properties/Settings.Designer.cs:
--------------------------------------------------------------------------------
1 | //------------------------------------------------------------------------------
2 | //
3 | // This code was generated by a tool.
4 | // Runtime Version:4.0.30319.42000
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 ProfinetTools.Properties
12 | {
13 |
14 |
15 | [global::System.Runtime.CompilerServices.CompilerGeneratedAttribute()]
16 | [global::System.CodeDom.Compiler.GeneratedCodeAttribute("Microsoft.VisualStudio.Editors.SettingsDesigner.SettingsSingleFileGenerator", "11.0.0.0")]
17 | internal sealed partial class Settings : global::System.Configuration.ApplicationSettingsBase
18 | {
19 |
20 | private static Settings defaultInstance = ((Settings)(global::System.Configuration.ApplicationSettingsBase.Synchronized(new Settings())));
21 |
22 | public static Settings Default
23 | {
24 | get
25 | {
26 | return defaultInstance;
27 | }
28 | }
29 | }
30 | }
31 |
--------------------------------------------------------------------------------
/ProfinetTools/Properties/Settings.settings:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
--------------------------------------------------------------------------------
/ProfinetTools/packages.config:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
--------------------------------------------------------------------------------
/README.md:
--------------------------------------------------------------------------------
1 | # ProfinetTools
2 | [](https://ci.appveyor.com/project/fbarresi/profinettools)
3 |
4 | Tools for profinet configuration
5 |
6 | # Requirements
7 | This software is based on the famouse *WinPcap* libraris.
8 |
9 | I suggest to use the [npcap](https://nmap.org/npcap/) improvement for better performace.
10 |
11 | Plese download it from [here](https://nmap.org/npcap/dist/npcap-0.98.exe) and install it.
12 |
13 | During the installation choose the option **WinPcap compatibility**
14 |
15 | # Installation
16 |
17 | Dowload the latest version of ProfinetTools from [here](https://github.com/fbarresi/ProfinetTools/releases/latest)
18 | you just need to execute the setup.
19 |
20 | # Usage
21 |
22 | ProfinetTools is an improvement of the opensource project [profinetexplorer](https://sourceforge.net/projects/profinetexplorer/) writte with modern WPF and reactive programming.
23 |
24 | It has a very simple user interface that allows you to scan your profinet network and assign names or ip configurations.
25 |
26 | ![alt text][screenshot]
27 |
28 | [screenshot]: https://github.com/fbarresi/ProfinetTools/blob/master/docs/screenshot.png "screenshot"
29 |
--------------------------------------------------------------------------------
/docs/screenshot.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/fbarresi/ProfinetTools/0315f0f698efd886809ba177edd7ee8e38b5166f/docs/screenshot.png
--------------------------------------------------------------------------------