//This file was generated by the LASAL2 CodeGenerator  -- 
//Please, do not edit this file (it might be overwritten by the next generator run)
//{{LSL_DECLARATION
#include "..\..\Class\SdiasSafetyManager\SdiasSafetyManager.h"
#include "..\..\Class\SafetyBase\SafetyBase.h"
#include "..\..\Class\SdiasManager\SdiasManager.h"

(*!
<Class
	Name               = "SdiasSafetyBase"
	Revision           = "1.10"
	GUID               = "{C9D93D75-D00D-4F2B-9B1D-C9428267FFB5}"
	RealtimeTask       = "false"
	CyclicTask         = "false"
	BackgroundTask     = "false"
	Sigmatek           = "true"
	OSInterface        = "false"
	HighPriority       = "false"
	Automatic          = "false"
	UpdateMode         = "Prescan"
	IconPath           = ".\Class\Tool.ico"
	SharedCommandTable = "true"
	Objectsize         = "(586,120)">
	<Channels>
		<Server Name="CallCommand" GUID="{A99C5070-EE59-42EF-A462-BAA83A995910}" Visualized="false" Initialize="false" WriteProtected="true" Retentive="false"/>
		<Server Name="ClassState" GUID="{4183DCF5-56A8-44D9-9E66-0C0060095175}" Visualized="true" Initialize="false" WriteProtected="true" Retentive="false"/>
		<Server Name="DeviceID" GUID="{293FCB43-F362-434D-8B62-54FDB70DDEA9}" Visualized="true" Initialize="false" WriteProtected="true" Retentive="false" Comment="id of the detected device at this place&#13;&#10;Bit8-7   Bus-Typ&#13;&#10;Bit6-4   Modul-Typ&#13;&#10;Bit3-1   Submodul-Typ"/>
		<Server Name="FWVersion" GUID="{63665078-4A8C-44A0-BCCD-70FF3FBF8ABF}" Visualized="true" Initialize="false" WriteProtected="true" Retentive="false" Comment="Firmware version of the safe io module&#13;&#10;&#13;&#10;Format:&#13;&#10;16#XXXXYYYY&#13;&#10;&#13;&#10;XXXX = Module ID&#13;&#10;YYYY = FW Version&#13;&#10;&#13;&#10;0 means the feature is not supported by the firmware of the SCP or from the module."/>
		<Server Name="HwVersion" GUID="{D0A7359B-DC0E-4079-8A27-968B09CDBE21}" Visualized="true" Initialize="false" WriteProtected="true" Retentive="false" Comment="Hardware version of the safe io module in the format xx.yy (e.g. 16#0120 means v1.20)&#13;&#10;0 means the feature is not supported by the firmware of the SCP"/>
		<Server Name="QuitComError" GUID="{D9C01530-B0F7-4D32-A95E-9725071F0254}" Visualized="true" Initialize="false" WriteProtected="false" Retentive="false" Comment="Write to this server to quit errors on safety cpu. &#13;&#10;It has the same function as QuitComError server on safety cpu.&#13;&#10;&#13;&#10;Server shows actual quit-state&#13;&#10;  2..busy with quitting general errors (safety dll version 6 or higher required)&#13;&#10;  1..busy with quitting communication error&#13;&#10;  0..ready&#13;&#10; -1..error at creating a new safety state&#13;&#10; -2..failed to disable user prompt for quit error&#13;&#10; -3..failed to select module via safety number&#13;&#10; -4..error at establishing connection to module (safety designer must not be online at the same time!)&#13;&#10; -5..failed to send the quit error command to the module&#13;&#10; -6..failed to delete the created safety state"/>
		<Server Name="RetryCounteruC1" GUID="{FDBE491B-4F19-4B40-90F6-E59B9DBD6C7E}" Visualized="true" Initialize="false" WriteProtected="true" Retentive="false" Comment="Shows the amount of retry counters of microprocessor 1.&#13;&#10;-1 ... Retrycounter read out is not supported by this firmware version."/>
		<Server Name="RetryCounteruC2" GUID="{9B5859BB-3C7F-449E-B724-F7D1D267F8EE}" Visualized="true" Initialize="false" WriteProtected="true" Retentive="false" Comment="Shows the amount of retry counters of microprocessor 2.&#13;&#10;-1 ... Retrycounter read out is not supported by this firmware version."/>
		<Server Name="SafetyNumber" GUID="{0A1547FA-741C-4E4B-A246-D35D487F9A2E}" Visualized="true" Initialize="false" WriteProtected="true" Retentive="false" Comment="This server shows the unique safety number of the hardware module"/>
		<Server Name="SerialNo" GUID="{17AB846E-6402-47B1-9757-A27B8E244FC0}" Class="String" Visualized="false" Initialize="false" WriteProtected="true" Retentive="false" Comment="This server shows the serial number of the hardware module."/>
		<Client Name="AnalogInputBytesNeeded" Required="false" Internal="false"/>
		<Client Name="InputsNeeded" Required="true" Internal="false"/>
		<Client Name="OutputsNeeded" Required="true" Internal="false"/>
		<Client Name="Place" Required="true" Internal="false" Comment="place at SDIAS Safety bus (0..15)"/>
		<Client Name="Required" Required="false" Internal="false" DefValue="1" Comment="0 = module is not required&#13;&#10;1 = module is required (CPU will crash if module is missing)"/>
		<Client Name="SdiasSafetyIn" Required="true" Internal="false" Comment="This client must be connected to a SdiasSafetyOut Server of a SCP011 class"/>
		<Client Name="SerialNoStr" Required="true" Internal="true"/>
		<Client Name="SetDeviceID" Required="true" Internal="false" Comment="Device ID of module&#13;&#10;Bit8-7   Bus-Typ&#13;&#10;Bit6-4   Modul-Typ&#13;&#10;Bit3-1   Submodul-Typ"/>
		<Client Name="toStdLib" Required="false" Internal="false"/>
	</Channels>
	<Dependencies>
		<Files>
			<File Path=".\Class\SdiasSafetyManager\SdiasSafetyManager.h" Include="true"/>
			<File Path=".\Class\SafetyBase\SafetyBase.h" Include="true"/>
			<File Path=".\Class\SdiasManager\SdiasManager.h" Include="true"/>
		</Files>
	</Dependencies>
	<RevDoku>
		<Owner Company="Sigmatek" Author="RamAnd"/>
		<Dokumentation Revision="1.10" Date="02.06.2021" Author="EisMic" Company="Sigmatek" Description="Added support to get fw version if available.&#13;&#10;Added support for safety analog input modules (SAI0xx).&#13;&#10;Added forwarding of newer SDIAS_CMD_xxx."/>
		<Dokumentation Revision="1.9" Date="31.07.2018" Author="ZoePat" Company="Sigmatek" Description="Added NewInst-command &quot;SDIAS_SAFETY_GET_INFO_PLACE&quot; to get the place."/>
		<Dokumentation Revision="1.8" Date="24.04.2018" Author="RamAnd" Company="Sigmatek" Description="Added server to show hardware version if this feature is supported by the safety firmware of the SCP."/>
		<Dokumentation Revision="1.7" Date="24.10.2016" Author="ZoePat" Company="Sigmatek" Description="Removed visualised-flag of server &quot;SerialNo&quot;, because the Server can not be used in the LSE. In excange the object of this class must be set to visualized in the derivations, to be able to visualize the embedded string object &quot;SerialNoStr&quot;."/>
		<Dokumentation Revision="1.6" Date="21.10.2014" Author="RamAnd" Company="Sigmatek" Description="Set Server QuitComError to visualized so it can be used in visualisation."/>
		<Dokumentation Revision="1.5" Date="31.10.2014" Author="lanste" Company="Sigmatek" Description="Added support to let derived classes react if the Hardware is not online."/>
		<Dokumentation Revision="1.4" Date="31.07.2014" Author="PieSte" Company="Sigmatek" Description="Added QuitComError server to quit errors on safety cpu."/>
		<Dokumentation Revision="1.3" Date="24.04.2014" Author="RamAnd" Company="Sigmatek" Description="Clear module info at the servers if a disconnect event occurs."/>
		<Dokumentation Revision="1.2" Date="22.04.2014" Author="EisMic" Company="Sigmatek" Description="Added new newinst command for safety retry counter."/>
		<Dokumentation Revision="1.1" Date="28.03.2014" Author="EisMic" Company="Sigmatek" Description="Added command in NewInst method of ClassState Server. Added servers RetryCounteruC1 and RetryCounteruC2."/>
		<Dokumentation Revision="1.0" Date="21.01.2014" Author="RamAnd" Company="Sigmatek" Description="First library version"/>
	</RevDoku>
	<Network Name="SdiasSafetyBase">
		<!-- List of Components in this network -->
		<Components>
			<Object
				Name       = "SerialNoStr"
				GUID       = "{CB4C4175-6645-4807-8DE2-8CCCC6A55AEE}"
				Class      = "String"
				Position   = "(240,300)"
				Visualized = "true">
				<Channels>
					<Server Name="Data"/>
					<Client Name="SingleRealloc" Value="1"/>
				</Channels>
			</Object>
		</Components>
		<Comments>
		</Comments>
		<!-- List of Connections in this network -->
		<Connections>
			<Connection Source="this.SerialNoStr" Destination="SerialNoStr.Data"/>
			<Connection Source="this.SerialNo" Destination="SerialNoStr.Data" Vertices="(728,450),(556,390),"/>
		</Connections>
		<!-- Headerfiles -->
		<Options>
		</Options>
	</Network>
</Class>
*)
SdiasSafetyBase : CLASS
  //Servers:
	ClassState 	: SvrChCmd_t_e_VaranErrors;
	DeviceID 	: SvrCh_UDINT;
	HwVersion 	: SvrCh_HDINT;
	FWVersion 	: SvrCh_HDINT;
	SerialNo 	: SvrChCmd_UDINT;
	SafetyNumber 	: SvrCh_HDINT;
	RetryCounteruC1 	: SvrCh_DINT;
	RetryCounteruC2 	: SvrCh_DINT;
	CallCommand 	: SvrChCmd_DINT;
	QuitComError 	: SvrCh_DINT;
  //Clients:
	SdiasSafetyIn 	: CltChCmd_DINT;
	Place 	: CltCh_UDINT;
	Required 	: CltCh_DINT;
	SetDeviceID 	: CltCh_DINT;
	InputsNeeded 	: CltCh_UDINT;
	OutputsNeeded 	: CltCh_UDINT;
	AnalogInputBytesNeeded 	: CltCh_DINT;
	toStdLib 	: CltChCmd__StdLib;
	SerialNoStr 	: CltChCmd_String;
  //Variables:
		us_FirstScan 	: DINT;
		IOStates : BDINT
		[
		];

		UnsafeOutputStates : BDINT
		[
		];

		us_oldRetryCounteruc1 	: USINT;			//! <Variable Comment="Marker for old retry counter from microprocessor 1." Name="us_oldRetryCounteruc1"/>
		us_oldRetryCounteruc2 	: USINT;			//! <Variable Comment="Marker for old retry counter from microprocessor 2." Name="us_oldRetryCounteruc2"/>
  //Functions:
	
	FUNCTION SdiasSafetyBase
		VAR_OUTPUT
			ret_code 	: ConfStates;
		END_VAR;
				//! <Function Comment="Called when class state was set to _NoHardware &#13;&#10;No Implementation Overload in derived classes if needed " Name="SetClassStateError"/>
	FUNCTION VIRTUAL SetClassStateError;
	
	FUNCTION VIRTUAL GLOBAL Init;
	
	FUNCTION VIRTUAL GLOBAL RtWork
		VAR_INPUT
			EAX 	: UDINT;
		END_VAR
		VAR_OUTPUT
			state (EAX) 	: UDINT;
		END_VAR;
	
	FUNCTION VIRTUAL GetAnalogInputDataPointer
		VAR_OUTPUT
			pAnalogInputData 	: ^void;
		END_VAR;
	
	FUNCTION VIRTUAL GLOBAL ClassState::NewInst
		VAR_INPUT
			pPara 	: ^CmdStruct;
			pResult 	: ^results;
		END_VAR
		VAR_OUTPUT
			ret_code 	: iprStates;
		END_VAR;
	
	FUNCTION VIRTUAL GLOBAL SerialNo::Read
		VAR_OUTPUT
			output (EAX) 	: UDINT;
		END_VAR;
	
	FUNCTION VIRTUAL GLOBAL SerialNo::Write
		VAR_INPUT
			input (EAX) 	: UDINT;
		END_VAR
		VAR_OUTPUT
			result (EAX) 	: UDINT;
		END_VAR;
	
	FUNCTION VIRTUAL GLOBAL CallCommand::NewInst
		VAR_INPUT
			pPara 	: ^CmdStruct;
			pResult 	: ^results;
		END_VAR
		VAR_OUTPUT
			ret_code 	: iprStates;
		END_VAR;
	
	FUNCTION VIRTUAL GLOBAL QuitComError::Write
		VAR_INPUT
			input (EAX) 	: DINT;
		END_VAR
		VAR_OUTPUT
			result (EAX) 	: DINT;
		END_VAR;
  //Tables:
	FUNCTION @STD
		VAR_OUTPUT
			ret_code	: CONFSTATES;
		END_VAR;
	FUNCTION GLOBAL TAB @CT_;
