diff --git a/ChangeLog b/ChangeLog index 41af8516..dfa052bc 100644 --- a/ChangeLog +++ b/ChangeLog @@ -19920,3 +19920,7 @@ * Incremented the package version to 3.4.0int1. 2020-07-21 Fred Gleason * Incremented the package version to 3.4.1. +2020-08-05 Fred Gleason + * Added an 'RDDataPacer' class. + * Modified the GVC7000 switcher driver to insert 50 mS pauses + between protocol commands. diff --git a/lib/Makefile.am b/lib/Makefile.am index 657db96f..289624b0 100644 --- a/lib/Makefile.am +++ b/lib/Makefile.am @@ -106,6 +106,7 @@ dist_librd_la_SOURCES = dbversion.h\ rddatepicker.cpp rddatepicker.h\ rddb.h rddb.cpp\ rddbheartbeat.cpp rddbheartbeat.h\ + rddatapacer.cpp rddatapacer.h\ rddatetime.cpp rddatetime.h\ rddebug.cpp rddebug.h\ rddeck.cpp rddeck.h\ @@ -270,6 +271,7 @@ nodist_librd_la_SOURCES = moc_rdadd_cart.cpp\ moc_rdcueedit.cpp\ moc_rdcueeditdialog.cpp\ moc_rdcut_dialog.cpp\ + moc_rddatapacer.cpp\ moc_rddatedialog.cpp\ moc_rddatepicker.cpp\ moc_rddbheartbeat.cpp\ diff --git a/lib/lib.pro b/lib/lib.pro index a283ca5c..7ef0fe46 100644 --- a/lib/lib.pro +++ b/lib/lib.pro @@ -71,6 +71,7 @@ SOURCES += rdcueeditdialog.cpp SOURCES += rdcut.cpp SOURCES += rdcut_path.cpp SOURCES += rdcut_dialog.cpp +SOURCES += rddatapacer.cpp SOURCES += rddatedialog.cpp SOURCES += rddatedecode.cpp SOURCES += rddatepicker.cpp @@ -194,6 +195,7 @@ HEADERS += rdcartdrag.h HEADERS += rdcatch_connect.h HEADERS += rdcddblookup.h HEADERS += rdcdplayer.h +HEADERS += rddatapacer.h HEADERS += rddiscrecord.h HEADERS += rddisclookup.h HEADERS += rdcheck_version.h diff --git a/lib/rddatapacer.cpp b/lib/rddatapacer.cpp new file mode 100644 index 00000000..f83a3903 --- /dev/null +++ b/lib/rddatapacer.cpp @@ -0,0 +1,80 @@ +// rddatapacer.cpp +// +// Pace a stream of data messages. +// +// (C) Copyright 2020 Fred Gleason +// +// 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 +// 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 "rddatapacer.h" + +RDDataPacer::RDDataPacer(QObject *parent) + : QObject(parent) +{ + d_pace_interval=RDDATAPACER_DEFAULT_PACE_INTERVAL; + + d_timer=new QTimer(this); + d_timer->setSingleShot(true); + connect(d_timer,SIGNAL(timeout()),this,SLOT(timeoutData())); +} + + +RDDataPacer::~RDDataPacer() +{ + delete d_timer; +} + + +int RDDataPacer::paceInterval() const +{ + return d_pace_interval; +} + + +void RDDataPacer::setPaceInterval(int msecs) +{ + d_pace_interval=msecs; +} + + +void RDDataPacer::send(const QByteArray &data) +{ + if(d_timer->isActive()) { + // + // Queue it up + // + d_data_queue.enqueue(data); + } + else { + // + // Wake up + // + emit dataSent(data); + d_timer->start(d_pace_interval); + } +} + + +void RDDataPacer::timeoutData() +{ + if(d_data_queue.isEmpty()) { + // + // Nothing to do, go to sleep + // + return; + } + emit dataSent(d_data_queue.dequeue()); + d_timer->start(d_pace_interval); +} diff --git a/lib/rddatapacer.h b/lib/rddatapacer.h new file mode 100644 index 00000000..71bee78f --- /dev/null +++ b/lib/rddatapacer.h @@ -0,0 +1,56 @@ +// rddatapacer.h +// +// Pace a stream of data messages. +// +// (C) Copyright 2020 Fred Gleason +// +// 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 +// 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 RDDATAPACER_H +#define RDDATAPACER_H + +#include +#include +#include +#include + +#define RDDATAPACER_DEFAULT_PACE_INTERVAL 100 + +class RDDataPacer : public QObject +{ + Q_OBJECT; + public: + RDDataPacer(QObject *parent=0); + ~RDDataPacer(); + int paceInterval() const; + void setPaceInterval(int msecs); + + signals: + void dataSent(const QByteArray &data); + + public slots: + void send(const QByteArray &data); + + private slots: + void timeoutData(); + + private: + QQueue d_data_queue; + QTimer *d_timer; + int d_pace_interval; +}; + + +#endif // RDDATAPACER_H diff --git a/ripcd/gvc7000.cpp b/ripcd/gvc7000.cpp index 1a6108a7..7647f7cd 100644 --- a/ripcd/gvc7000.cpp +++ b/ripcd/gvc7000.cpp @@ -54,6 +54,14 @@ Gvc7000::Gvc7000(RDMatrix *matrix,QObject *parent) gvc_reconnect_timer->setSingleShot(true); connect(gvc_reconnect_timer,SIGNAL(timeout()),this,SLOT(ipConnect())); + // + // Data Pacer + // + gvc_pacer=new RDDataPacer(this); + gvc_pacer->setPaceInterval(10); + connect(gvc_pacer,SIGNAL(dataSent(const QByteArray &)), + this,SLOT(sendCommandData(const QByteArray &))); + // // Initialize the connection // @@ -106,7 +114,7 @@ void Gvc7000::processCommand(RDMacro *cmd) emit rmlEcho(cmd); return; } - SendCommand(ToSeries7000Native(QString().sprintf("TI,%04X,%04X",cmd->arg(2).toInt()-1,cmd->arg(1).toInt()-1))); + gvc_pacer->send(ToSeries7000Native(QString().sprintf("TI,%04X,%04X",cmd->arg(2).toInt()-1,cmd->arg(1).toInt()-1)).toAscii()); cmd->acknowledge(true); emit rmlEcho(cmd); break; @@ -127,7 +135,7 @@ void Gvc7000::ipConnect() void Gvc7000::keepaliveData() { - SendCommand(ToSeries7000Native("QJ")); + gvc_pacer->send(ToSeries7000Native("QJ").toAscii()); } @@ -177,12 +185,19 @@ void Gvc7000::errorData(QAbstractSocket::SocketError err) } +void Gvc7000::sendCommandData(const QByteArray &data) +{ + syslog(LOG_DEBUG,"gvc7000 sending \"%s\"",data.constData()); + gvc_socket->write(data); +} + +/* void Gvc7000::SendCommand(const QString &str) { syslog(LOG_DEBUG,"gvc7000 sending \"%s\"",(const char *)str.toAscii()); gvc_socket->write(str.toAscii()); } - +*/ QString Gvc7000::ToSeries7000Native(const QString &str) const { diff --git a/ripcd/gvc7000.h b/ripcd/gvc7000.h index 78c6d01b..88ae05c2 100644 --- a/ripcd/gvc7000.h +++ b/ripcd/gvc7000.h @@ -26,6 +26,7 @@ #include #include +#include #include #include @@ -52,11 +53,12 @@ class Gvc7000 : public Switcher void connectedData(); void disconnectedData(); void errorData(QAbstractSocket::SocketError err); + void sendCommandData(const QByteArray &data); private: - void SendCommand(const QString &str); QString ToSeries7000Native(const QString &str) const; QTcpSocket *gvc_socket; + RDDataPacer *gvc_pacer; QHostAddress gvc_ipaddress; int gvc_matrix; int gvc_ipport;