- extended logging implementation

This commit is contained in:
Michael Zillgith 2016-05-16 23:35:33 +02:00
parent 2d45c2d679
commit a23b584d13
15 changed files with 460 additions and 92 deletions

View file

@ -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)))

View file

@ -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);

View file

@ -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

View file

@ -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

View file

@ -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);

View file

@ -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
*

View file

@ -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);

View file

@ -37,6 +37,7 @@ struct sMmsMapping {
#if (CONFIG_IEC61850_LOG_SERVICE == 1)
LinkedList logControls;
LinkedList logInstances;
#endif
#if (CONFIG_INCLUDE_GOOSE_SUPPORT == 1)

View file

@ -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)
{

View file

@ -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);
}

View file

@ -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);
}
}
}

View file

@ -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)
{

View file

@ -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;
}

View file

@ -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 <http://www.gnu.org/licenses/>.
*
* See COPYING file for the complete license text.
*/
#ifndef LIBIEC61850_SRC_LOGGING_LOGGING_API_H_
@ -8,24 +26,59 @@
#include <stdint.h>
#include <stdbool.h>
#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_ */

View file

@ -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) */