2022-10-31 Fred Gleason <fredg@paravelsystems.com>

* Refactored rdcatch(1) to use the notification mechanism instead of
	the 'StopDeck' catch command.

Signed-off-by: Fred Gleason <fredg@paravelsystems.com>
This commit is contained in:
Fred Gleason 2022-10-31 11:49:29 -04:00
parent 47cf0d34e4
commit eb060e37c9
12 changed files with 191 additions and 181 deletions

View File

@ -23593,3 +23593,6 @@
2022-10-31 Fred Gleason <fredg@paravelsystems.com>
* Removed vestigal support for the 'Reload Heartbeat Configuration'
catch protocol command.
2022-10-31 Fred Gleason <fredg@paravelsystems.com>
* Refactored rdcatch(1) to use the notification mechanism instead of
the 'StopDeck' catch command.

View File

@ -131,36 +131,6 @@
</variablelist>
</sect2>
<sect2 xml:id="sect.privileged_commands.stop_deck">
<title>Stop Deck</title>
<para>
Stop active event.
</para>
<para>
<userinput>SR <replaceable>deck-num</replaceable>!</userinput>
</para>
<variablelist>
<varlistentry>
<term><replaceable>deck-num</replaceable></term>
<listitem>
<para>
The number of the deck to stop.
</para>
</listitem>
</varlistentry>
</variablelist>
</sect2>
<sect2 xml:id="sect.privileged_commands.reload_heartbeat_configuration">
<title>Reload Heartbeat Configuration</title>
<para>
Reload the heartbeat configuration from the database.
</para>
<para>
<userinput>RH!</userinput>
</para>
</sect2>
<sect2 xml:id="sect.privileged_commands.input_monitor_state">
<title>Input Monitor State</title>
<para>

View File

