- initial commit for new repository structure

This commit is contained in:
Michael Zillgith 2014-12-01 10:34:45 +01:00
commit 48d717f12c
581 changed files with 129922 additions and 0 deletions

270
CHANGELOG Normal file
View File

@ -0,0 +1,270 @@
Changes to version 0.7.8
------------------------
- IED client: added client side support for Ed.1 compliant control (client side automatically detects if a control is ed1 or ed2 compliant)
- Tools: SCL parser throws exceptions if names are defined multiple times in the same context
- build support for FreeBSD (gmake and cmake)
- server: fixed BER encoding problen in file close/delete response messages
- server: fixed wrong reason-for-inclusion encoding for GI/integrity reports in buffered reporting
- server: fixed endianess issue with report entry id
- Configuration tools: fixed bug in static model generator - generator does not create RCBs for all logical devices
- mms server: added support for vmd-scope named variables
- mms server: support for standard MMS get-name-list behaviour (no flat address space)
- common: refactored MmsValue string handling
- some small extensions to C# client API
Changes to version 0.7.7
------------------------
- client: fixed encoding bug in file close service
- Configuration tools: fixed code generator problem with index report control blocks
- Configuration tools: fixed problem with multiple data sets in a logical node
- Configuration tools: configuration file generator can now handle arrays of data objects
- Configuration toosl: configuration file generator does now properly define predefined unicode strings
- removed some older functions of client API report setup in favor of ClientReportControlBlock
- client side report handling does no longer require to read the data set before reports can be received
- added preview version of C# client API
- added support (HAL) for Mac OS X (thanks to Michael Clausen - HES-SO Valais-Wallis)
- some fixes in server side report handling (data set containing complex data attributes or FCDOs)
- buffered reporting: fixed problem when buffer can only hold a single entry
- fixed problem in function MmsValue_cloneToBuffer used by buffered reporting
- fixed problem in GOOSE publisher (sqNum starts with 1 instead of 0)
- added convenience methods IedServer_updateInt64AttributeValue and IedServer_updateVisibleStringAttributeValue
- added conditional extern "C" declaration to header files for use in C++ projects
- server now closes TCP socket after sending the ACSE release message
Changes to version 0.7.6
------------------------
- Server: fixed bug: authenticator will be called and can accept client connection even if no authentication value is provided
- Tools: SCL parser accepts SCL files without communication section
- Server: fixed missing support for nested control objects (required to support IEC 61400-25-2)
- client API: fixed some bugs in client API functions of version 0.7.5
- client API: added support to receive CommandTermination message of enhanced control models
- server API: new function to get access to DataAttribute references without knowing the IED name
- some other small changes...
Changes to version 0.7.5
------------------------
- Client API: added convenience functions to avoid direct handling with MmsValue instances
- Added timestamp handling functions
- Configuration tools (genmodel/genconfig) allow specification of access point and IED for SCL files containing more then one IED / access point
- client/server: COTP layer is now more efficient
- added server example to illustrate using arrays of data objects
- MMS server: fixed potential dead-lock problem server side
- IED server: solved problem that client writes didn't trigger a report
- MMS server: fixed problem in fileDirectory response
- server: removed optional transfer syntax field in ACSE layer to improve compatibility with some clients
- some other smaller bug fixes ...
Changes to version 0.7.4
------------------------
- Configurations tools: fixed bug with default values and short addresses for sub data objects and sub data attributes
- DLL build with Visual Studio now exports functions
- server stack is more configurable (some services can be excluded to reduce binary size)
- improved doxygen documentation
- Client API: control service supports originator value (orIdent/orCat)
- Server: control service checks for valid originator value
- fixed problem with blocking client abort function
- Server API: helper functions for dynamic data model creation now contains support for most CDCs of IEC 61850-7-3 (Ed.2)
- Client API: client report structure now provides access to report timestamp
- Configuration tool: fixed data set problem with static model generator of 0.7 series
- fixed some other minor problems ...
Changes to version 0.7.3
------------------------
- Server/Client: MMS deleteFile and renameFile services
- IEC client API: deleteFile ACSI service
- fixed bug when compiling for big endian systems
- Client/Server API: added Quality data type and handling functions
- Server API: added IedServer_updateQuality, IedServer_updateFloatAttributeValue.. convenience functions.
- extended cmake builder (contains some experimental configuration options)
- added install target to cmake and make build systems.
Changes to version 0.7.2
------------------------
- Server API: added API to create data models at runtime
- Server: added some helper functions to create common CDCs at runtime
- Server/ Server API: added configuration file parser
- Server: Implemented AcseAuthenticator to provide more flexible authentication and access control schemes
- Server: added windows support for file services (both for Visual Studio and MinGW)
- Server/Tools: Added access to data attributes by simple integer short addresses ("sAddr" SCL file attribute)
- Tools: added configuration file generator tool
- Added examples for using file services and dynamic model features
- GOOSE publisher: fixed bug - sending wrong confRef field
Changes to version 0.7.1.1
--------------------------
- Server: fixed long term stack memory leak present in versions 0.7 and 0.7.1
Changes to version 0.7.1
------------------------
- Server API: Added IedServer_getFunctionalConstrainedData function to simplify handling of arrays of data objects.
- Client API: Made connetion parameters for ACSE and lower layers fully configurable (AP-title, AEQualifier, PSel, SSel, TSel) - required to be compatible with some servers
- MMS server: made number of concurrent TCP connections configurable by CONFIG_MAXIMUM_... define
- MMS client/server: added MMS status services
- MMS server: made MMS identify service optional
- added file access abstraction to HAL
- MMS client/server: added getFileDirectory, fileOpen, fileRead, fileClose services
- Client/server: added GetFile ACSI service
Changes to version 0.7
-----------------------
- Server: added support for buffered reporting
- Server: Bug fix: trigger reasons for reports are taken from SCL file
- Server/Server API: added callback to perform access control on write accesses
- Server/Server API: added default access policies to writable FCs
- Client API: get/setGoCBValues ACSI services - new ClientGooseControlBlock class
- Client API: added callbacks for connection losses
- GOOSE Subscriber: API change -> use GoCBReference instead of DataSetReference to identify a GOOSE message
- GOOSE Subscriber: Bug fix: Linux driver now switches interface to promiscuous mode.
- MMS Client: improved buffer handling
- MMS Client/MMS Client API: Added functions to browse and read VMD scope variables
- Client/Client API/Server: Implemented ABORT and RELEASE services
- Client API: Allows definition of association specific data sets
- MMS Client API: Removed all occurances of MmsIndication type in MMS client API
Changes to version 0.6
------------------------
- Client API: getDataSetDirectory ACSI service
- Client API: create and delete data set ACSI services
- Client API: added getRCBValue/setRCBValues ACSI services to improve client support for reporting
- client side stack: improved error handling
- Client API: Methods to allow clients track the connection state
- Client API: Report handler provides access to reason-for-inclusion
- Server API: added callbacks for connection events
- Server API: new ClientConnection object that will be handed over to some callback functions to allow connection specific reactions on events -> some callback handler signatures have changed!
- Added server side support for indexed RCBs
- more efficient server side buffer handling
- added BeagleBone LED control demo
- DEBUG output can be switched on/off for stack components
- and a lot of small improvements and bug fixes
Changes to version 0.5.3
------------------------
- MMS client/server: multiple variables can be written with a single MMS write request
- changed encoding of boolean to be compatible with buggy server devices
- added TCP keep alive support to MMS client
- added IedConnection_triggerGIReport function
- some enhancements in server side report handling
- some bug fixes
Changes to version 0.5.2.1
--------------------------
- all examples now compile with VC++
- CMake script supports GOOSE for Windows if winpcap is available
Changes to version 0.5.2
------------------------
- fixed problem when compiling with MINGW
- changed order of FC named variables according to standard
- fixed some other compatibility problems
- allows read access to sub-elements of control variables
- allows write access to GoCB if the control block is not enabled
- allows dynamically generated datasets to be used with GOOSE
Changes to version 0.5.1
------------------------
- made code compatible with Visual Studio C++ (tested with versions 2010/2012)
- added new build system based on cmake. It is now possible to create solution and project files for different versions ofVisual Studio as well as for other IDEs/toolchains.
- fixed interoperability problem in ACSE layer
- added server side support to use dynamically created data sets in reports (addSubscription service according to IEC 61400-25)
Changes to version 0.5
----------------------
- client support for control
- client support for multiple outstanding requests.
- full server support for all control models and time avtivated control
- added client and server support for MMS identify service
- extended build system to build shared libraries (linux shared objects and DLLs) with "make dynlib"
- some small bug fixes in model generator tool
- fixed bug in handling reject messages
Changes to version 0.4.1
------------------------
- SCL parser/code generator is more tolerant
- ubrcb supports resv handling
- fixed problems in presentation layer
- fixed problems when running on 64 bit systems
Changes to version 0.4.0.2
--------------------------
- removed too strict requirements in accepting session layer accept message client side.
- fixed memory management bugs in client and server.
Changes to version 0.4.0.1
--------------------------
- fixed problem in client association request message in new presentation layer code
- MMS read access to GoCB and control objects is now more flexibel to be compatible with more clients
Changes to version 0.4
----------------------
- GOOSE publisher for windows based on winpcap
- GOOSE subscriber for linux and windows
- Started to implement a IEC 61850 client API (supported functions yet: read/write variables, simple model discovery functions, support for receiving reports)
- reimplemented presentation layer and ACSE for more efficient memory handling.
- changed error handling in MMS client
Changes to version 0.3.3.1
--------------------------
- fixed bug in MMS client that causes a segmentation fault when the connection to the server cannot be established.
Changes to version 0.3.3
------------------------
- added facility to observe write access to individual data attributes.
- added experimental GOOSE publisher code for Linux. The server also exposes configuration parameters with the GoCB.
- Server now respects the "BufTm" parameter as set by the client or SCL file. This allows related events to be accumulated for the period of time specified by "BufTm" and reported in a single report message.
Changes to version 0.3.2
------------------------
- added support functions for MMS time types (MMS_BINARY_TIME and MMS_UTC_TIME).
- improved server side support for reporting. Reports can now contain TimeOfEntry values. The server now
respects most of the options for reports set by the client.
- added Semaphore functions to HAL API (thread.h). Semaphores are used by the server stack for internal
synchonization.
- fixed bugs in code that is responsible for remote access to report control blocks.
- fixed bug in COTP code when TPDU size is larger than 1024 bytes. TPDU size can now be as large as 16384 bytes.
- fixed bug in Hal_getTimeInMs function for Windows. Window filetime value will now be correctly converted.
- fixed problems with read access to complex array types (arrays of constructed attribute classes).
Changes to version 0.3.1
------------------------
- improved support for reporting - more options are possible, reason code can be included in reports
- basic support for control model (operate) in server and server API
- added server example for control model (server_example3)
Changes to version 0.3
----------------------
- change server API, access to data model via handles
- SCL file parser supports buffered and unbuffered report control blocks
- server support for unbuffered reporting (supported triggers are GI, integrity and value update)
- MMS client support for MMS information reports
- MMS stack supports fragmented transmission for MMS getNameList service
- new structure for examples directory -> each example is in its own directory and has its own Makefile
- server support for additional ACSI types -> better support for IEC 61850 data models
- server enforces write access restrictions to the IEC 61850 data model based on functional constraints.
- added support for TCP keepalive
- and a lot of bug fixes
Changes to version 0.2.1
------------------------
- fixed bug in SCL file parser
- Added doxygen generated documentation to source distribution
- some bug fixes
Changes to version 0.2
-----------------------
- Support for association specific data sets (named variable lists)
- Support for permanent data sets configured in SCL file
- fixed bug when deleting data sets
- data sets can now contain variables of different MMS domains (IEC 61850 logical devices)
- Changed handling of MMS GetNameList service in MMS client API
Changes to version 0.1.1
-------------------------
- a template project and makefile to simplify getting started with the library.
- New implementation of the model generator tool that now contains its own SCL file parser.

131
CMakeLists.txt Normal file
View File

@ -0,0 +1,131 @@
cmake_minimum_required(VERSION 2.8)
# automagically detect if we should cross-compile
if(DEFINED ENV{TOOLCHAIN})
set(CMAKE_C_COMPILER $ENV{TOOLCHAIN}gcc)
set(CMAKE_CXX_COMPILER $ENV{TOOLCHAIN}g++)
set(CMAKE_AR "$ENV{TOOLCHAIN}ar" CACHE FILEPATH "CW archiver" FORCE)
endif()
project(libiec61850)
set(LIB_VERSION_MAJOR "0")
set(LIB_VERSION_MINOR "7")
set(LIB_VERSION_PATCH "8")
# feature checks
include(CheckLibraryExists)
check_library_exists(rt clock_gettime "time.h" CONFIG_SYSTEM_HAS_CLOCK_GETTIME)
# check if we are on a little or a big endian
include (TestBigEndian)
test_big_endian(PLATFORM_IS_BIGENDIAN)
set(CONFIG_MMS_MAXIMUM_PDU_SIZE "65000" CACHE STRING "Configure the maximum size of an MMS PDU (default 65000)" )
set(CONFIG_MAXIMUM_TCP_CLIENT_CONNECTIONS 5 CACHE STRING "Configure the maximum number of clients allowed to connect to the server")
option(BUILD_EXAMPLES "Build the examples" ON)
# choose the library features which shall be included
option(CONFIG_INCLUDE_GOOSE_SUPPORT "Build with GOOSE support" ON)
option(CONFIG_IEC61850_CONTROL_SERVICE "Build with support for IEC 61850 control features" ON)
option(CONFIG_IEC61850_REPORT_SERVICE "Build with support for IEC 61850 reporting services" ON)
option(CONFIG_ACTIVATE_TCP_KEEPALIVE "Activate TCP keepalive" ON)
set(CONFIG_REPORTING_DEFAULT_REPORT_BUFFER_SIZE "8000" CACHE STRING "Default buffer size for buffered reports in byte" )
# advanced options
option(DEBUG "Enable debugging mode (include assertions)" OFF)
option(DEBUG_COTP "Enable COTP printf debugging" OFF)
option(DEBUG_ISO_SERVER "Enable ISO SERVER printf debugging" OFF)
option(DEBUG_ISO_CLIENT "Enable ISO CLIENT printf debugging" OFF)
option(DEBUG_IED_SERVER "Enable IED SERVER printf debugging" OFF)
option(DEBUG_IED_CLIENT "Enable IED CLIENT printf debugging" OFF)
option(DEBUG_MMS_SERVER "Enable MMS SERVER printf debugging" OFF)
option(DEBUG_MMS_CLIENT "Enable MMS CLIENT printf debugging" OFF)
#mark_as_advanced(DEBUG DEBUG_COTP DEBUG_ISO_SERVER DEBUG_ISO_CLIENT DEBUG_IED_SERVER
# DEBUG_IED_CLIENT DEBUG_MMS_SERVER DEBUG_MMS_CLIENT)
include_directories(
${CMAKE_CURRENT_BINARY_DIR}/config
src/common
src/goose
src/hal
src/hal/ethernet
src/hal/socket
src/hal/thread
src/hal/filesystem
src/hal/time
src/iedclient
src/iedcommon
src/iedserver
src/iedserver/impl
src/iedserver/mms_mapping
src/iedserver/model
src/mms/asn1
src/mms/iso_acse
src/mms/iso_client
src/mms/iso_cotp
src/mms/iso_mms/asn1c
src/mms/iso_mms/client
src/mms/iso_mms/common
src/mms/iso_mms/server
src/mms/iso_presentation
src/mms/iso_server
src/mms/iso_common
src/mms/iso_session
)
set(API_HEADERS
src/hal/time/time_hal.h
src/hal/ethernet/ethernet.h
src/hal/thread/thread.h
src/hal/filesystem/filesystem.h
src/common/libiec61850_common_api.h
src/common/linked_list.h
src/common/byte_buffer.h
src/iedclient/iec61850_client.h
src/iedcommon/iec61850_common.h
src/iedserver/iec61850_server.h
src/iedserver/model/model.h
src/iedserver/model/cdc.h
src/iedserver/model/dynamic_model.h
src/iedserver/model/config_file_parser.h
src/mms/iso_mms/common/mms_value.h
src/mms/iso_mms/common/mms_common.h
src/mms/iso_mms/common/mms_types.h
src/mms/iso_mms/server/mms_device_model.h
src/mms/iso_mms/server/mms_server.h
src/mms/iso_mms/server/mms_named_variable_list.h
src/mms/iso_mms/common/mms_type_spec.h
src/mms/asn1/ber_integer.h
src/mms/asn1/asn1_ber_primitive_value.h
src/mms/iso_server/iso_server.h
src/mms/iso_common/iso_connection_parameters.h
src/goose/goose_subscriber.h
src/mms/iso_mms/client/mms_client_connection.h
src/mms/iso_client/iso_client_connection.h
src/hal/socket/socket.h
)
IF(WIN32)
include_directories(
src/vs
)
ENDIF(WIN32)
# write the detected stuff to this file
configure_file(config/stack_config.h.cmake ${CMAKE_CURRENT_BINARY_DIR}/config/stack_config.h)
if(BUILD_EXAMPLES)
add_subdirectory(examples)
endif(BUILD_EXAMPLES)
add_subdirectory(src)
INSTALL(FILES ${API_HEADERS} DESTINATION include/libiec61850)

674
COPYING Normal file
View File

@ -0,0 +1,674 @@
GNU GENERAL PUBLIC LICENSE
Version 3, 29 June 2007
Copyright (C) 2007 Free Software Foundation, Inc. <http://fsf.org/>
Everyone is permitted to copy and distribute verbatim copies
of this license document, but changing it is not allowed.
Preamble
The GNU General Public License is a free, copyleft license for
software and other kinds of works.
The licenses for most software and other practical works are designed
to take away your freedom to share and change the works. By contrast,
the GNU General Public License is intended to guarantee your freedom to
share and change all versions of a program--to make sure it remains free
software for all its users. We, the Free Software Foundation, use the
GNU General Public License for most of our software; it applies also to
any other work released this way by its authors. You can apply it to
your programs, too.
When we speak of free software, we are referring to freedom, not
price. Our General Public Licenses are designed to make sure that you
have the freedom to distribute copies of free software (and charge for
them if you wish), that you receive source code or can get it if you
want it, that you can change the software or use pieces of it in new
free programs, and that you know you can do these things.
To protect your rights, we need to prevent others from denying you
these rights or asking you to surrender the rights. Therefore, you have
certain responsibilities if you distribute copies of the software, or if
you modify it: responsibilities to respect the freedom of others.
For example, if you distribute copies of such a program, whether
gratis or for a fee, you must pass on to the recipients the same
freedoms that you received. You must make sure that they, too, receive
or can get the source code. And you must show them these terms so they
know their rights.
Developers that use the GNU GPL protect your rights with two steps:
(1) assert copyright on the software, and (2) offer you this License
giving you legal permission to copy, distribute and/or modify it.
For the developers' and authors' protection, the GPL clearly explains
that there is no warranty for this free software. For both users' and
authors' sake, the GPL requires that modified versions be marked as
changed, so that their problems will not be attributed erroneously to
authors of previous versions.
Some devices are designed to deny users access to install or run
modified versions of the software inside them, although the manufacturer
can do so. This is fundamentally incompatible with the aim of
protecting users' freedom to change the software. The systematic
pattern of such abuse occurs in the area of products for individuals to
use, which is precisely where it is most unacceptable. Therefore, we
have designed this version of the GPL to prohibit the practice for those
products. If such problems arise substantially in other domains, we
stand ready to extend this provision to those domains in future versions
of the GPL, as needed to protect the freedom of users.
Finally, every program is threatened constantly by software patents.
States should not allow patents to restrict development and use of
software on general-purpose computers, but in those that do, we wish to
avoid the special danger that patents applied to a free program could
make it effectively proprietary. To prevent this, the GPL assures that
patents cannot be used to render the program non-free.
The precise terms and conditions for copying, distribution and
modification follow.
TERMS AND CONDITIONS
0. Definitions.
"This License" refers to version 3 of the GNU General Public License.
"Copyright" also means copyright-like laws that apply to other kinds of
works, such as semiconductor masks.
"The Program" refers to any copyrightable work licensed under this
License. Each licensee is addressed as "you". "Licensees" and
"recipients" may be individuals or organizations.
To "modify" a work means to copy from or adapt all or part of the work
in a fashion requiring copyright permission, other than the making of an
exact copy. The resulting work is called a "modified version" of the
earlier work or a work "based on" the earlier work.
A "covered work" means either the unmodified Program or a work based
on the Program.
To "propagate" a work means to do anything with it that, without
permission, would make you directly or secondarily liable for
infringement under applicable copyright law, except executing it on a
computer or modifying a private copy. Propagation includes copying,
distribution (with or without modification), making available to the
public, and in some countries other activities as well.
To "convey" a work means any kind of propagation that enables other
parties to make or receive copies. Mere interaction with a user through
a computer network, with no transfer of a copy, is not conveying.
An interactive user interface displays "Appropriate Legal Notices"
to the extent that it includes a convenient and prominently visible
feature that (1) displays an appropriate copyright notice, and (2)
tells the user that there is no warranty for the work (except to the
extent that warranties are provided), that licensees may convey the
work under this License, and how to view a copy of this License. If
the interface presents a list of user commands or options, such as a
menu, a prominent item in the list meets this criterion.
1. Source Code.
The "source code" for a work means the preferred form of the work
for making modifications to it. "Object code" means any non-source
form of a work.
A "Standard Interface" means an interface that either is an official
standard defined by a recognized standards body, or, in the case of
interfaces specified for a particular programming language, one that
is widely used among developers working in that language.
The "System Libraries" of an executable work include anything, other
than the work as a whole, that (a) is included in the normal form of
packaging a Major Component, but which is not part of that Major
Component, and (b) serves only to enable use of the work with that
Major Component, or to implement a Standard Interface for which an
implementation is available to the public in source code form. A
"Major Component", in this context, means a major essential component
(kernel, window system, and so on) of the specific operating system
(if any) on which the executable work runs, or a compiler used to
produce the work, or an object code interpreter used to run it.
The "Corresponding Source" for a work in object code form means all
the source code needed to generate, install, and (for an executable
work) run the object code and to modify the work, including scripts to
control those activities. However, it does not include the work's
System Libraries, or general-purpose tools or generally available free
programs which are used unmodified in performing those activities but
which are not part of the work. For example, Corresponding Source
includes interface definition files associated with source files for
the work, and the source code for shared libraries and dynamically
linked subprograms that the work is specifically designed to require,
such as by intimate data communication or control flow between those
subprograms and other parts of the work.
The Corresponding Source need not include anything that users
can regenerate automatically from other parts of the Corresponding
Source.
The Corresponding Source for a work in source code form is that
same work.
2. Basic Permissions.
All rights granted under this License are granted for the term of
copyright on the Program, and are irrevocable provided the stated
conditions are met. This License explicitly affirms your unlimited
permission to run the unmodified Program. The output from running a
covered work is covered by this License only if the output, given its
content, constitutes a covered work. This License acknowledges your
rights of fair use or other equivalent, as provided by copyright law.
You may make, run and propagate covered works that you do not
convey, without conditions so long as your license otherwise remains
in force. You may convey covered works to others for the sole purpose
of having them make modifications exclusively for you, or provide you
with facilities for running those works, provided that you comply with
the terms of this License in conveying all material for which you do
not control copyright. Those thus making or running the covered works
for you must do so exclusively on your behalf, under your direction
and control, on terms that prohibit them from making any copies of
your copyrighted material outside their relationship with you.
Conveying under any other circumstances is permitted solely under
the conditions stated below. Sublicensing is not allowed; section 10
makes it unnecessary.
3. Protecting Users' Legal Rights From Anti-Circumvention Law.
No covered work shall be deemed part of an effective technological
measure under any applicable law fulfilling obligations under article
11 of the WIPO copyright treaty adopted on 20 December 1996, or
similar laws prohibiting or restricting circumvention of such
measures.
When you convey a covered work, you waive any legal power to forbid
circumvention of technological measures to the extent such circumvention
is effected by exercising rights under this License with respect to
the covered work, and you disclaim any intention to limit operation or
modification of the work as a means of enforcing, against the work's
users, your or third parties' legal rights to forbid circumvention of
technological measures.
4. Conveying Verbatim Copies.
You may convey verbatim copies of the Program's source code as you
receive it, in any medium, provided that you conspicuously and
appropriately publish on each copy an appropriate copyright notice;
keep intact all notices stating that this License and any
non-permissive terms added in accord with section 7 apply to the code;
keep intact all notices of the absence of any warranty; and give all
recipients a copy of this License along with the Program.
You may charge any price or no price for each copy that you convey,
and you may offer support or warranty protection for a fee.
5. Conveying Modified Source Versions.
You may convey a work based on the Program, or the modifications to
produce it from the Program, in the form of source code under the
terms of section 4, provided that you also meet all of these conditions:
a) The work must carry prominent notices stating that you modified
it, and giving a relevant date.
b) The work must carry prominent notices stating that it is
released under this License and any conditions added under section
7. This requirement modifies the requirement in section 4 to
"keep intact all notices".
c) You must license the entire work, as a whole, under this
License to anyone who comes into possession of a copy. This
License will therefore apply, along with any applicable section 7
additional terms, to the whole of the work, and all its parts,
regardless of how they are packaged. This License gives no
permission to license the work in any other way, but it does not
invalidate such permission if you have separately received it.
d) If the work has interactive user interfaces, each must display
Appropriate Legal Notices; however, if the Program has interactive
interfaces that do not display Appropriate Legal Notices, your
work need not make them do so.
A compilation of a covered work with other separate and independent
works, which are not by their nature extensions of the covered work,
and which are not combined with it such as to form a larger program,
in or on a volume of a storage or distribution medium, is called an
"aggregate" if the compilation and its resulting copyright are not
used to limit the access or legal rights of the compilation's users
beyond what the individual works permit. Inclusion of a covered work
in an aggregate does not cause this License to apply to the other
parts of the aggregate.
6. Conveying Non-Source Forms.
You may convey a covered work in object code form under the terms
of sections 4 and 5, provided that you also convey the
machine-readable Corresponding Source under the terms of this License,
in one of these ways:
a) Convey the object code in, or embodied in, a physical product
(including a physical distribution medium), accompanied by the
Corresponding Source fixed on a durable physical medium
customarily used for software interchange.
b) Convey the object code in, or embodied in, a physical product
(including a physical distribution medium), accompanied by a
written offer, valid for at least three years and valid for as
long as you offer spare parts or customer support for that product
model, to give anyone who possesses the object code either (1) a
copy of the Corresponding Source for all the software in the
product that is covered by this License, on a durable physical
medium customarily used for software interchange, for a price no
more than your reasonable cost of physically performing this
conveying of source, or (2) access to copy the
Corresponding Source from a network server at no charge.
c) Convey individual copies of the object code with a copy of the
written offer to provide the Corresponding Source. This
alternative is allowed only occasionally and noncommercially, and
only if you received the object code with such an offer, in accord
with subsection 6b.
d) Convey the object code by offering access from a designated
place (gratis or for a charge), and offer equivalent access to the
Corresponding Source in the same way through the same place at no
further charge. You need not require recipients to copy the
Corresponding Source along with the object code. If the place to
copy the object code is a network server, the Corresponding Source
may be on a different server (operated by you or a third party)
that supports equivalent copying facilities, provided you maintain
clear directions next to the object code saying where to find the
Corresponding Source. Regardless of what server hosts the
Corresponding Source, you remain obligated to ensure that it is
available for as long as needed to satisfy these requirements.
e) Convey the object code using peer-to-peer transmission, provided
you inform other peers where the object code and Corresponding
Source of the work are being offered to the general public at no
charge under subsection 6d.
A separable portion of the object code, whose source code is excluded
from the Corresponding Source as a System Library, need not be
included in conveying the object code work.
A "User Product" is either (1) a "consumer product", which means any
tangible personal property which is normally used for personal, family,
or household purposes, or (2) anything designed or sold for incorporation
into a dwelling. In determining whether a product is a consumer product,
doubtful cases shall be resolved in favor of coverage. For a particular
product received by a particular user, "normally used" refers to a
typical or common use of that class of product, regardless of the status
of the particular user or of the way in which the particular user
actually uses, or expects or is expected to use, the product. A product
is a consumer product regardless of whether the product has substantial
commercial, industrial or non-consumer uses, unless such uses represent
the only significant mode of use of the product.
"Installation Information" for a User Product means any methods,
procedures, authorization keys, or other information required to install
and execute modified versions of a covered work in that User Product from
a modified version of its Corresponding Source. The information must
suffice to ensure that the continued functioning of the modified object
code is in no case prevented or interfered with solely because
modification has been made.
If you convey an object code work under this section in, or with, or
specifically for use in, a User Product, and the conveying occurs as
part of a transaction in which the right of possession and use of the
User Product is transferred to the recipient in perpetuity or for a
fixed term (regardless of how the transaction is characterized), the
Corresponding Source conveyed under this section must be accompanied
by the Installation Information. But this requirement does not apply
if neither you nor any third party retains the ability to install
modified object code on the User Product (for example, the work has
been installed in ROM).
The requirement to provide Installation Information does not include a
requirement to continue to provide support service, warranty, or updates
for a work that has been modified or installed by the recipient, or for
the User Product in which it has been modified or installed. Access to a
network may be denied when the modification itself materially and
adversely affects the operation of the network or violates the rules and
protocols for communication across the network.
Corresponding Source conveyed, and Installation Information provided,
in accord with this section must be in a format that is publicly
documented (and with an implementation available to the public in
source code form), and must require no special password or key for
unpacking, reading or copying.
7. Additional Terms.
"Additional permissions" are terms that supplement the terms of this
License by making exceptions from one or more of its conditions.
Additional permissions that are applicable to the entire Program shall
be treated as though they were included in this License, to the extent
that they are valid under applicable law. If additional permissions
apply only to part of the Program, that part may be used separately
under those permissions, but the entire Program remains governed by
this License without regard to the additional permissions.
When you convey a copy of a covered work, you may at your option
remove any additional permissions from that copy, or from any part of
it. (Additional permissions may be written to require their own
removal in certain cases when you modify the work.) You may place
additional permissions on material, added by you to a covered work,
for which you have or can give appropriate copyright permission.
Notwithstanding any other provision of this License, for material you
add to a covered work, you may (if authorized by the copyright holders of
that material) supplement the terms of this License with terms:
a) Disclaiming warranty or limiting liability differently from the
terms of sections 15 and 16 of this License; or
b) Requiring preservation of specified reasonable legal notices or
author attributions in that material or in the Appropriate Legal
Notices displayed by works containing it; or
c) Prohibiting misrepresentation of the origin of that material, or
requiring that modified versions of such material be marked in
reasonable ways as different from the original version; or
d) Limiting the use for publicity purposes of names of licensors or
authors of the material; or
e) Declining to grant rights under trademark law for use of some
trade names, trademarks, or service marks; or
f) Requiring indemnification of licensors and authors of that
material by anyone who conveys the material (or modified versions of
it) with contractual assumptions of liability to the recipient, for
any liability that these contractual assumptions directly impose on
those licensors and authors.
All other non-permissive additional terms are considered "further
restrictions" within the meaning of section 10. If the Program as you
received it, or any part of it, contains a notice stating that it is
governed by this License along with a term that is a further
restriction, you may remove that term. If a license document contains
a further restriction but permits relicensing or conveying under this
License, you may add to a covered work material governed by the terms
of that license document, provided that the further restriction does
not survive such relicensing or conveying.
If you add terms to a covered work in accord with this section, you
must place, in the relevant source files, a statement of the
additional terms that apply to those files, or a notice indicating
where to find the applicable terms.
Additional terms, permissive or non-permissive, may be stated in the
form of a separately written license, or stated as exceptions;
the above requirements apply either way.
8. Termination.
You may not propagate or modify a covered work except as expressly
provided under this License. Any attempt otherwise to propagate or
modify it is void, and will automatically terminate your rights under
this License (including any patent licenses granted under the third
paragraph of section 11).
However, if you cease all violation of this License, then your
license from a particular copyright holder is reinstated (a)
provisionally, unless and until the copyright holder explicitly and
finally terminates your license, and (b) permanently, if the copyright
holder fails to notify you of the violation by some reasonable means
prior to 60 days after the cessation.
Moreover, your license from a particular copyright holder is
reinstated permanently if the copyright holder notifies you of the
violation by some reasonable means, this is the first time you have
received notice of violation of this License (for any work) from that
copyright holder, and you cure the violation prior to 30 days after
your receipt of the notice.
Termination of your rights under this section does not terminate the
licenses of parties who have received copies or rights from you under
this License. If your rights have been terminated and not permanently
reinstated, you do not qualify to receive new licenses for the same
material under section 10.
9. Acceptance Not Required for Having Copies.
You are not required to accept this License in order to receive or
run a copy of the Program. Ancillary propagation of a covered work
occurring solely as a consequence of using peer-to-peer transmission
to receive a copy likewise does not require acceptance. However,
nothing other than this License grants you permission to propagate or
modify any covered work. These actions infringe copyright if you do
not accept this License. Therefore, by modifying or propagating a
covered work, you indicate your acceptance of this License to do so.
10. Automatic Licensing of Downstream Recipients.
Each time you convey a covered work, the recipient automatically
receives a license from the original licensors, to run, modify and
propagate that work, subject to this License. You are not responsible
for enforcing compliance by third parties with this License.
An "entity transaction" is a transaction transferring control of an
organization, or substantially all assets of one, or subdividing an
organization, or merging organizations. If propagation of a covered
work results from an entity transaction, each party to that
transaction who receives a copy of the work also receives whatever
licenses to the work the party's predecessor in interest had or could
give under the previous paragraph, plus a right to possession of the
Corresponding Source of the work from the predecessor in interest, if
the predecessor has it or can get it with reasonable efforts.
You may not impose any further restrictions on the exercise of the
rights granted or affirmed under this License. For example, you may
not impose a license fee, royalty, or other charge for exercise of
rights granted under this License, and you may not initiate litigation
(including a cross-claim or counterclaim in a lawsuit) alleging that
any patent claim is infringed by making, using, selling, offering for
sale, or importing the Program or any portion of it.
11. Patents.
A "contributor" is a copyright holder who authorizes use under this
License of the Program or a work on which the Program is based. The
work thus licensed is called the contributor's "contributor version".
A contributor's "essential patent claims" are all patent claims
owned or controlled by the contributor, whether already acquired or
hereafter acquired, that would be infringed by some manner, permitted
by this License, of making, using, or selling its contributor version,
but do not include claims that would be infringed only as a
consequence of further modification of the contributor version. For
purposes of this definition, "control" includes the right to grant
patent sublicenses in a manner consistent with the requirements of
this License.
Each contributor grants you a non-exclusive, worldwide, royalty-free
patent license under the contributor's essential patent claims, to
make, use, sell, offer for sale, import and otherwise run, modify and
propagate the contents of its contributor version.
In the following three paragraphs, a "patent license" is any express
agreement or commitment, however denominated, not to enforce a patent
(such as an express permission to practice a patent or covenant not to
sue for patent infringement). To "grant" such a patent license to a
party means to make such an agreement or commitment not to enforce a
patent against the party.
If you convey a covered work, knowingly relying on a patent license,
and the Corresponding Source of the work is not available for anyone
to copy, free of charge and under the terms of this License, through a
publicly available network server or other readily accessible means,
then you must either (1) cause the Corresponding Source to be so
available, or (2) arrange to deprive yourself of the benefit of the
patent license for this particular work, or (3) arrange, in a manner
consistent with the requirements of this License, to extend the patent
license to downstream recipients. "Knowingly relying" means you have
actual knowledge that, but for the patent license, your conveying the
covered work in a country, or your recipient's use of the covered work
in a country, would infringe one or more identifiable patents in that
country that you have reason to believe are valid.
If, pursuant to or in connection with a single transaction or
arrangement, you convey, or propagate by procuring conveyance of, a
covered work, and grant a patent license to some of the parties
receiving the covered work authorizing them to use, propagate, modify
or convey a specific copy of the covered work, then the patent license
you grant is automatically extended to all recipients of the covered
work and works based on it.
A patent license is "discriminatory" if it does not include within
the scope of its coverage, prohibits the exercise of, or is
conditioned on the non-exercise of one or more of the rights that are
specifically granted under this License. You may not convey a covered
work if you are a party to an arrangement with a third party that is
in the business of distributing software, under which you make payment
to the third party based on the extent of your activity of conveying
the work, and under which the third party grants, to any of the
parties who would receive the covered work from you, a discriminatory
patent license (a) in connection with copies of the covered work
conveyed by you (or copies made from those copies), or (b) primarily
for and in connection with specific products or compilations that
contain the covered work, unless you entered into that arrangement,
or that patent license was granted, prior to 28 March 2007.
Nothing in this License shall be construed as excluding or limiting
any implied license or other defenses to infringement that may
otherwise be available to you under applicable patent law.
12. No Surrender of Others' Freedom.
If conditions are imposed on you (whether by court order, agreement or
otherwise) that contradict the conditions of this License, they do not
excuse you from the conditions of this License. If you cannot convey a
covered work so as to satisfy simultaneously your obligations under this
License and any other pertinent obligations, then as a consequence you may
not convey it at all. For example, if you agree to terms that obligate you
to collect a royalty for further conveying from those to whom you convey
the Program, the only way you could satisfy both those terms and this
License would be to refrain entirely from conveying the Program.
13. Use with the GNU Affero General Public License.
Notwithstanding any other provision of this License, you have
permission to link or combine any covered work with a work licensed
under version 3 of the GNU Affero General Public License into a single
combined work, and to convey the resulting work. The terms of this
License will continue to apply to the part which is the covered work,
but the special requirements of the GNU Affero General Public License,
section 13, concerning interaction through a network will apply to the
combination as such.
14. Revised Versions of this License.
The Free Software Foundation may publish revised and/or new versions of
the GNU General Public License from time to time. Such new versions will
be similar in spirit to the present version, but may differ in detail to
address new problems or concerns.
Each version is given a distinguishing version number. If the
Program specifies that a certain numbered version of the GNU General
Public License "or any later version" applies to it, you have the
option of following the terms and conditions either of that numbered
version or of any later version published by the Free Software
Foundation. If the Program does not specify a version number of the
GNU General Public License, you may choose any version ever published
by the Free Software Foundation.
If the Program specifies that a proxy can decide which future
versions of the GNU General Public License can be used, that proxy's
public statement of acceptance of a version permanently authorizes you
to choose that version for the Program.
Later license versions may give you additional or different
permissions. However, no additional obligations are imposed on any
author or copyright holder as a result of your choosing to follow a
later version.
15. Disclaimer of Warranty.
THERE IS NO WARRANTY FOR THE PROGRAM, TO THE EXTENT PERMITTED BY
APPLICABLE LAW. EXCEPT WHEN OTHERWISE STATED IN WRITING THE COPYRIGHT
HOLDERS AND/OR OTHER PARTIES PROVIDE THE PROGRAM "AS IS" WITHOUT WARRANTY
OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING, BUT NOT LIMITED TO,
THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
PURPOSE. THE ENTIRE RISK AS TO THE QUALITY AND PERFORMANCE OF THE PROGRAM
IS WITH YOU. SHOULD THE PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF
ALL NECESSARY SERVICING, REPAIR OR CORRECTION.
16. Limitation of Liability.
IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING
WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MODIFIES AND/OR CONVEYS
THE PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES, INCLUDING ANY
GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING OUT OF THE
USE OR INABILITY TO USE THE PROGRAM (INCLUDING BUT NOT LIMITED TO LOSS OF
DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY YOU OR THIRD
PARTIES OR A FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER PROGRAMS),
EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE POSSIBILITY OF
SUCH DAMAGES.
17. Interpretation of Sections 15 and 16.
If the disclaimer of warranty and limitation of liability provided
above cannot be given local legal effect according to their terms,
reviewing courts shall apply local law that most closely approximates
an absolute waiver of all civil liability in connection with the
Program, unless a warranty or assumption of liability accompanies a
copy of the Program in return for a fee.
END OF TERMS AND CONDITIONS
How to Apply These Terms to Your New Programs
If you develop a new program, and you want it to be of the greatest
possible use to the public, the best way to achieve this is to make it
free software which everyone can redistribute and change under these terms.
To do so, attach the following notices to the program. It is safest
to attach them to the start of each source file to most effectively
state the exclusion of warranty; and each file should have at least
the "copyright" line and a pointer to where the full notice is found.
<one line to give the program's name and a brief idea of what it does.>
Copyright (C) <year> <name of author>
This program is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program. If not, see <http://www.gnu.org/licenses/>.
Also add information on how to contact you by electronic and paper mail.
If the program does terminal interaction, make it output a short
notice like this when it starts in an interactive mode:
<program> Copyright (C) <year> <name of author>
This program comes with ABSOLUTELY NO WARRANTY; for details type `show w'.
This is free software, and you are welcome to redistribute it
under certain conditions; type `show c' for details.
The hypothetical commands `show w' and `show c' should show the appropriate
parts of the General Public License. Of course, your program's commands
might be different; for a GUI interface, you would use an "about box".
You should also get your employer (if you work as a programmer) or school,
if any, to sign a "copyright disclaimer" for the program, if necessary.
For more information on this, and how to apply and follow the GNU GPL, see
<http://www.gnu.org/licenses/>.
The GNU General Public License does not permit incorporating your program
into proprietary programs. If your program is a subroutine library, you
may consider it more useful to permit linking proprietary applications with
the library. If this is what you want to do, use the GNU Lesser General
Public License instead of this License. But first, please read
<http://www.gnu.org/philosophy/why-not-lgpl.html>.

