Compare commits

..

No commits in common. "ethernet-handleset" and "master" have entirely different histories.

24 changed files with 190 additions and 748 deletions

View file

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

View file

@ -2,9 +2,9 @@ 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)
@ -32,15 +32,20 @@ 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
@ -58,23 +63,22 @@ option(DEBUG_MMS_CLIENT "Enable MMS CLIENT printf debugging" OFF)
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
@ -110,45 +114,42 @@ set(API_HEADERS
${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)
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}")
include(CPack)
endif(EXISTS "${CMAKE_ROOT}/Modules/CPack.cmake")
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}")
INCLUDE(CPack)
ENDIF(EXISTS "${CMAKE_ROOT}/Modules/CPack.cmake")

View file

@ -1,7 +1,5 @@
# README libIEC61850
[![Build Status](https://travis-ci.org/mz-automation/libiec61850.svg?branch=master)](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 (..).

View file

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

View file

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

View file

@ -7,7 +7,6 @@
*/
#include "goose_receiver.h"
#include "goose_subscriber.h"
#include "hal_thread.h"
#include <stdlib.h>

View file

@ -248,8 +248,6 @@ main(int argc, char** argv)
case FileOperationType_Set:
setFile(con);
break;
case FileOperationType_None:
break;
}

View file

@ -81,7 +81,7 @@ printJournalEntries(LinkedList journalEntries)
}
}
void
void*
printRawMmsMessage(void* parameter, uint8_t* message, int messageLength, bool received)
{
if (received)

View file

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

View file

@ -811,10 +811,3 @@ GooseReceiver_tick(GooseReceiver self)
else
return false;
}
void
GooseReceiver_addHandleSet(GooseReceiver self, EthernetHandleSet handles)
{
return EthernetHandleSet_addSocket(handles, self->ethSocket);
}

View file

@ -24,19 +24,18 @@
#ifndef GOOSE_RECEIVER_H_
#define GOOSE_RECEIVER_H_
#include <goose_subscriber.h>
#ifdef __cplusplus
extern "C" {
#endif
#include <stdbool.h>
/**
* \addtogroup goose_api_group
*/
/**@{*/
typedef struct sGooseSubscriber* GooseSubscriber;
typedef struct sGooseReceiver* GooseReceiver;
@ -134,20 +133,6 @@ GooseReceiver_stopThreadless(GooseReceiver self);
bool
GooseReceiver_tick(GooseReceiver self);
/* Forward declaration */
typedef struct sEthernetHandleSet* EthernetHandleSet;
/**
* \brief Add the receiver to a handleset for multiplexed asynchronous IO.
*
* Note: This function must only be called after GooseReceiver_startThreadless().
*
* \param[in] self The SVReceiver instance.
* \param[inout] handles The EthernetHandleSet to which the EthernetSocket of this receiver should be added.
*/
void
GooseReceiver_addHandleSet(GooseReceiver self, EthernetHandleSet handles);
/**@}*/
#ifdef __cplusplus

View file

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

View file

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

View file

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

View file

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

View file

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

View file

@ -351,6 +351,7 @@ IsoClientConnection_associate(IsoClientConnection self, IsoConnectionParameters
goto returnError;
}
ByteBuffer_wrap(self->receivePayloadBuffer, self->acseConnection.userDataBuffer,
self->acseConnection.userDataBufferSize, self->acseConnection.userDataBufferSize);

View file

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

View file

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

View file

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

View file

@ -59,7 +59,6 @@ struct sSV_ASDU {
uint64_t refrTm;
uint8_t smpMod;
uint16_t smpRate;
uint8_t* smpCntBuf;
@ -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)
{
@ -286,13 +257,13 @@ encodeUtcTime(uint64_t timeval, uint8_t* buffer, int bufPos)
SampledValuesPublisher
SampledValuesPublisher_create(CommParameters* parameters, const char* interfaceId)
{
SampledValuesPublisher self = (SampledValuesPublisher) GLOBAL_CALLOC(1, sizeof(struct sSampledValuesPublisher));
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;
}
SV_ASDU
@ -398,8 +369,7 @@ SV_ASDU_encodeToBuffer(SV_ASDU self, uint8_t* buffer, int bufPos)
buffer[bufPos++] = self->smpSynch;
/* SmpRate */
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);
@ -407,11 +377,15 @@ SV_ASDU_encodeToBuffer(SV_ASDU self, uint8_t* buffer, int bufPos)
self->_dataBuffer = buffer + bufPos;
bufPos += self->dataSize; /* data has to inserted by user before sending message */
/* SmpMod */
if (self->hasSmpMod) {
bufPos = BerEncoder_encodeTL(0x88, 4, 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;
@ -491,7 +465,7 @@ SampledValuesPublisher_publish(SampledValuesPublisher self)
void
SampledValuesPublisher_destroy(SampledValuesPublisher self)
{
GLOBAL_FREEMEM(self->buffer);
GLOBAL_FREEMEM(self->buffer);
}
@ -534,22 +508,6 @@ SV_ASDU_setINT32(SV_ASDU self, int index, int32_t value)
encodeInt32FixedSize(value, self->_dataBuffer, index);
}
int
SV_ASDU_addINT64(SV_ASDU self)
{
int index = self->dataSize;
self->dataSize += 8;
return index;
}
void
SV_ASDU_setINT64(SV_ASDU self, int index, int64_t value)
{
encodeInt64FixedSize(value, self->_dataBuffer, index);
}
int
SV_ASDU_addFLOAT(SV_ASDU self)
{
@ -565,6 +523,7 @@ 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
@ -591,15 +550,11 @@ void
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];
}
@ -641,9 +596,3 @@ SV_ASDU_setSmpMod(SV_ASDU self, uint8_t smpMod)
self->smpMod = smpMod;
}
void
SV_ASDU_setSmpRate(SV_ASDU self, uint16_t smpRate)
{
self->hasSmpRate = true;
self->smpRate = smpRate;
}