@ -371,7 +371,7 @@
RDCatch messages use the following format:
</para>
<para>
CATCH <replaceable choice='req'>hostname</replaceable>
CATCH <replaceable choice='req'>orig-hostname</replaceable>
<replaceable choice='req'>operation</replaceable>
<replaceable choice='req'>arg1</replaceable>
<replaceable choice='opt'>[...]</replaceable>
@ -379,7 +379,7 @@
<variablelist>
<varlistentry>
<term>
<replaceable>hostname</replaceable>
<replaceable>orig-hostname</replaceable>
</term>
<listitem>
<para>
@ -407,24 +407,34 @@
</para>
<table xml:id="table.rdcatch_event_processed" frame="all" pgwide="0">
<title>RDCatch Event Fields</title>
<tgroup cols="2" align="left" colsep="1" rowsep="1">
<colspec colname="Field" colwidth="2.0*"/>
<colspec colname="Value" colwidth="2.0*"/>
<tgroup cols="3" align="left" colsep="1" rowsep="1">
<colspec colname="Field" colwidth="10.0*"/>
<colspec colname="Offset" colwidth="2.0*"/>
<colspec colname="Value" colwidth="10.0*"/>
<tbody>
<row>
<entry>Field</entry>
<entry>Offset</entry>
<entry>Value</entry>
</row>
<row>
<entry>Hostname</entry>
<entry>Keyword</entry>
<entry>0</entry>
<entry>CATCH</entry>
</row>
<row>
<entry>Originating Hostname</entry>
<entry>1</entry>
<entry>String, from STATIONS.NAME</entry>
</row>
<row>
<entry>Operation</entry>
<entry>2</entry>
<entry>Integer. 1 [RDCatchEvent::DeckEventProcessedOp]</entry>
</row>
<row>
<entry>Deck Channel</entry>
<entry>3</entry>
<entry>
Integer. Record decks have values in the range 1-127,
while play decks have values in the range 128-254.
@ -432,8 +442,9 @@
</row>
<row>
<entry>Event Number</entry>
<entry>4</entry>
<entry>
Integer. The value of CUT_EVENTS.NUMBER.
Integer. The value of CUT_EVENTS.NUMBER.
</entry>
</row>
</tbody>
@ -449,20 +460,29 @@
</para>
<table xml:id="table.rdcatch_deck_status.request" frame="all" pgwide="0">
<title>RDCatch Event Request Fields</title>
<tgroup cols="2" align="left" colsep="1" rowsep="1">
<colspec colname="Field" colwidth="2.0*"/>
<colspec colname="Value" colwidth="2.0*"/>
<tgroup cols="3" align="left" colsep="1" rowsep="1">
<colspec colname="Field" colwidth="10.0*"/>
<colspec colname="Offset" colwidth="2.0*"/>
<colspec colname="Value" colwidth="10.0*"/>
<tbody>
<row>
<entry>Field</entry>
<entry>Offset</entry>
<entry>Value</entry>
</row>
<row>
<entry>Hostname</entry>
<entry>Keyword</entry>
<entry>0</entry>
<entry>CATCH</entry>
</row>
<row>
<entry>Originating Hostname</entry>
<entry>1</entry>
<entry>String, from STATIONS.NAME</entry>
</row>
<row>
<entry>Operation</entry>
<entry>2</entry>
<entry>Integer. 2 [RDCatchEvent::DeckStatusQueryOp]</entry>
</row>
</tbody>
@ -476,24 +496,34 @@
</para>
<table xml:id="table.rdcatch_deck_status.response" frame="all" pgwide="0">
<title>RDCatch Event Response Fields</title>
<tgroup cols="2" align="left" colsep="1" rowsep="1">
<colspec colname="Field" colwidth="2.0*"/>
<colspec colname="Value" colwidth="2.0*"/>
<tgroup cols="3" align="left" colsep="1" rowsep="1">
<colspec colname="Field" colwidth="10.0*"/>
<colspec colname="Offset" colwidth="2.0*"/>
<colspec colname="Value" colwidth="10.0*"/>
<tbody>
<row>
<entry>Field</entry>
<entry>Offset</entry>
<entry>Value</entry>
</row>
<row>
<entry>Hostname</entry>
<entry>Keyword</entry>
<entry>0</entry>
<entry>CATCH</entry>
</row>
<row>
<entry>Originating Hostname</entry>
<entry>1</entry>
<entry>String, from STATIONS.NAME</entry>
</row>
<row>
<entry>Operation</entry>
<entry>2</entry>
<entry>Integer. 3 [RDCatchEvent::DeckStatusResponseOp]</entry>
</row>
<row>
<entry>Deck Channel</entry>
<entry>3</entry>
<entry>
Integer. Record decks have values in the range 1-127,
while play decks have values in the range 128-254.
@ -501,27 +531,31 @@
</row>
<row>
<entry>Status</entry>
<entry>4</entry>
<entry>
Integer. Current status of the specified deck. See
<xref linkend="sect.rdcatch_deck_status.deck_status_codes" />
for code point values.
Integer. Current status of the specified deck. See
<xref linkend="sect.rdcatch_deck_status.deck_status_codes" />
for code point values.
</entry>
</row>
<row>
<entry>Event ID</entry>
<entry>5</entry>
<entry>
Unsigned Integer, from RECORDINGS.ID or 0 if deck is inactive.
Unsigned Integer, from RECORDINGS.ID or 0 if deck is inactive.
</entry>
</row>
<row>
<entry>Cart Number</entry>
<entry>6</entry>
<entry>
Unsigned Integer, from CART.NUMBER or 0 if deck status is not
3 [Active].
Unsigned Integer, from CART.NUMBER or 0 if deck status is not
3 [Active].
</entry>
</row>
<row>
<entry>Cut Number</entry>
<entry>7</entry>
<entry>
Integer, from cut part of CUTS.CUTNAME or 0 if deck status is
not 3 [Active].
@ -578,6 +612,57 @@
</sect3>
</sect2>
<sect2 xml:id="sect.rdcatch_stop_deck">
<title>Stop Deck Operation</title>
<para>
Emitted by <command>rdcatch</command><manvolnum>1</manvolnum> to
abort a Record or Play-out event.
</para>
<table xml:id="table.rdcatch_stop_deck" frame="all" pgwide="0">
<title>RDCatch Stop Deck Fields</title>
<tgroup cols="3" align="left" colsep="1" rowsep="1">
<colspec colname="Field" colwidth="10.0*"/>
<colspec colname="Offset" colwidth="2.0*"/>
<colspec colname="Value" colwidth="10.0*"/>
<tbody>
<row>
<entry>Field</entry>
<entry>Offset</entry>
<entry>Value</entry>
</row>
<row>
<entry>Keyword</entry>
<entry>0</entry>
<entry>CATCH</entry>
</row>
<row>
<entry>Originating Hostname</entry>
<entry>1</entry>
<entry>String, from STATIONS.NAME</entry>
</row>
<row>
<entry>Operation</entry>
<entry>2</entry>
<entry>Integer. 1 [RDCatchEvent::StopDeckOp]</entry>
</row>
<row>
<entry>Target Hostname</entry>
<entry>3</entry>
<entry>String, from STATIONS.NAME</entry>
</row>
<row>
<entry>Deck Channel</entry>
<entry>4</entry>
<entry>
Integer. Record decks have values in the range 1-127,
while play decks have values in the range 128-254.
</entry>
</row>
</tbody>
</tgroup>
</table>
</sect2>
</sect1>
</article>

