- IEC 61850 common: moved some internal code to better seperate

client/server side code
pull/179/head
Michael Zillgith 6 years ago
parent 16c061b4df
commit ebc71d9731

@ -442,6 +442,340 @@ Timestamp_toMmsValue(Timestamp* self, MmsValue* mmsValue)
return convertedValue;
}
char*
MmsMapping_getMmsDomainFromObjectReference(const char* objectReference, char* buffer)
{
int objRefLength = strlen(objectReference);
char* domainName = NULL;
/* check for object reference size limit VISIBLESTRING129 */
if (objRefLength > 129)
goto exit_function;
/* check if LD name is present */
int i;
for (i = 0; i < objRefLength; i++) {
if (objectReference[i] == '/') {
break;
}
}
/* check for LD name limit (=64 characters) */
if (i > 64)
goto exit_function;
if (i == objRefLength)
goto exit_function;
if (buffer == NULL)
domainName = (char*) GLOBAL_MALLOC(i + 1);
else
domainName = buffer;
int j;
for (j = 0; j < i; j++) {
domainName[j] = objectReference[j];
}
domainName[j] = 0;
exit_function:
return domainName;
}
char*
MmsMapping_createMmsVariableNameFromObjectReference(const char* objectReference,
FunctionalConstraint fc, char* buffer)
{
int objRefLength = strlen(objectReference);
/* check for object reference size limit VISIBLESTRING129 */
if (objRefLength > 129)
return NULL;
/* check if LD name is present */
int i;
for (i = 0; i < objRefLength; i++) {
if (objectReference[i] == '/') {
break;
}
}
/* check for LD name limit (= 64 characters) */
if (i > 64)
return NULL;
if (i == objRefLength)
i = 0; /* for the case when no LD name is present */
else
i++;
if (fc == IEC61850_FC_NONE) {
int len = objRefLength - i;
char* mmsVariableName;
if (buffer == NULL)
mmsVariableName = (char*) GLOBAL_MALLOC(len);
else
mmsVariableName = buffer;
strcpy(mmsVariableName, objectReference + i);
return mmsVariableName;
}
char* fcString = FunctionalConstraint_toString(fc);
if (fcString == NULL)
return NULL;
int namePartLength = objRefLength - i - 1;
/* ensure that limit due to MMS name part length = 64 is not exceeded */
if (namePartLength > 61)
return NULL;
char* mmsVariableName;
if (buffer == NULL)
mmsVariableName = (char*) GLOBAL_MALLOC(namePartLength + 5);
else
mmsVariableName = buffer;
int sourceIndex = i;
int destIndex = 0;
bool fcAdded = false;
while (sourceIndex < objRefLength) {
if (objectReference[sourceIndex] != '.')
mmsVariableName[destIndex++] = objectReference[sourceIndex++];
else {
if (!fcAdded) {
mmsVariableName[destIndex++] = '$';
mmsVariableName[destIndex++] = fcString[0];
mmsVariableName[destIndex++] = fcString[1];
mmsVariableName[destIndex++] = '$';
fcAdded = true;
}
else
mmsVariableName[destIndex++] = '$';
sourceIndex++;
}
}
if (!fcAdded) {
mmsVariableName[destIndex++] = '$';
mmsVariableName[destIndex++] = fcString[0];
mmsVariableName[destIndex++] = fcString[1];
}
mmsVariableName[destIndex] = 0;
return mmsVariableName;
}
MmsVariableAccessSpecification*
MmsMapping_ObjectReferenceToVariableAccessSpec(char* objectReference)
{
char* domainIdEnd = strchr(objectReference, '/');
if (domainIdEnd == NULL) /* no logical device name present */
return NULL;
int domainIdLen = domainIdEnd - objectReference;
if (domainIdLen > 64)
return NULL;
char* fcStart = strchr(objectReference, '[');
if (fcStart == NULL) /* no FC present */
return NULL;
char* fcEnd = strchr(fcStart, ']');
if (fcEnd == NULL) /* syntax error in FC */
return NULL;
if ((fcEnd - fcStart) != 3) /* syntax error in FC */
return NULL;
FunctionalConstraint fc = FunctionalConstraint_fromString(fcStart + 1);
MmsVariableAccessSpecification* accessSpec =
(MmsVariableAccessSpecification*) GLOBAL_CALLOC(1, sizeof(MmsVariableAccessSpecification));
accessSpec->domainId = StringUtils_createStringFromBuffer((uint8_t*) objectReference, domainIdLen);
char* indexBrace = strchr(domainIdEnd, '(');
char* itemIdEnd = indexBrace;
if (itemIdEnd == NULL)
itemIdEnd = strchr(domainIdEnd, '[');
int objRefLen = strlen(objectReference);
accessSpec->arrayIndex = -1; /* -1 --> not present */
if (itemIdEnd != NULL) {
int itemIdLen = itemIdEnd - domainIdEnd - 1;
char itemIdStr[129];
memcpy(itemIdStr, (domainIdEnd + 1), itemIdLen);
itemIdStr[itemIdLen] = 0;
accessSpec->itemId = MmsMapping_createMmsVariableNameFromObjectReference(itemIdStr, fc, NULL);
if (indexBrace != NULL) {
char* indexStart = itemIdEnd + 1;
char* indexEnd = strchr(indexStart, ')');
int indexLen = indexEnd - indexStart;
int index = StringUtils_digitsToInt(indexStart, indexLen);
accessSpec->arrayIndex = (int32_t) index;
int componentNameLen = objRefLen - ((indexEnd + 2) - objectReference) - 4;
if (componentNameLen > 0) {
accessSpec->componentName = StringUtils_createStringFromBuffer((uint8_t*) (indexEnd + 2), componentNameLen);
StringUtils_replace(accessSpec->componentName, '.', '$');
}
}
}
return accessSpec;
}
static int
getNumberOfDigits(int value)
{
int numberOfDigits = 1;
while (value > 9) {
numberOfDigits++;
value /= 10;
}
return numberOfDigits;
}
char*
MmsMapping_varAccessSpecToObjectReference(MmsVariableAccessSpecification* varAccessSpec)
{
char* domainId = varAccessSpec->domainId;
int domainIdLen = strlen(domainId);
char* itemId = varAccessSpec->itemId;
char* separator = strchr(itemId, '$');
int itemIdLen = strlen(itemId);
int arrayIndexLen = 0;
int componentPartLen = 0;
if (varAccessSpec->componentName != NULL)
componentPartLen = strlen(varAccessSpec->componentName);
if (varAccessSpec->arrayIndex > -1)
arrayIndexLen = 2 + getNumberOfDigits(varAccessSpec->arrayIndex);
int newStringLen = (domainIdLen + 1) + (itemIdLen - 2) + arrayIndexLen + 4 /* for FC */+ componentPartLen + 1;
char* newString = (char*) GLOBAL_MALLOC(newStringLen);
char* targetPos = newString;
/* Copy domain id part */
char* currentPos = domainId;
while (currentPos < (domainId + domainIdLen)) {
*targetPos = *currentPos;
targetPos++;
currentPos++;
}
*targetPos = '/';
targetPos++;
/* Copy item id parts */
currentPos = itemId;
while (currentPos < separator) {
*targetPos = *currentPos;
targetPos++;
currentPos++;
}
*targetPos = '.';
targetPos++;
currentPos = separator + 4;
while (currentPos < (itemId + itemIdLen)) {
if (*currentPos == '$')
*targetPos = '.';
else
*targetPos = *currentPos;
targetPos++;
currentPos++;
}
/* Add array index part */
if (varAccessSpec->arrayIndex > -1) {
sprintf(targetPos, "(%i)", varAccessSpec->arrayIndex);
targetPos += arrayIndexLen;
}
/* Add component part */
if (varAccessSpec->componentName != NULL) {
*targetPos = '.';
targetPos++;
int i;
for (i = 0; i < componentPartLen; i++) {
if (varAccessSpec->componentName[i] == '$')
*targetPos = '.';
else
*targetPos = varAccessSpec->componentName[i];
targetPos++;
}
}
/* add FC part */
*targetPos = '[';
targetPos++;
*targetPos = *(separator + 1);
targetPos++;
*targetPos = *(separator + 2);
targetPos++;
*targetPos = ']';
targetPos++;
*targetPos = 0; /* add terminator */
return newString;
}
char*
LibIEC61850_getVersionString()
{

@ -0,0 +1,41 @@
/*
* iec61850_common_internal.h
*
* Copyright 2019 Michael Zillgith
*
* This file is part of libIEC61850.
*
* libIEC61850 is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* libIEC61850 is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with libIEC61850. If not, see <http://www.gnu.org/licenses/>.
*
* See COPYING file for the complete license text.
*/
#ifndef SRC_IEC61850_INC_PRIVATE_IEC61850_COMMON_INTERNAL_H_
#define SRC_IEC61850_INC_PRIVATE_IEC61850_COMMON_INTERNAL_H_
#include "iec61850_model.h"
LIB61850_INTERNAL char*
MmsMapping_getMmsDomainFromObjectReference(const char* objectReference, char* buffer);
LIB61850_INTERNAL char*
MmsMapping_createMmsVariableNameFromObjectReference(const char* objectReference, FunctionalConstraint fc, char* buffer);
LIB61850_INTERNAL MmsVariableAccessSpecification*
MmsMapping_ObjectReferenceToVariableAccessSpec(char* objectReference);
LIB61850_INTERNAL char*
MmsMapping_varAccessSpecToObjectReference(MmsVariableAccessSpecification* varAccessSpec);
#endif /* SRC_IEC61850_INC_PRIVATE_IEC61850_COMMON_INTERNAL_H_ */

@ -24,7 +24,7 @@
#ifndef MMS_MAPPING_H_
#define MMS_MAPPING_H_
#include "iec61850_model.h"
#include "iec61850_common_internal.h"
#include "mms_device_model.h"
#include "control.h"
@ -106,15 +106,9 @@ MmsMapping_enableGoosePublishing(MmsMapping* self);
LIB61850_INTERNAL void
MmsMapping_disableGoosePublishing(MmsMapping* self);
LIB61850_INTERNAL char*
MmsMapping_getMmsDomainFromObjectReference(const char* objectReference, char* buffer);
LIB61850_INTERNAL void
MmsMapping_addControlObject(MmsMapping* self, ControlObject* controlObject);
LIB61850_INTERNAL char*
MmsMapping_createMmsVariableNameFromObjectReference(const char* objectReference, FunctionalConstraint fc, char* buffer);
LIB61850_INTERNAL char*
MmsMapping_getNextNameElement(char* name);
@ -133,12 +127,6 @@ MmsMapping_getDomainSpecificDataSet(MmsMapping* self, const char* dataSetName);
LIB61850_INTERNAL void
MmsMapping_freeDynamicallyCreatedDataSet(DataSet* dataSet);
LIB61850_INTERNAL MmsVariableAccessSpecification*
MmsMapping_ObjectReferenceToVariableAccessSpec(char* objectReference);
LIB61850_INTERNAL char*
MmsMapping_varAccessSpecToObjectReference(MmsVariableAccessSpecification* varAccessSpec);
LIB61850_INTERNAL void
MmsMapping_setConnectionIndicationHandler(MmsMapping* self, IedConnectionIndicationHandler handler, void* parameter);

@ -2948,147 +2948,6 @@ MmsMapping_getControlObject(MmsMapping* self, MmsDomain* domain, char* lnName, c
}
#endif /* (CONFIG_IEC61850_CONTROL_SERVICE == 1) */
char*
MmsMapping_getMmsDomainFromObjectReference(const char* objectReference, char* buffer)
{
int objRefLength = strlen(objectReference);
char* domainName = NULL;
/* check for object reference size limit VISIBLESTRING129 */
if (objRefLength > 129)
goto exit_function;
/* check if LD name is present */
int i;
for (i = 0; i < objRefLength; i++) {
if (objectReference[i] == '/') {
break;
}
}
/* check for LD name limit (=64 characters) */
if (i > 64)
goto exit_function;
if (i == objRefLength)
goto exit_function;
if (buffer == NULL)
domainName = (char*) GLOBAL_MALLOC(i + 1);
else
domainName = buffer;
int j;
for (j = 0; j < i; j++) {
domainName[j] = objectReference[j];
}
domainName[j] = 0;
exit_function:
return domainName;
}
char*
MmsMapping_createMmsVariableNameFromObjectReference(const char* objectReference,
FunctionalConstraint fc, char* buffer)
{
int objRefLength = strlen(objectReference);
/* check for object reference size limit VISIBLESTRING129 */
if (objRefLength > 129)
return NULL;
/* check if LD name is present */
int i;
for (i = 0; i < objRefLength; i++) {
if (objectReference[i] == '/') {
break;
}
}
/* check for LD name limit (= 64 characters) */
if (i > 64)
return NULL;
if (i == objRefLength)
i = 0; /* for the case when no LD name is present */
else
i++;
if (fc == IEC61850_FC_NONE) {
int len = objRefLength - i;
char* mmsVariableName;
if (buffer == NULL)
mmsVariableName = (char*) GLOBAL_MALLOC(len);
else
mmsVariableName = buffer;
strcpy(mmsVariableName, objectReference + i);
return mmsVariableName;
}
char* fcString = FunctionalConstraint_toString(fc);
if (fcString == NULL)
return NULL;
int namePartLength = objRefLength - i - 1;
/* ensure that limit due to MMS name part length = 64 is not exceeded */
if (namePartLength > 61)
return NULL;
char* mmsVariableName;
if (buffer == NULL)
mmsVariableName = (char*) GLOBAL_MALLOC(namePartLength + 5);
else
mmsVariableName = buffer;
int sourceIndex = i;
int destIndex = 0;
bool fcAdded = false;
while (sourceIndex < objRefLength) {
if (objectReference[sourceIndex] != '.')
mmsVariableName[destIndex++] = objectReference[sourceIndex++];
else {
if (!fcAdded) {
mmsVariableName[destIndex++] = '$';
mmsVariableName[destIndex++] = fcString[0];
mmsVariableName[destIndex++] = fcString[1];
mmsVariableName[destIndex++] = '$';
fcAdded = true;
}
else
mmsVariableName[destIndex++] = '$';
sourceIndex++;
}
}
if (!fcAdded) {
mmsVariableName[destIndex++] = '$';
mmsVariableName[destIndex++] = fcString[0];
mmsVariableName[destIndex++] = fcString[1];
}
mmsVariableName[destIndex] = 0;
return mmsVariableName;
}
#if (CONFIG_INCLUDE_GOOSE_SUPPORT == 1)
static void
@ -3293,197 +3152,3 @@ MmsMapping_freeDynamicallyCreatedDataSet(DataSet* dataSet)
GLOBAL_FREEMEM(dataSet);
}
MmsVariableAccessSpecification*
MmsMapping_ObjectReferenceToVariableAccessSpec(char* objectReference)
{
char* domainIdEnd = strchr(objectReference, '/');
if (domainIdEnd == NULL) /* no logical device name present */
return NULL;
int domainIdLen = domainIdEnd - objectReference;
if (domainIdLen > 64)
return NULL;
char* fcStart = strchr(objectReference, '[');
if (fcStart == NULL) /* no FC present */
return NULL;
char* fcEnd = strchr(fcStart, ']');
if (fcEnd == NULL) /* syntax error in FC */
return NULL;
if ((fcEnd - fcStart) != 3) /* syntax error in FC */
return NULL;
FunctionalConstraint fc = FunctionalConstraint_fromString(fcStart + 1);
MmsVariableAccessSpecification* accessSpec =
(MmsVariableAccessSpecification*) GLOBAL_CALLOC(1, sizeof(MmsVariableAccessSpecification));
accessSpec->domainId = StringUtils_createStringFromBuffer((uint8_t*) objectReference, domainIdLen);
char* indexBrace = strchr(domainIdEnd, '(');
char* itemIdEnd = indexBrace;
if (itemIdEnd == NULL)
itemIdEnd = strchr(domainIdEnd, '[');
int objRefLen = strlen(objectReference);
accessSpec->arrayIndex = -1; /* -1 --> not present */
if (itemIdEnd != NULL) {
int itemIdLen = itemIdEnd - domainIdEnd - 1;
char itemIdStr[129];
memcpy(itemIdStr, (domainIdEnd + 1), itemIdLen);
itemIdStr[itemIdLen] = 0;
accessSpec->itemId = MmsMapping_createMmsVariableNameFromObjectReference(itemIdStr, fc, NULL);
if (indexBrace != NULL) {
char* indexStart = itemIdEnd + 1;
char* indexEnd = strchr(indexStart, ')');
int indexLen = indexEnd - indexStart;
int index = StringUtils_digitsToInt(indexStart, indexLen);
accessSpec->arrayIndex = (int32_t) index;
int componentNameLen = objRefLen - ((indexEnd + 2) - objectReference) - 4;
if (componentNameLen > 0) {
accessSpec->componentName = StringUtils_createStringFromBuffer((uint8_t*) (indexEnd + 2), componentNameLen);
StringUtils_replace(accessSpec->componentName, '.', '$');
}
}
}
return accessSpec;
}
static int
getNumberOfDigits(int value)
{
int numberOfDigits = 1;
while (value > 9) {
numberOfDigits++;
value /= 10;
}
return numberOfDigits;
}
char*
MmsMapping_varAccessSpecToObjectReference(MmsVariableAccessSpecification* varAccessSpec)
{
char* domainId = varAccessSpec->domainId;
int domainIdLen = strlen(domainId);
char* itemId = varAccessSpec->itemId;
char* separator = strchr(itemId, '$');
int itemIdLen = strlen(itemId);
int arrayIndexLen = 0;
int componentPartLen = 0;
if (varAccessSpec->componentName != NULL)
componentPartLen = strlen(varAccessSpec->componentName);
if (varAccessSpec->arrayIndex > -1)
arrayIndexLen = 2 + getNumberOfDigits(varAccessSpec->arrayIndex);
int newStringLen = (domainIdLen + 1) + (itemIdLen - 2) + arrayIndexLen + 4 /* for FC */+ componentPartLen + 1;
char* newString = (char*) GLOBAL_MALLOC(newStringLen);
char* targetPos = newString;
/* Copy domain id part */
char* currentPos = domainId;
while (currentPos < (domainId + domainIdLen)) {
*targetPos = *currentPos;
targetPos++;
currentPos++;
}
*targetPos = '/';
targetPos++;
/* Copy item id parts */
currentPos = itemId;
while (currentPos < separator) {
*targetPos = *currentPos;
targetPos++;
currentPos++;
}
*targetPos = '.';
targetPos++;
currentPos = separator + 4;
while (currentPos < (itemId + itemIdLen)) {
if (*currentPos == '$')
*targetPos = '.';
else
*targetPos = *currentPos;
targetPos++;
currentPos++;
}
/* Add array index part */
if (varAccessSpec->arrayIndex > -1) {
sprintf(targetPos, "(%i)", varAccessSpec->arrayIndex);
targetPos += arrayIndexLen;
}
/* Add component part */
if (varAccessSpec->componentName != NULL) {
*targetPos = '.';
targetPos++;
int i;
for (i = 0; i < componentPartLen; i++) {
if (varAccessSpec->componentName[i] == '$')
*targetPos = '.';
else
*targetPos = varAccessSpec->componentName[i];
targetPos++;
}
}
/* add FC part */
*targetPos = '[';
targetPos++;
*targetPos = *(separator + 1);
targetPos++;
*targetPos = *(separator + 2);
targetPos++;
*targetPos = ']';
targetPos++;
*targetPos = 0; /* add terminator */
return newString;
}

Loading…
Cancel
Save