177
Makefile Normal file
View File

@ -0,0 +1,177 @@
LIBIEC_HOME=.
include make/target_system.mk
LIB_SOURCE_DIRS = src/mms/iso_acse
LIB_SOURCE_DIRS += src/mms/iso_acse/asn1c
LIB_SOURCE_DIRS += src/mms/iso_presentation/asn1c
LIB_SOURCE_DIRS += src/mms/iso_presentation
LIB_SOURCE_DIRS += src/mms/iso_session
LIB_SOURCE_DIRS += src/common
LIB_SOURCE_DIRS += src/mms/asn1
LIB_SOURCE_DIRS += src/mms/iso_cotp
LIB_SOURCE_DIRS += src/mms/iso_mms/server
LIB_SOURCE_DIRS += src/mms/iso_mms/client
LIB_SOURCE_DIRS += src/mms/iso_client/impl
LIB_SOURCE_DIRS += src/mms/iso_common
LIB_SOURCE_DIRS += src/mms/iso_mms/common
LIB_SOURCE_DIRS += src/mms/iso_mms/asn1c
LIB_SOURCE_DIRS += src/mms/iso_server
ifndef EXCLUDE_ETHERNET_WINDOWS
LIB_SOURCE_DIRS += src/goose
endif
LIB_SOURCE_DIRS += src/iedclient/impl
LIB_SOURCE_DIRS += src/iedcommon
LIB_SOURCE_DIRS += src/iedserver
LIB_SOURCE_DIRS += src/iedserver/model
LIB_SOURCE_DIRS += src/iedserver/mms_mapping
LIB_SOURCE_DIRS += src/iedserver/impl
LIB_SOURCE_DIRS += src/hal
ifeq ($(HAL_IMPL), WIN32)
LIB_SOURCE_DIRS += src/hal/socket/win32
LIB_SOURCE_DIRS += src/hal/thread/win32
LIB_SOURCE_DIRS += src/hal/ethernet/win32
LIB_SOURCE_DIRS += src/hal/filesystem/win32
LIB_SOURCE_DIRS += src/hal/time/win32
else ifeq ($(HAL_IMPL), POSIX)
LIB_SOURCE_DIRS += src/hal/socket/linux
LIB_SOURCE_DIRS += src/hal/thread/linux
LIB_SOURCE_DIRS += src/hal/ethernet/linux
LIB_SOURCE_DIRS += src/hal/filesystem/linux
LIB_SOURCE_DIRS += src/hal/time/unix
else ifeq ($(HAL_IMPL), BSD)
LIB_SOURCE_DIRS += src/hal/socket/bsd
LIB_SOURCE_DIRS += src/hal/thread/linux
LIB_SOURCE_DIRS += src/hal/ethernet/bsd
LIB_SOURCE_DIRS += src/hal/filesystem/linux
LIB_SOURCE_DIRS += src/hal/time/unix
endif
LIB_INCLUDE_DIRS += src/mms/iso_presentation
LIB_INCLUDE_DIRS += src/mms/iso_session
LIB_INCLUDE_DIRS += src/mms/iso_cotp
LIB_INCLUDE_DIRS += src/mms/iso_acse
LIB_INCLUDE_DIRS += config
LIB_INCLUDE_DIRS += src/mms/asn1
LIB_INCLUDE_DIRS += src/mms/iso_client
LIB_INCLUDE_DIRS += src/mms/iso_mms/server
LIB_INCLUDE_DIRS += src/mms/iso_mms/common
LIB_INCLUDE_DIRS += src/mms/iso_mms/client
LIB_INCLUDE_DIRS += src/mms/iso_mms/asn1c
LIB_INCLUDE_DIRS += src/common
LIB_INCLUDE_DIRS += src/hal/socket
LIB_INCLUDE_DIRS += src/hal/thread
LIB_INCLUDE_DIRS += src/hal/ethernet
LIB_INCLUDE_DIRS += src/hal/filesystem
LIB_INCLUDE_DIRS += src/hal/time
LIB_INCLUDE_DIRS += src/hal
LIB_INCLUDE_DIRS += src/goose
LIB_INCLUDE_DIRS += src/mms/iso_server
LIB_INCLUDE_DIRS += src/mms/iso_common
LIB_INCLUDE_DIRS += src/iedclient
LIB_INCLUDE_DIRS += src/iedcommon
LIB_INCLUDE_DIRS += src/iedserver
LIB_INCLUDE_DIRS += src/iedserver/model
LIB_INCLUDE_DIRS += src/iedserver/mms_mapping
LIB_INCLUDE_DIRS += src/iedserver/impl
ifeq ($(HAL_IMPL), WIN32)
LIB_INCLUDE_DIRS += third_party/winpcap/Include
endif
LIB_INCLUDES = $(addprefix -I,$(LIB_INCLUDE_DIRS))
ifndef INSTALL_PREFIX
INSTALL_PREFIX = ./.install
endif
LIB_API_HEADER_FILES = src/hal/time/time_hal.h
LIB_API_HEADER_FILES += src/hal/ethernet/ethernet.h
LIB_API_HEADER_FILES += src/hal/thread/thread.h
LIB_API_HEADER_FILES += src/hal/filesystem/filesystem.h
LIB_API_HEADER_FILES += src/common/libiec61850_common_api.h
LIB_API_HEADER_FILES += src/common/linked_list.h
LIB_API_HEADER_FILES += src/common/byte_buffer.h
LIB_API_HEADER_FILES += src/iedclient/iec61850_client.h
LIB_API_HEADER_FILES += src/iedcommon/iec61850_common.h
LIB_API_HEADER_FILES += src/iedserver/iec61850_server.h
LIB_API_HEADER_FILES += src/iedserver/model/model.h
LIB_API_HEADER_FILES += src/iedserver/model/cdc.h
LIB_API_HEADER_FILES += src/iedserver/model/dynamic_model.h
LIB_API_HEADER_FILES += src/iedserver/model/config_file_parser.h
LIB_API_HEADER_FILES += src/mms/iso_mms/common/mms_value.h
LIB_API_HEADER_FILES += src/mms/iso_mms/common/mms_common.h
LIB_API_HEADER_FILES += src/mms/iso_mms/common/mms_types.h
LIB_API_HEADER_FILES += src/mms/iso_mms/server/mms_device_model.h
LIB_API_HEADER_FILES += src/mms/iso_mms/server/mms_server.h
LIB_API_HEADER_FILES += src/mms/iso_mms/server/mms_named_variable_list.h
LIB_API_HEADER_FILES += src/mms/iso_mms/common/mms_type_spec.h
LIB_API_HEADER_FILES += src/mms/asn1/ber_integer.h
LIB_API_HEADER_FILES += src/mms/asn1/asn1_ber_primitive_value.h
LIB_API_HEADER_FILES += src/mms/iso_server/iso_server.h
LIB_API_HEADER_FILES += src/mms/iso_common/iso_connection_parameters.h
LIB_API_HEADER_FILES += src/goose/goose_subscriber.h
LIB_API_HEADER_FILES += src/mms/iso_mms/client/mms_client_connection.h
LIB_API_HEADER_FILES += src/mms/iso_client/iso_client_connection.h
LIB_API_HEADER_FILES += src/hal/socket/socket.h
get_sources_from_directory = $(wildcard $1/*.c)
get_sources = $(foreach dir, $1, $(call get_sources_from_directory,$(dir)))
src_to = $(addprefix $(LIB_OBJS_DIR)/,$(subst .c,$1,$2))
LIB_SOURCES = $(call get_sources,$(LIB_SOURCE_DIRS))
LIB_OBJS = $(call src_to,.o,$(LIB_SOURCES))
CFLAGS += -std=gnu99
#CFLAGS += -Wno-error=format
CFLAGS += -Wstrict-prototypes
CFLAGS += -Wuninitialized
CFLAGS += -Wsign-compare
CFLAGS += -Wpointer-arith
CFLAGS += -Wnested-externs
CFLAGS += -Wmissing-declarations
CFLAGS += -Wshadow
CFLAGS += -Wall
#CFLAGS += -Werror
all: lib
static_checks: lib
splint -preproc +posixlib +skip-sys-headers +gnuextensions $(LIB_INCLUDES) $(LIB_SOURCES)
cppcheck: lib
cppcheck --force --std=c99 --enable=all $(LIB_INCLUDES) $(LIB_SOURCES) 2> cppcheck-output.xml
lib: $(LIB_NAME)
dynlib: CFLAGS += -fPIC
dynlib: $(DYN_LIB_NAME)
.PHONY: examples
examples:
cd examples; $(MAKE)
$(LIB_NAME): $(LIB_OBJS)
$(AR) r $(LIB_NAME) $(LIB_OBJS)
$(RANLIB) $(LIB_NAME)
$(DYN_LIB_NAME): $(LIB_OBJS)
$(CC) $(LDFLAGS) $(DYNLIB_LDFLAGS) -shared -o $(DYN_LIB_NAME) $(LIB_OBJS) $(LDLIBS)
$(LIB_OBJS_DIR)/%.o: %.c config
@echo compiling $(notdir $<)
$(SILENCE)mkdir -p $(dir $@)
$(CC) $(CFLAGS) -c $(LIB_INCLUDES) $(OUTPUT_OPTION) $<
install: $(LIB_NAME)
mkdir -p $(INSTALL_PREFIX)/include
mkdir -p $(INSTALL_PREFIX)/lib
cp $(LIB_API_HEADER_FILES) $(INSTALL_PREFIX)/include
cp $(LIB_NAME) $(INSTALL_PREFIX)/lib
clean:
rm -f $(EXAMPLES)
rm -rf $(LIB_OBJS_DIR)

103
README Normal file
View File

@ -0,0 +1,103 @@
README:
-------
This file is part of the documentation of libiec61850. More documentation can be found online at http://libiec61850.com or in the provided doxygen documentation.
Content:
- Overview
- Building and running the examples
- Installing the library and the API headers
- Building on Windows with GOOSE support
- Building with the cmake build script
- C# client API
- Licensing
- Third-party contributions
Overview
---------
libiec61850 is an open-source (GPLv3) implementation of an IEC 61850 client and server library. It is implemented in C (according to the C99 standard) to provide maximum portability. It can be used to implement IEC 61850 compliant client and server applications on embedded systems and PCs running Linux and Windows. Included is a set of simple example applications that can be used as a starting point to implement own IEC 61850 compliant devices or to communicate with IEC 61850 devices.
Building and running the examples
----------------------------------------
In the project root directoy type
> make examples
If the build succeeds you can find a few binary files in the projects root directory. You can also find a binary version of the library ("libiec61850.a") in the "build" directory.
Run the sample applications in the example folders. E.g.:
> cd examples/server_example1
> sudo ./server_example1
on the Linux command line.
You can test the server examples by using a generic client or the provided client example applications.
Installing the library and the API headers
--------------------------------------------
The make and cmake build scripts provide an install target. This target copies the API header files and the static library to a single directory for the headers (INSTALL_PREFIX/include) and the static library (INSTALL_PREFIX/lib). With this feature it is more easy to integrate libiec61850 in an external application since you only have to add a simple include directory to the build tool of your choice.
This can be invoked with
make install
The default install directory for the make build script is ".install".
You can modify this by setting the INSTALL_PREFIX environment variable (e.g.):
make INSTALL_PREFIX=/usr/local install
For the cmake build script you have to provide the CMAKE_INSTALL_PREFIX variable
Building on windows with GOOSE support
---------------------------------------
To build the library and run libiec61850 applications with GOOSE support on Windows (7/8) the use of a third-party library (winpcap) is required. This is necessary because current versions of Windows have no working support for raw sockets. You can download winpcap here (http://www.winpcap.org).
1. Download and install winpcap. Make sure that the winpcap driver is loaded at boot time (you can choose this option at the last screen of the winpcap installer).
2. Reboot the system (you can do this also later, but you need to reboot or load the winpcap driver before running any llibiec61850 applications that use GOOSE).
3. Download the winpcap developers pack from here (http://www.winpcap.org/install/bin/WpdPack_4_1_2.zip)
4. Unpack the zip file. Copy the folders Lib and Include from the WpdPack directory in the third_party/winpcap directory of libiec61850
Building with the cmake build script
-------------------------------------
With the help of the cmake build script it is possible to create platform independet project descriptions and let cmake create specific project or build files for other tools like Make or Visual Studio.
If you have cmake installed fire up a command line (cmd.exe) and create a new subdirectory in the libiec61850-0.x folder. Change to this subdirectory. Then you can invoke cmake. As an command line argument you have to supply a "generator" that is used by cmake to create the project file for the actual build tool (in our case Visual Studio).
cmake -G "Visual Studio 11" ..
will instruct cmake to create a "solution" for Visual Studio 2012. To do the same thing for Visual Studio 2010 type
cmake -G "Visual Studio 10" ..
Note: The ".." at the end of the command line tells cmake where to find the main build script file (called CMakeLists.txt). This should point to the folder libiec61850-0.x which is in our case the parent directory (..).
To select some configuration options you can use ccmake or cmake-gui.
C# client API
--------------
A C#/.NET wrapper and examples and Visual Studio/MonoDevelop project files can be found in the dotnet folder. The examples and the C# wrapper API can be build and run on .NET or Mono.
Commercial licenses
-------------------
Commercial licensing and support options are provided by MZ Automation GmbH. Please contact info@mz-automation.de for more details.
Third-party contributions:
--------------------------
- The Mac OS X socket and ethernet layer has been kindly contributed by Michael Clausen, HES-SO Valais-Wallis, http://www.hevs.ch

143
config/stack_config.h Normal file
View File

@ -0,0 +1,143 @@
/*
* config.h
*
* Contains global defines to configure the stack. You need to recompile the stack to make
* changes effective (make clean; make)
*
*/
#ifndef STACK_CONFIG_H_
#define STACK_CONFIG_H_
/* include asserts if set to 1 */
#define DEBUG 0
/* print debugging information with printf if set to 1 */
#define DEBUG_COTP 0
#define DEBUG_ISO_SERVER 0
#define DEBUG_ISO_CLIENT 0
#define DEBUG_IED_SERVER 0
#define DEBUG_IED_CLIENT 0
#define DEBUG_MMS_CLIENT 0
#define DEBUG_MMS_SERVER 0
/* Maximum MMS PDU SIZE - default is 65000 */
#define CONFIG_MMS_MAXIMUM_PDU_SIZE 65000
/* number of concurrent MMS client connections the server accepts, -1 for no limit */
#define CONFIG_MAXIMUM_TCP_CLIENT_CONNECTIONS 5
/* activate TCP keep alive mechanism. 1 -> activate */
#define CONFIG_ACTIVATE_TCP_KEEPALIVE 1
/* time (in s) between last message and first keepalive message */
#define CONFIG_TCP_KEEPALIVE_IDLE 5
/* time between subsequent keepalive messages if no ack received */
#define CONFIG_TCP_KEEPALIVE_INTERVAL 2
/* number of not missing keepalive responses until socket is considered dead */
#define CONFIG_TCP_KEEPALIVE_CNT 2
/* maximum COTP (ISO 8073) TPDU size - valid range is 1024 - 8192 */
#define CONFIG_COTP_MAX_TPDU_SIZE 8192
/* timeout while reading from TCP stream in ms */
#define CONFIG_TCP_READ_TIMEOUT_MS 1000
/* Ethernet interface ID for GOOSE and SV */
#define CONFIG_ETHERNET_INTERFACE_ID "eth0"
//#define CONFIG_ETHERNET_INTERFACE_ID "vboxnet0"
//#define CONFIG_ETHERNET_INTERFACE_ID "en0" // OS X uses enX in place of ethX as ethernet NIC names.
/* Set to 1 to include GOOSE support in the build. Otherwise set to 0 */
#define CONFIG_INCLUDE_GOOSE_SUPPORT 1
#ifdef _WIN32
/* GOOSE will be disabled for Windows if ethernet support (winpcap) is not available */
#ifdef EXCLUDE_ETHERNET_WINDOWS
#ifdef CONFIG_INCLUDE_GOOSE_SUPPORT
#undef CONFIG_INCLUDE_GOOSE_SUPPORT
#endif
#define CONFIG_INCLUDE_GOOSE_SUPPORT 0
#define CONFIG_INCUDE_ETHERNET_WINDOWS 0
#else
#define CONFIG_INCLUDE_ETHERNET_WINDOWS 1
#undef CONFIG_ETHERNET_INTERFACE_ID
#define CONFIG_ETHERNET_INTERFACE_ID "0"
#endif
#endif
/* The GOOSE retransmission interval in ms for the stable condition - i.e. no monitored value changed */
#define CONFIG_GOOSE_STABLE_STATE_TRANSMISSION_INTERVAL 5000
/* The GOOSE retransmission interval in ms in the case an event happens. */
#define CONFIG_GOOSE_EVENT_RETRANSMISSION_INTERVAL 500
/* The number of GOOSE retransmissions after an event */
#define CONFIG_GOOSE_EVENT_RETRANSMISSION_COUNT 2
/* The default value for the priority field of the 802.1Q header (allowed range 0-7) */
#define CONFIG_GOOSE_DEFAULT_PRIORITY 4
/* The default value for the VLAN ID field of the 802.1Q header - the allowed range is 2-4096 or 0 if VLAN/priority is not used */
#define CONFIG_GOOSE_DEFAULT_VLAN_ID 0
/* Configure the 16 bit APPID field in the GOOSE header */
#define CONFIG_GOOSE_DEFAULT_APPID 0x1000
/* Default destination MAC address for GOOSE */
#define CONFIG_GOOSE_DEFAULT_DST_ADDRESS {0x01, 0x0c, 0xcd, 0x01, 0x00, 0x01}
/* include support for IEC 61850 control services */
#define CONFIG_IEC61850_CONTROL_SERVICE 1
/* The default select timeout in ms. This will apply only if no sboTimeout attribute exists for a control object. Set to 0 for no timeout. */
#define CONFIG_CONTROL_DEFAULT_SBO_TIMEOUT 15000
/* include support for IEC 61850 reporting services */
#define CONFIG_IEC61850_REPORT_SERVICE 1
/* The default buffer size of buffered RCBs in bytes */
#define CONFIG_REPORTING_DEFAULT_REPORT_BUFFER_SIZE 65536
/* default results for MMS identify service */
#define CONFIG_DEFAULT_MMS_VENDOR_NAME "libiec61850.com"
#define CONFIG_DEFAULT_MMS_MODEL_NAME "LIBIEC61850"
#define CONFIG_DEFAULT_MMS_REVISION "0.7.8"
/* MMS virtual file store base path - where file services are looking for files */
#define CONFIG_VIRTUAL_FILESTORE_BASEPATH "./vmd-filestore/"
/* Maximum number of open file per MMS connection (for MMS file read service) */
#define CONFIG_MMS_MAX_NUMBER_OF_OPEN_FILES_PER_CONNECTION 5
/* Definition of supported services */
#define MMS_DEFAULT_PROFILE 1
#if (MMS_DEFAULT_PROFILE == 1)
#define MMS_READ_SERVICE 1
#define MMS_WRITE_SERVICE 1
#define MMS_GET_NAME_LIST 1
#define MMS_GET_VARIABLE_ACCESS_ATTRIBUTES 1
#define MMS_DATA_SET_SERVICE 1
#define MMS_DYNAMIC_DATA_SETS 1
#define MMS_GET_DATA_SET_ATTRIBUTES 1
#define MMS_STATUS_SERVICE 1
#define MMS_IDENTIFY_SERVICE 1
#define MMS_FILE_SERVICE 1
#endif /* MMS_DEFAULT_PROFILE */
#if (MMS_WRITE_SERVICE != 1)
#undef CONFIG_IEC61850_CONTROL_SERVICE
#define CONFIG_IEC61850_CONTROL_SERVICE 0
#endif
/* support flatted named variable name space required by IEC 61850-8-1 MMS mapping */
#define CONFIG_MMS_SUPPORT_FLATTED_NAME_SPACE 1
/* VMD scope named variables are not used by IEC 61850 */
#define CONFIG_MMS_SUPPORT_VMD_SCOPE_NAMED_VARIABLES 0
#endif /* STACK_CONFIG_H_ */

149
config/stack_config.h.cmake Normal file
View File

@ -0,0 +1,149 @@
/*
* config.h (template for cmake)
*
* Contains global defines to configure the stack. You need to recompile the stack to make
* changes effective (make clean; make)
*
*/
#ifndef STACK_CONFIG_H_
#define STACK_CONFIG_H_
/* set to 0 for a little-endian target, 1 for a big-endian target */
#cmakedefine01 PLATFORM_IS_BIGENDIAN
/* define if the system supports clock_gettime */
#cmakedefine CONFIG_SYSTEM_HAS_CLOCK_GETTIME
/* include asserts if set to 1 */
#cmakedefine01 DEBUG
/* print debugging information with printf if set to 1 */
#cmakedefine01 DEBUG_COTP
#cmakedefine01 DEBUG_ISO_SERVER
#cmakedefine01 DEBUG_ISO_CLIENT
#cmakedefine01 DEBUG_IED_SERVER
#cmakedefine01 DEBUG_IED_CLIENT
#cmakedefine01 DEBUG_MMS_CLIENT
#cmakedefine01 DEBUG_MMS_SERVER
/* Maximum MMS PDU SIZE - default is 65000 */
#cmakedefine CONFIG_MMS_MAXIMUM_PDU_SIZE @CONFIG_MMS_MAXIMUM_PDU_SIZE@
/* number of concurrent MMS client connections the server accepts, -1 for no limit */
#cmakedefine CONFIG_MAXIMUM_TCP_CLIENT_CONNECTIONS @CONFIG_MAXIMUM_TCP_CLIENT_CONNECTIONS@
/* activate TCP keep alive mechanism. 1 -> activate */
#cmakedefine01 CONFIG_ACTIVATE_TCP_KEEPALIVE
/* time (in s) between last message and first keepalive message */
#define CONFIG_TCP_KEEPALIVE_IDLE 5
/* time between subsequent keepalive messages if no ack received */
#define CONFIG_TCP_KEEPALIVE_INTERVAL 2
/* number of not missing keepalive responses until socket is considered dead */
#define CONFIG_TCP_KEEPALIVE_CNT 2
/* maximum COTP (ISO 8073) TPDU size - valid range is 1024 - 8192 */
#define CONFIG_COTP_MAX_TPDU_SIZE 8192
/* timeout while reading from TCP stream in ms */
#define CONFIG_TCP_READ_TIMEOUT_MS 1000
/* Ethernet interface ID for GOOSE and SV */
//#define CONFIG_ETHERNET_INTERFACE_ID "eth0"
//#define CONFIG_ETHERNET_INTERFACE_ID "vboxnet0"
#define CONFIG_ETHERNET_INTERFACE_ID "en0" // OS X uses enX in place of ethX as ethernet NIC names.
/* Set to 1 to include GOOSE support in the build. Otherwise set to 0 */
#cmakedefine01 CONFIG_INCLUDE_GOOSE_SUPPORT
#ifdef _WIN32
/* GOOSE will be disabled for Windows if ethernet support (winpcap) is not available */
#ifdef EXCLUDE_ETHERNET_WINDOWS
#ifdef CONFIG_INCLUDE_GOOSE_SUPPORT
#undef CONFIG_INCLUDE_GOOSE_SUPPORT
#endif
#define CONFIG_INCLUDE_GOOSE_SUPPORT 0
#define CONFIG_INCUDE_ETHERNET_WINDOWS 0
#else
#define CONFIG_INCLUDE_ETHERNET_WINDOWS 1
#undef CONFIG_ETHERNET_INTERFACE_ID
#define CONFIG_ETHERNET_INTERFACE_ID "0"
#endif
#endif
/* The GOOSE retransmission interval in ms for the stable condition - i.e. no monitored value changed */
#define CONFIG_GOOSE_STABLE_STATE_TRANSMISSION_INTERVAL 5000
/* The GOOSE retransmission interval in ms in the case an event happens. */
#define CONFIG_GOOSE_EVENT_RETRANSMISSION_INTERVAL 500
/* The number of GOOSE retransmissions after an event */
#define CONFIG_GOOSE_EVENT_RETRANSMISSION_COUNT 2
/* The default value for the priority field of the 802.1Q header (allowed range 0-7) */
#define CONFIG_GOOSE_DEFAULT_PRIORITY 4
/* The default value for the VLAN ID field of the 802.1Q header - the allowed range is 2-4096 or 0 if VLAN/priority is not used */
#define CONFIG_GOOSE_DEFAULT_VLAN_ID 0
/* Configure the 16 bit APPID field in the GOOSE header */
#define CONFIG_GOOSE_DEFAULT_APPID 0x1000
/* Default destination MAC address for GOOSE */
#define CONFIG_GOOSE_DEFAULT_DST_ADDRESS {0x01, 0x0c, 0xcd, 0x01, 0x00, 0x01}
/* include support for IEC 61850 control services */
#cmakedefine01 CONFIG_IEC61850_CONTROL_SERVICE
/* The default select timeout in ms. This will apply only if no sboTimeout attribute exists for a control object. Set to 0 for no timeout. */
#define CONFIG_CONTROL_DEFAULT_SBO_TIMEOUT 15000
/* include support for IEC 61850 reporting services */
#cmakedefine01 CONFIG_IEC61850_REPORT_SERVICE
/* The default buffer size of buffered RCBs in bytes */
#cmakedefine CONFIG_REPORTING_DEFAULT_REPORT_BUFFER_SIZE @CONFIG_REPORTING_DEFAULT_REPORT_BUFFER_SIZE@
/* default results for MMS identify service */
#define CONFIG_DEFAULT_MMS_VENDOR_NAME "libiec61850.com"
#define CONFIG_DEFAULT_MMS_MODEL_NAME "LIBIEC61850"
#define CONFIG_DEFAULT_MMS_REVISION "${LIB_VERSION_MAJOR}.${LIB_VERSION_MINOR}.${LIB_VERSION_PATCH}"
/* support flatted named variable name space required by IEC 61850-8-1 MMS mapping */
#define CONFIG_MMS_SUPPORT_FLATTED_NAME_SPACE 1
/* VMD scope named variables are not used by IEC 61850 */
#define CONFIG_MMS_SUPPORT_VMD_SCOPE_NAMED_VARIABLES 0
/* MMS virtual file store base path - where file services are looking for files */
#define CONFIG_VIRTUAL_FILESTORE_BASEPATH "./vmd-filestore/"
/* Maximum number of open file per MMS connection (for MMS file read service) */
#define CONFIG_MMS_MAX_NUMBER_OF_OPEN_FILES_PER_CONNECTION 5
/* Definition of supported services */
#define MMS_DEFAULT_PROFILE 1
#if MMS_DEFAULT_PROFILE
#define MMS_READ_SERVICE 1
#define MMS_WRITE_SERVICE 1
#define MMS_GET_NAME_LIST 1
#define MMS_GET_VARIABLE_ACCESS_ATTRIBUTES 1
#define MMS_DATA_SET_SERVICE 1
#define MMS_DYNAMIC_DATA_SETS 1
#define MMS_GET_DATA_SET_ATTRIBUTES 1
#define MMS_STATUS_SERVICE 1
#define MMS_IDENTIFY_SERVICE 1
#define MMS_FILE_SERVICE 1
#endif /* MMS_DEFAULT_PROFILE */
#if (MMS_WRITE_SERVICE != 1)
#undef CONFIG_IEC61850_CONTROL_SERVICE
#define CONFIG_IEC61850_CONTROL_SERVICE 0
#endif
#endif /* STACK_CONFIG_H_ */

View File

@ -0,0 +1,21 @@
include_directories(
.
)
set(beagle_demo_SRCS
beagle_demo.c
static_model.c
)
IF(WIN32)
set_source_files_properties(${beagle_demo_SRCS}
PROPERTIES LANGUAGE CXX)
ENDIF(WIN32)
add_executable(server_example3
${beagle_demo_SRCS}
)
target_link_libraries(server_example3
iec61850
)

26
demos/beaglebone/Makefile Normal file
View File

@ -0,0 +1,26 @@
LIBIEC_HOME=../..
PROJECT_BINARY_NAME = beagle_demo
PROJECT_SOURCES = beagle_demo.c
PROJECT_SOURCES += beaglebone_leds.c
PROJECT_SOURCES += static_model.c
include $(LIBIEC_HOME)/make/target_system.mk
include $(LIBIEC_HOME)/make/stack_includes.mk
all: $(PROJECT_BINARY_NAME)
include $(LIBIEC_HOME)/make/common_targets.mk
LDLIBS += -lm
$(PROJECT_BINARY_NAME): $(PROJECT_SOURCES) $(LIB_NAME)
$(CC) $(CFLAGS) $(LDFLAGS) -o $(PROJECT_BINARY_NAME) $(PROJECT_SOURCES) $(INCLUDES) $(LIB_NAME) $(LDLIBS)
beagle_client: beagle_client.c $(LIB_NAME)
$(CC) $(CFLAGS) $(LDFLAGS) -o beagle_client beagle_client.c $(INCLUDES) $(LIB_NAME) $(LDLIBS)
clean:
rm -f $(PROJECT_BINARY_NAME) beagle_client

View File

@ -0,0 +1,107 @@
/*
* beagle_client.c
*
* Switch LEDs on the BeagleBone
*/
#include "iec61850_client.h"
#include <stdlib.h>
#include <stdio.h>
int main(int argc, char** argv) {
char* hostname;
int tcpPort = 102;
if (argc > 1)
hostname = argv[1];
else
hostname = "localhost";
if (argc > 2)
tcpPort = atoi(argv[2]);
IedClientError error;
IedConnection con = IedConnection_create();
IedConnection_connect(con, &error, hostname, tcpPort);
if (error == IED_ERROR_OK) {
/************************
* Direct control
***********************/
bool led4State = false;
ControlObjectClient controlLED1
= ControlObjectClient_create("beagleGenericIO/GGIO1.SPCSO1", con);
ControlObjectClient controlLED2
= ControlObjectClient_create("beagleGenericIO/GGIO1.SPCSO2", con);
ControlObjectClient controlLED3
= ControlObjectClient_create("beagleGenericIO/GGIO1.SPCSO3", con);
ControlObjectClient controlLED4
= ControlObjectClient_create("beagleGenericIO/GGIO1.DPCSO1", con);
MmsValue* ctlValOn = MmsValue_newBoolean(true);
MmsValue* ctlValOff = MmsValue_newBoolean(false);
if (!ControlObjectClient_operate(controlLED1, ctlValOff, 0)) goto control_error;
if (!ControlObjectClient_operate(controlLED2, ctlValOff, 0)) goto control_error;
if (!ControlObjectClient_operate(controlLED4, ctlValOff, 0)) goto control_error;
while (1) {
if (!ControlObjectClient_operate(controlLED3, ctlValOff, 0)) goto control_error;
if (!ControlObjectClient_operate(controlLED1, ctlValOn, 0)) goto control_error;
Thread_sleep(1000);
if (!ControlObjectClient_operate(controlLED1, ctlValOff, 0)) goto control_error;
if (!ControlObjectClient_operate(controlLED2, ctlValOn, 0)) goto control_error;
Thread_sleep(1000);
if (!ControlObjectClient_operate(controlLED2, ctlValOff, 0)) goto control_error;
if (!ControlObjectClient_operate(controlLED3, ctlValOn, 0)) goto control_error;
Thread_sleep(1000);
if (led4State == false) {
if (!ControlObjectClient_operate(controlLED4, ctlValOn, 0)) goto control_error;
led4State = true;
}
else {
if (!ControlObjectClient_operate(controlLED4, ctlValOff, 0)) goto control_error;
led4State = false;
}
}
goto exit_control_loop;
control_error:
printf("Error controlling device!\n");
exit_control_loop:
MmsValue_delete(ctlValOn);
MmsValue_delete(ctlValOff);
ControlObjectClient_destroy(controlLED1);
ControlObjectClient_destroy(controlLED2);
ControlObjectClient_destroy(controlLED3);
ControlObjectClient_destroy(controlLED4);
IedConnection_close(con);
}
else {
printf("Connection failed!\n");
}
IedConnection_destroy(con);
}

View File

@ -0,0 +1,252 @@
/*
* beagle_demo.c
*
* This demo shows how to connect the libiec61850 server stack to a real device.
*
*/
#include "iec61850_server.h"
#include "iso_server.h"
#include "acse.h"
#include "thread.h"
#include <signal.h>
#include <stdlib.h>
#include <stdio.h>
#include <math.h>
#include "static_model.h"
#include "beaglebone_leds.h"
/* import IEC 61850 device model created from SCL-File */
extern IedModel iedModel;
static int running = 0;
static IedServer iedServer = NULL;
static bool automaticOperationMode = true;
static ClientConnection controllingClient = NULL;
static uint32_t dpcState = 0;
void sigint_handler(int signalId)
{
running = 0;
}
void
connectionIndicationHandler(IedServer server, ClientConnection connection, bool connected, void* parameter)
{
char* clientAddress = ClientConnection_getPeerAddress(connection);
if (connected) {
printf("BeagleDemoServer: new client connection from %s\n", clientAddress);
}
else {
printf("BeagleDemoServer: client connection from %s closed\n", clientAddress);
if (controllingClient == connection) {
printf("Controlling client has closed connection -> switch to automatic operation mode\n");
controllingClient = NULL;
automaticOperationMode = true;
}
}
}
static CheckHandlerResult
performCheckHandler(void* parameter, MmsValue* ctlVal, bool test, bool interlockCheck, ClientConnection connection)
{
if (controllingClient == NULL) {
printf("Client takes control -> switch to remote control operation mode\n");
controllingClient = connection;
automaticOperationMode = false;
}
/* If there is already another client that controls the device reject the control attempt */
if (controllingClient == connection)
return CONTROL_ACCEPTED;
else
return CONTROL_TEMPORARILY_UNAVAILABLE;
}
void
updateLED1stVal(bool newLedState, uint64_t timeStamp) {
switchLED(LED1, newLedState);
IedServer_updateBooleanAttributeValue(iedServer, IEDMODEL_GenericIO_GGIO1_SPCSO1_stVal, newLedState);
IedServer_updateQuality(iedServer, IEDMODEL_GenericIO_GGIO1_SPCSO1_q, QUALITY_VALIDITY_GOOD | QUALITY_SOURCE_SUBSTITUTED);
IedServer_updateUTCTimeAttributeValue(iedServer, IEDMODEL_GenericIO_GGIO1_SPCSO1_t, timeStamp);
}
void
updateLED2stVal(bool newLedState, uint64_t timeStamp) {
switchLED(LED2, newLedState);
IedServer_updateBooleanAttributeValue(iedServer, IEDMODEL_GenericIO_GGIO1_SPCSO2_stVal, newLedState);
IedServer_updateQuality(iedServer, IEDMODEL_GenericIO_GGIO1_SPCSO2_q, QUALITY_VALIDITY_QUESTIONABLE | QUALITY_DETAIL_OSCILLATORY);
IedServer_updateUTCTimeAttributeValue(iedServer, IEDMODEL_GenericIO_GGIO1_SPCSO2_t, timeStamp);
}
void
updateLED3stVal(bool newLedState, uint64_t timeStamp) {
switchLED(LED3, newLedState);
IedServer_updateBooleanAttributeValue(iedServer, IEDMODEL_GenericIO_GGIO1_SPCSO3_stVal, newLedState);
IedServer_updateQuality(iedServer, IEDMODEL_GenericIO_GGIO1_SPCSO3_q, QUALITY_VALIDITY_GOOD);
IedServer_updateUTCTimeAttributeValue(iedServer, IEDMODEL_GenericIO_GGIO1_SPCSO3_t, timeStamp);
}
bool
controlHandlerForBinaryOutput(void* parameter, MmsValue* value, bool test)
{
if (test)
return true;
if (MmsValue_getType(value) != MMS_BOOLEAN)
return false;
uint64_t timeStamp = Hal_getTimeInMs();
bool newState = MmsValue_getBoolean(value);
if (parameter == IEDMODEL_GenericIO_GGIO1_SPCSO1)
updateLED1stVal(newState, timeStamp);
if (parameter == IEDMODEL_GenericIO_GGIO1_SPCSO2)
updateLED2stVal(newState, timeStamp);
if (parameter == IEDMODEL_GenericIO_GGIO1_SPCSO3)
updateLED3stVal(newState, timeStamp);
if (parameter == IEDMODEL_GenericIO_GGIO1_DPCSO1) { /* example for Double Point Control - DPC */
dpcState = 0; /* DPC_STATE_INTERMEDIATE */
IedServer_updateBitStringAttributeValue(iedServer, IEDMODEL_GenericIO_GGIO1_DPCSO1_stVal, dpcState);
IedServer_updateUTCTimeAttributeValue(iedServer, IEDMODEL_GenericIO_GGIO1_DPCSO1_t, timeStamp);
if (newState) {
flashLED(LED4);
Thread_sleep(3000);
switchLED(LED4, 1);
dpcState = 2; /* DPC_STATE_ON */
}
else {
flashLED(LED4);
Thread_sleep(3000);
switchLED(LED4, 0);
dpcState = 1; /* DPC_STATE_OFF */
}
IedServer_updateBitStringAttributeValue(iedServer, IEDMODEL_GenericIO_GGIO1_DPCSO1_stVal, dpcState);
IedServer_updateUTCTimeAttributeValue(iedServer, IEDMODEL_GenericIO_GGIO1_DPCSO1_t, timeStamp);
}
return true;
}
int main(int argc, char** argv) {
initLEDs();
iedServer = IedServer_create(&iedModel);
/* Set callback handlers */
IedServer_setConnectionIndicationHandler(iedServer, (IedConnectionIndicationHandler) connectionIndicationHandler, NULL);
IedServer_setPerformCheckHandler(iedServer, IEDMODEL_GenericIO_GGIO1_SPCSO1,
(ControlPerformCheckHandler) performCheckHandler, IEDMODEL_GenericIO_GGIO1_SPCSO1);
IedServer_setControlHandler(iedServer, IEDMODEL_GenericIO_GGIO1_SPCSO1, (ControlHandler) controlHandlerForBinaryOutput,
IEDMODEL_GenericIO_GGIO1_SPCSO1);
IedServer_setPerformCheckHandler(iedServer, IEDMODEL_GenericIO_GGIO1_SPCSO2,
(ControlPerformCheckHandler) performCheckHandler, IEDMODEL_GenericIO_GGIO1_SPCSO2);
IedServer_setControlHandler(iedServer, IEDMODEL_GenericIO_GGIO1_SPCSO2, (ControlHandler) controlHandlerForBinaryOutput,
IEDMODEL_GenericIO_GGIO1_SPCSO2);
IedServer_setPerformCheckHandler(iedServer, IEDMODEL_GenericIO_GGIO1_SPCSO3,
(ControlPerformCheckHandler) performCheckHandler, IEDMODEL_GenericIO_GGIO1_SPCSO3);
IedServer_setControlHandler(iedServer, IEDMODEL_GenericIO_GGIO1_SPCSO3, (ControlHandler) controlHandlerForBinaryOutput,
IEDMODEL_GenericIO_GGIO1_SPCSO3);
IedServer_setPerformCheckHandler(iedServer, IEDMODEL_GenericIO_GGIO1_DPCSO1,
(ControlPerformCheckHandler) performCheckHandler, IEDMODEL_GenericIO_GGIO1_DPCSO1);
IedServer_setControlHandler(iedServer, IEDMODEL_GenericIO_GGIO1_DPCSO1, (ControlHandler) controlHandlerForBinaryOutput,
IEDMODEL_GenericIO_GGIO1_DPCSO1);
/* Initialize process values */
MmsValue* DPCSO1_stVal = IedServer_getAttributeValue(iedServer, IEDMODEL_GenericIO_GGIO1_DPCSO1_stVal);
MmsValue_setBitStringFromInteger(DPCSO1_stVal, 1); /* set DPC to OFF */
/* MMS server will be instructed to start listening to client connections. */
IedServer_start(iedServer, 102);
if (!IedServer_isRunning(iedServer)) {
printf("Starting server failed! Exit.\n");
IedServer_destroy(iedServer);
exit(-1);
}
running = 1;
signal(SIGINT, sigint_handler);
float t = 0.f;
bool ledStateValue = false;
uint64_t nextLedToggleTime = Hal_getTimeInMs() + 1000;
while (running) {
uint64_t currentTime = Hal_getTimeInMs();
if (automaticOperationMode) {
if (nextLedToggleTime <= currentTime) {
nextLedToggleTime = currentTime + 1000;
ledStateValue = !ledStateValue;
updateLED1stVal(ledStateValue, currentTime);
updateLED2stVal(ledStateValue, currentTime);
updateLED3stVal(ledStateValue, currentTime);
}
}
t += 0.1f;
IedServer_lockDataModel(iedServer);
IedServer_updateFloatAttributeValue(iedServer, IEDMODEL_GenericIO_GGIO1_AnIn1_mag_f, sinf(t));
IedServer_updateQuality(iedServer, IEDMODEL_GenericIO_GGIO1_AnIn1_q, QUALITY_VALIDITY_GOOD);
IedServer_updateUTCTimeAttributeValue(iedServer, IEDMODEL_GenericIO_GGIO1_AnIn1_t, currentTime);
IedServer_updateFloatAttributeValue(iedServer, IEDMODEL_GenericIO_GGIO1_AnIn2_mag_f, sinf(t + 1.f));
IedServer_updateQuality(iedServer, IEDMODEL_GenericIO_GGIO1_AnIn2_q, QUALITY_VALIDITY_GOOD);
IedServer_updateUTCTimeAttributeValue(iedServer, IEDMODEL_GenericIO_GGIO1_AnIn2_t, currentTime);
IedServer_updateFloatAttributeValue(iedServer, IEDMODEL_GenericIO_GGIO1_AnIn3_mag_f, sinf(t + 2.f));
IedServer_updateQuality(iedServer, IEDMODEL_GenericIO_GGIO1_AnIn3_q, QUALITY_VALIDITY_GOOD);
IedServer_updateUTCTimeAttributeValue(iedServer, IEDMODEL_GenericIO_GGIO1_AnIn3_t, currentTime);
IedServer_updateFloatAttributeValue(iedServer, IEDMODEL_GenericIO_GGIO1_AnIn4_mag_f, sinf(t + 3.f));
IedServer_updateQuality(iedServer, IEDMODEL_GenericIO_GGIO1_AnIn4_q, QUALITY_VALIDITY_GOOD);
IedServer_updateUTCTimeAttributeValue(iedServer, IEDMODEL_GenericIO_GGIO1_AnIn4_t, currentTime);
IedServer_unlockDataModel(iedServer);
Thread_sleep(100);
}
/* stop MMS server - close TCP server socket and all client sockets */
IedServer_stop(iedServer);
/* Cleanup - free all resources */
IedServer_destroy(iedServer);
} /* main() */

View File

@ -0,0 +1,231 @@
<?xml version="1.0" encoding="UTF-8"?>
<SCL xmlns="http://www.iec.ch/61850/2003/SCL">
<Header id="" nameStructure="IEDName">
</Header>
<Communication>
<SubNetwork name="subnetwork1" type="8-MMS">
<Text>Station bus</Text>
<BitRate unit="b/s">10</BitRate>
<ConnectedAP iedName="beagle" apName="accessPoint1">
<Address>
<P type="IP">10.0.0.2</P>
<P type="IP-SUBNET">255.255.255.0</P>
<P type="IP-GATEWAY">10.0.0.1</P>
<P type="OSI-TSEL">0001</P>
<P type="OSI-PSEL">00000001</P>
<P type="OSI-SSEL">0001</P>
</Address>
</ConnectedAP>
</SubNetwork>
</Communication>
<IED name="beagle">
<Services>
<DynAssociation />
<GetDirectory />
<GetDataObjectDefinition />
<GetDataSetValue />
<DataSetDirectory />
<ReadWrite />
<GetCBValues />
<ConfLNs fixPrefix="true" fixLnInst="true" />
<GOOSE max="5" />
<GSSE max="5" />
<FileHandling />
<GSEDir />
<TimerActivatedControl />
</Services>
<AccessPoint name="accessPoint1">
<Server>
<Authentication />
<LDevice inst="GenericIO">
<LN0 lnClass="LLN0" lnType="LLN01" inst="">
<DataSet name="Events" desc="Events">
<FCDA ldInst="GenericIO" lnClass="GGIO" fc="ST" lnInst="1" doName="SPCSO1" daName="stVal" />
<FCDA ldInst="GenericIO" lnClass="GGIO" fc="ST" lnInst="1" doName="SPCSO2" daName="stVal" />
<FCDA ldInst="GenericIO" lnClass="GGIO" fc="ST" lnInst="1" doName="SPCSO3" daName="stVal" />
<FCDA ldInst="GenericIO" lnClass="GGIO" fc="ST" lnInst="1" doName="DPCSO1" daName="stVal" />
</DataSet>
<ReportControl name="EventsRCB" confRev="1" datSet="Events" rptID="Events1" buffered="false" intgPd="1000" bufTime="50">
<TrgOps period="true" />
<OptFields seqNum="true" timeStamp="true" dataSet="true" reasonCode="true" entryID="true" configRef="true" />
<RptEnabled max="1" />
</ReportControl>
<ReportControl name="EventsRCB2" confRev="1" datSet="Events" rptID="Events2" buffered="false" intgPd="1000" bufTime="50">
<TrgOps period="true" />
<OptFields seqNum="true" timeStamp="true" dataSet="true" reasonCode="true" entryID="true" configRef="true" />
<RptEnabled max="1" />
</ReportControl>
<DOI name="Mod">
<DAI name="ctlModel">
<Val>status-only</Val>
</DAI>
</DOI>
</LN0>
<LN lnClass="LPHD" lnType="LPHD1" inst="1" prefix="" />
<LN lnClass="GGIO" lnType="GGIO1" inst="1" prefix="">
<DOI name="Mod">
<DAI name="ctlModel">
<Val>status-only</Val>
</DAI>
</DOI>
<DOI name="SPCSO1">
<DAI name="ctlModel">
<Val>direct-with-normal-security</Val>
</DAI>
</DOI>
<DOI name="SPCSO2">
<DAI name="ctlModel">
<Val>direct-with-normal-security</Val>
</DAI>
</DOI>
<DOI name="SPCSO3">
<DAI name="ctlModel">
<Val>direct-with-normal-security</Val>
</DAI>
</DOI>
<DOI name="DPCSO1">
<DAI name="ctlModel">
<Val>direct-with-enhanced-security</Val>
</DAI>
</DOI>
</LN>
</LDevice>
</Server>
</AccessPoint>
</IED>
<DataTypeTemplates>
<LNodeType id="LLN01" lnClass="LLN0">
<DO name="Mod" type="INC_1_Mod" />
<DO name="Beh" type="INS_1_Beh" />
<DO name="Health" type="INS_1_Beh" />
<DO name="NamPlt" type="LPL_1_NamPlt" />
</LNodeType>
<LNodeType id="LPHD1" lnClass="LPHD">
<DO name="PhyNam" type="DPL_1_PhyNam" />
<DO name="PhyHealth" type="INS_1_Beh" />
<DO name="Proxy" type="SPS_1_Proxy" />
</LNodeType>
<LNodeType id="GGIO1" lnClass="GGIO">
<DO name="Mod" type="INC_2_Mod" />
<DO name="Beh" type="INS_1_Beh" />
<DO name="Health" type="INS_1_Beh" />
<DO name="NamPlt" type="LPL_2_NamPlt" />
<DO name="AnIn1" type="MV_1_AnIn1" />
<DO name="AnIn2" type="MV_1_AnIn1" />
<DO name="AnIn3" type="MV_1_AnIn1" />
<DO name="AnIn4" type="MV_1_AnIn1" />
<DO name="SPCSO1" type="SPC_2_SPCSO1" />
<DO name="SPCSO2" type="SPC_1_SPCSO2" />
<DO name="SPCSO3" type="SPC_1_SPCSO3" />
<DO name="DPCSO1" type="DPC_1_DPCSO1" />
<DO name="Ind1" type="SPS_1_Proxy" />
<DO name="Ind2" type="SPS_1_Proxy" />
<DO name="Ind3" type="SPS_1_Proxy" />
<DO name="Ind4" type="SPS_1_Proxy" />
</LNodeType>
<DOType id="INC_1_Mod" cdc="INC">
<DA name="stVal" bType="INT32" fc="ST" dchg="true" />
<DA name="q" bType="Quality" fc="ST" qchg="true" />
<DA name="t" bType="Timestamp" fc="ST" />
<DA name="ctlModel" type="CtlModels" bType="Enum" fc="CF" />
</DOType>
<DOType id="INS_1_Beh" cdc="INS">
<DA name="stVal" bType="INT32" fc="ST" dchg="true" />
<DA name="q" bType="Quality" fc="ST" qchg="true" />
<DA name="t" bType="Timestamp" fc="ST" />
</DOType>
<DOType id="LPL_1_NamPlt" cdc="LPL">
<DA name="vendor" bType="VisString255" fc="DC" />
<DA name="swRev" bType="VisString255" fc="DC" />
<DA name="d" bType="VisString255" fc="DC" />
<DA name="configRev" bType="VisString255" fc="DC" />
<DA name="ldNs" bType="VisString255" fc="EX" />
</DOType>
<DOType id="DPL_1_PhyNam" cdc="DPL">
<DA name="vendor" bType="VisString255" fc="DC" />
</DOType>
<DOType id="SPS_1_Proxy" cdc="SPS">
<DA name="stVal" bType="BOOLEAN" fc="ST" dchg="true" />
<DA name="q" bType="Quality" fc="ST" qchg="true" />
<DA name="t" bType="Timestamp" fc="ST" />
</DOType>
<DOType id="LPL_2_NamPlt" cdc="LPL">
<DA name="vendor" bType="VisString255" fc="DC" />
<DA name="swRev" bType="VisString255" fc="DC" />
<DA name="d" bType="VisString255" fc="DC" />
</DOType>
<DOType id="MV_1_AnIn1" cdc="MV">
<DA name="mag" type="AnalogueValue_1" bType="Struct" fc="MX" dchg="true" />
<DA name="q" bType="Quality" fc="MX" qchg="true" />
<DA name="t" bType="Timestamp" fc="MX" />
</DOType>
<DOType id="DPC_1_DPCSO1" cdc="DPC">
<DA name="stVal" bType="Dbpos" fc="ST" dchg="true" />
<DA name="q" bType="Quality" fc="ST" qchg="true" />
<DA name="Oper" type="SPCOperate_1" bType="Struct" fc="CO" />
<DA name="ctlModel" type="CtlModels" bType="Enum" fc="CF" />
<DA name="t" bType="Timestamp" fc="ST" />
</DOType>
<DOType id="INC_2_Mod" cdc="INC">
<DA name="q" bType="Quality" fc="ST" qchg="true" />
<DA name="t" bType="Timestamp" fc="ST" />
<DA name="ctlModel" type="CtlModels" bType="Enum" fc="CF" />
</DOType>
<DOType id="SPC_2_SPCSO1" cdc="SPC">
<DA name="stVal" bType="BOOLEAN" fc="ST" dchg="true" />
<DA name="q" bType="Quality" fc="ST" qchg="true" />
<DA name="Oper" type="SPCOperate_1" bType="Struct" fc="CO" />
<DA name="ctlModel" type="CtlModels" bType="Enum" fc="CF" />
<DA name="t" bType="Timestamp" fc="ST" />
</DOType>
<DOType id="SPC_1_SPCSO2" cdc="SPC">
<DA name="stVal" bType="BOOLEAN" fc="ST" dchg="true" />
<DA name="q" bType="Quality" fc="ST" qchg="true" />
<DA name="Oper" type="SPCOperate_1" bType="Struct" fc="CO" />
<DA name="ctlModel" type="CtlModels" bType="Enum" fc="CF" />
<DA name="t" bType="Timestamp" fc="ST" />
</DOType>
<DOType id="SPC_1_SPCSO3" cdc="SPC">
<DA name="stVal" bType="BOOLEAN" fc="ST" dchg="true" />
<DA name="q" bType="Quality" fc="ST" qchg="true" />
<DA name="Oper" type="SPCOperate_1" bType="Struct" fc="CO" />
<DA name="ctlModel" type="CtlModels" bType="Enum" fc="CF" />
<DA name="t" bType="Timestamp" fc="ST" />
</DOType>
<DAType id="AnalogueValue_1">
<BDA name="f" bType="FLOAT32" />
</DAType>
<DAType id="Originator_1">
<BDA name="orCat" type="OrCat" bType="Enum" />
<BDA name="orIdent" bType="Octet64" />
</DAType>
<DAType id="SPCOperate_1">
<BDA name="ctlVal" bType="BOOLEAN" />
<BDA name="origin" type="Originator_1" bType="Struct" />
<BDA name="ctlNum" bType="INT8U" />
<BDA name="T" bType="Timestamp" />
<BDA name="Test" bType="BOOLEAN" />
<BDA name="Check" bType="Check" />
</DAType>
<EnumType id="CtlModels">
<EnumVal ord="0">status-only</EnumVal>
<EnumVal ord="1">direct-with-normal-security</EnumVal>
<EnumVal ord="2">sbo-with-normal-security</EnumVal>
<EnumVal ord="3">direct-with-enhanced-security</EnumVal>
<EnumVal ord="4">sbo-with-enhanced-security</EnumVal>
</EnumType>
<EnumType id="OrCat">
<EnumVal ord="0">not-supported</EnumVal>
<EnumVal ord="1">bay-control</EnumVal>
<EnumVal ord="2">station-control</EnumVal>
<EnumVal ord="3">remote-control</EnumVal>
<EnumVal ord="4">automatic-bay</EnumVal>
<EnumVal ord="5">automatic-station</EnumVal>
<EnumVal ord="6">automatic-remote</EnumVal>
<EnumVal ord="7">maintenance</EnumVal>
<EnumVal ord="8">process</EnumVal>
</EnumType>
</DataTypeTemplates>
</SCL>

View File

@ -0,0 +1,61 @@
/*
* beaglebone_leds.c
*/
#include <stdio.h>
#include "beaglebone_leds.h"
static void
writeToFile(char* filename, char* text)
{
FILE* file = fopen(filename, "w");
fprintf(file, text);
fclose(file);
}
void
flashLED(char* led)
{
#ifndef SIMULATED
char filename[255];
sprintf(filename, "%s/trigger", led);
writeToFile(filename, "timer");
sprintf(filename, "%s/delay_on", led);
writeToFile(filename, "200");
sprintf(filename, "%s/delay_off", led);
writeToFile(filename, "200");
#else
printf("FLASH: %s\n", led);
#endif
}
void
switchLED(char* led, int value)
{
#ifndef SIMULATED
char filename[255];
char* valueStr[10];
sprintf(filename, "%s/trigger", led);
writeToFile(filename, "none");
sprintf(filename, "%s/brightness", led);
sprintf(valueStr, "%i", value);
writeToFile(filename, valueStr);
#else
printf("SWITCH: %s %i\n", led, value);
#endif
}
void
initLEDs()
{
switchLED(LED1, 0);
switchLED(LED2, 0);
switchLED(LED3, 0);
switchLED(LED4, 0);
}

View File

@ -0,0 +1,35 @@
/*
* beaglebone_leds.h
*/
#ifndef BEAGLEBONE_LEDS_H_
#define BEAGLEBONE_LEDS_H_
//#define SIMULATED 1
#if 0
#define LED1 "/sys/class/leds/beaglebone::usr0"
#define LED2 "/sys/class/leds/beaglebone::usr1"
#define LED3 "/sys/class/leds/beaglebone::usr2"
#define LED4 "/sys/class/leds/beaglebone::usr3"
#endif
#if 1
#define LED1 "/sys/class/leds/beaglebone:green:usr0"
#define LED2 "/sys/class/leds/beaglebone:green:usr1"
#define LED3 "/sys/class/leds/beaglebone:green:usr2"
#define LED4 "/sys/class/leds/beaglebone:green:usr3"
#endif
void
flashLED(char* led);
void
switchLED(char* led, int value);
void
initLEDs();
#endif /* BEAGLEBONE_LEDS_H_ */

File diff suppressed because it is too large Load Diff

View File

@ -0,0 +1,301 @@
/*
* static_model.h
*
* automatically generated from beagle_demo.icd
*/
#ifndef STATIC_MODEL_H_
#define STATIC_MODEL_H_
#include <stdlib.h>
#include "model.h"
extern IedModel iedModel;
extern LogicalDevice iedModel_GenericIO;
extern LogicalNode iedModel_GenericIO_LLN0;
extern DataObject iedModel_GenericIO_LLN0_Mod;
extern DataAttribute iedModel_GenericIO_LLN0_Mod_stVal;
extern DataAttribute iedModel_GenericIO_LLN0_Mod_q;
extern DataAttribute iedModel_GenericIO_LLN0_Mod_t;
extern DataAttribute iedModel_GenericIO_LLN0_Mod_ctlModel;
extern DataObject iedModel_GenericIO_LLN0_Beh;
extern DataAttribute iedModel_GenericIO_LLN0_Beh_stVal;
extern DataAttribute iedModel_GenericIO_LLN0_Beh_q;
extern DataAttribute iedModel_GenericIO_LLN0_Beh_t;
extern DataObject iedModel_GenericIO_LLN0_Health;
extern DataAttribute iedModel_GenericIO_LLN0_Health_stVal;
extern DataAttribute iedModel_GenericIO_LLN0_Health_q;
extern DataAttribute iedModel_GenericIO_LLN0_Health_t;
extern DataObject iedModel_GenericIO_LLN0_NamPlt;
extern DataAttribute iedModel_GenericIO_LLN0_NamPlt_vendor;
extern DataAttribute iedModel_GenericIO_LLN0_NamPlt_swRev;
extern DataAttribute iedModel_GenericIO_LLN0_NamPlt_d;
extern DataAttribute iedModel_GenericIO_LLN0_NamPlt_configRev;
extern DataAttribute iedModel_GenericIO_LLN0_NamPlt_ldNs;
extern LogicalNode iedModel_GenericIO_LPHD1;
extern DataObject iedModel_GenericIO_LPHD1_PhyNam;
extern DataAttribute iedModel_GenericIO_LPHD1_PhyNam_vendor;
extern DataObject iedModel_GenericIO_LPHD1_PhyHealth;
extern DataAttribute iedModel_GenericIO_LPHD1_PhyHealth_stVal;
extern DataAttribute iedModel_GenericIO_LPHD1_PhyHealth_q;
extern DataAttribute iedModel_GenericIO_LPHD1_PhyHealth_t;
extern DataObject iedModel_GenericIO_LPHD1_Proxy;
extern DataAttribute iedModel_GenericIO_LPHD1_Proxy_stVal;
extern DataAttribute iedModel_GenericIO_LPHD1_Proxy_q;
extern DataAttribute iedModel_GenericIO_LPHD1_Proxy_t;
extern LogicalNode iedModel_GenericIO_GGIO1;
extern DataObject iedModel_GenericIO_GGIO1_Mod;
extern DataAttribute iedModel_GenericIO_GGIO1_Mod_q;
extern DataAttribute iedModel_GenericIO_GGIO1_Mod_t;
extern DataAttribute iedModel_GenericIO_GGIO1_Mod_ctlModel;
extern DataObject iedModel_GenericIO_GGIO1_Beh;
extern DataAttribute iedModel_GenericIO_GGIO1_Beh_stVal;
extern DataAttribute iedModel_GenericIO_GGIO1_Beh_q;
extern DataAttribute iedModel_GenericIO_GGIO1_Beh_t;
extern DataObject iedModel_GenericIO_GGIO1_Health;
extern DataAttribute iedModel_GenericIO_GGIO1_Health_stVal;
extern DataAttribute iedModel_GenericIO_GGIO1_Health_q;
extern DataAttribute iedModel_GenericIO_GGIO1_Health_t;
extern DataObject iedModel_GenericIO_GGIO1_NamPlt;
extern DataAttribute iedModel_GenericIO_GGIO1_NamPlt_vendor;
extern DataAttribute iedModel_GenericIO_GGIO1_NamPlt_swRev;
extern DataAttribute iedModel_GenericIO_GGIO1_NamPlt_d;
extern DataObject iedModel_GenericIO_GGIO1_AnIn1;
extern DataAttribute iedModel_GenericIO_GGIO1_AnIn1_mag;
extern DataAttribute iedModel_GenericIO_GGIO1_AnIn1_mag_f;
extern DataAttribute iedModel_GenericIO_GGIO1_AnIn1_q;
extern DataAttribute iedModel_GenericIO_GGIO1_AnIn1_t;
extern DataObject iedModel_GenericIO_GGIO1_AnIn2;
extern DataAttribute iedModel_GenericIO_GGIO1_AnIn2_mag;
extern DataAttribute iedModel_GenericIO_GGIO1_AnIn2_mag_f;
extern DataAttribute iedModel_GenericIO_GGIO1_AnIn2_q;
extern DataAttribute iedModel_GenericIO_GGIO1_AnIn2_t;
extern DataObject iedModel_GenericIO_GGIO1_AnIn3;
extern DataAttribute iedModel_GenericIO_GGIO1_AnIn3_mag;
extern DataAttribute iedModel_GenericIO_GGIO1_AnIn3_mag_f;
extern DataAttribute iedModel_GenericIO_GGIO1_AnIn3_q;
extern DataAttribute iedModel_GenericIO_GGIO1_AnIn3_t;
extern DataObject iedModel_GenericIO_GGIO1_AnIn4;
extern DataAttribute iedModel_GenericIO_GGIO1_AnIn4_mag;
extern DataAttribute iedModel_GenericIO_GGIO1_AnIn4_mag_f;
extern DataAttribute iedModel_GenericIO_GGIO1_AnIn4_q;
extern DataAttribute iedModel_GenericIO_GGIO1_AnIn4_t;
extern DataObject iedModel_GenericIO_GGIO1_SPCSO1;
extern DataAttribute iedModel_GenericIO_GGIO1_SPCSO1_stVal;
extern DataAttribute iedModel_GenericIO_GGIO1_SPCSO1_q;
extern DataAttribute iedModel_GenericIO_GGIO1_SPCSO1_Oper;
extern DataAttribute iedModel_GenericIO_GGIO1_SPCSO1_Oper_ctlVal;
extern DataAttribute iedModel_GenericIO_GGIO1_SPCSO1_Oper_origin;
extern DataAttribute iedModel_GenericIO_GGIO1_SPCSO1_Oper_origin_orCat;
extern DataAttribute iedModel_GenericIO_GGIO1_SPCSO1_Oper_origin_orIdent;
extern DataAttribute iedModel_GenericIO_GGIO1_SPCSO1_Oper_ctlNum;
extern DataAttribute iedModel_GenericIO_GGIO1_SPCSO1_Oper_T;
extern DataAttribute iedModel_GenericIO_GGIO1_SPCSO1_Oper_Test;
extern DataAttribute iedModel_GenericIO_GGIO1_SPCSO1_Oper_Check;
extern DataAttribute iedModel_GenericIO_GGIO1_SPCSO1_ctlModel;
extern DataAttribute iedModel_GenericIO_GGIO1_SPCSO1_t;
extern DataObject iedModel_GenericIO_GGIO1_SPCSO2;
extern DataAttribute iedModel_GenericIO_GGIO1_SPCSO2_stVal;
extern DataAttribute iedModel_GenericIO_GGIO1_SPCSO2_q;
extern DataAttribute iedModel_GenericIO_GGIO1_SPCSO2_Oper;
extern DataAttribute iedModel_GenericIO_GGIO1_SPCSO2_Oper_ctlVal;
extern DataAttribute iedModel_GenericIO_GGIO1_SPCSO2_Oper_origin;
extern DataAttribute iedModel_GenericIO_GGIO1_SPCSO2_Oper_origin_orCat;
extern DataAttribute iedModel_GenericIO_GGIO1_SPCSO2_Oper_origin_orIdent;
extern DataAttribute iedModel_GenericIO_GGIO1_SPCSO2_Oper_ctlNum;
extern DataAttribute iedModel_GenericIO_GGIO1_SPCSO2_Oper_T;
extern DataAttribute iedModel_GenericIO_GGIO1_SPCSO2_Oper_Test;
extern DataAttribute iedModel_GenericIO_GGIO1_SPCSO2_Oper_Check;
extern DataAttribute iedModel_GenericIO_GGIO1_SPCSO2_ctlModel;
extern DataAttribute iedModel_GenericIO_GGIO1_SPCSO2_t;
extern DataObject iedModel_GenericIO_GGIO1_SPCSO3;
extern DataAttribute iedModel_GenericIO_GGIO1_SPCSO3_stVal;
extern DataAttribute iedModel_GenericIO_GGIO1_SPCSO3_q;
extern DataAttribute iedModel_GenericIO_GGIO1_SPCSO3_Oper;
extern DataAttribute iedModel_GenericIO_GGIO1_SPCSO3_Oper_ctlVal;
extern DataAttribute iedModel_GenericIO_GGIO1_SPCSO3_Oper_origin;
extern DataAttribute iedModel_GenericIO_GGIO1_SPCSO3_Oper_origin_orCat;
extern DataAttribute iedModel_GenericIO_GGIO1_SPCSO3_Oper_origin_orIdent;
extern DataAttribute iedModel_GenericIO_GGIO1_SPCSO3_Oper_ctlNum;
extern DataAttribute iedModel_GenericIO_GGIO1_SPCSO3_Oper_T;
extern DataAttribute iedModel_GenericIO_GGIO1_SPCSO3_Oper_Test;
extern DataAttribute iedModel_GenericIO_GGIO1_SPCSO3_Oper_Check;
extern DataAttribute iedModel_GenericIO_GGIO1_SPCSO3_ctlModel;
extern DataAttribute iedModel_GenericIO_GGIO1_SPCSO3_t;
extern DataObject iedModel_GenericIO_GGIO1_DPCSO1;
extern DataAttribute iedModel_GenericIO_GGIO1_DPCSO1_stVal;
extern DataAttribute iedModel_GenericIO_GGIO1_DPCSO1_q;
extern DataAttribute iedModel_GenericIO_GGIO1_DPCSO1_Oper;
extern DataAttribute iedModel_GenericIO_GGIO1_DPCSO1_Oper_ctlVal;
extern DataAttribute iedModel_GenericIO_GGIO1_DPCSO1_Oper_origin;
extern DataAttribute iedModel_GenericIO_GGIO1_DPCSO1_Oper_origin_orCat;
extern DataAttribute iedModel_GenericIO_GGIO1_DPCSO1_Oper_origin_orIdent;
extern DataAttribute iedModel_GenericIO_GGIO1_DPCSO1_Oper_ctlNum;
extern DataAttribute iedModel_GenericIO_GGIO1_DPCSO1_Oper_T;
extern DataAttribute iedModel_GenericIO_GGIO1_DPCSO1_Oper_Test;
extern DataAttribute iedModel_GenericIO_GGIO1_DPCSO1_Oper_Check;
extern DataAttribute iedModel_GenericIO_GGIO1_DPCSO1_ctlModel;
extern DataAttribute iedModel_GenericIO_GGIO1_DPCSO1_t;
extern DataObject iedModel_GenericIO_GGIO1_Ind1;
extern DataAttribute iedModel_GenericIO_GGIO1_Ind1_stVal;
extern DataAttribute iedModel_GenericIO_GGIO1_Ind1_q;
extern DataAttribute iedModel_GenericIO_GGIO1_Ind1_t;
extern DataObject iedModel_GenericIO_GGIO1_Ind2;
extern DataAttribute iedModel_GenericIO_GGIO1_Ind2_stVal;
extern DataAttribute iedModel_GenericIO_GGIO1_Ind2_q;
extern DataAttribute iedModel_GenericIO_GGIO1_Ind2_t;
extern DataObject iedModel_GenericIO_GGIO1_Ind3;
extern DataAttribute iedModel_GenericIO_GGIO1_Ind3_stVal;
extern DataAttribute iedModel_GenericIO_GGIO1_Ind3_q;
extern DataAttribute iedModel_GenericIO_GGIO1_Ind3_t;
extern DataObject iedModel_GenericIO_GGIO1_Ind4;
extern DataAttribute iedModel_GenericIO_GGIO1_Ind4_stVal;
extern DataAttribute iedModel_GenericIO_GGIO1_Ind4_q;
extern DataAttribute iedModel_GenericIO_GGIO1_Ind4_t;
#define IEDMODEL_GenericIO (&iedModel_GenericIO)
#define IEDMODEL_GenericIO_LLN0 (&iedModel_GenericIO_LLN0)
#define IEDMODEL_GenericIO_LLN0_Mod (&iedModel_GenericIO_LLN0_Mod)
#define IEDMODEL_GenericIO_LLN0_Mod_stVal (&iedModel_GenericIO_LLN0_Mod_stVal)
#define IEDMODEL_GenericIO_LLN0_Mod_q (&iedModel_GenericIO_LLN0_Mod_q)
#define IEDMODEL_GenericIO_LLN0_Mod_t (&iedModel_GenericIO_LLN0_Mod_t)
#define IEDMODEL_GenericIO_LLN0_Mod_ctlModel (&iedModel_GenericIO_LLN0_Mod_ctlModel)
#define IEDMODEL_GenericIO_LLN0_Beh (&iedModel_GenericIO_LLN0_Beh)
#define IEDMODEL_GenericIO_LLN0_Beh_stVal (&iedModel_GenericIO_LLN0_Beh_stVal)
#define IEDMODEL_GenericIO_LLN0_Beh_q (&iedModel_GenericIO_LLN0_Beh_q)
#define IEDMODEL_GenericIO_LLN0_Beh_t (&iedModel_GenericIO_LLN0_Beh_t)
#define IEDMODEL_GenericIO_LLN0_Health (&iedModel_GenericIO_LLN0_Health)
#define IEDMODEL_GenericIO_LLN0_Health_stVal (&iedModel_GenericIO_LLN0_Health_stVal)
#define IEDMODEL_GenericIO_LLN0_Health_q (&iedModel_GenericIO_LLN0_Health_q)
#define IEDMODEL_GenericIO_LLN0_Health_t (&iedModel_GenericIO_LLN0_Health_t)
#define IEDMODEL_GenericIO_LLN0_NamPlt (&iedModel_GenericIO_LLN0_NamPlt)
#define IEDMODEL_GenericIO_LLN0_NamPlt_vendor (&iedModel_GenericIO_LLN0_NamPlt_vendor)
#define IEDMODEL_GenericIO_LLN0_NamPlt_swRev (&iedModel_GenericIO_LLN0_NamPlt_swRev)
#define IEDMODEL_GenericIO_LLN0_NamPlt_d (&iedModel_GenericIO_LLN0_NamPlt_d)
#define IEDMODEL_GenericIO_LLN0_NamPlt_configRev (&iedModel_GenericIO_LLN0_NamPlt_configRev)
#define IEDMODEL_GenericIO_LLN0_NamPlt_ldNs (&iedModel_GenericIO_LLN0_NamPlt_ldNs)
#define IEDMODEL_GenericIO_LPHD1 (&iedModel_GenericIO_LPHD1)
#define IEDMODEL_GenericIO_LPHD1_PhyNam (&iedModel_GenericIO_LPHD1_PhyNam)
#define IEDMODEL_GenericIO_LPHD1_PhyNam_vendor (&iedModel_GenericIO_LPHD1_PhyNam_vendor)
#define IEDMODEL_GenericIO_LPHD1_PhyHealth (&iedModel_GenericIO_LPHD1_PhyHealth)
#define IEDMODEL_GenericIO_LPHD1_PhyHealth_stVal (&iedModel_GenericIO_LPHD1_PhyHealth_stVal)
#define IEDMODEL_GenericIO_LPHD1_PhyHealth_q (&iedModel_GenericIO_LPHD1_PhyHealth_q)
#define IEDMODEL_GenericIO_LPHD1_PhyHealth_t (&iedModel_GenericIO_LPHD1_PhyHealth_t)
#define IEDMODEL_GenericIO_LPHD1_Proxy (&iedModel_GenericIO_LPHD1_Proxy)
#define IEDMODEL_GenericIO_LPHD1_Proxy_stVal (&iedModel_GenericIO_LPHD1_Proxy_stVal)
#define IEDMODEL_GenericIO_LPHD1_Proxy_q (&iedModel_GenericIO_LPHD1_Proxy_q)
#define IEDMODEL_GenericIO_LPHD1_Proxy_t (&iedModel_GenericIO_LPHD1_Proxy_t)
#define IEDMODEL_GenericIO_GGIO1 (&iedModel_GenericIO_GGIO1)
#define IEDMODEL_GenericIO_GGIO1_Mod (&iedModel_GenericIO_GGIO1_Mod)
#define IEDMODEL_GenericIO_GGIO1_Mod_q (&iedModel_GenericIO_GGIO1_Mod_q)
#define IEDMODEL_GenericIO_GGIO1_Mod_t (&iedModel_GenericIO_GGIO1_Mod_t)
#define IEDMODEL_GenericIO_GGIO1_Mod_ctlModel (&iedModel_GenericIO_GGIO1_Mod_ctlModel)
#define IEDMODEL_GenericIO_GGIO1_Beh (&iedModel_GenericIO_GGIO1_Beh)
#define IEDMODEL_GenericIO_GGIO1_Beh_stVal (&iedModel_GenericIO_GGIO1_Beh_stVal)
#define IEDMODEL_GenericIO_GGIO1_Beh_q (&iedModel_GenericIO_GGIO1_Beh_q)
#define IEDMODEL_GenericIO_GGIO1_Beh_t (&iedModel_GenericIO_GGIO1_Beh_t)
#define IEDMODEL_GenericIO_GGIO1_Health (&iedModel_GenericIO_GGIO1_Health)
#define IEDMODEL_GenericIO_GGIO1_Health_stVal (&iedModel_GenericIO_GGIO1_Health_stVal)
#define IEDMODEL_GenericIO_GGIO1_Health_q (&iedModel_GenericIO_GGIO1_Health_q)
#define IEDMODEL_GenericIO_GGIO1_Health_t (&iedModel_GenericIO_GGIO1_Health_t)
#define IEDMODEL_GenericIO_GGIO1_NamPlt (&iedModel_GenericIO_GGIO1_NamPlt)
#define IEDMODEL_GenericIO_GGIO1_NamPlt_vendor (&iedModel_GenericIO_GGIO1_NamPlt_vendor)
#define IEDMODEL_GenericIO_GGIO1_NamPlt_swRev (&iedModel_GenericIO_GGIO1_NamPlt_swRev)
#define IEDMODEL_GenericIO_GGIO1_NamPlt_d (&iedModel_GenericIO_GGIO1_NamPlt_d)
#define IEDMODEL_GenericIO_GGIO1_AnIn1 (&iedModel_GenericIO_GGIO1_AnIn1)
#define IEDMODEL_GenericIO_GGIO1_AnIn1_mag (&iedModel_GenericIO_GGIO1_AnIn1_mag)
#define IEDMODEL_GenericIO_GGIO1_AnIn1_mag_f (&iedModel_GenericIO_GGIO1_AnIn1_mag_f)
#define IEDMODEL_GenericIO_GGIO1_AnIn1_q (&iedModel_GenericIO_GGIO1_AnIn1_q)
#define IEDMODEL_GenericIO_GGIO1_AnIn1_t (&iedModel_GenericIO_GGIO1_AnIn1_t)
#define IEDMODEL_GenericIO_GGIO1_AnIn2 (&iedModel_GenericIO_GGIO1_AnIn2)
#define IEDMODEL_GenericIO_GGIO1_AnIn2_mag (&iedModel_GenericIO_GGIO1_AnIn2_mag)
#define IEDMODEL_GenericIO_GGIO1_AnIn2_mag_f (&iedModel_GenericIO_GGIO1_AnIn2_mag_f)
#define IEDMODEL_GenericIO_GGIO1_AnIn2_q (&iedModel_GenericIO_GGIO1_AnIn2_q)
#define IEDMODEL_GenericIO_GGIO1_AnIn2_t (&iedModel_GenericIO_GGIO1_AnIn2_t)
#define IEDMODEL_GenericIO_GGIO1_AnIn3 (&iedModel_GenericIO_GGIO1_AnIn3)
#define IEDMODEL_GenericIO_GGIO1_AnIn3_mag (&iedModel_GenericIO_GGIO1_AnIn3_mag)
#define IEDMODEL_GenericIO_GGIO1_AnIn3_mag_f (&iedModel_GenericIO_GGIO1_AnIn3_mag_f)
#define IEDMODEL_GenericIO_GGIO1_AnIn3_q (&iedModel_GenericIO_GGIO1_AnIn3_q)
#define IEDMODEL_GenericIO_GGIO1_AnIn3_t (&iedModel_GenericIO_GGIO1_AnIn3_t)
#define IEDMODEL_GenericIO_GGIO1_AnIn4 (&iedModel_GenericIO_GGIO1_AnIn4)
#define IEDMODEL_GenericIO_GGIO1_AnIn4_mag (&iedModel_GenericIO_GGIO1_AnIn4_mag)
#define IEDMODEL_GenericIO_GGIO1_AnIn4_mag_f (&iedModel_GenericIO_GGIO1_AnIn4_mag_f)
#define IEDMODEL_GenericIO_GGIO1_AnIn4_q (&iedModel_GenericIO_GGIO1_AnIn4_q)
#define IEDMODEL_GenericIO_GGIO1_AnIn4_t (&iedModel_GenericIO_GGIO1_AnIn4_t)
#define IEDMODEL_GenericIO_GGIO1_SPCSO1 (&iedModel_GenericIO_GGIO1_SPCSO1)
#define IEDMODEL_GenericIO_GGIO1_SPCSO1_stVal (&iedModel_GenericIO_GGIO1_SPCSO1_stVal)
#define IEDMODEL_GenericIO_GGIO1_SPCSO1_q (&iedModel_GenericIO_GGIO1_SPCSO1_q)
#define IEDMODEL_GenericIO_GGIO1_SPCSO1_Oper (&iedModel_GenericIO_GGIO1_SPCSO1_Oper)
#define IEDMODEL_GenericIO_GGIO1_SPCSO1_Oper_ctlVal (&iedModel_GenericIO_GGIO1_SPCSO1_Oper_ctlVal)
#define IEDMODEL_GenericIO_GGIO1_SPCSO1_Oper_origin (&iedModel_GenericIO_GGIO1_SPCSO1_Oper_origin)
#define IEDMODEL_GenericIO_GGIO1_SPCSO1_Oper_origin_orCat (&iedModel_GenericIO_GGIO1_SPCSO1_Oper_origin_orCat)
#define IEDMODEL_GenericIO_GGIO1_SPCSO1_Oper_origin_orIdent (&iedModel_GenericIO_GGIO1_SPCSO1_Oper_origin_orIdent)
#define IEDMODEL_GenericIO_GGIO1_SPCSO1_Oper_ctlNum (&iedModel_GenericIO_GGIO1_SPCSO1_Oper_ctlNum)
#define IEDMODEL_GenericIO_GGIO1_SPCSO1_Oper_T (&iedModel_GenericIO_GGIO1_SPCSO1_Oper_T)
#define IEDMODEL_GenericIO_GGIO1_SPCSO1_Oper_Test (&iedModel_GenericIO_GGIO1_SPCSO1_Oper_Test)
#define IEDMODEL_GenericIO_GGIO1_SPCSO1_Oper_Check (&iedModel_GenericIO_GGIO1_SPCSO1_Oper_Check)
#define IEDMODEL_GenericIO_GGIO1_SPCSO1_ctlModel (&iedModel_GenericIO_GGIO1_SPCSO1_ctlModel)
#define IEDMODEL_GenericIO_GGIO1_SPCSO1_t (&iedModel_GenericIO_GGIO1_SPCSO1_t)
#define IEDMODEL_GenericIO_GGIO1_SPCSO2 (&iedModel_GenericIO_GGIO1_SPCSO2)
#define IEDMODEL_GenericIO_GGIO1_SPCSO2_stVal (&iedModel_GenericIO_GGIO1_SPCSO2_stVal)
#define IEDMODEL_GenericIO_GGIO1_SPCSO2_q (&iedModel_GenericIO_GGIO1_SPCSO2_q)
#define IEDMODEL_GenericIO_GGIO1_SPCSO2_Oper (&iedModel_GenericIO_GGIO1_SPCSO2_Oper)
#define IEDMODEL_GenericIO_GGIO1_SPCSO2_Oper_ctlVal (&iedModel_GenericIO_GGIO1_SPCSO2_Oper_ctlVal)
#define IEDMODEL_GenericIO_GGIO1_SPCSO2_Oper_origin (&iedModel_GenericIO_GGIO1_SPCSO2_Oper_origin)
#define IEDMODEL_GenericIO_GGIO1_SPCSO2_Oper_origin_orCat (&iedModel_GenericIO_GGIO1_SPCSO2_Oper_origin_orCat)
#define IEDMODEL_GenericIO_GGIO1_SPCSO2_Oper_origin_orIdent (&iedModel_GenericIO_GGIO1_SPCSO2_Oper_origin_orIdent)
#define IEDMODEL_GenericIO_GGIO1_SPCSO2_Oper_ctlNum (&iedModel_GenericIO_GGIO1_SPCSO2_Oper_ctlNum)
#define IEDMODEL_GenericIO_GGIO1_SPCSO2_Oper_T (&iedModel_GenericIO_GGIO1_SPCSO2_Oper_T)
#define IEDMODEL_GenericIO_GGIO1_SPCSO2_Oper_Test (&iedModel_GenericIO_GGIO1_SPCSO2_Oper_Test)
#define IEDMODEL_GenericIO_GGIO1_SPCSO2_Oper_Check (&iedModel_GenericIO_GGIO1_SPCSO2_Oper_Check)
#define IEDMODEL_GenericIO_GGIO1_SPCSO2_ctlModel (&iedModel_GenericIO_GGIO1_SPCSO2_ctlModel)
#define IEDMODEL_GenericIO_GGIO1_SPCSO2_t (&iedModel_GenericIO_GGIO1_SPCSO2_t)
#define IEDMODEL_GenericIO_GGIO1_SPCSO3 (&iedModel_GenericIO_GGIO1_SPCSO3)
#define IEDMODEL_GenericIO_GGIO1_SPCSO3_stVal (&iedModel_GenericIO_GGIO1_SPCSO3_stVal)
#define IEDMODEL_GenericIO_GGIO1_SPCSO3_q (&iedModel_GenericIO_GGIO1_SPCSO3_q)
#define IEDMODEL_GenericIO_GGIO1_SPCSO3_Oper (&iedModel_GenericIO_GGIO1_SPCSO3_Oper)
#define IEDMODEL_GenericIO_GGIO1_SPCSO3_Oper_ctlVal (&iedModel_GenericIO_GGIO1_SPCSO3_Oper_ctlVal)
#define IEDMODEL_GenericIO_GGIO1_SPCSO3_Oper_origin (&iedModel_GenericIO_GGIO1_SPCSO3_Oper_origin)
#define IEDMODEL_GenericIO_GGIO1_SPCSO3_Oper_origin_orCat (&iedModel_GenericIO_GGIO1_SPCSO3_Oper_origin_orCat)
#define IEDMODEL_GenericIO_GGIO1_SPCSO3_Oper_origin_orIdent (&iedModel_GenericIO_GGIO1_SPCSO3_Oper_origin_orIdent)
#define IEDMODEL_GenericIO_GGIO1_SPCSO3_Oper_ctlNum (&iedModel_GenericIO_GGIO1_SPCSO3_Oper_ctlNum)
#define IEDMODEL_GenericIO_GGIO1_SPCSO3_Oper_T (&iedModel_GenericIO_GGIO1_SPCSO3_Oper_T)
#define IEDMODEL_GenericIO_GGIO1_SPCSO3_Oper_Test (&iedModel_GenericIO_GGIO1_SPCSO3_Oper_Test)
#define IEDMODEL_GenericIO_GGIO1_SPCSO3_Oper_Check (&iedModel_GenericIO_GGIO1_SPCSO3_Oper_Check)
#define IEDMODEL_GenericIO_GGIO1_SPCSO3_ctlModel (&iedModel_GenericIO_GGIO1_SPCSO3_ctlModel)
#define IEDMODEL_GenericIO_GGIO1_SPCSO3_t (&iedModel_GenericIO_GGIO1_SPCSO3_t)
#define IEDMODEL_GenericIO_GGIO1_DPCSO1 (&iedModel_GenericIO_GGIO1_DPCSO1)
#define IEDMODEL_GenericIO_GGIO1_DPCSO1_stVal (&iedModel_GenericIO_GGIO1_DPCSO1_stVal)
#define IEDMODEL_GenericIO_GGIO1_DPCSO1_q (&iedModel_GenericIO_GGIO1_DPCSO1_q)
#define IEDMODEL_GenericIO_GGIO1_DPCSO1_Oper (&iedModel_GenericIO_GGIO1_DPCSO1_Oper)
#define IEDMODEL_GenericIO_GGIO1_DPCSO1_Oper_ctlVal (&iedModel_GenericIO_GGIO1_DPCSO1_Oper_ctlVal)
#define IEDMODEL_GenericIO_GGIO1_DPCSO1_Oper_origin (&iedModel_GenericIO_GGIO1_DPCSO1_Oper_origin)
#define IEDMODEL_GenericIO_GGIO1_DPCSO1_Oper_origin_orCat (&iedModel_GenericIO_GGIO1_DPCSO1_Oper_origin_orCat)
#define IEDMODEL_GenericIO_GGIO1_DPCSO1_Oper_origin_orIdent (&iedModel_GenericIO_GGIO1_DPCSO1_Oper_origin_orIdent)
#define IEDMODEL_GenericIO_GGIO1_DPCSO1_Oper_ctlNum (&iedModel_GenericIO_GGIO1_DPCSO1_Oper_ctlNum)
#define IEDMODEL_GenericIO_GGIO1_DPCSO1_Oper_T (&iedModel_GenericIO_GGIO1_DPCSO1_Oper_T)
#define IEDMODEL_GenericIO_GGIO1_DPCSO1_Oper_Test (&iedModel_GenericIO_GGIO1_DPCSO1_Oper_Test)
#define IEDMODEL_GenericIO_GGIO1_DPCSO1_Oper_Check (&iedModel_GenericIO_GGIO1_DPCSO1_Oper_Check)
#define IEDMODEL_GenericIO_GGIO1_DPCSO1_ctlModel (&iedModel_GenericIO_GGIO1_DPCSO1_ctlModel)
#define IEDMODEL_GenericIO_GGIO1_DPCSO1_t (&iedModel_GenericIO_GGIO1_DPCSO1_t)
#define IEDMODEL_GenericIO_GGIO1_Ind1 (&iedModel_GenericIO_GGIO1_Ind1)
#define IEDMODEL_GenericIO_GGIO1_Ind1_stVal (&iedModel_GenericIO_GGIO1_Ind1_stVal)
#define IEDMODEL_GenericIO_GGIO1_Ind1_q (&iedModel_GenericIO_GGIO1_Ind1_q)
#define IEDMODEL_GenericIO_GGIO1_Ind1_t (&iedModel_GenericIO_GGIO1_Ind1_t)
#define IEDMODEL_GenericIO_GGIO1_Ind2 (&iedModel_GenericIO_GGIO1_Ind2)
#define IEDMODEL_GenericIO_GGIO1_Ind2_stVal (&iedModel_GenericIO_GGIO1_Ind2_stVal)
#define IEDMODEL_GenericIO_GGIO1_Ind2_q (&iedModel_GenericIO_GGIO1_Ind2_q)
#define IEDMODEL_GenericIO_GGIO1_Ind2_t (&iedModel_GenericIO_GGIO1_Ind2_t)
#define IEDMODEL_GenericIO_GGIO1_Ind3 (&iedModel_GenericIO_GGIO1_Ind3)
#define IEDMODEL_GenericIO_GGIO1_Ind3_stVal (&iedModel_GenericIO_GGIO1_Ind3_stVal)
#define IEDMODEL_GenericIO_GGIO1_Ind3_q (&iedModel_GenericIO_GGIO1_Ind3_q)
#define IEDMODEL_GenericIO_GGIO1_Ind3_t (&iedModel_GenericIO_GGIO1_Ind3_t)
#define IEDMODEL_GenericIO_GGIO1_Ind4 (&iedModel_GenericIO_GGIO1_Ind4)
#define IEDMODEL_GenericIO_GGIO1_Ind4_stVal (&iedModel_GenericIO_GGIO1_Ind4_stVal)
#define IEDMODEL_GenericIO_GGIO1_Ind4_q (&iedModel_GenericIO_GGIO1_Ind4_q)
#define IEDMODEL_GenericIO_GGIO1_Ind4_t (&iedModel_GenericIO_GGIO1_Ind4_t)
#endif /* STATIC_MODEL_H_ */

View File

@ -0,0 +1,27 @@
using System.Reflection;
using System.Runtime.CompilerServices;
// Information about this assembly is defined by the following attributes.
// Change them to the values specific to your project.
[assembly: AssemblyTitle("IEC61850 API for C#")]
[assembly: AssemblyDescription("")]
[assembly: AssemblyConfiguration("")]
[assembly: AssemblyCompany("MZ Automation GmbH")]
[assembly: AssemblyProduct("")]
[assembly: AssemblyCopyright("Michael Zillgith")]
[assembly: AssemblyTrademark("")]
[assembly: AssemblyCulture("")]
// The assembly version has the format "{Major}.{Minor}.{Build}.{Revision}".
// The form "{Major}.{Minor}.*" will automatically update the build and revision,
// and "{Major}.{Minor}.{Build}.*" will update just the revision.
[assembly: AssemblyVersion("1.0.*")]
// The following attributes are used to specify the signing key for the assembly,
// if desired. See the Mono documentation for more information about signing.
//[assembly: AssemblyDelaySign(false)]
//[assembly: AssemblyKeyFile("")]

View File

@ -0,0 +1,131 @@
/*
* Control.cs
*
* Copyright 2014 Michael Zillgith
*
* This file is part of libIEC61850.
*
* libIEC61850 is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* libIEC61850 is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with libIEC61850. If not, see <http://www.gnu.org/licenses/>.
*
* See COPYING file for the complete license text.
*/
using System;
using System.Runtime.InteropServices;
using IEC61850.Common;
namespace IEC61850
{
namespace Common {
public enum ControlModel {
CONTROL_MODEL_STATUS_ONLY = 0,
CONTROL_MODEL_DIRECT_NORMAL = 1,
CONTROL_MODEL_SBO_NORMAL = 2,
CONTROL_MODEL_DIRECT_ENHANCED = 3,
CONTROL_MODEL_SBO_ENHANCED = 4
}
}
namespace Client {
public class ControlObject
{
[DllImport("iec61850", CallingConvention = CallingConvention.Cdecl)]
static extern IntPtr ControlObjectClient_create(string objectReference, IntPtr connection);
[DllImport("iec61850", CallingConvention = CallingConvention.Cdecl)]
static extern void ControlObjectClient_destroy(IntPtr self);
[DllImport("iec61850", CallingConvention = CallingConvention.Cdecl)]
static extern int ControlObjectClient_getControlModel(IntPtr self);
[DllImport("iec61850", CallingConvention = CallingConvention.Cdecl)]
static extern bool ControlObjectClient_operate(IntPtr self, IntPtr ctlVal, UInt64 operTime);
private IntPtr controlObject;
internal ControlObject (string objectReference, IntPtr connection)
{
this.controlObject = ControlObjectClient_create(objectReference, connection);
if (this.controlObject == System.IntPtr.Zero)
throw new IedConnectionException("Control object not found", 0);
}
~ControlObject ()
{
ControlObjectClient_destroy(controlObject);
}
public ControlModel GetControlModel ()
{
ControlModel controlModel = (ControlModel) ControlObjectClient_getControlModel(controlObject);
return controlModel;
}
public bool Operate (bool ctlVal)
{
return Operate (ctlVal, 0);
}
public bool Operate (bool ctlVal, UInt64 operTime)
{
MmsValue value = new MmsValue(ctlVal);
return Operate (value, operTime);
}
public bool Operate (float ctlVal)
{
return Operate (ctlVal, 0);
}
public bool Operate (float ctlVal, UInt64 operTime)
{
MmsValue value = new MmsValue(ctlVal);
return Operate (value, operTime);
}
public bool Operate (int ctlVal)
{
return Operate (ctlVal, 0);
}
public bool Operate (int ctlVal, UInt64 operTime)
{
MmsValue value = new MmsValue(ctlVal);
return Operate (value, operTime);
}
public bool Operate (MmsValue ctlVal)
{
return Operate (ctlVal, 0);
}
public bool Operate (MmsValue ctlVal, UInt64 operTime)
{
return ControlObjectClient_operate(controlObject, ctlVal.valueReference, operTime);
}
}
}
}

View File

@ -0,0 +1,94 @@
/*
* DataSet.cs
*
* Copyright 2014 Michael Zillgith
*
* This file is part of libIEC61850.
*
* libIEC61850 is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* libIEC61850 is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with libIEC61850. If not, see <http://www.gnu.org/licenses/>.
*
* See COPYING file for the complete license text.
*/
using System;
using System.Runtime.InteropServices;
namespace IEC61850
{
namespace Client
{
public class DataSet
{
[DllImport("iec61850", CallingConvention = CallingConvention.Cdecl)]
static extern void ClientDataSet_destroy (IntPtr self);
[DllImport("iec61850", CallingConvention = CallingConvention.Cdecl)]
static extern IntPtr ClientDataSet_getValues (IntPtr self);
[DllImport("iec61850", CallingConvention = CallingConvention.Cdecl)]
static extern IntPtr ClientDataSet_getReference (IntPtr self);
[DllImport("iec61850", CallingConvention = CallingConvention.Cdecl)]
static extern int ClientDataSet_getDataSetSize (IntPtr self);
private IntPtr nativeObject;
private MmsValue values = null;
private string reference = null;
internal DataSet (IntPtr nativeObject)
{
this.nativeObject = nativeObject;
}
public string GetReference ()
{
if (reference == null) {
IntPtr nativeString = ClientDataSet_getReference (nativeObject);
reference = Marshal.PtrToStringAnsi (nativeString);
}
return reference;
}
public MmsValue GetValues ()
{
if (values == null) {
IntPtr nativeValues = ClientDataSet_getValues (nativeObject);
values = new MmsValue (nativeValues, false);
}
return values;
}
public int GetSize ()
{
return ClientDataSet_getDataSetSize (nativeObject);
}
~DataSet ()
{
ClientDataSet_destroy (nativeObject);
}
internal IntPtr getNativeInstance ()
{
return nativeObject;
}
}
}
}

View File

@ -0,0 +1,789 @@
/*
* IEC61850ClientAPI.cs
*
* Copyright 2014 Michael Zillgith
*
* This file is part of libIEC61850.
*
* libIEC61850 is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* libIEC61850 is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with libIEC61850. If not, see <http://www.gnu.org/licenses/>.
*
* See COPYING file for the complete license text.
*/
using System;
using System.Text;
using System.Runtime.InteropServices;
using System.Collections.Generic;
using System.Collections;
using IEC61850.Common;
namespace IEC61850
{
namespace Client
{
/// <summary>
/// This class acts as the entry point for the IEC 61850 client API. It represents a single
/// (MMS) connection to a server.
/// </summary>
public partial class IedConnection
{
/*************
* MmsValue
*************/
[DllImport ("iec61850", CallingConvention=CallingConvention.Cdecl)]
static extern IntPtr MmsValue_toString (IntPtr self);
[DllImport ("iec61850", CallingConvention=CallingConvention.Cdecl)]
static extern float MmsValue_toFloat (IntPtr self);
[DllImport("iec61850", CallingConvention = CallingConvention.Cdecl)]
static extern bool MmsValue_getBoolean (IntPtr self);
[DllImport ("iec61850", CallingConvention=CallingConvention.Cdecl)]
static extern UInt32 MmsValue_getBitStringAsInteger (IntPtr self);
[DllImport ("iec61850", CallingConvention=CallingConvention.Cdecl)]
static extern int MmsValue_getType (IntPtr self);
[DllImport ("iec61850", CallingConvention=CallingConvention.Cdecl)]
static extern void MmsValue_delete (IntPtr self);
/****************
* IedConnection
***************/
[DllImport ("iec61850", CallingConvention=CallingConvention.Cdecl)]
static extern IntPtr IedConnection_create ();
[DllImport ("iec61850", CallingConvention=CallingConvention.Cdecl)]
static extern void IedConnection_connect (IntPtr self, out int error, string hostname, int tcpPort);
[DllImport ("iec61850", CallingConvention=CallingConvention.Cdecl)]
static extern void IedConnection_abort (IntPtr self, out int error);
[DllImport ("iec61850", CallingConvention=CallingConvention.Cdecl)]
private static extern void IedConnection_release(IntPtr self, out int error);
[DllImport ("iec61850", CallingConvention=CallingConvention.Cdecl)]
private static extern void IedConnection_close(IntPtr self);
[DllImport ("iec61850", CallingConvention=CallingConvention.Cdecl)]
static extern IntPtr IedConnection_readObject (IntPtr self, out int error, string objectReference, int fc);
[DllImport ("iec61850", CallingConvention=CallingConvention.Cdecl)]
static extern void IedConnection_writeObject (IntPtr self, out int error, string dataAttributeReference, int fc, IntPtr value);
[DllImport("iec61850", CallingConvention = CallingConvention.Cdecl)]
static extern IntPtr IedConnection_getDataDirectory (IntPtr self, out int error, string dataReference);
[DllImport("iec61850", CallingConvention = CallingConvention.Cdecl)]
static extern IntPtr IedConnection_getDataDirectoryFC (IntPtr self, out int error, string dataReference);
[DllImport("iec61850", CallingConvention = CallingConvention.Cdecl)]
static extern IntPtr IedConnection_getLogicalNodeDirectory (IntPtr self, out int error, string logicalNodeReference, int acsiClass);
[DllImport ("iec61850", CallingConvention=CallingConvention.Cdecl)]
static extern IntPtr IedConnection_getServerDirectory (IntPtr self, out int error, bool getFileNames);
[DllImport ("iec61850", CallingConvention=CallingConvention.Cdecl)]
static extern IntPtr IedConnection_getLogicalDeviceDirectory (IntPtr self, out int error, string logicalDeviceName);
private delegate void InternalConnectionClosedHandler (IntPtr parameter,IntPtr Iedconnection);
public delegate void ConnectionClosedHandler (IedConnection connection);
[DllImport("iec61850", CallingConvention = CallingConvention.Cdecl)]
static extern void IedConnection_installConnectionClosedHandler (IntPtr self, InternalConnectionClosedHandler handler, IntPtr parameter);
[DllImport("iec61850", CallingConvention = CallingConvention.Cdecl)]
static extern IntPtr IedConnection_readDataSetValues (IntPtr self, out int error, string dataSetReference, IntPtr dataSet);
[DllImport("iec61850", CallingConvention = CallingConvention.Cdecl)]
static extern IntPtr IedConnection_createDataSet (IntPtr self, out int error, string dataSetReference, IntPtr dataSet);
[DllImport("iec61850", CallingConvention = CallingConvention.Cdecl)]
static extern void IedConnection_deleteDataSet (IntPtr self, out int error, string dataSetReference);
[DllImport("iec61850", CallingConvention = CallingConvention.Cdecl)]
static extern IntPtr IedConnection_getDataSetDirectory (IntPtr self, out int error, string dataSetReference, out bool isDeletable);
[DllImport("iec61850", CallingConvention = CallingConvention.Cdecl)]
static extern IntPtr IedConnection_getMmsConnection (IntPtr self);
[DllImport("iec61850", CallingConvention = CallingConvention.Cdecl)]
static extern IntPtr MmsConnection_getIsoConnectionParameters(IntPtr mmsConnection);
/****************
* LinkedList
***************/
[DllImport("iec61850", CallingConvention = CallingConvention.Cdecl)]
static extern IntPtr LinkedList_getNext (IntPtr self);
[DllImport("iec61850", CallingConvention = CallingConvention.Cdecl)]
static extern IntPtr LinkedList_getData (IntPtr self);
[DllImport("iec61850", CallingConvention = CallingConvention.Cdecl)]
static extern void LinkedList_destroy (IntPtr self);
[DllImport("iec61850", CallingConvention = CallingConvention.Cdecl)]
static extern IntPtr LinkedList_create ();
[DllImport("iec61850", CallingConvention = CallingConvention.Cdecl)]
static extern void LinkedList_add (IntPtr self, IntPtr data);
private IntPtr connection;
private InternalConnectionClosedHandler connectionClosedHandler;
private ConnectionClosedHandler userProvidedHandler = null;
public IedConnection ()
{
connection = IedConnection_create ();
}
public IsoConnectionParameters GetConnectionParameters ()
{
IntPtr mmsConnection = IedConnection_getMmsConnection(connection);
IntPtr parameters = MmsConnection_getIsoConnectionParameters(mmsConnection);
return new IsoConnectionParameters(parameters);
}
/// <summary>Establish an MMS connection to a server</summary>
/// <exception cref="IedConnectionException">This exception is thrown if there is a connection or service error</exception>
public void Connect (string hostname, int tcpPort)
{
int error;
IedConnection_connect (connection, out error, hostname, tcpPort);
if (error != 0)
throw new IedConnectionException ("Connect to " + hostname + ":" + tcpPort + " failed", error);
}
/// <summary>Establish an MMS connection to a server.</summary>
/// <exception cref="IedConnectionException">This exception is thrown if there is a connection or service error.</exception>
public void Connect (string hostname)
{
Connect (hostname, 102);
}
/// <exception cref="IedConnectionException">This exception is thrown if there is a connection or service error</exception>
public ControlObject CreateControlObject (string objectReference)
{
ControlObject controlObject = new ControlObject (objectReference, connection);
return controlObject;
}
/// <exception cref="IedConnectionException">This exception is thrown if there is a connection or service error</exception>
public List<string> GetServerDirectory (bool fileDirectory = false)
{
int error;
IntPtr linkedList = IedConnection_getServerDirectory (connection, out error, fileDirectory);
if (error != 0)
throw new IedConnectionException ("GetDeviceDirectory failed", error);
IntPtr element = LinkedList_getNext (linkedList);
List<string> newList = new List<string> ();
while (element != IntPtr.Zero) {
string ld = Marshal.PtrToStringAnsi (LinkedList_getData (element));
newList.Add (ld);
element = LinkedList_getNext (element);
}
LinkedList_destroy (linkedList);
return newList;
}
/// <exception cref="IedConnectionException">This exception is thrown if there is a connection or service error</exception>
public List<string> GetLogicalDeviceDirectory (string logicalDeviceName)
{
int error;
IntPtr linkedList = IedConnection_getLogicalDeviceDirectory (connection, out error, logicalDeviceName);
if (error != 0)
throw new IedConnectionException ("GetLogicalDeviceDirectory failed", error);
IntPtr element = LinkedList_getNext (linkedList);
List<string> newList = new List<string> ();
while (element != IntPtr.Zero) {
string ln = Marshal.PtrToStringAnsi (LinkedList_getData (element));
newList.Add (ln);
element = LinkedList_getNext (element);
}
LinkedList_destroy (linkedList);
return newList;
}
/// <exception cref="IedConnectionException">This exception is thrown if there is a connection or service error</exception>
public List<string> GetLogicalNodeDirectory (string logicalNodeName, ACSIClass acsiClass)
{
int error;
IntPtr linkedList = IedConnection_getLogicalNodeDirectory (connection, out error, logicalNodeName, (int)acsiClass);
if (error != 0)
throw new IedConnectionException ("GetLogicalNodeDirectory failed", error);
IntPtr element = LinkedList_getNext (linkedList);
List<string> newList = new List<string> ();
while (element != IntPtr.Zero) {
string dataObject = Marshal.PtrToStringAnsi (LinkedList_getData (element));
newList.Add (dataObject);
element = LinkedList_getNext (element);
}
LinkedList_destroy (linkedList);
return newList;
}
/// <exception cref="IedConnectionException">This exception is thrown if there is a connection or service error</exception>
public List<string> GetDataDirectory (string dataReference)
{
int error;
IntPtr linkedList = IedConnection_getDataDirectory (connection, out error, dataReference);
if (error != 0)
throw new IedConnectionException ("GetDataDirectory failed", error);
IntPtr element = LinkedList_getNext (linkedList);
List<string> newList = new List<string> ();
while (element != IntPtr.Zero) {
string dataObject = Marshal.PtrToStringAnsi (LinkedList_getData (element));
newList.Add (dataObject);
element = LinkedList_getNext (element);
}
LinkedList_destroy (linkedList);
return newList;
}
/// <exception cref="IedConnectionException">This exception is thrown if there is a connection or service error</exception>
public List<string> GetDataDirectoryFC (string dataReference)
{
int error;
IntPtr linkedList = IedConnection_getDataDirectoryFC (connection, out error, dataReference);
if (error != 0)
throw new IedConnectionException ("GetDataDirectoryFC failed", error);
IntPtr element = LinkedList_getNext (linkedList);
List<string> newList = new List<string> ();
while (element != IntPtr.Zero) {
string dataObject = Marshal.PtrToStringAnsi (LinkedList_getData (element));
newList.Add (dataObject);
element = LinkedList_getNext (element);
}
LinkedList_destroy (linkedList);
return newList;
}
private IntPtr readObjectInternal (string objectReference, FunctionalConstraint fc)
{
int error;
IntPtr mmsValue = IedConnection_readObject (connection, out error, objectReference, (int)fc);
if (error != 0)
throw new IedConnectionException ("Reading value failed", error);
if (mmsValue.ToInt32 () == 0)
throw new IedConnectionException ("Variable not found on server", error);
return mmsValue;
}
/// <summary>Read the value of a data attribute (DA) or functional constraint data object (FCDO).</summary>
/// <param name="objectReference">The object reference of a DA or FCDO.</param>
/// <param name="fc">The functional constraint (FC) of the object</param>
/// <exception cref="IedConnectionException">This exception is thrown if there is a connection or service error</exception>
public MmsValue ReadValue (String objectReference, FunctionalConstraint fc)
{
var value = readObjectInternal (objectReference, fc);
return new MmsValue (value, true);
}
/// <summary>Read the value of a basic data attribute (BDA) of type boolean.</summary>
/// <param name="objectReference">The object reference of a BDA.</param>
/// <param name="fc">The functional constraint (FC) of the object</param>
/// <exception cref="IedConnectionException">This exception is thrown if there is a connection or service error</exception>
public bool ReadBooleanValue (string objectReference, FunctionalConstraint fc)
{
var mmsValue = ReadValue (objectReference, fc);
if (mmsValue.GetType () == MmsType.MMS_BOOLEAN)
return mmsValue.GetBoolean ();
else
throw new IedConnectionException ("Result is not of type timestamp (MMS_UTC_TIME)", 0);
}
/// <summary>Read the value of a basic data attribute (BDA) of type float.</summary>
/// <param name="objectReference">The object reference of a BDA.</param>
/// <param name="fc">The functional constraint (FC) of the object</param>
/// <exception cref="IedConnectionException">This exception is thrown if there is a connection or service error</exception>
public float ReadFloatValue (string objectReference, FunctionalConstraint fc)
{
IntPtr mmsValue = readObjectInternal (objectReference, fc);
if (MmsValue_getType (mmsValue) != (int)MmsType.MMS_FLOAT)
throw new IedConnectionException ("Result is not of type float", 0);
float value = MmsValue_toFloat (mmsValue);
MmsValue_delete (mmsValue);
return value;
}
/// <summary>Read the value of a basic data attribute (BDA) of type string (VisibleString or MmsString).</summary>
/// <param name="objectReference">The object reference of a BDA.</param>
/// <param name="fc">The functional constraint (FC) of the object</param>
/// <exception cref="IedConnectionException">This exception is thrown if there is a connection or service error</exception>
public string ReadStringValue (string objectReference, FunctionalConstraint fc)
{
IntPtr mmsValue = readObjectInternal (objectReference, fc);
if (!((MmsValue_getType (mmsValue) == (int)MmsType.MMS_VISIBLE_STRING) || (MmsValue_getType (mmsValue) == (int)MmsType.MMS_STRING))) {
MmsValue_delete (mmsValue);
throw new IedConnectionException ("Result is not of type string", 0);
}
IntPtr ptr = MmsValue_toString (mmsValue);
string returnString = Marshal.PtrToStringAnsi (ptr);
MmsValue_delete (mmsValue);
return returnString;
}
/// <summary>Read the value of a basic data attribute (BDA) of type quality.</summary>
/// <param name="objectReference">The object reference of a BDA.</param>
/// <param name="fc">The functional constraint (FC) of the object</param>
/// <exception cref="IedConnectionException">This exception is thrown if there is a connection or service error</exception>
public Quality ReadQualityValue (string objectReference, FunctionalConstraint fc)
{
IntPtr mmsValue = readObjectInternal (objectReference, fc);
if (MmsValue_getType (mmsValue) == (int)MmsType.MMS_BIT_STRING) {
int bitStringValue = (int)MmsValue_getBitStringAsInteger (mmsValue);
MmsValue_delete (mmsValue);
return new Quality (bitStringValue);
} else {
MmsValue_delete (mmsValue);
throw new IedConnectionException ("Result is not of type bit string(Quality)", 0);
}
}
/// <summary>Read the value of a basic data attribute (BDA) of type timestamp (MMS_UTC_TIME).</summary>
/// <param name="objectReference">The object reference of a BDA.</param>
/// <param name="fc">The functional constraint (FC) of the object</param>
/// <exception cref="IedConnectionException">This exception is thrown if there is a connection or service error</exception>
public UInt64 ReadTimestampValue (string objectReference, FunctionalConstraint fc)
{
var mmsValuePtr = readObjectInternal (objectReference, fc);
var mmsValue = new MmsValue (mmsValuePtr, true);
if (mmsValue.GetType () == MmsType.MMS_UTC_TIME)
return mmsValue.GetUtcTimeInMs ();
else
throw new IedConnectionException ("Result is not of type timestamp (MMS_UTC_TIME)", 0);
}
/// <summary>Read the value of a basic data attribute (BDA) of type integer (MMS_INTEGER).</summary>
/// <description>This function should also be used if enumerations are beeing read. Because
/// enumerations are mapped to integer types for the MMS mapping</description>
/// <param name="objectReference">The object reference of a BDA.</param>
/// <param name="fc">The functional constraint (FC) of the object</param>
/// <exception cref="IedConnectionException">This exception is thrown if there is a connection or service error</exception>
public Int64 ReadIntegerValue (string objectReference, FunctionalConstraint fc)
{
var mmsValuePtr = readObjectInternal (objectReference, fc);
var mmsValue = new MmsValue (mmsValuePtr, true);
if (mmsValue.GetType () == MmsType.MMS_INTEGER)
return mmsValue.ToInt64 ();
else
throw new IedConnectionException ("Result is not of type integer (MMS_INTEGER)", 0);
}
/// <exception cref="IedConnectionException">This exception is thrown if there is a connection or service error</exception>
public void WriteValue (string objectReference, FunctionalConstraint fc, MmsValue value)
{
int error;
IedConnection_writeObject (connection, out error, objectReference, (int)fc, value.valueReference);
if (error != 0)
throw new IedConnectionException ("Write value failed", error);
}
/// <exception cref="IedConnectionException">This exception is thrown if there is a connection or service error</exception>
public void Abort ()
{
int error;
IedConnection_abort (connection, out error);
if (error != 0)
throw new IedConnectionException ("Abort failed", error);
}
/// <exception cref="IedConnectionException">This exception is thrown if there is a connection or service error</exception>
public void Release ()
{
int error;
IedConnection_release(connection, out error);
if (error != 0)
throw new IedConnectionException ("Release failed", error);
}
public void Close ()
{
IedConnection_close(connection);
}
private void MyConnectionClosedHandler (IntPtr parameter, IntPtr self)
{
if (userProvidedHandler != null)
userProvidedHandler (this);
}
public void InstallConnectionClosedHandler (ConnectionClosedHandler handler)
{
connectionClosedHandler = new InternalConnectionClosedHandler (MyConnectionClosedHandler);
userProvidedHandler = handler;
IedConnection_installConnectionClosedHandler (connection, connectionClosedHandler, connection);
}
/// <exception cref="IedConnectionException">This exception is thrown if there is a connection or service error</exception>
public DataSet ReadDataSetValues (string dataSetReference, DataSet dataSet)
{
IntPtr nativeClientDataSet = IntPtr.Zero;
if (dataSet != null)
nativeClientDataSet = dataSet.getNativeInstance ();
int error;
nativeClientDataSet = IedConnection_readDataSetValues (connection, out error, dataSetReference, nativeClientDataSet);
if (error != 0)
throw new IedConnectionException ("Reading data set failed", error);
if (dataSet == null)
dataSet = new DataSet (nativeClientDataSet);
return dataSet;
}
public void CreateDataSet (string dataSetReference, List<string> dataSetElements)
{
IntPtr linkedList = LinkedList_create ();
foreach (string dataSetElement in dataSetElements) {
IntPtr handle = System.Runtime.InteropServices.Marshal.StringToHGlobalAuto (dataSetElement);
LinkedList_add (linkedList, handle);
}
int error;
IedConnection_createDataSet (connection, out error, dataSetReference, linkedList);
LinkedList_destroy (linkedList);
if (error != 0)
throw new IedConnectionException ("Failed to create data set", error);
}
public void DeleteDataSet (string dataSetReference)
{
int error;
IedConnection_deleteDataSet (connection, out error, dataSetReference);
if (error != 0)
throw new IedConnectionException ("Failed to delete data set", error);
}
/// <exception cref="IedConnectionException">This exception is thrown if there is a connection or service error</exception>
public List<string> GetDataSetDirectory (string dataSetReference)
{
int error;
bool isDeletable;
IntPtr linkedList = IedConnection_getDataSetDirectory (connection, out error, dataSetReference, out isDeletable);
if (error != 0)
throw new IedConnectionException ("getDataSetDirectory failed", error);
IntPtr element = LinkedList_getNext (linkedList);
List<string> newList = new List<string> ();
while (element != IntPtr.Zero) {
string dataObject = Marshal.PtrToStringAnsi (LinkedList_getData (element));
newList.Add (dataObject);
element = LinkedList_getNext (element);
}
LinkedList_destroy (linkedList);
return newList;
}
}
public class IedConnectionException : Exception
{
private int errorCode;
public IedConnectionException (string message, int errorCode) : base(message)
{
this.errorCode = errorCode;
}
public IedConnectionException (string message) : base(message)
{
this.errorCode = 0;
}
public int GetErrorCode ()
{
return this.errorCode;
}
public IedClientError GetIedClientError ()
{
return (IedClientError)this.errorCode;
}
}
public enum IedClientError
{
/* general errors */
/** No error occurred - service request has been successful */
IED_ERROR_OK = 0,
/** The service request can not be executed because the client is not yet connected */
IED_ERROR_NOT_CONNECTED = 1,
/** Connect service not execute because the client is already connected */
IED_ERROR_ALREADY_CONNECTED = 2,
/** The service request can not be executed caused by a loss of connection */
IED_ERROR_CONNECTION_LOST = 3,
/** The service or some given parameters are not supported by the client stack or by the server */
IED_ERROR_SERVICE_NOT_SUPPORTED = 4,
/** Connection rejected by server */
IED_ERROR_CONNECTION_REJECTED = 5,
/* client side errors */
/** API function has been called with an invalid argument */
IED_ERROR_USER_PROVIDED_INVALID_ARGUMENT = 10,
IED_ERROR_ENABLE_REPORT_FAILED_DATASET_MISMATCH = 11,
/** The object provided object reference is invalid (there is a syntactical error). */
IED_ERROR_OBJECT_REFERENCE_INVALID = 12,
/** Received object is of unexpected type */
IED_ERROR_UNEXPECTED_VALUE_RECEIVED = 13,
/* service error - error reported by server */
/** The communication to the server failed with a timeout */
IED_ERROR_TIMEOUT = 20,
/** The server rejected the access to the requested object/service due to access control */
IED_ERROR_ACCESS_DENIED = 21,
/** The server reported that the requested object does not exist */
IED_ERROR_OBJECT_DOES_NOT_EXIST = 22,
/** The server reported that the requested object already exists */
IED_ERROR_OBJECT_EXISTS = 23,
/** The server does not support the requested access method */
IED_ERROR_OBJECT_ACCESS_UNSUPPORTED = 24,
/* unknown error */
IED_ERROR_UNKNOWN = 99
}
}
namespace Common
{
[Flags]
public enum TriggerOptions {
NONE = 0,
DATA_CHANGED = 1,
QUALITY_CHANGED = 2,
DATA_UPDATE = 4,
INTEGRITY = 8,
GI = 16
}
[Flags]
public enum ReportOptions {
NONE = 0,
SEQ_NUM = 1,
TIME_STAMP = 2,
REASON_FOR_INCLUSION = 4,
DATA_SET = 8,
DATA_REFERENCE = 16,
BUFFER_OVERFLOW = 32,
ENTRY_ID = 64,
CONF_REV = 128
}
public enum Validity
{
GOOD = 0,
INVALID = 1,
RESERVED = 2,
QUESTIONABLE = 3
}
public class Quality
{
private UInt16 value;
public Quality (int bitStringValue)
{
value = (UInt16)bitStringValue;
}
public Quality ()
{
value = 0;
}
public Validity GetValidity ()
{
int qualityVal = value & 0x3;
return (Validity)qualityVal;
}
public void SetValidity (Validity validity)
{
value = (UInt16)(value & 0xfffc);
value += (ushort)validity;
}
}
public enum ACSIClass
{
ACSI_CLASS_DATA_OBJECT,
ACSI_CLASS_DATA_SET,
ACSI_CLASS_BRCB,
ACSI_CLASS_URCB,
ACSI_CLASS_LCB,
ACSI_CLASS_LOG,
ACSI_CLASS_SGCB,
ACSI_CLASS_GoCB,
ACSI_CLASS_GsCB,
ACSI_CLASS_MSVCB,
ACSI_CLASS_USVCB
}
public enum FunctionalConstraint
{
/** Status information */
ST = 0,
/** Measurands - analog values */
MX = 1,
/** Setpoint */
SP = 2,
/** Substitution */
SV = 3,
/** Configuration */
CF = 4,
/** Description */
DC = 5,
/** Setting group */
SG = 6,
/** Setting group editable */
SE = 7,
/** Service response / Service tracking */
SR = 8,
/** Operate received */
OR = 9,
/** Blocking */
BL = 10,
/** Extended definition */
EX = 11,
/** Control */
CO = 12,
ALL = 99,
NONE = -1
}
}
}

View File

@ -0,0 +1,45 @@
<?xml version="1.0" encoding="utf-8"?>
<Project DefaultTargets="Build" ToolsVersion="4.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
<PropertyGroup>
<Configuration Condition=" '$(Configuration)' == '' ">Debug</Configuration>
<Platform Condition=" '$(Platform)' == '' ">AnyCPU</Platform>
<ProductVersion>8.0.30703</ProductVersion>
<SchemaVersion>2.0</SchemaVersion>
<ProjectGuid>{C35D624E-5506-4560-8074-1728F1FA1A4D}</ProjectGuid>
<OutputType>Library</OutputType>
<RootNamespace>iec61850dotnet</RootNamespace>
<AssemblyName>iec61850dotnet</AssemblyName>
</PropertyGroup>
<PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Debug|AnyCPU' ">
<DebugSymbols>true</DebugSymbols>
<DebugType>full</DebugType>
<Optimize>false</Optimize>
<OutputPath>bin\Debug</OutputPath>
<DefineConstants>DEBUG;</DefineConstants>
<ErrorReport>prompt</ErrorReport>
<WarningLevel>4</WarningLevel>
<ConsolePause>false</ConsolePause>
</PropertyGroup>
<PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Release|AnyCPU' ">
<DebugType>none</DebugType>
<Optimize>true</Optimize>
<OutputPath>bin\Release</OutputPath>
<ErrorReport>prompt</ErrorReport>
<WarningLevel>4</WarningLevel>
<ConsolePause>false</ConsolePause>
</PropertyGroup>
<ItemGroup>
<Reference Include="System" />
</ItemGroup>
<ItemGroup>
<Compile Include="AssemblyInfo.cs" />
<Compile Include="MmsValue.cs" />
<Compile Include="DataSet.cs" />
<Compile Include="ReportControlBlock.cs" />
<Compile Include="IEC61850ClientAPI.cs" />
<Compile Include="Reporting.cs" />
<Compile Include="Control.cs" />
<Compile Include="IsoConnectionParameters.cs" />
</ItemGroup>
<Import Project="$(MSBuildBinPath)\Microsoft.CSharp.targets" />
</Project>

View File

@ -0,0 +1,121 @@
/*
* IsoConnectionParameters.cs
*
* Copyright 2014 Michael Zillgith
*
* This file is part of libIEC61850.
*
* libIEC61850 is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* libIEC61850 is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with libIEC61850. If not, see <http://www.gnu.org/licenses/>.
*
* See COPYING file for the complete license text.
*/
using System;
using System.Runtime.InteropServices;
namespace IEC61850
{
namespace Client
{
public enum AcseAuthenticationMechanism {
ACSE_AUTH_NONE = 0,
ACSE_AUTH_PASSWORD = 1
}
public class IsoConnectionParameters
{
[DllImport("iec61850", CallingConvention = CallingConvention.Cdecl)]
private static extern void IsoConnectionParameters_destroy(IntPtr self);
[DllImport("iec61850", CallingConvention = CallingConvention.Cdecl)]
private static extern void IsoConnectionParameters_setRemoteApTitle(IntPtr self, string apTitle, int aeQualifier);
[DllImport("iec61850", CallingConvention = CallingConvention.Cdecl)]
private static extern void IsoConnectionParameters_setRemoteAddresses(IntPtr self, UInt32 pSelector, UInt16 sSelector, UInt16 tSelector);
[DllImport("iec61850", CallingConvention = CallingConvention.Cdecl)]
private static extern void IsoConnectionParameters_setLocalApTitle(IntPtr self, string apTitle, int aeQualifier);
[DllImport("iec61850", CallingConvention = CallingConvention.Cdecl)]
private static extern void IsoConnectionParameters_setLocalAddresses(IntPtr self, UInt32 pSelector, UInt16 sSelector, UInt16 tSelector);
[DllImport("iec61850", CallingConvention = CallingConvention.Cdecl)]
private static extern void IsoConnectionParameters_setAcseAuthenticationParameter(IntPtr self, IntPtr acseAuthParameter);
[DllImport("iec61850", CallingConvention = CallingConvention.Cdecl)]
private static extern IntPtr AcseAuthenticationParameter_create();
[DllImport("iec61850", CallingConvention = CallingConvention.Cdecl)]
private static extern void AcseAuthenticationParameter_destroy(IntPtr self);
[DllImport("iec61850", CallingConvention = CallingConvention.Cdecl)]
private static extern void AcseAuthenticationParameter_setAuthMechanism(IntPtr self, int mechanism);
[DllImport("iec61850", CallingConvention = CallingConvention.Cdecl)]
private static extern void AcseAuthenticationParameter_setPassword(IntPtr self, string password);
private IntPtr self;
private IntPtr authParameter = IntPtr.Zero;
internal IsoConnectionParameters (IntPtr self)
{
this.self = self;
}
~IsoConnectionParameters ()
{
if (authParameter != IntPtr.Zero)
AcseAuthenticationParameter_destroy(authParameter);
IsoConnectionParameters_destroy(self);
}
public void SetRemoteApTitle(string apTitle, int aeQualifier)
{
IsoConnectionParameters_setRemoteApTitle(self, apTitle, aeQualifier);
}
public void SetRemoteAddresses (UInt32 pSelector, UInt16 sSelector, UInt16 tSelector)
{
IsoConnectionParameters_setRemoteAddresses(self, pSelector, sSelector, tSelector);
}
public void SetLocalApTitle (string apTitle, int aeQualifier)
{
IsoConnectionParameters_setLocalApTitle(self, apTitle, aeQualifier);
}
public void SetLocalAddresses (UInt32 pSelector, UInt16 sSelector, UInt16 tSelector)
{
IsoConnectionParameters_setLocalAddresses(self, pSelector, sSelector, tSelector);
}
public void UsePasswordAuthentication (string password)
{
if (authParameter == IntPtr.Zero) {
authParameter = AcseAuthenticationParameter_create ();
AcseAuthenticationParameter_setAuthMechanism (authParameter, (int)AcseAuthenticationMechanism.ACSE_AUTH_PASSWORD);
AcseAuthenticationParameter_setPassword (authParameter, password);
IsoConnectionParameters_setAcseAuthenticationParameter(self, authParameter);
}
else
throw new IedConnectionException("Authentication parameter already set");
}
}
}
}

View File

@ -0,0 +1,344 @@
/*
* MmsValue.cs
*
* Copyright 2014 Michael Zillgith
*
* This file is part of libIEC61850.
*
* libIEC61850 is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* libIEC61850 is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with libIEC61850. If not, see <http://www.gnu.org/licenses/>.
*
* See COPYING file for the complete license text.
*/
using System;
using System.Runtime.InteropServices;
using System.Collections.Generic;
using System.Collections;
namespace IEC61850
{
namespace Client
{
public class MmsValue : IEnumerable
{
[DllImport("iec61850", CallingConvention = CallingConvention.Cdecl)]
static extern IntPtr MmsValue_toString (IntPtr self);
[DllImport("iec61850", CallingConvention = CallingConvention.Cdecl)]
static extern float MmsValue_toFloat (IntPtr self);
[DllImport("iec61850", CallingConvention = CallingConvention.Cdecl)]
static extern double MmsValue_toDouble (IntPtr self);
[DllImport("iec61850", CallingConvention = CallingConvention.Cdecl)]
static extern bool MmsValue_getBoolean (IntPtr self);
[DllImport("iec61850", CallingConvention = CallingConvention.Cdecl)]
static extern UInt32 MmsValue_getBitStringAsInteger (IntPtr self);
[DllImport("iec61850", CallingConvention = CallingConvention.Cdecl)]
static extern Int32 MmsValue_toInt32 (IntPtr self);
[DllImport("iec61850", CallingConvention = CallingConvention.Cdecl)]
static extern Int64 MmsValue_toInt64 (IntPtr self);
[DllImport("iec61850", CallingConvention = CallingConvention.Cdecl)]
static extern UInt32 MmsValue_toUint32 (IntPtr self);
[DllImport("iec61850", CallingConvention = CallingConvention.Cdecl)]
static extern int MmsValue_getType (IntPtr self);
[DllImport("iec61850", CallingConvention = CallingConvention.Cdecl)]
static extern void MmsValue_delete (IntPtr self);
[DllImport("iec61850", CallingConvention = CallingConvention.Cdecl)]
static extern IntPtr MmsValue_getElement (IntPtr complexValue, int index);
[DllImport("iec61850", CallingConvention = CallingConvention.Cdecl)]
static extern int MmsValue_getArraySize (IntPtr self);
[DllImport("iec61850", CallingConvention = CallingConvention.Cdecl)]
static extern ulong MmsValue_getUtcTimeInMs (IntPtr self);
[DllImport("iec61850", CallingConvention = CallingConvention.Cdecl)]
static extern UInt32 MmsValue_toUnixTimestamp (IntPtr self);
[DllImport("iec61850", CallingConvention = CallingConvention.Cdecl)]
static extern IntPtr MmsValue_newBoolean (bool value);
[DllImport("iec61850", CallingConvention = CallingConvention.Cdecl)]
static extern IntPtr MmsValue_newFloat (float value);
[DllImport("iec61850", CallingConvention = CallingConvention.Cdecl)]
static extern IntPtr MmsValue_newDouble (double value);
[DllImport("iec61850", CallingConvention = CallingConvention.Cdecl)]
static extern IntPtr MmsValue_newIntegerFromInt32 (Int32 integer);
[DllImport("iec61850", CallingConvention = CallingConvention.Cdecl)]
static extern IntPtr MmsValue_newIntegerFromInt64 (Int64 integer);
internal MmsValue (IntPtr value)
{
valueReference = value;
this.responsableForDeletion = false;
}
internal MmsValue (IntPtr value, bool responsableForDeletion)
{
valueReference = value;
this.responsableForDeletion = responsableForDeletion;
}
public MmsValue (bool value)
{
valueReference = MmsValue_newBoolean (value);
}
public MmsValue (float value)
{
valueReference = MmsValue_newFloat (value);
}
public MmsValue (double value)
{
valueReference = MmsValue_newDouble (value);
}
public MmsValue (int value)
{
valueReference = MmsValue_newIntegerFromInt32 (value);
}
public MmsValue (long value)
{
valueReference = MmsValue_newIntegerFromInt64 (value);
}
~MmsValue ()
{
if (responsableForDeletion)
MmsValue_delete (valueReference);
}
internal IntPtr valueReference;
private bool responsableForDeletion;
public new MmsType GetType ()
{
return (MmsType)MmsValue_getType (valueReference);
}
public int Size ()
{
if ((GetType () == MmsType.MMS_ARRAY) || (GetType () == MmsType.MMS_STRUCTURE)) {
return MmsValue_getArraySize (valueReference);
} else
throw new MmsValueException ("Value is not a complex type");
}
public MmsValue GetElement (int index)
{
MmsType type = GetType ();
if ((type == MmsType.MMS_ARRAY) || (type == MmsType.MMS_STRUCTURE)) {
if ((index >= 0) && (index < Size ())) {
IntPtr value = MmsValue_getElement (valueReference, index);
return new MmsValue (value);
} else
throw new MmsValueException ("Index out of bounds");
} else
throw new MmsValueException ("Value is of wrong type");
}
public UInt32 ToUnixTimestamp ()
{
if (GetType () == MmsType.MMS_UTC_TIME)
return MmsValue_toUnixTimestamp (valueReference);
else
throw new MmsValueException ("Value is not a time type");
}
public ulong GetUtcTimeInMs ()
{
if (GetType () == MmsType.MMS_UTC_TIME) {
return MmsValue_getUtcTimeInMs (valueReference);
} else
throw new MmsValueException ("Value is not a time type");
}
public static DateTimeOffset MsTimeToDateTimeOffset (UInt64 msTime)
{
DateTimeOffset retVal = new DateTimeOffset (1970, 1, 1, 0, 0, 0, TimeSpan.Zero);
return retVal.AddMilliseconds (msTime);
}
public DateTimeOffset GetUtcTimeAsDateTimeOffset ()
{
if (GetType () == MmsType.MMS_UTC_TIME)
return MsTimeToDateTimeOffset (GetUtcTimeInMs ());
else
throw new MmsValueException ("Value is not a time type");
}
public Int32 ToInt32 ()
{
if (GetType () != MmsType.MMS_INTEGER)
throw new MmsValueException ("Value type is not integer");
Int32 retVal = MmsValue_toInt32 (valueReference);
return retVal;
}
public Int64 ToInt64 ()
{
if (GetType () != MmsType.MMS_INTEGER)
throw new MmsValueException ("Value type is not integer");
Int64 retVal = MmsValue_toInt64 (valueReference);
return retVal;
}
public UInt32 ToUint32 ()
{
if (GetType () != MmsType.MMS_UNSIGNED)
throw new MmsValueException ("Value type is not unsigned");
UInt32 retVal = MmsValue_toUint32 (valueReference);
return retVal;
}
public bool GetBoolean ()
{
if (GetType () == MmsType.MMS_BOOLEAN)
return MmsValue_getBoolean (valueReference);
else
throw new MmsValueException ("Value type is not boolean");
}
public float ToFloat ()
{
if (GetType () == MmsType.MMS_FLOAT)
return MmsValue_toFloat (valueReference);
else
throw new MmsValueException ("Value type is not float");
}
public double ToDouble ()
{
if (GetType () == MmsType.MMS_FLOAT)
return MmsValue_toDouble (valueReference);
else
throw new MmsValueException ("Value type is not float");
}
// override standard ToString() method
public override string ToString ()
{
switch (GetType ()) {
case MmsType.MMS_VISIBLE_STRING:
case MmsType.MMS_STRING:
return Marshal.PtrToStringAnsi (MmsValue_toString (valueReference));
case MmsType.MMS_BOOLEAN:
return GetBoolean ().ToString ();
case MmsType.MMS_INTEGER:
return ToInt64 ().ToString ();
case MmsType.MMS_UNSIGNED:
return ToUint32 ().ToString ();
case MmsType.MMS_FLOAT:
return ToDouble ().ToString ();
case MmsType.MMS_UTC_TIME:
return GetUtcTimeAsDateTimeOffset ().ToString ();
default:
return "unknown";
}
}
IEnumerator IEnumerable.GetEnumerator ()
{
return new MmsValueEnumerator (this);
}
private class MmsValueEnumerator : IEnumerator
{
private MmsValue value;
private int index = -1;
public MmsValueEnumerator (MmsValue value)
{
this.value = value;
}
#region IEnumerator Members
public void Reset ()
{
index = -1;
}
public object Current {
get { return value.GetElement (index);}
}
public bool MoveNext ()
{
index++;
if (index >= value.Size ())
return false;
else
return true;
}
#endregion
}
}
public class MmsValueException : Exception
{
public MmsValueException (string message)
: base(message)
{
}
}
public enum MmsType
{
MMS_ARRAY = 0,
MMS_STRUCTURE = 1,
MMS_BOOLEAN = 2,
MMS_BIT_STRING = 3,
MMS_INTEGER = 4,
MMS_UNSIGNED = 5,
MMS_FLOAT = 6,
MMS_OCTET_STRING = 7,
MMS_VISIBLE_STRING = 8,
MMS_GENERALIZED_TIME = 9,
MMS_BINARY_TIME = 10,
MMS_BCD = 11,
MMS_OBJ_ID = 12,
MMS_STRING = 13,
MMS_UTC_TIME = 14,
MMS_DATA_ACCESS_ERROR = 15
}
}
}

View File

@ -0,0 +1,415 @@
/*
* ReportControlBlock.cs
*
* Copyright 2014 Michael Zillgith
*
* This file is part of libIEC61850.
*
* libIEC61850 is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* libIEC61850 is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with libIEC61850. If not, see <http://www.gnu.org/licenses/>.
*
* See COPYING file for the complete license text.
*/
using System;
using System.Runtime.InteropServices;
using System.Diagnostics;
using IEC61850.Common;
namespace IEC61850
{
namespace Client
{
public delegate void ReportHandler (Report report, object parameter);
public class ReportControlBlock
{
[DllImport("iec61850", CallingConvention = CallingConvention.Cdecl)]
static extern IntPtr ClientReportControlBlock_create (string dataAttributeReference);
[DllImport("iec61850", CallingConvention = CallingConvention.Cdecl)]
static extern IntPtr IedConnection_getRCBValues (IntPtr connection, out int error, string rcbReference, IntPtr updateRcb);
[DllImport("iec61850", CallingConvention = CallingConvention.Cdecl)]
static extern void IedConnection_setRCBValues (IntPtr connection, out int error, IntPtr rcb, UInt32 parametersMask, bool singleRequest);
[DllImport("iec61850", CallingConvention = CallingConvention.Cdecl)]
static extern bool ClientReportControlBlock_isBuffered (IntPtr self);
[DllImport("iec61850", CallingConvention = CallingConvention.Cdecl)]
static extern IntPtr ClientReportControlBlock_getRptId (IntPtr self);
[DllImport("iec61850", CallingConvention = CallingConvention.Cdecl)]
static extern void ClientReportControlBlock_setRptId (IntPtr self, string rptId);
[DllImport("iec61850", CallingConvention = CallingConvention.Cdecl)]
static extern bool ClientReportControlBlock_getRptEna (IntPtr self);
[DllImport("iec61850", CallingConvention = CallingConvention.Cdecl)]
static extern void ClientReportControlBlock_setRptEna (IntPtr self, bool rptEna);
[DllImport("iec61850", CallingConvention = CallingConvention.Cdecl)]
static extern bool ClientReportControlBlock_getResv (IntPtr self);
[DllImport("iec61850", CallingConvention = CallingConvention.Cdecl)]
static extern void ClientReportControlBlock_setResv (IntPtr self, bool resv);
[DllImport("iec61850", CallingConvention = CallingConvention.Cdecl)]
static extern IntPtr ClientReportControlBlock_getDataSetReference (IntPtr self);
[DllImport("iec61850", CallingConvention = CallingConvention.Cdecl)]
static extern void ClientReportControlBlock_setDataSetReference (IntPtr self, string dataSetReference);
[DllImport("iec61850", CallingConvention = CallingConvention.Cdecl)]
static extern UInt32 ClientReportControlBlock_getConfRev (IntPtr self);
[DllImport("iec61850", CallingConvention = CallingConvention.Cdecl)]
static extern int ClientReportControlBlock_getOptFlds (IntPtr self);
[DllImport("iec61850", CallingConvention = CallingConvention.Cdecl)]
static extern void ClientReportControlBlock_setOptFlds (IntPtr self, int optFlds);
[DllImport("iec61850", CallingConvention = CallingConvention.Cdecl)]
static extern UInt32 ClientReportControlBlock_getBufTm (IntPtr self);
[DllImport("iec61850", CallingConvention = CallingConvention.Cdecl)]
static extern void ClientReportControlBlock_setBufTm (IntPtr self, UInt32 bufTm);
[DllImport("iec61850", CallingConvention = CallingConvention.Cdecl)]
static extern UInt16 ClientReportControlBlock_getSqNum (IntPtr self);
[DllImport("iec61850", CallingConvention = CallingConvention.Cdecl)]
static extern int ClientReportControlBlock_getTrgOps (IntPtr self);
[DllImport("iec61850", CallingConvention = CallingConvention.Cdecl)]
static extern void ClientReportControlBlock_setTrgOps (IntPtr self, int trgOps);
[DllImport("iec61850", CallingConvention = CallingConvention.Cdecl)]
static extern UInt32 ClientReportControlBlock_getIntgPd (IntPtr self);
[DllImport("iec61850", CallingConvention = CallingConvention.Cdecl)]
static extern void ClientReportControlBlock_setIntgPd (IntPtr self, UInt32 intgPd);
[DllImport("iec61850", CallingConvention = CallingConvention.Cdecl)]
static extern bool ClientReportControlBlock_getGI (IntPtr self);
[DllImport("iec61850", CallingConvention = CallingConvention.Cdecl)]
static extern void ClientReportControlBlock_setGI (IntPtr self, bool gi);
[DllImport("iec61850", CallingConvention = CallingConvention.Cdecl)]
static extern bool ClientReportControlBlock_getPurgeBuf (IntPtr self);
[DllImport("iec61850", CallingConvention = CallingConvention.Cdecl)]
static extern void ClientReportControlBlock_setPurgeBuf (IntPtr self, bool purgeBuf);
[DllImport("iec61850", CallingConvention = CallingConvention.Cdecl)]
static extern Int32 ClientReportControlBlock_getResvTms (IntPtr self);
[DllImport("iec61850", CallingConvention = CallingConvention.Cdecl)]
static extern void ClientReportControlBlock_setResvTms (IntPtr self, Int16 resvTms);
[DllImport("iec61850", CallingConvention = CallingConvention.Cdecl)]
static extern IntPtr ClientReportControlBlock_getEntryId (IntPtr self);
[DllImport("iec61850", CallingConvention = CallingConvention.Cdecl)]
static extern void ClientReportControlBlock_setEntryId (IntPtr self, IntPtr entryId);
[DllImport("iec61850", CallingConvention = CallingConvention.Cdecl)]
static extern UInt64 ClientReportControlBlock_getEntryTime (IntPtr self);
[DllImport("iec61850", CallingConvention = CallingConvention.Cdecl)]
static extern IntPtr ClientReportControlBlock_getOwner (IntPtr self);
[DllImport("iec61850", CallingConvention = CallingConvention.Cdecl)]
static extern void IedConnection_installReportHandler (IntPtr connection, string rcbReference, string rptId, InternalReportHandler handler,
IntPtr handlerParameter);
private delegate void InternalReportHandler (IntPtr parameter, IntPtr report);
private IntPtr self;
private IntPtr connection;
private string objectReference;
private bool flagRptId = false;
private bool flagRptEna = false;
private bool flagResv = false;
private bool flagDataSetReference = false;
private bool flagConfRev = false;
private bool flagOptFlds = false;
private bool flagBufTm = false;
private bool flagSqNum = false;
private bool flagTrgOps = false;
private bool flagIntgPd = false;
private bool flagGI = false;
private bool flagPurgeBuf = false;
private bool flagResvTms = false;
private bool flagEntryId = false;
private event ReportHandler reportHandler = null;
private object reportHandlerParameter;
private bool reportHandlerInstalled = false;
private void resetSendFlags ()
{
flagRptId = false;
flagRptEna = false;
flagResv = false;
flagDataSetReference = false;
flagConfRev = false;
flagOptFlds = false;
flagBufTm = false;
flagSqNum = false;
flagTrgOps = false;
flagIntgPd = false;
flagGI = false;
flagPurgeBuf = false;
flagResvTms = false;
flagEntryId = false;
}
private Report report = null;
private void internalReportHandler (IntPtr parameter, IntPtr report)
{
Console.WriteLine ("internalReportHandler called " + this);
try {
if (this.report == null)
this.report = new Report (report);
if (reportHandler != null)
reportHandler(this.report, reportHandlerParameter);
} catch (Exception e)
{
// older versions of mono 2.10 (for linux?) cause this exception
Console.WriteLine(e.Message);
}
}
internal ReportControlBlock (string objectReference, IntPtr connection)
{
self = ClientReportControlBlock_create (objectReference);
this.connection = connection;
this.objectReference = objectReference;
}
public void InstallReportHandler (ReportHandler reportHandler, object parameter)
{
this.reportHandler = new ReportHandler(reportHandler);
Console.WriteLine("Installed report handler " + this.reportHandler);
this.reportHandlerParameter = parameter;
if (reportHandlerInstalled == false) {
IedConnection_installReportHandler (this.connection, objectReference, this.GetRptId (), new InternalReportHandler(internalReportHandler), IntPtr.Zero);
reportHandlerInstalled = true;
}
}
public void GetRCBValues ()
{
int error;
IedConnection_getRCBValues (connection, out error, objectReference, self);
if (error != 0)
throw new IedConnectionException ("getRCBValues service failed", error);
}
public void SetRCBValues ()
{
SetRCBValues (true);
}
public void SetRCBValues (bool singleRequest)
{
UInt32 parametersMask = 0;
if (flagRptId)
parametersMask += 1;
if (flagRptEna)
parametersMask += 2;
if (flagResv)
parametersMask += 4;
if (flagDataSetReference)
parametersMask += 8;
if (flagConfRev)
parametersMask += 16;
if (flagOptFlds)
parametersMask += 32;
if (flagBufTm)
parametersMask += 64;
if (flagSqNum)
parametersMask += 128;
if (flagTrgOps)
parametersMask += 256;
if (flagIntgPd)
parametersMask += 512;
if (flagGI)
parametersMask += 1024;
if (flagPurgeBuf)
parametersMask += 2048;
if (flagEntryId)
parametersMask += 4096;
if (flagResvTms)
parametersMask += 16384;
int error;
IedConnection_setRCBValues (connection, out error, self, parametersMask, singleRequest);
if (error != 0)
throw new IedConnectionException ("setRCBValues service failed", error);
}
public bool IsBuffered ()
{
return ClientReportControlBlock_isBuffered (self);
}
public UInt64 getEntryTime ()
{
return ClientReportControlBlock_getEntryTime (self);
}
public DateTimeOffset GetEntryTimeAsDateTimeOffset ()
{
UInt64 entryTime = getEntryTime ();
DateTimeOffset retVal = new DateTimeOffset (1970, 1, 1, 0, 0, 0, TimeSpan.Zero);
return retVal.AddMilliseconds (entryTime);
}
public string GetDataSetReference ()
{
IntPtr dataSetRefPtr = ClientReportControlBlock_getDataSetReference (self);
return Marshal.PtrToStringAnsi (dataSetRefPtr);
}
public void SetDataSetReference (string dataSetReference)
{
ClientReportControlBlock_setDataSetReference (self, dataSetReference);
flagDataSetReference = true;
}
public string GetRptId ()
{
IntPtr rptIdPtr = ClientReportControlBlock_getRptId (self);
return Marshal.PtrToStringAnsi (rptIdPtr);
}
public bool GetRptEna ()
{
return ClientReportControlBlock_getRptEna (self);
}
public void SetRptEna (bool rptEna)
{
ClientReportControlBlock_setRptEna (self, rptEna);
flagRptEna = true;
}
public UInt32 GetBufTm()
{
return ClientReportControlBlock_getBufTm (self);
}
public void SetBufTm (UInt32 bufTm)
{
ClientReportControlBlock_setBufTm (self, bufTm);
flagBufTm = true;
}
public bool GetGI ()
{
return ClientReportControlBlock_getGI (self);
}
public void SetGI (bool GI)
{
ClientReportControlBlock_setGI (self, GI);
flagGI = true;
}
public bool GetResv ()
{
return ClientReportControlBlock_getResv (self);
}
public void SetResv (bool resv)
{
ClientReportControlBlock_setResv (self, resv);
flagResv = true;
}
public TriggerOptions GetTrgOps()
{
return (TriggerOptions) ClientReportControlBlock_getTrgOps (self);
}
public void SetTrgOps(TriggerOptions trgOps)
{
ClientReportControlBlock_setTrgOps (self, (int) trgOps);
flagTrgOps = true;
}
public UInt32 GetIntgPd ()
{
return ClientReportControlBlock_getIntgPd (self);
}
public void SetIntgPd (UInt32 intgPd)
{
ClientReportControlBlock_setIntgPd (self, intgPd);
flagIntgPd = true;
}
public ReportOptions GetOptFlds()
{
return (ReportOptions) ClientReportControlBlock_getOptFlds (self);
}
public void SetOptFlds(ReportOptions optFlds)
{
ClientReportControlBlock_setOptFlds (self, (int)optFlds);
flagOptFlds = true;
}
}
}
}

View File

@ -0,0 +1,136 @@
/*
* Reporting.cs
*
* Copyright 2014 Michael Zillgith
*
* This file is part of libIEC61850.
*
* libIEC61850 is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* libIEC61850 is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with libIEC61850. If not, see <http://www.gnu.org/licenses/>.
*
* See COPYING file for the complete license text.
*/
using System;
using System.Runtime.InteropServices;
namespace IEC61850
{
namespace Client
{
public partial class IedConnection
{
public ReportControlBlock getReportControlBlock (string rcbObjectReference)
{
return new ReportControlBlock (rcbObjectReference, connection);
}
}
public enum ReasonForInclusion
{
/** the element is not included in the received report */
REASON_NOT_INCLUDED = 0,
/** the element is included due to a change of the data value */
REASON_DATA_CHANGE = 1,
/** the element is included due to a change in the quality of data */
REASON_QUALITY_CHANGE = 2,
/** the element is included due to an update of the data value */
REASON_DATA_UPDATE = 3,
/** the element is included due to a periodic integrity report task */
REASON_INTEGRITY = 4,
/** the element is included due to a general interrogation by the client */
REASON_GI = 5,
/** the reason for inclusion is unknown */
REASON_UNKNOWN = 6
}
public class Report
{
[DllImport("iec61850", CallingConvention = CallingConvention.Cdecl)]
static extern bool ClientReport_hasTimestamp (IntPtr self);
[DllImport("iec61850", CallingConvention = CallingConvention.Cdecl)]
static extern UInt64 ClientReport_getTimestamp (IntPtr self);
[DllImport("iec61850", CallingConvention = CallingConvention.Cdecl)]
static extern IntPtr ClientReport_getDataSetValues(IntPtr self);
[DllImport("iec61850", CallingConvention = CallingConvention.Cdecl)]
static extern int ClientReport_getReasonForInclusion(IntPtr self, int elementIndex);
private IntPtr self;
private IntPtr dataSetValues = IntPtr.Zero;
private MmsValue values = null;
internal Report (IntPtr self)
{
this.self = self;
}
public bool HasTimestamp ()
{
return ClientReport_hasTimestamp (self);
}
public UInt64 GetTimestamp ()
{
if (HasTimestamp ())
return ClientReport_getTimestamp (self);
else
return 0;
}
public MmsValue GetDataSetValues ()
{
if (dataSetValues == IntPtr.Zero) {
dataSetValues = ClientReport_getDataSetValues(self);
if (dataSetValues == IntPtr.Zero)
throw new IedConnectionException("No report values available yet");
values = new MmsValue(dataSetValues);
}
return values;
}
public ReasonForInclusion GetReasonForInclusion (int index)
{
if (values == null) {
GetDataSetValues ();
if (values == null)
throw new IedConnectionException("No ReasonForInclusion available yet");
}
int dataSetSize = values.Size();
if (index >= dataSetSize)
throw new IedConnectionException("data set index out of range (count = " + dataSetSize + ")");
return (ReasonForInclusion) ClientReport_getReasonForInclusion(self, index);
}
}
}
}

View File

@ -0,0 +1,27 @@
using System.Reflection;
using System.Runtime.CompilerServices;
// Information about this assembly is defined by the following attributes.
// Change them to the values specific to your project.
[assembly: AssemblyTitle("authenticate")]
[assembly: AssemblyDescription("")]
[assembly: AssemblyConfiguration("")]
[assembly: AssemblyCompany("")]
[assembly: AssemblyProduct("")]
[assembly: AssemblyCopyright("mzillgit")]
[assembly: AssemblyTrademark("")]
[assembly: AssemblyCulture("")]
// The assembly version has the format "{Major}.{Minor}.{Build}.{Revision}".
// The form "{Major}.{Minor}.*" will automatically update the build and revision,
// and "{Major}.{Minor}.{Build}.*" will update just the revision.
[assembly: AssemblyVersion("1.0.*")]
// The following attributes are used to specify the signing key for the assembly,
// if desired. See the Mono documentation for more information about signing.
//[assembly: AssemblyDelaySign(false)]
//[assembly: AssemblyKeyFile("")]

View File

@ -0,0 +1,48 @@
using System;
using System.Collections.Generic;
using IEC61850.Client;
using IEC61850.Common;
namespace authenticate
{
class MainClass
{
public static void Main (string[] args)
{
IedConnection con = new IedConnection ();
string hostname;
if (args.Length > 0)
hostname = args[0];
else
hostname = "localhost";
Console.WriteLine("Connect to " + hostname);
try
{
IsoConnectionParameters parameters = con.GetConnectionParameters();
parameters.UsePasswordAuthentication("top secret");
con.Connect(hostname, 102);
List<string> serverDirectory = con.GetServerDirectory(false);
foreach (string entry in serverDirectory)
{
Console.WriteLine("LD: " + entry);
}
con.Release();
}
catch (IedConnectionException e)
{
Console.WriteLine(e.Message);
}
}
}
}

View File

@ -0,0 +1,45 @@
<?xml version="1.0" encoding="utf-8"?>
<Project DefaultTargets="Build" ToolsVersion="4.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
<PropertyGroup>
<Configuration Condition=" '$(Configuration)' == '' ">Debug</Configuration>
<Platform Condition=" '$(Platform)' == '' ">AnyCPU</Platform>
<ProductVersion>8.0.30703</ProductVersion>
<SchemaVersion>2.0</SchemaVersion>
<ProjectGuid>{0BECEC77-2315-4B95-AFF9-E6007E644BBF}</ProjectGuid>
<OutputType>Exe</OutputType>
<RootNamespace>authenticate</RootNamespace>
<AssemblyName>authenticate</AssemblyName>
</PropertyGroup>
<PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Debug|AnyCPU' ">
<DebugSymbols>true</DebugSymbols>
<DebugType>full</DebugType>
<Optimize>false</Optimize>
<OutputPath>bin\Debug</OutputPath>
<DefineConstants>DEBUG;</DefineConstants>
<ErrorReport>prompt</ErrorReport>
<WarningLevel>4</WarningLevel>
<Externalconsole>true</Externalconsole>
</PropertyGroup>
<PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Release|AnyCPU' ">
<DebugType>none</DebugType>
<Optimize>true</Optimize>
<OutputPath>bin\Release</OutputPath>
<ErrorReport>prompt</ErrorReport>
<WarningLevel>4</WarningLevel>
<Externalconsole>true</Externalconsole>
</PropertyGroup>
<ItemGroup>
<Reference Include="System" />
</ItemGroup>
<ItemGroup>
<Compile Include="Main.cs" />
<Compile Include="AssemblyInfo.cs" />
</ItemGroup>
<Import Project="$(MSBuildBinPath)\Microsoft.CSharp.targets" />
<ItemGroup>
<ProjectReference Include="..\IEC61850forCSharp\IEC61850forCSharp.csproj">
<Project>{C35D624E-5506-4560-8074-1728F1FA1A4D}</Project>
<Name>IEC61850forCSharp</Name>
</ProjectReference>
</ItemGroup>
</Project>

View File

@ -0,0 +1,27 @@
using System.Reflection;
using System.Runtime.CompilerServices;
// Information about this assembly is defined by the following attributes.
// Change them to the values specific to your project.
[assembly: AssemblyTitle("control")]
[assembly: AssemblyDescription("")]
[assembly: AssemblyConfiguration("")]
[assembly: AssemblyCompany("")]
[assembly: AssemblyProduct("")]
[assembly: AssemblyCopyright("mzillgit")]
[assembly: AssemblyTrademark("")]
[assembly: AssemblyCulture("")]
// The assembly version has the format "{Major}.{Minor}.{Build}.{Revision}".
// The form "{Major}.{Minor}.*" will automatically update the build and revision,
// and "{Major}.{Minor}.{Build}.*" will update just the revision.
[assembly: AssemblyVersion("1.0.*")]
// The following attributes are used to specify the signing key for the assembly,
// if desired. See the Mono documentation for more information about signing.
//[assembly: AssemblyDelaySign(false)]
//[assembly: AssemblyKeyFile("")]

View File

@ -0,0 +1,50 @@
using System;
using System.Collections.Generic;
using IEC61850.Common;
using IEC61850.Client;
namespace control
{
class ControlExample
{
public static void Main (string[] args)
{
IedConnection con = new IedConnection ();
string hostname;
if (args.Length > 0)
hostname = args[0];
else
hostname = "localhost";
Console.WriteLine("Connect to " + hostname);
try
{
con.Connect(hostname, 102);
string objectReference = "IEDM1CPUBHKW/DRCC1.DERStr";
ControlObject control = con.CreateControlObject(objectReference);
ControlModel controlModel = control.GetControlModel();
Console.WriteLine(objectReference + " has control model " + controlModel.ToString());
if (!control.Operate(true))
Console.WriteLine("operate failed!");
con.Abort();
}
catch (IedConnectionException e)
{
Console.WriteLine(e.Message);
}
}
}
}

View File

@ -0,0 +1,45 @@
<?xml version="1.0" encoding="utf-8"?>
<Project DefaultTargets="Build" ToolsVersion="4.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
<PropertyGroup>
<Configuration Condition=" '$(Configuration)' == '' ">Debug</Configuration>
<Platform Condition=" '$(Platform)' == '' ">AnyCPU</Platform>
<ProductVersion>8.0.30703</ProductVersion>
<SchemaVersion>2.0</SchemaVersion>
<ProjectGuid>{C351CFA4-E54E-49A1-86CE-69643535541A}</ProjectGuid>
<OutputType>Exe</OutputType>
<RootNamespace>control</RootNamespace>
<AssemblyName>control</AssemblyName>
</PropertyGroup>
<PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Debug|AnyCPU' ">
<DebugSymbols>true</DebugSymbols>
<DebugType>full</DebugType>
<Optimize>false</Optimize>
<OutputPath>bin\Debug</OutputPath>
<DefineConstants>DEBUG;</DefineConstants>
<ErrorReport>prompt</ErrorReport>
<WarningLevel>4</WarningLevel>
<Externalconsole>true</Externalconsole>
</PropertyGroup>
<PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Release|AnyCPU' ">
<DebugType>none</DebugType>
<Optimize>true</Optimize>
<OutputPath>bin\Release</OutputPath>
<ErrorReport>prompt</ErrorReport>
<WarningLevel>4</WarningLevel>
<Externalconsole>true</Externalconsole>
</PropertyGroup>
<ItemGroup>
<Reference Include="System" />
</ItemGroup>
<ItemGroup>
<Compile Include="AssemblyInfo.cs" />
<Compile Include="ControlExample.cs" />
</ItemGroup>
<Import Project="$(MSBuildBinPath)\Microsoft.CSharp.targets" />
<ItemGroup>
<ProjectReference Include="..\IEC61850forCSharp\IEC61850forCSharp.csproj">
<Project>{C35D624E-5506-4560-8074-1728F1FA1A4D}</Project>
<Name>IEC61850forCSharp</Name>
</ProjectReference>
</ItemGroup>
</Project>

View File

@ -0,0 +1,27 @@
using System.Reflection;
using System.Runtime.CompilerServices;
// Information about this assembly is defined by the following attributes.
// Change them to the values specific to your project.
[assembly: AssemblyTitle("datasets")]
[assembly: AssemblyDescription("")]
[assembly: AssemblyConfiguration("")]
[assembly: AssemblyCompany("")]
[assembly: AssemblyProduct("")]
[assembly: AssemblyCopyright("mzillgit")]
[assembly: AssemblyTrademark("")]
[assembly: AssemblyCulture("")]
// The assembly version has the format "{Major}.{Minor}.{Build}.{Revision}".
// The form "{Major}.{Minor}.*" will automatically update the build and revision,
// and "{Major}.{Minor}.{Build}.*" will update just the revision.
[assembly: AssemblyVersion("1.0.*")]
// The following attributes are used to specify the signing key for the assembly,
// if desired. See the Mono documentation for more information about signing.
//[assembly: AssemblyDelaySign(false)]
//[assembly: AssemblyKeyFile("")]

View File

@ -0,0 +1,77 @@
using System;
using System.Collections.Generic;
using IEC61850.Client;
namespace datasets
{
class DataSetExample
{
public static void Main (string[] args)
{
IedConnection con = new IedConnection ();
string hostname;
if (args.Length > 0)
hostname = args[0];
else
hostname = "10.0.2.2";
Console.WriteLine("Connect to " + hostname);
try
{
con.Connect(hostname, 102);
List<string> serverDirectory = con.GetServerDirectory(false);
foreach (string entry in serverDirectory)
{
Console.WriteLine("LD: " + entry);
}
// create a new data set
List<string> dataSetElements = new List<string>();
dataSetElements.Add("IEDM1CPUBHKW/DRCS1.ModOnConn.stVal[ST]");
dataSetElements.Add("IEDM1CPUBHKW/DRCS1.ModOnConn.t[ST]");
con.CreateDataSet("IEDM1CPUBHKW/LLN0.ds1", dataSetElements);
// get the directory of the data set
List<string> dataSetDirectory = con.GetDataSetDirectory("IEDM1CPUBHKW/LLN0.ds1");
foreach (string entry in dataSetDirectory)
{
Console.WriteLine("DS element: " + entry);
}
// read the values of the newly created data set
DataSet dataSet = con.ReadDataSetValues("IEDM1CPUBHKW/LLN0.ds1", null);
MmsValue dataSetValues = dataSet.GetValues();
Console.WriteLine ("Data set contains " + dataSetValues.Size() + " elements");
foreach (MmsValue value in dataSetValues) {
Console.WriteLine(" DS value: " + value + " type: " + value.GetType());
}
// delete the data set
con.DeleteDataSet("IEDM1CPUBHKW/LLN0.ds1");
con.Abort();
}
catch (IedConnectionException e)
{
Console.WriteLine(e.Message);
}
}
}
}

View File

@ -0,0 +1,45 @@
<?xml version="1.0" encoding="utf-8"?>
<Project DefaultTargets="Build" ToolsVersion="4.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
<PropertyGroup>
<Configuration Condition=" '$(Configuration)' == '' ">Debug</Configuration>
<Platform Condition=" '$(Platform)' == '' ">AnyCPU</Platform>
<ProductVersion>8.0.30703</ProductVersion>
<SchemaVersion>2.0</SchemaVersion>
<ProjectGuid>{D5C7DD38-032A-49B6-B74F-FFD9724A8AE4}</ProjectGuid>
<OutputType>Exe</OutputType>
<RootNamespace>datasets</RootNamespace>
<AssemblyName>datasets</AssemblyName>
</PropertyGroup>
<PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Debug|AnyCPU' ">
<DebugSymbols>true</DebugSymbols>
<DebugType>full</DebugType>
<Optimize>false</Optimize>
<OutputPath>bin\Debug</OutputPath>
<DefineConstants>DEBUG;</DefineConstants>
<ErrorReport>prompt</ErrorReport>
<WarningLevel>4</WarningLevel>
<Externalconsole>true</Externalconsole>
</PropertyGroup>
<PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Release|AnyCPU' ">
<DebugType>none</DebugType>
<Optimize>true</Optimize>
<OutputPath>bin\Release</OutputPath>
<ErrorReport>prompt</ErrorReport>
<WarningLevel>4</WarningLevel>
<Externalconsole>true</Externalconsole>
</PropertyGroup>
<ItemGroup>
<Reference Include="System" />
</ItemGroup>
<ItemGroup>
<Compile Include="AssemblyInfo.cs" />
<Compile Include="DataSetExample.cs" />
</ItemGroup>
<Import Project="$(MSBuildBinPath)\Microsoft.CSharp.targets" />
<ItemGroup>
<ProjectReference Include="..\IEC61850forCSharp\IEC61850forCSharp.csproj">
<Project>{C35D624E-5506-4560-8074-1728F1FA1A4D}</Project>
<Name>IEC61850forCSharp</Name>
</ProjectReference>
</ItemGroup>
</Project>

105
dotnet/dotnet.sln Normal file
View File

@ -0,0 +1,105 @@

Microsoft Visual Studio Solution File, Format Version 11.00
# Visual Studio 2010
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "IEC61850forCSharp", "IEC61850forCSharp\IEC61850forCSharp.csproj", "{C35D624E-5506-4560-8074-1728F1FA1A4D}"
EndProject
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "example1", "example1\example1.csproj", "{C616A6DF-831E-443C-9310-3F343A6E3D1A}"
EndProject
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "model_browsing", "model_browsing\model_browsing.csproj", "{59B85486-F48D-4978-BD35-8F5C3A8288D4}"
EndProject
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "datasets", "datasets\datasets.csproj", "{D5C7DD38-032A-49B6-B74F-FFD9724A8AE4}"
EndProject
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "control", "control\control.csproj", "{C351CFA4-E54E-49A1-86CE-69643535541A}"
EndProject
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "reporting", "reporting\reporting.csproj", "{9E29B4CE-EE5F-4CA6-85F6-5D1FF8B27BF8}"
EndProject
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "example2", "example2\example2.csproj", "{2A226B6D-1D1F-4BFE-B8CC-158116F71270}"
EndProject
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "authenticate", "authenticate\authenticate.csproj", "{0BECEC77-2315-4B95-AFF9-E6007E644BBF}"
EndProject
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "tests", "tests\tests.csproj", "{FBDFE530-DBEB-474B-BA54-9AB287DD57B3}"
EndProject
Global
GlobalSection(SolutionConfigurationPlatforms) = preSolution
Debug|Any CPU = Debug|Any CPU
Release|Any CPU = Release|Any CPU
EndGlobalSection
GlobalSection(ProjectConfigurationPlatforms) = postSolution
{0BECEC77-2315-4B95-AFF9-E6007E644BBF}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{0BECEC77-2315-4B95-AFF9-E6007E644BBF}.Debug|Any CPU.Build.0 = Debug|Any CPU
{0BECEC77-2315-4B95-AFF9-E6007E644BBF}.Release|Any CPU.ActiveCfg = Release|Any CPU
{0BECEC77-2315-4B95-AFF9-E6007E644BBF}.Release|Any CPU.Build.0 = Release|Any CPU
{2A226B6D-1D1F-4BFE-B8CC-158116F71270}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{2A226B6D-1D1F-4BFE-B8CC-158116F71270}.Debug|Any CPU.Build.0 = Debug|Any CPU
{2A226B6D-1D1F-4BFE-B8CC-158116F71270}.Release|Any CPU.ActiveCfg = Release|Any CPU
{2A226B6D-1D1F-4BFE-B8CC-158116F71270}.Release|Any CPU.Build.0 = Release|Any CPU
{59B85486-F48D-4978-BD35-8F5C3A8288D4}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{59B85486-F48D-4978-BD35-8F5C3A8288D4}.Debug|Any CPU.Build.0 = Debug|Any CPU
{59B85486-F48D-4978-BD35-8F5C3A8288D4}.Release|Any CPU.ActiveCfg = Release|Any CPU
{59B85486-F48D-4978-BD35-8F5C3A8288D4}.Release|Any CPU.Build.0 = Release|Any CPU
{9E29B4CE-EE5F-4CA6-85F6-5D1FF8B27BF8}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{9E29B4CE-EE5F-4CA6-85F6-5D1FF8B27BF8}.Debug|Any CPU.Build.0 = Debug|Any CPU
{9E29B4CE-EE5F-4CA6-85F6-5D1FF8B27BF8}.Release|Any CPU.ActiveCfg = Release|Any CPU
{9E29B4CE-EE5F-4CA6-85F6-5D1FF8B27BF8}.Release|Any CPU.Build.0 = Release|Any CPU
{C351CFA4-E54E-49A1-86CE-69643535541A}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{C351CFA4-E54E-49A1-86CE-69643535541A}.Debug|Any CPU.Build.0 = Debug|Any CPU
{C351CFA4-E54E-49A1-86CE-69643535541A}.Release|Any CPU.ActiveCfg = Release|Any CPU
{C351CFA4-E54E-49A1-86CE-69643535541A}.Release|Any CPU.Build.0 = Release|Any CPU
{C35D624E-5506-4560-8074-1728F1FA1A4D}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{C35D624E-5506-4560-8074-1728F1FA1A4D}.Debug|Any CPU.Build.0 = Debug|Any CPU
{C35D624E-5506-4560-8074-1728F1FA1A4D}.Release|Any CPU.ActiveCfg = Release|Any CPU
{C35D624E-5506-4560-8074-1728F1FA1A4D}.Release|Any CPU.Build.0 = Release|Any CPU
{C616A6DF-831E-443C-9310-3F343A6E3D1A}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{C616A6DF-831E-443C-9310-3F343A6E3D1A}.Debug|Any CPU.Build.0 = Debug|Any CPU
{C616A6DF-831E-443C-9310-3F343A6E3D1A}.Release|Any CPU.ActiveCfg = Release|Any CPU
{C616A6DF-831E-443C-9310-3F343A6E3D1A}.Release|Any CPU.Build.0 = Release|Any CPU
{D5C7DD38-032A-49B6-B74F-FFD9724A8AE4}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{D5C7DD38-032A-49B6-B74F-FFD9724A8AE4}.Debug|Any CPU.Build.0 = Debug|Any CPU
{D5C7DD38-032A-49B6-B74F-FFD9724A8AE4}.Release|Any CPU.ActiveCfg = Release|Any CPU
{D5C7DD38-032A-49B6-B74F-FFD9724A8AE4}.Release|Any CPU.Build.0 = Release|Any CPU
{FBDFE530-DBEB-474B-BA54-9AB287DD57B3}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{FBDFE530-DBEB-474B-BA54-9AB287DD57B3}.Debug|Any CPU.Build.0 = Debug|Any CPU
{FBDFE530-DBEB-474B-BA54-9AB287DD57B3}.Release|Any CPU.ActiveCfg = Release|Any CPU
{FBDFE530-DBEB-474B-BA54-9AB287DD57B3}.Release|Any CPU.Build.0 = Release|Any CPU
{740DC107-F506-416C-B145-F71649A4A5A0}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{740DC107-F506-416C-B145-F71649A4A5A0}.Debug|Any CPU.Build.0 = Debug|Any CPU
{740DC107-F506-416C-B145-F71649A4A5A0}.Release|Any CPU.ActiveCfg = Release|Any CPU
{740DC107-F506-416C-B145-F71649A4A5A0}.Release|Any CPU.Build.0 = Release|Any CPU
{EDC263E3-0419-4B23-91A4-250EF0A6DD62}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{EDC263E3-0419-4B23-91A4-250EF0A6DD62}.Debug|Any CPU.Build.0 = Debug|Any CPU
{EDC263E3-0419-4B23-91A4-250EF0A6DD62}.Release|Any CPU.ActiveCfg = Release|Any CPU
{EDC263E3-0419-4B23-91A4-250EF0A6DD62}.Release|Any CPU.Build.0 = Release|Any CPU
EndGlobalSection
GlobalSection(MonoDevelopProperties) = preSolution
StartupItem = IEC61850forCSharp\IEC61850forCSharp.csproj
Policies = $0
$0.DotNetNamingPolicy = $1
$1.DirectoryNamespaceAssociation = None
$1.ResourceNamePolicy = FileFormatDefault
$0.TextStylePolicy = $2
$2.FileWidth = 120
$2.TabsToSpaces = False
$2.inheritsSet = VisualStudio
$2.inheritsScope = text/plain
$2.scope = text/plain
$0.TextStylePolicy = $3
$3.inheritsSet = null
$3.scope = text/microsoft-resx
$0.XmlFormattingPolicy = $4
$4.inheritsSet = null
$4.scope = text/microsoft-resx
$0.TextStylePolicy = $5
$5.inheritsSet = null
$5.scope = application/xml
$0.XmlFormattingPolicy = $6
$6.inheritsSet = Mono
$6.inheritsScope = application/xml
$6.scope = application/xml
$0.StandardHeader = $7
$7.Text =
$7.IncludeInNewFiles = True
EndGlobalSection
GlobalSection(SolutionProperties) = preSolution
HideSolutionNode = FALSE
EndGlobalSection
EndGlobal

View File

@ -0,0 +1,27 @@
using System.Reflection;
using System.Runtime.CompilerServices;
// Information about this assembly is defined by the following attributes.
// Change them to the values specific to your project.
[assembly: AssemblyTitle("example1")]
[assembly: AssemblyDescription("")]
[assembly: AssemblyConfiguration("")]
[assembly: AssemblyCompany("")]
[assembly: AssemblyProduct("")]
[assembly: AssemblyCopyright("mzillgit")]
[assembly: AssemblyTrademark("")]
[assembly: AssemblyCulture("")]
// The assembly version has the format "{Major}.{Minor}.{Build}.{Revision}".
// The form "{Major}.{Minor}.*" will automatically update the build and revision,
// and "{Major}.{Minor}.{Build}.*" will update just the revision.
[assembly: AssemblyVersion("1.0.*")]
// The following attributes are used to specify the signing key for the assembly,
// if desired. See the Mono documentation for more information about signing.
//[assembly: AssemblyDelaySign(false)]
//[assembly: AssemblyKeyFile("")]

78
dotnet/example1/Main.cs Normal file
View File

@ -0,0 +1,78 @@
using System;
using System.Collections.Generic;
using IEC61850.Client;
using IEC61850.Common;
namespace example1
{
class MainClass
{
public static void Main (string[] args)
{
IedConnection con = new IedConnection ();
string hostname;
if (args.Length > 0)
hostname = args[0];
else
hostname = "10.0.2.2";
Console.WriteLine("Connect to " + hostname);
try
{
con.Connect(hostname, 102);
List<string> serverDirectory = con.GetServerDirectory(false);
foreach (string entry in serverDirectory)
{
Console.WriteLine("LD: " + entry);
}
List<string> lnDirectory = con.GetLogicalNodeDirectory("simpleIOGenericIO/LLN0", ACSIClass.ACSI_CLASS_DATA_SET);
foreach (string entry in lnDirectory)
{
Console.WriteLine("Dataset: " + entry);
}
string vendor = con.ReadStringValue ("simpleIOGenericIO/LLN0.NamPlt.vendor", FunctionalConstraint.DC);
Console.WriteLine ("Vendor: " + vendor);
/* read FCDO */
MmsValue value = con.ReadValue("simpleIOGenericIO/GGIO1.AnIn1", FunctionalConstraint.MX);
if (value.GetType() == MmsType.MMS_STRUCTURE)
{
Console.WriteLine("Value is of complex type");
for (int i = 0; i < value.Size(); i++)
{
Console.WriteLine(" element: " + value.GetElement(i).GetType());
if (value.GetElement(i).GetType() == MmsType.MMS_UTC_TIME)
{
Console.WriteLine(" -> " + value.GetElement(i).GetUtcTimeAsDateTimeOffset());
}
}
}
DataSet dataSet = con.ReadDataSetValues("simpleIOGenericIO/LLN0.Events", null);
Console.WriteLine("Read data set " + dataSet.GetReference());
con.Abort();
}
catch (IedConnectionException e)
{
Console.WriteLine(e.Message);
}
System.Threading.Thread.Sleep(2000);
}
}
}

View File

@ -0,0 +1,45 @@
<?xml version="1.0" encoding="utf-8"?>
<Project DefaultTargets="Build" ToolsVersion="4.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
<PropertyGroup>
<Configuration Condition=" '$(Configuration)' == '' ">Debug</Configuration>
<Platform Condition=" '$(Platform)' == '' ">AnyCPU</Platform>
<ProductVersion>8.0.30703</ProductVersion>
<SchemaVersion>2.0</SchemaVersion>
<ProjectGuid>{C616A6DF-831E-443C-9310-3F343A6E3D1A}</ProjectGuid>
<OutputType>Exe</OutputType>
<RootNamespace>example1</RootNamespace>
<AssemblyName>example1</AssemblyName>
</PropertyGroup>
<PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Debug|AnyCPU' ">
<DebugSymbols>true</DebugSymbols>
<DebugType>full</DebugType>
<Optimize>false</Optimize>
<OutputPath>bin\Debug</OutputPath>
<DefineConstants>DEBUG;</DefineConstants>
<ErrorReport>prompt</ErrorReport>
<WarningLevel>4</WarningLevel>
<Externalconsole>true</Externalconsole>
</PropertyGroup>
<PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Release|AnyCPU' ">
<DebugType>none</DebugType>
<Optimize>true</Optimize>
<OutputPath>bin\Release</OutputPath>
<ErrorReport>prompt</ErrorReport>
<WarningLevel>4</WarningLevel>
<Externalconsole>true</Externalconsole>
</PropertyGroup>
<ItemGroup>
<Reference Include="System" />
</ItemGroup>
<ItemGroup>
<Compile Include="Main.cs" />
<Compile Include="AssemblyInfo.cs" />
</ItemGroup>
<Import Project="$(MSBuildBinPath)\Microsoft.CSharp.targets" />
<ItemGroup>
<ProjectReference Include="..\IEC61850forCSharp\IEC61850forCSharp.csproj">
<Project>{C35D624E-5506-4560-8074-1728F1FA1A4D}</Project>
<Name>IEC61850forCSharp</Name>
</ProjectReference>
</ItemGroup>
</Project>

View File

@ -0,0 +1,27 @@
using System.Reflection;
using System.Runtime.CompilerServices;
// Information about this assembly is defined by the following attributes.
// Change them to the values specific to your project.
[assembly: AssemblyTitle("example2")]
[assembly: AssemblyDescription("")]
[assembly: AssemblyConfiguration("")]
[assembly: AssemblyCompany("")]
[assembly: AssemblyProduct("")]
[assembly: AssemblyCopyright("mzillgit")]
[assembly: AssemblyTrademark("")]
[assembly: AssemblyCulture("")]
// The assembly version has the format "{Major}.{Minor}.{Build}.{Revision}".
// The form "{Major}.{Minor}.*" will automatically update the build and revision,
// and "{Major}.{Minor}.{Build}.*" will update just the revision.
[assembly: AssemblyVersion("1.0.*")]
// The following attributes are used to specify the signing key for the assembly,
// if desired. See the Mono documentation for more information about signing.
//[assembly: AssemblyDelaySign(false)]
//[assembly: AssemblyKeyFile("")]

View File

@ -0,0 +1,44 @@
using System;
using System.Collections.Generic;
using IEC61850.Client;
using IEC61850.Common;
namespace example2
{
class WriteValueExample
{
public static void Main (string[] args)
{
IedConnection con = new IedConnection ();
string hostname;
if (args.Length > 0)
hostname = args[0];
else
hostname = "localhost";
Console.WriteLine("Connect to " + hostname);
try
{
con.Connect(hostname, 102);
float setMagF = con.ReadFloatValue("ied1Inverter/ZINV1.OutWSet.setMag.f", FunctionalConstraint.SP);
Console.WriteLine("ied1Inverter/ZINV1.OutWSet.setMag.f: " + setMagF);
setMagF += 1.0f;
con.WriteValue("ied1Inverter/ZINV1.OutWSet.setMag.f", FunctionalConstraint.SP, new MmsValue(setMagF));
con.Abort();
}
catch (IedConnectionException e)
{
Console.WriteLine("IED connection excepion: " + e.Message);
}
}
}
}

View File

@ -0,0 +1,45 @@
<?xml version="1.0" encoding="utf-8"?>
<Project DefaultTargets="Build" ToolsVersion="4.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
<PropertyGroup>
<Configuration Condition=" '$(Configuration)' == '' ">Debug</Configuration>
<Platform Condition=" '$(Platform)' == '' ">AnyCPU</Platform>
<ProductVersion>8.0.30703</ProductVersion>
<SchemaVersion>2.0</SchemaVersion>
<ProjectGuid>{2A226B6D-1D1F-4BFE-B8CC-158116F71270}</ProjectGuid>
<OutputType>Exe</OutputType>
<RootNamespace>example2</RootNamespace>
<AssemblyName>example2</AssemblyName>
</PropertyGroup>
<PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Debug|AnyCPU' ">
<DebugSymbols>true</DebugSymbols>
<DebugType>full</DebugType>
<Optimize>false</Optimize>
<OutputPath>bin\Debug</OutputPath>
<DefineConstants>DEBUG;</DefineConstants>
<ErrorReport>prompt</ErrorReport>
<WarningLevel>4</WarningLevel>
<Externalconsole>true</Externalconsole>
</PropertyGroup>
<PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Release|AnyCPU' ">
<DebugType>none</DebugType>
<Optimize>true</Optimize>
<OutputPath>bin\Release</OutputPath>
<ErrorReport>prompt</ErrorReport>
<WarningLevel>4</WarningLevel>
<Externalconsole>true</Externalconsole>
</PropertyGroup>
<ItemGroup>
<Reference Include="System" />
</ItemGroup>
<ItemGroup>
<Compile Include="AssemblyInfo.cs" />
<Compile Include="WriteValueExample.cs" />
</ItemGroup>
<Import Project="$(MSBuildBinPath)\Microsoft.CSharp.targets" />
<ItemGroup>
<ProjectReference Include="..\IEC61850forCSharp\IEC61850forCSharp.csproj">
<Project>{C35D624E-5506-4560-8074-1728F1FA1A4D}</Project>
<Name>IEC61850forCSharp</Name>
</ProjectReference>
</ItemGroup>
</Project>

View File

@ -0,0 +1,27 @@
using System.Reflection;
using System.Runtime.CompilerServices;
// Information about this assembly is defined by the following attributes.
// Change them to the values specific to your project.
[assembly: AssemblyTitle("model_browsing")]
[assembly: AssemblyDescription("")]
[assembly: AssemblyConfiguration("")]
[assembly: AssemblyCompany("")]
[assembly: AssemblyProduct("")]
[assembly: AssemblyCopyright("mzillgit")]
[assembly: AssemblyTrademark("")]
[assembly: AssemblyCulture("")]
// The assembly version has the format "{Major}.{Minor}.{Build}.{Revision}".
// The form "{Major}.{Minor}.*" will automatically update the build and revision,
// and "{Major}.{Minor}.{Build}.*" will update just the revision.
[assembly: AssemblyVersion("1.0.*")]
// The following attributes are used to specify the signing key for the assembly,
// if desired. See the Mono documentation for more information about signing.
//[assembly: AssemblyDelaySign(false)]
//[assembly: AssemblyKeyFile("")]

View File

@ -0,0 +1,94 @@
using System;
using System.Collections.Generic;
using IEC61850.Client;
using IEC61850.Common;
/// <summary>
/// Example for browsing the data model of a server. Shows logical devices, logical nodes,
/// data sets and report control blocks
/// </summary>
namespace model_browsing
{
class ModelBrowsing
{
public static void Main (string[] args)
{
IedConnection con = new IedConnection ();
string hostname;
if (args.Length > 0)
hostname = args[0];
else
hostname = "localhost";
try
{
Console.WriteLine("Connect to " + hostname + " ...");
con.Connect(hostname, 102);
Console.WriteLine("Connected.");
List<string> serverDirectory = con.GetServerDirectory(false);
foreach (string ldName in serverDirectory)
{
Console.WriteLine("LD: " + ldName);
List<string> lnNames = con.GetLogicalDeviceDirectory(ldName);
foreach (string lnName in lnNames)
{
Console.WriteLine(" LN: " + lnName);
string logicalNodeReference = ldName + "/" + lnName;
// discover data objects
List<string> dataObjects =
con.GetLogicalNodeDirectory(logicalNodeReference, ACSIClass.ACSI_CLASS_DATA_OBJECT);
foreach (string dataObject in dataObjects) {
Console.WriteLine(" DO: " + dataObject);
}
// discover data sets
List<string> dataSets =
con.GetLogicalNodeDirectory(logicalNodeReference, ACSIClass.ACSI_CLASS_DATA_SET);
foreach (string dataSet in dataSets) {
Console.WriteLine(" Dataset: " + dataSet);
}
// discover unbuffered report control blocks
List<string> urcbs =
con.GetLogicalNodeDirectory(logicalNodeReference, ACSIClass.ACSI_CLASS_URCB);
foreach (string urcb in urcbs) {
Console.WriteLine(" URCB: " + urcb);
}
// discover buffered report control blocks
List<string> brcbs =
con.GetLogicalNodeDirectory(logicalNodeReference, ACSIClass.ACSI_CLASS_BRCB);
foreach (string brcb in brcbs) {
Console.WriteLine(" BRCB: " + brcb);
}
}
}
con.Abort();
}
catch (IedConnectionException e)
{
Console.WriteLine(e.Message);
}
}
}
}

View File

@ -0,0 +1,45 @@
<?xml version="1.0" encoding="utf-8"?>
<Project DefaultTargets="Build" ToolsVersion="4.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
<PropertyGroup>
<Configuration Condition=" '$(Configuration)' == '' ">Debug</Configuration>
<Platform Condition=" '$(Platform)' == '' ">AnyCPU</Platform>
<ProductVersion>8.0.30703</ProductVersion>
<SchemaVersion>2.0</SchemaVersion>
<ProjectGuid>{59B85486-F48D-4978-BD35-8F5C3A8288D4}</ProjectGuid>
<OutputType>Exe</OutputType>
<RootNamespace>model_browsing</RootNamespace>
<AssemblyName>model_browsing</AssemblyName>
</PropertyGroup>
<PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Debug|AnyCPU' ">
<DebugSymbols>true</DebugSymbols>
<DebugType>full</DebugType>
<Optimize>false</Optimize>
<OutputPath>bin\Debug</OutputPath>
<DefineConstants>DEBUG;</DefineConstants>
<ErrorReport>prompt</ErrorReport>
<WarningLevel>4</WarningLevel>
<Externalconsole>true</Externalconsole>
</PropertyGroup>
<PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Release|AnyCPU' ">
<DebugType>none</DebugType>
<Optimize>true</Optimize>
<OutputPath>bin\Release</OutputPath>
<ErrorReport>prompt</ErrorReport>
<WarningLevel>4</WarningLevel>
<Externalconsole>true</Externalconsole>
</PropertyGroup>
<ItemGroup>
<Reference Include="System" />
</ItemGroup>
<ItemGroup>
<Compile Include="AssemblyInfo.cs" />
<Compile Include="ModelBrowsing.cs" />
</ItemGroup>
<Import Project="$(MSBuildBinPath)\Microsoft.CSharp.targets" />
<ItemGroup>
<ProjectReference Include="..\IEC61850forCSharp\IEC61850forCSharp.csproj">
<Project>{C35D624E-5506-4560-8074-1728F1FA1A4D}</Project>
<Name>IEC61850forCSharp</Name>
</ProjectReference>
</ItemGroup>
</Project>

View File

@ -0,0 +1,27 @@
using System.Reflection;
using System.Runtime.CompilerServices;
// Information about this assembly is defined by the following attributes.
// Change them to the values specific to your project.
[assembly: AssemblyTitle("reporting")]
[assembly: AssemblyDescription("")]
[assembly: AssemblyConfiguration("")]
[assembly: AssemblyCompany("")]
[assembly: AssemblyProduct("")]
[assembly: AssemblyCopyright("mzillgit")]
[assembly: AssemblyTrademark("")]
[assembly: AssemblyCulture("")]
// The assembly version has the format "{Major}.{Minor}.{Build}.{Revision}".
// The form "{Major}.{Minor}.*" will automatically update the build and revision,
// and "{Major}.{Minor}.{Build}.*" will update just the revision.
[assembly: AssemblyVersion("1.0.*")]
// The following attributes are used to specify the signing key for the assembly,
// if desired. See the Mono documentation for more information about signing.
//[assembly: AssemblyDelaySign(false)]
//[assembly: AssemblyKeyFile("")]

View File

@ -0,0 +1,87 @@
using System;
using System.Collections.Generic;
using System.Threading;
using IEC61850.Client;
using IEC61850.Common;
namespace reporting
{
class ReportingExample
{
private static void reportHandler (Report report, object parameter)
{
Console.WriteLine ("Received report:\n----------------");
if (report.HasTimestamp ())
Console.WriteLine (" timestamp: " + MmsValue.MsTimeToDateTimeOffset (report.GetTimestamp ()).ToString ());
MmsValue values = report.GetDataSetValues ();
Console.WriteLine (" report dataset contains " + values.Size () + " elements");
for (int i = 0; i < values.Size(); i++) {
if (report.GetReasonForInclusion(i) != ReasonForInclusion.REASON_NOT_INCLUDED) {
Console.WriteLine(" element " + i + " included for reason " + report.GetReasonForInclusion(i).ToString() + " " + values.GetElement(i));
}
}
}
private static bool running = true;
public static void Main (string[] args)
{
IedConnection con = new IedConnection ();
string hostname;
if (args.Length > 0)
hostname = args [0];
else
hostname = "localhost";
Console.WriteLine ("Connect to " + hostname);
try {
con.Connect (hostname, 102);
string rcbReference = "simpleIOGenericIO/LLN0.RP.EventsRCB";
ReportControlBlock rcb = con.getReportControlBlock(rcbReference);
rcb.GetRCBValues();
rcb.InstallReportHandler(reportHandler, null);
if (rcb.IsBuffered())
Console.WriteLine ("RCB: " + rcbReference + " is buffered");
Console.WriteLine(rcb.GetDataSetReference());
rcb.SetTrgOps(TriggerOptions.DATA_CHANGED | TriggerOptions.INTEGRITY);
rcb.SetIntgPd(5000);
rcb.SetRptEna(true);
rcb.SetRCBValues();
/* run until Ctrl-C is pressed */
Console.CancelKeyPress += delegate(object sender, ConsoleCancelEventArgs e) {
e.Cancel = true;
ReportingExample.running = false;
};
while (running) {
Thread.Sleep(10);
}
con.Abort ();
} catch (IedConnectionException e) {
Console.WriteLine (e.Message);
}
}
}
}

View File

@ -0,0 +1,45 @@
<?xml version="1.0" encoding="utf-8"?>
<Project DefaultTargets="Build" ToolsVersion="4.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
<PropertyGroup>
<Configuration Condition=" '$(Configuration)' == '' ">Debug</Configuration>
<Platform Condition=" '$(Platform)' == '' ">AnyCPU</Platform>
<ProductVersion>8.0.30703</ProductVersion>
<SchemaVersion>2.0</SchemaVersion>
<ProjectGuid>{9E29B4CE-EE5F-4CA6-85F6-5D1FF8B27BF8}</ProjectGuid>
<OutputType>Exe</OutputType>
<RootNamespace>reporting</RootNamespace>
<AssemblyName>reporting</AssemblyName>
</PropertyGroup>
<PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Debug|AnyCPU' ">
<DebugSymbols>true</DebugSymbols>
<DebugType>full</DebugType>
<Optimize>false</Optimize>
<OutputPath>bin\Debug</OutputPath>
<DefineConstants>DEBUG;</DefineConstants>
<ErrorReport>prompt</ErrorReport>
<WarningLevel>4</WarningLevel>
<Externalconsole>true</Externalconsole>
</PropertyGroup>
<PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Release|AnyCPU' ">
<DebugType>none</DebugType>
<Optimize>true</Optimize>
<OutputPath>bin\Release</OutputPath>
<ErrorReport>prompt</ErrorReport>
<WarningLevel>4</WarningLevel>
<Externalconsole>true</Externalconsole>
</PropertyGroup>
<ItemGroup>
<Reference Include="System" />
</ItemGroup>
<ItemGroup>
<Compile Include="AssemblyInfo.cs" />
<Compile Include="ReportingExample.cs" />
</ItemGroup>
<Import Project="$(MSBuildBinPath)\Microsoft.CSharp.targets" />
<ItemGroup>
<ProjectReference Include="..\IEC61850forCSharp\IEC61850forCSharp.csproj">
<Project>{C35D624E-5506-4560-8074-1728F1FA1A4D}</Project>
<Name>IEC61850forCSharp</Name>
</ProjectReference>
</ItemGroup>
</Project>

20
dotnet/tests/Test.cs Normal file
View File

@ -0,0 +1,20 @@
using NUnit.Framework;
using System;
using IEC61850.Common;
using IEC61850.Client;
namespace tests
{
[TestFixture ()]
public class Test
{
[Test ()]
public void TestCase ()
{
var val = new MmsValue (10.0f);
Assert.AreEqual (10.0f, val.ToFloat ());
}
}
}

45
dotnet/tests/tests.csproj Normal file
View File

@ -0,0 +1,45 @@
<?xml version="1.0" encoding="utf-8"?>
<Project DefaultTargets="Build" ToolsVersion="4.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
<PropertyGroup>
<Configuration Condition=" '$(Configuration)' == '' ">Debug</Configuration>
<Platform Condition=" '$(Platform)' == '' ">AnyCPU</Platform>
<ProductVersion>8.0.30703</ProductVersion>
<SchemaVersion>2.0</SchemaVersion>
<ProjectGuid>{FBDFE530-DBEB-474B-BA54-9AB287DD57B3}</ProjectGuid>
<OutputType>Library</OutputType>
<RootNamespace>tests</RootNamespace>
<AssemblyName>tests</AssemblyName>
</PropertyGroup>
<PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Debug|AnyCPU' ">
<DebugSymbols>true</DebugSymbols>
<DebugType>full</DebugType>
<Optimize>false</Optimize>
<OutputPath>bin\Debug</OutputPath>
<DefineConstants>DEBUG;</DefineConstants>
<ErrorReport>prompt</ErrorReport>
<WarningLevel>4</WarningLevel>
<ConsolePause>false</ConsolePause>
</PropertyGroup>
<PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Release|AnyCPU' ">
<DebugType>full</DebugType>
<Optimize>true</Optimize>
<OutputPath>bin\Release</OutputPath>
<ErrorReport>prompt</ErrorReport>
<WarningLevel>4</WarningLevel>
<ConsolePause>false</ConsolePause>
</PropertyGroup>
<ItemGroup>
<Reference Include="System" />
<Reference Include="nunit.framework" />
</ItemGroup>
<ItemGroup>
<Compile Include="Test.cs" />
</ItemGroup>
<Import Project="$(MSBuildBinPath)\Microsoft.CSharp.targets" />
<ItemGroup>
<ProjectReference Include="..\IEC61850forCSharp\IEC61850forCSharp.csproj">
<Project>{C35D624E-5506-4560-8074-1728F1FA1A4D}</Project>
<Name>IEC61850forCSharp</Name>
</ProjectReference>
</ItemGroup>
</Project>

23
examples/CMakeLists.txt Normal file
View File

@ -0,0 +1,23 @@
add_subdirectory(server_example1)
add_subdirectory(server_example2)
add_subdirectory(server_example3)
add_subdirectory(server_example4)
add_subdirectory(server_example5)
add_subdirectory(server_example_goose)
add_subdirectory(server_example_control)
add_subdirectory(server_example_dynamic)
add_subdirectory(server_example_config_file)
add_subdirectory(server_example_complex_array)
add_subdirectory(server_example_61400_25)
add_subdirectory(iec61850_client_example1)
add_subdirectory(iec61850_client_example2)
add_subdirectory(iec61850_client_example3)
add_subdirectory(iec61850_client_example4)
add_subdirectory(iec61850_client_example5)
add_subdirectory(iec61850_client_example_files)
add_subdirectory(iec61850_client_example_reporting)
add_subdirectory(goose_subscriber)
add_subdirectory(mms_client_example1)
add_subdirectory(mms_client_example2)
add_subdirectory(mms_client_example3)
add_subdirectory(mms_client_example4)

35
examples/Makefile Normal file
View File

@ -0,0 +1,35 @@
EXAMPLE_DIRS = mms_client_example1
EXAMPLE_DIRS += mms_client_example2
EXAMPLE_DIRS += mms_client_example3
EXAMPLE_DIRS += mms_client_example4
EXAMPLE_DIRS += mms_client_example5
EXAMPLE_DIRS += iec61850_client_example1
EXAMPLE_DIRS += iec61850_client_example2
EXAMPLE_DIRS += iec61850_client_example3
EXAMPLE_DIRS += iec61850_client_example4
EXAMPLE_DIRS += iec61850_client_example5
EXAMPLE_DIRS += iec61850_client_example_reporting
EXAMPLE_DIRS += server_example1
EXAMPLE_DIRS += server_example2
EXAMPLE_DIRS += server_example3
EXAMPLE_DIRS += server_example4
EXAMPLE_DIRS += server_example5
EXAMPLE_DIRS += server_example_goose
EXAMPLE_DIRS += server_example_control
EXAMPLE_DIRS += server_example_config_file
EXAMPLE_DIRS += server_example_dynamic
EXAMPLE_DIRS += server_example_complex_array
EXAMPLE_DIRS += server_example_61400_25
EXAMPLE_DIRS += goose_subscriber
EXAMPLE_DIRS += goose_publisher
EXAMPLE_DIRS += mms_utility
all: examples
examples:
-for d in $(EXAMPLE_DIRS); do(cd $$d && $(MAKE)); done
clean:
-for d in $(EXAMPLE_DIRS); do(cd $$d && $(MAKE) clean); done

View File

@ -0,0 +1,17 @@
LIBIEC_HOME=../..
PROJECT_BINARY_NAME = goose_publisher_example
PROJECT_SOURCES = goose_publisher_example.c
include $(LIBIEC_HOME)/make/target_system.mk
include $(LIBIEC_HOME)/make/stack_includes.mk
all: $(PROJECT_BINARY_NAME)
include $(LIBIEC_HOME)/make/common_targets.mk
$(PROJECT_BINARY_NAME): $(PROJECT_SOURCES) $(LIB_NAME)
$(CC) $(CFLAGS) $(LDFLAGS) -o $(PROJECT_BINARY_NAME) $(PROJECT_SOURCES) $(INCLUDES) $(LIB_NAME) $(LDLIBS)
clean:
rm -f $(PROJECT_BINARY_NAME)

View File

@ -0,0 +1,47 @@
/*
* goose_publisher_example.c
*/
#include <stdint.h>
#include <stdlib.h>
#include <string.h>
#include <stdbool.h>
#include <stdio.h>
#include <unistd.h>
#include "mms_value.h"
#include "goose_publisher.h"
// has to be executed as root!
int
main(int argc, char** argv)
{
LinkedList dataSetValues = LinkedList_create();
LinkedList_add(dataSetValues, MmsValue_newIntegerFromInt32(1234));
LinkedList_add(dataSetValues, MmsValue_newBinaryTime(false));
LinkedList_add(dataSetValues, MmsValue_newIntegerFromInt32(5678));
GoosePublisher publisher = GoosePublisher_create(NULL, "eth0");
GoosePublisher_setGoCbRef(publisher, "Test1/LLN0$GO$gocb1");
GoosePublisher_setConfRev(publisher, 1);
GoosePublisher_setDataSetRef(publisher, "Test1/LLN0$dataset1");
int i = 0;
for (i = 0; i < 3; i++) {
sleep(1);
if (GoosePublisher_publish(publisher, dataSetValues) == -1) {
printf("Error sending message!\n");
}
}
GoosePublisher_destroy(publisher);
}

View File

@ -0,0 +1,34 @@
set(goose_subscriber_example_SRCS
goose_subscriber_example.c
)
IF(WIN32)
IF(WITH_WPCAP)
set_source_files_properties(${goose_subscriber_example_SRCS}
PROPERTIES LANGUAGE CXX)
add_executable(goose_subscriber_example
${goose_subscriber_example_SRCS}
)
target_link_libraries(goose_subscriber_example
iec61850
)
ENDIF(WITH_WPCAP)
ELSE(WIN32)
add_executable(goose_subscriber_example
${goose_subscriber_example_SRCS}
)
target_link_libraries(goose_subscriber_example
iec61850
)
ENDIF(WIN32)

View File

@ -0,0 +1,17 @@
LIBIEC_HOME=../..
PROJECT_BINARY_NAME = goose_subscriber_example
PROJECT_SOURCES = goose_subscriber_example.c
include $(LIBIEC_HOME)/make/target_system.mk
include $(LIBIEC_HOME)/make/stack_includes.mk
all: $(PROJECT_BINARY_NAME)
include $(LIBIEC_HOME)/make/common_targets.mk
$(PROJECT_BINARY_NAME): $(PROJECT_SOURCES) $(LIB_NAME)
$(CC) $(CFLAGS) $(LDFLAGS) -o $(PROJECT_BINARY_NAME) $(PROJECT_SOURCES) $(INCLUDES) $(LIB_NAME) $(LDLIBS)
clean:
rm -f $(PROJECT_BINARY_NAME)

View File

@ -0,0 +1,75 @@
/*
* goose_subscriber_example.c
*
* This is an example for a standalone GOOSE subscriber
*
* Has to be started as root in Linux.
*/
#include "goose_subscriber.h"
#include "thread.h"
#include <stdlib.h>
#include <stdio.h>
#include <signal.h>
static int running = 1;
void sigint_handler(int signalId)
{
running = 0;
}
void
gooseListener(GooseSubscriber subscriber, void* parameter)
{
printf("GOOSE event:\n");
printf(" stNum: %u sqNum: %u\n", GooseSubscriber_getStNum(subscriber),
GooseSubscriber_getSqNum(subscriber));
printf(" timeToLive: %u\n", GooseSubscriber_getTimeAllowedToLive(subscriber));
printf(" timestamp: %"PRIu64"\n", GooseSubscriber_getTimestamp(subscriber));
MmsValue* values = GooseSubscriber_getDataSetValues(subscriber);
char buffer[1024];
MmsValue_printToBuffer(values, buffer, 1024);
printf("%s\n", buffer);
}
int
main(int argc, char** argv)
{
MmsValue* dataSetValues = MmsValue_createEmtpyArray(4);
int i;
for (i = 0; i < 4; i++) {
MmsValue* dataSetEntry = MmsValue_newBoolean(false);
MmsValue_setElement(dataSetValues, i, dataSetEntry);
}
// GooseSubscriber subscriber = GooseSubscriber_create("simpleIOGenericIO/LLN0$GO$gcbEvents", dataSetValues);
GooseSubscriber subscriber = GooseSubscriber_create("simpleIOGenericIO/LLN0$GO$gcbAnalogValues", NULL);
if (argc > 1) {
printf("Set interface id: %s\n", argv[1]);
GooseSubscriber_setInterfaceId(subscriber, argv[1]);
}
GooseSubscriber_setAppId(subscriber, 1000);
GooseSubscriber_setListener(subscriber, gooseListener, NULL);
GooseSubscriber_subscribe(subscriber);
signal(SIGINT, sigint_handler);
while (running) {
Thread_sleep(100);
}
GooseSubscriber_destroy(subscriber);
}

View File

@ -0,0 +1,17 @@
set(iec61850_client_example1_SRCS
client_example1.c
)
IF(WIN32)
set_source_files_properties(${iec61850_client_example1_SRCS}
PROPERTIES LANGUAGE CXX)
ENDIF(WIN32)
add_executable(iec61850_client_example1
${iec61850_client_example1_SRCS}
)
target_link_libraries(iec61850_client_example1
iec61850
)

View File

@ -0,0 +1,17 @@
LIBIEC_HOME=../..
PROJECT_BINARY_NAME = client_example1
PROJECT_SOURCES = client_example1.c
include $(LIBIEC_HOME)/make/target_system.mk
include $(LIBIEC_HOME)/make/stack_includes.mk
all: $(PROJECT_BINARY_NAME)
include $(LIBIEC_HOME)/make/common_targets.mk
$(PROJECT_BINARY_NAME): $(PROJECT_SOURCES) $(LIB_NAME)
$(CC) $(CFLAGS) $(LDFLAGS) -o $(PROJECT_BINARY_NAME) $(PROJECT_SOURCES) $(INCLUDES) $(LIB_NAME) $(LDLIBS)
clean:
rm -f $(PROJECT_BINARY_NAME)

View File

@ -0,0 +1,123 @@
/*
* client_example1.c
*
* This example is intended to be used with server_example3 or server_example_goose.
*/
#include "iec61850_client.h"
#include <stdlib.h>
#include <stdio.h>
#include "thread.h"
void
reportCallbackFunction(void* parameter, ClientReport report)
{
MmsValue* dataSetValues = ClientReport_getDataSetValues(report);
printf("received report for %s\n", ClientReport_getRcbReference(report));
int i;
for (i = 0; i < 4; i++) {
ReasonForInclusion reason = ClientReport_getReasonForInclusion(report, i);
if (reason != REASON_NOT_INCLUDED) {
printf(" GGIO1.SPCSO%i.stVal: %i (included for reason %i)\n", i,
MmsValue_getBoolean(MmsValue_getElement(dataSetValues, i)), reason);
}
}
}
int main(int argc, char** argv) {
char* hostname;
int tcpPort = 102;
if (argc > 1)
hostname = argv[1];
else
hostname = "localhost";
if (argc > 2)
tcpPort = atoi(argv[2]);
IedClientError error;
IedConnection con = IedConnection_create();
IedConnection_connect(con, &error, hostname, tcpPort);
if (error == IED_ERROR_OK) {
/* read an analog measurement value from server */
MmsValue* value = IedConnection_readObject(con, &error, "simpleIOGenericIO/GGIO1.AnIn1.mag.f", MX);
if (value != NULL) {
float fval = MmsValue_toFloat(value);
printf("read float value: %f\n", fval);
MmsValue_delete(value);
}
/* write a variable to the server */
value = MmsValue_newVisibleString("libiec61850.com");
IedConnection_writeObject(con, &error, "simpleIOGenericIO/GGIO1.NamPlt.vendor", DC, value);
if (error != IED_ERROR_OK)
printf("failed to write simpleIOGenericIO/GGIO1.NamPlt.vendor!\n");
MmsValue_delete(value);
/* read data set */
ClientDataSet clientDataSet = IedConnection_readDataSetValues(con, &error, "simpleIOGenericIO/LLN0.Events", NULL);
if (clientDataSet == NULL)
printf("failed to read dataset\n");
/* Read RCB values */
ClientReportControlBlock rcb =
IedConnection_getRCBValues(con, &error, "simpleIOGenericIO/LLN0.RP.EventsRCB", NULL);
/* Install handler for reports */
IedConnection_installReportHandler(con, "simpleIOGenericIO/LLN0.RP.EventsRCB", ClientReportControlBlock_getRptId(rcb),
reportCallbackFunction, NULL);
/* Set trigger options and enable report */
ClientReportControlBlock_setTrgOps(rcb, TRG_OPT_DATA_UPDATE | TRG_OPT_INTEGRITY | TRG_OPT_GI);
ClientReportControlBlock_setRptEna(rcb, true);
ClientReportControlBlock_setIntgPd(rcb, 5000);
IedConnection_setRCBValues(con, &error, rcb, RCB_ELEMENT_RPT_ENA | RCB_ELEMENT_TRG_OPS | RCB_ELEMENT_INTG_PD, true);
if (error != IED_ERROR_OK)
printf("report activation failed (code: %i)\n", error);
Thread_sleep(1000);
/* trigger GI report */
ClientReportControlBlock_setGI(rcb, true);
IedConnection_setRCBValues(con, &error, rcb, RCB_ELEMENT_GI, true);
if (error != IED_ERROR_OK)
printf("Error triggering a GI report (code: %i)\n", error);
Thread_sleep(60000);
/* disable reporting */
ClientReportControlBlock_setRptEna(rcb, false);
IedConnection_setRCBValues(con, &error, rcb, RCB_ELEMENT_RPT_ENA, true);
if (error != IED_ERROR_OK)
printf("disable reporting failed (code: %i)\n", error);
ClientDataSet_destroy(clientDataSet);
IedConnection_close(con);
}
else {
printf("Failed to connect to %s:%i\n", hostname, tcpPort);
}
IedConnection_destroy(con);
}

View File

@ -0,0 +1,17 @@
set(iec61850_client_example2_SRCS
client_example2.c
)
IF(WIN32)
set_source_files_properties(${iec61850_client_example2_SRCS}
PROPERTIES LANGUAGE CXX)
ENDIF(WIN32)
add_executable(iec61850_client_example2
${iec61850_client_example2_SRCS}
)
target_link_libraries(iec61850_client_example2
iec61850
)

View File

@ -0,0 +1,17 @@
LIBIEC_HOME=../..
PROJECT_BINARY_NAME = client_example2
PROJECT_SOURCES = client_example2.c
include $(LIBIEC_HOME)/make/target_system.mk
include $(LIBIEC_HOME)/make/stack_includes.mk
all: $(PROJECT_BINARY_NAME)
include $(LIBIEC_HOME)/make/common_targets.mk
$(PROJECT_BINARY_NAME): $(PROJECT_SOURCES) $(LIB_NAME)
$(CC) $(CFLAGS) $(LDFLAGS) -o $(PROJECT_BINARY_NAME) $(PROJECT_SOURCES) $(INCLUDES) $(LIB_NAME) $(LDLIBS)
clean:
rm -f $(PROJECT_BINARY_NAME)

View File

@ -0,0 +1,196 @@
/*
* client_example2.c
*
* This example shows how to browse the data model of an unknown device.
*/
#include "iec61850_client.h"
#include <stdlib.h>
#include <stdio.h>
void
printSpaces(int spaces)
{
int i;
for (i = 0; i < spaces; i++)
printf(" ");
}
void
printDataDirectory(char* doRef, IedConnection con, int spaces)
{
IedClientError error;
LinkedList dataAttributes = IedConnection_getDataDirectory(con, &error, doRef);
if (dataAttributes != NULL) {
LinkedList dataAttribute = LinkedList_getNext(dataAttributes);
while (dataAttribute != NULL) {
char* daName = (char*) dataAttribute->data;
printSpaces(spaces);
printf("DA: %s\n", (char*) dataAttribute->data);
dataAttribute = LinkedList_getNext(dataAttribute);
char daRef[129];
sprintf(daRef, "%s.%s", doRef, daName);
printDataDirectory(daRef, con, spaces + 2);
}
}
}
int
main(int argc, char** argv)
{
char* hostname;
int tcpPort = 102;
if (argc > 1)
hostname = argv[1];
else
hostname = "localhost";
if (argc > 2)
tcpPort = atoi(argv[2]);
IedClientError error;
IedConnection con = IedConnection_create();
IedConnection_connect(con, &error, hostname, tcpPort);
if (error == IED_ERROR_OK) {
printf("Get logical device list...\n");
LinkedList deviceList = IedConnection_getLogicalDeviceList(con, &error);
printf("error: %i\n", error);
LinkedList device = LinkedList_getNext(deviceList);
while (device != NULL) {
printf("LD: %s\n", (char*) device->data);
LinkedList logicalNodes = IedConnection_getLogicalDeviceDirectory(con, &error,
(char*) device->data);
LinkedList logicalNode = LinkedList_getNext(logicalNodes);
while (logicalNode != NULL) {
printf(" LN: %s\n", (char*) logicalNode->data);
char lnRef[129];
sprintf(lnRef, "%s/%s", (char*) device->data, (char*) logicalNode->data);
LinkedList dataObjects = IedConnection_getLogicalNodeDirectory(con, &error,
lnRef, ACSI_CLASS_DATA_OBJECT);
LinkedList dataObject = LinkedList_getNext(dataObjects);
while (dataObject != NULL) {
char* dataObjectName = (char*) dataObject->data;
printf(" DO: %s\n", dataObjectName);
dataObject = LinkedList_getNext(dataObject);
char doRef[129];
sprintf(doRef, "%s/%s.%s", (char*) device->data, (char*) logicalNode->data, dataObjectName);
printDataDirectory(doRef, con, 6);
}
LinkedList_destroy(dataObjects);
LinkedList dataSets = IedConnection_getLogicalNodeDirectory(con, &error, lnRef,
ACSI_CLASS_DATA_SET);
LinkedList dataSet = LinkedList_getNext(dataSets);
while (dataSet != NULL) {
char* dataSetName = (char*) dataSet->data;
bool isDeletable;
char dataSetRef[129];
sprintf(dataSetRef, "%s.%s", lnRef, dataSetName);
LinkedList dataSetMembers = IedConnection_getDataSetDirectory(con, &error, dataSetRef,
&isDeletable);
if (isDeletable)
printf(" Data set: %s (deletable)\n", dataSetName);
else
printf(" Data set: %s (not deletable)\n", dataSetName);
LinkedList dataSetMemberRef = LinkedList_getNext(dataSetMembers);
while (dataSetMemberRef != NULL) {
char* memberRef = (char*) dataSetMemberRef->data;
printf(" %s\n", memberRef);
dataSetMemberRef = LinkedList_getNext(dataSetMemberRef);
}
dataSet = LinkedList_getNext(dataSet);
}
LinkedList_destroy(dataSets);
LinkedList reports = IedConnection_getLogicalNodeDirectory(con, &error, lnRef,
ACSI_CLASS_URCB);
LinkedList report = LinkedList_getNext(reports);
while (report != NULL) {
char* reportName = (char*) report->data;
printf(" RP: %s\n", reportName);
report = LinkedList_getNext(report);
}
LinkedList_destroy(reports);
reports = IedConnection_getLogicalNodeDirectory(con, &error, lnRef,
ACSI_CLASS_BRCB);
report = LinkedList_getNext(reports);
while (report != NULL) {
char* reportName = (char*) report->data;
printf(" BR: %s\n", reportName);
report = LinkedList_getNext(report);
}
LinkedList_destroy(reports);
logicalNode = LinkedList_getNext(logicalNode);
}
LinkedList_destroy(logicalNodes);
device = LinkedList_getNext(device);
}
LinkedList_destroy(deviceList);
IedConnection_close(con);
}
else {
printf("Connection failed!\n");
}
IedConnection_destroy(con);
}

View File

@ -0,0 +1,17 @@
set(iec61850_client_example3_SRCS
client_example3.c
)
IF(WIN32)
set_source_files_properties(${iec61850_client_example3_SRCS}
PROPERTIES LANGUAGE CXX)
ENDIF(WIN32)
add_executable(iec61850_client_example3
${iec61850_client_example3_SRCS}
)
target_link_libraries(iec61850_client_example3
iec61850
)

View File

@ -0,0 +1,17 @@
LIBIEC_HOME=../..
PROJECT_BINARY_NAME = client_example3
PROJECT_SOURCES = client_example3.c
include $(LIBIEC_HOME)/make/target_system.mk
include $(LIBIEC_HOME)/make/stack_includes.mk
all: $(PROJECT_BINARY_NAME)
include $(LIBIEC_HOME)/make/common_targets.mk
$(PROJECT_BINARY_NAME): $(PROJECT_SOURCES) $(LIB_NAME)
$(CC) $(CFLAGS) $(LDFLAGS) -o $(PROJECT_BINARY_NAME) $(PROJECT_SOURCES) $(INCLUDES) $(LIB_NAME) $(LDLIBS)
clean:
rm -f $(PROJECT_BINARY_NAME)

View File

@ -0,0 +1,104 @@
/*
* client_example3.c
*
* How to control a device ... intended to be used with server_example_control
*/
#include "iec61850_client.h"
#include <stdlib.h>
#include <stdio.h>
int main(int argc, char** argv) {
char* hostname;
int tcpPort = 102;
if (argc > 1)
hostname = argv[1];
else
hostname = "localhost";
if (argc > 2)
tcpPort = atoi(argv[2]);
IedClientError error;
IedConnection con = IedConnection_create();
IedConnection_connect(con, &error, hostname, tcpPort);
if (error == IED_ERROR_OK) {
/************************
* Direct control
***********************/
ControlObjectClient control
= ControlObjectClient_create("simpleIOGenericIO/GGIO1.SPCSO1", con);
MmsValue* ctlVal = MmsValue_newBoolean(true);
if (ControlObjectClient_operate(control, ctlVal, 0 /* operate now */)) {
printf("simpleIOGenericIO/GGIO1.SPCSO1 operated successfully\n");
}
else {
printf("failed to operate simpleIOGenericIO/GGIO1.SPCSO1\n");
}
MmsValue_delete(ctlVal);
ControlObjectClient_destroy(control);
/* Check if status value has changed */
MmsValue* stVal = IedConnection_readObject(con, &error, "simpleIOGenericIO/GGIO1.SPCSO1.stVal", ST);
if (error == IED_ERROR_OK) {
bool state = MmsValue_getBoolean(stVal);
printf("New status of simpleIOGenericIO/GGIO1.SPCSO1.stVal: %i\n", state);
}
else {
printf("Reading status for simpleIOGenericIO/GGIO1.SPCSO1 failed!\n");
}
/************************
* Select before operate
***********************/
control = ControlObjectClient_create("simpleIOGenericIO/GGIO1.SPCSO2", con);
if (ControlObjectClient_select(control)) {
ctlVal = MmsValue_newBoolean(true);
if (ControlObjectClient_operate(control, ctlVal, 0 /* operate now */)) {
printf("simpleIOGenericIO/GGIO1.SPCSO2 operated successfully\n");
}
else {
printf("failed to operate simpleIOGenericIO/GGIO1.SPCSO2!\n");
}
MmsValue_delete(ctlVal);
}
else {
printf("failed to select simpleIOGenericIO/GGIO1.SPCSO2!\n");
}
ControlObjectClient_destroy(control);
IedConnection_close(con);
}
else {
printf("Connection failed!\n");
}
IedConnection_destroy(con);
}

View File

@ -0,0 +1,17 @@
set(iec61850_client_example4_SRCS
client_example4.c
)
IF(WIN32)
set_source_files_properties(${iec61850_client_example4_SRCS}
PROPERTIES LANGUAGE CXX)
ENDIF(WIN32)
add_executable(iec61850_client_example4
${iec61850_client_example4_SRCS}
)
target_link_libraries(iec61850_client_example4
iec61850
)

View File

@ -0,0 +1,17 @@
LIBIEC_HOME=../..
PROJECT_BINARY_NAME = client_example4
PROJECT_SOURCES = client_example4.c
include $(LIBIEC_HOME)/make/target_system.mk
include $(LIBIEC_HOME)/make/stack_includes.mk
all: $(PROJECT_BINARY_NAME)
include $(LIBIEC_HOME)/make/common_targets.mk
$(PROJECT_BINARY_NAME): $(PROJECT_SOURCES) $(LIB_NAME)
$(CC) $(CFLAGS) $(LDFLAGS) -o $(PROJECT_BINARY_NAME) $(PROJECT_SOURCES) $(INCLUDES) $(LIB_NAME) $(LDLIBS)
clean:
rm -f $(PROJECT_BINARY_NAME)

View File

@ -0,0 +1,92 @@
/*
* client_example4.c
*
* How to create and delete data sets at a remote server.
*
* This example is intended to be used with server_example3 or server_example_goose.
*/
#include "iec61850_client.h"
#include <stdlib.h>
#include <stdio.h>
#include "thread.h"
static void
printDataSetValues(MmsValue* dataSet)
{
int i;
for (i = 0; i < 4; i++) {
printf(" GGIO1.AnIn%i.mag.f: %f\n", i,
MmsValue_toFloat(MmsValue_getElement(MmsValue_getElement(
MmsValue_getElement(dataSet, i), 0), 0)));
}
}
void
reportCallbackFunction(void* parameter, ClientReport report)
{
MmsValue* dataSetValues = (MmsValue*) parameter;
printf("received report\n");
printDataSetValues(dataSetValues);
}
int main(int argc, char** argv) {
char* hostname;
int tcpPort = 102;
if (argc > 1)
hostname = argv[1];
else
hostname = "localhost";
if (argc > 2)
tcpPort = atoi(argv[2]);
IedClientError error;
IedConnection con = IedConnection_create();
IedConnection_connect(con, &error, hostname, tcpPort);
if (error == IED_ERROR_OK) {
/* Create a new data set at the remote server */
LinkedList newDataSetEntries = LinkedList_create();
LinkedList_add(newDataSetEntries, "simpleIOGenericIO/GGIO1.AnIn1[MX]");
LinkedList_add(newDataSetEntries, "simpleIOGenericIO/GGIO1.AnIn2[MX]");
LinkedList_add(newDataSetEntries, "simpleIOGenericIO/GGIO1.AnIn3[MX]");
LinkedList_add(newDataSetEntries, "simpleIOGenericIO/GGIO1.AnIn4[MX]");
IedConnection_createDataSet(con, &error, "simpleIOGenericIO/LLN0.AnalogueValues", newDataSetEntries);
LinkedList_destroyStatic(newDataSetEntries);
printf("error: %i\n", error);
/* read data set */
ClientDataSet clientDataSet;
clientDataSet = IedConnection_readDataSetValues(con, &error, "simpleIOGenericIO/LLN0.AnalogueValues", NULL);
printDataSetValues(ClientDataSet_getValues(clientDataSet));
Thread_sleep(1000);
IedConnection_deleteDataSet(con, &error, "simpleIOGenericIO/LLN0.AnalogueValues");
IedConnection_close(con);
}
else {
printf("Failed to connect to %s:%i\n", hostname, tcpPort);
}
IedConnection_destroy(con);
}

View File

@ -0,0 +1,17 @@
set(iec61850_client_example5_SRCS
client_example5.c
)
IF(WIN32)
set_source_files_properties(${iec61850_client_example5_SRCS}
PROPERTIES LANGUAGE CXX)
ENDIF(WIN32)
add_executable(iec61850_client_example5
${iec61850_client_example5_SRCS}
)
target_link_libraries(iec61850_client_example5
iec61850
)

View File

@ -0,0 +1,17 @@
LIBIEC_HOME=../..
PROJECT_BINARY_NAME = client_example5
PROJECT_SOURCES = client_example5.c
include $(LIBIEC_HOME)/make/target_system.mk
include $(LIBIEC_HOME)/make/stack_includes.mk
all: $(PROJECT_BINARY_NAME)
include $(LIBIEC_HOME)/make/common_targets.mk
$(PROJECT_BINARY_NAME): $(PROJECT_SOURCES) $(LIB_NAME)
$(CC) $(CFLAGS) $(LDFLAGS) -o $(PROJECT_BINARY_NAME) $(PROJECT_SOURCES) $(INCLUDES) $(LIB_NAME) $(LDLIBS)
clean:
rm -f $(PROJECT_BINARY_NAME)

View File

@ -0,0 +1,80 @@
/*
* client_example5.c
*
* - How to change connection parameters of the lower layers of MMS
* - How to use password authentication
*
*/
#include "iec61850_client.h"
#include <stdlib.h>
#include <stdio.h>
#include "thread.h"
int main(int argc, char** argv) {
char* hostname;
int tcpPort = 102;
if (argc > 1)
hostname = argv[1];
else
hostname = "localhost";
if (argc > 2)
tcpPort = atoi(argv[2]);
IedClientError error;
IedConnection con = IedConnection_create();
/* To change MMS parameters you need to get access to the underlying MmsConnection */
MmsConnection mmsConnection = IedConnection_getMmsConnection(con);
/* Get the container for the parameters */
IsoConnectionParameters parameters = MmsConnection_getIsoConnectionParameters(mmsConnection);
/* set remote AP-Title according to SCL file example from IEC 61850-8-1 */
IsoConnectionParameters_setRemoteApTitle(parameters, "1.3.9999.13", 12);
/* just some arbitrary numbers */
IsoConnectionParameters_setLocalApTitle(parameters, "1.2.1200.15.3", 1);
/* use this to skip AP-Title completely - this may be required by some "obscure" servers */
// IsoConnectionParameters_setRemoteApTitle(parameters, NULL, 0);
// IsoConnectionParameters_setLocalApTitle(parameters, NULL, 0);
/* change parameters for presentation, session and transport layers */
IsoConnectionParameters_setRemoteAddresses(parameters, 0x12345678, 12 , 13);
IsoConnectionParameters_setLocalAddresses(parameters, 0x87654321, 1234 , 2345);
char* password = "top secret";
/* use authentication */
AcseAuthenticationParameter auth = (AcseAuthenticationParameter) calloc(1, sizeof(struct sAcseAuthenticationParameter));
auth->mechanism = ACSE_AUTH_PASSWORD;
auth->value.password.octetString = (uint8_t*) password;
auth->value.password.passwordLength = strlen(password);
IsoConnectionParameters_setAcseAuthenticationParameter(parameters, auth);
/* call connect when all parameters are set */
IedConnection_connect(con, &error, hostname, tcpPort);
if (error == IED_ERROR_OK) {
Thread_sleep(1000);
IedConnection_abort(con, &error);
}
else {
printf("Failed to connect to %s:%i\n", hostname, tcpPort);
}
IedConnection_destroy(con);
}

View File

@ -0,0 +1,17 @@
set(iec61850_client_example_files_SRCS
client_example_files.c
)
IF(WIN32)
set_source_files_properties(${iec61850_client_example_files_SRCS}
PROPERTIES LANGUAGE CXX)
ENDIF(WIN32)
add_executable(iec61850_client_example_files
${iec61850_client_example_files_SRCS}
)
target_link_libraries(iec61850_client_example_files
iec61850
)

View File

@ -0,0 +1,17 @@
LIBIEC_HOME=../..
PROJECT_BINARY_NAME = client_example_files
PROJECT_SOURCES = client_example_files.c
include $(LIBIEC_HOME)/make/target_system.mk
include $(LIBIEC_HOME)/make/stack_includes.mk
all: $(PROJECT_BINARY_NAME)
include $(LIBIEC_HOME)/make/common_targets.mk
$(PROJECT_BINARY_NAME): $(PROJECT_SOURCES) $(LIB_NAME)
$(CC) $(CFLAGS) $(LDFLAGS) -o $(PROJECT_BINARY_NAME) $(PROJECT_SOURCES) $(INCLUDES) $(LIB_NAME) $(LDLIBS)
clean:
rm -f $(PROJECT_BINARY_NAME)

View File

@ -0,0 +1,104 @@
/*
* client_example_files.c
*
* This example demonstrates the usage of the file services
*
* - How to browse the file system of the server
* - How to download a file from the server
*
* Note: intended to be used with server_example3
*
*/
#include "iec61850_client.h"
#include <stdlib.h>
#include <stdio.h>
#include "thread.h"
#define MAX_BUFFER_SIZE 2000000
static uint8_t downloadBuffer[MAX_BUFFER_SIZE];
static int bufferPosition = 0;
static bool
downloadHandler(void* parameter, uint8_t* buffer, uint32_t bytesRead)
{
printf("received %i bytes\n", bytesRead);
if (bufferPosition + bytesRead < MAX_BUFFER_SIZE) {
memcpy(downloadBuffer + bufferPosition, buffer, bytesRead);
return false;
}
else
return true;
}
int main(int argc, char** argv) {
char* hostname;
int tcpPort = 102;
if (argc > 1)
hostname = argv[1];
else
hostname = "localhost";
if (argc > 2)
tcpPort = atoi(argv[2]);
IedClientError error;
IedConnection con = IedConnection_create();
IedConnection_connect(con, &error, hostname, tcpPort);
if (error == IED_ERROR_OK) {
/* Get the root directory */
LinkedList rootDirectory =
IedConnection_getFileDirectory(con, &error, NULL);
if (error != IED_ERROR_OK) {
printf("Error retrieving file directory\n");
goto abort_connection;
}
LinkedList directoryEntry = LinkedList_getNext(rootDirectory);
while (directoryEntry != NULL) {
FileDirectoryEntry entry = (FileDirectoryEntry) directoryEntry->data;
printf("%s %i\n", FileDirectoryEntry_getFileName(entry), FileDirectoryEntry_getFileSize(entry));
directoryEntry = LinkedList_getNext(directoryEntry);
}
/* Download a file from the server */
IedConnection_getFile(con, &error, "IEDSERVER.BIN", downloadHandler, NULL);
if (error != IED_ERROR_OK)
printf("Failed to get file!\n");
/* Delete file at server */
IedConnection_deleteFile(con, &error, "IEDSERVER.BIN");
if (error != IED_ERROR_OK)
printf("Failed to delete file! (code=%i)\n", error);
abort_connection:
IedConnection_abort(con, &error);
}
else {
printf("Failed to connect to %s:%i\n", hostname, tcpPort);
}
IedConnection_destroy(con);
}

View File

@ -0,0 +1,17 @@
set(iec61850_client_example_reporting_SRCS
client_example_reporting.c
)
IF(WIN32)
set_source_files_properties(${iec61850_client_example_reporting_SRCS}
PROPERTIES LANGUAGE CXX)
ENDIF(WIN32)
add_executable(iec61850_client_example_reporting
${iec61850_client_example_reporting_SRCS}
)
target_link_libraries(iec61850_client_example_reporting
iec61850
)

View File

@ -0,0 +1,17 @@
LIBIEC_HOME=../..
PROJECT_BINARY_NAME = client_example_reporting
PROJECT_SOURCES = client_example_reporting.c
include $(LIBIEC_HOME)/make/target_system.mk
include $(LIBIEC_HOME)/make/stack_includes.mk
all: $(PROJECT_BINARY_NAME)
include $(LIBIEC_HOME)/make/common_targets.mk
$(PROJECT_BINARY_NAME): $(PROJECT_SOURCES) $(LIB_NAME)
$(CC) $(CFLAGS) $(LDFLAGS) -o $(PROJECT_BINARY_NAME) $(PROJECT_SOURCES) $(INCLUDES) $(LIB_NAME) $(LDLIBS)
clean:
rm -f $(PROJECT_BINARY_NAME)

View File

@ -0,0 +1,168 @@
/*
* client_example_reporting.c
*
* This example is intended to be used with server_example3 or server_example_goose.
*/
#include "iec61850_client.h"
#include <stdlib.h>
#include <stdio.h>
#include <signal.h>
#include <time.h>
#include "thread.h"
static int running = 0;
void sigint_handler(int signalId)
{
running = 0;
}
void
reportCallbackFunction(void* parameter, ClientReport report)
{
LinkedList dataSetDirectory = (LinkedList) parameter;
MmsValue* dataSetValues = ClientReport_getDataSetValues(report);
printf("received report for %s with rptId %s\n", ClientReport_getRcbReference(report), ClientReport_getRptId(report));
if (ClientReport_hasTimestamp(report)) {
time_t unixTime = ClientReport_getTimestamp(report) / 1000;
#ifdef _MSC_VER
char* timeBuf = ctime(&unixTime);
#else
char timeBuf[30];
ctime_r(&unixTime, timeBuf);
#endif
printf(" report contains timestamp (%u):", (unsigned int) unixTime);
printf("%s \n", timeBuf);
}
int i;
for (i = 0; i < LinkedList_size(dataSetDirectory); i++) {
ReasonForInclusion reason = ClientReport_getReasonForInclusion(report, i);
if (reason != REASON_NOT_INCLUDED) {
LinkedList entry = LinkedList_get(dataSetDirectory, i);
char* entryName = (char*) entry->data;
printf(" %s (included for reason %i)\n", entryName, reason);
}
}
}
int main(int argc, char** argv) {
char* hostname;
int tcpPort = 102;
if (argc > 1)
hostname = argv[1];
else
hostname = "localhost";
if (argc > 2)
tcpPort = atoi(argv[2]);
running = 1;
signal(SIGINT, sigint_handler);
IedClientError error;
IedConnection con = IedConnection_create();
IedConnection_connect(con, &error, hostname, tcpPort);
if (error == IED_ERROR_OK) {
/* read data set directory */
LinkedList dataSetDirectory =
IedConnection_getDataSetDirectory(con, &error, "simpleIOGenericIO/LLN0.Events", NULL);
if (error != IED_ERROR_OK) {
printf("Reading data set directory failed!\n");
goto exit_error;
}
/* read data set */
ClientDataSet clientDataSet;
clientDataSet = IedConnection_readDataSetValues(con, &error, "simpleIOGenericIO/LLN0.Events", NULL);
if (clientDataSet == NULL) {
printf("failed to read dataset\n");
goto exit_error;
}
/* Read RCB values */
ClientReportControlBlock rcb =
IedConnection_getRCBValues(con, &error, "simpleIOGenericIO/LLN0.RP.EventsRCB", NULL);
if (error != IED_ERROR_OK) {
printf("getRCBValues service error!\n");
goto exit_error;
}
/* prepare the parameters of the RCP */
ClientReportControlBlock_setResv(rcb, true);
ClientReportControlBlock_setDataSetReference(rcb, "simpleIOGenericIO/LLN0$Events"); /* NOTE the "$" instead of "." ! */
ClientReportControlBlock_setRptEna(rcb, true);
/* Configure the report receiver */
IedConnection_installReportHandler(con, "simpleIOGenericIO/LLN0.RP.EventsRCB", ClientReportControlBlock_getRptId(rcb), reportCallbackFunction,
(void*) dataSetDirectory);
/* Write RCB parameters and enable report */
IedConnection_setRCBValues(con, &error, rcb, RCB_ELEMENT_RESV | RCB_ELEMENT_DATSET | RCB_ELEMENT_RPT_ENA, true);
if (error != IED_ERROR_OK) {
printf("setRCBValues service error!\n");
goto exit_error;
}
Thread_sleep(1000);
IedConnection_triggerGIReport(con, &error, "simpleIOGenericIO/LLN0.RP.EventsRCB");
if (error != IED_ERROR_OK) {
printf("Error triggering a GI report (code: %i)\n", error);
}
while (running) {
Thread_sleep(10);
IedConnectionState conState = IedConnection_getState(con);
if (conState != IED_STATE_CONNECTED) {
printf("Connection closed by server!\n");
running = 0;
}
}
exit_error:
/* disable reporting */
ClientReportControlBlock_setRptEna(rcb, false);
IedConnection_setRCBValues(con, &error, rcb, RCB_ELEMENT_RPT_ENA, true);
ClientDataSet_destroy(clientDataSet);
IedConnection_close(con);
}
else {
printf("Failed to connect to %s:%i\n", hostname, tcpPort);
}
IedConnection_destroy(con);
}

View File

@ -0,0 +1,17 @@
set(mms_client_example1_SRCS
mms_client_example1.c
)
IF(WIN32)
set_source_files_properties(${mms_client_example1_SRCS}
PROPERTIES LANGUAGE CXX)
ENDIF(WIN32)
add_executable(mms_client_example1
${mms_client_example1_SRCS}
)
target_link_libraries(mms_client_example1
iec61850
)

View File

@ -0,0 +1,17 @@
LIBIEC_HOME=../..
PROJECT_BINARY_NAME = mms_client_example1
PROJECT_SOURCES = mms_client_example1.c
include $(LIBIEC_HOME)/make/target_system.mk
include $(LIBIEC_HOME)/make/stack_includes.mk
all: $(PROJECT_BINARY_NAME)
include $(LIBIEC_HOME)/make/common_targets.mk
$(PROJECT_BINARY_NAME): $(PROJECT_SOURCES) $(LIB_NAME)
$(CC) $(CFLAGS) $(LDFLAGS) -o $(PROJECT_BINARY_NAME) $(PROJECT_SOURCES) $(INCLUDES) $(LIB_NAME) $(LDLIBS)
clean:
rm -f $(PROJECT_BINARY_NAME)

View File

@ -0,0 +1,51 @@
/*
* mms_client_example.c
*
* This is the most simple example. It illustrates how to create an MmsConnection
* object and connect to a MMS server.
*
* Copyright 2013 Michael Zillgith
*
* This file is part of libIEC61850.
*
* libIEC61850 is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* libIEC61850 is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with libIEC61850. If not, see <http://www.gnu.org/licenses/>.
*
* See COPYING file for the complete license text.
*/
#include <stdlib.h>
#include <stdio.h>
#include "mms_client_connection.h"
#include "thread.h"
int main(int argc, char** argv) {
MmsConnection con = MmsConnection_create();
MmsError mmsError;
if (MmsConnection_connect(con, &mmsError, "localhost", 102)) {
// add application code here
Thread_sleep(1000);
printf("Send abort\n");
MmsConnection_abort(con, &mmsError);
}
else
printf("Connect to server failed!\n");
MmsConnection_destroy(con);
}

View File

@ -0,0 +1,17 @@
set(mms_client_example2_SRCS
mms_client_example2.c
)
IF(WIN32)
set_source_files_properties(${mms_client_example2_SRCS}
PROPERTIES LANGUAGE CXX)
ENDIF(WIN32)
add_executable(mms_client_example2
${mms_client_example2_SRCS}
)
target_link_libraries(mms_client_example2
iec61850
)

View File

@ -0,0 +1,17 @@
LIBIEC_HOME=../..
PROJECT_BINARY_NAME = mms_client_example2
PROJECT_SOURCES = mms_client_example2.c
include $(LIBIEC_HOME)/make/target_system.mk
include $(LIBIEC_HOME)/make/stack_includes.mk
all: $(PROJECT_BINARY_NAME)
include $(LIBIEC_HOME)/make/common_targets.mk
$(PROJECT_BINARY_NAME): $(PROJECT_SOURCES) $(LIB_NAME)
$(CC) $(CFLAGS) $(LDFLAGS) -o $(PROJECT_BINARY_NAME) $(PROJECT_SOURCES) $(INCLUDES) $(LIB_NAME) $(LDLIBS)
clean:
rm -f $(PROJECT_BINARY_NAME)

View File

@ -0,0 +1,64 @@
#include <stdlib.h>
#include <stdio.h>
#include "mms_client_connection.h"
int main(int argc, char** argv) {
char* hostname;
int tcpPort = 102;
if (argc > 1)
hostname = argv[1];
else
hostname = "localhost";
if (argc > 2)
tcpPort = atoi(argv[2]);
MmsConnection con = MmsConnection_create();
MmsError mmsError;
/* Set maximum MMS PDU size (local detail) to 2000 byte */
MmsConnection_setLocalDetail(con, 2000);
if (!MmsConnection_connect(con, &mmsError, hostname, tcpPort)) {
printf("MMS connect failed!\n");
goto exit;
}
else
printf("MMS connected.\n\n");
printf("Domains present on server:\n--------------------------\n");
LinkedList nameList = MmsConnection_getDomainNames(con, &mmsError);
LinkedList_printStringList(nameList);
printf("\n");
LinkedList element = nameList;
while ((element = LinkedList_getNext(element)) != NULL) {
printf("\nNamed variables in domain: %s\n-------------------------------------------------\n", (char*) element->data);
LinkedList variableList = MmsConnection_getDomainVariableNames(con, &mmsError, (char*) element->data);
LinkedList_printStringList(variableList);
LinkedList_destroy(variableList);
printf("\nNamed variable lists (data sets) in domain: %s\n", (char*) element->data);
LinkedList dataSetList = MmsConnection_getDomainVariableListNames(con, &mmsError, (char*) element->data);
LinkedList_printStringList(dataSetList);
LinkedList_destroy(dataSetList);
}
LinkedList_destroy(nameList);
exit:
MmsConnection_destroy(con);
}

View File

@ -0,0 +1,17 @@
set(mms_client_example3_SRCS
mms_client_example3.c
)
IF(WIN32)
set_source_files_properties(${mms_client_example3_SRCS}
PROPERTIES LANGUAGE CXX)
ENDIF(WIN32)
add_executable(mms_client_example3
${mms_client_example3_SRCS}
)
target_link_libraries(mms_client_example3
iec61850
)

View File

@ -0,0 +1,17 @@
LIBIEC_HOME=../..
PROJECT_BINARY_NAME = mms_client_example3
PROJECT_SOURCES = mms_client_example3.c
include $(LIBIEC_HOME)/make/target_system.mk
include $(LIBIEC_HOME)/make/stack_includes.mk
all: $(PROJECT_BINARY_NAME)
include $(LIBIEC_HOME)/make/common_targets.mk
$(PROJECT_BINARY_NAME): $(PROJECT_SOURCES) $(LIB_NAME)
$(CC) $(CFLAGS) $(LDFLAGS) -o $(PROJECT_BINARY_NAME) $(PROJECT_SOURCES) $(INCLUDES) $(LIB_NAME) $(LDLIBS)
clean:
rm -f $(PROJECT_BINARY_NAME)

View File

@ -0,0 +1,41 @@
#include <stdlib.h>
#include <stdio.h>
#include "mms_client_connection.h"
int main(int argc, char** argv) {
char* hostname;
int tcpPort = 102;
if (argc > 1)
hostname = argv[1];
else
hostname = "localhost";
if (argc > 2)
tcpPort = atoi(argv[2]);
MmsConnection con = MmsConnection_create();
MmsError error;
if (!MmsConnection_connect(con, &error, hostname, tcpPort)) {
printf("MMS connect failed!\n");
goto exit;
}
else
printf("MMS connected.\n\n");
MmsValue* value =
MmsConnection_readVariable(con, &error, "simpleIOGenericIO", "LLN0$GO");
if (value == NULL)
printf("reading value failed!\n");
else
MmsValue_delete(value);
exit:
MmsConnection_destroy(con);
}

View File

@ -0,0 +1,17 @@
set(mms_client_example4_SRCS
mms_client_example4.c
)
IF(WIN32)
set_source_files_properties(${mms_client_example4_SRCS}
PROPERTIES LANGUAGE CXX)
ENDIF(WIN32)
add_executable(mms_client_example4
${mms_client_example4_SRCS}
)
target_link_libraries(mms_client_example4
iec61850
)

View File

@ -0,0 +1,17 @@
LIBIEC_HOME=../..
PROJECT_BINARY_NAME = mms_client_example4
PROJECT_SOURCES = mms_client_example4.c
include $(LIBIEC_HOME)/make/target_system.mk
include $(LIBIEC_HOME)/make/stack_includes.mk
all: $(PROJECT_BINARY_NAME)
include $(LIBIEC_HOME)/make/common_targets.mk
$(PROJECT_BINARY_NAME): $(PROJECT_SOURCES) $(LIB_NAME)
$(CC) $(CFLAGS) $(LDFLAGS) -o $(PROJECT_BINARY_NAME) $(PROJECT_SOURCES) $(INCLUDES) $(LIB_NAME) $(LDLIBS)
clean:
rm -f $(PROJECT_BINARY_NAME)

View File

@ -0,0 +1,114 @@
/*
* mms_client_example.c
*
* Copyright 2013 Michael Zillgith
*
* This file is part of libIEC61850.
*
* libIEC61850 is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* libIEC61850 is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with libIEC61850. If not, see <http://www.gnu.org/licenses/>.
*
* See COPYING file for the complete license text.
*/
#include <stdlib.h>
#include <stdio.h>
#include "mms_client_connection.h"
int main(int argc, char** argv) {
char* hostname;
int tcpPort = 102;
if (argc > 1)
hostname = argv[1];
else
hostname = "localhost";
if (argc > 2)
tcpPort = atoi(argv[2]);
MmsConnection con = MmsConnection_create();
MmsError mmsError;
char* password = "testpw";
/* use authentication */
AcseAuthenticationParameter auth = (AcseAuthenticationParameter) calloc(1, sizeof(struct sAcseAuthenticationParameter));
auth->mechanism = ACSE_AUTH_PASSWORD;
auth->value.password.octetString= (uint8_t*) password;
auth->value.password.passwordLength = strlen(password);
IsoConnectionParameters connectionParameters =
MmsConnection_getIsoConnectionParameters(con);
IsoConnectionParameters_setAcseAuthenticationParameter(connectionParameters, auth);
if (!MmsConnection_connect(con, &mmsError, hostname, tcpPort)) {
printf("MMS connect failed!\n");
goto exit;
}
else
printf("MMS connected.\n\n");
printf("Domains present on server:\n--------------------------\n");
LinkedList nameList = MmsConnection_getDomainNames(con, &mmsError);
LinkedList_printStringList(nameList);
LinkedList_destroy(nameList);
printf("\n");
printf("Named variables for domain SampleIEDDevice1:\n--------------------------------------------\n");
nameList = MmsConnection_getDomainVariableNames(con, &mmsError, "SampleIEDDevice1");
LinkedList_printStringList(nameList);
LinkedList_destroy(nameList);
printf("\n");
printf("Data sets for domain SampleIEDDevice1:\n--------------------------------------------\n");
nameList = MmsConnection_getDomainVariableListNames(con, &mmsError, "SampleIEDDevice1");
LinkedList_printStringList(nameList);
LinkedList_destroy(nameList);
printf("\n");
// MmsValue* value;
//
// MmsConnection_getVariableAccessAttributes(con, "SampleIEDDevice1", "MMXU2$MX$TotW");
//
// value = MmsConnection_readVariable(con, "SampleIEDDevice1", "MMXU2$MX$TotW$mag$f");
//
// printf("Read variable with value: %f\n", MmsValue_toFloat(value));
//
// MmsValue_setFloat(value, 1.234f);
//
// MmsConnection_writeVariable(con, "SampleIEDDevice1", "MMXU2$MX$TotW$mag$f", value);
//
// MmsValue_delete(value);
//
// value = MmsConnection_readVariable(con, "SampleIEDDevice1", "MMXU2$MX$TotW$mag$f");
//
// printf("Read variable with value: %f\n", MmsValue_toFloat(value));
//
// MmsValue_delete(value);
//
// value = MmsConnection_readVariable(con, "SampleIEDDevice1", "DGEN1$ST$Beh$stVal");
//
// printf("Read integer variable with value: %i\n", MmsValue_toInt32(value));
//
// MmsValue_delete(value);
exit:
MmsConnection_destroy(con);
}

View File

@ -0,0 +1,17 @@
set(mms_client_example5_SRCS
mms_client_example5.c
)
IF(WIN32)
set_source_files_properties(${mms_client_example5_SRCS}
PROPERTIES LANGUAGE CXX)
ENDIF(WIN32)
add_executable(mms_client_example5
${mms_client_example5_SRCS}
)
target_link_libraries(mms_client_example5
iec61850
)

View File

@ -0,0 +1,17 @@
LIBIEC_HOME=../..
PROJECT_BINARY_NAME = mms_client_example5
PROJECT_SOURCES = mms_client_example5.c
include $(LIBIEC_HOME)/make/target_system.mk
include $(LIBIEC_HOME)/make/stack_includes.mk
all: $(PROJECT_BINARY_NAME)
include $(LIBIEC_HOME)/make/common_targets.mk
$(PROJECT_BINARY_NAME): $(PROJECT_SOURCES) $(LIB_NAME)
$(CC) $(CFLAGS) $(LDFLAGS) -o $(PROJECT_BINARY_NAME) $(PROJECT_SOURCES) $(INCLUDES) $(LIB_NAME) $(LDLIBS)
clean:
rm -f $(PROJECT_BINARY_NAME)

View File

@ -0,0 +1,50 @@
#include <stdlib.h>
#include <stdio.h>
#include "mms_client_connection.h"
int main(int argc, char** argv) {
char* hostname;
int tcpPort = 102;
if (argc > 1)
hostname = argv[1];
else
hostname = "localhost";
if (argc > 2)
tcpPort = atoi(argv[2]);
MmsConnection con = MmsConnection_create();
MmsError error;
if (!MmsConnection_connect(con, &error, hostname, tcpPort)) {
printf("MMS connect failed!\n");
goto exit;
}
else
printf("MMS connected.\n\n");
LinkedList dataSetEntries = LinkedList_create();
MmsVariableAccessSpecification* dataSetEntry =
MmsVariableAccessSpecification_create("BayControllerQ", "QA1CSWI1$ST$Pos");
LinkedList_add(dataSetEntries, (void*) dataSetEntry);
dataSetEntry =
MmsVariableAccessSpecification_create("BayControllerQ", "QA1XCBR1$ST$Pos");
LinkedList_add(dataSetEntries, (void*) dataSetEntry);
MmsConnection_defineNamedVariableList(con, &error, "BayControllerQ", "LLN0$LIBIEC61850_CLIENT", dataSetEntries);
/* delete list and all elements */
LinkedList_destroy(dataSetEntries);
exit:
MmsConnection_destroy(con);
}

View File

@ -0,0 +1,17 @@
set(mms_utility_SRCS
mms_utility.c
)
IF(WIN32)
set_source_files_properties(${mms_utility_SRCS}
PROPERTIES LANGUAGE CXX)
ENDIF(WIN32)
add_executable(mms_utility
${mms_utility_SRCS}
)
target_link_libraries(mms_utility
iec61850
)

View File

@ -0,0 +1,17 @@
LIBIEC_HOME=../..
PROJECT_BINARY_NAME = mms_utility
PROJECT_SOURCES = mms_utility.c
include $(LIBIEC_HOME)/make/target_system.mk
include $(LIBIEC_HOME)/make/stack_includes.mk
all: $(PROJECT_BINARY_NAME)
include $(LIBIEC_HOME)/make/common_targets.mk
$(PROJECT_BINARY_NAME): $(PROJECT_SOURCES) $(LIB_NAME)
$(CC) $(CFLAGS) $(LDFLAGS) -o $(PROJECT_BINARY_NAME) $(PROJECT_SOURCES) $(INCLUDES) $(LIB_NAME) $(LDLIBS)
clean:
rm -f $(PROJECT_BINARY_NAME)

View File

@ -0,0 +1,115 @@
#include <stdlib.h>
#include <stdio.h>
#include <unistd.h>
#include "string_utilities.h"
#include "mms_client_connection.h"
static void
print_help()
{
printf("MMS utility (libiec61850 v0.5) options:\n");
printf("-h <hostname> specify hostname\n");
printf("-p <port> specify port\n");
printf("-l <max_pdu_size> specify maximum PDU size\n");
printf("-d show list of MMS domains\n");
printf("-i show server identity\n");
printf("-t <domain_name> show domain directory\n");
}
int main(int argc, char** argv) {
char* hostname = copyString("localhost");
int tcpPort = 102;
int maxPduSize = 65000;
char* domainName = NULL;
int readDeviceList = 0;
int getDeviceDirectory = 0;
int identifyDevice = 0;
int c;
while ((c = getopt(argc, argv, "idh:p:l:t:")) != -1)
switch (c) {
case 'h':
hostname = copyString(optarg);
break;
case 'p':
tcpPort = atoi(optarg);
break;
case 'l':
maxPduSize = atoi(optarg);
break;
case 'd':
readDeviceList = 1;
break;
case 'i':
identifyDevice = 1;
break;
case 't':
getDeviceDirectory = 1;
domainName = copyString(optarg);
break;
default:
print_help();
return 0;
}
MmsConnection con = MmsConnection_create();
MmsError error;
/* Set maximum MMS PDU size (local detail) to 2000 byte */
MmsConnection_setLocalDetail(con, maxPduSize);
if (!MmsConnection_connect(con, &error, hostname, tcpPort)) {
printf("MMS connect failed!\n");
goto exit;
}
else
printf("MMS connected.\n");
if (identifyDevice) {
MmsServerIdentity* identity =
MmsConnection_identify(con, &error);
if (identity != NULL) {
printf("\nServer identity:\n----------------\n");
printf(" vendor:\t%s\n", identity->vendorName);
printf(" model:\t%s\n", identity->modelName);
printf(" revision:\t%s\n", identity->revision);
}
else
printf("Reading server identity failed!\n");
}
if (readDeviceList) {
printf("\nDomains present on server:\n--------------------------\n");
LinkedList nameList = MmsConnection_getDomainNames(con, &error);
LinkedList_printStringList(nameList);
LinkedList_destroy(nameList);
}
if (getDeviceDirectory) {
LinkedList variableList = MmsConnection_getDomainVariableNames(con, &error,
domainName);
LinkedList element = variableList;
printf("\nMMS domain variables for domain %s\n", domainName);
while ((element = LinkedList_getNext(element)) != NULL) {
char* name = (char*) element->data;
if (strchr(name, '$') == NULL)
printf(" %s\n", name);
}
}
exit:
MmsConnection_destroy(con);
}

View File

@ -0,0 +1,21 @@
include_directories(
.
)
set(server_example1_SRCS
server_example1.c
static_model.c
)
IF(WIN32)
set_source_files_properties(${server_example1_SRCS}
PROPERTIES LANGUAGE CXX)
ENDIF(WIN32)
add_executable(server_example1
${server_example1_SRCS}
)
target_link_libraries(server_example1
iec61850
)

View File

@ -0,0 +1,20 @@
LIBIEC_HOME=../..
PROJECT_BINARY_NAME = server_example1
PROJECT_SOURCES = server_example1.c
PROJECT_SOURCES += static_model.c
include $(LIBIEC_HOME)/make/target_system.mk
include $(LIBIEC_HOME)/make/stack_includes.mk
all: $(PROJECT_BINARY_NAME)
include $(LIBIEC_HOME)/make/common_targets.mk
$(PROJECT_BINARY_NAME): $(PROJECT_SOURCES) $(LIB_NAME)
$(CC) $(CFLAGS) $(LDFLAGS) -o $(PROJECT_BINARY_NAME) $(PROJECT_SOURCES) $(INCLUDES) $(LIB_NAME) $(LDLIBS)
clean:
rm -f $(PROJECT_BINARY_NAME)

View File

@ -0,0 +1,184 @@
<?xml version="1.0" encoding="UTF-8"?>
<SCL xmlns="http://www.iec.ch/61850/2003/SCL">
<Header id=""/>
<IED name="SampleIED">
<Services>
<DynAssociation />
<GetDirectory />
<GetDataObjectDefinition />
<GetDataSetValue />
<DataSetDirectory />
<ReadWrite />
<GetCBValues />
<ConfLNs fixPrefix="true" fixLnInst="true" />
<GOOSE max="5" />
<GSSE max="5" />
<FileHandling />
<GSEDir />
<TimerActivatedControl />
</Services>
<AccessPoint name="accessPoint1">
<Server>
<Authentication />
<LDevice inst="Device1">
<LN0 lnClass="LLN0" lnType="LLN01" inst="">
<DataSet name="dataset1" desc="">
<FCDA ldInst="Device1" lnClass="LLN0" fc="ST" doName="Mod" daName="q" />
<FCDA ldInst="Device1" lnClass="MMXU" fc="ST" lnInst="1" doName="Mod" daName="q" />
<FCDA ldInst="Device1" lnClass="MMXU" fc="CF" lnInst="1" doName="Mod" daName="ctlModel" />
</DataSet>
<ReportControl name="LLN0_Events_BuffRep" rptID="LLN0$RP$brcbEV1" datSet="dataset1" confRev="1" buffered="true"
desc="Events brcb buffered report" intgPd="900000" bufTime="50">
<TrgOps dchg="true" qchg="false" dupd="false" period="true" />
<OptFields seqNum="true" timeStamp="true" dataSet="true" reasonCode="true" dataRef="false" entryID="true"
configRef="true" bufOvfl="true" />
<RptEnabled max="1" />
</ReportControl>
<DOI name="Mod">
<DAI name="ctlModel">
<Val>status-only</Val>
</DAI>
</DOI>
</LN0>
<LN lnClass="LPHD" lnType="LPHD1" inst="1" prefix="" />
<LN lnClass="DGEN" lnType="DGEN1" inst="1" prefix="">
<DOI name="Mod">
<DAI name="ctlModel">
<Val>status-only</Val>
</DAI>
</DOI>
</LN>
<LN lnClass="DSCH" lnType="DSCH1" inst="1" prefix="">
<DOI name="Mod">
<DAI name="ctlModel">
<Val>status-only</Val>
</DAI>
</DOI>
</LN>
<LN lnClass="MMXU" lnType="MMXU1" inst="1" prefix="">
<DOI name="Mod">
<DAI name="ctlModel">
<Val>status-only</Val>
</DAI>
</DOI>
</LN>
<LN lnClass="MMXU" lnType="MMXU2" inst="2" prefix="">
<DOI name="Mod">
<DAI name="ctlModel">
<Val>status-only</Val>
</DAI>
</DOI>
</LN>
</LDevice>
</Server>
</AccessPoint>
</IED>
<DataTypeTemplates>
<LNodeType id="LLN01" lnClass="LLN0">
<DO name="Mod" type="INC_1_Mod" />
<DO name="Beh" type="INS_1_Beh" />
<DO name="Health" type="INS_1_Beh" />
<DO name="NamPlt" type="LPL_1_NamPlt" />
</LNodeType>
<LNodeType id="LPHD1" lnClass="LPHD">
<DO name="PhyNam" type="DPL_1_PhyNam" />
<DO name="PhyHealth" type="INS_1_Beh" />
<DO name="Proxy" type="SPS_1_Proxy" />
</LNodeType>
<LNodeType id="MMXU2" lnClass="MMXU" desc="Measurement">
<DO name="Mod" type="INC_1_Mod" />
<DO name="Beh" type="INS_1_Beh" />
<DO name="Health" type="INS_1_Beh" />
<DO name="NamPlt" type="LPL_2_NamPlt" />
<DO name="TotW" type="MV_1_TotWh" />
</LNodeType>
<LNodeType id="DGEN1" lnClass="DGEN" desc="DER unit generator">
<DO name="Mod" type="ENC_1_Mod" />
<DO name="Beh" type="ENS_1_Beh" />
<DO name="Health" type="ENS_1_Beh" />
<DO name="NamPlt" type="LPL_2_NamPlt" />
<DO name="OpTmh" type="INS_1_Beh" />
<DO name="GnOpSt" type="ENS_1_Beh" />
<DO name="OpTmsRs" type="INS_1_Beh" />
<DO name="TotWh" type="MV_1_TotWh" />
</LNodeType>
<LNodeType id="DSCH1" lnClass="DSCH" desc="DER energy and/or ancillary services schedule">
<DO name="Mod" type="ENC_1_Mod" />
<DO name="Beh" type="ENS_1_Beh" />
<DO name="Health" type="ENS_1_Beh" />
<DO name="NamPlt" type="LPL_2_NamPlt" />
<DO name="SchdSt" type="INS_1_Beh" />
<DO name="SchdId" type="ING_1_SchdId" />
<DO name="SchdCat" type="ING_1_SchdId" />
<DO name="SchdTyp" type="ING_1_SchdId" />
<DO name="SchdAbsTm" type="SCA_1_SchdAbsTm" />
</LNodeType>
<LNodeType id="MMXU1" lnClass="MMXU" desc="Measurement">
<DO name="Mod" type="INC_1_Mod" />
<DO name="Beh" type="INS_1_Beh" />
<DO name="Health" type="INS_1_Beh" />
<DO name="NamPlt" type="LPL_2_NamPlt" />
</LNodeType>
<DOType id="INC_1_Mod" cdc="INC">
<DA name="q" bType="Quality" fc="ST" qchg="true" />
<DA name="t" bType="Timestamp" fc="ST" />
<DA name="ctlModel" type="CtlModels" bType="Enum" fc="CF" />
</DOType>
<DOType id="INS_1_Beh" cdc="INS">
<DA name="stVal" bType="INT32" fc="ST" dchg="true" />
<DA name="q" bType="Quality" fc="ST" qchg="true" />
<DA name="t" bType="Timestamp" fc="ST" />
</DOType>
<DOType id="LPL_1_NamPlt" cdc="LPL">
<DA name="vendor" bType="VisString255" fc="DC" />
<DA name="swRev" bType="VisString255" fc="DC" />
<DA name="d" bType="VisString255" fc="DC" />
<DA name="configRev" bType="VisString255" fc="DC" />
<DA name="ldNs" bType="VisString255" fc="EX" />
</DOType>
<DOType id="DPL_1_PhyNam" cdc="DPL">
<DA name="vendor" bType="VisString255" fc="DC" />
</DOType>
<DOType id="SPS_1_Proxy" cdc="SPS">
<DA name="stVal" bType="BOOLEAN" fc="ST" dchg="true" />
<DA name="q" bType="Quality" fc="ST" qchg="true" />
<DA name="t" bType="Timestamp" fc="ST" />
</DOType>
<DOType id="LPL_2_NamPlt" cdc="LPL">
<DA name="vendor" bType="VisString255" fc="DC" />
<DA name="swRev" bType="VisString255" fc="DC" />
<DA name="d" bType="VisString255" fc="DC" />
</DOType>
<DOType id="ENC_1_Mod" cdc="ENC">
<DA name="q" bType="Quality" fc="ST" qchg="true" />
<DA name="t" bType="Timestamp" fc="ST" />
<DA name="ctlModel" type="CtlModels" bType="Enum" fc="CF" />
</DOType>
<DOType id="ENS_1_Beh" cdc="ENS">
<DA name="stVal" bType="INT32" fc="ST" dchg="true" />
<DA name="q" bType="Quality" fc="ST" qchg="true" />
<DA name="t" bType="Timestamp" fc="ST" />
</DOType>
<DOType id="MV_1_TotWh" cdc="MV">
<DA name="mag" type="AnalogueValue_1" bType="Struct" fc="MX" dchg="true" />
<DA name="q" bType="Quality" fc="MX" qchg="true" />
<DA name="t" bType="Timestamp" fc="MX" />
</DOType>
<DOType id="SCA_1_SchdAbsTm" cdc="SCA">
<DA name="val" bType="FLOAT32" count="255" fc="SP" dchg="true" />
<DA name="time" bType="Timestamp" count="255" fc="SP" dchg="true" />
</DOType>
<DOType id="ING_1_SchdId" cdc="ING" />
<DAType id="AnalogueValue_1">
<BDA name="f" bType="FLOAT32" />
</DAType>
<EnumType id="CtlModels">
<EnumVal ord="0">status-only</EnumVal>
<EnumVal ord="1">direct-with-normal-security</EnumVal>
<EnumVal ord="2">sbo-with-normal-security</EnumVal>
<EnumVal ord="3">direct-with-enhanced-security</EnumVal>
<EnumVal ord="4">sbo-with-enhanced-security</EnumVal>
</EnumType>
</DataTypeTemplates>
</SCL>

View File

@ -0,0 +1,78 @@
/*
* server_example1.c
*
* Copyright 2013 Michael Zillgith
*
* This file is part of libIEC61850.
*
* libIEC61850 is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* libIEC61850 is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with libIEC61850. If not, see <http://www.gnu.org/licenses/>.
*
* See COPYING file for the complete license text.
*/
#include "iec61850_server.h"
#include "thread.h"
#include <signal.h>
#include <stdlib.h>
#include <stdio.h>
#include "static_model.h"
/* import IEC 61850 device model created from SCL-File */
extern IedModel iedModel;
static int running = 0;
void sigint_handler(int signalId)
{
running = 0;
}
int main(int argc, char** argv) {
int tcpPort = 102;
if (argc > 1) {
tcpPort = atoi(argv[1]);
}
IedServer iedServer = IedServer_create(&iedModel);
// get stored values from persistent storage
// set initial measurement and status values from process
/* MMS server will be instructed to start listening to client connections. */
IedServer_start(iedServer, tcpPort);
if (!IedServer_isRunning(iedServer)) {
printf("Starting server failed! Exit.\n");
IedServer_destroy(iedServer);
exit(-1);
}
running = 1;
signal(SIGINT, sigint_handler);
while (running) {
Thread_sleep(1);
}
/* stop MMS server - close TCP server socket and all client sockets */
IedServer_stop(iedServer);
/* Cleanup - free all resources */
IedServer_destroy(iedServer);
} /* main() */

File diff suppressed because it is too large Load Diff

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