- fixed bug in reporting when write to RptEna=false when RptEna already is false

- allow client to set data set in RCB to empty string
- data set deletion will be denied if data set is referenced in a RCB
This commit is contained in:
Michael Zillgith 2015-02-06 12:41:53 +01:00
parent e461a0fb46
commit 1a95580f94
5 changed files with 120 additions and 19 deletions

View file

@ -1048,7 +1048,7 @@ createDataSets(MmsDevice* mmsDevice, IedModel* iedModel)
MmsDomain* dataSetDomain = MmsDevice_getDomain(mmsDevice, domainName);
MmsNamedVariableList varList = MmsNamedVariableList_create(dataset->name, false);
MmsNamedVariableList varList = MmsNamedVariableList_create(dataSetDomain, dataset->name, false);
DataSetEntry* dataSetEntry = dataset->fcdas;
@ -2052,6 +2052,73 @@ mmsReadAccessHandler (void* parameter, MmsDomain* domain, char* variableId, MmsS
return DATA_ACCESS_ERROR_SUCCESS;
}
static bool
variableListChangedHandler (void* parameter, bool create, MmsVariableListType listType, MmsDomain* domain,
char* listName, MmsServerConnection* connection)
{
bool allow = true;
#if (DEBUG_IED_SERVER == 1)
if (create)
printf("create data set ");
else
printf("delete data set ");
switch (listType) {
case MMS_VMD_SPECIFIC:
printf("VMD ");
break;
case MMS_ASSOCIATION_SPECIFIC:
printf("association ");
break;
case MMS_DOMAIN_SPECIFIC:
printf("domain ");
break;
}
printf("specific (name=%s)\n", listName);
#endif /* (DEBUG_IED_SERVER == 1) */
MmsMapping* self = (MmsMapping*) parameter;
if (create == false) {
/* Check if data set is referenced in a report */
LinkedList element = self->reportControls;
while ((element = LinkedList_getNext(element)) != NULL) {
ReportControl* rc = (ReportControl*) element->data;
if (rc->isDynamicDataSet) {
if (rc->dataSet != NULL) {
if (listType == MMS_DOMAIN_SPECIFIC) {
if (rc->dataSet->logicalDeviceName != NULL) {
if (strcmp(rc->dataSet->name, listName) == 0) {
if (strcmp(rc->dataSet->logicalDeviceName, MmsDomain_getName(domain)) == 0) {
allow = false;
break;
}
}
}
}
else if (listType == MMS_ASSOCIATION_SPECIFIC) {
if (rc->dataSet->logicalDeviceName == NULL) {
if (strcmp(rc->dataSet->name, listName) == 0) {
allow = false;
break;
}
}
}
}
}
}
}
return allow;
}
void
MmsMapping_installHandlers(MmsMapping* self)
{
@ -2059,6 +2126,7 @@ MmsMapping_installHandlers(MmsMapping* self)
MmsServer_installWriteHandler(self->mmsServer, mmsWriteHandler, (void*) self);
MmsServer_installReadAccessHandler(self->mmsServer, mmsReadAccessHandler, (void*) self);
MmsServer_installConnectionHandler(self->mmsServer, mmsConnectionHandler, (void*) self);
MmsServer_installVariableListChangedHandler(self->mmsServer, variableListChangedHandler, (void*) self);
}
void
@ -2446,7 +2514,10 @@ MmsMapping_createDataSetByNamedVariableList(MmsMapping* self, MmsNamedVariableLi
{
DataSet* dataSet = (DataSet*) GLOBAL_MALLOC(sizeof(DataSet));
dataSet->logicalDeviceName = NULL; /* name is not relevant for dynamically created data set */
if (variableList->domain != NULL)
dataSet->logicalDeviceName = MmsDomain_getName(variableList->domain);
else
dataSet->logicalDeviceName = NULL; /* name is not relevant for association specific data sets */
dataSet->name = variableList->name;
dataSet->elementCount = LinkedList_size(variableList->listOfVariables);

View file

@ -468,13 +468,17 @@ updateReportDataset(MmsMapping* mapping, ReportControl* rc, MmsValue* newDatSet,
MmsValue* dataSetValue;
if (newDatSet != NULL)
dataSetValue = newDatSet;
if (newDatSet != NULL) {
if (strcmp(MmsValue_toString(newDatSet), "") == 0) {
success = true;
dataSetValue = NULL;
}
else
dataSetValue = newDatSet;
}
else
dataSetValue = ReportControl_getRCBValue(rc, "DatSet");
char* dataSetName = MmsValue_toString(dataSetValue);
if (rc->isDynamicDataSet) {
if (rc->dataSet != NULL) {
deleteDataSetValuesShadowBuffer(rc);
@ -485,6 +489,8 @@ updateReportDataset(MmsMapping* mapping, ReportControl* rc, MmsValue* newDatSet,
}
if (dataSetValue != NULL) {
char* dataSetName = MmsValue_toString(dataSetValue);
DataSet* dataSet = IedModel_lookupDataSet(mapping->model, dataSetName);
if (dataSet == NULL) {
@ -1084,10 +1090,10 @@ updateOwner(ReportControl* rc, MmsServerConnection* connection)
if (connection != NULL) {
char* clientAddressString = MmsServerConnection_getClientAddress(connection);
if (DEBUG_IED_SERVER) printf("reporting.c: set owner to %s\n", clientAddressString);
if (DEBUG_IED_SERVER) printf("IED_SERVER: reporting.c: set owner to %s\n", clientAddressString);
if (strchr(clientAddressString, '.') != NULL) {
if (DEBUG_IED_SERVER) printf("reporting.c: client address is IPv4 address\n");
if (DEBUG_IED_SERVER) printf("IED_SERVER: reporting.c: client address is IPv4 address\n");
{
uint8_t ipV4Addr[4];
@ -1114,7 +1120,7 @@ updateOwner(ReportControl* rc, MmsServerConnection* connection)
else {
uint8_t ipV6Addr[16];
MmsValue_setOctetString(owner, ipV6Addr, 0);
if (DEBUG_IED_SERVER) printf("reporting.c: client address is IPv6 address or unknown\n");
if (DEBUG_IED_SERVER) printf("IED_SERVER: reporting.c: client address is IPv6 address or unknown\n");
}
}
else {
@ -1219,6 +1225,9 @@ Reporting_RCBWriteAccessHandler(MmsMapping* self, ReportControl* rc, char* eleme
}
}
else {
if (rc->enabled == false)
goto exit_function;
if (((rc->enabled) || (rc->reserved)) && (rc->clientConnection != connection)) {
retVal = DATA_ACCESS_ERROR_TEMPORARILY_UNAVAILABLE;
goto exit_function;
@ -1247,7 +1256,10 @@ Reporting_RCBWriteAccessHandler(MmsMapping* self, ReportControl* rc, char* eleme
if (strcmp(elementName, "GI") == 0) {
if ((rc->enabled) && (rc->clientConnection == connection)) {
rc->gi = true;
if (MmsValue_getBoolean(value))
rc->gi = true;
retVal = DATA_ACCESS_ERROR_SUCCESS;
goto exit_function;
}
@ -1299,7 +1311,6 @@ Reporting_RCBWriteAccessHandler(MmsMapping* self, ReportControl* rc, char* eleme
retVal = DATA_ACCESS_ERROR_OBJECT_VALUE_INVALID;
goto exit_function;
}
}
retVal = DATA_ACCESS_ERROR_SUCCESS;
@ -1381,6 +1392,14 @@ Reporting_RCBWriteAccessHandler(MmsMapping* self, ReportControl* rc, char* eleme
goto exit_function;
}
else if (strcmp(elementName, "SqNum") == 0) {
retVal = DATA_ACCESS_ERROR_OBJECT_ACCESS_DENIED;
goto exit_function;
}
else if (strcmp(elementName, "Owner") == 0) {
retVal = DATA_ACCESS_ERROR_OBJECT_ACCESS_DENIED;
goto exit_function;
}
MmsValue* rcbValue = ReportControl_getRCBValue(rc, elementName);

View file

@ -38,6 +38,7 @@ extern "C" {
struct sMmsNamedVariableList {
bool deletable;
MmsDomain* domain;
char* name;
LinkedList listOfVariables;
};
@ -55,11 +56,14 @@ char*
MmsNamedVariableListEntry_getVariableName(MmsNamedVariableListEntry self);
MmsNamedVariableList
MmsNamedVariableList_create(char* name, bool deletable);
MmsNamedVariableList_create(MmsDomain* domain, char* name, bool deletable);
char*
MmsNamedVariableList_getName(MmsNamedVariableList self);
MmsDomain*
MmsNamedVariableList_getDomain(MmsNamedVariableList self);
bool
MmsNamedVariableList_isDeletable(MmsNamedVariableList self);

View file

@ -62,17 +62,24 @@ MmsNamedVariableListEntry_getVariableName(MmsNamedVariableListEntry self) {
}
MmsNamedVariableList
MmsNamedVariableList_create(char* name, bool deletable)
MmsNamedVariableList_create(MmsDomain* domain, char* name, bool deletable)
{
MmsNamedVariableList self = (MmsNamedVariableList) GLOBAL_MALLOC(sizeof(struct sMmsNamedVariableList));
self->deletable = deletable;
self->name = copyString(name);
self->listOfVariables = LinkedList_create();
self->domain = domain;
return self;
}
MmsDomain*
MmsNamedVariableList_getDomain(MmsNamedVariableList self)
{
return self->domain;
}
char*
MmsNamedVariableList_getName(MmsNamedVariableList self)
{

View file

@ -236,7 +236,7 @@ checkIfVariableExists(MmsDevice* device, MmsAccessSpecifier* accessSpecifier)
static MmsNamedVariableList
createNamedVariableList(MmsDevice* device,
createNamedVariableList(MmsDomain* domain, MmsDevice* device,
DefineNamedVariableListRequest_t* request,
char* variableListName, MmsError* mmsError)
{
@ -249,7 +249,7 @@ createNamedVariableList(MmsDevice* device,
goto exit_function;
}
namedVariableList = MmsNamedVariableList_create(variableListName, true);
namedVariableList = MmsNamedVariableList_create(domain, variableListName, true);
int i;
for (i = 0; i < variableCount; i++) {
@ -315,11 +315,11 @@ createNamedVariableList(MmsDevice* device,
varSpec->choice.name.choice.domainspecific.domainId.buf,
varSpec->choice.name.choice.domainspecific.domainId.size);
MmsDomain* domain = MmsDevice_getDomain(device, domainId);
MmsDomain* elementDomain = MmsDevice_getDomain(device, domainId);
MmsAccessSpecifier accessSpecifier;
accessSpecifier.domain = domain;
accessSpecifier.domain = elementDomain;
accessSpecifier.variableName = variableName;
accessSpecifier.arrayIndex = arrayIndex;
accessSpecifier.componentName = componentName;
@ -412,7 +412,7 @@ mmsServer_handleDefineNamedVariableListRequest(
else {
MmsError mmsError;
MmsNamedVariableList namedVariableList = createNamedVariableList(device,
MmsNamedVariableList namedVariableList = createNamedVariableList(domain, device,
request, variableListName, &mmsError);
if (namedVariableList != NULL) {
@ -456,7 +456,7 @@ mmsServer_handleDefineNamedVariableListRequest(
else {
MmsError mmsError;
MmsNamedVariableList namedVariableList = createNamedVariableList(device,
MmsNamedVariableList namedVariableList = createNamedVariableList(NULL, device,
request, variableListName, &mmsError);
if (namedVariableList != NULL) {