From 1688fd872b6097cc957e56116351b2d41f19d61e Mon Sep 17 00:00:00 2001 From: Michael Zillgith Date: Mon, 18 Apr 2016 18:35:05 +0200 Subject: [PATCH 1/4] - added python bindings --- CMakeLists.txt | 8 ++-- pyiec61850/CMakeLists.txt | 23 ++++++++++ pyiec61850/iec61850.i | 41 ++++++++++++++++++ pyiec61850/test_pyiec61850.py | 82 +++++++++++++++++++++++++++++++++++ 4 files changed, 151 insertions(+), 3 deletions(-) create mode 100644 pyiec61850/CMakeLists.txt create mode 100644 pyiec61850/iec61850.i create mode 100755 pyiec61850/test_pyiec61850.py diff --git a/CMakeLists.txt b/CMakeLists.txt index b303bdd5..f569a134 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -8,6 +8,7 @@ if(DEFINED ENV{TOOLCHAIN}) endif() project(libiec61850) +ENABLE_TESTING() set(LIB_VERSION_MAJOR "0") set(LIB_VERSION_MINOR "9") @@ -25,6 +26,7 @@ set(CONFIG_MMS_MAXIMUM_PDU_SIZE "65000" CACHE STRING "Configure the maximum size set(CONFIG_MAXIMUM_TCP_CLIENT_CONNECTIONS 5 CACHE STRING "Configure the maximum number of clients allowed to connect to the server") option(BUILD_EXAMPLES "Build the examples" ON) +option(BUILD_PYTHON_BINDINGS "Build Python bindings" OFF) option(CONFIG_MMS_SINGLE_THREADED "Compile for single threaded version" OFF) option(CONFIG_MMS_THREADLESS_STACK "Optimize stack for threadless operation (warning: single- or multi-threaded server will not work!)" OFF) @@ -119,6 +121,9 @@ add_subdirectory(src) INSTALL(FILES ${API_HEADERS} DESTINATION include/libiec61850) +IF(BUILD_PYTHON_BINDINGS) + add_subdirectory(pyiec61850) +ENDIF(BUILD_PYTHON_BINDINGS) IF(EXISTS "${CMAKE_ROOT}/Modules/CPack.cmake") INCLUDE(InstallRequiredSystemLibraries) @@ -144,6 +149,3 @@ SET(CPACK_COMPONENTS_ALL Libraries ApplicationData) INCLUDE(CPack) ENDIF(EXISTS "${CMAKE_ROOT}/Modules/CPack.cmake") - - - diff --git a/pyiec61850/CMakeLists.txt b/pyiec61850/CMakeLists.txt new file mode 100644 index 00000000..328a9966 --- /dev/null +++ b/pyiec61850/CMakeLists.txt @@ -0,0 +1,23 @@ +FIND_PACKAGE(SWIG REQUIRED) +INCLUDE(${SWIG_USE_FILE}) +FIND_PACKAGE(PythonLibs REQUIRED) +FIND_PACKAGE ( PythonInterp 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_BINARY_DIR}/iec61850.py DESTINATION ${PYTHON_SITE_DIR}) +INSTALL ( TARGETS _iec61850 LIBRARY DESTINATION ${PYTHON_SITE_DIR}) + +add_test(test_pyiec61850 ${PYTHON_EXECUTABLE} test_pyiec61850.py) diff --git a/pyiec61850/iec61850.i b/pyiec61850/iec61850.i new file mode 100644 index 00000000..2af52e80 --- /dev/null +++ b/pyiec61850/iec61850.i @@ -0,0 +1,41 @@ +/* File : iec61850.i */ +%module iec61850 +%ignore ControlObjectClient_setTestMode(ControlObjectClient self); +%ignore CDA_OperBoolean(ModelNode* parent, bool isTImeActivated); +%ignore LogicalNode_hasBufferedReports(LogicalNode* node); +%ignore LogicalNode_hasUnbufferedReports(LogicalNode* node); +%ignore MmsConnection_setIsoConnectionParameters(MmsConnection self, IsoConnectionParameters* params); +%include "stdint.i" +%{ +#include +#include +#include +ModelNode* toModelNode(LogicalNode * ln) +{ + return (ModelNode*) ln; +} +ModelNode* toModelNode(DataObject * DO) +{ + return (ModelNode*) DO; +} +DataAttribute* toDataAttribute(DataObject * DO) +{ return (DataAttribute*)DO;} +DataAttribute* toDataAttribute(ModelNode * MN) +{ return (DataAttribute*)MN;} +%} +%apply int *OUTPUT {IedClientError* error}; + +%include "iec61850_client.h" +%include "iso_connection_parameters.h" +%include "mms_client_connection.h" +%include "iso_connection_parameters.h" +%include "iec61850_common.h" +%include "mms_value.h" +%include "iec61850_model.h" +%include "iec61850_server.h" +%include "iec61850_dynamic_model.h" +%include "iec61850_cdc.h" +ModelNode* toModelNode(LogicalNode *); +ModelNode* toModelNode(DataObject *); +DataAttribute* toDataAttribute(DataObject *); +DataAttribute* toDataAttribute(ModelNode *); diff --git a/pyiec61850/test_pyiec61850.py b/pyiec61850/test_pyiec61850.py new file mode 100755 index 00000000..7f5d3655 --- /dev/null +++ b/pyiec61850/test_pyiec61850.py @@ -0,0 +1,82 @@ +#!/usr/bin/python +import sys +import time +import iec61850 +import threading +import traceback +import signal +import sys +def signal_handler(signal, frame): + global running + running =0 + print('You pressed Ctrl+C!') + #sys.exit(0) +signal.signal(signal.SIGINT, signal_handler) +tcpPort = 8102 +running = 1 +class myIECServer(): + def __init__(self): + self.__model = iec61850.IedModel_create("testmodel") + lDevice1 = iec61850.LogicalDevice_create("SENSORS", self.__model); + lln0 = iec61850.LogicalNode_create("LLN0", lDevice1); + ttmp1 = iec61850.LogicalNode_create("TTMP1", lDevice1); + iec61850.CDC_SAV_create("TmpSv", iec61850.toModelNode(ttmp1), 0, False) + iec61850.CDC_ASG_create("TmpSp", iec61850.toModelNode(ttmp1), 0, False) + self.__iedServer = iec61850.IedServer_create(self.__model) + iec61850.IedServer_start(self.__iedServer, tcpPort); + if not(iec61850.IedServer_isRunning(self.__iedServer)) : + print("Starting server failed! Exit.\n") + iec61850.IedServer_destroy(self.__iedServer) + sys.exit(-1) + def run(self): + global running + while running: + time.sleep(0.1) + self.stop() + def stop(self): + iec61850.IedServer_stop(self.__iedServer) + iec61850.IedServer_destroy(self.__iedServer) + iec61850.IedModel_destroy(self.__model) + +def testClient(): + con = iec61850.IedConnection_create() + error = iec61850.IedConnection_connect(con, "localhost", tcpPort) + if (error == iec61850.IED_ERROR_OK): + # Accessing to SAV values + theVal = "testmodelSENSORS/TTMP1.TmpSv.instMag.f" + theValType = iec61850.IEC61850_FC_MX + temperatureValue = iec61850.IedConnection_readFloatValue(con, theVal, theValType) + assert(temperatureValue[1]==0) + newValue= temperatureValue[0]+10 + err = iec61850.IedConnection_writeFloatValue(con, theVal, theValType, newValue) + assert(err==21) + # Accessing to ASG values + theVal = "testmodelSENSORS/TTMP1.TmpSp.setMag.f" + theValType = iec61850.IEC61850_FC_SP + temperatureSetpoint = iec61850.IedConnection_readFloatValue(con, theVal, theValType) + print temperatureSetpoint + assert(temperatureValue[1]==0) + newValue= temperatureValue[0]+10 + err = iec61850.IedConnection_writeFloatValue(con, theVal, theValType, newValue) + assert(err==0) + temperatureSetpoint = iec61850.IedConnection_readFloatValue(con, theVal, theValType) + print temperatureSetpoint + assert(temperatureSetpoint[0]==newValue) + iec61850.IedConnection_close(con) + else: + print "Connection error" + sys.exit(-1) + iec61850.IedConnection_destroy(con) + print "client ok" +try: + srv=myIECServer() + srvThread = threading.Thread(target = srv.run) + srvThread.start() + testClient() + running = 0 + #signal.pause() +except: + running = 0 + print "Error :" + traceback.print_exc(file=sys.stdout) + sys.exit(-1) From 2f8e011a0fe89837f9b56ecd86868c18f986beed Mon Sep 17 00:00:00 2001 From: Michael Zillgith Date: Wed, 20 Apr 2016 17:48:57 +0200 Subject: [PATCH 2/4] - fixed initialization problem with uninitialized integer values --- src/mms/asn1/asn1_ber_primitive_value.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/mms/asn1/asn1_ber_primitive_value.c b/src/mms/asn1/asn1_ber_primitive_value.c index 5571d924..26564ee8 100644 --- a/src/mms/asn1/asn1_ber_primitive_value.c +++ b/src/mms/asn1/asn1_ber_primitive_value.c @@ -30,7 +30,7 @@ Asn1PrimitiveValue_create(int size) { Asn1PrimitiveValue* self = (Asn1PrimitiveValue*) GLOBAL_MALLOC(sizeof(Asn1PrimitiveValue)); - self->size = size; + self->size = 1; self->maxSize = size; self->octets = (uint8_t*) GLOBAL_CALLOC(1, size); From 8f45ac88c6b14f51a85e4faadf21f0db73dd837b Mon Sep 17 00:00:00 2001 From: Michael Zillgith Date: Fri, 6 May 2016 10:56:44 +0200 Subject: [PATCH 3/4] - added functions ControlObjectClient_setInterlockCheck and ControlObjectClient_setSynchroCheck to replace the functions ControlObjectClient_enableInterlockCheck and ControlObjectClient_enableSynchroCheck --- dotnet/IEC61850forCSharp/Control.cs | 32 ++++++++++++++++++++++------ dotnet/example3/Main.cs | 2 +- src/iec61850/client/client_control.c | 13 +++++++++++ src/iec61850/inc/iec61850_client.h | 24 +++++++++++++++++++++ src/vs/libiec61850-wo-goose.def | 2 ++ src/vs/libiec61850.def | 3 ++- 6 files changed, 67 insertions(+), 9 deletions(-) diff --git a/dotnet/IEC61850forCSharp/Control.cs b/dotnet/IEC61850forCSharp/Control.cs index cd425d88..f0faa906 100644 --- a/dotnet/IEC61850forCSharp/Control.cs +++ b/dotnet/IEC61850forCSharp/Control.cs @@ -137,11 +137,11 @@ namespace IEC61850 [DllImport("iec61850", CallingConvention = CallingConvention.Cdecl)] private static extern void ControlObjectClient_setOrigin(IntPtr self, string orIdent, int orCat); - [DllImport("iec61850", CallingConvention = CallingConvention.Cdecl)] - private static extern void ControlObjectClient_enableInterlockCheck(IntPtr self); + [DllImport("iec61850", CallingConvention = CallingConvention.Cdecl)] + private static extern void ControlObjectClient_setInterlockCheck(IntPtr self, bool value); - [DllImport("iec61850", CallingConvention = CallingConvention.Cdecl)] - private static extern void ControlObjectClient_enableSynchroCheck(IntPtr self); + [DllImport("iec61850", CallingConvention = CallingConvention.Cdecl)] + private static extern void ControlObjectClient_setSynchroCheck(IntPtr self, bool value); [UnmanagedFunctionPointer(CallingConvention.Cdecl)] private delegate void InternalCommandTerminationHandler(IntPtr parameter,IntPtr controlClient); @@ -373,19 +373,37 @@ namespace IEC61850 /// /// Enables the synchro check for operate commands /// + [Obsolete("use SetSynchroCheck instead")] public void EnableSynchroCheck () { - ControlObjectClient_enableSynchroCheck(controlObject); + ControlObjectClient_setSynchroCheck (controlObject, true); } /// /// Enables the interlock check for operate and select commands /// - public void EnableInterlockCheck () + [Obsolete("use SetInterlockCheck instead")] + public void EnableInterlockCheck () { - ControlObjectClient_enableInterlockCheck(controlObject); + ControlObjectClient_setInterlockCheck (controlObject, true); } + /// + /// Sets the value of the interlock check flag for operate and select commands + /// + public void SetInterlockCheck (bool value) + { + ControlObjectClient_setInterlockCheck (controlObject, value); + } + + /// + /// Sets the value of the synchro check flag for operate command + /// + public void SetSynchroCheck (bool value) + { + ControlObjectClient_setSynchroCheck (controlObject, value); + } + /// /// Gets the last received LastApplError (Additional Cause Diagnostics) value. /// diff --git a/dotnet/example3/Main.cs b/dotnet/example3/Main.cs index 343efc8d..86fe0644 100644 --- a/dotnet/example3/Main.cs +++ b/dotnet/example3/Main.cs @@ -24,7 +24,7 @@ namespace example3 { IsoConnectionParameters parameters = con.GetConnectionParameters(); - parameters.SetRemoteAddresses(1,1, new byte[] {0x00, 0x01, 0x02, 0x03}); + parameters.SetRemoteAddresses(1, new byte[] {0x00, 0x01}, new byte[] {0x00, 0x01, 0x02, 0x03}); con.ConnectTimeout = 10000; diff --git a/src/iec61850/client/client_control.c b/src/iec61850/client/client_control.c index ce2823e0..d638c0a3 100644 --- a/src/iec61850/client/client_control.c +++ b/src/iec61850/client/client_control.c @@ -848,12 +848,25 @@ ControlObjectClient_enableInterlockCheck(ControlObjectClient self) self->interlockCheck = true; } +void +ControlObjectClient_setInterlockCheck(ControlObjectClient self, bool value) +{ + self->interlockCheck = value; +} + + void ControlObjectClient_enableSynchroCheck(ControlObjectClient self) { self->synchroCheck = true; } +void +ControlObjectClient_setSynchroCheck(ControlObjectClient self, bool value) +{ + self->synchroCheck = value; +} + void ControlObjectClient_setLastApplError(ControlObjectClient self, LastApplError lastApplError) { diff --git a/src/iec61850/inc/iec61850_client.h b/src/iec61850/inc/iec61850_client.h index ed5c8911..b5ce446c 100644 --- a/src/iec61850/inc/iec61850_client.h +++ b/src/iec61850/inc/iec61850_client.h @@ -1510,12 +1510,36 @@ ControlObjectClient_setOrigin(ControlObjectClient self, const char* orIdent, int void ControlObjectClient_useConstantT(ControlObjectClient self, bool useConstantT); +/** + * \deprecated use ControlObjectClient_setInterlockCheck instead + */ void ControlObjectClient_enableInterlockCheck(ControlObjectClient self); +/** + * \deprecated use ControlObjectClient_setSynchroCheck instead + */ void ControlObjectClient_enableSynchroCheck(ControlObjectClient self); +/** + * \brief Set the value of the interlock check flag when a control command is sent + * + * \param self the ControlObjectClient instance + * \param value if true the server will perform a interlock check if supported + */ +void +ControlObjectClient_setInterlockCheck(ControlObjectClient self, bool value); + +/** + * \brief Set the value of the synchro check flag when a control command is sent + * + * \param self the ControlObjectClient instance + * \param value if true the server will perform a synchro check if supported + */ +void +ControlObjectClient_setSynchroCheck(ControlObjectClient self, bool value); + /** * \brief Private a callback handler that is invoked when a command termination message is received. diff --git a/src/vs/libiec61850-wo-goose.def b/src/vs/libiec61850-wo-goose.def index 8354e2fa..ceaac212 100644 --- a/src/vs/libiec61850-wo-goose.def +++ b/src/vs/libiec61850-wo-goose.def @@ -523,4 +523,6 @@ EXPORTS MmsValue_getUtcTimeQuality MmsConnection_getMmsConnectionParameters IedServer_updateVisibleStringAttributeValue + ControlObjectClient_setInterlockCheck + ControlObjectClient_setSynchroCheck diff --git a/src/vs/libiec61850.def b/src/vs/libiec61850.def index 7ad6426e..45744181 100644 --- a/src/vs/libiec61850.def +++ b/src/vs/libiec61850.def @@ -600,4 +600,5 @@ EXPORTS MmsValue_getUtcTimeQuality MmsConnection_getMmsConnectionParameters IedServer_updateVisibleStringAttributeValue - + ControlObjectClient_setInterlockCheck + ControlObjectClient_setSynchroCheck From 29b9e46697999168fde854ddce2840e17a0f7178 Mon Sep 17 00:00:00 2001 From: Michael Zillgith Date: Fri, 6 May 2016 12:21:19 +0200 Subject: [PATCH 4/4] - added function MmsConnection_getMmsConnectionParameters --- CMakeLists.txt | 4 ++-- examples/iec61850_client_example4/CMakeLists.txt | 4 ++-- .../iec61850_client_example_files/CMakeLists.txt | 4 ++-- .../CMakeLists.txt | 4 ++-- examples/mms_client_example2/CMakeLists.txt | 4 ++-- examples/mms_client_example3/CMakeLists.txt | 4 ++-- examples/mms_client_example4/CMakeLists.txt | 4 ++-- src/CMakeLists.txt | 11 ++++++++--- src/mms/inc/mms_client_connection.h | 14 ++++++++++++-- src/mms/iso_mms/client/mms_client_connection.c | 6 ++++++ src/mms/iso_mms/client/mms_client_initiate.c | 5 +++++ 11 files changed, 45 insertions(+), 19 deletions(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index f569a134..e374c898 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -104,11 +104,11 @@ set(API_HEADERS src/sampled_values/sv_publisher.h ) -IF(WIN32) +IF(MSVC) include_directories( src/vs ) -ENDIF(WIN32) +ENDIF(MSVC) # write the detected stuff to this file configure_file(config/stack_config.h.cmake ${CMAKE_CURRENT_BINARY_DIR}/config/stack_config.h) diff --git a/examples/iec61850_client_example4/CMakeLists.txt b/examples/iec61850_client_example4/CMakeLists.txt index 2c14b05c..cacd87bf 100644 --- a/examples/iec61850_client_example4/CMakeLists.txt +++ b/examples/iec61850_client_example4/CMakeLists.txt @@ -3,10 +3,10 @@ set(iec61850_client_example4_SRCS client_example4.c ) -IF(WIN32) +IF(MSVC) set_source_files_properties(${iec61850_client_example4_SRCS} PROPERTIES LANGUAGE CXX) -ENDIF(WIN32) +ENDIF(MSVC) add_executable(iec61850_client_example4 ${iec61850_client_example4_SRCS} diff --git a/examples/iec61850_client_example_files/CMakeLists.txt b/examples/iec61850_client_example_files/CMakeLists.txt index 10b7ab02..36cba273 100644 --- a/examples/iec61850_client_example_files/CMakeLists.txt +++ b/examples/iec61850_client_example_files/CMakeLists.txt @@ -3,10 +3,10 @@ set(iec61850_client_example_files_SRCS client_example_files.c ) -IF(WIN32) +IF(MSVC) set_source_files_properties(${iec61850_client_example_files_SRCS} PROPERTIES LANGUAGE CXX) -ENDIF(WIN32) +ENDIF(MSVC) add_executable(iec61850_client_example_files ${iec61850_client_example_files_SRCS} diff --git a/examples/iec61850_client_example_reporting/CMakeLists.txt b/examples/iec61850_client_example_reporting/CMakeLists.txt index 621f1298..8fa60dfb 100644 --- a/examples/iec61850_client_example_reporting/CMakeLists.txt +++ b/examples/iec61850_client_example_reporting/CMakeLists.txt @@ -3,10 +3,10 @@ set(iec61850_client_example_reporting_SRCS client_example_reporting.c ) -IF(WIN32) +IF(MSVC) set_source_files_properties(${iec61850_client_example_reporting_SRCS} PROPERTIES LANGUAGE CXX) -ENDIF(WIN32) +ENDIF(MSVC) add_executable(iec61850_client_example_reporting ${iec61850_client_example_reporting_SRCS} diff --git a/examples/mms_client_example2/CMakeLists.txt b/examples/mms_client_example2/CMakeLists.txt index b56f7a51..15016df7 100644 --- a/examples/mms_client_example2/CMakeLists.txt +++ b/examples/mms_client_example2/CMakeLists.txt @@ -3,10 +3,10 @@ set(mms_client_example2_SRCS mms_client_example2.c ) -IF(WIN32) +IF(MSVC) set_source_files_properties(${mms_client_example2_SRCS} PROPERTIES LANGUAGE CXX) -ENDIF(WIN32) +ENDIF(MSVC) add_executable(mms_client_example2 ${mms_client_example2_SRCS} diff --git a/examples/mms_client_example3/CMakeLists.txt b/examples/mms_client_example3/CMakeLists.txt index 4a5cab0a..df110000 100644 --- a/examples/mms_client_example3/CMakeLists.txt +++ b/examples/mms_client_example3/CMakeLists.txt @@ -3,10 +3,10 @@ set(mms_client_example3_SRCS mms_client_example3.c ) -IF(WIN32) +IF(MSVC) set_source_files_properties(${mms_client_example3_SRCS} PROPERTIES LANGUAGE CXX) -ENDIF(WIN32) +ENDIF(MSVC) add_executable(mms_client_example3 ${mms_client_example3_SRCS} diff --git a/examples/mms_client_example4/CMakeLists.txt b/examples/mms_client_example4/CMakeLists.txt index 6335c595..96b9edfc 100644 --- a/examples/mms_client_example4/CMakeLists.txt +++ b/examples/mms_client_example4/CMakeLists.txt @@ -3,10 +3,10 @@ set(mms_client_example4_SRCS mms_client_example4.c ) -IF(WIN32) +IF(MSVC) set_source_files_properties(${mms_client_example4_SRCS} PROPERTIES LANGUAGE CXX) -ENDIF(WIN32) +ENDIF(MSVC) add_executable(mms_client_example4 ${mms_client_example4_SRCS} diff --git a/src/CMakeLists.txt b/src/CMakeLists.txt index 31a74e92..266c2799 100644 --- a/src/CMakeLists.txt +++ b/src/CMakeLists.txt @@ -213,14 +213,18 @@ endif() set_source_files_properties(${lib_asn1c_SRCS} PROPERTIES LANGUAGE C) +IF(MSVC) set_source_files_properties(${lib_common_SRCS} ${lib_windows_SRCS} PROPERTIES LANGUAGE CXX) +ENDIF() IF(WITH_WPCAP) +IF(MSVC) set_source_files_properties(${lib_goose_SRCS} PROPERTIES LANGUAGE CXX) set_source_files_properties(${lib_sv_SRCS} PROPERTIES LANGUAGE CXX) +ENDIF() ELSE() add_definitions(-DEXCLUDE_ETHERNET_WINDOWS) ENDIF() @@ -311,8 +315,10 @@ IF(UNIX) ) ENDIF (CONFIG_SYSTEM_HAS_CLOCK_GETTIME) ENDIF(UNIX) - - +IF(MINGW) + target_link_libraries(iec61850-shared ws2_32 iphlpapi) + target_link_libraries(iec61850 ws2_32 iphlpapi) +ENDIF(MINGW) iF(WITH_WPCAP) target_link_libraries(iec61850 ${CMAKE_CURRENT_SOURCE_DIR}/../third_party/winpcap/lib/wpcap.lib @@ -330,7 +336,6 @@ if(MSVC) ) endif() - ELSE(WITH_WPCAP) if(MSVC) set_target_properties(iec61850-shared PROPERTIES diff --git a/src/mms/inc/mms_client_connection.h b/src/mms/inc/mms_client_connection.h index fc234e7e..29195485 100644 --- a/src/mms/inc/mms_client_connection.h +++ b/src/mms/inc/mms_client_connection.h @@ -1,7 +1,7 @@ /* * mms_client_connection.h * - * Copyright 2013 Michael Zillgith + * Copyright 2013-2016 Michael Zillgith * * This file is part of libIEC61850. * @@ -49,6 +49,7 @@ typedef struct sMmsConnectionParameters { int maxServOutstandingCalled; int dataStructureNestingLevel; int maxPduSize; /* local detail */ + uint8_t servicesSupported[11]; } MmsConnectionParameters; typedef struct { @@ -112,7 +113,7 @@ MmsConnection_setInformationReportHandler(MmsConnection self, MmsInformationRepo void* parameter); /** - * \brief Get the connection parameters for an MmsConnection instance + * \brief Get the ISO connection parameters for an MmsConnection instance * * \param self MmsConnection instance to operate on * \return params the to be used by this connection @@ -120,6 +121,15 @@ MmsConnection_setInformationReportHandler(MmsConnection self, MmsInformationRepo IsoConnectionParameters MmsConnection_getIsoConnectionParameters(MmsConnection self); +/** + * \brief Get the MMS specific connection parameters for an MmsConnection instance + * + * \param self MmsConnection instance to operate on + * \return params the to be used by this connection + */ +MmsConnectionParameters +MmsConnection_getMmsConnectionParameters(MmsConnection self); + /** * \brief User provided handler function that will be called if the connection to the server is lost * diff --git a/src/mms/iso_mms/client/mms_client_connection.c b/src/mms/iso_mms/client/mms_client_connection.c index 166ed6f4..3e444449 100644 --- a/src/mms/iso_mms/client/mms_client_connection.c +++ b/src/mms/iso_mms/client/mms_client_connection.c @@ -841,6 +841,12 @@ MmsConnection_getIsoConnectionParameters(MmsConnection self) return self->isoParameters; } +MmsConnectionParameters +MmsConnection_getMmsConnectionParameters(MmsConnection self) +{ + return self->parameters; +} + static void waitForConnectResponse(MmsConnection self) { diff --git a/src/mms/iso_mms/client/mms_client_initiate.c b/src/mms/iso_mms/client/mms_client_initiate.c index 6458ae21..e8c7d7d4 100644 --- a/src/mms/iso_mms/client/mms_client_initiate.c +++ b/src/mms/iso_mms/client/mms_client_initiate.c @@ -130,6 +130,11 @@ mmsClient_parseInitiateResponse(MmsConnection self) self->parameters.maxServOutstandingCalling = initiateResponse->negotiatedMaxServOutstandingCalling; + int i; + + for (i = 0; i < 11; i++) + self->parameters.servicesSupported[i] = initiateResponse->mmsInitResponseDetail.servicesSupportedCalled.buf[i]; + result = true; } else