From 0e8980ae0f21edc40c84f672e6f2dd0db444d95b Mon Sep 17 00:00:00 2001 From: Michael Zillgith Date: Mon, 26 Jan 2015 15:52:14 +0100 Subject: [PATCH] - added function MmsValue_getUtcTimeBuffer - fixed problem with entry time in buffered reporting - fixed bug in file directory service when clients sends an empty string as filename - fixed problem in file read service. Server now respects the negotiated maximum PDU size --- src/iec61850/inc/iec61850_server.h | 17 ++++++++++++++++- src/iec61850/server/impl/ied_server.c | 18 ++++++++++++++++++ src/iec61850/server/mms_mapping/reporting.c | 1 + src/mms/inc/mms_value.h | 12 ++++++++++++ src/mms/iso_mms/common/mms_value.c | 6 ++++++ src/mms/iso_mms/server/mms_file_service.c | 12 +++++++++--- src/vs/libiec61850-wo-goose.def | 4 +++- src/vs/libiec61850.def | 3 ++- 8 files changed, 67 insertions(+), 6 deletions(-) diff --git a/src/iec61850/inc/iec61850_server.h b/src/iec61850/inc/iec61850_server.h index be780385..8ebc15b8 100644 --- a/src/iec61850/inc/iec61850_server.h +++ b/src/iec61850/inc/iec61850_server.h @@ -597,11 +597,26 @@ IedServer_updateVisibleStringAttributeValue(IedServer self, DataAttribute* dataA * * \param self the instance of IedServer to operate on. * \param dataAttribute the data attribute handle - * \param value the new UTC time value of the data attribute. + * \param value the new UTC time value of the data attribute as a ms timestamp */ void IedServer_updateUTCTimeAttributeValue(IedServer self, DataAttribute* dataAttribute, uint64_t value); +/** + * \brief Update the value of an IEC 61850 UTC time (timestamp) data attribute. + * + * Update the value of a UTC time data attribute without handling MmsValue instances. + * + * This function will also check if a trigger condition is satisfied in the case when a report or GOOSE + * control block is enabled. + * + * \param self the instance of IedServer to operate on. + * \param dataAttribute the data attribute handle + * \param value the new UTC time value of the data attribute as a Timestamp + */ +void +IedServer_updateTimestampAttributeValue(IedServer self, DataAttribute* dataAttribute, Timestamp* timestamp); + /** * \brief Update a quality ("q") IEC 61850 data attribute. * diff --git a/src/iec61850/server/impl/ied_server.c b/src/iec61850/server/impl/ied_server.c index 46d472be..1e3a5d6a 100644 --- a/src/iec61850/server/impl/ied_server.c +++ b/src/iec61850/server/impl/ied_server.c @@ -24,6 +24,7 @@ #include "iec61850_server.h" #include "mms_mapping.h" #include "mms_mapping_internal.h" +#include "mms_value_internal.h" #include "control.h" #include "stack_config.h" #include "ied_server_private.h" @@ -957,6 +958,23 @@ IedServer_updateUTCTimeAttributeValue(IedServer self, DataAttribute* dataAttribu } } +void +IedServer_updateTimestampAttributeValue(IedServer self, DataAttribute* dataAttribute, Timestamp* timestamp) +{ + assert(MmsValue_getType(dataAttribute->mmsValue) == MMS_UTC_TIME); + assert(dataAttribute != NULL); + assert(self != NULL); + + if (memcmp(dataAttribute->mmsValue->value.utcTime, timestamp->val, 8) == 0) { + checkForUpdateTrigger(self, dataAttribute); + } + else { + MmsValue_setUtcTimeByBuffer(dataAttribute->mmsValue, timestamp->val); + + checkForChangedTriggers(self, dataAttribute); + } +} + void IedServer_updateQuality(IedServer self, DataAttribute* dataAttribute, Quality quality) { diff --git a/src/iec61850/server/mms_mapping/reporting.c b/src/iec61850/server/mms_mapping/reporting.c index d49a6064..f5cd0706 100644 --- a/src/iec61850/server/mms_mapping/reporting.c +++ b/src/iec61850/server/mms_mapping/reporting.c @@ -933,6 +933,7 @@ createBufferedReportControlBlock(ReportControlBlock* reportControlBlock, namedVariable = (MmsVariableSpecification*) GLOBAL_CALLOC(1, sizeof(MmsVariableSpecification)); namedVariable->name = copyString("TimeOfEntry"); namedVariable->type = MMS_BINARY_TIME; + namedVariable->typeSpec.binaryTime = 6; rcb->typeSpec.structure.elements[12] = namedVariable; mmsValue->value.structure.components[12] = MmsValue_newBinaryTime(false); diff --git a/src/mms/inc/mms_value.h b/src/mms/inc/mms_value.h index bb86fa07..6a44a0bb 100644 --- a/src/mms/inc/mms_value.h +++ b/src/mms/inc/mms_value.h @@ -437,6 +437,18 @@ MmsValue_setUtcTimeMs(MmsValue* self, uint64_t timeval); void MmsValue_setUtcTimeByBuffer(MmsValue* self, const uint8_t* buffer); +/** + * \brief return the raw buffer containing the UTC time data + * + * Note: This will return the address of the raw byte buffer. The array length is 8 byte. + * + * \param self MmsValue instance to operate on. Has to be of a type MMS_UTCTIME. + * + * \return the buffer containing the raw data + */ +uint8_t* +MmsValue_getUtcTimeBuffer(MmsValue* self); + /** * \brief Get a millisecond time value from an MmsValue object of MMS_UTCTIME type. * diff --git a/src/mms/iso_mms/common/mms_value.c b/src/mms/iso_mms/common/mms_value.c index ee2e3023..cf56ea34 100644 --- a/src/mms/iso_mms/common/mms_value.c +++ b/src/mms/iso_mms/common/mms_value.c @@ -727,6 +727,12 @@ MmsValue_setUtcTimeByBuffer(MmsValue* self, const uint8_t* buffer) } } +uint8_t* +MmsValue_getUtcTimeBuffer(MmsValue* self) +{ + return self->value.utcTime; +} + uint64_t MmsValue_getUtcTimeInMs(const MmsValue* self) { diff --git a/src/mms/iso_mms/server/mms_file_service.c b/src/mms/iso_mms/server/mms_file_service.c index ce1833df..ffaaae62 100644 --- a/src/mms/iso_mms/server/mms_file_service.c +++ b/src/mms/iso_mms/server/mms_file_service.c @@ -315,14 +315,15 @@ exit_reject_invalid_pdu: static void -createFileReadResponse(uint32_t invokeId, ByteBuffer* response, MmsFileReadStateMachine* frsm) +createFileReadResponse(MmsServerConnection* connection, uint32_t invokeId, + ByteBuffer* response, MmsFileReadStateMachine* frsm) { /* determine remaining bytes in file */ uint32_t bytesLeft = frsm->fileSize - frsm->readPosition; uint32_t fileChunkSize = 0; - uint32_t maxFileChunkSize = CONFIG_MMS_MAXIMUM_PDU_SIZE - 15; + uint32_t maxFileChunkSize = connection->maxPduSize - 20; uint32_t fileReadResponseSize = 1; /* for tag */ @@ -384,7 +385,7 @@ mmsServer_handleFileReadRequest( MmsFileReadStateMachine* frsm = getFrsm(connection, frsmId); if (frsm != NULL) - createFileReadResponse(invokeId, response, frsm); + createFileReadResponse(connection, invokeId, response, frsm); else mmsServer_createConfirmedErrorPdu(invokeId, response, MMS_ERROR_FILE_OTHER); } @@ -452,6 +453,11 @@ createFileDirectoryResponse(uint32_t invokeId, ByteBuffer* response, char* direc DirectoryHandle directory = FileSystem_openDirectory(directoryName); + if (continueAfterFileName != NULL) { + if (strlen(continueAfterFileName) == 0) + continueAfterFileName = NULL; + } + if (directory != NULL) { bool isDirectory; char* fileName = FileSystem_readDirectory(directory, &isDirectory); diff --git a/src/vs/libiec61850-wo-goose.def b/src/vs/libiec61850-wo-goose.def index dbbebc3e..1624ef2a 100644 --- a/src/vs/libiec61850-wo-goose.def +++ b/src/vs/libiec61850-wo-goose.def @@ -482,4 +482,6 @@ EXPORTS IedServer_getBitStringAttributeValue IedServer_getStringAttributeValue ModelNode_getChildWithFc - + IedServer_updateTimestampAttributeValue + MmsValue_getUtcTimeBuffer + diff --git a/src/vs/libiec61850.def b/src/vs/libiec61850.def index 0878e2f0..852e2a10 100644 --- a/src/vs/libiec61850.def +++ b/src/vs/libiec61850.def @@ -506,4 +506,5 @@ EXPORTS IedServer_getBitStringAttributeValue IedServer_getStringAttributeValue ModelNode_getChildWithFc - + IedServer_updateTimestampAttributeValue + MmsValue_getUtcTimeBuffer