END_CLASS;

#pragma using String
#pragma usingLtd _StdLib


//}}LSL_DECLARATION


FUNCTION GLOBAL TAB SdiasSafetyBase::@CT_
0$UINT,
2#0100000000000000$UINT, //TY_SDIASSAFETYBASE
1$UINT, 10$UINT, (SIZEOF(::SdiasSafetyBase))$UINT, 
10$UINT, 9$UINT, 0$UINT, 
TO_UDINT(2010300054), "SdiasSafetyBase", //Class
TO_UDINT(0), 0, 0$UINT, 0$UINT, //Baseclass
//Servers:
(::SdiasSafetyBase.ClassState.pMeth)$UINT, _CH_CMD$UINT, 2#0000000000000000$UINT, TO_UDINT(1096059024), "ClassState", 
(::SdiasSafetyBase.DeviceID.pMeth)$UINT, _CH_SVR$UINT, 2#0000000000000000$UINT, TO_UDINT(4261957967), "DeviceID", 
(::SdiasSafetyBase.HwVersion.pMeth)$UINT, _CH_SVR$UINT, 2#0000000000000000$UINT, TO_UDINT(3247816137), "HwVersion", 
(::SdiasSafetyBase.FWVersion.pMeth)$UINT, _CH_SVR$UINT, 2#0000000000000000$UINT, TO_UDINT(156722779), "FWVersion", 
(::SdiasSafetyBase.SerialNo.pMeth)$UINT, _CH_SVR_OBJ$UINT, 2#0000000001000000$UINT, TO_UDINT(1856804640), "SerialNo", 
(::SdiasSafetyBase.SafetyNumber.pMeth)$UINT, _CH_SVR$UINT, 2#0000000000000000$UINT, TO_UDINT(2430374202), "SafetyNumber", 
(::SdiasSafetyBase.RetryCounteruC1.pMeth)$UINT, _CH_SVR$UINT, 2#0000000000000000$UINT, TO_UDINT(3589774504), "RetryCounteruC1", 
(::SdiasSafetyBase.RetryCounteruC2.pMeth)$UINT, _CH_SVR$UINT, 2#0000000000000000$UINT, TO_UDINT(1291767058), "RetryCounteruC2", 
(::SdiasSafetyBase.CallCommand.pMeth)$UINT, _CH_CMD$UINT, 2#0000000000000000$UINT, TO_UDINT(1059212957), "CallCommand", 
(::SdiasSafetyBase.QuitComError.pMeth)$UINT, _CH_SVR$UINT, 2#0000000000000000$UINT, TO_UDINT(1389350282), "QuitComError", 
//Clients:
(::SdiasSafetyBase.SdiasSafetyIn.pCh)$UINT, _CH_CLT_CMD$UINT, 2#0000000000000010$UINT, TO_UDINT(4176021060), "SdiasSafetyIn", 
(::SdiasSafetyBase.Place.pCh)$UINT, _CH_CLT_DATA$UINT, 2#0000000000000010$UINT, TO_UDINT(2202636669), "Place", 
(::SdiasSafetyBase.Required.pCh)$UINT, _CH_CLT_DATA$UINT, 2#0000000000000000$UINT, TO_UDINT(648558917), "Required", 
(::SdiasSafetyBase.SetDeviceID.pCh)$UINT, _CH_CLT_DATA$UINT, 2#0000000000000010$UINT, TO_UDINT(1188845681), "SetDeviceID", 
(::SdiasSafetyBase.InputsNeeded.pCh)$UINT, _CH_CLT_DATA$UINT, 2#0000000000000010$UINT, TO_UDINT(2449930879), "InputsNeeded", 
(::SdiasSafetyBase.OutputsNeeded.pCh)$UINT, _CH_CLT_DATA$UINT, 2#0000000000000010$UINT, TO_UDINT(957415998), "OutputsNeeded", 
(::SdiasSafetyBase.AnalogInputBytesNeeded.pCh)$UINT, _CH_CLT_DATA$UINT, 2#0000000000000000$UINT, TO_UDINT(1396409636), "AnalogInputBytesNeeded", 
(::SdiasSafetyBase.toStdLib.pCh)$UINT, _CH_CLT_OBJ$UINT, 2#0000000000000000$UINT, TO_UDINT(2501598121), "toStdLib", TO_UDINT(3689364044), "_StdLib", 2$UINT, 0$UINT, 
(::SdiasSafetyBase.SerialNoStr.pCh)$UINT, _CH_CLT_OBJ$UINT, 2#0000000000000010$UINT, TO_UDINT(321148131), "SerialNoStr", TO_UDINT(1850111279), "String", 1$UINT, 11$UINT, 
END_FUNCTION


