- fixed problems in handling array elements and array element components

pull/265/head
Michael Zillgith 5 years ago
parent 6a3c66eafa
commit e4b2849894

@ -102,6 +102,20 @@
</LN>
<LN lnClass="MHAI" lnType="MHAI1" inst="1" prefix="">
<DataSet name="TestMHAI">
<FCDA ldInst="ComplexArray" lnClass="MHAI" lnInst="1" doName="HA" fc="MX" daName="phsAHar(7)"/>
<FCDA ldInst="ComplexArray" lnClass="MHAI" lnInst="1" doName="HA" fc="MX" daName="phsAHar(8)"/>
<FCDA ldInst="ComplexArray" lnClass="MHAI" lnInst="1" doName="HA" fc="MX" daName="phsAHar(9).cVal"/>
<FCDA ldInst="ComplexArray" lnClass="MHAI" lnInst="1" doName="HA" fc="MX" daName="phsAHar(10).cVal.mag"/>
<FCDA ldInst="ComplexArray" lnClass="MHAI" lnInst="1" doName="HA" fc="MX" daName="phsAHar(11).cVal.mag.f"/>
</DataSet>
<ReportControl name="MHAIRCB" confRev="1" datSet="TestMHAI" rptID="TestMHAI" buffered="false" intgPd="1000" bufTime="50">
<TrgOps period="true" />
<OptFields seqNum="true" timeStamp="true" dataSet="true" reasonCode="true" configRef="true" />
<RptEnabled max="1" />
</ReportControl>
<DOI name="HA">
<DAI name="numHar">
<Val>16</Val>

