- added feature: synchronization of integrity report times (LIB61850-323)

- fixed potential memory access problems in ReportControlBlock getter functions
pull/396/head
Michael Zillgith 3 years ago
parent c76b5dd2da
commit cfbe677bc5

@ -96,6 +96,9 @@ struct sIedServerConfig
/** RCB has owner attribute (default: true) */ /** RCB has owner attribute (default: true) */
bool enableOwnerForRCB; bool enableOwnerForRCB;
/** integrity report start times will by synchronized with straight numbers (default: false) */
bool syncIntegrityReportTimes;
}; };
/** /**
@ -179,6 +182,30 @@ IedServerConfig_setMaxMmsConnections(IedServerConfig self, int maxConnections);
LIB61850_API int LIB61850_API int
IedServerConfig_getMaxMmsConnections(IedServerConfig self); IedServerConfig_getMaxMmsConnections(IedServerConfig self);
/**
* \brief Enable synchronized integrity report times
*
* NOTE: When this flag is enabled the integrity report generation times are
* aligned with the UTC epoch. Then the unix time stamps are straight multiples of the
* integrity interval.
*
* \param enable when true synchronized integrity report times are enabled
*/
void
IedServerConfig_setSyncIntegrityReportTimes(IedServerConfig self, bool enable);
/**
* \brief Check if synchronized integrity report times are enabled
*
* NOTE: When this flag is enabled the integrity report generation times are
* aligned with the UTC epoch. Then the unix time stamps are straight multiples of the
* integrity interval.
*
* \return true, when enabled, false otherwise
*/
bool
IedServerConfig_getSyncIntegrityReportTimes(IedServerConfig self);
/** /**
* \brief Set the basepath of the file services * \brief Set the basepath of the file services
* *

@ -49,6 +49,7 @@ struct sIedServer
int reportBufferSizeURCBs; int reportBufferSizeURCBs;
bool enableBRCBResvTms; bool enableBRCBResvTms;
bool enableOwnerForRCB; bool enableOwnerForRCB;
bool syncIntegrityReportTimes;
#endif #endif
#if (CONFIG_MMS_THREADLESS_STACK != 1) #if (CONFIG_MMS_THREADLESS_STACK != 1)

@ -484,11 +484,13 @@ IedServer_createWithConfig(IedModel* dataModel, TLSConfiguration tlsConfiguratio
self->reportBufferSizeURCBs = serverConfiguration->reportBufferSizeURCBs; self->reportBufferSizeURCBs = serverConfiguration->reportBufferSizeURCBs;
self->enableBRCBResvTms = serverConfiguration->enableResvTmsForBRCB; self->enableBRCBResvTms = serverConfiguration->enableResvTmsForBRCB;
self->enableOwnerForRCB = serverConfiguration->enableOwnerForRCB; self->enableOwnerForRCB = serverConfiguration->enableOwnerForRCB;
self->syncIntegrityReportTimes = serverConfiguration->syncIntegrityReportTimes;
} }
else { else {
self->reportBufferSizeBRCBs = CONFIG_REPORTING_DEFAULT_REPORT_BUFFER_SIZE; self->reportBufferSizeBRCBs = CONFIG_REPORTING_DEFAULT_REPORT_BUFFER_SIZE;
self->reportBufferSizeURCBs = CONFIG_REPORTING_DEFAULT_REPORT_BUFFER_SIZE; self->reportBufferSizeURCBs = CONFIG_REPORTING_DEFAULT_REPORT_BUFFER_SIZE;
self->enableOwnerForRCB = false; self->enableOwnerForRCB = false;
self->syncIntegrityReportTimes = false;
#if (CONFIG_IEC61850_BRCB_WITH_RESVTMS == 1) #if (CONFIG_IEC61850_BRCB_WITH_RESVTMS == 1)
self->enableBRCBResvTms = true; self->enableBRCBResvTms = true;
#else #else

@ -58,6 +58,7 @@ IedServerConfig_create()
self->enableResvTmsForSGCB = true; self->enableResvTmsForSGCB = true;
self->enableResvTmsForBRCB = true; self->enableResvTmsForBRCB = true;
self->enableOwnerForRCB = false; self->enableOwnerForRCB = false;
self->syncIntegrityReportTimes = false;
} }
return self; return self;
@ -251,3 +252,15 @@ IedServerConfig_getMaxMmsConnections(IedServerConfig self)
{ {
return self->maxMmsConnections; return self->maxMmsConnections;
} }
void
IedServerConfig_setSyncIntegrityReportTimes(IedServerConfig self, bool enable)
{
self->syncIntegrityReportTimes = enable;
}
bool
IedServerConfig_getSyncIntegrityReportTimes(IedServerConfig self)
{
return self->syncIntegrityReportTimes;
}

@ -929,6 +929,21 @@ refreshTriggerOptions(ReportControl* rc)
#endif #endif
} }
static uint64_t
getNextRoundedStartTime(uint64_t currentTime, uint64_t intgPd)
{
uint64_t modTime = currentTime % intgPd;
uint64_t delta = 0;
if (modTime != 0) {
delta = intgPd - modTime;
}
uint64_t nextTime = currentTime + delta;
return nextTime;
}
static void static void
refreshIntegrityPeriod(ReportControl* rc) refreshIntegrityPeriod(ReportControl* rc)
{ {
@ -943,9 +958,15 @@ refreshIntegrityPeriod(ReportControl* rc)
Semaphore_post(rc->rcbValuesLock); Semaphore_post(rc->rcbValuesLock);
#endif #endif
if (rc->buffered == false) if (rc->buffered == false) {
if (rc->server->syncIntegrityReportTimes) {
rc->nextIntgReportTime = getNextRoundedStartTime(Hal_getTimeInMs(), rc->intgPd);
}
else {
rc->nextIntgReportTime = Hal_getTimeInMs() + rc->intgPd; rc->nextIntgReportTime = Hal_getTimeInMs() + rc->intgPd;
} }
}
}
static void static void
refreshBufferTime(ReportControl* rc) refreshBufferTime(ReportControl* rc)
@ -2128,7 +2149,14 @@ Reporting_RCBWriteAccessHandler(MmsMapping* self, ReportControl* rc, char* eleme
refreshIntegrityPeriod(rc); refreshIntegrityPeriod(rc);
if (rc->buffered) { if (rc->buffered) {
if (rc->server->syncIntegrityReportTimes) {
rc->nextIntgReportTime = getNextRoundedStartTime(Hal_getTimeInMs(), rc->intgPd);
}
else {
rc->nextIntgReportTime = 0; rc->nextIntgReportTime = 0;
}
purgeBuf(rc); purgeBuf(rc);
if (self->rcbEventHandler) { if (self->rcbEventHandler) {
@ -3784,8 +3812,14 @@ processEventsForReport(ReportControl* rc, uint64_t currentTimeInMs)
/* check for system time change effects */ /* check for system time change effects */
if ((rc->nextIntgReportTime < currentTimeInMs) || (rc->nextIntgReportTime > currentTimeInMs + rc->intgPd)) { if ((rc->nextIntgReportTime < currentTimeInMs) || (rc->nextIntgReportTime > currentTimeInMs + rc->intgPd)) {
if (rc->server->syncIntegrityReportTimes) {
rc->nextIntgReportTime = getNextRoundedStartTime(currentTimeInMs, rc->intgPd);
}
else {
rc->nextIntgReportTime = currentTimeInMs + rc->intgPd; rc->nextIntgReportTime = currentTimeInMs + rc->intgPd;
} }
}
enqueueReport(rc, true, false, currentTimeInMs); enqueueReport(rc, true, false, currentTimeInMs);
@ -3794,8 +3828,13 @@ processEventsForReport(ReportControl* rc, uint64_t currentTimeInMs)
else { else {
/* check for system time change effects */ /* check for system time change effects */
if ((rc->nextIntgReportTime < currentTimeInMs) || (rc->nextIntgReportTime > currentTimeInMs + rc->intgPd)) { if ((rc->nextIntgReportTime < currentTimeInMs) || (rc->nextIntgReportTime > currentTimeInMs + rc->intgPd)) {
if (rc->server->syncIntegrityReportTimes) {
rc->nextIntgReportTime = getNextRoundedStartTime(currentTimeInMs, rc->intgPd);
}
else {
rc->nextIntgReportTime = currentTimeInMs + rc->intgPd; rc->nextIntgReportTime = currentTimeInMs + rc->intgPd;
} }
}
} }
} }
@ -4169,6 +4208,8 @@ ReportControlBlock_getGI(ReportControlBlock* self)
bool bool
ReportControlBlock_getPurgeBuf(ReportControlBlock* self) ReportControlBlock_getPurgeBuf(ReportControlBlock* self)
{ {
bool purgeBuf = false;
if (self->trgOps & 64) { if (self->trgOps & 64) {
ReportControl* rc = (ReportControl*)(self->sibling); ReportControl* rc = (ReportControl*)(self->sibling);
@ -4178,22 +4219,23 @@ ReportControlBlock_getPurgeBuf(ReportControlBlock* self)
MmsValue* purgeBufValue = ReportControl_getRCBValue(rc, "PurgeBuf"); MmsValue* purgeBufValue = ReportControl_getRCBValue(rc, "PurgeBuf");
bool purgeBuf = MmsValue_getBoolean(purgeBufValue); if (purgeBufValue) {
purgeBuf = MmsValue_getBoolean(purgeBufValue);
}
#if (CONFIG_MMS_THREADLESS_STACK != 1) #if (CONFIG_MMS_THREADLESS_STACK != 1)
Semaphore_post(rc->rcbValuesLock); Semaphore_post(rc->rcbValuesLock);
#endif #endif
}
return purgeBuf; return purgeBuf;
} }
else {
return false;
}
}
MmsValue* MmsValue*
ReportControlBlock_getEntryId(ReportControlBlock* self) ReportControlBlock_getEntryId(ReportControlBlock* self)
{ {
MmsValue* entryId = NULL;
if (self->trgOps & 64) { if (self->trgOps & 64) {
ReportControl* rc = (ReportControl*)(self->sibling); ReportControl* rc = (ReportControl*)(self->sibling);
@ -4203,22 +4245,21 @@ ReportControlBlock_getEntryId(ReportControlBlock* self)
MmsValue* entryIdValue = ReportControl_getRCBValue(rc, "EntryID"); MmsValue* entryIdValue = ReportControl_getRCBValue(rc, "EntryID");
MmsValue* entryId = MmsValue_clone(entryIdValue); entryId = MmsValue_clone(entryIdValue);
#if (CONFIG_MMS_THREADLESS_STACK != 1) #if (CONFIG_MMS_THREADLESS_STACK != 1)
Semaphore_post(rc->rcbValuesLock); Semaphore_post(rc->rcbValuesLock);
#endif #endif
}
return entryId; return entryId;
} }
else {
return NULL;
}
}
uint64_t uint64_t
ReportControlBlock_getTimeofEntry(ReportControlBlock* self) ReportControlBlock_getTimeofEntry(ReportControlBlock* self)
{ {
uint64_t timeofEntry = 0;
if (self->trgOps & 64) { if (self->trgOps & 64) {
ReportControl* rc = (ReportControl*)(self->sibling); ReportControl* rc = (ReportControl*)(self->sibling);
@ -4228,22 +4269,23 @@ ReportControlBlock_getTimeofEntry(ReportControlBlock* self)
MmsValue* timeofEntryValue = ReportControl_getRCBValue(rc, "TimeofEntry"); MmsValue* timeofEntryValue = ReportControl_getRCBValue(rc, "TimeofEntry");
uint64_t timeofEntry = MmsValue_getBinaryTimeAsUtcMs(timeofEntryValue); if (timeofEntryValue) {
timeofEntry = MmsValue_getBinaryTimeAsUtcMs(timeofEntryValue);
}
#if (CONFIG_MMS_THREADLESS_STACK != 1) #if (CONFIG_MMS_THREADLESS_STACK != 1)
Semaphore_post(rc->rcbValuesLock); Semaphore_post(rc->rcbValuesLock);
#endif #endif
}
return timeofEntry; return timeofEntry;
} }
else {
return 0;
}
}
int16_t int16_t
ReportControlBlock_getResvTms(ReportControlBlock* self) ReportControlBlock_getResvTms(ReportControlBlock* self)
{ {
int16_t resvTms = 0;
if (self->trgOps & 64) { if (self->trgOps & 64) {
ReportControl* rc = (ReportControl*)(self->sibling); ReportControl* rc = (ReportControl*)(self->sibling);
@ -4253,22 +4295,23 @@ ReportControlBlock_getResvTms(ReportControlBlock* self)
MmsValue* resvTmsValue = ReportControl_getRCBValue(rc, "ResvTms"); MmsValue* resvTmsValue = ReportControl_getRCBValue(rc, "ResvTms");
int16_t resvTms = (int16_t)MmsValue_toInt32(resvTmsValue); if (resvTmsValue) {
resvTms = (int16_t)MmsValue_toInt32(resvTmsValue);
}
#if (CONFIG_MMS_THREADLESS_STACK != 1) #if (CONFIG_MMS_THREADLESS_STACK != 1)
Semaphore_post(rc->rcbValuesLock); Semaphore_post(rc->rcbValuesLock);
#endif #endif
}
return resvTms; return resvTms;
} }
else {
return 0;
}
}
bool bool
ReportControlBlock_getResv(ReportControlBlock* self) ReportControlBlock_getResv(ReportControlBlock* self)
{ {
bool resv = false;
if (self->trgOps & 64) { if (self->trgOps & 64) {
ReportControl* rc = (ReportControl*)(self->sibling); ReportControl* rc = (ReportControl*)(self->sibling);
@ -4278,18 +4321,17 @@ ReportControlBlock_getResv(ReportControlBlock* self)
MmsValue* resvValue = ReportControl_getRCBValue(rc, "Resv"); MmsValue* resvValue = ReportControl_getRCBValue(rc, "Resv");
bool resv = MmsValue_getBoolean(resvValue); if (resvValue) {
resv = MmsValue_getBoolean(resvValue);
}
#if (CONFIG_MMS_THREADLESS_STACK != 1) #if (CONFIG_MMS_THREADLESS_STACK != 1)
Semaphore_post(rc->rcbValuesLock); Semaphore_post(rc->rcbValuesLock);
#endif #endif
}
return resv; return resv;
} }
else {
return false;
}
}
MmsValue* MmsValue*
ReportControlBlock_getOwner(ReportControlBlock* self) ReportControlBlock_getOwner(ReportControlBlock* self)

Loading…
Cancel
Save