- IED server: implemented write access handler for array elements and components of array elements (LIB61850-437)

- IED server: new function IedServer_handleWriteAccessForDataObject (LIB61850-437)
pull/515/head
Michael Zillgith 1 year ago
parent d1ab50298f
commit 3280712e5a

@ -429,11 +429,11 @@ getCharWeight(int c)
{ {
static bool initialized = false; static bool initialized = false;
static char lookupTable[LT_MAX_CHARS + 1]; static char lookupTable[LT_MAX_CHARS + 1];
static const char* charOrder = "AaBbCcDdEeFfGgHhIiJjKkLlMmNnOoPpQqRrSsTtUuVvWwXxYyZz$_0123456789";
if (!initialized) { if (!initialized) {
int ltIndex; int ltIndex;
int weight = 1; int weight = 1;
const char* charOrder = "AaBbCcDdEeFfGgHhIiJjKkLlMmNnOoPpQqRrSsTtUuVvWwXxYyZz$_0123456789";
for (ltIndex = 1; ltIndex < LT_MAX_CHARS; ltIndex++) { for (ltIndex = 1; ltIndex < LT_MAX_CHARS; ltIndex++) {
if (strchr(charOrder, ltIndex)) continue; if (strchr(charOrder, ltIndex)) continue;

@ -3,7 +3,7 @@
* *
* IEC 61850 server API for libiec61850. * IEC 61850 server API for libiec61850.
* *
* Copyright 2013-2023 Michael Zillgith * Copyright 2013-2024 Michael Zillgith
* *
* This file is part of libIEC61850. * This file is part of libIEC61850.
* *
@ -1845,6 +1845,19 @@ LIB61850_API void
IedServer_handleWriteAccessForComplexAttribute(IedServer self, DataAttribute* dataAttribute, IedServer_handleWriteAccessForComplexAttribute(IedServer self, DataAttribute* dataAttribute,
WriteAccessHandler handler, void* parameter); WriteAccessHandler handler, void* parameter);
/**
* \brief Install a WriteAccessHandler for all data attributes of a data object with a specific FC
*
* \param self the instance of IedServer to operate on.
* \param dataObject the data object to monitor
* \param fc the functional constraint to monitor
* \param handler the callback function that is invoked if a client tries to write to
* the monitored data attribute.
* \param parameter a user provided parameter that is passed to the WriteAccessHandler when called.
*/
LIB61850_API void
IedServer_handleWriteAccessForDataObject(IedServer self, DataObject* dataObject, FunctionalConstraint fc, WriteAccessHandler handler, void* parameter);
typedef enum { typedef enum {
ACCESS_POLICY_ALLOW, ACCESS_POLICY_ALLOW,
ACCESS_POLICY_DENY ACCESS_POLICY_DENY

@ -124,7 +124,7 @@ LIB61850_INTERNAL MmsValue*
LIBIEC61850_LOG_SVC_readAccessControlBlock(MmsMapping* self, MmsDomain* domain, char* variableIdOrig, MmsServerConnection connection); LIBIEC61850_LOG_SVC_readAccessControlBlock(MmsMapping* self, MmsDomain* domain, char* variableIdOrig, MmsServerConnection connection);
LIB61850_INTERNAL MmsDataAccessError LIB61850_INTERNAL MmsDataAccessError
LIBIEC61850_LOG_SVC_writeAccessLogControlBlock(MmsMapping* self, MmsDomain* domain, char* variableIdOrig, LIBIEC61850_LOG_SVC_writeAccessLogControlBlock(MmsMapping* self, MmsDomain* domain, const char* variableIdOrig,
MmsValue* value, MmsServerConnection connection); MmsValue* value, MmsServerConnection connection);
#endif /* LIBIEC61850_SRC_IEC61850_INC_PRIVATE_LOGGING_H_ */ #endif /* LIBIEC61850_SRC_IEC61850_INC_PRIVATE_LOGGING_H_ */

@ -149,7 +149,7 @@ LIB61850_INTERNAL void
MmsMapping_installReadAccessHandler(MmsMapping* self, ReadAccessHandler handler, void* paramter); MmsMapping_installReadAccessHandler(MmsMapping* self, ReadAccessHandler handler, void* paramter);
LIB61850_INTERNAL MmsDataAccessError LIB61850_INTERNAL MmsDataAccessError
Control_writeAccessControlObject(MmsMapping* self, MmsDomain* domain, char* variableIdOrig, Control_writeAccessControlObject(MmsMapping* self, MmsDomain* domain, const char* variableIdOrig,
MmsValue* value, MmsServerConnection connection); MmsValue* value, MmsServerConnection connection);
LIB61850_INTERNAL MmsValue* LIB61850_INTERNAL MmsValue*

@ -41,7 +41,7 @@ LIB61850_INTERNAL MmsValue*
LIBIEC61850_SV_readAccessSampledValueControlBlock(MmsMapping* self, MmsDomain* domain, char* variableIdOrig , MmsServerConnection connection); LIBIEC61850_SV_readAccessSampledValueControlBlock(MmsMapping* self, MmsDomain* domain, char* variableIdOrig , MmsServerConnection connection);
LIB61850_INTERNAL MmsDataAccessError LIB61850_INTERNAL MmsDataAccessError
LIBIEC61850_SV_writeAccessSVControlBlock(MmsMapping* self, MmsDomain* domain, char* variableIdOrig, LIBIEC61850_SV_writeAccessSVControlBlock(MmsMapping* self, MmsDomain* domain, const char* variableIdOrig,
MmsValue* value, MmsServerConnection connection); MmsValue* value, MmsServerConnection connection);
LIB61850_INTERNAL void LIB61850_INTERNAL void

@ -126,7 +126,7 @@ LIB61850_INTERNAL void
ReportControl_valueUpdated(ReportControl* self, int dataSetEntryIndex, int flag, bool modelLocked); ReportControl_valueUpdated(ReportControl* self, int dataSetEntryIndex, int flag, bool modelLocked);
LIB61850_INTERNAL MmsValue* LIB61850_INTERNAL MmsValue*
ReportControl_getRCBValue(ReportControl* rc, char* elementName); ReportControl_getRCBValue(ReportControl* rc, const char* elementName);
LIB61850_INTERNAL MmsVariableSpecification* LIB61850_INTERNAL MmsVariableSpecification*
Reporting_createMmsBufferedRCBs(MmsMapping* self, MmsDomain* domain, Reporting_createMmsBufferedRCBs(MmsMapping* self, MmsDomain* domain,
@ -137,7 +137,7 @@ Reporting_createMmsUnbufferedRCBs(MmsMapping* self, MmsDomain* domain,
LogicalNode* logicalNode, int reportsCount); LogicalNode* logicalNode, int reportsCount);
LIB61850_INTERNAL MmsDataAccessError LIB61850_INTERNAL MmsDataAccessError
Reporting_RCBWriteAccessHandler(MmsMapping* self, ReportControl* rc, char* elementName, MmsValue* value, Reporting_RCBWriteAccessHandler(MmsMapping* self, ReportControl* rc, const char* elementName, MmsValue* value,
MmsServerConnection connection); MmsServerConnection connection);
LIB61850_INTERNAL bool LIB61850_INTERNAL bool

@ -1679,6 +1679,38 @@ IedServer_handleWriteAccessForComplexAttribute(IedServer self, DataAttribute* da
} }
} }
void
IedServer_handleWriteAccessForDataObject(IedServer self, DataObject* dataObject, FunctionalConstraint fc, WriteAccessHandler handler, void* parameter)
{
if (dataObject == NULL) {
if (DEBUG_IED_SERVER)
printf("IED_SERVER: IedServer_handlerWriteAccessForDataObject - dataObject == NULL!\n");
}
else
{
ModelNode* childElement = dataObject->firstChild;
while (childElement)
{
if (childElement->modelType == DataAttributeModelType)
{
DataAttribute* dataAttribute = (DataAttribute*) childElement;
if (dataAttribute->fc == fc)
{
IedServer_handleWriteAccessForComplexAttribute(self, dataAttribute, handler, parameter);
}
}
else if (childElement->modelType == DataObjectModelType)
{
IedServer_handleWriteAccessForDataObject(self, (DataObject*) childElement, fc, handler, parameter);
}
childElement = childElement->sibling;
}
}
}
void void
IedServer_setReadAccessHandler(IedServer self, ReadAccessHandler handler, void* parameter) IedServer_setReadAccessHandler(IedServer self, ReadAccessHandler handler, void* parameter)
{ {

@ -1923,7 +1923,7 @@ checkValidityOfOriginParameter(MmsValue* origin)
} }
MmsDataAccessError MmsDataAccessError
Control_writeAccessControlObject(MmsMapping* self, MmsDomain* domain, char* variableIdOrig, Control_writeAccessControlObject(MmsMapping* self, MmsDomain* domain, const char* variableIdOrig,
MmsValue* value, MmsServerConnection connection) MmsValue* value, MmsServerConnection connection)
{ {
MmsDataAccessError indication = DATA_ACCESS_ERROR_OBJECT_ACCESS_DENIED; MmsDataAccessError indication = DATA_ACCESS_ERROR_OBJECT_ACCESS_DENIED;

@ -482,7 +482,7 @@ copyLCBValuesToTrackingObject(MmsMapping* self, LogControl* logControl)
#endif /* (CONFIG_IEC61850_SERVICE_TRACKING == 1) */ #endif /* (CONFIG_IEC61850_SERVICE_TRACKING == 1) */
MmsDataAccessError MmsDataAccessError
LIBIEC61850_LOG_SVC_writeAccessLogControlBlock(MmsMapping* self, MmsDomain* domain, char* variableIdOrig, LIBIEC61850_LOG_SVC_writeAccessLogControlBlock(MmsMapping* self, MmsDomain* domain, const char* variableIdOrig,
MmsValue* value, MmsServerConnection connection) MmsValue* value, MmsServerConnection connection)
{ {
(void)connection; (void)connection;

@ -2344,7 +2344,7 @@ lookupGCB(MmsMapping* self, MmsDomain* domain, char* lnName, char* objectName)
#endif #endif
static MmsDataAccessError static MmsDataAccessError
writeAccessGooseControlBlock(MmsMapping* self, MmsDomain* domain, char* variableIdOrig, writeAccessGooseControlBlock(MmsMapping* self, MmsDomain* domain, const char* variableIdOrig,
MmsValue* value, MmsServerConnection connection) MmsValue* value, MmsServerConnection connection)
{ {
char variableId[130]; char variableId[130];
@ -2605,12 +2605,24 @@ getAccessPolicyForFC(MmsMapping* self, FunctionalConstraint fc)
static MmsDataAccessError static MmsDataAccessError
mmsWriteHandler(void* parameter, MmsDomain* domain, mmsWriteHandler(void* parameter, MmsDomain* domain,
char* variableId, MmsValue* value, MmsServerConnection connection) const char* variableId, int arrayIdx, const char* componentId, MmsValue* value, MmsServerConnection connection)
{ {
MmsMapping* self = (MmsMapping*) parameter; MmsMapping* self = (MmsMapping*) parameter;
if (DEBUG_IED_SERVER) if (DEBUG_IED_SERVER)
{
if (arrayIdx != -1) {
if (componentId) {
printf("IED_SERVER: Write requested %s(%i).%s\n", variableId, arrayIdx, componentId);
}
else {
printf("IED_SERVER: Write requested %s(%i)\n", variableId, arrayIdx);
}
}
else {
printf("IED_SERVER: Write requested %s\n", variableId); printf("IED_SERVER: Write requested %s\n", variableId);
}
}
/* Access control based on functional constraint */ /* Access control based on functional constraint */
@ -2691,7 +2703,7 @@ mmsWriteHandler(void* parameter, MmsDomain* domain,
if (rcNameLen == variableIdLen) { if (rcNameLen == variableIdLen) {
if (strncmp(variableId, rc->name, variableIdLen) == 0) { if (strncmp(variableId, rc->name, variableIdLen) == 0) {
char* elementName = variableId + rcNameLen + 1; const char* elementName = variableId + rcNameLen + 1;
return Reporting_RCBWriteAccessHandler(self, rc, elementName, value, connection); return Reporting_RCBWriteAccessHandler(self, rc, elementName, value, connection);
} }
@ -2946,13 +2958,19 @@ 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, BL */ /* writable data model elements - SP, SV, CF, DC, BL */
if (fc != IEC61850_FC_NONE) { if (fc != IEC61850_FC_NONE)
{
MmsValue* cachedValue; MmsValue* cachedValue;
if (arrayIdx != -1) {
cachedValue = MmsServer_getValueFromCacheEx2(self->mmsServer, domain, variableId, arrayIdx, componentId);
}
else {
cachedValue = MmsServer_getValueFromCache(self->mmsServer, domain, variableId); cachedValue = MmsServer_getValueFromCache(self->mmsServer, domain, variableId);
}
if (cachedValue) { 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;
} }
@ -2965,7 +2983,8 @@ mmsWriteHandler(void* parameter, MmsDomain* domain,
printf("IED_SERVER: write to %s policy:%i\n", variableId, nodeAccessPolicy); printf("IED_SERVER: write to %s policy:%i\n", variableId, nodeAccessPolicy);
#if (CONFIG_IEC61850_SETTING_GROUPS == 1) #if (CONFIG_IEC61850_SETTING_GROUPS == 1)
if (isFunctionalConstraint("SE", separator)) { if (isFunctionalConstraint("SE", separator))
{
SettingGroup* sg = getSettingGroupByMmsDomain(self, domain); SettingGroup* sg = getSettingGroupByMmsDomain(self, domain);
if (sg != NULL) { if (sg != NULL) {
@ -2982,12 +3001,13 @@ mmsWriteHandler(void* parameter, MmsDomain* domain,
/* Call write access handlers */ /* Call write access handlers */
LinkedList writeHandlerListElement = LinkedList_getNext(self->attributeAccessHandlers); LinkedList writeHandlerListElement = LinkedList_getNext(self->attributeAccessHandlers);
while (writeHandlerListElement != NULL) { while (writeHandlerListElement)
{
AttributeAccessHandler* accessHandler = (AttributeAccessHandler*) writeHandlerListElement->data; AttributeAccessHandler* accessHandler = (AttributeAccessHandler*) writeHandlerListElement->data;
DataAttribute* dataAttribute = accessHandler->attribute; DataAttribute* dataAttribute = accessHandler->attribute;
if (dataAttribute->mmsValue == cachedValue) { if (dataAttribute->mmsValue == cachedValue)
{
ClientConnection clientConnection = private_IedServer_getClientConnectionByHandle(self->iedServer, ClientConnection clientConnection = private_IedServer_getClientConnectionByHandle(self->iedServer,
connection); connection);
@ -2995,7 +3015,8 @@ 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) || (handlerResult == DATA_ACCESS_ERROR_SUCCESS_NO_UPDATE)) { 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) if (handlerResult == DATA_ACCESS_ERROR_SUCCESS_NO_UPDATE)
@ -3011,14 +3032,14 @@ mmsWriteHandler(void* parameter, MmsDomain* domain,
} }
/* DENY access if no handler is found and default policy is DENY */ /* DENY access if no handler is found and default policy is DENY */
if (!handlerFound) { if (!handlerFound)
{
if (nodeAccessPolicy == ACCESS_POLICY_DENY) if (nodeAccessPolicy == ACCESS_POLICY_DENY)
return DATA_ACCESS_ERROR_OBJECT_ACCESS_DENIED; return DATA_ACCESS_ERROR_OBJECT_ACCESS_DENIED;
} }
if (updateValue) { if (updateValue)
{
DataAttribute* da = IedModel_lookupDataAttributeByMmsValue(self->model, cachedValue); DataAttribute* da = IedModel_lookupDataAttributeByMmsValue(self->model, cachedValue);
if (da) if (da)

@ -131,7 +131,7 @@ MmsSampledValueControlBlock_isEnabled(MmsSampledValueControlBlock self)
} }
MmsDataAccessError MmsDataAccessError
LIBIEC61850_SV_writeAccessSVControlBlock(MmsMapping* self, MmsDomain* domain, char* variableIdOrig, LIBIEC61850_SV_writeAccessSVControlBlock(MmsMapping* self, MmsDomain* domain, const char* variableIdOrig,
MmsValue* value, MmsServerConnection connection) MmsValue* value, MmsServerConnection connection)
{ {
char variableId[130]; char variableId[130];

@ -252,7 +252,7 @@ ReportControl_destroy(ReportControl* self)
} }
MmsValue* MmsValue*
ReportControl_getRCBValue(ReportControl* rc, char* elementName) ReportControl_getRCBValue(ReportControl* rc, const char* elementName)
{ {
if (rc->buffered) { if (rc->buffered) {
if (strcmp(elementName, "RptID") == 0) if (strcmp(elementName, "RptID") == 0)
@ -460,7 +460,7 @@ copyRCBValuesToTrackingObject(MmsMapping* self, ReportControl* rc)
} }
static void static void
updateSingleTrackingValue(MmsMapping* self, ReportControl* rc, char* name, MmsValue* newValue) updateSingleTrackingValue(MmsMapping* self, ReportControl* rc, const char* name, MmsValue* newValue)
{ {
if (rc->buffered) { if (rc->buffered) {
if (self->brcbTrk) { if (self->brcbTrk) {
@ -1906,7 +1906,7 @@ reserveRcb(ReportControl* rc, MmsServerConnection connection)
} }
MmsDataAccessError MmsDataAccessError
Reporting_RCBWriteAccessHandler(MmsMapping* self, ReportControl* rc, char* elementName, MmsValue* value, Reporting_RCBWriteAccessHandler(MmsMapping* self, ReportControl* rc, const char* elementName, MmsValue* value,
MmsServerConnection connection) MmsServerConnection connection)
{ {
MmsDataAccessError retVal = DATA_ACCESS_ERROR_SUCCESS; MmsDataAccessError retVal = DATA_ACCESS_ERROR_SUCCESS;

@ -399,7 +399,7 @@ mmsServer_isAccessToArrayComponent(AlternateAccess_t* alternateAccess);
LIB61850_INTERNAL MmsValue* LIB61850_INTERNAL MmsValue*
mmsServer_getComponentOfArrayElement(AlternateAccess_t* alternateAccess, MmsVariableSpecification* namedVariable, mmsServer_getComponentOfArrayElement(AlternateAccess_t* alternateAccess, MmsVariableSpecification* namedVariable,
MmsValue* structuredValue); MmsValue* structuredValue, char* componentId);
LIB61850_INTERNAL int LIB61850_INTERNAL int
mmsServer_getLowIndex(AlternateAccess_t* alternateAccess); mmsServer_getLowIndex(AlternateAccess_t* alternateAccess);
@ -417,6 +417,10 @@ LIB61850_INTERNAL MmsDataAccessError
mmsServer_setValue(MmsServer self, MmsDomain* domain, char* itemId, MmsValue* value, mmsServer_setValue(MmsServer self, MmsDomain* domain, char* itemId, MmsValue* value,
MmsServerConnection connection); MmsServerConnection connection);
LIB61850_INTERNAL MmsDataAccessError
mmsServer_setValueEx(MmsServer self, MmsDomain* domain, char* itemId, MmsValue* value,
MmsServerConnection connection, int arrayIdx, const char* componentId);
/** /**
* \brief Get the current value of a variable in the server data model * \brief Get the current value of a variable in the server data model
* *

@ -34,7 +34,7 @@ typedef MmsDataAccessError (*MmsReadAccessHandler) (void* parameter, MmsDomain*
char* variableId, MmsServerConnection connection, bool isDirectAccess); char* variableId, MmsServerConnection connection, bool isDirectAccess);
typedef MmsDataAccessError (*MmsWriteVariableHandler)(void* parameter, typedef MmsDataAccessError (*MmsWriteVariableHandler)(void* parameter,
MmsDomain* domain, char* variableId, MmsValue* value, MmsDomain* domain, const char* variableId, int arrayIdx, const char* componentId, MmsValue* value,
MmsServerConnection connection); MmsServerConnection connection);
typedef bool (*MmsListAccessHandler) (void* parameter, MmsGetNameListType listType, MmsDomain* domain, typedef bool (*MmsListAccessHandler) (void* parameter, MmsGetNameListType listType, MmsDomain* domain,

@ -202,30 +202,35 @@ alternateArrayAccess(MmsServerConnection connection,
MmsValue* arrayValue = mmsServer_getValue(connection->server, domain, itemId, connection, false); MmsValue* arrayValue = mmsServer_getValue(connection->server, domain, itemId, connection, false);
if (arrayValue != NULL) { if (arrayValue != NULL)
{
MmsValue* value = NULL; MmsValue* value = NULL;
if (numberOfElements == 0) if (numberOfElements == 0)
if (mmsServer_isAccessToArrayComponent(alternateAccess)) { {
if (mmsServer_isAccessToArrayComponent(alternateAccess))
{
if (namedVariable->typeSpec.array.elementTypeSpec->type == MMS_STRUCTURE) { if (namedVariable->typeSpec.array.elementTypeSpec->type == MMS_STRUCTURE) {
MmsValue* structValue = MmsValue_getElement(arrayValue, index); MmsValue* structValue = MmsValue_getElement(arrayValue, index);
if (structValue != NULL) if (structValue != NULL)
value = mmsServer_getComponentOfArrayElement(alternateAccess, value = mmsServer_getComponentOfArrayElement(alternateAccess,
namedVariable, structValue); namedVariable, structValue, NULL);
} }
} }
else { else {
value = MmsValue_getElement(arrayValue, index); value = MmsValue_getElement(arrayValue, index);
} }
else { }
else
{
value = MmsValue_createEmptyArray(numberOfElements); value = MmsValue_createEmptyArray(numberOfElements);
MmsValue_setDeletable(value); MmsValue_setDeletable(value);
int resultIndex = 0; int resultIndex = 0;
while (index < lowIndex + numberOfElements) { while (index < lowIndex + numberOfElements)
{
MmsValue* elementValue = NULL; MmsValue* elementValue = NULL;
elementValue = MmsValue_getElement(arrayValue, index); elementValue = MmsValue_getElement(arrayValue, index);

@ -536,9 +536,10 @@ mmsServer_setValue(MmsServer self, MmsDomain* domain, char* itemId, MmsValue* va
{ {
MmsDataAccessError indication; MmsDataAccessError indication;
if (self->writeHandler != NULL) { if (self->writeHandler)
{
indication = self->writeHandler(self->writeHandlerParameter, domain, indication = self->writeHandler(self->writeHandlerParameter, domain,
itemId, value, connection); itemId, -1, NULL, value, connection);
} }
else { else {
MmsValue* cachedValue; MmsValue* cachedValue;
@ -548,7 +549,36 @@ mmsServer_setValue(MmsServer self, MmsDomain* domain, char* itemId, MmsValue* va
cachedValue = MmsServer_getValueFromCache(self, domain, itemId); cachedValue = MmsServer_getValueFromCache(self, domain, itemId);
if (cachedValue != NULL) { if (cachedValue) {
MmsValue_update(cachedValue, value);
indication = DATA_ACCESS_ERROR_SUCCESS;
} else
indication = DATA_ACCESS_ERROR_OBJECT_VALUE_INVALID;
}
return indication;
}
MmsDataAccessError
mmsServer_setValueEx(MmsServer self, MmsDomain* domain, char* itemId, MmsValue* value,
MmsServerConnection connection, int arrayIdx, const char* componentId)
{
MmsDataAccessError indication;
if (self->writeHandler)
{
indication = self->writeHandler(self->writeHandlerParameter, domain,
itemId, arrayIdx, componentId, value, connection);
}
else {
MmsValue* cachedValue = NULL;
if (domain == NULL)
domain = (MmsDomain*) self->device;
cachedValue = MmsServer_getValueFromCacheEx2(self, domain, itemId, arrayIdx, componentId);
if (cachedValue) {
MmsValue_update(cachedValue, value); MmsValue_update(cachedValue, value);
indication = DATA_ACCESS_ERROR_SUCCESS; indication = DATA_ACCESS_ERROR_SUCCESS;
} else } else
@ -591,8 +621,6 @@ mmsServer_checkReadAccess(MmsServer self, MmsDomain* domain, char* itemId, MmsSe
{ {
MmsDataAccessError accessError = DATA_ACCESS_ERROR_SUCCESS; MmsDataAccessError accessError = DATA_ACCESS_ERROR_SUCCESS;
printf("mmsServer_checkReadAccess(%s/%s)\n", domain->domainName, itemId);
if (self->readAccessHandler) { if (self->readAccessHandler) {
accessError = accessError =
self->readAccessHandler(self->readAccessHandlerParameter, (domain == (MmsDomain*) self->device) ? NULL : domain, self->readAccessHandler(self->readAccessHandlerParameter, (domain == (MmsDomain*) self->device) ? NULL : domain,

@ -287,7 +287,7 @@ mmsServer_isAccessToArrayComponent(AlternateAccess_t* alternateAccess)
MmsValue* MmsValue*
mmsServer_getComponentOfArrayElement(AlternateAccess_t* alternateAccess, MmsVariableSpecification* namedVariable, mmsServer_getComponentOfArrayElement(AlternateAccess_t* alternateAccess, MmsVariableSpecification* namedVariable,
MmsValue* structuredValue) MmsValue* structuredValue, char* componentId)
{ {
MmsValue* retValue = NULL; MmsValue* retValue = NULL;
@ -319,16 +319,33 @@ mmsServer_getComponentOfArrayElement(AlternateAccess_t* alternateAccess, MmsVari
{ {
MmsValue* value = MmsValue_getElement(structuredValue, i); MmsValue* value = MmsValue_getElement(structuredValue, i);
if (value)
{
if (mmsServer_isAccessToArrayComponent( if (mmsServer_isAccessToArrayComponent(
alternateAccess->list.array[0]->choice.unnamed->choice.selectAlternateAccess.alternateAccess)) { alternateAccess->list.array[0]->choice.unnamed->choice.selectAlternateAccess.alternateAccess))
{
if (componentId)
{
strcat(componentId, structSpec->typeSpec.structure.elements[i]->name);
strcat(componentId, "$");
}
retValue = retValue =
mmsServer_getComponentOfArrayElement( mmsServer_getComponentOfArrayElement(
alternateAccess->list.array[0]->choice.unnamed->choice.selectAlternateAccess.alternateAccess, alternateAccess->list.array[0]->choice.unnamed->choice.selectAlternateAccess.alternateAccess,
structSpec->typeSpec.structure.elements[i], structSpec->typeSpec.structure.elements[i],
value); value, componentId);
} }
else else
{
if (componentId)
{
strcat(componentId, structSpec->typeSpec.structure.elements[i]->name);
}
retValue = value; retValue = value;
}
}
goto exit_function; goto exit_function;
} }

@ -517,33 +517,36 @@ getComponent(MmsServerConnection connection, MmsDomain* domain, AlternateAccess_
{ {
MmsVariableSpecification* retValue = NULL; MmsVariableSpecification* retValue = NULL;
if (mmsServer_isComponentAccess(alternateAccess)) { if (mmsServer_isComponentAccess(alternateAccess))
{
Identifier_t component = Identifier_t component =
alternateAccess->list.array[0]->choice.unnamed->choice.selectAccess.choice.component; alternateAccess->list.array[0]->choice.unnamed->choice.selectAccess.choice.component;
if (component.size > 129) if (component.size > 129)
goto exit_function; goto exit_function;
if (namedVariable->type == MMS_STRUCTURE) { if (namedVariable->type == MMS_STRUCTURE)
{
int i; int i;
for (i = 0; i < namedVariable->typeSpec.structure.elementCount; i++) { for (i = 0; i < namedVariable->typeSpec.structure.elementCount; i++)
{
if ((int) strlen(namedVariable->typeSpec.structure.elements[i]->name) if ((int) strlen(namedVariable->typeSpec.structure.elements[i]->name)
== component.size) { == component.size)
{
if (!strncmp(namedVariable->typeSpec.structure.elements[i]->name, if (!strncmp(namedVariable->typeSpec.structure.elements[i]->name,
(char*) component.buf, component.size)) (char*) component.buf, component.size))
{ {
if (strlen(variableName) + component.size < 199) { if (strlen(variableName) + component.size < 199)
{
StringUtils_appendString(variableName, 200, "$"); StringUtils_appendString(variableName, 200, "$");
/* here we need strncat because component.buf is not null terminated! */ /* here we need strncat because component.buf is not null terminated! */
strncat(variableName, (const char*)component.buf, (size_t)component.size); strncat(variableName, (const char*)component.buf, (size_t)component.size);
if (alternateAccess->list.array[0]->choice.unnamed->choice.selectAlternateAccess.alternateAccess if (alternateAccess->list.array[0]->choice.unnamed->choice.selectAlternateAccess.alternateAccess
!= NULL) { != NULL)
{
retValue = retValue =
getComponent(connection, domain, getComponent(connection, domain,
alternateAccess->list.array[0]->choice.unnamed->choice.selectAlternateAccess.alternateAccess, alternateAccess->list.array[0]->choice.unnamed->choice.selectAlternateAccess.alternateAccess,
@ -690,7 +693,7 @@ mmsServer_handleWriteRequest(
AlternateAccess_t* alternateAccess = varSpec->alternateAccess; AlternateAccess_t* alternateAccess = varSpec->alternateAccess;
if (alternateAccess != NULL) if (alternateAccess)
{ {
if ((variable->type == MMS_STRUCTURE) && (mmsServer_isComponentAccess(alternateAccess) == false)) { if ((variable->type == MMS_STRUCTURE) && (mmsServer_isComponentAccess(alternateAccess) == false)) {
accessResults[i] = DATA_ACCESS_ERROR_OBJECT_ATTRIBUTE_INCONSISTENT; accessResults[i] = DATA_ACCESS_ERROR_OBJECT_ATTRIBUTE_INCONSISTENT;
@ -717,7 +720,7 @@ mmsServer_handleWriteRequest(
continue; continue;
} }
if (alternateAccess != NULL) if (alternateAccess)
{ {
if (domain == NULL) if (domain == NULL)
domain = (MmsDomain*) device; domain = (MmsDomain*) device;
@ -747,18 +750,26 @@ mmsServer_handleWriteRequest(
{ {
MmsVariableSpecification* namedVariable = MmsDomain_getNamedVariable(domain, nameIdStr); MmsVariableSpecification* namedVariable = MmsDomain_getNamedVariable(domain, nameIdStr);
char componentId[65];
componentId[0] = 0;
if (namedVariable) { if (namedVariable) {
elementValue = mmsServer_getComponentOfArrayElement(alternateAccess, namedVariable, elementValue); elementValue = mmsServer_getComponentOfArrayElement(alternateAccess, namedVariable, elementValue, componentId);
} }
if ((namedVariable == NULL) || (elementValue == NULL)) { if ((namedVariable == NULL) || (elementValue == NULL)) {
accessResults[i] = DATA_ACCESS_ERROR_OBJECT_NONE_EXISTENT; accessResults[i] = DATA_ACCESS_ERROR_OBJECT_NONE_EXISTENT;
goto end_of_main_loop;
} }
else
{
accessResults[i] = mmsServer_setValueEx(connection->server, domain, nameIdStr, value, connection, index, componentId);
} }
if (MmsValue_update(elementValue, value) == false) { goto end_of_main_loop;
accessResults[i] = DATA_ACCESS_ERROR_TYPE_INCONSISTENT; }
else
{
accessResults[i] = mmsServer_setValueEx(connection->server, domain, nameIdStr, value, connection, index, NULL);
goto end_of_main_loop; goto end_of_main_loop;
} }
} }
@ -816,16 +827,13 @@ mmsServer_handleWriteRequest(
goto end_of_main_loop; goto end_of_main_loop;
} }
MmsDataAccessError valueIndication = accessResults[i] = mmsServer_setValue(connection->server, domain, nameIdStr, value, connection);
mmsServer_setValue(connection->server, domain, nameIdStr, value, connection);
if (valueIndication == DATA_ACCESS_ERROR_NO_RESPONSE)
sendResponse = false;
accessResults[i] = valueIndication;
end_of_main_loop: end_of_main_loop:
if (accessResults[i] == DATA_ACCESS_ERROR_NO_RESPONSE)
sendResponse = false;
MmsValue_delete(value); MmsValue_delete(value);
} }

Loading…
Cancel
Save