From 922c5eec50a9aa1f5fe9e7bfa23a7c1094873b31 Mon Sep 17 00:00:00 2001 From: Michael Zillgith Date: Thu, 9 Jun 2016 00:40:32 +0200 Subject: [PATCH] - make GetLogicalNodeDirectory(DATA SET) dynamic. Creates a request at each call. --- examples/server_example1/server_example1.c | 2 - src/iec61850/client/ied_connection.c | 90 ++++++++++------------ src/iec61850/inc/iec61850_client.h | 5 +- 3 files changed, 43 insertions(+), 54 deletions(-) diff --git a/examples/server_example1/server_example1.c b/examples/server_example1/server_example1.c index 14a0b2a1..f702b1ad 100644 --- a/examples/server_example1/server_example1.c +++ b/examples/server_example1/server_example1.c @@ -49,8 +49,6 @@ int main(int argc, char** argv) { IedServer iedServer = IedServer_create(&iedModel); - // get stored values from persistent storage - // set initial measurement and status values from process /* MMS server will be instructed to start listening to client connections. */ diff --git a/src/iec61850/client/ied_connection.c b/src/iec61850/client/ied_connection.c index 3b87f4e9..bf1782f4 100644 --- a/src/iec61850/client/ied_connection.c +++ b/src/iec61850/client/ied_connection.c @@ -39,7 +39,6 @@ typedef struct sICLogicalDevice { char* name; LinkedList variables; - LinkedList dataSets; } ICLogicalDevice; struct sClientDataSet @@ -165,12 +164,6 @@ ICLogicalDevice_setVariableList(ICLogicalDevice* self, LinkedList variables) self->variables = variables; } -static void -ICLogicalDevice_setDataSetList(ICLogicalDevice* self, LinkedList dataSets) -{ - self->dataSets = dataSets; -} - static void ICLogicalDevice_destroy(ICLogicalDevice* self) { @@ -179,9 +172,6 @@ ICLogicalDevice_destroy(ICLogicalDevice* self) if (self->variables != NULL) LinkedList_destroy(self->variables); - if (self->dataSets != NULL) - LinkedList_destroy(self->dataSets); - GLOBAL_FREEMEM(self); } @@ -1015,16 +1005,6 @@ IedConnection_getDeviceModelFromServer(IedConnection self, IedClientError* error break; } - LinkedList dataSets = MmsConnection_getDomainVariableListNames(self->connection, - &mmsError, name); - - if (dataSets != NULL) - ICLogicalDevice_setDataSetList(icLogicalDevice, dataSets); - else { - *error = iedConnection_mapMmsErrorToIedError(mmsError); - break; - } - LinkedList_add(logicalDevices, icLogicalDevice); logicalDevice = LinkedList_getNext(logicalDevice); @@ -1354,6 +1334,41 @@ getLogicalNodeDirectoryDataSets(IedConnection self, IedClientError* error, const const char* logicalNodeName) { MmsConnection mmsCon = self->connection; + + MmsError mmsError; + + LinkedList dataSets = MmsConnection_getDomainVariableListNames(mmsCon, &mmsError, logicalDeviceName); + + if (mmsError != MMS_ERROR_NONE) { + *error = iedConnection_mapMmsErrorToIedError(mmsError); + return NULL; + } + + LinkedList lnDataSets = LinkedList_create(); + + LinkedList dataSet = LinkedList_getNext(dataSets); + + while (dataSet != NULL) { + char* dataSetName = (char*) LinkedList_getData(dataSet); + + char* lnDataSetName = strchr(dataSetName, '$'); + + if (lnDataSetName != NULL) { + lnDataSetName[0] = 0; + lnDataSetName += 1; + + if (strcmp(dataSetName, logicalNodeName) == 0) { + char* lnDataSet = copyString(lnDataSetName); + LinkedList_add(lnDataSets, (void*) lnDataSet); + } + } + + dataSet = LinkedList_getNext(dataSet); + } + + LinkedList_destroy(dataSets); + + return lnDataSets; } LinkedList /**/ @@ -1385,9 +1400,11 @@ IedConnection_getLogicalNodeDirectory(IedConnection self, IedClientError* error, char* logicalNodeName = ldSep + 1; - if (acsiClass == ACSI_CLASS_LOG) { + if (acsiClass == ACSI_CLASS_LOG) return getLogicalNodeDirectoryLogs(self, error, logicalDeviceName, logicalNodeName); - } + + if (acsiClass == ACSI_CLASS_DATA_SET) + return getLogicalNodeDirectoryDataSets(self, error, logicalDeviceName, logicalNodeName); if (self->logicalDevices == NULL) IedConnection_getDeviceModelFromServer(self, error); @@ -1498,35 +1515,6 @@ IedConnection_getLogicalNodeDirectory(IedConnection self, IedClientError* error, addVariablesWithFc("LG", logicalNodeName, ld->variables, lnDirectory); break; - case ACSI_CLASS_DATA_SET: - { - LinkedList dataSet = LinkedList_getNext(ld->dataSets); - - while (dataSet != NULL) { - char* dataSetName = (char*) dataSet->data; - - char* fcPos = strchr(dataSetName, '$'); - - if (fcPos == NULL) - goto next_data_set_element; - - size_t lnNameLen = fcPos - dataSetName; - - if (strlen(logicalNodeName) != lnNameLen) - goto next_data_set_element; - - if (memcmp(dataSetName, logicalNodeName, lnNameLen) != 0) - goto next_data_set_element; - - LinkedList_add(lnDirectory, copyString(fcPos + 1)); - - next_data_set_element: - - dataSet = LinkedList_getNext(dataSet); - } - } - break; - default: if (DEBUG_IED_CLIENT) printf("IED_CLIENT: ACSI class not yet supported!\n"); diff --git a/src/iec61850/inc/iec61850_client.h b/src/iec61850/inc/iec61850_client.h index b5ce446c..76ec2c26 100644 --- a/src/iec61850/inc/iec61850_client.h +++ b/src/iec61850/inc/iec61850_client.h @@ -1661,7 +1661,10 @@ IedConnection_getLogicalNodeVariables(IedConnection self, IedClientError* error, /** * \brief returns the directory of the given logical node (LN) containing elements of the specified ACSI class * - * Implementation of the GetLogicalNodeDirectory ACSI service. + * Implementation of the GetLogicalNodeDirectory ACSI service. In contrast to the ACSI description this + * function does not always creates a request to the server. For most ACSI classes it simply accesses the + * data model that was retrieved before. An exception to this rule are the ACSI classes ACSI_CLASS_DATASET and + * ACSI_CLASS_LOG. Both always perform a request to the server. * * \param self the connection object * \param error the error code if an error occurs