Commit dcdc6089 authored by claes's avatar claes

Reconnect forever

parent 51d9d780
/* /*
* Proview $Id: rt_io_m_mb_tcp_slave.c,v 1.3 2008-05-29 06:49:45 claes Exp $ * Proview $Id: rt_io_m_mb_tcp_slave.c,v 1.4 2008-05-30 11:22:06 claes Exp $
* Copyright (C) 2005 SSAB Oxelsund AB. * Copyright (C) 2005 SSAB Oxelsund AB.
* *
* This program is free software; you can redistribute it and/or * This program is free software; you can redistribute it and/or
...@@ -32,9 +32,6 @@ ...@@ -32,9 +32,6 @@
#include <unistd.h> #include <unistd.h>
#include <sys/socket.h> #include <sys/socket.h>
#include "rt_io_mb_locals.h"
#include "pwr.h" #include "pwr.h"
#include "co_cdh.h" #include "co_cdh.h"
#include "pwr_baseclasses.h" #include "pwr_baseclasses.h"
...@@ -46,8 +43,11 @@ ...@@ -46,8 +43,11 @@
#include "rt_io_msg.h" #include "rt_io_msg.h"
#include "rt_errh.h" #include "rt_errh.h"
#include "co_cdh.h" #include "co_cdh.h"
#include "co_time.h"
#include "rt_mb_msg.h" #include "rt_mb_msg.h"
#include "rt_io_mb_locals.h"
char rcv_buffer[65536]; char rcv_buffer[65536];
/* Check if channel should be fetched from diagnostic area, /* Check if channel should be fetched from diagnostic area,
...@@ -58,6 +58,12 @@ static int connect_slave( io_sRackLocal *local, io_sRack *rp) ...@@ -58,6 +58,12 @@ static int connect_slave( io_sRackLocal *local, io_sRack *rp)
pwr_tStatus sts; pwr_tStatus sts;
pwr_sClass_Modbus_TCP_Slave *op; pwr_sClass_Modbus_TCP_Slave *op;
int buffsize = 10000; int buffsize = 10000;
int flags;
fd_set fdr; /* For select call */
fd_set fdw; /* For select call */
struct timeval tv;
clock_gettime(CLOCK_MONOTONIC, &local->last_try_connect_time);
op = (pwr_sClass_Modbus_TCP_Slave *) rp->op; op = (pwr_sClass_Modbus_TCP_Slave *) rp->op;
...@@ -83,10 +89,35 @@ static int connect_slave( io_sRackLocal *local, io_sRack *rp) ...@@ -83,10 +89,35 @@ static int connect_slave( io_sRackLocal *local, io_sRack *rp)
/* Connect to remote address */ /* Connect to remote address */
fcntl(local->s, F_SETFL, (flags = fcntl(local->s, F_GETFL)) | O_NONBLOCK);
sts = connect(local->s, (struct sockaddr *) &local->rem_addr, sizeof(local->rem_addr)); sts = connect(local->s, (struct sockaddr *) &local->rem_addr, sizeof(local->rem_addr));
if (sts < 0) { if (sts < 0) {
FD_ZERO(&fdr);
FD_ZERO(&fdw);
FD_SET(local->s, &fdr);
FD_SET(local->s, &fdw);
if (op->ReconnectLimit > 200) {
tv.tv_sec = 0;
tv.tv_usec = 1000 * op->ReconnectLimit;
} else {
tv.tv_sec = 0;
tv.tv_usec = 200000;
}
sts = select(32, &fdr, &fdw, NULL, &tv);
if (sts <= 0) {
close(local->s);
errh_Error( "Error connecting remote socket for IO modbus slave %s, %d", rp->Name, sts); errh_Error( "Error connecting remote socket for IO modbus slave %s, %d", rp->Name, sts);
return -1;
}
} }
fcntl(local->s, F_SETFL, (flags = fcntl(local->s, F_GETFL)) ^ O_NONBLOCK);
return sts; return sts;
} }
...@@ -100,6 +131,7 @@ static pwr_tStatus recv_data(io_sRackLocal *local, ...@@ -100,6 +131,7 @@ static pwr_tStatus recv_data(io_sRackLocal *local,
pwr_tStatus sts; pwr_tStatus sts;
fd_set fdr; /* For select call */ fd_set fdr; /* For select call */
fd_set fde; /* For select call */ fd_set fde; /* For select call */
fd_set fdw; /* For select call */
struct timeval tv; struct timeval tv;
pwr_tBoolean found; pwr_tBoolean found;
int data_size; int data_size;
...@@ -115,10 +147,24 @@ static pwr_tStatus recv_data(io_sRackLocal *local, ...@@ -115,10 +147,24 @@ static pwr_tStatus recv_data(io_sRackLocal *local,
while (sts > 0) { while (sts > 0) {
FD_ZERO(&fdr); FD_ZERO(&fdr);
FD_ZERO(&fdw);
FD_ZERO(&fde); FD_ZERO(&fde);
FD_SET(local->s, &fdr); FD_SET(local->s, &fdr);
FD_SET(local->s, &fdw);
FD_SET(local->s, &fde); FD_SET(local->s, &fde);
tv.tv_sec = 0;
tv.tv_usec = 0;
sts = select(32, &fdr, &fdw, &fde, &tv);
if (!(FD_ISSET(local->s, &fdw))) {
sp->Status = MB__CONNDOWN;
close(local->s);
errh_Error( "Connection down to modbus slave, %s", rp->Name);
return IO__SUCCESS;
}
if (local->expected_msgs > 0) { if (local->expected_msgs > 0) {
tv.tv_sec = 0; tv.tv_sec = 0;
tv.tv_usec = 100000; tv.tv_usec = 100000;
...@@ -127,6 +173,11 @@ static pwr_tStatus recv_data(io_sRackLocal *local, ...@@ -127,6 +173,11 @@ static pwr_tStatus recv_data(io_sRackLocal *local,
tv.tv_usec = 0; tv.tv_usec = 0;
} }
FD_ZERO(&fdr);
FD_ZERO(&fde);
FD_SET(local->s, &fdr);
FD_SET(local->s, &fde);
sts = select(32, &fdr, NULL, &fde, &tv); sts = select(32, &fdr, NULL, &fde, &tv);
if (sts < 0) { if (sts < 0) {
...@@ -135,7 +186,14 @@ static pwr_tStatus recv_data(io_sRackLocal *local, ...@@ -135,7 +186,14 @@ static pwr_tStatus recv_data(io_sRackLocal *local,
return IO__SUCCESS; return IO__SUCCESS;
} }
if (sts > 0) { if ((sts == 0) && (local->expected_msgs > 0)) {
sp->Status = MB__CONNDOWN;
close(local->s);
errh_Error( "Connection down to modbus slave, %s", rp->Name);
return IO__SUCCESS;
}
if (sts > 0 && FD_ISSET(local->s, &fdr)) {
data_size = recv(local->s, rcv_buffer, sizeof(rec_buf), 0); data_size = recv(local->s, rcv_buffer, sizeof(rec_buf), 0);
if (data_size < 0) { if (data_size < 0) {
...@@ -294,7 +352,14 @@ static pwr_tStatus send_data(io_sRackLocal *local, ...@@ -294,7 +352,14 @@ static pwr_tStatus send_data(io_sRackLocal *local,
rr.addr = htons(mp->Address); rr.addr = htons(mp->Address);
rr.quant = ntohs(local_card->input_size * 8); rr.quant = ntohs(local_card->input_size * 8);
sts = send(local->s, &rr, sizeof(read_req), 0); sts = send(local->s, &rr, sizeof(read_req), MSG_DONTWAIT);
if (sts < 0) {
sp->Status = MB__CONNDOWN;
close(local->s);
errh_Error( "Connection down to modbus slave, %s", rp->Name);
return IO__SUCCESS;
}
local->expected_msgs++; local->expected_msgs++;
sp->TX_packets++; sp->TX_packets++;
break; break;
...@@ -315,7 +380,13 @@ static pwr_tStatus send_data(io_sRackLocal *local, ...@@ -315,7 +380,13 @@ static pwr_tStatus send_data(io_sRackLocal *local,
rr.addr = htons(mp->Address); rr.addr = htons(mp->Address);
rr.quant = ntohs((local_card->input_size + 1) / 2); rr.quant = ntohs((local_card->input_size + 1) / 2);
sts = send(local->s, &rr, sizeof(read_req), 0); sts = send(local->s, &rr, sizeof(read_req), MSG_DONTWAIT);
if (sts < 0) {
sp->Status = MB__CONNDOWN;
close(local->s);
errh_Error( "Connection down to modbus slave, %s", rp->Name);
return IO__SUCCESS;
}
sp->TX_packets++; sp->TX_packets++;
local->expected_msgs++; local->expected_msgs++;
break; break;
...@@ -343,7 +414,13 @@ static pwr_tStatus send_data(io_sRackLocal *local, ...@@ -343,7 +414,13 @@ static pwr_tStatus send_data(io_sRackLocal *local,
wcr.bc = local_card->output_size; wcr.bc = local_card->output_size;
memcpy(wcr.reg, local_card->output_area, local_card->output_size); memcpy(wcr.reg, local_card->output_area, local_card->output_size);
sts = send(local->s, &wcr, ntohs(wcr.head.length) + 6, 0); sts = send(local->s, &wcr, ntohs(wcr.head.length) + 6, MSG_DONTWAIT);
if (sts < 0) {
sp->Status = MB__CONNDOWN;
close(local->s);
errh_Error( "Connection down to modbus slave, %s", rp->Name);
return IO__SUCCESS;
}
local->expected_msgs++; local->expected_msgs++;
sp->TX_packets++; sp->TX_packets++;
break; break;
...@@ -366,7 +443,13 @@ static pwr_tStatus send_data(io_sRackLocal *local, ...@@ -366,7 +443,13 @@ static pwr_tStatus send_data(io_sRackLocal *local,
wrr.bc = local_card->output_size; wrr.bc = local_card->output_size;
memcpy(wrr.reg, local_card->output_area, local_card->output_size); memcpy(wrr.reg, local_card->output_area, local_card->output_size);
sts = send(local->s, &wrr, ntohs(wrr.head.length) + 6, 0); sts = send(local->s, &wrr, ntohs(wrr.head.length) + 6, MSG_DONTWAIT);
if (sts < 0) {
sp->Status = MB__CONNDOWN;
close(local->s);
errh_Error( "Connection down to modbus slave, %s", rp->Name);
return IO__SUCCESS;
}
sp->TX_packets++; sp->TX_packets++;
local->expected_msgs++; local->expected_msgs++;
break; break;
...@@ -435,7 +518,7 @@ static pwr_tStatus IoRackInit ( ...@@ -435,7 +518,7 @@ static pwr_tStatus IoRackInit (
sts = connect_slave(local, rp); sts = connect_slave(local, rp);
if (sts < 0) { if (sts < 0) {
op->Status = MB__INITFAIL; op->Status = MB__CONNDOWN;
} else { } else {
op->Status = MB__NORMAL; op->Status = MB__NORMAL;
} }
...@@ -616,24 +699,27 @@ static pwr_tStatus IoRackRead ( ...@@ -616,24 +699,27 @@ static pwr_tStatus IoRackRead (
io_sRackLocal *local; io_sRackLocal *local;
pwr_sClass_Modbus_TCP_Slave *sp; pwr_sClass_Modbus_TCP_Slave *sp;
pwr_tStatus sts; pwr_tStatus sts;
pwr_tTime now;
pwr_tDeltaTime dt;
local = rp->Local; local = rp->Local;
sp = (pwr_sClass_Modbus_TCP_Slave *) rp->op; sp = (pwr_sClass_Modbus_TCP_Slave *) rp->op;
if (sp->Status == MB__CONNDOWN && sp->DisableSlave != 1 && if (sp->Status == MB__CONNDOWN && sp->DisableSlave != 1) {
sp->ReconnectCount < sp->ReconnectLimit &&
sp->ErrorCount >= sp->ErrorLimit) {
/* Reconnect */ /* Reconnect */
sp->ReconnectCount++;
sts = connect_slave(local, rp);
clock_gettime(CLOCK_MONOTONIC, &now);
time_Adiff(&dt, &now, &local->last_try_connect_time);
if (dt.tv_sec >= (1 << MIN(sp->ReconnectCount, 6))) {
sts = connect_slave(local, rp);
if (sts >= 0) { if (sts >= 0) {
sp->ErrorCount = 0; sp->ReconnectCount = 0;
sp->Status = MB__NORMAL; sp->Status = MB__NORMAL;
} else { } else {
sp->ReconnectCount++;
memset(&sp->Inputs, 0, local->input_size); memset(&sp->Inputs, 0, local->input_size);
sp->ErrorCount = 0; }
} }
} }
......
/* /*
* Proview $Id: rt_io_mb_locals.h,v 1.1 2008-02-29 08:01:07 claes Exp $ * Proview $Id: rt_io_mb_locals.h,v 1.2 2008-05-30 11:22:06 claes Exp $
* Copyright (C) 2005 SSAB Oxelsund AB. * Copyright (C) 2005 SSAB Oxelsund AB.
* *
* This program is free software; you can redistribute it and/or * This program is free software; you can redistribute it and/or
...@@ -76,6 +76,7 @@ typedef struct { ...@@ -76,6 +76,7 @@ typedef struct {
int input_size; int input_size;
int output_size; int output_size;
int expected_msgs; int expected_msgs;
pwr_tTime last_try_connect_time;
} io_sRackLocal; } io_sRackLocal;
typedef struct { typedef struct {
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment