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 51a60770..d2f898de 100644 Binary files a/tools/model_generator/genconfig.jar and b/tools/model_generator/genconfig.jar differ diff --git a/tools/model_generator/genmodel.jar b/tools/model_generator/genmodel.jar index 84067d06..7edb5dba 100644 Binary files a/tools/model_generator/genmodel.jar and b/tools/model_generator/genmodel.jar differ 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) {