- IEC 61850 server/MMS server: make file service configurable at runtime with IedServerConfig object (new functions IedServerConfig_enableFileService and IedServerConfig_isFileServiceEnabled)

pull/72/head
Michael Zillgith 7 years ago
parent af35ee17fa
commit 143bc977c0

@ -232,6 +232,9 @@
*/
#define CONFIG_SET_FILESTORE_BASEPATH_AT_RUNTIME 1
/* enable to configure MmsServer at runtime */
#define CONFIG_MMS_SERVER_CONFIG_SERVICES_AT_RUNTIME 1
/************************************************************************************
* Check configuration for consistency - DO NOT MODIFY THIS PART!
************************************************************************************/

@ -215,6 +215,9 @@
*/
#define CONFIG_SET_FILESTORE_BASEPATH_AT_RUNTIME 1
/* enable to configure MmsServer at runtime */
#define CONFIG_MMS_SERVER_CONFIG_SERVICES_AT_RUNTIME 1
/************************************************************************************
* Check configuration for consistency - DO NOT MODIFY THIS PART!
************************************************************************************/

@ -53,6 +53,9 @@ struct sIedServerConfig
/** Base path (directory where the file service serves files */
char* fileServiceBasepath;
/** when true (default) enable MMS file service */
bool enableFileService;
};
/**
@ -99,7 +102,21 @@ IedServerConfig_setFileServiceBasePath(IedServerConfig self, const char* basepat
const char*
IedServerConfig_getFileServiceBasePath(IedServerConfig self);
/**
* \brief Enable/disable the MMS file service support
*
* \param[in] enable set true to enable the file services, otherwise false
*/
void
IedServerConfig_enableFileService(IedServerConfig self, bool enable);
/**
* \brief Is the MMS file service enabled or disabled
*
* \return true if enabled, false otherwise
*/
bool
IedServerConfig_isFileServiceEnabled(IedServerConfig self);
/**
* An opaque handle for an IED server instance

@ -421,6 +421,11 @@ IedServer_createWithConfig(IedModel* dataModel, TLSConfiguration tlsConfiguratio
self->mmsServer = MmsServer_create(self->mmsDevice, tlsConfiguration);
#if (CONFIG_MMS_SERVER_CONFIG_SERVICES_AT_RUNTIME == 1)
if (serverConfiguration)
MmsServer_enableFileService(self->mmsServer, serverConfiguration->enableFileService);
#endif
if (serverConfiguration)
MmsServer_setFilestoreBasepath(self->mmsServer, serverConfiguration->fileServiceBasepath);

@ -32,6 +32,7 @@ IedServerConfig_create()
if (self) {
self->reportBufferSize = CONFIG_REPORTING_DEFAULT_REPORT_BUFFER_SIZE;
self->fileServiceBasepath = StringUtils_copyString(CONFIG_VIRTUAL_FILESTORE_BASEPATH);
self->enableFileService = true;
}
return self;
@ -73,3 +74,16 @@ IedServerConfig_getFileServiceBasePath(IedServerConfig self)
{
return self->fileServiceBasepath;
}
void
IedServerConfig_enableFileService(IedServerConfig self, bool enable)
{
self->enableFileService = enable;
}
bool
IedServerConfig_isFileServiceEnabled(IedServerConfig self)
{
return self->enableFileService;
}

@ -225,6 +225,17 @@ MmsServer_installFileAccessHandler(MmsServer self, MmsFileAccessHandler handler,
void
MmsServer_setFilestoreBasepath(MmsServer self, const char* basepath);
/**
* \brief Enable/disable MMS file services at runtime
*
* NOTE: requires CONFIG_MMS_SERVER_CONFIG_SERVICES_AT_RUNTIME = 1 in stack configuration
*
* \param[in] self the MmsServer instance
* \param[in] enable true to enable file services, false to disable
*/
void
MmsServer_enableFileService(MmsServer self, bool enable);
/**
* \brief lock the cached server data model
*

@ -164,6 +164,10 @@ struct sMmsServer {
char* filestoreBasepath;
#endif
#if (CONFIG_MMS_SERVER_CONFIG_SERVICES_AT_RUNTIME == 1)
bool fileServiceEnabled;
#endif /* (CONFIG_SET_FILESTORE_BASEPATH_AT_RUNTIME == 1) */
};
struct sMmsServerConnection {

@ -1,7 +1,7 @@
/*
* mms_association_service.c
*
* Copyright 2013, 2014 Michael Zillgith
* Copyright 2013-2018 Michael Zillgith
*
* This file is part of libIEC61850.
*
@ -62,58 +62,6 @@
#define MMS_SERVICE_CONCLUDE 0x10
#define MMS_SERVICE_CANCEL 0x08
//TODO make dependent on stack configuration!
/* servicesSupported MMS bitstring */
static uint8_t servicesSupported[] =
{
0x00
#if (MMS_STATUS_SERVICE == 1)
| MMS_SERVICE_STATUS
#endif
| MMS_SERVICE_GET_NAME_LIST
#if (MMS_IDENTIFY_SERVICE == 1)
| MMS_SERVICE_IDENTIFY
#endif
| MMS_SERVICE_READ
| MMS_SERVICE_WRITE
| MMS_SERVICE_GET_VARIABLE_ACCESS_ATTRIBUTES
,
0x00
| MMS_SERVICE_DEFINE_NAMED_VARIABLE_LIST
| MMS_SERVICE_DELETE_NAMED_VARIABLE_LIST
| MMS_SERVICE_GET_NAMED_VARIABLE_LIST_ATTRIBUTES
,
0x00,
0x00,
0x00,
0x00
#if (MMS_OBTAIN_FILE_SERVICE == 1)
| MMS_SERVICE_OBTAIN_FILE
#endif
,
0x00,
0x00,
0x00
#if (MMS_JOURNAL_SERVICE == 1)
| MMS_SERVICE_READ_JOURNAL
#endif
,
0x00
#if (MMS_FILE_SERVICE == 1)
| MMS_SERVICE_FILE_OPEN
| MMS_SERVICE_FILE_READ
| MMS_SERVICE_FILE_CLOSE
| MMS_SERVICE_FILE_RENAME
| MMS_SERVICE_FILE_DELETE
| MMS_SERVICE_FILE_DIRECTORY
#endif
| MMS_SERVICE_INFORMATION_REPORT
,
0x00
| MMS_SERVICE_CONCLUDE
| MMS_SERVICE_CANCEL
};
/* negotiated parameter CBB */
static uint8_t parameterCBB[] =
{
@ -127,7 +75,7 @@ static uint8_t parameterCBB[] =
*********************************************************************************************/
static int
encodeInitResponseDetail(uint8_t* buffer, int bufPos, bool encode)
encodeInitResponseDetail(MmsServerConnection self, uint8_t* buffer, int bufPos, bool encode)
{
int initResponseDetailSize = 14 + 5 + 3;
@ -140,6 +88,126 @@ encodeInitResponseDetail(uint8_t* buffer, int bufPos, bool encode)
bufPos = BerEncoder_encodeBitString(0x81, 11, parameterCBB, buffer, bufPos);
#if (CONFIG_MMS_SERVER_CONFIG_SERVICES_AT_RUNTIME == 1)
uint8_t servicesSupported[] =
{
0x00
#if (MMS_STATUS_SERVICE == 1)
| MMS_SERVICE_STATUS
#endif
| MMS_SERVICE_GET_NAME_LIST
#if (MMS_IDENTIFY_SERVICE == 1)
| MMS_SERVICE_IDENTIFY
#endif
| MMS_SERVICE_READ
| MMS_SERVICE_WRITE
| MMS_SERVICE_GET_VARIABLE_ACCESS_ATTRIBUTES
,
0x00
#if ((MMS_DATA_SET_SERVICE == 1) && (MMS_DYNAMIC_DATA_SETS == 1))
| MMS_SERVICE_DEFINE_NAMED_VARIABLE_LIST
| MMS_SERVICE_DELETE_NAMED_VARIABLE_LIST
#endif
#if ((MMS_DATA_SET_SERVICE == 1) && (MMS_GET_DATA_SET_ATTRIBUTES == 1))
| MMS_SERVICE_GET_NAMED_VARIABLE_LIST_ATTRIBUTES
#endif
,
0x00,
0x00,
0x00,
0x00
,
0x00,
0x00,
0x00
#if (MMS_JOURNAL_SERVICE == 1)
| MMS_SERVICE_READ_JOURNAL
#endif
,
0x00
| MMS_SERVICE_INFORMATION_REPORT
,
0x00
| MMS_SERVICE_CONCLUDE
| MMS_SERVICE_CANCEL
};
if (self->server->fileServiceEnabled) {
#if (MMS_OBTAIN_FILE_SERVICE == 1)
servicesSupported[5] |= MMS_SERVICE_OBTAIN_FILE;
#endif
#if (MMS_FILE_SERVICE == 1)
servicesSupported[9] |= MMS_SERVICE_FILE_OPEN;
servicesSupported[9] |= MMS_SERVICE_FILE_READ;
servicesSupported[9] |= MMS_SERVICE_FILE_CLOSE;
servicesSupported[9] |= MMS_SERVICE_FILE_RENAME;
servicesSupported[9] |= MMS_SERVICE_FILE_DELETE;
servicesSupported[9] |= MMS_SERVICE_FILE_DIRECTORY;
#endif /* (MMS_FILE_SERVICE == 1) */
}
#else
uint8_t servicesSupported[] =
{
0x00
#if (MMS_STATUS_SERVICE == 1)
| MMS_SERVICE_STATUS
#endif
| MMS_SERVICE_GET_NAME_LIST
#if (MMS_IDENTIFY_SERVICE == 1)
| MMS_SERVICE_IDENTIFY
#endif
| MMS_SERVICE_READ
| MMS_SERVICE_WRITE
| MMS_SERVICE_GET_VARIABLE_ACCESS_ATTRIBUTES
,
0x00
#if ((MMS_DATA_SET_SERVICE == 1) && (MMS_DYNAMIC_DATA_SETS == 1))
| MMS_SERVICE_DEFINE_NAMED_VARIABLE_LIST
| MMS_SERVICE_DELETE_NAMED_VARIABLE_LIST
#endif
#if ((MMS_DATA_SET_SERVICE == 1) && (MMS_GET_DATA_SET_ATTRIBUTES == 1))
| MMS_SERVICE_GET_NAMED_VARIABLE_LIST_ATTRIBUTES
#endif
,
0x00,
0x00,
0x00,
0x00
#if (MMS_OBTAIN_FILE_SERVICE == 1)
| MMS_SERVICE_OBTAIN_FILE
#endif
,
0x00,
0x00,
0x00
#if (MMS_JOURNAL_SERVICE == 1)
| MMS_SERVICE_READ_JOURNAL
#endif
,
0x00
#if (MMS_FILE_SERVICE == 1)
| MMS_SERVICE_FILE_OPEN
| MMS_SERVICE_FILE_READ
| MMS_SERVICE_FILE_CLOSE
| MMS_SERVICE_FILE_RENAME
| MMS_SERVICE_FILE_DELETE
| MMS_SERVICE_FILE_DIRECTORY
#endif
| MMS_SERVICE_INFORMATION_REPORT
,
0x00
| MMS_SERVICE_CONCLUDE
| MMS_SERVICE_CANCEL
};
#endif /* (CONFIG_MMS_SERVER_CONFIG_SERVICES_AT_RUNTIME == 1) */
bufPos = BerEncoder_encodeBitString(0x82, 85, servicesSupported, buffer, bufPos);
return bufPos;
@ -159,7 +227,7 @@ createInitiateResponse(MmsServerConnection self, ByteBuffer* writeBuffer)
initiateResponseLength += 2 + BerEncoder_UInt32determineEncodedSize(self->maxServOutstandingCalled);
initiateResponseLength += 2 + BerEncoder_UInt32determineEncodedSize(self->dataStructureNestingLevel);
initiateResponseLength += encodeInitResponseDetail(NULL, 0, false);
initiateResponseLength += encodeInitResponseDetail(self, NULL, 0, false);
/* Initiate response pdu */
bufPos = BerEncoder_encodeTL(0xa9, initiateResponseLength, buffer, bufPos);
@ -172,7 +240,7 @@ createInitiateResponse(MmsServerConnection self, ByteBuffer* writeBuffer)
bufPos = BerEncoder_encodeUInt32WithTL(0x83, self->dataStructureNestingLevel, buffer, bufPos);
bufPos = encodeInitResponseDetail(buffer, bufPos, true);
bufPos = encodeInitResponseDetail(self, buffer, bufPos, true);
writeBuffer->size = bufPos;

@ -67,6 +67,10 @@ MmsServer_create(MmsDevice* device, TLSConfiguration tlsConfiguration)
IsoServer_setUserLock(self->isoServer, self->modelMutex);
#endif
#if (CONFIG_MMS_SERVER_CONFIG_SERVICES_AT_RUNTIME == 1)
self->fileServiceEnabled = true;
#endif /* (CONFIG_MMS_SERVER_CONFIG_SERVICES_AT_RUNTIME == 1) */
return self;
}
@ -99,6 +103,15 @@ MmsServer_setFilestoreBasepath(MmsServer self, const char* basepath)
#endif /* (CONFIG_SET_FILESTORE_BASEPATH_AT_RUNTIME == 1) */
}
#if (CONFIG_MMS_SERVER_CONFIG_SERVICES_AT_RUNTIME == 1)
void
MmsServer_enableFileService(MmsServer self, bool enable)
{
self->fileServiceEnabled = enable;
}
#endif /* (CONFIG_MMS_SERVER_CONFIG_SERVICES_AT_RUNTIME == 1) */
void
MmsServer_lockModel(MmsServer self)

@ -171,9 +171,22 @@ handleConfirmedRequestPdu(
{
#if (MMS_OBTAIN_FILE_SERVICE == 1)
#if (CONFIG_MMS_SERVER_CONFIG_SERVICES_AT_RUNTIME == 1)
case 0x2e: /* obtain-file */
if (self->server->fileServiceEnabled)
mmsServer_handleObtainFileRequest(self, buffer, bufPos, bufPos + length, invokeId, response);
else
mmsMsg_createMmsRejectPdu(&invokeId, MMS_ERROR_REJECT_UNRECOGNIZED_SERVICE, response);
break;
#else
case 0x2e: /* obtain-file */
mmsServer_handleObtainFileRequest(self, buffer, bufPos, bufPos + length, invokeId, response);
break;
#endif /* (CONFIG_MMS_SERVER_CONFIG_SERVICES_AT_RUNTIME == 1) */
#endif /* MMS_OBTAIN_FILE_SERVICE == 1 */
#if (MMS_JOURNAL_SERVICE == 1)
@ -183,29 +196,86 @@ handleConfirmedRequestPdu(
#endif /* (MMS_JOURNAL_SERVICE == 1) */
#if (MMS_FILE_SERVICE == 1)
#if (CONFIG_MMS_SERVER_CONFIG_SERVICES_AT_RUNTIME == 1)
case 0x48: /* file-open-request */
if (self->server->fileServiceEnabled)
mmsServer_handleFileOpenRequest(self, buffer, bufPos, bufPos + length, invokeId, response);
else
mmsMsg_createMmsRejectPdu(&invokeId, MMS_ERROR_REJECT_UNRECOGNIZED_SERVICE, response);
break;
#else
case 0x48: /* file-open-request */
mmsServer_handleFileOpenRequest(self, buffer, bufPos, bufPos + length, invokeId, response);
break;
#endif /* (CONFIG_MMS_SERVER_CONFIG_SERVICES_AT_RUNTIME == 1) */
#if (CONFIG_MMS_SERVER_CONFIG_SERVICES_AT_RUNTIME == 1)
case 0x49: /* file-read-request */
if (self->server->fileServiceEnabled)
mmsServer_handleFileReadRequest(self, buffer, bufPos, bufPos + length, invokeId, response);
else
mmsMsg_createMmsRejectPdu(&invokeId, MMS_ERROR_REJECT_UNRECOGNIZED_SERVICE, response);
break;
#else
case 0x49: /* file-read-request */
mmsServer_handleFileReadRequest(self, buffer, bufPos, bufPos + length, invokeId, response);
break;
#endif /* (CONFIG_MMS_SERVER_CONFIG_SERVICES_AT_RUNTIME == 1) */
#if (CONFIG_MMS_SERVER_CONFIG_SERVICES_AT_RUNTIME == 1)
case 0x4a: /* file-close-request */
if (self->server->fileServiceEnabled)
mmsServer_handleFileCloseRequest(self, buffer, bufPos, bufPos + length, invokeId, response);
else
mmsMsg_createMmsRejectPdu(&invokeId, MMS_ERROR_REJECT_UNRECOGNIZED_SERVICE, response);
break;
#else
case 0x4a: /* file-close-request */
mmsServer_handleFileCloseRequest(self, buffer, bufPos, bufPos + length, invokeId, response);
break;
#endif /* (CONFIG_MMS_SERVER_CONFIG_SERVICES_AT_RUNTIME == 1) */
#if (CONFIG_MMS_SERVER_CONFIG_SERVICES_AT_RUNTIME == 1)
case 0x4b: /* file-rename-request */
if (self->server->fileServiceEnabled)
mmsServer_handleFileRenameRequest(self, buffer, bufPos, bufPos + length, invokeId, response);
else
mmsMsg_createMmsRejectPdu(&invokeId, MMS_ERROR_REJECT_UNRECOGNIZED_SERVICE, response);
break;
#else
case 0x4b: /* file-rename-request */
mmsServer_handleFileRenameRequest(self, buffer, bufPos, bufPos + length, invokeId, response);
break;
#endif /* (CONFIG_MMS_SERVER_CONFIG_SERVICES_AT_RUNTIME == 1) */
#if (CONFIG_MMS_SERVER_CONFIG_SERVICES_AT_RUNTIME == 1)
case 0x4c: /* file-delete-request */
if (self->server->fileServiceEnabled)
mmsServer_handleFileDeleteRequest(self, buffer, bufPos, bufPos + length, invokeId, response);
else
mmsMsg_createMmsRejectPdu(&invokeId, MMS_ERROR_REJECT_UNRECOGNIZED_SERVICE, response);
break;
#else
case 0x4c: /* file-delete-request */
mmsServer_handleFileDeleteRequest(self, buffer, bufPos, bufPos + length, invokeId, response);
break;
#endif /* (CONFIG_MMS_SERVER_CONFIG_SERVICES_AT_RUNTIME == 1) */
#if (CONFIG_MMS_SERVER_CONFIG_SERVICES_AT_RUNTIME == 1)
case 0x4d: /* file-directory-request */
if (self->server->fileServiceEnabled)
mmsServer_handleFileDirectoryRequest(self, buffer, bufPos, bufPos + length, invokeId, response);
else
mmsMsg_createMmsRejectPdu(&invokeId, MMS_ERROR_REJECT_UNRECOGNIZED_SERVICE, response);
break;
#else
case 0x4d: /* file-directory-request */
mmsServer_handleFileDirectoryRequest(self, buffer, bufPos, bufPos + length, invokeId, response);
break;
#endif /* (CONFIG_MMS_SERVER_CONFIG_SERVICES_AT_RUNTIME == 1) */
#endif /* MMS_FILE_SERVICE == 1 */
default:

@ -604,3 +604,5 @@ EXPORTS
ClientGooseControlBlock_getMaxTime
ClientGooseControlBlock_getFixedOffs
ControlObjectClient_getCtlValType
IedServerConfig_enableFileService
IedServerConfig_isFileServiceEnabled

@ -732,3 +732,5 @@ EXPORTS
ClientGooseControlBlock_getFixedOffs
ControlObjectClient_getCtlValType
SVPublisher_ASDU_setSmpCntWrap
IedServerConfig_enableFileService
IedServerConfig_isFileServiceEnabled

Loading…
Cancel
Save