@ -1,14 +1,79 @@
/*
* static_model.c
*
* automatically generated from mhai_array.icd
* automatically generated from mhai_array.cid
*/
#include "static_model.h"
static void initializeValues();
extern DataSet iedModelds_ComplexArray_MHAI1_TestMHAI;
extern DataSetEntry iedModelds_ComplexArray_MHAI1_TestMHAI_fcda0;
extern DataSetEntry iedModelds_ComplexArray_MHAI1_TestMHAI_fcda1;
extern DataSetEntry iedModelds_ComplexArray_MHAI1_TestMHAI_fcda2;
extern DataSetEntry iedModelds_ComplexArray_MHAI1_TestMHAI_fcda3;
extern DataSetEntry iedModelds_ComplexArray_MHAI1_TestMHAI_fcda4;
DataSetEntry iedModelds_ComplexArray_MHAI1_TestMHAI_fcda0 = {
"ComplexArray",
false,
"MHAI1$MX$HA$phsAHar",
7,
NULL,
NULL,
&iedModelds_ComplexArray_MHAI1_TestMHAI_fcda1
};
DataSetEntry iedModelds_ComplexArray_MHAI1_TestMHAI_fcda1 = {
"ComplexArray",
false,
"MHAI1$MX$HA$phsAHar",
8,
NULL,
NULL,
&iedModelds_ComplexArray_MHAI1_TestMHAI_fcda2
};
DataSetEntry iedModelds_ComplexArray_MHAI1_TestMHAI_fcda2 = {
"ComplexArray",
false,
"MHAI1$MX$HA$phsAHar",
9,
"cVal",
NULL,
&iedModelds_ComplexArray_MHAI1_TestMHAI_fcda3
};
DataSetEntry iedModelds_ComplexArray_MHAI1_TestMHAI_fcda3 = {
"ComplexArray",
false,
"MHAI1$MX$HA$phsAHar",
10,
"cVal$mag",
NULL,
&iedModelds_ComplexArray_MHAI1_TestMHAI_fcda4
};
DataSetEntry iedModelds_ComplexArray_MHAI1_TestMHAI_fcda4 = {
"ComplexArray",
false,
"MHAI1$MX$HA$phsAHar",
11,
"cVal$mag$f",
NULL,
NULL
};
DataSet iedModelds_ComplexArray_MHAI1_TestMHAI = {
"ComplexArray",
"MHAI1$TestMHAI",
5,
&iedModelds_ComplexArray_MHAI1_TestMHAI_fcda0,
NULL
};
LogicalDevice iedModel_ComplexArray = {
LogicalDeviceModelType,
"ComplexArray",
@ -1977,7 +2042,9 @@ DataAttribute iedModel_ComplexArray_MHAI1_HA_frequency = {
NULL,
0};
extern ReportControlBlock iedModel_ComplexArray_MHAI1_report0;
ReportControlBlock iedModel_ComplexArray_MHAI1_report0 = {&iedModel_ComplexArray_MHAI1, "MHAIRCB01", "TestMHAI", false, "TestMHAI", 1, 24, 175, 50, 1000, {0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0}, NULL};
@ -1988,8 +2055,8 @@ DataAttribute iedModel_ComplexArray_MHAI1_HA_frequency = {
IedModel iedModel = {
"test",
&iedModel_ComplexArray,
NULL,
NULL,
&iedModelds_ComplexArray_MHAI1_TestMHAI,
&iedModel_ComplexArray_MHAI1_report0,
NULL,
NULL,
NULL,

@ -1,7 +1,7 @@
/*
* static_model.h
*
* automatically generated from mhai_array.icd
* automatically generated from mhai_array.cid
*/
#ifndef STATIC_MODEL_H_

@ -377,18 +377,64 @@ updateDataSetsWithCachedValues(IedServer self)
MmsDomain* domain = MmsDevice_getDomain(self->mmsDevice, domainName);
MmsValue* value = MmsServer_getValueFromCache(self->mmsServer, domain, dataSetEntry->variableName);
char variableName[66];
strncpy(variableName, dataSetEntry->variableName, 65);
variableName[65] = 0;
MmsVariableSpecification* typeSpec = NULL;
MmsValue* value = MmsServer_getValueFromCacheEx(self->mmsServer, domain, variableName, &typeSpec);
if (value == NULL) {
if (DEBUG_IED_SERVER) {
printf("LD: %s dataset: %s : error cannot get value from cache for %s -> %s!\n",
printf("IED_SERVER: LD: %s dataset: %s : error cannot get value from cache for %s -> %s!\n",
dataSet->logicalDeviceName, dataSet->name,
dataSetEntry->logicalDeviceName,
dataSetEntry->variableName);
}
}
else
dataSetEntry->value = value;
else {
/* check if array element */
if (dataSetEntry->index != -1) {
if (typeSpec->type == MMS_ARRAY) {
MmsValue* elementValue = MmsValue_getElement(value, dataSetEntry->index);
if (elementValue) {
if (dataSetEntry->componentName) {
MmsVariableSpecification* elementType = typeSpec->typeSpec.array.elementTypeSpec;
MmsValue* subElementValue = MmsVariableSpecification_getChildValue(elementType, elementValue, dataSetEntry->componentName);
if (subElementValue) {
dataSetEntry->value = subElementValue;
}
else {
if (DEBUG_IED_SERVER)
printf("IED_SERVER: ERROR - component %s of array element not found\n", dataSetEntry->componentName);
}
}
else {
dataSetEntry->value = elementValue;
}
}
else {
if (DEBUG_IED_SERVER)
printf("IED_SERVER: ERROR - array element %i not found\n", dataSetEntry->index);
}
}
else {
if (DEBUG_IED_SERVER)
printf("IED_SERVER: ERROR - variable %s/%s is not an array\n", dataSetEntry->logicalDeviceName, dataSetEntry->variableName);
}
}
else {
dataSetEntry->value = value;
}
}
dataSetEntry = dataSetEntry->sibling;
}

@ -3732,7 +3732,6 @@ MmsMapping_createDataSetByNamedVariableList(MmsMapping* self, MmsNamedVariableLi
/* use variable name part of domain name as logicalDeviceName */
dataSetEntry->logicalDeviceName = MmsDomain_getName(listEntry->domain) + strlen(self->model->name);
dataSetEntry->variableName = listEntry->variableName;
dataSetEntry->index = listEntry->arrayIndex;
dataSetEntry->componentName = listEntry->componentName;
@ -3743,8 +3742,49 @@ MmsMapping_createDataSetByNamedVariableList(MmsMapping* self, MmsNamedVariableLi
else
lastDataSetEntry->sibling = dataSetEntry;
dataSetEntry->value =
MmsServer_getValueFromCache(self->mmsServer, listEntry->domain, listEntry->variableName);
MmsVariableSpecification* dataSetEntryVarSpec = NULL;
MmsValue* dataSetEntryValue = MmsServer_getValueFromCacheEx(self->mmsServer, listEntry->domain, listEntry->variableName, &dataSetEntryVarSpec);
if (dataSetEntryValue) {
if (dataSetEntry->index != -1) {
if (dataSetEntryVarSpec->type == MMS_ARRAY) {
MmsValue* elementValue = MmsValue_getElement(dataSetEntryValue, dataSetEntry->index);
if (elementValue) {
if (dataSetEntry->componentName) {
MmsVariableSpecification* elementType = dataSetEntryVarSpec->typeSpec.array.elementTypeSpec;
MmsValue* subElementValue = MmsVariableSpecification_getChildValue(elementType, elementValue, dataSetEntry->componentName);
if (subElementValue) {
dataSetEntry->value = subElementValue;
}
else {
if (DEBUG_IED_SERVER)
printf("IED_SERVER: ERROR - component %s of array element not found\n", dataSetEntry->componentName);
}
}
else {
dataSetEntry->value = elementValue;
}
}
else {
if (DEBUG_IED_SERVER)
printf("IED_SERVER: ERROR - array element %i not found\n", dataSetEntry->index);
}
}
else {
if (DEBUG_IED_SERVER)
printf("IED_SERVER: ERROR - variable %s/%s is not an array\n", dataSetEntry->logicalDeviceName, dataSetEntry->variableName);
}
}
else {
dataSetEntry->value = dataSetEntryValue;
}
}
lastDataSetEntry = dataSetEntry;

@ -177,6 +177,9 @@ mmsClient_createAlternateAccess(uint32_t index, uint32_t elementCount);
LIB61850_INTERNAL void
mmsClient_deleteAlternateAccess(AlternateAccess_t* alternateAccess);
LIB61850_INTERNAL AlternateAccess_t*
mmsClient_createAlternateAccessComponent(const char* componentName);
LIB61850_INTERNAL void
mmsClient_deleteAlternateAccessIndexComponent(AlternateAccess_t* alternateAccess);

@ -79,6 +79,9 @@ MmsServer_getDevice(MmsServer self);
LIB61850_INTERNAL MmsValue*
MmsServer_getValueFromCache(MmsServer self, MmsDomain* domain, const char* itemId);
LIB61850_INTERNAL MmsValue*
MmsServer_getValueFromCacheEx(MmsServer self, MmsDomain* domain, const char* itemId, MmsVariableSpecification** typeSpec);
LIB61850_INTERNAL bool
MmsServer_isLocked(MmsServer self);

@ -36,7 +36,7 @@ LIB61850_INTERNAL void
MmsValueCache_insertValue(MmsValueCache self, char* itemId, MmsValue* value);
LIB61850_INTERNAL MmsValue*
MmsValueCache_lookupValue(MmsValueCache self, const char* itemId);
MmsValueCache_lookupValue(MmsValueCache self, const char* itemId, MmsVariableSpecification** outSpec);
LIB61850_INTERNAL void
MmsValueCache_destroy(MmsValueCache self);

@ -137,8 +137,8 @@ mmsClient_deleteAlternateAccess(AlternateAccess_t* alternateAccess)
GLOBAL_FREEMEM(alternateAccess);
}
static AlternateAccess_t*
createAlternateAccessComponent(const char* componentName)
AlternateAccess_t*
mmsClient_createAlternateAccessComponent(const char* componentName)
{
AlternateAccess_t* alternateAccess = (AlternateAccess_t*) GLOBAL_CALLOC(1, sizeof(AlternateAccess_t));
alternateAccess->list.count = 1;
@ -161,7 +161,7 @@ createAlternateAccessComponent(const char* componentName)
(uint8_t*) StringUtils_copySubString((char*) componentName, (char*) separator);
alternateAccess->list.array[0]->choice.unnamed->choice.selectAlternateAccess.accessSelection.choice.component.size = size;
alternateAccess->list.array[0]->choice.unnamed->choice.selectAlternateAccess.alternateAccess = createAlternateAccessComponent(separator + 1);
alternateAccess->list.array[0]->choice.unnamed->choice.selectAlternateAccess.alternateAccess = mmsClient_createAlternateAccessComponent(separator + 1);
}
else {
int size = strlen(componentName);
@ -201,7 +201,7 @@ mmsClient_createAlternateAccessIndexComponent(uint32_t index, const char* compon
asn_long2INTEGER(asnIndex, index);
alternateAccess->list.array[0]->choice.unnamed->choice.selectAlternateAccess.alternateAccess = createAlternateAccessComponent(componentName);
alternateAccess->list.array[0]->choice.unnamed->choice.selectAlternateAccess.alternateAccess = mmsClient_createAlternateAccessComponent(componentName);
}
else {
alternateAccess->list.array[0]->choice.unnamed->present = AlternateAccessSelection_PR_selectAccess;
@ -217,3 +217,4 @@ mmsClient_createAlternateAccessIndexComponent(uint32_t index, const char* compon
return alternateAccess;
}

@ -354,49 +354,12 @@ mmsClient_createDefineNamedVariableListRequest(
domainspecific.itemId.buf = (uint8_t*) StringUtils_copyString(variableSpec->itemId);
if (variableSpec->arrayIndex != -1) {
AlternateAccess_t* alternateAccess = (AlternateAccess_t*) GLOBAL_CALLOC(1, sizeof(AlternateAccess_t));
alternateAccess->list.count = 1;
alternateAccess->list.array = (struct AlternateAccess__Member**) GLOBAL_CALLOC(1, sizeof(struct AlternateAccess__Member*));
alternateAccess->list.array[0] = (struct AlternateAccess__Member*) GLOBAL_CALLOC(1, sizeof(struct AlternateAccess__Member));
alternateAccess->list.array[0]->present = AlternateAccess__Member_PR_unnamed;
alternateAccess->list.array[0]->choice.unnamed = (AlternateAccessSelection_t*) GLOBAL_CALLOC(1, sizeof(AlternateAccessSelection_t));
alternateAccess->list.array[0]->choice.unnamed->present = AlternateAccessSelection_PR_selectAlternateAccess;
alternateAccess->list.array[0]->choice.unnamed->choice.selectAlternateAccess.accessSelection.present =
AlternateAccessSelection__selectAlternateAccess__accessSelection_PR_index;
asn_long2INTEGER(&(alternateAccess->list.array[0]->choice.unnamed->choice.selectAlternateAccess.accessSelection.choice.index),
variableSpec->arrayIndex);
if (variableSpec->componentName != NULL) {
AlternateAccess_t* componentAccess = (AlternateAccess_t*) GLOBAL_CALLOC(1, sizeof(AlternateAccess_t));
componentAccess->list.count = 1;
componentAccess->list.array = (struct AlternateAccess__Member**) GLOBAL_CALLOC(1, sizeof(struct AlternateAccess__Member*));
componentAccess->list.array[0] = (struct AlternateAccess__Member*) GLOBAL_CALLOC(1, sizeof(struct AlternateAccess__Member));
componentAccess->list.array[0]->present = AlternateAccess__Member_PR_unnamed;
componentAccess->list.array[0]->choice.unnamed = (AlternateAccessSelection_t*) GLOBAL_CALLOC(1, sizeof(AlternateAccessSelection_t));
componentAccess->list.array[0]->choice.unnamed->present = AlternateAccessSelection_PR_selectAccess;
componentAccess->list.array[0]->choice.unnamed->choice.selectAccess.present =
AlternateAccessSelection__selectAccess_PR_component;
Identifier_t* componentIdentifier =
&(componentAccess->list.array[0]->choice.unnamed->choice.selectAccess.choice.component);
componentIdentifier->size = strlen(variableSpec->componentName);
componentIdentifier->buf = (uint8_t*) StringUtils_copyString(variableSpec->componentName);
alternateAccess->list.array[0]->choice.unnamed->choice.selectAlternateAccess.alternateAccess
= componentAccess;
if (variableSpec->componentName) {
request->listOfVariable.list.array[i]->alternateAccess = mmsClient_createAlternateAccessIndexComponent(variableSpec->arrayIndex, variableSpec->componentName);
}
else {
request->listOfVariable.list.array[i]->alternateAccess = mmsClient_createAlternateAccess(variableSpec->arrayIndex, 0);
}
request->listOfVariable.list.array[i]->alternateAccess = alternateAccess;
}
element = LinkedList_getNext(element);
@ -404,9 +367,16 @@ mmsClient_createDefineNamedVariableListRequest(
i++;
}
der_encode(&asn_DEF_MmsPdu, mmsPdu,
asn_enc_rval_t rval = der_encode(&asn_DEF_MmsPdu, mmsPdu,
(asn_app_consume_bytes_f*) mmsClient_write_out, (void*) writeBuffer);
if (rval.encoded == -1) {
writeBuffer->size = 0;
if (DEBUG_MMS_SERVER)
printf("MMS_CLIENT: createDefineNamedVariableListRequest - failed to encode request!\n");
}
asn_DEF_MmsPdu.free_struct(&asn_DEF_MmsPdu, mmsPdu, 0);
}

@ -46,6 +46,8 @@ void
MmsNamedVariableListEntry_destroy(MmsNamedVariableListEntry self)
{
GLOBAL_FREEMEM(self->variableName);
if (self->componentName)
GLOBAL_FREEMEM(self->componentName);
GLOBAL_FREEMEM(self);
}

@ -1,7 +1,7 @@
/*
* mms_named_variable_list_service.c
*
* Copyright 2013-2015 Michael Zillgith
* Copyright 2013-2020 Michael Zillgith
*
* This file is part of libIEC61850.
*
@ -23,6 +23,7 @@
#include "libiec61850_platform_includes.h"
#include "mms_server_internal.h"
#include "mms_client_internal.h"
#include "mms_named_variable_list.h"
#include "ber_encoder.h"
@ -281,6 +282,8 @@ checkIfVariableExists(MmsDevice* device, MmsAccessSpecifier* accessSpecifier)
return false;
if (accessSpecifier->componentName != NULL) {
variableSpec = variableSpec->typeSpec.array.elementTypeSpec;
if (MmsVariableSpecification_getNamedVariableRecursive(variableSpec, accessSpecifier->componentName) == NULL)
return false;
}
@ -289,6 +292,74 @@ 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,
@ -299,6 +370,9 @@ createNamedVariableList(MmsServer server, MmsDomain* domain, MmsDevice* device,
int variableCount = request->listOfVariable.list.count;
if (DEBUG_MMS_SERVER)
printf("MMS_SERVER: create-named-variable-list (%i variable(s) | max=%i)\n", variableCount, server->maxDataSetEntries);
#if (CONFIG_MMS_SERVER_CONFIG_SERVICES_AT_RUNTIME == 1)
if ((variableCount == 0 ) || (variableCount > server->maxDataSetEntries)) {
#else
@ -324,6 +398,10 @@ createNamedVariableList(MmsServer server, MmsDomain* domain, MmsDevice* device,
if (request->listOfVariable.list.array[i]->alternateAccess != NULL) {
if (request->listOfVariable.list.array[i]->alternateAccess->list.count != 1) {
if (DEBUG_MMS_SERVER)
printf("MMS_SERVER: create-named-variable list - only one alternate access specification allowed!\n");
MmsNamedVariableList_destroy(namedVariableList);
namedVariableList = NULL;
break;
@ -334,21 +412,31 @@ createNamedVariableList(MmsServer server, MmsDomain* domain, MmsDevice* device,
request->listOfVariable.list.array[i]->alternateAccess->list.array[0];
if ((alternateAccess->present == AlternateAccess__Member_PR_unnamed)
&&(alternateAccess->choice.unnamed->present == AlternateAccessSelection_PR_selectAlternateAccess)
&& (alternateAccess->choice.unnamed->present == AlternateAccessSelection_PR_selectAlternateAccess)
&& (alternateAccess->choice.unnamed->choice.selectAlternateAccess.accessSelection.present ==
AlternateAccessSelection__selectAlternateAccess__accessSelection_PR_index))
{
asn_INTEGER2long(&(alternateAccess->choice.unnamed->choice.selectAlternateAccess.accessSelection.choice.index),
&arrayIndex);
Identifier_t componentIdentifier = alternateAccess->choice.unnamed->
choice.selectAlternateAccess.alternateAccess->list.array[0]->
choice.unnamed->choice.selectAccess.choice.component;
componentName =
StringUtils_createStringFromBufferInBuffer(componentNameBuf,
componentIdentifier.buf, componentIdentifier.size);
if (alternateAccess->choice.unnamed->choice.selectAlternateAccess.alternateAccess) {
componentNameBuf[0] = 0;
componentName = getComponentNameFromAlternateAccess(
alternateAccess->choice.unnamed->choice.selectAlternateAccess.alternateAccess,
componentNameBuf, 0);
}
else {
if (DEBUG_MMS_SERVER)
printf("MMS_SERVER: create-named-variable-list - component specification is missing!\n");
}
}
else if ((alternateAccess->present == AlternateAccess__Member_PR_unnamed)
&& (alternateAccess->choice.unnamed->present == AlternateAccessSelection_PR_selectAccess)
&& (alternateAccess->choice.unnamed->choice.selectAccess.present == AlternateAccessSelection__selectAccess_PR_index)
)
{
asn_INTEGER2long(&(alternateAccess->choice.unnamed->choice.selectAccess.choice.index), &arrayIndex);
}
else {
MmsNamedVariableList_destroy(namedVariableList);
@ -356,9 +444,7 @@ createNamedVariableList(MmsServer server, MmsDomain* domain, MmsDevice* device,
*mmsError = MMS_ERROR_DEFINITION_INVALID_ADDRESS;
break;
}
}
}
if (varSpec->present == VariableSpecification_PR_name) {
@ -383,15 +469,21 @@ createNamedVariableList(MmsServer server, MmsDomain* domain, MmsDevice* device,
accessSpecifier.arrayIndex = arrayIndex;
accessSpecifier.componentName = componentName;
if (DEBUG_MMS_SERVER)
printf("MMS SERVER: add named variable list entry: %s/%s(%li)%s\n", MmsDomain_getName(elementDomain), variableName, arrayIndex, componentName);
/* check if element exists */
if (checkIfVariableExists(device, &accessSpecifier) == true) {
MmsNamedVariableListEntry variable =
MmsNamedVariableListEntry_create(accessSpecifier);
MmsNamedVariableList_addVariable(namedVariableList, variable);
}
else {
if (DEBUG_MMS_SERVER)
printf("MMS_SERVER: failed - variable does not exist!\n");
MmsNamedVariableList_destroy(namedVariableList);
namedVariableList = NULL;
i = variableCount; /* exit loop after freeing loop variables */
@ -655,6 +747,15 @@ createGetNamedVariableListAttributesResponse(int invokeId, ByteBuffer* response,
varListResponse->listOfVariable.list.array[i]->variableSpecification.choice.name.choice.
domainspecific.itemId.size = strlen(variableEntry->variableName);
if (variableEntry->arrayIndex != -1) {
varListResponse->listOfVariable.list.array[i]->alternateAccess =
mmsClient_createAlternateAccessIndexComponent(variableEntry->arrayIndex, variableEntry->componentName);
}
else if (variableEntry->componentName) {
varListResponse->listOfVariable.list.array[i]->alternateAccess =
mmsClient_createAlternateAccessComponent(variableEntry->componentName);
}
variable = LinkedList_getNext(variable);
}

@ -269,9 +269,6 @@ alternateArrayAccess(MmsServerConnection connection,
int lowIndex = mmsServer_getLowIndex(alternateAccess);
int numberOfElements = mmsServer_getNumberOfElements(alternateAccess);
if (DEBUG_MMS_SERVER) printf("Alternate access index: %i elements %i\n",
lowIndex, numberOfElements);
int index = lowIndex;
MmsValue* arrayValue = mmsServer_getValue(connection->server, domain, itemId, connection, false);
@ -707,6 +704,61 @@ exit:
#if (MMS_DATA_SET_SERVICE == 1)
static void
addNamedVariableToNamedVariableListResultList(MmsVariableSpecification* namedVariable, MmsDomain* domain, char* nameIdStr,
LinkedList /*<MmsValue>*/ values, MmsServerConnection connection, MmsNamedVariableListEntry listEntry)
{
if (namedVariable != NULL) {
if (DEBUG_MMS_SERVER)
printf("MMS read: found named variable %s with search string %s\n",
namedVariable->name, nameIdStr);
MmsValue* value = mmsServer_getValue(connection->server, domain, nameIdStr, connection, false);
if (value) {
if (listEntry->arrayIndex != -1) {
if (MmsValue_getType(value) == MMS_ARRAY) {
MmsValue* elementValue = MmsValue_getElement(value, listEntry->arrayIndex);
if (listEntry->componentName) {
MmsVariableSpecification* elementType = namedVariable->typeSpec.array.elementTypeSpec;
MmsValue* subElementValue = MmsVariableSpecification_getChildValue(elementType, elementValue, listEntry->componentName);
if (subElementValue) {
appendValueToResultList(subElementValue, values);
}
else {
if (DEBUG_IED_SERVER)
printf("IED_SERVER: ERROR - component %s of array element not found\n", listEntry->componentName);
}
}
else {
appendValueToResultList(elementValue, values);
}
}
else {
if (DEBUG_MMS_SERVER)
printf("MMS_SERVER: data set entry of unexpected type!\n");
appendErrorToResultList(values, DATA_ACCESS_ERROR_OBJECT_NONE_EXISTENT);
}
}
else {
appendValueToResultList(value, values);
}
}
else {
appendErrorToResultList(values, DATA_ACCESS_ERROR_OBJECT_NONE_EXISTENT);
}
}
else
appendErrorToResultList(values, DATA_ACCESS_ERROR_OBJECT_NONE_EXISTENT);
}
static void
createNamedVariableListResponse(MmsServerConnection connection, MmsNamedVariableList namedList,
int invokeId, ByteBuffer* response, bool isSpecWithResult, VarAccessSpec* accessSpec)
@ -731,8 +783,8 @@ createNamedVariableListResponse(MmsServerConnection connection, MmsNamedVariable
MmsVariableSpecification* namedVariable = MmsDomain_getNamedVariable(variableDomain,
variableName);
addNamedVariableToResultList(namedVariable, variableDomain, variableName,
values, connection, NULL, false);
addNamedVariableToNamedVariableListResultList(namedVariable, variableDomain, variableName,
values, connection, variableListEntry);
variable = LinkedList_getNext(variable);
}

@ -444,7 +444,18 @@ MmsServer_getValueFromCache(MmsServer self, MmsDomain* domain, const char* itemI
MmsValueCache cache = (MmsValueCache) Map_getEntry(self->valueCaches, domain);
if (cache != NULL)
return MmsValueCache_lookupValue(cache, itemId);
return MmsValueCache_lookupValue(cache, itemId, NULL);
return NULL ;
}
MmsValue*
MmsServer_getValueFromCacheEx(MmsServer self, MmsDomain* domain, const char* itemId, MmsVariableSpecification** typeSpec)
{
MmsValueCache cache = (MmsValueCache) Map_getEntry(self->valueCaches, domain);
if (cache != NULL)
return MmsValueCache_lookupValue(cache, itemId, typeSpec);
return NULL ;
}

@ -89,7 +89,7 @@ getChildSubString (const char* itemId, char* parentId)
}
static MmsValue*
searchCacheForValue(MmsValueCache self, const char* itemId, char* parentId)
searchCacheForValue(MmsValueCache self, const char* itemId, char* parentId, MmsVariableSpecification** outSpec)
{
MmsValueCacheEntry* cacheEntry;
MmsValue* value = NULL;
@ -100,7 +100,7 @@ searchCacheForValue(MmsValueCache self, const char* itemId, char* parentId)
char* parentItemId = getParentSubString(parentId);
if (parentItemId != NULL) {
value = searchCacheForValue(self, itemId, parentItemId);
value = searchCacheForValue(self, itemId, parentItemId, outSpec);
}
}
else {
@ -109,13 +109,18 @@ searchCacheForValue(MmsValueCache self, const char* itemId, char* parentId)
MmsVariableSpecification* typeSpec = MmsDomain_getNamedVariable(self->domain, parentId);
value = MmsVariableSpecification_getChildValue(typeSpec, cacheEntry->value, childId);
if (outSpec) {
*outSpec = MmsVariableSpecification_getNamedVariableRecursive(typeSpec, childId);
}
}
return value;
}
MmsValue*
MmsValueCache_lookupValue(MmsValueCache self, const char* itemId)
MmsValueCache_lookupValue(MmsValueCache self, const char* itemId, MmsVariableSpecification** outSpec)
{
/*
* get value for first matching key substring!
@ -133,14 +138,20 @@ MmsValueCache_lookupValue(MmsValueCache self, const char* itemId)
char* parentItemId = getParentSubString(itemIdCopy);
if (parentItemId != NULL) {
value = searchCacheForValue(self, itemId, parentItemId);
value = searchCacheForValue(self, itemId, parentItemId, outSpec);
}
GLOBAL_FREEMEM(itemIdCopy);
}
if (cacheEntry != NULL)
if (cacheEntry != NULL) {
if (outSpec) {
*outSpec = cacheEntry->typeSpec;
}
return cacheEntry->value;
}
else
return value;
}

@ -1565,12 +1565,41 @@ public class StaticModelGenerator {
if (fcda.getDaName() != null)
mmsVariableName += "$" + toMmsString(fcda.getDaName());
// TODO implement index processing!
int arrayStart = mmsVariableName.indexOf('(');
String variableName = mmsVariableName;
int arrayIndex = -1;
String componentName = null;
if (arrayStart != -1) {
variableName = mmsVariableName.substring(0, arrayStart);
int arrayEnd = mmsVariableName.indexOf(')');
String arrayIndexStr = mmsVariableName.substring(arrayStart + 1, arrayEnd);
arrayIndex = Integer.parseInt(arrayIndexStr);
String componentNamePart = mmsVariableName.substring(arrayEnd + 1);
if ((componentNamePart != null) && (componentNamePart.length() > 0)) {
if (componentNamePart.charAt(0) == '$') {
componentNamePart = componentNamePart.substring(1);
}
if ((componentNamePart != null) && (componentNamePart.length() > 0))
componentName = componentNamePart;
}
}
cOut.println(" false,");
cOut.println(" \"" + mmsVariableName + "\",");
cOut.println(" -1,");
cOut.println(" NULL,");
cOut.println(" \"" + variableName + "\", ");
cOut.println(" " + arrayIndex + ",");
if (componentName == null)
cOut.println(" NULL,");
else
cOut.println(" \"" + componentName + "\",");
cOut.println(" NULL,");
if (fcdaCount + 1 < numberOfFcdas)

Loading…
Cancel
Save