diff --git a/dotnet/IEC61850forCSharp/IEC61850ClientAPI.cs b/dotnet/IEC61850forCSharp/IEC61850ClientAPI.cs
index e1336319..e24a20d4 100644
--- a/dotnet/IEC61850forCSharp/IEC61850ClientAPI.cs
+++ b/dotnet/IEC61850forCSharp/IEC61850ClientAPI.cs
@@ -1143,6 +1143,9 @@ namespace IEC61850
/** The server does not support the requested access method */
IED_ERROR_OBJECT_ACCESS_UNSUPPORTED = 24,
+ /** The server expected an object of another type */
+ IED_ERROR_TYPE_INCONSISTENT = 25,
+
/* unknown error */
IED_ERROR_UNKNOWN = 99
}
diff --git a/dotnet/IEC61850forCSharp/Reporting.cs b/dotnet/IEC61850forCSharp/Reporting.cs
index e88f5ff1..256880f4 100644
--- a/dotnet/IEC61850forCSharp/Reporting.cs
+++ b/dotnet/IEC61850forCSharp/Reporting.cs
@@ -120,6 +120,9 @@ namespace IEC61850
[DllImport("iec61850", CallingConvention = CallingConvention.Cdecl)]
static extern IntPtr ClientReport_getRptId(IntPtr self);
+ [DllImport("iec61850", CallingConvention = CallingConvention.Cdecl)]
+ static extern IntPtr ClientReport_getEntryId(IntPtr self);
+
[DllImport("iec61850", CallingConvention = CallingConvention.Cdecl)]
static extern IntPtr ClientReport_getDataReference(IntPtr self, int elementIndex);
@@ -286,6 +289,23 @@ namespace IEC61850
return Marshal.PtrToStringAnsi (rptId);
}
+ ///
+ /// Gets the EntryID of this report.
+ ///
+ /// The entryID as a byte array representing an MMS octet string.
+ public byte[] GetEntryId ()
+ {
+ IntPtr entryIdRef = ClientReport_getEntryId (self);
+
+ if (entryIdRef == IntPtr.Zero)
+ return null;
+ else {
+ MmsValue entryId = new MmsValue (entryIdRef);
+
+ return entryId.getOctetString ();
+ }
+ }
+
}
}
diff --git a/dotnet/control/ControlExample.cs b/dotnet/control/ControlExample.cs
index 7fc136a5..aa3d0a5a 100644
--- a/dotnet/control/ControlExample.cs
+++ b/dotnet/control/ControlExample.cs
@@ -32,7 +32,7 @@ namespace control
{
con.Connect(hostname, 102);
- /* direct control with normal security */
+ /* direct control with normal security or SBO with normal security */
string objectReference = "simpleIOGenericIO/GGIO1.SPCSO1";
ControlObject control = con.CreateControlObject(objectReference);
@@ -41,11 +41,35 @@ namespace control
Console.WriteLine(objectReference + " has control model " + controlModel.ToString());
- if (controlModel != ControlModel.STATUS_ONLY)
- control.Operate(true);
- if (!control.Operate(true))
- Console.WriteLine("operate failed!");
+ switch (controlModel) {
+
+ case ControlModel.STATUS_ONLY:
+ Console.WriteLine("Control is status-only!");
+ break;
+
+ case ControlModel.DIRECT_NORMAL:
+ case ControlModel.DIRECT_ENHANCED:
+ if (!control.Operate(true))
+ Console.WriteLine("operate failed!");
+ else
+ Console.WriteLine("operated successfully!");
+ break;
+
+ case ControlModel.SBO_NORMAL:
+ case ControlModel.SBO_ENHANCED:
+
+ if (control.Select()) {
+ if (!control.Operate(true))
+ Console.WriteLine("operate failed!");
+ else
+ Console.WriteLine("operated successfully!");
+ }
+ else
+ Console.WriteLine("Select failed!");
+
+ break;
+ }
/* direct control with enhanced security */
objectReference = "simpleIOGenericIO/GGIO1.SPCSO3";
diff --git a/dotnet/reporting/ReportingExample.cs b/dotnet/reporting/ReportingExample.cs
index 6a1d9538..4a319cc2 100644
--- a/dotnet/reporting/ReportingExample.cs
+++ b/dotnet/reporting/ReportingExample.cs
@@ -4,6 +4,7 @@ using System.Threading;
using IEC61850.Client;
using IEC61850.Common;
+using System.Runtime.Remoting.Metadata.W3cXsd2001;
namespace reporting
{
@@ -21,6 +22,14 @@ namespace reporting
MmsValue values = report.GetDataSetValues ();
+ byte[] entryId = report.GetEntryId ();
+
+ if (entryId != null) {
+ SoapHexBinary shb = new SoapHexBinary(entryId);
+
+ Console.WriteLine (" entryID: " + shb.ToString ());
+ }
+
Console.WriteLine (" report dataset contains " + values.Size () + " elements");
for (int i = 0; i < values.Size(); i++) {
@@ -53,9 +62,7 @@ namespace reporting
if (args.Length > 0)
hostname = args [0];
else
- hostname = "localhost";
-
- hostname = "10.0.2.2";
+ hostname = "localhost";
Console.WriteLine ("Connect to " + hostname);
@@ -64,9 +71,11 @@ namespace reporting
string rcbReference1 = "simpleIOGenericIO/LLN0.RP.EventsRCB01";
string rcbReference2 = "simpleIOGenericIO/LLN0.RP.EventsIndexed01";
+ string rcbReference3 = "simpleIOGenericIO/LLN0.BR.Measurements01";
ReportControlBlock rcb1 = con.GetReportControlBlock(rcbReference1);
ReportControlBlock rcb2 = con.GetReportControlBlock(rcbReference2);
+ ReportControlBlock rcb3 = con.GetReportControlBlock(rcbReference3);
rcb1.GetRCBValues();
@@ -84,6 +93,9 @@ namespace reporting
rcb2.GetRCBValues();
+ if (rcb2.IsBuffered())
+ Console.WriteLine ("RCB: " + rcbReference2 + " is buffered");
+
rcb2.InstallReportHandler(reportHandler, rcb2);
rcb2.SetOptFlds(ReportOptions.REASON_FOR_INCLUSION | ReportOptions.SEQ_NUM | ReportOptions.TIME_STAMP |
@@ -94,6 +106,21 @@ namespace reporting
rcb2.SetRCBValues();
+ rcb3.GetRCBValues();
+
+ if (rcb3.IsBuffered())
+ Console.WriteLine ("RCB: " + rcbReference3 + " is buffered");
+
+ rcb3.InstallReportHandler(reportHandler, rcb2);
+
+ rcb3.SetOptFlds(ReportOptions.REASON_FOR_INCLUSION | ReportOptions.SEQ_NUM | ReportOptions.TIME_STAMP |
+ ReportOptions.CONF_REV | ReportOptions.ENTRY_ID | ReportOptions.DATA_REFERENCE | ReportOptions.DATA_SET);
+ rcb3.SetTrgOps(TriggerOptions.DATA_CHANGED | TriggerOptions.INTEGRITY);
+ rcb3.SetIntgPd(2000);
+ rcb3.SetRptEna(true);
+
+ rcb3.SetRCBValues();
+
/* run until Ctrl-C is pressed */
Console.CancelKeyPress += delegate(object sender, ConsoleCancelEventArgs e) {
diff --git a/src/iec61850/client/ied_connection.c b/src/iec61850/client/ied_connection.c
index 8fd66de0..5d9f7436 100644
--- a/src/iec61850/client/ied_connection.c
+++ b/src/iec61850/client/ied_connection.c
@@ -76,6 +76,9 @@ iedConnection_mapMmsErrorToIedError(MmsError mmsError)
case MMS_ERROR_DEFINITION_OBJECT_EXISTS:
return IED_ERROR_OBJECT_EXISTS;
+ case MMS_ERROR_DEFINITION_TYPE_INCONSISTENT:
+ return IED_ERROR_TYPE_INCONSISTENT;
+
case MMS_ERROR_SERVICE_TIMEOUT:
return IED_ERROR_TIMEOUT;
diff --git a/src/iec61850/inc/iec61850_client.h b/src/iec61850/inc/iec61850_client.h
index 7377300a..6fefb049 100644
--- a/src/iec61850/inc/iec61850_client.h
+++ b/src/iec61850/inc/iec61850_client.h
@@ -129,6 +129,9 @@ typedef enum {
/** The server does not support the requested access method */
IED_ERROR_OBJECT_ACCESS_UNSUPPORTED = 24,
+ /** The server expected an object of another type */
+ IED_ERROR_TYPE_INCONSISTENT = 25,
+
/* unknown error */
IED_ERROR_UNKNOWN = 99
} IedClientError;
diff --git a/src/mms/iso_mms/server/mms_write_service.c b/src/mms/iso_mms/server/mms_write_service.c
index 9d50073b..291cf14f 100644
--- a/src/mms/iso_mms/server/mms_write_service.c
+++ b/src/mms/iso_mms/server/mms_write_service.c
@@ -212,6 +212,14 @@ mmsServer_handleWriteRequest(
continue;
}
+ /* Check for correct type */
+ if (MmsValue_getType(value) != MmsVariableSpecification_getType(variable)) {
+ GLOBAL_FREEMEM(nameIdStr);
+ MmsValue_delete(value);
+ accessResults[i] = DATA_ACCESS_ERROR_TYPE_INCONSISTENT;
+ continue;
+ }
+
if (alternateAccess != NULL) {
if (domain != NULL)