- started to implemente server side read journal handling

This commit is contained in:
Michael Zillgith 2016-05-10 17:39:51 +02:00
parent 4b3a9dc850
commit 7de010e1f5
14 changed files with 284 additions and 9 deletions

View file

@ -17,6 +17,9 @@ LIB_SOURCE_DIRS += src/mms/iso_common
LIB_SOURCE_DIRS += src/mms/iso_mms/common
LIB_SOURCE_DIRS += src/mms/iso_mms/asn1c
LIB_SOURCE_DIRS += src/mms/iso_server
LIB_SOURCE_DIRS += src/logging
ifndef EXCLUDE_ETHERNET_WINDOWS
LIB_SOURCE_DIRS += src/goose
LIB_SOURCE_DIRS += src/sampled_values

View file

@ -186,6 +186,7 @@
#define MMS_READ_SERVICE 1
#define MMS_WRITE_SERVICE 1
#define MMS_GET_NAME_LIST 1
#define MMS_JOURNAL_SERVICE 1
#define MMS_GET_VARIABLE_ACCESS_ATTRIBUTES 1
#define MMS_DATA_SET_SERVICE 1
#define MMS_DYNAMIC_DATA_SETS 1

View file

@ -175,6 +175,7 @@
#define MMS_READ_SERVICE 1
#define MMS_WRITE_SERVICE 1
#define MMS_GET_NAME_LIST 1
#define MMS_JOURNAL_SERVICE 1
#define MMS_GET_VARIABLE_ACCESS_ATTRIBUTES 1
#define MMS_DATA_SET_SERVICE 1
#define MMS_DYNAMIC_DATA_SETS 1

View file

