- MMS server: added callback for variable list creation/deletion

pull/6/head
Michael Zillgith 11 years ago
parent 751dc5f7c2
commit e461a0fb46

@ -32,9 +32,10 @@
extern "C" { extern "C" {
#endif #endif
#include "stack_config.h"
#include "mms_device_model.h" #include "mms_device_model.h"
#include "mms_value.h" #include "mms_value.h"
#include "iso_server.h" #include "iso_server.h"
typedef enum { typedef enum {
@ -67,9 +68,11 @@ typedef struct sMmsServerConnection {
int maxPduSize; /* local detail */ int maxPduSize; /* local detail */
IsoConnection isoConnection; IsoConnection isoConnection;
MmsServer server; MmsServer server;
LinkedList /*<MmsNamedVariableList>*/namedVariableLists; /* aa-specific named variable lists */
uint32_t lastInvokeId; uint32_t lastInvokeId;
#if (MMS_DYNAMIC_DATA_SETS == 1)
LinkedList /*<MmsNamedVariableList>*/namedVariableLists; /* aa-specific named variable lists */
#endif
#if (MMS_FILE_SERVICE == 1) #if (MMS_FILE_SERVICE == 1)
int32_t nextFrsmId; int32_t nextFrsmId;
@ -78,6 +81,12 @@ typedef struct sMmsServerConnection {
} MmsServerConnection; } MmsServerConnection;
typedef enum {
MMS_DOMAIN_SPECIFIC,
MMS_ASSOCIATION_SPECIFIC,
MMS_VMD_SPECIFIC
} MmsVariableListType;
typedef MmsValue* (*MmsReadVariableHandler)(void* parameter, MmsDomain* domain, typedef MmsValue* (*MmsReadVariableHandler)(void* parameter, MmsDomain* domain,
char* variableId, MmsServerConnection* connection); char* variableId, MmsServerConnection* connection);
@ -127,6 +136,32 @@ MmsServer_getValueFromCache(MmsServer self, MmsDomain* domain, char* itemId);
bool bool
MmsServer_isLocked(MmsServer self); MmsServer_isLocked(MmsServer self);
/**
* \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 true if operation has to be accepted, false if operation has to be rejected. In case of false an error message
* is returned to the client.
*/
typedef bool (*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)
*
* \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
*/
void
MmsServer_installVariableListChangedHandler(MmsServer self, MmsNamedVariableListChangedHandler handler, void* parameter);
/** /**
* \brief lock the cached server data model * \brief lock the cached server data model
* *

@ -74,6 +74,9 @@ struct sMmsServer {
MmsConnectionHandler connectionHandler; MmsConnectionHandler connectionHandler;
void* connectionHandlerParameter; void* connectionHandlerParameter;
MmsNamedVariableListChangedHandler variableListChangedHandler;
void* variableListChangedHandlerParameter;
Map openConnections; Map openConnections;
Map valueCaches; Map valueCaches;
bool isLocked; bool isLocked;
@ -82,14 +85,14 @@ struct sMmsServer {
Semaphore modelMutex; Semaphore modelMutex;
#endif #endif
#if MMS_STATUS_SERVICE == 1 #if (MMS_STATUS_SERVICE == 1)
int vmdLogicalStatus; int vmdLogicalStatus;
int vmdPhysicalStatus; int vmdPhysicalStatus;
MmsStatusRequestListener statusRequestListener; MmsStatusRequestListener statusRequestListener;
void* statusRequestListenerParameter; void* statusRequestListenerParameter;
#endif /* MMS_STATUS_SERVICE == 1 */ #endif /* MMS_STATUS_SERVICE == 1 */
#if MMS_IDENTIFY_SERVICE == 1 #if (MMS_IDENTIFY_SERVICE == 1)
char* vendorName; char* vendorName;
char* modelName; char* modelName;
char* revision; char* revision;
@ -245,4 +248,8 @@ mmsServer_createMmsWriteResponse(MmsServerConnection* connection,
void void
mmsServer_writeMmsRejectPdu(uint32_t* invokeId, int reason, ByteBuffer* response); mmsServer_writeMmsRejectPdu(uint32_t* invokeId, int reason, ByteBuffer* response);
bool
mmsServer_callVariableListChangedHandler(bool create, MmsVariableListType listType, MmsDomain* domain,
char* listName, MmsServerConnection* connection);
#endif /* MMS_SERVER_INTERNAL_H_ */ #endif /* MMS_SERVER_INTERNAL_H_ */

@ -1,7 +1,7 @@
/* /*
* mms_named_variable_list_service.c * mms_named_variable_list_service.c
* *
* Copyright 2013, 2014 Michael Zillgith * Copyright 2013-2015 Michael Zillgith
* *
* This file is part of libIEC61850. * This file is part of libIEC61850.
* *
@ -47,6 +47,19 @@
#define CONFIG_MMS_MAX_NUMBER_OF_DATA_SET_MEMBERS 50 #define CONFIG_MMS_MAX_NUMBER_OF_DATA_SET_MEMBERS 50
#endif #endif
bool
mmsServer_callVariableListChangedHandler(bool create, MmsVariableListType listType, MmsDomain* domain,
char* listName, MmsServerConnection* connection)
{
MmsServer self = connection->server;
if (self->variableListChangedHandler != NULL)
return self->variableListChangedHandler(self->variableListChangedHandlerParameter,
create, listType, domain, listName, connection);
else
return true;
}
static void static void
createDeleteNamedVariableListResponse(uint32_t invokeId, ByteBuffer* response, createDeleteNamedVariableListResponse(uint32_t invokeId, ByteBuffer* response,
uint32_t numberMatched, uint32_t numberDeleted) uint32_t numberMatched, uint32_t numberDeleted)
@ -117,41 +130,46 @@ mmsServer_handleDeleteNamedVariableListRequest(MmsServerConnection* connection,
for (i = 0; i < numberItems; i++) { for (i = 0; i < numberItems; i++) {
if (request->listOfVariableListName->list.array[i]->present == ObjectName_PR_domainspecific) { if (request->listOfVariableListName->list.array[i]->present == ObjectName_PR_domainspecific) {
char domainIdStr[65]; char domainName[65];
char nameIdStr[65]; char listName[65];
mmsMsg_copyAsn1IdentifierToStringBuffer(request->listOfVariableListName->list.array[i]->choice.domainspecific.domainId, mmsMsg_copyAsn1IdentifierToStringBuffer(request->listOfVariableListName->list.array[i]->choice.domainspecific.domainId,
domainIdStr, 65); domainName, 65);
mmsMsg_copyAsn1IdentifierToStringBuffer(request->listOfVariableListName->list.array[i]->choice.domainspecific.itemId, mmsMsg_copyAsn1IdentifierToStringBuffer(request->listOfVariableListName->list.array[i]->choice.domainspecific.itemId,
nameIdStr, 65); listName, 65);
MmsDomain* domain = MmsDevice_getDomain(device, domainIdStr); MmsDomain* domain = MmsDevice_getDomain(device, domainName);
MmsNamedVariableList variableList = MmsDomain_getNamedVariableList(domain, nameIdStr); MmsNamedVariableList variableList = MmsDomain_getNamedVariableList(domain, listName);
if (variableList != NULL) { if (variableList != NULL) {
numberMatched++; numberMatched++;
if (MmsNamedVariableList_isDeletable(variableList)) { if (MmsNamedVariableList_isDeletable(variableList)) {
MmsDomain_deleteNamedVariableList(domain, nameIdStr);
if (mmsServer_callVariableListChangedHandler(false, MMS_DOMAIN_SPECIFIC, domain, listName, connection) == true) {
MmsDomain_deleteNamedVariableList(domain, listName);
numberDeleted++; numberDeleted++;
} }
} }
} }
}
else if (request->listOfVariableListName->list.array[i]->present == ObjectName_PR_aaspecific) { else if (request->listOfVariableListName->list.array[i]->present == ObjectName_PR_aaspecific) {
char itemId[65]; char listName[65];
mmsMsg_copyAsn1IdentifierToStringBuffer(request->listOfVariableListName->list.array[i]->choice.aaspecific, mmsMsg_copyAsn1IdentifierToStringBuffer(request->listOfVariableListName->list.array[i]->choice.aaspecific,
itemId, 65); listName, 65);
MmsNamedVariableList variableList = MmsServerConnection_getNamedVariableList(connection, itemId); MmsNamedVariableList variableList = MmsServerConnection_getNamedVariableList(connection, listName);
if (variableList != NULL) { if (variableList != NULL) {
numberMatched++; numberMatched++;
numberDeleted++;
MmsServerConnection_deleteNamedVariableList(connection, itemId); if (mmsServer_callVariableListChangedHandler(false, MMS_ASSOCIATION_SPECIFIC, NULL, listName, connection) == true) {
numberDeleted++;
MmsServerConnection_deleteNamedVariableList(connection, listName);
}
} }
} }
} }
@ -398,9 +416,16 @@ mmsServer_handleDefineNamedVariableListRequest(
request, variableListName, &mmsError); request, variableListName, &mmsError);
if (namedVariableList != NULL) { if (namedVariableList != NULL) {
if (mmsServer_callVariableListChangedHandler(true, MMS_DOMAIN_SPECIFIC, domain, variableListName, connection) == true) {
MmsDomain_addNamedVariableList(domain, namedVariableList); MmsDomain_addNamedVariableList(domain, namedVariableList);
createDefineNamedVariableListResponse(invokeId, response); createDefineNamedVariableListResponse(invokeId, response);
} }
else {
MmsNamedVariableList_destroy(namedVariableList);
mmsServer_createConfirmedErrorPdu(invokeId, response, MMS_ERROR_ACCESS_OBJECT_ACCESS_DENIED);
}
}
else else
mmsServer_createConfirmedErrorPdu(invokeId, response, mmsError); mmsServer_createConfirmedErrorPdu(invokeId, response, mmsError);
} }
@ -435,9 +460,17 @@ mmsServer_handleDefineNamedVariableListRequest(
request, variableListName, &mmsError); request, variableListName, &mmsError);
if (namedVariableList != NULL) { if (namedVariableList != NULL) {
if (mmsServer_callVariableListChangedHandler(true, MMS_ASSOCIATION_SPECIFIC, NULL, variableListName, connection) == true) {
MmsServerConnection_addNamedVariableList(connection, namedVariableList); MmsServerConnection_addNamedVariableList(connection, namedVariableList);
createDefineNamedVariableListResponse(invokeId, response); createDefineNamedVariableListResponse(invokeId, response);
} }
else {
MmsNamedVariableList_destroy(namedVariableList);
mmsServer_createConfirmedErrorPdu(invokeId, response, MMS_ERROR_ACCESS_OBJECT_ACCESS_DENIED);
}
}
else else
mmsServer_createConfirmedErrorPdu(invokeId, response, mmsError); mmsServer_createConfirmedErrorPdu(invokeId, response, mmsError);
} }

@ -112,6 +112,13 @@ MmsServer_installConnectionHandler(MmsServer self, MmsConnectionHandler connecti
self->connectionHandlerParameter = parameter; self->connectionHandlerParameter = parameter;
} }
void
MmsServer_installVariableListChangedHandler(MmsServer self, MmsNamedVariableListChangedHandler handler, void* parameter)
{
self->variableListChangedHandler = handler;
self->variableListChangedHandlerParameter = parameter;
}
void void
MmsServer_setClientAuthenticator(MmsServer self, AcseAuthenticator authenticator, void* authenticatorParameter) MmsServer_setClientAuthenticator(MmsServer self, AcseAuthenticator authenticator, void* authenticatorParameter)
{ {

Loading…
Cancel
Save