First commit. OpenPLC v3 beta 1

This commit is contained in:
thiagoralves 2018-06-14 10:43:51 -07:00
parent cb922e153c
commit 1b10e97e5e
2742 changed files with 568737 additions and 2 deletions

View File

@ -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.

253
install.sh Executable file
View File

@ -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

673
utils/apt-cyg/apt-cyg Normal file
View File

@ -0,0 +1,673 @@
#!/bin/bash
# apt-cyg: install tool for Cygwin similar to debian apt-get
#
# The MIT License (MIT)
#
# Copyright (c) 2013 Trans-code Design
#
# Permission is hereby granted, free of charge, to any person obtaining a copy
# of this software and associated documentation files (the "Software"), to deal
# in the Software without restriction, including without limitation the rights
# to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
# copies of the Software, and to permit persons to whom the Software is
# furnished to do so, subject to the following conditions:
#
# The above copyright notice and this permission notice shall be included in
# all copies or substantial portions of the Software.
#
# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
# AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
# THE SOFTWARE.
if [ ${BASH_VERSINFO}${BASH_VERSINFO[1]} -lt 42 ]
then
echo 'Bash version 4.2+ required'
exit
fi
usage="\
NAME
apt-cyg - package manager utility
SYNOPSIS
apt-cyg [operation] [options] [targets]
DESCRIPTION
apt-cyg is a package management utility that tracks installed packages on a
Cygwin system. Invoking apt-cyg involves specifying an operation with any
potential options and targets to operate on. A target is usually a package
name, file name, URL, or a search string. Targets can be provided as command
line arguments.
OPERATIONS
install
Install package(s).
remove
Remove package(s) from the system.
update
Download a fresh copy of the master package list (setup.ini) from the
server defined in setup.rc.
download
Retrieve package(s) from the server, but do not install/upgrade anything.
show
Display information on given package(s).
depends
Produce a dependency tree for a package.
rdepends
Produce a tree of packages that depend on the named package.
list
Search each locally-installed package for names that match regexp. If no
package names are provided in the command line, all installed packages will
be queried.
listall
This will search each package in the master package list (setup.ini) for
names that match regexp.
category
Display all packages that are members of a named category.
listfiles
List all files owned by a given package. Multiple packages can be specified
on the command line.
search
Search for downloaded packages that own the specified file(s). The path can
be relative or absolute, and one or more files can be specified.
searchall
Search cygwin.com to retrieve file information about packages. The provided
target is considered to be a filename and searchall will return the
package(s) which contain this file.
mirror
Set the mirror; a full URL to a location where the database, packages, and
signatures for this repository can be found. If no URL is provided, display
current mirror.
cache
Set the package cache directory. If a file is not found in cache directory,
it will be downloaded. Unix and Windows forms are accepted, as well as
absolute or regular paths. If no directory is provided, display current
cache.
OPTIONS
--nodeps
Specify this option to skip all dependency checks.
--version
Display version and exit.
"
version="\
apt-cyg version 1
The MIT License (MIT)
Copyright (c) 2005-9 Stephen Jungels
"
function wget {
if command wget -h &>/dev/null
then
command wget "$@"
else
warn wget is not installed, using lynx as fallback
set "${*: -1}"
lynx -source "$1" > "${1##*/}"
fi
}
function find-workspace {
# default working directory and mirror
# work wherever setup worked last, if possible
cache=$(awk '
BEGIN {
RS = "\n\\<"
FS = "\n\t"
}
$1 == "last-cache" {
print $2
}
' /etc/setup/setup.rc)
mirror=$(awk '
/last-mirror/ {
getline
print $1
}
' /etc/setup/setup.rc)
mirrordir=$(sed '
s / %2f g
s : %3a g
' <<< "$mirror")
mkdir -p "$cache/$mirrordir/$arch"
cd "$cache/$mirrordir/$arch"
if [ -e setup.ini ]
then
return 0
else
get-setup
return 1
fi
}
function get-setup {
touch setup.ini
mv setup.ini setup.ini-save
wget -N $mirror/$arch/setup.bz2
if [ -e setup.bz2 ]
then
bunzip2 setup.bz2
mv setup setup.ini
echo Updated setup.ini
else
echo Error updating setup.ini, reverting
mv setup.ini-save setup.ini
fi
}
function check-packages {
if [[ $pks ]]
then
return 0
else
echo No packages found.
return 1
fi
}
function warn {
printf '\e[1;31m%s\e[m\n' "$*" >&2
}
function apt-update {
if find-workspace
then
get-setup
fi
}
function apt-category {
check-packages
find-workspace
for pkg in "${pks[@]}"
do
awk '
$1 == "@" {
pck = $2
}
$1 == "category:" && $0 ~ query {
print pck
}
' query="$pks" setup.ini
done
}
function apt-list {
local sbq
for pkg in "${pks[@]}"
do
let sbq++ && echo
awk 'NR>1 && $1~pkg && $0=$1' pkg="$pkg" /etc/setup/installed.db
done
let sbq && return
awk 'NR>1 && $0=$1' /etc/setup/installed.db
}
function apt-listall {
check-packages
find-workspace
local sbq
for pkg in "${pks[@]}"
do
let sbq++ && echo
awk '$1~pkg && $0=$1' RS='\n\n@ ' FS='\n' pkg="$pkg" setup.ini
done
}
function apt-listfiles {
check-packages
find-workspace
local pkg sbq
for pkg in "${pks[@]}"
do
(( sbq++ )) && echo
if [ ! -e /etc/setup/"$pkg".lst.gz ]
then
download "$pkg"
fi
gzip -cd /etc/setup/"$pkg".lst.gz
done
}
function apt-show {
find-workspace
check-packages
for pkg in "${pks[@]}"
do
(( notfirst++ )) && echo
awk '
$1 == query {
print
fd++
}
END {
if (! fd)
print "Unable to locate package " query
}
' RS='\n\n@ ' FS='\n' query="$pkg" setup.ini
done
}
function apt-depends {
find-workspace
check-packages
for pkg in "${pks[@]}"
do
awk '
@include "join"
$1 == "@" {
apg = $2
}
$1 == "requires:" {
for (z=2; z<=NF; z++)
reqs[apg][z-1] = $z
}
END {
prpg(ENVIRON["pkg"])
}
function smartmatch(small, large, values) {
for (each in large)
values[large[each]]
return small in values
}
function prpg(fpg) {
if (smartmatch(fpg, spath)) return
spath[length(spath)+1] = fpg
print join(spath, 1, length(spath), " > ")
if (isarray(reqs[fpg]))
for (each in reqs[fpg])
prpg(reqs[fpg][each])
delete spath[length(spath)]
}
' setup.ini
done
}
function apt-rdepends {
find-workspace
for pkg in "${pks[@]}"
do
awk '
@include "join"
$1 == "@" {
apg = $2
}
$1 == "requires:" {
for (z=2; z<=NF; z++)
reqs[$z][length(reqs[$z])+1] = apg
}
END {
prpg(ENVIRON["pkg"])
}
function smartmatch(small, large, values) {
for (each in large)
values[large[each]]
return small in values
}
function prpg(fpg) {
if (smartmatch(fpg, spath)) return
spath[length(spath)+1] = fpg
print join(spath, 1, length(spath), " < ")
if (isarray(reqs[fpg]))
for (each in reqs[fpg])
prpg(reqs[fpg][each])
delete spath[length(spath)]
}
' setup.ini
done
}
function apt-download {
check-packages
find-workspace
local pkg sbq
for pkg in "${pks[@]}"
do
(( sbq++ )) && echo
download "$pkg"
done
}
function download {
local pkg digest digactual
pkg=$1
# look for package and save desc file
awk '$1 == pc' RS='\n\n@ ' FS='\n' pc=$pkg setup.ini > desc
if [ ! -s desc ]
then
echo Unable to locate package $pkg
exit 1
fi
# download and unpack the bz2 or xz file
# pick the latest version, which comes first
set -- $(awk '$1 == "install:"' desc)
if (( ! $# ))
then
echo 'Could not find "install" in package description: obsolete package?'
exit 1
fi
dn=$(dirname $2)
bn=$(basename $2)
# check the md5
digest=$4
case ${#digest} in
32) hash=md5sum ;;
128) hash=sha512sum ;;
esac
mkdir -p "$cache/$mirrordir/$dn"
cd "$cache/$mirrordir/$dn"
if ! test -e $bn || ! $hash -c <<< "$digest $bn"
then
wget -O $bn $mirror/$dn/$bn
$hash -c <<< "$digest $bn" || exit
fi
tar tf $bn | gzip > /etc/setup/"$pkg".lst.gz
cd ~-
mv desc "$cache/$mirrordir/$dn"
echo $dn $bn > /tmp/dwn
}
function apt-search {
check-packages
echo Searching downloaded packages...
for pkg in "${pks[@]}"
do
key=$(type -P "$pkg" | sed s./..)
[[ $key ]] || key=$pkg
for manifest in /etc/setup/*.lst.gz
do
if gzip -cd $manifest | grep -q "$key"
then
package=$(sed '
s,/etc/setup/,,
s,.lst.gz,,
' <<< $manifest)
echo $package
fi
done
done
}
function apt-searchall {
cd /tmp
for pkg in "${pks[@]}"
do
printf -v qs 'text=1&arch=%s&grep=%s' $arch "$pkg"
wget -O matches cygwin.com/cgi-bin2/package-grep.cgi?"$qs"
awk '
NR == 1 {next}
mc[$1]++ {next}
/-debuginfo-/ {next}
/^cygwin32-/ {next}
{print $1}
' FS=-[[:digit:]] matches
done
}
function apt-install {
check-packages
find-workspace
local pkg dn bn requires wr package sbq script
for pkg in "${pks[@]}"
do
if grep -q "^$pkg " /etc/setup/installed.db
then
echo Package $pkg is already installed, skipping
continue
fi
(( sbq++ )) && echo
echo Installing $pkg
download $pkg
read dn bn </tmp/dwn
echo Unpacking...
cd "$cache/$mirrordir/$dn"
tar -x -C / -f $bn
# update the package database
awk '
ins != 1 && pkg < $1 {
print pkg, bz, 0
ins = 1
}
1
END {
if (ins != 1) print pkg, bz, 0
}
' pkg="$pkg" bz=$bn /etc/setup/installed.db > /tmp/awk.$$
mv /etc/setup/installed.db /etc/setup/installed.db-save
mv /tmp/awk.$$ /etc/setup/installed.db
[ -v nodeps ] && continue
# recursively install required packages
requires=$(awk '$1=="requires", $0=$2' FS=': ' desc)
cd ~-
wr=0
if [[ $requires ]]
then
echo Package $pkg requires the following packages, installing:
echo $requires
for package in $requires
do
if grep -q "^$package " /etc/setup/installed.db
then
echo Package $package is already installed, skipping
continue
fi
apt-cyg install --noscripts $package || (( wr++ ))
done
fi
if (( wr ))
then
echo some required packages did not install, continuing
fi
# run all postinstall scripts
[ -v noscripts ] && continue
find /etc/postinstall -name '*.sh' | while read script
do
echo Running $script
$script
mv $script $script.done
done
echo Package $pkg installed
done
}
function apt-remove {
check-packages
cd /etc
cygcheck awk bash bunzip2 grep gzip mv sed tar xz > setup/essential.lst
for pkg in "${pks[@]}"
do
if ! grep -q "^$pkg " setup/installed.db
then
echo Package $pkg is not installed, skipping
continue
fi
if [ ! -e setup/"$pkg".lst.gz ]
then
warn Package manifest missing, cannot remove $pkg. Exiting
exit 1
fi
gzip -dk setup/"$pkg".lst.gz
awk '
NR == FNR {
if ($NF) ess[$NF]
next
}
$NF in ess {
exit 1
}
' FS='[/\\\\]' setup/{essential,$pkg}.lst
esn=$?
if [ $esn = 0 ]
then
echo Removing $pkg
if [ -e preremove/"$pkg".sh ]
then
preremove/"$pkg".sh
rm preremove/"$pkg".sh
fi
mapfile dt < setup/"$pkg".lst
for each in ${dt[*]}
do
[ -f /$each ] && rm /$each
done
for each in ${dt[*]}
do
[ -d /$each ] && rmdir --i /$each
done
rm -f setup/"$pkg".lst.gz postinstall/"$pkg".sh.done
awk -i inplace '$1 != ENVIRON["pkg"]' setup/installed.db
echo Package $pkg removed
fi
rm setup/"$pkg".lst
if [ $esn = 1 ]
then
warn apt-cyg cannot remove package $pkg, exiting
exit 1
fi
done
}
function apt-mirror {
if [ "$pks" ]
then
awk -i inplace '
1
/last-mirror/ {
getline
print "\t" pks
}
' pks="$pks" /etc/setup/setup.rc
echo Mirror set to "$pks".
else
awk '
/last-mirror/ {
getline
print $1
}
' /etc/setup/setup.rc
fi
}
function apt-cache {
if [ "$pks" ]
then
vas=$(cygpath -aw "$pks")
awk -i inplace '
1
/last-cache/ {
getline
print "\t" vas
}
' vas="${vas//\\/\\\\}" /etc/setup/setup.rc
echo Cache set to "$vas".
else
awk '
/last-cache/ {
getline
print $1
}
' /etc/setup/setup.rc
fi
}
if [ -p /dev/stdin ]
then
mapfile -t pks
fi
# process options
until [ $# = 0 ]
do
case "$1" in
--nodeps)
nodeps=1
shift
;;
--noscripts)
noscripts=1
shift
;;
--version)
printf "$version"
exit
;;
update)
command=$1
shift
;;
list | cache | remove | depends | listall | download | listfiles |\
show | mirror | search | install | category | rdepends | searchall )
if [[ $command ]]
then
pks+=("$1")
else
command=$1
fi
shift
;;
*)
pks+=("$1")
shift
;;
esac
done
set -a
if type -t apt-$command | grep -q function
then
readonly arch=${HOSTTYPE/i6/x}
apt-$command
else
printf "$usage"
fi

BIN
utils/apt-cyg/wget.exe Executable file

Binary file not shown.

View File

@ -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.

View File

@ -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
)

19
utils/dnp3_src/NOTICE Normal file
View File

@ -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

31
utils/dnp3_src/README.md Executable file
View File

@ -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

View File

@ -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

View File

@ -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

View File

@ -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()

View File

@ -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()

View File

@ -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})

View File

@ -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.

View File

@ -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

View File

@ -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 {}

View File

@ -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>

View File

@ -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.
//

View File

@ -0,0 +1,2 @@
/* vim: set ts=4 sw=4: */

View File

@ -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.
*/

View File

@ -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;
}

View File

@ -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;
}

View File

@ -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;
}

View File

@ -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;
}
}
}

