FUNCTION_BLOCK "FB_TCP_LCOM_TeleHandler"
{ S7_Optimized_Access := 'TRUE' }
VERSION : 0.1
   VAR_INPUT 
      xInGetFirst : Bool;   // Holt das erste älteste Telegram aus dem Puffer 
      xInReset : Bool;   // Setzt den TeleHandler zurück
      xInSendTele : Bool;   // Das gewünschte Telegram wird versendet
      stInTelegramSend : "UDT_TelegramData_Send";   // Das Telegram, dass versendet werden soll
      stInTelegramDefinition : "UDT_TelegramDefinition";   // Telegram-Definition 
      stInTcpTypeConfig : "LCom_typeConfig";
   END_VAR

   VAR_OUTPUT 
      stOutNewTelegram : "UDT_TelegramData";   // Das erste älteste Telegram, wird mit xInGetFirst geholt
      xOutConnectionActive : Bool;   // Verbindungszustand zum Partner
      xOutTelegramAvailable : Bool;   // Zeigt an, ob ein Telegram zur Verfügung steht
      xOutError : Bool;   // Fehler 
      sOutErrorText : String;   // Fehler Text
   END_VAR

   VAR_IN_OUT 
      xInOutSendTele : Bool;
      fbInOutSendFIFO : "LGF_FIFO";
      arFifoSendBuffer : Array[1..100] of "UDT_TelegramData_Send";
   END_VAR

   VAR 
      stTelegramSend { S7_SetPoint := 'False'} : "UDT_TelegramData_Send";
      xStart : Bool;
      arTelegramList { S7_SetPoint := 'False'} : Array[0.."TELEGRAM_RECV_LIST_MAX"] of "UDT_TelegramData";   // Telegramliste mit allen aktuellen Telegrammen
      nTelegramListWrite { S7_SetPoint := 'True'} : DInt := 0;   // Index zum Schreiben
      nTelegramListRead { S7_SetPoint := 'True'} : DInt := 0;   // Index zum Lesen
      fbTeleRecvFifo : "LGF_FIFO";
      fbTeleSendFifo : "LGF_FIFO";
      fbTcpComm { S7_SetPoint := 'False'} : "LCom_Communication";   // Aufruf TCP-Baustein // IST MULTIINSTANZ HIER SINNVOLL???
      stTcpParam : Struct   // TCP-Parameter
         xEnable : Bool;   // enables TCP/IP connection
         xSendRequest : Bool;   // triggers a send request
         xSending : Bool;
         nRcvLen : UInt;   // length of data you want to receive from partner (opt. DBs = 0)
         nSendLen : UInt;   // length of date so send to partner
         xAdhocMode : Bool;   // activate adhoc Mode to receive data with variable len
         xConnectionEstablished { S7_SetPoint := 'True'} : Bool;   // connection to partner established
         xNdr { S7_SetPoint := 'True'} : Bool;   // new data received
         xDone { S7_SetPoint := 'True'} : Bool;   // send request finished successully
         xBusy : Bool;   // block is busy
         xError : Bool;   // error occurred
         nRcvdLen : UDInt;   // length of received data
         nStatusId : UInt;   // error location in block
         nStatus : Word;   // status word from OUC blocks
         t_TelegramReceiveBuffer : Array[0..#cTelegramLengthReceive] of Byte;   // Empfangspuffer
         t_TelegramSendBuffer : Array[0..#cTelegramLengthSend] of Byte;   // Sendepuffer
         stDiagnosticData : "LCom_typeDiagnostics";
         stTypeConfig : "LCom_typeConfig";
      END_STRUCT;
      stRecvFifoParam : Struct   // Recv-Fifo Parameter
         xEnq : Bool;
         xDeq : Bool;
         xReset : Bool;
         xClear : Bool;
         nInitItem : String;
         nMaxElementCount : USInt;
         sStringIn : String;
         sStringOut : String;
         arStringBuffer : Array[1..10] of String;
      END_STRUCT;
      stSendFifoParam : Struct   // Send-Fifo Parameter
         xEnq : Bool;
         xDeq : Bool;
         xReset : Bool;
         xClear : Bool;
         nInitItem : String;
         nMaxElementCount : USInt;
         sStringIn : String;
         sStringOut : String;
         arStringBuffer : Array[1..100] of String;
      END_STRUCT;
      statEdgeGetFirst : Bool;   // Flankenmerker GetFirst
      statEdgeReset : Bool;   // Flankenmerker Reset
      statEdgeSend : Bool;   // Flankenmerker Send
      stTelegramDefinition { S7_SetPoint := 'False'} : "UDT_TelegramDefinition";   // Telegram-Definition
      stFirstTelegram : "UDT_TelegramData";   // Das erste älteste Telegram
      sBuildString { S7_SetPoint := 'True'} : String;   // String zum Versenden wird hier zusammengestellt
      nStateConn : Int;   // Verbindungszustand TCP
      sConnectionStatus : String;   // Verbindungzustand TCP Text
      tOnRetryEnable {InstructionName := 'TON_TIME'; LibVersion := '1.0'} : TON_TIME;   // Totzeit Verbindung neu aufbauen
      tOnWatchdogConn {InstructionName := 'TON_TIME'; LibVersion := '1.0'} : TON_TIME;   // Überwachungszeit Verbindungsaufbau
      arAnalyzeBuffer : Array[0..100000] of Byte;   // Zwischenpuffer für Parser
      nAnalyzeBufferLen : UDInt := 0;   // Länge des Zwischenpuffer
      nParseState : Int;   // Parse Zustand
      nLenTelegram : UDInt;   // Hilfsvariable Telegrammlänge
      arRecvdTelegram : Array[0..100000] of Byte;   // Das empfangene Telegramm in Bytes
      xTelegramAvailable { S7_SetPoint := 'True'} : Bool;   // Zeigt an, ob ein Telegramm zur Verfügung steht
      xTestSend : Bool;
      "Char" : Char;
      "String" : String[1];
      fbEventLogSending : "FB_EventLog_Root";
      fbEventLogReceiving : "FB_EventLog_Root";
      sLogReceiveMessage : String;
      sLogRecvSingle : String[1];
      fTrigSending {InstructionName := 'F_TRIG'; LibVersion := '1.0'} : F_TRIG;
   END_VAR

   VAR_TEMP 
      tempEdgeGetFirst : Bool;
      tempEdgeReset : Bool;
      tempEdgeSend : Bool;
      i : DInt;
      x : UDInt;
      y : UDInt;
      p : UDInt;
      n : UDInt;
      r : UDInt;
      RetVal_MoveBlk_RecvdTele : Int;
      RetVal_MoveBlk_Zwischenpuffer : Int;
      RetVal_MoveBlk_ZwPu : Int;
      Laenge : DInt;
      a : UDInt;
      RetVal_StartMarkerFound : Bool;
      RetVal_EndMarkerFound : Bool;
      strLen : UInt;
      xSuccess_Append_SendFIFO : Bool;
      xSuccess_GF_SendFIFO : Bool;
      sInitialEmptyString : String;
      j : DInt;
      stInitialTelegram : "UDT_TelegramData_Send";
      empty : "UDT_TelegramData_Send";
      xSuccess : Bool;
   END_VAR

   VAR CONSTANT 
      cTelegramLengthSend : UDInt := 65535;   // Länge des Sendepuffer
      cTelegramLengthReceive : UDInt := 65535;   // Länge des Empfangspuffer
      cCheckSumLength : UDInt := 10;   // Checksumme Länge
      STATE_NOTCONNECTED : Int := 0;   // State: nicht Verbunden
      STATE_CONNECTED : Int := 1;   // State: Verbunden
      STATE_RECONNECT : Int := 4;   // State: Neu verbinden
      E_TeleParseState_START : Int := 0;   // ParseState: Warte auf Startmarker
      E_TeleParseState_DATA : Int := 1;   // ParseState: Analyse Daten
   END_VAR


BEGIN
	REGION Edges
	    // Flankenerkennung
	    #tempEdgeGetFirst := #xInGetFirst AND NOT #statEdgeGetFirst;
	    #statEdgeGetFirst := #xInGetFirst;
	    
	    #tempEdgeReset := #xInReset AND NOT #statEdgeReset;
	    #statEdgeReset := #xInReset;
	    
	    #tempEdgeSend := #xInOutSendTele AND NOT #statEdgeSend;
	    #statEdgeSend := #xInOutSendTele;
	    
	END_REGION
	
	REGION Initialize 
	    // Eingangswerte werden umkopiert
	    #stTelegramDefinition.sStartMarker := #stInTelegramDefinition.#sStartMarker;
	    #stTelegramDefinition.nStartMarkerLen := INT_TO_UDINT(LEN(#stInTelegramDefinition.#sStartMarker));
	    
	    #stTelegramDefinition.sEndMarker := #stInTelegramDefinition.#sEndMarker;
	    #stTelegramDefinition.nEndMarkerLen := INT_TO_UDINT(LEN(#stInTelegramDefinition.#sEndMarker));
	    
	    #stTelegramDefinition.bSeparatorByte := #stInTelegramDefinition.#bSeparatorByte;
	    
	    #stTelegramDefinition.sStartMarkerSend := #stInTelegramDefinition.#sStartMarkerSend;
	    #stTelegramDefinition.nStartMarkerLenSend := INT_TO_UDINT(LEN(#stInTelegramDefinition.#sStartMarkerSend));
	    
	    #stTelegramDefinition.sEndMarkerSend := #stInTelegramDefinition.#sEndMarkerSend;
	    #stTelegramDefinition.nEndMarkerLenSend := INT_TO_UDINT(LEN(#stInTelegramDefinition.#sEndMarkerSend));
	    
	    #stTelegramDefinition.nLength := #stInTelegramDefinition.#nLength;
	    
	    #stTelegramDefinition.nTelegramIDDataField := #stInTelegramDefinition.#nTelegramIDDataField;
	    #stTelegramDefinition.xTelegramIDIsNumber := #stInTelegramDefinition.#xTelegramIDIsNumber;
	    
	END_REGION
	
	REGION Reset
	    // Telehandler rücksetzen
	    IF #tempEdgeReset THEN
	        FOR #i := 0 TO 100000 DO
	            #arAnalyzeBuffer[#i] := 0;
	        END_FOR;
	        
	        // #arAnalyzeBuffer := #arEmptyBuffer;
	        #nAnalyzeBufferLen := 0;
	        
	        FOR #i := 0 TO "TELEGRAM_RECV_LIST_MAX" DO
	            #arTelegramList[#i].sIDString := '';
	            #arTelegramList[#i].nID := 0;
	            #arTelegramList[#i].xCRC32ValidationResult := FALSE;
	            FOR #j := 1 TO "TELEGRAM_DATA_MAX" DO
	                #arTelegramList[#i].arDataString[#j] := '';
	            END_FOR;
	            #arTelegramList[#i].nDataCount := 0;
	        END_FOR;
	        
	        #nTelegramListRead := 0;
	        #nTelegramListWrite := 0;
	        
	        //   #stFirstTelegram := #stEmptyTelegram;
	        #stFirstTelegram.nDataCount := 0;
	        #stFirstTelegram.nID := 0;
	        #stFirstTelegram.sIDString := '';
	        #stFirstTelegram.xCRC32ValidationResult := FALSE;
	        FOR #i := 1 TO "TELEGRAM_DATA_MAX" DO
	            #stFirstTelegram.arDataString[#i] := '';
	        END_FOR;
	        
	        #stSendFifoParam.xClear := TRUE;
	        FOR #i := 0 TO 65535 DO
	            #stTcpParam.t_TelegramSendBuffer[#i] := 0;
	        END_FOR;
	        
	        //  #stTcpParam.t_TelegramSendBuffer := #arEmptyBuffer;
	        
	    ELSE
	        #stSendFifoParam.xClear := FALSE;
	    END_IF;
	    
	END_REGION
	
	REGION GetFirst
	    IF #tempEdgeGetFirst THEN   // Erstes Telegram holen
	        IF (#nTelegramListRead <> #nTelegramListWrite) THEN // Liste ist nicht leer
	            #stFirstTelegram := #arTelegramList[#nTelegramListRead]; // Erstes Telegram schreiben
	            
	            #nTelegramListRead := #nTelegramListRead + 1;   // Lese-Index inkrementieren
	            IF (#nTelegramListRead > "TELEGRAM_RECV_LIST_MAX") THEN   // Lese-Index rücksetzen wenn Max erreicht
	                #nTelegramListRead := 0;
	            END_IF;
	            
	            #xTelegramAvailable := (#nTelegramListRead <> #nTelegramListWrite); // Telegramm verfügbar, wenn Indexe ungleich
	        ELSE
	            //   #stFirstTelegram := #stEmptyTelegram;
	            #stFirstTelegram.nDataCount := 0;
	            #stFirstTelegram.nID := 0;
	            #stFirstTelegram.sIDString := '';
	            #stFirstTelegram.xCRC32ValidationResult := FALSE;
	            FOR #i := 1 TO "TELEGRAM_DATA_MAX" DO
	                #stFirstTelegram.arDataString[#i] := '';
	            END_FOR;
	            // TODO Error                           // Fehler erzeugen, weil z.B. FIFO leer ist
	        END_IF;
	    END_IF;
	    
	END_REGION
	
	
	REGION Parse
	    IF (* #xStart *)(#nStateConn = #STATE_CONNECTED) AND #stTcpParam.xNdr THEN // neue Daten?
	        FOR #p := 0 TO #stTcpParam.nRcvdLen - 1 DO // Alle empfangenen Bytes durchgehen
	            #arAnalyzeBuffer[#nAnalyzeBufferLen] := #stTcpParam.t_TelegramReceiveBuffer[#p];   // Byte[p] von Empfangspuffer in Analysepuffer kopieren
	            #nAnalyzeBufferLen := #nAnalyzeBufferLen + 1;                     // Pufferlänge inkrementieren
	            
	            REGION 0000: ParseState = START
	                // ParseState = Start
	                IF #nParseState = #E_TeleParseState_START THEN  // Start-Zustand
	                    IF #stTelegramDefinition.nStartMarkerLen > 0 THEN // Start Marker definiert? (>0 bedeutet das einer definiert wurde)
	                        IF #nAnalyzeBufferLen >= #stTelegramDefinition.nStartMarkerLen THEN    // Wenn die Zeichen im Zwischenpuffer noch geringer sind als die Länge des definierten Startmarkers, dann nichts zu tun, nächstes Zeichen holen --> END_IF
	                            #RetVal_StartMarkerFound := "FC_ParseCheckForStart"(bInNewData := #stTcpParam.t_TelegramReceiveBuffer[#p], //Funktion überprüft den Startmarker
	                                                                                arInBuffer := #arAnalyzeBuffer,
	                                                                                nInBufferLen := #nAnalyzeBufferLen,
	                                                                                stInTelegramDefinition := #stTelegramDefinition);
	                            IF NOT #RetVal_StartMarkerFound THEN
	                                #RetVal_MoveBlk_ZwPu := MOVE_BLK_VARIANT(SRC := #arAnalyzeBuffer, COUNT := #nAnalyzeBufferLen - 1, SRC_INDEX := 1, DEST_INDEX := 0, DEST => #arAnalyzeBuffer);
	                                #nAnalyzeBufferLen := #nAnalyzeBufferLen - 1;
	                            ELSE
	                                #nParseState := #E_TeleParseState_DATA; //StartMarker gefunden, Zustandswechsel zu Daten
	                            END_IF;
	                        END_IF;
	                    ELSE    // Es wurde kein StartMarker definiert / ohne Startmarker
	                        #nParseState := #E_TeleParseState_DATA;
	                    END_IF;
	                END_IF;
	            END_REGION
	            
	            REGION 0001: ParseState = DATA
	                IF #nParseState = #E_TeleParseState_DATA THEN   // Daten-Analyse
	                    #RetVal_EndMarkerFound := "FC_ParseCheckForEnd"(bInNewData := #stTcpParam.t_TelegramReceiveBuffer[#p], // Funktion überprüft den Endmarker
	                                                                    arInBuffer := #arAnalyzeBuffer,
	                                                                    nInBufferLen := #nAnalyzeBufferLen,
	                                                                    stInTelegramDefinition := #stTelegramDefinition);
	                    
	                    #RetVal_StartMarkerFound := "FC_ParseCheckForStart"(bInNewData := #stTcpParam.t_TelegramReceiveBuffer[#p], //Funktion überprüft den Startmarker
	                                                                        arInBuffer := #arAnalyzeBuffer,
	                                                                        nInBufferLen := #nAnalyzeBufferLen,
	                                                                        stInTelegramDefinition := #stTelegramDefinition);
	                    
	                    IF #RetVal_EndMarkerFound THEN  // End-Marker wurde gefunden
	                        // reset RecvdTelegram
	                        // #arRecvdTelegram := #arEmptyBuffer;
	                        FOR #i := 0 TO 100000 DO
	                            #arRecvdTelegram[#i] := 0;
	                        END_FOR;
	                        
	                        // Telegram aus Puffer rauskopieren ohne die Marker!
	                        #nLenTelegram := (#nAnalyzeBufferLen - (#stTelegramDefinition.nStartMarkerLen + #stTelegramDefinition.nEndMarkerLen));
	                        #RetVal_MoveBlk_RecvdTele := MOVE_BLK_VARIANT(SRC := #arAnalyzeBuffer, COUNT := #nLenTelegram, SRC_INDEX := #stTelegramDefinition.nStartMarkerLen, DEST_INDEX := 0, DEST => #arRecvdTelegram);
	                        
	                        // Zwischenpuffer reset
	                        FOR #i := 0 TO 100000 DO
	                            #arAnalyzeBuffer[#i] := 0;
	                        END_FOR;
	                        
	                        // #arAnalyzeBuffer := #arEmptyBuffer;
	                        #nAnalyzeBufferLen := 0;
	                        
	                        //Reset die telegramList-Position wo wir die neuen Daten reinschreiben
	                        //      #arTelegramList[#nTelegramListWrite] := #stEmptyTelegram;
	                        
	                        #arTelegramList[#nTelegramListWrite].nID := 0;
	                        #arTelegramList[#nTelegramListWrite].sIDString := '';
	                        #arTelegramList[#nTelegramListWrite].xCRC32ValidationResult := FALSE;
	                        FOR #i := 1 TO "TELEGRAM_DATA_MAX" DO
	                            #arTelegramList[#nTelegramListWrite].arDataString[#i] := '';
	                        END_FOR;
	                        #arTelegramList[#nTelegramListWrite].nDataCount := 1;
	                        
	                        IF (#stTelegramDefinition.bSeparatorByte <> 0) THEN // Es gibt ein Separator Byte, ansonsten wird davon ausgegangen, dass es alles am Stück ist
	                            #x := 0;
	                            FOR #y := 0 TO #nLenTelegram DO // Ganzes Telegram durchgehen
	                                IF (#arRecvdTelegram[#y] = #stTelegramDefinition.bSeparatorByte) THEN // Wenn das Byte dem Separator-Byte entspricht
	                                    #x := 0;
	                                    #arTelegramList[#nTelegramListWrite].nDataCount := #arTelegramList[#nTelegramListWrite].nDataCount + 1; // DataCount inkrementieren, da neues Datenfeld
	                                    IF (#arTelegramList[#nTelegramListWrite].nDataCount > "TELEGRAM_DATA_MAX") THEN // Fehler abfangen, wenn zu viele Datenfelder im Telegram sind
	                                        // TODO Error erzeugen
	                                        EXIT;
	                                    END_IF;
	                                ELSE
	                                    IF (#x <= "TELEGRAM_DATA_FIELD_MAX") THEN
	                                        #String := CHAR_TO_STRING((BYTE_TO_CHAR(#arRecvdTelegram[#y])));
	                                        #arTelegramList[#nTelegramListWrite].arDataString[#arTelegramList[#nTelegramListWrite].nDataCount] := CONCAT(IN1 := #arTelegramList[#nTelegramListWrite].arDataString[#arTelegramList[#nTelegramListWrite].nDataCount], IN2 := #String);
	                                        //   #arData_Test[#arTelegramList[#nTelegramListWrite].nDataCount, #x + 1] := #arRecvdTelegram[#y]; // Byte in 2D-Array of Byte schreiben
	                                        #x := #x + 1;
	                                    END_IF;
	                                END_IF;
	                            END_FOR;
	                        ELSE    // Wenn kein Separator-Byte definiert wurde, dann das Telegram an die erste Position schreiben
	                            FOR #a := 0 TO #nLenTelegram DO
	                                //  #arData_Test[1, #a + 1] := #arRecvdTelegram[#a];
	                                #String := CHAR_TO_STRING((BYTE_TO_CHAR(#arRecvdTelegram[#a])));
	                                #arTelegramList[#nTelegramListWrite].arDataString[#arTelegramList[#nTelegramListWrite].nDataCount] := CONCAT(IN1 := #arTelegramList[#nTelegramListWrite].arDataString[#arTelegramList[#nTelegramListWrite].nDataCount], IN2 := #String);
	                            END_FOR;
	                        END_IF;
	                        
	                        // convert each byte field into a string  
	                        (*  FOR #n := 1 TO DINT_TO_UDINT(#arTelegramList[#nTelegramListWrite].nDataCount) DO //1 TO 64
	                            Chars_TO_Strg(Chars := #arData_Test[#n],
	                                          pChars := 0,
	                                          Cnt := "TELEGRAM_DATA_FIELD_MAX",
	                                          Strg => #arTelegramList[#nTelegramListWrite].arDataString[#n]);
	                        END_FOR; *)
	                        
	                        // increment write pointer to telegram data ring buffer:
	                        
	                        #sLogReceiveMessage := '';
	                        FOR #a := 0 TO #nLenTelegram DO
	                            #sLogRecvSingle := CHAR_TO_STRING((BYTE_TO_CHAR(#arRecvdTelegram[#a])));
	                            #sLogReceiveMessage := CONCAT(IN1 := #sLogReceiveMessage, IN2 := #sLogRecvSingle);
	                        END_FOR;
	                        
	                        
	                        #fbEventLogReceiving.sInMessage := #sLogReceiveMessage;
	                        (* FOR #j := 1 TO #arTelegramList[#nTelegramListWrite].nDataCount DO
	                             #fbEventLogReceiving.sInMessage := CONCAT_STRING(IN1:= #fbEventLogReceiving.sInMessage, IN2:= '<GS>',IN3:=#arTelegramList[#nTelegramListWrite].arDataString[#j]);
	                         END_FOR; *)
	                        #fbEventLogReceiving.xInTrigger := 1;
	                        
	                        #nTelegramListWrite := #nTelegramListWrite + 1;
	                        IF (#nTelegramListWrite > "TELEGRAM_RECV_LIST_MAX") THEN // Wenn Maximum an Telegrammen erreicht, dann Index zurücksetzen, ältestes wird überschrieben
	                            #nTelegramListWrite := 0;
	                        END_IF;
	                        
	                        #xTelegramAvailable := TRUE; // Info rausgeben
	                        
	                        #nParseState := #E_TeleParseState_START; // Zustandswechsel 
	                        
	                    END_IF;
	                ELSIF #RetVal_StartMarkerFound AND (#nAnalyzeBufferLen > #stTelegramDefinition.nStartMarkerLen) THEN
	                    //  #Laenge := #nAnalyzeBufferLen - #stTelegramDefinition.nStartMarkerLen; // 8192 - ...
	                    #RetVal_MoveBlk_Zwischenpuffer := MOVE_BLK_VARIANT(SRC := #arAnalyzeBuffer, COUNT := ((#cTelegramLengthReceive + 1) - #nAnalyzeBufferLen - #stTelegramDefinition.nStartMarkerLen), SRC_INDEX := UDINT_TO_DINT(#nAnalyzeBufferLen - #stTelegramDefinition.nStartMarkerLen), DEST_INDEX := 0, DEST => #arAnalyzeBuffer);
	                    #nAnalyzeBufferLen := #stTelegramDefinition.nStartMarkerLen;
	                ELSE
	                    IF (UDINT_TO_DINT(#stTelegramDefinition.nLength) > 0 AND
	                        #nAnalyzeBufferLen >= UDINT_TO_DINT(#stTelegramDefinition.nLength)) THEN
	                        
	                        #RetVal_MoveBlk_Zwischenpuffer := MOVE_BLK_VARIANT(SRC := #arAnalyzeBuffer, COUNT := #cTelegramLengthReceive + 1, SRC_INDEX := 1, DEST_INDEX := 0, DEST => #arAnalyzeBuffer);
	                        
	                        #nAnalyzeBufferLen := #nAnalyzeBufferLen - 1;
	                        
	                    END_IF;
	                END_IF;
	            END_REGION
	            
	        END_FOR;
	        FOR #i := 0 TO 65535 DO
	            #stTcpParam.t_TelegramReceiveBuffer[#i] := 0;
	        END_FOR;
	        //  #stTcpParam.t_TelegramReceiveBuffer := #temp_TelegramReceiveBuffer;
	    END_IF;
	    #xStart := FALSE;
	    
	END_REGION
	
	(* REGION Sending
	    IF #tempEdgeSend THEN
	        REGION Prepare new Telegram and add to Send-FIFO
	            // add start string
	            IF (#stTelegramDefinition.sStartMarkerSend <> '') THEN
	                #sBuildString := #stTelegramDefinition.sStartMarkerSend;
	            ELSE
	                #sBuildString[1] := '0';
	            END_IF;
	            
	            // add data fields:
	            FOR #i := 1 TO #stInTelegramSend.nDataCount DO
	                IF (#i > 1) THEN
	                    #sBuildString := CONCAT(IN1 := #sBuildString, IN2 := CHAR_TO_STRING(#stTelegramDefinition.bSeparatorByte));
	                END_IF;
	                
	                IF (#stInTelegramSend.arDataString[#i] <> '') THEN
	                    #sBuildString := CONCAT(IN1 := #sBuildString, IN2 := #stInTelegramSend.arDataString[#i]);
	                END_IF;
	            END_FOR;
	            
	            // add end string:
	            IF (#stTelegramDefinition.sEndMarkerSend <> '') THEN
	                #sBuildString := CONCAT(IN1 := #sBuildString, IN2 := #stTelegramDefinition.sEndMarkerSend);
	            END_IF;
	            
	            REGION SendStr
	                // hier dann sBuildString mit Enqueue in SendFIFO schieben zum Versenden
	                IF NOT #fbTeleSendFifo.isFull THEN
	                    //        #stSendFifoParam.sStringIn := #sBuildString;
	                    "FC_FIFO_Append"(DataIn := #sBuildString,
	                                     InitialItem := #sInitialEmptyString,
	                                     MaxNo := 100,
	                                     Success => #xSuccess_Append_SendFIFO,
	                                     fifoBuffer := #fbTeleSendFifo,
	                                     buffer := #stSendFifoParam.arStringBuffer);
	                    //     #stSendFifoParam.xEnq := TRUE;
	                    #xInOutSendTele := FALSE;
	                    #fbEventLogSending.sInMessage := #sBuildString;
	                    #fbEventLogSending.xInTrigger := 1;
	                ELSE
	                    // Error Todo
	                    ;
	                END_IF;
	            END_REGION ;
	        END_REGION
	    END_IF;
	END_REGION *)
	
	REGION Send Telegram
	    IF NOT #fbInOutSendFIFO.isEmpty AND                 // Es gibt etwas zum Senden?
	        (#nStateConn = #STATE_CONNECTED) AND // Verbindung zum Partner aufgebaut
	        //NOT #stSendFifoParam.xDeq AND                  // FIFO nicht busy
	        NOT #stTcpParam.xSendRequest AND                   // Aktuell kein aktiver Sendeauftrag
	        NOT #stTcpParam.xSending
	    THEN
	        "FC_FIFO_GetFirst"(xInInitialItem := #stInitialTelegram,
	                           nInMaxNo := 100,
	                           xOutSuccess => #xSuccess_GF_SendFIFO,
	                           xOutData => #stTelegramSend,
	                           fifoBuffer := #fbInOutSendFIFO,
	                           buffer := #arFifoSendBuffer);
	    END_IF;
	    
	    IF #xSuccess_GF_SendFIFO THEN                           // Wenn erstes Telegram herausgeholt
	        REGION Log 
	            IF "FB_CommunicationLogger_DB".fbTeleHandler.xOutConnectionActive AND NOT #xInSendTele THEN
	                
	                //   "DB_CommunciationParametersLogger".xIsLogger := TRUE;
	                
	                "FC_FIFO_Append"(DataIn := #stTelegramSend,
	                                 InitialItem := #empty,
	                                 MaxNo := 100,
	                                 Success => #xSuccess,
	                                 fifoBuffer := "DB_LGF_FIFO_CommLogger",
	                                 buffer := "DB_Buffer_CommunicationLogger".BUFFER);
	                ;
	            END_IF;
	            
	        END_REGION ;
	        
	        
	        REGION Prepare Telegram for sending
	            // add start string
	            IF (#stTelegramDefinition.sStartMarkerSend <> '') THEN
	                #sBuildString := #stTelegramDefinition.sStartMarkerSend;
	            ELSE
	                #sBuildString[1] := '0';
	            END_IF;
	            
	            // add data fields:
	            FOR #i := 1 TO #stTelegramSend.nDataCount DO
	                IF (#i > 1) THEN
	                    #sBuildString := CONCAT(IN1 := #sBuildString, IN2 := CHAR_TO_STRING(#stTelegramDefinition.bSeparatorByte));
	                END_IF;
	                
	                IF (#stTelegramSend.arDataString[#i] <> '') THEN
	                    #sBuildString := CONCAT(IN1 := #sBuildString, IN2 := #stTelegramSend.arDataString[#i]);
	                END_IF;
	            END_FOR;
	            
	            // add end string:
	            IF (#stTelegramDefinition.sEndMarkerSend <> '') THEN
	                #sBuildString := CONCAT(IN1 := #sBuildString, IN2 := #stTelegramDefinition.sEndMarkerSend);
	            END_IF;
	        END_REGION
	        
	        #strLen := INT_TO_UINT(LEN(#sBuildString)); // Telegramlänge ermitteln
	        Strg_TO_Chars(Strg := #sBuildString,        // Telegramstring in Array of Byte umwandeln  
	                      pChars := 0,
	                      Cnt => #strLen,
	                      Chars := #stTcpParam.t_TelegramSendBuffer);
	        #stTcpParam.nSendLen := #strLen;                          // Telegramlänge übergeben
	        #stTcpParam.xSendRequest := TRUE;                         // Sendeauftrag starten
	    END_IF;
	    
	END_REGION
	
	REGION TCP-Verbindungszustand 
	    CASE #nStateConn OF
	            
	        #STATE_RECONNECT:
	            
	            REGION STATE: RECONNECT
	                // Status
	                #sConnectionStatus := 'RECONNECTING';
	                
	                // Static
	                #stTcpParam.xSendRequest := FALSE;
	                #stTcpParam.xEnable := FALSE; // Disable connection
	                
	                // Transition
	                IF #tOnRetryEnable.Q THEN   // Totzeit
	                    #nStateConn := #STATE_NOTCONNECTED;
	                END_IF;
	            END_REGION
	            
	        #STATE_NOTCONNECTED:
	            
	            REGION STATE: NOT CONNECTED
	                // Status
	                #sConnectionStatus := 'NOT CONNECTED';
	                
	                // Static
	                #stTcpParam.xSendRequest := FALSE;
	                #stTcpParam.xEnable := TRUE;   // Verbindungsaufbau aktivieren / TCP-Baustein aktivieren
	                
	                // Transition
	                IF #stTcpParam.xConnectionEstablished THEN // Erfolgreich verbunden mit Partner?
	                    #nStateConn := #STATE_CONNECTED;
	                ELSIF #tOnWatchdogConn.Q THEN   // Nach Timeout wird der Verbindungsaufbau neu getriggert
	                    #nStateConn := #STATE_RECONNECT;
	                END_IF;
	            END_REGION
	            
	        #STATE_CONNECTED:
	            
	            REGION STATE: CONNECTED
	                #sConnectionStatus := 'CONNECTED';
	                
	                IF NOT #stTcpParam.xConnectionEstablished THEN    // Verbindung verloren?
	                    #nStateConn := #STATE_RECONNECT;              // Neue Verbindung starten
	                END_IF;
	            END_REGION
	            
	    END_CASE;
	    
	END_REGION
	
	REGION TCP-Communication: Server  
	    #fbTcpComm(configuration := #stInTcpTypeConfig,
	               enable := #stTcpParam.xEnable,
	               send := #stTcpParam.xSendRequest,
	               sendDataLength := #stTcpParam.nSendLen,
	               connected => #stTcpParam.xConnectionEstablished,
	               sending => #stTcpParam.xSending,
	               dataReceived => #stTcpParam.xNdr,
	               receivedDataLength => #stTcpParam.nRcvdLen,
	               busy => #stTcpParam.xBusy,
	               error => #stTcpParam.xError,
	               status => #stTcpParam.nStatus,
	               sendBuffer := #stTcpParam.t_TelegramSendBuffer,
	               receiveBuffer := #stTcpParam.t_TelegramReceiveBuffer,
	               diagnostics := #stTcpParam.stDiagnosticData);
	    
	    #fTrigSending(CLK:= #stTcpParam.xSending);
	    
	    IF #fTrigSending.Q THEN
	        #stTcpParam.xSendRequest := FALSE;
	    END_IF;
	END_REGION
	
	REGION Timer
	    #tOnRetryEnable(IN := #nStateConn = #STATE_RECONNECT,
	                    PT := t#50ms);
	    
	    #tOnWatchdogConn(IN := #nStateConn = #STATE_NOTCONNECTED,
	                     PT := t#15s);
	END_REGION
	
	REGION Outputs
	    #xOutTelegramAvailable := #xTelegramAvailable;
	    #stOutNewTelegram := #stFirstTelegram;
	    #xOutConnectionActive := (#nStateConn = #STATE_CONNECTED);
	END_REGION
	
	REGION Logging
	    #fbEventLogSending(sInInstance := CONCAT(IN1 := ''(* #stInTcpParameters.sInInstance *), IN2 := '-Sending'),
	                       nInLogLevel := 0(* "E_LogLevel.DEBUG" *));
	    #fbEventLogSending.xInTrigger := 0;
	    #fbEventLogReceiving(sInInstance := CONCAT(IN1 := ''(* #stInTcpParameters.sInInstance *), IN2 := '-Receiving'),
	                         nInLogLevel := 0(* "E_LogLevel.DEBUG" *));
	    #fbEventLogReceiving.xInTrigger := 0;
	END_REGION
END_FUNCTION_BLOCK