#define USER_CNT_SdiasSafetyBase 2

TYPE
	_LSL_STD_VMETH	: STRUCT
			CmdTable	: CMDMETH;
			UserFcts	: ARRAY[0..USER_CNT_SdiasSafetyBase] OF ^Void;
	END_STRUCT;
END_TYPE

FUNCTION SdiasSafetyBase::@STD
	VAR_OUTPUT
		ret_code	: CONFSTATES;
	END_VAR
	VAR
		vmt	: _LSL_STD_VMETH;
	END_VAR

	//Command Methods
	InitCmdTable (nCmd := nSTDCMD + USER_CNT_SdiasSafetyBase, pCmd := #vmt.CmdTable);
	vmt.CmdTable.NewInstr		:= #NewInst();
#pragma warning (disable : 74)
	vmt.UserFcts[0]		:= #SetClassStateError();

#pragma warning (default : 74)
	vmt.CmdTable.Init		:= #Init();
	vmt.CmdTable.RtWork		:= #RtWork();
#pragma warning (disable : 74)
	vmt.UserFcts[1]		:= #GetAnalogInputDataPointer();

#pragma warning (default : 74)
	ClassState.pMeth		:= StoreCmd (pCmd := #vmt.CmdTable, SHARED);

	IF ClassState.pMeth THEN
		ret_code	:= C_OK;
	ELSE
		ret_code	:= C_OUTOF_NEAR;
		RETURN;
	END_IF;
	_memcpy((#vmt.CmdTable)$^USINT, SerialNo.pMeth, SIZEOF(CMDMETH));
	vmt.CmdTable.nCmds		:= nSTDCMD;
	vmt.CmdTable.Read		:= #SerialNo::Read();
	vmt.CmdTable.Write		:= #SerialNo::Write();
	SerialNo.pMeth		:= StoreCmd (pCmd := #vmt.CmdTable, SHARED);

	IF SerialNo.pMeth THEN
		ret_code	:= C_OK;
	ELSE
		ret_code	:= C_OUTOF_NEAR;
		RETURN;
	END_IF;
	_memcpy((#vmt.CmdTable)$^USINT, CallCommand.pMeth, SIZEOF(CMDMETH));
	vmt.CmdTable.nCmds		:= nSTDCMD;
	vmt.CmdTable.NewInstr		:= #CallCommand::NewInst();
	CallCommand.pMeth		:= StoreCmd (pCmd := #vmt.CmdTable, SHARED);

	IF CallCommand.pMeth THEN
		ret_code	:= C_OK;
	ELSE
		ret_code	:= C_OUTOF_NEAR;
		RETURN;
	END_IF;
	QuitComError.pMeth			:= StoreMethod( #M_RD_DIRECT(), #QuitComError::Write() );
	IF QuitComError.pMeth THEN
		ret_code	:= C_OK;
	ELSE
		ret_code	:= C_OUTOF_NEAR;
		RETURN;
	END_IF;
	ret_code	:= SdiasSafetyBase();

END_FUNCTION

//{{LSL_IMPLEMENTATION


FUNCTION VIRTUAL GLOBAL SdiasSafetyBase::Init
	VAR
		MyPara 	 : CmdStruct;
		MyResult : Results;
	END_VAR

#ifdef DEACTIVATED_LSL
  IF Place.Read() = DEACTIVATED_LSL THEN
    Place := DEACTIVATED_LSL;
    ClassState := _NoHardware;
    return;
  END_IF;
#endif

  us_FirstScan += 1;
  
  if us_FirstScan = 1 then
  
    Place         := Place.Read();
    Required    := required.Read();  
    SetDeviceID := SetDeviceID.Read();
    
    if AnalogInputBytesNeeded = 0 then
      
      //We 
      MyPara.uiCmd := SDIAS_SAFETY_LOGIN;
      MyPara.aPara[0] := this$DINT;
      MyPara.aPara[1] := Place$DINT;
      MyPara.aPara[2] := SetDeviceID$USINT;
      MyPara.aPara[3] := Required;
      MyPara.aPara[4] := InputsNeeded$USINT;
      MyPara.aPara[5] := OutputsNeeded$USINT;
      MyPara.aPara[6] := (#IOStates)$DINT;
      MyPara.aPara[7] := (#UnsafeOutputStates)$DINT;

      if SdiasSafetyIn.NewInst(#MyPara, #MyResult) <> READY then
#ifdef HWC_LogError
        HWC_LogError(this, "@077E (SdiasSafetyBase::Init) Failed to login to SdiasSafetyManager.");
#endif
      end_if;
    else
        
      //Use new version of login commando, is needed for analog input bytes 
      MyPara.uiCmd := SDIAS_SAFETY_LOGIN_V2;
          
      MyPara.aPara[0]  := 0x01;                         //version of command
      MyPara.aPara[1]  := this$DINT;                    //This pointer
      MyPara.aPara[2]  := Place$DINT;                   //Place
      MyPara.aPara[3]  := SetDeviceID$USINT;            //Set Device ID
      MyPara.aPara[4]  := Required;                     //Required Setting
      MyPara.aPara[5]  := InputsNeeded$USINT;           //InputsNeeded
      MyPara.aPara[6]  := OutputsNeeded$USINT;          //OutputsNeeded
      MyPara.aPara[7]  := (#IOStates)$DINT;             //IOStates
      MyPara.aPara[8]  := (#UnsafeOutputStates)$DINT;   //UnsafeOutputStates
      MyPara.aPara[9]  := AnalogInputBytesNeeded$USINT; //AnalogInputBytesNeeded
      
      
      MyPara.aPara[10] := GetAnalogInputDataPointer()$DINT; //Pointer to the analog input data

      if SdiasSafetyIn.NewInst(#MyPara, #MyResult) <> READY then
#ifdef HWC_LogError
        HWC_LogError(this, "@077E (SdiasSafetyBase::Init) Failed to login to SdiasSafetyManager.");
#endif
      end_if;
    
    end_if;

    
  
  end_if;

END_FUNCTION


FUNCTION SdiasSafetyBase::SdiasSafetyBase
	VAR_OUTPUT
		ret_code 	: ConfStates;
	END_VAR

  ClassState := _NotInitialized;
  
	ret_code := C_OK;

END_FUNCTION


FUNCTION VIRTUAL GLOBAL SdiasSafetyBase::RtWork
	VAR_INPUT
		EAX 	: UDINT;
	END_VAR
	VAR_OUTPUT
		state (EAX) 	: UDINT;
	END_VAR

  // overload this method to refresh the safe in- and outputs

	state := READY;

END_FUNCTION


FUNCTION VIRTUAL GLOBAL SdiasSafetyBase::ClassState::NewInst
	VAR_INPUT
		pPara 	: ^CmdStruct;
		pResult 	: ^Results;
	END_VAR
	VAR_OUTPUT
		ret_code 	: IprStates;
	END_VAR
  VAR
  	pSerNoStr : ^CHAR;
    TempVer   : ARRAY [0..3] OF HSINT;
  END_VAR

	ret_code := READY;

	CASE pPara^.uiCmd OF
//**********************************************************************************************************************************************************
		SDIAS_SET_CLASS_STATE:
    
      // Only set "_ModuleFoundButManagerIsOff" if state = _ClassOk so that errorstates do not get overwriten
      if ( (pPara^.aPara[0]$t_e_VaranErrors = _ModuleFoundButManagerIsOff) & 
           (ClassState <> _ClassOk) )  then
        return;
      end_if;

    
      ClassState := pPara^.aPara[0]$t_e_VaranErrors;
      DeviceID   := pPara^.aPara[1]$UDINT;
      
      // if the module has been disconnected => also delete the other infos about it
      if (ClassState = _NoHardware) then
        SerialNoStr.Clear();
        SafetyNumber := 0;
        
        // if we support retry counters => also reset them
        if RetryCounteruC1 <> -1 then
          RetryCounteruC1 := RetryCounteruC2 := 0;
          us_oldRetryCounteruc1 := us_oldRetryCounteruc2 := 0;
        end_if;        
        
      end_if;
      
      if (ClassState <> _ClassOk) then
        // Let derived classes update their servers
        SetClassStateError();
      end_if;

//**********************************************************************************************************************************************************
    SDIAS_SET_NUMBERS:
      SafetyNumber := pPara^.aPara[0]$HDINT;
      pSerNoStr    := pPara^.aPara[1]$^CHAR;
      SerialNoStr.WriteDataOff(udLen:=_strlen(src:=pSerNoStr), udOff:=0, pData:=pSerNoStr);
      
      //Check if hw version is available
      if pPara^.aPara[2]$HDINT then

(*

excerpt from SdiasManager firmware (translated to st)
iHwVersion ... 4 Byte Version from Type Label

Modul.HWVersion       := (iHwVersion SHR 24) AND 16#00FF;
Modul.HWVersionMidLow :=((iHwVersion SHR  8) AND 16#FF00) OR (iHwVersion AND 16#FF);


excerpt from SdiasManager class

// hardware version: for 1.10 (printed on the module) we have to transform 16#01 major and 16#0100 minor (drop high nibbles of minor) to 16#00000110
HwVersionServer  :=   Modul.HWVersion        SHL 8)            OR 
                    ((Modul.HWVersionMidLow  SHR 4) AND 16#F0) OR
                    ((Modul.HWVersionMidLow       ) AND 16#0F));

conclusion => take nibble 1,2,4 and 8 to generate a 2 byte version info

*)
        TempVer[0]$HDINT  := pPara^.aPara[2]$HDINT;     
        HwVersion         := ((TempVer[3] AND 16#FF) SHL 8) OR 
                             ((TempVer[2] AND 16#0F) SHL 4) OR
                              (TempVer[0] AND 16#0F);
      end_if;
      
      //Check if fw version is available
      if pPara^.aPara[3]$HDINT then
        FWVersion := pPara^.aPara[3]$HDINT;     
      end_if;
      
      
//**********************************************************************************************************************************************************
    SDIAS_SET_RETRY_COUNTER:
    //Only Write if Retry counter has changed
    if pPara^.aPara[0] <> us_oldRetryCounteruc1 then
      //Add new amount and substract the old one
      RetryCounteruC1 += to_usint(pPara^.aPara[0] - us_oldRetryCounteruc1);
      us_oldRetryCounteruc1 := pPara^.aPara[0]$USINT;
                        
    end_if;
    
    //Only Write if Retry counter has changed
    if pPara^.aPara[1] <> us_oldRetryCounteruc2 then
      //Add new amount and substract the old one
      RetryCounteruC2 += to_usint(pPara^.aPara[1] - us_oldRetryCounteruc2);
      us_oldRetryCounteruc2 := pPara^.aPara[1]$USINT;
      
    end_if;
    
//**********************************************************************************************************************************************************
    SDIAS_RETRY_COUNTER_NOT_AVAILABLE:
      RetryCounteruC1 := -1;
      RetryCounteruC2 := -1;
      
//**********************************************************************************************************************************************************
	  SDIAS_SET_ASY_STATE:
      QuitComError := pPara^.aPara[0]$^t_AsyRefresh^.QuitComError;
      
//**********************************************************************************************************************************************************
    SDIAS_SAFETY_GET_INFO_PLACE:
      // return the safety place
      ret_code := READY;
      pResult^.uiLng := sizeof(UINT);
      pResult^.aData[0]$UINT := Place$UINT;

//**********************************************************************************************************************************************************
  END_CASE;

END_FUNCTION


FUNCTION VIRTUAL GLOBAL SdiasSafetyBase::CallCommand::NewInst
	VAR_INPUT
		pPara 	: ^CmdStruct;
		pResult 	: ^Results;
	END_VAR
	VAR_OUTPUT
		ret_code 	: IprStates;
	END_VAR

	ret_code := ERROR;

	CASE pPara^.uiCmd OF
//**********************************************************************************************************************************************************
    // forward commands from clients to manager 
    SDIAS_CMD_ADD_RD_ACCESS,
    SDIAS_CMD_ADD_WR_ACCESS,
    SDIAS_CMD_SDO_SEND_REQUEST,
    SDIAS_CMD_CHANGE_LED_STATE,
    SDIAS_CMD_DA_RD_ACCESS,
    SDIAS_CMD_DA_WR_ACCESS,
    SDIAS_CMD_REQUIRED_ERROR,
    SDIAS_CMD_INIT_STATE_LOGIN,
    SDIAS_CMD_GET_HW_PATH,
    SDIAS_CMD_INSTALL_CYCLIC_TASK,
    SDIAS_CMD_GET_CONNECTION_TYPE,
    SDIAS_CMD_GET_MIB_ADDR,
    SDIAS_CMD_GET_MOI_ADDR,
    SDIAS_CMD_ADD_DYN_RD_ACCESS,
    SDIAS_CMD_ADD_DYN_WR_ACCESS,
    SDIAS_CMD_CHANGE_DYN_ACCESS,
    SDIAS_CMD_CREATE_MUTEX,
    SDIAS_CMD_IS_VARAN_AVAILABLE,
    SDIAS_CMD_GET_OWN_OBJECTPATH,
    SDIAS_CMD_ADD_DEVICE_ID,
    SDIAS_CMD_GET_SUPPORTED_FEATURES:
      ret_code := SdiasSafetyIn.NewInst(pPara, pResult);
//**********************************************************************************************************************************************************
	END_CASE;

END_FUNCTION


FUNCTION VIRTUAL GLOBAL SdiasSafetyBase::SerialNo::Read
	VAR_OUTPUT
		output (EAX) 	: UDINT;
	END_VAR

	SerialNo := SerialNoStr.Data.Read();
	output := SerialNo;

END_FUNCTION


FUNCTION VIRTUAL GLOBAL SdiasSafetyBase::SerialNo::Write
	VAR_INPUT
		input (EAX) 	: UDINT;
	END_VAR
	VAR_OUTPUT
		result (EAX) 	: UDINT;
	END_VAR

	SerialNo := input;
	result := (SerialNoStr.Data.Write(SerialNo))$UDINT;

END_FUNCTION


FUNCTION VIRTUAL GLOBAL SdiasSafetyBase::QuitComError::Write
	VAR_INPUT
		input (EAX) 	: DINT;
	END_VAR
	VAR_OUTPUT
		result (EAX) 	: DINT;
	END_VAR
  VAR
		MyPara 	  : CmdStruct;
		MyResult	: results;
  END_VAR

  QuitComError := input;
  // tell the outer class
  MyPara.uiCmd    := SDIAS_SET_QUITCOMERROR_IO;
  MyPara.aPara[0] := QuitComError;
  result$UDINT    := SdiasSafetyIn.NewInst(#MyPara, #MyResult);
	
END_FUNCTION


FUNCTION VIRTUAL SdiasSafetyBase::SetClassStateError

  // Called when class state was set to _NoHardware 
  // No Implementation Overload in derived classes if needed 
  
END_FUNCTION


FUNCTION VIRTUAL SdiasSafetyBase::GetAnalogInputDataPointer
	VAR_OUTPUT
		pAnalogInputData 	: ^void;
	END_VAR
  
  pAnalogInputData := NIL;
  
  //Method has to be overwritten in derived classes when using analog input data
  
END_FUNCTION
