2019-05-24 Fred Gleason <fredg@paravelsystems.com>

* Added an 'RDSocketStrings()' function in
	'lib/rdsocketstrings.[cpp|h]'.
	* Fixed a bug in 'RDLiveWire' that caused false watchdog triggers.
This commit is contained in:
Fred Gleason 2019-05-24 13:04:42 -04:00
parent e363e61791
commit 4a59a80fe2
7 changed files with 187 additions and 40 deletions

View File

@ -18689,3 +18689,7 @@
2019-05-23 Patrick Linstruth <patrick@deltecent.com>
* Fixed regression with "State" label overlapping "Date" field
in rdgpimon(1).
2019-05-24 Fred Gleason <fredg@paravelsystems.com>
* Added an 'RDSocketStrings()' function in
'lib/rdsocketstrings.[cpp|h]'.
* Fixed a bug in 'RDLiveWire' that caused false watchdog triggers.

View File

@ -208,6 +208,7 @@ dist_librd_la_SOURCES = dbversion.h\
rdslotdialog.cpp rdslotdialog.h\
rdslotoptions.cpp rdslotoptions.h\
rdsocket.cpp rdsocket.h\
rdsocketstrings.cpp rdsocketstrings.h\
rdsound_panel.cpp rdsound_panel.h\
rdstation.cpp rdstation.h\
rdstatus.cpp rdstatus.h\

View File

@ -142,6 +142,7 @@ SOURCES += rdsettings.cpp
SOURCES += rdsimpleplayer.cpp
SOURCES += rdslider.cpp
SOURCES += rdsocket.cpp
SOURCES += rdsocketstrings.cpp
SOURCES += rdsound_panel.cpp
SOURCES += rdstation.cpp
SOURCES += rdstatus.cpp
@ -275,6 +276,7 @@ HEADERS += rdsettings.h
HEADERS += rdsimpleplayer.h
HEADERS += rdslider.h
HEADERS += rdsocket.h
HEADERS += rdsocketstrings.h
HEADERS += rdsound_panel.h
HEADERS += rdstation.h
HEADERS += rdstatus.h

View File

