diff --git a/CHANGELOG b/CHANGELOG index ab86d705..c1b73337 100644 --- a/CHANGELOG +++ b/CHANGELOG @@ -1,5 +1,6 @@ Changes to version 0.9.0.2 -------------------------- +- added CONFIG_IEC61850_EDITION_1 configuration option to enable server builds for edition 1 (at the moment only remove "Owner" form RCBs). - fixed encoding problem with negative frsmId in client file read service - allow 1 to 16 octet size ISO session selector (small API change in IsoConnectionParameters methods) - added C++ compatible headers to GOOSE/SV publisher headers diff --git a/config/stack_config.h b/config/stack_config.h index c21730e5..8e0a8940 100644 --- a/config/stack_config.h +++ b/config/stack_config.h @@ -36,7 +36,7 @@ * 0 ==> server runs in multi-threaded mode (one thread for each connection and * one server background thread ) */ -#define CONFIG_MMS_SINGLE_THREADED 0 +#define CONFIG_MMS_SINGLE_THREADED 1 /* * Optimize stack for threadless operation - don't use semaphores @@ -77,6 +77,9 @@ /* Set to 1 to include Sampled Values support in the build. Otherwise set to 0 */ #define CONFIG_IEC61850_SAMPLED_VALUES_SUPPORT 1 +/* Set to 1 to compile for edition 1 server - default is 0 to compile for edition 2 */ +#define CONFIG_IEC61850_EDITION_1 0 + #ifdef _WIN32 /* GOOSE will be disabled for Windows if ethernet support (winpcap) is not available */ diff --git a/config/stack_config.h.cmake b/config/stack_config.h.cmake index 3c44e1f4..c7ad4c4c 100644 --- a/config/stack_config.h.cmake +++ b/config/stack_config.h.cmake @@ -74,6 +74,9 @@ /* Set to 1 to include Sampled Values support in the build. Otherwise set to 0 */ #define CONFIG_IEC61850_SAMPLED_VALUES_SUPPORT 1 +/* Set to 1 to compile for edition 1 server - default is 0 to compile for edition 2 */ +#define CONFIG_IEC61850_EDITION_1 0 + #ifdef _WIN32 /* GOOSE will be disabled for Windows if ethernet support (winpcap) is not available */ diff --git a/src/iec61850/server/mms_mapping/reporting.c b/src/iec61850/server/mms_mapping/reporting.c index 238b9dbc..2b9212bb 100644 --- a/src/iec61850/server/mms_mapping/reporting.c +++ b/src/iec61850/server/mms_mapping/reporting.c @@ -47,6 +47,20 @@ #define CONFIG_IEC61850_BRCB_WITH_RESVTMS 0 #endif + +#ifndef CONFIG_IEC61850_EDITION_1 +#define CONFIG_IEC61850_EDITION_1 0 +#endif + +#if (CONFIG_IEC61850_EDITION_1 == 1) +#define CONFIG_REPORTING_SUPPORTS_OWNER 0 +#endif + +#ifndef CONFIG_REPORTING_SUPPORTS_OWNER +#define CONFIG_REPORTING_SUPPORTS_OWNER 1 +#endif + + static ReportBuffer* ReportBuffer_create(void) { @@ -269,6 +283,8 @@ updateTimeOfEntry(ReportControl* self, uint64_t currentTime) static void sendReport(ReportControl* self, bool isIntegrity, bool isGI) { + updateTimeOfEntry(self, Hal_getTimeInMs()); + LinkedList reportElements = LinkedList_create(); LinkedList deletableElements = LinkedList_create(); @@ -734,10 +750,17 @@ createUnbufferedReportControlBlock(ReportControlBlock* reportControlBlock, MmsValue* mmsValue = (MmsValue*) GLOBAL_CALLOC(1, sizeof(MmsValue)); mmsValue->deleteValue = false; mmsValue->type = MMS_STRUCTURE; - mmsValue->value.structure.size = 12; - mmsValue->value.structure.components = (MmsValue**) GLOBAL_CALLOC(12, sizeof(MmsValue*)); - rcb->typeSpec.structure.elementCount = 12; +#if (CONFIG_REPORTING_SUPPORTS_OWNER == 1) + int structSize = 12; +#else + int structSize = 11; +#endif + + mmsValue->value.structure.size = structSize; + mmsValue->value.structure.components = (MmsValue**) GLOBAL_CALLOC(structSize, sizeof(MmsValue*)); + + rcb->typeSpec.structure.elementCount = structSize; rcb->typeSpec.structure.elements = (MmsVariableSpecification**) GLOBAL_CALLOC(12, sizeof(MmsVariableSpecification*)); @@ -834,12 +857,14 @@ createUnbufferedReportControlBlock(ReportControlBlock* reportControlBlock, rcb->typeSpec.structure.elements[10] = namedVariable; mmsValue->value.structure.components[10] = MmsValue_newBoolean(false); +#if (CONFIG_REPORTING_SUPPORTS_OWNER == 1) namedVariable = (MmsVariableSpecification*) GLOBAL_CALLOC(1, sizeof(MmsVariableSpecification)); namedVariable->name = copyString("Owner"); namedVariable->type = MMS_OCTET_STRING; namedVariable->typeSpec.octetString = -64; rcb->typeSpec.structure.elements[11] = namedVariable; mmsValue->value.structure.components[11] = MmsValue_newOctetString(0, 128); +#endif /* (CONFIG_REPORTING_SUPPORTS_OWNER == 1) */ reportControl->rcbValues = mmsValue; @@ -860,14 +885,15 @@ createBufferedReportControlBlock(ReportControlBlock* reportControlBlock, rcb->name = copyString(reportControlBlock->name); rcb->type = MMS_STRUCTURE; - int brcbElementCount; + int brcbElementCount = 13; #if (CONFIG_IEC61850_BRCB_WITH_RESVTMS == 1) - brcbElementCount = 15; -#else - brcbElementCount = 14; + brcbElementCount++; #endif +#if (CONFIG_REPORTING_SUPPORTS_OWNER == 1) + brcbElementCount++; +#endif MmsValue* mmsValue = (MmsValue*) GLOBAL_CALLOC(1, sizeof(MmsValue)); mmsValue->deleteValue = false; @@ -989,7 +1015,9 @@ createBufferedReportControlBlock(ReportControlBlock* reportControlBlock, reportControl->timeOfEntry = mmsValue->value.structure.components[12]; +#if ((CONFIG_IEC61850_BRCB_WITH_RESVTMS == 1) || (CONFIG_REPORTING_SUPPORTS_OWNER == 1)) int currentIndex = 13; +#endif #if (CONFIG_IEC61850_BRCB_WITH_RESVTMS == 1) namedVariable = (MmsVariableSpecification*) GLOBAL_CALLOC(1, sizeof(MmsVariableSpecification)); @@ -1001,12 +1029,14 @@ createBufferedReportControlBlock(ReportControlBlock* reportControlBlock, currentIndex++; #endif /* (CONFIG_IEC61850_BRCB_WITH_RESVTMS == 1) */ +#if (CONFIG_REPORTING_SUPPORTS_OWNER == 1) namedVariable = (MmsVariableSpecification*) GLOBAL_CALLOC(1, sizeof(MmsVariableSpecification)); namedVariable->name = copyString("Owner"); namedVariable->type = MMS_OCTET_STRING; namedVariable->typeSpec.octetString = -64; rcb->typeSpec.structure.elements[currentIndex] = namedVariable; mmsValue->value.structure.components[currentIndex] = MmsValue_newOctetString(0, 128); /* size 4 is enough to store client IPv4 address */ +#endif /* (CONFIG_REPORTING_SUPPORTS_OWNER == 1) */ reportControl->rcbValues = mmsValue; @@ -1016,7 +1046,7 @@ createBufferedReportControlBlock(ReportControlBlock* reportControlBlock, refreshTriggerOptions(reportControl); return rcb; -} +} /* createBufferedReportControlBlock() */ static ReportControlBlock* getRCBForLogicalNodeWithIndex(MmsMapping* self, LogicalNode* logicalNode, @@ -1118,15 +1148,12 @@ Reporting_createMmsUnbufferedRCBs(MmsMapping* self, MmsDomain* domain, return namedVariable; } -#define CONFIG_REPORTING_SUPPORTS_OWNER 1 - static void updateOwner(ReportControl* rc, MmsServerConnection connection) { rc->clientConnection = connection; #if (CONFIG_REPORTING_SUPPORTS_OWNER == 1) - MmsValue* owner = ReportControl_getRCBValue(rc, "Owner"); if (owner != NULL) { @@ -1646,6 +1673,8 @@ enqueueReport(ReportControl* reportControl, bool isIntegrity, bool isGI, uint64_ reportControl->name, (unsigned) reportControl->sqNum, reportControl->enabled, reportControl->isBuffering, reportControl->buffered, isIntegrity, isGI); + updateTimeOfEntry(reportControl, Hal_getTimeInMs()); + ReportBuffer* buffer = reportControl->reportBuffer; /* calculate size of complete buffer entry */ @@ -2362,8 +2391,6 @@ processEventsForReport(ReportControl* rc, uint64_t currentTimeInMs) rc->triggered = false; } - updateTimeOfEntry(rc, currentTimeInMs); - if (rc->buffered) enqueueReport(rc, false, true, currentTimeInMs); else @@ -2391,7 +2418,6 @@ processEventsForReport(ReportControl* rc, uint64_t currentTimeInMs) } rc->nextIntgReportTime = currentTimeInMs + rc->intgPd; - updateTimeOfEntry(rc, currentTimeInMs); if (rc->buffered) enqueueReport(rc, true, false, currentTimeInMs); diff --git a/src/mms/asn1/asn1_ber_primitive_value.c b/src/mms/asn1/asn1_ber_primitive_value.c index d08e885b..5571d924 100644 --- a/src/mms/asn1/asn1_ber_primitive_value.c +++ b/src/mms/asn1/asn1_ber_primitive_value.c @@ -37,16 +37,6 @@ Asn1PrimitiveValue_create(int size) return self; } -//Asn1PrimitiveValue* -//Asn1PrimitiveValue_createFromBuffer(uint8_t buffer, int bufferSize) -//{ -// Asn1PrimitiveValue* self = GLOBAL_MALLOC(sizeof(Asn1PrimitiveValue)); -// self->size = bufferSize; -// self->maxSize = bufferSize; -// self->octets = GLOBAL_MALLOC(1, bufferSize); -// -//} - Asn1PrimitiveValue* Asn1PrimitiveValue_clone(Asn1PrimitiveValue* self) {