mirror of
https://github.com/thiagoralves/OpenPLC_v3.git
synced 2026-09-24 07:23:59 +08:00
First commit. OpenPLC v3 beta 1
This commit is contained in:
@@ -1,2 +1,24 @@
|
||||
# OpenPLC_v3
|
||||
OpenPLC Runtime version 3
|
||||
# OpenPLC Runtime version 3
|
||||
OpenPLC is an open-source [Programmable Logic Controller](https://en.wikipedia.org/wiki/Programmable_logic_controller) that is based on easy to use software. Our focus is to provide a low cost industrial solution for automation and research. OpenPLC has been used in [many research papers](https://scholar.google.com/scholar?as_ylo=2014&q=openplc&hl=en&as_sdt=0,1) as a framework for industrial cyber security research, given that it is the only controller to provide the entire source code.
|
||||
The OpenPLC Project consists of three sub-projects:
|
||||
1. [Runtime](https://github.com/thiagoralves/OpenPLC_v3)
|
||||
2. [Programming editor](http://www.openplcproject.com/downloads)
|
||||
3. [HMI builder](http://www.openplcproject.com/reference-installing-scadabr)
|
||||
<br/>
|
||||
To install:
|
||||
<br/>
|
||||
git clone https://github.com/thiagoralves/OpenPLC_v3.git
|
||||
<br/>
|
||||
cd OpenPLC_v3
|
||||
<br/>
|
||||
./install.sh [platform]
|
||||
<br/>
|
||||
where [platform] can be
|
||||
<br/>
|
||||
**win** - Install OpenPLC on Windows over Cygwin
|
||||
<br/>
|
||||
**linux** - Install OpenPLC on a Debian-based Linux distribution
|
||||
<br/>
|
||||
**rpi** - Install OpenPLC on a Raspberry Pi
|
||||
<br/>
|
||||
**custom** - Skip all specific package installation and tries to install OpenPLC assuming your system already has all dependencies met. This option can be useful if you're trying to install OpenPLC on an unsuported Linux platform or had manually installed all the dependency packages before.
|
||||
|
||||
Executable
+253
@@ -0,0 +1,253 @@
|
||||
#!/bin/bash
|
||||
if [ $# -eq 0 ]; then
|
||||
echo ""
|
||||
echo "Error: You must provide a platform name as argument"
|
||||
echo ""
|
||||
echo "Usage: ./install.sh [platform] where [platform] can be"
|
||||
echo " win Install OpenPLC on Windows over Cygwin"
|
||||
echo " linux Install OpenPLC on a Debian-based Linux distribution"
|
||||
echo " rpi Install OpenPLC on a Raspberry Pi"
|
||||
echo " custom Skip all specific package installation and tries to install"
|
||||
echo " OpenPLC assuming your system already has all dependencies met."
|
||||
echo " This option can be useful if you're trying to install OpenPLC"
|
||||
echo " on an unsuported Linux platform or had manually installed"
|
||||
echo " all the dependency packages before."
|
||||
echo ""
|
||||
exit 1
|
||||
fi
|
||||
|
||||
if [ "$1" == "win" ]; then
|
||||
echo "Installing OpenPLC on Windows"
|
||||
cp ./utils/apt-cyg/apt-cyg ./
|
||||
cp ./utils/apt-cyg/wget.exe /bin
|
||||
install apt-cyg /bin
|
||||
apt-cyg install lynx
|
||||
rm -f /bin/wget.exe
|
||||
apt-cyg install wget gcc-core gcc-g++ git pkg-config automake autoconf libtool make python2 python2-pip sqlite3
|
||||
lynx -source https://bootstrap.pypa.io/get-pip.py > get-pip.py
|
||||
python get-pip.py
|
||||
pip install flask
|
||||
pip install flask-login
|
||||
|
||||
echo ""
|
||||
echo "[MATIEC COMPILER]"
|
||||
cp ./utils/matiec_src/bin_win32/*.* ./webserver/
|
||||
if [ $? -ne 0 ]; then
|
||||
echo "Error compiling MatIEC"
|
||||
echo "OpenPLC was NOT installed!"
|
||||
exit 1
|
||||
fi
|
||||
|
||||
echo ""
|
||||
echo "[ST OPTIMIZER]"
|
||||
cd utils/st_optimizer_src
|
||||
g++ st_optimizer.cpp -o st_optimizer
|
||||
cp ./st_optimizer.exe ../../webserver/
|
||||
if [ $? -ne 0 ]; then
|
||||
echo "Error compiling ST Optimizer"
|
||||
echo "OpenPLC was NOT installed!"
|
||||
exit 1
|
||||
fi
|
||||
cd ../..
|
||||
|
||||
echo ""
|
||||
echo "[GLUE GENERATOR]"
|
||||
cd utils/glue_generator_src
|
||||
g++ glue_generator.cpp -o glue_generator
|
||||
cp ./glue_generator.exe ../../webserver/core
|
||||
if [ $? -ne 0 ]; then
|
||||
echo "Error compiling Glue Generator"
|
||||
echo "OpenPLC was NOT installed!"
|
||||
exit 1
|
||||
fi
|
||||
cd ../..
|
||||
|
||||
echo ""
|
||||
echo "[OPEN DNP3]"
|
||||
cd webserver/core
|
||||
mv dnp3.cpp dnp3.disabled
|
||||
if [ $? -ne 0 ]; then
|
||||
echo "Error disabling OpenDNP3"
|
||||
echo "OpenPLC was NOT installed!"
|
||||
exit 1
|
||||
fi
|
||||
mv dnp3_dummy.disabled dnp3_dummy.cpp
|
||||
if [ $? -ne 0 ]; then
|
||||
echo "Error disabling OpenDNP3"
|
||||
echo "OpenPLC was NOT installed!"
|
||||
exit 1
|
||||
fi
|
||||
cd ../..
|
||||
|
||||
echo ""
|
||||
echo "[FINALIZING]"
|
||||
cd webserver/scripts
|
||||
./change_hardware_layer.sh blank
|
||||
./compile_program.sh blank_program.st
|
||||
cp ./start_openplc.sh ../../
|
||||
|
||||
|
||||
|
||||
elif [ "$1" == "linux" ]; then
|
||||
echo "Installing OpenPLC on Linux"
|
||||
sudo apt-get update
|
||||
sudo apt-get install build-essential pkg-config bison flex autoconf automake libtool make git python2.7 python-pip sqlite3 cmake
|
||||
|
||||
echo ""
|
||||
echo "[MATIEC COMPILER]"
|
||||
cd utils/matiec_src
|
||||
autoreconf -i
|
||||
./configure
|
||||
make
|
||||
cp ./iec2c ../../webserver/
|
||||
if [ $? -ne 0 ]; then
|
||||
echo "Error compiling MatIEC"
|
||||
echo "OpenPLC was NOT installed!"
|
||||
exit 1
|
||||
fi
|
||||
cd ../..
|
||||
|
||||
echo ""
|
||||
echo "[ST OPTIMIZER]"
|
||||
cd utils/st_optimizer_src
|
||||
g++ st_optimizer.cpp -o st_optimizer
|
||||
cp ./st_optimizer ../../webserver/
|
||||
if [ $? -ne 0 ]; then
|
||||
echo "Error compiling ST Optimizer"
|
||||
echo "OpenPLC was NOT installed!"
|
||||
exit 1
|
||||
fi
|
||||
cd ../..
|
||||
|
||||
echo ""
|
||||
echo "[GLUE GENERATOR]"
|
||||
cd utils/glue_generator_src
|
||||
g++ glue_generator.cpp -o glue_generator
|
||||
cp ./glue_generator ../../webserver/core
|
||||
if [ $? -ne 0 ]; then
|
||||
echo "Error compiling Glue Generator"
|
||||
echo "OpenPLC was NOT installed!"
|
||||
exit 1
|
||||
fi
|
||||
cd ../..
|
||||
|
||||
echo ""
|
||||
echo "[OPEN DNP3]"
|
||||
cd utils/dnp3_src
|
||||
echo "creating swapfile..."
|
||||
sudo dd if=/dev/zero of=swapfile bs=1M count=1000
|
||||
sudo mkswap swapfile
|
||||
sudo swapon swapfile
|
||||
cmake ../dnp3_src
|
||||
make
|
||||
sudo make install
|
||||
if [ $? -ne 0 ]; then
|
||||
echo "Error installing OpenDNP3"
|
||||
echo "OpenPLC was NOT installed!"
|
||||
exit 1
|
||||
fi
|
||||
sudo ldconfig
|
||||
echo "removing swapfile..."
|
||||
sudo swapoff swapfile
|
||||
sudo rm -f ./swapfile
|
||||
cd ../..
|
||||
|
||||
echo ""
|
||||
echo "[FINALIZING]"
|
||||
cd webserver/scripts
|
||||
./change_hardware_layer.sh blank_linux
|
||||
./compile_program.sh blank_program.st
|
||||
cp ./start_openplc.sh ../../
|
||||
|
||||
|
||||
|
||||
elif [ "$1" == "rpi" ]; then
|
||||
echo "Installing OpenPLC on Raspberry Pi"
|
||||
sudo apt-get update
|
||||
sudo apt-get install build-essential pkg-config bison flex autoconf automake libtool make git python2.7 python-pip sqlite3 cmake wiringpi
|
||||
|
||||
echo ""
|
||||
echo "[MATIEC COMPILER]"
|
||||
cd utils/matiec_src
|
||||
autoreconf -i
|
||||
./configure
|
||||
make
|
||||
cp ./iec2c ../../webserver/
|
||||
if [ $? -ne 0 ]; then
|
||||
echo "Error compiling MatIEC"
|
||||
echo "OpenPLC was NOT installed!"
|
||||
exit 1
|
||||
fi
|
||||
cd ../..
|
||||
|
||||
echo ""
|
||||
echo "[ST OPTIMIZER]"
|
||||
cd utils/st_optimizer_src
|
||||
g++ st_optimizer.cpp -o st_optimizer
|
||||
cp ./st_optimizer ../../webserver/
|
||||
if [ $? -ne 0 ]; then
|
||||
echo "Error compiling ST Optimizer"
|
||||
echo "OpenPLC was NOT installed!"
|
||||
exit 1
|
||||
fi
|
||||
cd ../..
|
||||
|
||||
echo ""
|
||||
echo "[GLUE GENERATOR]"
|
||||
cd utils/glue_generator_src
|
||||
g++ glue_generator.cpp -o glue_generator
|
||||
cp ./glue_generator ../../webserver/core
|
||||
if [ $? -ne 0 ]; then
|
||||
echo "Error compiling Glue Generator"
|
||||
echo "OpenPLC was NOT installed!"
|
||||
exit 1
|
||||
fi
|
||||
cd ../..
|
||||
|
||||
echo ""
|
||||
echo "[OPEN DNP3]"
|
||||
cd utils/dnp3_src
|
||||
echo "creating swapfile..."
|
||||
sudo dd if=/dev/zero of=swapfile bs=1M count=1000
|
||||
sudo mkswap swapfile
|
||||
sudo swapon swapfile
|
||||
cmake ../dnp3_src
|
||||
make
|
||||
sudo make install
|
||||
if [ $? -ne 0 ]; then
|
||||
echo "Error installing OpenDNP3"
|
||||
echo "OpenPLC was NOT installed!"
|
||||
exit 1
|
||||
fi
|
||||
sudo ldconfig
|
||||
echo "removing swapfile..."
|
||||
sudo swapoff swapfile
|
||||
sudo rm -f ./swapfile
|
||||
cd ../..
|
||||
|
||||
echo ""
|
||||
echo "[FINALIZING]"
|
||||
cd webserver/scripts
|
||||
./change_hardware_layer.sh blank_linux
|
||||
./compile_program.sh blank_program.st
|
||||
cp ./start_openplc.sh ../../
|
||||
|
||||
|
||||
else
|
||||
echo ""
|
||||
echo "Error: unrecognized platform"
|
||||
echo ""
|
||||
echo "Usage: ./install.sh [platform] where [platform] can be"
|
||||
echo " win Install OpenPLC on Windows over Cygwin"
|
||||
echo " linux Install OpenPLC on a Debian-based Linux distribution"
|
||||
echo " rpi Install OpenPLC on a Raspberry Pi"
|
||||
echo " custom Skip all specific package installation and tries to install"
|
||||
echo " OpenPLC assuming your system already has all dependencies met."
|
||||
echo " This option can be useful if you're trying to install OpenPLC"
|
||||
echo " on an unsuported Linux platform or had manually installed"
|
||||
echo " all the dependency packages before."
|
||||
echo ""
|
||||
exit 1
|
||||
fi
|
||||
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
Executable
BIN
Binary file not shown.
@@ -0,0 +1,209 @@
|
||||
### 2.2.0 ###
|
||||
* No changes from 2.2.0-RC5
|
||||
|
||||
### 2.2.0-RC5 ###
|
||||
* :beetle: Fixed a [bug](https://github.com/automatak/dnp3/issues/200) where connection attempts were not retrieved after failed DNS resolution.
|
||||
|
||||
### 2.2.0-RC4 ###
|
||||
* :beetle: Fixed a [regression](https://github.com/automatak/dnp3/issues/197) in outstation whereby the session could hang indefinitely if a non-read request was received during UnsolConirmWait.
|
||||
|
||||
### 2.2.0-RC3 ###
|
||||
* :beetle: Fixed a [regression](https://github.com/automatak/dnp3/issues/195) whereby multi segment messages could be transmitted with trailing garbage.
|
||||
* :beetle: Fixed a bug whereby improper TLS shutdown from the remote host could result in an infinite loop. TLS shutdown is no longer utilized in favor of just a hard TCP close.
|
||||
|
||||
### 2.2.0-RC2 ###
|
||||
* :beetle: Java bindings in 2.2.0-RC1 were leaking local references. Modified the bindings to use resource management class to ensure this doens't happen going forward.
|
||||
* :beetle: Fixed a [bug](https://github.com/automatak/dnp3/issues/187) in outstation/master enable/disable that put the session into an invalid state.
|
||||
|
||||
### 2.2.0-RC1 ###
|
||||
* :star: Java bindings have been added to the project.
|
||||
* :star: New API for creating "masters as servers" (aka GPRS-based systems)
|
||||
* :wrench: DNP3Manager now returns shared_ptr<IChannel>. IChannel now returns shared_ptr<IMaster/IOutstation>. Shutdown is now idempotent on
|
||||
these interfaces used via shared_ptr.
|
||||
* :wrench: Channel, master, and outstation now accept all callback interfaces via shared_ptr.
|
||||
* :wrench: The external format for statistics has been changed to ease maintainence. Each class now owns the statistics it increments.
|
||||
* :beetle: Fixed a [bug](https://github.com/automatak/dnp3/issues/175) where the keep-alive timer would rapidly fire in C# if set to Timespan.MaxValue.
|
||||
* :beetle: Fixed a [bug](https://github.com/automatak/dnp3/issues/164) in the outstation state machine where it would incorrectly ignore repeat READ requests.
|
||||
* :beetle: Fixed a bug in the ASDU formatting where a request for a range of 255 measurement values would result in a malformed response.
|
||||
* :beetle: Fixed a [bug](https://github.com/automatak/dnp3/issues/173) in the TLS client that caused the channel to be unrecoverable after any disconnect.
|
||||
|
||||
### 2.1.0 ###
|
||||
* Minor formatting and documentation tweaks
|
||||
|
||||
### 2.1.0-RC6 ###
|
||||
* :wrench: The C# LinkConfig class now uses Timespan for timeouts for consistency with other API elements. This also solved
|
||||
an issue where the LinkTimeout could not be effectively disabled since MaxInt wasn't big enough to ensure it never ran.
|
||||
* :wrench: Moved experimental SA components to the "secauth" branch.
|
||||
* :wrench: ILogHandler is now injected as an argument to the DNP3Manager constructor as a shared_ptr.
|
||||
* :star: Master and outstation interfaces can now control their log level independently of the channel they're created on.
|
||||
* :beetle: Fixed a bug in the C# bindings where the ILogHandler was prematurely freed by the GC.
|
||||
* Refactored cmake build files into several sub-files for better modularity.
|
||||
|
||||
### 2.1.0-RC5 ###
|
||||
* :beetle: Fixed a bug in the master multi-drop functionality where removing an active master, caused remaining session to freeze.
|
||||
* :beetle: Fixed a bug in ClearRestartTask where the completion callback was invoked with the wrong task type.
|
||||
* :star: HeaderInfo class in ISOEHandler now exposes isEvent member which tells user if header is for an event type. Added this to C# as well.
|
||||
* :star: C++ outstation demos now load the current timestamp using overloaded MeasUpdate constructor
|
||||
|
||||
### 2.1.0-RC4 ###
|
||||
* :star: Tagged released now automatically deployed to Nuget via AppVeyor build
|
||||
* :star: Code generator now produces lookup functions for group variation time/tag information.
|
||||
* :star: Added a decoder feature used to power the website decoder.
|
||||
|
||||
### 2.1.0-RC3 ###
|
||||
* :beetle: Fixed a bug in the C# bindings where non-zero based indices were not being detected properly.
|
||||
|
||||
### 2.1.0-RC2 ###
|
||||
* :beetle: Fixed a bug that was causing the keep-alive to not retry at the configured rate
|
||||
|
||||
### 2.1.0-RC1 ###
|
||||
* Migrated fully to CMake, including generated SLN
|
||||
* Separated include vs private headers
|
||||
* New guide + doxygen docs
|
||||
* Add an ILinkListener interface inherited by IMasterApplication/IOutstationApplication that allows you to monitor link-layer activity.
|
||||
* Master can now send any combination and # of commands in a single request
|
||||
* Support for TLS client/server (optional in build)
|
||||
* Modified the IMaster interface to inherit from ICommandProcessor which now contains only two methods.
|
||||
* Master now uses Task[T] everywhere instead of custom Future[T]. Eases uses with TPL and async/await.
|
||||
* Master now has a parameter to timeout tasks that fail to start within a certain TimeDuration.
|
||||
* Implemented the RequestLinkStates/LinkStatus heartbeat functionality in 1815.
|
||||
* :beetle: Fixed a bug in the way CTO objects were handled w/ Group2Var3 and Group4Var3
|
||||
* C# bindings now use .NET Task[T] instead of custom Future[T]
|
||||
* Introduced an experimental version of SAv5 (not intended for production use)
|
||||
* Significantly refactored the master/outstation internals to accommodate adding SA via inheritance.
|
||||
* Added parser/formatter generators for variable-length objects in Group120
|
||||
|
||||
|
||||
### 2.0.1 ###
|
||||
No changes to 2.0.1-RC3 for final 2.0.1 release
|
||||
|
||||
### 2.0.1-RC3 ###
|
||||
* Workaround for broken std::chrono::steady_clock impl thanks to Liam MacIsaac.
|
||||
* Based on user feedback, the .NET outstation API now uses a more intuitive "ChangeSet" to update values in the outstation.
|
||||
* The .NET "simulator" has been restored with more features surfaced and outstation plugins can now be written to simulate devices.
|
||||
|
||||
### 2.0.1-RC2 ###
|
||||
* DNPManager.AddTCPClient now takes an additional parameter for the local adapter address (0.0.0.0 == all adapters)
|
||||
* Overloaded CROB constructor allows for non-standard control codes to be specified.
|
||||
* Fixed a thread-safety issue in the outstation on data update. The API has shifted for updating the outstation database to accomodate this fix.
|
||||
* Fixed an uninitialized control code variable in the CROB introduced in 2.0.1-RC1.
|
||||
|
||||
### 2.0.1-RC1 ###
|
||||
* Added support for Group50Var4 (Time and Interval) objects. These are static only objects (no events) that can are read/write.
|
||||
* Added support for Binary/Analog command events to the parser and the master API courtesy of Sid Hoda.
|
||||
* Added support for the ASSIGN_CLASS function code.
|
||||
* Assignment to the outstation db is automatic, but there is a callback on IOutstationApplication for any desired user action
|
||||
* The master can assign class automatically during the startup handshaking based on callbacks in IMasterApplication
|
||||
* Substantially refactored/simplified the master scheduler to make extension easier.
|
||||
* Most tasks that are explicitly rejected via IIN bits (e.g. enable/disable unsol) no longer retry on failure
|
||||
* Added support for discontigous outstation databases based on an earlier contriubtion from Alan Murray
|
||||
* Virtual (dnp3) indices are now assigned after creation of the outstation, but before enabling it
|
||||
* Note: Discontigous mode must be set in the OutstationConfig in C++, automatically detected in C#
|
||||
* Discontiguous mode is slightly less performant on range-based READ's because of O(log(n)) binary search
|
||||
* Static and event response types can now be configured on a per-point basis
|
||||
* In C++ this occurs after creating the outstation instance, but before enabling it.
|
||||
* In C#, all values are specified in the DatabaseTemplate
|
||||
* Fixed a minor conformance issue: Group1Var1 is now promoted to Group1Var2 if the quality != ONLINE
|
||||
* The are now two methods for monitoring master tasks
|
||||
* Callbacks on IMasterApplication for built-in tasks and ones that were created with a userId
|
||||
* Optional per-task callback interfaces supplied when the task was created
|
||||
* Arbitrary master scans (qualifiers 0x06, 0x00/0x01, 0x07/0x08) can now be created in C# using an API contributed by Damon Sutherland
|
||||
* Added a flag to the outstation that limits the number of queued event checks to 1. This was done for determinism on embedded systems with limited space to queue executor actions.
|
||||
|
||||
|
||||
|
||||
### 2.0.0 ###
|
||||
* Fixed an issue in openpal::Synchronized where the stack would deadlock under heavy contention
|
||||
* Fixed bug where counter 'numTransportErrorRx' was incremented twice
|
||||
* The log alias in LogRoot is now dynamically sized removed the artificial limitation
|
||||
|
||||
|
||||
### 2.0.0-RC3 ###
|
||||
* Dynamic memory allocation now allowed in core library during initialization.
|
||||
* Removed various redundant static container types in openpal
|
||||
* Database and event buffers now create they underlying storage from configuration
|
||||
* Hard limits that were in Configure.h are no longer necessary.
|
||||
* C++/C# master API now receives callback whenever an IIN field is received to allow user layer processing.
|
||||
* Fixed a bug where periodic taks with period < 0 would rapid-retry instead ()
|
||||
* Added an embedded demo for the sam3x8E ARM (arduino DUE)
|
||||
* Parsers are no longer singletons, both groups of functions to reduce SRAM usage on embedded systems.
|
||||
* ICommandHandler semantics switched back to Select/Operate to more closely match spec. Operate is indistinguisable from DirectOperate at user layer
|
||||
* Include guards now prepend library name to avoid potential conflicts
|
||||
* Master can now bind arbitrary 0x06 (all objects) periodic scans
|
||||
|
||||
|
||||
### 2.0.0-RC2 ###
|
||||
|
||||
Conformance fixes based on testing with 3rd party harness. Only remaining level 2 conformance item is handling broadcast addressing.
|
||||
* Outstation now handles limited count (0x07, 0x08) request headers for class polls and specific variation polls.
|
||||
* IOutstationApplication can now handle cold/warm restart function codes.
|
||||
|
||||
Master measurement API (ISOEHandler) now informs application of qualifer, group variation, and validity of timestamps for each header received.
|
||||
|
||||
### 2.0.0-RC1 ###
|
||||
|
||||
## Refactoring / Improvements - General ##
|
||||
* To enable ports to other platforms and MCUs, the 1.1.x library was divided into 4 sub-libraries.
|
||||
* openpal - The Platform Abstraction Layer (PAL) provides abtract base classes for key abstractions like IPhysicalLayer, IExecutor, ITimer, etc.
|
||||
* opendnp3 - The core dnp3 library. It only depends on openpal and is platform independent C++11.
|
||||
* asiopal - Implements the PAL using boost::asio. This PAL can be used on server platforms like Windows, Linux, & OSX. It only depends on openpal.
|
||||
* asiodnp3 - Provides a nice wrapper to opendnp3 for server platforms. Depends on all three libraries.
|
||||
|
||||
* Library uses a new parser and generator that vastly improves readability, maintainability, performance, and safety.
|
||||
* Example applications for Atmel Studio for Arduino boards have been added. They are not yet production ready, but a proof of concept.
|
||||
* Stack depth has been reduced to better suite embedded systems.
|
||||
* Core library is now organized by layer making navigation, maintainence, and learning the library easier.
|
||||
* C++ libraries are now exception-free. They can be compiled with -fno-exceptions.
|
||||
* IExecutor now uses an "Action0" which is a parameterless functor. Uses type-safe erasure/lambdas combined with static allocation.
|
||||
* Core library now uses sprintf instead of iostreams. All usage of std::string removed to improve portability.
|
||||
* Removed some instances of recursion in the link layer CRC checking. The library is now recursion-free.
|
||||
* The library no longer uses BOOST. Instead it uses the standalone verison (header only) of [ASIO](http://think-async.com/)
|
||||
* Tests were ported from BOOST_TEST to [Catch](https://github.com/philsquared/Catch). Catch is header only and redistributed with the project.
|
||||
* Core library no longer uses STL. This makes ports to MCUs much easier.
|
||||
* Core library no longer uses dynamic memory allocation. Databases and buffers are either statically allocated or injected allowing the user to choose.
|
||||
* Library no longer uses size_t as this type changes length on 32/64-bit platforms. Explicit types are now used from <cstdint>.
|
||||
* Application layer objects and most enums are now generated using a companion Scala project in the 'generation' folder.
|
||||
* Buffer wrappers "WriteBuffer" and "ReadOnlyBuffer" are now passed around internally instead of pairs of uint8_t* and uint32_t.
|
||||
* Upgraded solution file to VS2013
|
||||
* x86 and x64 outputs now build side-by-side
|
||||
* LogEntry class no longer carries timestamp. This allows the timestamp to be set by the specific platform.
|
||||
* Setpoint/Control terminology changed to AnalogOutput & BinaryOutput to correspond to the specification.
|
||||
* Libraries no longer have separate src/include directories. This decision was premature.
|
||||
* Clang is now an officially supported compiler and will also be used for static analysis. Project compiles with Clang 3.4.
|
||||
* Logging is now explicitly controlled using the bitfields instead of enums. This allows dnp3 specific log levels to be defined without polluting openpal with their definitions.
|
||||
|
||||
## External Features ##
|
||||
|
||||
* Ticket 56 - Measurement types can now tell the user if the timestamp is valid or not (bool IsTimeValid() const)
|
||||
* Ticket 43 - Master command callbacks now provide a type that can distinguish between local and remote failure, e.g. when the repsonse times out or the channel is closed.
|
||||
* Ticket 47 - TCP client can now perform asynchronous DNS host resolution and try mutliple resolved addresses in a single "open" sequence.
|
||||
* Ticket 56 - C++ channels can also specify a "strategy" for full control over the wait period for retry.
|
||||
* Ticket 30 - Outstation API now provides control of the NeedTime IIN bit.
|
||||
* Ticket 29 - Scans are now exposed as part of the master API. Callbacks can be registered to observe success and failure. Class scans may be defined dynamically and performed on demand.
|
||||
* C++ TCP Client/Server can now configure native socket types with an optional functor. This allows platform-specific customization of things like TCP keep-alives.
|
||||
* Master applications now specify "ISOEHandler" (Sequence of Events) instead of "IDataObserver". It allows users to discern between static and event types.
|
||||
* Renamed outstation API "IDataObserver" to the more descriptive "IMeasurementLoader"
|
||||
* Outstation now uses a simple interface "ITimeWriteHandler" to receive time write requests
|
||||
* The start of a master or outstation is delayed until a Enable() method is called. Stacks may be dynamically paused/resumed at runtime with the Enable/Disable methods.
|
||||
* Master now supports additional types:
|
||||
* Frozen Counters, Double-bit Binaries, and Octet Strings
|
||||
* Outstation now supports additional types:
|
||||
* Frozen Counters, Double-bit Binaries, and AO/BO status events
|
||||
* Java Future can now be called with an optional timeout
|
||||
* Channels now have expoential backoff capability controlled by min/max retry parameters.
|
||||
* Each channel can low control the its log level dynamically via the SetLogFilters() method.
|
||||
|
||||
## Bug / conformance fixes ##
|
||||
* Default integrity poll is now a Class 1/2/3/0 scan as per the specification.
|
||||
* Outstation now reports events in correct order-of-occurence across all seven types it supports.
|
||||
* Physical layer disconnects now observer the minRetry parameter. This prevents rapid connect/disconnect cycling when a server is closing connections.
|
||||
* Transport layer can now receive non-fin packets with payload length between 1 and 249. It's very strange for an implementation to do this, but its actually in the spec.
|
||||
* Count-of-zero headers are now explicitly disallowed and parsing is halted.
|
||||
* Ticket 57 - When a READ is received while waiting for a confirm, any further retries should be canceled. (also fixed on 1.1.x)
|
||||
* Ticket 62 - Fixed a bug where the master scheduler could hang if the the channel was closed while waiting for response to a command.
|
||||
|
||||
## Removed ##
|
||||
* VTO "routers" are now longer provided. 0-length strings of all types (Groups 110-113) are now explicitly not allowed.
|
||||
* ASIOPAL now explicitly uses std::chrono::steady_clock for timers. There is no longer a typedef.
|
||||
* Library no longer supports 4-octet qualifier codes. All indices used uint16_t as underlying type.
|
||||
* Support for "delta" values has been removed. New implementations do not need to support this according to the spec.
|
||||
@@ -0,0 +1,260 @@
|
||||
cmake_minimum_required (VERSION 2.8)
|
||||
|
||||
project (opendnp3)
|
||||
set(OPENDNP3_MAJOR_VERSION 2)
|
||||
set(OPENDNP3_MINOR_VERSION 2)
|
||||
set(OPENDNP3_MICRO_VERSION 1)
|
||||
set(OPENDNP3_VERSION ${OPENDNP3_MAJOR_VERSION}.${OPENDNP3_MINOR_VERSION}.${OPENDNP3_MICRO_VERSION})
|
||||
|
||||
if(NOT CMAKE_BUILD_TYPE)
|
||||
set(CMAKE_BUILD_TYPE "Release" CACHE STRING
|
||||
"Choose the type of build, options are: Debug Release
|
||||
RelWithDebInfo MinSizeRel."
|
||||
FORCE)
|
||||
endif()
|
||||
|
||||
message("CMake build is: ${CMAKE_BUILD_TYPE}")
|
||||
|
||||
include(${PROJECT_SOURCE_DIR}/cmake/settings.cmake)
|
||||
|
||||
# various optional libraries and projects
|
||||
|
||||
option(DNP3_ALL "Build all optional projects (secauth, demos, tests)" OFF)
|
||||
option(DNP3_TEST "Build tests" OFF)
|
||||
option(DNP3_DEMO "Build demo applications" OFF)
|
||||
option(DNP3_DECODER "Build the decoder library" OFF)
|
||||
option(DNP3_TLS "Build TLS client/server support" OFF)
|
||||
option(DNP3_JAVA "Build the Java bindings" OFF)
|
||||
|
||||
# other options off-by-default that you can enable
|
||||
option(WERROR "Set all warnings to errors" OFF)
|
||||
option(STATICLIBS "Builds static versions of all installed libraries" OFF)
|
||||
option(COVERAGE "Builds the libraries with coverage info for gcov (gcc only)" OFF)
|
||||
option(PROFILE "Builds the libraries with profiling support (gcc only)" OFF)
|
||||
|
||||
if(DNP3_ALL)
|
||||
message("enabling all optional components")
|
||||
set(DNP3_DEMO ON)
|
||||
set(DNP3_TEST ON)
|
||||
set(DNP3_TLS ON)
|
||||
set(DNP3_DECODER ON)
|
||||
set(DNP3_JAVA ON)
|
||||
endif()
|
||||
|
||||
if(DNP3_JAVA)
|
||||
find_package(Java COMPONENTS Development)
|
||||
find_package(JNI REQUIRED)
|
||||
include_directories(${JNI_INCLUDE_DIRS})
|
||||
endif()
|
||||
|
||||
SET(ASIO_SUBMODULE_DIR "${PROJECT_SOURCE_DIR}/deps/asio/asio/include")
|
||||
|
||||
# detection stuff for ASIO
|
||||
if (EXISTS "${ASIO_SUBMODULE_DIR}/asio.hpp")
|
||||
message("ASIO has been checked out as a git submodule: ${ASIO_SUBMODULE_DIR}")
|
||||
include_directories(${ASIO_SUBMODULE_DIR})
|
||||
else()
|
||||
message("ASIO has NOT been checked out as a git submodule...")
|
||||
if (ASIO_HOME)
|
||||
message("ASIO_HOME defined in cache: ${ASIO_HOME}")
|
||||
include_directories(${ASIO_HOME})
|
||||
else()
|
||||
if(DEFINED ENV{ASIO_HOME})
|
||||
message("ASIO_HOME defined in environment: $ENV{ASIO_HOME}")
|
||||
include_directories($ENV{ASIO_HOME})
|
||||
else()
|
||||
message("ASIO_HOME was not defined. ASIO expected to be on include path")
|
||||
endif()
|
||||
endif()
|
||||
endif()
|
||||
|
||||
# required for ASIO in C++11 only mode
|
||||
add_definitions(-DASIO_STANDALONE)
|
||||
|
||||
if(DNP3_TLS)
|
||||
add_definitions(-DOPENDNP3_USE_TLS)
|
||||
|
||||
find_package(OpenSSL REQUIRED)
|
||||
message("OpenSSL libraries: ${OPENSSL_LIBRARIES}")
|
||||
if(WIN32)
|
||||
include_directories(${OPENSSL_INCLUDE_DIR})
|
||||
endif()
|
||||
endif()
|
||||
|
||||
set(CMAKE_REQUIRED_FLAGS ${CMAKE_CXX_FLAGS})
|
||||
|
||||
# include paths for all the local libraries
|
||||
include_directories(./cpp/libs/src)
|
||||
include_directories(./cpp/libs/include)
|
||||
include_directories(./cpp/tests/libs/src)
|
||||
|
||||
# ---- openpal library ----
|
||||
file(GLOB_RECURSE openpal_SRC ./cpp/libs/src/openpal/*.cpp ./cpp/libs/src/openpal/*.h ./cpp/libs/include/openpal/*.h)
|
||||
add_library(openpal ${LIB_TYPE} ${openpal_SRC})
|
||||
install(TARGETS openpal DESTINATION lib)
|
||||
set_target_properties(openpal PROPERTIES FOLDER libs)
|
||||
|
||||
# ---- opendnp3 library ----
|
||||
file(GLOB_RECURSE opendnp3_SRC ./cpp/libs/src/opendnp3/*.cpp ./cpp/libs/src/opendnp3/*.h ./cpp/libs/include/opendnp3/*.h)
|
||||
add_library(opendnp3 ${LIB_TYPE} ${opendnp3_SRC})
|
||||
target_link_libraries(opendnp3 openpal)
|
||||
install(TARGETS opendnp3 DESTINATION lib)
|
||||
set_target_properties(opendnp3 PROPERTIES FOLDER libs)
|
||||
|
||||
if(DNP3_DECODER)
|
||||
file(GLOB_RECURSE dnp3decode_SRC ./cpp/libs/src/dnp3decode/*.cpp ./cpp/libs/src/dnp3decode/*.h ./cpp/libs/include/dnp3decode/*.h)
|
||||
add_library(dnp3decode ${LIB_TYPE} ${dnp3decode_SRC})
|
||||
target_link_libraries(dnp3decode opendnp3)
|
||||
install(TARGETS dnp3decode DESTINATION lib)
|
||||
set_target_properties(dnp3decode PROPERTIES FOLDER libs)
|
||||
endif()
|
||||
|
||||
# ---- asiopal library ----
|
||||
file(GLOB_RECURSE asiopal_HPP ./cpp/libs/src/asiopal/*.h ./cpp/libs/include/asiopal/*.h)
|
||||
|
||||
if(DNP3_TLS)
|
||||
file(GLOB_RECURSE asiopal_CPP ./cpp/libs/src/asiopal/*.cpp)
|
||||
else()
|
||||
file(GLOB asiopal_CPP ./cpp/libs/src/asiopal/*.cpp)
|
||||
endif()
|
||||
|
||||
add_library(asiopal ${LIB_TYPE} ${asiopal_HPP} ${asiopal_CPP})
|
||||
|
||||
set(asiopal_link_libraries "openpal")
|
||||
if(DNP3_TLS)
|
||||
set(asiopal_link_libraries "${asiopal_link_libraries};${OPENSSL_LIBRARIES}")
|
||||
endif()
|
||||
|
||||
target_link_libraries(asiopal ${asiopal_link_libraries})
|
||||
install(TARGETS asiopal DESTINATION lib)
|
||||
set_target_properties(asiopal PROPERTIES FOLDER libs)
|
||||
|
||||
# ---- asiodnp3 library ----
|
||||
file(GLOB_RECURSE asiodnp3_HPP ./cpp/libs/src/asiodnp3/*.h ./cpp/libs/include/asiodnp3/*.h)
|
||||
if(DNP3_TLS)
|
||||
file(GLOB_RECURSE asiodnp3_CPP ./cpp/libs/src/asiodnp3/*.cpp)
|
||||
else()
|
||||
file(GLOB asiodnp3_CPP ./cpp/libs/src/asiodnp3/*.cpp)
|
||||
endif()
|
||||
add_library(asiodnp3 ${LIB_TYPE} ${asiodnp3_HPP} ${asiodnp3_CPP})
|
||||
target_link_libraries(asiodnp3 asiopal opendnp3)
|
||||
install(TARGETS asiodnp3 DESTINATION lib)
|
||||
set_target_properties(asiodnp3 PROPERTIES FOLDER libs)
|
||||
|
||||
if(DNP3_JAVA)
|
||||
file(GLOB_RECURSE opendnp3java_SRC ./java/cpp/*.h ./java/cpp/*.cpp)
|
||||
add_library(opendnp3java SHARED ${opendnp3java_SRC})
|
||||
target_link_libraries(opendnp3java asiodnp3)
|
||||
install(TARGETS opendnp3java DESTINATION lib)
|
||||
set_target_properties(opendnp3java PROPERTIES FOLDER libs)
|
||||
endif()
|
||||
|
||||
# ----- install -----
|
||||
|
||||
# common pattern and exludes for all installed headers
|
||||
set(INSTALL_ARGS FILES_MATCHING PATTERN "*.h" PATTERN ".deps" EXCLUDE PATTERN ".libs" EXCLUDE)
|
||||
install(DIRECTORY ./cpp/libs/include/ DESTINATION include ${INSTALL_ARGS})
|
||||
|
||||
if(DNP3_DEMO)
|
||||
|
||||
# ----- master demo executable -----
|
||||
add_executable(master-demo ./cpp/examples/master/main.cpp)
|
||||
target_link_libraries (master-demo LINK_PUBLIC asiodnp3 ${PTHREAD})
|
||||
set_target_properties(master-demo PROPERTIES FOLDER demos)
|
||||
|
||||
# ----- master demo executable -----
|
||||
add_executable(master-gprs-demo ./cpp/examples/master-gprs/main.cpp)
|
||||
target_link_libraries (master-gprs-demo LINK_PUBLIC asiodnp3 ${PTHREAD})
|
||||
set_target_properties(master-gprs-demo PROPERTIES FOLDER demos)
|
||||
|
||||
# ----- outstation demo executable -----
|
||||
add_executable(outstation-demo ./cpp/examples/outstation/main.cpp)
|
||||
target_link_libraries (outstation-demo LINK_PUBLIC asiodnp3 ${PTHREAD})
|
||||
set_target_properties(outstation-demo PROPERTIES FOLDER demos)
|
||||
|
||||
if(DNP3_DECODER)
|
||||
|
||||
# ----- decoder executable -----
|
||||
add_executable(decoder ./cpp/examples/decoder/main.cpp)
|
||||
target_link_libraries (decoder asiodnp3 dnp3decode ${PTHREAD})
|
||||
set_target_properties(decoder PROPERTIES FOLDER demos)
|
||||
|
||||
endif()
|
||||
|
||||
if(DNP3_TLS)
|
||||
|
||||
# ----- master tls executable -----
|
||||
add_executable(master-tls-demo ./cpp/examples/tls/master/main.cpp)
|
||||
target_link_libraries (master-tls-demo LINK_PUBLIC asiodnp3 ${PTHREAD})
|
||||
set_target_properties(master-tls-demo PROPERTIES FOLDER demos/tls)
|
||||
|
||||
# ----- outstation tls executable -----
|
||||
add_executable(outstation-tls-demo ./cpp/examples/tls/outstation/main.cpp)
|
||||
target_link_libraries (outstation-tls-demo LINK_PUBLIC asiodnp3 ${PTHREAD})
|
||||
set_target_properties(outstation-tls-demo PROPERTIES FOLDER demos/tls)
|
||||
|
||||
# ----- master-gprs tls executable -----
|
||||
add_executable(master-gprs-tls-demo ./cpp/examples/tls/master-gprs/main.cpp)
|
||||
target_link_libraries (master-gprs-tls-demo LINK_PUBLIC asiodnp3 ${PTHREAD})
|
||||
set_target_properties(master-gprs-tls-demo PROPERTIES FOLDER demos/tls)
|
||||
|
||||
endif()
|
||||
|
||||
endif()
|
||||
|
||||
if(DNP3_TEST)
|
||||
|
||||
enable_testing()
|
||||
|
||||
# ----- testlib library ------
|
||||
file(GLOB_RECURSE testlib_SRC ./cpp/tests/libs/src/testlib/*.cpp ./cpp/tests/libs/src/testlib/*.h)
|
||||
add_library(testlib ${testlib_SRC})
|
||||
target_link_libraries(testlib openpal)
|
||||
set_target_properties(testlib PROPERTIES FOLDER tests/mocks)
|
||||
|
||||
# ----- dnp3mocks library ------
|
||||
file(GLOB_RECURSE dnp3mocks_SRC ./cpp/tests/libs/src/dnp3mocks/*.cpp ./cpp/tests/libs/src/dnp3mocks/*.h)
|
||||
add_library(dnp3mocks ${dnp3mocks_SRC})
|
||||
target_link_libraries(dnp3mocks opendnp3 testlib)
|
||||
set_target_properties(dnp3mocks PROPERTIES FOLDER tests/mocks)
|
||||
|
||||
# ----- openpal tests -----
|
||||
file(GLOB_RECURSE openpal_TESTSRC ./cpp/tests/openpal/src/*.cpp ./cpp/tests/openpal/src/*.h)
|
||||
add_executable (testopenpal ${openpal_TESTSRC})
|
||||
target_link_libraries (testopenpal LINK_PUBLIC testlib ${PTHREAD})
|
||||
set_target_properties(testopenpal PROPERTIES FOLDER tests)
|
||||
add_test(testopenpal testopenpal)
|
||||
|
||||
# ----- opendnp3 tests -----
|
||||
file(GLOB_RECURSE opendnp3_TESTSRC ./cpp/tests/opendnp3/src/*.cpp ./cpp/tests/opendnp3/src/*.h)
|
||||
add_executable (testopendnp3 ${opendnp3_TESTSRC})
|
||||
target_link_libraries (testopendnp3 LINK_PUBLIC dnp3mocks ${PTHREAD})
|
||||
set_target_properties(testopendnp3 PROPERTIES FOLDER tests)
|
||||
add_test(testopendnp3 testopendnp3)
|
||||
|
||||
# ----- asiopal tests -----
|
||||
if(DNP3_TLS)
|
||||
file(GLOB_RECURSE asiopal_TESTSRC ./cpp/tests/asiopal/src/*.cpp ./cpp/tests/asiopal/src/*.h)
|
||||
else()
|
||||
file(GLOB asiopal_TESTSRC ./cpp/tests/asiopal/src/*.cpp ./cpp/tests/asiopal/src/*.h ./cpp/tests/asiopal/src/mocks/*.cpp ./cpp/tests/asiopal/src/mocks/*.h)
|
||||
endif()
|
||||
add_executable (testasiopal ${asiopal_TESTSRC})
|
||||
target_link_libraries (testasiopal LINK_PUBLIC asiopal testlib ${PTHREAD})
|
||||
set_target_properties(testasiopal PROPERTIES FOLDER tests)
|
||||
add_test(testasiopal testasiopal)
|
||||
|
||||
# ----- asiodnp3 tests -----
|
||||
file(GLOB_RECURSE asiodnp3_TESTSRC ./cpp/tests/asiodnp3/src/*.cpp ./cpp/tests/asiodnp3/src/*.h)
|
||||
add_executable (testasiodnp3 ${asiodnp3_TESTSRC})
|
||||
target_link_libraries (testasiodnp3 LINK_PUBLIC asiodnp3 dnp3mocks ${PTHREAD})
|
||||
set_target_properties(testasiodnp3 PROPERTIES FOLDER tests)
|
||||
add_test(testasiodnp3 testasiodnp3)
|
||||
|
||||
endif()
|
||||
|
||||
add_custom_target(
|
||||
format
|
||||
WORKING_DIRECTORY ${CMAKE_CURRENT_SOURCE_DIR}
|
||||
COMMAND astyle -R ./cpp/*.h ./cpp/*.cpp --options=./config/astyle.cfg --exclude=./cpp/libs/include/opendnp3/gen --exclude=./cpp/libs/src/opendnp3/gen --exclude=./cpp/libs/src/opendnp3/objects
|
||||
COMMAND astyle -R ./java/cpp/adapters/*.h ./java/cpp/adapters/*.cpp --options=./config/astyle.cfg
|
||||
)
|
||||
@@ -0,0 +1,19 @@
|
||||
=========================================================================
|
||||
== NOTICE file corresponding to the section 4 d of ==
|
||||
== the Apache License, Version 2.0, ==
|
||||
== in this case for the opendnp3 ==
|
||||
=========================================================================
|
||||
|
||||
This product includes software developed by Green Energy Corp
|
||||
(http://www.greenenergycorp.com/) and Automatak LLC (https://wwww.automatak.com).
|
||||
|
||||
Please read the LICENSE file present in the root directory of this
|
||||
distribution.
|
||||
|
||||
Aside from contributions to the oepdnp3 distribution listed above, this repository
|
||||
also distributes the following 3rd party softare:
|
||||
|
||||
https://github.com/philsquared/Catch (test only dependency)
|
||||
|
||||
Project requires, but specified as a git-submodule:
|
||||
* ASIO (https://github.com/chriskohlhoff/asio) 1.10.6 or later
|
||||
Executable
+31
@@ -0,0 +1,31 @@
|
||||
Overview
|
||||
========
|
||||
|
||||
Opendnp3 is a portable, scalable, and rigorously tested implementation
|
||||
of the DNP3 (www.dnp.org) protocol stack written in C++11. The library
|
||||
is designed for high-performance applications like many concurrent TCP
|
||||
sessions or huge device simulations. It also embeds very nicely on Linux.
|
||||
|
||||
Documentation
|
||||
=============
|
||||
|
||||
The documentation can be found on the [project homepage](http://www.automatak.com/opendnp3/#documentation).
|
||||
|
||||
If you want to help contribute to the official guide its in [this repo](https://github.com/automatak/dnp3-guide).
|
||||
|
||||
License
|
||||
=============
|
||||
|
||||
Licensed under the terms of the [Apache 2.0 License](http://www.apache.org/licenses/LICENSE-2.0.html).
|
||||
|
||||
Copyright (c) 2010, 2011 Green Energy Corp
|
||||
|
||||
Copyright (c) 2013 - 2015 Automatak LLC
|
||||
|
||||
Copyright (c) 2010 - 2015 various contributors
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
@@ -0,0 +1,42 @@
|
||||
version: 2.0.{build}
|
||||
branches:
|
||||
only:
|
||||
- 2.0.x
|
||||
os: Visual Studio 2015
|
||||
configuration: Release
|
||||
platform: x86
|
||||
clone_folder: C:\projects\dnp3
|
||||
environment:
|
||||
OSSL_LIB32_DIR: C:\OpenSSL-Win32\lib\VC
|
||||
OPENDNP3_DIR: C:\projects\dnp3\build\lib
|
||||
install:
|
||||
- git describe --tags --exact-match & cmd /c exit 0
|
||||
- git submodule update --init --recursive
|
||||
build_script:
|
||||
- cmd: MKDIR build
|
||||
- cmd: CD build
|
||||
- cmd: MKDIR lib
|
||||
- cmd: cmake .. -DCMAKE_INSTALL_PREFIX=lib -DDNP3_TEST=ON -DDNP3_TLS=ON -DCMAKE_BUILD_TYPE=Release
|
||||
- cmd: msbuild opendnp3.sln /p:Configuration=Release /p:Platform=Win32
|
||||
- cmd: msbuild INSTALL.vcxproj /p:Configuration=Release /p:Platform=Win32
|
||||
- cmd: cd ..
|
||||
- cmd: msbuild dotnet\bindings.sln /p:Configuration=Release /p:Platform=Win32
|
||||
after_build:
|
||||
- ps: >-
|
||||
if ($env:APPVEYOR_REPO_TAG -eq "true"){
|
||||
nuget pack dotnet\nuget\opendnp3.nuspec -Version "$env:APPVEYOR_REPO_TAG_NAME"
|
||||
}
|
||||
test_script:
|
||||
- cmd: c:\projects\dnp3\build\Release\testasiodnp3.exe
|
||||
- cmd: c:\projects\dnp3\build\Release\testasiopal.exe
|
||||
- cmd: c:\projects\dnp3\build\Release\testopendnp3.exe
|
||||
- cmd: c:\projects\dnp3\build\Release\testopenpal.exe
|
||||
artifacts:
|
||||
- path: '**\*.nupkg'
|
||||
name: nuget
|
||||
deploy:
|
||||
provider: NuGet
|
||||
api_key:
|
||||
secure: H7w8XBF6q0Gxyo1xKhywjZ4qrjfy3W87oGAAu30BIas1paWIE1UMvk6QM/3xzVE9
|
||||
on:
|
||||
appveyor_repo_tag: true
|
||||
@@ -0,0 +1,43 @@
|
||||
@ECHO OFF
|
||||
|
||||
SETLOCAL
|
||||
|
||||
SET CONFIGURATION=Release
|
||||
IF NOT [%1]==[] (SET CONFIGURATION=%1)
|
||||
SET PLATFORM=Win32
|
||||
IF NOT [%2]==[] (SET PLATFORM=%2)
|
||||
|
||||
where cmake 1>nul
|
||||
IF ERRORLEVEL 1 (
|
||||
ECHO cmake could not be found
|
||||
GOTO :QUIT
|
||||
)
|
||||
IF ["%OSSL_LIB32_DIR%"]==[] (
|
||||
ECHO OpenSSL could not be found
|
||||
GOTO :QUIT
|
||||
)
|
||||
ECHO OSSL_LIB32_DIR is %OSSL_LIB32_DIR%
|
||||
IF ["%VS140COMNTOOLS%"]==[] (
|
||||
ECHO VS2015 could not be found
|
||||
GOTO: QUIT
|
||||
)
|
||||
ECHO VS140COMNTOOLS is %VS140COMNTOOLS%
|
||||
|
||||
:BUILD
|
||||
CALL "%VS140COMNTOOLS%VsDevCmd.bat"
|
||||
|
||||
IF EXIST build RMDIR build /s /q
|
||||
MKDIR build\lib
|
||||
CD build
|
||||
|
||||
SET OPENDNP3_DIR=%CD%\lib
|
||||
ECHO OPENDNP3_DIR is %OPENDNP3_DIR%
|
||||
|
||||
cmake .. -DCMAKE_INSTALL_PREFIX=lib -DDNP3_TEST=ON -DDNP3_TLS=ON -DCMAKE_BUILD_TYPE=%CONFIGURATION% -G"Visual Studio 14 2015"
|
||||
msbuild opendnp3.sln /p:Configuration=%CONFIGURATION% /p:Platform=%PLATFORM%
|
||||
msbuild INSTALL.vcxproj /p:Configuration=%CONFIGURATION% /p:Platform=%PLATFORM%
|
||||
msbuild ..\dotnet\bindings.sln /target:Clean
|
||||
msbuild ..\dotnet\bindings.sln /p:Configuration=%CONFIGURATION% /p:Platform=%PLATFORM%
|
||||
|
||||
:QUIT
|
||||
ENDLOCAL
|
||||
@@ -0,0 +1,24 @@
|
||||
if (WIN32)
|
||||
if(MSVC)
|
||||
add_definitions(-D_WIN32_WINNT=0x0501)
|
||||
add_definitions(-DASIO_HAS_STD_SYSTEM_ERROR)
|
||||
|
||||
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} /W3 /MP")
|
||||
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -D_SCL_SECURE_NO_WARNINGS -D_CRT_SECURE_NO_WARNINGS ${WINSOCKAPI} /wd4251 /wd4996 /wd4273 /wd4275 /wd4018 /wd4146 /EHsc")
|
||||
|
||||
set_property(GLOBAL PROPERTY USE_FOLDERS ON) #allows the creation of solution folders
|
||||
set(LIB_TYPE STATIC) #default to static on MSVC
|
||||
else()
|
||||
if (MINGW)
|
||||
# MINGW is a hybred between the Windows system and GCC compiler
|
||||
add_definitions(-D_WIN32_WINNT=0x0501)
|
||||
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -std=c++14")
|
||||
|
||||
set(LIB_TYPE STATIC) #default to static on MinGW
|
||||
|
||||
# We need to link the demos with these
|
||||
set(NET_LIBS "ws2_32" "wsock32")
|
||||
endif()
|
||||
endif()
|
||||
endif()
|
||||
|
||||
@@ -0,0 +1,52 @@
|
||||
if (UNIX)
|
||||
set(PTHREAD pthread)
|
||||
find_package(Threads)
|
||||
if(STATICLIBS)
|
||||
set(LIB_TYPE STATIC)
|
||||
else()
|
||||
set(LIB_TYPE SHARED)
|
||||
endif()
|
||||
|
||||
set(CMAKE_C_FLAGS "-Wall -Wno-multichar -Wunused-variable -Wno-unused-parameter -Wunused-function -Wunused -Wno-system-headers -Wwrite-strings -save-temps")
|
||||
|
||||
if (${CYGWIN})
|
||||
set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS}")
|
||||
elseif(${MINGW})
|
||||
set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS}")
|
||||
else()
|
||||
set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -fPIC")
|
||||
endif()
|
||||
set(CMAKE_CXX_FLAGS "${CMAKE_C_FLAGS} -Wno-deprecated -Wno-parentheses -std=c++14")
|
||||
|
||||
set(CMAKE_CXX_FLAGS_DEBUG "-O0 -g")
|
||||
set(CMAKE_CXX_FLAGS_MINSIZEREL "-Os -DNDEBUG")
|
||||
set(CMAKE_CXX_FLAGS_RELEASE "-O4 -DNDEBUG")
|
||||
set(CMAKE_CXX_FLAGS_RELWITHDEBINFO "-O2 -g")
|
||||
|
||||
# Compiler-specific C++14 activation.
|
||||
if ("${CMAKE_CXX_COMPILER_ID}" MATCHES "GNU")
|
||||
if(CMAKE_CXX_COMPILER_VERSION VERSION_LESS 4.9)
|
||||
message(FATAL_ERROR "${PROJECT_NAME} requires g++ 4.9 or greater")
|
||||
endif ()
|
||||
elseif ("${CMAKE_CXX_COMPILER_ID}" MATCHES "Clang")
|
||||
if(CMAKE_CXX_COMPILER_VERSION VERSION_LESS 3.5)
|
||||
message(FATAL_ERROR "${PROJECT_NAME} requires clang 3.5 or greater")
|
||||
endif ()
|
||||
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -stdlib=libc++")
|
||||
else ()
|
||||
message(FATAL_ERROR "Your C++ compiler does not support C++14: ${CMAKE_CXX_COMPILER_ID} - ${CMAKE_CXX_COMPILER_VERSION}")
|
||||
endif ()
|
||||
|
||||
if(COVERAGE)
|
||||
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} --coverage")
|
||||
endif()
|
||||
|
||||
if(PROFILE)
|
||||
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -pg")
|
||||
endif()
|
||||
|
||||
if (WERROR)
|
||||
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -Werror")
|
||||
endif()
|
||||
|
||||
endif()
|
||||
@@ -0,0 +1,6 @@
|
||||
get_filename_component(settings_cmake_dir "${CMAKE_CURRENT_LIST_FILE}" PATH)
|
||||
|
||||
include("${settings_cmake_dir}/inc/msvc.cmake")
|
||||
include("${settings_cmake_dir}/inc/posix.cmake")
|
||||
|
||||
set(CMAKE_RUNTIME_OUTPUT_DIRECTORY ${CMAKE_BINARY_DIR})
|
||||
@@ -0,0 +1,19 @@
|
||||
Licensed to Green Energy Corp (www.greenenergycorp.com) under one or
|
||||
more contributor license agreements. See the NOTICE file distributed
|
||||
with this work for additional information regarding copyright ownership.
|
||||
Green Energy Corp licenses this file to you under the Apache License,
|
||||
Version 2.0 (the "License"); you may not use this file except in
|
||||
compliance with the License. You may obtain a copy of the License at
|
||||
|
||||
http://www.apache.org/licenses/LICENSE-2.0
|
||||
|
||||
Unless required by applicable law or agreed to in writing, software
|
||||
distributed under the License is distributed on an "AS IS" BASIS,
|
||||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
See the License for the specific language governing permissions and
|
||||
limitations under the License.
|
||||
|
||||
This project was forked on 01/01/2013 by Automatak, LLC and modifications
|
||||
may have been made to this file. Automatak, LLC licenses these modifications
|
||||
to you under the terms of the License.
|
||||
|
||||
Executable
+9
@@ -0,0 +1,9 @@
|
||||
# don't create backup files
|
||||
--style=allman
|
||||
--suffix=none
|
||||
--indent=tab
|
||||
--indent-cases
|
||||
--pad-oper
|
||||
--break-closing-brackets
|
||||
--keep-one-line-statements
|
||||
--align-pointer=type
|
||||
File diff suppressed because it is too large
Load Diff
Binary file not shown.
|
After Width: | Height: | Size: 4.1 KiB |
@@ -0,0 +1,21 @@
|
||||
/*! \mainpage opendnp3
|
||||
|
||||
Overview
|
||||
========
|
||||
Welcome to <a href="http://www.automatak.com/opendnp3">opendnp3</a>, a rigorously-tested, Apache-licensed implementation of the
|
||||
DNP3 protocol (aka IEEE-1815).
|
||||
|
||||
About this page
|
||||
===============
|
||||
This is autogenerated C++ API documentation for developers. This documentation
|
||||
complements the <a href="http://www.automatak.com/opendnp3/docs/guide/current">developers guide</a>.
|
||||
|
||||
Please refer to the guide for architecture, supported features, build instructions, and examples.
|
||||
*/
|
||||
|
||||
/**
|
||||
* @namespace openpal
|
||||
*
|
||||
* Some docs here for openpal
|
||||
*/
|
||||
namespace openpal {}
|
||||
@@ -0,0 +1,49 @@
|
||||
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
|
||||
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
|
||||
<modelVersion>4.0.0</modelVersion>
|
||||
|
||||
<groupId>com.automatak.dnp3</groupId>
|
||||
<artifactId>formatting</artifactId>
|
||||
<version>1.1.0</version>
|
||||
<packaging>pom</packaging>
|
||||
|
||||
<name>opendnp3</name>
|
||||
<url>http://www.github.com/automatak/dnp3</url>
|
||||
<description>This is a project only for header formatting, nothing more</description>
|
||||
|
||||
<build>
|
||||
<plugins>
|
||||
<plugin>
|
||||
<groupId>com.mycila</groupId>
|
||||
<artifactId>license-maven-plugin</artifactId>
|
||||
<version>2.5</version>
|
||||
<configuration>
|
||||
<header>APACHE_LICENSE_HEADER</header>
|
||||
<mapping>
|
||||
<h>SLASHSTAR_STYLE</h>
|
||||
<cpp>SLASHSTAR_STYLE</cpp>
|
||||
</mapping>
|
||||
<includes>
|
||||
<include>cpp/**/*.h</include>
|
||||
<include>cpp/**/*.cpp</include>
|
||||
</includes>
|
||||
<excludes>
|
||||
<exclude>cpp/libs/include/opendnp3/gen/*</exclude>
|
||||
<exclude>cpp/libs/src/opendnp3/gen/*</exclude>
|
||||
<exclude>cpp/libs/src/opendnp3/objects/*</exclude>
|
||||
</excludes>
|
||||
</configuration>
|
||||
<executions>
|
||||
<execution>
|
||||
<goals>
|
||||
<goal>check</goal>
|
||||
</goals>
|
||||
</execution>
|
||||
</executions>
|
||||
</plugin>
|
||||
</plugins>
|
||||
</build>
|
||||
|
||||
</project>
|
||||
|
||||
|
||||
@@ -0,0 +1,23 @@
|
||||
|
||||
extensions: .cs .cpp .h
|
||||
|
||||
//
|
||||
// Licensed to Green Energy Corp (www.greenenergycorp.com) under one or
|
||||
// more contributor license agreements. See the NOTICE file distributed
|
||||
// with this work for additional information regarding copyright ownership.
|
||||
// Green Energy Corp licenses this file to you under the Apache License,
|
||||
// Version 2.0 (the "License"); you may not use this file except in
|
||||
// compliance with the License. You may obtain a copy of the License at
|
||||
//
|
||||
// http://www.apache.org/licenses/LICENSE-2.0
|
||||
//
|
||||
// Unless required by applicable law or agreed to in writing, software
|
||||
// distributed under the License is distributed on an "AS IS" BASIS,
|
||||
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
// See the License for the specific language governing permissions and
|
||||
// limitations under the License.
|
||||
//
|
||||
// This file was forked on 01/01/2013 by Automatak, LLC and modifications
|
||||
// have been made to this file. Automatak, LLC licenses these modifications to
|
||||
// you under the terms of the License.
|
||||
//
|
||||
@@ -0,0 +1,2 @@
|
||||
|
||||
/* vim: set ts=4 sw=4: */
|
||||
@@ -0,0 +1,17 @@
|
||||
/*
|
||||
* Licensed to Green Energy Corp (www.greenenergycorp.com) under one or more
|
||||
* contributor license agreements. See the NOTICE file distributed with this
|
||||
* work for additional information regarding copyright ownership. Green Enery
|
||||
* Corp licenses this file to you under the Apache License, Version 2.0 (the
|
||||
* "License"); you may not use this file except in compliance with the
|
||||
* License. You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
|
||||
* WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
|
||||
* License for the specific language governing permissions and limitations
|
||||
* under the License.
|
||||
*/
|
||||
|
||||
@@ -0,0 +1,92 @@
|
||||
/*
|
||||
* Licensed to Green Energy Corp (www.greenenergycorp.com) under one or
|
||||
* more contributor license agreements. See the NOTICE file distributed
|
||||
* with this work for additional information regarding copyright ownership.
|
||||
* Green Energy Corp licenses this file to you under the Apache License,
|
||||
* Version 2.0 (the "License"); you may not use this file except in
|
||||
* compliance with the License. You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*
|
||||
* This project was forked on 01/01/2013 by Automatak, LLC and modifications
|
||||
* may have been made to this file. Automatak, LLC licenses these modifications
|
||||
* to you under the terms of the License.
|
||||
*/
|
||||
|
||||
#include <openpal/logging/Logger.h>
|
||||
#include <openpal/container/Buffer.h>
|
||||
|
||||
#include <dnp3decode/Decoder.h>
|
||||
#include <opendnp3/LogLevels.h>
|
||||
#include <asiodnp3/ConsoleLogger.h>
|
||||
|
||||
using namespace std;
|
||||
using namespace openpal;
|
||||
using namespace opendnp3;
|
||||
using namespace asiodnp3;
|
||||
|
||||
enum class Mode
|
||||
{
|
||||
Link,
|
||||
Transport,
|
||||
App
|
||||
};
|
||||
|
||||
Mode GetMode(const std::string& mode)
|
||||
{
|
||||
if (mode == "link")
|
||||
{
|
||||
return Mode::Link;
|
||||
}
|
||||
else if (mode == "transport")
|
||||
{
|
||||
return Mode::Transport;
|
||||
}
|
||||
else
|
||||
{
|
||||
return Mode::App;
|
||||
}
|
||||
}
|
||||
|
||||
int main(int argc, char* argv[])
|
||||
{
|
||||
openpal::Logger logger(ConsoleLogger::Create(), "decoder", LogFilters(~0));
|
||||
IDecoderCallbacks callback;
|
||||
Decoder decoder(callback, logger);
|
||||
|
||||
Buffer buffer(4096);
|
||||
|
||||
const Mode MODE = (argc > 1) ? GetMode(argv[1]) : Mode::Link;
|
||||
|
||||
while (true)
|
||||
{
|
||||
const size_t NUM_READ = fread(buffer(), 1, buffer.Size(), stdin);
|
||||
|
||||
if (NUM_READ == 0)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
switch (MODE)
|
||||
{
|
||||
case(Mode::Link):
|
||||
decoder.DecodeLPDU(buffer.ToRSlice().Take(NUM_READ));
|
||||
break;
|
||||
case(Mode::Transport) :
|
||||
decoder.DecodeTPDU(buffer.ToRSlice().Take(NUM_READ));
|
||||
break;
|
||||
default:
|
||||
decoder.DecodeAPDU(buffer.ToRSlice().Take(NUM_READ));
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
@@ -0,0 +1,77 @@
|
||||
/*
|
||||
* Licensed to Green Energy Corp (www.greenenergycorp.com) under one or
|
||||
* more contributor license agreements. See the NOTICE file distributed
|
||||
* with this work for additional information regarding copyright ownership.
|
||||
* Green Energy Corp licenses this file to you under the Apache License,
|
||||
* Version 2.0 (the "License"); you may not use this file except in
|
||||
* compliance with the License. You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*
|
||||
* This project was forked on 01/01/2013 by Automatak, LLC and modifications
|
||||
* may have been made to this file. Automatak, LLC licenses these modifications
|
||||
* to you under the terms of the License.
|
||||
*/
|
||||
#include <asiodnp3/DNP3Manager.h>
|
||||
#include <asiodnp3/ConsoleLogger.h>
|
||||
#include <asiodnp3/DefaultListenCallbacks.h>
|
||||
|
||||
#include <opendnp3/LogLevels.h>
|
||||
#include <iostream>
|
||||
#include <thread>
|
||||
|
||||
using namespace std;
|
||||
using namespace openpal;
|
||||
using namespace asiopal;
|
||||
using namespace asiodnp3;
|
||||
using namespace opendnp3;
|
||||
|
||||
int main(int argc, char* argv[])
|
||||
{
|
||||
// Specify what log levels to use. NORMAL is warning and above
|
||||
// You can add all the comms logging by uncommenting below
|
||||
const uint32_t FILTERS = levels::NORMAL | levels::ALL_COMMS;
|
||||
|
||||
const auto NUM_THREAD = std::thread::hardware_concurrency();
|
||||
|
||||
auto callbacks = std::make_shared<DefaultListenCallbacks>();
|
||||
|
||||
// This is the main point of interaction with the stack
|
||||
DNP3Manager manager(NUM_THREAD, ConsoleLogger::Create());
|
||||
|
||||
std::error_code ec;
|
||||
auto server1 = manager.CreateListener("server-20000", FILTERS, IPEndpoint::AllAdapters(20000), callbacks, ec);
|
||||
|
||||
if (ec)
|
||||
{
|
||||
std::cout << ec.message() << std::endl;
|
||||
return ec.value();
|
||||
}
|
||||
|
||||
do
|
||||
{
|
||||
std::cout << "Enter a command" << std::endl;
|
||||
std::cout << "x - exits program" << std::endl;
|
||||
|
||||
char cmd;
|
||||
std::cin >> cmd;
|
||||
switch(cmd)
|
||||
{
|
||||
case('x'):
|
||||
return 0;
|
||||
default:
|
||||
std::cout << "Unknown action: " << cmd << std::endl;
|
||||
break;
|
||||
}
|
||||
}
|
||||
while(true);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
@@ -0,0 +1,165 @@
|
||||
/*
|
||||
* Licensed to Green Energy Corp (www.greenenergycorp.com) under one or
|
||||
* more contributor license agreements. See the NOTICE file distributed
|
||||
* with this work for additional information regarding copyright ownership.
|
||||
* Green Energy Corp licenses this file to you under the Apache License,
|
||||
* Version 2.0 (the "License"); you may not use this file except in
|
||||
* compliance with the License. You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*
|
||||
* This project was forked on 01/01/2013 by Automatak, LLC and modifications
|
||||
* may have been made to this file. Automatak, LLC licenses these modifications
|
||||
* to you under the terms of the License.
|
||||
*/
|
||||
#include <asiodnp3/DNP3Manager.h>
|
||||
#include <asiodnp3/PrintingSOEHandler.h>
|
||||
#include <asiodnp3/ConsoleLogger.h>
|
||||
#include <asiodnp3/DefaultMasterApplication.h>
|
||||
#include <asiodnp3/PrintingCommandCallback.h>
|
||||
#include <asiodnp3/PrintingChannelListener.h>
|
||||
|
||||
#include <asiopal/UTCTimeSource.h>
|
||||
|
||||
#include <opendnp3/LogLevels.h>
|
||||
|
||||
using namespace std;
|
||||
using namespace openpal;
|
||||
using namespace asiopal;
|
||||
using namespace asiodnp3;
|
||||
using namespace opendnp3;
|
||||
|
||||
int main(int argc, char* argv[])
|
||||
{
|
||||
// Specify what log levels to use. NORMAL is warning and above
|
||||
// You can add all the comms logging by uncommenting below
|
||||
const uint32_t FILTERS = levels::NORMAL | levels::ALL_APP_COMMS;
|
||||
|
||||
// This is the main point of interaction with the stack
|
||||
DNP3Manager manager(1, ConsoleLogger::Create());
|
||||
|
||||
// Connect via a TCPClient socket to a outstation
|
||||
auto channel = manager.AddTCPClient("tcpclient", FILTERS, ChannelRetry::Default(), "127.0.0.1", "0.0.0.0", 20000, PrintingChannelListener::Create());
|
||||
|
||||
// The master config object for a master. The default are
|
||||
// useable, but understanding the options are important.
|
||||
MasterStackConfig stackConfig;
|
||||
|
||||
// you can override application layer settings for the master here
|
||||
// in this example, we've change the application layer timeout to 2 seconds
|
||||
stackConfig.master.responseTimeout = TimeDuration::Seconds(2);
|
||||
stackConfig.master.disableUnsolOnStartup = true;
|
||||
|
||||
// You can override the default link layer settings here
|
||||
// in this example we've changed the default link layer addressing
|
||||
stackConfig.link.LocalAddr = 1;
|
||||
stackConfig.link.RemoteAddr = 10;
|
||||
|
||||
// Create a new master on a previously declared port, with a
|
||||
// name, log level, command acceptor, and config info. This
|
||||
// returns a thread-safe interface used for sending commands.
|
||||
auto master = channel->AddMaster(
|
||||
"master", // id for logging
|
||||
PrintingSOEHandler::Create(), // callback for data processing
|
||||
asiodnp3::DefaultMasterApplication::Create(), // master application instance
|
||||
stackConfig // stack configuration
|
||||
);
|
||||
|
||||
|
||||
// do an integrity poll (Class 3/2/1/0) once per minute
|
||||
auto integrityScan = master->AddClassScan(ClassField::AllClasses(), TimeDuration::Minutes(1));
|
||||
|
||||
// do a Class 1 exception poll every 5 seconds
|
||||
auto exceptionScan = master->AddClassScan(ClassField(ClassField::CLASS_1), TimeDuration::Seconds(2));
|
||||
|
||||
// Enable the master. This will start communications.
|
||||
master->Enable();
|
||||
|
||||
bool channelCommsLoggingEnabled = true;
|
||||
bool masterCommsLoggingEnabled = true;
|
||||
|
||||
while (true)
|
||||
{
|
||||
std::cout << "Enter a command" << std::endl;
|
||||
std::cout << "x - exits program" << std::endl;
|
||||
std::cout << "a - performs and ad-hoc range scan" << std::endl;
|
||||
std::cout << "i - integrity demand scan" << std::endl;
|
||||
std::cout << "e - exception demand scan" << std::endl;
|
||||
std::cout << "d - diable unsolcited" << std::endl;
|
||||
std::cout << "r - cold restart" << std::endl;
|
||||
std::cout << "c - send crob" << std::endl;
|
||||
|
||||
char cmd;
|
||||
std::cin >> cmd;
|
||||
switch(cmd)
|
||||
{
|
||||
case('a') :
|
||||
master->ScanRange(GroupVariationID(1, 2), 0, 3);
|
||||
break;
|
||||
case('d') :
|
||||
master->PerformFunction("disable unsol", FunctionCode::DISABLE_UNSOLICITED,
|
||||
{ Header::AllObjects(60, 2), Header::AllObjects(60, 3), Header::AllObjects(60, 4) }
|
||||
);
|
||||
break;
|
||||
case('r') :
|
||||
{
|
||||
auto print = [](const RestartOperationResult & result)
|
||||
{
|
||||
if(result.summary == TaskCompletion::SUCCESS)
|
||||
{
|
||||
std::cout << "Success, Time: " << result.restartTime.GetMilliseconds() << std::endl;
|
||||
}
|
||||
else
|
||||
{
|
||||
std::cout << "Failure: " << TaskCompletionToString(result.summary) << std::endl;
|
||||
}
|
||||
};
|
||||
master->Restart(RestartType::COLD, print);
|
||||
break;
|
||||
}
|
||||
case('x'):
|
||||
// C++ destructor on DNP3Manager cleans everything up for you
|
||||
return 0;
|
||||
case('i'):
|
||||
integrityScan->Demand();
|
||||
break;
|
||||
case('e'):
|
||||
exceptionScan->Demand();
|
||||
break;
|
||||
case('c'):
|
||||
{
|
||||
ControlRelayOutputBlock crob(ControlCode::LATCH_ON);
|
||||
master->SelectAndOperate(crob, 0, PrintingCommandCallback::Get());
|
||||
break;
|
||||
}
|
||||
case('t') :
|
||||
{
|
||||
channelCommsLoggingEnabled = !channelCommsLoggingEnabled;
|
||||
auto levels = channelCommsLoggingEnabled ? levels::ALL_COMMS : levels::NORMAL;
|
||||
channel->SetLogFilters(levels);
|
||||
std::cout << "Channel logging set to: " << levels << std::endl;
|
||||
break;
|
||||
}
|
||||
case('u') :
|
||||
{
|
||||
masterCommsLoggingEnabled = !masterCommsLoggingEnabled;
|
||||
auto levels = masterCommsLoggingEnabled ? levels::ALL_COMMS : levels::NORMAL;
|
||||
master->SetLogFilters(levels);
|
||||
std::cout << "Master logging set to: " << levels << std::endl;
|
||||
break;
|
||||
}
|
||||
default:
|
||||
std::cout << "Unknown action: " << cmd << std::endl;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
@@ -0,0 +1,166 @@
|
||||
/*
|
||||
* Licensed to Green Energy Corp (www.greenenergycorp.com) under one or
|
||||
* more contributor license agreements. See the NOTICE file distributed
|
||||
* with this work for additional information regarding copyright ownership.
|
||||
* Green Energy Corp licenses this file to you under the Apache License,
|
||||
* Version 2.0 (the "License"); you may not use this file except in
|
||||
* compliance with the License. You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*
|
||||
* This project was forked on 01/01/2013 by Automatak, LLC and modifications
|
||||
* may have been made to this file. Automatak, LLC licenses these modifications
|
||||
* to you under the terms of the License.
|
||||
*/
|
||||
#include <asiodnp3/DNP3Manager.h>
|
||||
#include <asiodnp3/PrintingSOEHandler.h>
|
||||
#include <asiodnp3/PrintingChannelListener.h>
|
||||
#include <asiodnp3/ConsoleLogger.h>
|
||||
#include <asiodnp3/UpdateBuilder.h>
|
||||
|
||||
#include <asiopal/UTCTimeSource.h>
|
||||
#include <opendnp3/outstation/SimpleCommandHandler.h>
|
||||
|
||||
#include <opendnp3/outstation/IUpdateHandler.h>
|
||||
|
||||
#include <opendnp3/LogLevels.h>
|
||||
|
||||
#include <string>
|
||||
#include <thread>
|
||||
#include <iostream>
|
||||
|
||||
using namespace std;
|
||||
using namespace opendnp3;
|
||||
using namespace openpal;
|
||||
using namespace asiopal;
|
||||
using namespace asiodnp3;
|
||||
|
||||
void ConfigureDatabase(DatabaseConfig& config)
|
||||
{
|
||||
// example of configuring analog index 0 for Class2 with floating point variations by default
|
||||
config.analog[0].clazz = PointClass::Class2;
|
||||
config.analog[0].svariation = StaticAnalogVariation::Group30Var5;
|
||||
config.analog[0].evariation = EventAnalogVariation::Group32Var7;
|
||||
}
|
||||
|
||||
struct State
|
||||
{
|
||||
uint32_t count = 0;
|
||||
double value = 0;
|
||||
bool binary = false;
|
||||
DoubleBit dbit = DoubleBit::DETERMINED_OFF;
|
||||
};
|
||||
|
||||
void AddUpdates(UpdateBuilder& builder, State& state, const std::string& arguments);
|
||||
|
||||
|
||||
|
||||
int main(int argc, char* argv[])
|
||||
{
|
||||
|
||||
// Specify what log levels to use. NORMAL is warning and above
|
||||
// You can add all the comms logging by uncommenting below.
|
||||
const uint32_t FILTERS = levels::NORMAL | levels::ALL_COMMS;
|
||||
|
||||
// This is the main point of interaction with the stack
|
||||
// Allocate a single thread to the pool since this is a single outstation
|
||||
// Log messages to the console
|
||||
DNP3Manager manager(1, ConsoleLogger::Create());
|
||||
|
||||
// Create a TCP server (listener)
|
||||
auto channel = manager.AddTCPServer("server", FILTERS, ChannelRetry::Default(), "0.0.0.0", 20000, PrintingChannelListener::Create());
|
||||
|
||||
// The main object for a outstation. The defaults are useable,
|
||||
// but understanding the options are important.
|
||||
OutstationStackConfig config(DatabaseSizes::AllTypes(10));
|
||||
|
||||
// Specify the maximum size of the event buffers
|
||||
config.outstation.eventBufferConfig = EventBufferConfig::AllTypes(10);
|
||||
|
||||
// you can override an default outstation parameters here
|
||||
// in this example, we've enabled the oustation to use unsolicted reporting
|
||||
// if the master enables it
|
||||
config.outstation.params.allowUnsolicited = true;
|
||||
|
||||
// You can override the default link layer settings here
|
||||
// in this example we've changed the default link layer addressing
|
||||
config.link.LocalAddr = 10;
|
||||
config.link.RemoteAddr = 1;
|
||||
|
||||
config.link.KeepAliveTimeout = openpal::TimeDuration::Max();
|
||||
|
||||
// You can optionally change the default reporting variations or class assignment prior to enabling the outstation
|
||||
ConfigureDatabase(config.dbConfig);
|
||||
|
||||
// Create a new outstation with a log level, command handler, and
|
||||
// config info this returns a thread-safe interface used for
|
||||
// updating the outstation's database.
|
||||
auto outstation = channel->AddOutstation("outstation", SuccessCommandHandler::Create(), DefaultOutstationApplication::Create(), config);
|
||||
|
||||
// Enable the outstation and start communications
|
||||
outstation->Enable();
|
||||
|
||||
// variables used in example loop
|
||||
string input;
|
||||
State state;
|
||||
|
||||
while (true)
|
||||
{
|
||||
std::cout << "Enter one or more measurement changes then press <enter>" << std::endl;
|
||||
std::cout << "c = counter, b = binary, d = doublebit, a = analog, 'quit' = exit" << std::endl;
|
||||
std::cin >> input;
|
||||
|
||||
if (input == "quit") return 0; // DNP3Manager destructor cleanups up everything automatically
|
||||
else
|
||||
{
|
||||
// update measurement values based on input string
|
||||
UpdateBuilder builder;
|
||||
AddUpdates(builder, state, input);
|
||||
outstation->Apply(builder.Build());
|
||||
}
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
void AddUpdates(UpdateBuilder& builder, State& state, const std::string& arguments)
|
||||
{
|
||||
for (const char& c : arguments)
|
||||
{
|
||||
switch (c)
|
||||
{
|
||||
case('c'):
|
||||
{
|
||||
builder.Update(Counter(state.count), 0);
|
||||
++state.count;
|
||||
break;
|
||||
}
|
||||
case('a'):
|
||||
{
|
||||
builder.Update(Analog(state.value), 0);
|
||||
state.value += 1;
|
||||
break;
|
||||
}
|
||||
case('b'):
|
||||
{
|
||||
builder.Update(Binary(state.binary), 0);
|
||||
state.binary = !state.binary;
|
||||
break;
|
||||
}
|
||||
case('d'):
|
||||
{
|
||||
builder.Update(DoubleBitBinary(state.dbit), 0);
|
||||
state.dbit = (state.dbit == DoubleBit::DETERMINED_OFF) ? DoubleBit::DETERMINED_ON : DoubleBit::DETERMINED_OFF;
|
||||
break;
|
||||
}
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,104 @@
|
||||
/*
|
||||
* Licensed to Green Energy Corp (www.greenenergycorp.com) under one or
|
||||
* more contributor license agreements. See the NOTICE file distributed
|
||||
* with this work for additional information regarding copyright ownership.
|
||||
* Green Energy Corp licenses this file to you under the Apache License,
|
||||
* Version 2.0 (the "License"); you may not use this file except in
|
||||
* compliance with the License. You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*
|
||||
* This project was forked on 01/01/2013 by Automatak, LLC and modifications
|
||||
* may have been made to this file. Automatak, LLC licenses these modifications
|
||||
* to you under the terms of the License.
|
||||
*/
|
||||
#include <asiodnp3/DNP3Manager.h>
|
||||
#include <asiodnp3/ConsoleLogger.h>
|
||||
#include <asiodnp3/DefaultListenCallbacks.h>
|
||||
|
||||
#include <opendnp3/LogLevels.h>
|
||||
#include <iostream>
|
||||
#include <thread>
|
||||
|
||||
using namespace std;
|
||||
using namespace openpal;
|
||||
using namespace asiopal;
|
||||
using namespace asiodnp3;
|
||||
using namespace opendnp3;
|
||||
|
||||
int main(int argc, char* argv[])
|
||||
{
|
||||
if (argc != 4)
|
||||
{
|
||||
std::cout << "usage: master-gprs-tls-demo <ca certificate> <certificate chain> <private key>" << std::endl;
|
||||
return -1;
|
||||
}
|
||||
|
||||
std::string caCertificate(argv[1]);
|
||||
std::string certificateChain(argv[2]);
|
||||
std::string privateKey(argv[3]);
|
||||
|
||||
|
||||
std::cout << "Using CA certificate: " << caCertificate << std::endl;
|
||||
std::cout << "Using certificate chain: " << certificateChain << std::endl;
|
||||
std::cout << "Using private key file: " << privateKey << std::endl;
|
||||
|
||||
// Specify what log levels to use. NORMAL is warning and above
|
||||
// You can add all the comms logging by uncommenting below
|
||||
const uint32_t FILTERS = levels::NORMAL | levels::ALL_COMMS;
|
||||
|
||||
const auto NUM_THREAD = std::thread::hardware_concurrency();
|
||||
|
||||
auto callbacks = std::make_shared<DefaultListenCallbacks>();
|
||||
|
||||
// This is the main point of interaction with the stack
|
||||
DNP3Manager manager(NUM_THREAD, ConsoleLogger::Create());
|
||||
|
||||
std::error_code ec;
|
||||
auto server1 = manager.CreateListener(
|
||||
"server-20001",
|
||||
FILTERS,
|
||||
IPEndpoint::AllAdapters(20001),
|
||||
TLSConfig(
|
||||
caCertificate,
|
||||
certificateChain,
|
||||
privateKey,
|
||||
2
|
||||
),
|
||||
callbacks,
|
||||
ec
|
||||
);
|
||||
|
||||
if (ec)
|
||||
{
|
||||
std::cout << ec.message() << std::endl;
|
||||
return ec.value();
|
||||
}
|
||||
|
||||
do
|
||||
{
|
||||
std::cout << "Enter a command" << std::endl;
|
||||
std::cout << "x - exits program" << std::endl;
|
||||
|
||||
char cmd;
|
||||
std::cin >> cmd;
|
||||
switch(cmd)
|
||||
{
|
||||
case('x'):
|
||||
return 0;
|
||||
default:
|
||||
std::cout << "Unknown action: " << cmd << std::endl;
|
||||
break;
|
||||
}
|
||||
}
|
||||
while(true);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
@@ -0,0 +1,178 @@
|
||||
/*
|
||||
* Licensed to Green Energy Corp (www.greenenergycorp.com) under one or
|
||||
* more contributor license agreements. See the NOTICE file distributed
|
||||
* with this work for additional information regarding copyright ownership.
|
||||
* Green Energy Corp licenses this file to you under the Apache License,
|
||||
* Version 2.0 (the "License"); you may not use this file except in
|
||||
* compliance with the License. You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*
|
||||
* This project was forked on 01/01/2013 by Automatak, LLC and modifications
|
||||
* may have been made to this file. Automatak, LLC licenses these modifications
|
||||
* to you under the terms of the License.
|
||||
*/
|
||||
#include <asiodnp3/DNP3Manager.h>
|
||||
#include <asiodnp3/PrintingSOEHandler.h>
|
||||
#include <asiodnp3/PrintingChannelListener.h>
|
||||
#include <asiodnp3/ConsoleLogger.h>
|
||||
#include <asiodnp3/DefaultMasterApplication.h>
|
||||
#include <asiodnp3/PrintingCommandCallback.h>
|
||||
|
||||
#include <asiopal/UTCTimeSource.h>
|
||||
|
||||
#include <opendnp3/LogLevels.h>
|
||||
|
||||
using namespace std;
|
||||
using namespace openpal;
|
||||
using namespace asiopal;
|
||||
using namespace asiodnp3;
|
||||
using namespace opendnp3;
|
||||
|
||||
int main(int argc, char* argv[])
|
||||
{
|
||||
if (argc != 3)
|
||||
{
|
||||
std::cout << "usage: master-tls-demo <peer certificate> <private key/certificate>" << std::endl;
|
||||
return -1;
|
||||
}
|
||||
|
||||
std::string peerCertificate(argv[1]);
|
||||
std::string privateKey(argv[2]);
|
||||
|
||||
std::cout << "Using peer cert: " << peerCertificate << std::endl;
|
||||
std::cout << "Using private key file: " << privateKey << std::endl;
|
||||
|
||||
|
||||
// Specify what log levels to use. NORMAL is warning and above
|
||||
// You can add all the comms logging by uncommenting below
|
||||
const uint32_t FILTERS = levels::NORMAL | levels::ALL_APP_COMMS;
|
||||
|
||||
// This is the main point of interaction with the stack
|
||||
// send log messages to the console
|
||||
DNP3Manager manager(1, ConsoleLogger::Create());
|
||||
|
||||
std::error_code ec;
|
||||
|
||||
// Connect via a TCPClient socket to a outstation
|
||||
auto channel = manager.AddTLSClient(
|
||||
"tls-client",
|
||||
FILTERS,
|
||||
ChannelRetry::Default(),
|
||||
"127.0.0.1",
|
||||
"0.0.0.0",
|
||||
20001,
|
||||
TLSConfig(peerCertificate, privateKey, privateKey),
|
||||
PrintingChannelListener::Create(),
|
||||
ec
|
||||
);
|
||||
|
||||
if (ec)
|
||||
{
|
||||
std::cout << "Unable to create tls client: " << ec.message() << std::endl;
|
||||
return ec.value();
|
||||
}
|
||||
|
||||
// The master config object for a master. The default are
|
||||
// useable, but understanding the options are important.
|
||||
MasterStackConfig stackConfig;
|
||||
|
||||
// you can override application layer settings for the master here
|
||||
// in this example, we've change the application layer timeout to 2 seconds
|
||||
stackConfig.master.responseTimeout = TimeDuration::Seconds(2);
|
||||
stackConfig.master.disableUnsolOnStartup = true;
|
||||
|
||||
// You can override the default link layer settings here
|
||||
// in this example we've changed the default link layer addressing
|
||||
stackConfig.link.LocalAddr = 1;
|
||||
stackConfig.link.RemoteAddr = 10;
|
||||
|
||||
// Create a new master on a previously declared port, with a
|
||||
// name, log level, command acceptor, and config info. This
|
||||
// returns a thread-safe interface used for sending commands.
|
||||
auto master = channel->AddMaster(
|
||||
"master", // id for logging
|
||||
PrintingSOEHandler::Create(), // callback for data processing
|
||||
asiodnp3::DefaultMasterApplication::Create(), // master application instance
|
||||
stackConfig // stack configuration
|
||||
);
|
||||
|
||||
|
||||
// do an integrity poll (Class 3/2/1/0) once per minute
|
||||
auto integrityScan = master->AddClassScan(ClassField::AllClasses(), TimeDuration::Minutes(1));
|
||||
|
||||
// do a Class 1 exception poll every 5 seconds
|
||||
auto exceptionScan = master->AddClassScan(ClassField(ClassField::CLASS_1), TimeDuration::Seconds(2));
|
||||
|
||||
// Enable the master. This will start communications.
|
||||
master->Enable();
|
||||
|
||||
do
|
||||
{
|
||||
std::cout << "Enter a command" << std::endl;
|
||||
std::cout << "x - exits program" << std::endl;
|
||||
std::cout << "a - performs and ad-hoc range scan" << std::endl;
|
||||
std::cout << "i - integrity demand scan" << std::endl;
|
||||
std::cout << "e - exception demand scan" << std::endl;
|
||||
std::cout << "d - diable unsolcited" << std::endl;
|
||||
std::cout << "r - cold restart" << std::endl;
|
||||
std::cout << "c - send crob" << std::endl;
|
||||
|
||||
char cmd;
|
||||
std::cin >> cmd;
|
||||
switch(cmd)
|
||||
{
|
||||
case('a') :
|
||||
master->ScanRange(GroupVariationID(1, 2), 0, 3);
|
||||
break;
|
||||
case('d') :
|
||||
master->PerformFunction("disable unsol", FunctionCode::DISABLE_UNSOLICITED,
|
||||
{ Header::AllObjects(60, 2), Header::AllObjects(60, 3), Header::AllObjects(60, 4) }
|
||||
);
|
||||
break;
|
||||
case('r') :
|
||||
{
|
||||
auto print = [](const RestartOperationResult & result)
|
||||
{
|
||||
if(result.summary == TaskCompletion::SUCCESS)
|
||||
{
|
||||
std::cout << "Success, Time: " << result.restartTime.GetMilliseconds() << std::endl;
|
||||
}
|
||||
else
|
||||
{
|
||||
std::cout << "Failure: " << TaskCompletionToString(result.summary) << std::endl;
|
||||
}
|
||||
};
|
||||
master->Restart(RestartType::COLD, print);
|
||||
break;
|
||||
}
|
||||
case('x'):
|
||||
// C++ destructor on DNP3Manager cleans everything up for you
|
||||
return 0;
|
||||
case('i'):
|
||||
integrityScan->Demand();
|
||||
break;
|
||||
case('e'):
|
||||
exceptionScan->Demand();
|
||||
break;
|
||||
case('c'):
|
||||
{
|
||||
ControlRelayOutputBlock crob(ControlCode::LATCH_ON);
|
||||
master->SelectAndOperate(crob, 0, PrintingCommandCallback::Get());
|
||||
break;
|
||||
}
|
||||
default:
|
||||
std::cout << "Unknown action: " << cmd << std::endl;
|
||||
break;
|
||||
}
|
||||
}
|
||||
while(true);
|
||||
|
||||
return 0;
|
||||
}
|
||||
@@ -0,0 +1,196 @@
|
||||
/*
|
||||
* Licensed to Green Energy Corp (www.greenenergycorp.com) under one or
|
||||
* more contributor license agreements. See the NOTICE file distributed
|
||||
* with this work for additional information regarding copyright ownership.
|
||||
* Green Energy Corp licenses this file to you under the Apache License,
|
||||
* Version 2.0 (the "License"); you may not use this file except in
|
||||
* compliance with the License. You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*
|
||||
* This project was forked on 01/01/2013 by Automatak, LLC and modifications
|
||||
* may have been made to this file. Automatak, LLC licenses these modifications
|
||||
* to you under the terms of the License.
|
||||
*/
|
||||
#include <asiodnp3/DNP3Manager.h>
|
||||
#include <asiodnp3/PrintingSOEHandler.h>
|
||||
#include <asiodnp3/PrintingChannelListener.h>
|
||||
#include <asiodnp3/ConsoleLogger.h>
|
||||
#include <asiodnp3/UpdateBuilder.h>
|
||||
|
||||
#include <asiopal/UTCTimeSource.h>
|
||||
#include <opendnp3/outstation/SimpleCommandHandler.h>
|
||||
|
||||
#include <opendnp3/outstation/Database.h>
|
||||
|
||||
#include <opendnp3/LogLevels.h>
|
||||
|
||||
#include <string>
|
||||
#include <thread>
|
||||
#include <iostream>
|
||||
|
||||
using namespace std;
|
||||
using namespace opendnp3;
|
||||
using namespace openpal;
|
||||
using namespace asiopal;
|
||||
using namespace asiodnp3;
|
||||
|
||||
void ConfigureDatabase(DatabaseConfig& config)
|
||||
{
|
||||
// example of configuring analog index 0 for Class2 with floating point variations by default
|
||||
config.analog[0].clazz = PointClass::Class2;
|
||||
config.analog[0].svariation = StaticAnalogVariation::Group30Var5;
|
||||
config.analog[0].evariation = EventAnalogVariation::Group32Var7;
|
||||
}
|
||||
|
||||
struct State
|
||||
{
|
||||
uint32_t count = 0;
|
||||
double value = 0;
|
||||
bool binary = false;
|
||||
DoubleBit dbit = DoubleBit::DETERMINED_OFF;
|
||||
};
|
||||
|
||||
void AddUpdates(UpdateBuilder& builder, State& state, const std::string& arguments);
|
||||
|
||||
int main(int argc, char* argv[])
|
||||
{
|
||||
if (argc != 4)
|
||||
{
|
||||
std::cout << "usage: master-gprs-tls-demo <ca certificate> <certificate chain> <private key>" << std::endl;
|
||||
return -1;
|
||||
}
|
||||
|
||||
std::string caCertificate(argv[1]);
|
||||
std::string certificateChain(argv[2]);
|
||||
std::string privateKey(argv[3]);
|
||||
|
||||
std::cout << "Using CA certificate: " << caCertificate << std::endl;
|
||||
std::cout << "Using certificate chain: " << certificateChain << std::endl;
|
||||
std::cout << "Using private key file: " << privateKey << std::endl;
|
||||
|
||||
// Specify what log levels to use. NORMAL is warning and above
|
||||
// You can add all the comms logging by uncommenting below.
|
||||
const uint32_t FILTERS = levels::NORMAL; // | levels::ALL_COMMS;
|
||||
|
||||
// This is the main point of interaction with the stack
|
||||
// Allocate a single thread to the pool since this is a single outstation
|
||||
DNP3Manager manager(1, ConsoleLogger::Create());
|
||||
|
||||
std::error_code ec;
|
||||
|
||||
// Create a TCP server (listener)
|
||||
auto channel = manager.AddTLSClient(
|
||||
"server",
|
||||
FILTERS,
|
||||
ChannelRetry::Default(),
|
||||
"127.0.0.1",
|
||||
"0.0.0.0",
|
||||
20001,
|
||||
TLSConfig(
|
||||
caCertificate,
|
||||
certificateChain,
|
||||
privateKey,
|
||||
2
|
||||
),
|
||||
PrintingChannelListener::Create(),
|
||||
ec
|
||||
);
|
||||
|
||||
if (ec)
|
||||
{
|
||||
std::cout << "Unable to create tls server: " << ec.message() << std::endl;
|
||||
return ec.value();
|
||||
}
|
||||
|
||||
// The main object for a outstation. The defaults are useable,
|
||||
// but understanding the options are important.
|
||||
OutstationStackConfig stackConfig(DatabaseSizes::AllTypes(10));
|
||||
|
||||
// specify the maximum size of the event buffers
|
||||
stackConfig.outstation.eventBufferConfig = EventBufferConfig::AllTypes(10);
|
||||
|
||||
// you can override an default outstation parameters here
|
||||
// in this example, we've enabled the oustation to use unsolicted reporting
|
||||
// if the master enables it
|
||||
stackConfig.outstation.params.allowUnsolicited = true;
|
||||
|
||||
// You can override the default link layer settings here
|
||||
// in this example we've changed the default link layer addressing
|
||||
stackConfig.link.LocalAddr = 10;
|
||||
stackConfig.link.RemoteAddr = 1;
|
||||
|
||||
// You can optionally change the default reporting variations or class assignment prior to enabling the outstation
|
||||
ConfigureDatabase(stackConfig.dbConfig);
|
||||
|
||||
// Create a new outstation with a log level, command handler, and
|
||||
// config info this returns a thread-safe interface used for
|
||||
// updating the outstation's database.
|
||||
auto outstation = channel->AddOutstation("outstation", SuccessCommandHandler::Create(), DefaultOutstationApplication::Create(), stackConfig);
|
||||
|
||||
// Enable the outstation and start communications
|
||||
outstation->Enable();
|
||||
|
||||
// variables used in example loop
|
||||
string input;
|
||||
State state;
|
||||
|
||||
while (true)
|
||||
{
|
||||
std::cout << "Enter one or more measurement changes then press <enter>" << std::endl;
|
||||
std::cout << "c = counter, b = binary, d = doublebit, a = analog, 'quit' = exit" << std::endl;
|
||||
std::cin >> input;
|
||||
|
||||
if (input == "quit") return 0;
|
||||
else
|
||||
{
|
||||
UpdateBuilder builder;
|
||||
AddUpdates(builder, state, input);
|
||||
outstation->Apply(builder.Build());
|
||||
}
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
void AddUpdates(UpdateBuilder& builder, State& state, const std::string& arguments)
|
||||
{
|
||||
for (const char& c : arguments)
|
||||
{
|
||||
switch (c)
|
||||
{
|
||||
case('c'):
|
||||
{
|
||||
builder.Update(Counter(state.count), 0);
|
||||
++state.count;
|
||||
break;
|
||||
}
|
||||
case('a'):
|
||||
{
|
||||
builder.Update(Analog(state.value), 0);
|
||||
state.value += 1;
|
||||
break;
|
||||
}
|
||||
case('b'):
|
||||
{
|
||||
builder.Update(Binary(state.binary), 0);
|
||||
state.binary = !state.binary;
|
||||
break;
|
||||
}
|
||||
case('d'):
|
||||
{
|
||||
builder.Update(DoubleBitBinary(state.dbit), 0);
|
||||
state.dbit = (state.dbit == DoubleBit::DETERMINED_OFF) ? DoubleBit::DETERMINED_ON : DoubleBit::DETERMINED_OFF;
|
||||
break;
|
||||
}
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,61 @@
|
||||
/*
|
||||
* Licensed to Green Energy Corp (www.greenenergycorp.com) under one or
|
||||
* more contributor license agreements. See the NOTICE file distributed
|
||||
* with this work for additional information regarding copyright ownership.
|
||||
* Green Energy Corp licenses this file to you under the Apache License,
|
||||
* Version 2.0 (the "License"); you may not use this file except in
|
||||
* compliance with the License. You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*
|
||||
* This project was forked on 01/01/2013 by Automatak, LLC and modifications
|
||||
* may have been made to this file. Automatak, LLC licenses these modifications
|
||||
* to you under the terms of the License.
|
||||
*/
|
||||
#ifndef ASIODNP3_CONSOLELOGGER_H
|
||||
#define ASIODNP3_CONSOLELOGGER_H
|
||||
|
||||
#include <mutex>
|
||||
#include <memory>
|
||||
|
||||
#include <openpal/logging/ILogHandler.h>
|
||||
#include <openpal/util/Uncopyable.h>
|
||||
|
||||
namespace asiodnp3
|
||||
{
|
||||
|
||||
std::ostringstream& operator<<(std::ostringstream& ss, const openpal::LogFilters& filters);
|
||||
|
||||
/**
|
||||
* LogHandler that prints all log messages to the console
|
||||
*/
|
||||
class ConsoleLogger final : public openpal::ILogHandler, private openpal::Uncopyable
|
||||
{
|
||||
|
||||
public:
|
||||
|
||||
virtual void Log(const openpal::LogEntry& entry) override;
|
||||
|
||||
static std::shared_ptr<openpal::ILogHandler>Create(bool printLocation = false)
|
||||
{
|
||||
return std::make_shared<ConsoleLogger>(printLocation);
|
||||
};
|
||||
|
||||
ConsoleLogger(bool printLocation) : printLocation(printLocation) {}
|
||||
|
||||
private:
|
||||
|
||||
bool printLocation;
|
||||
|
||||
std::mutex mutex;
|
||||
};
|
||||
|
||||
}
|
||||
|
||||
#endif
|
||||
@@ -0,0 +1,221 @@
|
||||
/*
|
||||
* Licensed to Green Energy Corp (www.greenenergycorp.com) under one or
|
||||
* more contributor license agreements. See the NOTICE file distributed
|
||||
* with this work for additional information regarding copyright ownership.
|
||||
* Green Energy Corp licenses this file to you under the Apache License,
|
||||
* Version 2.0 (the "License"); you may not use this file except in
|
||||
* compliance with the License. You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*
|
||||
* This project was forked on 01/01/2013 by Automatak, LLC and modifications
|
||||
* may have been made to this file. Automatak, LLC licenses these modifications
|
||||
* to you under the terms of the License.
|
||||
*/
|
||||
#ifndef ASIODNP3_DNP3MANAGER_H
|
||||
#define ASIODNP3_DNP3MANAGER_H
|
||||
|
||||
#include <openpal/logging/ILogHandler.h>
|
||||
#include <openpal/executor/TimeDuration.h>
|
||||
|
||||
#include <opendnp3/gen/ChannelState.h>
|
||||
|
||||
#include <asiodnp3/IChannel.h>
|
||||
#include <asiodnp3/IChannelListener.h>
|
||||
#include <asiodnp3/IListenCallbacks.h>
|
||||
|
||||
#include <asiopal/SerialTypes.h>
|
||||
#include <asiopal/ChannelRetry.h>
|
||||
#include <asiopal/TLSConfig.h>
|
||||
#include <asiopal/IListener.h>
|
||||
#include <asiopal/IPEndpoint.h>
|
||||
|
||||
#include <memory>
|
||||
#include <system_error>
|
||||
|
||||
namespace asiodnp3
|
||||
{
|
||||
|
||||
class DNP3ManagerImpl;
|
||||
|
||||
|
||||
/**
|
||||
* Root DNP3 object used to create channels and sessions.
|
||||
*/
|
||||
class DNP3Manager
|
||||
{
|
||||
|
||||
public:
|
||||
|
||||
/**
|
||||
* Construct a manager
|
||||
*
|
||||
* @param concurrencyHint How many threads to allocate in the thread pool
|
||||
* @param handler Callback interface for log messages
|
||||
* @param onThreadStart Action to run when a thread pool thread starts
|
||||
* @param onThreadExit Action to run just before a thread pool thread exits
|
||||
*/
|
||||
DNP3Manager(
|
||||
uint32_t concurrencyHint,
|
||||
std::shared_ptr<openpal::ILogHandler> handler = std::shared_ptr<openpal::ILogHandler>(),
|
||||
std::function<void()> onThreadStart = []() {},
|
||||
std::function<void()> onThreadExit = []() {}
|
||||
);
|
||||
|
||||
~DNP3Manager();
|
||||
|
||||
|
||||
/**
|
||||
* Permanently shutdown the manager and all sub-objects that have been created. Stop
|
||||
* the thead pool.
|
||||
*/
|
||||
void Shutdown();
|
||||
|
||||
/**
|
||||
* Add a persistent TCP client channel. Automatically attempts to reconnect.
|
||||
*
|
||||
* @param id Alias that will be used for logging purposes with this channel
|
||||
* @param levels Bitfield that describes the logging level for this channel and associated sessions
|
||||
* @param retry Retry parameters for failed channels
|
||||
* @param host IP address of remote outstation (i.e. 127.0.0.1 or www.google.com)
|
||||
* @param local adapter address on which to attempt the connection (use 0.0.0.0 for all adapters)
|
||||
* @param port Port of remote outstation is listening on
|
||||
* @param listener optional callback interface (can be nullptr) for info about the running channel
|
||||
* @return shared_ptr to a channel interface
|
||||
*/
|
||||
std::shared_ptr<IChannel> AddTCPClient(
|
||||
const std::string& id,
|
||||
uint32_t levels,
|
||||
const asiopal::ChannelRetry& retry,
|
||||
const std::string& host,
|
||||
const std::string& local,
|
||||
uint16_t port,
|
||||
std::shared_ptr<IChannelListener> listener);
|
||||
|
||||
/**
|
||||
* Add a persistent TCP server channel. Only accepts a single connection at a time.
|
||||
*
|
||||
* @param id Alias that will be used for logging purposes with this channel
|
||||
* @param levels Bitfield that describes the logging level for this channel and associated sessions
|
||||
* @param retry Retry parameters for failed channels
|
||||
* @param endpoint Network adapter to listen on, i.e. 127.0.0.1 or 0.0.0.0
|
||||
* @param port Port to listen on
|
||||
* @param listener optional callback interface (can be nullptr) for info about the running channel
|
||||
* @return shared_ptr to a channel interface
|
||||
*/
|
||||
std::shared_ptr<IChannel> AddTCPServer(
|
||||
const std::string& id,
|
||||
uint32_t levels,
|
||||
const asiopal::ChannelRetry& retry,
|
||||
const std::string& endpoint,
|
||||
uint16_t port,
|
||||
std::shared_ptr<IChannelListener> listener);
|
||||
|
||||
/**
|
||||
* Add a persistent TCP serial channel
|
||||
*
|
||||
* @param id Alias that will be used for logging purposes with this channel
|
||||
* @param levels Bitfield that describes the logging level for this channel and associated sessions
|
||||
* @param retry Retry parameters for failed channels
|
||||
* @param settings settings object that fully parameterizes the serial port
|
||||
* @param listener optional callback interface (can be nullptr) for info about the running channel
|
||||
* @return shared_ptr to a channel interface
|
||||
*/
|
||||
std::shared_ptr<IChannel> AddSerial(
|
||||
const std::string& id,
|
||||
uint32_t levels,
|
||||
const asiopal::ChannelRetry& retry,
|
||||
asiopal::SerialSettings settings,
|
||||
std::shared_ptr<IChannelListener> listener);
|
||||
|
||||
/**
|
||||
* Add a TLS client channel
|
||||
*
|
||||
* @throw std::system_error Throws underlying ASIO exception of TLS configuration is invalid
|
||||
*
|
||||
* @param id Alias that will be used for logging purposes with this channel
|
||||
* @param levels Bitfield that describes the logging level for this channel and associated sessions
|
||||
* @param retry Retry parameters for failed channels
|
||||
* @param host IP address of remote outstation (i.e. 127.0.0.1 or www.google.com)
|
||||
* @param local adapter address on which to attempt the connection (use 0.0.0.0 for all adapters)
|
||||
* @param port Port of remote outstation is listening on
|
||||
* @param config TLS configuration information
|
||||
* @param listener optional callback interface (can be nullptr) for info about the running channel
|
||||
* @param ec An error code. If set, a nullptr will be returned
|
||||
* @return shared_ptr to a channel interface
|
||||
*/
|
||||
std::shared_ptr<IChannel> AddTLSClient(
|
||||
const std::string& id,
|
||||
uint32_t levels,
|
||||
const asiopal::ChannelRetry& retry,
|
||||
const std::string& host,
|
||||
const std::string& local,
|
||||
uint16_t port,
|
||||
const asiopal::TLSConfig& config,
|
||||
std::shared_ptr<IChannelListener> listener,
|
||||
std::error_code& ec);
|
||||
|
||||
|
||||
/**
|
||||
* Add a TLS server channel
|
||||
*
|
||||
* @throw std::system_error Throws underlying ASIO exception of TLS configuration is invalid
|
||||
*
|
||||
* @param id Alias that will be used for logging purposes with this channel
|
||||
* @param levels Bitfield that describes the logging level for this channel and associated sessions
|
||||
* @param retry Retry parameters for failed channels
|
||||
* @param endpoint Network adapter to listen on, i.e. 127.0.0.1 or 0.0.0.0
|
||||
* @param port Port to listen on
|
||||
* @param config TLS configuration information
|
||||
* @param listener optional callback interface (can be nullptr) for info about the running channel
|
||||
* @param ec An error code. If set, a nullptr will be returned
|
||||
* @return shared_ptr to a channel interface
|
||||
*/
|
||||
std::shared_ptr<IChannel> AddTLSServer(
|
||||
const std::string& id,
|
||||
uint32_t levels,
|
||||
const asiopal::ChannelRetry& retry,
|
||||
const std::string& endpoint,
|
||||
uint16_t port,
|
||||
const asiopal::TLSConfig& config,
|
||||
std::shared_ptr<IChannelListener> listener,
|
||||
std::error_code& ec);
|
||||
|
||||
/**
|
||||
* Create a TCP listener that will be used to accept incoming connections
|
||||
*/
|
||||
std::shared_ptr<asiopal::IListener> CreateListener(
|
||||
std::string loggerid,
|
||||
openpal::LogFilters loglevel,
|
||||
asiopal::IPEndpoint endpoint,
|
||||
std::shared_ptr<IListenCallbacks> callbacks,
|
||||
std::error_code& ec
|
||||
);
|
||||
|
||||
/**
|
||||
* Create a TLS listener that will be used to accept incoming connections
|
||||
*/
|
||||
std::shared_ptr<asiopal::IListener> CreateListener(
|
||||
std::string loggerid,
|
||||
openpal::LogFilters loglevel,
|
||||
asiopal::IPEndpoint endpoint,
|
||||
const asiopal::TLSConfig& config,
|
||||
std::shared_ptr<IListenCallbacks> callbacks,
|
||||
std::error_code& ec
|
||||
);
|
||||
|
||||
private:
|
||||
|
||||
std::unique_ptr<DNP3ManagerImpl> impl;
|
||||
|
||||
};
|
||||
|
||||
}
|
||||
|
||||
#endif
|
||||
@@ -0,0 +1,83 @@
|
||||
/*
|
||||
* Licensed to Green Energy Corp (www.greenenergycorp.com) under one or
|
||||
* more contributor license agreements. See the NOTICE file distributed
|
||||
* with this work for additional information regarding copyright ownership.
|
||||
* Green Energy Corp licenses this file to you under the Apache License,
|
||||
* Version 2.0 (the "License"); you may not use this file except in
|
||||
* compliance with the License. You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*
|
||||
* This project was forked on 01/01/2013 by Automatak, LLC and modifications
|
||||
* may have been made to this file. Automatak, LLC licenses these modifications
|
||||
* to you under the terms of the License.
|
||||
*/
|
||||
#ifndef ASIODNP3_DATABASECONFIG_H
|
||||
#define ASIODNP3_DATABASECONFIG_H
|
||||
|
||||
#include "opendnp3/outstation/MeasurementConfig.h"
|
||||
|
||||
#include "opendnp3/outstation/DatabaseSizes.h"
|
||||
|
||||
#include "openpal/container/Array.h"
|
||||
|
||||
namespace asiodnp3
|
||||
{
|
||||
|
||||
class DatabaseConfig
|
||||
{
|
||||
public:
|
||||
|
||||
DatabaseConfig(const opendnp3::DatabaseSizes& sizes) :
|
||||
sizes(sizes),
|
||||
binary(sizes.numBinary),
|
||||
doubleBinary(sizes.numDoubleBinary),
|
||||
analog(sizes.numAnalog),
|
||||
counter(sizes.numCounter),
|
||||
frozenCounter(sizes.numFrozenCounter),
|
||||
boStatus(sizes.numBinaryOutputStatus),
|
||||
aoStatus(sizes.numAnalogOutputStatus),
|
||||
timeAndInterval(sizes.numTimeAndInterval)
|
||||
{
|
||||
InitIndices(binary);
|
||||
InitIndices(doubleBinary);
|
||||
InitIndices(analog);
|
||||
InitIndices(counter);
|
||||
InitIndices(frozenCounter);
|
||||
InitIndices(boStatus);
|
||||
InitIndices(aoStatus);
|
||||
InitIndices(timeAndInterval);
|
||||
}
|
||||
|
||||
const opendnp3::DatabaseSizes sizes;
|
||||
|
||||
openpal::Array<opendnp3::BinaryConfig, uint16_t> binary;
|
||||
openpal::Array<opendnp3::DoubleBitBinaryConfig, uint16_t> doubleBinary;
|
||||
openpal::Array<opendnp3::AnalogConfig, uint16_t> analog;
|
||||
openpal::Array<opendnp3::CounterConfig, uint16_t> counter;
|
||||
openpal::Array<opendnp3::FrozenCounterConfig, uint16_t> frozenCounter;
|
||||
openpal::Array<opendnp3::BOStatusConfig, uint16_t> boStatus;
|
||||
openpal::Array<opendnp3::AOStatusConfig, uint16_t> aoStatus;
|
||||
openpal::Array<opendnp3::TimeAndIntervalConfig, uint16_t> timeAndInterval;
|
||||
|
||||
private:
|
||||
|
||||
template <class T>
|
||||
void InitIndices(T& values)
|
||||
{
|
||||
for (auto i = 0; i < values.Size(); ++i)
|
||||
{
|
||||
values[i].vIndex = i;
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
}
|
||||
|
||||
#endif
|
||||
@@ -0,0 +1,62 @@
|
||||
/*
|
||||
* Licensed to Green Energy Corp (www.greenenergycorp.com) under one or
|
||||
* more contributor license agreements. See the NOTICE file distributed
|
||||
* with this work for additional information regarding copyright ownership.
|
||||
* Green Energy Corp licenses this file to you under the Apache License,
|
||||
* Version 2.0 (the "License"); you may not use this file except in
|
||||
* compliance with the License. You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*
|
||||
* This project was forked on 01/01/2013 by Automatak, LLC and modifications
|
||||
* may have been made to this file. Automatak, LLC licenses these modifications
|
||||
* to you under the terms of the License.
|
||||
*/
|
||||
#ifndef ASIODNP3_DEFAULTLISTENCALLBACKS_H
|
||||
#define ASIODNP3_DEFAULTLISTENCALLBACKS_H
|
||||
|
||||
#include "asiodnp3/IListenCallbacks.h"
|
||||
#include "asiodnp3/PrintingSOEHandler.h"
|
||||
#include "asiodnp3/DefaultMasterApplication.h"
|
||||
|
||||
namespace asiodnp3
|
||||
{
|
||||
|
||||
/**
|
||||
* Callback interface invoked when a new connection is accepted
|
||||
*/
|
||||
class DefaultListenCallbacks final : public IListenCallbacks
|
||||
{
|
||||
public:
|
||||
|
||||
DefaultListenCallbacks();
|
||||
|
||||
virtual ~DefaultListenCallbacks() {}
|
||||
|
||||
virtual bool AcceptConnection(uint64_t sessionid, const std::string& ipaddress) override;
|
||||
|
||||
virtual bool AcceptCertificate(uint64_t sessionid, const X509Info& info) override;
|
||||
|
||||
virtual openpal::TimeDuration GetFirstFrameTimeout() override;
|
||||
|
||||
virtual void OnFirstFrame(uint64_t sessionid, const opendnp3::LinkHeaderFields& header, ISessionAcceptor& acceptor) override;
|
||||
|
||||
virtual void OnConnectionClose(uint64_t sessionid, const std::shared_ptr<IMasterSession>& session) override;
|
||||
|
||||
virtual void OnCertificateError(uint64_t sessionid, const X509Info& info, int error) override;
|
||||
|
||||
private:
|
||||
|
||||
std::string SessionIdToString(uint64_t id);
|
||||
};
|
||||
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
@@ -0,0 +1,63 @@
|
||||
/*
|
||||
* Licensed to Green Energy Corp (www.greenenergycorp.com) under one or
|
||||
* more contributor license agreements. See the NOTICE file distributed
|
||||
* with this work for additional information regarding copyright ownership.
|
||||
* Green Energy Corp licenses this file to you under the Apache License,
|
||||
* Version 2.0 (the "License"); you may not use this file except in
|
||||
* compliance with the License. You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*
|
||||
* This project was forked on 01/01/2013 by Automatak, LLC and modifications
|
||||
* may have been made to this file. Automatak, LLC licenses these modifications
|
||||
* to you under the terms of the License.
|
||||
*/
|
||||
#ifndef ASIODNP3_DEFAULTMASTERAPPLICATION_H
|
||||
#define ASIODNP3_DEFAULTMASTERAPPLICATION_H
|
||||
|
||||
#include <opendnp3/master/IMasterApplication.h>
|
||||
|
||||
#include <memory>
|
||||
|
||||
namespace asiodnp3
|
||||
{
|
||||
|
||||
class DefaultMasterApplication : public opendnp3::IMasterApplication
|
||||
{
|
||||
public:
|
||||
|
||||
DefaultMasterApplication() {}
|
||||
|
||||
static std::shared_ptr<IMasterApplication> Create()
|
||||
{
|
||||
return std::make_shared<DefaultMasterApplication>();
|
||||
}
|
||||
|
||||
virtual void OnReceiveIIN(const opendnp3::IINField& iin) override final {}
|
||||
|
||||
virtual void OnTaskStart(opendnp3::MasterTaskType type, opendnp3::TaskId id) override final {}
|
||||
|
||||
virtual void OnTaskComplete(const opendnp3::TaskInfo& info) override final {}
|
||||
|
||||
virtual bool AssignClassDuringStartup() override final
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
virtual void ConfigureAssignClassRequest(const opendnp3::WriteHeaderFunT& fun) override final {}
|
||||
|
||||
virtual openpal::UTCTimestamp Now() override final;
|
||||
|
||||
virtual void OnStateChange(opendnp3::LinkStatus value) override final {}
|
||||
|
||||
};
|
||||
|
||||
}
|
||||
|
||||
#endif
|
||||
@@ -0,0 +1,79 @@
|
||||
/*
|
||||
* Licensed to Green Energy Corp (www.greenenergycorp.com) under one or
|
||||
* more contributor license agreements. See the NOTICE file distributed
|
||||
* with this work for additional information regarding copyright ownership.
|
||||
* Green Energy Corp licenses this file to you under the Apache License,
|
||||
* Version 2.0 (the "License"); you may not use this file except in
|
||||
* compliance with the License. You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*
|
||||
* This project was forked on 01/01/2013 by Automatak, LLC and modifications
|
||||
* may have been made to this file. Automatak, LLC licenses these modifications
|
||||
* to you under the terms of the License.
|
||||
*/
|
||||
|
||||
#ifndef ASIODNP3_ERRORCODES_H
|
||||
#define ASIODNP3_ERRORCODES_H
|
||||
|
||||
#include <system_error>
|
||||
|
||||
|
||||
namespace asiodnp3
|
||||
{
|
||||
|
||||
enum class Error : int
|
||||
{
|
||||
SHUTTING_DOWN,
|
||||
NO_TLS_SUPPORT,
|
||||
NO_SERIAL_SUPPORT
|
||||
};
|
||||
|
||||
class ErrorCategory final : public std::error_category
|
||||
{
|
||||
public:
|
||||
|
||||
static const std::error_category& Instance()
|
||||
{
|
||||
return instance;
|
||||
}
|
||||
|
||||
virtual const char* name() const noexcept
|
||||
{
|
||||
return "dnp3";
|
||||
}
|
||||
|
||||
virtual std::string message(int ev) const;
|
||||
|
||||
private:
|
||||
|
||||
ErrorCategory() {}
|
||||
ErrorCategory(const ErrorCategory&) = delete;
|
||||
|
||||
static ErrorCategory instance;
|
||||
};
|
||||
|
||||
inline std::error_code make_error_code(Error err)
|
||||
{
|
||||
return std::error_code(static_cast<int>(err), ErrorCategory::Instance());
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
|
||||
namespace std
|
||||
{
|
||||
|
||||
template <>
|
||||
struct is_error_code_enum<asiodnp3::Error> : public true_type {};
|
||||
|
||||
}
|
||||
|
||||
|
||||
#endif
|
||||
@@ -0,0 +1,105 @@
|
||||
/*
|
||||
* Licensed to Green Energy Corp (www.greenenergycorp.com) under one or
|
||||
* more contributor license agreements. See the NOTICE file distributed
|
||||
* with this work for additional information regarding copyright ownership.
|
||||
* Green Energy Corp licenses this file to you under the Apache License,
|
||||
* Version 2.0 (the "License"); you may not use this file except in
|
||||
* compliance with the License. You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*
|
||||
* This project was forked on 01/01/2013 by Automatak, LLC and modifications
|
||||
* may have been made to this file. Automatak, LLC licenses these modifications
|
||||
* to you under the terms of the License.
|
||||
*/
|
||||
#ifndef ASIODNP3_ICHANNEL_H
|
||||
#define ASIODNP3_ICHANNEL_H
|
||||
|
||||
#include <opendnp3/gen/ChannelState.h>
|
||||
#include <opendnp3/link/LinkStatistics.h>
|
||||
|
||||
#include <opendnp3/master/ISOEHandler.h>
|
||||
#include <opendnp3/master/IMasterApplication.h>
|
||||
|
||||
#include <opendnp3/outstation/ICommandHandler.h>
|
||||
#include <opendnp3/outstation/IOutstationApplication.h>
|
||||
|
||||
#include <openpal/logging/LogFilters.h>
|
||||
#include <openpal/executor/IExecutor.h>
|
||||
|
||||
#include "asiopal/IResourceManager.h"
|
||||
|
||||
#include "IMaster.h"
|
||||
#include "IOutstation.h"
|
||||
#include "MasterStackConfig.h"
|
||||
#include "OutstationStackConfig.h"
|
||||
|
||||
#include <memory>
|
||||
|
||||
namespace asiodnp3
|
||||
{
|
||||
|
||||
/**
|
||||
* Represents a communication channel upon which masters and outstations can be bound.
|
||||
*/
|
||||
class IChannel : public asiopal::IResource
|
||||
{
|
||||
public:
|
||||
|
||||
virtual ~IChannel() {}
|
||||
|
||||
/**
|
||||
* Synchronously read the channel statistics
|
||||
*/
|
||||
virtual opendnp3::LinkStatistics GetStatistics() = 0;
|
||||
|
||||
/**
|
||||
* @return The current logger settings for this channel
|
||||
*/
|
||||
virtual openpal::LogFilters GetLogFilters() const = 0;
|
||||
|
||||
/**
|
||||
* @param filters Adjust the filters to this value
|
||||
*/
|
||||
virtual void SetLogFilters(const openpal::LogFilters& filters) = 0;
|
||||
|
||||
/**
|
||||
* Add a master to the channel
|
||||
*
|
||||
* @param id An ID that gets used for logging
|
||||
* @param SOEHandler Callback object for all received measurements
|
||||
* @param application The master application bound to the master session
|
||||
* @param config Configuration object that controls how the master behaves
|
||||
*
|
||||
* @return shared_ptr to the running master
|
||||
*/
|
||||
virtual std::shared_ptr<IMaster> AddMaster(const std::string& id,
|
||||
std::shared_ptr<opendnp3::ISOEHandler> SOEHandler,
|
||||
std::shared_ptr<opendnp3::IMasterApplication> application,
|
||||
const MasterStackConfig& config) = 0;
|
||||
|
||||
/**
|
||||
* Add an outstation to the channel
|
||||
*
|
||||
* @param id An ID that gets used for logging
|
||||
* @param commandHandler Callback object for handling command requests
|
||||
* @param application Callback object for user code
|
||||
* @param config Configuration object that controls how the outstation behaves
|
||||
* @return shared_ptr to the running outstation
|
||||
*/
|
||||
virtual std::shared_ptr<IOutstation> AddOutstation( const std::string& id,
|
||||
std::shared_ptr<opendnp3::ICommandHandler> commandHandler,
|
||||
std::shared_ptr<opendnp3::IOutstationApplication> application,
|
||||
const OutstationStackConfig& config) = 0;
|
||||
|
||||
};
|
||||
|
||||
}
|
||||
|
||||
#endif
|
||||
@@ -0,0 +1,47 @@
|
||||
/*
|
||||
* Licensed to Green Energy Corp (www.greenenergycorp.com) under one or
|
||||
* more contributor license agreements. See the NOTICE file distributed
|
||||
* with this work for additional information regarding copyright ownership.
|
||||
* Green Energy Corp licenses this file to you under the Apache License,
|
||||
* Version 2.0 (the "License"); you may not use this file except in
|
||||
* compliance with the License. You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*
|
||||
* This project was forked on 01/01/2013 by Automatak, LLC and modifications
|
||||
* may have been made to this file. Automatak, LLC licenses these modifications
|
||||
* to you under the terms of the License.
|
||||
*/
|
||||
#ifndef ASIODNP3_ICHANNELLISTENER_H
|
||||
#define ASIODNP3_ICHANNELLISTENER_H
|
||||
|
||||
#include <opendnp3/gen/ChannelState.h>
|
||||
|
||||
namespace asiodnp3
|
||||
{
|
||||
|
||||
/**
|
||||
* Callback interface for receiving information about a running channel
|
||||
*/
|
||||
class IChannelListener
|
||||
{
|
||||
public:
|
||||
|
||||
virtual ~IChannelListener() {}
|
||||
|
||||
/*
|
||||
* Receive callbacks for state transitions on the channels executor
|
||||
*/
|
||||
virtual void OnStateChange(opendnp3::ChannelState state) = 0;
|
||||
|
||||
};
|
||||
|
||||
}
|
||||
|
||||
#endif
|
||||
@@ -0,0 +1,94 @@
|
||||
/*
|
||||
* Licensed to Green Energy Corp (www.greenenergycorp.com) under one or
|
||||
* more contributor license agreements. See the NOTICE file distributed
|
||||
* with this work for additional information regarding copyright ownership.
|
||||
* Green Energy Corp licenses this file to you under the Apache License,
|
||||
* Version 2.0 (the "License"); you may not use this file except in
|
||||
* compliance with the License. You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*
|
||||
* This project was forked on 01/01/2013 by Automatak, LLC and modifications
|
||||
* may have been made to this file. Automatak, LLC licenses these modifications
|
||||
* to you under the terms of the License.
|
||||
*/
|
||||
#ifndef ASIODNP3_ILISTENCALLBACKS_H
|
||||
#define ASIODNP3_ILISTENCALLBACKS_H
|
||||
|
||||
#include <openpal/executor/TimeDuration.h>
|
||||
#include <opendnp3/link/LinkHeaderFields.h>
|
||||
|
||||
#include "asiodnp3/ISessionAcceptor.h"
|
||||
#include "asiodnp3/X509Info.h"
|
||||
|
||||
namespace asiodnp3
|
||||
{
|
||||
|
||||
/**
|
||||
* Callback interface invoked when a new connection is accepted
|
||||
*/
|
||||
class IListenCallbacks
|
||||
{
|
||||
public:
|
||||
|
||||
virtual ~IListenCallbacks() {}
|
||||
|
||||
/**
|
||||
* Ask user code if the following connection should be accepted
|
||||
*
|
||||
* @param sessionid Incrementing id used to uniquely identify the session
|
||||
* @param ipaddress The IP address of the connecting host. Can optionally be used for connection filtering
|
||||
*
|
||||
* @return If true, the connection is accepted and a link frame parser is created to handle incoming frame data
|
||||
*/
|
||||
virtual bool AcceptConnection(uint64_t sessionid, const std::string& ipaddress) = 0;
|
||||
|
||||
/**
|
||||
* Ask user code if the following preverified certificate should be accepted
|
||||
*
|
||||
* @param sessionid Incrementing id used to uniquely identify the session
|
||||
* @param info Information from the x509 certificate
|
||||
*
|
||||
* @return If true, if the certificate should be accepted, false otherwise.
|
||||
*/
|
||||
virtual bool AcceptCertificate(uint64_t sessionid, const X509Info& info) = 0;
|
||||
|
||||
/// return the amount of time the session should wait for the first frame
|
||||
virtual openpal::TimeDuration GetFirstFrameTimeout() = 0;
|
||||
|
||||
/**
|
||||
* Called when the first link-layer frame is received for a session
|
||||
*/
|
||||
virtual void OnFirstFrame(
|
||||
uint64_t sessionid,
|
||||
const opendnp3::LinkHeaderFields& header,
|
||||
ISessionAcceptor& acceptor
|
||||
) = 0;
|
||||
|
||||
/**
|
||||
* Called when a socket closes
|
||||
*
|
||||
* @param sessionid Incrementing id used to uniquely identify the session
|
||||
* @param session Possibly NULL shared_ptr to the master session if it was created
|
||||
*/
|
||||
virtual void OnConnectionClose(uint64_t sessionid, const std::shared_ptr<IMasterSession>& session) = 0;
|
||||
|
||||
/**
|
||||
* Called when a certificate fails verification
|
||||
*
|
||||
* @param sessionid Incrementing id used to uniquely identify the session
|
||||
* @param info Information from the x509 certificate
|
||||
* @param error Error code with reason for failed verification
|
||||
*/
|
||||
virtual void OnCertificateError(uint64_t sessionid, const X509Info& info, int error) = 0;
|
||||
};
|
||||
|
||||
}
|
||||
|
||||
#endif
|
||||
@@ -0,0 +1,44 @@
|
||||
/*
|
||||
* Licensed to Green Energy Corp (www.greenenergycorp.com) under one or
|
||||
* more contributor license agreements. See the NOTICE file distributed
|
||||
* with this work for additional information regarding copyright ownership.
|
||||
* Green Energy Corp licenses this file to you under the Apache License,
|
||||
* Version 2.0 (the "License"); you may not use this file except in
|
||||
* compliance with the License. You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*
|
||||
* This project was forked on 01/01/2013 by Automatak, LLC and modifications
|
||||
* may have been made to this file. Automatak, LLC licenses these modifications
|
||||
* to you under the terms of the License.
|
||||
*/
|
||||
#ifndef ASIODNP3_IMASTER_H
|
||||
#define ASIODNP3_IMASTER_H
|
||||
|
||||
#include "asiodnp3/IStack.h"
|
||||
#include "asiodnp3/IMasterOperations.h"
|
||||
|
||||
namespace asiodnp3
|
||||
{
|
||||
|
||||
/**
|
||||
* Interface that represents a running master session.
|
||||
*/
|
||||
class IMaster : public IMasterOperations, public IStack
|
||||
{
|
||||
public:
|
||||
|
||||
virtual ~IMaster() {}
|
||||
|
||||
};
|
||||
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
@@ -0,0 +1,124 @@
|
||||
/*
|
||||
* Licensed to Green Energy Corp (www.greenenergycorp.com) under one or
|
||||
* more contributor license agreements. See the NOTICE file distributed
|
||||
* with this work for additional information regarding copyright ownership.
|
||||
* Green Energy Corp licenses this file to you under the Apache License,
|
||||
* Version 2.0 (the "License"); you may not use this file except in
|
||||
* compliance with the License. You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*
|
||||
* This project was forked on 01/01/2013 by Automatak, LLC and modifications
|
||||
* may have been made to this file. Automatak, LLC licenses these modifications
|
||||
* to you under the terms of the License.
|
||||
*/
|
||||
#ifndef ASIODNP3_IMASTEROPERATIONS_H
|
||||
#define ASIODNP3_IMASTEROPERATIONS_H
|
||||
|
||||
#include <opendnp3/app/ClassField.h>
|
||||
#include <opendnp3/app/MeasurementTypes.h>
|
||||
#include <opendnp3/StackStatistics.h>
|
||||
|
||||
#include <opendnp3/master/HeaderTypes.h>
|
||||
#include <opendnp3/master/TaskConfig.h>
|
||||
#include <opendnp3/master/ICommandProcessor.h>
|
||||
#include <opendnp3/master/RestartOperationResult.h>
|
||||
|
||||
#include <opendnp3/gen/FunctionCode.h>
|
||||
#include <opendnp3/gen/RestartType.h>
|
||||
|
||||
#include <openpal/executor/TimeDuration.h>
|
||||
#include <openpal/logging/LogFilters.h>
|
||||
|
||||
#include <asiodnp3/IMasterScan.h>
|
||||
|
||||
#include <vector>
|
||||
#include <memory>
|
||||
|
||||
namespace asiodnp3
|
||||
{
|
||||
|
||||
/**
|
||||
* All the operations that the user can perform on a running master
|
||||
*/
|
||||
class IMasterOperations : public opendnp3::ICommandProcessor
|
||||
{
|
||||
public:
|
||||
|
||||
virtual ~IMasterOperations() {}
|
||||
|
||||
/**
|
||||
* @param filters Adjust the filters to this value
|
||||
*/
|
||||
virtual void SetLogFilters(const openpal::LogFilters& filters) = 0;
|
||||
|
||||
/**
|
||||
* Add a recurring user-defined scan from a vector of headers
|
||||
* @ return A proxy class used to manipulate the scan
|
||||
*/
|
||||
virtual std::shared_ptr<IMasterScan> AddScan(openpal::TimeDuration period, const std::vector<opendnp3::Header>& headers, const opendnp3::TaskConfig& config = opendnp3::TaskConfig::Default()) = 0;
|
||||
|
||||
/**
|
||||
* Add a scan that requests all objects using qualifier code 0x06
|
||||
* @ return A proxy class used to manipulate the scan
|
||||
*/
|
||||
virtual std::shared_ptr<IMasterScan> AddAllObjectsScan(opendnp3::GroupVariationID gvId, openpal::TimeDuration period, const opendnp3::TaskConfig& config = opendnp3::TaskConfig::Default()) = 0;
|
||||
|
||||
/**
|
||||
* Add a class-based scan to the master
|
||||
* @return A proxy class used to manipulate the scan
|
||||
*/
|
||||
virtual std::shared_ptr<IMasterScan> AddClassScan(const opendnp3::ClassField& field, openpal::TimeDuration period, const opendnp3::TaskConfig& config = opendnp3::TaskConfig::Default()) = 0;
|
||||
|
||||
/**
|
||||
* Add a start/stop (range) scan to the master
|
||||
* @return A proxy class used to manipulate the scan
|
||||
*/
|
||||
virtual std::shared_ptr<IMasterScan> AddRangeScan(opendnp3::GroupVariationID gvId, uint16_t start, uint16_t stop, openpal::TimeDuration period, const opendnp3::TaskConfig& config = opendnp3::TaskConfig::Default()) = 0;
|
||||
|
||||
/**
|
||||
* Initiate a single user defined scan via a vector of headers
|
||||
*/
|
||||
virtual void Scan(const std::vector<opendnp3::Header>& headers, const opendnp3::TaskConfig& config = opendnp3::TaskConfig::Default()) = 0;
|
||||
|
||||
/**
|
||||
* Initiate a single scan that requests all objects (0x06 qualifier code) for a certain group and variation
|
||||
*/
|
||||
virtual void ScanAllObjects(opendnp3::GroupVariationID gvId, const opendnp3::TaskConfig& config = opendnp3::TaskConfig::Default()) = 0;
|
||||
|
||||
/**
|
||||
* Initiate a single class-based scan
|
||||
*/
|
||||
virtual void ScanClasses(const opendnp3::ClassField& field, const opendnp3::TaskConfig& config = opendnp3::TaskConfig::Default()) = 0;
|
||||
/**
|
||||
* Initiate a single start/stop (range) scan
|
||||
*/
|
||||
virtual void ScanRange(opendnp3::GroupVariationID gvId, uint16_t start, uint16_t stop, const opendnp3::TaskConfig& config = opendnp3::TaskConfig::Default()) = 0;
|
||||
|
||||
/**
|
||||
* Write a time and interval object to a specific index
|
||||
*/
|
||||
virtual void Write(const opendnp3::TimeAndInterval& value, uint16_t index, const opendnp3::TaskConfig& config = opendnp3::TaskConfig::Default()) = 0;
|
||||
|
||||
/**
|
||||
* Perform a cold or warm restart and get back the time-to-complete value
|
||||
*/
|
||||
virtual void Restart(opendnp3::RestartType op, const opendnp3::RestartOperationCallbackT& callback, opendnp3::TaskConfig config = opendnp3::TaskConfig::Default()) = 0;
|
||||
|
||||
/**
|
||||
* Perform any operation that requires just a function code
|
||||
*/
|
||||
virtual void PerformFunction(const std::string& name, opendnp3::FunctionCode func, const std::vector<opendnp3::Header>& headers, const opendnp3::TaskConfig& config = opendnp3::TaskConfig::Default()) = 0;
|
||||
|
||||
};
|
||||
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
@@ -0,0 +1,43 @@
|
||||
/*
|
||||
* Licensed to Green Energy Corp (www.greenenergycorp.com) under one or
|
||||
* more contributor license agreements. See the NOTICE file distributed
|
||||
* with this work for additional information regarding copyright ownership.
|
||||
* Green Energy Corp licenses this file to you under the Apache License,
|
||||
* Version 2.0 (the "License"); you may not use this file except in
|
||||
* compliance with the License. You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*
|
||||
* This project was forked on 01/01/2013 by Automatak, LLC and modifications
|
||||
* may have been made to this file. Automatak, LLC licenses these modifications
|
||||
* to you under the terms of the License.
|
||||
*/
|
||||
#ifndef ASIODNP3_IMASTERSCAN_H
|
||||
#define ASIODNP3_IMASTERSCAN_H
|
||||
|
||||
namespace asiodnp3
|
||||
{
|
||||
|
||||
/**
|
||||
* Interface for interacting w/ a permanently bound scan
|
||||
*/
|
||||
class IMasterScan
|
||||
{
|
||||
public:
|
||||
|
||||
virtual ~IMasterScan() {}
|
||||
|
||||
/// Request that the scan be performed as soon as possible
|
||||
virtual bool Demand() = 0;
|
||||
|
||||
};
|
||||
|
||||
}
|
||||
|
||||
#endif
|
||||
@@ -0,0 +1,47 @@
|
||||
/*
|
||||
* Licensed to Green Energy Corp (www.greenenergycorp.com) under one or
|
||||
* more contributor license agreements. See the NOTICE file distributed
|
||||
* with this work for additional information regarding copyright ownership.
|
||||
* Green Energy Corp licenses this file to you under the Apache License,
|
||||
* Version 2.0 (the "License"); you may not use this file except in
|
||||
* compliance with the License. You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*
|
||||
* This project was forked on 01/01/2013 by Automatak, LLC and modifications
|
||||
* may have been made to this file. Automatak, LLC licenses these modifications
|
||||
* to you under the terms of the License.
|
||||
*/
|
||||
#ifndef ASIODNP3_IMASTERSESSION_H
|
||||
#define ASIODNP3_IMASTERSESSION_H
|
||||
|
||||
#include "asiodnp3/IMasterOperations.h"
|
||||
|
||||
namespace asiodnp3
|
||||
{
|
||||
|
||||
/**
|
||||
* Interface that represents an emphemeral master session
|
||||
*/
|
||||
class IMasterSession : public IMasterOperations
|
||||
{
|
||||
public:
|
||||
|
||||
virtual ~IMasterSession() {}
|
||||
|
||||
virtual opendnp3::StackStatistics GetStackStatistics() = 0;
|
||||
|
||||
virtual void BeginShutdown() = 0;
|
||||
|
||||
};
|
||||
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
@@ -0,0 +1,63 @@
|
||||
/*
|
||||
* Licensed to Green Energy Corp (www.greenenergycorp.com) under one or
|
||||
* more contributor license agreements. See the NOTICE file distributed
|
||||
* with this work for additional information regarding copyright ownership.
|
||||
* Green Energy Corp licenses this file to you under the Apache License,
|
||||
* Version 2.0 (the "License"); you may not use this file except in
|
||||
* compliance with the License. You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*
|
||||
* This project was forked on 01/01/2013 by Automatak, LLC and modifications
|
||||
* may have been made to this file. Automatak, LLC licenses these modifications
|
||||
* to you under the terms of the License.
|
||||
*/
|
||||
#ifndef ASIODNP3_IOUTSTATION_H
|
||||
#define ASIODNP3_IOUTSTATION_H
|
||||
|
||||
#include "asiodnp3/IStack.h"
|
||||
#include "asiodnp3/Updates.h"
|
||||
|
||||
#include <openpal/logging/LogFilters.h>
|
||||
|
||||
namespace asiodnp3
|
||||
{
|
||||
|
||||
/**
|
||||
* Interface representing a running outstation.
|
||||
*/
|
||||
class IOutstation : public IStack
|
||||
{
|
||||
friend class MeasUpdate;
|
||||
|
||||
public:
|
||||
|
||||
virtual ~IOutstation() {}
|
||||
|
||||
/**
|
||||
* @param filters Adjust the filters to this value
|
||||
*/
|
||||
virtual void SetLogFilters(const openpal::LogFilters& filters) = 0;
|
||||
|
||||
/**
|
||||
* Sets the restart IIN bit. Normally applications should not
|
||||
* touch this bit, but it is provided for simulating restarts.
|
||||
*/
|
||||
virtual void SetRestartIIN() = 0;
|
||||
|
||||
/**
|
||||
* Apply a set of measurement updates to the outstation
|
||||
*/
|
||||
virtual void Apply(const Updates& updates) = 0;
|
||||
|
||||
};
|
||||
|
||||
}
|
||||
|
||||
#endif
|
||||
@@ -0,0 +1,54 @@
|
||||
/*
|
||||
* Licensed to Green Energy Corp (www.greenenergycorp.com) under one or
|
||||
* more contributor license agreements. See the NOTICE file distributed
|
||||
* with this work for additional information regarding copyright ownership.
|
||||
* Green Energy Corp licenses this file to you under the Apache License,
|
||||
* Version 2.0 (the "License"); you may not use this file except in
|
||||
* compliance with the License. You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*
|
||||
* This project was forked on 01/01/2013 by Automatak, LLC and modifications
|
||||
* may have been made to this file. Automatak, LLC licenses these modifications
|
||||
* to you under the terms of the License.
|
||||
*/
|
||||
#ifndef ASIODNP3_ISESSION_ACCEPTOR_H
|
||||
#define ASIODNP3_ISESSION_ACCEPTOR_H
|
||||
|
||||
#include <opendnp3/master/ISOEHandler.h>
|
||||
#include <opendnp3/master/IMasterApplication.h>
|
||||
|
||||
#include "asiodnp3/MasterStackConfig.h"
|
||||
#include "asiodnp3/IMasterSession.h"
|
||||
|
||||
#include <memory>
|
||||
|
||||
namespace asiodnp3
|
||||
{
|
||||
|
||||
/**
|
||||
* Callback interface invoked when a new connection is accepted
|
||||
*/
|
||||
class ISessionAcceptor
|
||||
{
|
||||
public:
|
||||
|
||||
virtual ~ISessionAcceptor() {}
|
||||
|
||||
virtual std::shared_ptr<IMasterSession> AcceptSession(
|
||||
const std::string& sessionid,
|
||||
std::shared_ptr<opendnp3::ISOEHandler> SOEHandler,
|
||||
std::shared_ptr<opendnp3::IMasterApplication> application,
|
||||
const MasterStackConfig& config
|
||||
) = 0;
|
||||
};
|
||||
|
||||
}
|
||||
|
||||
#endif
|
||||
@@ -0,0 +1,60 @@
|
||||
/*
|
||||
* Licensed to Green Energy Corp (www.greenenergycorp.com) under one or
|
||||
* more contributor license agreements. See the NOTICE file distributed
|
||||
* with this work for additional information regarding copyright ownership.
|
||||
* Green Energy Corp licenses this file to you under the Apache License,
|
||||
* Version 2.0 (the "License"); you may not use this file except in
|
||||
* compliance with the License. You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*
|
||||
* This project was forked on 01/01/2013 by Automatak, LLC and modifications
|
||||
* may have been made to this file. Automatak, LLC licenses these modifications
|
||||
* to you under the terms of the License.
|
||||
*/
|
||||
#ifndef ASIODNP3_ISTACK_H
|
||||
#define ASIODNP3_ISTACK_H
|
||||
|
||||
#include <opendnp3/StackStatistics.h>
|
||||
|
||||
#include "asiopal/IResourceManager.h"
|
||||
|
||||
namespace asiodnp3
|
||||
{
|
||||
|
||||
/**
|
||||
* Base class for masters or outstations
|
||||
*/
|
||||
class IStack : public asiopal::IResource
|
||||
{
|
||||
public:
|
||||
|
||||
virtual ~IStack() {}
|
||||
|
||||
/**
|
||||
* Synchronously enable communications
|
||||
*/
|
||||
virtual bool Enable() = 0;
|
||||
|
||||
/**
|
||||
* Synchronously disable communications
|
||||
*/
|
||||
virtual bool Disable() = 0;
|
||||
|
||||
/**
|
||||
* @return stack statistics counters
|
||||
*/
|
||||
virtual opendnp3::StackStatistics GetStackStatistics() = 0;
|
||||
|
||||
};
|
||||
|
||||
|
||||
}
|
||||
|
||||
#endif
|
||||
@@ -0,0 +1,48 @@
|
||||
/*
|
||||
* Licensed to Green Energy Corp (www.greenenergycorp.com) under one or
|
||||
* more contributor license agreements. See the NOTICE file distributed
|
||||
* with this work for additional information regarding copyright ownership.
|
||||
* Green Energy Corp licenses this file to you under the Apache License,
|
||||
* Version 2.0 (the "License"); you may not use this file except in
|
||||
* compliance with the License. You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*
|
||||
* This project was forked on 01/01/2013 by Automatak, LLC and modifications
|
||||
* may have been made to this file. Automatak, LLC licenses these modifications
|
||||
* to you under the terms of the License.
|
||||
*/
|
||||
#ifndef ASIODNP3_MASTERSTACKCONFIG_H
|
||||
#define ASIODNP3_MASTERSTACKCONFIG_H
|
||||
|
||||
#include "opendnp3/master/MasterParams.h"
|
||||
#include "opendnp3/link/LinkConfig.h"
|
||||
|
||||
namespace asiodnp3
|
||||
{
|
||||
|
||||
/** A composite configuration struct that contains all the config
|
||||
information for a dnp3 master stack
|
||||
*/
|
||||
struct MasterStackConfig
|
||||
{
|
||||
MasterStackConfig() : link(true, false)
|
||||
{}
|
||||
|
||||
/// Master config
|
||||
opendnp3::MasterParams master;
|
||||
|
||||
/// Link layer config
|
||||
opendnp3::LinkConfig link;
|
||||
};
|
||||
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
@@ -0,0 +1,89 @@
|
||||
/*
|
||||
* Licensed to Green Energy Corp (www.greenenergycorp.com) under one or
|
||||
* more contributor license agreements. See the NOTICE file distributed
|
||||
* with this work for additional information regarding copyright ownership.
|
||||
* Green Energy Corp licenses this file to you under the Apache License,
|
||||
* Version 2.0 (the "License"); you may not use this file except in
|
||||
* compliance with the License. You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*
|
||||
* This project was forked on 01/01/2013 by Automatak, LLC and modifications
|
||||
* may have been made to this file. Automatak, LLC licenses these modifications
|
||||
* to you under the terms of the License.
|
||||
*/
|
||||
#ifndef ASIOPAL_MASTERTCPSERVER_H
|
||||
#define ASIOPAL_MASTERTCPSERVER_H
|
||||
|
||||
#include <openpal/logging/Logger.h>
|
||||
|
||||
#include <asiopal/TCPServer.h>
|
||||
#include <asiopal/ResourceManager.h>
|
||||
#include <asiopal/IListener.h>
|
||||
#include <asiopal/IPEndpoint.h>
|
||||
|
||||
#include "asiodnp3/IListenCallbacks.h"
|
||||
|
||||
namespace asiodnp3
|
||||
{
|
||||
/**
|
||||
* Binds and listens on an IPv4 TCP port
|
||||
*
|
||||
* Meant to be used exclusively as a shared_ptr
|
||||
*/
|
||||
class MasterTCPServer final : public asiopal::TCPServer
|
||||
{
|
||||
|
||||
public:
|
||||
|
||||
MasterTCPServer(
|
||||
const openpal::Logger& logger,
|
||||
const std::shared_ptr<asiopal::Executor>& executor,
|
||||
const asiopal::IPEndpoint& endpoint,
|
||||
const std::shared_ptr<IListenCallbacks>& callbacks,
|
||||
const std::shared_ptr<asiopal::ResourceManager>& manager,
|
||||
std::error_code& ec
|
||||
);
|
||||
|
||||
static std::shared_ptr<MasterTCPServer> Create(
|
||||
const openpal::Logger& logger,
|
||||
const std::shared_ptr<asiopal::Executor>& executor,
|
||||
const asiopal::IPEndpoint& endpoint,
|
||||
const std::shared_ptr<IListenCallbacks>& callbacks,
|
||||
const std::shared_ptr<asiopal::ResourceManager>& manager,
|
||||
std::error_code& ec)
|
||||
{
|
||||
auto server = std::make_shared<MasterTCPServer>(logger, executor, endpoint, callbacks, manager, ec);
|
||||
|
||||
if (!ec)
|
||||
{
|
||||
server->StartAccept();
|
||||
}
|
||||
|
||||
return server;
|
||||
}
|
||||
|
||||
|
||||
private:
|
||||
|
||||
std::shared_ptr<IListenCallbacks> callbacks;
|
||||
std::shared_ptr<asiopal::ResourceManager> manager;
|
||||
|
||||
static std::string SessionIdToString(uint64_t sessionid);
|
||||
|
||||
// implement the virutal methods from TCPServer
|
||||
|
||||
virtual void OnShutdown() override;
|
||||
|
||||
virtual void AcceptConnection(uint64_t sessionid, const std::shared_ptr<asiopal::Executor>& executor, asio::ip::tcp::socket) override;
|
||||
};
|
||||
|
||||
}
|
||||
|
||||
#endif
|
||||
@@ -0,0 +1,63 @@
|
||||
/*
|
||||
* Licensed to Green Energy Corp (www.greenenergycorp.com) under one or
|
||||
* more contributor license agreements. See the NOTICE file distributed
|
||||
* with this work for additional information regarding copyright ownership.
|
||||
* Green Energy Corp licenses this file to you under the Apache License,
|
||||
* Version 2.0 (the "License"); you may not use this file except in
|
||||
* compliance with the License. You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*
|
||||
* This project was forked on 01/01/2013 by Automatak, LLC and modifications
|
||||
* may have been made to this file. Automatak, LLC licenses these modifications
|
||||
* to you under the terms of the License.
|
||||
*/
|
||||
#ifndef OPENDNP3_OUTSTATIONSTACKCONFIG_H
|
||||
#define OPENDNP3_OUTSTATIONSTACKCONFIG_H
|
||||
|
||||
#include "opendnp3/outstation/OutstationConfig.h"
|
||||
#include "opendnp3/outstation/EventBufferConfig.h"
|
||||
#include "opendnp3/outstation/DatabaseSizes.h"
|
||||
#include "asiodnp3/DatabaseConfig.h"
|
||||
#include "opendnp3/link/LinkConfig.h"
|
||||
|
||||
namespace asiodnp3
|
||||
{
|
||||
|
||||
/**
|
||||
A composite configuration struct that contains all the config
|
||||
information for a dnp3 outstation stack
|
||||
*/
|
||||
struct OutstationStackConfig
|
||||
{
|
||||
|
||||
OutstationStackConfig(const opendnp3::DatabaseSizes& dbSizes) :
|
||||
dbConfig(dbSizes),
|
||||
link(false, false)
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
OutstationStackConfig() = delete;
|
||||
|
||||
// Configuration of the database
|
||||
DatabaseConfig dbConfig;
|
||||
|
||||
/// Outstation config
|
||||
opendnp3::OutstationConfig outstation;
|
||||
|
||||
/// Link layer config
|
||||
opendnp3::LinkConfig link;
|
||||
|
||||
};
|
||||
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
@@ -0,0 +1,57 @@
|
||||
/*
|
||||
* Licensed to Green Energy Corp (www.greenenergycorp.com) under one or
|
||||
* more contributor license agreements. See the NOTICE file distributed
|
||||
* with this work for additional information regarding copyright ownership.
|
||||
* Green Energy Corp licenses this file to you under the Apache License,
|
||||
* Version 2.0 (the "License"); you may not use this file except in
|
||||
* compliance with the License. You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*
|
||||
* This project was forked on 01/01/2013 by Automatak, LLC and modifications
|
||||
* may have been made to this file. Automatak, LLC licenses these modifications
|
||||
* to you under the terms of the License.
|
||||
*/
|
||||
#ifndef ASIODNP3_PRINTINGCHANNELLISTENER_H
|
||||
#define ASIODNP3_PRINTINGCHANNELLISTENER_H
|
||||
|
||||
#include "asiodnp3/IChannelListener.h"
|
||||
|
||||
#include "openpal/util/Uncopyable.h"
|
||||
|
||||
#include <iostream>
|
||||
#include <memory>
|
||||
|
||||
namespace asiodnp3
|
||||
{
|
||||
|
||||
/**
|
||||
* Callback interface for receiving information about a running channel
|
||||
*/
|
||||
class PrintingChannelListener final : public IChannelListener, private openpal::Uncopyable
|
||||
{
|
||||
public:
|
||||
|
||||
virtual void OnStateChange(opendnp3::ChannelState state) override
|
||||
{
|
||||
std::cout << "channel state change: " << opendnp3::ChannelStateToString(state) << std::endl;
|
||||
}
|
||||
|
||||
static std::shared_ptr<IChannelListener> Create()
|
||||
{
|
||||
return std::make_shared<PrintingChannelListener>();
|
||||
}
|
||||
|
||||
PrintingChannelListener() {}
|
||||
|
||||
};
|
||||
|
||||
}
|
||||
|
||||
#endif
|
||||
@@ -0,0 +1,41 @@
|
||||
/*
|
||||
* Licensed to Green Energy Corp (www.greenenergycorp.com) under one or
|
||||
* more contributor license agreements. See the NOTICE file distributed
|
||||
* with this work for additional information regarding copyright ownership.
|
||||
* Green Energy Corp licenses this file to you under the Apache License,
|
||||
* Version 2.0 (the "License"); you may not use this file except in
|
||||
* compliance with the License. You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*
|
||||
* This project was forked on 01/01/2013 by Automatak, LLC and modifications
|
||||
* may have been made to this file. Automatak, LLC licenses these modifications
|
||||
* to you under the terms of the License.
|
||||
*/
|
||||
#ifndef ASIODNP3_PRINTINGCOMMANDCALLBACK_H
|
||||
#define ASIODNP3_PRINTINGCOMMANDCALLBACK_H
|
||||
|
||||
#include <opendnp3/master/CommandCallbackT.h>
|
||||
|
||||
#include <openpal/util/Uncopyable.h>
|
||||
|
||||
namespace asiodnp3
|
||||
{
|
||||
|
||||
class PrintingCommandCallback : public openpal::StaticOnly
|
||||
{
|
||||
|
||||
public:
|
||||
static opendnp3::CommandCallbackT Get();
|
||||
|
||||
};
|
||||
|
||||
}
|
||||
|
||||
#endif
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user