FUNCTION_BLOCK "FB_CommunicationLogger"
{ S7_Optimized_Access := 'TRUE' }
VERSION : 0.1
   VAR_IN_OUT 
      fbInOutSendFIFO : "LGF_FIFO";
      arFifoSendBuffer : Array[1..100] of "UDT_TelegramData_Send";
   END_VAR

   VAR 
      fbTeleHandler : "FB_TCP_LCOM_TeleHandler";
      xReset : Bool;
      xSendTele : Bool;
      stTelegramToSend : "UDT_TelegramData_Send";
      nState : Int;
      xRetVal : Bool;
      stNewTelegram { S7_SetPoint := 'False'} : "UDT_TelegramData";
      stTeleGOHDRespM : "UDT_Telegram_GOHDRespM";
      arPayloadHelp : Array[0..200] of Byte;
      cnt : UInt;
      LStream_JsonDeserializer_Instance : "LStream_JsonDeserializer";
      typeElement { S7_SetPoint := 'False'} : Array[0..10] of "LStream_typeElement" := [(2, 'DecisionPoint', (), (), ()), (3, 'GIN', (), (), ()), (2, 'Barcode', (), (), ()), (1, 'Actions', (), (), true), ((), (), (), (), ()), ((), (), (), (), ()), ((), (), (), (), ()), ((), (), (), (), ()), ((), (), (), (), ()), ((), (), (), (), ()), ((), (), (), (), ())];
      xDone : Bool;
      rTrigConnectionActive {InstructionName := 'R_TRIG'; LibVersion := '1.0'} : R_TRIG;
      xSendHeartbeat : Bool;
      tOnHeartbeat {InstructionName := 'TON_TIME'; LibVersion := '1.0'} : TON_TIME;
   END_VAR

   VAR_TEMP 
      xStart : Bool;
      test : "UDT_TelegramData_Send";
   END_VAR


