From 386d2acd325e055788398ea443ce29f1b2b6b6dd Mon Sep 17 00:00:00 2001 From: Michael Zillgith Date: Wed, 28 Oct 2015 10:37:24 +0100 Subject: [PATCH] - .NET API: added methods GetEntryID/SetEntryID to ReportControlBlock - client API: added function ClientReport_getDataSetName - common API: added function MmsValue_getStringSize - API: changed some char* to const char* --- .../IEC61850forCSharp/ReportControlBlock.cs | 36 +++++++++++++++++++ src/iec61850/client/client_goose_control.c | 4 +-- src/iec61850/client/client_report.c | 33 +++++++++++++++++ src/iec61850/client/client_report_control.c | 4 +-- src/iec61850/client/ied_connection.c | 4 +-- src/iec61850/inc/iec61850_client.h | 19 +++++++--- src/iec61850/inc/iec61850_server.h | 2 +- .../inc_private/ied_connection_private.h | 2 +- src/iec61850/inc_private/mms_mapping.h | 4 +-- src/iec61850/server/impl/ied_server.c | 4 +-- src/iec61850/server/mms_mapping/mms_goose.c | 2 +- src/iec61850/server/mms_mapping/mms_mapping.c | 4 +-- src/iec61850/server/mms_mapping/reporting.c | 2 +- src/mms/inc/mms_value.h | 19 +++++++++- src/mms/inc_private/mms_server_connection.h | 2 +- src/mms/iso_mms/common/mms_value.c | 11 +++++- .../iso_mms/server/mms_server_connection.c | 2 +- src/vs/libiec61850-wo-goose.def | 4 ++- src/vs/libiec61850.def | 2 ++ 19 files changed, 135 insertions(+), 25 deletions(-) diff --git a/dotnet/IEC61850forCSharp/ReportControlBlock.cs b/dotnet/IEC61850forCSharp/ReportControlBlock.cs index 76cf65fc..889e8d61 100644 --- a/dotnet/IEC61850forCSharp/ReportControlBlock.cs +++ b/dotnet/IEC61850forCSharp/ReportControlBlock.cs @@ -429,6 +429,42 @@ namespace IEC61850 return retVal.AddMilliseconds (entryTime); } + /// + /// Gets the entryID of RCB + /// + /// Returns the EntryID of the last received GetRCBValues service response. + /// The EntryID is only present in buffered RCBs (BRCBs). + /// + /// The entry ID + public byte[] GetEntryID() + { + IntPtr entryIdRef = ClientReportControlBlock_getEntryId (self); + + if (entryIdRef == IntPtr.Zero) + return null; + else { + MmsValue entryId = new MmsValue (entryIdRef); + + return entryId.getOctetString (); + } + } + + public void SetEntryID(byte[] entryId) + { + flagEntryId = true; + + + + MmsValue entryID = MmsValue.NewOctetString (entryId.Length); + + entryID.setOctetString (entryId); + + ClientReportControlBlock_setEntryId (self, entryID.valueReference); + + + } + + /// /// Gets the data set reference of the associated data set /// diff --git a/src/iec61850/client/client_goose_control.c b/src/iec61850/client/client_goose_control.c index f6d7a61e..65eec919 100644 --- a/src/iec61850/client/client_goose_control.c +++ b/src/iec61850/client/client_goose_control.c @@ -90,7 +90,7 @@ ClientGooseControlBlock_setGoEna(ClientGooseControlBlock self, bool goEna) MmsValue_setBoolean(self->goEna, goEna); } -char* +const char* ClientGooseControlBlock_getGoID(ClientGooseControlBlock self) { if (self->goID != NULL) @@ -108,7 +108,7 @@ ClientGooseControlBlock_setGoID(ClientGooseControlBlock self, const char* goID) MmsValue_setVisibleString(self->goID, goID); } -char* +const char* ClientGooseControlBlock_getDatSet(ClientGooseControlBlock self) { if (self->datSet != NULL) diff --git a/src/iec61850/client/client_report.c b/src/iec61850/client/client_report.c index ad07eb4f..f930c4cd 100644 --- a/src/iec61850/client/client_report.c +++ b/src/iec61850/client/client_report.c @@ -37,6 +37,10 @@ struct sClientReport void* callbackParameter; char* rcbReference; char* rptId; + + char* dataSetName; + int dataSetNameSize; /* size of the dataSetName buffer */ + MmsValue* entryId; MmsValue* dataReferences; MmsValue* dataSetValues; @@ -106,6 +110,9 @@ ClientReport_destroy(ClientReport self) if (self->reasonForInclusion != NULL) GLOBAL_FREEMEM(self->reasonForInclusion); + if (self->dataSetName != NULL) + GLOBAL_FREEMEM((void*) self->dataSetName); + GLOBAL_FREEMEM(self); } @@ -221,6 +228,12 @@ ClientReport_getDataReference(ClientReport self, int elementIndex) return dataReference; } +const char* +ClientReport_getDataSetName(ClientReport self) +{ + return self->dataSetName; +} + MmsValue* ClientReport_getDataSetValues(ClientReport self) { @@ -397,6 +410,26 @@ private_IedConnection_handleReport(IedConnection self, MmsValue* value) /* check if data set name is present */ if (MmsValue_getBitStringBit(optFlds, 4) == true) { matchingReport->hasDataSetName = true; + + MmsValue* dataSetName = MmsValue_getElement(value, inclusionIndex); + + const char* dataSetNameStr = MmsValue_toString(dataSetName); + + if (matchingReport->dataSetName == NULL) { + matchingReport->dataSetName = (char*) GLOBAL_MALLOC(MmsValue_getStringSize(dataSetName) + 1); + matchingReport->dataSetNameSize = MmsValue_getStringSize(dataSetName) + 1; + } + else { + if (matchingReport->dataSetNameSize < MmsValue_getStringSize(dataSetName) + 1) { + GLOBAL_FREEMEM((void*) matchingReport->dataSetName); + + matchingReport->dataSetName = (char*) GLOBAL_MALLOC(MmsValue_getStringSize(dataSetName) + 1); + matchingReport->dataSetNameSize = MmsValue_getStringSize(dataSetName) + 1; + } + } + + strcpy(matchingReport->dataSetName, dataSetNameStr); + inclusionIndex++; } diff --git a/src/iec61850/client/client_report_control.c b/src/iec61850/client/client_report_control.c index 933a9378..3d01defe 100644 --- a/src/iec61850/client/client_report_control.c +++ b/src/iec61850/client/client_report_control.c @@ -93,7 +93,7 @@ ClientReportControlBlock_isBuffered(ClientReportControlBlock self) return self->isBuffered; } -char* +const char* ClientReportControlBlock_getRptId(ClientReportControlBlock self) { if (self->rptId != NULL) @@ -150,7 +150,7 @@ ClientReportControlBlock_setResv(ClientReportControlBlock self, bool resv) MmsValue_setBoolean(self->resv, resv); } -char* +const char* ClientReportControlBlock_getDataSetReference(ClientReportControlBlock self) { if (self->datSet != NULL) diff --git a/src/iec61850/client/ied_connection.c b/src/iec61850/client/ied_connection.c index b13c3011..7c305683 100644 --- a/src/iec61850/client/ied_connection.c +++ b/src/iec61850/client/ied_connection.c @@ -238,7 +238,7 @@ ClientDataSet_getDataSetSize(ClientDataSet self) } bool -private_IedConnection_doesControlObjectMatch(char* objRef, char* cntrlObj) +private_IedConnection_doesControlObjectMatch(const char* objRef, const char* cntrlObj) { int i = 0; @@ -420,7 +420,7 @@ handleLastApplErrorMessage(IedConnection self, MmsValue* lastApplError) while (control != NULL) { ControlObjectClient object = (ControlObjectClient) control->data; - char* objectRef = ControlObjectClient_getObjectReference(object); + const char* objectRef = ControlObjectClient_getObjectReference(object); if (private_IedConnection_doesControlObjectMatch(objectRef, MmsValue_toString(cntrlObj))) { ControlObjectClient_setLastApplError(object, self->lastApplError); diff --git a/src/iec61850/inc/iec61850_client.h b/src/iec61850/inc/iec61850_client.h index 9fdea010..f0b86f81 100644 --- a/src/iec61850/inc/iec61850_client.h +++ b/src/iec61850/inc/iec61850_client.h @@ -363,13 +363,13 @@ ClientGooseControlBlock_getGoEna(ClientGooseControlBlock self); void ClientGooseControlBlock_setGoEna(ClientGooseControlBlock self, bool goEna); -char* +const char* ClientGooseControlBlock_getGoID(ClientGooseControlBlock self); void ClientGooseControlBlock_setGoID(ClientGooseControlBlock self, const char* goID); -char* +const char* ClientGooseControlBlock_getDatSet(ClientGooseControlBlock self); void @@ -679,6 +679,17 @@ IedConnection_triggerGIReport(IedConnection self, IedClientError* error, const c * Access to received reports ****************************************/ +/** + * \brief Get the name of the report data set + * + * NOTE: the returned string is only valid as long as the ClientReport instance exists! + * + * \param self the ClientReport instance + * \return report data set name as 0 terminated string + */ +const char* +ClientReport_getDataSetName(ClientReport self); + /** * \brief return the received data set values of the report * @@ -843,7 +854,7 @@ ClientReportControlBlock_getObjectReference(ClientReportControlBlock self); bool ClientReportControlBlock_isBuffered(ClientReportControlBlock self); -char* +const char* ClientReportControlBlock_getRptId(ClientReportControlBlock self); void @@ -861,7 +872,7 @@ ClientReportControlBlock_getResv(ClientReportControlBlock self); void ClientReportControlBlock_setResv(ClientReportControlBlock self, bool resv); -char* +const char* ClientReportControlBlock_getDataSetReference(ClientReportControlBlock self); /** diff --git a/src/iec61850/inc/iec61850_server.h b/src/iec61850/inc/iec61850_server.h index 834a4673..1af1dba5 100644 --- a/src/iec61850/inc/iec61850_server.h +++ b/src/iec61850/inc/iec61850_server.h @@ -454,7 +454,7 @@ IedServer_getBitStringAttributeValue(IedServer self, const DataAttribute* dataAt * * \return the value as a C string (null terminated string) */ -char* +const char* IedServer_getStringAttributeValue(IedServer self, const DataAttribute* dataAttribute); diff --git a/src/iec61850/inc_private/ied_connection_private.h b/src/iec61850/inc_private/ied_connection_private.h index 1334ed10..b2a7bb6d 100644 --- a/src/iec61850/inc_private/ied_connection_private.h +++ b/src/iec61850/inc_private/ied_connection_private.h @@ -73,7 +73,7 @@ IedClientError private_IedConnection_mapMmsErrorToIedError(MmsError mmsError); bool -private_IedConnection_doesControlObjectMatch(char* objRef, char* cntrlObj); +private_IedConnection_doesControlObjectMatch(const char* objRef, const char* cntrlObj); void private_IedConnection_addControlClient(IedConnection self, ControlObjectClient control); diff --git a/src/iec61850/inc_private/mms_mapping.h b/src/iec61850/inc_private/mms_mapping.h index 11e7a778..b969b48c 100644 --- a/src/iec61850/inc_private/mms_mapping.h +++ b/src/iec61850/inc_private/mms_mapping.h @@ -118,10 +118,10 @@ ControlObject* MmsMapping_getControlObject(MmsMapping* self, MmsDomain* domain, char* lnName, char* coName); MmsNamedVariableList -MmsMapping_getDomainSpecificVariableList(MmsMapping* self, char* variableListReference); +MmsMapping_getDomainSpecificVariableList(MmsMapping* self, const char* variableListReference); DataSet* -MmsMapping_getDomainSpecificDataSet(MmsMapping* self, char* dataSetName); +MmsMapping_getDomainSpecificDataSet(MmsMapping* self, const char* dataSetName); void MmsMapping_freeDynamicallyCreatedDataSet(DataSet* dataSet); diff --git a/src/iec61850/server/impl/ied_server.c b/src/iec61850/server/impl/ied_server.c index 5f418cf6..7652650a 100644 --- a/src/iec61850/server/impl/ied_server.c +++ b/src/iec61850/server/impl/ied_server.c @@ -742,7 +742,7 @@ IedServer_getBitStringAttributeValue(IedServer self, const DataAttribute* dataAt return MmsValue_getBitStringAsInteger(dataAttribute->mmsValue); } -char* +const char* IedServer_getStringAttributeValue(IedServer self, const DataAttribute* dataAttribute) { assert(self != NULL); @@ -933,7 +933,7 @@ IedServer_updateVisibleStringAttributeValue(IedServer self, DataAttribute* dataA assert(dataAttribute != NULL); assert(self != NULL); - char *currentValue = MmsValue_toString(dataAttribute->mmsValue); + const char *currentValue = MmsValue_toString(dataAttribute->mmsValue); if (!strcmp(currentValue ,value)) { checkForUpdateTrigger(self, dataAttribute); diff --git a/src/iec61850/server/mms_mapping/mms_goose.c b/src/iec61850/server/mms_mapping/mms_goose.c index 175da405..85428f30 100644 --- a/src/iec61850/server/mms_mapping/mms_goose.c +++ b/src/iec61850/server/mms_mapping/mms_goose.c @@ -187,7 +187,7 @@ MmsGooseControlBlock_enable(MmsGooseControlBlock self) self->dataSet = NULL; - char* dataSetRef = MmsValue_toString(MmsValue_getElement(self->mmsValue, 2)); + const char* dataSetRef = MmsValue_toString(MmsValue_getElement(self->mmsValue, 2)); if (dataSetRef != NULL) { diff --git a/src/iec61850/server/mms_mapping/mms_mapping.c b/src/iec61850/server/mms_mapping/mms_mapping.c index 959d24ca..15b57642 100644 --- a/src/iec61850/server/mms_mapping/mms_mapping.c +++ b/src/iec61850/server/mms_mapping/mms_mapping.c @@ -2744,7 +2744,7 @@ MmsMapping_createDataSetByNamedVariableList(MmsMapping* self, MmsNamedVariableLi } MmsNamedVariableList -MmsMapping_getDomainSpecificVariableList(MmsMapping* self, char* variableListReference) +MmsMapping_getDomainSpecificVariableList(MmsMapping* self, const char* variableListReference) { char variableListReferenceCopy[193]; @@ -2773,7 +2773,7 @@ MmsMapping_getDomainSpecificVariableList(MmsMapping* self, char* variableListRef } DataSet* -MmsMapping_getDomainSpecificDataSet(MmsMapping* self, char* dataSetName) +MmsMapping_getDomainSpecificDataSet(MmsMapping* self, const char* dataSetName) { MmsNamedVariableList variableList = MmsMapping_getDomainSpecificVariableList(self, dataSetName); diff --git a/src/iec61850/server/mms_mapping/reporting.c b/src/iec61850/server/mms_mapping/reporting.c index 8d06212e..61ee939f 100644 --- a/src/iec61850/server/mms_mapping/reporting.c +++ b/src/iec61850/server/mms_mapping/reporting.c @@ -489,7 +489,7 @@ updateReportDataset(MmsMapping* mapping, ReportControl* rc, MmsValue* newDatSet, } if (dataSetValue != NULL) { - char* dataSetName = MmsValue_toString(dataSetValue); + const char* dataSetName = MmsValue_toString(dataSetValue); DataSet* dataSet = IedModel_lookupDataSet(mapping->model, dataSetName); diff --git a/src/mms/inc/mms_value.h b/src/mms/inc/mms_value.h index 4c07e1a3..0a8aeb8a 100644 --- a/src/mms/inc/mms_value.h +++ b/src/mms/inc/mms_value.h @@ -292,9 +292,26 @@ MmsValue_setBoolean(MmsValue* value, bool boolValue); bool MmsValue_getBoolean(const MmsValue* value); -char* +/** + * \brief Returns the value of an MMS_VISIBLE_STRING object as C string + * + * \param self MmsValue instance to operate on. Has to be of a type MMS_VISIBLE_STRING or MMS_STRING. + * + * \returns the string value as 0 terminated C string + */ +const char* MmsValue_toString(MmsValue* self); +/** + * \brief Returns the (maximum) length of the string + * + * NOTE: this function return the amount of memory allocated for the string buffer - 1. + * + * \param self MmsValue instance to operate on. Has to be of a type MMS_VISIBLE_STRING or MMS_STRING. + */ +int +MmsValue_getStringSize(MmsValue* self); + void MmsValue_setVisibleString(MmsValue* self, const char* string); diff --git a/src/mms/inc_private/mms_server_connection.h b/src/mms/inc_private/mms_server_connection.h index df5046d9..8102bed6 100644 --- a/src/mms/inc_private/mms_server_connection.h +++ b/src/mms/inc_private/mms_server_connection.h @@ -49,7 +49,7 @@ bool MmsServerConnection_addNamedVariableList(MmsServerConnection self, MmsNamedVariableList variableList); MmsNamedVariableList -MmsServerConnection_getNamedVariableList(MmsServerConnection self, char* variableListName); +MmsServerConnection_getNamedVariableList(MmsServerConnection self, const char* variableListName); LinkedList MmsServerConnection_getNamedVariableLists(MmsServerConnection self); diff --git a/src/mms/iso_mms/common/mms_value.c b/src/mms/iso_mms/common/mms_value.c index 074e732b..8c9492a4 100644 --- a/src/mms/iso_mms/common/mms_value.c +++ b/src/mms/iso_mms/common/mms_value.c @@ -1727,7 +1727,7 @@ MmsValue_setVisibleString(MmsValue* self, const char* string) } } -char* +const char* MmsValue_toString(MmsValue* self) { if ((self->type == MMS_VISIBLE_STRING) || (self->type == MMS_STRING)) @@ -1736,6 +1736,15 @@ MmsValue_toString(MmsValue* self) return NULL; } +int +MmsValue_getStringSize(MmsValue* self) +{ + if ((self->type == MMS_VISIBLE_STRING) || (self->type == MMS_STRING)) + return self->value.visibleString.size; + else + return 0; +} + MmsValue* MmsValue_newUtcTime(uint32_t timeval) { diff --git a/src/mms/iso_mms/server/mms_server_connection.c b/src/mms/iso_mms/server/mms_server_connection.c index d6119930..60bc6543 100644 --- a/src/mms/iso_mms/server/mms_server_connection.c +++ b/src/mms/iso_mms/server/mms_server_connection.c @@ -353,7 +353,7 @@ MmsServerConnection_deleteNamedVariableList(MmsServerConnection self, char* list } MmsNamedVariableList -MmsServerConnection_getNamedVariableList(MmsServerConnection self, char* variableListName) +MmsServerConnection_getNamedVariableList(MmsServerConnection self, const char* variableListName) { //TODO remove code duplication - similar to MmsDomain_getNamedVariableList ! MmsNamedVariableList variableList = NULL; diff --git a/src/vs/libiec61850-wo-goose.def b/src/vs/libiec61850-wo-goose.def index f43450a4..9b30b7d0 100644 --- a/src/vs/libiec61850-wo-goose.def +++ b/src/vs/libiec61850-wo-goose.def @@ -492,4 +492,6 @@ EXPORTS ControlObjectClient_useConstantT ControlObjectClient_setOrigin LogicalDevice_getChildByMmsVariableName - LogicalNode_getDataSet + LogicalNode_getDataSet + ClientReport_getDataSetName + MmsValue_getStringSize \ No newline at end of file diff --git a/src/vs/libiec61850.def b/src/vs/libiec61850.def index 52d5ba48..a88a7fc5 100644 --- a/src/vs/libiec61850.def +++ b/src/vs/libiec61850.def @@ -517,3 +517,5 @@ EXPORTS ControlObjectClient_setOrigin LogicalDevice_getChildByMmsVariableName LogicalNode_getDataSet + ClientReport_getDataSetName + MmsValue_getStringSize