View file

@ -85,12 +85,6 @@ SV_ASDU_addINT32(SV_ASDU self);
void
SV_ASDU_setINT32(SV_ASDU self, int index, int32_t value);
int
SV_ASDU_addINT64(SV_ASDU self);
void
SV_ASDU_setINT64(SV_ASDU self, int index, int64_t value);
int
SV_ASDU_addFLOAT(SV_ASDU self);
@ -127,18 +121,6 @@ SV_ASDU_setRefrTm(SV_ASDU self, uint64_t refrTm);
void
SV_ASDU_setSmpMod(SV_ASDU self, uint8_t smpMod);
/**
* \brief Set the sample rate of the ASDU.
*
* If not set the transmitted ASDU will not contain an smpRate value.
*
* \param self the SV_ASDU
*
* \param smpRate Amount of samples (default per nominal period, see SmpMod).
*/
void
SV_ASDU_setSmpRate(SV_ASDU self, uint16_t smpRate);
#ifdef __cplusplus
}
#endif

View file

@ -50,13 +50,7 @@ struct sSVReceiver {
uint8_t* buffer;
EthernetSocket ethSocket;
LinkedList subscriberList;
#if (CONFIG_MMS_THREADLESS_STACK == 0)
Semaphore subscriberListLock;
#endif
};
struct sSVSubscriber {
@ -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,10 +174,6 @@ 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);
}
@ -229,11 +199,6 @@ SVReceiver_stopThreadless(SVReceiver self)
self->running = false;
}
void
SVReceiver_addHandleSet(SVReceiver self, EthernetHandleSet handles)
{
return EthernetHandleSet_addSocket(handles, self->ethSocket);
}
static void
parseASDU(SVReceiver self, SVSubscriber subscriber, uint8_t* buffer, int length)
@ -433,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;
@ -467,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);
@ -642,20 +598,6 @@ SVClientASDU_getINT32(SVClientASDU self, int index)
return retVal;
}
int64_t
SVClientASDU_getINT64(SVClientASDU 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
SVClientASDU_getINT8U(SVClientASDU self, int index)
{
@ -692,19 +634,6 @@ SVClientASDU_getINT32U(SVClientASDU self, int index)
return retVal;
}
uint64_t
SVClientASDU_getINT64U(SVClientASDU 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
SVClientASDU_getFLOAT32(SVClientASDU self, int index)

View file

@ -52,25 +52,24 @@ extern "C" {
*
* | 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.
@ -210,32 +209,9 @@ 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);
/* Forward declaration */
typedef struct sEthernetHandleSet* EthernetHandleSet;
/**
* \brief Add the receiver to a handleset for multiplexed asynchronous IO.
*
* Note: This function must only be called after SVReceiver_startThreadless().
*
* \param[in] self The SVReceiver instance.
* \param[inout] handles The EthernetHandleSet to which the EthernetSocket of this receiver should be added.
*/
void
SVReceiver_addHandleSet(SVReceiver self, EthernetHandleSet handles);
/*
* Subscriber
*/
@ -345,17 +321,6 @@ SVClientASDU_getINT16(SVClientASDU self, int index);
int32_t
SVClientASDU_getINT32(SVClientASDU 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
SVClientASDU_getINT64(SVClientASDU self, int index);
/**
* \brief Get an INT8U data value in the data part of the ASDU
*
@ -389,17 +354,6 @@ SVClientASDU_getINT16U(SVClientASDU self, int index);
uint32_t
SVClientASDU_getINT32U(SVClientASDU 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
SVClientASDU_getINT64U(SVClientASDU self, int index);
/**
* \brief Get an FLOAT32 data value in the data part of the ASDU
*