diff --git a/src/iec61850/inc_private/reporting.h b/src/iec61850/inc_private/reporting.h index f57abdf1..4102e1c1 100644 --- a/src/iec61850/inc_private/reporting.h +++ b/src/iec61850/inc_private/reporting.h @@ -153,6 +153,9 @@ Reporting_processReportEventsAfterUnlock(MmsMapping* self); LIB61850_INTERNAL void Reporting_sendReports(MmsMapping* self, MmsServerConnection connection); +LIB61850_INTERNAL void +Reporting_deactivateAllReports(MmsMapping* self); + LIB61850_INTERNAL void Reporting_deactivateReportsForConnection(MmsMapping* self, MmsServerConnection connection); diff --git a/src/iec61850/server/impl/ied_server.c b/src/iec61850/server/impl/ied_server.c index b1dcdd17..a158caf8 100644 --- a/src/iec61850/server/impl/ied_server.c +++ b/src/iec61850/server/impl/ied_server.c @@ -719,6 +719,8 @@ IedServer_stop(IedServer self) MmsMapping_stopEventWorkerThread(self->mmsMapping); + Reporting_deactivateAllReports(self->mmsMapping); + #if (CONFIG_MMS_SINGLE_THREADED == 1) Thread_destroy(self->serverThread); self->serverThread = NULL; diff --git a/src/iec61850/server/mms_mapping/mms_mapping.c b/src/iec61850/server/mms_mapping/mms_mapping.c index 384b8616..e65f426e 100644 --- a/src/iec61850/server/mms_mapping/mms_mapping.c +++ b/src/iec61850/server/mms_mapping/mms_mapping.c @@ -3135,6 +3135,11 @@ mmsConnectionHandler(void* parameter, MmsServerConnection connection, MmsServerE else if (event == MMS_SERVER_CONNECTION_CLOSED) { ClientConnection clientConnection = private_IedServer_getClientConnectionByHandle(self->iedServer, connection); + if (clientConnection == NULL) { + printf("clientConnection == NULL -> exit\n"); + exit(-1); + } + /* call user provided handler function */ if (self->connectionIndicationHandler != NULL) self->connectionIndicationHandler(self->iedServer, clientConnection, false, diff --git a/src/iec61850/server/mms_mapping/reporting.c b/src/iec61850/server/mms_mapping/reporting.c index 525b0d06..853625de 100644 --- a/src/iec61850/server/mms_mapping/reporting.c +++ b/src/iec61850/server/mms_mapping/reporting.c @@ -2099,50 +2099,71 @@ exit_function: return retVal; } -void -Reporting_deactivateReportsForConnection(MmsMapping* self, MmsServerConnection connection) +static void +Reporting_disableReportControlInstance(MmsMapping* self, ReportControl* rc) { - LinkedList reportControl = self->reportControls; + rc->enabled = false; + rc->clientConnection = NULL; - while ((reportControl = LinkedList_getNext(reportControl)) != NULL) { - ReportControl* rc = (ReportControl*) reportControl->data; + MmsValue* rptEna = ReportControl_getRCBValue(rc, "RptEna"); + MmsValue_setBoolean(rptEna, false); - if (rc->clientConnection == connection) { + rc->reserved = false; - rc->enabled = false; - rc->clientConnection = NULL; + if (rc->buffered == false) { - MmsValue* rptEna = ReportControl_getRCBValue(rc, "RptEna"); - MmsValue_setBoolean(rptEna, false); + if (rc->resvTms != -1) { + MmsValue* resv = ReportControl_getRCBValue(rc, "Resv"); + MmsValue_setBoolean(resv, false); + } - rc->reserved = false; + if (rc->resvTms != -1) + updateOwner(rc, NULL); - if (rc->buffered == false) { + /* delete buffer content */ + purgeBuf(rc); + } + else { + if (rc->resvTms == 0) + updateOwner(rc, NULL); + else if (rc->resvTms > 0) { + rc->reservationTimeout = Hal_getTimeInMs() + (rc->resvTms * 1000); + } + } - if (rc->resvTms != -1) { - MmsValue* resv = ReportControl_getRCBValue(rc, "Resv"); - MmsValue_setBoolean(resv, false); - } +#if (CONFIG_IEC61850_SERVICE_TRACKING == 1) + copyRCBValuesToTrackingObject(self, rc); + updateGenericTrackingObjectValues(self, rc, IEC61850_SERVICE_TYPE_INTERNAL_CHANGE, DATA_ACCESS_ERROR_SUCCESS); +#endif /* (CONFIG_IEC61850_SERVICE_TRACKING == 1) */ +} - if (rc->resvTms != -1) - updateOwner(rc, NULL); +void +Reporting_deactivateAllReports(MmsMapping* self) +{ + LinkedList rcElem = LinkedList_getNext(self->reportControls); - /* delete buffer content */ - purgeBuf(rc); - } - else { - if (rc->resvTms == 0) - updateOwner(rc, NULL); - else if (rc->resvTms > 0) { - rc->reservationTimeout = Hal_getTimeInMs() + (rc->resvTms * 1000); - } - } + while (rcElem) { + ReportControl* rc = (ReportControl*)LinkedList_getData(rcElem); -#if (CONFIG_IEC61850_SERVICE_TRACKING == 1) - copyRCBValuesToTrackingObject(self, rc); - updateGenericTrackingObjectValues(self, rc, IEC61850_SERVICE_TYPE_INTERNAL_CHANGE, DATA_ACCESS_ERROR_SUCCESS); -#endif /* (CONFIG_IEC61850_SERVICE_TRACKING == 1) */ + Reporting_disableReportControlInstance(self, rc); + + rcElem = LinkedList_getNext(rcElem); + } +} + +void +Reporting_deactivateReportsForConnection(MmsMapping* self, MmsServerConnection connection) +{ + LinkedList rcElem = LinkedList_getNext(self->reportControls); + + while (rcElem) { + ReportControl* rc = (ReportControl*)LinkedList_getData(rcElem); + + if (rc->clientConnection == connection) { + Reporting_disableReportControlInstance(self, rc); } + + rcElem = LinkedList_getNext(rcElem); } } @@ -2224,6 +2245,8 @@ removeAllGIReportsFromReportBuffer(ReportBuffer* reportBuffer) printf("\n"); #endif + reportBuffer->reportsCount--; + if (reportBuffer->nextToTransmit == currentReport) reportBuffer->nextToTransmit = currentReport->next; @@ -2253,6 +2276,10 @@ enqueueReport(ReportControl* reportControl, bool isIntegrity, bool isGI, uint64_ reportControl->name, (unsigned) reportControl->sqNum, reportControl->enabled, reportControl->isBuffering, reportControl->buffered, isIntegrity, isGI); + ReportBuffer* buffer = reportControl->reportBuffer; + + Semaphore_wait(buffer->lock); + bool isBuffered = reportControl->buffered; bool overflow = false; @@ -2260,10 +2287,6 @@ enqueueReport(ReportControl* reportControl, bool isIntegrity, bool isGI, uint64_ int inclusionBitStringSize = MmsValue_getBitStringSize(reportControl->inclusionField); - ReportBuffer* buffer = reportControl->reportBuffer; - - Semaphore_wait(buffer->lock); - /* calculate size of complete buffer entry */ int bufferEntrySize = MemoryAllocator_getAlignedSize(sizeof(ReportBufferEntry)); @@ -2417,9 +2440,8 @@ enqueueReport(ReportControl* reportControl, bool isIntegrity, bool isGI, uint64_ #if (DEBUG_IED_SERVER == 1) printf("IED_SERVER: REMOVE report with ID "); printReportId(buffer->oldestReport); - printf("\n"); + printf(" (index: %li, size: %i)\n", (void*)(buffer->oldestReport) - (void*)(buffer->memoryBlock), buffer->oldestReport->entryLength); #endif - buffer->oldestReport = buffer->oldestReport->next; buffer->reportsCount--; @@ -2451,7 +2473,7 @@ enqueueReport(ReportControl* reportControl, bool isIntegrity, bool isGI, uint64_ } #if (DEBUG_IED_SERVER == 1) - printf("IED_SERVER: REMOVE report with ID "); + printf("IED_SERVER: REMOVE[1] report with ID "); printReportId(buffer->oldestReport); printf("\n"); #endif @@ -2474,7 +2496,7 @@ enqueueReport(ReportControl* reportControl, bool isIntegrity, bool isGI, uint64_ } #if (DEBUG_IED_SERVER == 1) - printf("IED_SERVER: REMOVE report with ID "); + printf("IED_SERVER: REMOVE[2] report with ID "); printReportId(buffer->oldestReport); printf("\n"); #endif @@ -2498,7 +2520,7 @@ enqueueReport(ReportControl* reportControl, bool isIntegrity, bool isGI, uint64_ } #if (DEBUG_IED_SERVER == 1) - printf("IED_SERVER: REMOVE report with ID "); + printf("IED_SERVER: REMOVE[3] report with ID "); printReportId(buffer->oldestReport); printf("\n"); #endif @@ -3031,8 +3053,6 @@ sendNextReportEntrySegment(ReportControl* self) DataSetEntry* dataSetEntry = getDataSetEntryWithIndex(self->dataSet->fcdas, startElementIndex); for (i = startElementIndex; i < maxIndex; i++) { - assert(dataSetEntry->value != NULL); - bool addReferenceForEntry = false; if (report->flags > 0)