- IED server: Implemented read/write access control to RCBs (LIB61850-391)

v1.6_develop_387
Michael Zillgith 3 years ago
parent acfbe16452
commit 76dbcb4496

@ -75,6 +75,17 @@ connectionHandler (IedServer self, ClientConnection connection, bool connected,
printf("Connection closed\n");
}
/*
* This handler is called before the rcbEventHandler and can be use to allow or permit read or write access to the RCB
*/
bool
rcbAccessHandler(void* parameter, ReportControlBlock* rcb, ClientConnection connection, IedServer_RCBEventType operation)
{
printf("RCB: %s access: %s\n", ReportControlBlock_getName(rcb), operation == RCB_EVENT_GET_PARAMETER ? "READ" : "WRITE");
return false;
}
static void
rcbEventHandler(void* parameter, ReportControlBlock* rcb, ClientConnection connection, IedServer_RCBEventType event, const char* parameterName, MmsDataAccessError serviceError)
{
@ -167,6 +178,8 @@ main(int argc, char** argv)
IedServer_setConnectionIndicationHandler(iedServer, (IedConnectionIndicationHandler) connectionHandler, NULL);
IedServer_setRCBAccessHandler(iedServer, rcbAccessHandler, NULL);
IedServer_setRCBEventHandler(iedServer, rcbEventHandler, NULL);
/* By default access to variables with FC=DC and FC=CF is not allowed.

@ -1622,6 +1622,30 @@ typedef void (*IedServer_RCBEventHandler) (void* parameter, ReportControlBlock*
LIB61850_API void
IedServer_setRCBEventHandler(IedServer self, IedServer_RCBEventHandler handler, void* parameter);
/**
* \brief Callback that is called in case of RCB access to give the user the opportunity to block or allow the operation
*
* \note This callback is called before the IedServer_RCBEventHandler and only in case of operations (RCB_EVENT_GET_PARAMETER, RCB_EVENT_SET_PARAMETER, RCB_EVENT_ENABLE
*
* \param parameter user provided parameter
* \param rcb affected report control block
* \param connection client connection that is involved
* \param operation one of the following operation event types: RCB_EVENT_GET_PARAMETER, RCB_EVENT_SET_PARAMETER
*/
typedef bool
(*IedServer_RCBAccessHandler) (void* parameter, ReportControlBlock* rcb, ClientConnection connection, IedServer_RCBEventType operation);
/**
* \brief Set a handler to control read and write access to report control blocks (RCBs)
*
* \param self the instance of IedServer to operate on.
* \param handler the event handler to be used
* \param parameter a user provided parameter that is passed to the handler.
*/
LIB61850_API void
IedServer_setRCBAccessHandler(IedServer self, IedServer_RCBAccessHandler handler, void* parameter);
/**@}*/
/**

@ -335,6 +335,9 @@ struct sMmsMapping {
IedServer_RCBEventHandler rcbEventHandler;
void* rcbEventHandlerParameter;
IedServer_RCBAccessHandler rcbAccessHandler;
void* rcbAccessHandlerParameter;
IedServer_DataSetAccessHandler dataSetAccessHandler;
void* dataSetAccessHandlerParameter;
};

@ -140,7 +140,7 @@ LIB61850_INTERNAL MmsDataAccessError
Reporting_RCBWriteAccessHandler(MmsMapping* self, ReportControl* rc, char* elementName, MmsValue* value,
MmsServerConnection connection);
LIB61850_INTERNAL void
LIB61850_INTERNAL bool
ReportControl_readAccess(ReportControl* rc, MmsMapping* mmsMapping, MmsServerConnection connection, char* elementName);
LIB61850_INTERNAL void

@ -689,6 +689,13 @@ IedServer_setRCBEventHandler(IedServer self, IedServer_RCBEventHandler handler,
self->mmsMapping->rcbEventHandlerParameter = parameter;
}
void
IedServer_setRCBAccessHandler(IedServer self, IedServer_RCBAccessHandler handler, void* parameter)
{
self->mmsMapping->rcbAccessHandler = handler;
self->mmsMapping->rcbAccessHandlerParameter = parameter;
}
void
IedServer_destroy(IedServer self)
{

@ -1697,21 +1697,35 @@ checkReservationTimeout(MmsMapping* self, ReportControl* rc)
}
}
void
bool
ReportControl_readAccess(ReportControl* rc, MmsMapping* mmsMapping, MmsServerConnection connection, char* elementName)
{
(void)elementName;
bool accessAllowed = true;
MmsDataAccessError accessError = DATA_ACCESS_ERROR_SUCCESS;
/* check reservation timeout */
if (rc->buffered) {
checkReservationTimeout(mmsMapping, rc);
}
if (mmsMapping->rcbEventHandler) {
ClientConnection clientConnection = private_IedServer_getClientConnectionByHandle(mmsMapping->iedServer, connection);
ClientConnection clientConnection = NULL;
if (mmsMapping->rcbAccessHandler || mmsMapping->rcbEventHandler) {
clientConnection = private_IedServer_getClientConnectionByHandle(mmsMapping->iedServer, connection);
}
if (mmsMapping->rcbAccessHandler) {
if (mmsMapping->rcbAccessHandler(mmsMapping->rcbAccessHandlerParameter, rc->rcb, clientConnection, RCB_EVENT_GET_PARAMETER) == false) {
accessError = DATA_ACCESS_ERROR_OBJECT_ACCESS_DENIED;
accessAllowed = false;
}
}
mmsMapping->rcbEventHandler(mmsMapping->rcbEventHandlerParameter, rc->rcb, clientConnection, RCB_EVENT_GET_PARAMETER, elementName, DATA_ACCESS_ERROR_SUCCESS);
if (mmsMapping->rcbEventHandler) {
mmsMapping->rcbEventHandler(mmsMapping->rcbEventHandlerParameter, rc->rcb, clientConnection, RCB_EVENT_GET_PARAMETER, elementName, accessError);
}
return accessAllowed;
}
static bool
@ -1809,6 +1823,15 @@ Reporting_RCBWriteAccessHandler(MmsMapping* self, ReportControl* rc, char* eleme
ClientConnection clientConnection = private_IedServer_getClientConnectionByHandle(self->iedServer, connection);
/* check if write access to RCB is allowed on this connection */
if (self->rcbAccessHandler) {
if (self->rcbAccessHandler(self->rcbAccessHandlerParameter, rc->rcb, clientConnection, RCB_EVENT_SET_PARAMETER) == false) {
retVal = DATA_ACCESS_ERROR_OBJECT_ACCESS_DENIED;
goto exit_function_only_tracking;
}
}
/* check reservation timeout for buffered RCBs */
if (rc->buffered) {
@ -2491,6 +2514,8 @@ exit_function:
ReportControl_unlockNotify(rc);
exit_function_only_tracking:
#if (CONFIG_IEC61850_SERVICE_TRACKING == 1)
if (rc->buffered)
updateGenericTrackingObjectValues(self, rc, IEC61850_SERVICE_TYPE_SET_BRCB_VALUES, retVal);

Loading…
Cancel
Save