From 05f32320e18b6ef2d08da91b48d28e21f30ebdf4 Mon Sep 17 00:00:00 2001 From: Michael Zillgith Date: Mon, 3 Jun 2024 15:36:15 +0100 Subject: [PATCH] - added function to get timestamp of received command (ControlAction_getT) (LIB61850-422) --- config/stack_config.h | 2 +- config/stack_config.h.cmake | 2 +- dotnet/IEC61850forCSharp/IEC61850CommonAPI.cs | 18 +++++++++++++++++- dotnet/IEC61850forCSharp/IEC61850ServerAPI.cs | 15 +++++++++++++++ src/iec61850/inc/iec61850_server.h | 12 +++++++++++- src/iec61850/inc_private/control.h | 4 +++- src/iec61850/server/mms_mapping/control.c | 19 ++++++++++++++++++- 7 files changed, 66 insertions(+), 6 deletions(-) diff --git a/config/stack_config.h b/config/stack_config.h index 2559069c..bc3045d0 100644 --- a/config/stack_config.h +++ b/config/stack_config.h @@ -170,7 +170,7 @@ /* allow application to set server identity (for MMS identity service) at runtime */ #define CONFIG_IEC61850_SUPPORT_SERVER_IDENTITY 1 -/* Force memory alignment - required for some platforms (required more memory for buffered reporting) */ +/* Force memory alignment - required for some platforms (requires more memory for buffered reporting) */ #define CONFIG_IEC61850_FORCE_MEMORY_ALIGNMENT 1 /* overwrite default results for MMS identify service */ diff --git a/config/stack_config.h.cmake b/config/stack_config.h.cmake index 437d87d9..adfeca96 100644 --- a/config/stack_config.h.cmake +++ b/config/stack_config.h.cmake @@ -160,7 +160,7 @@ /* allow application to set server identity (for MMS identity service) at runtime */ #define CONFIG_IEC61850_SUPPORT_SERVER_IDENTITY 1 -/* Force memory alignment - required for some platforms (required more memory for buffered reporting) */ +/* Force memory alignment - required for some platforms (requires more memory for buffered reporting) */ #define CONFIG_IEC61850_FORCE_MEMORY_ALIGNMENT 1 /* default results for MMS identify service */ diff --git a/dotnet/IEC61850forCSharp/IEC61850CommonAPI.cs b/dotnet/IEC61850forCSharp/IEC61850CommonAPI.cs index 818276c4..980d9ceb 100644 --- a/dotnet/IEC61850forCSharp/IEC61850CommonAPI.cs +++ b/dotnet/IEC61850forCSharp/IEC61850CommonAPI.cs @@ -1,7 +1,7 @@ /* * IEC61850CommonAPI.cs * - * Copyright 2014-2017 Michael Zillgith + * Copyright 2014-2024 Michael Zillgith * * This file is part of libIEC61850. * @@ -454,6 +454,9 @@ namespace IEC61850 SetByMmsUtcTime (mmsUtcTime); } + /// + /// Initializes a new instance of the class. + /// public Timestamp() { self = Timestamp_create (); @@ -461,6 +464,19 @@ namespace IEC61850 responsibleForDeletion = true; } + /// + /// Initializes a new instance of the class. + /// + public Timestamp(Timestamp other) : this() + { + SetTimeInSeconds (other.GetTimeInSeconds ()); + SetSubsecondPrecision (other.GetSubsecondPrecision ()); + SetFractionOfSecondPart (other.GetFractionOfSecondPart ()); + SetLeapSecondKnow(other.IsLeapSecondKnown()); + SetClockFailure(other.HasClockFailure()); + SetClockNotSynchronized(other.IsClockNotSynchronized()); + } + public Timestamp(byte[] value) { self = Timestamp_createFromByteArray (value); diff --git a/dotnet/IEC61850forCSharp/IEC61850ServerAPI.cs b/dotnet/IEC61850forCSharp/IEC61850ServerAPI.cs index 97adae02..8a0c5bf3 100644 --- a/dotnet/IEC61850forCSharp/IEC61850ServerAPI.cs +++ b/dotnet/IEC61850forCSharp/IEC61850ServerAPI.cs @@ -1874,6 +1874,9 @@ namespace IEC61850 [return: MarshalAs(UnmanagedType.I1)] static extern bool ControlAction_getInterlockCheck(IntPtr self); + [DllImport("iec61850", CallingConvention = CallingConvention.Cdecl)] + static extern IntPtr ControlAction_getT(IntPtr self); + private IntPtr self; private IedServer.ControlHandlerInfo info; private IedServer iedServer; @@ -2003,6 +2006,18 @@ namespace IEC61850 { return ControlAction_getInterlockCheck(self); } + + /// + /// Gets the time (paramter T) of the control action + /// + public Timestamp GetT() + { + IntPtr tPtr = ControlAction_getT(self); + + Timestamp t = new Timestamp(tPtr, false); + + return new Timestamp(t); + } } public delegate void GoCBEventHandler(MmsGooseControlBlock goCB, int cbEvent, object parameter); diff --git a/src/iec61850/inc/iec61850_server.h b/src/iec61850/inc/iec61850_server.h index d33d1a00..6dc69524 100644 --- a/src/iec61850/inc/iec61850_server.h +++ b/src/iec61850/inc/iec61850_server.h @@ -1449,7 +1449,7 @@ LIB61850_API DataObject* ControlAction_getControlObject(ControlAction self); /** - * \brief Gets the time of the control, if it's a timeActivatedControl, returns 0, if it's not. + * \brief Gets the time of the control (attribute "operTm"), if it's a timeActivatedControl, returns 0, if it's not. * * \param self the control action instance * @@ -1458,6 +1458,16 @@ ControlAction_getControlObject(ControlAction self); LIB61850_API uint64_t ControlAction_getControlTime(ControlAction self); +/** + * \brief Gets the time (attribute "T") of the last received control action (Oper or Select) + * + * \param self the control action instance + * + * \return the time of the last received control action + */ +LIB61850_API Timestamp* +ControlAction_getT(ControlAction self); + /** * \brief Control model callback to perform the static tests (optional). * diff --git a/src/iec61850/inc_private/control.h b/src/iec61850/inc_private/control.h index 66cb6706..adf56731 100644 --- a/src/iec61850/inc_private/control.h +++ b/src/iec61850/inc_private/control.h @@ -1,7 +1,7 @@ /* * control.h * - * Copyright 2013-2019 Michael Zillgith + * Copyright 2013-2024 Michael Zillgith * * This file is part of libIEC61850. * @@ -90,6 +90,8 @@ struct sControlObject MmsValue* origin; MmsValue* timestamp; + Timestamp T; + MmsValue* ctlNumSt; MmsValue* originSt; diff --git a/src/iec61850/server/mms_mapping/control.c b/src/iec61850/server/mms_mapping/control.c index 34fb18d5..07ef4324 100644 --- a/src/iec61850/server/mms_mapping/control.c +++ b/src/iec61850/server/mms_mapping/control.c @@ -169,6 +169,7 @@ getCancelParameterTest(MmsValue* operParameters) return NULL; } +/* access the MmsValue of Oper.T or SBOw.T */ static MmsValue* getOperParameterTime(MmsValue* operParameters) { @@ -182,7 +183,7 @@ getOperParameterTime(MmsValue* operParameters) timeParameter = MmsValue_getElement(operParameters, 3); } - if (timeParameter != NULL) + if (timeParameter) if ((MmsValue_getType(timeParameter) == MMS_UTC_TIME) || (MmsValue_getType(timeParameter) == MMS_BINARY_TIME)) return timeParameter; @@ -2125,6 +2126,7 @@ Control_writeAccessControlObject(MmsMapping* self, MmsDomain* domain, const char MmsValue* origin = getOperParameterOrigin(value); MmsValue* check = getOperParameterCheck(value); MmsValue* test = getOperParameterTest(value); + MmsValue* t = getOperParameterTime(value); if (checkValidityOfOriginParameter(origin) == false) { @@ -2139,6 +2141,11 @@ Control_writeAccessControlObject(MmsMapping* self, MmsDomain* domain, const char goto free_and_return; } + if (t) + { + Timestamp_fromMmsValue(&(controlObject->T), t); + } + int state = getState(controlObject); uint64_t currentTime = Hal_getTimeInMs(); @@ -2270,6 +2277,8 @@ Control_writeAccessControlObject(MmsMapping* self, MmsDomain* domain, const char goto free_and_return; } + Timestamp_fromMmsValue(&(controlObject->T), timeParameter); + if (checkValidityOfOriginParameter(origin) == false) { indication = DATA_ACCESS_ERROR_OBJECT_ACCESS_DENIED; @@ -2690,4 +2699,12 @@ ControlAction_getControlTime(ControlAction self) return controlObject->operateTime; } +Timestamp* +ControlAction_getT(ControlAction self) +{ + ControlObject* controlObject = (ControlObject*) self; + + return &(controlObject->T); +} + #endif /* (CONFIG_IEC61850_CONTROL_SERVICE == 1) */