diff --git a/dotnet/IEC61850forCSharp/IEC61850ClientAPI.cs b/dotnet/IEC61850forCSharp/IEC61850ClientAPI.cs
index 4c2a53c4..26221b4d 100644
--- a/dotnet/IEC61850forCSharp/IEC61850ClientAPI.cs
+++ b/dotnet/IEC61850forCSharp/IEC61850ClientAPI.cs
@@ -431,6 +431,9 @@ namespace IEC61850
[DllImport("iec61850", CallingConvention = CallingConvention.Cdecl)]
static extern UInt32 IedConnection_getRequestTimeout(IntPtr self);
+ [DllImport("iec61850", CallingConvention = CallingConvention.Cdecl)]
+ static extern void IedConnection_setTimeQuality(IntPtr self, [MarshalAs(UnmanagedType.I1)] bool leapSecondKnown, [MarshalAs(UnmanagedType.I1)] bool clockFailure, [MarshalAs(UnmanagedType.I1)] bool clockNotSynchronized, int subsecondPrecision);
+
[DllImport("iec61850", CallingConvention = CallingConvention.Cdecl)]
static extern void IedConnection_connect(IntPtr self, out int error, string hostname, int tcpPort);
@@ -807,6 +810,18 @@ namespace IEC61850
}
}
+ ///
+ /// Set the time quality for all timestamps generated by this IedConnection instance
+ ///
+ /// set or unset leap seconds known flag
+ /// set or unset clock failure flag
+ /// set or unset clock not synchronized flag
+ /// set the subsecond precision (number of significant bits of the fractionOfSecond part of the time stamp)
+ public void SetTimeQuality(bool leapSecondKnown, bool clockFailure, bool clockNotSynchronized, int subsecondPrecision)
+ {
+ IedConnection_setTimeQuality(connection, leapSecondKnown, clockFailure, clockNotSynchronized, subsecondPrecision);
+ }
+
///
/// Gets the underlying MmsConnection instance.
///
diff --git a/src/iec61850/client/client_control.c b/src/iec61850/client/client_control.c
index 5bbfd924..64d98e24 100644
--- a/src/iec61850/client/client_control.c
+++ b/src/iec61850/client/client_control.c
@@ -441,8 +441,12 @@ prepareOperParameters(ControlObjectClient self, MmsValue* ctlVal, uint64_t operT
MmsValue* ctlTime;
- if (self->edition == 2)
+ if (self->edition == 2) {
ctlTime = MmsValue_newUtcTimeByMsTime(timestamp);
+
+ if (self->connection)
+ MmsValue_setUtcTimeQuality(ctlTime, self->connection->timeQuality);
+ }
else {
ctlTime = MmsValue_newBinaryTime(false);
MmsValue_setBinaryTime(ctlTime, timestamp);
@@ -682,8 +686,12 @@ prepareSBOwParameters(ControlObjectClient self, MmsValue* ctlVal)
if (self->useConstantT)
self->constantT = timestamp;
- if (self->edition == 2)
+ if (self->edition == 2) {
ctlTime = MmsValue_newUtcTimeByMsTime(timestamp);
+
+ if (self->connection)
+ MmsValue_setUtcTimeQuality(ctlTime, self->connection->timeQuality);
+ }
else {
ctlTime = MmsValue_newBinaryTime(false);
MmsValue_setBinaryTime(ctlTime, timestamp);
@@ -1089,8 +1097,12 @@ createCancelParameters(ControlObjectClient self)
MmsValue* ctlTime;
- if (self->edition == 2)
+ if (self->edition == 2) {
ctlTime = MmsValue_newUtcTimeByMsTime(timestamp);
+
+ if (self->connection)
+ MmsValue_setUtcTimeQuality(ctlTime, self->connection->timeQuality);
+ }
else {
ctlTime = MmsValue_newBinaryTime(false);
MmsValue_setBinaryTime(ctlTime, timestamp);
diff --git a/src/iec61850/client/ied_connection.c b/src/iec61850/client/ied_connection.c
index 3eb1d371..7d31dad5 100644
--- a/src/iec61850/client/ied_connection.c
+++ b/src/iec61850/client/ied_connection.c
@@ -672,6 +672,25 @@ IedConnection_getRequestTimeout(IedConnection self)
return 0;
}
+void
+IedConnection_setTimeQuality(IedConnection self, bool leapSecondKnown, bool clockFailure, bool clockNotSynchronized, int subsecondPrecision)
+{
+ uint8_t timeQuality = 0;
+
+ if (clockNotSynchronized)
+ timeQuality += 0x20;
+
+ if (clockFailure)
+ timeQuality += 0x40;
+
+ if (leapSecondKnown)
+ timeQuality += 0x80;
+
+ timeQuality += (subsecondPrecision & 0x1f);
+
+ self->timeQuality = timeQuality;
+}
+
IedConnectionState
IedConnection_getState(IedConnection self)
{
diff --git a/src/iec61850/inc/iec61850_client.h b/src/iec61850/inc/iec61850_client.h
index 9d1946e9..01a9cb95 100644
--- a/src/iec61850/inc/iec61850_client.h
+++ b/src/iec61850/inc/iec61850_client.h
@@ -266,6 +266,18 @@ IedConnection_setRequestTimeout(IedConnection self, uint32_t timeoutInMs);
LIB61850_API uint32_t
IedConnection_getRequestTimeout(IedConnection self);
+/**
+ * \brief Set the time quality for all timestamps generated by this IedConnection instance
+ *
+ * \param self the connection object
+ * \param leapSecondKnown set/unset leap seconds known flag
+ * \param clockFailure set/unset clock failure flag
+ * \param clockNotSynchronized set/unset clock not synchronized flag
+ * \param subsecondPrecision set the subsecond precision (number of significant bits of the fractionOfSecond part of the time stamp)
+ */
+LIB61850_API void
+IedConnection_setTimeQuality(IedConnection self, bool leapSecondKnown, bool clockFailure, bool clockNotSynchronized, int subsecondPrecision);
+
/**
* \brief Perform MMS message handling and house-keeping tasks (for non-thread mode only)
*
diff --git a/src/iec61850/inc_private/ied_connection_private.h b/src/iec61850/inc_private/ied_connection_private.h
index 5b7200ed..aefc2168 100644
--- a/src/iec61850/inc_private/ied_connection_private.h
+++ b/src/iec61850/inc_private/ied_connection_private.h
@@ -75,6 +75,8 @@ struct sIedConnection
void* connectionStateChangedHandlerParameter;
uint32_t connectionTimeout;
+
+ uint8_t timeQuality;
};
struct sClientReportControlBlock {