View File

@ -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;
}

View File

@ -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;
}

View File

@ -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;
}
}
}

View File

@ -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

View File

@ -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

View File

@ -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

View File

@ -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

View File

@ -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

View File

@ -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

View File

@ -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

View File

@ -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

View File

@ -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

View File

@ -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

View File

@ -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

View File

@ -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

View File

@ -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

View File

@ -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

View File

@ -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

View File

@ -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

View File

@ -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

View File

@ -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

View File

@ -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

View File

@ -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

View File

@ -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

View File

@ -0,0 +1,126 @@
/*
* 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_PRINTINGSOEHANDLER_H
#define ASIODNP3_PRINTINGSOEHANDLER_H
#include <opendnp3/master/ISOEHandler.h>
#include <iostream>
#include <sstream>
#include <memory>
namespace asiodnp3
{
/**
* ISOEHandler singleton that prints to the console.
*/
class PrintingSOEHandler final : public opendnp3::ISOEHandler
{
public:
PrintingSOEHandler()
{}
static std::shared_ptr<ISOEHandler> Create()
{
return std::make_shared<PrintingSOEHandler>();
}
virtual void Process(const opendnp3::HeaderInfo& info, const opendnp3::ICollection<opendnp3::Indexed<opendnp3::Binary>>& values) override;
virtual void Process(const opendnp3::HeaderInfo& info, const opendnp3::ICollection<opendnp3::Indexed<opendnp3::DoubleBitBinary>>& values) override;
virtual void Process(const opendnp3::HeaderInfo& info, const opendnp3::ICollection<opendnp3::Indexed<opendnp3::Analog>>& values) override;
virtual void Process(const opendnp3::HeaderInfo& info, const opendnp3::ICollection<opendnp3::Indexed<opendnp3::Counter>>& values) override;
virtual void Process(const opendnp3::HeaderInfo& info, const opendnp3::ICollection<opendnp3::Indexed<opendnp3::FrozenCounter>>& values) override;
virtual void Process(const opendnp3::HeaderInfo& info, const opendnp3::ICollection<opendnp3::Indexed<opendnp3::BinaryOutputStatus>>& values) override;
virtual void Process(const opendnp3::HeaderInfo& info, const opendnp3::ICollection<opendnp3::Indexed<opendnp3::AnalogOutputStatus>>& values) override;
virtual void Process(const opendnp3::HeaderInfo& info, const opendnp3::ICollection<opendnp3::Indexed<opendnp3::OctetString>>& values) override;
virtual void Process(const opendnp3::HeaderInfo& info, const opendnp3::ICollection<opendnp3::Indexed<opendnp3::TimeAndInterval>>& values) override;
virtual void Process(const opendnp3::HeaderInfo& info, const opendnp3::ICollection<opendnp3::Indexed<opendnp3::BinaryCommandEvent>>& values) override;
virtual void Process(const opendnp3::HeaderInfo& info, const opendnp3::ICollection<opendnp3::Indexed<opendnp3::AnalogCommandEvent>>& values) override;
virtual void Process(const opendnp3::HeaderInfo& info, const opendnp3::ICollection<opendnp3::Indexed<opendnp3::SecurityStat>>& values) override;
virtual void Process(const opendnp3::HeaderInfo& info, const opendnp3::ICollection<opendnp3::DNPTime>& values) override;
protected:
void Start() final {}
void End() final {}
private:
template <class T>
static void PrintAll(const opendnp3::HeaderInfo& info, const opendnp3::ICollection<opendnp3::Indexed<T>>& values)
{
auto print = [&](const opendnp3::Indexed<T>& pair)
{
Print<T>(info, pair.value, pair.index);
};
values.ForeachItem(print);
}
template <class T>
static void Print(const opendnp3::HeaderInfo& info, const T& value, uint16_t index)
{
std::cout << "[" << index << "] : " <<
ValueToString(value) << " : " <<
static_cast<int>(value.flags.value) << " : " <<
value.time << std::endl;
}
template <class T>
static std::string ValueToString(const T& meas)
{
std::ostringstream oss;
oss << meas.value;
return oss.str();
}
static std::string GetTimeString(opendnp3::TimestampMode tsmode)
{
std::ostringstream oss;
switch (tsmode)
{
case(opendnp3::TimestampMode::SYNCHRONIZED) :
return "synchronized";
break;
case(opendnp3::TimestampMode::UNSYNCHRONIZED) :
oss << "unsynchronized";
break;
default:
oss << "no timestamp";
break;
}
return oss.str();
}
static std::string ValueToString(const opendnp3::DoubleBitBinary& meas)
{
return opendnp3::DoubleBitToString(meas.value);
}
};
}
#endif

View File

