diff --git a/src/hal/socket/win32/socket_win32.c b/src/hal/socket/win32/socket_win32.c index 11c5405..1d888e9 100644 --- a/src/hal/socket/win32/socket_win32.c +++ b/src/hal/socket/win32/socket_win32.c @@ -311,7 +311,7 @@ Socket_connect(Socket self, const char* address, int port) timeout.tv_sec = self->connectTimeout / 1000; timeout.tv_usec = (self->connectTimeout % 1000) * 1000; - if (select(self->fd + 1, NULL, &fdSet, NULL, &timeout) == SOCKET_ERROR) + if (select(self->fd + 1, NULL, &fdSet, NULL, &timeout) < 0) return false; else return true; diff --git a/src/iec61850/inc/iec61850_model.h b/src/iec61850/inc/iec61850_model.h index b44378d..01d1a1e 100644 --- a/src/iec61850/inc/iec61850_model.h +++ b/src/iec61850/inc/iec61850_model.h @@ -253,36 +253,52 @@ struct sGSEControlBlock { /** * \brief get the number of direct children of a model node * - * \param node the model node instance + * \param self the model node instance * * \return the number of children of the model node * ΒΈ */ int -ModelNode_getChildCount(ModelNode* modelNode); +ModelNode_getChildCount(ModelNode* self); /** * \brief return a child model node * - * \param node the model node instance - * \param the name of the child model node + * \param self the model node instance + * \param name the name of the child model node * * \return the model node instance or NULL if model node does not exist. */ ModelNode* -ModelNode_getChild(ModelNode* modelNode, const char* name); +ModelNode_getChild(ModelNode* self, const char* name); + +/** + * \brief return a child model node with a given functional constraint + * + * Sometimes the name is not enough to identify a model node. This is the case when + * editable setting groups are used. In this case the setting group members have two different + * model nodes associated that differ in their FC (SG and SE). + * + * \param self the model node instance + * \param name the name of the child model node + * \param fc the functional constraint of the model node + * + * \return the model node instance or NULL if model node does not exist. + */ +ModelNode* +ModelNode_getChildWithFc(ModelNode* self, const char* name, FunctionalConstraint fc); /** * \brief Return the IEC 61850 object reference of a model node * - * \param node the model node instance + * \param self the model node instance * \param objectReference pointer to a buffer where to write the object reference string. If NULL * is given the buffer is allocated by the function. * * \return the object reference string */ char* -ModelNode_getObjectReference(ModelNode* node, char* objectReference); +ModelNode_getObjectReference(ModelNode* self, char* objectReference); /** * \brief Set the name of the IED diff --git a/src/iec61850/server/model/model.c b/src/iec61850/server/model/model.c index d01ac1a..89e3512 100644 --- a/src/iec61850/server/model/model.c +++ b/src/iec61850/server/model/model.c @@ -457,6 +457,56 @@ ModelNode_getChild(ModelNode* self, const char* name) return matchingNode; } +ModelNode* +ModelNode_getChildWithFc(ModelNode* self, const char* name, FunctionalConstraint fc) +{ + // check for separator + const char* separator = strchr(name, '.'); + + int nameElementLength = 0; + + if (separator != NULL) + nameElementLength = (separator - name); + else + nameElementLength = strlen(name); + + ModelNode* nextNode = self->firstChild; + + ModelNode* matchingNode = NULL; + + while (nextNode != NULL) { + int nodeNameLen = strlen(nextNode->name); + + if (nodeNameLen == nameElementLength) { + if (memcmp(nextNode->name, name, nodeNameLen) == 0) { + + if (separator == NULL) { + if (nextNode->modelType == DataAttributeModelType) { + DataAttribute* da = (DataAttribute*) nextNode; + + if (da->fc == fc) { + matchingNode = nextNode; + break; + } + } + } + else { + matchingNode = nextNode; + break; + } + } + } + + nextNode = nextNode->sibling; + } + + if ((separator != NULL) && (matchingNode != NULL)) { + return ModelNode_getChildWithFc(matchingNode, separator + 1, fc); + } + else + return matchingNode; +} + inline LogicalNode* diff --git a/src/mms/iso_session/iso_session.c b/src/mms/iso_session/iso_session.c index 8e0fe0c..e3db269 100644 --- a/src/mms/iso_session/iso_session.c +++ b/src/mms/iso_session/iso_session.c @@ -338,10 +338,7 @@ IsoSession_createFinishSpdu(IsoSession* self, BufferChain buffer, BufferChain pa buf[offset++] = 9; /* FINISH-SPDU code */ - buf[offset++] = 5 + payload->length; /* LI */ - buf[offset++] = 17; /* PI-Code transport-disconnect */ - buf[offset++] = 1; /* LI = 1 */ - buf[offset++] = 2; /* transport-connection-released */ + buf[offset++] = 2 + payload->length; /* LI */ buf[offset++] = 193; /* PGI-Code user data */ buf[offset++] = payload->length; /* LI of user data */ diff --git a/src/vs/libiec61850-wo-goose.def b/src/vs/libiec61850-wo-goose.def index ddfae6b..dbbebc3 100644 --- a/src/vs/libiec61850-wo-goose.def +++ b/src/vs/libiec61850-wo-goose.def @@ -481,4 +481,5 @@ EXPORTS IedServer_getUTCTimeAttributeValue IedServer_getBitStringAttributeValue IedServer_getStringAttributeValue + ModelNode_getChildWithFc diff --git a/src/vs/libiec61850.def b/src/vs/libiec61850.def index 18a6306..0878e2f 100644 --- a/src/vs/libiec61850.def +++ b/src/vs/libiec61850.def @@ -505,4 +505,5 @@ EXPORTS IedServer_getUTCTimeAttributeValue IedServer_getBitStringAttributeValue IedServer_getStringAttributeValue - + ModelNode_getChildWithFc +