, bError=> , nErrId=> , hSocket=> _hSocket, eState=> ); // Get connected state _xConnected := (_fbTcpConnection.eState = E_SocketConnectionState.eSOCKET_CONNECTED); // Receive timeout after sending a command _tonReceiveTimeout(IN := _xEnableReceiveTimeout, PT := _timReceiveTimeoutTime); // Receive state machine CASE _iStateReceive OF // Main socket not connected 0: IF _xConnected THEN _iStateReceive := 10; END_IF // Call receive 10: _fbSocketReceive( sSrvNetId:= '', hSocket:= _hSocket, cbLen:= SIZEOF(_abReceivedBuffer) - _udiReceivedBytes, pDest:= ADR(_abReceivedBuffer) + _udiReceivedBytes, bExecute:= TRUE, tTimeout:= _timReceiveTimeout, bBusy=> , bError=> , nErrId=> , nRecBytes=> ); IF (NOT _fbSocketReceive.bBusy) AND (NOT _fbSocketReceive.bError) THEN _fbSocketReceive(bExecute := FALSE); IF _fbSocketReceive.nRecBytes > 0 THEN _udiReceivedBytes := _udiReceivedBytes + _fbSocketReceive.nRecBytes; _iStateReceive := 20; ELSE _iStateReceive := 15; END_IF END_IF // If we have an error, check if we are connected IF _fbSocketReceive.bError THEN _fbSocketReceive(bExecute := FALSE); _iStateReceive := 0; END_IF // Wait some time before rechecking 15: _tonPollTimer(IN := TRUE, PT := _timPollingTime); IF _tonPollTimer.Q THEN _tonPollTimer(IN := FALSE); _iStateReceive := 10; END_IF // Check if we are still connected IF (NOT _xConnected) THEN _tonPollTimer(IN := FALSE); _sReceivedResponse := ''; _iStateReceive := 0; END_IF // Check received data 20: // Check if received command is complete MEMCPY(destAddr := ADR(_sReceivedResponse), srcAddr := ADR(_abReceivedBuffer), n := _udiReceivedBytes); _udiReceivedBytes := 0; //_xCmdReceived := TRUE; // Go back to polling wait state _iStateReceive := 15; END_CASE CASE _iState OF // Wait for active connection to tray feeder 0: IF _xConnected THEN _iState := 10; END_IF // Connected and idle 10: // Got to disconnected state if connection is lost IF (NOT _xConnected) THEN _iState := 0; END_IF IF _xSendCmd THEN _xSendCmd := FALSE; _xBusy := TRUE; _iState := 20; END_IF // Check if we received a response without sending a command // IF _xCmdReceived THEN // _iState := 50; // END_IF // Send command 20: _fbSocketSend( sSrvNetId:= '', hSocket:= _hSocket, cbLen:= SIZEOF(_sCmd), pSrc:= ADR(_sCmd), bExecute:= TRUE, tTimeout:= _timSendTimeout, bBusy=> , bError=> , nErrId=> ); IF (NOT _fbSocketSend.bBusy) AND (NOT _fbSocketSend.bError) THEN _fbSocketSend(bExecute := FALSE); //_xEnableReceiveTimeout := TRUE; //_iState := 30; END_IF IF _fbSocketSend.bError THEN _fbSocketSend(bExecute := FALSE); _iState := 90; END_IF // Wait for response 30: // Received a response IF _xCmdReceived THEN _xCmdReceived := FALSE; _xEnableReceiveTimeout := FALSE; _uiRetries := 0; _iState := 40; END_IF // Didnt receive command ack in time // So resend the command if max retries are not reached IF _tonReceiveTimeout.Q THEN _xEnableReceiveTimeout := FALSE; _uiRetries := _uiRetries + 1; // Check if we reached the max number of retries IF _uiRetries > MAX_RETRIES THEN _iState := 90; ELSE // Retry by sendind command again _iState := 20; END_IF END_IF // Check response 40: // Check for cmd id IF (TO_STRING(_sReceivedResponse[0]) <> UINT_TO_STRING(_uiCmdId)) THEN // Wrong command id received _iState := 90; END_IF // For for response indicator IF _sReceivedResponse[1] <> F_ToASC('<') THEN // Wrong response indicator _iState := 90; END_IF // Check for correct cmd _xReceivedResponseOk := TRUE; FOR _diCounter := 2 TO (LEN(_sReceivedResponse) - 1) DO IF _sReceivedResponse[_diCounter] = F_ToASC(':') THEN EXIT; ELSIF _sReceivedResponse[_diCounter] <> _sCmd[_diCounter] THEN _xReceivedResponseOk := FALSE; EXIT; END_IF END_FOR IF _xReceivedResponseOk THEN _iState := 10; ELSE _iState := 90; END_IF 50: // Get command id _uiReceivedCommandId := STRING_TO_UINT(TO_STRING(_sReceivedResponse[0])); // Check if it is a new command IF (_uiReceivedCommandId <> _uiLastReceivedResponseId) OR (_uiReceivedCommandId = 0) THEN _uiLastReceivedResponseId := _uiReceivedCommandId; xNewResponseReady := TRUE; // Send acknowledgement _iState := 60; END_IF // Prepare ack response 60: _sAck := CONCAT(UINT_TO_STRING(_uiLastReceivedResponseId), '<'); FOR _diCounter := 2 TO (LEN(_sReceivedResponse) - 1) DO IF _sReceivedResponse[_diCounter] <> F_ToASC(':') THEN _sAck[_diCounter] := _sReceivedResponse[_diCounter]; ELSE _sAck[_diCounter] := F_ToASC('\0'); EXIT; END_IF END_FOR _iState := 70; // Send ack response 70: _fbSocketSend( sSrvNetId:= '', hSocket:= _hSocket, cbLen:= SIZEOF(_sAck), pSrc:= ADR(_sAck), bExecute:= TRUE, tTimeout:= _timSendTimeout, bBusy=> , bError=> , nErrId=> ); IF (NOT _fbSocketSend.bBusy) AND (NOT _fbSocketSend.bError) THEN _fbSocketSend(bExecute := FALSE); _xEnableReceiveTimeout := TRUE; _iState := 10; END_IF IF _fbSocketSend.bError THEN _fbSocketSend(bExecute := FALSE); _iState := 90; END_IF // Error 90: _xError := TRUE; _xBusy := FALSE; IF xConfirmAlarms THEN _xError := FALSE; _iState := 0; END_IF END_CASE // Copy output buffers to outputs xConnected := _xConnected; xBusy := _xBusy; xError := _xError;]]> 9 THEN _uiCmdId := 1; END_IF // Create command with id _sCmd := CONCAT(UINT_TO_STRING(_uiCmdId), '>'); _sCmd := CONCAT(_sCmd, sCmd); // start sendind command state machine _xSendCmd := TRUE; M_SendCmd := TRUE;]]>