@ -0,0 +1,58 @@
/*
* 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_UPDATEBUILDER_H
#define ASIODNP3_UPDATEBUILDER_H
#include "asiodnp3/Updates.h"
namespace asiodnp3
{
class UpdateBuilder
{
public:
UpdateBuilder& Update(const opendnp3::Binary& meas, uint16_t index, opendnp3::EventMode mode = opendnp3::EventMode::Detect);
UpdateBuilder& Update(const opendnp3::DoubleBitBinary& meas, uint16_t index, opendnp3::EventMode mode = opendnp3::EventMode::Detect);
UpdateBuilder& Update(const opendnp3::Analog& meas, uint16_t index, opendnp3::EventMode mode = opendnp3::EventMode::Detect);
UpdateBuilder& Update(const opendnp3::Counter& meas, uint16_t index, opendnp3::EventMode mode = opendnp3::EventMode::Detect);
UpdateBuilder& Update(const opendnp3::FrozenCounter& meas, uint16_t index, opendnp3::EventMode mode = opendnp3::EventMode::Detect);
UpdateBuilder& Update(const opendnp3::BinaryOutputStatus& meas, uint16_t index, opendnp3::EventMode mode = opendnp3::EventMode::Detect);
UpdateBuilder& Update(const opendnp3::AnalogOutputStatus& meas, uint16_t index, opendnp3::EventMode mode = opendnp3::EventMode::Detect);
UpdateBuilder& Update(const opendnp3::TimeAndInterval& meas, uint16_t index);
UpdateBuilder& Modify(opendnp3::FlagsType type, uint16_t start, uint16_t stop, uint8_t flags);
Updates Build() const;
private:
template <class T>
UpdateBuilder& AddMeas(const T& meas, uint16_t index, opendnp3::EventMode mode);
void Add(const update_func_t& fun);
std::shared_ptr<shared_updates_t> updates;
};
}
#endif

View File

@ -0,0 +1,66 @@
/*
* 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_UPDATES_H
#define ASIODNP3_UPDATES_H
#include <vector>
#include <memory>
#include <functional>
#include "opendnp3/outstation/IUpdateHandler.h"
namespace asiodnp3
{
typedef std::function<void(opendnp3::IUpdateHandler&)> update_func_t;
typedef std::vector<update_func_t> shared_updates_t;
class Updates
{
friend class UpdateBuilder;
public:
void Apply(opendnp3::IUpdateHandler& handler) const
{
if (!updates) return;
for(auto& update : *updates)
{
update(handler);
}
}
bool IsEmpty() const
{
return updates ? updates->empty() : true;
}
private:
Updates(const std::shared_ptr<shared_updates_t>& updates) : updates(updates) {}
const std::shared_ptr<shared_updates_t> updates;
};
}
#endif

View File

@ -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_X509_INFO_H
#define ASIODNP3_X509_INFO_H
#include <openpal/container/RSlice.h>
#include <openpal/util/Uncopyable.h>
#include <string>
namespace asiodnp3
{
/**
* Select information from a preverified x509 certificate
* that user can can inspect an optionally reject
*/
class X509Info : private openpal::Uncopyable
{
public:
X509Info(int depth_, const openpal::RSlice sha1thumbprint_, std::string subjectName_) :
depth(depth_),
sha1thumbprint(sha1thumbprint_),
subjectName(subjectName_)
{}
// the depth of the certificate in the chain
int depth;
// the sha1 thumbprint
openpal::RSlice sha1thumbprint;
// the extracted subject name
std::string subjectName;
private:
X509Info();
};
}
#endif

View File

@ -0,0 +1,37 @@
/*
* 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_ASIOSERIALHELPERS_H
#define ASIOPAL_ASIOSERIALHELPERS_H
#include <asio.hpp>
#include <asio/basic_serial_port.hpp>
#include "SerialTypes.h"
namespace asiopal
{
// Serial port configuration functions "free" to keep the classes simple.
bool Configure(const SerialSettings& settings, asio::serial_port& port, std::error_code& ec);
}
#endif

View File

@ -0,0 +1,72 @@
/*
* 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_CHANNEL_RETRY_H
#define OPENDNP3_CHANNEL_RETRY_H
#include <openpal/executor/TimeDuration.h>
#include "asiopal/IOpenDelayStrategy.h"
namespace asiopal
{
/// Class used to configure how channel failures are retried
class ChannelRetry
{
public:
/*
* Construct a channel retry config class
*
* @param minOpenRetry minimum connection retry interval on failure
* @param maxOpenRetry maximum connection retry interval on failure
*/
ChannelRetry(
openpal::TimeDuration minOpenRetry,
openpal::TimeDuration maxOpenRetry,
IOpenDelayStrategy& strategy = ExponentialBackoffStrategy::Instance()
);
/// Return the default configuration of exponential backoff from 1 sec to 1 minute
static ChannelRetry Default();
/// minimum connection retry interval on failure
openpal::TimeDuration minOpenRetry;
/// maximum connection retry interval on failure
openpal::TimeDuration maxOpenRetry;
openpal::TimeDuration NextDelay(const openpal::TimeDuration& current) const
{
return strategy.GetNextDelay(current, maxOpenRetry);
}
private:
//// Strategy to use (default to exponential backoff)
IOpenDelayStrategy& strategy;
};
}
#endif

View File

@ -0,0 +1,120 @@
/*
* 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_EXECUTOR_H
#define ASIOPAL_EXECUTOR_H
#include <openpal/executor/IExecutor.h>
#include <openpal/util/Uncopyable.h>
#include "asiopal/IO.h"
#include "asiopal/SteadyClock.h"
#include <future>
namespace asiopal
{
/**
*
* Implementation of openpal::IExecutor backed by asio::strand
*
* Shutdown life-cycle guarantees are provided by using std::shared_ptr
*
*/
class Executor final :
public openpal::IExecutor,
public std::enable_shared_from_this<Executor>,
private openpal::Uncopyable
{
public:
Executor(const std::shared_ptr<IO>& io);
static std::shared_ptr<Executor> Create(const std::shared_ptr<IO>& io)
{
return std::make_shared<Executor>(io);
}
/// ---- Implement IExecutor -----
virtual openpal::MonotonicTimestamp GetTime() override;
virtual openpal::ITimer* Start(const openpal::TimeDuration&, const openpal::action_t& runnable) override;
virtual openpal::ITimer* Start(const openpal::MonotonicTimestamp&, const openpal::action_t& runnable) override;
virtual void Post(const openpal::action_t& runnable) override;
template <class T>
T ReturnFrom(const std::function<T()>& action);
void BlockUntil(const std::function<void ()>& action);
void BlockUntilAndFlush(const std::function<void()>& action);
private:
// we hold a shared_ptr to the pool so that it cannot dissapear while the strand is still executing
std::shared_ptr<IO> io;
public:
// Create a new Executor that shares the underling std::shared_ptr<IO>
std::shared_ptr<Executor> Fork() const
{
return Create(this->io);
}
asio::strand strand;
private:
openpal::ITimer* Start(const steady_clock_t::time_point& expiration, const openpal::action_t& runnable);
};
template <class T>
T Executor::ReturnFrom(const std::function<T()>& action)
{
if (strand.running_in_this_thread())
{
return action();
}
std::promise<T> ready;
auto future = ready.get_future();
auto run = [&]
{
ready.set_value(action());
};
strand.post(run);
future.wait();
return future.get();
}
}
#endif

View File

@ -0,0 +1,168 @@
/*
* 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_IASYNCCHANNEL_H
#define ASIOPAL_IASYNCCHANNEL_H
#include <openpal/container/WSlice.h>
#include <openpal/container/RSlice.h>
#include <openpal/util/Uncopyable.h>
#include "asiopal/Executor.h"
#include "asiopal/IChannelCallbacks.h"
#include <functional>
#include <memory>
namespace asiopal
{
class IAsyncChannel : public std::enable_shared_from_this<IAsyncChannel>, private openpal::Uncopyable
{
public:
IAsyncChannel(const std::shared_ptr<Executor>& executor) : executor(executor)
{}
virtual ~IAsyncChannel() {}
void SetCallbacks(const std::shared_ptr<IChannelCallbacks>& callbacks)
{
assert(callbacks);
this->callbacks = callbacks;
}
inline bool BeginRead(const openpal::WSlice& buffer)
{
assert(callbacks);
if (this->CanRead())
{
this->reading = true;
this->BeginReadImpl(buffer);
return true;
}
else
{
return false;
}
}
inline bool BeginWrite(const openpal::RSlice& buffer)
{
assert(callbacks);
if (this->CanWrite())
{
this->writing = true;
this->BeginWriteImpl(buffer);
return true;
}
else
{
return false;
}
}
inline bool Shutdown()
{
if (this->is_shutting_down) return false;
this->is_shutting_down = true;
this->ShutdownImpl();
// keep the channel alive until it's not reading or writing
auto action = [self = shared_from_this()]()
{
self->CheckForShutdown(self);
};
this->executor->strand.post(action);
return true;
}
inline bool CanRead() const
{
return callbacks && !is_shutting_down && !reading;
}
inline bool CanWrite() const
{
return callbacks && !is_shutting_down && !writing;
}
const std::shared_ptr<Executor> executor;
protected:
inline void OnReadCallback(const std::error_code& ec, size_t num)
{
this->reading = false;
if (this->callbacks && !is_shutting_down)
{
this->callbacks->OnReadComplete(ec, num);
}
}
inline void OnWriteCallback(const std::error_code& ec, size_t num)
{
this->writing = false;
if (this->callbacks && !is_shutting_down)
{
this->callbacks->OnWriteComplete(ec, num);
}
}
private:
void CheckForShutdown(std::shared_ptr<IAsyncChannel> self)
{
if (self->reading || self->writing)
{
auto action = [self]()
{
self->CheckForShutdown(self);
};
self->executor->strand.post(action);
}
else
{
self->callbacks.reset(); // drop the callbacks
}
}
std::shared_ptr<IChannelCallbacks> callbacks;
bool is_shutting_down = false;
bool reading = false;
bool writing = false;
virtual void BeginReadImpl(openpal::WSlice buffer) = 0;
virtual void BeginWriteImpl(const openpal::RSlice& buffer) = 0;
virtual void ShutdownImpl() = 0;
};
}
#endif

View File

@ -0,0 +1,40 @@
/*
* 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_ICHANNELCALLBACKS_H
#define ASIOPAL_ICHANNELCALLBACKS_H
#include <system_error>
namespace asiopal
{
struct IChannelCallbacks
{
virtual ~IChannelCallbacks() {};
virtual void OnReadComplete(const std::error_code& ec, size_t num) = 0;
virtual void OnWriteComplete(const std::error_code& ec, size_t num) = 0;
};
}
#endif

View File

@ -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 ASIOPAL_ILISTENER_H
#define ASIOPAL_ILISTENER_H
#include "asiopal/IResourceManager.h"
namespace asiopal
{
/**
* Represents a running TCP or TLS listener that can be shutdown
* so that no new connections are accepted.
*/
class IListener : public IResource
{
public:
virtual ~IListener() {}
};
}
#endif

View File

@ -0,0 +1,46 @@
/*
* 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_IO_H
#define ASIOPAL_IO_H
#include <asio.hpp>
namespace asiopal
{
/**
* Container class for an asio::io_service
*/
class IO
{
public:
virtual ~IO() {}
asio::io_service service;
};
}
#endif

View File

