- 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) */
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
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
*

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

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

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

Loading…
Cancel
Save