diff --git a/src/iec61850/server/mms_mapping/mms_mapping.c b/src/iec61850/server/mms_mapping/mms_mapping.c index fc080ea2..4d6d8b31 100644 --- a/src/iec61850/server/mms_mapping/mms_mapping.c +++ b/src/iec61850/server/mms_mapping/mms_mapping.c @@ -1,7 +1,7 @@ /* * mms_mapping.c * - * Copyright 2013-2022 Michael Zillgith + * Copyright 2013-2023 Michael Zillgith * * This file is part of libIEC61850. * @@ -3379,7 +3379,7 @@ mmsReadAccessHandler (void* parameter, MmsDomain* domain, char* variableId, MmsS } static MmsError -variableListChangedHandler (void* parameter, bool create, MmsVariableListType listType, MmsDomain* domain, +variableListAccessHandler (void* parameter, MmsVariableListAccessType accessType, MmsVariableListType listType, MmsDomain* domain, char* listName, MmsServerConnection connection) { MmsError allow = MMS_ERROR_NONE; @@ -3389,10 +3389,16 @@ variableListChangedHandler (void* parameter, bool create, MmsVariableListType li /* TODO add log message */ #if (DEBUG_IED_SERVER == 1) - if (create) + if (accessType == MMS_VARLIST_CREATE) printf("IED_SERVER: create data set "); - else + else if (accessType == MMS_VARLIST_DELETE) printf("IED_SERVER: delete data set "); + else if (accessType == MMS_VARLIST_READ) + printf("IED_SERVER: read data set "); + else if (accessType == MMS_VARLIST_WRITE) + printf("IED_SERVER: write data set "); + else if (accessType == MMS_VARLIST_READ) + printf("IED_SERVER: get directory of data set "); switch (listType) { case MMS_VMD_SPECIFIC: @@ -3411,7 +3417,10 @@ variableListChangedHandler (void* parameter, bool create, MmsVariableListType li MmsMapping* self = (MmsMapping*) parameter; - if (create) { + if (accessType == MMS_VARLIST_CREATE) { + + //TODO call user callback hander (IedServer_DataSetAccessHandler) + if (listType == MMS_DOMAIN_SPECIFIC) { /* check if LN exists - otherwise reject request (to fulfill test case sDsN1c) */ @@ -3441,7 +3450,10 @@ variableListChangedHandler (void* parameter, bool create, MmsVariableListType li } } - else { + else if (accessType == MMS_VARLIST_DELETE) { + + //TODO call user callback hander (IedServer_DataSetAccessHandler) + /* Check if data set is referenced in a report */ LinkedList rcElement = self->reportControls; @@ -3519,6 +3531,15 @@ variableListChangedHandler (void* parameter, bool create, MmsVariableListType li #endif /* (CONFIG_IEC61850_LOG_SERVICE == 1) */ } + else if (accessType == MMS_VARLIST_READ) { + //TODO call user callback hander (IedServer_DataSetAccessHandler) + } + else if (accessType == MMS_VARLIST_WRITE) { + //TODO call user callback hander (IedServer_DataSetAccessHandler) + } + else if (accessType == MMS_VARLIST_GET_DIRECTORY) { + //TODO call user callback hander (IedServer_DataSetAccessHandler) + } return allow; } @@ -3530,7 +3551,7 @@ MmsMapping_installHandlers(MmsMapping* self) MmsServer_installWriteHandler(self->mmsServer, mmsWriteHandler, (void*) self); MmsServer_installReadAccessHandler(self->mmsServer, mmsReadAccessHandler, (void*) self); MmsServer_installConnectionHandler(self->mmsServer, mmsConnectionHandler, (void*) self); - MmsServer_installVariableListChangedHandler(self->mmsServer, variableListChangedHandler, (void*) self); + MmsServer_installVariableListAccessHandler(self->mmsServer, variableListAccessHandler, (void*) self); } void diff --git a/src/mms/inc/mms_server.h b/src/mms/inc/mms_server.h index 2986d5b3..b9c22417 100644 --- a/src/mms/inc/mms_server.h +++ b/src/mms/inc/mms_server.h @@ -81,29 +81,14 @@ typedef MmsError (*MmsNamedVariableListAccessHandler)(void* parameter, MmsVariab char* listName, MmsServerConnection connection); /** - * \brief callback handler that is called whenever a named variable list changes - * - * \param parameter a user provided parameter - * \param create if true the the request if a request to create a new variable list, false is a delete request - * \param listType the type (scope) of the named variable list (either domain, association or VMD specific) - * \param domain the MMS domain the list is belonging to (is NULL for association or VMD specific lists!) - * \param listName the name - * \param connection client connection that requests the creation of deletion of the variable list - * - * \return MMS_ERROR_NONE if the request is accepted, otherwise the MmsError value that has to be sent back to the client - */ -typedef MmsError (*MmsNamedVariableListChangedHandler)(void* parameter, bool create, MmsVariableListType listType, MmsDomain* domain, - char* listName, MmsServerConnection connection); - -/** - * \brief Install callback handler that is called when a named variable list changes (is created or deleted) + * \brief Install callback handler that is called when a named variable list is accessed by a client * * \param self the MmsServer instance to operate on * \param handler the callback handler function * \param parameter user provided parameter that is passed to the callback handler */ LIB61850_INTERNAL void -MmsServer_installVariableListChangedHandler(MmsServer self, MmsNamedVariableListChangedHandler handler, void* parameter); +MmsServer_installVariableListAccessHandler(MmsServer self, MmsNamedVariableListAccessHandler handler, void* parameter); /** * \brief ObtainFile service callback handler diff --git a/src/mms/inc_private/mms_server_internal.h b/src/mms/inc_private/mms_server_internal.h index bbf5195f..fc875597 100644 --- a/src/mms/inc_private/mms_server_internal.h +++ b/src/mms/inc_private/mms_server_internal.h @@ -123,8 +123,8 @@ struct sMmsServer { MmsConnectionHandler connectionHandler; void* connectionHandlerParameter; - MmsNamedVariableListChangedHandler variableListChangedHandler; - void* variableListChangedHandlerParameter; + MmsNamedVariableListAccessHandler variableListAccessHandler; + void* variableListAccessHandlerParameter; AcseAuthenticator authenticator; void* authenticatorParameter; @@ -421,7 +421,7 @@ mmsServer_createMmsWriteResponse(MmsServerConnection connection, uint32_t invokeId, ByteBuffer* response, int numberOfItems, MmsDataAccessError* accessResults); LIB61850_INTERNAL MmsError -mmsServer_callVariableListChangedHandler(bool create, MmsVariableListType listType, MmsDomain* domain, +mmsServer_callVariableListChangedHandler(MmsVariableListAccessType accessType, MmsVariableListType listType, MmsDomain* domain, char* listName, MmsServerConnection connection); #endif /* MMS_SERVER_INTERNAL_H_ */ diff --git a/src/mms/iso_mms/server/mms_named_variable_list_service.c b/src/mms/iso_mms/server/mms_named_variable_list_service.c index 3a27061c..4baf4ab3 100644 --- a/src/mms/iso_mms/server/mms_named_variable_list_service.c +++ b/src/mms/iso_mms/server/mms_named_variable_list_service.c @@ -1,7 +1,7 @@ /* * mms_named_variable_list_service.c * - * Copyright 2013-2020 Michael Zillgith + * Copyright 2013-2023 Michael Zillgith * * This file is part of libIEC61850. * @@ -49,17 +49,17 @@ #endif MmsError -mmsServer_callVariableListChangedHandler(bool create, MmsVariableListType listType, MmsDomain* domain, +mmsServer_callVariableListChangedHandler(MmsVariableListAccessType accessType, MmsVariableListType listType, MmsDomain* domain, char* listName, MmsServerConnection connection) { MmsServer self = connection->server; - if (self->variableListChangedHandler != NULL) { + if (self->variableListAccessHandler != NULL) { if (DEBUG_MMS_SERVER) - printf("MMS_SERVER: call MmsNamedVariableListChangedHandler for new list %s\n", listName); + printf("MMS_SERVER: call MmsNamedVariableListAccessHandler for new list %s\n", listName); - return self->variableListChangedHandler(self->variableListChangedHandlerParameter, - create, listType, domain, listName, connection); + return self->variableListAccessHandler(self->variableListAccessHandlerParameter, + accessType, listType, domain, listName, connection); } else return MMS_ERROR_NONE; @@ -180,7 +180,7 @@ mmsServer_handleDeleteNamedVariableListRequest(MmsServerConnection connection, if (MmsNamedVariableList_isDeletable(variableList)) { - MmsError deleteError = mmsServer_callVariableListChangedHandler(false, MMS_DOMAIN_SPECIFIC, domain, listName, connection); + MmsError deleteError = mmsServer_callVariableListChangedHandler(MMS_VARLIST_DELETE, MMS_DOMAIN_SPECIFIC, domain, listName, connection); if (deleteError == MMS_ERROR_NONE) { MmsDomain_deleteNamedVariableList(domain, listName); @@ -203,7 +203,7 @@ mmsServer_handleDeleteNamedVariableListRequest(MmsServerConnection connection, if (variableList != NULL) { numberMatched++; - MmsError deleteError = mmsServer_callVariableListChangedHandler(false, MMS_ASSOCIATION_SPECIFIC, NULL, listName, connection); + MmsError deleteError = mmsServer_callVariableListChangedHandler(MMS_VARLIST_DELETE, MMS_ASSOCIATION_SPECIFIC, NULL, listName, connection); if (deleteError == MMS_ERROR_NONE) { numberDeleted++; @@ -224,7 +224,7 @@ mmsServer_handleDeleteNamedVariableListRequest(MmsServerConnection connection, if (variableList != NULL) { numberMatched++; - MmsError deleteError = mmsServer_callVariableListChangedHandler(false, MMS_VMD_SPECIFIC, NULL, listName, connection); + MmsError deleteError = mmsServer_callVariableListChangedHandler(MMS_VARLIST_DELETE, MMS_VMD_SPECIFIC, NULL, listName, connection); if (deleteError == MMS_ERROR_NONE) { numberDeleted++; @@ -526,7 +526,7 @@ mmsServer_handleDefineNamedVariableListRequest( if (namedVariableList != NULL) { - mmsError = mmsServer_callVariableListChangedHandler(true, MMS_DOMAIN_SPECIFIC, domain, variableListName, connection); + mmsError = mmsServer_callVariableListChangedHandler(MMS_VARLIST_CREATE, MMS_DOMAIN_SPECIFIC, domain, variableListName, connection); if (mmsError == MMS_ERROR_NONE) { MmsDomain_addNamedVariableList(domain, namedVariableList); @@ -576,7 +576,7 @@ mmsServer_handleDefineNamedVariableListRequest( if (namedVariableList != NULL) { - if (mmsServer_callVariableListChangedHandler(true, MMS_ASSOCIATION_SPECIFIC, NULL, variableListName, connection) == MMS_ERROR_NONE) { + if (mmsServer_callVariableListChangedHandler(MMS_VARLIST_CREATE, MMS_ASSOCIATION_SPECIFIC, NULL, variableListName, connection) == MMS_ERROR_NONE) { MmsServerConnection_addNamedVariableList(connection, namedVariableList); createDefineNamedVariableListResponse(invokeId, response); } @@ -619,7 +619,7 @@ mmsServer_handleDefineNamedVariableListRequest( request, variableListName, &mmsError); if (namedVariableList != NULL) { - if (mmsServer_callVariableListChangedHandler(true, MMS_VMD_SPECIFIC, NULL, variableListName, connection) + if (mmsServer_callVariableListChangedHandler(MMS_VARLIST_CREATE, MMS_VMD_SPECIFIC, NULL, variableListName, connection) == MMS_ERROR_NONE) { LinkedList_add(vmdScopeNVLs, (void*) namedVariableList); diff --git a/src/mms/iso_mms/server/mms_read_service.c b/src/mms/iso_mms/server/mms_read_service.c index 2638bc0b..3193c699 100644 --- a/src/mms/iso_mms/server/mms_read_service.c +++ b/src/mms/iso_mms/server/mms_read_service.c @@ -768,9 +768,21 @@ handleReadNamedVariableListRequest( else { MmsNamedVariableList namedList = MmsDomain_getNamedVariableList(domain, nameIdStr); - if (namedList != NULL) { - createNamedVariableListResponse(connection, namedList, invokeId, response, isSpecWithResult(read), - &accessSpec); + if (namedList) + { + + MmsError accessError = mmsServer_callVariableListChangedHandler(MMS_VARLIST_READ, MMS_DOMAIN_SPECIFIC, domain, namedList->name, connection); + + if (accessError == MMS_ERROR_NONE) { + createNamedVariableListResponse(connection, namedList, invokeId, response, isSpecWithResult(read), + &accessSpec); + } + else { + if (DEBUG_MMS_SERVER) printf("MMS read: named variable list %s access error: %i\n", nameIdStr, accessError); + + mmsMsg_createServiceErrorPdu(invokeId, response, accessError); + } + } else { if (DEBUG_MMS_SERVER) printf("MMS read: named variable list %s not found!\n", nameIdStr); @@ -791,14 +803,24 @@ handleReadNamedVariableListRequest( mmsMsg_createServiceErrorPdu(invokeId, response, MMS_ERROR_ACCESS_OBJECT_NON_EXISTENT); else { - VarAccessSpec accessSpec; + MmsError accessError = mmsServer_callVariableListChangedHandler(MMS_VARLIST_READ, MMS_VMD_SPECIFIC, NULL, namedList->name, connection); + + if (accessError == MMS_ERROR_NONE) { + VarAccessSpec accessSpec; - accessSpec.isNamedVariableList = true; - accessSpec.specific = 0; - accessSpec.domainId = NULL; - accessSpec.itemId = listName; + accessSpec.isNamedVariableList = true; + accessSpec.specific = 0; + accessSpec.domainId = NULL; + accessSpec.itemId = listName; + + createNamedVariableListResponse(connection, namedList, invokeId, response, isSpecWithResult(read), &accessSpec); + } + else { + if (DEBUG_MMS_SERVER) printf("MMS read: VMD specific named variable list %s access error: %i\n", listName, accessError); + + mmsMsg_createServiceErrorPdu(invokeId, response, accessError); + } - createNamedVariableListResponse(connection, namedList, invokeId, response, isSpecWithResult(read), &accessSpec); } } #if (MMS_DYNAMIC_DATA_SETS == 1) @@ -815,14 +837,25 @@ handleReadNamedVariableListRequest( if (namedList == NULL) mmsMsg_createServiceErrorPdu(invokeId, response, MMS_ERROR_ACCESS_OBJECT_NON_EXISTENT); else { - VarAccessSpec accessSpec; - accessSpec.isNamedVariableList = true; - accessSpec.specific = 2; - accessSpec.domainId = NULL; - accessSpec.itemId = listName; + MmsError accessError = mmsServer_callVariableListChangedHandler(MMS_VARLIST_READ, MMS_ASSOCIATION_SPECIFIC, NULL, namedList->name, connection); + + if (accessError == MMS_ERROR_NONE) { + + VarAccessSpec accessSpec; - createNamedVariableListResponse(connection, namedList, invokeId, response, isSpecWithResult(read), &accessSpec); + accessSpec.isNamedVariableList = true; + accessSpec.specific = 2; + accessSpec.domainId = NULL; + accessSpec.itemId = listName; + + createNamedVariableListResponse(connection, namedList, invokeId, response, isSpecWithResult(read), &accessSpec); + } + else { + if (DEBUG_MMS_SERVER) printf("MMS read: association specific named variable list %s access error: %i\n", listName, accessError); + + mmsMsg_createServiceErrorPdu(invokeId, response, accessError); + } } } #endif /* (MMS_DYNAMIC_DATA_SETS == 1) */ diff --git a/src/mms/iso_mms/server/mms_server.c b/src/mms/iso_mms/server/mms_server.c index ed2cf725..e6cccfa5 100644 --- a/src/mms/iso_mms/server/mms_server.c +++ b/src/mms/iso_mms/server/mms_server.c @@ -359,10 +359,10 @@ MmsServer_installConnectionHandler(MmsServer self, MmsConnectionHandler connecti } void -MmsServer_installVariableListChangedHandler(MmsServer self, MmsNamedVariableListChangedHandler handler, void* parameter) +MmsServer_installVariableListAccessHandler(MmsServer self, MmsNamedVariableListAccessHandler handler, void* parameter) { - self->variableListChangedHandler = handler; - self->variableListChangedHandlerParameter = parameter; + self->variableListAccessHandler = handler; + self->variableListAccessHandlerParameter = parameter; } void