@ -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 ASIOPAL_IOPENDELAYSTRATEGY_H
#define ASIOPAL_IOPENDELAYSTRATEGY_H
#include <openpal/executor/TimeDuration.h>
#include <openpal/util/Uncopyable.h>
namespace asiopal
{
/**
* A strategy interface for controlling how connection are retried
*/
class IOpenDelayStrategy
{
public:
virtual ~IOpenDelayStrategy() {}
/**
* The the next delay based on the current and the maximum.
*/
virtual openpal::TimeDuration GetNextDelay(const openpal::TimeDuration& current, const openpal::TimeDuration& max) const = 0;
};
/**
* Implements IOpenDelayStrategy using exponential-backoff.
*/
class ExponentialBackoffStrategy : public IOpenDelayStrategy, private openpal::Uncopyable
{
static ExponentialBackoffStrategy instance;
public:
static IOpenDelayStrategy& Instance();
virtual openpal::TimeDuration GetNextDelay(const openpal::TimeDuration& current, const openpal::TimeDuration& max) const override final;
};
}
#endif

View File

@ -0,0 +1,55 @@
/*
* 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_IPENDPOINT_H
#define ASIOPAL_IPENDPOINT_H
#include <string>
#include <cstdint>
namespace asiopal
{
class IPEndpoint
{
public:
IPEndpoint(const std::string& address, uint16_t port) :
address(address),
port(port)
{}
static IPEndpoint AllAdapters(uint16_t port)
{
return IPEndpoint("0.0.0.0", port);
}
static IPEndpoint Localhost(uint16_t port)
{
return IPEndpoint("127.0.0.1", port);
}
std::string address;
uint16_t port;
};
}
#endif

View File

@ -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 ASIOPAL_IRESOURCEMANAGER_H
#define ASIOPAL_IRESOURCEMANAGER_H
#include <memory>
namespace asiopal
{
/**
* Anything that can be shutdown
*/
struct IResource
{
public:
virtual ~IResource() {}
virtual void Shutdown() = 0;
};
struct IResourceManager
{
public:
virtual ~IResourceManager() {}
/// notify the handler that the resource is shutting down, and it doesn't
/// have to track it anymore
virtual void Detach(const std::shared_ptr<IResource>& resource) = 0;
};
}
#endif

View File

@ -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 ASIOPAL_LOGGING_CONNECTION_CONDITION_H
#define ASIOPAL_LOGGING_CONNECTION_CONDITION_H
#include <openpal/logging/Logger.h>
#include <openpal/logging/LogMacros.h>
#include <openpal/logging/LogLevels.h>
namespace asiopal
{
class LoggingConnectionCondition
{
public:
LoggingConnectionCondition(openpal::Logger logger) : logger(logger)
{}
template <typename Iterator>
Iterator operator()(const std::error_code& ec, Iterator next)
{
if (ec)
{
FORMAT_LOG_BLOCK(logger, openpal::logflags::WARN, "connection error: %s", ec.message().c_str());
}
return next;
}
private:
openpal::Logger logger;
};
}
#endif

View File

@ -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.
*/
#ifndef ASIOPAL_RESOURCEMANAGER_H
#define ASIOPAL_RESOURCEMANAGER_H
#include "IResourceManager.h"
#include <set>
#include <mutex>
#include <memory>
namespace asiopal
{
class ResourceManager final : public IResourceManager
{
public:
static std::shared_ptr<ResourceManager> Create()
{
return std::make_shared<ResourceManager>();
}
virtual void Detach(const std::shared_ptr<IResource>& resource) override;
void Shutdown();
template <class R, class T>
std::shared_ptr<R> Bind(const T& create)
{
std::lock_guard <std::mutex> lock(this->mutex);
if (this->is_shutting_down)
{
return nullptr;
}
else
{
auto item = create();
if (item)
{
this->resources.insert(item);
}
return item;
}
}
private:
std::mutex mutex;
bool is_shutting_down = false;
std::set<std::shared_ptr<asiopal::IResource>> resources;
};
}
#endif

View File

@ -0,0 +1,59 @@
/*
* 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_SERIALCHANNEL_H
#define ASIOPAL_SERIALCHANNEL_H
#include "IAsyncChannel.h"
#include "asiopal/SerialTypes.h"
#include <asio/serial_port.hpp>
namespace asiopal
{
class SerialChannel final : public IAsyncChannel
{
public:
static std::shared_ptr<SerialChannel> Create(std::shared_ptr<Executor> executor)
{
return std::make_shared<SerialChannel>(executor);
}
SerialChannel(std::shared_ptr<Executor> executor);
bool Open(const SerialSettings& settings, std::error_code& ec);
private:
virtual void BeginReadImpl(openpal::WSlice buffer) override;
virtual void BeginWriteImpl(const openpal::RSlice& buffer) override;
virtual void ShutdownImpl() override;
asio::basic_serial_port<> port;
};
}
#endif

View File

@ -0,0 +1,74 @@
/*
* 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_SERIALTYPES_H
#define ASIOPAL_SERIALTYPES_H
#include "openpal/executor/TimeDuration.h"
#include "opendnp3/gen/Parity.h"
#include "opendnp3/gen/FlowControl.h"
#include "opendnp3/gen/StopBits.h"
#include <string>
namespace asiopal
{
/// Settings structure for the serial port
struct SerialSettings
{
/// Defaults to the familiar 9600 8/N/1, no flow control
SerialSettings() :
baud(9600),
dataBits(8),
stopBits(opendnp3::StopBits::One),
parity(opendnp3::Parity::None),
flowType(opendnp3::FlowControl::None),
asyncOpenDelay(openpal::TimeDuration::Milliseconds(500))
{}
/// name of the port, i.e. "COM1" or "/dev/tty0"
std::string deviceName;
/// Baud rate of the port, i.e. 9600 or 57600
int baud;
/// Data bits, usually 8
int dataBits;
/// Stop bits, usually set to 1
opendnp3::StopBits stopBits;
/// Parity setting for the port, usually PAR_NONE
opendnp3::Parity parity;
/// Flow control setting, usually FLOW_NONE
opendnp3::FlowControl flowType;
/// Some physical layers need time to "settle" so that the first tx isn't lost
openpal::TimeDuration asyncOpenDelay;
};
}
#endif

View File

@ -0,0 +1,55 @@
/*
* 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_SOCKETCHANNEL_H
#define ASIOPAL_SOCKETCHANNEL_H
#include "IAsyncChannel.h"
namespace asiopal
{
class SocketChannel final : public IAsyncChannel
{
public:
static std::shared_ptr<IAsyncChannel> Create(std::shared_ptr<Executor> executor, asio::ip::tcp::socket socket)
{
return std::make_shared<SocketChannel>(executor, std::move(socket));
}
SocketChannel(std::shared_ptr<Executor> executor, asio::ip::tcp::socket socket);
protected:
virtual void BeginReadImpl(openpal::WSlice buffer) override;
virtual void BeginWriteImpl(const openpal::RSlice& buffer) override;
virtual void ShutdownImpl() override;
private:
asio::ip::tcp::socket socket;
};
}
#endif

View File

@ -0,0 +1,59 @@
/*
* 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_SOCKET_HELPERS_H
#define ASIOPAL_SOCKET_HELPERS_H
#include <openpal/util/Uncopyable.h>
#include <system_error>
#include <asio.hpp>
namespace asiopal
{
class SocketHelpers : private openpal::StaticOnly
{
public:
/**
* Bind a socket object to a local endpoint given an address. If the address is empty, 0.0.0.0 is used
*/
template <class SocketType>
static void BindToLocalAddress(const std::string& address, asio::ip::tcp::endpoint& endpoint, SocketType& socket, std::error_code& ec)
{
auto string = address.empty() ? "0.0.0.0" : address;
auto addr = asio::ip::address::from_string(string, ec);
if (!ec)
{
endpoint.address(addr);
socket.open(asio::ip::tcp::v4(), ec);
if (!ec)
{
socket.bind(endpoint, ec);
}
}
}
};
}
#endif

View File

@ -0,0 +1,82 @@
/*
* 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_STEADYCLOCK_H
#define ASIOPAL_STEADYCLOCK_H
#include <chrono>
namespace asiopal
{
#if (defined WIN32 && (_MSC_VER < 1900)) // Windows with VS eariler than 2015, e.g. 2013
#include <Windows.h>
/*
Custom steady clock implementation to handle the situation where the Windows steady clock
implementation is not monotonic. Normal steady clock implementation is used on other platforms.
*/
struct SteadyClockWindows
{
// Type defininitions for this clock - ticks are in nanoseconds for this clock
typedef LONGLONG representation;
typedef std::ratio_multiply<std::ratio<1, 1>, std::nano> period;
typedef std::chrono::duration<representation, period> duration;
typedef std::chrono::time_point<SteadyClockWindows, duration> time_point;
static time_point now()
{
// Special case for WIN32 because std::chrono::steady_clock is broken
LARGE_INTEGER freq;
LONGLONG nanoSecondsPerTick = 0;
if (QueryPerformanceFrequency(&freq))
{
nanoSecondsPerTick = LONGLONG(1000000000.0L / freq.QuadPart);
}
LARGE_INTEGER performanceCount;
if (nanoSecondsPerTick <= 0 || !QueryPerformanceCounter(&performanceCount))
{
// Error condition, return 0 time
return time_point();
}
// Return time in nanoseconds
LONGLONG timeNanos = performanceCount.QuadPart * nanoSecondsPerTick;
return time_point(duration(timeNanos));
}
};
// use this custom steady clock
typedef SteadyClockWindows steady_clock_t;
#else
// In all other situations use the normal steady clock
typedef std::chrono::steady_clock steady_clock_t;
#endif
}
#endif

View File

@ -0,0 +1,78 @@
/*
* 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_SYNCHRONIZED_H
#define ASIOPAL_SYNCHRONIZED_H
#include <asio.hpp>
#include <mutex>
#include <condition_variable>
namespace asiopal
{
/**
* Provides thread-safe access to a value that can be set once.
*/
template <class T>
class Synchronized
{
public:
Synchronized() : value(), isSet(false)
{}
T WaitForValue()
{
std::unique_lock<std::mutex> lock(mutex);
while (!isSet)
{
auto complete = [this]()
{
return isSet;
};
condition.wait(lock, complete);
}
return value;
}
void SetValue(T value_)
{
std::unique_lock<std::mutex> lock(mutex);
this->value = value_;
isSet = true;
condition.notify_all();
}
private:
T value;
bool isSet;
std::mutex mutex;
std::condition_variable condition;
};
}
#endif

