From 99c0c8bc75a3189ca11bfa9c5a487c0273541e53 Mon Sep 17 00:00:00 2001 From: Michael Zillgith Date: Fri, 23 Jun 2017 23:41:07 +0200 Subject: [PATCH] - added IedModel_getDeviceByInst function --- src/iec61850/inc/iec61850_model.h | 96 +++++++++++++++++++++++-------- src/iec61850/server/model/model.c | 30 +++++++--- src/vs/libiec61850-wo-goose.def | 2 + src/vs/libiec61850.def | 2 + 4 files changed, 98 insertions(+), 32 deletions(-) diff --git a/src/iec61850/inc/iec61850_model.h b/src/iec61850/inc/iec61850_model.h index 0b37007..d4fbcb7 100644 --- a/src/iec61850/inc/iec61850_model.h +++ b/src/iec61850/inc/iec61850_model.h @@ -389,7 +389,11 @@ char* ModelNode_getObjectReference(ModelNode* self, char* objectReference); /** + * \brief Get the type of the ModelNode * + * \param self the ModelNode instance + * + * \return the type of the ModelNode (one of LD, LN, DO, DA) */ ModelNodeType ModelNode_getType(ModelNode* self); @@ -413,13 +417,13 @@ IedModel_setIedName(IedModel* self, const char* iedName); * as it happens to appear on the wire. E.g. if IED name in SCL file would be "IED1" * and the logical device "WD1" the resulting LD name would be "IED1WD". * - * \param model the IedModel instance that holds the model node + * \param self the IedModel instance that holds the model node * \param objectReference the IEC 61850 object reference * * \return the model node instance or NULL if model node does not exist. */ ModelNode* -IedModel_getModelNodeByObjectReference(IedModel* model, const char* objectReference); +IedModel_getModelNodeByObjectReference(IedModel* self, const char* objectReference); SVControlBlock* IedModel_getSVControlBlock(IedModel* self, LogicalNode* parentLN, const char* svcbName); @@ -431,13 +435,13 @@ IedModel_getSVControlBlock(IedModel* self, LogicalNode* parentLN, const char* sv * IED name as part of the logical device name. This function is useful for * devices where the IED name can be configured. * - * \param model the IedModel instance that holds the model node + * \param self the IedModel instance that holds the model node * \param objectReference the IEC 61850 object reference * * \return the model node instance or NULL if model node does not exist. */ ModelNode* -IedModel_getModelNodeByShortObjectReference(IedModel* model, const char* objectReference); +IedModel_getModelNodeByShortObjectReference(IedModel* self, const char* objectReference); /** * \brief Lookup a model node by its short address @@ -445,13 +449,25 @@ IedModel_getModelNodeByShortObjectReference(IedModel* model, const char* objectR * Short address is a 32 bit unsigned integer as specified in the "sAddr" attribute of * the ICD file or in the configuration file. * - * \param model the IedModel instance that holds the model node + * \param self the IedModel instance that holds the model node * \param shortAddress * * \return the model node instance or NULL if model node does not exist. */ ModelNode* -IedModel_getModelNodeByShortAddress(IedModel* model, uint32_t shortAddress); +IedModel_getModelNodeByShortAddress(IedModel* self, uint32_t shortAddress); + +/** + * \brief Lookup logical device (LD) by device instance name (SCL attribute "inst") + * + * \param self IedModel instance + * \param ldInst the logical device instance name (SCL attribute "inst") + * + * \return The matching LogicalDevice instance + */ +LogicalDevice* +IedModel_getDeviceByInst(IedModel* self, const char* ldInst); + /** * \brief Lookup a logical node by name that is part of the given logical device @@ -462,7 +478,7 @@ IedModel_getModelNodeByShortAddress(IedModel* model, uint32_t shortAddress); * \return the logical device instance or NULL if it does not exist */ LogicalNode* -LogicalDevice_getLogicalNode(LogicalDevice* device, const char* lnName); +LogicalDevice_getLogicalNode(LogicalDevice* self, const char* lnName); /** * \brief Get the setting group control block (SGCB) of the logical device @@ -472,7 +488,7 @@ LogicalDevice_getLogicalNode(LogicalDevice* device, const char* lnName); * \return the SGCB instance or NULL if no SGCB is available */ SettingGroupControlBlock* -LogicalDevice_getSettingGroupControlBlock(LogicalDevice* device); +LogicalDevice_getSettingGroupControlBlock(LogicalDevice* self); /**@}*/ @@ -482,37 +498,69 @@ LogicalDevice_getSettingGroupControlBlock(LogicalDevice* device); /** * \brief unset all MmsValue references in the data model * - * \param model the IedModel instance that holds the model node + * \param self the IedModel instance that holds the model node */ void -IedModel_setAttributeValuesToNull(IedModel* iedModel); +IedModel_setAttributeValuesToNull(IedModel* self); +/** + * \brief Lookup logical device (LD) by device name + * + * \param self IedModel instance + * \param ldInst the logical device name (as it is seen from the protocol side - MMS domain name) + * + * \return The matching LogicalDevice instance + */ LogicalDevice* -IedModel_getDevice(IedModel* model, const char* deviceName); +IedModel_getDevice(IedModel* self, const char* ldName); -/* - * \param dataSetReference MMS mapping object reference! e.g. ied1Inverter/LLN0$dataset1 +/** + * \brief Lookup a data set in the IED model + * + * \param self IedModel instance + * \param dataSetReference MMS mapping object reference! e.g. ied1Inverter/LLN0$dataset1 + * + * \return The matching DataSet instance */ DataSet* -IedModel_lookupDataSet(IedModel* model, const char* dataSetReference); +IedModel_lookupDataSet(IedModel* self, const char* dataSetReference); + +/** + * \brief Lookup a DataAttribute instance with the corresponding MmsValue instance + * + * \param self IedModel instance + * \param value the MmsValue instance (from the MMS value cache) + * + * \return the matching DataAttribute instance + */ +DataAttribute* +IedModel_lookupDataAttributeByMmsValue(IedModel* self, MmsValue* value); + + +/** + * \brief Get the number of logical devices + * + * \param self IedModel instance + * + * \return the number of logical devices + */ +int +IedModel_getLogicalDeviceCount(IedModel* self); int -IedModel_getLogicalDeviceCount(IedModel* iedModel); - -int -LogicalDevice_getLogicalNodeCount(LogicalDevice* logicalDevice); +LogicalDevice_getLogicalNodeCount(LogicalDevice* self); ModelNode* -LogicalDevice_getChildByMmsVariableName(LogicalDevice* logicalDevice, const char* mmsVariableName); +LogicalDevice_getChildByMmsVariableName(LogicalDevice* self, const char* mmsVariableName); bool -LogicalNode_hasFCData(LogicalNode* node, FunctionalConstraint fc); +LogicalNode_hasFCData(LogicalNode* self, FunctionalConstraint fc); bool -LogicalNode_hasBufferedReports(LogicalNode* node); +LogicalNode_hasBufferedReports(LogicalNode* self); bool -LogicalNode_hasUnbufferedReports(LogicalNode* node); +LogicalNode_hasUnbufferedReports(LogicalNode* self); /** * \brief get a data set instance @@ -526,10 +574,8 @@ DataSet* LogicalNode_getDataSet(LogicalNode* self, const char* dataSetName); bool -DataObject_hasFCData(DataObject* dataObject, FunctionalConstraint fc); +DataObject_hasFCData(DataObject* self, FunctionalConstraint fc); -DataAttribute* -IedModel_lookupDataAttributeByMmsValue(IedModel* model, MmsValue* value); #ifdef __cplusplus } diff --git a/src/iec61850/server/model/model.c b/src/iec61850/server/model/model.c index 03a0092..6c709b9 100644 --- a/src/iec61850/server/model/model.c +++ b/src/iec61850/server/model/model.c @@ -93,9 +93,9 @@ IedModel_getLogicalDeviceCount(IedModel* iedModel) } DataSet* -IedModel_lookupDataSet(IedModel* model, const char* dataSetReference /* e.g. ied1Inverter/LLN0$dataset1 */) +IedModel_lookupDataSet(IedModel* self, const char* dataSetReference /* e.g. ied1Inverter/LLN0$dataset1 */) { - DataSet* dataSet = model->dataSets; + DataSet* dataSet = self->dataSets; const char* separator = strchr(dataSetReference, '/'); @@ -106,9 +106,9 @@ IedModel_lookupDataSet(IedModel* model, const char* dataSetReference /* e.g. ie char domainName[65]; - int modelNameLen = strlen(model->name); + int modelNameLen = strlen(self->name); - memcpy(domainName, model->name, modelNameLen); + memcpy(domainName, self->name, modelNameLen); while (dataSet != NULL) { @@ -129,15 +129,15 @@ IedModel_lookupDataSet(IedModel* model, const char* dataSetReference /* e.g. ie } LogicalDevice* -IedModel_getDevice(IedModel* model, const char* deviceName) +IedModel_getDevice(IedModel* self, const char* deviceName) { - LogicalDevice* device = model->firstChild; + LogicalDevice* device = self->firstChild; while (device != NULL) { char domainName[65]; - strncpy(domainName, model->name, 64); + strncpy(domainName, self->name, 64); strncat(domainName, device->name, 64); if (strcmp(domainName, deviceName) == 0) @@ -149,6 +149,22 @@ IedModel_getDevice(IedModel* model, const char* deviceName) return NULL; } +LogicalDevice* +IedModel_getDeviceByInst(IedModel* self, const char* ldInst) +{ + LogicalDevice* device = self->firstChild; + + while (device != NULL) { + + if (strcmp(device->name, ldInst) == 0) + return device; + + device = (LogicalDevice*) device->sibling; + } + + return NULL; +} + static DataAttribute* ModelNode_getDataAttributeByMmsValue(ModelNode* self, MmsValue* value) { diff --git a/src/vs/libiec61850-wo-goose.def b/src/vs/libiec61850-wo-goose.def index 757cbcc..f7388f5 100644 --- a/src/vs/libiec61850-wo-goose.def +++ b/src/vs/libiec61850-wo-goose.def @@ -569,3 +569,5 @@ EXPORTS IedConnection_setFilestoreBasepath IedServer_setFilestoreBasepath GooseReceiver_isRunning + IedModel_getDeviceByInst + \ No newline at end of file diff --git a/src/vs/libiec61850.def b/src/vs/libiec61850.def index ef9e200..52e6cbf 100644 --- a/src/vs/libiec61850.def +++ b/src/vs/libiec61850.def @@ -647,3 +647,5 @@ EXPORTS IedConnection_setFilestoreBasepath IedServer_setFilestoreBasepath GooseReceiver_isRunning + IedModel_getDeviceByInst + \ No newline at end of file