BEGIN
	REGION Info
	    // Kommunikation zu Fortna WCSBL 
	    // Telegramme:
	    // Senden:
	    // GOHDReqM  (Zielanfrage)             | Von Schönenberger -> Fortna WCSBL
	    // GOHDUM    (Update)                  | Von Schönenberger -> Fortna WCSBL 
	    // Empfangen:
	    // GOHDRespM (Antwort auf Zielanfrage) | Von Fortna WCSBL  -> Schönenberger
	END_REGION
	
	REGION Call TeleHandler
	    // hardware identifier of the local interface, PLC tags--Default tag table--System constant default value: PROFINET_interface_1 = 64
	    #fbTeleHandler.stInTcpTypeConfig.connection.interfaceID := "Local~PN-Interface_SchSy"; //"Local"~PN-Interface_Customer";
	    //unique connection identifier (W#16#0001...W#16#0FFF)
	    #fbTeleHandler.stInTcpTypeConfig.connection.connectionID := 100;
	    //used protocol: 1=TCP protocol, 2=LCom protocol
	    #fbTeleHandler.stInTcpTypeConfig.connection.comService := "LCOM_TCP_CONNECTION";
	    //FALSE: passive (server), TRUE: active connection establishment (client)
	    #fbTeleHandler.stInTcpTypeConfig.connection.isClient := TRUE;
	    //TRUE: accept requests from all partners, FALSE: only specified partner is allowed in case of server
	    #fbTeleHandler.stInTcpTypeConfig.connection.acceptUnknownPartner := TRUE;
	    //local port number (possible values: 1...49151; caution: some may be reserved for internal use; recommended values: 2000...5000)
	    #fbTeleHandler.stInTcpTypeConfig.connection.localPort := 4711;
	    //partner port number, use only in case of client or specified partner (possible values: 1...49151; recommended values: 2000...5000)
	    #fbTeleHandler.stInTcpTypeConfig.connection.partnerPort := 4711;
	    
	    //partner IP address xxx.xxx.xxx.xxx = [1].[2].[3].[4], use only in case of client or specified partner
	    #fbTeleHandler.stInTcpTypeConfig.connection.partnerIP.ADDR[1] := 192;
	    #fbTeleHandler.stInTcpTypeConfig.connection.partnerIP.ADDR[2] := 168;
	    #fbTeleHandler.stInTcpTypeConfig.connection.partnerIP.ADDR[3] := 3;
	    #fbTeleHandler.stInTcpTypeConfig.connection.partnerIP.ADDR[4] := 245;
	    
	    #fbTeleHandler.stInTcpTypeConfig.connection.connectType := "LCOM_CON_TYPE_IPV4";
	    
	    // Telegramdefinition
	    #fbTeleHandler.stInTelegramDefinition.sStartMarker := '$02';
	    #fbTeleHandler.stInTelegramDefinition.sEndMarker := '$03';
	    #fbTeleHandler.stInTelegramDefinition.sStartMarkerSend := '$02';
	    #fbTeleHandler.stInTelegramDefinition.sEndMarkerSend := '$03';
	    #fbTeleHandler.stInTelegramDefinition.bSeparatorByte := '$1D'; //',';
	    #fbTeleHandler.stInTelegramDefinition.nLength := 0;
	    #fbTeleHandler.stInTelegramDefinition.nTelegramIDDataField := 0;
	    #fbTeleHandler.stInTelegramDefinition.xTelegramIDIsNumber := FALSE;
	    
	    #fbTeleHandler(xInReset := #xReset,
	                   xInSendTele := true,
	                   xInOutSendTele := #xSendTele,
	                   stInTelegramSend := #stTelegramToSend,
	                   fbInOutSendFIFO:= #fbInOutSendFIFO,
	                   arFifoSendBuffer:=#arFifoSendBuffer);
	END_REGION
	
	REGION Reset SequenceNumber
	    #rTrigConnectionActive(CLK:=#fbTeleHandler.xOutConnectionActive);
	    
	    IF #rTrigConnectionActive.Q THEN
	        "DB_CommunciationParametersLogger".nSeqNum := 0;
	    END_IF;
	END_REGION
	
	REGION Send Heartbeat
	  (*  IF #fbTeleHandler.xOutConnectionActive THEN
	        #xSendHeartbeat := TRUE;
	        
	        IF #tOnHeartbeat.Q THEN
	            #xSendHeartbeat := FALSE;
	            "FC_Send_HB"(sInPLCID := "cPLCID",
	                         FIFO := "DB_LGF_FIFO_CommLogger",
	                         BUFFER := "DB_Buffer_CommunicationLogger".BUFFER,
	                         nInOutSequenceNumber:="DB_CommunciationParametersLogger".nSeqNum);
	        END_IF;
	    ELSE
	        #xSendHeartbeat := FALSE;
	    END_IF;
	    
	    #tOnHeartbeat(IN := #xSendHeartbeat,
	                  PT := t#15s); *)
	END_REGION
	
	REGION Empfangen
	    //Wird nicht benötigt
	    CASE #nState OF
	        0: // Waiting
	            //New Telegram
	            IF #fbTeleHandler.xOutTelegramAvailable THEN
	                #fbTeleHandler.xInGetFirst := TRUE;
	                #nState := 100;
	            END_IF;
	        100: // Get new Telegram
	            #stNewTelegram := #fbTeleHandler.stOutNewTelegram;
	            #fbTeleHandler.xInGetFirst := FALSE;
	            #nState := 200;
	        200: //Analyze Telegram
	            #stTeleGOHDRespM.stHeader.sPlcId := #stNewTelegram.arDataString[1];
	            #stTeleGOHDRespM.stHeader.sSeqNum := #stNewTelegram.arDataString[2];
	            #stTeleGOHDRespM.stHeader.sMessageType := #stNewTelegram.arDataString[3];
	            
	            IF #stTeleGOHDRespM.stHeader.sMessageType = 'GOHDRespM' THEN
	                
	                Strg_TO_Chars(Strg := #stNewTelegram.arDataString[4],
	                              pChars := 0,
	                              Cnt => #cnt,
	                              Chars := #arPayloadHelp);
	                
	                #typeElement[0].type := 2;
	                #typeElement[0].key := 'DecisionPoint';
	                #typeElement[1].type := 3;
	                #typeElement[1].key := 'GIN';
	                #typeElement[2].type := 2;
	                #typeElement[2].key := 'Barcode';
	                #typeElement[3].type := 1;
	                #typeElement[3].key := 'Actions';
	                
	                #xStart := TRUE;
	                
	                IF #xDone THEN
	                    #xStart := FALSE;
	                    
	                    #stTeleGOHDRespM.stPayload.sDecisionPoint := #typeElement[0].value;
	                    
	                    STRG_VAL(IN := #typeElement[1].value,
	                             FORMAT := 0,
	                             P := 1,
	                             OUT => #stTeleGOHDRespM.stPayload.nGin);
	                    
	                    STRG_VAL(IN := #typeElement[2].value,
	                             FORMAT := 0,
	                             P := 1,
	                             OUT => #stTeleGOHDRespM.stPayload.nBarcode);
	                    
	                    #stTeleGOHDRespM.stPayload.arActions[0] := #typeElement[4].value;
	                    #stTeleGOHDRespM.stPayload.arActions[1] := #typeElement[5].value;
	                    #stTeleGOHDRespM.stPayload.arActions[2] := #typeElement[6].value;
	                    #stTeleGOHDRespM.stPayload.arActions[3] := #typeElement[7].value;
	                    #stTeleGOHDRespM.stPayload.arActions[4] := #typeElement[8].value;
	                    
	                   (* IF #stTeleGOHDRespM.stPayload.sDecisionPoint = 'GOH.Rec.01' THEN
	                        IF "DB_JamArea0102".stJam0102_4.arCarrier[1].nBarcode = #stTeleGOHDRespM.stPayload.nBarcode THEN
	                            IF #stTeleGOHDRespM.stPayload.arActions[0] = '1' THEN
	                                "DB_JamArea0102".stJam0102_4.arCarrier[1].nDestination := "cDestInboundOut";
	                            ELSIF #stTeleGOHDRespM.stPayload.arActions[0] = '-1' THEN
	                                "DB_JamArea0102".stJam0102_4.arCarrier[1].nDestination := "cDestClearing";
	                            END_IF;
	                        END_IF;
	                    END_IF; *)
	                    
	                    #xDone := FALSE;
	                    
	                    
	                    
	                    
	                    (*    REGION Send ACK
	                            "FC_TeleClear"(#stTelegramToSend);
	                            
	                            #xRetVal := "FC_TeleSetData"(nDataField := 1,
	                                                         sData := '4711',
	                                                         stInOutTelegram := #stTelegramToSend);
	                            
	                            #xRetVal := "FC_TeleSetData"(nDataField := 2,
	                                                         sData := #stNewTelegram.arDataString[2],
	                                                         stInOutTelegram := #stTelegramToSend);
	                            
	                            #xRetVal := "FC_TeleSetData"(nDataField := 3,
	                                                         sData := 'ACK',
	                                                         stInOutTelegram := #stTelegramToSend);
	                            
	                            #xRetVal := "FC_TeleSetData"(nDataField := 4,
	                                                         sData := '123',
	                                                         stInOutTelegram := #stTelegramToSend);
	                            #xSendTele := TRUE;
	                        END_REGION *)
	                    
	                    #nState := 0;
	                END_IF;
	                
	            ELSE
	                #nState := 0;
	            END_IF;
	    END_CASE;
	END_REGION
	
	REGION LStream    
	    #LStream_JsonDeserializer_Instance(execute := #xStart,
	                                       tree := #typeElement,
	                                       raw := #arPayloadHelp);
	    
	    IF #LStream_JsonDeserializer_Instance.done THEN
	        #xDone := TRUE;
	    END_IF;
	END_REGION
	
	
END_FUNCTION_BLOCK