View File

@ -90,12 +90,6 @@ void RDCatchConnect::reloadDropboxes()
}
void RDCatchConnect::stop(int deck)
{
SendCommand(QString::asprintf("SR %d!",deck));
}
void RDCatchConnect::monitor(int deck,bool state)
{
SendCommand(QString::asprintf("MN %d %d!",deck,state));

View File

@ -49,7 +49,6 @@ class RDCatchConnect : public QObject
void reloadDropboxes();
public slots:
void stop(int deck);
void monitor(int deck,bool state);
void toggleMonitor(int deck);
void setExitCode(int id,RDRecording::ExitCode code,const QString &msg);

View File

@ -73,6 +73,18 @@ void RDCatchEvent::setHostName(const QString &str)
}
QString RDCatchEvent::targetHostName() const
{
return d_target_host_name;
}
void RDCatchEvent::setTargetHostName(const QString &str)
{
d_target_host_name=str;
}
unsigned RDCatchEvent::eventId() const
{
return d_event_id;
@ -141,7 +153,7 @@ bool RDCatchEvent::isValid() const
bool RDCatchEvent::read(const QString &str)
{
printf("RDCatchEvent::read(\"%s\")\n",str.toUtf8().constData());
// printf("RDCatchEvent::read(\"%s\")\n",str.toUtf8().constData());
RDCatchEvent::Operation op=RDCatchEvent::NullOp;
QStringList f0=str.split(" ");
@ -216,6 +228,17 @@ bool RDCatchEvent::read(const QString &str)
}
}
if(ok&&(op==RDCatchEvent::StopDeckOp)) {
if(f0.size()!=5) {
return false;
}
d_operation=op;
d_host_name=f0.at(1);
d_target_host_name=f0.at(3);
d_deck_channel=f0.at(4).toInt();
return true;
}
return false;
}
@ -252,6 +275,11 @@ QString RDCatchEvent::write() const
case RDCatchEvent::NullOp:
case RDCatchEvent::LastOp:
break;
case RDCatchEvent::StopDeckOp:
ret+=" "+d_target_host_name;
ret+=QString::asprintf(" %u",d_deck_channel);
break;
}
return ret;
@ -290,6 +318,12 @@ QString RDCatchEvent::dump() const
ret+=QString::asprintf("cut number: %d\n",d_cut_number);
break;
case RDCatchEvent::StopDeckOp:
ret+="operation: RDCatchEvent::DeckEventProcessedOp\n";
ret+="target hostname: "+d_target_host_name+"\n";
ret+=QString::asprintf("deck channel: %u\n",d_deck_channel);
break;
case RDCatchEvent::NullOp:
case RDCatchEvent::LastOp:
break;

View File

@ -31,13 +31,15 @@ class RDCatchEvent
public:
enum Operation {NullOp=0,DeckEventProcessedOp=1,
DeckStatusQueryOp=2,DeckStatusResponseOp=3,
LastOp=5};
StopDeckOp=5,LastOp=6};
RDCatchEvent(RDDeck::Status status);
RDCatchEvent();
Operation operation() const;
void setOperation(Operation op);
QString hostName() const;
void setHostName(const QString &str);
QString targetHostName() const;
void setTargetHostName(const QString &str);
unsigned eventId() const;
void setEventId(unsigned id);
unsigned cartNumber() const;
@ -59,6 +61,7 @@ class RDCatchEvent
private:
Operation d_operation;
QString d_host_name;
QString d_target_host_name;
unsigned d_event_id;
unsigned d_cart_number;
int d_cut_number;

View File

