diff --git a/examples/server_example_access_control/server_example_access_control.c b/examples/server_example_access_control/server_example_access_control.c index 365576e8..7dca5dc3 100644 --- a/examples/server_example_access_control/server_example_access_control.c +++ b/examples/server_example_access_control/server_example_access_control.c @@ -23,6 +23,38 @@ sigint_handler(int signalId) running = 0; } +static const char* +ACSIClassToStr(ACSIClass acsiClass) +{ + switch (acsiClass) + { + case ACSI_CLASS_BRCB: + return "BRCB"; + case ACSI_CLASS_URCB: + return "URCB"; + case ACSI_CLASS_GoCB: + return "GoCB"; + case ACSI_CLASS_SGCB: + return "SGCB"; + case ACSI_CLASS_LCB: + return "LCB"; + case ACSI_CLASS_GsCB: + return "GsCB"; + case ACSI_CLASS_LOG: + return "log"; + case ACSI_CLASS_DATA_SET: + return "dataset"; + case ACSI_CLASS_DATA_OBJECT: + return "data-object"; + case ACSI_CLASS_MSVCB: + return "MSVCB"; + case ACSI_CLASS_USVCB: + return "USVCB"; + default: + return "unknown"; + } +} + static ControlHandlerResult controlHandlerForBinaryOutput(ControlAction action, void* parameter, MmsValue* value, bool test) { @@ -65,7 +97,6 @@ controlHandlerForBinaryOutput(ControlAction action, void* parameter, MmsValue* v return CONTROL_RESULT_OK; } - static void connectionHandler (IedServer self, ClientConnection connection, bool connected, void* parameter) { @@ -137,25 +168,35 @@ dataSetAccessHandler(void* parameter, ClientConnection connection, IedServer_Dat static MmsDataAccessError readAccessHandler(LogicalDevice* ld, LogicalNode* ln, DataObject* dataObject, FunctionalConstraint fc, ClientConnection connection, void* parameter) { - printf("Read access to %s/%s.%s\n", ld->name, ln->name, dataObject->name); + printf("Read access to %s/%s.%s\n", ld->name, ln->name, dataObject ? dataObject->name : "-"); - if (!strcmp(ln->name, "GGIO1") && !strcmp(dataObject->name, "AnIn1")) { - return DATA_ACCESS_ERROR_OBJECT_ACCESS_DENIED; + if (dataObject == NULL) { + if (!strcmp(ln->name, "GGIO1")) { + return DATA_ACCESS_ERROR_OBJECT_ACCESS_DENIED; + } + } + else { + if (!strcmp(ln->name, "GGIO1") && !strcmp(dataObject->name, "AnIn1")) { + return DATA_ACCESS_ERROR_OBJECT_ACCESS_DENIED; + } } return DATA_ACCESS_ERROR_SUCCESS; } static bool -listObjectsAccessHandler(void* parameter, ClientConnection connection, LogicalDevice* ld, LogicalNode* ln, DataObject* dataObject, FunctionalConstraint fc) +listObjectsAccessHandler(void* parameter, ClientConnection connection, ACSIClass acsiClass, LogicalDevice* ld, LogicalNode* ln, const char* objectName, const char* subObjectName, FunctionalConstraint fc) { - printf("list objects access to %s/%s.%s[%s]\n", ld->name, ln->name, dataObject ? dataObject->name : "-", FunctionalConstraint_toString(fc)); + if (subObjectName) + printf("list objects access[2] to %s/%s.%s.%s [acsi-class: %s(%i)] [FC=%s]\n", ld->name, ln ? ln->name : "-", objectName, subObjectName, ACSIClassToStr(acsiClass), acsiClass, FunctionalConstraint_toString(fc)); + else + printf("list objects access[2] to %s/%s.%s [acsi-class: %s(%i)] [FC=%s]\n", ld->name, ln ? ln->name : "-", objectName, ACSIClassToStr(acsiClass), acsiClass, FunctionalConstraint_toString(fc)); - if (!strcmp(ln->name, "GGIO1")) { - if (dataObject && !strcmp(dataObject->name, "AnIn1")) { - return false; - } - } + // if (acsiClass == ACSI_CLASS_BRCB) { + // return true; + // } + + // return false; return true; } diff --git a/examples/server_example_access_control/static_model.c b/examples/server_example_access_control/static_model.c index 26f5f4fc..f38f886e 100644 --- a/examples/server_example_access_control/static_model.c +++ b/examples/server_example_access_control/static_model.c @@ -1,7 +1,7 @@ /* * static_model.c * - * automatically generated from simpleIO_direct_control.cid + * automatically generated from ../../examples/server_example_basic_io/simpleIO_direct_control.cid */ #include "static_model.h" @@ -2169,7 +2169,15 @@ ReportControlBlock iedModel_GenericIO_LLN0_report9 = {&iedModel_GenericIO_LLN0, +extern LogControlBlock iedModel_GenericIO_LLN0_lcb0; +extern LogControlBlock iedModel_GenericIO_LLN0_lcb1; +LogControlBlock iedModel_GenericIO_LLN0_lcb0 = {&iedModel_GenericIO_LLN0, "EventLog", "Events", "GenericIO/LLN0$EventLog", 3, 0, true, true, &iedModel_GenericIO_LLN0_lcb1}; +LogControlBlock iedModel_GenericIO_LLN0_lcb1 = {&iedModel_GenericIO_LLN0, "GeneralLog", NULL, NULL, 3, 0, true, true, NULL}; +extern Log iedModel_GenericIO_LLN0_log0; +extern Log iedModel_GenericIO_LLN0_log1; +Log iedModel_GenericIO_LLN0_log0 = {&iedModel_GenericIO_LLN0, "GeneralLog", &iedModel_GenericIO_LLN0_log1}; +Log iedModel_GenericIO_LLN0_log1 = {&iedModel_GenericIO_LLN0, "EventLog", NULL}; IedModel iedModel = { @@ -2180,8 +2188,8 @@ IedModel iedModel = { NULL, NULL, NULL, - NULL, - NULL, + &iedModel_GenericIO_LLN0_lcb0, + &iedModel_GenericIO_LLN0_log0, initializeValues }; diff --git a/src/iec61850/inc/iec61850_client.h b/src/iec61850/inc/iec61850_client.h index c3a174fe..1326c1e7 100644 --- a/src/iec61850/inc/iec61850_client.h +++ b/src/iec61850/inc/iec61850_client.h @@ -2467,20 +2467,6 @@ IedConnection_getServerDirectory(IedConnection self, IedClientError* error, bool LIB61850_API LinkedList /**/ IedConnection_getLogicalDeviceDirectory(IedConnection self, IedClientError* error, const char* logicalDeviceName); -typedef enum { - ACSI_CLASS_DATA_OBJECT, - ACSI_CLASS_DATA_SET, - ACSI_CLASS_BRCB, - ACSI_CLASS_URCB, - ACSI_CLASS_LCB, - ACSI_CLASS_LOG, - ACSI_CLASS_SGCB, - ACSI_CLASS_GoCB, - ACSI_CLASS_GsCB, - ACSI_CLASS_MSVCB, - ACSI_CLASS_USVCB -} ACSIClass; - /** * \brief returns a list of all MMS variables that are children of the given logical node * diff --git a/src/iec61850/inc/iec61850_common.h b/src/iec61850/inc/iec61850_common.h index 9a364656..53aa6e86 100644 --- a/src/iec61850/inc/iec61850_common.h +++ b/src/iec61850/inc/iec61850_common.h @@ -55,6 +55,21 @@ typedef struct { uint8_t dstAddress[6]; } PhyComAddress; +/** IEC 61850 ACSI classes */ +typedef enum { + ACSI_CLASS_DATA_OBJECT, + ACSI_CLASS_DATA_SET, + ACSI_CLASS_BRCB, + ACSI_CLASS_URCB, + ACSI_CLASS_LCB, + ACSI_CLASS_LOG, + ACSI_CLASS_SGCB, + ACSI_CLASS_GoCB, + ACSI_CLASS_GsCB, + ACSI_CLASS_MSVCB, + ACSI_CLASS_USVCB +} ACSIClass; + /** * \brief Control model (represented by "ctlModel" attribute) */ diff --git a/src/iec61850/inc/iec61850_server.h b/src/iec61850/inc/iec61850_server.h index 94324a00..2288b207 100644 --- a/src/iec61850/inc/iec61850_server.h +++ b/src/iec61850/inc/iec61850_server.h @@ -2010,13 +2010,21 @@ IedServer_setDirectoryAccessHandler(IedServer self, IedServer_DirectoryAccessHan /** * \brief Callback that is called when a client is invoking a list objects service * + * This callback can be used to control the list object access to specific objects and is called for each object that are subject to a client request. + * * \param parameter user provided parameter * \param connection client connection that is involved + * \param acsiClass the ACSI class of the object + * \param ld the logical device of the object + * \param ln the logical node of the object + * \param objectName the name of the object (e.g. data object name, data set name, log name, RCB name, ...) + * \param subObjectName the name of a sub element of an object or NULL + * \param fc the functional constraint of the object of IEC61850_FC_NONE when the object has no FC. * * \return true to include the object in the service response, otherwise false */ typedef bool -(*IedServer_ListObjectsAccessHandler) (void* parameter, ClientConnection connection, LogicalDevice* ld, LogicalNode* ln, DataObject* dataObject, FunctionalConstraint fc); +(*IedServer_ListObjectsAccessHandler)(void* parameter, ClientConnection connection, ACSIClass acsiClass, LogicalDevice* ld, LogicalNode* ln, const char* objectName, const char* subObjectName, FunctionalConstraint fc); /** * \brief Set a handler to control which objects are return by the list objects services diff --git a/src/iec61850/server/mms_mapping/mms_mapping.c b/src/iec61850/server/mms_mapping/mms_mapping.c index 91e12f62..9b37a81b 100644 --- a/src/iec61850/server/mms_mapping/mms_mapping.c +++ b/src/iec61850/server/mms_mapping/mms_mapping.c @@ -3315,7 +3315,7 @@ mmsConnectionHandler(void* parameter, MmsServerConnection connection, MmsServerE } static bool -mmsListObjectsAccessHandler(void* parameter, MmsDomain* domain, char* variableId, MmsServerConnection connection) +mmsListObjectsAccessHandler(void* parameter, MmsGetNameListType listType, MmsDomain* domain, char* variableId, MmsServerConnection connection) { MmsMapping* self = (MmsMapping*) parameter; @@ -3324,20 +3324,75 @@ mmsListObjectsAccessHandler(void* parameter, MmsDomain* domain, char* variableId bool allowAccess = true; - if (self->listObjectsAccessHandler) + if (listType == MMS_GETNAMELIST_DATASETS) { - char* separator = strchr(variableId, '$'); + if (self->listObjectsAccessHandler) { -#if (CONFIG_IEC61850_SETTING_GROUPS == 1) + char str[65]; - if (separator) { - if (isFunctionalConstraint("SE", separator)) { - goto exit_function; + char* ldName = MmsDomain_getName(domain); + + LogicalDevice* ld = IedModel_getDevice(self->model, ldName); + + LogicalNode* ln = NULL; + + char* objectName = variableId; + + char* separator = strchr(variableId, '$'); + + if (separator) { + StringUtils_createStringFromBufferInBuffer(str, (uint8_t*) variableId, separator - variableId); + + ln = LogicalDevice_getLogicalNode(ld, str); + + if (ln) { + objectName = separator + 1; + } } + + ClientConnection clientConnection = private_IedServer_getClientConnectionByHandle(self->iedServer, connection); + + allowAccess = self->listObjectsAccessHandler(self->listObjectsAccessHandlerParameter, clientConnection, ACSI_CLASS_DATA_SET, ld, ln, objectName, NULL, IEC61850_FC_NONE); } -#endif /* (CONFIG_IEC61850_SETTING_GROUPS == 1) */ + return allowAccess; + } + else if (listType == MMS_GETNAMELIST_JOURNALS) + { + if (self->listObjectsAccessHandler) { + char str[65]; + + char* ldName = MmsDomain_getName(domain); + + char* objectName = variableId; + LogicalDevice* ld = IedModel_getDevice(self->model, ldName); + + LogicalNode* ln = NULL; + + char* separator = strchr(variableId, '$'); + + if (separator) { + StringUtils_createStringFromBufferInBuffer(str, (uint8_t*) variableId, separator - variableId); + + ln = LogicalDevice_getLogicalNode(ld, str); + + if (ln) { + objectName = separator + 1; + } + } + + ClientConnection clientConnection = private_IedServer_getClientConnectionByHandle(self->iedServer, connection); + + allowAccess = self->listObjectsAccessHandler(self->listObjectsAccessHandlerParameter, clientConnection, ACSI_CLASS_LOG, ld, ln, objectName, NULL, IEC61850_FC_NONE); + } + + return allowAccess; + } + + if (self->listObjectsAccessHandler) + { + char* separator = strchr(variableId, '$'); char* ldName = MmsDomain_getName(domain); LogicalDevice* ld = IedModel_getDevice(self->model, ldName); @@ -3353,11 +3408,76 @@ mmsListObjectsAccessHandler(void* parameter, MmsDomain* domain, char* variableId fc == IEC61850_FC_MS || fc == IEC61850_FC_RP || fc == IEC61850_FC_LG || fc == IEC61850_FC_GO) { + char* subObjectName = NULL; + + char str[65]; + char subObjectBuf[65]; + + StringUtils_createStringFromBufferInBuffer(str, (uint8_t*) variableId, separator - variableId); + + LogicalNode* ln = LogicalDevice_getLogicalNode(ld, str); + + if (ln) { + char* doStart = strchr(separator + 1, '$'); + + if (doStart != NULL) { + + char* doEnd = strchr(doStart + 1, '$'); + + if (doEnd == NULL) { + StringUtils_copyStringToBuffer(doStart + 1, str); + } + else { + doEnd--; + + StringUtils_createStringFromBufferInBuffer(str, (uint8_t*) (doStart + 1), doEnd - doStart); + + subObjectName = StringUtils_copyStringToBuffer(doEnd + 2, subObjectBuf); + } + } + } + + ACSIClass acsiClass = ACSI_CLASS_USVCB; + + switch (fc) + { + case IEC61850_FC_BR: + acsiClass = ACSI_CLASS_BRCB; + break; + + case IEC61850_FC_RP: + acsiClass = ACSI_CLASS_URCB; + break; + + case IEC61850_FC_GO: + acsiClass = ACSI_CLASS_GoCB; + break; + + case IEC61850_FC_LG: + acsiClass = ACSI_CLASS_LCB; + break; + + case IEC61850_FC_MS: + acsiClass = ACSI_CLASS_MSVCB; + break; + + default: + break; + } + + if (self->listObjectsAccessHandler) { + ClientConnection clientConnection = private_IedServer_getClientConnectionByHandle(self->iedServer, connection); + + allowAccess = self->listObjectsAccessHandler(self->listObjectsAccessHandlerParameter, clientConnection, acsiClass, ld, ln, str, subObjectName, fc); + } + goto exit_function; } else { char str[65]; + char* subObjectName = NULL; + char subObjectBuf[65]; StringUtils_createStringFromBufferInBuffer(str, (uint8_t*) variableId, separator - variableId); @@ -3378,11 +3498,20 @@ mmsListObjectsAccessHandler(void* parameter, MmsDomain* domain, char* variableId doEnd--; StringUtils_createStringFromBufferInBuffer(str, (uint8_t*) (doStart + 1), doEnd - doStart); + + subObjectName = StringUtils_copyStringToBuffer(doEnd + 2, subObjectBuf); } if (fc == IEC61850_FC_SP) { - if (!strcmp(str, "SGCB")) + if (!strcmp(str, "SGCB")) { + + ClientConnection clientConnection = private_IedServer_getClientConnectionByHandle(self->iedServer, + connection); + + allowAccess = self->listObjectsAccessHandler(self->listObjectsAccessHandlerParameter, clientConnection, ACSI_CLASS_SGCB, ld, ln, str, subObjectName, fc); + goto exit_function; + } } ModelNode* dobj = ModelNode_getChild((ModelNode*) ln, str); @@ -3394,7 +3523,9 @@ mmsListObjectsAccessHandler(void* parameter, MmsDomain* domain, char* variableId ClientConnection clientConnection = private_IedServer_getClientConnectionByHandle(self->iedServer, connection); - allowAccess = self->listObjectsAccessHandler(self->listObjectsAccessHandlerParameter, clientConnection, ld, ln, (DataObject*) dobj, fc); + if (self->listObjectsAccessHandler) { + allowAccess = self->listObjectsAccessHandler(self->listObjectsAccessHandlerParameter, clientConnection, ACSI_CLASS_DATA_OBJECT, ld, ln, dobj->name, subObjectName, fc); + } } } } @@ -3404,7 +3535,9 @@ mmsListObjectsAccessHandler(void* parameter, MmsDomain* domain, char* variableId ClientConnection clientConnection = private_IedServer_getClientConnectionByHandle(self->iedServer, connection); - allowAccess = self->listObjectsAccessHandler(self->listObjectsAccessHandlerParameter, clientConnection, ld, ln, NULL, fc); + if (self->listObjectsAccessHandler) { + allowAccess = self->listObjectsAccessHandler(self->listObjectsAccessHandlerParameter, clientConnection, ACSI_CLASS_DATA_OBJECT, ld, ln, NULL, NULL, fc); + } } } } @@ -3417,7 +3550,9 @@ mmsListObjectsAccessHandler(void* parameter, MmsDomain* domain, char* variableId ClientConnection clientConnection = private_IedServer_getClientConnectionByHandle(self->iedServer, connection); - allowAccess = self->listObjectsAccessHandler(self->listObjectsAccessHandlerParameter, clientConnection, ld, ln, NULL, fc); + if (self->listObjectsAccessHandler) { + allowAccess = self->listObjectsAccessHandler(self->listObjectsAccessHandlerParameter, clientConnection, ACSI_CLASS_DATA_OBJECT, ld, ln, NULL, NULL, fc); + } } } } @@ -3505,8 +3640,10 @@ mmsReadAccessHandler (void* parameter, MmsDomain* domain, char* variableId, MmsS } if (fc == IEC61850_FC_SP) { - if (!strcmp(str, "SGCB")) + if (!strcmp(str, "SGCB")) { + //TODO RBAC2 add callback return DATA_ACCESS_ERROR_SUCCESS; + } } ModelNode* dobj = ModelNode_getChild((ModelNode*) ln, str); diff --git a/src/mms/inc_private/mms_server_internal.h b/src/mms/inc_private/mms_server_internal.h index 606e0827..08d0988a 100644 --- a/src/mms/inc_private/mms_server_internal.h +++ b/src/mms/inc_private/mms_server_internal.h @@ -426,7 +426,7 @@ LIB61850_INTERNAL MmsValue* mmsServer_getValue(MmsServer self, MmsDomain* domain, char* itemId, MmsServerConnection connection, bool isDirectAccess); LIB61850_INTERNAL bool -mmsServer_checkListAccess(MmsServer self, MmsDomain* domain, char* itemId, MmsServerConnection connection); +mmsServer_checkListAccess(MmsServer self, MmsGetNameListType listType, MmsDomain* domain, char* itemId, MmsServerConnection connection); LIB61850_INTERNAL void mmsServer_createMmsWriteResponse(MmsServerConnection connection, diff --git a/src/mms/inc_private/mms_server_libinternal.h b/src/mms/inc_private/mms_server_libinternal.h index da5de7a5..bdaf4b68 100644 --- a/src/mms/inc_private/mms_server_libinternal.h +++ b/src/mms/inc_private/mms_server_libinternal.h @@ -37,7 +37,7 @@ typedef MmsDataAccessError (*MmsWriteVariableHandler)(void* parameter, MmsDomain* domain, char* variableId, MmsValue* value, MmsServerConnection connection); -typedef bool (*MmsListAccessHandler) (void* parameter, MmsDomain* domain, +typedef bool (*MmsListAccessHandler) (void* parameter, MmsGetNameListType listType, MmsDomain* domain, char* variableId, MmsServerConnection connection); typedef void (*MmsConnectionHandler)(void* parameter, 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 6d6c1568..7ee8a581 100644 --- a/src/mms/iso_mms/server/mms_get_namelist_service.c +++ b/src/mms/iso_mms/server/mms_get_namelist_service.c @@ -159,7 +159,7 @@ addSubNamedVaribleNamesToList(MmsServerConnection connection, LinkedList nameLis if (variableName) { - bool accessAllowed = mmsServer_checkListAccess(connection->server, domain, variableName, connection); + bool accessAllowed = mmsServer_checkListAccess(connection->server, MMS_GETNAMELIST_DATA, domain, variableName, connection); if (accessAllowed) { @@ -218,7 +218,11 @@ getJournalListDomainSpecific(MmsServerConnection connection, char* domainName) MmsJournal journal = (MmsJournal) LinkedList_getData(journalList); - LinkedList_add(nameList, (void*) journal->name); + allowAccess = mmsServer_checkListAccess(connection->server, MMS_GETNAMELIST_JOURNALS, domain, journal->name, connection); + + if (allowAccess) { + LinkedList_add(nameList, (void*) journal->name); + } } } @@ -264,7 +268,7 @@ getNameListDomainSpecific(MmsServerConnection connection, char* domainName) for (i = 0; i < domain->namedVariablesCount; i++) { - bool accessAllowed = mmsServer_checkListAccess(connection->server, domain, variables[index[i]]->name, connection); + bool accessAllowed = mmsServer_checkListAccess(connection->server, MMS_GETNAMELIST_DATA, domain, variables[index[i]]->name, connection); if (accessAllowed) { @@ -301,7 +305,7 @@ getNameListDomainSpecific(MmsServerConnection connection, char* domainName) #if (MMS_DATA_SET_SERVICE == 1) static LinkedList -createStringsFromNamedVariableList(LinkedList variableLists) +createStringsFromNamedVariableList(LinkedList variableLists, MmsServerConnection connection, MmsDomain* domain) { LinkedList nameList = LinkedList_create(); LinkedList variableListsElement = LinkedList_getNext(variableLists); @@ -310,8 +314,14 @@ createStringsFromNamedVariableList(LinkedList variableLists) MmsNamedVariableList variableList = (MmsNamedVariableList) variableListsElement->data; - LinkedList_add(nameList, - StringUtils_copyString(MmsNamedVariableList_getName(variableList))); + printf("createStringsFromNamedVariableList: %s\n", MmsNamedVariableList_getName(variableList)); + + bool accessAllowed = mmsServer_checkListAccess(connection->server, MMS_GETNAMELIST_DATASETS, domain, variableList->name, connection); + + if (accessAllowed) { + LinkedList_add(nameList, + StringUtils_copyString(MmsNamedVariableList_getName(variableList))); + } variableListsElement = LinkedList_getNext(variableListsElement); } @@ -338,7 +348,7 @@ getNamedVariableListsDomainSpecific(MmsServerConnection connection, char* domain if (allowAccess) { LinkedList variableLists = MmsDomain_getNamedVariableLists(domain); - nameList = createStringsFromNamedVariableList(variableLists); + nameList = createStringsFromNamedVariableList(variableLists, connection, domain); } } @@ -354,7 +364,7 @@ getNamedVariableListsVMDSpecific(MmsServerConnection connection) LinkedList variableLists = MmsDevice_getNamedVariableLists(device); - nameList = createStringsFromNamedVariableList(variableLists); + nameList = createStringsFromNamedVariableList(variableLists, connection, NULL); return nameList; } @@ -367,7 +377,7 @@ getNamedVariableListAssociationSpecific(MmsServerConnection connection) LinkedList variableLists = MmsServerConnection_getNamedVariableLists(connection); - nameList = createStringsFromNamedVariableList(variableLists); + nameList = createStringsFromNamedVariableList(variableLists, connection, NULL); return nameList; } diff --git a/src/mms/iso_mms/server/mms_get_var_access_service.c b/src/mms/iso_mms/server/mms_get_var_access_service.c index 840d90b5..c27ff76b 100644 --- a/src/mms/iso_mms/server/mms_get_var_access_service.c +++ b/src/mms/iso_mms/server/mms_get_var_access_service.c @@ -245,7 +245,7 @@ createVariableAccessAttributesResponse( goto exit_function; } - bool accessAllowed = mmsServer_checkListAccess(connection->server, domain, nameId, connection); + bool accessAllowed = mmsServer_checkListAccess(connection->server, MMS_GETNAMELIST_DATA, domain, nameId, connection); if (!accessAllowed) { if (DEBUG_MMS_SERVER) diff --git a/src/mms/iso_mms/server/mms_server.c b/src/mms/iso_mms/server/mms_server.c index 3229b21e..18b95464 100644 --- a/src/mms/iso_mms/server/mms_server.c +++ b/src/mms/iso_mms/server/mms_server.c @@ -603,12 +603,12 @@ mmsServer_checkReadAccess(MmsServer self, MmsDomain* domain, char* itemId, MmsSe } bool -mmsServer_checkListAccess(MmsServer self, MmsDomain* domain, char* itemId, MmsServerConnection connection) +mmsServer_checkListAccess(MmsServer self, MmsGetNameListType listType, MmsDomain* domain, char* itemId, MmsServerConnection connection) { bool allowAccess = true; if (self->listAccessHandler) { - allowAccess = self->listAccessHandler(self->listAccessHandlerParameter, domain, itemId, connection); + allowAccess = self->listAccessHandler(self->listAccessHandlerParameter, listType, domain, itemId, connection); } return allowAccess;