Merge branch 'pavo_changes' of mz-automation.de:libiec61850 into pavo_changes
Conflicts: src/vs/libiec61850-wo-goose.def src/vs/libiec61850.def
This commit is contained in:
commit
e8f7f17a8f
21 changed files with 248 additions and 90 deletions
|
@ -18,8 +18,8 @@
|
|||
#define DEBUG_ISO_SERVER 0
|
||||
#define DEBUG_ISO_CLIENT 0
|
||||
#define DEBUG_IED_SERVER 0
|
||||
#define DEBUG_IED_CLIENT 0
|
||||
#define DEBUG_MMS_CLIENT 0
|
||||
#define DEBUG_IED_CLIENT 1
|
||||
#define DEBUG_MMS_CLIENT 1
|
||||
#define DEBUG_MMS_SERVER 0
|
||||
#define DEBUG_GOOSE_SUBSCRIBER 0
|
||||
#define DEBUG_GOOSE_PUBLISHER 0
|
||||
|
|
|
@ -164,6 +164,7 @@ namespace IEC61850
|
|||
commandTerminationHandler(commandTerminationHandlerParameter, this);
|
||||
}
|
||||
|
||||
private InternalCommandTerminationHandler intCommandTerminationHandler;
|
||||
|
||||
internal ControlObject (string objectReference, IntPtr connection, IedConnection iedConnection)
|
||||
{
|
||||
|
@ -174,7 +175,7 @@ namespace IEC61850
|
|||
if (this.controlObject == System.IntPtr.Zero)
|
||||
throw new IedConnectionException("Control object not found", 0);
|
||||
|
||||
InternalCommandTerminationHandler intCommandTerminationHandler = new InternalCommandTerminationHandler (MyCommandTerminationHandler);
|
||||
intCommandTerminationHandler = new InternalCommandTerminationHandler (MyCommandTerminationHandler);
|
||||
|
||||
ControlObjectClient_setCommandTerminationHandler(controlObject, intCommandTerminationHandler, controlObject);
|
||||
}
|
||||
|
|
|
@ -261,8 +261,10 @@ namespace IEC61850
|
|||
|
||||
~IedConnection ()
|
||||
{
|
||||
Console.WriteLine ("IedConnection destructor invoked");
|
||||
if (connection != IntPtr.Zero)
|
||||
IedConnection_destroy(connection);
|
||||
Console.WriteLine ("IedConnection destructor finished");
|
||||
}
|
||||
|
||||
public IsoConnectionParameters GetConnectionParameters ()
|
||||
|
|
|
@ -159,6 +159,7 @@ namespace IEC61850
|
|||
|
||||
private IntPtr self;
|
||||
private IntPtr connection;
|
||||
private IedConnection iedConnection = null;
|
||||
private string objectReference;
|
||||
private bool flagRptId = false;
|
||||
private bool flagRptEna = false;
|
||||
|
@ -202,6 +203,7 @@ namespace IEC61850
|
|||
|
||||
private void internalReportHandler (IntPtr parameter, IntPtr report)
|
||||
{
|
||||
Console.WriteLine ("called internalReportHandler");
|
||||
try {
|
||||
|
||||
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);
|
||||
this.iedConnection = iedConnection;
|
||||
this.connection = connection;
|
||||
this.objectReference = objectReference;
|
||||
}
|
||||
|
||||
~ReportControlBlock()
|
||||
{
|
||||
IedConnection_uninstallReportHandler(connection, objectReference);
|
||||
Console.WriteLine ("Destructor invoked");
|
||||
//IedConnection_uninstallReportHandler(connection, objectReference);
|
||||
//this.iedConnection = null;
|
||||
Console.WriteLine ("Destructor finished");
|
||||
}
|
||||
|
||||
public string GetObjectReference ()
|
||||
|
|
|
@ -33,7 +33,7 @@ namespace IEC61850
|
|||
{
|
||||
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 rcb2 = con.GetReportControlBlock(rcbReference2);
|
||||
ReportControlBlock rcb3 = con.GetReportControlBlock(rcbReference3);
|
||||
|
||||
rcb1.GetRCBValues();
|
||||
|
||||
// note: the second parameter is not required!
|
||||
rcb1.InstallReportHandler(reportHandler, rcb1);
|
||||
|
||||
if (rcb1.IsBuffered())
|
||||
Console.WriteLine ("RCB: " + rcbReference1 + " is buffered");
|
||||
|
||||
rcb1.SetTrgOps(TriggerOptions.DATA_CHANGED | TriggerOptions.INTEGRITY);
|
||||
rcb1.SetIntgPd(5000);
|
||||
rcb1.SetRptEna(true);
|
||||
|
||||
rcb1.SetRCBValues();
|
||||
|
||||
rcb2.GetRCBValues();
|
||||
|
||||
if (rcb2.IsBuffered())
|
||||
Console.WriteLine ("RCB: " + rcbReference2 + " is buffered");
|
||||
|
||||
rcb2.InstallReportHandler(reportHandler, rcb2);
|
||||
ReportControlBlock rcb3 = con.GetReportControlBlock(rcbReference3);
|
||||
|
||||
rcb1.GetRCBValues();
|
||||
|
||||
// note: the second parameter is not required!
|
||||
rcb1.InstallReportHandler(reportHandler, rcb1);
|
||||
|
||||
if (rcb1.IsBuffered())
|
||||
Console.WriteLine("RCB: " + rcbReference1 + " is buffered");
|
||||
|
||||
rcb1.SetTrgOps(TriggerOptions.DATA_CHANGED | TriggerOptions.INTEGRITY);
|
||||
rcb1.SetIntgPd(5000);
|
||||
rcb1.SetRptEna(true);
|
||||
|
||||
rcb1.SetRCBValues();
|
||||
|
||||
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 |
|
||||
ReportOptions.CONF_REV | ReportOptions.ENTRY_ID | ReportOptions.DATA_REFERENCE | ReportOptions.DATA_SET);
|
||||
rcb2.SetTrgOps(TriggerOptions.DATA_CHANGED | TriggerOptions.INTEGRITY);
|
||||
rcb2.SetIntgPd(2000);
|
||||
rcb2.SetRptEna(true);
|
||||
|
||||
rcb2.SetRCBValues();
|
||||
ReportOptions.CONF_REV | ReportOptions.ENTRY_ID | ReportOptions.DATA_REFERENCE | ReportOptions.DATA_SET);
|
||||
rcb2.SetTrgOps(TriggerOptions.DATA_CHANGED | TriggerOptions.INTEGRITY);
|
||||
rcb2.SetIntgPd(2000);
|
||||
rcb2.SetRptEna(true);
|
||||
|
||||
rcb2.SetRCBValues();
|
||||
|
||||
rcb3.GetRCBValues();
|
||||
|
||||
|
@ -128,14 +128,20 @@ namespace reporting
|
|||
ReportingExample.running = false;
|
||||
};
|
||||
|
||||
/* stop main loop when connection is lost */
|
||||
con.InstallConnectionClosedHandler(delegate(IedConnection connection) {
|
||||
Console.WriteLine("Connection closed");
|
||||
ReportingExample.running = false;
|
||||
});
|
||||
|
||||
while (running) {
|
||||
Thread.Sleep(10);
|
||||
}
|
||||
|
||||
con.Abort ();
|
||||
} catch (IedConnectionException e) {
|
||||
Console.WriteLine (e.Message);
|
||||
}
|
||||
Console.WriteLine ("Error: " + e.Message);
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1,45 +1,95 @@
|
|||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<Project DefaultTargets="Build" ToolsVersion="4.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
|
||||
<PropertyGroup>
|
||||
<Configuration Condition=" '$(Configuration)' == '' ">Debug</Configuration>
|
||||
<Platform Condition=" '$(Platform)' == '' ">AnyCPU</Platform>
|
||||
<ProductVersion>8.0.30703</ProductVersion>
|
||||
<SchemaVersion>2.0</SchemaVersion>
|
||||
<ProjectGuid>{9E29B4CE-EE5F-4CA6-85F6-5D1FF8B27BF8}</ProjectGuid>
|
||||
<OutputType>Exe</OutputType>
|
||||
<RootNamespace>reporting</RootNamespace>
|
||||
<AssemblyName>reporting</AssemblyName>
|
||||
</PropertyGroup>
|
||||
<PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Debug|AnyCPU' ">
|
||||
<DebugSymbols>true</DebugSymbols>
|
||||
<DebugType>full</DebugType>
|
||||
<Optimize>false</Optimize>
|
||||
<OutputPath>bin\Debug</OutputPath>
|
||||
<DefineConstants>DEBUG;</DefineConstants>
|
||||
<ErrorReport>prompt</ErrorReport>
|
||||
<WarningLevel>4</WarningLevel>
|
||||
<Externalconsole>true</Externalconsole>
|
||||
</PropertyGroup>
|
||||
<PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Release|AnyCPU' ">
|
||||
<DebugType>none</DebugType>
|
||||
<Optimize>true</Optimize>
|
||||
<OutputPath>bin\Release</OutputPath>
|
||||
<ErrorReport>prompt</ErrorReport>
|
||||
<WarningLevel>4</WarningLevel>
|
||||
<Externalconsole>true</Externalconsole>
|
||||
</PropertyGroup>
|
||||
<ItemGroup>
|
||||
<Reference Include="System" />
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<Compile Include="AssemblyInfo.cs" />
|
||||
<Compile Include="ReportingExample.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>
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<Project DefaultTargets="Build" ToolsVersion="4.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
|
||||
<PropertyGroup>
|
||||
<Configuration Condition=" '$(Configuration)' == '' ">Debug</Configuration>
|
||||
<Platform Condition=" '$(Platform)' == '' ">AnyCPU</Platform>
|
||||
<ProductVersion>8.0.30703</ProductVersion>
|
||||
<SchemaVersion>2.0</SchemaVersion>
|
||||
<ProjectGuid>{9E29B4CE-EE5F-4CA6-85F6-5D1FF8B27BF8}</ProjectGuid>
|
||||
<OutputType>Exe</OutputType>
|
||||
<RootNamespace>reporting</RootNamespace>
|
||||
<AssemblyName>reporting</AssemblyName>
|
||||
<PublishUrl>publish\</PublishUrl>
|
||||
<Install>true</Install>
|
||||
<InstallFrom>Disk</InstallFrom>
|
||||
<UpdateEnabled>false</UpdateEnabled>
|
||||
<UpdateMode>Foreground</UpdateMode>
|
||||
<UpdateInterval>7</UpdateInterval>
|
||||
<UpdateIntervalUnits>Days</UpdateIntervalUnits>
|
||||
<UpdatePeriodically>false</UpdatePeriodically>
|
||||
<UpdateRequired>false</UpdateRequired>
|
||||
<MapFileExtensions>true</MapFileExtensions>
|
||||
<ApplicationRevision>0</ApplicationRevision>
|
||||
<ApplicationVersion>1.0.0.%2a</ApplicationVersion>
|
||||
<IsWebBootstrapper>false</IsWebBootstrapper>
|
||||
<UseApplicationTrust>false</UseApplicationTrust>
|
||||
<BootstrapperEnabled>true</BootstrapperEnabled>
|
||||
</PropertyGroup>
|
||||
<PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Debug|AnyCPU' ">
|
||||
<DebugSymbols>true</DebugSymbols>
|
||||
<DebugType>full</DebugType>
|
||||
<Optimize>false</Optimize>
|
||||
<OutputPath>bin\Debug</OutputPath>
|
||||
<DefineConstants>DEBUG;</DefineConstants>
|
||||
<ErrorReport>prompt</ErrorReport>
|
||||
<WarningLevel>4</WarningLevel>
|
||||
<Externalconsole>true</Externalconsole>
|
||||
<UseVSHostingProcess>true</UseVSHostingProcess>
|
||||
</PropertyGroup>
|
||||
<PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Release|AnyCPU' ">
|
||||
<DebugType>none</DebugType>
|
||||
<Optimize>true</Optimize>
|
||||
<OutputPath>bin\Release</OutputPath>
|
||||
<ErrorReport>prompt</ErrorReport>
|
||||
<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>
|
|
@ -46,8 +46,12 @@ struct sControlObjectClient
|
|||
bool interlockCheck;
|
||||
bool synchroCheck;
|
||||
bool hasTimeActivatedMode;
|
||||
|
||||
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;
|
||||
|
||||
CommandTerminationHandler commandTerminationHandler;
|
||||
|
@ -380,7 +384,16 @@ ControlObjectClient_operate(ControlObjectClient self, MmsValue* ctlVal, uint64_t
|
|||
MmsValue* ctlNum = MmsValue_newUnsignedFromUint32(self->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;
|
||||
|
||||
if (self->edition == 2)
|
||||
|
@ -485,6 +498,9 @@ ControlObjectClient_selectWithValue(ControlObjectClient self, MmsValue* ctlVal)
|
|||
uint64_t timestamp = Hal_getTimeInMs();
|
||||
MmsValue* ctlTime;
|
||||
|
||||
if (self->useConstantT)
|
||||
self->constantT = timestamp;
|
||||
|
||||
if (self->edition == 2)
|
||||
ctlTime = MmsValue_newUtcTimeByMsTime(timestamp);
|
||||
else {
|
||||
|
@ -609,7 +625,13 @@ ControlObjectClient_cancel(ControlObjectClient self)
|
|||
MmsValue* ctlNum = MmsValue_newUnsignedFromUint32(self->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;
|
||||
|
||||
if (self->edition == 2)
|
||||
|
@ -652,6 +674,12 @@ ControlObjectClient_cancel(ControlObjectClient self)
|
|||
return true;
|
||||
}
|
||||
|
||||
void
|
||||
ControlObjectClient_useConstantT(ControlObjectClient self, bool useConstantT)
|
||||
{
|
||||
self->useConstantT = useConstantT;
|
||||
}
|
||||
|
||||
void
|
||||
ControlObjectClient_enableInterlockCheck(ControlObjectClient self)
|
||||
{
|
||||
|
|
|
@ -267,7 +267,9 @@ IedConnection_installReportHandler(IedConnection self, const char* rcbReference,
|
|||
else
|
||||
report->rptId = NULL;
|
||||
|
||||
Semaphore_wait(self->reportHandlerMutex);
|
||||
LinkedList_add(self->enabledReports, report);
|
||||
Semaphore_post(self->reportHandlerMutex);
|
||||
|
||||
if (DEBUG_IED_CLIENT)
|
||||
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
|
||||
IedConnection_uninstallReportHandler(IedConnection self, const char* rcbReference)
|
||||
{
|
||||
Semaphore_wait(self->reportHandlerMutex);
|
||||
|
||||
ClientReport report = lookupReportHandler(self, rcbReference);
|
||||
|
||||
if (report != NULL) {
|
||||
LinkedList_remove(self->enabledReports, report);
|
||||
ClientReport_destroy(report);
|
||||
}
|
||||
|
||||
Semaphore_post(self->reportHandlerMutex);
|
||||
}
|
||||
|
||||
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)
|
||||
matchingReport->callback(matchingReport->callbackParameter, matchingReport);
|
||||
|
||||
Semaphore_post(self->reportHandlerMutex);
|
||||
printf("U2\n");
|
||||
exit_function:
|
||||
return;
|
||||
}
|
||||
|
|
|
@ -485,6 +485,7 @@ IedConnection_create()
|
|||
self->state = IED_STATE_IDLE;
|
||||
|
||||
self->stateMutex = Semaphore_create(1);
|
||||
self->reportHandlerMutex = Semaphore_create(1);
|
||||
|
||||
self->connectionTimeout = DEFAULT_CONNECTION_TIMEOUT;
|
||||
|
||||
|
@ -629,6 +630,7 @@ IedConnection_destroy(IedConnection self)
|
|||
printf("D6\n");
|
||||
|
||||
Semaphore_destroy(self->stateMutex);
|
||||
Semaphore_destroy(self->reportHandlerMutex);
|
||||
|
||||
printf("D7\n");
|
||||
|
||||
|
@ -637,6 +639,7 @@ IedConnection_destroy(IedConnection self)
|
|||
printf("D8\n");
|
||||
}
|
||||
|
||||
|
||||
MmsVariableSpecification*
|
||||
IedConnection_getVariableSpecification(IedConnection self, IedClientError* error, const char* objectReference,
|
||||
FunctionalConstraint fc)
|
||||
|
@ -1145,7 +1148,6 @@ mmsFileReadHandler(void* parameter, int32_t frsmId, uint8_t* buffer, uint32_t by
|
|||
{
|
||||
struct sClientProvidedFileReadHandler* handler = (struct sClientProvidedFileReadHandler*) parameter;
|
||||
|
||||
|
||||
handler->retVal = handler->handler(handler->handlerParameter, buffer, bytesReceived);
|
||||
|
||||
handler->byteReceived += bytesReceived;
|
||||
|
|
|
@ -1335,6 +1335,17 @@ ControlObjectClient_setTestMode(ControlObjectClient self);
|
|||
void
|
||||
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
|
||||
ControlObjectClient_enableInterlockCheck(ControlObjectClient self);
|
||||
|
||||
|
|
|
@ -40,6 +40,7 @@ struct sIedConnection
|
|||
LastApplError lastApplError;
|
||||
|
||||
Semaphore stateMutex;
|
||||
Semaphore reportHandlerMutex;
|
||||
|
||||
IedConnectionClosedHandler connectionCloseHandler;
|
||||
void* connectionClosedParameter;
|
||||
|
|
|
@ -1414,6 +1414,8 @@ writeAccessGooseControlBlock(MmsMapping* self, MmsDomain* domain, char* variable
|
|||
|
||||
#if (CONFIG_GOOSE_DATSET_WRITABLE == 1)
|
||||
if (strcmp(varName, "DatSet") == 0) {
|
||||
// allow to set non-existing data set?
|
||||
|
||||
MmsValue_update(MmsValue_getElement(MmsGooseControlBlock_getMmsValues(mmsGCB), 2), value);
|
||||
allowAccess = true;
|
||||
}
|
||||
|
|
|
@ -106,6 +106,8 @@ connectionHandlingThread(IsoClientConnection self)
|
|||
|
||||
TpktState packetState;
|
||||
|
||||
printf("P1\n");
|
||||
|
||||
while ((packetState = CotpConnection_readToTpktBuffer(self->cotpConnection)) == TPKT_WAITING)
|
||||
{
|
||||
Thread_sleep(1);
|
||||
|
@ -116,6 +118,9 @@ connectionHandlingThread(IsoClientConnection self)
|
|||
}
|
||||
}
|
||||
|
||||
printf("P2\n");
|
||||
|
||||
|
||||
if (packetState == TPKT_ERROR)
|
||||
break;
|
||||
|
||||
|
@ -146,27 +151,44 @@ connectionHandlingThread(IsoClientConnection self)
|
|||
break;
|
||||
}
|
||||
|
||||
printf("P3\n");
|
||||
|
||||
|
||||
self->callback(ISO_IND_DATA, self->callbackParameter,
|
||||
&(self->presentation->nextPayload));
|
||||
|
||||
printf("P4\n");
|
||||
|
||||
|
||||
/* wait for user to release the buffer */
|
||||
Semaphore_wait(self->receiveBufferMutex);
|
||||
|
||||
|
||||
printf("P5\n");
|
||||
|
||||
CotpConnection_resetPayload(self->cotpConnection);
|
||||
}
|
||||
|
||||
printf("I1\n");
|
||||
|
||||
self->callback(ISO_IND_CLOSED, self->callbackParameter, NULL);
|
||||
|
||||
printf("I2\n");
|
||||
|
||||
self->state = STATE_IDLE;
|
||||
|
||||
Socket_destroy(self->socket);
|
||||
|
||||
printf("I3\n");
|
||||
|
||||
if (DEBUG_ISO_CLIENT)
|
||||
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);
|
||||
|
||||
printf("I4\n");
|
||||
|
||||
self->handlingThreadRunning = false;
|
||||
}
|
||||
|
||||
|
@ -427,12 +449,16 @@ IsoClientConnection_close(IsoClientConnection self)
|
|||
if (DEBUG_ISO_CLIENT)
|
||||
printf("ISO_CLIENT: IsoClientConnection_close\n");
|
||||
|
||||
printf("B1\n");
|
||||
|
||||
if (self->handlingThreadRunning) {
|
||||
self->stopHandlingThread = true;
|
||||
while (self->handlingThreadRunning)
|
||||
Thread_sleep(1);
|
||||
}
|
||||
|
||||
printf("B2\n");
|
||||
|
||||
self->state = STATE_IDLE;
|
||||
}
|
||||
|
||||
|
|
|
@ -490,4 +490,5 @@ EXPORTS
|
|||
ClientReport_getBufOvfl
|
||||
MmsValue_getUtcTimeInMsWithUs
|
||||
IedModel_setIedNameForDynamicModel
|
||||
ControlObjectClient_useConstantT
|
||||
ControlObjectClient_setOrigin
|
||||
|
|
|
@ -91,7 +91,7 @@ EXPORTS
|
|||
ControlObjectClient_getObjectReference @218
|
||||
ControlObjectClient_operate @219
|
||||
ControlObjectClient_select @220
|
||||
ControlObjectClient_selectWithValue @221MmsConnection_setConnectTimeout
|
||||
ControlObjectClient_selectWithValue @221
|
||||
ControlObjectClient_setLastApplError @222
|
||||
ControlObjectClient_setCommandTerminationHandler
|
||||
DataAttribute_create @273
|
||||
|
@ -514,4 +514,5 @@ EXPORTS
|
|||
ClientReport_getBufOvfl
|
||||
MmsValue_getUtcTimeInMsWithUs
|
||||
IedModel_setIedNameForDynamicModel
|
||||
ControlObjectClient_useConstantT
|
||||
ControlObjectClient_setOrigin
|
||||
|
|
Binary file not shown.
Binary file not shown.
|
@ -76,8 +76,11 @@ public class LogControl {
|
|||
reasonCode = reasonCodeBoolean;
|
||||
|
||||
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");
|
||||
|
||||
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");
|
||||
|
||||
|
|
|
@ -32,7 +32,7 @@ public class TriggerOptions {
|
|||
private boolean qchg = false; /* 2 */
|
||||
private boolean dupd = false; /* 4 */
|
||||
private boolean period = false; /* 8 */
|
||||
private boolean gi = false; /* 16 */
|
||||
private boolean gi = true; /* 16 */
|
||||
|
||||
public TriggerOptions(Node trgOpsNode) throws SclParserException {
|
||||
|
||||
|
@ -56,6 +56,11 @@ public class TriggerOptions {
|
|||
if (giVal != null)
|
||||
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) {
|
||||
this.dchg = dchg;
|
||||
|
|
Loading…
Add table
Reference in a new issue