@ -251,7 +251,15 @@ void DeckMon::monitorButtonData()
void DeckMon::abortButtonData()
{
emit abortClicked();
RDCatchEvent *evt=new RDCatchEvent();
evt->setOperation(RDCatchEvent::StopDeckOp);
evt->setTargetHostName(mon_station);
evt->setDeckChannel(mon_channel);
rda->ripc()->sendCatchEvent(evt);
delete evt;
// emit abortClicked();
}

View File

@ -50,7 +50,7 @@ class DeckMon : public RDFrame
signals:
void monitorClicked();
void abortClicked();
// void abortClicked();
protected:
void resizeEvent(QResizeEvent *e);

View File

@ -181,8 +181,8 @@ MainWidget::MainWidget(RDConfig *c,QWidget *parent)
catch_monitor_vbox->setSpacing(2);
catch_monitor_area->setWidget(catch_monitor_vbox);
QSignalMapper *mapper=new QSignalMapper(this);
connect(mapper,SIGNAL(mapped(int)),this,SLOT(abortData(int)));
// QSignalMapper *mapper=new QSignalMapper(this);
// connect(mapper,SIGNAL(mapped(int)),this,SLOT(abortData(int)));
QSignalMapper *mon_mapper=new QSignalMapper(this);
connect(mon_mapper,SIGNAL(mapped(int)),this,SLOT(monitorData(int)));
QString sql;
@ -205,21 +205,6 @@ MainWidget::MainWidget(RDConfig *c,QWidget *parent)
connect(catch_connect.back()->connector(),
SIGNAL(meterLevel(int,int,int,int)),
this,SLOT(meterLevelData(int,int,int,int)));
/*
connect(catch_connect.back()->connector(),
SIGNAL(eventUpdated(int)),
this,SLOT(eventUpdatedData(int)));
*/
/*
connect(catch_connect.back()->connector(),
SIGNAL(eventPurged(int)),
this,SLOT(eventPurgedData(int)));
*/
/*
connect(catch_connect.back()->connector(),
SIGNAL(deckEventSent(int,int,int)),
this,SLOT(deckEventSentData(int,int,int)));
*/
connect(catch_connect.back()->connector(),
SIGNAL(heartbeatFailed(int)),
this,SLOT(heartbeatFailedData(int)));
@ -254,10 +239,6 @@ MainWidget::MainWidget(RDConfig *c,QWidget *parent)
(rda->config()->stationName().toLower()==
q->value(0).toString().toLower()));
catch_monitor.back()->deckMon()->show();
mapper->setMapping(catch_monitor.back()->deckMon(),
catch_monitor.size()-1);
connect(catch_monitor.back()->deckMon(),SIGNAL(abortClicked()),
mapper,SLOT(map()));
mon_mapper->setMapping(catch_monitor.back()->deckMon(),
catch_monitor.size()-1);
connect(catch_monitor.back()->deckMon(),SIGNAL(monitorClicked()),
@ -789,15 +770,6 @@ void MainWidget::monitorChangedData(int serial,unsigned chan,bool state)
}
}
/*
void MainWidget::deckEventSentData(int serial,int chan,int number)
{
int mon=GetMonitor(serial,chan);
if(mon>=0) {
catch_monitor[mon]->deckMon()->setEvent(number);
}
}
*/
void MainWidget::catchEventReceivedData(RDCatchEvent *evt)
{
@ -816,6 +788,7 @@ void MainWidget::catchEventReceivedData(RDCatchEvent *evt)
case RDCatchEvent::DeckEventProcessedOp:
case RDCatchEvent::DeckStatusQueryOp:
case RDCatchEvent::StopDeckOp:
case RDCatchEvent::NullOp:
case RDCatchEvent::LastOp:
break;
@ -969,13 +942,6 @@ void MainWidget::meterLevelData(int serial,int deck,int l_r,int level)
}
void MainWidget::abortData(int id)
{
catch_connect[catch_monitor[id]->serialNumber()]->connector()->
stop(catch_monitor[id]->channelNumber());
}
void MainWidget::monitorData(int id)
{
catch_connect[catch_monitor[id]->serialNumber()]->connector()->
@ -1033,12 +999,6 @@ void MainWidget::eventUpdatedData(int id)
nextEventData();
}
/*
void MainWidget::eventPurgedData(int id)
{
catch_recordings_model->removeRecord(id);
}
*/
void MainWidget::heartbeatFailedData(int id)
{

View File

@ -93,7 +93,7 @@ class MainWidget : public RDMainWindow
void playedData(int);
void playStoppedData(int);
void meterLevelData(int,int,int,int);
void abortData(int);
// void abortData(int);
void monitorData(int);
void selectionChangedData(const QItemSelection &before,
const QItemSelection &after);
@ -103,7 +103,6 @@ class MainWidget : public RDMainWindow
void clockData();
void midnightData();
void eventUpdatedData(int id);
// void eventPurgedData(int id);
void heartbeatFailedData(int id);
void quitMainWidget();

View File

@ -460,6 +460,35 @@ void MainObject::catchEventReceivedData(RDCatchEvent *evt)
SendFullEventResponse(rda->station()->address());
break;
case RDCatchEvent::StopDeckOp:
if((evt->deckChannel()>0)&&(evt->deckChannel()<(MAX_DECKS+1))) {
switch(catch_record_deck_status[evt->deckChannel()-1]) {
case RDDeck::Recording:
catch_record_aborting[evt->deckChannel()-1]=true;
rda->cae()->stopRecord(catch_record_card[evt->deckChannel()-1],
catch_record_stream[evt->deckChannel()-1]);
break;
case RDDeck::Waiting:
startTimerData(catch_record_id[evt->deckChannel()-1]);
break;
default:
break;
}
}
if((evt->deckChannel()>128)&&(evt->deckChannel()<(MAX_DECKS+129))) {
switch(catch_playout_deck_status[evt->deckChannel()-129]) {
case RDDeck::Recording:
rda->cae()->stopPlay(catch_playout_handle[evt->deckChannel()-129]);
break;
default:
break;
}
}
break;
case RDCatchEvent::DeckEventProcessedOp:
case RDCatchEvent::DeckStatusResponseOp:
case RDCatchEvent::NullOp:
@ -1844,84 +1873,10 @@ void MainObject::DispatchCommand(ServerConnection *conn)
LoadDeckList();
}
if((cmds.at(0)=="RE")&&(cmds.size()==2)) { // Request Status
/*
chan=cmds.at(1).toInt(&ok);
if(!ok) {
EchoArgs(conn->id(),'-');
return;
}
if(chan==0) {
SendFullStatus(conn->id());
return;
}
chan--;
if(chan<MAX_DECKS) {
if(catch_record_deck_status[chan]==RDDeck::Offline) {
EchoArgs(conn->id(),'-');
return;
}
EchoCommand(conn->id(),QString::asprintf("RE %u %d %d!",
chan+1,
catch_record_deck_status[chan],
catch_record_id[chan]));
EchoCommand(conn->id(),QString::asprintf("MN %u %d!",chan+1,
catch_monitor_state[chan]));
return;
}
if((chan>=128)&&(chan<(MAX_DECKS+128))) {
if(catch_playout_deck_status[chan-128]==RDDeck::Offline) {
EchoArgs(conn->id(),'-');
return;
}
EchoCommand(conn->id(),
QString::asprintf("RE %u %d %d!",
chan+1,catch_playout_deck_status[chan-128],
catch_playout_id[chan-128]));
return;
}
EchoArgs(conn->id(),'-');
*/
return;
}
if((cmds.at(0)=="RM")&&(cmds.size()==2)) { // Enable/Disable Metering
conn->setMeterEnabled(cmds.at(1).trimmed()!="0");
}
if((cmds.at(0)=="SR")&&(cmds.size()==2)) { // Stop Recording
chan=cmds.at(1).toInt(&ok);
if(!ok) {
return;
}
if((chan>0)&&(chan<(MAX_DECKS+1))) {
switch(catch_record_deck_status[chan-1]) {
case RDDeck::Recording:
catch_record_aborting[chan-1]=true;
rda->cae()->stopRecord(catch_record_card[chan-1],
catch_record_stream[chan-1]);
break;
case RDDeck::Waiting:
startTimerData(catch_record_id[chan-1]);
break;
default:
break;
}
}
if((chan>128)&&(chan<(MAX_DECKS+129))) {
switch(catch_playout_deck_status[chan-129]) {
case RDDeck::Recording:
rda->cae()->stopPlay(catch_playout_handle[chan-129]);
break;
default:
break;
}
}
}
if((cmds.at(0)=="MN")&&(cmds.size()==3)) { // Monitor State
chan=cmds.at(1).toInt(&ok);
if(!ok) {