- IEC 61850 server: control models - allow delaying select response with check handler (new handler return value CONTROL_WAITING_FOR_SELECT)

pull/215/head
Michael Zillgith 6 years ago
parent abcf93416f
commit d86055173d

@ -1,3 +1,7 @@
Changes to version 1.5.0
------------------------
- IEC 61850 server: control models - allow delaying select response with check handler (new handler return value CONTROL_WAITING_FOR_SELECT)
Changes to version 1.4.1
------------------------
- MMS server: refactored connection handling; more efficient use of HandleSet

@ -1146,6 +1146,7 @@ IedServer_setEditSettingGroupConfirmationHandler(IedServer self, SettingGroupCon
*/
typedef enum {
CONTROL_ACCEPTED = -1, /** check passed */
CONTROL_WAITING_FOR_SELECT = 0, /** select operation in progress - handler will be called again later */
CONTROL_HARDWARE_FAULT = 1, /** check failed due to hardware fault */
CONTROL_TEMPORARILY_UNAVAILABLE = 2, /** control is already selected or operated */
CONTROL_OBJECT_ACCESS_DENIED = 3, /** check failed due to access control reason - access denied for this client or state */

@ -1,7 +1,7 @@
/*
* control.c
*
* Copyright 2013-2019 Michael Zillgith
* Copyright 2013-2020 Michael Zillgith
*
* This file is part of libIEC61850.
*
@ -45,6 +45,7 @@
#define STATE_PERFORM_TEST 3
#define STATE_WAIT_FOR_EXECUTION 4
#define STATE_OPERATE 5
#define STATE_WAIT_FOR_SELECT 6
#define PENDING_EVENT_SELECTED 1
#define PENDING_EVENT_UNSELECTED 2
@ -55,6 +56,8 @@
static MmsValue emptyString = {MMS_STRUCTURE};
static MmsValue delayedResponse = {MMS_DATA_ACCESS_ERROR, 0, {DATA_ACCESS_ERROR_NO_RESPONSE}};
void
ControlObject_sendLastApplError(ControlObject* self, MmsServerConnection connection, char* ctlVariable, int error,
ControlAddCause addCause, MmsValue* ctlNum, MmsValue* origin, bool handlerMode);
@ -65,10 +68,6 @@ ControlObject_sendCommandTerminationPositive(ControlObject* self);
void
ControlObject_sendCommandTerminationNegative(ControlObject* self);
MmsValue*
Control_readAccessControlObject(MmsMapping* self, MmsDomain* domain, char* variableIdOrig,
MmsServerConnection connection);
static void
unselectObject(ControlObject* self);
@ -123,6 +122,65 @@ setStSeld(ControlObject* self, bool value)
}
}
static void
updateSboTimeoutValue(ControlObject* self)
{
if (self->sboTimeout != NULL) {
uint32_t sboTimeoutVal = MmsValue_toInt32(self->sboTimeout);
if (DEBUG_IED_SERVER)
printf("IED_SERVER: set timeout for %s/%s.%s to %u\n", MmsDomain_getName(self->mmsDomain), self->lnName, self->name, sboTimeoutVal);
self->selectTimeout = sboTimeoutVal;
}
else
self->selectTimeout = CONFIG_CONTROL_DEFAULT_SBO_TIMEOUT;
}
static void
selectObject(ControlObject* self, uint64_t selectTime, MmsServerConnection connection)
{
if (DEBUG_IED_SERVER)
printf("IED_SERVER: control %s/%s.%s selected\n", MmsDomain_getName(self->mmsDomain), self->lnName, self->name);
updateSboTimeoutValue(self);
self->selectTime = selectTime;
self->mmsConnection = connection;
setStSeld(self, true);
setState(self, STATE_READY);
}
static void
unselectObject(ControlObject* self)
{
setState(self, STATE_UNSELECTED);
setStSeld(self, false);
if (DEBUG_IED_SERVER)
printf("IED_SERVER: control %s/%s.%s unselected\n", MmsDomain_getName(self->mmsDomain), self->lnName, self->name);
}
static void
checkSelectTimeout(ControlObject* self, uint64_t currentTime)
{
if ((self->ctlModel == 2) || (self->ctlModel == 4)) {
if (getState(self) == STATE_READY) {
if (self->selectTimeout > 0) {
if (currentTime > (self->selectTime + self->selectTimeout)) {
if (DEBUG_IED_SERVER)
printf("IED_SERVER: select-timeout (timeout-val = %i) for control %s/%s.%s\n",
self->selectTimeout, MmsDomain_getName(self->mmsDomain), self->lnName, self->name);
unselectObject(self);
}
}
}
}
}
static void
setOpRcvd(ControlObject* self, bool value)
{
@ -159,7 +217,6 @@ setOpOk(ControlObject* self, bool value, uint64_t currentTimeInMs)
/* TODO update time quality */
}
self->pendingEvents |= PENDING_EVENT_OP_OK_TRUE;
}
else
@ -171,21 +228,6 @@ setOpOk(ControlObject* self, bool value, uint64_t currentTimeInMs)
}
}
static void
updateSboTimeoutValue(ControlObject* self)
{
if (self->sboTimeout != NULL) {
uint32_t sboTimeoutVal = MmsValue_toInt32(self->sboTimeout);
if (DEBUG_IED_SERVER)
printf("IED_SERVER: set timeout for %s/%s.%s to %u\n", MmsDomain_getName(self->mmsDomain), self->lnName, self->name, sboTimeoutVal);
self->selectTimeout = sboTimeoutVal;
}
else
self->selectTimeout = CONFIG_CONTROL_DEFAULT_SBO_TIMEOUT;
}
static bool
isSboClassOperateOnce(ControlObject* self)
{
@ -280,6 +322,74 @@ executeStateMachine:
switch (state) {
case STATE_WAIT_FOR_SELECT:
{
self->isSelect = 1;
CheckHandlerResult checkHandlerResult = self->checkHandler((ControlAction) self, self->checkHandlerParameter, NULL, false, false);
self->isSelect = 0;
if (checkHandlerResult != CONTROL_WAITING_FOR_SELECT) {
if (self->ctlModel == 2) {
LinkedList values = LinkedList_create();
if (checkHandlerResult == CONTROL_ACCEPTED) {
LinkedList_add(values, self->sbo);
selectObject(self, Hal_getTimeInMs(), self->mmsConnection);
}
else {
LinkedList_add(values, &emptyString);
setState(self, STATE_UNSELECTED);
}
MmsServerConnection_sendReadResponse(self->mmsConnection, self->operateInvokeId, values, false);
LinkedList_destroyStatic(values);
}
else if (self->ctlModel == 4) {
if (checkHandlerResult == CONTROL_ACCEPTED) {
selectObject(self, Hal_getTimeInMs(), self->mmsConnection);
if (self->ctlNumSt)
MmsValue_update(self->ctlNumSt, self->ctlNum);
if (self->originSt)
MmsValue_update(self->originSt, self->origin);
MmsServerConnection_sendWriteResponse(self->mmsConnection, self->operateInvokeId, DATA_ACCESS_ERROR_SUCCESS, false);
if (DEBUG_IED_SERVER)
printf("IED_SERVER: SBOw - selected successful\n");
}
else {
setState(self, STATE_UNSELECTED);
ControlObject_sendLastApplError(self, self->mmsConnection, "SBOw", 0,
ADD_CAUSE_SELECT_FAILED, self->ctlNum, self->origin, false);
MmsServerConnection_sendWriteResponse(self->mmsConnection, self->operateInvokeId, (MmsDataAccessError) checkHandlerResult, false);
if (DEBUG_IED_SERVER)
printf("IED_SERVER: SBOw - select rejected by application!\n");
}
}
else {
/* ERROR: invalid internal state! */
setState(self, STATE_WAIT_FOR_SELECT);
}
}
}
break;
case STATE_WAIT_FOR_ACTIVATION_TIME:
case STATE_WAIT_FOR_EXECUTION:
{
@ -681,50 +791,6 @@ ControlObject_getMmsValue(ControlObject* self)
return self->mmsValue;
}
static void
selectObject(ControlObject* self, uint64_t selectTime, MmsServerConnection connection)
{
if (DEBUG_IED_SERVER)
printf("IED_SERVER: control %s/%s.%s selected\n", MmsDomain_getName(self->mmsDomain), self->lnName, self->name);
updateSboTimeoutValue(self);
self->selectTime = selectTime;
self->mmsConnection = connection;
setStSeld(self, true);
setState(self, STATE_READY);
}
static void
unselectObject(ControlObject* self)
{
setState(self, STATE_UNSELECTED);
setStSeld(self, false);
if (DEBUG_IED_SERVER)
printf("IED_SERVER: control %s/%s.%s unselected\n", MmsDomain_getName(self->mmsDomain), self->lnName, self->name);
}
static void
checkSelectTimeout(ControlObject* self, uint64_t currentTime)
{
if ((self->ctlModel == 2) || (self->ctlModel == 4)) {
if (getState(self) == STATE_READY) {
if (self->selectTimeout > 0) {
if (currentTime > (self->selectTime + self->selectTimeout)) {
if (DEBUG_IED_SERVER)
printf("IED_SERVER: select-timeout (timeout-val = %i) for control %s/%s.%s\n",
self->selectTimeout, MmsDomain_getName(self->mmsDomain), self->lnName, self->name);
unselectObject(self);
}
}
}
}
}
bool
ControlObject_unselect(ControlObject* self, MmsServerConnection connection)
{
@ -1181,7 +1247,7 @@ doesElementEquals(char* element, char* name)
MmsValue*
Control_readAccessControlObject(MmsMapping* self, MmsDomain* domain, char* variableIdOrig,
MmsServerConnection connection)
MmsServerConnection connection, bool isDirectAccess)
{
MmsValue* value = NULL;
@ -1259,28 +1325,36 @@ Control_readAccessControlObject(MmsMapping* self, MmsDomain* domain, char* varia
value = &emptyString;
checkSelectTimeout(controlObject, currentTime);
if (isDirectAccess == true) {
checkSelectTimeout(controlObject, currentTime);
if (getState(controlObject) == STATE_UNSELECTED) {
CheckHandlerResult checkResult = CONTROL_ACCEPTED;
if (getState(controlObject) == STATE_UNSELECTED) {
CheckHandlerResult checkResult = CONTROL_ACCEPTED;
/* opRcvd must not be set here! */
/* opRcvd must not be set here! */
controlObject->addCauseValue = ADD_CAUSE_UNKNOWN;
controlObject->addCauseValue = ADD_CAUSE_UNKNOWN;
if (controlObject->checkHandler != NULL) { /* perform operative tests */
if (controlObject->checkHandler != NULL) { /* perform operative tests */
controlObject->isSelect = 1;
controlObject->isSelect = 1;
checkResult = controlObject->checkHandler((ControlAction) controlObject,
controlObject->checkHandlerParameter, NULL, false, false);
checkResult = controlObject->checkHandler((ControlAction) controlObject,
controlObject->checkHandlerParameter, NULL, false, false);
controlObject->isSelect = 0;
}
controlObject->isSelect = 0;
}
if (checkResult == CONTROL_ACCEPTED) {
selectObject(controlObject, currentTime, connection);
value = controlObject->sbo;
if (checkResult == CONTROL_ACCEPTED) {
selectObject(controlObject, currentTime, connection);
value = controlObject->sbo;
}
else if (checkResult == CONTROL_WAITING_FOR_SELECT) {
controlObject->mmsConnection = connection;
controlObject->operateInvokeId = MmsServerConnection_getLastInvokeId(connection);
setState(controlObject, STATE_WAIT_FOR_SELECT);
value = &delayedResponse;
}
}
}
@ -1398,11 +1472,9 @@ Control_writeAccessControlObject(MmsMapping* self, MmsDomain* domain, char* vari
varName = NULL;
}
if (DEBUG_IED_SERVER)
printf("IED_SERVER: write access control: objectName: (%s) varName: (%s)\n", objectName, varName);
if (varName == NULL) {
indication = DATA_ACCESS_ERROR_OBJECT_ACCESS_DENIED;
goto free_and_return;
@ -1489,6 +1561,18 @@ Control_writeAccessControlObject(MmsMapping* self, MmsDomain* domain, char* vari
if (DEBUG_IED_SERVER)
printf("IED_SERVER: SBOw - selected successful\n");
}
else if (checkResult == CONTROL_WAITING_FOR_SELECT) {
controlObject->mmsConnection = connection;
controlObject->operateInvokeId = MmsServerConnection_getLastInvokeId(connection);
MmsValue_update(controlObject->ctlVal, ctlVal);
MmsValue_update(controlObject->ctlNum, ctlNum);
MmsValue_update(controlObject->origin, origin);
setState(controlObject, STATE_WAIT_FOR_SELECT);
indication = DATA_ACCESS_ERROR_NO_RESPONSE;
}
else {
indication = (MmsDataAccessError) checkResult;

@ -71,7 +71,7 @@ typedef struct
#if (CONFIG_IEC61850_CONTROL_SERVICE == 1)
MmsValue*
Control_readAccessControlObject(MmsMapping* self, MmsDomain* domain, char* variableIdOrig,
MmsServerConnection connection);
MmsServerConnection connection, bool isDirectAccess);
#endif
void /* Create PHYCOMADDR ACSI type instance */
@ -2248,7 +2248,7 @@ readAccessGooseControlBlock(MmsMapping* self, MmsDomain* domain, char* variableI
static MmsValue*
mmsReadHandler(void* parameter, MmsDomain* domain, char* variableId, MmsServerConnection connection)
mmsReadHandler(void* parameter, MmsDomain* domain, char* variableId, MmsServerConnection connection, bool isDirectAccess)
{
MmsMapping* self = (MmsMapping*) parameter;
@ -2267,7 +2267,7 @@ mmsReadHandler(void* parameter, MmsDomain* domain, char* variableId, MmsServerCo
#if (CONFIG_IEC61850_CONTROL_SERVICE == 1)
/* Controllable objects - CO */
if (isControllable(separator)) {
retValue = Control_readAccessControlObject(self, domain, variableId, connection);
retValue = Control_readAccessControlObject(self, domain, variableId, connection, isDirectAccess);
goto exit_function;
}
#endif
@ -2362,7 +2362,6 @@ mmsReadHandler(void* parameter, MmsDomain* domain, char* variableId, MmsServerCo
/* handle read access to other objects */
exit_function:
return retValue;
}
@ -2436,7 +2435,7 @@ mmsConnectionHandler(void* parameter, MmsServerConnection connection, MmsServerE
}
static MmsDataAccessError
mmsReadAccessHandler (void* parameter, MmsDomain* domain, char* variableId, MmsServerConnection connection)
mmsReadAccessHandler (void* parameter, MmsDomain* domain, char* variableId, MmsServerConnection connection, bool isDirectAccess)
{
MmsMapping* self = (MmsMapping*) parameter;

@ -99,6 +99,9 @@ LIB61850_INTERNAL void
MmsServerConnection_sendWriteResponse(MmsServerConnection self, uint32_t invokeId, MmsDataAccessError indication,
bool handlerMode);
LIB61850_INTERNAL void
MmsServerConnection_sendReadResponse(MmsServerConnection self, uint32_t invokeId, LinkedList values,
bool handlerMode);
LIB61850_INTERNAL uint32_t
MmsServerConnection_getLastInvokeId(MmsServerConnection self);

@ -391,8 +391,13 @@ LIB61850_INTERNAL MmsDataAccessError
mmsServer_setValue(MmsServer self, MmsDomain* domain, char* itemId, MmsValue* value,
MmsServerConnection connection);
/**
* \brief Get the current value of a variable in the server data model
*
* \param isDirectAccess the access is result of a direct single read access to the variable and no part of broader read request
*/
LIB61850_INTERNAL MmsValue*
mmsServer_getValue(MmsServer self, MmsDomain* domain, char* itemId, MmsServerConnection connection);
mmsServer_getValue(MmsServer self, MmsDomain* domain, char* itemId, MmsServerConnection connection, bool isDirectAccess);
LIB61850_INTERNAL void
mmsServer_createMmsWriteResponse(MmsServerConnection connection,

@ -28,10 +28,10 @@
#include "mms_device_model.h"
typedef MmsValue* (*MmsReadVariableHandler)(void* parameter, MmsDomain* domain,
char* variableId, MmsServerConnection connection);
char* variableId, MmsServerConnection connection, bool isDirectAccess);
typedef MmsDataAccessError (*MmsReadAccessHandler) (void* parameter, MmsDomain* domain,
char* variableId, MmsServerConnection connection);
char* variableId, MmsServerConnection connection, bool isDirectAccess);
typedef MmsDataAccessError (*MmsWriteVariableHandler)(void* parameter,
MmsDomain* domain, char* variableId, MmsValue* value,

@ -51,7 +51,7 @@ addNamedVariableValue(MmsVariableSpecification* namedVariable, MmsServerConnecti
if (namedVariable->type == MMS_STRUCTURE) {
value = mmsServer_getValue(connection->server, domain, itemId, connection);
value = mmsServer_getValue(connection->server, domain, itemId, connection, false);
if (value != NULL)
goto exit_function;
@ -86,7 +86,7 @@ addNamedVariableValue(MmsVariableSpecification* namedVariable, MmsServerConnecti
}
}
else {
value = mmsServer_getValue(connection->server, domain, itemId, connection);
value = mmsServer_getValue(connection->server, domain, itemId, connection, false);
}
exit_function:
@ -183,7 +183,6 @@ getComponent(MmsServerConnection connection, MmsDomain* domain, AlternateAccess_
strcat(variableName, "$");
strncat(variableName, (const char*) component.buf, component.size);
if (alternateAccess->list.array[0]->choice.unnamed->choice.selectAlternateAccess.alternateAccess
!= NULL) {
retValue =
@ -193,7 +192,7 @@ getComponent(MmsServerConnection connection, MmsDomain* domain, AlternateAccess_
variableName);
}
else {
retValue = mmsServer_getValue(connection->server, domain, variableName, connection);
retValue = mmsServer_getValue(connection->server, domain, variableName, connection, false);
}
}
}
@ -275,7 +274,7 @@ alternateArrayAccess(MmsServerConnection connection,
int index = lowIndex;
MmsValue* arrayValue = mmsServer_getValue(connection->server, domain, itemId, connection);
MmsValue* arrayValue = mmsServer_getValue(connection->server, domain, itemId, connection, false);
if (arrayValue != NULL) {
@ -335,7 +334,7 @@ alternateArrayAccess(MmsServerConnection connection,
static void
addNamedVariableToResultList(MmsVariableSpecification* namedVariable, MmsDomain* domain, char* nameIdStr,
LinkedList /*<MmsValue>*/ values, MmsServerConnection connection, AlternateAccess_t* alternateAccess)
LinkedList /*<MmsValue>*/ values, MmsServerConnection connection, AlternateAccess_t* alternateAccess, bool isAccessToSingleVariable)
{
if (namedVariable != NULL) {
@ -345,7 +344,7 @@ addNamedVariableToResultList(MmsVariableSpecification* namedVariable, MmsDomain*
if (namedVariable->type == MMS_STRUCTURE) {
MmsValue* value = mmsServer_getValue(connection->server, domain, nameIdStr, connection);
MmsValue* value = mmsServer_getValue(connection->server, domain, nameIdStr, connection, isAccessToSingleVariable);
if (alternateAccess != NULL) {
@ -379,7 +378,7 @@ addNamedVariableToResultList(MmsVariableSpecification* namedVariable, MmsDomain*
nameIdStr, values, namedVariable);
}
else { /* return complete array */
MmsValue* value = mmsServer_getValue(connection->server, domain, nameIdStr, connection);
MmsValue* value = mmsServer_getValue(connection->server, domain, nameIdStr, connection, isAccessToSingleVariable);
appendValueToResultList(value, values);
}
}
@ -389,7 +388,7 @@ addNamedVariableToResultList(MmsVariableSpecification* namedVariable, MmsDomain*
appendErrorToResultList(values, DATA_ACCESS_ERROR_OBJECT_NONE_EXISTENT);
}
else {
MmsValue* value = mmsServer_getValue(connection->server, domain, nameIdStr, connection);
MmsValue* value = mmsServer_getValue(connection->server, domain, nameIdStr, connection, isAccessToSingleVariable);
if (value == NULL) {
if (DEBUG_MMS_SERVER)
@ -641,7 +640,7 @@ handleReadListOfVariablesRequest(
appendErrorToResultList(values, DATA_ACCESS_ERROR_OBJECT_NONE_EXISTENT);
else
addNamedVariableToResultList(namedVariable, domain, nameIdStr,
values, connection, alternateAccess);
values, connection, alternateAccess, variableCount == 1);
}
}
#if (CONFIG_MMS_SUPPORT_VMD_SCOPE_NAMED_VARIABLES == 1)
@ -678,7 +677,28 @@ handleReadListOfVariablesRequest(
}
}
encodeReadResponse(connection, invokeId, response, values, NULL);
bool sendResponse = true;
LinkedList valueElement = LinkedList_getNext(values);
while (valueElement) {
MmsValue* value = (MmsValue*) LinkedList_getData(valueElement);
if (value) {
if (MmsValue_getType(value) == MMS_DATA_ACCESS_ERROR) {
if (MmsValue_getDataAccessError(value) == DATA_ACCESS_ERROR_NO_RESPONSE) {
sendResponse = false;
break;
}
}
}
valueElement = LinkedList_getNext(valueElement);
}
if (sendResponse)
encodeReadResponse(connection, invokeId, response, values, NULL);
exit:
@ -689,7 +709,7 @@ exit:
static void
createNamedVariableListResponse(MmsServerConnection connection, MmsNamedVariableList namedList,
int invokeId, ByteBuffer* response, ReadRequest_t* read, VarAccessSpec* accessSpec)
int invokeId, ByteBuffer* response, bool isSpecWithResult, VarAccessSpec* accessSpec)
{
LinkedList /*<MmsValue>*/ values = LinkedList_create();
@ -712,12 +732,12 @@ createNamedVariableListResponse(MmsServerConnection connection, MmsNamedVariable
variableName);
addNamedVariableToResultList(namedVariable, variableDomain, variableName,
values, connection, NULL);
values, connection, NULL, false);
variable = LinkedList_getNext(variable);
}
if (isSpecWithResult(read)) /* add specification to result */
if (isSpecWithResult) /* add specification to result */
encodeReadResponse(connection, invokeId, response, values, accessSpec);
else
encodeReadResponse(connection, invokeId, response, values, NULL);
@ -769,7 +789,7 @@ handleReadNamedVariableListRequest(
MmsNamedVariableList namedList = MmsDomain_getNamedVariableList(domain, nameIdStr);
if (namedList != NULL) {
createNamedVariableListResponse(connection, namedList, invokeId, response, read,
createNamedVariableListResponse(connection, namedList, invokeId, response, isSpecWithResult(read),
&accessSpec);
}
else {
@ -798,7 +818,7 @@ handleReadNamedVariableListRequest(
accessSpec.domainId = NULL;
accessSpec.itemId = listName;
createNamedVariableListResponse(connection, namedList, invokeId, response, read, &accessSpec);
createNamedVariableListResponse(connection, namedList, invokeId, response, isSpecWithResult(read), &accessSpec);
}
}
#if (MMS_DYNAMIC_DATA_SETS == 1)
@ -822,7 +842,7 @@ handleReadNamedVariableListRequest(
accessSpec.domainId = NULL;
accessSpec.itemId = listName;
createNamedVariableListResponse(connection, namedList, invokeId, response, read, &accessSpec);
createNamedVariableListResponse(connection, namedList, invokeId, response, isSpecWithResult(read), &accessSpec);
}
}
#endif /* (MMS_DYNAMIC_DATA_SETS == 1) */
@ -868,3 +888,23 @@ exit_function:
asn_DEF_MmsPdu.free_struct(&asn_DEF_MmsPdu, mmsPdu, 0);
}
void
MmsServerConnection_sendReadResponse(MmsServerConnection self, uint32_t invokeId, LinkedList values, bool handlerMode)
{
if (handlerMode == false)
IsoConnection_lock(self->isoConnection);
ByteBuffer* response = MmsServer_reserveTransmitBuffer(self->server);
ByteBuffer_setSize(response, 0);
encodeReadResponse(self, invokeId, response, values, NULL);
IsoConnection_sendMessage(self->isoConnection, response);
MmsServer_releaseTransmitBuffer(self->server);
if (handlerMode == false)
IsoConnection_unlock(self->isoConnection);
}

@ -367,14 +367,14 @@ mmsServer_setValue(MmsServer self, MmsDomain* domain, char* itemId, MmsValue* va
MmsValue*
mmsServer_getValue(MmsServer self, MmsDomain* domain, char* itemId, MmsServerConnection connection)
mmsServer_getValue(MmsServer self, MmsDomain* domain, char* itemId, MmsServerConnection connection, bool isDirectAccess)
{
MmsValue* value = NULL;
if (self->readAccessHandler != NULL) {
MmsDataAccessError accessError =
self->readAccessHandler(self->readAccessHandlerParameter, (domain == (MmsDomain*) self->device) ? NULL : domain,
itemId, connection);
itemId, connection, isDirectAccess);
if (accessError != DATA_ACCESS_ERROR_SUCCESS) {
value = MmsValue_newDataAccessError(accessError);
@ -388,7 +388,7 @@ mmsServer_getValue(MmsServer self, MmsDomain* domain, char* itemId, MmsServerCon
if (value == NULL)
if (self->readHandler != NULL)
value = self->readHandler(self->readHandlerParameter, (domain == (MmsDomain*) self->device) ? NULL : domain,
itemId, connection);
itemId, connection, isDirectAccess);
exit_function:
return value;

@ -359,7 +359,7 @@ createWriteNamedVariableListResponse(
MmsDomain* variableDomain = MmsNamedVariableListEntry_getDomain(variableListEntry);
char* variableName = MmsNamedVariableListEntry_getVariableName(variableListEntry);
MmsValue* oldValue = mmsServer_getValue(connection->server, variableDomain, variableName, connection);
MmsValue* oldValue = mmsServer_getValue(connection->server, variableDomain, variableName, connection, false);
Data_t* dataElement = writeRequest->listOfData.list.array[i];

Loading…
Cancel
Save