﻿<?xml version="1.0" encoding="utf-8"?>
<TcPlcObject Version="1.1.0.1">
  <POU Name="UDPReader" Id="{b0e7fa5e-686c-4d67-ad25-d934b48002e0}" SpecialFunc="None">
    <Declaration><![CDATA[// Handles all communication with EL6021 Serial card and delivers complete NMEA strings when found
FUNCTION_BLOCK UDPReader
VAR_INPUT
	Local_IP 	: STRING;
    Local_Port 	: UDINT;
	NMEAmessage : REFERENCE TO STRING(NMEA_BUFFER_SIZE);	//Buffer size must be same as reference!!!
	END_VAR

VAR_OUTPUT
	bNewData			: BOOL;				(*1 cycle TRUE*)
END_VAR
VAR CONSTANT
{attribute 'hide'} NMEA_BUFFER_SIZE : UINT :=200;
END_VAR

VAR
    socketHandler : FB_ConnectionlessSocket;
    receiver : FB_SocketUdpReceiveFrom;
    closeAll : FB_SocketCloseAll;
    state : DINT;  
    
    execClose : BOOL;
    execSocket : BOOL;
    execRecv : BOOL;
    
    hSocket : T_HSOCKET;
    
    timerSocket : TON;
    timerRec : TON;
    
    msg : STRING(NMEA_BUFFER_SIZE);	// incoming buffer for UDP data
    //_message : STRING(255);
	
END_VAR]]></Declaration>
    <Implementation>
      <ST><![CDATA[closeAll(
    sSrvNetId := '',
    bExecute := execClose,
    tTimeout := T#10S
);

socketHandler(
    sSrvNetId := '',
    nMode := 0,
    sLocalHost := Local_IP,
    nLocalPort := Local_Port,
    bEnable := execSocket,
    tReconnect := T#20S,
    hSocket => hSocket
);

receiver(
    sSrvNetId := '',
    hSocket := hSocket,
    cbLen := SIZEOF(msg)-1,
    pDest := ADR(msg),
    bExecute := execRecv,
    tTimeout := T#20S
);

bNewData := FALSE;
    

timerSocket(IN:=state = 2, PT:=T#1S);


CASE state OF
    0: 
        msg := '';
        execSocket := FALSE;
        execRecv := FALSE;
        execClose := FALSE;
        state := 1;
        
     1:
        execSocket := FALSE;
        execRecv := FALSE;
        execClose := TRUE;
        state := 1;
		// next lines are not doing anything
        IF closeAll.bBusy THEN 
            state := 2;
		END_IF
        
    2: 
        execSocket := FALSE;
        execRecv := FALSE;
        execClose := FALSE;
        state := 2;
        IF closeAll.bError THEN	// this one always kicks the state back to 0
            state := 0;
        ELSIF NOT closeAll.bBusy THEN 
            state := 10;
		END_IF
    
    10:
        execSocket := FALSE;
        execRecv := FALSE;
        execClose := FALSE;
        state := 11;

    11:
        execSocket := TRUE;
        execRecv := FALSE;
        execClose := FALSE;
        IF socketHandler.bBusy THEN
            state := 12;
        END_IF
        
    12:   
        execSocket := TRUE;
        execRecv := FALSE;
        execClose := FALSE;
        IF NOT socketHandler.bBusy THEN
            IF socketHandler.bError THEN
               state := 10;
            ELSE
               state := 20;
            END_IF
            
		END_IF
        
    20:
        execSocket := TRUE;
        execRecv := FALSE;
        execClose := FALSE;
        receiver(bExecute := TRUE);
        state := 21;
                
    21:
        execSocket := TRUE;
        execRecv := TRUE;
        execClose := FALSE;
        IF receiver.bError THEN 
            state := 20;
            execRecv := FALSE;
        ELSIF NOT receiver.bBusy THEN
            IF receiver.nRecBytes > 0 THEN
                msg[receiver.nRecBytes] := 0;	// adds '0' to string?
                NMEAmessage := msg;
                bNewData := TRUE;
			END_IF
            state := 20;
            execRecv := FALSE;
        END_IF
             
END_CASE


]]></ST>
    </Implementation>
  </POU>
</TcPlcObject>