diff --git a/config/stack_config.h b/config/stack_config.h
index 3e900e11..a1a9170f 100644
--- a/config/stack_config.h
+++ b/config/stack_config.h
@@ -153,6 +153,9 @@
/* default reservation time of a setting group control block in s */
#define CONFIG_IEC61850_SG_RESVTMS 300
+/* include support for IEC 61850 log services */
+#define CONFIG_IEC61850_LOG_SERVICE 1
+
/* default results for MMS identify service */
#define CONFIG_DEFAULT_MMS_VENDOR_NAME "libiec61850.com"
#define CONFIG_DEFAULT_MMS_MODEL_NAME "LIBIEC61850"
diff --git a/examples/mms_utility/mms_utility.c b/examples/mms_utility/mms_utility.c
index 792833be..b56ea13b 100644
--- a/examples/mms_utility/mms_utility.c
+++ b/examples/mms_utility/mms_utility.c
@@ -168,6 +168,9 @@ int main(int argc, char** argv) {
char* name = (char*) element->data;
printf(" %s\n", name);
+
+ printf(" read journal...\n");
+ MmsConnection_readJournal(con, &error, domainName, name);
}
}
}
diff --git a/src/iec61850/inc_private/logging.h b/src/iec61850/inc_private/logging.h
new file mode 100644
index 00000000..33de8a89
--- /dev/null
+++ b/src/iec61850/inc_private/logging.h
@@ -0,0 +1,46 @@
+/*
+ * logging.h
+ *
+ * Copyright 2016 Michael Zillgith
+ *
+ * This file is part of libIEC61850.
+ *
+ * libIEC61850 is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * libIEC61850 is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with libIEC61850. If not, see .
+ *
+ * See COPYING file for the complete license text.
+ */
+
+
+#ifndef LIBIEC61850_SRC_IEC61850_INC_PRIVATE_LOGGING_H_
+#define LIBIEC61850_SRC_IEC61850_INC_PRIVATE_LOGGING_H_
+
+typedef struct {
+ char* name;
+
+ DataSet* dataSet;
+
+ bool enabled;
+
+ int triggerOps;
+
+} LogControl;
+
+LogControl*
+LogControl_create(bool buffered, LogicalNode* parentLN);
+
+void
+LogControl_destroy(LogControl* self);
+
+
+#endif /* LIBIEC61850_SRC_IEC61850_INC_PRIVATE_LOGGING_H_ */
diff --git a/src/iec61850/server/impl/ied_server.c b/src/iec61850/server/impl/ied_server.c
index f18bebd8..e212db2d 100644
--- a/src/iec61850/server/impl/ied_server.c
+++ b/src/iec61850/server/impl/ied_server.c
@@ -773,12 +773,22 @@ IedServer_getStringAttributeValue(IedServer self, const DataAttribute* dataAttri
static inline void
checkForUpdateTrigger(IedServer self, DataAttribute* dataAttribute)
{
-#if (CONFIG_IEC61850_REPORT_SERVICE== 1)
+#if ((CONFIG_IEC61850_REPORT_SERVICE == 1) || (CONFIG_IEC61850_LOG_SERVICE == 1))
if (dataAttribute->triggerOptions & TRG_OPT_DATA_UPDATE) {
+
+#if (CONFIG_IEC61850_REPORT_SERVICE == 1)
MmsMapping_triggerReportObservers(self->mmsMapping, dataAttribute->mmsValue,
REPORT_CONTROL_VALUE_UPDATE);
- }
#endif
+
+#if (CONFIG_IEC61850_LOG_SERVICE == 1)
+ //MmsMapping_triggerLogObserver(self->mmsMapping, dataAttribute->mmsValue,...)
+
+#endif
+
+
+ }
+#endif /* ((CONFIG_IEC61850_REPORT_SERVICE == 1) || (CONFIG_IEC61850_LOG_SERVICE == 1)) */
}
static inline void
diff --git a/src/iec61850/server/mms_mapping/logging.c b/src/iec61850/server/mms_mapping/logging.c
new file mode 100644
index 00000000..a7fddee5
--- /dev/null
+++ b/src/iec61850/server/mms_mapping/logging.c
@@ -0,0 +1,47 @@
+/*
+ * logging.c
+ *
+ * Copyright 2016 Michael Zillgith
+ *
+ * This file is part of libIEC61850.
+ *
+ * libIEC61850 is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * libIEC61850 is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with libIEC61850. If not, see .
+ *
+ * See COPYING file for the complete license text.
+ */
+
+#include "libiec61850_platform_includes.h"
+#include "stack_config.h"
+#include "logging.h"
+
+
+LogControl*
+LogControl_create(bool buffered, LogicalNode* parentLN)
+{
+ LogControl* self = (LogControl*) GLOBAL_MALLOC(sizeof(LogControl));
+
+ self->enabled = false;
+ self->dataSet = NULL;
+ self->triggerOps = 0;
+
+ return self;
+}
+
+void
+LogControl_destroy(LogControl* self)
+{
+ if (self != NULL) {
+ GLOBAL_FREEMEM(self);
+ }
+}
diff --git a/src/iec61850/server/mms_mapping/reporting.c b/src/iec61850/server/mms_mapping/reporting.c
index b0e052dc..03d29fd3 100644
--- a/src/iec61850/server/mms_mapping/reporting.c
+++ b/src/iec61850/server/mms_mapping/reporting.c
@@ -31,7 +31,7 @@
#include "simple_allocator.h"
#include "mem_alloc_linked_list.h"
-#include "reporting.h"
+#include "stack_config.h"
#include "mms_mapping_internal.h"
#include "mms_value_internal.h"
#include "conversions.h"
diff --git a/src/mms/inc/mms_client_connection.h b/src/mms/inc/mms_client_connection.h
index 85794d2a..9b895e65 100644
--- a/src/mms/inc/mms_client_connection.h
+++ b/src/mms/inc/mms_client_connection.h
@@ -711,6 +711,10 @@ MmsConnection_getFileDirectory(MmsConnection self, MmsError* mmsError, const cha
MmsFileDirectoryHandler handler, void* handlerParameter);
+LinkedList
+MmsConnection_readJournal(MmsConnection self, MmsError* mmsError, const char* domainId, const char* itemId);
+
+
/**
* \brief Destroy (free) an MmsServerIdentity object
*
diff --git a/src/mms/inc/mms_device_model.h b/src/mms/inc/mms_device_model.h
index 218bdeff..6bed93ee 100644
--- a/src/mms/inc/mms_device_model.h
+++ b/src/mms/inc/mms_device_model.h
@@ -49,14 +49,22 @@ typedef struct {
MmsDomain** domains;
} MmsDevice;
+
+struct sMmsJournal {
+ char* name;
+};
+
+typedef struct sMmsJournal* MmsJournal;
+
/*
- * Server side data structure to hold informations for a MMS domain (Logical Device)
+ * Server side data structure to hold information of an MMS domain (Logical Device)
*/
struct sMmsDomain {
char* domainName;
int namedVariablesCount;
MmsVariableSpecification** namedVariables;
LinkedList /**/ namedVariableLists;
+ LinkedList /* */ journals;
};
/**
@@ -80,6 +88,9 @@ MmsDomain_create(char* domainName);
char*
MmsDomain_getName(MmsDomain* self);
+void
+MmsDomain_addJournal(MmsDomain* self, MmsJournal journal);
+
/**
* Delete a MmsDomain instance
*
@@ -185,6 +196,12 @@ MmsDevice_getNamedVariableLists(MmsDevice* self);
MmsNamedVariableList
MmsDevice_getNamedVariableListWithName(MmsDevice* self, const char* variableListName);
+MmsJournal
+MmsJournal_create(const char* name);
+
+void
+MmsJournal_destroy(MmsJournal self);
+
/**@}*/
#ifdef __cplusplus
diff --git a/src/mms/inc_private/mms_client_internal.h b/src/mms/inc_private/mms_client_internal.h
index b31891b0..95f4a8b8 100644
--- a/src/mms/inc_private/mms_client_internal.h
+++ b/src/mms/inc_private/mms_client_internal.h
@@ -260,4 +260,7 @@ int
mmsClient_createMmsGetNameListRequestAssociationSpecific(long invokeId, ByteBuffer* writeBuffer,
const char* continueAfter);
+void
+mmsClient_createReadJournalRequest(uint32_t invokeId, ByteBuffer* request, const char* domainId, const char* itemId);
+
#endif /* MMS_MSG_INTERNAL_H_ */
diff --git a/src/mms/iso_mms/client/mms_client_connection.c b/src/mms/iso_mms/client/mms_client_connection.c
index f76e28ff..dd4dbff7 100644
--- a/src/mms/iso_mms/client/mms_client_connection.c
+++ b/src/mms/iso_mms/client/mms_client_connection.c
@@ -1637,6 +1637,34 @@ MmsConnection_getServerStatus(MmsConnection self, MmsError* mmsError, int* vmdLo
}
+LinkedList
+MmsConnection_readJournal(MmsConnection self, MmsError* mmsError, const char* domainId, const char* itemId)
+{
+ ByteBuffer* payload = IsoClientConnection_allocateTransmitBuffer(self->isoClient);
+
+ *mmsError = MMS_ERROR_NONE;
+
+ uint32_t invokeId = getNextInvokeId(self);
+
+ mmsClient_createReadJournalRequest(invokeId, payload, domainId, itemId);
+
+ ByteBuffer* responseMessage = sendRequestAndWaitForResponse(self, invokeId, payload);
+
+ if (self->lastResponseError != MMS_ERROR_NONE)
+ *mmsError = self->lastResponseError;
+ else if (responseMessage != NULL) {
+ // if (mmsClient_parseFileOpenResponse(self, &frsmId, fileSize, lastModified) == false)
+ // *mmsError = MMS_ERROR_PARSING_RESPONSE;
+ }
+
+ releaseResponse(self);
+
+ if (self->associationState == MMS_STATE_CLOSED)
+ *mmsError = MMS_ERROR_CONNECTION_LOST;
+
+ return NULL;
+}
+
int32_t
MmsConnection_fileOpen(MmsConnection self, MmsError* mmsError, const char* filename, uint32_t initialPosition,
uint32_t* fileSize, uint64_t* lastModified)
diff --git a/src/mms/iso_mms/client/mms_client_files.c b/src/mms/iso_mms/client/mms_client_files.c
index 81b18bb2..2ecf29a1 100644
--- a/src/mms/iso_mms/client/mms_client_files.c
+++ b/src/mms/iso_mms/client/mms_client_files.c
@@ -32,6 +32,51 @@
#include "ber_decode.h"
#include "conversions.h"
+void
+mmsClient_createReadJournalRequest(uint32_t invokeId, ByteBuffer* request, const char* domainId, const char* itemId)
+{
+ /* calculate sizes */
+ uint32_t invokeIdSize = BerEncoder_UInt32determineEncodedSize(invokeId);
+
+ uint32_t domainIdStringSize = strlen(domainId);
+ uint32_t domainIdSize = 1 + BerEncoder_determineLengthSize(domainIdStringSize) + domainIdStringSize;
+
+ uint32_t itemIdStringSize = strlen(itemId);
+ uint32_t itemIdSize = 1 + BerEncoder_determineLengthSize(itemIdStringSize) + itemIdStringSize;
+
+ uint32_t objectIdSize = domainIdSize + itemIdSize;
+
+ uint32_t journalNameSize = 1 + BerEncoder_determineLengthSize(objectIdSize) + (objectIdSize);
+
+ uint32_t journalReadSize = 1 + BerEncoder_determineLengthSize(journalNameSize) + (journalNameSize);
+
+ uint32_t confirmedRequestPduSize = 1 + 2 + 2 + invokeIdSize + journalReadSize;
+
+ /* encode to buffer */
+ int bufPos = 0;
+ uint8_t* buffer = request->buffer;
+
+ bufPos = BerEncoder_encodeTL(0xa0, confirmedRequestPduSize, buffer, bufPos);
+ bufPos = BerEncoder_encodeTL(0x02, invokeIdSize, buffer, bufPos);
+ bufPos = BerEncoder_encodeUInt32(invokeId, buffer, bufPos);
+
+ /* Encode FileOpen tag (context | structured ) [65 = 41h] */
+ buffer[bufPos++] = 0xbf;
+ buffer[bufPos++] = 0x41;
+
+ bufPos = BerEncoder_encodeLength(journalReadSize, buffer, bufPos);
+ bufPos = BerEncoder_encodeTL(0xa0, journalNameSize, buffer, bufPos);
+
+ bufPos = BerEncoder_encodeTL(0xa1, objectIdSize, buffer, bufPos);
+
+// bufPos = BerEncoder_encodeTL(0xa1, domainIdStringSize, buffer, bufPos);
+
+ bufPos = BerEncoder_encodeOctetString(0x1a, (uint8_t*) domainId, domainIdStringSize, buffer, bufPos);
+ bufPos = BerEncoder_encodeOctetString(0x1a, (uint8_t*) itemId, itemIdStringSize, buffer, bufPos);
+
+ request->size = bufPos;
+}
+
void
mmsClient_createFileOpenRequest(uint32_t invokeId, ByteBuffer* request, const char* fileName, uint32_t initialPosition)
{
diff --git a/src/mms/iso_mms/server/mms_domain.c b/src/mms/iso_mms/server/mms_domain.c
index 5e22fe29..b2ceb194 100644
--- a/src/mms/iso_mms/server/mms_domain.c
+++ b/src/mms/iso_mms/server/mms_domain.c
@@ -41,6 +41,7 @@ MmsDomain_create(char* domainName)
self->domainName = copyString(domainName);
self->namedVariableLists = LinkedList_create();
+ self->journals = NULL;
return self;
}
@@ -57,6 +58,10 @@ MmsDomain_destroy(MmsDomain* self)
GLOBAL_FREEMEM(self->namedVariables);
}
+ if (self->journals != NULL) {
+ LinkedList_destroyDeep(self->journals, (LinkedListValueDeleteFunction) MmsJournal_destroy);
+ }
+
LinkedList_destroyDeep(self->namedVariableLists, (LinkedListValueDeleteFunction) MmsNamedVariableList_destroy);
GLOBAL_FREEMEM(self);
@@ -68,6 +73,15 @@ MmsDomain_getName(MmsDomain* self)
return self->domainName;
}
+void
+MmsDomain_addJournal(MmsDomain* self, MmsJournal journal)
+{
+ if (self->journals == NULL)
+ self->journals = LinkedList_create();
+
+ LinkedList_add(self->journals, (void*) journal);
+}
+
bool
MmsDomain_addNamedVariableList(MmsDomain* self, MmsNamedVariableList variableList)
{
diff --git a/src/mms/iso_mms/server/mms_journal.c b/src/mms/iso_mms/server/mms_journal.c
new file mode 100644
index 00000000..48758333
--- /dev/null
+++ b/src/mms/iso_mms/server/mms_journal.c
@@ -0,0 +1,41 @@
+/*
+ * mms_journal.c
+ *
+ * Copyright 2016 Michael Zillgith
+ *
+ * This file is part of libIEC61850.
+ *
+ * libIEC61850 is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * libIEC61850 is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with libIEC61850. If not, see .
+ *
+ * See COPYING file for the complete license text.
+ */
+
+#include "mms_device_model.h"
+
+MmsJournal
+MmsJournal_create(const char* name)
+{
+ MmsJournal self = (MmsJournal) GLOBAL_MALLOC(sizeof(struct sMmsJournal));
+
+ self->name = copyString(name);
+
+ return self;
+}
+
+void
+MmsJournal_destroy(MmsJournal self)
+{
+ GLOBAL_FREEMEM(self->name);
+ GLOBAL_FREEMEM(self);
+}