@ -2,7 +2,7 @@
//
// A LiveWire Node Driver for Rivendell
//
// (C) Copyright 2007,2016 Fred Gleason <fredg@paravelsystems.com>
// (C) Copyright 2007-2019 Fred Gleason <fredg@paravelsystems.com>
//
// This program is free software; you can redistribute it and/or modify
// it under the terms of the GNU General Public License version 2 as
@ -27,6 +27,7 @@
#include <rd.h>
#include <rdlivewire.h>
#include <rdsocketstrings.h>
AString::AString()
: QString()
@ -92,24 +93,25 @@ RDLiveWire::RDLiveWire(unsigned id,QObject *parent)
//
// Connection Socket
//
live_socket=new Q3Socket(this,"live_socket");
live_socket=new QTcpSocket(this);
connect(live_socket,SIGNAL(connected()),this,SLOT(connectedData()));
connect(live_socket,SIGNAL(connectionClosed()),
this,SLOT(connectionClosedData()));
connect(live_socket,SIGNAL(readyRead()),this,SLOT(readyReadData()));
connect(live_socket,SIGNAL(error(int)),this,SLOT(errorData(int)));
connect(live_socket,SIGNAL(error(QAbstracketSocket::SocketError)),
this,SLOT(errorData(QAbstrackSocket::SocketError)));
//
// Watchdog Timers
//
live_watchdog_timer=new QTimer(this,",live_watchdog_timer");
live_watchdog_timer=new QTimer(this);
connect(live_watchdog_timer,SIGNAL(timeout()),this,SLOT(watchdogData()));
live_watchdog_timeout_timer=new QTimer(this,",live_watchdog_timeout_timer");
live_watchdog_timeout_timer=new QTimer(this);
connect(live_watchdog_timeout_timer,SIGNAL(timeout()),
this,SLOT(watchdogTimeoutData()));
this,SLOT(watchdogTimeoutData()));
live_holdoff_timer=new QTimer(this,",live_holdoff_timer");
live_holdoff_timer=new QTimer(this);
connect(live_holdoff_timer,SIGNAL(timeout()),this,SLOT(holdoffData()));
}
@ -371,7 +373,7 @@ void RDLiveWire::connectionClosedData()
live_watchdog_state=true;
int holdoff=GetHoldoff();
emit watchdogStateChanged(live_id,QString().sprintf(
"Connection to LiveWire node at %s:%d closed, attempting reconnect, holdoff = %d mS",
"connection to LiveWire node at %s:%d closed, attempting reconnect, holdoff = %d mS",
(const char *)live_hostname,live_tcp_port,holdoff));
live_holdoff_timer->start(holdoff,true);
}
@ -406,34 +408,28 @@ void RDLiveWire::readyReadData()
}
void RDLiveWire::errorData(int err)
void RDLiveWire::errorData(QAbstractSocket::SocketError err)
{
int interval=RDLIVEWIRE_RECONNECT_MIN_INTERVAL;
switch((Q3Socket::Error)err) {
case Q3Socket::ErrConnectionRefused:
live_watchdog_state=true;
interval=GetHoldoff();
emit watchdogStateChanged(live_id,QString().sprintf(
"Connection to LiveWire node at %s:%d refused, attempting reconnect, holdoff = %d mS",
(const char *)live_hostname,
live_tcp_port,interval));
live_holdoff_timer->start(interval,true);
break;
switch(err) {
case QAbstractSocket::ErrConnectionRefused:
live_watchdog_state=true;
interval=GetHoldoff();
emit watchdogStateChanged(live_id,QString().sprintf(
"connection to LiveWire node at %s:%d refused, attempting reconnect, holdoff = %d mS",
(const char *)live_hostname,
live_tcp_port,interval));
live_holdoff_timer->start(interval,true);
break;
case Q3Socket::ErrHostNotFound:
emit watchdogStateChanged(live_id,QString().sprintf(
"Error on connection to LiveWire node at %s:%d: Host Not Found",
(const char *)live_hostname,
live_tcp_port));
break;
case Q3Socket::ErrSocketRead:
emit watchdogStateChanged(live_id,QString().sprintf(
"Error on connection to LiveWire node at %s:%d: Socket Read Error",
(const char *)live_hostname,
live_tcp_port));
break;
default:
syslog(LOG_WARNING,
"socket error on connection to LiveWire node at %s:%d: %s",
(const char *)live_hostname,
live_tcp_port,
(const char *)RDSocketStrings(err));
break;
}
}
@ -513,7 +509,7 @@ void RDLiveWire::watchdogTimeoutData()
live_gpo_initialized=false;
int holdoff=GetHoldoff();
emit watchdogStateChanged(live_id,QString().sprintf(
"Connection to LiveWire node at %s:%d lost, attempting reconnect, holdoff = %d mS",
"connection to LiveWire node at %s:%d lost, attempting reconnect, holdoff = %d mS",
(const char *)live_hostname,live_tcp_port,holdoff));
live_holdoff_timer->start(holdoff,true);
}
@ -623,7 +619,7 @@ void RDLiveWire::ReadVersion(const QString &cmd)
}
if(f1[0]=="NGPI") {
live_gpis=f1[1].toInt();
QSignalMapper *mapper=new QSignalMapper(this,"gpi_mapper");
QSignalMapper *mapper=new QSignalMapper(this);
connect(mapper,SIGNAL(mapped(int)),this,SLOT(gpiTimeoutData(int)));
for(int i=0;i<live_gpis;i++) {
live_gpi_states.push_back(new bool[RD_LIVEWIRE_GPIO_BUNDLE_SIZE]);
@ -647,7 +643,7 @@ void RDLiveWire::ReadVersion(const QString &cmd)
}
if(f1[0]=="NGPO") {
live_gpos=f1[1].toInt();
QSignalMapper *mapper=new QSignalMapper(this,"gpo_mapper");
QSignalMapper *mapper=new QSignalMapper(this);
connect(mapper,SIGNAL(mapped(int)),this,SLOT(gpoTimeoutData(int)));
for(int i=0;i<live_gpos;i++) {
live_gpo_states.push_back(new bool[RD_LIVEWIRE_GPIO_BUNDLE_SIZE]);
@ -681,7 +677,7 @@ void RDLiveWire::ReadVersion(const QString &cmd)
if(live_watchdog_state) {
live_watchdog_state=false;
emit watchdogStateChanged(live_id,QString().sprintf(
"Connection to LiveWire node at %s:%d restored",
"connection to LiveWire node at %s:%d restored",
(const char *)live_hostname,live_tcp_port));
}
live_watchdog_timer->start(RDLIVEWIRE_WATCHDOG_INTERVAL,true);

View File

@ -2,7 +2,7 @@
//
// A LiveWire Node Driver for Rivendell
//
// (C) Copyright 2007,2016 Fred Gleason <fredg@paravelsystems.com>
// (C) Copyright 2007-2019 Fred Gleason <fredg@paravelsystems.com>
//
// This program is free software; you can redistribute it and/or modify
// it under the terms of the GNU General Public License version 2 as
@ -25,7 +25,7 @@
#include <qstring.h>
#include <qobject.h>
#include <q3socket.h>
#include <qtcpsocket.h>
#include <qstringlist.h>
#include <qtimer.h>
@ -92,7 +92,7 @@ class RDLiveWire : public QObject
void connectedData();
void connectionClosedData();
void readyReadData();
void errorData(int err);
void errorData(QAbstractSocket::SocketError err);
void gpiTimeoutData(int id);
void gpoTimeoutData(int id);
void watchdogData();
@ -131,7 +131,7 @@ class RDLiveWire : public QObject
std::vector<QTimer *>live_gpi_timers;
std::vector<QTimer *>live_gpo_timers;
int live_gpos;
Q3Socket *live_socket;
QTcpSocket *live_socket;
char live_buf[RD_LIVEWIRE_MAX_CMD_LENGTH];
int live_ptr;
bool live_connected;

114
lib/rdsocketstrings.cpp Normal file
View File

@ -0,0 +1,114 @@
// rdsocketstrings.cpp
//
// Human-readable strings for QAbstractSocket::SocketError
//
// (C) Copyright 2019 Fred Gleason <fredg@paravelsystems.com>
//
// This program is free software; you can redistribute it and/or modify
// it under the terms of the GNU Library General Public License
// version 2 as published by the Free Software Foundation.
//
// This program is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU General Public License for more details.
//
// You should have received a copy of the GNU General Public
// License along with this program; if not, write to the Free Software
// Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
//
#include "rdsocketstrings.h"
//
// This REALLY ought to be provided by QAbstractSocket!
//
QString RDSocketStrings(QAbstractSocket::SocketError err)
{
QString ret="unknown socket error";
switch(err) {
case QAbstractSocket::ErrConnectionRefused:
ret="connection refused";
break;
case QAbstractSocket::ErrHostNotFound:
ret="host not found";
break;
case QAbstractSocket::ErrSocketRead:
ret="socket read error";
break;
case QAbstractSocket::RemoteHostClosedError:
ret="remote host closed connection";
break;
case QAbstractSocket::SocketAccessError:
ret="socket access error";
break;
case QAbstractSocket::SocketResourceError:
ret="socket resource error";
break;
case QAbstractSocket::SocketTimeoutError:
ret="connection timed out";
break;
case QAbstractSocket::DatagramTooLargeError:
ret="datagram too large";
break;
case QAbstractSocket::NetworkError:
ret="general network error";
break;
case QAbstractSocket::AddressInUseError:
ret="socket address in use";
break;
case QAbstractSocket::SocketAddressNotAvailableError:
ret="socket address not available";
break;
case QAbstractSocket::UnsupportedSocketOperationError:
ret="unsupported socket operation";
break;
case QAbstractSocket::UnfinishedSocketOperationError:
ret="unfinished socket operation";
break;
case QAbstractSocket::ProxyAuthenticationRequiredError:
ret="proxy authentication required";
break;
case QAbstractSocket::SslHandshakeFailedError:
ret="ssl handshake failed";
break;
case QAbstractSocket::ProxyConnectionRefusedError:
ret="proxy connection refused";
break;
case QAbstractSocket::ProxyConnectionClosedError:
ret="proxy closed connection";
break;
case QAbstractSocket::ProxyConnectionTimeoutError:
ret="proxy connection timed out";
break;
case QAbstractSocket::ProxyNotFoundError:
ret="proxy not found";
break;
case QAbstractSocket::ProxyProtocolError:
ret="proxy protocol error";
break;
}
return ret;
}

30
lib/rdsocketstrings.h Normal file
View File

@ -0,0 +1,30 @@
// rdsocketstrings.h
//
// Human-readable strings for QAbstractSocket::SocketError
//
// (C) Copyright 2019 Fred Gleason <fredg@paravelsystems.com>
//
// This program is free software; you can redistribute it and/or modify
// it under the terms of the GNU Library General Public License
// version 2 as published by the Free Software Foundation.
//
// This program is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU General Public License for more details.
//
// You should have received a copy of the GNU General Public
// License along with this program; if not, write to the Free Software
// Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
//
#ifndef RDSOCKETSTRINGS_H
#define RDSOCKETSTRINGS_H
#include <qabstractsocket.h>
#include <qstring.h>
QString RDSocketStrings(QAbstractSocket::SocketError err);
#endif // RDSOCKETSTRINGS_H