diff --git a/examples/server_example_basic_io/server_example_basic_io.c b/examples/server_example_basic_io/server_example_basic_io.c index 54887187..d5c9a6b8 100644 --- a/examples/server_example_basic_io/server_example_basic_io.c +++ b/examples/server_example_basic_io/server_example_basic_io.c @@ -97,7 +97,9 @@ main(int argc, char** argv) IedServerConfig_enableFileService(config, false); /* disable dynamic data set service */ - IedServerConfig_enableDynamicDataSetService(config, true); + IedServerConfig_enableDynamicDataSetService(config, false); + + IedServerConfig_enableLogService(config, true); /* Create a new IEC 61850 server instance */ iedServer = IedServer_createWithConfig(&iedModel, NULL, config); diff --git a/src/iec61850/inc/iec61850_server.h b/src/iec61850/inc/iec61850_server.h index 1f17d226..d5f7b954 100644 --- a/src/iec61850/inc/iec61850_server.h +++ b/src/iec61850/inc/iec61850_server.h @@ -59,6 +59,9 @@ struct sIedServerConfig /** when true (default) enable dynamic data set services for MMS */ bool enableDynamicDataSetService; + + /** when true (default) enable log service */ + bool enableLogService; }; /** @@ -137,6 +140,22 @@ IedServerConfig_enableDynamicDataSetService(IedServerConfig self, bool enable); bool IedServerConfig_isDynamicDataSetServiceEnabled(IedServerConfig self); +/** + * \brief Enable/disable the log service for MMS + * + * \param[in] enable set true to enable dynamic data set service, otherwise false + */ +void +IedServerConfig_enableLogService(IedServerConfig self, bool enable); + +/** + * \brief Is the log service for MMS enabled or disabled + * + * \return true if enabled, false otherwise + */ +bool +IedServerConfig_isLogServiceEnabled(IedServerConfig self); + /** * An opaque handle for an IED server instance */ diff --git a/src/iec61850/inc_private/ied_server_private.h b/src/iec61850/inc_private/ied_server_private.h index d78702cc..825c032b 100644 --- a/src/iec61850/inc_private/ied_server_private.h +++ b/src/iec61850/inc_private/ied_server_private.h @@ -51,6 +51,10 @@ struct sIedServer Semaphore dataModelLock; #endif +#if (CONFIG_MMS_SERVER_CONFIG_SERVICES_AT_RUNTIME == 1) + bool logServiceEnabled; +#endif + bool running; }; diff --git a/src/iec61850/server/impl/ied_server.c b/src/iec61850/server/impl/ied_server.c index 200032fa..c5f9a745 100644 --- a/src/iec61850/server/impl/ied_server.c +++ b/src/iec61850/server/impl/ied_server.c @@ -404,9 +404,17 @@ IedServer_createWithConfig(IedModel* dataModel, TLSConfiguration tlsConfiguratio self->running = false; self->localIpAddress = NULL; +#if (CONFIG_MMS_SERVER_CONFIG_SERVICES_AT_RUNTIME == 1) + self->logServiceEnabled = true; + + if (serverConfiguration) { + self->logServiceEnabled = serverConfiguration->enableLogService; + } +#endif /* (CONFIG_MMS_SERVER_CONFIG_SERVICES_AT_RUNTIME == 1) */ + #if (CONFIG_MMS_THREADLESS_STACK != 1) self->dataModelLock = Semaphore_create(1); -#endif +#endif /* (CONFIG_MMS_SERVER_CONFIG_SERVICES_AT_RUNTIME == 1) */ #if (CONFIG_IEC61850_REPORT_SERVICE == 1) if (serverConfiguration) @@ -425,6 +433,7 @@ IedServer_createWithConfig(IedModel* dataModel, TLSConfiguration tlsConfiguratio if (serverConfiguration) { MmsServer_enableFileService(self->mmsServer, serverConfiguration->enableFileService); MmsServer_enableDynamicNamedVariableListService(self->mmsServer, serverConfiguration->enableDynamicDataSetService); + MmsServer_enableJournalService(self->mmsServer, serverConfiguration->enableLogService); } #endif diff --git a/src/iec61850/server/impl/ied_server_config.c b/src/iec61850/server/impl/ied_server_config.c index 956b0645..fe8c7ea5 100644 --- a/src/iec61850/server/impl/ied_server_config.c +++ b/src/iec61850/server/impl/ied_server_config.c @@ -34,6 +34,7 @@ IedServerConfig_create() self->fileServiceBasepath = StringUtils_copyString(CONFIG_VIRTUAL_FILESTORE_BASEPATH); self->enableFileService = true; self->enableDynamicDataSetService = true; + self->enableLogService = true; } return self; @@ -99,3 +100,15 @@ IedServerConfig_isDynamicDataSetServiceEnabled(IedServerConfig self) { return self->enableDynamicDataSetService; } + +void +IedServerConfig_enableLogService(IedServerConfig self, bool enable) +{ + self->enableLogService = enable; +} + +bool +IedServerConfig_isLogServiceEnabled(IedServerConfig self) +{ + return self->enableLogService; +} diff --git a/src/iec61850/server/mms_mapping/mms_mapping.c b/src/iec61850/server/mms_mapping/mms_mapping.c index 811039be..e7958bb6 100644 --- a/src/iec61850/server/mms_mapping/mms_mapping.c +++ b/src/iec61850/server/mms_mapping/mms_mapping.c @@ -1010,12 +1010,22 @@ createNamedVariableFromLogicalNode(MmsMapping* self, MmsDomain* domain, #endif /* (CONFIG_IEC61850_REPORT_SERVICE == 1) */ #if (CONFIG_IEC61850_LOG_SERVICE == 1) - if (lcbCount > 0) { - namedVariable->typeSpec.structure.elements[currentComponent] = - Logging_createLCBs(self, domain, logicalNode, lcbCount); - currentComponent++; +#if (CONFIG_MMS_SERVER_CONFIG_SERVICES_AT_RUNTIME == 1) + if (self->iedServer->logServiceEnabled) { +#endif + + if (lcbCount > 0) { + namedVariable->typeSpec.structure.elements[currentComponent] = + Logging_createLCBs(self, domain, logicalNode, lcbCount); + + currentComponent++; + } + +#if (CONFIG_MMS_SERVER_CONFIG_SERVICES_AT_RUNTIME == 1) } +#endif + #endif /* (CONFIG_IEC61850_LOG_SERVICE == 1) */ @@ -1118,33 +1128,42 @@ createMmsDomainFromIedDevice(MmsMapping* self, LogicalDevice* logicalDevice) goto exit_function; #if (CONFIG_IEC61850_LOG_SERVICE == 1) - /* add logs (journals) */ - Log* log = self->model->logs; - while (log != NULL) { +#if (CONFIG_MMS_SERVER_CONFIG_SERVICES_AT_RUNTIME == 1) + if (self->iedServer->logServiceEnabled) { +#endif + /* add logs (journals) */ + Log* log = self->model->logs; - char journalName[65]; + while (log != NULL) { - int nameLength = strlen(log->parent->name) + strlen(log->name); + char journalName[65]; - if (nameLength > 63) { - if (DEBUG_IED_SERVER) - printf("IED_SERVER: Log name %s invalid! Resulting journal name too long! Skip log\n", log->name); - } - else { - strcpy(journalName, log->parent->name); - strcat(journalName, "$"); - strcat(journalName, log->name); + int nameLength = strlen(log->parent->name) + strlen(log->name); + + if (nameLength > 63) { + if (DEBUG_IED_SERVER) + printf("IED_SERVER: Log name %s invalid! Resulting journal name too long! Skip log\n", log->name); + } + else { + strcpy(journalName, log->parent->name); + strcat(journalName, "$"); + strcat(journalName, log->name); + + MmsDomain_addJournal(domain, journalName); - MmsDomain_addJournal(domain, journalName); + LogInstance* logInstance = LogInstance_create(log->parent, log->name); - LogInstance* logInstance = LogInstance_create(log->parent, log->name); + LinkedList_add(self->logInstances, (void*) logInstance); + } - LinkedList_add(self->logInstances, (void*) logInstance); + log = log->sibling; } - log = log->sibling; +#if (CONFIG_MMS_SERVER_CONFIG_SERVICES_AT_RUNTIME == 1) } +#endif + #endif /* (CONFIG_IEC61850_LOG_SERVICE == 1) */ int nodesCount = LogicalDevice_getLogicalNodeCount(logicalDevice); diff --git a/src/mms/inc/mms_server.h b/src/mms/inc/mms_server.h index d0a2cd60..5d6cd93b 100644 --- a/src/mms/inc/mms_server.h +++ b/src/mms/inc/mms_server.h @@ -247,6 +247,17 @@ MmsServer_enableFileService(MmsServer self, bool enable); void MmsServer_enableDynamicNamedVariableListService(MmsServer self, bool enable); +/** + * \brief Enable/disable journal service + * + * 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 journal service, false to disable + */ +void +MmsServer_enableJournalService(MmsServer self, bool enable); + /** * \brief lock the cached server data model * diff --git a/src/mms/inc_private/mms_server_internal.h b/src/mms/inc_private/mms_server_internal.h index 0013d63a..37cffb35 100644 --- a/src/mms/inc_private/mms_server_internal.h +++ b/src/mms/inc_private/mms_server_internal.h @@ -167,6 +167,7 @@ struct sMmsServer { #if (CONFIG_MMS_SERVER_CONFIG_SERVICES_AT_RUNTIME == 1) bool fileServiceEnabled; bool dynamicVariableListServiceEnabled; + bool journalServiceEnabled; #endif /* (CONFIG_SET_FILESTORE_BASEPATH_AT_RUNTIME == 1) */ }; diff --git a/src/mms/iso_mms/server/mms_association_service.c b/src/mms/iso_mms/server/mms_association_service.c index e31a411a..25c69dde 100644 --- a/src/mms/iso_mms/server/mms_association_service.c +++ b/src/mms/iso_mms/server/mms_association_service.c @@ -112,15 +112,10 @@ encodeInitResponseDetail(MmsServerConnection self, uint8_t* buffer, int bufPos, 0x00, 0x00, 0x00, - 0x00 - , 0x00, 0x00, - 0x00 - #if (MMS_JOURNAL_SERVICE == 1) - | MMS_SERVICE_READ_JOURNAL - #endif - , + 0x00, + 0x00, 0x00 | MMS_SERVICE_INFORMATION_REPORT , @@ -156,6 +151,12 @@ encodeInitResponseDetail(MmsServerConnection self, uint8_t* buffer, int bufPos, } + if (self->server->journalServiceEnabled) { +#if (MMS_JOURNAL_SERVICE == 1) + servicesSupported[8] |= MMS_SERVICE_READ_JOURNAL; +#endif + } + #else uint8_t servicesSupported[] = diff --git a/src/mms/iso_mms/server/mms_get_namelist_service.c b/src/mms/iso_mms/server/mms_get_namelist_service.c index bf0637f1..486383bc 100644 --- a/src/mms/iso_mms/server/mms_get_namelist_service.c +++ b/src/mms/iso_mms/server/mms_get_namelist_service.c @@ -615,11 +615,10 @@ mmsServer_handleGetNameListRequest( #endif /* (MMS_DATA_SET_SERVICE == 1) */ else if (objectClass == OBJECT_CLASS_JOURNAL) { - LinkedList nameList = LinkedList_create(); -#if (CONFIG_MMS_SORT_NAME_LIST == 1) - StringUtils_sortList(nameList); -#endif + /* response with empty list */ + + LinkedList nameList = LinkedList_create(); createNameListResponse(connection, invokeId, nameList, response, continueAfter); diff --git a/src/mms/iso_mms/server/mms_server.c b/src/mms/iso_mms/server/mms_server.c index 3b029e17..2352926d 100644 --- a/src/mms/iso_mms/server/mms_server.c +++ b/src/mms/iso_mms/server/mms_server.c @@ -70,6 +70,7 @@ MmsServer_create(MmsDevice* device, TLSConfiguration tlsConfiguration) #if (CONFIG_MMS_SERVER_CONFIG_SERVICES_AT_RUNTIME == 1) self->fileServiceEnabled = true; self->dynamicVariableListServiceEnabled = true; + self->journalServiceEnabled = true; #endif /* (CONFIG_MMS_SERVER_CONFIG_SERVICES_AT_RUNTIME == 1) */ return self; @@ -118,6 +119,12 @@ MmsServer_enableDynamicNamedVariableListService(MmsServer self, bool enable) self->dynamicVariableListServiceEnabled = enable; } +void +MmsServer_enableJournalService(MmsServer self, bool enable) +{ + self->journalServiceEnabled = enable; +} + #endif /* (CONFIG_MMS_SERVER_CONFIG_SERVICES_AT_RUNTIME == 1) */ void diff --git a/src/mms/iso_mms/server/mms_server_connection.c b/src/mms/iso_mms/server/mms_server_connection.c index 4017b636..c689fdb5 100644 --- a/src/mms/iso_mms/server/mms_server_connection.c +++ b/src/mms/iso_mms/server/mms_server_connection.c @@ -190,9 +190,21 @@ handleConfirmedRequestPdu( #endif /* MMS_OBTAIN_FILE_SERVICE == 1 */ #if (MMS_JOURNAL_SERVICE == 1) + +#if (CONFIG_MMS_SERVER_CONFIG_SERVICES_AT_RUNTIME == 1) + case 0x41: /* read-journal */ + if (self->server->journalServiceEnabled) + mmsServer_handleReadJournalRequest(self, buffer, bufPos, bufPos + length, invokeId, response); + else + mmsMsg_createMmsRejectPdu(&invokeId, MMS_ERROR_REJECT_UNRECOGNIZED_SERVICE, response); + break; + +#else case 0x41: /* read-journal */ mmsServer_handleReadJournalRequest(self, buffer, bufPos, bufPos + length, invokeId, response); break; +#endif /* (CONFIG_MMS_SERVER_CONFIG_SERVICES_AT_RUNTIME == 1) */ + #endif /* (MMS_JOURNAL_SERVICE == 1) */ #if (MMS_FILE_SERVICE == 1) diff --git a/src/vs/libiec61850-wo-goose.def b/src/vs/libiec61850-wo-goose.def index 284acd03..c769a4d8 100644 --- a/src/vs/libiec61850-wo-goose.def +++ b/src/vs/libiec61850-wo-goose.def @@ -608,3 +608,5 @@ EXPORTS IedServerConfig_isFileServiceEnabled IedServerConfig_enableDynamicDataSetService IedServerConfig_isDynamicDataSetServiceEnabled + IedServerConfig_enableLogService + IedServerConfig_isLogServiceEnabled diff --git a/src/vs/libiec61850.def b/src/vs/libiec61850.def index b11db748..8e5edab4 100644 --- a/src/vs/libiec61850.def +++ b/src/vs/libiec61850.def @@ -736,3 +736,5 @@ EXPORTS IedServerConfig_isFileServiceEnabled IedServerConfig_enableDynamicDataSetService IedServerConfig_isDynamicDataSetServiceEnabled + IedServerConfig_enableLogService + IedServerConfig_isLogServiceEnabled