Compare commits
No commits in common. "sv-goose-bugfixes" and "master" have entirely different histories.
sv-goose-b
...
master
34 changed files with 1516 additions and 4093 deletions
25
.travis.yml
25
.travis.yml
|
@ -1,25 +0,0 @@
|
|||
language: c
|
||||
|
||||
compiler:
|
||||
- clang
|
||||
- gcc
|
||||
|
||||
addons:
|
||||
apt:
|
||||
packages:
|
||||
- cmake
|
||||
- swig
|
||||
- libsqlite3-dev
|
||||
- python-dev
|
||||
|
||||
before_install:
|
||||
- if [ "$TRAVIS_OS_NAME" == "osx" ]; then
|
||||
brew update;
|
||||
brew install swig python sqlite;
|
||||
fi
|
||||
- mkdir -p build && cd build
|
||||
|
||||
script:
|
||||
- cmake .. -DBUILD_PYTHON_BINDINGS=ON
|
||||
- make
|
||||
- make test
|
|
@ -1,9 +1,3 @@
|
|||
Changes to version 1.2.0
|
||||
------------------------
|
||||
|
||||
- Added pkg-config file
|
||||
- The Sampled Values APIs have been renamed. The old version of the API is deprecated but still supported and will be removed in the next major version of the library.
|
||||
|
||||
Changes to version 1.1.0
|
||||
------------------------
|
||||
|
||||
|
|
139
CMakeLists.txt
139
CMakeLists.txt
|
@ -2,18 +2,17 @@ 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)
|
||||
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)
|
||||
ENABLE_TESTING()
|
||||
|
||||
set(LIB_VERSION_MAJOR "1")
|
||||
set(LIB_VERSION_MINOR "2")
|
||||
set(LIB_VERSION_MINOR "1")
|
||||
set(LIB_VERSION_PATCH "0")
|
||||
set(LIB_VERSION "${LIB_VERSION_MAJOR}.${LIB_VERSION_MINOR}.${LIB_VERSION_PATCH}")
|
||||
|
||||
set(CMAKE_MODULE_PATH ${CMAKE_MODULE_PATH} "${CMAKE_SOURCE_DIR}/third_party/cmake/modules/")
|
||||
|
||||
|
@ -33,68 +32,53 @@ option(BUILD_PYTHON_BINDINGS "Build Python bindings" OFF)
|
|||
|
||||
option(CONFIG_MMS_SINGLE_THREADED "Compile for single threaded version" ON)
|
||||
option(CONFIG_MMS_THREADLESS_STACK "Optimize stack for threadless operation (warning: single- or multi-threaded server will not work!)" OFF)
|
||||
option(CONFIG_ACTIVATE_TCP_KEEPALIVE "Activate TCP keepalive" ON)
|
||||
option(CONFIG_INCLUDE_GOOSE_SUPPORT "Build with GOOSE support" 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_IEC61850_LOG_SERVICE "Build with support for IEC 61850 logging services" ON)
|
||||
|
||||
option(CONFIG_IEC61850_SETTING_GROUPS "Build with support for IEC 61850 setting group 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_SOCKET "Enable printf debugging for socket layer" ${DEBUG})
|
||||
option(DEBUG_COTP "Enable COTP printf debugging" ${DEBUG})
|
||||
option(DEBUG_ISO_SERVER "Enable ISO SERVER printf debugging" ${DEBUG})
|
||||
option(DEBUG_ISO_CLIENT "Enable ISO CLIENT printf debugging" ${DEBUG})
|
||||
option(DEBUG_IED_SERVER "Enable IED SERVER printf debugging" ${DEBUG})
|
||||
option(DEBUG_IED_CLIENT "Enable IED CLIENT printf debugging" ${DEBUG})
|
||||
option(DEBUG_MMS_SERVER "Enable MMS SERVER printf debugging" ${DEBUG})
|
||||
option(DEBUG_MMS_CLIENT "Enable MMS CLIENT printf debugging" ${DEBUG})
|
||||
option(DEBUG_GOOSE_SUBSCRIBER "Enable GOOSE subscriber printf debugging" ${DEBUG})
|
||||
option(DEBUG_GOOSE_PUBLISHER "Enable GOOSE publisher printf debugging" ${DEBUG})
|
||||
option(DEBUG_SV_SUBSCRIBER "Enable Sampled Values subscriber debugging" ${DEBUG})
|
||||
option(DEBUG_SV_PUBLISHER "Enable Sampled Values publisher debugging" ${DEBUG})
|
||||
option(DEBUG_HAL_ETHERNET "Enable Ethernet HAL printf debugging" ${DEBUG})
|
||||
|
||||
#mark_as_advanced(
|
||||
# DEBUG_SOCKET
|
||||
# DEBUG_COTP
|
||||
# DEBUG_ISO_SERVER
|
||||
# DEBUG_ISO_CLIENT
|
||||
# DEBUG_IED_SERVER
|
||||
# DEBUG_IED_CLIENT
|
||||
# DEBUG_MMS_SERVER
|
||||
# DEBUG_MMS_CLIENT
|
||||
# DEBUG_GOOSE_SUBSCRIBER
|
||||
# DEBUG_GOOSE_PUBLISHER
|
||||
# DEBUG_SV_SUBSCRIBER
|
||||
# DEBUG_SV_PUBLISHER
|
||||
# DEBUG_HAL_ETHERNET
|
||||
#)
|
||||
option(DEBUG_SOCKET "Enable printf debugging for socket layer" 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/inc
|
||||
src/goose
|
||||
src/sampled_values
|
||||
src/hal/inc
|
||||
src/iec61850/inc
|
||||
src/iec61850/inc_private
|
||||
src/mms/inc
|
||||
src/mms/inc_private
|
||||
src/mms/iso_mms/asn1c
|
||||
src/logging
|
||||
${CMAKE_CURRENT_LIST_DIR}/src/common/inc
|
||||
${CMAKE_CURRENT_LIST_DIR}/src/goose
|
||||
${CMAKE_CURRENT_LIST_DIR}/src/sampled_values
|
||||
${CMAKE_CURRENT_LIST_DIR}/src/hal/inc
|
||||
${CMAKE_CURRENT_LIST_DIR}/src/iec61850/inc
|
||||
${CMAKE_CURRENT_LIST_DIR}/src/iec61850/inc_private
|
||||
${CMAKE_CURRENT_LIST_DIR}/src/mms/inc
|
||||
${CMAKE_CURRENT_LIST_DIR}/src/mms/inc_private
|
||||
${CMAKE_CURRENT_LIST_DIR}/src/mms/iso_mms/asn1c
|
||||
${CMAKE_CURRENT_LIST_DIR}/src/logging
|
||||
)
|
||||
|
||||
set(API_HEADERS
|
||||
src/hal/inc/hal_time.h
|
||||
src/hal/inc/hal_thread.h
|
||||
src/hal/inc/hal_filesystem.h
|
||||
src/hal/inc/hal_ethernet.h
|
||||
src/hal/inc/platform_endian.h
|
||||
src/common/inc/libiec61850_common_api.h
|
||||
src/common/inc/libiec61850_platform_includes.h
|
||||
|
@ -126,51 +110,46 @@ set(API_HEADERS
|
|||
src/goose/goose_publisher.h
|
||||
src/sampled_values/sv_subscriber.h
|
||||
src/sampled_values/sv_publisher.h
|
||||
src/sampled_values/sv_publisher_deprecated.h
|
||||
src/sampled_values/sv_subscriber_deprecated.h
|
||||
src/logging/logging_api.h
|
||||
${CMAKE_CURRENT_BINARY_DIR}/config/stack_config.h
|
||||
)
|
||||
|
||||
if(MSVC)
|
||||
include_directories(
|
||||
src/vs
|
||||
)
|
||||
endif(MSVC)
|
||||
IF(MSVC)
|
||||
include_directories(
|
||||
src/vs
|
||||
)
|
||||
ENDIF(MSVC)
|
||||
|
||||
# write the detected stuff to this file
|
||||
configure_file(
|
||||
${CMAKE_CURRENT_LIST_DIR}/config/stack_config.h.cmake
|
||||
${CMAKE_CURRENT_BINARY_DIR}/config/stack_config.h
|
||||
)
|
||||
configure_file(${CMAKE_CURRENT_LIST_DIR}/config/stack_config.h.cmake ${CMAKE_CURRENT_BINARY_DIR}/config/stack_config.h)
|
||||
|
||||
if(BUILD_EXAMPLES)
|
||||
add_subdirectory(examples)
|
||||
add_subdirectory(examples)
|
||||
endif(BUILD_EXAMPLES)
|
||||
|
||||
add_subdirectory(${CMAKE_CURRENT_LIST_DIR}/src)
|
||||
|
||||
install(FILES ${API_HEADERS} DESTINATION include/libiec61850 COMPONENT Development)
|
||||
INSTALL(FILES ${API_HEADERS} DESTINATION include/libiec61850 COMPONENT Development)
|
||||
|
||||
if(BUILD_PYTHON_BINDINGS)
|
||||
add_subdirectory(${CMAKE_CURRENT_LIST_DIR}/pyiec61850)
|
||||
endif(BUILD_PYTHON_BINDINGS)
|
||||
IF(BUILD_PYTHON_BINDINGS)
|
||||
add_subdirectory(${CMAKE_CURRENT_LIST_DIR}/pyiec61850)
|
||||
ENDIF(BUILD_PYTHON_BINDINGS)
|
||||
|
||||
set(CPACK_PACKAGE_DESCRIPTION "IEC 61850 MMS/GOOSE client and server library")
|
||||
set(CPACK_PACKAGE_DESCRIPTION_SUMMARY "IEC 61850 MMS/GOOSE client and server library")
|
||||
set(CPACK_PACKAGE_VENDOR "MZ Automation GmbH")
|
||||
set(CPACK_PACKAGE_CONTACT "info@libiec61850.com")
|
||||
set(CPACK_PACKAGE_VERSION_MAJOR "${LIB_VERSION_MAJOR}")
|
||||
set(CPACK_PACKAGE_VERSION_MINOR "${LIB_VERSION_MINOR}")
|
||||
set(CPACK_PACKAGE_VERSION_PATCH "${LIB_VERSION_PATCH}")
|
||||
set(CPACK_PACKAGE_FILE_NAME "${CMAKE_PROJECT_NAME}_${LIB_VERSION_MAJOR}.${LIB_VERSION_MINOR}.${CPACK_PACKAGE_VERSION_PATCH}_${CMAKE_SYSTEM_PROCESSOR}")
|
||||
set(CPACK_SOURCE_PACKAGE_FILE_NAME "${CMAKE_PROJECT_NAME}_${LIB_VERSION_MAJOR}.${LIB_VERSION_MINOR}.${CPACK_PACKAGE_VERSION_PATCH}")
|
||||
|
||||
set(CPACK_COMPONENTS_ALL Libraries Development Applications)
|
||||
IF(EXISTS "${CMAKE_ROOT}/Modules/CPack.cmake")
|
||||
INCLUDE(InstallRequiredSystemLibraries)
|
||||
|
||||
SET(CPACK_PACKAGE_DESCRIPTION "IEC 61850 MMS/GOOSE client and server library")
|
||||
SET(CPACK_PACKAGE_DESCRIPTION_SUMMARY "IEC 61850 MMS/GOOSE client and server library")
|
||||
SET(CPACK_PACKAGE_VENDOR "MZ Automation GmbH")
|
||||
SET(CPACK_PACKAGE_CONTACT "info@libiec61850.com")
|
||||
SET(CPACK_PACKAGE_VERSION_MAJOR "${LIB_VERSION_MAJOR}")
|
||||
SET(CPACK_PACKAGE_VERSION_MINOR "${LIB_VERSION_MINOR}")
|
||||
SET(CPACK_PACKAGE_VERSION_PATCH "${LIB_VERSION_PATCH}")
|
||||
SET(CPACK_PACKAGE_FILE_NAME "${CMAKE_PROJECT_NAME}_${LIB_VERSION_MAJOR}.${LIB_VERSION_MINOR}.${CPACK_PACKAGE_VERSION_PATCH}_${CMAKE_SYSTEM_PROCESSOR}")
|
||||
SET(CPACK_SOURCE_PACKAGE_FILE_NAME "${CMAKE_PROJECT_NAME}_${LIB_VERSION_MAJOR}.${LIB_VERSION_MINOR}.${CPACK_PACKAGE_VERSION_PATCH}")
|
||||
|
||||
SET(CPACK_COMPONENTS_ALL Libraries Development Applications)
|
||||
#set(CPACK_PACKAGE_INSTALL_DIRECTORY "${CMAKE_PROJECT_NAME}")
|
||||
|
||||
if(EXISTS "${CMAKE_ROOT}/Modules/CPack.cmake")
|
||||
include(InstallRequiredSystemLibraries)
|
||||
|
||||
include(CPack)
|
||||
endif(EXISTS "${CMAKE_ROOT}/Modules/CPack.cmake")
|
||||
INCLUDE(CPack)
|
||||
|
||||
ENDIF(EXISTS "${CMAKE_ROOT}/Modules/CPack.cmake")
|
||||
|
|
14
README.md
14
README.md
|
@ -1,7 +1,5 @@
|
|||
# README libIEC61850
|
||||
|
||||
[](https://travis-ci.org/mz-automation/libiec61850)
|
||||
|
||||
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. Also consider to review the examples to understand how to use the library
|
||||
|
||||
Content:
|
||||
|
@ -75,17 +73,15 @@ To build the library and run libiec61850 applications with GOOSE support on Wind
|
|||
|
||||
## Building with the cmake build script
|
||||
|
||||
With the help of the cmake build script it is possible to create platform independent project descriptions and let cmake create specific project or build files for other tools like Make or Visual Studio.
|
||||
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 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 2015).
|
||||
If you have cmake installed fire up a command line (cmd.exe) and create a new subdirectory in the libiec61850 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 14 2015" ..`
|
||||
`cmake -G "Visual Studio 11" ..`
|
||||
|
||||
will instruct cmake to create a "solution" for Visual Studio 2015. The resulting project files will be 32 bit.
|
||||
will instruct cmake to create a "solution" for Visual Studio 2012. To do the same thing for Visual Studio 2010 type
|
||||
|
||||
To build 64 bit libraries the "Win64" generator option has to be added.
|
||||
|
||||
`cmake -G "Visual Studio 14 2015 Win64" ..`
|
||||
`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 which is in our case the parent directory (..).
|
||||
|
||||
|
|
|
@ -29,9 +29,9 @@
|
|||
#cmakedefine01 DEBUG_MMS_SERVER
|
||||
#cmakedefine01 DEBUG_GOOSE_SUBSCRIBER
|
||||
#cmakedefine01 DEBUG_GOOSE_PUBLISHER
|
||||
#cmakedefine01 DEBUG_SV_SUBSCRIBER
|
||||
#cmakedefine01 DEBUG_SV_PUBLISHER
|
||||
#cmakedefine01 DEBUG_HAL_ETHERNET
|
||||
#cmakedefine01 DEBUG_SV_SUBSCRIBER 0
|
||||
#cmakedefine01 DEBUG_SV_PUBLISHER 0
|
||||
#cmakedefine01 DEBUG_HAL_ETHERNET 0
|
||||
|
||||
/* 1 ==> server runs in single threaded mode (one dedicated thread for the server)
|
||||
* 0 ==> server runs in multi threaded mode (one thread for each connection and
|
||||
|
|
|
@ -11,34 +11,35 @@ add_subdirectory(server_example_61400_25)
|
|||
add_subdirectory(server_example_setting_groups)
|
||||
add_subdirectory(server_example_logging)
|
||||
add_subdirectory(server_example_files)
|
||||
|
||||
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)
|
||||
IF(WIN32)
|
||||
else()
|
||||
add_subdirectory(iec61850_client_example_files)
|
||||
endif()
|
||||
add_subdirectory(iec61850_client_example_reporting)
|
||||
add_subdirectory(iec61850_client_example_log)
|
||||
|
||||
if(NOT WIN32)
|
||||
add_subdirectory(iec61850_client_example_files)
|
||||
IF(WIN32)
|
||||
if(EXISTS "${CMAKE_CURRENT_SOURCE_DIR}/../third_party/winpcap/Lib/wpcap.lib")
|
||||
message("Found winpcap -> compile examples for GOOSE and SV")
|
||||
add_subdirectory(server_example_goose)
|
||||
add_subdirectory(goose_subscriber)
|
||||
add_subdirectory(goose_publisher)
|
||||
add_subdirectory(sv_subscriber)
|
||||
add_subdirectory(iec61850_9_2_LE_example)
|
||||
add_subdirectory(iec61850_sv_client_example)
|
||||
add_subdirectory(sv_publisher)
|
||||
endif()
|
||||
|
||||
if(WIN32)
|
||||
if (EXISTS "${CMAKE_CURRENT_SOURCE_DIR}/../third_party/winpcap/Lib/wpcap.lib")
|
||||
set(BUILD_SV_GOOSE_EXAMPLES ON)
|
||||
message("Found winpcap -> compile examples for GOOSE and SV")
|
||||
endif()
|
||||
else()
|
||||
set(BUILD_SV_GOOSE_EXAMPLES ON)
|
||||
endif()
|
||||
|
||||
if(${BUILD_SV_GOOSE_EXAMPLES})
|
||||
add_subdirectory(server_example_goose)
|
||||
add_subdirectory(goose_subscriber)
|
||||
add_subdirectory(goose_publisher)
|
||||
add_subdirectory(sv_subscriber)
|
||||
add_subdirectory(iec61850_9_2_LE_example)
|
||||
add_subdirectory(iec61850_sv_client_example)
|
||||
add_subdirectory(sv_publisher)
|
||||
add_subdirectory(server_example_goose)
|
||||
add_subdirectory(goose_subscriber)
|
||||
add_subdirectory(goose_publisher)
|
||||
add_subdirectory(sv_subscriber)
|
||||
add_subdirectory(iec61850_9_2_LE_example)
|
||||
add_subdirectory(iec61850_sv_client_example)
|
||||
add_subdirectory(sv_publisher)
|
||||
endif()
|
||||
|
|
|
@ -7,7 +7,6 @@
|
|||
*/
|
||||
|
||||
#include "goose_receiver.h"
|
||||
#include "goose_subscriber.h"
|
||||
#include "hal_thread.h"
|
||||
|
||||
#include <stdlib.h>
|
||||
|
|
|
@ -53,27 +53,27 @@ static int vol2;
|
|||
static int vol3;
|
||||
static int vol4;
|
||||
|
||||
static SVPublisher svPublisher;
|
||||
static SVPublisher_ASDU asdu;
|
||||
static SampledValuesPublisher svPublisher;
|
||||
static SV_ASDU asdu;
|
||||
|
||||
static void
|
||||
setupSVPublisher(const char* svInterface)
|
||||
{
|
||||
svPublisher = SVPublisher_create(NULL, svInterface);
|
||||
svPublisher = SampledValuesPublisher_create(NULL, svInterface);
|
||||
|
||||
asdu = SVPublisher_addASDU(svPublisher, "xxxxMUnn01", NULL, 1);
|
||||
asdu = SampledValuesPublisher_addASDU(svPublisher, "xxxxMUnn01", NULL, 1);
|
||||
|
||||
amp1 = SVPublisher_ASDU_addINT32(asdu);
|
||||
amp2 = SVPublisher_ASDU_addINT32(asdu);
|
||||
amp3 = SVPublisher_ASDU_addINT32(asdu);
|
||||
amp4 = SVPublisher_ASDU_addINT32(asdu);
|
||||
amp1 = SV_ASDU_addINT32(asdu);
|
||||
amp2 = SV_ASDU_addINT32(asdu);
|
||||
amp3 = SV_ASDU_addINT32(asdu);
|
||||
amp4 = SV_ASDU_addINT32(asdu);
|
||||
|
||||
vol1 = SVPublisher_ASDU_addINT32(asdu);
|
||||
vol2 = SVPublisher_ASDU_addINT32(asdu);
|
||||
vol3 = SVPublisher_ASDU_addINT32(asdu);
|
||||
vol4 = SVPublisher_ASDU_addINT32(asdu);
|
||||
vol1 = SV_ASDU_addINT32(asdu);
|
||||
vol2 = SV_ASDU_addINT32(asdu);
|
||||
vol3 = SV_ASDU_addINT32(asdu);
|
||||
vol4 = SV_ASDU_addINT32(asdu);
|
||||
|
||||
SVPublisher_setupComplete(svPublisher);
|
||||
SampledValuesPublisher_setupComplete(svPublisher);
|
||||
}
|
||||
|
||||
static void sVCBEventHandler (SVControlBlock* svcb, int event, void* parameter)
|
||||
|
@ -143,19 +143,19 @@ main(int argc, char** argv)
|
|||
|
||||
if (svcbEnabled) {
|
||||
|
||||
SVPublisher_ASDU_setINT32(asdu, amp1, current);
|
||||
SVPublisher_ASDU_setINT32(asdu, amp2, current);
|
||||
SVPublisher_ASDU_setINT32(asdu, amp3, current);
|
||||
SVPublisher_ASDU_setINT32(asdu, amp4, current);
|
||||
SV_ASDU_setINT32(asdu, amp1, current);
|
||||
SV_ASDU_setINT32(asdu, amp2, current);
|
||||
SV_ASDU_setINT32(asdu, amp3, current);
|
||||
SV_ASDU_setINT32(asdu, amp4, current);
|
||||
|
||||
SVPublisher_ASDU_setINT32(asdu, vol1, voltage);
|
||||
SVPublisher_ASDU_setINT32(asdu, vol2, voltage);
|
||||
SVPublisher_ASDU_setINT32(asdu, vol3, voltage);
|
||||
SVPublisher_ASDU_setINT32(asdu, vol4, voltage);
|
||||
SV_ASDU_setINT32(asdu, vol1, voltage);
|
||||
SV_ASDU_setINT32(asdu, vol2, voltage);
|
||||
SV_ASDU_setINT32(asdu, vol3, voltage);
|
||||
SV_ASDU_setINT32(asdu, vol4, voltage);
|
||||
|
||||
SVPublisher_ASDU_increaseSmpCnt(asdu);
|
||||
SV_ASDU_increaseSmpCnt(asdu);
|
||||
|
||||
SVPublisher_publish(svPublisher);
|
||||
SampledValuesPublisher_publish(svPublisher);
|
||||
}
|
||||
|
||||
voltage++;
|
||||
|
@ -168,7 +168,7 @@ main(int argc, char** argv)
|
|||
IedServer_stop(iedServer);
|
||||
|
||||
/* Cleanup - free all resources */
|
||||
SVPublisher_destroy(svPublisher);
|
||||
SampledValuesPublisher_destroy(svPublisher);
|
||||
IedServer_destroy(iedServer);
|
||||
|
||||
return 0;
|
||||
|
|
|
@ -248,8 +248,6 @@ main(int argc, char** argv)
|
|||
case FileOperationType_Set:
|
||||
setFile(con);
|
||||
break;
|
||||
case FileOperationType_None:
|
||||
break;
|
||||
}
|
||||
|
||||
|
||||
|
|
|
@ -81,7 +81,7 @@ printJournalEntries(LinkedList journalEntries)
|
|||
}
|
||||
}
|
||||
|
||||
void
|
||||
void*
|
||||
printRawMmsMessage(void* parameter, uint8_t* message, int messageLength, bool received)
|
||||
{
|
||||
if (received)
|
||||
|
|
|
@ -29,19 +29,19 @@ main(int argc, char** argv)
|
|||
|
||||
printf("Using interface %s\n", interface);
|
||||
|
||||
SVPublisher svPublisher = SVPublisher_create(NULL, interface);
|
||||
SampledValuesPublisher svPublisher = SampledValuesPublisher_create(NULL, interface);
|
||||
|
||||
SVPublisher_ASDU asdu1 = SVPublisher_addASDU(svPublisher, "svpub1", NULL, 1);
|
||||
SV_ASDU asdu1 = SampledValuesPublisher_addASDU(svPublisher, "svpub1", NULL, 1);
|
||||
|
||||
int float1 = SVPublisher_ASDU_addFLOAT(asdu1);
|
||||
int float2 = SVPublisher_ASDU_addFLOAT(asdu1);
|
||||
int float1 = SV_ASDU_addFLOAT(asdu1);
|
||||
int float2 = SV_ASDU_addFLOAT(asdu1);
|
||||
|
||||
SVPublisher_ASDU asdu2 = SVPublisher_addASDU(svPublisher, "svpub2", NULL, 1);
|
||||
SV_ASDU asdu2 = SampledValuesPublisher_addASDU(svPublisher, "svpub2", NULL, 1);
|
||||
|
||||
int float3 = SVPublisher_ASDU_addFLOAT(asdu2);
|
||||
int float4 = SVPublisher_ASDU_addFLOAT(asdu2);
|
||||
int float3 = SV_ASDU_addFLOAT(asdu2);
|
||||
int float4 = SV_ASDU_addFLOAT(asdu2);
|
||||
|
||||
SVPublisher_setupComplete(svPublisher);
|
||||
SampledValuesPublisher_setupComplete(svPublisher);
|
||||
|
||||
float fVal1 = 1234.5678f;
|
||||
float fVal2 = 0.12345f;
|
||||
|
@ -49,19 +49,19 @@ main(int argc, char** argv)
|
|||
int i;
|
||||
|
||||
while (running) {
|
||||
SVPublisher_ASDU_setFLOAT(asdu1, float1, fVal1);
|
||||
SVPublisher_ASDU_setFLOAT(asdu1, float2, fVal2);
|
||||
SV_ASDU_setFLOAT(asdu1, float1, fVal1);
|
||||
SV_ASDU_setFLOAT(asdu1, float2, fVal2);
|
||||
|
||||
SVPublisher_ASDU_increaseSmpCnt(asdu1);
|
||||
SVPublisher_ASDU_increaseSmpCnt(asdu2);
|
||||
SV_ASDU_increaseSmpCnt(asdu1);
|
||||
SV_ASDU_increaseSmpCnt(asdu2);
|
||||
|
||||
fVal1 += 1.1f;
|
||||
fVal2 += 0.1f;
|
||||
|
||||
SVPublisher_publish(svPublisher);
|
||||
SampledValuesPublisher_publish(svPublisher);
|
||||
|
||||
Thread_sleep(50);
|
||||
}
|
||||
|
||||
SVPublisher_destroy(svPublisher);
|
||||
SampledValuesPublisher_destroy(svPublisher);
|
||||
}
|
||||
|
|
|
@ -21,17 +21,17 @@ void sigint_handler(int signalId)
|
|||
|
||||
/* Callback handler for received SV messages */
|
||||
static void
|
||||
svUpdateListener (SVSubscriber subscriber, void* parameter, SVSubscriber_ASDU asdu)
|
||||
svUpdateListener (SVSubscriber subscriber, void* parameter, SVClientASDU asdu)
|
||||
{
|
||||
printf("svUpdateListener called\n");
|
||||
|
||||
const char* svID = SVSubscriber_ASDU_getSvId(asdu);
|
||||
const char* svID = SVClientASDU_getSvId(asdu);
|
||||
|
||||
if (svID != NULL)
|
||||
printf(" svID=(%s)\n", svID);
|
||||
|
||||
printf(" smpCnt: %i\n", SVSubscriber_ASDU_getSmpCnt(asdu));
|
||||
printf(" confRev: %u\n", SVSubscriber_ASDU_getConfRev(asdu));
|
||||
printf(" smpCnt: %i\n", SVClientASDU_getSmpCnt(asdu));
|
||||
printf(" confRev: %u\n", SVClientASDU_getConfRev(asdu));
|
||||
|
||||
/*
|
||||
* Access to the data requires a priori knowledge of the data set.
|
||||
|
@ -43,9 +43,9 @@ svUpdateListener (SVSubscriber subscriber, void* parameter, SVSubscriber_ASDU as
|
|||
* To prevent damages due configuration, please check the length of the
|
||||
* data block of the SV message before accessing the data.
|
||||
*/
|
||||
if (SVSubscriber_ASDU_getDataSize(asdu) >= 8) {
|
||||
printf(" DATA[0]: %f\n", SVSubscriber_ASDU_getFLOAT32(asdu, 0));
|
||||
printf(" DATA[1]: %f\n", SVSubscriber_ASDU_getFLOAT32(asdu, 4));
|
||||
if (SVClientASDU_getDataSize(asdu) >= 8) {
|
||||
printf(" DATA[0]: %f\n", SVClientASDU_getFLOAT32(asdu, 0));
|
||||
printf(" DATA[1]: %f\n", SVClientASDU_getFLOAT32(asdu, 4));
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -1,40 +1,23 @@
|
|||
find_package(SWIG REQUIRED)
|
||||
include(${SWIG_USE_FILE})
|
||||
|
||||
find_package(PythonLibs REQUIRED)
|
||||
find_package(PythonInterp ${PYTHONLIBS_VERSION_STRING} EXACT REQUIRED)
|
||||
|
||||
include_directories(${PYTHON_INCLUDE_PATH})
|
||||
include_directories(${CMAKE_CURRENT_SOURCE_DIR})
|
||||
|
||||
set(CMAKE_SWIG_FLAGS "")
|
||||
set_property(SOURCE iec61850.i PROPERTY CPLUSPLUS ON)
|
||||
|
||||
if(WIN32)
|
||||
set(LIBS iec61850 ws2_32)
|
||||
else()
|
||||
set(LIBS iec61850-shared)
|
||||
endif()
|
||||
|
||||
if(${SWIG_VERSION} VERSION_LESS 3.0)
|
||||
swig_add_module(iec61850 python iec61850.i)
|
||||
else()
|
||||
swig_add_library(iec61850
|
||||
LANGUAGE python
|
||||
SOURCES iec61850.i
|
||||
)
|
||||
endif()
|
||||
|
||||
swig_link_libraries(iec61850 ${PYTHON_LIBRARIES} ${LIBS})
|
||||
|
||||
# Finding python modules install path
|
||||
execute_process(
|
||||
COMMAND ${PYTHON_EXECUTABLE} -c
|
||||
"import site, sys; sys.stdout.write(site.getsitepackages()[-1])"
|
||||
OUTPUT_VARIABLE PYTHON_SITE_DIR
|
||||
)
|
||||
|
||||
install(FILES ${CMAKE_CURRENT_BINARY_DIR}/iec61850.py DESTINATION ${PYTHON_SITE_DIR})
|
||||
install(TARGETS _iec61850 LIBRARY DESTINATION ${PYTHON_SITE_DIR})
|
||||
FIND_PACKAGE(SWIG REQUIRED)
|
||||
INCLUDE(${SWIG_USE_FILE})
|
||||
FIND_PACKAGE(PythonLibs REQUIRED)
|
||||
FIND_PACKAGE ( PythonInterp ${PYTHONLIBS_VERSION_STRING} EXACT REQUIRED )
|
||||
INCLUDE_DIRECTORIES(${PYTHON_INCLUDE_PATH})
|
||||
INCLUDE_DIRECTORIES(${CMAKE_CURRENT_SOURCE_DIR})
|
||||
SET(CMAKE_SWIG_FLAGS "")
|
||||
SET_PROPERTY(SOURCE iec61850.i PROPERTY CPLUSPLUS ON)
|
||||
SWIG_ADD_MODULE(iec61850 python iec61850.i)
|
||||
IF(WIN32)
|
||||
SWIG_LINK_LIBRARIES(iec61850 ${PYTHON_LIBRARIES} iec61850 ws2_32)
|
||||
ELSE()
|
||||
SWIG_LINK_LIBRARIES(iec61850 ${PYTHON_LIBRARIES} iec61850-shared)
|
||||
ENDIF(WIN32)
|
||||
EXECUTE_PROCESS ( #Finding python modules install path
|
||||
COMMAND ${PYTHON_EXECUTABLE} -c
|
||||
"import site, sys; sys.stdout.write(site.getsitepackages()[-1])"
|
||||
OUTPUT_VARIABLE PYTHON_SITE_DIR
|
||||
)
|
||||
INSTALL ( FILES ${CMAKE_CURRENT_BINARY_DIR}/iec61850.py DESTINATION ${PYTHON_SITE_DIR})
|
||||
INSTALL ( TARGETS _iec61850 LIBRARY DESTINATION ${PYTHON_SITE_DIR})
|
||||
|
||||
add_test(test_pyiec61850 ${PYTHON_EXECUTABLE} ${CMAKE_CURRENT_LIST_DIR}/test_pyiec61850.py)
|
||||
|
|
|
@ -367,22 +367,10 @@ if(MSVC)
|
|||
endif()
|
||||
ENDIF(WITH_WPCAP)
|
||||
|
||||
if(UNIX)
|
||||
configure_file(
|
||||
${CMAKE_CURRENT_LIST_DIR}/libiec61850.pc.in
|
||||
${CMAKE_CURRENT_BINARY_DIR}/libiec61850.pc @ONLY
|
||||
)
|
||||
install(FILES "${CMAKE_CURRENT_BINARY_DIR}/libiec61850.pc" DESTINATION "${CMAKE_INSTALL_PREFIX}/share/pkgconfig")
|
||||
endif()
|
||||
|
||||
find_package(Doxygen)
|
||||
if(DOXYGEN_FOUND)
|
||||
configure_file(Doxyfile.in ${CMAKE_CURRENT_BINARY_DIR}/Doxyfile @ONLY)
|
||||
add_custom_target(doc ${DOXYGEN_EXECUTABLE} ${CMAKE_CURRENT_BINARY_DIR}/Doxyfile WORKING_DIRECTORY ${CMAKE_CURRENT_SOURCE_DIR} COMMENT "Generating API documentation with Doxygen" VERBATIM)
|
||||
endif(DOXYGEN_FOUND)
|
||||
|
||||
install (TARGETS iec61850 iec61850-shared
|
||||
RUNTIME DESTINATION bin COMPONENT Applications
|
||||
ARCHIVE DESTINATION lib COMPONENT Libraries
|
||||
LIBRARY DESTINATION lib COMPONENT Libraries
|
||||
)
|
||||
|
||||
|
|
2450
src/Doxyfile.in
2450
src/Doxyfile.in
File diff suppressed because it is too large
Load diff
1154
src/doxygen.config
Normal file
1154
src/doxygen.config
Normal file
File diff suppressed because it is too large
Load diff
|
@ -129,10 +129,6 @@ parseAllData(uint8_t* buffer, int allDataLength, MmsValue* dataSetValues)
|
|||
MmsValue* value = MmsValue_getElement(dataSetValues, elementIndex);
|
||||
|
||||
bufPos = BerDecoder_decodeLength(buffer, &elementLength, bufPos, allDataLength);
|
||||
if (bufPos < 0) {
|
||||
if (DEBUG_GOOSE_SUBSCRIBER) printf("GOOSE_SUBSCRIBER: Malformed message: failed to decode BER length tag!\n");
|
||||
return 0;
|
||||
}
|
||||
|
||||
if (bufPos + elementLength > allDataLength) {
|
||||
if (DEBUG_GOOSE_SUBSCRIBER) printf("GOOSE_SUBSCRIBER: Malformed message: sub element is too large!\n");
|
||||
|
@ -281,10 +277,6 @@ parseAllDataUnknownValue(GooseSubscriber self, uint8_t* buffer, int allDataLengt
|
|||
uint8_t tag = buffer[bufPos++];
|
||||
|
||||
bufPos = BerDecoder_decodeLength(buffer, &elementLength, bufPos, allDataLength);
|
||||
if (bufPos < 0) {
|
||||
if (DEBUG_GOOSE_SUBSCRIBER) printf("GOOSE_SUBSCRIBER: Malformed message: failed to decode BER length tag!\n");
|
||||
return 0;
|
||||
}
|
||||
|
||||
if (bufPos + elementLength > allDataLength) {
|
||||
if (DEBUG_GOOSE_SUBSCRIBER) printf("GOOSE_SUBSCRIBER: Malformed message: sub element is too large!\n");
|
||||
|
@ -339,10 +331,6 @@ parseAllDataUnknownValue(GooseSubscriber self, uint8_t* buffer, int allDataLengt
|
|||
uint8_t tag = buffer[bufPos++];
|
||||
|
||||
bufPos = BerDecoder_decodeLength(buffer, &elementLength, bufPos, allDataLength);
|
||||
if (bufPos < 0) {
|
||||
if (DEBUG_GOOSE_SUBSCRIBER) printf("GOOSE_SUBSCRIBER: Malformed message: failed to decode BER length tag!\n");
|
||||
return 0;
|
||||
}
|
||||
|
||||
if (bufPos + elementLength > allDataLength) {
|
||||
if (DEBUG_GOOSE_SUBSCRIBER) printf("GOOSE_SUBSCRIBER: Malformed message: sub element is too large!\n");
|
||||
|
@ -473,10 +461,6 @@ parseGoosePayload(GooseReceiver self, uint8_t* buffer, int apduLength)
|
|||
if (buffer[bufPos++] == 0x61) {
|
||||
int gooseLength;
|
||||
bufPos = BerDecoder_decodeLength(buffer, &gooseLength, bufPos, apduLength);
|
||||
if (bufPos < 0) {
|
||||
if (DEBUG_GOOSE_SUBSCRIBER) printf("GOOSE_SUBSCRIBER: Malformed message: failed to decode BER length tag!\n");
|
||||
return 0;
|
||||
}
|
||||
|
||||
int gooseEnd = bufPos + gooseLength;
|
||||
|
||||
|
@ -485,10 +469,6 @@ parseGoosePayload(GooseReceiver self, uint8_t* buffer, int apduLength)
|
|||
|
||||
uint8_t tag = buffer[bufPos++];
|
||||
bufPos = BerDecoder_decodeLength(buffer, &elementLength, bufPos, apduLength);
|
||||
if (bufPos < 0) {
|
||||
if (DEBUG_GOOSE_SUBSCRIBER) printf("GOOSE_SUBSCRIBER: Malformed message: failed to decode BER length tag!\n");
|
||||
return 0;
|
||||
}
|
||||
|
||||
if (bufPos + elementLength > apduLength) {
|
||||
if (DEBUG_GOOSE_SUBSCRIBER)
|
||||
|
@ -794,7 +774,7 @@ GooseReceiver_destroy(GooseReceiver self)
|
|||
/***************************************
|
||||
* Functions for non-threaded operation
|
||||
***************************************/
|
||||
EthernetSocket
|
||||
void
|
||||
GooseReceiver_startThreadless(GooseReceiver self)
|
||||
{
|
||||
if (self->interfaceId == NULL)
|
||||
|
@ -808,8 +788,6 @@ GooseReceiver_startThreadless(GooseReceiver self)
|
|||
}
|
||||
else
|
||||
self->running = false;
|
||||
|
||||
return self->ethSocket;
|
||||
}
|
||||
|
||||
void
|
||||
|
|
|
@ -24,20 +24,18 @@
|
|||
#ifndef GOOSE_RECEIVER_H_
|
||||
#define GOOSE_RECEIVER_H_
|
||||
|
||||
#include <goose_subscriber.h>
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
#include <stdbool.h>
|
||||
|
||||
typedef struct sEthernetSocket* EthernetSocket;
|
||||
|
||||
/**
|
||||
* \addtogroup goose_api_group
|
||||
*/
|
||||
/**@{*/
|
||||
|
||||
typedef struct sGooseSubscriber* GooseSubscriber;
|
||||
|
||||
typedef struct sGooseReceiver* GooseReceiver;
|
||||
|
||||
|
@ -117,7 +115,7 @@ GooseReceiver_destroy(GooseReceiver self);
|
|||
/***************************************
|
||||
* Functions for non-threaded operation
|
||||
***************************************/
|
||||
EthernetSocket
|
||||
void
|
||||
GooseReceiver_startThreadless(GooseReceiver self);
|
||||
|
||||
void
|
||||
|
|
|
@ -22,7 +22,6 @@
|
|||
*/
|
||||
#include <sys/socket.h>
|
||||
#include <sys/ioctl.h>
|
||||
#include <sys/poll.h>
|
||||
#include <arpa/inet.h>
|
||||
#include <unistd.h>
|
||||
#include <net/if.h>
|
||||
|
@ -47,82 +46,12 @@ struct sEthernetSocket {
|
|||
struct bpf_program bpfProgram; // BPF filter machine code program.
|
||||
};
|
||||
|
||||
struct sEthernetHandleSet {
|
||||
struct pollfd *handles;
|
||||
int nhandles;
|
||||
};
|
||||
|
||||
EthernetHandleSet
|
||||
EthernetHandleSet_new(void)
|
||||
{
|
||||
EthernetHandleSet result = (EthernetHandleSet) GLOBAL_MALLOC(sizeof(struct sEthernetHandleSet));
|
||||
|
||||
if (result != NULL) {
|
||||
result->handles = NULL;
|
||||
result->nhandles = 0;
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
void
|
||||
EthernetHandleSet_addSocket(EthernetHandleSet self, const EthernetSocket sock)
|
||||
{
|
||||
if (self != NULL && sock != NULL) {
|
||||
int i = self->nhandles++;
|
||||
self->handles = realloc(self->handles, self->nhandles * sizeof(struct pollfd));
|
||||
|
||||
self->handles[i].fd = sock->bpf;
|
||||
self->handles[i].events = POLLIN;
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
EthernetHandleSet_removeSocket(EthernetHandleSet self, const EthernetSocket sock)
|
||||
{
|
||||
if ((self != NULL) && (sock != NULL)) {
|
||||
unsigned i;
|
||||
for (i = 0; i < self->nhandles; i++) {
|
||||
if (self->handles[i].fd == sock->bpf) {
|
||||
memmove(&self->handles[i], &self->handles[i+1], sizeof(struct pollfd) * (self->nhandles - i - 1));
|
||||
self->nhandles--;
|
||||
return;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
int
|
||||
EthernetHandleSet_waitReady(EthernetHandleSet self, unsigned int timeoutMs)
|
||||
{
|
||||
int result;
|
||||
|
||||
if ((self != NULL) && (self->nhandles >= 0)) {
|
||||
result = poll(self->handles, self->nhandles, timeoutMs);
|
||||
}
|
||||
else {
|
||||
result = -1;
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
void
|
||||
EthernetHandleSet_destroy(EthernetHandleSet self)
|
||||
{
|
||||
if (self->nhandles)
|
||||
free(self->handles);
|
||||
|
||||
GLOBAL_FREEMEM(self);
|
||||
}
|
||||
int
|
||||
activateBpdFilter(EthernetSocket self)
|
||||
int _Ethernet_activateBpdFilter(EthernetSocket self)
|
||||
{
|
||||
return ioctl(self->bpf, BIOCSETF, &self->bpfProgram);
|
||||
}
|
||||
|
||||
static int
|
||||
setBpfEthernetAddressFilter(EthernetSocket self, uint8_t *addr)
|
||||
int _Ethernet_setBpfEthernetAddressFilter(EthernetSocket self, uint8_t *addr)
|
||||
{
|
||||
if (addr)
|
||||
{
|
||||
|
@ -133,19 +62,18 @@ setBpfEthernetAddressFilter(EthernetSocket self, uint8_t *addr)
|
|||
memcpy((void *)&self->bpfProgram.bf_insns[3].k, &addr[2], 4);
|
||||
memcpy((void *)&self->bpfProgram.bf_insns[5].k, &addr, 2);
|
||||
|
||||
return activateBpdFilter(self);
|
||||
return _Ethernet_activateBpdFilter(self);
|
||||
}
|
||||
else
|
||||
{
|
||||
// Disable Ethernet address filter.
|
||||
self->bpfProgram.bf_insns[0].k = 0;
|
||||
|
||||
return activateBpdFilter(self);
|
||||
return _Ethernet_activateBpdFilter(self);
|
||||
}
|
||||
}
|
||||
|
||||
static int
|
||||
setBpfEthertypeFilter(EthernetSocket self, uint16_t etherType)
|
||||
int _Ethernet_setBpfEthertypeFilter(EthernetSocket self, uint16_t etherType)
|
||||
{
|
||||
if (etherType)
|
||||
{
|
||||
|
@ -155,14 +83,14 @@ setBpfEthertypeFilter(EthernetSocket self, uint16_t etherType)
|
|||
// Set protocol.
|
||||
self->bpfProgram.bf_insns[9].k = etherType;
|
||||
|
||||
return activateBpdFilter(self);
|
||||
return _Ethernet_activateBpdFilter(self);
|
||||
}
|
||||
else
|
||||
{
|
||||
// Disable Ethertype filter.
|
||||
self->bpfProgram.bf_insns[6].k = 0;
|
||||
|
||||
return activateBpdFilter(self);
|
||||
return _Ethernet_activateBpdFilter(self);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -355,15 +283,13 @@ Ethernet_createSocket(const char* interfaceId, uint8_t* destAddress)
|
|||
return self;
|
||||
}
|
||||
|
||||
void
|
||||
Ethernet_setProtocolFilter(EthernetSocket self, uint16_t etherType)
|
||||
void Ethernet_setProtocolFilter(EthernetSocket self, uint16_t etherType)
|
||||
{
|
||||
if (!self || !self->bpfProgram.bf_insns || setBpfEthertypeFilter(self, etherType))
|
||||
if (!self || !self->bpfProgram.bf_insns || _Ethernet_setBpfEthertypeFilter(self, etherType))
|
||||
printf("Unable to set ethertype filter!\n");
|
||||
}
|
||||
|
||||
int
|
||||
Ethernet_receivePacket(EthernetSocket self, uint8_t* buffer, int bufferSize)
|
||||
int Ethernet_receivePacket(EthernetSocket self, uint8_t* buffer, int bufferSize)
|
||||
{
|
||||
// If the actual buffer is empty, make a read call to the BSP device in order to get new data.
|
||||
if (self->bpfEnd - self->bpfPositon < 4)
|
||||
|
@ -409,15 +335,13 @@ Ethernet_receivePacket(EthernetSocket self, uint8_t* buffer, int bufferSize)
|
|||
return 0;
|
||||
}
|
||||
|
||||
void
|
||||
Ethernet_sendPacket(EthernetSocket self, uint8_t* buffer, int packetSize)
|
||||
void Ethernet_sendPacket(EthernetSocket self, uint8_t* buffer, int packetSize)
|
||||
{
|
||||
// Just send the packet as it is.
|
||||
write(self->bpf, buffer, packetSize);
|
||||
}
|
||||
|
||||
void
|
||||
Ethernet_destroySocket(EthernetSocket self)
|
||||
void Ethernet_destroySocket(EthernetSocket self)
|
||||
{
|
||||
// Close the BPF device.
|
||||
close(self->bpf);
|
||||
|
|
|
@ -23,7 +23,6 @@
|
|||
|
||||
#include <sys/socket.h>
|
||||
#include <sys/ioctl.h>
|
||||
#include <sys/poll.h>
|
||||
#include <linux/if_packet.h>
|
||||
#include <linux/if_ether.h>
|
||||
#include <linux/if_arp.h>
|
||||
|
@ -41,75 +40,6 @@ struct sEthernetSocket {
|
|||
struct sockaddr_ll socketAddress;
|
||||
};
|
||||
|
||||
struct sEthernetHandleSet {
|
||||
struct pollfd *handles;
|
||||
int nhandles;
|
||||
};
|
||||
|
||||
EthernetHandleSet
|
||||
EthernetHandleSet_new(void)
|
||||
{
|
||||
EthernetHandleSet result = (EthernetHandleSet) GLOBAL_MALLOC(sizeof(struct sEthernetHandleSet));
|
||||
|
||||
if (result != NULL) {
|
||||
result->handles = NULL;
|
||||
result->nhandles = 0;
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
void
|
||||
EthernetHandleSet_addSocket(EthernetHandleSet self, const EthernetSocket sock)
|
||||
{
|
||||
if (self != NULL && sock != NULL) {
|
||||
int i = self->nhandles++;
|
||||
self->handles = realloc(self->handles, self->nhandles * sizeof(struct pollfd));
|
||||
|
||||
self->handles[i].fd = sock->rawSocket;
|
||||
self->handles[i].events = POLLIN;
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
EthernetHandleSet_removeSocket(EthernetHandleSet self, const EthernetSocket sock)
|
||||
{
|
||||
if ((self != NULL) && (sock != NULL)) {
|
||||
unsigned i;
|
||||
for (i = 0; i < self->nhandles; i++) {
|
||||
if (self->handles[i].fd == sock->rawSocket) {
|
||||
memmove(&self->handles[i], &self->handles[i+1], sizeof(struct pollfd) * (self->nhandles - i - 1));
|
||||
self->nhandles--;
|
||||
return;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
int
|
||||
EthernetHandleSet_waitReady(EthernetHandleSet self, unsigned int timeoutMs)
|
||||
{
|
||||
int result;
|
||||
|
||||
if ((self != NULL) && (self->nhandles >= 0)) {
|
||||
result = poll(self->handles, self->nhandles, timeoutMs);
|
||||
}
|
||||
else {
|
||||
result = -1;
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
void
|
||||
EthernetHandleSet_destroy(EthernetHandleSet self)
|
||||
{
|
||||
if (self->nhandles)
|
||||
free(self->handles);
|
||||
|
||||
GLOBAL_FREEMEM(self);
|
||||
}
|
||||
|
||||
static int
|
||||
getInterfaceIndex(int sock, const char* deviceName)
|
||||
{
|
||||
|
|
|
@ -47,8 +47,6 @@
|
|||
|
||||
#define HAVE_REMOTE
|
||||
|
||||
// Enable WinPcap specific extension: pcap_getevent()
|
||||
#define WPCAP
|
||||
#include "pcap.h"
|
||||
|
||||
struct sEthernetSocket {
|
||||
|
@ -56,11 +54,6 @@ struct sEthernetSocket {
|
|||
struct bpf_program etherTypeFilter;
|
||||
};
|
||||
|
||||
struct sEthernetHandleSet {
|
||||
HANDLE *handles;
|
||||
int nhandles;
|
||||
};
|
||||
|
||||
#ifdef __GNUC__ /* detect MINGW */
|
||||
|
||||
#ifndef __MINGW64_VERSION_MAJOR
|
||||
|
@ -97,6 +90,7 @@ typedef ULONG (WINAPI* pgetadaptersaddresses)(ULONG family, ULONG flags, PVOID r
|
|||
|
||||
static pgetadaptersaddresses GetAdaptersAddresses;
|
||||
|
||||
|
||||
static bool dllLoaded = false;
|
||||
|
||||
static void
|
||||
|
@ -121,71 +115,6 @@ loadDLLs(void)
|
|||
|
||||
#endif /* __GNUC__ */
|
||||
|
||||
EthernetHandleSet
|
||||
EthernetHandleSet_new(void)
|
||||
{
|
||||
EthernetHandleSet result = (EthernetHandleSet) GLOBAL_MALLOC(sizeof(struct sEthernetHandleSet));
|
||||
|
||||
if (result != NULL) {
|
||||
result->handles = NULL;
|
||||
result->nhandles = 0;
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
void
|
||||
EthernetHandleSet_addSocket(EthernetHandleSet self, const EthernetSocket sock)
|
||||
{
|
||||
if (self != NULL && sock != NULL) {
|
||||
int i = self->nhandles++;
|
||||
self->handles = (HANDLE *) realloc(self->handles, self->nhandles * sizeof(HANDLE));
|
||||
|
||||
self->handles[i] = pcap_getevent(sock->rawSocket);
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
EthernetHandleSet_removeSocket(EthernetHandleSet self, const EthernetSocket sock)
|
||||
{
|
||||
if ((self != NULL) && (sock != NULL)) {
|
||||
HANDLE h = pcap_getevent(socket->rawSocket);
|
||||
|
||||
unsigned i;
|
||||
for (i = 0; i < self->nhandles; i++) {
|
||||
if (self->handles[i] == h) {
|
||||
memmove(&self->handles[i], &self->handles[i+1], sizeof(HANDLE) * (self->nhandles - i - 1));
|
||||
self->nhandles--;
|
||||
return;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
int
|
||||
EthernetHandleSet_waitReady(EthernetHandleSet self, unsigned int timeoutMs)
|
||||
{
|
||||
int result;
|
||||
|
||||
if ((self != NULL) && (self->nhandles > 0)) {
|
||||
result = WaitForMultipleObjects(self->nhandles, self->handles, 0, timeoutMs);
|
||||
}
|
||||
else {
|
||||
result = -1;
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
void
|
||||
EthernetHandleSet_destroy(EthernetHandleSet self)
|
||||
{
|
||||
if (self->handles)
|
||||
free(self->handles);
|
||||
|
||||
GLOBAL_FREEMEM(self);
|
||||
}
|
||||
|
||||
static char*
|
||||
getInterfaceName(int interfaceIndex)
|
||||
{
|
||||
|
@ -286,6 +215,8 @@ getAdapterMacAddress(char* pcapAdapterName, uint8_t* macAddress)
|
|||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
void
|
||||
Ethernet_getInterfaceMACAddress(const char* interfaceId, uint8_t* addr)
|
||||
{
|
||||
|
@ -407,28 +338,6 @@ Ethernet_isSupported()
|
|||
return false;
|
||||
}
|
||||
|
||||
EthernetHandleSet
|
||||
EthernetHandleSet_new(void)
|
||||
{
|
||||
return NULL;
|
||||
}
|
||||
|
||||
void
|
||||
EthernetHandleSet_addSocket(EthernetHandleSet self, const EthernetSocket sock)
|
||||
{
|
||||
}
|
||||
|
||||
int
|
||||
EthernetHandleSet_waitReady(EthernetHandleSet self, unsigned int timeoutMs)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
void
|
||||
EthernetHandleSet_destroy(EthernetHandleSet self)
|
||||
{
|
||||
}
|
||||
|
||||
void
|
||||
Ethernet_getInterfaceMACAddress(const char* interfaceId, uint8_t* addr)
|
||||
{
|
||||
|
|
|
@ -48,58 +48,6 @@ extern "C" {
|
|||
*/
|
||||
typedef struct sEthernetSocket* EthernetSocket;
|
||||
|
||||
/** Opaque reference for a set of ethernet socket handles */
|
||||
typedef struct sEthernetHandleSet* EthernetHandleSet;
|
||||
|
||||
/**
|
||||
* \brief Create a new connection handle set (EthernetHandleSet)
|
||||
*
|
||||
* \return new EthernetHandleSet instance
|
||||
*/
|
||||
EthernetHandleSet
|
||||
EthernetHandleSet_new(void);
|
||||
|
||||
/**
|
||||
* \brief add a socket to an existing handle set
|
||||
*
|
||||
* \param self the HandleSet instance
|
||||
* \param sock the socket to add
|
||||
*/
|
||||
void
|
||||
EthernetHandleSet_addSocket(EthernetHandleSet self, const EthernetSocket sock);
|
||||
|
||||
/**
|
||||
* \brief remove a socket from an existing handle set
|
||||
*
|
||||
* \param self the HandleSet instance
|
||||
* \param sock the socket to add
|
||||
*/
|
||||
void
|
||||
EthernetHandleSet_removeSocket(EthernetHandleSet self, const EthernetSocket sock);
|
||||
|
||||
/**
|
||||
* \brief wait for a socket to become ready
|
||||
*
|
||||
* This function is corresponding to the BSD socket select function.
|
||||
* The function will return after \p timeoutMs ms if no data is pending.
|
||||
*
|
||||
* \param self the HandleSet instance
|
||||
* \param timeout in milliseconds (ms)
|
||||
* \return It returns the number of sockets on which data is pending
|
||||
* or 0 if no data is pending on any of the monitored connections.
|
||||
* The function shall return -1 if a socket error occures.
|
||||
*/
|
||||
int
|
||||
EthernetHandleSet_waitReady(EthernetHandleSet self, unsigned int timeoutMs);
|
||||
|
||||
/**
|
||||
* \brief destroy the EthernetHandleSet instance
|
||||
*
|
||||
* \param self the HandleSet instance to destroy
|
||||
*/
|
||||
void
|
||||
EthernetHandleSet_destroy(EthernetHandleSet self);
|
||||
|
||||
/**
|
||||
* \brief Return the MAC address of an Ethernet interface.
|
||||
*
|
||||
|
|
|
@ -63,7 +63,7 @@ HandleSet
|
|||
Handleset_new(void);
|
||||
|
||||
/**
|
||||
* \brief add a socket to an existing handle set
|
||||
* \brief add a soecket to an existing handle set
|
||||
*
|
||||
* \param self the HandleSet instance
|
||||
* \param sock the socket to add
|
||||
|
@ -71,17 +71,18 @@ Handleset_new(void);
|
|||
void
|
||||
Handleset_addSocket(HandleSet self, const Socket sock);
|
||||
|
||||
|
||||
/**
|
||||
* \brief wait for a socket to become ready
|
||||
*
|
||||
* This function is corresponding to the BSD socket select function.
|
||||
* The function will return after \p timeoutMs ms if no data is pending.
|
||||
* It returns the number of sockets on which data is pending or 0 if no data is pending
|
||||
* on any of the monitored connections. The function will return after "timeout" ms if no
|
||||
* data is pending.
|
||||
* The function shall return -1 if a socket error occures.
|
||||
*
|
||||
* \param self the HandleSet instance
|
||||
* \param timeout in milliseconds (ms)
|
||||
* \return It returns the number of sockets on which data is pending
|
||||
* or 0 if no data is pending on any of the monitored connections.
|
||||
* The function shall return -1 if a socket error occures.
|
||||
* \param self the HandleSet instance
|
||||
* \param timeout in milliseconds (ms)
|
||||
*/
|
||||
int
|
||||
Handleset_waitReady(HandleSet self, unsigned int timeoutMs);
|
||||
|
|
|
@ -1,13 +0,0 @@
|
|||
prefix=@CMAKE_INSTALL_PREFIX@
|
||||
exec_prefix=@CMAKE_INSTALL_PREFIX@/bin
|
||||
libdir=@CMAKE_INSTALL_PREFIX@/lib
|
||||
sharedlibdir=@CMAKE_INSTALL_PREFIX@/lib
|
||||
includedir=@CMAKE_INSTALL_PREFIX@/include
|
||||
|
||||
Name: @PROJECT_NAME@
|
||||
Description: @CPACK_PACKAGE_DESCRIPTION@
|
||||
Version: @LIB_VERSION_MAJOR@.@LIB_VERSION_MINOR@.@LIB_VERSION_PATCH@
|
||||
|
||||
Requires:
|
||||
Libs: -L${libdir} -L${sharedlibdir} -liec61850
|
||||
Cflags: -I${includedir}
|
|
@ -351,6 +351,7 @@ IsoClientConnection_associate(IsoClientConnection self, IsoConnectionParameters
|
|||
goto returnError;
|
||||
}
|
||||
|
||||
|
||||
ByteBuffer_wrap(self->receivePayloadBuffer, self->acseConnection.userDataBuffer,
|
||||
self->acseConnection.userDataBufferSize, self->acseConnection.userDataBufferSize);
|
||||
|
||||
|
|
|
@ -449,8 +449,6 @@ CotpConnection_init(CotpConnection* self, Socket socket,
|
|||
self->options.tSelDst = tsel;
|
||||
self->payload = payloadBuffer;
|
||||
|
||||
CotpConnection_resetPayload(self);
|
||||
|
||||
/* default TPDU size is maximum size */
|
||||
CotpConnection_setTpduSize(self, COTP_MAX_TPDU_SIZE);
|
||||
|
||||
|
|
|
@ -35,48 +35,45 @@
|
|||
|
||||
void
|
||||
mmsClient_createDeleteNamedVariableListRequest(long invokeId, ByteBuffer* writeBuffer,
|
||||
const char* domainId, const char* listNameId)
|
||||
const char* domainId, const char* listNameId)
|
||||
{
|
||||
MmsPdu_t* mmsPdu = mmsClient_createConfirmedRequestPdu(invokeId);
|
||||
MmsPdu_t* mmsPdu = mmsClient_createConfirmedRequestPdu(invokeId);
|
||||
|
||||
mmsPdu->choice.confirmedRequestPdu.confirmedServiceRequest.present =
|
||||
ConfirmedServiceRequest_PR_deleteNamedVariableList;
|
||||
mmsPdu->choice.confirmedRequestPdu.confirmedServiceRequest.present =
|
||||
ConfirmedServiceRequest_PR_deleteNamedVariableList;
|
||||
|
||||
DeleteNamedVariableListRequest_t* request =
|
||||
&(mmsPdu->choice.confirmedRequestPdu.confirmedServiceRequest.choice.deleteNamedVariableList);
|
||||
DeleteNamedVariableListRequest_t* request =
|
||||
&(mmsPdu->choice.confirmedRequestPdu.confirmedServiceRequest.choice.deleteNamedVariableList);
|
||||
|
||||
request->listOfVariableListName = (struct DeleteNamedVariableListRequest__listOfVariableListName*) GLOBAL_CALLOC(1,
|
||||
sizeof(struct DeleteNamedVariableListRequest__listOfVariableListName));
|
||||
request->listOfVariableListName = (struct DeleteNamedVariableListRequest__listOfVariableListName*) GLOBAL_CALLOC(1,
|
||||
sizeof(struct DeleteNamedVariableListRequest__listOfVariableListName));
|
||||
|
||||
request->listOfVariableListName->list.count = 1;
|
||||
request->listOfVariableListName->list.size = 1;
|
||||
request->listOfVariableListName->list.count = 1;
|
||||
request->listOfVariableListName->list.size = 1;
|
||||
|
||||
request->listOfVariableListName->list.array = (ObjectName_t**) GLOBAL_CALLOC(1, sizeof(ObjectName_t*));
|
||||
request->listOfVariableListName->list.array[0] = (ObjectName_t*) GLOBAL_CALLOC(1, sizeof(ObjectName_t));
|
||||
request->listOfVariableListName->list.array = (ObjectName_t**) GLOBAL_CALLOC(1, sizeof(ObjectName_t*));
|
||||
request->listOfVariableListName->list.array[0] = (ObjectName_t*) GLOBAL_CALLOC(1, sizeof(ObjectName_t));
|
||||
|
||||
if (domainId != NULL) {
|
||||
if (domainId != NULL) {
|
||||
request->listOfVariableListName->list.array[0]->present = ObjectName_PR_domainspecific;
|
||||
request->listOfVariableListName->list.array[0]->choice.domainspecific.domainId.size = strlen(domainId);
|
||||
request->listOfVariableListName->list.array[0]->choice.domainspecific.domainId.buf =
|
||||
(uint8_t*) StringUtils_copyString(domainId);
|
||||
request->listOfVariableListName->list.array[0]->choice.domainspecific.domainId.buf = (uint8_t*) StringUtils_copyString(domainId);
|
||||
request->listOfVariableListName->list.array[0]->choice.domainspecific.itemId.size = strlen(listNameId);
|
||||
request->listOfVariableListName->list.array[0]->choice.domainspecific.itemId.buf =
|
||||
(uint8_t*) StringUtils_copyString(listNameId);
|
||||
}
|
||||
else {
|
||||
request->listOfVariableListName->list.array[0]->present = ObjectName_PR_vmdspecific;
|
||||
request->listOfVariableListName->list.array[0]->choice.vmdspecific.size = strlen(listNameId);
|
||||
request->listOfVariableListName->list.array[0]->choice.vmdspecific.buf =
|
||||
(uint8_t*) StringUtils_copyString(listNameId);
|
||||
}
|
||||
request->listOfVariableListName->list.array[0]->choice.domainspecific.itemId.buf = (uint8_t*) StringUtils_copyString(listNameId);
|
||||
}
|
||||
else {
|
||||
request->listOfVariableListName->list.array[0]->present = ObjectName_PR_vmdspecific;
|
||||
request->listOfVariableListName->list.array[0]->choice.vmdspecific.size = strlen(listNameId);
|
||||
request->listOfVariableListName->list.array[0]->choice.vmdspecific.buf = (uint8_t*) StringUtils_copyString(listNameId);
|
||||
}
|
||||
|
||||
request->scopeOfDelete = (INTEGER_t*) GLOBAL_CALLOC(1, sizeof(INTEGER_t));
|
||||
asn_long2INTEGER(request->scopeOfDelete, DeleteNamedVariableListRequest__scopeOfDelete_specific);
|
||||
request->scopeOfDelete = (INTEGER_t*) GLOBAL_CALLOC(1, sizeof(INTEGER_t));
|
||||
asn_long2INTEGER(request->scopeOfDelete, DeleteNamedVariableListRequest__scopeOfDelete_specific);
|
||||
|
||||
der_encode(&asn_DEF_MmsPdu, mmsPdu,
|
||||
(asn_app_consume_bytes_f*) mmsClient_write_out, (void*) writeBuffer);
|
||||
(asn_app_consume_bytes_f*) mmsClient_write_out, (void*) writeBuffer);
|
||||
|
||||
asn_DEF_MmsPdu.free_struct(&asn_DEF_MmsPdu, mmsPdu, 0);
|
||||
asn_DEF_MmsPdu.free_struct(&asn_DEF_MmsPdu, mmsPdu, 0);
|
||||
}
|
||||
|
||||
void
|
||||
|
@ -223,25 +220,11 @@ parseNamedVariableAttributes(GetNamedVariableListAttributesResponse_t* response,
|
|||
LinkedList attributes = LinkedList_create();
|
||||
|
||||
for (i = 0; i < attributesCount; i++) {
|
||||
|
||||
char* domainId;
|
||||
char* itemId;
|
||||
|
||||
|
||||
if (response->listOfVariable.list.array[i]->variableSpecification.choice.name.present == ObjectName_PR_vmdspecific) {
|
||||
|
||||
domainId = NULL;
|
||||
|
||||
itemId = mmsMsg_createStringFromAsnIdentifier(response->listOfVariable.list.array[i]->
|
||||
variableSpecification.choice.name.choice.vmdspecific);
|
||||
}
|
||||
else {
|
||||
domainId = mmsMsg_createStringFromAsnIdentifier(response->listOfVariable.list.array[i]->
|
||||
char* domainId = mmsMsg_createStringFromAsnIdentifier(response->listOfVariable.list.array[i]->
|
||||
variableSpecification.choice.name.choice.domainspecific.domainId);
|
||||
|
||||
itemId = mmsMsg_createStringFromAsnIdentifier(response->listOfVariable.list.array[i]->
|
||||
char* itemId = mmsMsg_createStringFromAsnIdentifier(response->listOfVariable.list.array[i]->
|
||||
variableSpecification.choice.name.choice.domainspecific.itemId);
|
||||
}
|
||||
|
||||
MmsVariableAccessSpecification* listEntry = MmsVariableAccessSpecification_create(domainId, itemId);
|
||||
|
||||
|
|
|
@ -498,7 +498,8 @@ mmsServer_handleDefineNamedVariableListRequest(
|
|||
char variableListName[65];
|
||||
|
||||
if (request->variableListName.choice.aaspecific.size > 64) {
|
||||
mmsMsg_createMmsRejectPdu(&invokeId, MMS_ERROR_REJECT_REQUEST_INVALID_ARGUMENT, response);
|
||||
//TODO send reject PDU instead?
|
||||
mmsMsg_createServiceErrorPdu(invokeId, response, MMS_ERROR_ACCESS_OBJECT_NON_EXISTENT);
|
||||
goto exit_free_struct;
|
||||
}
|
||||
|
||||
|
@ -542,7 +543,8 @@ mmsServer_handleDefineNamedVariableListRequest(
|
|||
char variableListName[65];
|
||||
|
||||
if (request->variableListName.choice.vmdspecific.size > 64) {
|
||||
mmsMsg_createMmsRejectPdu(&invokeId, MMS_ERROR_REJECT_REQUEST_INVALID_ARGUMENT, response);
|
||||
//TODO send reject PDU instead?
|
||||
mmsMsg_createServiceErrorPdu(invokeId, response, MMS_ERROR_ACCESS_OBJECT_NON_EXISTENT);
|
||||
goto exit_free_struct;
|
||||
}
|
||||
|
||||
|
@ -581,6 +583,7 @@ mmsServer_handleDefineNamedVariableListRequest(
|
|||
exit_free_struct:
|
||||
asn_DEF_MmsPdu.free_struct(&asn_DEF_MmsPdu, mmsPdu, 0);
|
||||
|
||||
exit_function:
|
||||
return;
|
||||
}
|
||||
|
||||
|
|
|
@ -42,9 +42,9 @@
|
|||
|
||||
#define SV_MAX_MESSAGE_SIZE 1518
|
||||
|
||||
struct sSVPublisher_ASDU {
|
||||
const char* svID;
|
||||
const char* datset;
|
||||
struct sSV_ASDU {
|
||||
char* svID;
|
||||
char* datset;
|
||||
int dataSize;
|
||||
|
||||
bool hasRefrTm;
|
||||
|
@ -59,16 +59,15 @@ struct sSVPublisher_ASDU {
|
|||
|
||||
uint64_t refrTm;
|
||||
uint8_t smpMod;
|
||||
uint16_t smpRate;
|
||||
|
||||
uint8_t* smpCntBuf;
|
||||
|
||||
SVPublisher_ASDU _next;
|
||||
SV_ASDU _next;
|
||||
};
|
||||
|
||||
|
||||
|
||||
struct sSVPublisher {
|
||||
struct sSampledValuesPublisher {
|
||||
uint8_t* buffer;
|
||||
uint16_t appId;
|
||||
EthernetSocket ethernetSocket;
|
||||
|
@ -79,14 +78,14 @@ struct sSVPublisher {
|
|||
int payloadLength; /* length of payload buffer */
|
||||
|
||||
int asduCount; /* number of ASDUs in the APDU */
|
||||
SVPublisher_ASDU asduLIst;
|
||||
SV_ASDU asduLIst;
|
||||
|
||||
|
||||
};
|
||||
|
||||
|
||||
static void
|
||||
preparePacketBuffer(SVPublisher self, CommParameters* parameters, const char* interfaceID)
|
||||
preparePacketBuffer(SampledValuesPublisher self, CommParameters* parameters, const char* interfaceID)
|
||||
{
|
||||
uint8_t srcAddr[6];
|
||||
|
||||
|
@ -221,34 +220,6 @@ encodeInt32FixedSize(int32_t value, uint8_t* buffer, int bufPos)
|
|||
return bufPos;
|
||||
}
|
||||
|
||||
static int
|
||||
encodeInt64FixedSize(int64_t value, uint8_t* buffer, int bufPos)
|
||||
{
|
||||
uint8_t* valueArray = (uint8_t*) &value;
|
||||
|
||||
#if (ORDER_LITTLE_ENDIAN == 1)
|
||||
buffer[bufPos++] = valueArray[7];
|
||||
buffer[bufPos++] = valueArray[6];
|
||||
buffer[bufPos++] = valueArray[5];
|
||||
buffer[bufPos++] = valueArray[4];
|
||||
buffer[bufPos++] = valueArray[3];
|
||||
buffer[bufPos++] = valueArray[2];
|
||||
buffer[bufPos++] = valueArray[1];
|
||||
buffer[bufPos++] = valueArray[0];
|
||||
#else
|
||||
buffer[bufPos++] = valueArray[0];
|
||||
buffer[bufPos++] = valueArray[1];
|
||||
buffer[bufPos++] = valueArray[2];
|
||||
buffer[bufPos++] = valueArray[3];
|
||||
buffer[bufPos++] = valueArray[4];
|
||||
buffer[bufPos++] = valueArray[5];
|
||||
buffer[bufPos++] = valueArray[6];
|
||||
buffer[bufPos++] = valueArray[7];
|
||||
#endif
|
||||
|
||||
return bufPos;
|
||||
}
|
||||
|
||||
static int
|
||||
encodeUtcTime(uint64_t timeval, uint8_t* buffer, int bufPos)
|
||||
{
|
||||
|
@ -283,22 +254,22 @@ encodeUtcTime(uint64_t timeval, uint8_t* buffer, int bufPos)
|
|||
return bufPos + 8;
|
||||
}
|
||||
|
||||
SVPublisher
|
||||
SVPublisher_create(CommParameters* parameters, const char* interfaceId)
|
||||
SampledValuesPublisher
|
||||
SampledValuesPublisher_create(CommParameters* parameters, const char* interfaceId)
|
||||
{
|
||||
SVPublisher self = (SVPublisher) GLOBAL_CALLOC(1, sizeof(struct sSVPublisher));
|
||||
SampledValuesPublisher self = (SampledValuesPublisher) GLOBAL_CALLOC(1, sizeof(struct sSampledValuesPublisher));
|
||||
|
||||
self->asduLIst = NULL;
|
||||
self->asduLIst = NULL;
|
||||
|
||||
preparePacketBuffer(self, parameters, interfaceId);
|
||||
preparePacketBuffer(self, parameters, interfaceId);
|
||||
|
||||
return self;
|
||||
return self;
|
||||
}
|
||||
|
||||
SVPublisher_ASDU
|
||||
SVPublisher_addASDU(SVPublisher self, const char* svID, const char* datset, uint32_t confRev)
|
||||
SV_ASDU
|
||||
SampledValuesPublisher_addASDU(SampledValuesPublisher self, char* svID, char* datset, uint32_t confRev)
|
||||
{
|
||||
SVPublisher_ASDU newAsdu = (SVPublisher_ASDU) GLOBAL_CALLOC(1, sizeof(struct sSVPublisher_ASDU));
|
||||
SV_ASDU newAsdu = (SV_ASDU) GLOBAL_CALLOC(1, sizeof(struct sSV_ASDU));
|
||||
|
||||
newAsdu->svID = svID;
|
||||
newAsdu->datset = datset;
|
||||
|
@ -310,7 +281,7 @@ SVPublisher_addASDU(SVPublisher self, const char* svID, const char* datset, uint
|
|||
if (self->asduLIst == NULL)
|
||||
self->asduLIst = newAsdu;
|
||||
else {
|
||||
SVPublisher_ASDU lastAsdu = self->asduLIst;
|
||||
SV_ASDU lastAsdu = self->asduLIst;
|
||||
|
||||
while (lastAsdu->_next != NULL)
|
||||
lastAsdu = lastAsdu->_next;
|
||||
|
@ -322,7 +293,7 @@ SVPublisher_addASDU(SVPublisher self, const char* svID, const char* datset, uint
|
|||
}
|
||||
|
||||
static int
|
||||
SVPublisher_ASDU_getEncodedSize(SVPublisher_ASDU self)
|
||||
SV_ASDU_getEncodedSize(SV_ASDU self)
|
||||
{
|
||||
int encodedSize = 0;
|
||||
|
||||
|
@ -362,9 +333,9 @@ SVPublisher_ASDU_getEncodedSize(SVPublisher_ASDU self)
|
|||
}
|
||||
|
||||
static int
|
||||
SVPublisher_ASDU_encodeToBuffer(SVPublisher_ASDU self, uint8_t* buffer, int bufPos)
|
||||
SV_ASDU_encodeToBuffer(SV_ASDU self, uint8_t* buffer, int bufPos)
|
||||
{
|
||||
int encodedSize = SVPublisher_ASDU_getEncodedSize(self);
|
||||
int encodedSize = SV_ASDU_getEncodedSize(self);
|
||||
|
||||
/* tag and length field */
|
||||
bufPos = BerEncoder_encodeTL(0x30, encodedSize, buffer, bufPos);
|
||||
|
@ -398,10 +369,7 @@ SVPublisher_ASDU_encodeToBuffer(SVPublisher_ASDU self, uint8_t* buffer, int bufP
|
|||
buffer[bufPos++] = self->smpSynch;
|
||||
|
||||
/* SmpRate */
|
||||
if (self->hasSmpRate) {
|
||||
bufPos = BerEncoder_encodeTL(0x86, 2, buffer, bufPos);
|
||||
bufPos = encodeUInt16FixedSize(self->smpRate, buffer, bufPos);
|
||||
}
|
||||
//TODO implement me
|
||||
|
||||
/* Sample */
|
||||
bufPos = BerEncoder_encodeTL(0x87, self->dataSize, buffer, bufPos);
|
||||
|
@ -409,28 +377,32 @@ SVPublisher_ASDU_encodeToBuffer(SVPublisher_ASDU self, uint8_t* buffer, int bufP
|
|||
self->_dataBuffer = buffer + bufPos;
|
||||
|
||||
bufPos += self->dataSize; /* data has to inserted by user before sending message */
|
||||
|
||||
|
||||
/* SmpMod */
|
||||
if (self->hasSmpMod) {
|
||||
bufPos = BerEncoder_encodeTL(0x88, 2, buffer, bufPos);
|
||||
bufPos = encodeUInt16FixedSize(self->smpMod, buffer, bufPos);
|
||||
bufPos = BerEncoder_encodeTL(0x84, 4, buffer, bufPos);
|
||||
buffer[bufPos++] = 0;
|
||||
buffer[bufPos++] = 0;
|
||||
buffer[bufPos++] = 0;
|
||||
buffer[bufPos++] = self->smpMod;
|
||||
|
||||
}
|
||||
|
||||
return bufPos;
|
||||
}
|
||||
|
||||
void
|
||||
SVPublisher_setupComplete(SVPublisher self)
|
||||
SampledValuesPublisher_setupComplete(SampledValuesPublisher self)
|
||||
{
|
||||
int numberOfAsdu = 0;
|
||||
|
||||
/* determine number of ASDUs and length of all ASDUs */
|
||||
SVPublisher_ASDU nextAsdu = self->asduLIst;
|
||||
SV_ASDU nextAsdu = self->asduLIst;
|
||||
int totalASDULength = 0;
|
||||
|
||||
while (nextAsdu != NULL) {
|
||||
numberOfAsdu++;
|
||||
int asduLength = SVPublisher_ASDU_getEncodedSize(nextAsdu);
|
||||
int asduLength = SV_ASDU_getEncodedSize(nextAsdu);
|
||||
|
||||
/* tag and length field */
|
||||
asduLength += BerEncoder_determineLengthSize(asduLength);
|
||||
|
@ -459,7 +431,7 @@ SVPublisher_setupComplete(SVPublisher self)
|
|||
nextAsdu = self->asduLIst;
|
||||
|
||||
while (nextAsdu != NULL) {
|
||||
bufPos = SVPublisher_ASDU_encodeToBuffer(nextAsdu, buffer, bufPos);
|
||||
bufPos = SV_ASDU_encodeToBuffer(nextAsdu, buffer, bufPos);
|
||||
|
||||
nextAsdu = nextAsdu->_next;
|
||||
}
|
||||
|
@ -480,7 +452,7 @@ SVPublisher_setupComplete(SVPublisher self)
|
|||
|
||||
|
||||
void
|
||||
SVPublisher_publish(SVPublisher self)
|
||||
SampledValuesPublisher_publish(SampledValuesPublisher self)
|
||||
{
|
||||
if (DEBUG_SV_PUBLISHER)
|
||||
printf("SV_PUBLISHER: send SV message\n");
|
||||
|
@ -491,21 +463,21 @@ SVPublisher_publish(SVPublisher self)
|
|||
|
||||
|
||||
void
|
||||
SVPublisher_destroy(SVPublisher self)
|
||||
SampledValuesPublisher_destroy(SampledValuesPublisher self)
|
||||
{
|
||||
GLOBAL_FREEMEM(self->buffer);
|
||||
GLOBAL_FREEMEM(self->buffer);
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
SVPublisher_ASDU_resetBuffer(SVPublisher_ASDU self)
|
||||
SV_ASDU_resetBuffer(SV_ASDU self)
|
||||
{
|
||||
self->dataSize = 0;
|
||||
}
|
||||
|
||||
|
||||
int
|
||||
SVPublisher_ASDU_addINT8(SVPublisher_ASDU self)
|
||||
SV_ASDU_addINT8(SV_ASDU self)
|
||||
{
|
||||
int index = self->dataSize;
|
||||
|
||||
|
@ -515,13 +487,13 @@ SVPublisher_ASDU_addINT8(SVPublisher_ASDU self)
|
|||
}
|
||||
|
||||
void
|
||||
SVPublisher_ASDU_setINT8(SVPublisher_ASDU self, int index, int8_t value)
|
||||
SV_ASDU_setINT8(SV_ASDU self, int index, int8_t value)
|
||||
{
|
||||
self->_dataBuffer[index] = value;
|
||||
}
|
||||
|
||||
int
|
||||
SVPublisher_ASDU_addINT32(SVPublisher_ASDU self)
|
||||
SV_ASDU_addINT32(SV_ASDU self)
|
||||
{
|
||||
int index = self->dataSize;
|
||||
|
||||
|
@ -531,29 +503,13 @@ SVPublisher_ASDU_addINT32(SVPublisher_ASDU self)
|
|||
}
|
||||
|
||||
void
|
||||
SVPublisher_ASDU_setINT32(SVPublisher_ASDU self, int index, int32_t value)
|
||||
SV_ASDU_setINT32(SV_ASDU self, int index, int32_t value)
|
||||
{
|
||||
encodeInt32FixedSize(value, self->_dataBuffer, index);
|
||||
}
|
||||
|
||||
int
|
||||
SVPublisher_ASDU_addINT64(SVPublisher_ASDU self)
|
||||
{
|
||||
int index = self->dataSize;
|
||||
|
||||
self->dataSize += 8;
|
||||
|
||||
return index;
|
||||
}
|
||||
|
||||
void
|
||||
SVPublisher_ASDU_setINT64(SVPublisher_ASDU self, int index, int64_t value)
|
||||
{
|
||||
encodeInt64FixedSize(value, self->_dataBuffer, index);
|
||||
}
|
||||
|
||||
int
|
||||
SVPublisher_ASDU_addFLOAT(SVPublisher_ASDU self)
|
||||
SV_ASDU_addFLOAT(SV_ASDU self)
|
||||
{
|
||||
int index = self->dataSize;
|
||||
|
||||
|
@ -563,10 +519,11 @@ SVPublisher_ASDU_addFLOAT(SVPublisher_ASDU self)
|
|||
}
|
||||
|
||||
void
|
||||
SVPublisher_ASDU_setFLOAT(SVPublisher_ASDU self, int index, float value)
|
||||
SV_ASDU_setFLOAT(SV_ASDU self, int index, float value)
|
||||
{
|
||||
uint8_t* buf = (uint8_t*) &value;
|
||||
|
||||
|
||||
#if (ORDER_LITTLE_ENDIAN == 1)
|
||||
BerEncoder_revertByteOrder(buf, 4);
|
||||
#endif
|
||||
|
@ -582,7 +539,7 @@ SVPublisher_ASDU_setFLOAT(SVPublisher_ASDU self, int index, float value)
|
|||
|
||||
|
||||
int
|
||||
SVPublisher_ASDU_addFLOAT64(SVPublisher_ASDU self)
|
||||
SV_ASDU_addFLOAT64(SV_ASDU self)
|
||||
{
|
||||
int index = self->dataSize;
|
||||
self->dataSize += 8;
|
||||
|
@ -590,31 +547,27 @@ SVPublisher_ASDU_addFLOAT64(SVPublisher_ASDU self)
|
|||
}
|
||||
|
||||
void
|
||||
SVPublisher_ASDU_setFLOAT64(SVPublisher_ASDU self, int index, double value)
|
||||
SV_ASDU_setFLOAT64(SV_ASDU self, int index, double value)
|
||||
{
|
||||
uint8_t* buf = (uint8_t*) &value;
|
||||
|
||||
#if (ORDER_LITTLE_ENDIAN == 1)
|
||||
BerEncoder_revertByteOrder(buf, 8);
|
||||
#endif
|
||||
|
||||
int i;
|
||||
|
||||
uint8_t* buffer = self->_dataBuffer + index;
|
||||
|
||||
for (i = 0; i < 8; i++) {
|
||||
buffer[i] = buf[i];
|
||||
}
|
||||
}
|
||||
|
||||
uint16_t
|
||||
SVPublisher_ASDU_getSmpCnt(SVPublisher_ASDU self)
|
||||
SV_ASDU_getSmpCnt(SV_ASDU self)
|
||||
{
|
||||
return self->smpCnt;
|
||||
}
|
||||
|
||||
void
|
||||
SVPublisher_ASDU_setSmpCnt(SVPublisher_ASDU self, uint16_t value)
|
||||
SV_ASDU_setSmpCnt(SV_ASDU self, uint16_t value)
|
||||
{
|
||||
self->smpCnt = value;
|
||||
|
||||
|
@ -622,7 +575,7 @@ SVPublisher_ASDU_setSmpCnt(SVPublisher_ASDU self, uint16_t value)
|
|||
}
|
||||
|
||||
void
|
||||
SVPublisher_ASDU_increaseSmpCnt(SVPublisher_ASDU self)
|
||||
SV_ASDU_increaseSmpCnt(SV_ASDU self)
|
||||
{
|
||||
self->smpCnt++;
|
||||
|
||||
|
@ -630,22 +583,16 @@ SVPublisher_ASDU_increaseSmpCnt(SVPublisher_ASDU self)
|
|||
}
|
||||
|
||||
void
|
||||
SVPublisher_ASDU_setRefrTm(SVPublisher_ASDU self, uint64_t refrTm)
|
||||
SV_ASDU_setRefrTm(SV_ASDU self, uint64_t refrTm)
|
||||
{
|
||||
self->hasRefrTm = true;
|
||||
self->refrTm = refrTm;
|
||||
}
|
||||
|
||||
void
|
||||
SVPublisher_ASDU_setSmpMod(SVPublisher_ASDU self, uint8_t smpMod)
|
||||
SV_ASDU_setSmpMod(SV_ASDU self, uint8_t smpMod)
|
||||
{
|
||||
self->hasSmpMod = true;
|
||||
self->smpMod = smpMod;
|
||||
}
|
||||
|
||||
void
|
||||
SVPublisher_ASDU_setSmpRate(SVPublisher_ASDU self, uint16_t smpRate)
|
||||
{
|
||||
self->hasSmpRate = true;
|
||||
self->smpRate = smpRate;
|
||||
}
|
||||
|
|
|
@ -43,11 +43,6 @@ typedef struct sCommParameters {
|
|||
|
||||
#endif
|
||||
|
||||
/**
|
||||
* \defgroup sv_publisher_api_group IEC 61850 Sampled Values (SV) publisher API
|
||||
*/
|
||||
/**@{*/
|
||||
|
||||
#define IEC61850_SV_SMPSYNC_NOT_SYNCHRONIZED 0
|
||||
#define IEC61850_SV_SMPSYNC_SYNCED_UNSPEC_LOCAL_CLOCK 1
|
||||
#define IEC61850_SV_SMPSYNC_SYNCED_GLOBAL_CLOCK 2
|
||||
|
@ -56,241 +51,79 @@ typedef struct sCommParameters {
|
|||
#define IEC61850_SV_SMPMOD_SAMPLES_PER_SECOND 1
|
||||
#define IEC61850_SV_SMPMOD_SECONDS_PER_SAMPLE 2
|
||||
|
||||
/**
|
||||
* \brief An opaque type representing an IEC 61850-9-2 Sampled Values publisher.
|
||||
*/
|
||||
typedef struct sSVPublisher* SVPublisher;
|
||||
typedef struct sSampledValuesPublisher* SampledValuesPublisher;
|
||||
|
||||
/**
|
||||
* \brief An opaque type representing an IEC 61850-9-2 Sampled Values Application Service Data Unit (ASDU).
|
||||
*/
|
||||
typedef struct sSVPublisher_ASDU* SVPublisher_ASDU;
|
||||
typedef struct sSV_ASDU* SV_ASDU;
|
||||
|
||||
/**
|
||||
* \brief Create a new IEC61850-9-2 Sampled Values publisher.
|
||||
*
|
||||
* \param[in] interfaceId the name of the interface over which the SV publisher should send SV packets.
|
||||
* \param[in] parameters optional parameters for setting VLAN options and destination MAC address. Use NULL for default values.
|
||||
* \return the new SV publisher instance.
|
||||
*/
|
||||
SVPublisher
|
||||
SVPublisher_create(CommParameters* parameters, const char* interfaceId);
|
||||
SampledValuesPublisher
|
||||
SampledValuesPublisher_create(CommParameters* parameters, const char* interfaceId);
|
||||
|
||||
/**
|
||||
* \brief Create an Application Service Data Unit (ASDU) and add it to an existing Sampled Values publisher.
|
||||
*
|
||||
* \param[in] svID
|
||||
* \param[in] datset
|
||||
* \param[in] confRev Configuration revision number. Should be incremented each time that the configuration of the logical device changes.
|
||||
* \return the new ASDU instance.
|
||||
*/
|
||||
SVPublisher_ASDU
|
||||
SVPublisher_addASDU(SVPublisher self, const char* svID, const char* datset, uint32_t confRev);
|
||||
SV_ASDU
|
||||
SampledValuesPublisher_addASDU(SampledValuesPublisher self, char* svID, char* datset, uint32_t confRev);
|
||||
|
||||
/**
|
||||
* \brief Prepare the publisher for publishing.
|
||||
*
|
||||
* This method must be called before SVPublisher_publish().
|
||||
*
|
||||
* \param[in] self the Sampled Values publisher instance.
|
||||
*/
|
||||
void
|
||||
SVPublisher_setupComplete(SVPublisher self);
|
||||
SampledValuesPublisher_setupComplete(SampledValuesPublisher self);
|
||||
|
||||
/**
|
||||
* \brief Publish all registered ASDUs
|
||||
*
|
||||
* \param[in] self the Sampled Values publisher instance.
|
||||
*/
|
||||
void
|
||||
SVPublisher_publish(SVPublisher self);
|
||||
SampledValuesPublisher_publish(SampledValuesPublisher self);
|
||||
|
||||
/**
|
||||
* \brief Destroy an IEC61850-9-2 Sampled Values instance.
|
||||
*
|
||||
* \param[in] self the Sampled Values publisher instance.
|
||||
*/
|
||||
void
|
||||
SVPublisher_destroy(SVPublisher self);
|
||||
SampledValuesPublisher_destroy(SampledValuesPublisher self);
|
||||
|
||||
/**
|
||||
* \addtogroup sv_publisher_asdu_group Values Application Service Data Unit (ASDU)
|
||||
* @{
|
||||
*/
|
||||
|
||||
/**
|
||||
* \brief Reset the internal data buffer of an ASDU.
|
||||
*
|
||||
* All data elements added by SVPublisher_ASDU_add*() functions are removed.
|
||||
* SVPublisher_setupComplete() must be called afterwards.
|
||||
*
|
||||
* \param[in] self the Sampled Values ASDU instance.
|
||||
*/
|
||||
void
|
||||
SVPublisher_ASDU_resetBuffer(SVPublisher_ASDU self);
|
||||
SV_ASDU_resetBuffer(SV_ASDU self);
|
||||
|
||||
/**
|
||||
* \brief Reserve memory for a signed 8-bit integer in the ASDU.
|
||||
*
|
||||
* \param[in] self the Sampled Values ASDU instance.
|
||||
* \return the offset in bytes within the ASDU data block.
|
||||
*/
|
||||
int
|
||||
SVPublisher_ASDU_addINT8(SVPublisher_ASDU self);
|
||||
SV_ASDU_addINT8(SV_ASDU self);
|
||||
|
||||
/**
|
||||
* \brief Set the value of a 8-bit integer in the ASDU.
|
||||
*
|
||||
* \param[in] self the Sampled Values ASDU instance.
|
||||
* \param[in] index The offset within the data block of the ASDU in bytes.
|
||||
* \param[in] value The value which should be set.
|
||||
*/
|
||||
void
|
||||
SVPublisher_ASDU_setINT8(SVPublisher_ASDU self, int index, int8_t value);
|
||||
SV_ASDU_setINT8(SV_ASDU self, int index, int8_t value);
|
||||
|
||||
/**
|
||||
* \brief Reserve memory for a signed 32-bit integer in the ASDU.
|
||||
*
|
||||
* \param[in] self the Sampled Values ASDU instance.
|
||||
* \return the offset in bytes within the ASDU data block.
|
||||
*/
|
||||
int
|
||||
SVPublisher_ASDU_addINT32(SVPublisher_ASDU self);
|
||||
SV_ASDU_addINT32(SV_ASDU self);
|
||||
|
||||
/**
|
||||
* \brief Set the value of a 32-bit integer in the ASDU.
|
||||
*
|
||||
* \param[in] self the Sampled Values ASDU instance.
|
||||
* \param[in] index The offset within the data block of the ASDU in bytes.
|
||||
* \param[in] value The value which should be set.
|
||||
*/
|
||||
void
|
||||
SVPublisher_ASDU_setINT32(SVPublisher_ASDU self, int index, int32_t value);
|
||||
SV_ASDU_setINT32(SV_ASDU self, int index, int32_t value);
|
||||
|
||||
/**
|
||||
* \brief Reserve memory for a signed 64-bit integer in the ASDU.
|
||||
*
|
||||
* \param[in] self the Sampled Values ASDU instance.
|
||||
* \return the offset in bytes of the new element within the ASDU data block.
|
||||
*/
|
||||
int
|
||||
SVPublisher_ASDU_addINT64(SVPublisher_ASDU self);
|
||||
SV_ASDU_addFLOAT(SV_ASDU self);
|
||||
|
||||
/**
|
||||
* \brief Set the value of a 64-bit integer in the ASDU.
|
||||
*
|
||||
* \param[in] self the Sampled Values ASDU instance.
|
||||
* \param[in] index The offset within the data block of the ASDU in bytes.
|
||||
* \param[in] value The value which should be set.
|
||||
*/
|
||||
void
|
||||
SVPublisher_ASDU_setINT64(SVPublisher_ASDU self, int index, int64_t value);
|
||||
SV_ASDU_setFLOAT(SV_ASDU self, int index, float value);
|
||||
|
||||
/**
|
||||
* \brief Reserve memory for a single precission floating point number in the ASDU.
|
||||
*
|
||||
* \param[in] self the Sampled Values ASDU instance.
|
||||
* \return the offset in bytes of the new element within the ASDU data block.
|
||||
*/
|
||||
int
|
||||
SVPublisher_ASDU_addFLOAT(SVPublisher_ASDU self);
|
||||
SV_ASDU_addFLOAT64(SV_ASDU self);
|
||||
|
||||
/**
|
||||
* \brief Set the value of a single precission floating point number in the ASDU.
|
||||
*
|
||||
* \param[in] self the Sampled Values ASDU instance.
|
||||
* \param[in] index The offset within the data block of the ASDU in bytes.
|
||||
* \param[in] value The value which should be set.
|
||||
*/
|
||||
void
|
||||
SVPublisher_ASDU_setFLOAT(SVPublisher_ASDU self, int index, float value);
|
||||
SV_ASDU_setFLOAT64(SV_ASDU self, int index, double value);
|
||||
|
||||
/**
|
||||
* \brief Reserve memory for a double precission floating point number in the ASDU.
|
||||
*
|
||||
* \param[in] self the Sampled Values ASDU instance.
|
||||
* \return the offset in bytes of the new element within the ASDU data block.
|
||||
*/
|
||||
int
|
||||
SVPublisher_ASDU_addFLOAT64(SVPublisher_ASDU self);
|
||||
|
||||
/**
|
||||
* \brief Set the value of a double precission floating pointer number in the ASDU.
|
||||
*
|
||||
* \param[in] self the Sampled Values ASDU instance.
|
||||
* \param[in] index The offset within the data block of the ASDU in bytes.
|
||||
* \param[in] value The value which should be set.
|
||||
*/
|
||||
void
|
||||
SVPublisher_ASDU_setFLOAT64(SVPublisher_ASDU self, int index, double value);
|
||||
SV_ASDU_setSmpCnt(SV_ASDU self, uint16_t value);
|
||||
|
||||
/**
|
||||
* \brief Set the sample count attribute of the ASDU.
|
||||
*
|
||||
* \param[in] self the Sampled Values ASDU instance.
|
||||
* \param[in] value the new value of the attribute.
|
||||
*/
|
||||
void
|
||||
SVPublisher_ASDU_setSmpCnt(SVPublisher_ASDU self, uint16_t value);
|
||||
|
||||
/**
|
||||
* \brief Get the sample count attribute of the ASDU.
|
||||
*
|
||||
* \param[in] self the Sampled Values ASDU instance.
|
||||
*/
|
||||
uint16_t
|
||||
SVPublisher_ASDU_getSmpCnt(SVPublisher_ASDU self);
|
||||
SV_ASDU_getSmpCnt(SV_ASDU self);
|
||||
|
||||
/**
|
||||
* \brief Increment the sample count attribute of the ASDU.
|
||||
*
|
||||
* The parameter SmpCnt shall contain the values of a counter, which is incremented each time a new sample of the analogue value is taken.
|
||||
* The sample values shall be kept in the right order.
|
||||
* If the counter is used to indicate time consistency of various sampled values, the counter shall be reset by an external synchronization event.
|
||||
*
|
||||
* \param[in] self the Sampled Values ASDU instance.
|
||||
*/
|
||||
void
|
||||
SVPublisher_ASDU_increaseSmpCnt(SVPublisher_ASDU self);
|
||||
SV_ASDU_increaseSmpCnt(SV_ASDU self);
|
||||
|
||||
/**
|
||||
* \brief Set the refresh time attribute of the ASDU.
|
||||
*
|
||||
* \param[in] self the Sampled Values ASDU instance.
|
||||
*/
|
||||
void
|
||||
SVPublisher_ASDU_setRefrTm(SVPublisher_ASDU self, uint64_t refrTm);
|
||||
SV_ASDU_setRefrTm(SV_ASDU self, uint64_t refrTm);
|
||||
|
||||
/**
|
||||
* \brief Set the sample mode attribute of the ASDU.
|
||||
* \brief Set the sample mode of the ASDU
|
||||
*
|
||||
* The attribute SmpMod shall specify if the sample rate is defined in units of samples per nominal period, samples per second or seconds per sample.
|
||||
* If it is missing, the default value is samples per period.
|
||||
* If not set the transmitted ASDU will not contain an sampleMod value
|
||||
*
|
||||
* \param self the SV_ASDU
|
||||
*
|
||||
* \param[in] self the Sampled Values ASDU instance.
|
||||
* \param smpMod one of IEC61850_SV_SMPMOD_PER_NOMINAL_PERIOD, IEC61850_SV_SMPMOD_SAMPLES_PER_SECOND or IEC61850_SV_SMPMOD_SECONDS_PER_SAMPLE
|
||||
*/
|
||||
void
|
||||
SVPublisher_ASDU_setSmpMod(SVPublisher_ASDU self, uint8_t smpMod);
|
||||
|
||||
/**
|
||||
* \brief Set the sample rate attribute of the ASDU.
|
||||
*
|
||||
* The attribute SmpRate shall specify the sample rate.
|
||||
* The value shall be interpreted depending on the value of the SmpMod attribute.
|
||||
*
|
||||
* \param[in] self the Sampled Values ASDU instance.
|
||||
* \param smpRate Amount of samples (default per nominal period, see SmpMod).
|
||||
*/
|
||||
void
|
||||
SVPublisher_ASDU_setSmpRate(SVPublisher_ASDU self, uint16_t smpRate);
|
||||
|
||||
/**@} @}*/
|
||||
SV_ASDU_setSmpMod(SV_ASDU self, uint8_t smpMod);
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#include "sv_publisher_deprecated.h"
|
||||
|
||||
#endif /* LIBIEC61850_SRC_SAMPLED_VALUES_SV_PUBLISHER_H_ */
|
||||
|
|
|
@ -1,211 +0,0 @@
|
|||
/*
|
||||
* sv_publisher.h
|
||||
*
|
||||
* Copyright 2016 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.
|
||||
*/
|
||||
|
||||
|
||||
#ifndef LIBIEC61850_SRC_SAMPLED_VALUES_SV_PUBLISHER_DEPRECATED_H_
|
||||
#define LIBIEC61850_SRC_SAMPLED_VALUES_SV_PUBLISHER_DEPRECATED_H_
|
||||
|
||||
#include "libiec61850_platform_includes.h"
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
#if defined(__GNUC__) || defined(__clang__)
|
||||
#define DEPRECATED __attribute__((deprecated))
|
||||
#else
|
||||
#define DEPRECATED
|
||||
#endif
|
||||
|
||||
/**
|
||||
* \addtogroup sv_publisher_deprecated_api_group Deprecated API
|
||||
* \ingroup sv_publisher_api_group IEC 61850 Sampled Values (SV) publisher API
|
||||
* \deprecated
|
||||
* @{
|
||||
*/
|
||||
|
||||
typedef DEPRECATED struct sSVPublisher* SampledValuesPublisher;
|
||||
|
||||
typedef DEPRECATED struct sSV_ASDU* SV_ASDU;
|
||||
|
||||
static DEPRECATED
|
||||
SVPublisher
|
||||
SampledValuesPublisher_create(CommParameters* parameters, const char* interfaceId)
|
||||
{
|
||||
return SVPublisher_create(parameters, interfaceId);
|
||||
}
|
||||
|
||||
static DEPRECATED
|
||||
SVPublisher_ASDU
|
||||
SampledValuesPublisher_addASDU(SVPublisher self, char* svID, char* datset, uint32_t confRev)
|
||||
{
|
||||
return SVPublisher_addASDU(self, svID, datset, confRev);
|
||||
}
|
||||
|
||||
static DEPRECATED
|
||||
void
|
||||
SampledValuesPublisher_setupComplete(SVPublisher self)
|
||||
{
|
||||
SVPublisher_setupComplete(self);
|
||||
}
|
||||
|
||||
static DEPRECATED
|
||||
void
|
||||
SampledValuesPublisher_publish(SVPublisher self)
|
||||
{
|
||||
SVPublisher_publish(self);
|
||||
}
|
||||
|
||||
static DEPRECATED
|
||||
void
|
||||
SampledValuesPublisher_destroy(SVPublisher self)
|
||||
{
|
||||
SVPublisher_destroy(self);
|
||||
}
|
||||
|
||||
static DEPRECATED
|
||||
void
|
||||
SV_ASDU_resetBuffer(SVPublisher_ASDU self)
|
||||
{
|
||||
SVPublisher_ASDU_resetBuffer(self);
|
||||
}
|
||||
|
||||
static DEPRECATED
|
||||
int
|
||||
SV_ASDU_addINT8(SVPublisher_ASDU self)
|
||||
{
|
||||
return SVPublisher_ASDU_addINT8(self);
|
||||
}
|
||||
|
||||
static DEPRECATED
|
||||
void
|
||||
SV_ASDU_setINT8(SVPublisher_ASDU self, int index, int8_t value)
|
||||
{
|
||||
SVPublisher_ASDU_setINT8(self, index, value);
|
||||
}
|
||||
|
||||
static DEPRECATED
|
||||
int
|
||||
SV_ASDU_addINT32(SVPublisher_ASDU self)
|
||||
{
|
||||
return SVPublisher_ASDU_addINT32(self);
|
||||
}
|
||||
|
||||
static DEPRECATED
|
||||
void
|
||||
SV_ASDU_setINT32(SVPublisher_ASDU self, int index, int32_t value)
|
||||
{
|
||||
SVPublisher_ASDU_setINT32(self, index, value);
|
||||
}
|
||||
|
||||
static DEPRECATED
|
||||
int
|
||||
SV_ASDU_addINT64(SVPublisher_ASDU self)
|
||||
{
|
||||
return SVPublisher_ASDU_addINT64(self);
|
||||
}
|
||||
|
||||
static DEPRECATED
|
||||
void
|
||||
SV_ASDU_setINT64(SVPublisher_ASDU self, int index, int64_t value)
|
||||
{
|
||||
SVPublisher_ASDU_setINT64(self, index, value);
|
||||
}
|
||||
|
||||
static DEPRECATED
|
||||
int
|
||||
SV_ASDU_addFLOAT(SVPublisher_ASDU self)
|
||||
{
|
||||
return SVPublisher_ASDU_addFLOAT(self);
|
||||
}
|
||||
|
||||
static DEPRECATED
|
||||
void
|
||||
SV_ASDU_setFLOAT(SVPublisher_ASDU self, int index, float value)
|
||||
{
|
||||
SVPublisher_ASDU_setFLOAT(self, index, value);
|
||||
}
|
||||
|
||||
static DEPRECATED
|
||||
int
|
||||
SV_ASDU_addFLOAT64(SVPublisher_ASDU self)
|
||||
{
|
||||
return SVPublisher_ASDU_addFLOAT64(self);
|
||||
}
|
||||
|
||||
static DEPRECATED
|
||||
void
|
||||
SV_ASDU_setFLOAT64(SVPublisher_ASDU self, int index, double value)
|
||||
{
|
||||
SVPublisher_ASDU_setFLOAT64(self, index, value);
|
||||
}
|
||||
|
||||
static DEPRECATED
|
||||
void
|
||||
SV_ASDU_setSmpCnt(SVPublisher_ASDU self, uint16_t value)
|
||||
{
|
||||
SVPublisher_ASDU_setSmpCnt(self, value);
|
||||
}
|
||||
|
||||
static DEPRECATED
|
||||
uint16_t
|
||||
SV_ASDU_getSmpCnt(SVPublisher_ASDU self)
|
||||
{
|
||||
return SVPublisher_ASDU_getSmpCnt(self);
|
||||
}
|
||||
|
||||
static DEPRECATED
|
||||
void
|
||||
SV_ASDU_increaseSmpCnt(SVPublisher_ASDU self)
|
||||
{
|
||||
SVPublisher_ASDU_increaseSmpCnt(self);
|
||||
}
|
||||
|
||||
static DEPRECATED
|
||||
void
|
||||
SV_ASDU_setRefrTm(SVPublisher_ASDU self, uint64_t refrTm)
|
||||
{
|
||||
SVPublisher_ASDU_setRefrTm(self, refrTm);
|
||||
}
|
||||
|
||||
static DEPRECATED
|
||||
void
|
||||
SV_ASDU_setSmpMod(SVPublisher_ASDU self, uint8_t smpMod)
|
||||
{
|
||||
SVPublisher_ASDU_setSmpMod(self, smpMod);
|
||||
}
|
||||
|
||||
static DEPRECATED
|
||||
void
|
||||
SV_ASDU_setSmpRate(SVPublisher_ASDU self, uint16_t smpRate)
|
||||
{
|
||||
SVPublisher_ASDU_setSmpRate(self, smpRate);
|
||||
}
|
||||
|
||||
/**@}*/
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif /* LIBIEC61850_SRC_SAMPLED_VALUES_SV_PUBLISHER_DEPRECATED_H_ */
|
|
@ -50,13 +50,7 @@ struct sSVReceiver {
|
|||
|
||||
uint8_t* buffer;
|
||||
EthernetSocket ethSocket;
|
||||
|
||||
LinkedList subscriberList;
|
||||
|
||||
#if (CONFIG_MMS_THREADLESS_STACK == 0)
|
||||
Semaphore subscriberListLock;
|
||||
#endif
|
||||
|
||||
};
|
||||
|
||||
struct sSVSubscriber {
|
||||
|
@ -67,23 +61,23 @@ struct sSVSubscriber {
|
|||
void* listenerParameter;
|
||||
};
|
||||
|
||||
struct sSVSubscriber_ASDU {
|
||||
struct sSVClientASDU {
|
||||
|
||||
char* svId;
|
||||
char* datSet;
|
||||
|
||||
uint8_t* smpCnt;
|
||||
uint8_t* confRev;
|
||||
uint8_t* refrTm;
|
||||
uint8_t* smpSynch;
|
||||
uint8_t* smpMod;
|
||||
uint8_t* smpRate;
|
||||
|
||||
|
||||
int dataBufferLength;
|
||||
uint8_t* dataBuffer;
|
||||
};
|
||||
|
||||
|
||||
|
||||
|
||||
SVReceiver
|
||||
SVReceiver_create(void)
|
||||
{
|
||||
|
@ -94,10 +88,6 @@ SVReceiver_create(void)
|
|||
self->buffer = (uint8_t*) GLOBAL_MALLOC(ETH_BUFFER_LENGTH);
|
||||
|
||||
self->checkDestAddr = false;
|
||||
|
||||
#if (CONFIG_MMS_THREADLESS_STACK == 0)
|
||||
self->subscriberListLock = Semaphore_create(1);
|
||||
#endif
|
||||
}
|
||||
|
||||
return self;
|
||||
|
@ -121,29 +111,13 @@ SVReceiver_disableDestAddrCheck(SVReceiver self)
|
|||
void
|
||||
SVReceiver_addSubscriber(SVReceiver self, SVSubscriber subscriber)
|
||||
{
|
||||
#if (CONFIG_MMS_THREADLESS_STACK == 0)
|
||||
Semaphore_wait(self->subscriberListLock);
|
||||
#endif
|
||||
|
||||
LinkedList_add(self->subscriberList, (void*) subscriber);
|
||||
|
||||
#if (CONFIG_MMS_THREADLESS_STACK == 0)
|
||||
Semaphore_post(self->subscriberListLock);
|
||||
#endif
|
||||
}
|
||||
|
||||
void
|
||||
SVReceiver_removeSubscriber(SVReceiver self, SVSubscriber subscriber)
|
||||
{
|
||||
#if (CONFIG_MMS_THREADLESS_STACK == 0)
|
||||
Semaphore_wait(self->subscriberListLock);
|
||||
#endif
|
||||
|
||||
LinkedList_remove(self->subscriberList, (void*) subscriber);
|
||||
|
||||
#if (CONFIG_MMS_THREADLESS_STACK == 0)
|
||||
Semaphore_post(self->subscriberListLock);
|
||||
#endif
|
||||
}
|
||||
|
||||
static void
|
||||
|
@ -200,15 +174,11 @@ SVReceiver_destroy(SVReceiver self)
|
|||
LinkedList_destroyDeep(self->subscriberList,
|
||||
(LinkedListValueDeleteFunction) SVSubscriber_destroy);
|
||||
|
||||
#if (CONFIG_MMS_THREADLESS_STACK == 0)
|
||||
Semaphore_destroy(self->subscriberListLock);
|
||||
#endif
|
||||
|
||||
GLOBAL_FREEMEM(self->buffer);
|
||||
GLOBAL_FREEMEM(self);
|
||||
}
|
||||
|
||||
EthernetSocket
|
||||
void
|
||||
SVReceiver_startThreadless(SVReceiver self)
|
||||
{
|
||||
if (self->interfaceId == NULL)
|
||||
|
@ -219,8 +189,6 @@ SVReceiver_startThreadless(SVReceiver self)
|
|||
Ethernet_setProtocolFilter(self->ethSocket, ETH_P_SV);
|
||||
|
||||
self->running = true;
|
||||
|
||||
return self->ethSocket;
|
||||
}
|
||||
|
||||
void
|
||||
|
@ -231,15 +199,17 @@ SVReceiver_stopThreadless(SVReceiver self)
|
|||
self->running = false;
|
||||
}
|
||||
|
||||
|
||||
static void
|
||||
parseASDU(SVReceiver self, SVSubscriber subscriber, uint8_t* buffer, int length)
|
||||
{
|
||||
int bufPos = 0;
|
||||
int svIdLength = 0;
|
||||
int datSetLength = 0;
|
||||
|
||||
struct sSVSubscriber_ASDU asdu;
|
||||
memset(&asdu, 0, sizeof(struct sSVSubscriber_ASDU));
|
||||
struct sSVClientASDU asdu;
|
||||
memset(&asdu, 0, sizeof(struct sSVClientASDU));
|
||||
|
||||
int svIdLength = 0;
|
||||
|
||||
|
||||
while (bufPos < length) {
|
||||
int elementLength;
|
||||
|
@ -247,10 +217,6 @@ parseASDU(SVReceiver self, SVSubscriber subscriber, uint8_t* buffer, int length)
|
|||
uint8_t tag = buffer[bufPos++];
|
||||
|
||||
bufPos = BerDecoder_decodeLength(buffer, &elementLength, bufPos, length);
|
||||
if (bufPos < 0) {
|
||||
if (DEBUG_SV_SUBSCRIBER) printf("SV_SUBSCRIBER: Malformed message: failed to decode BER length tag!\n");
|
||||
return;
|
||||
}
|
||||
|
||||
switch (tag) {
|
||||
|
||||
|
@ -259,11 +225,6 @@ parseASDU(SVReceiver self, SVSubscriber subscriber, uint8_t* buffer, int length)
|
|||
svIdLength = elementLength;
|
||||
break;
|
||||
|
||||
case 0x81:
|
||||
asdu.datSet = (char*) (buffer + bufPos);
|
||||
datSetLength = elementLength;
|
||||
break;
|
||||
|
||||
case 0x82:
|
||||
asdu.smpCnt = buffer + bufPos;
|
||||
break;
|
||||
|
@ -280,21 +241,12 @@ parseASDU(SVReceiver self, SVSubscriber subscriber, uint8_t* buffer, int length)
|
|||
asdu.smpSynch = buffer + bufPos;
|
||||
break;
|
||||
|
||||
case 0x86:
|
||||
asdu.smpRate = buffer + bufPos;
|
||||
break;
|
||||
|
||||
case 0x87:
|
||||
asdu.dataBuffer = buffer + bufPos;
|
||||
asdu.dataBufferLength = elementLength;
|
||||
break;
|
||||
|
||||
case 0x88:
|
||||
asdu.smpMod = buffer + bufPos;
|
||||
break;
|
||||
|
||||
default: /* ignore unknown tag */
|
||||
if (DEBUG_SV_SUBSCRIBER) printf("SV_SUBSCRIBER: found unknown tag %02x\n", tag);
|
||||
break;
|
||||
}
|
||||
|
||||
|
@ -303,25 +255,6 @@ parseASDU(SVReceiver self, SVSubscriber subscriber, uint8_t* buffer, int length)
|
|||
|
||||
if (asdu.svId != NULL)
|
||||
asdu.svId[svIdLength] = 0;
|
||||
if (asdu.datSet != NULL)
|
||||
asdu.datSet[datSetLength] = 0;
|
||||
|
||||
if (DEBUG_SV_SUBSCRIBER) {
|
||||
printf("SV_SUBSCRIBER: SV ASDU: ----------------\n");
|
||||
printf("SV_SUBSCRIBER: DataLength: %d\n", asdu.dataBufferLength);
|
||||
printf("SV_SUBSCRIBER: SvId: %s\n", asdu.svId);
|
||||
printf("SV_SUBSCRIBER: SmpCnt: %d\n", SVSubscriber_ASDU_getSmpCnt(&asdu));
|
||||
printf("SV_SUBSCRIBER: ConfRev: %d\n", SVSubscriber_ASDU_getConfRev(&asdu));
|
||||
|
||||
if (SVSubscriber_ASDU_hasDatSet(&asdu))
|
||||
printf("SV_SUBSCRIBER: DatSet: %s\n", asdu.datSet);
|
||||
if (SVSubscriber_ASDU_hasRefrTm(&asdu))
|
||||
printf("SV_SUBSCRIBER: RefrTm: %lu\n", SVSubscriber_ASDU_getRefrTmAsMs(&asdu));
|
||||
if (SVSubscriber_ASDU_hasSmpMod(&asdu))
|
||||
printf("SV_SUBSCRIBER: SmpMod: %d\n", SVSubscriber_ASDU_getSmpMod(&asdu));
|
||||
if (SVSubscriber_ASDU_hasSmpRate(&asdu))
|
||||
printf("SV_SUBSCRIBER: SmpRate: %d\n", SVSubscriber_ASDU_getSmpRate(&asdu));
|
||||
}
|
||||
|
||||
/* Call callback handler */
|
||||
if (subscriber->listener != NULL)
|
||||
|
@ -339,10 +272,6 @@ parseSequenceOfASDU(SVReceiver self, SVSubscriber subscriber, uint8_t* buffer, i
|
|||
uint8_t tag = buffer[bufPos++];
|
||||
|
||||
bufPos = BerDecoder_decodeLength(buffer, &elementLength, bufPos, length);
|
||||
if (bufPos < 0) {
|
||||
if (DEBUG_SV_SUBSCRIBER) printf("SV_SUBSCRIBER: Malformed message: failed to decode BER length tag!\n");
|
||||
return;
|
||||
}
|
||||
|
||||
switch (tag) {
|
||||
case 0x30:
|
||||
|
@ -350,7 +279,6 @@ parseSequenceOfASDU(SVReceiver self, SVSubscriber subscriber, uint8_t* buffer, i
|
|||
break;
|
||||
|
||||
default: /* ignore unknown tag */
|
||||
if (DEBUG_SV_SUBSCRIBER) printf("SV_SUBSCRIBER: found unknown tag %02x\n", tag);
|
||||
break;
|
||||
}
|
||||
|
||||
|
@ -367,10 +295,6 @@ parseSVPayload(SVReceiver self, SVSubscriber subscriber, uint8_t* buffer, int ap
|
|||
int elementLength;
|
||||
|
||||
bufPos = BerDecoder_decodeLength(buffer, &elementLength, bufPos, apduLength);
|
||||
if (bufPos < 0) {
|
||||
if (DEBUG_SV_SUBSCRIBER) printf("SV_SUBSCRIBER: Malformed message: failed to decode BER length tag!\n");
|
||||
return;
|
||||
}
|
||||
|
||||
int svEnd = bufPos + elementLength;
|
||||
|
||||
|
@ -378,10 +302,6 @@ parseSVPayload(SVReceiver self, SVSubscriber subscriber, uint8_t* buffer, int ap
|
|||
uint8_t tag = buffer[bufPos++];
|
||||
|
||||
bufPos = BerDecoder_decodeLength(buffer, &elementLength, bufPos, svEnd);
|
||||
if (bufPos < 0) {
|
||||
if (DEBUG_SV_SUBSCRIBER) printf("SV_SUBSCRIBER: Malformed message: failed to decode BER length tag!\n");
|
||||
return;
|
||||
}
|
||||
|
||||
if (bufPos + elementLength > apduLength) {
|
||||
if (DEBUG_SV_SUBSCRIBER)
|
||||
|
@ -403,7 +323,6 @@ parseSVPayload(SVReceiver self, SVSubscriber subscriber, uint8_t* buffer, int ap
|
|||
break;
|
||||
|
||||
default: /* ignore unknown tag */
|
||||
if (DEBUG_SV_SUBSCRIBER) printf("SV_SUBSCRIBER: found unknown tag %02x\n", tag);
|
||||
break;
|
||||
}
|
||||
|
||||
|
@ -479,11 +398,6 @@ parseSVMessage(SVReceiver self, int numbytes)
|
|||
|
||||
|
||||
/* check if there is a matching subscriber */
|
||||
|
||||
#if (CONFIG_MMS_THREADLESS_STACK == 0)
|
||||
Semaphore_wait(self->subscriberListLock);
|
||||
#endif
|
||||
|
||||
LinkedList element = LinkedList_getNext(self->subscriberList);
|
||||
|
||||
SVSubscriber subscriber;
|
||||
|
@ -513,10 +427,6 @@ parseSVMessage(SVReceiver self, int numbytes)
|
|||
element = LinkedList_getNext(element);
|
||||
}
|
||||
|
||||
#if (CONFIG_MMS_THREADLESS_STACK == 0)
|
||||
Semaphore_post(self->subscriberListLock);
|
||||
#endif
|
||||
|
||||
|
||||
if (subscriberFound)
|
||||
parseSVPayload(self, subscriber, buffer + bufPos, apduLength);
|
||||
|
@ -570,7 +480,7 @@ SVSubscriber_setListener(SVSubscriber self, SVUpdateListener listener, void* pa
|
|||
}
|
||||
|
||||
uint16_t
|
||||
SVSubscriber_ASDU_getSmpCnt(SVSubscriber_ASDU self)
|
||||
SVClientASDU_getSmpCnt(SVClientASDU self)
|
||||
{
|
||||
uint16_t retVal;
|
||||
uint8_t* valBytes = (uint8_t*) &retVal;
|
||||
|
@ -615,7 +525,7 @@ decodeUtcTime(uint8_t* buffer, uint8_t* timeQuality)
|
|||
}
|
||||
|
||||
uint64_t
|
||||
SVSubscriber_ASDU_getRefrTmAsMs(SVSubscriber_ASDU self)
|
||||
SVClientASDU_getRefrTmAsMs(SVClientASDU self)
|
||||
{
|
||||
uint64_t msTime = 0;
|
||||
|
||||
|
@ -626,43 +536,20 @@ SVSubscriber_ASDU_getRefrTmAsMs(SVSubscriber_ASDU self)
|
|||
}
|
||||
|
||||
bool
|
||||
SVSubscriber_ASDU_hasRefrTm(SVSubscriber_ASDU self)
|
||||
SVClientASDU_hasRefrTm(SVClientASDU self)
|
||||
{
|
||||
return (self->refrTm != NULL);
|
||||
}
|
||||
|
||||
bool
|
||||
SVSubscriber_ASDU_hasDatSet(SVSubscriber_ASDU self)
|
||||
{
|
||||
return (self->datSet != NULL);
|
||||
}
|
||||
|
||||
bool
|
||||
SVSubscriber_ASDU_hasSmpRate(SVSubscriber_ASDU self)
|
||||
{
|
||||
return (self->smpRate != NULL);
|
||||
}
|
||||
|
||||
bool
|
||||
SVSubscriber_ASDU_hasSmpMod(SVSubscriber_ASDU self)
|
||||
{
|
||||
return (self->smpMod != NULL);
|
||||
}
|
||||
|
||||
const char*
|
||||
SVSubscriber_ASDU_getSvId(SVSubscriber_ASDU self)
|
||||
SVClientASDU_getSvId(SVClientASDU self)
|
||||
{
|
||||
return self->svId;
|
||||
}
|
||||
|
||||
const char*
|
||||
SVSubscriber_ASDU_getDatSet(SVSubscriber_ASDU self)
|
||||
{
|
||||
return self->datSet;
|
||||
}
|
||||
|
||||
uint32_t
|
||||
SVSubscriber_ASDU_getConfRev(SVSubscriber_ASDU self)
|
||||
SVClientASDU_getConfRev(SVClientASDU self)
|
||||
{
|
||||
uint32_t retVal = *((uint32_t*) (self->confRev));
|
||||
|
||||
|
@ -675,30 +562,8 @@ SVSubscriber_ASDU_getConfRev(SVSubscriber_ASDU self)
|
|||
return retVal;
|
||||
}
|
||||
|
||||
uint8_t
|
||||
SVSubscriber_ASDU_getSmpMod(SVSubscriber_ASDU self)
|
||||
{
|
||||
uint8_t retVal = *((uint8_t*) (self->smpMod));
|
||||
|
||||
return retVal;
|
||||
}
|
||||
|
||||
uint16_t
|
||||
SVSubscriber_ASDU_getSmpRate(SVSubscriber_ASDU self)
|
||||
{
|
||||
uint16_t retVal = *((uint16_t*) (self->smpRate));
|
||||
|
||||
#if (ORDER_LITTLE_ENDIAN == 1)
|
||||
uint8_t* buf = (uint8_t*) (&retVal);
|
||||
|
||||
BerEncoder_revertByteOrder(buf, 2);
|
||||
#endif
|
||||
|
||||
return retVal;
|
||||
}
|
||||
|
||||
int8_t
|
||||
SVSubscriber_ASDU_getINT8(SVSubscriber_ASDU self, int index)
|
||||
SVClientASDU_getINT8(SVClientASDU self, int index)
|
||||
{
|
||||
int8_t retVal = *((int8_t*) (self->dataBuffer + index));
|
||||
|
||||
|
@ -706,7 +571,7 @@ SVSubscriber_ASDU_getINT8(SVSubscriber_ASDU self, int index)
|
|||
}
|
||||
|
||||
int16_t
|
||||
SVSubscriber_ASDU_getINT16(SVSubscriber_ASDU self, int index)
|
||||
SVClientASDU_getINT16(SVClientASDU self, int index)
|
||||
{
|
||||
int16_t retVal = *((int16_t*) (self->dataBuffer + index));
|
||||
|
||||
|
@ -720,7 +585,7 @@ SVSubscriber_ASDU_getINT16(SVSubscriber_ASDU self, int index)
|
|||
}
|
||||
|
||||
int32_t
|
||||
SVSubscriber_ASDU_getINT32(SVSubscriber_ASDU self, int index)
|
||||
SVClientASDU_getINT32(SVClientASDU self, int index)
|
||||
{
|
||||
int32_t retVal = *((int32_t*) (self->dataBuffer + index));
|
||||
|
||||
|
@ -733,22 +598,8 @@ SVSubscriber_ASDU_getINT32(SVSubscriber_ASDU self, int index)
|
|||
return retVal;
|
||||
}
|
||||
|
||||
int64_t
|
||||
SVSubscriber_ASDU_getINT64(SVSubscriber_ASDU self, int index)
|
||||
{
|
||||
int64_t retVal = *((int64_t*) (self->dataBuffer + index));
|
||||
|
||||
#if (ORDER_LITTLE_ENDIAN == 1)
|
||||
uint8_t* buf = (uint8_t*) (&retVal);
|
||||
|
||||
BerEncoder_revertByteOrder(buf, 8);
|
||||
#endif
|
||||
|
||||
return retVal;
|
||||
}
|
||||
|
||||
uint8_t
|
||||
SVSubscriber_ASDU_getINT8U(SVSubscriber_ASDU self, int index)
|
||||
SVClientASDU_getINT8U(SVClientASDU self, int index)
|
||||
{
|
||||
uint8_t retVal = *((uint8_t*) (self->dataBuffer + index));
|
||||
|
||||
|
@ -756,7 +607,7 @@ SVSubscriber_ASDU_getINT8U(SVSubscriber_ASDU self, int index)
|
|||
}
|
||||
|
||||
uint16_t
|
||||
SVSubscriber_ASDU_getINT16U(SVSubscriber_ASDU self, int index)
|
||||
SVClientASDU_getINT16U(SVClientASDU self, int index)
|
||||
{
|
||||
uint16_t retVal = *((uint16_t*) (self->dataBuffer + index));
|
||||
|
||||
|
@ -770,7 +621,7 @@ SVSubscriber_ASDU_getINT16U(SVSubscriber_ASDU self, int index)
|
|||
}
|
||||
|
||||
uint32_t
|
||||
SVSubscriber_ASDU_getINT32U(SVSubscriber_ASDU self, int index)
|
||||
SVClientASDU_getINT32U(SVClientASDU self, int index)
|
||||
{
|
||||
uint32_t retVal = *((uint32_t*) (self->dataBuffer + index));
|
||||
|
||||
|
@ -783,22 +634,9 @@ SVSubscriber_ASDU_getINT32U(SVSubscriber_ASDU self, int index)
|
|||
return retVal;
|
||||
}
|
||||
|
||||
uint64_t
|
||||
SVSubscriber_ASDU_getINT64U(SVSubscriber_ASDU self, int index)
|
||||
{
|
||||
uint64_t retVal = *((uint64_t*) (self->dataBuffer + index));
|
||||
|
||||
#if (ORDER_LITTLE_ENDIAN == 1)
|
||||
uint8_t* buf = (uint8_t*) (&retVal);
|
||||
|
||||
BerEncoder_revertByteOrder(buf, 8);
|
||||
#endif
|
||||
|
||||
return retVal;
|
||||
}
|
||||
|
||||
float
|
||||
SVSubscriber_ASDU_getFLOAT32(SVSubscriber_ASDU self, int index)
|
||||
SVClientASDU_getFLOAT32(SVClientASDU self, int index)
|
||||
{
|
||||
float retVal = *((float*) (self->dataBuffer + index));
|
||||
|
||||
|
@ -812,7 +650,7 @@ SVSubscriber_ASDU_getFLOAT32(SVSubscriber_ASDU self, int index)
|
|||
}
|
||||
|
||||
double
|
||||
SVSubscriber_ASDU_getFLOAT64(SVSubscriber_ASDU self, int index)
|
||||
SVClientASDU_getFLOAT64(SVClientASDU self, int index)
|
||||
{
|
||||
double retVal = *((double*) (self->dataBuffer + index));
|
||||
|
||||
|
@ -827,7 +665,7 @@ SVSubscriber_ASDU_getFLOAT64(SVSubscriber_ASDU self, int index)
|
|||
|
||||
|
||||
int
|
||||
SVSubscriber_ASDU_getDataSize(SVSubscriber_ASDU self)
|
||||
SVClientASDU_getDataSize(SVClientASDU self)
|
||||
{
|
||||
return self->dataBufferLength;
|
||||
}
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
/*
|
||||
* sv_subscriber.h
|
||||
* sv_subscriber_api.h
|
||||
*
|
||||
* Copyright 2015 Michael Zillgith
|
||||
*
|
||||
|
@ -30,10 +30,8 @@
|
|||
extern "C" {
|
||||
#endif
|
||||
|
||||
typedef struct sEthernetSocket* EthernetSocket;
|
||||
|
||||
/**
|
||||
* \defgroup sv_subscriber_api_group IEC 61850 Sampled Values (SV) subscriber API
|
||||
* \defgroup sv_subscriber_api_group IEC 61850 sampled values (SV) subscriber API
|
||||
*
|
||||
* The sampled values (SV) subscriber API consists of three different objects.
|
||||
* The \ref SVReceiver object is responsible for handling all SV Ethernet messages
|
||||
|
@ -42,37 +40,36 @@ typedef struct sEthernetSocket* EthernetSocket;
|
|||
* An \ref SVSubscriber object is associated to a SV data stream that is identified by its appID
|
||||
* and destination Ethernet address. The \reg SVSubscriber object is used to install a callback
|
||||
* handler \ref SVUpdateListener that is invoked for each ASDU (application service data unit) received for the
|
||||
* associated stream. An \ref SVSubscriber_ASDU is an object that represents a single ASDU. Each ASDU contains
|
||||
* associated stream. An \ref SVClientASDU is an object that represents a single ASDU. Each ASDU contains
|
||||
* some meta information that can be obtained by specific access functions like e.g.
|
||||
* \ref SVSubscriber_ASDU_getSmpCnt to access the "SmpCnt" (sample count) attribute of the ASDU. The actual
|
||||
* \ref SVClientASDU_getSmpCnt to access the "SmpCnt" (sample count) attribute of the ASDU. The actual
|
||||
* measurement data contained in the ASDU does not consist of structured ASN.1 data but stored as raw binary
|
||||
* data. Without a priori knowledge of the dataset associated with the ASDU data stream it is not
|
||||
* possible to interpret the received data correctly. Therefore you have to provide the data access functions
|
||||
* with an index value to indicate the data type and the start of the data in the data block of the ASDU.
|
||||
* E.g. reading a data set consisting of two FLOAT32 values you can use two subsequent calls of
|
||||
* \ref SVSubscriber_ASDU_getFLOAT32 one with index = 0 and the second one with index = 4.
|
||||
* \ref SVClientASDU_getFLOAT32 one with index = 0 and the second one with index = 4.
|
||||
*
|
||||
* | IEC 61850 type | required bytes |
|
||||
* | -------------- | -------------- |
|
||||
* | BOOLEAN | 1 byte |
|
||||
* | INT8 | 1 byte |
|
||||
* | INT16 | 2 byte |
|
||||
* | INT32 | 4 byte |
|
||||
* | INT64 | 8 byte |
|
||||
* | INT8U | 1 byte |
|
||||
* | INT16U | 2 byte |
|
||||
* | INT24U | 3 byte |
|
||||
* | INT32U | 4 byte |
|
||||
* | INT64U | 8 byte |
|
||||
* | FLOAT32 | 4 byte |
|
||||
* | FLOAT64 | 8 byte |
|
||||
* | ENUMERATED | 4 byte |
|
||||
* | CODED ENUM | 4 byte |
|
||||
* | OCTET STRING | 20 byte |
|
||||
* | VISIBLE STRING | 35 byte |
|
||||
* | TimeStamp | 8 byte |
|
||||
* | EntryTime | 6 byte |
|
||||
* | BITSTRING | 4 byte |
|
||||
* | BOOLEAN | 1 byte |
|
||||
* | INT8 | 1 byte |
|
||||
* | INT16 | 2 byte |
|
||||
* | INT32 | 4 byte |
|
||||
* | INT64 | 8 byte |
|
||||
* | INT8U | 1 byte |
|
||||
* | INT16U | 2 byte |
|
||||
* | INT24U | 3 byte |
|
||||
* | INT32U | 4 byte |
|
||||
* | FLOAT32 | 4 byte |
|
||||
* | FLOAT64 | 8 byte |
|
||||
* | ENUMERATED | 4 byte |
|
||||
* | CODED ENUM | 4 byte |
|
||||
* | OCTET STRING | 20 byte |
|
||||
* | VISIBLE STRING | 35 byte |
|
||||
* | TimeStamp | 8 byte |
|
||||
* | EntryTime | 6 byte |
|
||||
* | BITSTRING | 4 byte |
|
||||
*
|
||||
* The SV subscriber API can be used independent of the IEC 61850 client API. In order to access the SVCB via MMS you
|
||||
* have to use the IEC 61850 client API. Please see \ref ClientSVControlBlock object in section \ref IEC61850_CLIENT_SV.
|
||||
|
@ -88,18 +85,18 @@ typedef struct sEthernetSocket* EthernetSocket;
|
|||
* sampled value data. Each ASDU represents a single sample consisting of multiple measurement
|
||||
* values with a single dedicated timestamp.
|
||||
*
|
||||
* NOTE: SVSubscriber_ASDU are statically allocated and are only valid inside of the SVUpdateListener
|
||||
* NOTE: SVClientASDU are statically allocated and are only valid inside of the SVUpdateListener
|
||||
* function when called by the library. If you need the data contained in the ASDU elsewhere
|
||||
* you have to copy and store the data by yourself!
|
||||
*/
|
||||
typedef struct sSVSubscriber_ASDU* SVSubscriber_ASDU;
|
||||
typedef struct sSVClientASDU* SVClientASDU;
|
||||
|
||||
/**
|
||||
* \brief opaque handle to a SV subscriber instance
|
||||
*
|
||||
* A subscriber is an instance associated with a single stream of measurement data. It is identified
|
||||
* by the Ethernet destination address, the appID value (both are on SV message level) and the svID value
|
||||
* that is part of each ASDU (SVSubscriber_ASDU object).
|
||||
* that is part of each ASDU (SVClientASDU object).
|
||||
*/
|
||||
typedef struct sSVSubscriber* SVSubscriber;
|
||||
|
||||
|
@ -112,7 +109,7 @@ typedef struct sSVSubscriber* SVSubscriber;
|
|||
* \param parameter a user provided parameter that is simply passed to the callback
|
||||
* \param asdu SV ASDU data structure. This structure is only valid inside of the callback function
|
||||
*/
|
||||
typedef void (*SVUpdateListener)(SVSubscriber subscriber, void* parameter, SVSubscriber_ASDU asdu);
|
||||
typedef void (*SVUpdateListener)(SVSubscriber subscriber, void* parameter, SVClientASDU asdu);
|
||||
|
||||
/**
|
||||
* \brief opaque handle to a SV receiver instance
|
||||
|
@ -206,21 +203,12 @@ SVReceiver_destroy(SVReceiver self);
|
|||
* Functions for non-threaded operation
|
||||
***************************************/
|
||||
|
||||
EthernetSocket
|
||||
void
|
||||
SVReceiver_startThreadless(SVReceiver self);
|
||||
|
||||
void
|
||||
SVReceiver_stopThreadless(SVReceiver self);
|
||||
|
||||
/**
|
||||
* \brief Parse SV messages if they are available.
|
||||
*
|
||||
* Call after reception of ethernet frame and periodically to to house keeping tasks
|
||||
*
|
||||
* \param self the receiver object
|
||||
*
|
||||
* \return true if a message was available and has been parsed, false otherwise
|
||||
*/
|
||||
bool
|
||||
SVReceiver_tick(SVReceiver self);
|
||||
|
||||
|
@ -250,14 +238,9 @@ void
|
|||
SVSubscriber_destroy(SVSubscriber self);
|
||||
|
||||
/*************************************************************************
|
||||
* SVSubscriber_ASDU object methods
|
||||
* SVClientASDU object methods
|
||||
**************************************************************************/
|
||||
|
||||
/**
|
||||
* \addtogroup sv_subscriber_asdu_group Values Application Service Data Unit (ASDU)
|
||||
* @{
|
||||
*/
|
||||
|
||||
/**
|
||||
* \brief return the SmpCnt value included in the SV ASDU
|
||||
*
|
||||
|
@ -267,7 +250,7 @@ SVSubscriber_destroy(SVSubscriber self);
|
|||
* \param self ASDU object instance
|
||||
*/
|
||||
uint16_t
|
||||
SVSubscriber_ASDU_getSmpCnt(SVSubscriber_ASDU self);
|
||||
SVClientASDU_getSmpCnt(SVClientASDU self);
|
||||
|
||||
/**
|
||||
* \brief return the SvID value included in the SV ASDU
|
||||
|
@ -275,15 +258,7 @@ SVSubscriber_ASDU_getSmpCnt(SVSubscriber_ASDU self);
|
|||
* \param self ASDU object instance
|
||||
*/
|
||||
const char*
|
||||
SVSubscriber_ASDU_getSvId(SVSubscriber_ASDU self);
|
||||
|
||||
/**
|
||||
* \brief return the DatSet value included in the SV ASDU
|
||||
*
|
||||
* \param self ASDU object instance
|
||||
*/
|
||||
const char*
|
||||
SVSubscriber_ASDU_getDatSet(SVSubscriber_ASDU self);
|
||||
SVClientASDU_getSvId(SVClientASDU self);
|
||||
|
||||
/**
|
||||
* \brief return the ConfRev value included in the SV ASDU
|
||||
|
@ -291,33 +266,7 @@ SVSubscriber_ASDU_getDatSet(SVSubscriber_ASDU self);
|
|||
* \param self ASDU object instance
|
||||
*/
|
||||
uint32_t
|
||||
SVSubscriber_ASDU_getConfRev(SVSubscriber_ASDU self);
|
||||
|
||||
/**
|
||||
* \brief return the SmpMod value included in the SV ASDU
|
||||
*
|
||||
* \param self ASDU object instance
|
||||
*/
|
||||
uint8_t
|
||||
SVSubscriber_ASDU_getSmpMod(SVSubscriber_ASDU self);
|
||||
|
||||
/**
|
||||
* \brief return the SmpRate value included in the SV ASDU
|
||||
*
|
||||
* \param self ASDU object instance
|
||||
*/
|
||||
uint16_t
|
||||
SVSubscriber_ASDU_getSmpRate(SVSubscriber_ASDU self);
|
||||
|
||||
/**
|
||||
* \brief Check if DatSet value is included in the SV ASDU
|
||||
*
|
||||
* \param self ASDU object instance
|
||||
*
|
||||
* \return true if DatSet value is present, false otherwise
|
||||
*/
|
||||
bool
|
||||
SVSubscriber_ASDU_hasDatSet(SVSubscriber_ASDU self);
|
||||
SVClientASDU_getConfRev(SVClientASDU self);
|
||||
|
||||
/**
|
||||
* \brief Check if RefrTm value is included in the SV ASDU
|
||||
|
@ -327,27 +276,7 @@ SVSubscriber_ASDU_hasDatSet(SVSubscriber_ASDU self);
|
|||
* \return true if RefrTm value is present, false otherwise
|
||||
*/
|
||||
bool
|
||||
SVSubscriber_ASDU_hasRefrTm(SVSubscriber_ASDU self);
|
||||
|
||||
/**
|
||||
* \brief Check if SmpMod value is included in the SV ASDU
|
||||
*
|
||||
* \param self ASDU object instance
|
||||
*
|
||||
* \return true if SmpMod value is present, false otherwise
|
||||
*/
|
||||
bool
|
||||
SVSubscriber_ASDU_hasSmpMod(SVSubscriber_ASDU self);
|
||||
|
||||
/**
|
||||
* \brief Check if SmpRate value is included in the SV ASDU
|
||||
*
|
||||
* \param self ASDU object instance
|
||||
*
|
||||
* \return true if SmpRate value is present, false otherwise
|
||||
*/
|
||||
bool
|
||||
SVSubscriber_ASDU_hasSmpRate(SVSubscriber_ASDU self);
|
||||
SVClientASDU_hasRefrTm(SVClientASDU self);
|
||||
|
||||
/**
|
||||
* \brief Get the RefrTim value included in SV ASDU as ms timestamp
|
||||
|
@ -357,7 +286,7 @@ SVSubscriber_ASDU_hasSmpRate(SVSubscriber_ASDU self);
|
|||
* \return the time value as ms timestamp or 0 if RefrTm is not present in the SV ASDU
|
||||
*/
|
||||
uint64_t
|
||||
SVSubscriber_ASDU_getRefrTmAsMs(SVSubscriber_ASDU self);
|
||||
SVClientASDU_getRefrTmAsMs(SVClientASDU self);
|
||||
|
||||
/**
|
||||
* \brief Get an INT8 data value in the data part of the ASDU
|
||||
|
@ -368,7 +297,7 @@ SVSubscriber_ASDU_getRefrTmAsMs(SVSubscriber_ASDU self);
|
|||
* \return SV data
|
||||
*/
|
||||
int8_t
|
||||
SVSubscriber_ASDU_getINT8(SVSubscriber_ASDU self, int index);
|
||||
SVClientASDU_getINT8(SVClientASDU self, int index);
|
||||
|
||||
/**
|
||||
* \brief Get an INT16 data value in the data part of the ASDU
|
||||
|
@ -379,7 +308,7 @@ SVSubscriber_ASDU_getINT8(SVSubscriber_ASDU self, int index);
|
|||
* \return SV data
|
||||
*/
|
||||
int16_t
|
||||
SVSubscriber_ASDU_getINT16(SVSubscriber_ASDU self, int index);
|
||||
SVClientASDU_getINT16(SVClientASDU self, int index);
|
||||
|
||||
/**
|
||||
* \brief Get an INT32 data value in the data part of the ASDU
|
||||
|
@ -390,18 +319,7 @@ SVSubscriber_ASDU_getINT16(SVSubscriber_ASDU self, int index);
|
|||
* \return SV data
|
||||
*/
|
||||
int32_t
|
||||
SVSubscriber_ASDU_getINT32(SVSubscriber_ASDU self, int index);
|
||||
|
||||
/**
|
||||
* \brief Get an INT64 data value in the data part of the ASDU
|
||||
*
|
||||
* \param self ASDU object instance
|
||||
* \param index the index (byte position of the start) of the data in the data part
|
||||
*
|
||||
* \return SV data
|
||||
*/
|
||||
int64_t
|
||||
SVSubscriber_ASDU_getINT64(SVSubscriber_ASDU self, int index);
|
||||
SVClientASDU_getINT32(SVClientASDU self, int index);
|
||||
|
||||
/**
|
||||
* \brief Get an INT8U data value in the data part of the ASDU
|
||||
|
@ -412,7 +330,7 @@ SVSubscriber_ASDU_getINT64(SVSubscriber_ASDU self, int index);
|
|||
* \return SV data
|
||||
*/
|
||||
uint8_t
|
||||
SVSubscriber_ASDU_getINT8U(SVSubscriber_ASDU self, int index);
|
||||
SVClientASDU_getINT8U(SVClientASDU self, int index);
|
||||
|
||||
/**
|
||||
* \brief Get an INT16U data value in the data part of the ASDU
|
||||
|
@ -423,7 +341,7 @@ SVSubscriber_ASDU_getINT8U(SVSubscriber_ASDU self, int index);
|
|||
* \return SV data
|
||||
*/
|
||||
uint16_t
|
||||
SVSubscriber_ASDU_getINT16U(SVSubscriber_ASDU self, int index);
|
||||
SVClientASDU_getINT16U(SVClientASDU self, int index);
|
||||
|
||||
/**
|
||||
* \brief Get an INT32U data value in the data part of the ASDU
|
||||
|
@ -434,18 +352,7 @@ SVSubscriber_ASDU_getINT16U(SVSubscriber_ASDU self, int index);
|
|||
* \return SV data
|
||||
*/
|
||||
uint32_t
|
||||
SVSubscriber_ASDU_getINT32U(SVSubscriber_ASDU self, int index);
|
||||
|
||||
/**
|
||||
* \brief Get an INT64U data value in the data part of the ASDU
|
||||
*
|
||||
* \param self ASDU object instance
|
||||
* \param index the index (byte position of the start) of the data in the data part
|
||||
*
|
||||
* \return SV data
|
||||
*/
|
||||
uint64_t
|
||||
SVSubscriber_ASDU_getINT64U(SVSubscriber_ASDU self, int index);
|
||||
SVClientASDU_getINT32U(SVClientASDU self, int index);
|
||||
|
||||
/**
|
||||
* \brief Get an FLOAT32 data value in the data part of the ASDU
|
||||
|
@ -456,7 +363,7 @@ SVSubscriber_ASDU_getINT64U(SVSubscriber_ASDU self, int index);
|
|||
* \return SV data
|
||||
*/
|
||||
float
|
||||
SVSubscriber_ASDU_getFLOAT32(SVSubscriber_ASDU self, int index);
|
||||
SVClientASDU_getFLOAT32(SVClientASDU self, int index);
|
||||
|
||||
/**
|
||||
* \brief Get an FLOAT64 data value in the data part of the ASDU
|
||||
|
@ -467,7 +374,7 @@ SVSubscriber_ASDU_getFLOAT32(SVSubscriber_ASDU self, int index);
|
|||
* \return SV data
|
||||
*/
|
||||
double
|
||||
SVSubscriber_ASDU_getFLOAT64(SVSubscriber_ASDU self, int index);
|
||||
SVClientASDU_getFLOAT64(SVClientASDU self, int index);
|
||||
|
||||
/**
|
||||
* \brief Returns the size of the data part of the ASDU
|
||||
|
@ -477,14 +384,13 @@ SVSubscriber_ASDU_getFLOAT64(SVSubscriber_ASDU self, int index);
|
|||
* \return size of the ASDU data part in bytes.
|
||||
*/
|
||||
int
|
||||
SVSubscriber_ASDU_getDataSize(SVSubscriber_ASDU self);
|
||||
SVClientASDU_getDataSize(SVClientASDU self);
|
||||
|
||||
/**@} @}*/
|
||||
/**@}*/
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#include "sv_subscriber_deprecated.h"
|
||||
|
||||
#endif /* SAMPLED_VALUES_SV_SUBSCRIBER_ */
|
||||
|
|
|
@ -1,167 +0,0 @@
|
|||
/*
|
||||
* sv_subscriber_deprecated.h
|
||||
*
|
||||
* Copyright 2015 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.
|
||||
*/
|
||||
|
||||
#ifndef SAMPLED_VALUES_SV_SUBSCRIBER_DEPRECATED_H_
|
||||
#define SAMPLED_VALUES_SV_SUBSCRIBER_DEPRECATED_H_
|
||||
|
||||
#include "libiec61850_common_api.h"
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
#if defined(__GNUC__) || defined(__clang__)
|
||||
#define DEPRECATED __attribute__((deprecated))
|
||||
#else
|
||||
#define DEPRECATED
|
||||
#endif
|
||||
|
||||
/**
|
||||
* \addtogroup sv_subscriber_deprecated_api_group Deprecated API
|
||||
* \ingroup sv_subscriber_api_group IEC 61850 Sampled Values (SV) publisher API
|
||||
* \deprecated
|
||||
* @{
|
||||
*/
|
||||
|
||||
typedef struct sSVSubscriberASDU* SVClientASDU;
|
||||
|
||||
static DEPRECATED
|
||||
uint16_t
|
||||
SVClientASDU_getSmpCnt(SVSubscriber_ASDU self)
|
||||
{
|
||||
return SVSubscriber_ASDU_getSmpCnt(self);
|
||||
}
|
||||
|
||||
static DEPRECATED
|
||||
const char*
|
||||
SVClientASDU_getSvId(SVSubscriber_ASDU self)
|
||||
{
|
||||
return SVSubscriber_ASDU_getSvId(self);
|
||||
}
|
||||
|
||||
static DEPRECATED
|
||||
uint32_t
|
||||
SVClientASDU_getConfRev(SVSubscriber_ASDU self)
|
||||
{
|
||||
return SVSubscriber_ASDU_getConfRev(self);
|
||||
}
|
||||
|
||||
static DEPRECATED
|
||||
bool
|
||||
SVClientASDU_hasRefrTm(SVSubscriber_ASDU self)
|
||||
{
|
||||
return SVSubscriber_ASDU_hasRefrTm(self);
|
||||
}
|
||||
|
||||
static DEPRECATED
|
||||
uint64_t
|
||||
SVClientASDU_getRefrTmAsMs(SVSubscriber_ASDU self)
|
||||
{
|
||||
return SVSubscriber_ASDU_getRefrTmAsMs(self);
|
||||
}
|
||||
|
||||
static DEPRECATED
|
||||
int8_t
|
||||
SVClientASDU_getINT8(SVSubscriber_ASDU self, int index)
|
||||
{
|
||||
return SVSubscriber_ASDU_getINT8(self, index);
|
||||
}
|
||||
|
||||
static DEPRECATED
|
||||
int16_t
|
||||
SVClientASDU_getINT16(SVSubscriber_ASDU self, int index)
|
||||
{
|
||||
return SVSubscriber_ASDU_getINT16(self, index);
|
||||
}
|
||||
|
||||
static DEPRECATED
|
||||
int32_t
|
||||
SVClientASDU_getINT32(SVSubscriber_ASDU self, int index)
|
||||
{
|
||||
return SVSubscriber_ASDU_getINT32(self, index);
|
||||
}
|
||||
|
||||
static DEPRECATED
|
||||
int64_t
|
||||
SVClientASDU_getINT64(SVSubscriber_ASDU self, int index)
|
||||
{
|
||||
return SVSubscriber_ASDU_getINT64(self, index);
|
||||
}
|
||||
|
||||
static DEPRECATED
|
||||
uint8_t
|
||||
SVClientASDU_getINT8U(SVSubscriber_ASDU self, int index)
|
||||
{
|
||||
return SVSubscriber_ASDU_getINT8U(self, index);
|
||||
}
|
||||
|
||||
static DEPRECATED
|
||||
uint16_t
|
||||
SVClientASDU_getINT16U(SVSubscriber_ASDU self, int index)
|
||||
{
|
||||
return SVSubscriber_ASDU_getINT16U(self, index);
|
||||
}
|
||||
|
||||
static DEPRECATED
|
||||
uint32_t
|
||||
SVClientASDU_getINT32U(SVSubscriber_ASDU self, int index)
|
||||
{
|
||||
return SVSubscriber_ASDU_getINT32U(self, index);
|
||||
}
|
||||
|
||||
static DEPRECATED
|
||||
uint64_t
|
||||
SVClientASDU_getINT64U(SVSubscriber_ASDU self, int index)
|
||||
{
|
||||
return SVSubscriber_ASDU_getINT64U(self, index);
|
||||
}
|
||||
|
||||
static DEPRECATED
|
||||
float
|
||||
SVClientASDU_getFLOAT32(SVSubscriber_ASDU self, int index)
|
||||
{
|
||||
return SVSubscriber_ASDU_getFLOAT32(self, index);
|
||||
}
|
||||
|
||||
static DEPRECATED
|
||||
double
|
||||
SVClientASDU_getFLOAT64(SVSubscriber_ASDU self, int index)
|
||||
{
|
||||
return SVSubscriber_ASDU_getFLOAT64(self, index);
|
||||
}
|
||||
|
||||
static DEPRECATED
|
||||
int
|
||||
SVClientASDU_getDataSize(SVSubscriber_ASDU self)
|
||||
{
|
||||
return SVSubscriber_ASDU_getDataSize(self);
|
||||
}
|
||||
|
||||
/**@}*/
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
|
||||
#endif /* SAMPLED_VALUES_SV_SUBSCRIBER_DEPRECATED_H_ */
|
Loading…
Add table
Reference in a new issue