diff --git a/examples/server_example_service_tracking/server_example_service_tracking.c b/examples/server_example_service_tracking/server_example_service_tracking.c
index 3d7fd414..817a04a8 100644
--- a/examples/server_example_service_tracking/server_example_service_tracking.c
+++ b/examples/server_example_service_tracking/server_example_service_tracking.c
@@ -175,7 +175,7 @@ main(int argc, char** argv)
IedServerConfig_enableDynamicDataSetService(config, true);
/* disable log service */
- IedServerConfig_enableLogService(config, false);
+ IedServerConfig_enableLogService(config, true);
/* set maximum number of clients */
IedServerConfig_setMaxMmsConnections(config, 5);
diff --git a/examples/server_example_service_tracking/simpleIO_ltrk_tests.icd b/examples/server_example_service_tracking/simpleIO_ltrk_tests.icd
index 229ccbba..18434248 100644
--- a/examples/server_example_service_tracking/simpleIO_ltrk_tests.icd
+++ b/examples/server_example_service_tracking/simpleIO_ltrk_tests.icd
@@ -82,6 +82,8 @@
+
+
@@ -104,6 +106,17 @@
+
+
+
+
+
+
+
+
+
+
+
@@ -241,6 +254,7 @@
+
@@ -404,6 +418,24 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/examples/server_example_service_tracking/static_model.c b/examples/server_example_service_tracking/static_model.c
index 5b735ced..a8841232 100644
--- a/examples/server_example_service_tracking/static_model.c
+++ b/examples/server_example_service_tracking/static_model.c
@@ -223,6 +223,8 @@ extern DataSetEntry iedModelds_GenericIO_LLN0_ServiceTracking_fcda3;
extern DataSetEntry iedModelds_GenericIO_LLN0_ServiceTracking_fcda4;
extern DataSetEntry iedModelds_GenericIO_LLN0_ServiceTracking_fcda5;
extern DataSetEntry iedModelds_GenericIO_LLN0_ServiceTracking_fcda6;
+extern DataSetEntry iedModelds_GenericIO_LLN0_ServiceTracking_fcda7;
+extern DataSetEntry iedModelds_GenericIO_LLN0_ServiceTracking_fcda8;
DataSetEntry iedModelds_GenericIO_LLN0_ServiceTracking_fcda0 = {
"GenericIO",
@@ -291,13 +293,33 @@ DataSetEntry iedModelds_GenericIO_LLN0_ServiceTracking_fcda6 = {
-1,
NULL,
NULL,
+ &iedModelds_GenericIO_LLN0_ServiceTracking_fcda7
+};
+
+DataSetEntry iedModelds_GenericIO_LLN0_ServiceTracking_fcda7 = {
+ "GenericIO",
+ false,
+ "LTRK1$SR$SgcbTrk",
+ -1,
+ NULL,
+ NULL,
+ &iedModelds_GenericIO_LLN0_ServiceTracking_fcda8
+};
+
+DataSetEntry iedModelds_GenericIO_LLN0_ServiceTracking_fcda8 = {
+ "GenericIO",
+ false,
+ "LTRK1$SR$LocbTrk",
+ -1,
+ NULL,
+ NULL,
NULL
};
DataSet iedModelds_GenericIO_LLN0_ServiceTracking = {
"GenericIO",
"LLN0$ServiceTracking",
- 7,
+ 9,
&iedModelds_GenericIO_LLN0_ServiceTracking_fcda0,
NULL
};
@@ -4384,7 +4406,7 @@ DataObject iedModel_GenericIO_LTRK1_SgcbTrk = {
DataObjectModelType,
"SgcbTrk",
(ModelNode*) &iedModel_GenericIO_LTRK1,
- NULL,
+ (ModelNode*) &iedModel_GenericIO_LTRK1_LocbTrk,
(ModelNode*) &iedModel_GenericIO_LTRK1_SgcbTrk_objRef,
0
};
@@ -4597,6 +4619,236 @@ DataAttribute iedModel_GenericIO_LTRK1_SgcbTrk_resvTms = {
NULL,
0};
+DataObject iedModel_GenericIO_LTRK1_LocbTrk = {
+ DataObjectModelType,
+ "LocbTrk",
+ (ModelNode*) &iedModel_GenericIO_LTRK1,
+ NULL,
+ (ModelNode*) &iedModel_GenericIO_LTRK1_LocbTrk_objRef,
+ 0
+};
+
+DataAttribute iedModel_GenericIO_LTRK1_LocbTrk_objRef = {
+ DataAttributeModelType,
+ "objRef",
+ (ModelNode*) &iedModel_GenericIO_LTRK1_LocbTrk,
+ (ModelNode*) &iedModel_GenericIO_LTRK1_LocbTrk_serviceType,
+ NULL,
+ 0,
+ IEC61850_FC_SR,
+ IEC61850_VISIBLE_STRING_129,
+ 0 + TRG_OPT_DATA_UPDATE,
+ NULL,
+ 0};
+
+DataAttribute iedModel_GenericIO_LTRK1_LocbTrk_serviceType = {
+ DataAttributeModelType,
+ "serviceType",
+ (ModelNode*) &iedModel_GenericIO_LTRK1_LocbTrk,
+ (ModelNode*) &iedModel_GenericIO_LTRK1_LocbTrk_errorCode,
+ NULL,
+ 0,
+ IEC61850_FC_SR,
+ IEC61850_ENUMERATED,
+ 0,
+ NULL,
+ 0};
+
+DataAttribute iedModel_GenericIO_LTRK1_LocbTrk_errorCode = {
+ DataAttributeModelType,
+ "errorCode",
+ (ModelNode*) &iedModel_GenericIO_LTRK1_LocbTrk,
+ (ModelNode*) &iedModel_GenericIO_LTRK1_LocbTrk_originatorID,
+ NULL,
+ 0,
+ IEC61850_FC_SR,
+ IEC61850_ENUMERATED,
+ 0,
+ NULL,
+ 0};
+
+DataAttribute iedModel_GenericIO_LTRK1_LocbTrk_originatorID = {
+ DataAttributeModelType,
+ "originatorID",
+ (ModelNode*) &iedModel_GenericIO_LTRK1_LocbTrk,
+ (ModelNode*) &iedModel_GenericIO_LTRK1_LocbTrk_t,
+ NULL,
+ 0,
+ IEC61850_FC_SR,
+ IEC61850_OCTET_STRING_64,
+ 0,
+ NULL,
+ 0};
+
+DataAttribute iedModel_GenericIO_LTRK1_LocbTrk_t = {
+ DataAttributeModelType,
+ "t",
+ (ModelNode*) &iedModel_GenericIO_LTRK1_LocbTrk,
+ (ModelNode*) &iedModel_GenericIO_LTRK1_LocbTrk_d,
+ NULL,
+ 0,
+ IEC61850_FC_SR,
+ IEC61850_TIMESTAMP,
+ 0,
+ NULL,
+ 0};
+
+DataAttribute iedModel_GenericIO_LTRK1_LocbTrk_d = {
+ DataAttributeModelType,
+ "d",
+ (ModelNode*) &iedModel_GenericIO_LTRK1_LocbTrk,
+ (ModelNode*) &iedModel_GenericIO_LTRK1_LocbTrk_dU,
+ NULL,
+ 0,
+ IEC61850_FC_DC,
+ IEC61850_VISIBLE_STRING_255,
+ 0,
+ NULL,
+ 0};
+
+DataAttribute iedModel_GenericIO_LTRK1_LocbTrk_dU = {
+ DataAttributeModelType,
+ "dU",
+ (ModelNode*) &iedModel_GenericIO_LTRK1_LocbTrk,
+ (ModelNode*) &iedModel_GenericIO_LTRK1_LocbTrk_cdcNs,
+ NULL,
+ 0,
+ IEC61850_FC_DC,
+ IEC61850_UNICODE_STRING_255,
+ 0,
+ NULL,
+ 0};
+
+DataAttribute iedModel_GenericIO_LTRK1_LocbTrk_cdcNs = {
+ DataAttributeModelType,
+ "cdcNs",
+ (ModelNode*) &iedModel_GenericIO_LTRK1_LocbTrk,
+ (ModelNode*) &iedModel_GenericIO_LTRK1_LocbTrk_cdcName,
+ NULL,
+ 0,
+ IEC61850_FC_EX,
+ IEC61850_VISIBLE_STRING_255,
+ 0,
+ NULL,
+ 0};
+
+DataAttribute iedModel_GenericIO_LTRK1_LocbTrk_cdcName = {
+ DataAttributeModelType,
+ "cdcName",
+ (ModelNode*) &iedModel_GenericIO_LTRK1_LocbTrk,
+ (ModelNode*) &iedModel_GenericIO_LTRK1_LocbTrk_dataNs,
+ NULL,
+ 0,
+ IEC61850_FC_EX,
+ IEC61850_VISIBLE_STRING_255,
+ 0,
+ NULL,
+ 0};
+
+DataAttribute iedModel_GenericIO_LTRK1_LocbTrk_dataNs = {
+ DataAttributeModelType,
+ "dataNs",
+ (ModelNode*) &iedModel_GenericIO_LTRK1_LocbTrk,
+ (ModelNode*) &iedModel_GenericIO_LTRK1_LocbTrk_logEna,
+ NULL,
+ 0,
+ IEC61850_FC_EX,
+ IEC61850_VISIBLE_STRING_255,
+ 0,
+ NULL,
+ 0};
+
+DataAttribute iedModel_GenericIO_LTRK1_LocbTrk_logEna = {
+ DataAttributeModelType,
+ "logEna",
+ (ModelNode*) &iedModel_GenericIO_LTRK1_LocbTrk,
+ (ModelNode*) &iedModel_GenericIO_LTRK1_LocbTrk_datSet,
+ NULL,
+ 0,
+ IEC61850_FC_SR,
+ IEC61850_BOOLEAN,
+ 0,
+ NULL,
+ 0};
+
+DataAttribute iedModel_GenericIO_LTRK1_LocbTrk_datSet = {
+ DataAttributeModelType,
+ "datSet",
+ (ModelNode*) &iedModel_GenericIO_LTRK1_LocbTrk,
+ (ModelNode*) &iedModel_GenericIO_LTRK1_LocbTrk_optFlds,
+ NULL,
+ 0,
+ IEC61850_FC_SR,
+ IEC61850_VISIBLE_STRING_129,
+ 0,
+ NULL,
+ 0};
+
+DataAttribute iedModel_GenericIO_LTRK1_LocbTrk_optFlds = {
+ DataAttributeModelType,
+ "optFlds",
+ (ModelNode*) &iedModel_GenericIO_LTRK1_LocbTrk,
+ (ModelNode*) &iedModel_GenericIO_LTRK1_LocbTrk_bufTm,
+ NULL,
+ 0,
+ IEC61850_FC_SR,
+ IEC61850_OPTFLDS,
+ 0,
+ NULL,
+ 0};
+
+DataAttribute iedModel_GenericIO_LTRK1_LocbTrk_bufTm = {
+ DataAttributeModelType,
+ "bufTm",
+ (ModelNode*) &iedModel_GenericIO_LTRK1_LocbTrk,
+ (ModelNode*) &iedModel_GenericIO_LTRK1_LocbTrk_trgOps,
+ NULL,
+ 0,
+ IEC61850_FC_SR,
+ IEC61850_INT32U,
+ 0,
+ NULL,
+ 0};
+
+DataAttribute iedModel_GenericIO_LTRK1_LocbTrk_trgOps = {
+ DataAttributeModelType,
+ "trgOps",
+ (ModelNode*) &iedModel_GenericIO_LTRK1_LocbTrk,
+ (ModelNode*) &iedModel_GenericIO_LTRK1_LocbTrk_intgPd,
+ NULL,
+ 0,
+ IEC61850_FC_SR,
+ IEC61850_TRGOPS,
+ 0,
+ NULL,
+ 0};
+
+DataAttribute iedModel_GenericIO_LTRK1_LocbTrk_intgPd = {
+ DataAttributeModelType,
+ "intgPd",
+ (ModelNode*) &iedModel_GenericIO_LTRK1_LocbTrk,
+ (ModelNode*) &iedModel_GenericIO_LTRK1_LocbTrk_logRef,
+ NULL,
+ 0,
+ IEC61850_FC_SR,
+ IEC61850_INT32U,
+ 0,
+ NULL,
+ 0};
+
+DataAttribute iedModel_GenericIO_LTRK1_LocbTrk_logRef = {
+ DataAttributeModelType,
+ "logRef",
+ (ModelNode*) &iedModel_GenericIO_LTRK1_LocbTrk,
+ NULL,
+ NULL,
+ 0,
+ IEC61850_FC_SR,
+ IEC61850_VISIBLE_STRING_129,
+ 0,
+ NULL,
+ 0};
+
extern ReportControlBlock iedModel_GenericIO_LLN0_report0;
extern ReportControlBlock iedModel_GenericIO_LLN0_report1;
extern ReportControlBlock iedModel_GenericIO_LLN0_report2;
@@ -4635,7 +4887,15 @@ extern SettingGroupControlBlock iedModel_GenericIO_LLN0_sgcb;
SettingGroupControlBlock iedModel_GenericIO_LLN0_sgcb = {&iedModel_GenericIO_LLN0, 1, 5, 0, false, 0, 0, NULL};
+extern LogControlBlock iedModel_GenericIO_LLN0_lcb0;
+extern LogControlBlock iedModel_GenericIO_LLN0_lcb1;
+LogControlBlock iedModel_GenericIO_LLN0_lcb0 = {&iedModel_GenericIO_LLN0, "EventLog", "Events", "GenericIO/LLN0$EventLog", 3, 0, true, true, &iedModel_GenericIO_LLN0_lcb1};
+LogControlBlock iedModel_GenericIO_LLN0_lcb1 = {&iedModel_GenericIO_LLN0, "GeneralLog", NULL, NULL, 3, 0, true, true, NULL};
+extern Log iedModel_GenericIO_LLN0_log0;
+extern Log iedModel_GenericIO_LLN0_log1;
+Log iedModel_GenericIO_LLN0_log0 = {&iedModel_GenericIO_LLN0, "GeneralLog", &iedModel_GenericIO_LLN0_log1};
+Log iedModel_GenericIO_LLN0_log1 = {&iedModel_GenericIO_LLN0, "EventLog", NULL};
IedModel iedModel = {
@@ -4646,8 +4906,8 @@ IedModel iedModel = {
&iedModel_GenericIO_LLN0_gse0,
NULL,
&iedModel_GenericIO_LLN0_sgcb,
- NULL,
- NULL,
+ &iedModel_GenericIO_LLN0_lcb0,
+ &iedModel_GenericIO_LLN0_log0,
initializeValues
};
diff --git a/examples/server_example_service_tracking/static_model.h b/examples/server_example_service_tracking/static_model.h
index 31868808..9e50ab2b 100644
--- a/examples/server_example_service_tracking/static_model.h
+++ b/examples/server_example_service_tracking/static_model.h
@@ -356,6 +356,24 @@ extern DataAttribute iedModel_GenericIO_LTRK1_SgcbTrk_editSG;
extern DataAttribute iedModel_GenericIO_LTRK1_SgcbTrk_cnfEdit;
extern DataAttribute iedModel_GenericIO_LTRK1_SgcbTrk_lActTm;
extern DataAttribute iedModel_GenericIO_LTRK1_SgcbTrk_resvTms;
+extern DataObject iedModel_GenericIO_LTRK1_LocbTrk;
+extern DataAttribute iedModel_GenericIO_LTRK1_LocbTrk_objRef;
+extern DataAttribute iedModel_GenericIO_LTRK1_LocbTrk_serviceType;
+extern DataAttribute iedModel_GenericIO_LTRK1_LocbTrk_errorCode;
+extern DataAttribute iedModel_GenericIO_LTRK1_LocbTrk_originatorID;
+extern DataAttribute iedModel_GenericIO_LTRK1_LocbTrk_t;
+extern DataAttribute iedModel_GenericIO_LTRK1_LocbTrk_d;
+extern DataAttribute iedModel_GenericIO_LTRK1_LocbTrk_dU;
+extern DataAttribute iedModel_GenericIO_LTRK1_LocbTrk_cdcNs;
+extern DataAttribute iedModel_GenericIO_LTRK1_LocbTrk_cdcName;
+extern DataAttribute iedModel_GenericIO_LTRK1_LocbTrk_dataNs;
+extern DataAttribute iedModel_GenericIO_LTRK1_LocbTrk_logEna;
+extern DataAttribute iedModel_GenericIO_LTRK1_LocbTrk_datSet;
+extern DataAttribute iedModel_GenericIO_LTRK1_LocbTrk_optFlds;
+extern DataAttribute iedModel_GenericIO_LTRK1_LocbTrk_bufTm;
+extern DataAttribute iedModel_GenericIO_LTRK1_LocbTrk_trgOps;
+extern DataAttribute iedModel_GenericIO_LTRK1_LocbTrk_intgPd;
+extern DataAttribute iedModel_GenericIO_LTRK1_LocbTrk_logRef;
@@ -704,6 +722,24 @@ extern DataAttribute iedModel_GenericIO_LTRK1_SgcbTrk_resvTms;
#define IEDMODEL_GenericIO_LTRK1_SgcbTrk_cnfEdit (&iedModel_GenericIO_LTRK1_SgcbTrk_cnfEdit)
#define IEDMODEL_GenericIO_LTRK1_SgcbTrk_lActTm (&iedModel_GenericIO_LTRK1_SgcbTrk_lActTm)
#define IEDMODEL_GenericIO_LTRK1_SgcbTrk_resvTms (&iedModel_GenericIO_LTRK1_SgcbTrk_resvTms)
+#define IEDMODEL_GenericIO_LTRK1_LocbTrk (&iedModel_GenericIO_LTRK1_LocbTrk)
+#define IEDMODEL_GenericIO_LTRK1_LocbTrk_objRef (&iedModel_GenericIO_LTRK1_LocbTrk_objRef)
+#define IEDMODEL_GenericIO_LTRK1_LocbTrk_serviceType (&iedModel_GenericIO_LTRK1_LocbTrk_serviceType)
+#define IEDMODEL_GenericIO_LTRK1_LocbTrk_errorCode (&iedModel_GenericIO_LTRK1_LocbTrk_errorCode)
+#define IEDMODEL_GenericIO_LTRK1_LocbTrk_originatorID (&iedModel_GenericIO_LTRK1_LocbTrk_originatorID)
+#define IEDMODEL_GenericIO_LTRK1_LocbTrk_t (&iedModel_GenericIO_LTRK1_LocbTrk_t)
+#define IEDMODEL_GenericIO_LTRK1_LocbTrk_d (&iedModel_GenericIO_LTRK1_LocbTrk_d)
+#define IEDMODEL_GenericIO_LTRK1_LocbTrk_dU (&iedModel_GenericIO_LTRK1_LocbTrk_dU)
+#define IEDMODEL_GenericIO_LTRK1_LocbTrk_cdcNs (&iedModel_GenericIO_LTRK1_LocbTrk_cdcNs)
+#define IEDMODEL_GenericIO_LTRK1_LocbTrk_cdcName (&iedModel_GenericIO_LTRK1_LocbTrk_cdcName)
+#define IEDMODEL_GenericIO_LTRK1_LocbTrk_dataNs (&iedModel_GenericIO_LTRK1_LocbTrk_dataNs)
+#define IEDMODEL_GenericIO_LTRK1_LocbTrk_logEna (&iedModel_GenericIO_LTRK1_LocbTrk_logEna)
+#define IEDMODEL_GenericIO_LTRK1_LocbTrk_datSet (&iedModel_GenericIO_LTRK1_LocbTrk_datSet)
+#define IEDMODEL_GenericIO_LTRK1_LocbTrk_optFlds (&iedModel_GenericIO_LTRK1_LocbTrk_optFlds)
+#define IEDMODEL_GenericIO_LTRK1_LocbTrk_bufTm (&iedModel_GenericIO_LTRK1_LocbTrk_bufTm)
+#define IEDMODEL_GenericIO_LTRK1_LocbTrk_trgOps (&iedModel_GenericIO_LTRK1_LocbTrk_trgOps)
+#define IEDMODEL_GenericIO_LTRK1_LocbTrk_intgPd (&iedModel_GenericIO_LTRK1_LocbTrk_intgPd)
+#define IEDMODEL_GenericIO_LTRK1_LocbTrk_logRef (&iedModel_GenericIO_LTRK1_LocbTrk_logRef)
#endif /* STATIC_MODEL_H_ */
diff --git a/src/iec61850/inc_private/ied_server_private.h b/src/iec61850/inc_private/ied_server_private.h
index e866a503..0de69cb4 100644
--- a/src/iec61850/inc_private/ied_server_private.h
+++ b/src/iec61850/inc_private/ied_server_private.h
@@ -73,6 +73,9 @@ struct sIedServer
};
+LIB61850_INTERNAL IEC61850_ServiceError
+private_IedServer_convertMmsDataAccessErrorToServiceError(MmsDataAccessError mmsError);
+
LIB61850_INTERNAL ClientConnection
private_IedServer_getClientConnectionByHandle(IedServer self, void* serverConnectionHandle);
diff --git a/src/iec61850/inc_private/mms_mapping_internal.h b/src/iec61850/inc_private/mms_mapping_internal.h
index fd7c241f..8fe3baa4 100644
--- a/src/iec61850/inc_private/mms_mapping_internal.h
+++ b/src/iec61850/inc_private/mms_mapping_internal.h
@@ -236,6 +236,26 @@ struct sSgcbTrkInstance
DataAttribute* lActTm;
};
+typedef struct sLocbTrkInstance* LocbTrkInstance;
+
+struct sLocbTrkInstance
+{
+ /* inherited from ServiceTrkInstance */
+ DataObject* dobj;
+ DataAttribute* objRef;
+ DataAttribute* serviceType;
+ DataAttribute* errorCode;
+ DataAttribute* originatorID; /* optional */
+ DataAttribute* t;
+
+ /* LocbTrk specific attributes */
+ DataAttribute* logEna;
+ DataAttribute* datSet;
+ DataAttribute* trgOps;
+ DataAttribute* intgPd;
+ DataAttribute* logRef;
+};
+
#endif /* (CONFIG_IEC61850_SERVICE_TRACKING == 1) */
struct sMmsMapping {
@@ -292,6 +312,7 @@ struct sMmsMapping {
ControlTrkInstance bacTrk;
SgcbTrkInstance sgcbTrk;
ServiceTrkInstance genTrk;
+ LocbTrkInstance locbTrk;
#endif /* (CONFIG_IEC61850_SERVICE_TRACKING == 1) */
/* flag indicates if data model is locked --> prevents reports to be sent */
diff --git a/src/iec61850/server/mms_mapping/control.c b/src/iec61850/server/mms_mapping/control.c
index 66a4c6ad..222c9fd8 100644
--- a/src/iec61850/server/mms_mapping/control.c
+++ b/src/iec61850/server/mms_mapping/control.c
@@ -292,38 +292,6 @@ copyControlValuesToTrackingObject(MmsMapping* self, ControlObject* controlObject
}
}
-static IEC61850_ServiceError
-convertMmsDataAccessErrorToServiceError(MmsDataAccessError mmsError)
-{
- IEC61850_ServiceError errVal = IEC61850_SERVICE_ERROR_NO_ERROR;
-
- switch (mmsError) {
- case DATA_ACCESS_ERROR_SUCCESS:
- case DATA_ACCESS_ERROR_NO_RESPONSE:
- break;
- case DATA_ACCESS_ERROR_TEMPORARILY_UNAVAILABLE:
- errVal = IEC61850_SERVICE_ERROR_INSTANCE_LOCKED_BY_OTHER_CLIENT;
- break;
- case DATA_ACCESS_ERROR_OBJECT_ACCESS_DENIED:
- errVal = IEC61850_SERVICE_ERROR_ACCESS_VIOLATION;
- break;
- case DATA_ACCESS_ERROR_TYPE_INCONSISTENT:
- errVal = IEC61850_SERVICE_ERROR_PARAMETER_VALUE_INCONSISTENT;
- break;
- case DATA_ACCESS_ERROR_OBJECT_NONE_EXISTENT:
- errVal = IEC61850_SERVICE_ERROR_INSTANCE_NOT_AVAILABLE;
- break;
- default:
- if (DEBUG_IED_SERVER)
- printf("IED_SERVER: Data access error %i not mapped!\n", mmsError);
-
- errVal = IEC61850_SERVICE_ERROR_FAILED_DUE_TO_SERVER_CONSTRAINT;
- break;
- }
-
- return errVal;
-}
-
static IEC61850_ServiceError
convertCheckHandlerResultToServiceError(CheckHandlerResult controlHandlerResult)
{
@@ -2248,7 +2216,8 @@ free_and_return:
#if (CONFIG_IEC61850_SERVICE_TRACKING == 1)
if (serviceError == IEC61850_SERVICE_ERROR_NO_ERROR)
- updateGenericTrackingObjectValues(self, controlObject, serviceType, convertMmsDataAccessErrorToServiceError(indication));
+ updateGenericTrackingObjectValues(self, controlObject, serviceType,
+ private_IedServer_convertMmsDataAccessErrorToServiceError(indication));
else
updateGenericTrackingObjectValues(self, controlObject, serviceType, serviceError);
#endif /* (CONFIG_IEC61850_SERVICE_TRACKING == 1) */
diff --git a/src/iec61850/server/mms_mapping/logging.c b/src/iec61850/server/mms_mapping/logging.c
index 83f88ca2..45a11ed1 100644
--- a/src/iec61850/server/mms_mapping/logging.c
+++ b/src/iec61850/server/mms_mapping/logging.c
@@ -31,6 +31,7 @@
#include "simple_allocator.h"
#include "mem_alloc_linked_list.h"
+#include "ied_server_private.h"
#include "mms_mapping_internal.h"
#include "mms_value_internal.h"
@@ -367,10 +368,75 @@ freeDynamicDataSet(LogControl* self)
}
}
+#if (CONFIG_IEC61850_SERVICE_TRACKING == 1)
+
+static void
+updateGenericTrackingObjectValues(MmsMapping* self, LogControl* logControl, IEC61850_ServiceType serviceType, MmsDataAccessError errVal)
+{
+ ServiceTrkInstance trkInst = (ServiceTrkInstance) self->locbTrk;
+
+ if (trkInst) {
+ if (trkInst->serviceType)
+ MmsValue_setInt32(trkInst->serviceType->mmsValue, (int) serviceType);
+
+ if (trkInst->t)
+ MmsValue_setUtcTimeMs(trkInst->t->mmsValue, Hal_getTimeInMs());
+
+ if (trkInst->errorCode)
+ MmsValue_setInt32(trkInst->errorCode->mmsValue,
+ private_IedServer_convertMmsDataAccessErrorToServiceError(errVal));
+
+ char objRef[130];
+
+ /* create object reference */
+ LogicalNode* ln = logControl->logControlBlock->parent;
+ LogicalDevice* ld = (LogicalDevice*) ln->parent;
+
+ char* iedName = self->iedServer->model->name;
+
+ snprintf(objRef, 129, "%s%s/%s.%s", iedName, ld->name, ln->name, logControl->logControlBlock->name);
+
+ if (trkInst->objRef) {
+ IedServer_updateVisibleStringAttributeValue(self->iedServer, trkInst->objRef, objRef);
+ }
+ }
+}
+
+static void
+copyLCBValuesToTrackingObject(MmsMapping* self, LogControl* logControl)
+{
+ if (self->locbTrk) {
+ LocbTrkInstance trkInst = self->locbTrk;
+
+ if (trkInst->logEna)
+ MmsValue_setBoolean(trkInst->logEna->mmsValue, logControl->enabled);
+
+ if (trkInst->logRef)
+ MmsValue_setVisibleString(trkInst->logRef->mmsValue, logControl->logControlBlock->logRef);
+
+ if (trkInst->datSet) {
+ MmsValue_setVisibleString(trkInst->datSet->mmsValue, logControl->dataSetRef);
+ }
+
+ if (trkInst->intgPd)
+ MmsValue_setUint32(trkInst->intgPd->mmsValue, logControl->intgPd);
+
+ if (trkInst->trgOps) {
+ MmsValue_setBitStringFromInteger(trkInst->trgOps->mmsValue, logControl->triggerOps * 2);
+ }
+
+ /* TODO update other attributes? */
+ }
+}
+
+#endif /* (CONFIG_IEC61850_SERVICE_TRACKING == 1) */
+
MmsDataAccessError
LIBIEC61850_LOG_SVC_writeAccessLogControlBlock(MmsMapping* self, MmsDomain* domain, char* variableIdOrig,
MmsValue* value, MmsServerConnection connection)
{
+ MmsDataAccessError retVal = DATA_ACCESS_ERROR_SUCCESS;
+
bool updateValue = false;
char variableId[130];
@@ -416,8 +482,10 @@ LIBIEC61850_LOG_SVC_writeAccessLogControlBlock(MmsMapping* self, MmsDomain* doma
if (DEBUG_IED_SERVER)
printf("IED_SERVER: enabled log control %s\n", logControl->name);
}
- else
- return DATA_ACCESS_ERROR_OBJECT_ATTRIBUTE_INCONSISTENT;
+ else {
+ retVal = DATA_ACCESS_ERROR_OBJECT_ATTRIBUTE_INCONSISTENT;
+ goto exit_function;
+ }
}
updateValue = true;
@@ -459,14 +527,17 @@ LIBIEC61850_LOG_SVC_writeAccessLogControlBlock(MmsMapping* self, MmsDomain* doma
logControl->logInstance = logInstance;
updateValue = true;
}
- else
- return DATA_ACCESS_ERROR_OBJECT_VALUE_INVALID;
-
+ else {
+ retVal = DATA_ACCESS_ERROR_OBJECT_VALUE_INVALID;
+ goto exit_function;
+ }
}
}
}
- else
- return DATA_ACCESS_ERROR_TEMPORARILY_UNAVAILABLE;
+ else {
+ retVal = DATA_ACCESS_ERROR_TEMPORARILY_UNAVAILABLE;
+ goto exit_function;
+ }
}
else if (strcmp(varName, "DatSet") == 0) {
@@ -521,30 +592,36 @@ LIBIEC61850_LOG_SVC_writeAccessLogControlBlock(MmsMapping* self, MmsDomain* doma
if (dataSet == NULL) {
if (DEBUG_IED_SERVER)
printf("IED_SERVER: data set (%s) not found!\n", logControl->dataSetRef);
- return DATA_ACCESS_ERROR_OBJECT_VALUE_INVALID;
+
+ retVal = DATA_ACCESS_ERROR_OBJECT_VALUE_INVALID;
+ goto exit_function;
}
}
-
-
}
- else
- return DATA_ACCESS_ERROR_TEMPORARILY_UNAVAILABLE;
+ else {
+ retVal = DATA_ACCESS_ERROR_TEMPORARILY_UNAVAILABLE;
+ goto exit_function;
+ }
}
else if (strcmp(varName, "IntgPd") == 0) {
if (logControl->enabled == false) {
logControl->intgPd = MmsValue_toUint32(value);
updateValue = true;
}
- else
- return DATA_ACCESS_ERROR_TEMPORARILY_UNAVAILABLE;
+ else {
+ retVal = DATA_ACCESS_ERROR_TEMPORARILY_UNAVAILABLE;
+ goto exit_function;
+ }
}
else if (strcmp(varName, "TrgOps") == 0) {
if (logControl->enabled == false) {
logControl->triggerOps = (MmsValue_getBitStringAsInteger(value) / 2);
updateValue = true;
}
- else
- return DATA_ACCESS_ERROR_TEMPORARILY_UNAVAILABLE;
+ else {
+ retVal = DATA_ACCESS_ERROR_TEMPORARILY_UNAVAILABLE;
+ goto exit_function;
+ }
}
if (updateValue) {
@@ -552,10 +629,20 @@ LIBIEC61850_LOG_SVC_writeAccessLogControlBlock(MmsMapping* self, MmsDomain* doma
MmsValue_update(element, value);
- return DATA_ACCESS_ERROR_SUCCESS;
+ retVal = DATA_ACCESS_ERROR_SUCCESS;
+ goto exit_function;
}
- return DATA_ACCESS_ERROR_OBJECT_ACCESS_DENIED;
+ retVal = DATA_ACCESS_ERROR_OBJECT_ACCESS_DENIED;
+
+exit_function:
+
+#if (CONFIG_IEC61850_SERVICE_TRACKING == 1)
+ copyLCBValuesToTrackingObject(self, logControl);
+ updateGenericTrackingObjectValues(self, logControl, IEC61850_SERVICE_TYPE_SET_LCB_VALUES, retVal);
+#endif
+
+ return retVal;
}
MmsValue*
diff --git a/src/iec61850/server/mms_mapping/mms_goose.c b/src/iec61850/server/mms_mapping/mms_goose.c
index 292d1be0..f0ffaee8 100644
--- a/src/iec61850/server/mms_mapping/mms_goose.c
+++ b/src/iec61850/server/mms_mapping/mms_goose.c
@@ -108,35 +108,6 @@ copyGCBValuesToTrackingObject(MmsGooseControlBlock gc)
}
}
-static IEC61850_ServiceError
-convertMmsDataAccessErrorToServiceError(MmsDataAccessError mmsError)
-{
- IEC61850_ServiceError errVal = IEC61850_SERVICE_ERROR_NO_ERROR;
-
- switch (mmsError) {
- case DATA_ACCESS_ERROR_SUCCESS:
- break;
- case DATA_ACCESS_ERROR_TEMPORARILY_UNAVAILABLE:
- errVal = IEC61850_SERVICE_ERROR_INSTANCE_LOCKED_BY_OTHER_CLIENT;
- break;
- case DATA_ACCESS_ERROR_OBJECT_ACCESS_DENIED:
- errVal = IEC61850_SERVICE_ERROR_ACCESS_VIOLATION;
- break;
- case DATA_ACCESS_ERROR_TYPE_INCONSISTENT:
- errVal = IEC61850_SERVICE_ERROR_PARAMETER_VALUE_INCONSISTENT;
- break;
- case DATA_ACCESS_ERROR_OBJECT_NONE_EXISTENT:
- errVal = IEC61850_SERVICE_ERROR_INSTANCE_NOT_AVAILABLE;
- break;
- default:
- printf("Data access error %i not mapped!\n", mmsError);
- errVal = IEC61850_SERVICE_ERROR_FAILED_DUE_TO_SERVER_CONSTRAINT;
- break;
- }
-
- return errVal;
-}
-
static void
updateGenericTrackingObjectValues(MmsGooseControlBlock gc, IEC61850_ServiceType serviceType, MmsDataAccessError errVal)
{
@@ -154,7 +125,8 @@ updateGenericTrackingObjectValues(MmsGooseControlBlock gc, IEC61850_ServiceType
MmsValue_setUtcTimeMs(trkInst->t->mmsValue, Hal_getTimeInMs());
if (trkInst->errorCode)
- MmsValue_setInt32(trkInst->errorCode->mmsValue, convertMmsDataAccessErrorToServiceError(errVal));
+ MmsValue_setInt32(trkInst->errorCode->mmsValue,
+ private_IedServer_convertMmsDataAccessErrorToServiceError(errVal));
char objRef[130];
diff --git a/src/iec61850/server/mms_mapping/mms_mapping.c b/src/iec61850/server/mms_mapping/mms_mapping.c
index 265605d0..0830c1e9 100644
--- a/src/iec61850/server/mms_mapping/mms_mapping.c
+++ b/src/iec61850/server/mms_mapping/mms_mapping.c
@@ -612,8 +612,8 @@ copySGCBValuesToTrackingObject(MmsMapping* self, SettingGroupControlBlock* sgcb)
}
}
-static IEC61850_ServiceError
-convertMmsDataAccessErrorToServiceError(MmsDataAccessError mmsError)
+IEC61850_ServiceError
+private_IedServer_convertMmsDataAccessErrorToServiceError(MmsDataAccessError mmsError)
{
IEC61850_ServiceError errVal = IEC61850_SERVICE_ERROR_NO_ERROR;
@@ -661,7 +661,8 @@ updateGenericTrackingObjectValues(MmsMapping* self, SettingGroupControlBlock* sg
MmsValue_setUtcTimeMs(trkInst->t->mmsValue, Hal_getTimeInMs());
if (trkInst->errorCode)
- MmsValue_setInt32(trkInst->errorCode->mmsValue, convertMmsDataAccessErrorToServiceError(errVal));
+ MmsValue_setInt32(trkInst->errorCode->mmsValue,
+ private_IedServer_convertMmsDataAccessErrorToServiceError(errVal));
char objRef[129];
@@ -1211,6 +1212,37 @@ getSgcbTrackingAttributes(SgcbTrkInstance svcTrkInst, DataObject* trkObj)
}
}
+static void
+getLocbTrackingAttributes(LocbTrkInstance svcTrkInst, DataObject* trkObj)
+{
+ ModelNode* modelNode = trkObj->firstChild;
+
+ while (modelNode) {
+ if (modelNode->modelType == DataAttributeModelType) {
+ DataAttribute* da = (DataAttribute*) modelNode;
+
+ if (!strcmp(da->name, "logEna")) {
+ svcTrkInst->logEna = da;
+ }
+ if (!strcmp(da->name, "datSet")) {
+ svcTrkInst->datSet = da;
+ }
+ else if (!strcmp(da->name, "trgOps")) {
+ svcTrkInst->trgOps = da;
+ }
+ else if (!strcmp(da->name, "intgPd")) {
+ svcTrkInst->intgPd = da;
+ }
+ else if (!strcmp(da->name, "logRef")) {
+ svcTrkInst->logRef = da;
+ }
+ }
+
+ modelNode = modelNode->sibling;
+ }
+
+}
+
static void
getControlTrackingAttributes(ControlTrkInstance svcTrkInst, DataObject* trkObj)
{
@@ -1394,7 +1426,28 @@ checkForServiceTrackingVariables(MmsMapping* self, LogicalNode* logicalNode)
getCommonTrackingAttributes((ServiceTrkInstance) self->sgcbTrk, sgcbTrk);
getSgcbTrackingAttributes(self->sgcbTrk, sgcbTrk);
}
+ }
+ }
+ else if (!strcmp(modelNode->name, "LocbTrk")) {
+ if (DEBUG_IED_SERVER)
+ printf("IED_SERVER: LocbTrk data object found!\n");
+
+ DataObject* locbTrk = (DataObject*) modelNode;
+
+ if (self->locbTrk) {
+ if (DEBUG_IED_SERVER)
+ printf("IED_SERVER: ERROR: multiple LocbTrk instances found in server\n");
+ }
+ else {
+ /* Setup LocbTrk references */
+ self->locbTrk = (LocbTrkInstance) GLOBAL_CALLOC(1, sizeof(struct sLocbTrkInstance));
+ if (self->locbTrk) {
+ self->locbTrk->dobj = locbTrk;
+
+ getCommonTrackingAttributes((ServiceTrkInstance) self->locbTrk, locbTrk);
+ getLocbTrackingAttributes(self->locbTrk, locbTrk);
+ }
}
}
else if (!strcmp(modelNode->name, "GenTrk")) {
@@ -1984,6 +2037,7 @@ MmsMapping_destroy(MmsMapping* self)
if (self->bacTrk) GLOBAL_FREEMEM(self->bacTrk);
if (self->sgcbTrk) GLOBAL_FREEMEM(self->sgcbTrk);
if (self->genTrk) GLOBAL_FREEMEM(self->genTrk);
+ if (self->locbTrk) GLOBAL_FREEMEM(self->locbTrk);
#endif
LinkedList_destroy(self->attributeAccessHandlers);
diff --git a/src/iec61850/server/mms_mapping/reporting.c b/src/iec61850/server/mms_mapping/reporting.c
index 8f870227..3feed31f 100644
--- a/src/iec61850/server/mms_mapping/reporting.c
+++ b/src/iec61850/server/mms_mapping/reporting.c
@@ -487,35 +487,6 @@ updateSingleTrackingValue(MmsMapping* self, ReportControl* rc, char* name, MmsVa
}
}
-static IEC61850_ServiceError
-convertMmsDataAccessErrorToServiceError(MmsDataAccessError mmsError)
-{
- IEC61850_ServiceError errVal = IEC61850_SERVICE_ERROR_NO_ERROR;
-
- switch (mmsError) {
- case DATA_ACCESS_ERROR_SUCCESS:
- break;
- case DATA_ACCESS_ERROR_TEMPORARILY_UNAVAILABLE:
- errVal = IEC61850_SERVICE_ERROR_INSTANCE_LOCKED_BY_OTHER_CLIENT;
- break;
- case DATA_ACCESS_ERROR_OBJECT_ACCESS_DENIED:
- errVal = IEC61850_SERVICE_ERROR_ACCESS_VIOLATION;
- break;
- case DATA_ACCESS_ERROR_TYPE_INCONSISTENT:
- errVal = IEC61850_SERVICE_ERROR_PARAMETER_VALUE_INCONSISTENT;
- break;
- case DATA_ACCESS_ERROR_OBJECT_NONE_EXISTENT:
- errVal = IEC61850_SERVICE_ERROR_INSTANCE_NOT_AVAILABLE;
- break;
- default:
- printf("Data access error %i not mapped!\n", mmsError);
- errVal = IEC61850_SERVICE_ERROR_FAILED_DUE_TO_SERVER_CONSTRAINT;
- break;
- }
-
- return errVal;
-}
-
static void
updateGenericTrackingObjectValues(MmsMapping* self, ReportControl* rc, IEC61850_ServiceType serviceType, MmsDataAccessError errVal)
{
@@ -540,7 +511,8 @@ updateGenericTrackingObjectValues(MmsMapping* self, ReportControl* rc, IEC61850_
MmsValue_setUtcTimeMs(trkInst->t->mmsValue, Hal_getTimeInMs());
if (trkInst->errorCode)
- MmsValue_setInt32(trkInst->errorCode->mmsValue, convertMmsDataAccessErrorToServiceError(errVal));
+ MmsValue_setInt32(trkInst->errorCode->mmsValue,
+ private_IedServer_convertMmsDataAccessErrorToServiceError(errVal));
char objRef[130];