View File

@ -0,0 +1,84 @@
/*
* 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_TCPCLIENT_H
#define ASIOPAL_TCPCLIENT_H
#include "asiopal/Executor.h"
#include "asiopal/IPEndpoint.h"
#include "asiopal/LoggingConnectionCondition.h"
namespace asiopal
{
class TCPClient final : public std::enable_shared_from_this<TCPClient>, private openpal::Uncopyable
{
public:
typedef std::function<void(const std::shared_ptr<Executor>& executor, asio::ip::tcp::socket, const std::error_code& ec)> connect_callback_t;
static std::shared_ptr<TCPClient> Create(
const openpal::Logger& logger,
const std::shared_ptr<Executor>& executor,
const IPEndpoint& remote,
const std::string& adapter)
{
return std::make_shared<TCPClient>(logger, executor, remote, adapter);
}
TCPClient(
const openpal::Logger& logger,
const std::shared_ptr<Executor>& executor,
const IPEndpoint& remote,
const std::string& adapter
);
bool Cancel();
bool BeginConnect(const connect_callback_t& callback);
private:
void HandleResolveResult(
const connect_callback_t& callback,
const asio::ip::tcp::resolver::iterator& endpoints,
const std::error_code& ec
);
bool PostConnectError(const connect_callback_t& callback, const std::error_code& ec);
bool connecting = false;
bool canceled = false;
LoggingConnectionCondition condition;
const std::shared_ptr<Executor> executor;
const std::string host;
const std::string adapter;
asio::ip::tcp::socket socket;
asio::ip::tcp::endpoint remoteEndpoint;
asio::ip::tcp::endpoint localEndpoint;
asio::ip::tcp::resolver resolver;
};
}
#endif

View File

@ -0,0 +1,86 @@
/*
* 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_TCPSERVER_H
#define ASIOPAL_TCPSERVER_H
#include "asiopal/IPEndpoint.h"
#include "asiopal/Executor.h"
#include "asiopal/IListener.h"
#include <openpal/util/Uncopyable.h>
#include <openpal/logging/Logger.h>
#include <memory>
namespace asiopal
{
/**
* Binds and listens on an IPv4 TCP port
*
* Meant to be used exclusively as a shared_ptr
*/
class TCPServer :
public std::enable_shared_from_this<TCPServer>,
public IListener,
private openpal::Uncopyable
{
public:
TCPServer(
const openpal::Logger& logger,
const std::shared_ptr<Executor>& executor,
const IPEndpoint& endpoint,
std::error_code& ec
);
/// Implement IListener
void Shutdown() override final;
protected:
/// Inherited classes must define these functions
virtual void OnShutdown() = 0;
virtual void AcceptConnection(uint64_t sessionid, const std::shared_ptr<Executor>& executor, asio::ip::tcp::socket) = 0;
/// Start asynchronously accepting connections on the strand
void StartAccept();
openpal::Logger logger;
std::shared_ptr<Executor> executor;
private:
void Configure(const std::string& adapter, std::error_code& ec);
asio::ip::tcp::endpoint endpoint;
asio::ip::tcp::acceptor acceptor;
asio::ip::tcp::socket socket;
asio::ip::tcp::endpoint remote_endpoint;
uint64_t session_id = 0;
};
}
#endif

View File

@ -0,0 +1,98 @@
/*
* 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_TLS_CONFIG_H
#define ASIOPAL_TLS_CONFIG_H
#include <string>
namespace asiopal
{
/**
* TLS configuration information
*/
struct TLSConfig
{
/**
* Construct a TLS configuration
*
* @param peerCertFilePath Certificate file used to verify the peer or server. Can be CA file or a self-signed cert provided by other party.
* @param localCertFilePath File that contains the certificate (or certificate chain) that will be presented to the remote side of the connection
* @param privateKeyFilePath File that contains the private key corresponding to the local certificate
* @param maxVerifyDepth The maximum certificate chain verification depth (0 == self-signed only)
* @param allowTLSv10 Allow TLS version 1.0 (default false)
* @param allowTLSv11 Allow TLS version 1.1 (default false)
* @param allowTLSv12 Allow TLS version 1.2 (default true)
* @param cipherList The openssl cipher-list, defaults to "" which does not modify the default cipher list
*
* localCertFilePath and privateKeyFilePath can optionally be the same file, i.e. a PEM that contains both pieces of data.
*
*/
TLSConfig(
const std::string& peerCertFilePath,
const std::string& localCertFilePath,
const std::string& privateKeyFilePath,
int maxVerifyDepth = 0,
bool allowTLSv10 = false,
bool allowTLSv11 = false,
bool allowTLSv12 = true,
const std::string& cipherList = ""
) :
peerCertFilePath(peerCertFilePath),
localCertFilePath(localCertFilePath),
privateKeyFilePath(privateKeyFilePath),
maxVerifyDepth(maxVerifyDepth),
allowTLSv10(allowTLSv10),
allowTLSv11(allowTLSv11),
allowTLSv12(allowTLSv12),
cipherList(cipherList)
{}
/// Certificate file used to verify the peer or server. Can be CA file or a self-signed cert provided by other party.
std::string peerCertFilePath;
/// File that contains the certificate (or certificate chain) that will be presented to the remote side of the connection
std::string localCertFilePath;
/// File that contains the private key corresponding to the local certificate
std::string privateKeyFilePath;
/// max verification depth (defaults to 0 - peer certificate only)
int maxVerifyDepth;
/// Allow TLS version 1.0 (default false)
bool allowTLSv10;
/// Allow TLS version 1.1 (default false)
bool allowTLSv11;
/// Allow TLS version 1.2 (default true)
bool allowTLSv12;
/// openssl format cipher list
std::string cipherList;
};
}
#endif

View File

@ -0,0 +1,81 @@
/*
* 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_THREADPOOL_H
#define ASIOPAL_THREADPOOL_H
#include <openpal/logging/Logger.h>
#include "asiopal/SteadyClock.h"
#include "asiopal/Executor.h"
#include <functional>
#include <thread>
#include <memory>
namespace asiopal
{
/**
* A thread pool that calls asio::io_service::run
*/
class ThreadPool
{
public:
friend class ThreadPoolTest;
ThreadPool(
const openpal::Logger& logger,
const std::shared_ptr<IO>& io,
uint32_t concurrency,
std::function<void()> onThreadStart = []() {},
std::function<void()> onThreadExit = []() {}
);
~ThreadPool();
inline std::shared_ptr<Executor> CreateExecutor() const
{
return Executor::Create(io);
}
void Shutdown();
private:
openpal::Logger logger;
const std::shared_ptr<IO> io;
std::function<void ()> onThreadStart;
std::function<void ()> onThreadExit;
bool isShutdown;
void Run(int threadnum);
asio::basic_waitable_timer< asiopal::steady_clock_t > infiniteTimer;
std::vector<std::unique_ptr<std::thread>> threads;
};
}
#endif

View File

@ -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 ASIOPAL_TIMECONVERSIONS_H
#define ASIOPAL_TIMECONVERSIONS_H
#include "SteadyClock.h"
#include "openpal/util/Uncopyable.h"
#include "openpal/executor/MonotonicTimestamp.h"
namespace asiopal
{
class TimeConversions : private openpal::StaticOnly
{
static const int64_t MAX_MILLISECONDS = std::chrono::duration_cast<std::chrono::milliseconds>(steady_clock_t::duration::max()).count();
public:
static steady_clock_t::time_point Convert(const openpal::MonotonicTimestamp& timestamp);
static openpal::MonotonicTimestamp Convert(const steady_clock_t::time_point& timestamp);
};
}
#endif

View File

@ -0,0 +1,59 @@
/*
* 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_TIMER_H
#define ASIOPAL_TIMER_H
#include <asio.hpp>
#include <openpal/executor/ITimer.h>
#include <openpal/util/Uncopyable.h>
#include "asiopal/SteadyClock.h"
namespace asiopal
{
/**
*
* Implementation of openpal::ITimer backed by asio::basic_waitable_timer<steady_clock>
*
*/
class Timer final : public openpal::ITimer, private openpal::Uncopyable
{
friend class Executor;
public:
Timer(asio::io_service& service);
virtual void Cancel() override;
virtual openpal::MonotonicTimestamp ExpiresAt() override;
private:
asio::basic_waitable_timer< asiopal::steady_clock_t > timer;
};
}
#endif

View File

@ -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 ASIOPAL_UTCTIMESOURCE_H
#define ASIOPAL_UTCTIMESOURCE_H
#include <openpal/executor/IUTCTimeSource.h>
namespace asiopal
{
/**
* Interface that defines a method to get UTC timestamps
*/
class UTCTimeSource : public openpal::IUTCTimeSource
{
public:
static openpal::IUTCTimeSource& Instance();
openpal::UTCTimestamp Now();
private:
UTCTimeSource() {}
static UTCTimeSource instance;
};
}
#endif

View File

