diff --git a/examples/iec61850_client_example_files/client_example_files.c b/examples/iec61850_client_example_files/client_example_files.c index 33c6750b..7d369269 100644 --- a/examples/iec61850_client_example_files/client_example_files.c +++ b/examples/iec61850_client_example_files/client_example_files.c @@ -52,6 +52,10 @@ int main(int argc, char** argv) { IedConnection con = IedConnection_create(); + MmsConnection mmsCon = IedConnection_getMmsConnection(con); + + MmsConnection_setLocalDetail(mmsCon, 800); + IedConnection_connect(con, &error, hostname, tcpPort); if (error == IED_ERROR_OK) { diff --git a/make/target_system.mk b/make/target_system.mk index c7edf351..9158d12d 100644 --- a/make/target_system.mk +++ b/make/target_system.mk @@ -56,6 +56,8 @@ endif ifeq ($(TARGET), LINUX-ARM) TOOLCHAIN_PREFIX=$(ARM_TOOLCHAIN_PREFIX) +CFLAGS += -mno-unaligned-access +CFLAGS += -mcpu=arm926ej-s endif ifeq ($(TARGET), UCLINUX-WAGO) diff --git a/src/iec61850/server/impl/ied_server.c b/src/iec61850/server/impl/ied_server.c index 199e1082..f18bebd8 100644 --- a/src/iec61850/server/impl/ied_server.c +++ b/src/iec61850/server/impl/ied_server.c @@ -491,7 +491,7 @@ singleThreadedServerThread(void* parameter) IedServer_performPeriodicTasks(self); - //Thread_sleep(1); + Thread_sleep(1); running = mmsMapping->reportThreadRunning; } diff --git a/src/iec61850/server/mms_mapping/mms_mapping.c b/src/iec61850/server/mms_mapping/mms_mapping.c index 70841ef3..fdb430a9 100644 --- a/src/iec61850/server/mms_mapping/mms_mapping.c +++ b/src/iec61850/server/mms_mapping/mms_mapping.c @@ -2773,6 +2773,7 @@ eventWorkerThread(MmsMapping* self) self->reportThreadFinished = false; while (running) { + processPeriodicTasks(self); Thread_sleep(1); /* hand-over control to other threads */ diff --git a/src/iec61850/server/mms_mapping/reporting.c b/src/iec61850/server/mms_mapping/reporting.c index 2ee7173f..b0e052dc 100644 --- a/src/iec61850/server/mms_mapping/reporting.c +++ b/src/iec61850/server/mms_mapping/reporting.c @@ -143,6 +143,20 @@ ReportControl_unlockNotify(ReportControl* self) } +static void +purgeBuf(ReportControl* rc) +{ + if (DEBUG_IED_SERVER) printf("IED_SERVER: reporting.c: run purgeBuf\n"); + + ReportBuffer* reportBuffer = rc->reportBuffer; + + reportBuffer->lastEnqueuedReport = NULL; + reportBuffer->oldestReport = NULL; + reportBuffer->nextToTransmit = NULL; + reportBuffer->reportsCount = 0; +} + + static void deleteDataSetValuesShadowBuffer(ReportControl* self) { @@ -389,7 +403,6 @@ sendReport(ReportControl* self, bool isIntegrity, bool isGI) } } - /* add data set value elements */ DataSetEntry* dataSetEntry = self->dataSet->fcdas; @@ -497,6 +510,11 @@ updateReportDataset(MmsMapping* mapping, ReportControl* rc, MmsValue* newDatSet, if (strcmp(MmsValue_toString(newDatSet), "") == 0) { success = true; dataSetValue = NULL; + + if (rc->buffered) { + rc->isBuffering = false; + purgeBuf(rc); + } } else dataSetValue = newDatSet; @@ -583,6 +601,9 @@ updateReportDataset(MmsMapping* mapping, ReportControl* rc, MmsValue* newDatSet, rc->inclusionFlags = (ReportInclusionFlag*) GLOBAL_CALLOC(dataSet->elementCount, sizeof(ReportInclusionFlag)); success = true; + + rc->isBuffering = true; + goto exit_function; } @@ -671,19 +692,6 @@ refreshTriggerOptions(ReportControl* rc) rc->triggerOps += TRG_OPT_GI; } -static void -purgeBuf(ReportControl* rc) -{ - if (DEBUG_IED_SERVER) printf("IED_SERVER: reporting.c: run purgeBuf\n"); - - ReportBuffer* reportBuffer = rc->reportBuffer; - - reportBuffer->lastEnqueuedReport = NULL; - reportBuffer->oldestReport = NULL; - reportBuffer->nextToTransmit = NULL; - reportBuffer->reportsCount = 0; -} - static void refreshIntegrityPeriod(ReportControl* rc) { @@ -1634,6 +1642,8 @@ printReportId(ReportBufferEntry* report) static void removeAllGIReportsFromReportBuffer(ReportBuffer* reportBuffer) { + printf("removeAllGIReportsFromReportBuffer\n"); + ReportBufferEntry* currentReport = reportBuffer->oldestReport; ReportBufferEntry* lastReport = NULL; @@ -1669,7 +1679,8 @@ removeAllGIReportsFromReportBuffer(ReportBuffer* reportBuffer) static void enqueueReport(ReportControl* reportControl, bool isIntegrity, bool isGI, uint64_t timeOfEntry) { - if (DEBUG_IED_SERVER) printf("IED_SERVER: enqueueReport: RCB name: %s (SQN:%u) enabled:%i buffered:%i buffering:%i intg:%i GI:%i\n", + // if (DEBUG_IED_SERVER) + printf("IED_SERVER: enqueueReport: RCB name: %s (SQN:%u) enabled:%i buffered:%i buffering:%i intg:%i GI:%i\n", reportControl->name, (unsigned) reportControl->sqNum, reportControl->enabled, reportControl->isBuffering, reportControl->buffered, isIntegrity, isGI); @@ -1729,7 +1740,7 @@ enqueueReport(ReportControl* reportControl, bool isIntegrity, bool isGI, uint64_ if (DEBUG_IED_SERVER) printf("IED_SERVER: enqueueReport: report buffer too small for report entry! Skip event!\n"); - return; + goto exit_function; } if (isGI) removeAllGIReportsFromReportBuffer(buffer); @@ -1737,7 +1748,8 @@ enqueueReport(ReportControl* reportControl, bool isIntegrity, bool isGI, uint64_ uint8_t* entryBufPos = NULL; uint8_t* entryStartPos; - if (DEBUG_IED_SERVER) printf("IED_SERVER: number of buffered reports:%i\n", buffer->reportsCount); + if (DEBUG_IED_SERVER) + printf("IED_SERVER: number of buffered reports:%i\n", buffer->reportsCount); if (buffer->lastEnqueuedReport == NULL) { /* buffer is empty - we start at the beginning of the memory block */ entryBufPos = buffer->memoryBlock; @@ -2005,7 +2017,10 @@ enqueueReport(ReportControl* reportControl, bool isIntegrity, bool isGI, uint64_ buffer->oldestReport = buffer->lastEnqueuedReport; reportControl->lastEntryId = entryId; -} + +exit_function: + return; +} /* enqueuReport() */ static void sendNextReportEntry(ReportControl* self) @@ -2354,6 +2369,7 @@ cleanup_and_return: if (localStorage != NULL) GLOBAL_FREEMEM(localStorage); + } void @@ -2376,6 +2392,8 @@ Reporting_activateBufferedReports(MmsMapping* self) static void processEventsForReport(ReportControl* rc, uint64_t currentTimeInMs) { + + if ((rc->enabled) || (rc->isBuffering)) { if (rc->triggerOps & TRG_OPT_GI) { @@ -2443,8 +2461,9 @@ processEventsForReport(ReportControl* rc, uint64_t currentTimeInMs) if (rc->buffered && rc->enabled) sendNextReportEntry(rc); - } + + } void diff --git a/src/mms/iso_mms/common/mms_value.c b/src/mms/iso_mms/common/mms_value.c index ebfa924f..b096c04b 100644 --- a/src/mms/iso_mms/common/mms_value.c +++ b/src/mms/iso_mms/common/mms_value.c @@ -994,6 +994,8 @@ MmsValue_cloneToBuffer(const MmsValue* self, uint8_t* destinationAddress) int i; for (i = 0; i < self->value.structure.size; i++) { newValue->value.structure.components[i] = (MmsValue*) destinationAddress; + //memcpy(&(newValue->value.structure.components[i]), &(destinationAddress), sizeof (MmsValue*)); + destinationAddress = MmsValue_cloneToBuffer(self->value.structure.components[i], destinationAddress); } } diff --git a/src/mms/iso_mms/server/mms_access_result.c b/src/mms/iso_mms/server/mms_access_result.c index 59d52ab6..8409e7b9 100644 --- a/src/mms/iso_mms/server/mms_access_result.c +++ b/src/mms/iso_mms/server/mms_access_result.c @@ -66,36 +66,28 @@ encodeArrayAccessResult(MmsValue* value, uint8_t* buffer, int bufPos, bool encod static int encodeStructuredAccessResult(MmsValue* value, uint8_t* buffer, int bufPos, bool encode) { - if (value == NULL) // TODO report internal error - return 0; - int componentsSize = 0; int i; int size; - int components = value->value.structure.size; + int componentCount = value->value.structure.size; - for (i = 0; i < components; i++) { - MmsValue* component = value->value.structure.components[i]; + MmsValue** components = value->value.structure.components; - componentsSize += mmsServer_encodeAccessResult(component, NULL, 0, false); - } + for (i = 0; i < componentCount; i++) + componentsSize += mmsServer_encodeAccessResult(components[i], NULL, 0, false); if (encode) { buffer[bufPos++] = 0xa2; /* tag for structure */ bufPos = BerEncoder_encodeLength(componentsSize, buffer, bufPos); - for (i = 0; i < components; i++) { - MmsValue* component = value->value.structure.components[i]; - - bufPos = mmsServer_encodeAccessResult(component, buffer, bufPos, true); - } + for (i = 0; i < componentCount; i++) + bufPos = mmsServer_encodeAccessResult(components[i], buffer, bufPos, true); size = bufPos; } - else { + else size = 1 + componentsSize + BerEncoder_determineLengthSize(componentsSize); - } return size; } @@ -103,9 +95,6 @@ encodeStructuredAccessResult(MmsValue* value, uint8_t* buffer, int bufPos, bool int mmsServer_encodeAccessResult(MmsValue* value, uint8_t* buffer, int bufPos, bool encode) { -// if (value == NULL) // TODO report internal error -// return 0; - int size; switch (value->type) { diff --git a/src/mms/iso_mms/server/mms_file_service.c b/src/mms/iso_mms/server/mms_file_service.c index 9bf8b72a..582fb7cf 100644 --- a/src/mms/iso_mms/server/mms_file_service.c +++ b/src/mms/iso_mms/server/mms_file_service.c @@ -459,15 +459,15 @@ addFileEntriesToResponse(uint8_t* buffer, int bufPos, int maxBufSize, char* dire if (isDirectory) { bufPos = addFileEntriesToResponse(buffer, bufPos, maxBufSize, directoryName, continueAfterFileName, moreFollows); - - if (*moreFollows == true) - break; } else { bufPos = addFileEntriesToResponse(buffer, bufPos, maxBufSize, directoryName, continueAfterFileName, moreFollows); } + if (*moreFollows == true) + break; + fileName = FileSystem_readDirectory(directory, &isDirectory); } @@ -503,12 +503,13 @@ addFileEntriesToResponse(uint8_t* buffer, int bufPos, int maxBufSize, char* dire if (overallEntrySize > bufferSpaceLeft) { *moreFollows = true; - //break; } + else { - bufPos = BerEncoder_encodeTL(0x30, dirEntrySize, buffer, bufPos); /* SEQUENCE (DirectoryEntry) */ - bufPos = encodeFileSpecification(0xa0, directoryName, buffer, bufPos); /* fileName */ - bufPos = encodeFileAttributes(0xa1, fileSize, gtString, buffer, bufPos); /* file attributes */ + bufPos = BerEncoder_encodeTL(0x30, dirEntrySize, buffer, bufPos); /* SEQUENCE (DirectoryEntry) */ + bufPos = encodeFileSpecification(0xa0, directoryName, buffer, bufPos); /* fileName */ + bufPos = encodeFileAttributes(0xa1, fileSize, gtString, buffer, bufPos); /* file attributes */ + } } else bufPos = -1; diff --git a/src/mms/iso_mms/server/mms_information_report.c b/src/mms/iso_mms/server/mms_information_report.c index eee0bb25..3dd4127d 100644 --- a/src/mms/iso_mms/server/mms_information_report.c +++ b/src/mms/iso_mms/server/mms_information_report.c @@ -234,14 +234,10 @@ MmsServerConnection_sendInformationReportVMDSpecific(MmsServerConnection self, c variableAccessSpecSize += BerEncoder_determineLengthSize(objectNameSize); variableAccessSpecSize += 1; /* space for tag (a1) */ - int variableCount = LinkedList_size(values); - /* iterate values list and add values to the accessResultList */ LinkedList value = LinkedList_getNext(values); - int i; - - for (i = 0; i < variableCount; i++) { + while (value != NULL) { MmsValue* data = (MmsValue*) value->data; @@ -267,7 +263,7 @@ MmsServerConnection_sendInformationReportVMDSpecific(MmsServerConnection self, c goto exit_function; } - if (DEBUG_MMS_SERVER) printf("MMS_SERVER: sendInfReport: %i items\n", variableCount); + if (DEBUG_MMS_SERVER) printf("MMS_SERVER: sendInfReport\n"); ByteBuffer* reportBuffer = self->server->reportBuffer; @@ -286,7 +282,7 @@ MmsServerConnection_sendInformationReportVMDSpecific(MmsServerConnection self, c value = LinkedList_getNext(values); - for (i = 0; i < variableCount; i++) { + while (value != NULL) { MmsValue* data = (MmsValue*) value->data;