- IED server: WriteAccessHandler can tell the stack not to update the

value when returning DATA_ACCESS_ERROR_SUCCESS_NO_UPDATE
pull/309/head
Michael Zillgith 5 years ago
parent 5f2e14f712
commit 74a227bdf2

@ -1591,13 +1591,17 @@ MmsGooseControlBlock_getFixedOffs(MmsGooseControlBlock self);
* One application can be to allow write access only from a specific client. Another * One application can be to allow write access only from a specific client. Another
* application could be to check if the value is in the allowed range before the write * application could be to check if the value is in the allowed range before the write
* is accepted. * is accepted.
* When the callback returns DATA_ACCESS_ERROR_SUCCESS the write access is accepted and the stack will
* update the value automatically.
* When the callback returns DATA_ACCESS_ERROR_SUCCESS_NO_UPDATE the write access is accepted but the
* stack will not update the value automatically.
* *
* \param the data attribute that has been written by an MMS client. * \param the data attribute that has been written by an MMS client.
* \param the value the client want to write to the data attribute * \param the value the client want to write to the data attribute
* \param connection the connection object of the client connection that invoked the write operation * \param connection the connection object of the client connection that invoked the write operation
* \param parameter the user provided parameter * \param parameter the user provided parameter
* *
* \return DATA_ACCESS_ERROR_SUCCESS if access is accepted, DATA_ACCESS_ERROR_OBJECT_ACCESS_DENIED if access is denied. * \return DATA_ACCESS_ERROR_SUCCESS, or DATA_ACCESS_ERROR_SUCCESS_NO_UPDATE if access is accepted, DATA_ACCESS_ERROR_OBJECT_ACCESS_DENIED if access is denied.
*/ */
typedef MmsDataAccessError typedef MmsDataAccessError
(*WriteAccessHandler) (DataAttribute* dataAttribute, MmsValue* value, ClientConnection connection, void* parameter); (*WriteAccessHandler) (DataAttribute* dataAttribute, MmsValue* value, ClientConnection connection, void* parameter);

@ -2769,16 +2769,17 @@ mmsWriteHandler(void* parameter, MmsDomain* domain,
} }
#endif /* (CONFIG_IEC61850_SETTING_GROUPS == 1) */ #endif /* (CONFIG_IEC61850_SETTING_GROUPS == 1) */
/* writable data model elements - SP, SV, CF, DC */ /* writable data model elements - SP, SV, CF, DC, BL */
if (fc != IEC61850_FC_NONE) { if (fc != IEC61850_FC_NONE) {
MmsValue* cachedValue; MmsValue* cachedValue;
cachedValue = MmsServer_getValueFromCache(self->mmsServer, domain, variableId); cachedValue = MmsServer_getValueFromCache(self->mmsServer, domain, variableId);
if (cachedValue != NULL) { if (cachedValue) {
if (!MmsValue_equalTypes(cachedValue, value)) if (!MmsValue_equalTypes(cachedValue, value)) {
return DATA_ACCESS_ERROR_OBJECT_VALUE_INVALID; return DATA_ACCESS_ERROR_OBJECT_VALUE_INVALID;
}
bool handlerFound = false; bool handlerFound = false;
@ -2800,6 +2801,8 @@ mmsWriteHandler(void* parameter, MmsDomain* domain,
} }
#endif #endif
bool updateValue = true;
/* Call write access handlers */ /* Call write access handlers */
LinkedList writeHandlerListElement = LinkedList_getNext(self->attributeAccessHandlers); LinkedList writeHandlerListElement = LinkedList_getNext(self->attributeAccessHandlers);
@ -2820,12 +2823,16 @@ mmsWriteHandler(void* parameter, MmsDomain* domain,
accessHandler->handler(dataAttribute, matchingValue, clientConnection, accessHandler->handler(dataAttribute, matchingValue, clientConnection,
accessHandler->parameter); accessHandler->parameter);
if (handlerResult == DATA_ACCESS_ERROR_SUCCESS) if ((handlerResult == DATA_ACCESS_ERROR_SUCCESS) || (handlerResult == DATA_ACCESS_ERROR_SUCCESS_NO_UPDATE)) {
handlerFound = true; handlerFound = true;
if (handlerResult == DATA_ACCESS_ERROR_SUCCESS_NO_UPDATE)
updateValue = false;
}
else else
return handlerResult; return handlerResult;
} }
} }
else { /* if ACCESS_POLICY_DENY only allow direct access to handled data attribute */ else { /* if ACCESS_POLICY_DENY only allow direct access to handled data attribute */
if (dataAttribute->mmsValue == cachedValue) { if (dataAttribute->mmsValue == cachedValue) {
@ -2837,14 +2844,17 @@ mmsWriteHandler(void* parameter, MmsDomain* domain,
accessHandler->handler(dataAttribute, value, clientConnection, accessHandler->handler(dataAttribute, value, clientConnection,
accessHandler->parameter); accessHandler->parameter);
if (handlerResult == DATA_ACCESS_ERROR_SUCCESS) { if ((handlerResult == DATA_ACCESS_ERROR_SUCCESS) || (handlerResult == DATA_ACCESS_ERROR_SUCCESS_NO_UPDATE)) {
handlerFound = true; handlerFound = true;
if (handlerResult == DATA_ACCESS_ERROR_SUCCESS_NO_UPDATE)
updateValue = false;
break; break;
} }
else else
return handlerResult; return handlerResult;
} }
} }
writeHandlerListElement = LinkedList_getNext(writeHandlerListElement); writeHandlerListElement = LinkedList_getNext(writeHandlerListElement);
@ -2858,12 +2868,14 @@ mmsWriteHandler(void* parameter, MmsDomain* domain,
} }
DataAttribute* da = IedModel_lookupDataAttributeByMmsValue(self->model, cachedValue); if (updateValue) {
DataAttribute* da = IedModel_lookupDataAttributeByMmsValue(self->model, cachedValue);
if (da != NULL) if (da)
IedServer_updateAttributeValue(self->iedServer, da, value); IedServer_updateAttributeValue(self->iedServer, da, value);
else else
return DATA_ACCESS_ERROR_OBJECT_ACCESS_DENIED; return DATA_ACCESS_ERROR_OBJECT_ACCESS_DENIED;
}
return DATA_ACCESS_ERROR_SUCCESS; return DATA_ACCESS_ERROR_SUCCESS;
} }

@ -44,6 +44,7 @@ extern "C" {
typedef enum { typedef enum {
DATA_ACCESS_ERROR_SUCCESS_NO_UPDATE = -3,
DATA_ACCESS_ERROR_NO_RESPONSE = -2, /* for server internal purposes only! */ DATA_ACCESS_ERROR_NO_RESPONSE = -2, /* for server internal purposes only! */
DATA_ACCESS_ERROR_SUCCESS = -1, DATA_ACCESS_ERROR_SUCCESS = -1,
DATA_ACCESS_ERROR_OBJECT_INVALIDATED = 0, DATA_ACCESS_ERROR_OBJECT_INVALIDATED = 0,

Loading…
Cancel
Save