@ -0,0 +1,55 @@
/*
* 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_DECODER_H
#define OPENDNP3_DECODER_H
#include <openpal/container/RSlice.h>
#include <openpal/logging/Logger.h>
#include "IDecoderCallbacks.h"
namespace opendnp3
{
class DecoderImpl;
// stand-alone DNP3 decoder
class Decoder
{
public:
Decoder(IDecoderCallbacks& callbacks, openpal::Logger logger);
~Decoder();
void DecodeLPDU(const openpal::RSlice& data);
void DecodeTPDU(const openpal::RSlice& data);
void DecodeAPDU(const openpal::RSlice& data);
private:
DecoderImpl* impl;
};
}
#endif

View File

@ -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 OPENDNP3_IDECODERCALLBACKS_H
#define OPENDNP3_IDECODERCALLBACKS_H
#include <openpal/util/Uncopyable.h>
namespace opendnp3
{
class IDecoderCallbacks : openpal::Uncopyable
{
friend class Indent;
protected:
virtual void PushIndent() {};
virtual void PopIndent() {};
};
}
#endif

View File

@ -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.
*/
#ifndef OPENDNP3_LOGLEVELS_H
#define OPENDNP3_LOGLEVELS_H
#include <openpal/logging/LogLevels.h>
namespace opendnp3
{
const char* LogFlagToString(int32_t flag);
namespace flags
{
// define most of these in terms of the base openpal filters
const int32_t EVENT = openpal::logflags::EVENT;
const int32_t ERR = openpal::logflags::ERR;
const int32_t WARN = openpal::logflags::WARN;
const int32_t INFO = openpal::logflags::INFO;
const int32_t DBG = openpal::logflags::DBG;
// up-shift the custom dnp3 filters
const int32_t LINK_RX = DBG << 1;
const int32_t LINK_RX_HEX = DBG << 2;
const int32_t LINK_TX = DBG << 3;
const int32_t LINK_TX_HEX = DBG << 4;
const int32_t TRANSPORT_RX = DBG << 5;
const int32_t TRANSPORT_TX = DBG << 6;
const int32_t APP_HEADER_RX = DBG << 7;
const int32_t APP_HEADER_TX = DBG << 8;
const int32_t APP_OBJECT_RX = DBG << 9;
const int32_t APP_OBJECT_TX = DBG << 10;
const int32_t APP_HEX_RX = DBG << 11;
const int32_t APP_HEX_TX = DBG << 12;
}
namespace levels
{
const int32_t NOTHING = 0;
const int32_t ALL = ~NOTHING;
const int32_t NORMAL = flags::EVENT | flags::ERR | flags::WARN | flags::INFO;
const int32_t ALL_APP_COMMS = flags::APP_HEADER_RX | flags::APP_HEADER_TX | flags::APP_OBJECT_RX | flags::APP_OBJECT_TX | flags::APP_HEX_RX | flags::APP_HEX_TX;
const int32_t ALL_COMMS = flags::LINK_RX | flags::LINK_TX | flags::TRANSPORT_RX | flags::TRANSPORT_TX | ALL_APP_COMMS;
}
}
#endif

View File

@ -0,0 +1,97 @@
/*
* 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_STACKSTATISTICS_H
#define OPENDNP3_STACKSTATISTICS_H
#include <cstdint>
namespace opendnp3
{
/**
* Statistics related to both a master or outstation session
*/
struct StackStatistics
{
struct Link
{
/// number of unexpected frames
uint32_t numUnexpectedFrame = 0;
/// frames received w/ wrong master bit
uint32_t numBadMasterBit = 0;
/// frames received for an unknown destination
uint32_t numUnknownDestination = 0;
/// frames received for an unknown source
uint32_t numUnknownSource = 0;
};
struct Transport
{
struct Rx
{
/// Number of valid TPDU's received
uint32_t numTransportRx = 0;
/// Number of TPDUs dropped due to malformed contents
uint32_t numTransportErrorRx = 0;
/// Number of times received data was too big for reassembly buffer
uint32_t numTransportBufferOverflow = 0;
/// number of times transport buffer is discard due to new FIR
uint32_t numTransportDiscard = 0;
/// number of segments ignored due to bad FIR/FIN or SEQ
uint32_t numTransportIgnore = 0;
};
struct Tx
{
/// Number of TPDUs transmitted
uint32_t numTransportTx = 0;
};
Transport() = default;
Transport(const Rx& rx, const Tx& tx) : rx(rx), tx(tx) {}
Rx rx;
Tx tx;
};
StackStatistics() = default;
StackStatistics(const Link& link, const Transport& transport) :
link(link),
transport(transport)
{
}
Link link;
Transport transport;
};
}
#endif

View File

@ -0,0 +1,53 @@
/*
* 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_ANALOGCOMMANDEVENT_H
#define OPENDNP3_ANALOGCOMMANDEVENT_H
#include "opendnp3/gen/CommandStatus.h"
#include "opendnp3/app/DNPTime.h"
namespace opendnp3
{
/**
* Occurs when an outstation receives and analog command. Maps to Group43.
*/
class AnalogCommandEvent
{
public:
AnalogCommandEvent();
AnalogCommandEvent(double value, CommandStatus status);
AnalogCommandEvent(double value, CommandStatus status, DNPTime time);
double value;
CommandStatus status;
DNPTime time;
bool operator==(const AnalogCommandEvent& rhs) const;
};
}
#endif

View File

@ -0,0 +1,127 @@
/*
* 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_ANALOGOUTPUT_H
#define OPENDNP3_ANALOGOUTPUT_H
#include "opendnp3/gen/CommandStatus.h"
namespace opendnp3
{
/**
* The object to represent a setpoint request from the master. Think of
* this like turning a dial on the front of a machine to desired setting.
*/
template <class T>
class AnalogOutput
{
public:
AnalogOutput() :
value(0),
status(CommandStatus::SUCCESS)
{}
AnalogOutput(T value_) :
value(value_),
status(CommandStatus::SUCCESS)
{}
AnalogOutput(T value_, CommandStatus status_) :
value(value_),
status(status_)
{}
bool ValuesEqual(const AnalogOutput<T>& lhs) const
{
return value == lhs.value;
}
T value;
/**
* The status value defaults to CS_SUCCESS for requests
*/
CommandStatus status;
};
/**
* 16-bit signed integer analog output. The underlying serialization is Group41, Variation 2
*/
class AnalogOutputInt16 : public AnalogOutput<int16_t>
{
public:
AnalogOutputInt16();
AnalogOutputInt16(int16_t);
AnalogOutputInt16(int16_t, CommandStatus);
bool operator==(const AnalogOutputInt16& arRHS) const;
};
/**
* 32-bit signed integer analog output. The underlying serialization is Group41, Variation 1
*/
class AnalogOutputInt32 : public AnalogOutput<int32_t>
{
public:
AnalogOutputInt32();
AnalogOutputInt32(int32_t);
AnalogOutputInt32(int32_t, CommandStatus);
bool operator==(const AnalogOutputInt32& arRHS) const;
};
/**
* Single precision analog output. The underlying serialization is Group41, Variation 3
*/
class AnalogOutputFloat32 : public AnalogOutput<float>
{
public:
AnalogOutputFloat32();
AnalogOutputFloat32(float);
AnalogOutputFloat32(float, CommandStatus);
bool operator==(const AnalogOutputFloat32& arRHS) const;
};
/**
* Double precision analog output. The underlying serialization is Group41, Variation 3
*/
class AnalogOutputDouble64 : public AnalogOutput<double>
{
public:
AnalogOutputDouble64();
AnalogOutputDouble64(double);
AnalogOutputDouble64(double, CommandStatus);
bool operator==(const AnalogOutputDouble64& arRHS) const;
};
}
#endif

View File

@ -0,0 +1,38 @@
/*
* 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_APPCONSTANTS_H
#define OPENDNP3_APPCONSTANTS_H
#include <cstdint>
#include <openpal/executor/TimeDuration.h>
namespace opendnp3
{
// the default size for an APDU
const uint32_t DEFAULT_MAX_APDU_SIZE = 2048;
// default timeout in milliseconds for the application layer
const openpal::TimeDuration DEFAULT_APP_TIMEOUT = openpal::TimeDuration::Milliseconds(5000);
}
#endif

View File

@ -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.
*/
#ifndef OPENDNP3_BASEMEASUREMENTTYPES_H
#define OPENDNP3_BASEMEASUREMENTTYPES_H
#include <cstdint>
#include "opendnp3/app/DNPTime.h"
#include "opendnp3/app/Flags.h"
namespace opendnp3
{
/**
Base class shared by all of the DataPoint types.
*/
class Measurement
{
public:
Flags flags; // bitfield that stores type specific quality information
DNPTime time; // timestamp associated with the measurement
protected:
Measurement()
{}
Measurement(Flags flags) : flags(flags)
{}
Measurement(Flags flags, DNPTime time) : flags(flags), time(time)
{}
};
/// Common subclass to analogs and counters
template <class T>
class TypedMeasurement : public Measurement
{
public:
T value;
typedef T Type;
protected:
TypedMeasurement(): Measurement(), value(0) {}
TypedMeasurement(Flags flags) : Measurement(flags), value(0) {}
TypedMeasurement(T value, Flags flags) : Measurement(flags), value(value) {}
TypedMeasurement(T value, Flags flags, DNPTime time) : Measurement(flags, time), value(value) {}
};
}
#endif

View File

@ -0,0 +1,69 @@
/*
* 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_BINARYCOMMANDEVENT_H
#define OPENDNP3_BINARYCOMMANDEVENT_H
#include "opendnp3/gen/CommandStatus.h"
#include "opendnp3/app/Flags.h"
#include "opendnp3/app/DNPTime.h"
namespace opendnp3
{
/**
Maps to Group13Var1/2
*/
class BinaryCommandEvent
{
public:
BinaryCommandEvent();
BinaryCommandEvent(Flags flags);
BinaryCommandEvent(Flags flags, DNPTime time);
BinaryCommandEvent(bool value, CommandStatus status);
BinaryCommandEvent(bool value, CommandStatus status, DNPTime time);
bool value;
CommandStatus status;
DNPTime time;
Flags GetFlags() const;
bool operator==(const BinaryCommandEvent& rhs) const;
private:
static const uint8_t ValueMask = 0x80;
static const uint8_t StatusMask = 0x7F;
static bool GetValueFromFlags(Flags flags);
static CommandStatus GetStatusFromFlags(Flags flags);
};
}
#endif

View File

@ -0,0 +1,93 @@
/*
* 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_CLASSFIELD_H
#define OPENDNP3_CLASSFIELD_H
#include <cstdint>
#include "opendnp3/app/EventType.h"
#include "opendnp3/gen/PointClass.h"
namespace opendnp3
{
/**
* Specifies a set of event classes e.g. some subset of {0, 1, 2, 3}
*/
class ClassField
{
public:
ClassField();
ClassField(PointClass pc);
ClassField(uint8_t mask_);
ClassField(bool class0, bool class1, bool class2, bool class3);
bool IsEmpty() const;
bool Intersects(const ClassField& other) const;
uint8_t GetBitfield() const
{
return bitfield;
};
ClassField OnlyEventClasses() const;
void Clear(const ClassField& field);
void Set(const ClassField& field);
void Set(PointClass pc);
static const uint8_t CLASS_0 = static_cast<uint8_t>(PointClass::Class0);
static const uint8_t CLASS_1 = static_cast<uint8_t>(PointClass::Class1);
static const uint8_t CLASS_2 = static_cast<uint8_t>(PointClass::Class2);
static const uint8_t CLASS_3 = static_cast<uint8_t>(PointClass::Class3);
static const uint8_t EVENT_CLASSES = CLASS_1 | CLASS_2 | CLASS_3;
static const uint8_t ALL_CLASSES = EVENT_CLASSES | CLASS_0;
bool HasEventType(EventClass ec) const;
bool HasClass0() const;
bool HasClass1() const;
bool HasClass2() const;
bool HasClass3() const;
bool HasEventClass() const;
bool HasAnyClass() const;
static ClassField None();
static ClassField AllClasses();
static ClassField AllEventClasses();
private:
uint8_t bitfield;
};
}
#endif

