Hi Everybody,
newbie here with PLCs, using a B&R plc.
I'm playing with a printer and its tcp socket communication.
Connection works fine if there are no errors, I followed the example, so tcpOpen, tcpClient, then send something and close.
If, for any reason, the connection is lost (cable disconnected for example), the tcpclient connection is stuck forever in ERR_FUB_BUSY state, and even when I connect the cable back, it's impossible to start a new connection. The only solution is to restart the plc.
I tried also with an external socket tester and it works perfectly fine.
What I'm missing? It's unable to correctly close the socket if the connection is lost?
Thanks
newbie here with PLCs, using a B&R plc.
I'm playing with a printer and its tcp socket communication.
Connection works fine if there are no errors, I followed the example, so tcpOpen, tcpClient, then send something and close.
If, for any reason, the connection is lost (cable disconnected for example), the tcpclient connection is stuck forever in ERR_FUB_BUSY state, and even when I connect the cable back, it's impossible to start a new connection. The only solution is to restart the plc.
I tried also with an external socket tester and it works perfectly fine.
What I'm missing? It's unable to correctly close the socket if the connection is lost?
Thanks
Code:
CASE ClientTCP.Step OF
0: (* Open Ethernet Interface *)
IF test_tcp OR start_send_label OR start_send_label_ricetta THEN
TcpOpen_0.enable := 1;
TcpOpen_0.pIfAddr := 0; (* Which Interface to open *)
TcpOpen_0.port := 8000; (* Port on client side to use *)
TcpOpen_0.options := tcpOPT_REUSEADDR;
TcpOpen_0;
IF TcpOpen_0.status = 0 THEN (* TcpOpen successfull *)
TON_timeout_comunicaz_tcpip.IN := TRUE;
ClientTCP.Step := 10;
ELSIF TcpOpen_0.status = ERR_FUB_BUSY THEN (* TcpOpen not finished -> redo *)
(* Busy *)
ELSE (* Goto Error Step *)
ClientTCP.Step := 100;
END_IF
END_IF
10: (* Connect to the other Station *)
TcpClient_0.enable := 1;
TcpClient_0.ident := TcpOpen_0.ident; (* Connection Ident from AsTCP.TCP_Open *)
TcpClient_0.portserv := 8000; (* Port on server side to use *)
TcpClient_0.pServer := ADR('172.17.40.20'); (* Server Address *)
TcpClient_0;
IF TcpClient_0.status = 0 THEN
TON_timeout_comunicaz_tcpip.IN := FALSE;
ClientTCP.Step := 20;
ELSIF TcpClient_0.status = ERR_FUB_BUSY THEN (* TcpClient not finished -> redo *)
(* Busy *)
// timeout for connection
IF TON_timeout_comunicaz_tcpip.Q THEN
TON_timeout_comunicaz_tcpip.IN := FALSE;
MpAlarmXSet(gAlarmXCore_Hmi, 'PrinterNetworkError');
ClientTCP.Step := 40;
END_IF
ELSIF TcpClient_0.status = tcpERR_INVALID THEN (* Port error -> Close actual connection, and reopen a new one *)
TON_timeout_comunicaz_tcpip.IN := FALSE;
ClientTCP.Step := 40;
ELSE (* Goto Error Step *)
ClientTCP.Step := 100;
END_IF
20: (* Send Data to the Server *)
TcpSend_0.enable := 1;
TcpSend_0.ident := TcpOpen_0.ident; (* Connection Ident from AsTCP.TCP_Open *)
TcpSend_0.pData := ADR(test_string); (* Which data to send *)
TcpSend_0.datalen := SIZEOF(test_string); (* Lenght of data to send *)
TcpSend_0.flags := 0;
TcpSend_0;
IF TcpSend_0.status = 0 THEN (* Data was sent sucessfully -> close socket *)
ClientTCP.Step := 40;
ELSIF TcpSend_0.status = ERR_FUB_BUSY THEN (* TcpSend not finished -> redo *)
(* Busy *)
// timeout
IF TON_timeout_comunicaz_tcpip.Q THEN
TON_timeout_comunicaz_tcpip.IN := FALSE;
MpAlarmXSet(gAlarmXCore_Hmi, 'PrinterNetworkError');
ClientTCP.Step := 40;
END_IF
ELSIF (TcpSend_0.status = tcpERR_SENTLEN) OR (TcpSend_0.status = tcpERR_NOT_CONNECTED) THEN (* Connection Lost *)
TON_timeout_comunicaz_tcpip.IN := FALSE;
MpAlarmXSet(gAlarmXCore_Hmi, 'PrinterNetworkError');
ClientTCP.Step := 40;
ELSE (* Goto Error Step *)
TON_timeout_comunicaz_tcpip.IN := FALSE;
MpAlarmXSet(gAlarmXCore_Hmi, 'PrinterNetworkError');
label_chunk_ready := FALSE;
ClientTCP.Step := 100;
END_IF
// ---------------------
40: (* Close connection *)
TcpClose_0.enable := 1;
TcpClose_0.ident := TcpOpen_0.ident; (* Connection Ident from AsTCP.TCP_Open *)
TcpClose_0.how := tcpSHUT_RD; //0;
TcpClose_0; (* Call the Function*)
test_tcp := FALSE;
IF TcpClose_0.status = 0 THEN (* Close sucessfull *)
ClientTCP.Step := 0;
ELSIF TcpClose_0.status = ERR_FUB_BUSY THEN (* TcpClose not finished -> redo *)
(* Busy *)
IF MpAlarmXCheckReaction (gAlarmXCore_Hmi, 'PrinterNetworkError_') THEN
ClientTCP.Step := 100;
END_IF
ELSE (* Goto Error Step *)
ClientTCP.Step := 100;
END_IF
100: (* Here some error Handling has to be implemented *)
TON_timeout_comunicaz_tcpip.IN := FALSE;
ClientTCP.Step := 0;
END_CASE