From 3288bc0fc506a38dfaa45699e016c945d5a28cdf Mon Sep 17 00:00:00 2001 From: Michael Zillgith Date: Fri, 15 Apr 2022 20:16:26 +0200 Subject: [PATCH] - MmsConnection_readNamedVariableListDirectory: added code to parse array index and array component of data set entries (LIB61850-317) --- src/mms/inc_private/mms_common_internal.h | 3 + .../client/mms_client_named_variable_list.c | 54 +++++++++++++- src/mms/iso_mms/common/mms_common_msg.c | 71 ++++++++++++++++++- .../server/mms_named_variable_list_service.c | 71 +------------------ 4 files changed, 125 insertions(+), 74 deletions(-) diff --git a/src/mms/inc_private/mms_common_internal.h b/src/mms/inc_private/mms_common_internal.h index f5431a87..62d07b17 100644 --- a/src/mms/inc_private/mms_common_internal.h +++ b/src/mms/inc_private/mms_common_internal.h @@ -118,6 +118,9 @@ mmsMsg_createStringFromAsnIdentifier(Identifier_t identifier); LIB61850_INTERNAL void mmsMsg_copyAsn1IdentifierToStringBuffer(Identifier_t identifier, char* buffer, int bufSize); +LIB61850_INTERNAL char* +mmsMsg_getComponentNameFromAlternateAccess(AlternateAccess_t* alternateAccess, char* componentNameBuf, int nameBufPos); + LIB61850_INTERNAL void mmsMsg_deleteAccessResultList(AccessResult_t** accessResult, int variableCount); diff --git a/src/mms/iso_mms/client/mms_client_named_variable_list.c b/src/mms/iso_mms/client/mms_client_named_variable_list.c index 98c30ab0..0af73479 100644 --- a/src/mms/iso_mms/client/mms_client_named_variable_list.c +++ b/src/mms/iso_mms/client/mms_client_named_variable_list.c @@ -222,8 +222,11 @@ parseNamedVariableAttributes(GetNamedVariableListAttributesResponse_t* response, for (i = 0; i < attributesCount; i++) { - char* domainId; - char* itemId; + char* domainId = NULL; + char* itemId = NULL; + int arrayIdx = -1; + char componentNameBuffer[129]; + char* componentName = NULL; if (response->listOfVariable.list.array[i]->variableSpecification.choice.name.present == ObjectName_PR_vmdspecific) { @@ -240,7 +243,52 @@ parseNamedVariableAttributes(GetNamedVariableListAttributesResponse_t* response, variableSpecification.choice.name.choice.domainspecific.itemId); } - MmsVariableAccessSpecification* listEntry = MmsVariableAccessSpecification_create(domainId, itemId); + if (response->listOfVariable.list.array[i]->alternateAccess) { + AlternateAccess_t* alternateAccess = response->listOfVariable.list.array[i]->alternateAccess; + + if (alternateAccess->list.count > 0) { + if (alternateAccess->list.array[0]->choice.unnamed->present == AlternateAccessSelection_PR_selectAlternateAccess) { + + if (alternateAccess->list.array[0]->choice.unnamed->choice.selectAlternateAccess.accessSelection.present + == alternateAccess->list.array[0]->choice.unnamed->choice.selectAlternateAccess.accessSelection.present) + { + INTEGER_t* asnIndex = + &(alternateAccess->list.array[0]->choice.unnamed->choice.selectAccess.choice.index); + + if (asnIndex) { + long indexValue; + + if (asn_INTEGER2long(asnIndex, &indexValue) != -1) { + arrayIdx = (int)indexValue; + } + } + + AlternateAccess_t* nestedAltAccess = alternateAccess->list.array[0]->choice.unnamed->choice.selectAlternateAccess.alternateAccess; + + if (nestedAltAccess) { + componentName = mmsMsg_getComponentNameFromAlternateAccess(nestedAltAccess, componentNameBuffer, 0); + } + } + } + else if (alternateAccess->list.array[0]->choice.unnamed->present == AlternateAccessSelection_PR_selectAccess) { + INTEGER_t* asnIndex = + &(alternateAccess->list.array[0]->choice.unnamed->choice.selectAccess.choice.index); + + if (asnIndex) { + long indexValue; + + if (asn_INTEGER2long(asnIndex, &indexValue) != -1) { + arrayIdx = (int)indexValue; + } + } + } + } + } + + if (componentName) + componentName = StringUtils_copyString(componentName); + + MmsVariableAccessSpecification* listEntry = MmsVariableAccessSpecification_createAlternateAccess(domainId, itemId, arrayIdx, componentName); LinkedList_add(attributes, listEntry); } diff --git a/src/mms/iso_mms/common/mms_common_msg.c b/src/mms/iso_mms/common/mms_common_msg.c index eefd408f..fb7d7548 100644 --- a/src/mms/iso_mms/common/mms_common_msg.c +++ b/src/mms/iso_mms/common/mms_common_msg.c @@ -1,7 +1,7 @@ /* * mms_common_msg.c * - * Copyright 2013-2019 Michael Zillgith + * Copyright 2013-2022 Michael Zillgith * * This file is part of libIEC61850. * @@ -489,6 +489,75 @@ mmsMsg_copyAsn1IdentifierToStringBuffer(Identifier_t identifier, char* buffer, i } } +char* +mmsMsg_getComponentNameFromAlternateAccess(AlternateAccess_t* alternateAccess, char* componentNameBuf, int nameBufPos) +{ + if (alternateAccess->list.count == 1) { + + if (alternateAccess->list.array[0]->present == AlternateAccess__Member_PR_unnamed) { + + if (alternateAccess->list.array[0]->choice.unnamed->present == AlternateAccessSelection_PR_selectAlternateAccess) { + + if (alternateAccess->list.array[0]->choice.unnamed->choice.selectAlternateAccess.accessSelection.present == + AlternateAccessSelection__selectAlternateAccess__accessSelection_PR_component) + { + Identifier_t componentIdentifier = alternateAccess->list.array[0]->choice.unnamed-> + choice.selectAlternateAccess.accessSelection.choice.component; + + AlternateAccess_t* nextAlternateAccess = alternateAccess->list.array[0]->choice.unnamed-> + choice.selectAlternateAccess.alternateAccess; + + if (nextAlternateAccess) { + if (nameBufPos + componentIdentifier.size + 1 < 65) { + memcpy(componentNameBuf + nameBufPos, componentIdentifier.buf, componentIdentifier.size); + nameBufPos += componentIdentifier.size; + componentNameBuf[nameBufPos++] = '$'; + return mmsMsg_getComponentNameFromAlternateAccess(nextAlternateAccess, componentNameBuf, nameBufPos); + } + else { + if (DEBUG_MMS_SERVER) + printf("MMS_SERVER: component identifier name too long!\n"); + } + } + else { + if (DEBUG_MMS_SERVER) + printf("MMS_SERVER: next alternate access specification is missing!\n"); + } + } + } + else if (alternateAccess->list.array[0]->choice.unnamed->present == AlternateAccessSelection_PR_selectAccess) { + + /* final component part */ + + if (alternateAccess->list.array[0]->choice.unnamed->choice.selectAccess.present == + AlternateAccessSelection__selectAccess_PR_component) + { + Identifier_t componentIdentifier = alternateAccess->list.array[0]->choice.unnamed-> + choice.selectAccess.choice.component; + + if (nameBufPos + componentIdentifier.size + 1 < 65) { + memcpy(componentNameBuf + nameBufPos, componentIdentifier.buf, componentIdentifier.size); + nameBufPos += componentIdentifier.size; + componentNameBuf[nameBufPos++] = 0; + return componentNameBuf; + } + else { + if (DEBUG_MMS_SERVER) + printf("MMS_SERVER: component identifier name too long!\n"); + } + } + } + + } + + } + + if (DEBUG_MMS_SERVER) + printf("MMS_SERVER: invalid component access specification\n"); + + return NULL; +} + #if (MMS_FILE_SERVICE == 1) void diff --git a/src/mms/iso_mms/server/mms_named_variable_list_service.c b/src/mms/iso_mms/server/mms_named_variable_list_service.c index e7d152c2..dbe35ffb 100644 --- a/src/mms/iso_mms/server/mms_named_variable_list_service.c +++ b/src/mms/iso_mms/server/mms_named_variable_list_service.c @@ -296,75 +296,6 @@ checkIfVariableExists(MmsDevice* device, MmsAccessSpecifier* accessSpecifier) return true; } -static char* -getComponentNameFromAlternateAccess(AlternateAccess_t* alternateAccess, char* componentNameBuf, int nameBufPos) -{ - if (alternateAccess->list.count == 1) { - - if (alternateAccess->list.array[0]->present == AlternateAccess__Member_PR_unnamed) { - - if (alternateAccess->list.array[0]->choice.unnamed->present == AlternateAccessSelection_PR_selectAlternateAccess) { - - if (alternateAccess->list.array[0]->choice.unnamed->choice.selectAlternateAccess.accessSelection.present == - AlternateAccessSelection__selectAlternateAccess__accessSelection_PR_component) - { - Identifier_t componentIdentifier = alternateAccess->list.array[0]->choice.unnamed-> - choice.selectAlternateAccess.accessSelection.choice.component; - - AlternateAccess_t* nextAlternateAccess = alternateAccess->list.array[0]->choice.unnamed-> - choice.selectAlternateAccess.alternateAccess; - - if (nextAlternateAccess) { - if (nameBufPos + componentIdentifier.size + 1 < 65) { - memcpy(componentNameBuf + nameBufPos, componentIdentifier.buf, componentIdentifier.size); - nameBufPos += componentIdentifier.size; - componentNameBuf[nameBufPos++] = '$'; - return getComponentNameFromAlternateAccess(nextAlternateAccess, componentNameBuf, nameBufPos); - } - else { - if (DEBUG_MMS_SERVER) - printf("MMS_SERVER: component identifier name too long!\n"); - } - } - else { - if (DEBUG_MMS_SERVER) - printf("MMS_SERVER: next alternate access specification is missing!\n"); - } - } - } - else if (alternateAccess->list.array[0]->choice.unnamed->present == AlternateAccessSelection_PR_selectAccess) { - - /* final component part */ - - if (alternateAccess->list.array[0]->choice.unnamed->choice.selectAccess.present == - AlternateAccessSelection__selectAccess_PR_component) - { - Identifier_t componentIdentifier = alternateAccess->list.array[0]->choice.unnamed-> - choice.selectAccess.choice.component; - - if (nameBufPos + componentIdentifier.size + 1 < 65) { - memcpy(componentNameBuf + nameBufPos, componentIdentifier.buf, componentIdentifier.size); - nameBufPos += componentIdentifier.size; - componentNameBuf[nameBufPos++] = 0; - return componentNameBuf; - } - else { - if (DEBUG_MMS_SERVER) - printf("MMS_SERVER: component identifier name too long!\n"); - } - } - } - - } - - } - - if (DEBUG_MMS_SERVER) - printf("MMS_SERVER: invalid component access specification\n"); - - return NULL; -} - static MmsNamedVariableList createNamedVariableList(MmsServer server, MmsDomain* domain, MmsDevice* device, DefineNamedVariableListRequest_t* request, @@ -426,7 +357,7 @@ createNamedVariableList(MmsServer server, MmsDomain* domain, MmsDevice* device, if (alternateAccess->choice.unnamed->choice.selectAlternateAccess.alternateAccess) { componentNameBuf[0] = 0; - componentName = getComponentNameFromAlternateAccess( + componentName = mmsMsg_getComponentNameFromAlternateAccess( alternateAccess->choice.unnamed->choice.selectAlternateAccess.alternateAccess, componentNameBuf, 0); }