From 66da568bea8bd59c43346a2fa799fd9abe3b817f Mon Sep 17 00:00:00 2001 From: Michael Zillgith Date: Thu, 4 Dec 2014 14:30:37 +0100 Subject: [PATCH] - fixed bug with setting groups --- .../goose_publisher/goose_publisher_example.c | 3 +- src/mms/iso_mms/server/mms_access_result.c | 29 +++++++++----- src/mms/iso_mms/server/mms_read_service.c | 12 ++++-- src/mms/iso_mms/server/mms_server.c | 11 ++++-- src/mms/iso_server/iso_connection.c | 15 ++++--- tools/model_generator/genconfig.jar | Bin 73079 -> 73492 bytes tools/model_generator/genmodel.jar | Bin 73078 -> 73220 bytes .../scl/DataAttributeDefinition.java | 13 ++---- .../libiec61850/scl/model/DataModelValue.java | 37 +++++++++++++++++- .../src/com/libiec61850/scl/model/IED.java | 7 ++++ .../tools/DynamicModelGenerator.java | 7 +++- 11 files changed, 100 insertions(+), 34 deletions(-) diff --git a/examples/goose_publisher/goose_publisher_example.c b/examples/goose_publisher/goose_publisher_example.c index 47b0390a..1b6c0107 100644 --- a/examples/goose_publisher/goose_publisher_example.c +++ b/examples/goose_publisher/goose_publisher_example.c @@ -11,6 +11,7 @@ #include "mms_value.h" #include "goose_publisher.h" +#include "hal_thread.h" // has to be executed as root! int @@ -44,7 +45,7 @@ main(int argc, char** argv) int i = 0; for (i = 0; i < 3; i++) { - sleep(1); + Thread_sleep(1000); if (GoosePublisher_publish(publisher, dataSetValues) == -1) { printf("Error sending message!\n"); diff --git a/src/mms/iso_mms/server/mms_access_result.c b/src/mms/iso_mms/server/mms_access_result.c index 627e3535..767f04ca 100644 --- a/src/mms/iso_mms/server/mms_access_result.c +++ b/src/mms/iso_mms/server/mms_access_result.c @@ -28,9 +28,12 @@ static int encodeArrayAccessResult(MmsValue* value, uint8_t* buffer, int bufPos, bool encode) { - int elementsSize = 0; + if (value == NULL) // TODO report internal error + return 0; + int elementsSize = 0; int i; + int size; int arraySize = MmsValue_getArraySize(value); @@ -50,21 +53,24 @@ encodeArrayAccessResult(MmsValue* value, uint8_t* buffer, int bufPos, bool encod bufPos = mmsServer_encodeAccessResult(element, buffer, bufPos, true); } - return bufPos; + size = bufPos; } else { - int size = 1 + elementsSize + BerEncoder_determineLengthSize(elementsSize); - - return size; + size = 1 + elementsSize + BerEncoder_determineLengthSize(elementsSize); } + + return size; } static int encodeStructuredAccessResult(MmsValue* value, uint8_t* buffer, int bufPos, bool encode) { - int componentsSize = 0; + if (value == NULL) // TODO report internal error + return 0; + int componentsSize = 0; int i; + int size; int components = value->value.structure.size; @@ -84,18 +90,21 @@ encodeStructuredAccessResult(MmsValue* value, uint8_t* buffer, int bufPos, bool bufPos = mmsServer_encodeAccessResult(component, buffer, bufPos, true); } - return bufPos; + size = bufPos; } else { - int size = 1 + componentsSize + BerEncoder_determineLengthSize(componentsSize); - - return size; + size = 1 + componentsSize + BerEncoder_determineLengthSize(componentsSize); } + + return size; } int mmsServer_encodeAccessResult(MmsValue* value, uint8_t* buffer, int bufPos, bool encode) { + if (value == NULL) // TODO report internal error + return 0; + int size; switch (value->type) { diff --git a/src/mms/iso_mms/server/mms_read_service.c b/src/mms/iso_mms/server/mms_read_service.c index 80399ec7..135ffb08 100644 --- a/src/mms/iso_mms/server/mms_read_service.c +++ b/src/mms/iso_mms/server/mms_read_service.c @@ -69,16 +69,22 @@ addNamedVariableValue(MmsVariableSpecification* namedVariable, MmsServerConnecti int i; for (i = 0; i < componentCount; i++) { - char* newNameIdStr = createString(3, itemId, "$", + char newNameIdStr[65]; + + createStringInBuffer(newNameIdStr, 3, itemId, "$", namedVariable->typeSpec.structure.elements[i]->name); MmsValue* element = addNamedVariableValue(namedVariable->typeSpec.structure.elements[i], connection, domain, newNameIdStr); - MmsValue_setElement(value, i, element); + if (element == NULL) { + MmsValue_delete(value); + value = NULL; + break; + } - GLOBAL_FREEMEM(newNameIdStr); + MmsValue_setElement(value, i, element); } } } diff --git a/src/mms/iso_mms/server/mms_server.c b/src/mms/iso_mms/server/mms_server.c index 42550b3d..6f4f07a9 100644 --- a/src/mms/iso_mms/server/mms_server.c +++ b/src/mms/iso_mms/server/mms_server.c @@ -151,9 +151,8 @@ MmsServer_getValueFromCache(MmsServer self, MmsDomain* domain, char* itemId) { MmsValueCache cache = (MmsValueCache) Map_getEntry(self->valueCaches, domain); - if (cache != NULL) { + if (cache != NULL) return MmsValueCache_lookupValue(cache, itemId); - } return NULL ; } @@ -205,8 +204,11 @@ mmsServer_getValue(MmsServer self, MmsDomain* domain, char* itemId, MmsServerCon MmsDataAccessError accessError = self->readAccessHandler(self->readAccessHandlerParameter, domain, itemId, connection); - if (accessError != DATA_ACCESS_ERROR_SUCCESS) - return NULL; + if (accessError != DATA_ACCESS_ERROR_SUCCESS) { + value = MmsValue_newDataAccessError(accessError); + MmsValue_setDeletable(value); + goto exit_function; + } } value = MmsServer_getValueFromCache(self, domain, itemId); @@ -216,6 +218,7 @@ mmsServer_getValue(MmsServer self, MmsDomain* domain, char* itemId, MmsServerCon value = self->readHandler(self->readHandlerParameter, domain, itemId, connection); +exit_function: return value; } diff --git a/src/mms/iso_server/iso_connection.c b/src/mms/iso_server/iso_connection.c index 19201cd5..8ae5168c 100644 --- a/src/mms/iso_server/iso_connection.c +++ b/src/mms/iso_server/iso_connection.c @@ -130,21 +130,20 @@ IsoConnection_addHandleSet(const IsoConnection self, HandleSet handles) void IsoConnection_handleTcpConnection(IsoConnection self) { - assert(self->msgRcvdHandler != NULL); - TpktState tpktState = CotpConnection_readToTpktBuffer(self->cotpConnection); if (tpktState == TPKT_ERROR) self->state = ISO_CON_STATE_STOPPED; if (tpktState != TPKT_PACKET_COMPLETE) - return; + goto exit_function; CotpIndication cotpIndication = CotpConnection_parseIncomingMessage(self->cotpConnection); switch (cotpIndication) { case COTP_MORE_FRAGMENTS_FOLLOW: - return; + goto exit_function; + case COTP_CONNECT_INDICATION: if (DEBUG_ISO_SERVER) printf("ISO_SERVER: COTP connection indication\n"); @@ -418,6 +417,9 @@ IsoConnection_handleTcpConnection(IsoConnection self) self->state = ISO_CON_STATE_STOPPED; break; } + +exit_function: + return; } #if (CONFIG_MMS_SINGLE_THREADED == 0) @@ -509,7 +511,7 @@ IsoConnection_sendMessage(IsoConnection self, ByteBuffer* message, bool handlerM if (self->state == ISO_CON_STATE_STOPPED) { if (DEBUG_ISO_SERVER) printf("DEBUG_ISO_SERVER: sendMessage: connection already stopped!\n"); - return; + goto exit_error; } #if (CONFIG_MMS_THREADLESS_STACK != 1) @@ -554,6 +556,9 @@ IsoConnection_sendMessage(IsoConnection self, ByteBuffer* message, bool handlerM if (self->isInsideCallback == false) Semaphore_post(self->conMutex); #endif + +exit_error: + return; } void diff --git a/tools/model_generator/genconfig.jar b/tools/model_generator/genconfig.jar index 51a607704ed83d7937fabac716ab1ede51eb763a..d2f898de6436e73021d8b143227173b5b5acd648 100644 GIT binary patch delta 14295 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 OR6zW@JXnZw0RA69W8eM& delta 9536 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 diff --git a/tools/model_generator/src/com/libiec61850/scl/DataAttributeDefinition.java b/tools/model_generator/src/com/libiec61850/scl/DataAttributeDefinition.java index bbc2fba4..6707194a 100644 --- a/tools/model_generator/src/com/libiec61850/scl/DataAttributeDefinition.java +++ b/tools/model_generator/src/com/libiec61850/scl/DataAttributeDefinition.java @@ -109,15 +109,10 @@ public class DataAttributeDefinition { String value = elementNode.getTextContent(); - if (attributeType != AttributeType.ENUMERATED) - try { - this.value = new DataModelValue(attributeType, null, value); - } catch (IllegalValueException e) { - // TODO Auto-generated catch block - e.printStackTrace(); - } - } - + if (attributeType != AttributeType.ENUMERATED) { + this.value = new DataModelValue(attributeType, this.type, value); + } + } } } } diff --git a/tools/model_generator/src/com/libiec61850/scl/model/DataModelValue.java b/tools/model_generator/src/com/libiec61850/scl/model/DataModelValue.java index b924c562..b072dc91 100644 --- a/tools/model_generator/src/com/libiec61850/scl/model/DataModelValue.java +++ b/tools/model_generator/src/com/libiec61850/scl/model/DataModelValue.java @@ -26,17 +26,26 @@ package com.libiec61850.scl.model; import com.libiec61850.scl.types.EnumerationType; import com.libiec61850.scl.types.IllegalValueException; import com.libiec61850.scl.types.SclType; +import com.libiec61850.scl.types.TypeDeclarations; public class DataModelValue { private Object value = null; + private String unknownEnumValue = null; + private String enumType = null; + + public DataModelValue(AttributeType type, String enumType, String value) { + this.unknownEnumValue = value; + this.enumType = enumType; + } public DataModelValue(AttributeType type, SclType sclType, String value) throws IllegalValueException { switch (type) { case ENUMERATED: - EnumerationType enumType = (EnumerationType) sclType; + EnumerationType enumType = (EnumerationType) sclType; this.value = (Object) (new Integer(enumType.getOrdByEnumString(value))); + break; case INT8: case INT16: @@ -95,6 +104,32 @@ public class DataModelValue { return value; } + public String getUnknownEnumValue() { + return unknownEnumValue; + } + + public void updateEnumOrdValue(TypeDeclarations typeDecls) + { + if (enumType != null) { + + System.out.println("Lookup enum type " + enumType); + + SclType sclType = typeDecls.lookupType(enumType); + + if (sclType != null) { + + EnumerationType enumType = (EnumerationType) sclType; + try { + this.value = (Object) (new Integer(enumType.getOrdByEnumString(unknownEnumValue))); + } catch (IllegalValueException e) { + e.printStackTrace(); + } + } + else + System.out.println(" failed!"); + } + } + public long getLongValue() { return (Long) value; } diff --git a/tools/model_generator/src/com/libiec61850/scl/model/IED.java b/tools/model_generator/src/com/libiec61850/scl/model/IED.java index 0c98214e..fb381aeb 100644 --- a/tools/model_generator/src/com/libiec61850/scl/model/IED.java +++ b/tools/model_generator/src/com/libiec61850/scl/model/IED.java @@ -33,6 +33,7 @@ import com.libiec61850.scl.types.TypeDeclarations; public class IED { private String name; private List accessPoints; + private TypeDeclarations typeDeclarations; public IED(Node iedNode, TypeDeclarations typeDeclarations) throws SclParserException { @@ -48,6 +49,12 @@ public class IED { for (Node accessPointNode : accessPointNodes) { this.accessPoints.add(new AccessPoint(accessPointNode, typeDeclarations)); } + + this.typeDeclarations = typeDeclarations; + } + + public TypeDeclarations getTypeDeclarations() { + return typeDeclarations; } public String getName() { diff --git a/tools/model_generator/src/com/libiec61850/tools/DynamicModelGenerator.java b/tools/model_generator/src/com/libiec61850/tools/DynamicModelGenerator.java index 2fb76e4f..d2e65a56 100644 --- a/tools/model_generator/src/com/libiec61850/tools/DynamicModelGenerator.java +++ b/tools/model_generator/src/com/libiec61850/tools/DynamicModelGenerator.java @@ -284,8 +284,13 @@ public class DynamicModelGenerator { DataModelValue value = dataAttribute.getValue(); /* if no value is given use default value for type if present */ - if (value == null) + if (value == null) { value = dataAttribute.getDefinition().getValue(); + + if (value != null) + if (value.getValue() == null) + value.updateEnumOrdValue(ied.getTypeDeclarations()); + } if (value != null) {