- 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:
parent
e461a0fb46
commit
1a95580f94
5 changed files with 120 additions and 19 deletions
|
@ -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);
|
||||
|
|
|
@ -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);
|
||||
|
||||
|
|
|
@ -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);
|
||||
|
||||
|
|
|
@ -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)
|
||||
{
|
||||
|
|
|
@ -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) {
|
||||
|
|
Loading…
Add table
Reference in a new issue