Merge branch 'master' into pavo_changes
Conflicts: tools/model_generator/genconfig.jar tools/model_generator/genmodel.jar
This commit is contained in:
commit
6ad3c4b17e
21 changed files with 251 additions and 90 deletions
|
@ -18,8 +18,8 @@
|
||||||
#define DEBUG_ISO_SERVER 0
|
#define DEBUG_ISO_SERVER 0
|
||||||
#define DEBUG_ISO_CLIENT 0
|
#define DEBUG_ISO_CLIENT 0
|
||||||
#define DEBUG_IED_SERVER 0
|
#define DEBUG_IED_SERVER 0
|
||||||
#define DEBUG_IED_CLIENT 0
|
#define DEBUG_IED_CLIENT 1
|
||||||
#define DEBUG_MMS_CLIENT 0
|
#define DEBUG_MMS_CLIENT 1
|
||||||
#define DEBUG_MMS_SERVER 0
|
#define DEBUG_MMS_SERVER 0
|
||||||
#define DEBUG_GOOSE_SUBSCRIBER 0
|
#define DEBUG_GOOSE_SUBSCRIBER 0
|
||||||
#define DEBUG_GOOSE_PUBLISHER 0
|
#define DEBUG_GOOSE_PUBLISHER 0
|
||||||
|
|
|
@ -164,6 +164,7 @@ namespace IEC61850
|
||||||
commandTerminationHandler(commandTerminationHandlerParameter, this);
|
commandTerminationHandler(commandTerminationHandlerParameter, this);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private InternalCommandTerminationHandler intCommandTerminationHandler;
|
||||||
|
|
||||||
internal ControlObject (string objectReference, IntPtr connection, IedConnection iedConnection)
|
internal ControlObject (string objectReference, IntPtr connection, IedConnection iedConnection)
|
||||||
{
|
{
|
||||||
|
@ -174,7 +175,7 @@ namespace IEC61850
|
||||||
if (this.controlObject == System.IntPtr.Zero)
|
if (this.controlObject == System.IntPtr.Zero)
|
||||||
throw new IedConnectionException("Control object not found", 0);
|
throw new IedConnectionException("Control object not found", 0);
|
||||||
|
|
||||||
InternalCommandTerminationHandler intCommandTerminationHandler = new InternalCommandTerminationHandler (MyCommandTerminationHandler);
|
intCommandTerminationHandler = new InternalCommandTerminationHandler (MyCommandTerminationHandler);
|
||||||
|
|
||||||
ControlObjectClient_setCommandTerminationHandler(controlObject, intCommandTerminationHandler, controlObject);
|
ControlObjectClient_setCommandTerminationHandler(controlObject, intCommandTerminationHandler, controlObject);
|
||||||
}
|
}
|
||||||
|
|
|
@ -261,8 +261,10 @@ namespace IEC61850
|
||||||
|
|
||||||
~IedConnection ()
|
~IedConnection ()
|
||||||
{
|
{
|
||||||
|
Console.WriteLine ("IedConnection destructor invoked");
|
||||||
if (connection != IntPtr.Zero)
|
if (connection != IntPtr.Zero)
|
||||||
IedConnection_destroy(connection);
|
IedConnection_destroy(connection);
|
||||||
|
Console.WriteLine ("IedConnection destructor finished");
|
||||||
}
|
}
|
||||||
|
|
||||||
public IsoConnectionParameters GetConnectionParameters ()
|
public IsoConnectionParameters GetConnectionParameters ()
|
||||||
|
|
|
@ -159,6 +159,7 @@ namespace IEC61850
|
||||||
|
|
||||||
private IntPtr self;
|
private IntPtr self;
|
||||||
private IntPtr connection;
|
private IntPtr connection;
|
||||||
|
private IedConnection iedConnection = null;
|
||||||
private string objectReference;
|
private string objectReference;
|
||||||
private bool flagRptId = false;
|
private bool flagRptId = false;
|
||||||
private bool flagRptEna = false;
|
private bool flagRptEna = false;
|
||||||
|
@ -202,6 +203,7 @@ namespace IEC61850
|
||||||
|
|
||||||
private void internalReportHandler (IntPtr parameter, IntPtr report)
|
private void internalReportHandler (IntPtr parameter, IntPtr report)
|
||||||
{
|
{
|
||||||
|
Console.WriteLine ("called internalReportHandler");
|
||||||
try {
|
try {
|
||||||
|
|
||||||
if (this.report == null)
|
if (this.report == null)
|
||||||
|
@ -217,16 +219,20 @@ namespace IEC61850
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
internal ReportControlBlock (string objectReference, IntPtr connection)
|
internal ReportControlBlock (string objectReference, IedConnection iedConnection, IntPtr connection)
|
||||||
{
|
{
|
||||||
self = ClientReportControlBlock_create (objectReference);
|
self = ClientReportControlBlock_create (objectReference);
|
||||||
|
this.iedConnection = iedConnection;
|
||||||
this.connection = connection;
|
this.connection = connection;
|
||||||
this.objectReference = objectReference;
|
this.objectReference = objectReference;
|
||||||
}
|
}
|
||||||
|
|
||||||
~ReportControlBlock()
|
~ReportControlBlock()
|
||||||
{
|
{
|
||||||
IedConnection_uninstallReportHandler(connection, objectReference);
|
Console.WriteLine ("Destructor invoked");
|
||||||
|
//IedConnection_uninstallReportHandler(connection, objectReference);
|
||||||
|
//this.iedConnection = null;
|
||||||
|
Console.WriteLine ("Destructor finished");
|
||||||
}
|
}
|
||||||
|
|
||||||
public string GetObjectReference ()
|
public string GetObjectReference ()
|
||||||
|
|
|
@ -33,7 +33,7 @@ namespace IEC61850
|
||||||
{
|
{
|
||||||
public ReportControlBlock GetReportControlBlock (string rcbObjectReference)
|
public ReportControlBlock GetReportControlBlock (string rcbObjectReference)
|
||||||
{
|
{
|
||||||
return new ReportControlBlock (rcbObjectReference, connection);
|
return new ReportControlBlock (rcbObjectReference, this, connection);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -75,36 +75,36 @@ namespace reporting
|
||||||
|
|
||||||
ReportControlBlock rcb1 = con.GetReportControlBlock(rcbReference1);
|
ReportControlBlock rcb1 = con.GetReportControlBlock(rcbReference1);
|
||||||
ReportControlBlock rcb2 = con.GetReportControlBlock(rcbReference2);
|
ReportControlBlock rcb2 = con.GetReportControlBlock(rcbReference2);
|
||||||
ReportControlBlock rcb3 = con.GetReportControlBlock(rcbReference3);
|
ReportControlBlock rcb3 = con.GetReportControlBlock(rcbReference3);
|
||||||
|
|
||||||
rcb1.GetRCBValues();
|
rcb1.GetRCBValues();
|
||||||
|
|
||||||
// note: the second parameter is not required!
|
// note: the second parameter is not required!
|
||||||
rcb1.InstallReportHandler(reportHandler, rcb1);
|
rcb1.InstallReportHandler(reportHandler, rcb1);
|
||||||
|
|
||||||
if (rcb1.IsBuffered())
|
if (rcb1.IsBuffered())
|
||||||
Console.WriteLine ("RCB: " + rcbReference1 + " is buffered");
|
Console.WriteLine("RCB: " + rcbReference1 + " is buffered");
|
||||||
|
|
||||||
rcb1.SetTrgOps(TriggerOptions.DATA_CHANGED | TriggerOptions.INTEGRITY);
|
rcb1.SetTrgOps(TriggerOptions.DATA_CHANGED | TriggerOptions.INTEGRITY);
|
||||||
rcb1.SetIntgPd(5000);
|
rcb1.SetIntgPd(5000);
|
||||||
rcb1.SetRptEna(true);
|
rcb1.SetRptEna(true);
|
||||||
|
|
||||||
rcb1.SetRCBValues();
|
rcb1.SetRCBValues();
|
||||||
|
|
||||||
rcb2.GetRCBValues();
|
rcb2.GetRCBValues();
|
||||||
|
|
||||||
if (rcb2.IsBuffered())
|
if (rcb2.IsBuffered())
|
||||||
Console.WriteLine ("RCB: " + rcbReference2 + " is buffered");
|
Console.WriteLine("RCB: " + rcbReference2 + " is buffered");
|
||||||
|
|
||||||
rcb2.InstallReportHandler(reportHandler, rcb2);
|
rcb2.InstallReportHandler(reportHandler, rcb2);
|
||||||
|
|
||||||
rcb2.SetOptFlds(ReportOptions.REASON_FOR_INCLUSION | ReportOptions.SEQ_NUM | ReportOptions.TIME_STAMP |
|
rcb2.SetOptFlds(ReportOptions.REASON_FOR_INCLUSION | ReportOptions.SEQ_NUM | ReportOptions.TIME_STAMP |
|
||||||
ReportOptions.CONF_REV | ReportOptions.ENTRY_ID | ReportOptions.DATA_REFERENCE | ReportOptions.DATA_SET);
|
ReportOptions.CONF_REV | ReportOptions.ENTRY_ID | ReportOptions.DATA_REFERENCE | ReportOptions.DATA_SET);
|
||||||
rcb2.SetTrgOps(TriggerOptions.DATA_CHANGED | TriggerOptions.INTEGRITY);
|
rcb2.SetTrgOps(TriggerOptions.DATA_CHANGED | TriggerOptions.INTEGRITY);
|
||||||
rcb2.SetIntgPd(2000);
|
rcb2.SetIntgPd(2000);
|
||||||
rcb2.SetRptEna(true);
|
rcb2.SetRptEna(true);
|
||||||
|
|
||||||
rcb2.SetRCBValues();
|
rcb2.SetRCBValues();
|
||||||
|
|
||||||
rcb3.GetRCBValues();
|
rcb3.GetRCBValues();
|
||||||
|
|
||||||
|
@ -128,14 +128,20 @@ namespace reporting
|
||||||
ReportingExample.running = false;
|
ReportingExample.running = false;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
/* stop main loop when connection is lost */
|
||||||
|
con.InstallConnectionClosedHandler(delegate(IedConnection connection) {
|
||||||
|
Console.WriteLine("Connection closed");
|
||||||
|
ReportingExample.running = false;
|
||||||
|
});
|
||||||
|
|
||||||
while (running) {
|
while (running) {
|
||||||
Thread.Sleep(10);
|
Thread.Sleep(10);
|
||||||
}
|
}
|
||||||
|
|
||||||
con.Abort ();
|
con.Abort ();
|
||||||
} catch (IedConnectionException e) {
|
} catch (IedConnectionException e) {
|
||||||
Console.WriteLine (e.Message);
|
Console.WriteLine ("Error: " + e.Message);
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,45 +1,95 @@
|
||||||
<?xml version="1.0" encoding="utf-8"?>
|
<?xml version="1.0" encoding="utf-8"?>
|
||||||
<Project DefaultTargets="Build" ToolsVersion="4.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
|
<Project DefaultTargets="Build" ToolsVersion="4.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
|
||||||
<PropertyGroup>
|
<PropertyGroup>
|
||||||
<Configuration Condition=" '$(Configuration)' == '' ">Debug</Configuration>
|
<Configuration Condition=" '$(Configuration)' == '' ">Debug</Configuration>
|
||||||
<Platform Condition=" '$(Platform)' == '' ">AnyCPU</Platform>
|
<Platform Condition=" '$(Platform)' == '' ">AnyCPU</Platform>
|
||||||
<ProductVersion>8.0.30703</ProductVersion>
|
<ProductVersion>8.0.30703</ProductVersion>
|
||||||
<SchemaVersion>2.0</SchemaVersion>
|
<SchemaVersion>2.0</SchemaVersion>
|
||||||
<ProjectGuid>{9E29B4CE-EE5F-4CA6-85F6-5D1FF8B27BF8}</ProjectGuid>
|
<ProjectGuid>{9E29B4CE-EE5F-4CA6-85F6-5D1FF8B27BF8}</ProjectGuid>
|
||||||
<OutputType>Exe</OutputType>
|
<OutputType>Exe</OutputType>
|
||||||
<RootNamespace>reporting</RootNamespace>
|
<RootNamespace>reporting</RootNamespace>
|
||||||
<AssemblyName>reporting</AssemblyName>
|
<AssemblyName>reporting</AssemblyName>
|
||||||
</PropertyGroup>
|
<PublishUrl>publish\</PublishUrl>
|
||||||
<PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Debug|AnyCPU' ">
|
<Install>true</Install>
|
||||||
<DebugSymbols>true</DebugSymbols>
|
<InstallFrom>Disk</InstallFrom>
|
||||||
<DebugType>full</DebugType>
|
<UpdateEnabled>false</UpdateEnabled>
|
||||||
<Optimize>false</Optimize>
|
<UpdateMode>Foreground</UpdateMode>
|
||||||
<OutputPath>bin\Debug</OutputPath>
|
<UpdateInterval>7</UpdateInterval>
|
||||||
<DefineConstants>DEBUG;</DefineConstants>
|
<UpdateIntervalUnits>Days</UpdateIntervalUnits>
|
||||||
<ErrorReport>prompt</ErrorReport>
|
<UpdatePeriodically>false</UpdatePeriodically>
|
||||||
<WarningLevel>4</WarningLevel>
|
<UpdateRequired>false</UpdateRequired>
|
||||||
<Externalconsole>true</Externalconsole>
|
<MapFileExtensions>true</MapFileExtensions>
|
||||||
</PropertyGroup>
|
<ApplicationRevision>0</ApplicationRevision>
|
||||||
<PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Release|AnyCPU' ">
|
<ApplicationVersion>1.0.0.%2a</ApplicationVersion>
|
||||||
<DebugType>none</DebugType>
|
<IsWebBootstrapper>false</IsWebBootstrapper>
|
||||||
<Optimize>true</Optimize>
|
<UseApplicationTrust>false</UseApplicationTrust>
|
||||||
<OutputPath>bin\Release</OutputPath>
|
<BootstrapperEnabled>true</BootstrapperEnabled>
|
||||||
<ErrorReport>prompt</ErrorReport>
|
</PropertyGroup>
|
||||||
<WarningLevel>4</WarningLevel>
|
<PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Debug|AnyCPU' ">
|
||||||
<Externalconsole>true</Externalconsole>
|
<DebugSymbols>true</DebugSymbols>
|
||||||
</PropertyGroup>
|
<DebugType>full</DebugType>
|
||||||
<ItemGroup>
|
<Optimize>false</Optimize>
|
||||||
<Reference Include="System" />
|
<OutputPath>bin\Debug</OutputPath>
|
||||||
</ItemGroup>
|
<DefineConstants>DEBUG;</DefineConstants>
|
||||||
<ItemGroup>
|
<ErrorReport>prompt</ErrorReport>
|
||||||
<Compile Include="AssemblyInfo.cs" />
|
<WarningLevel>4</WarningLevel>
|
||||||
<Compile Include="ReportingExample.cs" />
|
<Externalconsole>true</Externalconsole>
|
||||||
</ItemGroup>
|
<UseVSHostingProcess>true</UseVSHostingProcess>
|
||||||
<Import Project="$(MSBuildBinPath)\Microsoft.CSharp.targets" />
|
</PropertyGroup>
|
||||||
<ItemGroup>
|
<PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Release|AnyCPU' ">
|
||||||
<ProjectReference Include="..\IEC61850forCSharp\IEC61850forCSharp.csproj">
|
<DebugType>none</DebugType>
|
||||||
<Project>{C35D624E-5506-4560-8074-1728F1FA1A4D}</Project>
|
<Optimize>true</Optimize>
|
||||||
<Name>IEC61850forCSharp</Name>
|
<OutputPath>bin\Release</OutputPath>
|
||||||
</ProjectReference>
|
<ErrorReport>prompt</ErrorReport>
|
||||||
</ItemGroup>
|
<WarningLevel>4</WarningLevel>
|
||||||
|
<Externalconsole>true</Externalconsole>
|
||||||
|
</PropertyGroup>
|
||||||
|
<ItemGroup>
|
||||||
|
<Reference Include="System" />
|
||||||
|
</ItemGroup>
|
||||||
|
<ItemGroup>
|
||||||
|
<Compile Include="AssemblyInfo.cs" />
|
||||||
|
<Compile Include="Properties\Settings.Designer.cs">
|
||||||
|
<AutoGen>True</AutoGen>
|
||||||
|
<DesignTimeSharedInput>True</DesignTimeSharedInput>
|
||||||
|
<DependentUpon>Settings.settings</DependentUpon>
|
||||||
|
</Compile>
|
||||||
|
<Compile Include="ReportingExample.cs" />
|
||||||
|
<Compile Include="Settings.cs" />
|
||||||
|
</ItemGroup>
|
||||||
|
<Import Project="$(MSBuildBinPath)\Microsoft.CSharp.targets" />
|
||||||
|
<ItemGroup>
|
||||||
|
<ProjectReference Include="..\IEC61850forCSharp\IEC61850forCSharp.csproj">
|
||||||
|
<Project>{C35D624E-5506-4560-8074-1728F1FA1A4D}</Project>
|
||||||
|
<Name>IEC61850forCSharp</Name>
|
||||||
|
</ProjectReference>
|
||||||
|
</ItemGroup>
|
||||||
|
<ItemGroup>
|
||||||
|
<None Include="Properties\Settings.settings">
|
||||||
|
<Generator>SettingsSingleFileGenerator</Generator>
|
||||||
|
<LastGenOutput>Settings.Designer.cs</LastGenOutput>
|
||||||
|
</None>
|
||||||
|
</ItemGroup>
|
||||||
|
<ItemGroup>
|
||||||
|
<BootstrapperPackage Include=".NETFramework,Version=v4.0">
|
||||||
|
<Visible>False</Visible>
|
||||||
|
<ProductName>Microsoft .NET Framework 4 %28x86 and x64%29</ProductName>
|
||||||
|
<Install>true</Install>
|
||||||
|
</BootstrapperPackage>
|
||||||
|
<BootstrapperPackage Include="Microsoft.Net.Client.3.5">
|
||||||
|
<Visible>False</Visible>
|
||||||
|
<ProductName>.NET Framework 3.5 SP1 Client Profile</ProductName>
|
||||||
|
<Install>false</Install>
|
||||||
|
</BootstrapperPackage>
|
||||||
|
<BootstrapperPackage Include="Microsoft.Net.Framework.3.5.SP1">
|
||||||
|
<Visible>False</Visible>
|
||||||
|
<ProductName>.NET Framework 3.5 SP1</ProductName>
|
||||||
|
<Install>false</Install>
|
||||||
|
</BootstrapperPackage>
|
||||||
|
<BootstrapperPackage Include="Microsoft.Windows.Installer.4.5">
|
||||||
|
<Visible>False</Visible>
|
||||||
|
<ProductName>Windows Installer 4.5</ProductName>
|
||||||
|
<Install>true</Install>
|
||||||
|
</BootstrapperPackage>
|
||||||
|
</ItemGroup>
|
||||||
</Project>
|
</Project>
|
|
@ -46,8 +46,12 @@ struct sControlObjectClient
|
||||||
bool interlockCheck;
|
bool interlockCheck;
|
||||||
bool synchroCheck;
|
bool synchroCheck;
|
||||||
bool hasTimeActivatedMode;
|
bool hasTimeActivatedMode;
|
||||||
|
|
||||||
int edition; /* 1 = Ed. 1 - 2 = Ed. 2 */
|
int edition; /* 1 = Ed. 1 - 2 = Ed. 2 */
|
||||||
|
|
||||||
|
bool useConstantT; /* some servers require a constant T parameter for select and operate */
|
||||||
|
uint64_t constantT; /* timestamp of select/operate to be used when constant T option is selected */
|
||||||
|
|
||||||
LastApplError lastApplError;
|
LastApplError lastApplError;
|
||||||
|
|
||||||
CommandTerminationHandler commandTerminationHandler;
|
CommandTerminationHandler commandTerminationHandler;
|
||||||
|
@ -380,7 +384,16 @@ ControlObjectClient_operate(ControlObjectClient self, MmsValue* ctlVal, uint64_t
|
||||||
MmsValue* ctlNum = MmsValue_newUnsignedFromUint32(self->ctlNum);
|
MmsValue* ctlNum = MmsValue_newUnsignedFromUint32(self->ctlNum);
|
||||||
MmsValue_setElement(operParameters, index++, ctlNum);
|
MmsValue_setElement(operParameters, index++, ctlNum);
|
||||||
|
|
||||||
uint64_t timestamp = Hal_getTimeInMs();
|
uint64_t timestamp;
|
||||||
|
|
||||||
|
if ((self->ctlModel == CONTROL_MODEL_SBO_ENHANCED) && (self->useConstantT))
|
||||||
|
timestamp = self->constantT;
|
||||||
|
else
|
||||||
|
timestamp = Hal_getTimeInMs();
|
||||||
|
|
||||||
|
if (self->useConstantT)
|
||||||
|
self->constantT = timestamp;
|
||||||
|
|
||||||
MmsValue* ctlTime;
|
MmsValue* ctlTime;
|
||||||
|
|
||||||
if (self->edition == 2)
|
if (self->edition == 2)
|
||||||
|
@ -485,6 +498,9 @@ ControlObjectClient_selectWithValue(ControlObjectClient self, MmsValue* ctlVal)
|
||||||
uint64_t timestamp = Hal_getTimeInMs();
|
uint64_t timestamp = Hal_getTimeInMs();
|
||||||
MmsValue* ctlTime;
|
MmsValue* ctlTime;
|
||||||
|
|
||||||
|
if (self->useConstantT)
|
||||||
|
self->constantT = timestamp;
|
||||||
|
|
||||||
if (self->edition == 2)
|
if (self->edition == 2)
|
||||||
ctlTime = MmsValue_newUtcTimeByMsTime(timestamp);
|
ctlTime = MmsValue_newUtcTimeByMsTime(timestamp);
|
||||||
else {
|
else {
|
||||||
|
@ -609,7 +625,13 @@ ControlObjectClient_cancel(ControlObjectClient self)
|
||||||
MmsValue* ctlNum = MmsValue_newUnsignedFromUint32(self->ctlNum);
|
MmsValue* ctlNum = MmsValue_newUnsignedFromUint32(self->ctlNum);
|
||||||
MmsValue_setElement(cancelParameters, index++, ctlNum);
|
MmsValue_setElement(cancelParameters, index++, ctlNum);
|
||||||
|
|
||||||
uint64_t timestamp = Hal_getTimeInMs();
|
uint64_t timestamp;
|
||||||
|
|
||||||
|
if (self->useConstantT)
|
||||||
|
timestamp = self->constantT;
|
||||||
|
else
|
||||||
|
timestamp = Hal_getTimeInMs();
|
||||||
|
|
||||||
MmsValue* ctlTime;
|
MmsValue* ctlTime;
|
||||||
|
|
||||||
if (self->edition == 2)
|
if (self->edition == 2)
|
||||||
|
@ -652,6 +674,12 @@ ControlObjectClient_cancel(ControlObjectClient self)
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
ControlObjectClient_useConstantT(ControlObjectClient self, bool useConstantT)
|
||||||
|
{
|
||||||
|
self->useConstantT = useConstantT;
|
||||||
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
ControlObjectClient_enableInterlockCheck(ControlObjectClient self)
|
ControlObjectClient_enableInterlockCheck(ControlObjectClient self)
|
||||||
{
|
{
|
||||||
|
|
|
@ -267,7 +267,9 @@ IedConnection_installReportHandler(IedConnection self, const char* rcbReference,
|
||||||
else
|
else
|
||||||
report->rptId = NULL;
|
report->rptId = NULL;
|
||||||
|
|
||||||
|
Semaphore_wait(self->reportHandlerMutex);
|
||||||
LinkedList_add(self->enabledReports, report);
|
LinkedList_add(self->enabledReports, report);
|
||||||
|
Semaphore_post(self->reportHandlerMutex);
|
||||||
|
|
||||||
if (DEBUG_IED_CLIENT)
|
if (DEBUG_IED_CLIENT)
|
||||||
printf("DEBUG_IED_CLIENT: Installed new report callback handler for %s\n", rcbReference);
|
printf("DEBUG_IED_CLIENT: Installed new report callback handler for %s\n", rcbReference);
|
||||||
|
@ -276,12 +278,16 @@ IedConnection_installReportHandler(IedConnection self, const char* rcbReference,
|
||||||
void
|
void
|
||||||
IedConnection_uninstallReportHandler(IedConnection self, const char* rcbReference)
|
IedConnection_uninstallReportHandler(IedConnection self, const char* rcbReference)
|
||||||
{
|
{
|
||||||
|
Semaphore_wait(self->reportHandlerMutex);
|
||||||
|
|
||||||
ClientReport report = lookupReportHandler(self, rcbReference);
|
ClientReport report = lookupReportHandler(self, rcbReference);
|
||||||
|
|
||||||
if (report != NULL) {
|
if (report != NULL) {
|
||||||
LinkedList_remove(self->enabledReports, report);
|
LinkedList_remove(self->enabledReports, report);
|
||||||
ClientReport_destroy(report);
|
ClientReport_destroy(report);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Semaphore_post(self->reportHandlerMutex);
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
|
@ -544,9 +550,13 @@ private_IedConnection_handleReport(IedConnection self, MmsValue* value)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
printf("U0 sem wait\n");
|
||||||
|
Semaphore_wait(self->reportHandlerMutex);
|
||||||
|
printf("U1 call user\n");
|
||||||
if (matchingReport->callback != NULL)
|
if (matchingReport->callback != NULL)
|
||||||
matchingReport->callback(matchingReport->callbackParameter, matchingReport);
|
matchingReport->callback(matchingReport->callbackParameter, matchingReport);
|
||||||
|
Semaphore_post(self->reportHandlerMutex);
|
||||||
|
printf("U2\n");
|
||||||
exit_function:
|
exit_function:
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
|
@ -485,6 +485,7 @@ IedConnection_create()
|
||||||
self->state = IED_STATE_IDLE;
|
self->state = IED_STATE_IDLE;
|
||||||
|
|
||||||
self->stateMutex = Semaphore_create(1);
|
self->stateMutex = Semaphore_create(1);
|
||||||
|
self->reportHandlerMutex = Semaphore_create(1);
|
||||||
|
|
||||||
self->connectionTimeout = DEFAULT_CONNECTION_TIMEOUT;
|
self->connectionTimeout = DEFAULT_CONNECTION_TIMEOUT;
|
||||||
|
|
||||||
|
@ -629,6 +630,7 @@ IedConnection_destroy(IedConnection self)
|
||||||
printf("D6\n");
|
printf("D6\n");
|
||||||
|
|
||||||
Semaphore_destroy(self->stateMutex);
|
Semaphore_destroy(self->stateMutex);
|
||||||
|
Semaphore_destroy(self->reportHandlerMutex);
|
||||||
|
|
||||||
printf("D7\n");
|
printf("D7\n");
|
||||||
|
|
||||||
|
@ -637,6 +639,7 @@ IedConnection_destroy(IedConnection self)
|
||||||
printf("D8\n");
|
printf("D8\n");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
MmsVariableSpecification*
|
MmsVariableSpecification*
|
||||||
IedConnection_getVariableSpecification(IedConnection self, IedClientError* error, const char* objectReference,
|
IedConnection_getVariableSpecification(IedConnection self, IedClientError* error, const char* objectReference,
|
||||||
FunctionalConstraint fc)
|
FunctionalConstraint fc)
|
||||||
|
@ -1145,7 +1148,6 @@ mmsFileReadHandler(void* parameter, int32_t frsmId, uint8_t* buffer, uint32_t by
|
||||||
{
|
{
|
||||||
struct sClientProvidedFileReadHandler* handler = (struct sClientProvidedFileReadHandler*) parameter;
|
struct sClientProvidedFileReadHandler* handler = (struct sClientProvidedFileReadHandler*) parameter;
|
||||||
|
|
||||||
|
|
||||||
handler->retVal = handler->handler(handler->handlerParameter, buffer, bytesReceived);
|
handler->retVal = handler->handler(handler->handlerParameter, buffer, bytesReceived);
|
||||||
|
|
||||||
handler->byteReceived += bytesReceived;
|
handler->byteReceived += bytesReceived;
|
||||||
|
|
|
@ -1335,6 +1335,17 @@ ControlObjectClient_setTestMode(ControlObjectClient self);
|
||||||
void
|
void
|
||||||
ControlObjectClient_setOrigin(ControlObjectClient self, const char* orIdent, int orCat);
|
ControlObjectClient_setOrigin(ControlObjectClient self, const char* orIdent, int orCat);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* \brief Use a constant T parameter for all command (select, operate, cancel) of a single control sequence
|
||||||
|
*
|
||||||
|
* NOTE: Some non-standard compliant servers may require this to accept oper/cancel requests
|
||||||
|
*
|
||||||
|
* \param self the ControlObjectClient instance
|
||||||
|
* \param useContantT enable this behaviour with true, disable with false
|
||||||
|
*/
|
||||||
|
void
|
||||||
|
ControlObjectClient_useConstantT(ControlObjectClient self, bool useConstantT);
|
||||||
|
|
||||||
void
|
void
|
||||||
ControlObjectClient_enableInterlockCheck(ControlObjectClient self);
|
ControlObjectClient_enableInterlockCheck(ControlObjectClient self);
|
||||||
|
|
||||||
|
|
|
@ -40,6 +40,7 @@ struct sIedConnection
|
||||||
LastApplError lastApplError;
|
LastApplError lastApplError;
|
||||||
|
|
||||||
Semaphore stateMutex;
|
Semaphore stateMutex;
|
||||||
|
Semaphore reportHandlerMutex;
|
||||||
|
|
||||||
IedConnectionClosedHandler connectionCloseHandler;
|
IedConnectionClosedHandler connectionCloseHandler;
|
||||||
void* connectionClosedParameter;
|
void* connectionClosedParameter;
|
||||||
|
|
|
@ -1414,6 +1414,8 @@ writeAccessGooseControlBlock(MmsMapping* self, MmsDomain* domain, char* variable
|
||||||
|
|
||||||
#if (CONFIG_GOOSE_DATSET_WRITABLE == 1)
|
#if (CONFIG_GOOSE_DATSET_WRITABLE == 1)
|
||||||
if (strcmp(varName, "DatSet") == 0) {
|
if (strcmp(varName, "DatSet") == 0) {
|
||||||
|
// allow to set non-existing data set?
|
||||||
|
|
||||||
MmsValue_update(MmsValue_getElement(MmsGooseControlBlock_getMmsValues(mmsGCB), 2), value);
|
MmsValue_update(MmsValue_getElement(MmsGooseControlBlock_getMmsValues(mmsGCB), 2), value);
|
||||||
allowAccess = true;
|
allowAccess = true;
|
||||||
}
|
}
|
||||||
|
|
|
@ -106,6 +106,8 @@ connectionHandlingThread(IsoClientConnection self)
|
||||||
|
|
||||||
TpktState packetState;
|
TpktState packetState;
|
||||||
|
|
||||||
|
printf("P1\n");
|
||||||
|
|
||||||
while ((packetState = CotpConnection_readToTpktBuffer(self->cotpConnection)) == TPKT_WAITING)
|
while ((packetState = CotpConnection_readToTpktBuffer(self->cotpConnection)) == TPKT_WAITING)
|
||||||
{
|
{
|
||||||
Thread_sleep(1);
|
Thread_sleep(1);
|
||||||
|
@ -116,6 +118,9 @@ connectionHandlingThread(IsoClientConnection self)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
printf("P2\n");
|
||||||
|
|
||||||
|
|
||||||
if (packetState == TPKT_ERROR)
|
if (packetState == TPKT_ERROR)
|
||||||
break;
|
break;
|
||||||
|
|
||||||
|
@ -146,27 +151,44 @@ connectionHandlingThread(IsoClientConnection self)
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
printf("P3\n");
|
||||||
|
|
||||||
|
|
||||||
self->callback(ISO_IND_DATA, self->callbackParameter,
|
self->callback(ISO_IND_DATA, self->callbackParameter,
|
||||||
&(self->presentation->nextPayload));
|
&(self->presentation->nextPayload));
|
||||||
|
|
||||||
|
printf("P4\n");
|
||||||
|
|
||||||
|
|
||||||
/* wait for user to release the buffer */
|
/* wait for user to release the buffer */
|
||||||
Semaphore_wait(self->receiveBufferMutex);
|
Semaphore_wait(self->receiveBufferMutex);
|
||||||
|
|
||||||
|
|
||||||
|
printf("P5\n");
|
||||||
|
|
||||||
CotpConnection_resetPayload(self->cotpConnection);
|
CotpConnection_resetPayload(self->cotpConnection);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
printf("I1\n");
|
||||||
|
|
||||||
self->callback(ISO_IND_CLOSED, self->callbackParameter, NULL);
|
self->callback(ISO_IND_CLOSED, self->callbackParameter, NULL);
|
||||||
|
|
||||||
|
printf("I2\n");
|
||||||
|
|
||||||
self->state = STATE_IDLE;
|
self->state = STATE_IDLE;
|
||||||
|
|
||||||
Socket_destroy(self->socket);
|
Socket_destroy(self->socket);
|
||||||
|
|
||||||
|
printf("I3\n");
|
||||||
|
|
||||||
if (DEBUG_ISO_CLIENT)
|
if (DEBUG_ISO_CLIENT)
|
||||||
printf("ISO_CLIENT_CONNECTION: exit connection %p\n", self);
|
printf("ISO_CLIENT_CONNECTION: exit connection %p\n", self);
|
||||||
|
|
||||||
/* release buffer to enable resuse of client connection */
|
/* release buffer to enable reuse of client connection */
|
||||||
Semaphore_post(self->receiveBufferMutex);
|
Semaphore_post(self->receiveBufferMutex);
|
||||||
|
|
||||||
|
printf("I4\n");
|
||||||
|
|
||||||
self->handlingThreadRunning = false;
|
self->handlingThreadRunning = false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -427,12 +449,16 @@ IsoClientConnection_close(IsoClientConnection self)
|
||||||
if (DEBUG_ISO_CLIENT)
|
if (DEBUG_ISO_CLIENT)
|
||||||
printf("ISO_CLIENT: IsoClientConnection_close\n");
|
printf("ISO_CLIENT: IsoClientConnection_close\n");
|
||||||
|
|
||||||
|
printf("B1\n");
|
||||||
|
|
||||||
if (self->handlingThreadRunning) {
|
if (self->handlingThreadRunning) {
|
||||||
self->stopHandlingThread = true;
|
self->stopHandlingThread = true;
|
||||||
while (self->handlingThreadRunning)
|
while (self->handlingThreadRunning)
|
||||||
Thread_sleep(1);
|
Thread_sleep(1);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
printf("B2\n");
|
||||||
|
|
||||||
self->state = STATE_IDLE;
|
self->state = STATE_IDLE;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -490,3 +490,6 @@ EXPORTS
|
||||||
ClientReport_getBufOvfl
|
ClientReport_getBufOvfl
|
||||||
MmsValue_getUtcTimeInMsWithUs
|
MmsValue_getUtcTimeInMsWithUs
|
||||||
IedModel_setIedNameForDynamicModel
|
IedModel_setIedNameForDynamicModel
|
||||||
|
ControlObjectClient_useConstantT
|
||||||
|
ControlObjectClient_setOrigin
|
||||||
|
|
||||||
|
|
|
@ -91,7 +91,7 @@ EXPORTS
|
||||||
ControlObjectClient_getObjectReference @218
|
ControlObjectClient_getObjectReference @218
|
||||||
ControlObjectClient_operate @219
|
ControlObjectClient_operate @219
|
||||||
ControlObjectClient_select @220
|
ControlObjectClient_select @220
|
||||||
ControlObjectClient_selectWithValue @221MmsConnection_setConnectTimeout
|
ControlObjectClient_selectWithValue @221
|
||||||
ControlObjectClient_setLastApplError @222
|
ControlObjectClient_setLastApplError @222
|
||||||
ControlObjectClient_setCommandTerminationHandler
|
ControlObjectClient_setCommandTerminationHandler
|
||||||
DataAttribute_create @273
|
DataAttribute_create @273
|
||||||
|
@ -514,3 +514,5 @@ EXPORTS
|
||||||
ClientReport_getBufOvfl
|
ClientReport_getBufOvfl
|
||||||
MmsValue_getUtcTimeInMsWithUs
|
MmsValue_getUtcTimeInMsWithUs
|
||||||
IedModel_setIedNameForDynamicModel
|
IedModel_setIedNameForDynamicModel
|
||||||
|
ControlObjectClient_useConstantT
|
||||||
|
ControlObjectClient_setOrigin
|
||||||
|
|
Binary file not shown.
Binary file not shown.
|
@ -76,8 +76,11 @@ public class LogControl {
|
||||||
reasonCode = reasonCodeBoolean;
|
reasonCode = reasonCodeBoolean;
|
||||||
|
|
||||||
Node trgOpsNode = ParserUtils.getChildNodeWithTag(logControlNode, "TrgOps");
|
Node trgOpsNode = ParserUtils.getChildNodeWithTag(logControlNode, "TrgOps");
|
||||||
|
|
||||||
this.triggerOptions = new TriggerOptions(trgOpsNode);
|
if (trgOpsNode != null)
|
||||||
|
this.triggerOptions = new TriggerOptions(trgOpsNode);
|
||||||
|
else
|
||||||
|
this.triggerOptions = new TriggerOptions(); // use default values if no node present
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -77,7 +77,10 @@ public class ReportControlBlock {
|
||||||
|
|
||||||
Node trgOpsNode = ParserUtils.getChildNodeWithTag(reportControlNode, "TrgOps");
|
Node trgOpsNode = ParserUtils.getChildNodeWithTag(reportControlNode, "TrgOps");
|
||||||
|
|
||||||
this.triggerOptions = new TriggerOptions(trgOpsNode);
|
if (trgOpsNode != null)
|
||||||
|
this.triggerOptions = new TriggerOptions(trgOpsNode);
|
||||||
|
else
|
||||||
|
this.triggerOptions = new TriggerOptions(); // use default values if no node present
|
||||||
|
|
||||||
Node optFieldsNode = ParserUtils.getChildNodeWithTag(reportControlNode, "OptFields");
|
Node optFieldsNode = ParserUtils.getChildNodeWithTag(reportControlNode, "OptFields");
|
||||||
|
|
||||||
|
|
|
@ -32,7 +32,7 @@ public class TriggerOptions {
|
||||||
private boolean qchg = false; /* 2 */
|
private boolean qchg = false; /* 2 */
|
||||||
private boolean dupd = false; /* 4 */
|
private boolean dupd = false; /* 4 */
|
||||||
private boolean period = false; /* 8 */
|
private boolean period = false; /* 8 */
|
||||||
private boolean gi = false; /* 16 */
|
private boolean gi = true; /* 16 */
|
||||||
|
|
||||||
public TriggerOptions(Node trgOpsNode) throws SclParserException {
|
public TriggerOptions(Node trgOpsNode) throws SclParserException {
|
||||||
|
|
||||||
|
@ -56,6 +56,11 @@ public class TriggerOptions {
|
||||||
if (giVal != null)
|
if (giVal != null)
|
||||||
this.gi = giVal;
|
this.gi = giVal;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/** Constructor for default values when trigger options are not present */
|
||||||
|
public TriggerOptions() {
|
||||||
|
// nothing to do
|
||||||
|
}
|
||||||
|
|
||||||
public TriggerOptions(boolean dchg, boolean qchg, boolean dupd, boolean period, boolean gi) {
|
public TriggerOptions(boolean dchg, boolean qchg, boolean dupd, boolean period, boolean gi) {
|
||||||
this.dchg = dchg;
|
this.dchg = dchg;
|
||||||
|
|
Loading…
Add table
Reference in a new issue