View File

@ -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 OPENDNP3_CONTROLRELAYOUTPUTBLOCK_H
#define OPENDNP3_CONTROLRELAYOUTPUTBLOCK_H
#include "opendnp3/gen/CommandStatus.h"
#include "opendnp3/gen/ControlCode.h"
namespace opendnp3
{
/**
* Describes an incoming control request from the master. It is the
* applications responsibility to handle the request and return an
* approiate status code.The PULSE_CLOSE and PULSE_TRIP ControlCodes
* require setting the mOnTimeMS, mOffTimeMS and mCount variables, otherwise
* just use the defaults.
*/
class ControlRelayOutputBlock
{
public:
// primary constructor where the control code is set by enumeration
ControlRelayOutputBlock(
ControlCode code = ControlCode::LATCH_ON,
uint8_t count = 1,
uint32_t onTime = 100,
uint32_t offTime = 100,
CommandStatus status = CommandStatus::SUCCESS);
// overloaded constructor that allows the user to set a raw control code for non-standard codes
ControlRelayOutputBlock(
uint8_t rawCode,
uint8_t count = 1,
uint32_t onTime = 100,
uint32_t offTime = 100,
CommandStatus status = CommandStatus::SUCCESS);
/// allows matching of exact code
ControlCode functionCode;
/// The raw code in bytes
uint8_t rawCode;
/// the number of times to repeat the operation
uint8_t count;
/// the 'on' time for the pulse train
uint32_t onTimeMS;
/// the 'off' time for the pulse train
uint32_t offTimeMS;
/// status of the resulting operation
CommandStatus status;
bool ValuesEqual(const ControlRelayOutputBlock& lhs) const
{
return (functionCode == lhs.functionCode) &&
(count == lhs.count) &&
(onTimeMS == lhs.onTimeMS) &&
(offTimeMS == lhs.offTimeMS);
}
bool operator==(const ControlRelayOutputBlock& lhs) const
{
return this->ValuesEqual(lhs) && (this->status == lhs.status);
}
};
}
#endif

View File

@ -0,0 +1,34 @@
/*
* 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_DNPTIME_H
#define OPENDNP3_DNPTIME_H
#include <openpal/serialization/UInt48Type.h>
namespace opendnp3
{
typedef openpal::UInt48Type DNPTime;
}
#endif

View File

@ -0,0 +1,80 @@
/*
* 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_EVENTCELLS_H
#define OPENDNP3_EVENTCELLS_H
#include "opendnp3/app/EventType.h"
#include "opendnp3/gen/PointClass.h"
namespace opendnp3
{
/// A null object for types that have no metadata
struct EmptyEventCell
{
};
/// Base class for different types of event metadata
template <class Spec>
struct EventCellBase
{
PointClass clazz;
typename Spec::meas_t lastEvent;
typename Spec::event_variation_t evariation;
void SetEventValue(const typename Spec::meas_t& value)
{
lastEvent = value;
}
protected:
EventCellBase() : clazz(PointClass::Class1), lastEvent(), evariation(Spec::DefaultEventVariation)
{}
};
/// Metatype w/o a deadband
template <class Spec>
struct SimpleEventCell : EventCellBase<Spec>
{
bool IsEvent(const typename Spec::config_t& config, const typename Spec::meas_t& newValue) const
{
return Spec::IsEvent(this->lastEvent, newValue);
}
};
/// Structure for holding metadata information on points that have support deadbanding
template <class Spec>
struct DeadbandEventCell : SimpleEventCell<Spec>
{
bool IsEvent(const typename Spec::config_t& config, const typename Spec::meas_t& newValue) const
{
return Spec::IsEvent(this->lastEvent, newValue, config.deadband);
}
};
} //end namespace
#endif

View File

@ -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 OPENDNP3_EVENTTRIGGERS_H
#define OPENDNP3_EVENTTRIGGERS_H
#include "opendnp3/app/BaseMeasurementTypes.h"
namespace opendnp3
{
namespace measurements
{
template <class T, class U>
bool IsEvent(const T& val1, const T& val2, T deadband)
{
// T can be unsigned data type so std::abs won't work since it only directly supports signed data types
// If one uses std::abs and T is unsigned one will get an ambiguous override error.
U diff = (val2 > val1) ? (static_cast<U>(val2) - static_cast<U>(val1)) : (static_cast<U>(val1) - static_cast<U>(val2));
return diff > deadband;
}
bool IsEvent(const TypedMeasurement<double>& newMeas, const TypedMeasurement<double>& oldMeas, double deadband);
}
}
#endif

View File

@ -0,0 +1,52 @@
/*
* 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_EVENTTYPE_H
#define OPENDNP3_EVENTTYPE_H
#include <cstdint>
namespace opendnp3
{
static const int NUM_OUTSTATION_EVENT_TYPES = 8;
enum class EventType : uint16_t
{
Binary = 0,
Analog = 1,
Counter = 2,
FrozenCounter = 3,
DoubleBitBinary = 4,
BinaryOutputStatus = 5,
AnalogOutputStatus = 6,
SecurityStat = 7
};
enum class EventClass : uint8_t
{
EC1 = 0,
EC2 = 1,
EC3 = 2
};
}
#endif

View File

@ -0,0 +1,112 @@
/*
* 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_FLAGS_H
#define OPENDNP3_FLAGS_H
#include "opendnp3/app/QualityMasks.h"
namespace opendnp3
{
/**
Measurement Flags
*/
class Flags
{
public:
Flags() : value(0)
{}
Flags(uint8_t value) : value(value)
{}
inline bool IsSet(BinaryQuality flag) const
{
return IsSetAny(flag);
}
inline bool IsSet(AnalogQuality flag) const
{
return IsSetAny(flag);
}
inline bool IsSet(CounterQuality flag) const
{
return IsSetAny(flag);
}
inline bool IsSet(FrozenCounterQuality flag) const
{
return IsSetAny(flag);
}
inline bool IsSet(BinaryOutputStatusQuality flag) const
{
return IsSetAny(flag);
}
inline bool IsSet(AnalogOutputStatusQuality flag) const
{
return IsSetAny(flag);
}
inline void Set(BinaryQuality flag)
{
SetAny(flag);
}
inline void Set(AnalogQuality flag)
{
SetAny(flag);
}
inline void Set(CounterQuality flag)
{
SetAny(flag);
}
inline void Set(FrozenCounterQuality flag)
{
SetAny(flag);
}
inline void Set(BinaryOutputStatusQuality flag)
{
SetAny(flag);
}
inline void Set(AnalogOutputStatusQuality flag)
{
SetAny(flag);
}
uint8_t value;
protected:
template <class T>
bool IsSetAny(T flag) const
{
return (value & static_cast<uint8_t>(flag)) != 0;
}
template <class T>
void SetAny(T flag)
{
value |= static_cast<uint8_t>(flag);
}
};
}
#endif

View File

@ -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 OPENDNP3_GROUPVARIATIONID_H
#define OPENDNP3_GROUPVARIATIONID_H
#include <cstdint>
namespace opendnp3
{
/// Simple uint8_t/uint8_t tuple for group and variation
struct GroupVariationID
{
GroupVariationID() : group(0xFF), variation(0xFF)
{}
GroupVariationID(uint8_t aGroup, uint8_t aVariation):
group(aGroup),
variation(aVariation)
{
}
uint8_t group;
uint8_t variation;
};
}
#endif

View File

@ -0,0 +1,198 @@
/*
* 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_IINFIELD_H
#define OPENDNP3_IINFIELD_H
#include <cstdint>
namespace opendnp3
{
enum class IINBit
{
ALL_STATIONS = 0,
CLASS1_EVENTS,
CLASS2_EVENTS,
CLASS3_EVENTS,
NEED_TIME,
LOCAL_CONTROL,
DEVICE_TROUBLE,
DEVICE_RESTART,
FUNC_NOT_SUPPORTED,
OBJECT_UNKNOWN,
PARAM_ERROR,
EVENT_BUFFER_OVERFLOW,
ALREADY_EXECUTING,
CONFIG_CORRUPT,
RESERVED1,
RESERVED2 = 15
};
/** DNP3 two-byte IIN field.
*/
class IINField
{
private:
enum class LSBMask : uint8_t
{
ALL_STATIONS = 0x01,
CLASS1_EVENTS = 0x02,
CLASS2_EVENTS = 0x04,
CLASS3_EVENTS = 0x08,
NEED_TIME = 0x10,
LOCAL_CONTROL = 0x20,
DEVICE_TROUBLE = 0x40,
DEVICE_RESTART = 0x80,
};
enum class MSBMask : uint8_t
{
FUNC_NOT_SUPPORTED = 0x01,
OBJECT_UNKNOWN = 0x02,
PARAM_ERROR = 0x04,
EVENT_BUFFER_OVERFLOW = 0x08,
ALREADY_EXECUTING = 0x10,
CONFIG_CORRUPT = 0x20,
RESERVED1 = 0x40,
RESERVED2 = 0x80,
//special mask that indicates if there was any error processing a request
REQUEST_ERROR_MASK = FUNC_NOT_SUPPORTED | OBJECT_UNKNOWN | PARAM_ERROR
};
public:
static IINField Empty()
{
return IINField(0, 0);
}
IINField(IINBit bit) : LSB(0), MSB(0)
{
this->SetBit(bit);
}
IINField(uint8_t aLSB, uint8_t aMSB) : LSB(aLSB), MSB(aMSB)
{}
IINField() : LSB(0), MSB(0)
{}
bool IsSet(IINBit bit) const;
bool IsClear(IINBit bit) const
{
return !IsSet(bit);
}
void SetBit(IINBit bit);
void ClearBit(IINBit bit);
void SetBitToValue(IINBit bit, bool value);
bool operator==(const IINField& arRHS) const;
bool Any() const
{
return (LSB | MSB) != 0;
}
void Clear()
{
LSB = MSB = 0;
}
bool HasRequestError() const
{
return Get(MSBMask::REQUEST_ERROR_MASK);
}
IINField operator|(const IINField& aIIN) const
{
return IINField(LSB | aIIN.LSB, MSB | aIIN.MSB);
}
IINField& operator|=(const IINField& aIIN)
{
MSB |= aIIN.MSB;
LSB |= aIIN.LSB;
return *this;
}
IINField operator&(const IINField& aIIN) const
{
return IINField(LSB & aIIN.LSB, MSB & aIIN.MSB);
}
IINField& operator&=(const IINField& aIIN)
{
MSB &= aIIN.MSB;
LSB &= aIIN.LSB;
return *this;
}
IINField operator~() const
{
return IINField(~LSB, ~MSB);
}
uint8_t LSB;
uint8_t MSB;
private:
static const uint8_t REQUEST_ERROR_MASK;
inline bool Get(LSBMask bit) const
{
return (LSB & static_cast<uint8_t>(bit)) != 0;
}
inline bool Get(MSBMask bit) const
{
return (MSB & static_cast<uint8_t>(bit)) != 0;
}
inline void Set(LSBMask bit)
{
LSB |= static_cast<uint8_t>(bit);
}
inline void Set(MSBMask bit)
{
MSB |= static_cast<uint8_t>(bit);
}
inline void Clear(LSBMask bit)
{
LSB &= ~static_cast<uint8_t>(bit);
}
inline void Clear(MSBMask bit)
{
MSB &= ~static_cast<uint8_t>(bit);
}
};
}
#endif

