diff --git a/Makefile b/Makefile
index b5619d4..eeaa5cd 100644
--- a/Makefile
+++ b/Makefile
@@ -59,6 +59,7 @@ LIB_INCLUDE_DIRS += src/goose
LIB_INCLUDE_DIRS += src/sampled_values
LIB_INCLUDE_DIRS += src/iec61850/inc
LIB_INCLUDE_DIRS += src/iec61850/inc_private
+LIB_INCLUDE_DIRS += src/logging
ifeq ($(HAL_IMPL), WIN32)
LIB_INCLUDE_DIRS += third_party/winpcap/Include
endif
@@ -100,6 +101,7 @@ LIB_API_HEADER_FILES += src/goose/goose_receiver.h
LIB_API_HEADER_FILES += src/goose/goose_publisher.h
LIB_API_HEADER_FILES += src/sampled_values/sv_subscriber.h
LIB_API_HEADER_FILES += src/sampled_values/sv_publisher.h
+LIB_API_HEADER_FILES += src/logging/logging_api.h
get_sources_from_directory = $(wildcard $1/*.c)
get_sources = $(foreach dir, $1, $(call get_sources_from_directory,$(dir)))
diff --git a/examples/mms_utility/mms_utility.c b/examples/mms_utility/mms_utility.c
index d34172d..3e22b24 100644
--- a/examples/mms_utility/mms_utility.c
+++ b/examples/mms_utility/mms_utility.c
@@ -172,7 +172,7 @@ int main(int argc, char** argv) {
printf(" read journal...\n");
// MmsConnection_readJournal(con, &error, domainName, name);
-#if 1
+#if 0
uint64_t timestamp = Hal_getTimeInMs();
MmsValue* startTime = MmsValue_newBinaryTime(false);
@@ -184,7 +184,7 @@ int main(int argc, char** argv) {
MmsConnection_readJournalTimeRange(con, &error, domainName, name, startTime, endTime);
#endif
-#if 0
+#if 1
uint64_t timestamp = Hal_getTimeInMs();
MmsValue* startTime = MmsValue_newBinaryTime(false);
diff --git a/make/stack_includes.mk b/make/stack_includes.mk
index 3ddcc44..f1afbeb 100644
--- a/make/stack_includes.mk
+++ b/make/stack_includes.mk
@@ -8,3 +8,4 @@ INCLUDES += -I$(LIBIEC_HOME)/src/iec61850/inc_private
INCLUDES += -I$(LIBIEC_HOME)/src/hal/inc
INCLUDES += -I$(LIBIEC_HOME)/src/goose
INCLUDES += -I$(LIBIEC_HOME)/src/sampled_values
+INCLUDES += -I$(LIBIEC_HOME)/src/logging
diff --git a/src/iec61850/inc/iec61850_common.h b/src/iec61850/inc/iec61850_common.h
index 938c9d1..929074a 100644
--- a/src/iec61850/inc/iec61850_common.h
+++ b/src/iec61850/inc/iec61850_common.h
@@ -30,6 +30,7 @@ extern "C" {
#include "libiec61850_common_api.h"
+#include "logging_api.h"
/**
* @defgroup iec61850_common_api_group IEC 61850 API common parts
diff --git a/src/iec61850/inc/iec61850_model.h b/src/iec61850/inc/iec61850_model.h
index 961e640..969b35d 100644
--- a/src/iec61850/inc/iec61850_model.h
+++ b/src/iec61850/inc/iec61850_model.h
@@ -517,6 +517,9 @@ LogicalNode_hasUnbufferedReports(LogicalNode* node);
DataSet*
LogicalNode_getDataSet(LogicalNode* self, const char* dataSetName);
+void
+LogicalNode_setLogStorage(LogicalNode* self, const char* logName, LogStorage logStorage);
+
bool
DataObject_hasFCData(DataObject* dataObject, FunctionalConstraint fc);
diff --git a/src/iec61850/inc/iec61850_server.h b/src/iec61850/inc/iec61850_server.h
index 0c9f7ca..338f76b 100644
--- a/src/iec61850/inc/iec61850_server.h
+++ b/src/iec61850/inc/iec61850_server.h
@@ -650,6 +650,9 @@ IedServer_updateQuality(IedServer self, DataAttribute* dataAttribute, Quality qu
/**@}*/
+void
+IedServer_setLogStorage(IedServer self, const char* logRef, LogStorage logStorage);
+
/**
* @defgroup IEC61850_SERVER_SETTING_GROUPS Server side setting group handling
*
diff --git a/src/iec61850/inc_private/logging.h b/src/iec61850/inc_private/logging.h
index 2846323..70b36f8 100644
--- a/src/iec61850/inc_private/logging.h
+++ b/src/iec61850/inc_private/logging.h
@@ -25,6 +25,13 @@
#ifndef LIBIEC61850_SRC_IEC61850_INC_PRIVATE_LOGGING_H_
#define LIBIEC61850_SRC_IEC61850_INC_PRIVATE_LOGGING_H_
+typedef struct {
+ char* name;
+ LogicalNode* parentLN;
+
+ LogStorage logStorage;
+} LogInstance;
+
typedef struct {
char* name;
LogControlBlock* logControlBlock;
@@ -39,6 +46,7 @@ typedef struct {
MmsValue* mmsValue;
MmsVariableSpecification* mmsType;
+ LogInstance* logInstance;
bool enabled;
@@ -46,12 +54,22 @@ typedef struct {
} LogControl;
+
+LogInstance*
+LogInstance_create(LogicalNode* parentLN, const char* name);
+
+void
+LogInstance_destroy(LogInstance* self);
+
LogControl*
LogControl_create(LogicalNode* parentLN, MmsMapping* mmsMapping);
void
LogControl_destroy(LogControl* self);
+void
+LogControl_setLogStorage(LogControl* self, LogStorage logStorage);
+
MmsVariableSpecification*
Logging_createLCBs(MmsMapping* self, MmsDomain* domain, LogicalNode* logicalNode,
int lcbCount);
diff --git a/src/iec61850/inc_private/mms_mapping_internal.h b/src/iec61850/inc_private/mms_mapping_internal.h
index 8266079..b5c193e 100644
--- a/src/iec61850/inc_private/mms_mapping_internal.h
+++ b/src/iec61850/inc_private/mms_mapping_internal.h
@@ -37,6 +37,7 @@ struct sMmsMapping {
#if (CONFIG_IEC61850_LOG_SERVICE == 1)
LinkedList logControls;
+ LinkedList logInstances;
#endif
#if (CONFIG_INCLUDE_GOOSE_SUPPORT == 1)
diff --git a/src/iec61850/server/impl/ied_server.c b/src/iec61850/server/impl/ied_server.c
index d7e4027..5a2a467 100644
--- a/src/iec61850/server/impl/ied_server.c
+++ b/src/iec61850/server/impl/ied_server.c
@@ -1244,6 +1244,14 @@ IedServer_setEditSettingGroupConfirmationHandler(IedServer self, SettingGroupCon
#endif
}
+void
+IedServer_setLogStorage(IedServer self, const char* logRef, LogStorage logStorage)
+{
+#if (CONFIG_IEC61850_LOG_SERVICE == 1)
+ MmsMapping_setLogStorage(self->mmsMapping, logRef, logStorage);
+#endif
+}
+
ClientConnection
private_IedServer_getClientConnectionByHandle(IedServer self, void* serverConnectionHandle)
{
diff --git a/src/iec61850/server/mms_mapping/logging.c b/src/iec61850/server/mms_mapping/logging.c
index 8a07a52..cdef07f 100644
--- a/src/iec61850/server/mms_mapping/logging.c
+++ b/src/iec61850/server/mms_mapping/logging.c
@@ -36,6 +36,26 @@
#include "mms_value_internal.h"
+LogInstance*
+LogInstance_create(LogicalNode* parentLN, const char* name)
+{
+ LogInstance* self = (LogInstance*) GLOBAL_MALLOC(sizeof(LogInstance));
+
+
+ self->name = copyString(name);
+ self->parentLN = parentLN;
+ self->logStorage = NULL;
+
+ return self;
+}
+
+void
+LogInstance_destroy(LogInstance* self)
+{
+ GLOBAL_FREEMEM(self->name);
+ GLOBAL_FREEMEM(self);
+}
+
LogControl*
LogControl_create(LogicalNode* parentLN, MmsMapping* mmsMapping)
{
@@ -47,6 +67,7 @@ LogControl_create(LogicalNode* parentLN, MmsMapping* mmsMapping)
self->logicalNode = parentLN;
self->mmsMapping = mmsMapping;
self->dataSetRef = NULL;
+ self->logInstance = NULL;
return self;
}
@@ -59,6 +80,12 @@ LogControl_destroy(LogControl* self)
}
}
+void
+LogControl_setLog(LogControl* self, LogInstance* logInstance)
+{
+ self->logInstance = logInstance;
+}
+
static LogControlBlock*
getLCBForLogicalNodeWithIndex(MmsMapping* self, LogicalNode* logicalNode, int index)
{
@@ -337,7 +364,86 @@ createLogControlBlock(LogControlBlock* logControlBlock,
return lcb;
}
+static LogInstance*
+getLogInstanceByLogRef(MmsMapping* self, const char* logRef)
+{
+ char refStr[130];
+ char* domainName;
+ char* lnName;
+ char* logName;
+ strncpy(refStr, logRef, 129);
+
+ printf("getLogInst... %s\n", refStr);
+
+ domainName = refStr;
+
+ lnName = strchr(refStr, '/');
+
+ if (lnName == NULL)
+ return NULL;
+
+ if ((lnName - domainName) > 64)
+ return NULL;
+
+ lnName[0] = 0;
+ lnName++;
+
+ logName = strchr(lnName, '$');
+
+ if (logName == NULL)
+ return NULL;
+
+ logName[0] = 0;
+ logName++;
+
+ printf("LOG: dn: %s ln: %s name: %s\n", domainName, lnName, logName);
+
+ LinkedList instance = LinkedList_getNext(self->logInstances);
+
+ while (instance != NULL) {
+
+ LogInstance* logInstance = LinkedList_getData(instance);
+
+ printf("logInstance: %s\n", logInstance->name);
+
+ if (strcmp(logInstance->name, logName) == 0) {
+ printf (" lnName: %s\n", logInstance->parentLN->name);
+
+ if (strcmp(lnName, logInstance->parentLN->name) == 0) {
+ LogicalDevice* ld = (LogicalDevice*) logInstance->parentLN->parent;
+
+ printf(" ldName: %s\n", ld->name);
+
+ if (strcmp(ld->name, domainName) == 0)
+ return logInstance;
+ }
+ }
+
+ instance = LinkedList_getNext(instance);
+ }
+
+ return NULL;
+}
+
+static LogInstance*
+getLogInstance(MmsMapping* self, LogicalNode* logicalNode, const char* logName)
+{
+ LinkedList logInstance = LinkedList_getNext(self->logInstances);
+
+ while (logInstance != NULL) {
+ LogInstance* instance = (LogInstance*) LinkedList_getData(logInstance);
+
+ printf("LOG: %s (%s)\n", instance->name, logName);
+
+ if ((strcmp(instance->name, logName) == 0) && (logicalNode == instance->parentLN))
+ return instance;
+
+ logInstance = LinkedList_getNext(logInstance);
+ }
+
+ return NULL;
+}
MmsVariableSpecification*
Logging_createLCBs(MmsMapping* self, MmsDomain* domain, LogicalNode* logicalNode,
@@ -366,6 +472,9 @@ Logging_createLCBs(MmsMapping* self, MmsDomain* domain, LogicalNode* logicalNode
namedVariable->typeSpec.structure.elements[currentLcb] =
createLogControlBlock(logControlBlock, logControl);
+ //getLogInstanceByLogRef(self, logControlBlock->logRef);
+ logControl->logInstance = getLogInstance(self, logicalNode, logControlBlock->logRef);
+
LinkedList_add(self->logControls, logControl);
currentLcb++;
@@ -374,4 +483,15 @@ Logging_createLCBs(MmsMapping* self, MmsDomain* domain, LogicalNode* logicalNode
return namedVariable;
}
+void
+MmsMapping_setLogStorage(MmsMapping* self, const char* logRef, LogStorage logStorage)
+{
+ LogInstance* logInstance = getLogInstanceByLogRef(self, logRef);
+ if (logInstance != NULL)
+ logInstance->logStorage = logStorage;
+
+ //if (DEBUG_IED_SERVER)
+ if (logInstance == NULL)
+ printf("IED_SERVER: MmsMapping_setLogStorage no matching log for %s found!\n", logRef);
+}
diff --git a/src/iec61850/server/mms_mapping/mms_mapping.c b/src/iec61850/server/mms_mapping/mms_mapping.c
index 30a1fb5..ae7d351 100644
--- a/src/iec61850/server/mms_mapping/mms_mapping.c
+++ b/src/iec61850/server/mms_mapping/mms_mapping.c
@@ -1118,6 +1118,12 @@ createMmsDomainFromIedDevice(MmsMapping* self, LogicalDevice* logicalDevice)
MmsDomain_addJournal(domain, log->name);
+ printf("log->name: %s\n", log->name);
+
+ LogInstance* logInstance = LogInstance_create(log->parent, log->name);
+
+ LinkedList_add(self->logInstances, (void*) logInstance);
+
log = log->sibling;
}
#endif /* (CONFIG_IEC61850_LOG_SERVICE == 1) */
@@ -1248,6 +1254,7 @@ MmsMapping_create(IedModel* model)
#if (CONFIG_IEC61850_LOG_SERVICE == 1)
self->logControls = LinkedList_create();
+ self->logInstances = LinkedList_create();
#endif
#if (CONFIG_INCLUDE_GOOSE_SUPPORT == 1)
@@ -1311,6 +1318,11 @@ MmsMapping_destroy(MmsMapping* self)
LinkedList_destroy(self->settingGroups);
#endif
+#if (CONFIG_IEC61850_LOG_SERVICE == 1)
+ LinkedList_destroyDeep(self->logControls, (LinkedListValueDeleteFunction) LogControl_destroy);
+ LinkedList_destroyDeep(self->logInstances, (LinkedListValueDeleteFunction) LogInstance_destroy);
+#endif
+
LinkedList_destroy(self->observedObjects);
LinkedList_destroy(self->attributeAccessHandlers);
@@ -2512,7 +2524,7 @@ MmsMapping_setConnectionIndicationHandler(MmsMapping* self, IedConnectionIndicat
self->connectionIndicationHandlerParameter = parameter;
}
-#if ((CONFIG_IEC61850_REPORT_SERVICE == 1) || (CONFIG_INCLUDE_GOOSE_SUPPORT == 1))
+
static bool
isMemberValueRecursive(MmsValue* container, MmsValue* value)
@@ -2540,6 +2552,8 @@ isMemberValueRecursive(MmsValue* container, MmsValue* value)
return isMemberValue;
}
+#if ((CONFIG_IEC61850_REPORT_SERVICE == 1) || (CONFIG_INCLUDE_GOOSE_SUPPORT == 1))
+
static bool
DataSet_isMemberValue(DataSet* dataSet, MmsValue* value, int* index)
{
@@ -2569,6 +2583,38 @@ DataSet_isMemberValue(DataSet* dataSet, MmsValue* value, int* index)
}
#endif /* ((CONFIG_IEC61850_REPORT_SERVICE == 1) || (CONFIG_INCLUDE_GOOSE_SUPPORT)) */
+#if (CONFIG_IEC61850_LOG_SERVICE == 1)
+
+static bool
+DataSet_isMemberValueWithRef(DataSet* dataSet, MmsValue* value, char* dataRef)
+{
+ int i = 0;
+
+ DataSetEntry* dataSetEntry = dataSet->fcdas;
+
+ while (dataSetEntry != NULL) {
+
+ MmsValue* dataSetValue = dataSetEntry->value;
+
+ if (dataSetValue != NULL) { /* prevent invalid data set members */
+ if (isMemberValueRecursive(dataSetValue, value)) {
+ if (dataRef != NULL)
+ sprintf(dataRef, "%s/%s", dataSetEntry->logicalDeviceName, dataSetEntry->variableName);
+
+ return true;
+ }
+ }
+
+ i++;
+
+ dataSetEntry = dataSetEntry->sibling;
+ }
+
+ return false;
+}
+
+#endif /* (CONFIG_IEC61850_LOG_SERVICE == 1) */
+
#if (CONFIG_IEC61850_REPORT_SERVICE == 1)
void
MmsMapping_triggerReportObservers(MmsMapping* self, MmsValue* value, ReportInclusionFlag flag)
@@ -2622,9 +2668,6 @@ MmsMapping_triggerLogging(MmsMapping* self, MmsValue* value, LogInclusionFlag fl
if ((lc->enabled) && (lc->dataSet != NULL)) {
-
- int index;
-
switch (flag) {
case LOG_CONTROL_VALUE_UPDATE:
@@ -2650,8 +2693,32 @@ MmsMapping_triggerLogging(MmsMapping* self, MmsValue* value, LogInclusionFlag fl
continue;
}
- if (DataSet_isMemberValue(lc->dataSet, value, &index)) {
- printf("Log value - flag:%i\n", flag);
+ char dataRef[130];
+
+ if (DataSet_isMemberValueWithRef(lc->dataSet, value, dataRef)) {
+ printf("Log value - dataRef: %s flag: %i\n", dataRef, flag);
+
+ //TODO log to logInstance
+
+ if (lc->logInstance != NULL) {
+
+ LogStorage logStorage = lc->logInstance->logStorage;
+
+ if (logStorage != NULL) {
+
+ uint64_t entryID = LogStorage_addEntry(logStorage, Hal_getTimeInMs());
+
+ int dataSize = MmsValue_encodeMmsData(value, NULL, 0, false);
+
+ uint8_t* data = GLOBAL_MALLOC(dataSize);
+
+ MmsValue_encodeMmsData(value, data, 0, true);
+
+ LogStorage_addEntryData(logStorage, entryID, dataRef, data, dataSize, flag);
+
+
+ }
+ }
}
diff --git a/src/iec61850/server/model/model.c b/src/iec61850/server/model/model.c
index 9b96b70..b6ced89 100644
--- a/src/iec61850/server/model/model.c
+++ b/src/iec61850/server/model/model.c
@@ -372,7 +372,7 @@ LogicalNode_hasFCData(LogicalNode* node, FunctionalConstraint fc)
DataSet*
LogicalNode_getDataSet(LogicalNode* self, const char* dataSetName)
{
- assert(self->modelType == LogicalNodeModelType);
+ assert(self->modelType == LogicalNodeModelType);
assert(dataSetName != NULL);
char dsName[66];
@@ -409,6 +409,20 @@ exit_error:
return NULL;
}
+
+void
+LogicalNode_setLogStorage(LogicalNode* self, const char* logName, LogStorage logStorage)
+{
+ assert(self->modelType == LogicalNodeModelType);
+ assert(logName != NULL);
+
+ LogicalDevice* ld = (LogicalDevice*) self->parent;
+
+ IedModel* iedModel = (IedModel*) ld->parent;
+
+
+}
+
int
LogicalDevice_getLogicalNodeCount(LogicalDevice* logicalDevice)
{
diff --git a/src/logging/log_storage_sqlite.c b/src/logging/log_storage_sqlite.c
deleted file mode 100644
index df76632..0000000
--- a/src/logging/log_storage_sqlite.c
+++ /dev/null
@@ -1,67 +0,0 @@
-/*
- * log_storage_sqlite.c
- *
- */
-
-
-#include "logging_api.h"
-
-
-static bool
-SqLiteLogStorage_initializeLog(const char* logName, int logSize);
-
-static bool
-SqLiteLogStorage_storeEntry(const char* logName, uint64_t entryID, MmsValue* timestamp,
- int entrySize, uint8_t* entryData);
-
-static bool
-SqLiteLogStorage_getEntries(const char* logName, MmsValue* timestamp,
- LogEntryCallback callback, void* parameter);
-
-static bool
-SqLiteLogStorage_getEntriesAfter(const char* logName, MmsValue* timestamp, uint64_t entryID,
- LogEntryCallback callback, void* parameter);
-
-static struct sLogStorage logStorageInstance = {
- SqLiteLogStorage_initializeLog,
- SqLiteLogStorage_storeEntry,
- SqLiteLogStorage_getEntries,
- SqLiteLogStorage_getEntriesAfter
-};
-
-LogStorage
-SqLiteStorage_createInstance()
-{
- return &logStorageInstance;
-}
-
-static bool
-SqLiteLogStorage_initializeLog(const char* logName, int logSize)
-{
- return true;
-}
-
-static bool
-SqLiteLogStorage_storeEntry(const char* logName, uint64_t entryID, MmsValue* timestamp,
- int entrySize, uint8_t* entryData)
-{
- return true;
-}
-
-static bool
-SqLiteLogStorage_getEntries(const char* logName, MmsValue* timestamp,
- LogEntryCallback callback, void* parameter)
-{
- return true;
-}
-
-static bool
-SqLiteLogStorage_getEntriesAfter(const char* logName, MmsValue* timestamp, uint64_t entryID,
- LogEntryCallback callback, void* parameter)
-{
- return true;
-}
-
-
-
-
diff --git a/src/logging/logging_api.h b/src/logging/logging_api.h
index deb0a9c..575e590 100644
--- a/src/logging/logging_api.h
+++ b/src/logging/logging_api.h
@@ -1,6 +1,24 @@
/*
- * logging_api.h
+ * logging_api.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_LOGGING_LOGGING_API_H_
@@ -8,24 +26,59 @@
#include
#include
-#include "mms_value.h"
typedef struct sLogStorage* LogStorage;
-typedef void (*LogEntryCallback) (void* parameter, MmsValue* timestamp, uint64_t entryID, int entrySize,
- uint8_t* entryData);
+/**
+ *
+ * \param moreFollow - more data will follow - if false, the data is not valid
+ *
+ * \return true ready to receive new data, false abort operation
+ */
+typedef bool (*LogEntryCallback) (void* parameter, uint64_t timestamp, uint64_t entryID, bool moreFollow);
+
+typedef bool (*LogEntryDataCallback) (void* parameter, const char* dataRef, uint8_t* data, int dataSize, uint8_t reasonCode, bool moreFollow);
struct sLogStorage {
- bool (*initializeLog) (const char* logName, int logSize);
- bool (*storeEntry) (const char* logName, uint64_t entryID, MmsValue* timestamp, int entrySize,
- uint8_t* entryData);
+ void* instanceData;
- bool (*getEntries) (const char* logName, MmsValue* timestamp,
- LogEntryCallback callback, void* parameter);
+ LogEntryCallback entryCallback;
+ LogEntryDataCallback entryDataCallback;
- bool (*getEntriesAfter) (const char* logName, MmsValue* timestamp, uint64_t entryID,
- LogEntryCallback callback, void* parameter);
+ void* callbackParameter;
+
+ // bool (*initializeLog) (const char* logName, int logSize);
+
+ uint64_t (*addEntry) (LogStorage self, uint64_t timestamp);
+
+ bool (*addEntryData) (LogStorage self, uint64_t entryID, const char* dataRef, uint8_t* data, int dataSize, uint8_t reasonCode);
+
+ bool (*getEntries) (LogStorage self, uint64_t startingTime, uint64_t endingTime);
+
+ bool (*getEntriesAfter) (LogStorage self, uint64_t startingTime, uint64_t entryID);
+
+ void (*destroy) (LogStorage self);
};
+
+
+uint64_t
+LogStorage_addEntry(LogStorage self, uint64_t timestamp);
+
+bool
+LogStorage_addEntryData(LogStorage self, uint64_t entryID, const char* dataRef, uint8_t* data, int dataSize, uint8_t reasonCode);
+
+bool
+LogStorage_getEntries(LogStorage self, uint64_t startingTime, uint64_t endingTime);
+
+bool
+LogStorage_getEntriesAfter(LogStorage self, uint64_t startingTime, uint64_t entryID);
+
+void
+LogStorage_setCallbacks(LogStorage self, LogEntryCallback entryCallback, LogEntryDataCallback entryDataCallback, void* callbackParameter);
+
+void
+LogStorage_destroy(LogStorage self);
+
#endif /* LIBIEC61850_SRC_LOGGING_LOGGING_API_H_ */
diff --git a/src/mms/iso_mms/server/mms_journal_service.c b/src/mms/iso_mms/server/mms_journal_service.c
index a9ef4ad..8b8843c 100644
--- a/src/mms/iso_mms/server/mms_journal_service.c
+++ b/src/mms/iso_mms/server/mms_journal_service.c
@@ -23,6 +23,7 @@
#include "libiec61850_platform_includes.h"
#include "mms_server_internal.h"
+#include "mms_value_internal.h"
#if (MMS_JOURNAL_SERVICE == 1)
@@ -69,8 +70,21 @@ mmsServer_handleReadJournalRequest(
char domainId[65];
char logName[65];
+ char entryIdBuf[64]; /* maximum size of entry id is 64 bytes! */
+
+ MmsValue entrySpec;
+ entrySpec.type = MMS_OCTET_STRING;
+ entrySpec.value.octetString.buf = entryIdBuf;
+ entrySpec.value.octetString.maxSize = 64;
+
+ MmsValue rangeStart;
+ MmsValue rangeStop;
bool hasNames = false;
+ bool hasRangeStartSpec = false;
+ bool hasRangeStopSpec = false;
+ bool hasTimeSpec = false;
+ bool hasEntrySpec = false;
while (bufPos < maxBufPos) {
uint8_t tag = requestBuffer[bufPos++];
@@ -85,7 +99,7 @@ mmsServer_handleReadJournalRequest(
switch (tag) {
- case 0xa0:
+ case 0xa0: /* journalName */
{
uint8_t objectIdTag = requestBuffer[bufPos++];
@@ -93,7 +107,7 @@ mmsServer_handleReadJournalRequest(
switch (objectIdTag) {
case 0xa1: /* domain-specific */
- printf(" domain-specific-log\n");
+ printf("domain-specific-log \n");
if (!parseStringWithMaxLength(domainId, 64, requestBuffer, &bufPos, bufPos + length, invokeId, response)) {
return;
@@ -105,8 +119,9 @@ mmsServer_handleReadJournalRequest(
printf(" domain: %s log: %s\n", domainId, logName);
- break;
+ hasNames = true;
+ break;
default:
mmsServer_writeMmsRejectPdu(&invokeId, MMS_ERROR_REJECT_UNRECOGNIZED_MODIFIER, response);
@@ -117,13 +132,142 @@ mmsServer_handleReadJournalRequest(
break;
+ case 0xa1: /* rangeStartSpecification */
+ {
+ uint8_t subTag = requestBuffer[bufPos++];
+ bufPos = BerDecoder_decodeLength(requestBuffer, &length, bufPos, maxBufPos);
+
+ if (subTag != 0x80) {
+ mmsServer_writeMmsRejectPdu(&invokeId, MMS_ERROR_REJECT_UNRECOGNIZED_MODIFIER, response);
+ return;
+ }
+
+
+ if ((length == 4) || (length == 6)) {
+
+ rangeStart.type = MMS_BINARY_TIME;
+ rangeStart.value.binaryTime.size = length;
+
+ memcpy(rangeStart.value.binaryTime.buf, requestBuffer + bufPos, length);
+
+ char stringBuf[100];
+ MmsValue_printToBuffer(&rangeStart, stringBuf, 100);
+
+ printf("rangeStartSpec: %s\n", stringBuf);
+
+ hasRangeStartSpec = true;
+ }
+ else {
+ mmsServer_writeMmsRejectPdu(&invokeId, MMS_ERROR_REJECT_REQUEST_INVALID_ARGUMENT, response);
+ return;
+ }
+
+ bufPos += length;
+ }
+
+ break;
+
+ case 0xa2: /* rangeStopSpecification */
+ {
+ uint8_t subTag = requestBuffer[bufPos++];
+ bufPos = BerDecoder_decodeLength(requestBuffer, &length, bufPos, maxBufPos);
+
+ if (subTag != 0x80) {
+ mmsServer_writeMmsRejectPdu(&invokeId, MMS_ERROR_REJECT_UNRECOGNIZED_MODIFIER, response);
+ return;
+ }
+
+
+ if ((length == 4) || (length == 6)) {
+ rangeStop.type = MMS_BINARY_TIME;
+ rangeStop.value.binaryTime.size = length;
+
+ memcpy(rangeStop.value.binaryTime.buf, requestBuffer + bufPos, length);
+
+ char stringBuf[100];
+ MmsValue_printToBuffer(&rangeStop, stringBuf, 100);
+
+ printf("rangeStopSpec: %s\n", stringBuf);
+
+ hasRangeStopSpec = true;
+ }
+ else {
+ mmsServer_writeMmsRejectPdu(&invokeId, MMS_ERROR_REJECT_REQUEST_INVALID_ARGUMENT, response);
+ return;
+ }
+
+ bufPos += length;
+ }
+
+ break;
+
+ case 0xa5: /* entryToStartAfter */
+ {
+ printf("entryToStartAfter\n");
+ int maxSubBufPos = bufPos + length;
+
+ while (bufPos < maxSubBufPos) {
+ uint8_t subTag = requestBuffer[bufPos++];
+ bufPos = BerDecoder_decodeLength(requestBuffer, &length, bufPos, maxBufPos);
+
+ switch (subTag) {
+ case 0x80: /* timeSpecification */
+
+ if ((length == 4) || (length == 6)) {
+ rangeStart.type = MMS_BINARY_TIME;
+ rangeStart.value.binaryTime.size = length;
+
+ memcpy(rangeStart.value.binaryTime.buf, requestBuffer + bufPos, length);
+
+ char stringBuf[100];
+ MmsValue_printToBuffer(&rangeStart, stringBuf, 100);
+
+ printf("timeSpecification: %s\n", stringBuf);
+
+ hasRangeStopSpec = true;
+ }
+ else {
+ mmsServer_writeMmsRejectPdu(&invokeId, MMS_ERROR_REJECT_REQUEST_INVALID_ARGUMENT, response);
+ return;
+ }
+
+ break;
+
+ case 0x81: /* entrySpecification */
+
+ if (length <= entrySpec.value.octetString.maxSize) {
+ memcpy(entrySpec.value.octetString.buf, requestBuffer + bufPos, length);
+ entrySpec.value.octetString.size = length;
+
+ printf("EntrySpecification with size %i\n", length);
+
+ hasEntrySpec = true;
+ }
+ else {
+ mmsServer_writeMmsRejectPdu(&invokeId, MMS_ERROR_REJECT_REQUEST_INVALID_ARGUMENT, response);
+ return;
+ }
+
+ break;
+
+ default:
+ mmsServer_writeMmsRejectPdu(&invokeId, MMS_ERROR_REJECT_UNRECOGNIZED_MODIFIER, response);
+ return;
+ }
+
+ bufPos += length;
+ }
+
+ }
+ break;
+
default:
mmsServer_writeMmsRejectPdu(&invokeId, MMS_ERROR_REJECT_INVALID_PDU, response);
return;
}
-
- bufPos += length;
}
+
+ //TODO check if required fields are present
}
#endif /* (MMS_JOURNAL_SERVICE == 1) */