- added function MmsValue_getUtcTimeInMsWithUs to C and C# API

This commit is contained in:
Michael Zillgith 2015-04-21 09:28:48 +02:00
parent 48b02ec1b0
commit e84da95752
11 changed files with 113 additions and 10 deletions

View file

@ -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");
}
/// <summary>
/// Gets the timestamp value as UTC time in ms and the additional us part.
/// </summary>
/// <description>
/// 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.
/// </description>
/// <param name='usec'>
/// returns the usec part of the time value
/// </param>
/// <returns>
/// The UTC time in ms.
/// </returns>
/// <exception cref="MmsValueException">This exception is thrown if the value has the wrong type.</exception>
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");
}
/// <summary>
/// Convert a millisecond time (milliseconds since epoch) to DataTimeOffset
/// </summary>

View file

@ -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);

View file

@ -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)

View file

@ -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++;
}

View file

@ -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
*

View file

@ -527,8 +527,6 @@ ModelNode_getChildWithFc(ModelNode* self, const char* name, FunctionalConstraint
return matchingNode;
}
inline
LogicalNode*
LogicalDevice_getLogicalNode(LogicalDevice* self, const char* nodeName)
{

View file

@ -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
*

View file

@ -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*

View file

@ -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)

View file

@ -487,4 +487,5 @@ EXPORTS
Timestamp_clearFlags
IedServer_setGooseInterfaceId
MmsServerIdentity_destroy
ClientReport_getBufOvfl
MmsValue_getUtcTimeInMsWithUs

View file

@ -511,4 +511,5 @@ EXPORTS
Timestamp_clearFlags
IedServer_setGooseInterfaceId
MmsServerIdentity_destroy
ClientReport_getBufOvfl
MmsValue_getUtcTimeInMsWithUs