- 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
* application could be to check if the value is in the allowed range before the write
* 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 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 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
(*WriteAccessHandler) (DataAttribute* dataAttribute, MmsValue* value, ClientConnection connection, void* parameter);

@ -2769,16 +2769,17 @@ mmsWriteHandler(void* parameter, MmsDomain* domain,
}
#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) {
MmsValue* cachedValue;
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;
}
bool handlerFound = false;
@ -2800,6 +2801,8 @@ mmsWriteHandler(void* parameter, MmsDomain* domain,
}
#endif
bool updateValue = true;
/* Call write access handlers */
LinkedList writeHandlerListElement = LinkedList_getNext(self->attributeAccessHandlers);
@ -2820,12 +2823,16 @@ mmsWriteHandler(void* parameter, MmsDomain* domain,
accessHandler->handler(dataAttribute, matchingValue, clientConnection,
accessHandler->parameter);
if (handlerResult == DATA_ACCESS_ERROR_SUCCESS)
if ((handlerResult == DATA_ACCESS_ERROR_SUCCESS) || (handlerResult == DATA_ACCESS_ERROR_SUCCESS_NO_UPDATE)) {
handlerFound = true;
if (handlerResult == DATA_ACCESS_ERROR_SUCCESS_NO_UPDATE)
updateValue = false;
}
else
return handlerResult;
}
}
else { /* if ACCESS_POLICY_DENY only allow direct access to handled data attribute */
if (dataAttribute->mmsValue == cachedValue) {
@ -2837,14 +2844,17 @@ mmsWriteHandler(void* parameter, MmsDomain* domain,
accessHandler->handler(dataAttribute, value, clientConnection,
accessHandler->parameter);
if (handlerResult == DATA_ACCESS_ERROR_SUCCESS) {
if ((handlerResult == DATA_ACCESS_ERROR_SUCCESS) || (handlerResult == DATA_ACCESS_ERROR_SUCCESS_NO_UPDATE)) {
handlerFound = true;
if (handlerResult == DATA_ACCESS_ERROR_SUCCESS_NO_UPDATE)
updateValue = false;
break;
}
else
return handlerResult;
}
}
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)
IedServer_updateAttributeValue(self->iedServer, da, value);
else
return DATA_ACCESS_ERROR_OBJECT_ACCESS_DENIED;
if (da)
IedServer_updateAttributeValue(self->iedServer, da, value);
else
return DATA_ACCESS_ERROR_OBJECT_ACCESS_DENIED;
}
return DATA_ACCESS_ERROR_SUCCESS;
}

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

Loading…
Cancel
Save