From a23b584d13a7c933b5ef428ef54c673c60636d87 Mon Sep 17 00:00:00 2001 From: Michael Zillgith Date: Mon, 16 May 2016 23:35:33 +0200 Subject: [PATCH] - extended logging implementation --- Makefile | 2 + examples/mms_utility/mms_utility.c | 4 +- make/stack_includes.mk | 1 + src/iec61850/inc/iec61850_common.h | 1 + src/iec61850/inc/iec61850_model.h | 3 + src/iec61850/inc/iec61850_server.h | 3 + src/iec61850/inc_private/logging.h | 18 ++ .../inc_private/mms_mapping_internal.h | 1 + src/iec61850/server/impl/ied_server.c | 8 + src/iec61850/server/mms_mapping/logging.c | 120 ++++++++++++++ src/iec61850/server/mms_mapping/mms_mapping.c | 79 ++++++++- src/iec61850/server/model/model.c | 16 +- src/logging/log_storage_sqlite.c | 67 -------- src/logging/logging_api.h | 75 +++++++-- src/mms/iso_mms/server/mms_journal_service.c | 154 +++++++++++++++++- 15 files changed, 460 insertions(+), 92 deletions(-) delete mode 100644 src/logging/log_storage_sqlite.c 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) */