From 3280712e5ac6fe1145a35fa69bf82ca1f9e5a883 Mon Sep 17 00:00:00 2001 From: Michael Zillgith Date: Wed, 27 Mar 2024 18:55:07 +0000 Subject: [PATCH] - IED server: implemented write access handler for array elements and components of array elements (LIB61850-437) - IED server: new function IedServer_handleWriteAccessForDataObject (LIB61850-437) --- src/common/string_utilities.c | 14 ++--- src/iec61850/inc/iec61850_server.h | 15 ++++- src/iec61850/inc_private/logging.h | 2 +- src/iec61850/inc_private/mms_mapping.h | 2 +- src/iec61850/inc_private/mms_sv.h | 2 +- src/iec61850/inc_private/reporting.h | 4 +- src/iec61850/server/impl/ied_server.c | 32 +++++++++++ src/iec61850/server/mms_mapping/control.c | 2 +- src/iec61850/server/mms_mapping/logging.c | 2 +- src/iec61850/server/mms_mapping/mms_mapping.c | 55 +++++++++++++------ src/iec61850/server/mms_mapping/mms_sv.c | 2 +- src/iec61850/server/mms_mapping/reporting.c | 6 +- src/mms/inc_private/mms_server_internal.h | 6 +- src/mms/inc_private/mms_server_libinternal.h | 2 +- src/mms/iso_mms/server/mms_read_service.c | 17 ++++-- src/mms/iso_mms/server/mms_server.c | 38 +++++++++++-- src/mms/iso_mms/server/mms_server_common.c | 37 +++++++++---- src/mms/iso_mms/server/mms_write_service.c | 54 ++++++++++-------- 18 files changed, 210 insertions(+), 82 deletions(-) diff --git a/src/common/string_utilities.c b/src/common/string_utilities.c index 2f659e6f..1608f964 100644 --- a/src/common/string_utilities.c +++ b/src/common/string_utilities.c @@ -90,14 +90,14 @@ StringUtils_copyStringToBufferAndReplace(const char* str, char* buffer, char old char* StringUtils_createStringFromBuffer(const uint8_t* buf, int size) { - char* newStr = (char*) GLOBAL_MALLOC(size + 1); + char* newStr = (char*) GLOBAL_MALLOC(size + 1); - if (newStr) { - memcpy(newStr, buf, size); - newStr[size] = 0; - } + if (newStr) { + memcpy(newStr, buf, size); + newStr[size] = 0; + } - return newStr; + return newStr; } char* @@ -429,11 +429,11 @@ getCharWeight(int c) { static bool initialized = false; static char lookupTable[LT_MAX_CHARS + 1]; + static const char* charOrder = "AaBbCcDdEeFfGgHhIiJjKkLlMmNnOoPpQqRrSsTtUuVvWwXxYyZz$_0123456789"; if (!initialized) { int ltIndex; int weight = 1; - const char* charOrder = "AaBbCcDdEeFfGgHhIiJjKkLlMmNnOoPpQqRrSsTtUuVvWwXxYyZz$_0123456789"; for (ltIndex = 1; ltIndex < LT_MAX_CHARS; ltIndex++) { if (strchr(charOrder, ltIndex)) continue; diff --git a/src/iec61850/inc/iec61850_server.h b/src/iec61850/inc/iec61850_server.h index b14bb6cb..e059175f 100644 --- a/src/iec61850/inc/iec61850_server.h +++ b/src/iec61850/inc/iec61850_server.h @@ -3,7 +3,7 @@ * * IEC 61850 server API for libiec61850. * - * Copyright 2013-2023 Michael Zillgith + * Copyright 2013-2024 Michael Zillgith * * This file is part of libIEC61850. * @@ -1845,6 +1845,19 @@ LIB61850_API void IedServer_handleWriteAccessForComplexAttribute(IedServer self, DataAttribute* dataAttribute, 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 { ACCESS_POLICY_ALLOW, ACCESS_POLICY_DENY diff --git a/src/iec61850/inc_private/logging.h b/src/iec61850/inc_private/logging.h index 82ef712b..79c3f246 100644 --- a/src/iec61850/inc_private/logging.h +++ b/src/iec61850/inc_private/logging.h @@ -124,7 +124,7 @@ LIB61850_INTERNAL MmsValue* LIBIEC61850_LOG_SVC_readAccessControlBlock(MmsMapping* self, MmsDomain* domain, char* variableIdOrig, MmsServerConnection connection); 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); #endif /* LIBIEC61850_SRC_IEC61850_INC_PRIVATE_LOGGING_H_ */ diff --git a/src/iec61850/inc_private/mms_mapping.h b/src/iec61850/inc_private/mms_mapping.h index 63ec5742..340a2d81 100644 --- a/src/iec61850/inc_private/mms_mapping.h +++ b/src/iec61850/inc_private/mms_mapping.h @@ -149,7 +149,7 @@ LIB61850_INTERNAL void MmsMapping_installReadAccessHandler(MmsMapping* self, ReadAccessHandler handler, void* paramter); LIB61850_INTERNAL MmsDataAccessError -Control_writeAccessControlObject(MmsMapping* self, MmsDomain* domain, char* variableIdOrig, +Control_writeAccessControlObject(MmsMapping* self, MmsDomain* domain, const char* variableIdOrig, MmsValue* value, MmsServerConnection connection); LIB61850_INTERNAL MmsValue* diff --git a/src/iec61850/inc_private/mms_sv.h b/src/iec61850/inc_private/mms_sv.h index 6f8663bf..a0bb0ded 100644 --- a/src/iec61850/inc_private/mms_sv.h +++ b/src/iec61850/inc_private/mms_sv.h @@ -41,7 +41,7 @@ LIB61850_INTERNAL MmsValue* LIBIEC61850_SV_readAccessSampledValueControlBlock(MmsMapping* self, MmsDomain* domain, char* variableIdOrig , MmsServerConnection connection); 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); LIB61850_INTERNAL void diff --git a/src/iec61850/inc_private/reporting.h b/src/iec61850/inc_private/reporting.h index 558343c2..eddeb2d1 100644 --- a/src/iec61850/inc_private/reporting.h +++ b/src/iec61850/inc_private/reporting.h @@ -126,7 +126,7 @@ LIB61850_INTERNAL void ReportControl_valueUpdated(ReportControl* self, int dataSetEntryIndex, int flag, bool modelLocked); LIB61850_INTERNAL MmsValue* -ReportControl_getRCBValue(ReportControl* rc, char* elementName); +ReportControl_getRCBValue(ReportControl* rc, const char* elementName); LIB61850_INTERNAL MmsVariableSpecification* Reporting_createMmsBufferedRCBs(MmsMapping* self, MmsDomain* domain, @@ -137,7 +137,7 @@ Reporting_createMmsUnbufferedRCBs(MmsMapping* self, MmsDomain* domain, LogicalNode* logicalNode, int reportsCount); 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); LIB61850_INTERNAL bool diff --git a/src/iec61850/server/impl/ied_server.c b/src/iec61850/server/impl/ied_server.c index 8a5c4baa..8c83ddc0 100644 --- a/src/iec61850/server/impl/ied_server.c +++ b/src/iec61850/server/impl/ied_server.c @@ -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 IedServer_setReadAccessHandler(IedServer self, ReadAccessHandler handler, void* parameter) { diff --git a/src/iec61850/server/mms_mapping/control.c b/src/iec61850/server/mms_mapping/control.c index 6fd42d01..6643bb91 100644 --- a/src/iec61850/server/mms_mapping/control.c +++ b/src/iec61850/server/mms_mapping/control.c @@ -1923,7 +1923,7 @@ checkValidityOfOriginParameter(MmsValue* origin) } MmsDataAccessError -Control_writeAccessControlObject(MmsMapping* self, MmsDomain* domain, char* variableIdOrig, +Control_writeAccessControlObject(MmsMapping* self, MmsDomain* domain, const char* variableIdOrig, MmsValue* value, MmsServerConnection connection) { MmsDataAccessError indication = DATA_ACCESS_ERROR_OBJECT_ACCESS_DENIED; diff --git a/src/iec61850/server/mms_mapping/logging.c b/src/iec61850/server/mms_mapping/logging.c index 7fcb78f1..59b0ba40 100644 --- a/src/iec61850/server/mms_mapping/logging.c +++ b/src/iec61850/server/mms_mapping/logging.c @@ -482,7 +482,7 @@ copyLCBValuesToTrackingObject(MmsMapping* self, LogControl* logControl) #endif /* (CONFIG_IEC61850_SERVICE_TRACKING == 1) */ 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) { (void)connection; diff --git a/src/iec61850/server/mms_mapping/mms_mapping.c b/src/iec61850/server/mms_mapping/mms_mapping.c index 4cc38d39..3371e502 100644 --- a/src/iec61850/server/mms_mapping/mms_mapping.c +++ b/src/iec61850/server/mms_mapping/mms_mapping.c @@ -2344,7 +2344,7 @@ lookupGCB(MmsMapping* self, MmsDomain* domain, char* lnName, char* objectName) #endif static MmsDataAccessError -writeAccessGooseControlBlock(MmsMapping* self, MmsDomain* domain, char* variableIdOrig, +writeAccessGooseControlBlock(MmsMapping* self, MmsDomain* domain, const char* variableIdOrig, MmsValue* value, MmsServerConnection connection) { char variableId[130]; @@ -2605,12 +2605,24 @@ getAccessPolicyForFC(MmsMapping* self, FunctionalConstraint fc) static MmsDataAccessError 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; if (DEBUG_IED_SERVER) - printf("IED_SERVER: Write requested %s\n", variableId); + { + 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); + } + } /* Access control based on functional constraint */ @@ -2691,7 +2703,7 @@ mmsWriteHandler(void* parameter, MmsDomain* domain, if (rcNameLen == variableIdLen) { 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); } @@ -2946,13 +2958,19 @@ mmsWriteHandler(void* parameter, MmsDomain* domain, #endif /* (CONFIG_IEC61850_SETTING_GROUPS == 1) */ /* writable data model elements - SP, SV, CF, DC, BL */ - if (fc != IEC61850_FC_NONE) { + if (fc != IEC61850_FC_NONE) + { MmsValue* cachedValue; - cachedValue = MmsServer_getValueFromCache(self->mmsServer, domain, variableId); - - if (cachedValue) { + if (arrayIdx != -1) { + cachedValue = MmsServer_getValueFromCacheEx2(self->mmsServer, domain, variableId, arrayIdx, componentId); + } + else { + cachedValue = MmsServer_getValueFromCache(self->mmsServer, domain, variableId); + } + if (cachedValue) + { if (!MmsValue_equalTypes(cachedValue, value)) { 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); #if (CONFIG_IEC61850_SETTING_GROUPS == 1) - if (isFunctionalConstraint("SE", separator)) { + if (isFunctionalConstraint("SE", separator)) + { SettingGroup* sg = getSettingGroupByMmsDomain(self, domain); if (sg != NULL) { @@ -2982,12 +3001,13 @@ mmsWriteHandler(void* parameter, MmsDomain* domain, /* Call write access handlers */ LinkedList writeHandlerListElement = LinkedList_getNext(self->attributeAccessHandlers); - while (writeHandlerListElement != NULL) { + while (writeHandlerListElement) + { AttributeAccessHandler* accessHandler = (AttributeAccessHandler*) writeHandlerListElement->data; DataAttribute* dataAttribute = accessHandler->attribute; - if (dataAttribute->mmsValue == cachedValue) { - + if (dataAttribute->mmsValue == cachedValue) + { ClientConnection clientConnection = private_IedServer_getClientConnectionByHandle(self->iedServer, connection); @@ -2995,7 +3015,8 @@ mmsWriteHandler(void* parameter, MmsDomain* domain, accessHandler->handler(dataAttribute, value, clientConnection, 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; 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 */ - if (!handlerFound) { - + if (!handlerFound) + { if (nodeAccessPolicy == ACCESS_POLICY_DENY) return DATA_ACCESS_ERROR_OBJECT_ACCESS_DENIED; - } - if (updateValue) { + if (updateValue) + { DataAttribute* da = IedModel_lookupDataAttributeByMmsValue(self->model, cachedValue); if (da) diff --git a/src/iec61850/server/mms_mapping/mms_sv.c b/src/iec61850/server/mms_mapping/mms_sv.c index ef2ad775..3fbd0d2b 100644 --- a/src/iec61850/server/mms_mapping/mms_sv.c +++ b/src/iec61850/server/mms_mapping/mms_sv.c @@ -131,7 +131,7 @@ MmsSampledValueControlBlock_isEnabled(MmsSampledValueControlBlock self) } MmsDataAccessError -LIBIEC61850_SV_writeAccessSVControlBlock(MmsMapping* self, MmsDomain* domain, char* variableIdOrig, +LIBIEC61850_SV_writeAccessSVControlBlock(MmsMapping* self, MmsDomain* domain, const char* variableIdOrig, MmsValue* value, MmsServerConnection connection) { char variableId[130]; diff --git a/src/iec61850/server/mms_mapping/reporting.c b/src/iec61850/server/mms_mapping/reporting.c index 493d5e48..33143eb1 100644 --- a/src/iec61850/server/mms_mapping/reporting.c +++ b/src/iec61850/server/mms_mapping/reporting.c @@ -252,7 +252,7 @@ ReportControl_destroy(ReportControl* self) } MmsValue* -ReportControl_getRCBValue(ReportControl* rc, char* elementName) +ReportControl_getRCBValue(ReportControl* rc, const char* elementName) { if (rc->buffered) { if (strcmp(elementName, "RptID") == 0) @@ -460,7 +460,7 @@ copyRCBValuesToTrackingObject(MmsMapping* self, ReportControl* rc) } 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 (self->brcbTrk) { @@ -1906,7 +1906,7 @@ reserveRcb(ReportControl* rc, MmsServerConnection connection) } MmsDataAccessError -Reporting_RCBWriteAccessHandler(MmsMapping* self, ReportControl* rc, char* elementName, MmsValue* value, +Reporting_RCBWriteAccessHandler(MmsMapping* self, ReportControl* rc, const char* elementName, MmsValue* value, MmsServerConnection connection) { MmsDataAccessError retVal = DATA_ACCESS_ERROR_SUCCESS; diff --git a/src/mms/inc_private/mms_server_internal.h b/src/mms/inc_private/mms_server_internal.h index 08d0988a..3fae4f26 100644 --- a/src/mms/inc_private/mms_server_internal.h +++ b/src/mms/inc_private/mms_server_internal.h @@ -399,7 +399,7 @@ mmsServer_isAccessToArrayComponent(AlternateAccess_t* alternateAccess); LIB61850_INTERNAL MmsValue* mmsServer_getComponentOfArrayElement(AlternateAccess_t* alternateAccess, MmsVariableSpecification* namedVariable, - MmsValue* structuredValue); + MmsValue* structuredValue, char* componentId); LIB61850_INTERNAL int mmsServer_getLowIndex(AlternateAccess_t* alternateAccess); @@ -417,6 +417,10 @@ LIB61850_INTERNAL MmsDataAccessError mmsServer_setValue(MmsServer self, MmsDomain* domain, char* itemId, MmsValue* value, 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 * diff --git a/src/mms/inc_private/mms_server_libinternal.h b/src/mms/inc_private/mms_server_libinternal.h index bdaf4b68..f7daa70c 100644 --- a/src/mms/inc_private/mms_server_libinternal.h +++ b/src/mms/inc_private/mms_server_libinternal.h @@ -34,7 +34,7 @@ typedef MmsDataAccessError (*MmsReadAccessHandler) (void* parameter, MmsDomain* char* variableId, MmsServerConnection connection, bool isDirectAccess); 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); typedef bool (*MmsListAccessHandler) (void* parameter, MmsGetNameListType listType, MmsDomain* domain, diff --git a/src/mms/iso_mms/server/mms_read_service.c b/src/mms/iso_mms/server/mms_read_service.c index 21b40c1c..043e03ce 100644 --- a/src/mms/iso_mms/server/mms_read_service.c +++ b/src/mms/iso_mms/server/mms_read_service.c @@ -202,30 +202,35 @@ alternateArrayAccess(MmsServerConnection connection, MmsValue* arrayValue = mmsServer_getValue(connection->server, domain, itemId, connection, false); - if (arrayValue != NULL) { - + if (arrayValue != NULL) + { MmsValue* value = NULL; if (numberOfElements == 0) - if (mmsServer_isAccessToArrayComponent(alternateAccess)) { + { + if (mmsServer_isAccessToArrayComponent(alternateAccess)) + { if (namedVariable->typeSpec.array.elementTypeSpec->type == MMS_STRUCTURE) { MmsValue* structValue = MmsValue_getElement(arrayValue, index); if (structValue != NULL) value = mmsServer_getComponentOfArrayElement(alternateAccess, - namedVariable, structValue); + namedVariable, structValue, NULL); } } else { value = MmsValue_getElement(arrayValue, index); } - else { + } + else + { value = MmsValue_createEmptyArray(numberOfElements); MmsValue_setDeletable(value); int resultIndex = 0; - while (index < lowIndex + numberOfElements) { + while (index < lowIndex + numberOfElements) + { MmsValue* elementValue = NULL; elementValue = MmsValue_getElement(arrayValue, index); diff --git a/src/mms/iso_mms/server/mms_server.c b/src/mms/iso_mms/server/mms_server.c index 18b95464..2f6f2b27 100644 --- a/src/mms/iso_mms/server/mms_server.c +++ b/src/mms/iso_mms/server/mms_server.c @@ -536,9 +536,10 @@ mmsServer_setValue(MmsServer self, MmsDomain* domain, char* itemId, MmsValue* va { MmsDataAccessError indication; - if (self->writeHandler != NULL) { + if (self->writeHandler) + { indication = self->writeHandler(self->writeHandlerParameter, domain, - itemId, value, connection); + itemId, -1, NULL, value, connection); } else { MmsValue* cachedValue; @@ -548,7 +549,36 @@ mmsServer_setValue(MmsServer self, MmsDomain* domain, char* itemId, MmsValue* va 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); indication = DATA_ACCESS_ERROR_SUCCESS; } else @@ -591,8 +621,6 @@ mmsServer_checkReadAccess(MmsServer self, MmsDomain* domain, char* itemId, MmsSe { MmsDataAccessError accessError = DATA_ACCESS_ERROR_SUCCESS; - printf("mmsServer_checkReadAccess(%s/%s)\n", domain->domainName, itemId); - if (self->readAccessHandler) { accessError = self->readAccessHandler(self->readAccessHandlerParameter, (domain == (MmsDomain*) self->device) ? NULL : domain, diff --git a/src/mms/iso_mms/server/mms_server_common.c b/src/mms/iso_mms/server/mms_server_common.c index f1524e83..545702be 100644 --- a/src/mms/iso_mms/server/mms_server_common.c +++ b/src/mms/iso_mms/server/mms_server_common.c @@ -287,7 +287,7 @@ mmsServer_isAccessToArrayComponent(AlternateAccess_t* alternateAccess) MmsValue* mmsServer_getComponentOfArrayElement(AlternateAccess_t* alternateAccess, MmsVariableSpecification* namedVariable, - MmsValue* structuredValue) + MmsValue* structuredValue, char* componentId) { MmsValue* retValue = NULL; @@ -319,16 +319,33 @@ mmsServer_getComponentOfArrayElement(AlternateAccess_t* alternateAccess, MmsVari { MmsValue* value = MmsValue_getElement(structuredValue, i); - if (mmsServer_isAccessToArrayComponent( - alternateAccess->list.array[0]->choice.unnamed->choice.selectAlternateAccess.alternateAccess)) { - retValue = - mmsServer_getComponentOfArrayElement( - alternateAccess->list.array[0]->choice.unnamed->choice.selectAlternateAccess.alternateAccess, - structSpec->typeSpec.structure.elements[i], - value); + if (value) + { + if (mmsServer_isAccessToArrayComponent( + alternateAccess->list.array[0]->choice.unnamed->choice.selectAlternateAccess.alternateAccess)) + { + if (componentId) + { + strcat(componentId, structSpec->typeSpec.structure.elements[i]->name); + strcat(componentId, "$"); + } + + retValue = + mmsServer_getComponentOfArrayElement( + alternateAccess->list.array[0]->choice.unnamed->choice.selectAlternateAccess.alternateAccess, + structSpec->typeSpec.structure.elements[i], + value, componentId); + } + else + { + if (componentId) + { + strcat(componentId, structSpec->typeSpec.structure.elements[i]->name); + } + + retValue = value; + } } - else - retValue = value; goto exit_function; } diff --git a/src/mms/iso_mms/server/mms_write_service.c b/src/mms/iso_mms/server/mms_write_service.c index fdde1f16..f46ddef6 100644 --- a/src/mms/iso_mms/server/mms_write_service.c +++ b/src/mms/iso_mms/server/mms_write_service.c @@ -517,33 +517,36 @@ getComponent(MmsServerConnection connection, MmsDomain* domain, AlternateAccess_ { MmsVariableSpecification* retValue = NULL; - if (mmsServer_isComponentAccess(alternateAccess)) { + if (mmsServer_isComponentAccess(alternateAccess)) + { Identifier_t component = alternateAccess->list.array[0]->choice.unnamed->choice.selectAccess.choice.component; if (component.size > 129) goto exit_function; - if (namedVariable->type == MMS_STRUCTURE) { - + if (namedVariable->type == MMS_STRUCTURE) + { 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) - == component.size) { + == component.size) + { if (!strncmp(namedVariable->typeSpec.structure.elements[i]->name, (char*) component.buf, component.size)) { - if (strlen(variableName) + component.size < 199) { - + if (strlen(variableName) + component.size < 199) + { StringUtils_appendString(variableName, 200, "$"); /* here we need strncat because component.buf is not null terminated! */ strncat(variableName, (const char*)component.buf, (size_t)component.size); if (alternateAccess->list.array[0]->choice.unnamed->choice.selectAlternateAccess.alternateAccess - != NULL) { + != NULL) + { retValue = getComponent(connection, domain, alternateAccess->list.array[0]->choice.unnamed->choice.selectAlternateAccess.alternateAccess, @@ -690,7 +693,7 @@ mmsServer_handleWriteRequest( AlternateAccess_t* alternateAccess = varSpec->alternateAccess; - if (alternateAccess != NULL) + if (alternateAccess) { if ((variable->type == MMS_STRUCTURE) && (mmsServer_isComponentAccess(alternateAccess) == false)) { accessResults[i] = DATA_ACCESS_ERROR_OBJECT_ATTRIBUTE_INCONSISTENT; @@ -717,7 +720,7 @@ mmsServer_handleWriteRequest( continue; } - if (alternateAccess != NULL) + if (alternateAccess) { if (domain == NULL) domain = (MmsDomain*) device; @@ -747,18 +750,26 @@ mmsServer_handleWriteRequest( { MmsVariableSpecification* namedVariable = MmsDomain_getNamedVariable(domain, nameIdStr); + char componentId[65]; + componentId[0] = 0; + if (namedVariable) { - elementValue = mmsServer_getComponentOfArrayElement(alternateAccess, namedVariable, elementValue); + elementValue = mmsServer_getComponentOfArrayElement(alternateAccess, namedVariable, elementValue, componentId); } if ((namedVariable == NULL) || (elementValue == NULL)) { 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) { - accessResults[i] = DATA_ACCESS_ERROR_TYPE_INCONSISTENT; + goto end_of_main_loop; + } + else + { + accessResults[i] = mmsServer_setValueEx(connection->server, domain, nameIdStr, value, connection, index, NULL); goto end_of_main_loop; } } @@ -816,16 +827,13 @@ mmsServer_handleWriteRequest( goto end_of_main_loop; } - MmsDataAccessError valueIndication = - mmsServer_setValue(connection->server, domain, nameIdStr, value, connection); - - if (valueIndication == DATA_ACCESS_ERROR_NO_RESPONSE) - sendResponse = false; - - accessResults[i] = valueIndication; + accessResults[i] = mmsServer_setValue(connection->server, domain, nameIdStr, value, connection); end_of_main_loop: + if (accessResults[i] == DATA_ACCESS_ERROR_NO_RESPONSE) + sendResponse = false; + MmsValue_delete(value); }