diff --git a/dotnet/IEC61850forCSharp/MmsValue.cs b/dotnet/IEC61850forCSharp/MmsValue.cs
index c545fca..3f69b7b 100644
--- a/dotnet/IEC61850forCSharp/MmsValue.cs
+++ b/dotnet/IEC61850forCSharp/MmsValue.cs
@@ -91,6 +91,9 @@ namespace IEC61850
[DllImport("iec61850", CallingConvention = CallingConvention.Cdecl)]
static extern ulong MmsValue_getUtcTimeInMs (IntPtr self);
+ [DllImport("iec61850", CallingConvention = CallingConvention.Cdecl)]
+ static extern ulong MmsValue_getUtcTimeInMsWithUs(IntPtr self, [Out] uint usec);
+
[DllImport("iec61850", CallingConvention = CallingConvention.Cdecl)]
static extern UInt32 MmsValue_toUnixTimestamp (IntPtr self);
@@ -385,6 +388,33 @@ namespace IEC61850
throw new MmsValueException ("Value is not a time type");
}
+ ///
+ /// Gets the timestamp value as UTC time in ms and the additional us part.
+ ///
+ ///
+ /// Return the value as milliseconds since epoch (1.1.1970 UTC) and the additional us part.
+ /// The value has to be of type MMS_UTC_TIME.
+ ///
+ ///
+ /// returns the usec part of the time value
+ ///
+ ///
+ /// The UTC time in ms.
+ ///
+ /// This exception is thrown if the value has the wrong type.
+ public ulong GetUtcTimeInMsWithUs(out int usec)
+ {
+ if (GetType() == MmsType.MMS_UTC_TIME)
+ {
+ uint uusec = 0;
+ var msVal = MmsValue_getUtcTimeInMsWithUs(valueReference, uusec);
+ usec = (int)uusec;
+ return msVal;
+ }
+ else
+ throw new MmsValueException("Value is not a time type");
+ }
+
///
/// Convert a millisecond time (milliseconds since epoch) to DataTimeOffset
///
diff --git a/dotnet/IEC61850forCSharp/Reporting.cs b/dotnet/IEC61850forCSharp/Reporting.cs
index 583627f..e88f5ff 100644
--- a/dotnet/IEC61850forCSharp/Reporting.cs
+++ b/dotnet/IEC61850forCSharp/Reporting.cs
@@ -106,6 +106,10 @@ namespace IEC61850
[return: MarshalAs(UnmanagedType.I1)]
static extern bool ClientReport_hasBufOvfl(IntPtr self);
+ [DllImport("iec61850", CallingConvention = CallingConvention.Cdecl)]
+ [return: MarshalAs(UnmanagedType.I1)]
+ static extern bool ClientReport_getBufOvfl(IntPtr self);
+
[DllImport("iec61850", CallingConvention = CallingConvention.Cdecl)]
[return: MarshalAs(UnmanagedType.I1)]
static extern bool ClientReport_hasDataReference(IntPtr self);
@@ -180,6 +184,11 @@ namespace IEC61850
return ClientReport_hasBufOvfl(self);
}
+ public bool GetBufOvfl ()
+ {
+ return ClientReport_getBufOvfl(self);
+ }
+
public bool HasSeqNum ()
{
return ClientReport_hasSeqNum(self);
diff --git a/dotnet/control/ControlExample.cs b/dotnet/control/ControlExample.cs
index 1ca2b51..7fc136a 100644
--- a/dotnet/control/ControlExample.cs
+++ b/dotnet/control/ControlExample.cs
@@ -41,7 +41,7 @@ namespace control
Console.WriteLine(objectReference + " has control model " + controlModel.ToString());
- if (controlModel != ControlModel.CONTROL_MODEL_STATUS_ONLY)
+ if (controlModel != ControlModel.STATUS_ONLY)
control.Operate(true);
if (!control.Operate(true))
@@ -54,7 +54,7 @@ namespace control
controlModel = control.GetControlModel();
Console.WriteLine(objectReference + " has control model " + controlModel.ToString());
- if (controlModel == ControlModel.CONTROL_MODEL_DIRECT_ENHANCED) {
+ if (controlModel == ControlModel.DIRECT_ENHANCED) {
control.SetCommandTerminationHandler(commandTerminationHandler, null);
control.Operate(true);
@@ -62,8 +62,6 @@ namespace control
Thread.Sleep(1000);
}
-
-
con.Abort();
}
catch (IedConnectionException e)
diff --git a/src/iec61850/client/client_report.c b/src/iec61850/client/client_report.c
index bf944ee..4381544 100644
--- a/src/iec61850/client/client_report.c
+++ b/src/iec61850/client/client_report.c
@@ -54,6 +54,7 @@ struct sClientReport
uint64_t timestamp;
uint16_t seqNum;
uint32_t confRev;
+ bool bufOverflow;
};
char*
@@ -190,6 +191,12 @@ ClientReport_hasBufOvfl(ClientReport self)
return self->hasBufOverflow;
}
+bool
+ClientReport_getBufOvfl(ClientReport self)
+{
+ return self->bufOverflow;
+}
+
bool
ClientReport_hasDataReference(ClientReport self)
{
@@ -390,9 +397,13 @@ private_IedConnection_handleReport(IedConnection self, MmsValue* value)
if (DEBUG_IED_CLIENT)
printf("DEBUG_IED_CLIENT: Found enabled report!\n");
- /* skip bufOvfl */
+ /* check bufOvfl */
if (MmsValue_getBitStringBit(optFlds, 6) == true) {
+ MmsValue* bufOverflow = MmsValue_getElement(value, inclusionIndex);
+
matchingReport->hasBufOverflow = true;
+ matchingReport->bufOverflow = MmsValue_getBoolean(bufOverflow);
+
inclusionIndex++;
}
diff --git a/src/iec61850/inc/iec61850_client.h b/src/iec61850/inc/iec61850_client.h
index b1b3401..95bead9 100644
--- a/src/iec61850/inc/iec61850_client.h
+++ b/src/iec61850/inc/iec61850_client.h
@@ -730,9 +730,26 @@ ClientReport_hasConfRev(ClientReport self);
uint32_t
ClientReport_getConfRev(ClientReport self);
+/**
+ * \brief Indicates if the report contains the bufOvfl (buffer overflow) flag
+ *
+ * \param self the ClientReport instance
+ *
+ * \returns true if the report contains the bufOvfl flag, false otherwise
+ */
bool
ClientReport_hasBufOvfl(ClientReport self);
+/**
+ * \brief Get the value of the bufOvfl flag
+ *
+ * \param self the ClientReport instance
+ *
+ * \returns true if bufOvfl is set, false otherwise
+ */
+bool
+ClientReport_getBufOvfl(ClientReport self);
+
/**
* \brief Indicates if the report contains data references for the reported data set members
*
diff --git a/src/iec61850/server/model/model.c b/src/iec61850/server/model/model.c
index 2a5d5aa..8aef85e 100644
--- a/src/iec61850/server/model/model.c
+++ b/src/iec61850/server/model/model.c
@@ -527,8 +527,6 @@ ModelNode_getChildWithFc(ModelNode* self, const char* name, FunctionalConstraint
return matchingNode;
}
-
-inline
LogicalNode*
LogicalDevice_getLogicalNode(LogicalDevice* self, const char* nodeName)
{
diff --git a/src/mms/inc/mms_value.h b/src/mms/inc/mms_value.h
index 11d1818..7f11956 100644
--- a/src/mms/inc/mms_value.h
+++ b/src/mms/inc/mms_value.h
@@ -459,6 +459,17 @@ MmsValue_getUtcTimeBuffer(MmsValue* self);
uint64_t
MmsValue_getUtcTimeInMs(const MmsValue* value);
+/**
+ * \brief Get a millisecond time value and optional us part from an MmsValue object of MMS_UTCTIME type.
+ *
+ * \param self MmsValue instance to operate on. Has to be of a type MMS_UTCTIME.
+ * \param usec a pointer to store the us (microsecond) value.
+ *
+ * \return the value in milliseconds since epoch (1970/01/01 00:00 UTC)
+ */
+uint64_t
+MmsValue_getUtcTimeInMsWithUs(const MmsValue* self, uint32_t* usec);
+
/**
* \brief set the TimeQuality byte of the UtcTime
*
diff --git a/src/mms/iso_mms/common/mms_value.c b/src/mms/iso_mms/common/mms_value.c
index ff821a3..7093736 100644
--- a/src/mms/iso_mms/common/mms_value.c
+++ b/src/mms/iso_mms/common/mms_value.c
@@ -755,6 +755,33 @@ MmsValue_getUtcTimeInMs(const MmsValue* self)
return msVal;
}
+uint64_t
+MmsValue_getUtcTimeInMsWithUs(const MmsValue* self, uint32_t* usec)
+{
+ uint32_t timeval32;
+ const uint8_t* valueArray = self->value.utcTime;
+
+#if (ORDER_LITTLE_ENDIAN == 1)
+ memcpyReverseByteOrder((uint8_t*) &timeval32, valueArray, 4);
+#else
+ memcpy((uint8_t*)&timeval32, valueArray, 4);
+#endif
+
+ uint64_t fractionOfSecond = 0;
+
+ fractionOfSecond = (valueArray[4] << 16);
+ fractionOfSecond += (valueArray[5] << 8);
+ fractionOfSecond += (valueArray[6]);
+
+ uint64_t remainder = fractionOfSecond * 1000000ULL / 0x1000000ULL; // in usec
+
+ uint64_t msVal = (timeval32 * 1000LL) + (remainder / 1000LL);
+
+ if (usec != NULL)
+ *usec = remainder % 1000LL;
+
+ return msVal;
+}
MmsValue*
diff --git a/src/mms/iso_server/iso_server.c b/src/mms/iso_server/iso_server.c
index 7bcb8f0..65bc885 100644
--- a/src/mms/iso_server/iso_server.c
+++ b/src/mms/iso_server/iso_server.c
@@ -479,7 +479,7 @@ IsoServer_startListening(IsoServer self)
if (DEBUG_ISO_SERVER)
printf("ISO_SERVER: new iso server thread started\n");
}
-#endif
+#endif /* (CONFIG_MMS_THREADLESS_STACK != 1) */
void
IsoServer_startListeningThreadless(IsoServer self)
diff --git a/src/vs/libiec61850-wo-goose.def b/src/vs/libiec61850-wo-goose.def
index 8459efe..8a8b60a 100644
--- a/src/vs/libiec61850-wo-goose.def
+++ b/src/vs/libiec61850-wo-goose.def
@@ -487,4 +487,5 @@ EXPORTS
Timestamp_clearFlags
IedServer_setGooseInterfaceId
MmsServerIdentity_destroy
-
\ No newline at end of file
+ ClientReport_getBufOvfl
+ MmsValue_getUtcTimeInMsWithUs
diff --git a/src/vs/libiec61850.def b/src/vs/libiec61850.def
index cbfa888..b944370 100644
--- a/src/vs/libiec61850.def
+++ b/src/vs/libiec61850.def
@@ -511,4 +511,5 @@ EXPORTS
Timestamp_clearFlags
IedServer_setGooseInterfaceId
MmsServerIdentity_destroy
-
+ ClientReport_getBufOvfl
+ MmsValue_getUtcTimeInMsWithUs