View File

@ -0,0 +1,102 @@
/*
* 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_ITRANSACTABLE_H
#define OPENDNP3_ITRANSACTABLE_H
#include <openpal/util/Uncopyable.h>
namespace opendnp3
{
/**
Something that can be performed atomically or needing Start()/End() signals
*/
class ITransactable
{
public:
friend class Transaction;
virtual ~ITransactable() {}
protected:
virtual void Start() = 0;
virtual void End() = 0;
};
/**
Uses RAII to safely perform a transaction
*/
class Transaction : private openpal::Uncopyable
{
public:
Transaction(ITransactable& transactable) : pTransactable(&transactable)
{
pTransactable->Start();
}
Transaction(ITransactable* pTransactable_) : pTransactable(pTransactable_)
{
if (pTransactable)
{
pTransactable->Start();
}
}
~Transaction()
{
if (pTransactable)
{
pTransactable->End();
}
}
static void Start(ITransactable* t)
{
if (t)
{
t->Start();
}
}
static void End(ITransactable* t)
{
if (t)
{
t->End();
}
}
template <class ReturnType, class TransactionType, class Fun>
static ReturnType Apply(TransactionType& transactable, const Fun& fun)
{
Transaction t(transactable);
return fun(transactable);
}
private:
ITransactable* pTransactable;
};
}
#endif

View File

@ -0,0 +1,56 @@
/*
* 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_INDEXED_H
#define OPENDNP3_INDEXED_H
#include <cstdint>
namespace opendnp3
{
/**
* A simple tuple for pairing Values with an index
*/
template <class T>
class Indexed
{
public:
Indexed(const T& value_, uint16_t index_) :
value(value_),
index(index_)
{}
Indexed(): value(), index(0)
{}
T value;
uint16_t index;
};
template <class T>
Indexed<T> WithIndex(const T& value, uint16_t index)
{
return Indexed<T>(value, index);
}
}
#endif

View File

@ -0,0 +1,175 @@
/*
* 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_MEASUREMENTINFO_H
#define OPENDNP3_MEASUREMENTINFO_H
#include "opendnp3/app/MeasurementTypes.h"
#include "opendnp3/app/SecurityStat.h"
#include "opendnp3/app/EventType.h"
#include "opendnp3/gen/StaticBinaryVariation.h"
#include "opendnp3/gen/StaticDoubleBinaryVariation.h"
#include "opendnp3/gen/StaticBinaryOutputStatusVariation.h"
#include "opendnp3/gen/StaticCounterVariation.h"
#include "opendnp3/gen/StaticFrozenCounterVariation.h"
#include "opendnp3/gen/StaticAnalogVariation.h"
#include "opendnp3/gen/StaticAnalogOutputStatusVariation.h"
#include "opendnp3/gen/StaticTimeAndIntervalVariation.h"
#include "opendnp3/gen/StaticSecurityStatVariation.h"
#include "opendnp3/gen/EventBinaryVariation.h"
#include "opendnp3/gen/EventDoubleBinaryVariation.h"
#include "opendnp3/gen/EventBinaryOutputStatusVariation.h"
#include "opendnp3/gen/EventCounterVariation.h"
#include "opendnp3/gen/EventFrozenCounterVariation.h"
#include "opendnp3/gen/EventAnalogVariation.h"
#include "opendnp3/gen/EventAnalogOutputStatusVariation.h"
#include "opendnp3/gen/EventSecurityStatVariation.h"
#include "opendnp3/gen/StaticTypeBitmask.h"
#include "opendnp3/gen/BinaryQuality.h"
#include "openpal/util/Uncopyable.h"
namespace opendnp3
{
struct BinaryInfo : private openpal::StaticOnly
{
typedef Binary meas_t;
typedef bool value_t;
typedef EventBinaryVariation event_variation_t;
typedef StaticBinaryVariation static_variation_t;
static const EventType EventTypeEnum = EventType::Binary;
static const StaticTypeBitmask StaticTypeEnum = StaticTypeBitmask::BinaryInput;
static const event_variation_t DefaultEventVariation = EventBinaryVariation::Group2Var1;
static const static_variation_t DefaultStaticVariation = StaticBinaryVariation::Group1Var2;
};
struct DoubleBitBinaryInfo : private openpal::StaticOnly
{
typedef DoubleBitBinary meas_t;
typedef DoubleBit value_t;
typedef EventDoubleBinaryVariation event_variation_t;
typedef StaticDoubleBinaryVariation static_variation_t;
static const EventType EventTypeEnum = EventType::DoubleBitBinary;
static const StaticTypeBitmask StaticTypeEnum = StaticTypeBitmask::DoubleBinaryInput;
static const event_variation_t DefaultEventVariation = EventDoubleBinaryVariation::Group4Var1;
static const static_variation_t DefaultStaticVariation = StaticDoubleBinaryVariation::Group3Var2;
};
class BinaryOutputStatusInfo : private openpal::StaticOnly
{
public:
typedef BinaryOutputStatus meas_t;
typedef bool value_t;
typedef EventBinaryOutputStatusVariation event_variation_t;
typedef StaticBinaryOutputStatusVariation static_variation_t;
static const EventType EventTypeEnum = EventType::BinaryOutputStatus;
static const StaticTypeBitmask StaticTypeEnum = StaticTypeBitmask::BinaryOutputStatus;
static const event_variation_t DefaultEventVariation = EventBinaryOutputStatusVariation::Group11Var1;
static const static_variation_t DefaultStaticVariation = StaticBinaryOutputStatusVariation::Group10Var2;
};
struct AnalogInfo : private openpal::StaticOnly
{
typedef Analog meas_t;
typedef double value_t;
typedef EventAnalogVariation event_variation_t;
typedef StaticAnalogVariation static_variation_t;
static const EventType EventTypeEnum = EventType::Analog;
static const StaticTypeBitmask StaticTypeEnum = StaticTypeBitmask::AnalogInput;
static const event_variation_t DefaultEventVariation = EventAnalogVariation::Group32Var1;
static const static_variation_t DefaultStaticVariation = StaticAnalogVariation::Group30Var1;
};
struct CounterInfo : private openpal::StaticOnly
{
typedef Counter meas_t;
typedef uint32_t value_t;
typedef EventCounterVariation event_variation_t;
typedef StaticCounterVariation static_variation_t;
static const EventType EventTypeEnum = EventType::Counter;
static const StaticTypeBitmask StaticTypeEnum = StaticTypeBitmask::Counter;
static const event_variation_t DefaultEventVariation = EventCounterVariation::Group22Var1;
static const static_variation_t DefaultStaticVariation = StaticCounterVariation::Group20Var1;
};
struct FrozenCounterInfo : private openpal::StaticOnly
{
typedef FrozenCounter meas_t;
typedef uint32_t value_t;
typedef EventFrozenCounterVariation event_variation_t;
typedef StaticFrozenCounterVariation static_variation_t;
static const EventType EventTypeEnum = EventType::FrozenCounter;
static const StaticTypeBitmask StaticTypeEnum = StaticTypeBitmask::FrozenCounter;
static const event_variation_t DefaultEventVariation = EventFrozenCounterVariation::Group23Var1;
static const static_variation_t DefaultStaticVariation = StaticFrozenCounterVariation::Group21Var1;
};
struct AnalogOutputStatusInfo : private openpal::StaticOnly
{
typedef AnalogOutputStatus meas_t;
typedef double value_t;
typedef EventAnalogOutputStatusVariation event_variation_t;
typedef StaticAnalogOutputStatusVariation static_variation_t;
static const EventType EventTypeEnum = EventType::AnalogOutputStatus;
static const StaticTypeBitmask StaticTypeEnum = StaticTypeBitmask::AnalogOutputStatus;
static const event_variation_t DefaultEventVariation = EventAnalogOutputStatusVariation::Group42Var1;
static const static_variation_t DefaultStaticVariation = StaticAnalogOutputStatusVariation::Group40Var1;
};
struct TimeAndIntervalInfo : private openpal::StaticOnly
{
typedef TimeAndInterval meas_t;
typedef StaticTimeAndIntervalVariation static_variation_t;
const static StaticTypeBitmask StaticTypeEnum = StaticTypeBitmask::TimeAndInterval;
const static StaticTimeAndIntervalVariation DefaultStaticVariation = StaticTimeAndIntervalVariation::Group50Var4;
};
struct SecurityStatInfo : private openpal::StaticOnly
{
typedef SecurityStat meas_t;
typedef SecurityStat::Value value_t;
typedef EventSecurityStatVariation event_variation_t;
typedef StaticSecurityStatVariation static_variation_t;
const static EventType EventTypeEnum = EventType::SecurityStat;
const static event_variation_t DefaultEventVariation = EventSecurityStatVariation::Group122Var1;
const static static_variation_t DefaultStaticVariation = StaticSecurityStatVariation::Group121Var1;
};
}
#endif

Some files were not shown because too many files have changed in this diff Show More