From d4312d21acf079dd613cf24474edb9c613347f6c Mon Sep 17 00:00:00 2001 From: Michael Zillgith Date: Wed, 13 Apr 2022 15:49:27 +0200 Subject: [PATCH] - fixed bugs in ReportControlBlock getter functions and .NET wrapper code --- dotnet/IEC61850forCSharp/IEC61850ServerAPI.cs | 5 +- dotnet/server1/Program.cs | 13 +++- src/iec61850/inc/iec61850_dynamic_model.h | 71 ++++++++++++++++++- src/iec61850/server/mms_mapping/mms_goose.c | 12 ++-- src/iec61850/server/mms_mapping/reporting.c | 6 +- 5 files changed, 92 insertions(+), 15 deletions(-) diff --git a/dotnet/IEC61850forCSharp/IEC61850ServerAPI.cs b/dotnet/IEC61850forCSharp/IEC61850ServerAPI.cs index 40bbf830..3cd8b548 100644 --- a/dotnet/IEC61850forCSharp/IEC61850ServerAPI.cs +++ b/dotnet/IEC61850forCSharp/IEC61850ServerAPI.cs @@ -1309,7 +1309,7 @@ namespace IEC61850 static extern void ReportControlBlock_setPreconfiguredClient(IntPtr self, byte type, [Out] byte[] buf); [DllImport("iec61850", CallingConvention = CallingConvention.Cdecl)] - static extern string ReportControlBlock_getName(IntPtr self); + static extern IntPtr ReportControlBlock_getName(IntPtr self); [DllImport("iec61850", CallingConvention = CallingConvention.Cdecl)] [return: MarshalAs(UnmanagedType.I1)] @@ -1396,7 +1396,7 @@ namespace IEC61850 { if (name == null) { - name = ReportControlBlock_getName(self); + name = Marshal.PtrToStringAnsi(ReportControlBlock_getName(self)); } return name; @@ -2865,7 +2865,6 @@ namespace IEC61850 [DllImport("iec61850", CallingConvention = CallingConvention.Cdecl)] static extern IntPtr ReportControlBlock_getParent(IntPtr self); - private RCBEventHandler rcbEventHandler = null; private object rcbEventHandlerParameter = null; diff --git a/dotnet/server1/Program.cs b/dotnet/server1/Program.cs index 2d2801dc..9a5cc89b 100644 --- a/dotnet/server1/Program.cs +++ b/dotnet/server1/Program.cs @@ -71,10 +71,19 @@ namespace server1 { Console.WriteLine("RCB: " + rcb.Parent.GetObjectReference() + "." + rcb.Name + " event: " + eventType.ToString()); + if (con != null) + { + Console.WriteLine(" caused by client " + con.GetPeerAddress()); + } + else + { + Console.WriteLine(" client = null"); + } + if (eventType == RCBEventType.ENABLED) { - //Console.WriteLine(" RptID: " + rcb.RptID); - //Console.WriteLine(" DatSet: " + rcb.DataSet); + Console.WriteLine(" RptID: " + rcb.RptID); + Console.WriteLine(" DatSet: " + rcb.DataSet); Console.WriteLine(" TrgOps: " + rcb.TrgOps.ToString()); } diff --git a/src/iec61850/inc/iec61850_dynamic_model.h b/src/iec61850/inc/iec61850_dynamic_model.h index 71cc901d..0945ee94 100644 --- a/src/iec61850/inc/iec61850_dynamic_model.h +++ b/src/iec61850/inc/iec61850_dynamic_model.h @@ -243,27 +243,96 @@ ReportControlBlock_isBuffered(ReportControlBlock* self); LIB61850_API LogicalNode* ReportControlBlock_getParent(ReportControlBlock* self); +/** + * \brief Get the name of the currently set report ID + * + * \param self the RCB instance + * + * \return a null terminated string containing the current data set name (the string has to be released by the caller!) + */ LIB61850_API char* ReportControlBlock_getRptID(ReportControlBlock* self); -LIB61850_API int +/** + * \brief Check if RCB instance is enabled + * + * \param self the RCB instance + * + * \return true when the RCB instance is enabled, false otherwise + */ +LIB61850_API bool ReportControlBlock_getRptEna(ReportControlBlock* self); +/** + * \brief Get the name of the currenlty set data set + * + * \param self the RCB instance + * + * \return a null terminated string containing the current data set name (the string has to be released by the caller!) + */ LIB61850_API char* ReportControlBlock_getDataSet(ReportControlBlock* self); +/** + * \brief Get the confRev value + * + * \param self the RCB instance + * + * \return confRev value + */ LIB61850_API uint32_t ReportControlBlock_getConfRev(ReportControlBlock* self); +/** + * \brief Get the currently set OptFlds value + * + * The OptField (option field) value is a bit field with the following fields: + * - RPT_OPT_SEQ_NUM + * - RPT_OPT_TIME_STAMP + * - RPT_OPT_REASON_FOR_INCLUSION + * - RPT_OPT_DATA_SET + * - RPT_OPT_DATA_REFERENCE + * - RPT_OPT_BUFFER_OVERFLOW + * - RPT_OPT_ENTRY_ID + * - RPT_OPT_CONF_REV + * + * \param self the RCB instance + * + * \return OptFlds options value + */ LIB61850_API uint32_t ReportControlBlock_getOptFlds(ReportControlBlock* self); +/** + * \brief Get the BufTm value (buffer time) + * + * The buffer time is the maximum value between an event and + * the actual report generation. + * + * \param self the RCB instance + * + * \return bufTm value + */ LIB61850_API uint32_t ReportControlBlock_getBufTm(ReportControlBlock* self); LIB61850_API uint16_t ReportControlBlock_getSqNum(ReportControlBlock* self); +/** + * \brief Get the currently set trigger options + * + * The trigger option value is a bit field with the following fields: + * - TRG_OPT_DATA_CHANGED + * - TRG_OPT_QUALITY_CHANGED + * - TRG_OPT_DATA_UPDATE + * - TRG_OPT_INTEGRITY + * - TRG_OPT_GI + * + * \param self the RCB instance + * + * \return trigger options value + */ LIB61850_API uint32_t ReportControlBlock_getTrgOps(ReportControlBlock* self); diff --git a/src/iec61850/server/mms_mapping/mms_goose.c b/src/iec61850/server/mms_mapping/mms_goose.c index 11e83202..a5352b00 100644 --- a/src/iec61850/server/mms_mapping/mms_goose.c +++ b/src/iec61850/server/mms_mapping/mms_goose.c @@ -444,12 +444,14 @@ MmsGooseControlBlock_enable(MmsGooseControlBlock self, MmsMapping* mmsMapping) /* Calculate maximum GOOSE message size */ int maxGooseMessageSize = 26 + 51 + 6; - maxGooseMessageSize += strlen(self->goCBRef); + maxGooseMessageSize += (int)strlen(self->goCBRef); + if (self->goId) - maxGooseMessageSize += strlen(self->goId); + maxGooseMessageSize += (int)strlen(self->goId); else - maxGooseMessageSize += strlen(self->goCBRef); - maxGooseMessageSize += strlen(self->dataSetRef); + maxGooseMessageSize += (int)strlen(self->goCBRef); + + maxGooseMessageSize += (int)strlen(self->dataSetRef); maxGooseMessageSize += dataSetSize; @@ -466,7 +468,6 @@ MmsGooseControlBlock_enable(MmsGooseControlBlock self, MmsMapping* mmsMapping) MmsValue_setBoolean(goEna, true); - MmsValue* dstAddress = MmsValue_getElement(self->mmsValue, 5); CommParameters commParameters; @@ -515,7 +516,6 @@ MmsGooseControlBlock_enable(MmsGooseControlBlock self, MmsMapping* mmsMapping) LinkedList_add(self->dataSetValues, dataSetEntry->value); dataSetEntry = dataSetEntry->sibling; } - } else { if (DEBUG_IED_SERVER) diff --git a/src/iec61850/server/mms_mapping/reporting.c b/src/iec61850/server/mms_mapping/reporting.c index f7020dd8..8efc160c 100644 --- a/src/iec61850/server/mms_mapping/reporting.c +++ b/src/iec61850/server/mms_mapping/reporting.c @@ -3942,7 +3942,7 @@ ReportControl_valueUpdated(ReportControl* self, int dataSetEntryIndex, int flag, ReportControl_unlockNotify(self); } -int +bool ReportControlBlock_getRptEna(ReportControlBlock* self) { if (self->trgOps & 64) { @@ -3976,7 +3976,7 @@ ReportControlBlock_getRptID(ReportControlBlock* self) return rptIdStr; } else { - return self->rptId; + return strdup(self->rptId); } } @@ -4001,7 +4001,7 @@ ReportControlBlock_getDataSet(ReportControlBlock* self) return dataSetStr; } else { - return self->dataSetName; + return strdup(self->dataSetName); } }