@ -190,8 +190,8 @@ enableLogging(LogControl* logControl)
printf(" data set (%s) not found!\n", logControl->dataSetRef);
return false;
}
else
logControl->dataSet = dataSet;
return true;
}
@ -326,6 +326,7 @@ createLogControlBlock(LogControlBlock* logControlBlock,
logControl->mmsType = lcb;
logControl->mmsValue = mmsValue;
logControl->logControlBlock = logControlBlock;
logControl->triggerOps = logControlBlock->trgOps;
logControl->enabled = logControlBlock->logEna;

View file

@ -2621,12 +2621,37 @@ MmsMapping_triggerLogging(MmsMapping* self, MmsValue* value, LogInclusionFlag fl
LogControl* lc = (LogControl*) element->data;
if ((lc->enabled) && (lc->dataSet != NULL)) {
// switch (flag) {
int index;
switch (flag) {
case LOG_CONTROL_VALUE_UPDATE:
if ((lc->triggerOps & TRG_OPT_DATA_UPDATE) == 0)
continue;
break;
case LOG_CONTROL_VALUE_CHANGED:
if (((lc->triggerOps & TRG_OPT_DATA_CHANGED) == 0) &&
((lc->triggerOps & TRG_OPT_DATA_UPDATE) == 0))
continue;
break;
case LOG_CONTROL_QUALITY_CHANGED:
if ((lc->triggerOps & TRG_OPT_QUALITY_CHANGED) == 0)
continue;
break;
default:
continue;
}
if (DataSet_isMemberValue(lc->dataSet, value, &index)) {
printf("Log value\n");
printf("Log value - flag:%i\n", flag);
}

View file

@ -1679,7 +1679,7 @@ removeAllGIReportsFromReportBuffer(ReportBuffer* reportBuffer)
static void
enqueueReport(ReportControl* reportControl, bool isIntegrity, bool isGI, uint64_t timeOfEntry)
{
// if (DEBUG_IED_SERVER)
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);

View file

@ -0,0 +1,67 @@
/*
* 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;
}

31
src/logging/logging_api.h Normal file
View file

@ -0,0 +1,31 @@
/*
* logging_api.h
*
*/
#ifndef LIBIEC61850_SRC_LOGGING_LOGGING_API_H_
#define LIBIEC61850_SRC_LOGGING_LOGGING_API_H_
#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);
struct sLogStorage {
bool (*initializeLog) (const char* logName, int logSize);
bool (*storeEntry) (const char* logName, uint64_t entryID, MmsValue* timestamp, int entrySize,
uint8_t* entryData);
bool (*getEntries) (const char* logName, MmsValue* timestamp,
LogEntryCallback callback, void* parameter);
bool (*getEntriesAfter) (const char* logName, MmsValue* timestamp, uint64_t entryID,
LogEntryCallback callback, void* parameter);
};
#endif /* LIBIEC61850_SRC_LOGGING_LOGGING_API_H_ */

View file

@ -221,6 +221,14 @@ mmsServer_handleStatusRequest(
int invokeId,
ByteBuffer* response);
void
mmsServer_handleReadJournalRequest(
MmsServerConnection connection,
uint8_t* requestBuffer,
int bufPos, int maxBufPos,
uint32_t invokeId,
ByteBuffer* response);
void
mmsServer_handleFileDirectoryRequest(
MmsServerConnection connection,

View file

@ -60,7 +60,7 @@ mmsClient_createReadJournalRequest(uint32_t invokeId, ByteBuffer* request, const
bufPos = BerEncoder_encodeTL(0x02, invokeIdSize, buffer, bufPos);
bufPos = BerEncoder_encodeUInt32(invokeId, buffer, bufPos);
/* Encode FileOpen tag (context | structured ) [65 = 41h] */
/* Encode read journal tag (context | structured ) [65 = 41h] */
buffer[bufPos++] = 0xbf;
buffer[bufPos++] = 0x41;
@ -69,8 +69,6 @@ mmsClient_createReadJournalRequest(uint32_t invokeId, ByteBuffer* request, const
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);

View file

@ -28,6 +28,9 @@
MmsJournal
MmsJournal_create(const char* name)
{
if (DEBUG_MMS_SERVER)
printf("MMS_SERVER: create new journal %s\n", name);
MmsJournal self = (MmsJournal) GLOBAL_MALLOC(sizeof(struct sMmsJournal));
self->name = copyString(name);

View file

@ -0,0 +1,131 @@
/*
* mms_journal_service.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 <http://www.gnu.org/licenses/>.
*
* See COPYING file for the complete license text.
*/
#include "libiec61850_platform_includes.h"
#include "mms_server_internal.h"
#if (MMS_JOURNAL_SERVICE == 1)
static bool
parseStringWithMaxLength(char* filename, int maxLength, uint8_t* buffer, int* bufPos, int maxBufPos , uint32_t invokeId, ByteBuffer* response)
{
uint8_t tag = buffer[(*bufPos)++];
int length;
if (tag != 0x19) {
mmsServer_writeMmsRejectPdu(&invokeId, MMS_ERROR_REJECT_INVALID_PDU, response);
return false;
}
*bufPos = BerDecoder_decodeLength(buffer, &length, *bufPos, maxBufPos);
if (*bufPos < 0) {
mmsServer_writeMmsRejectPdu(&invokeId, MMS_ERROR_REJECT_INVALID_PDU, response);
return false;
}
if (length > maxLength) {
mmsServer_writeMmsRejectPdu(&invokeId, MMS_ERROR_REJECT_REQUEST_INVALID_ARGUMENT, response);
return false;
}
memcpy(filename, buffer + *bufPos, length);
filename[length] = 0;
*bufPos += length;
return true;
}
void
mmsServer_handleReadJournalRequest(
MmsServerConnection connection,
uint8_t* requestBuffer,
int bufPos, int maxBufPos,
uint32_t invokeId,
ByteBuffer* response)
{
printf("READ-JOURNAL\n");
char domainId[65];
char logName[65];
bool hasNames = false;
while (bufPos < maxBufPos) {
uint8_t tag = requestBuffer[bufPos++];
int length;
bufPos = BerDecoder_decodeLength(requestBuffer, &length, bufPos, maxBufPos);
if (bufPos < 0) {
mmsServer_writeMmsRejectPdu(&invokeId, MMS_ERROR_REJECT_INVALID_PDU, response);
return;
}
switch (tag) {
case 0xa0:
{
uint8_t objectIdTag = requestBuffer[bufPos++];
bufPos = BerDecoder_decodeLength(requestBuffer, &length, bufPos, maxBufPos);
switch (objectIdTag) {
case 0xa1: /* domain-specific */
printf(" domain-specific-log\n");
if (!parseStringWithMaxLength(domainId, 64, requestBuffer, &bufPos, bufPos + length, invokeId, response)) {
mmsServer_writeMmsRejectPdu(&invokeId, MMS_ERROR_REJECT_REQUEST_INVALID_ARGUMENT, response);
return;
}
if (!parseStringWithMaxLength(logName, 64, requestBuffer, &bufPos, bufPos + length, invokeId, response)) {
mmsServer_writeMmsRejectPdu(&invokeId, MMS_ERROR_REJECT_REQUEST_INVALID_ARGUMENT, response);
return;
}
printf(" domain: %s log: %s\n", domainId, logName);
break;
default:
mmsServer_writeMmsRejectPdu(&invokeId, MMS_ERROR_REJECT_UNRECOGNIZED_MODIFIER, response);
return;
}
}
break;
default:
mmsServer_writeMmsRejectPdu(&invokeId, MMS_ERROR_REJECT_INVALID_PDU, response);
return;
}
bufPos += length;
}
}
#endif /* (MMS_JOURNAL_SERVICE == 1) */

View file

@ -113,6 +113,12 @@ handleConfirmedRequestPdu(
if (extendedTag) {
switch(tag) {
#if (MMS_JOURNAL_SERVICE == 1)
case 0x41: /* read-journal */
mmsServer_handleReadJournalRequest(self, buffer, bufPos, bufPos + length, invokeId, response);
break;
#endif /* (MMS_JOURNAL_SERVICE == 1) */
#if (MMS_FILE_SERVICE == 1)
case 0x48: /* file-open-request */
mmsServer_handleFileOpenRequest(self, buffer, bufPos, bufPos + length, invokeId, response);

View file

@ -24,7 +24,7 @@
#include "libiec61850_platform_includes.h"
#include "mms_server_internal.h"
#if MMS_STATUS_SERVICE == 1
#if (MMS_STATUS_SERVICE == 1)
void
mmsServer_handleStatusRequest(