void PendingList::checkTimeouts()
{
qint64 t1
= QDateTime::currentMSecsSinceEpoch();
for (int i = 0; i < MAX_CLIENTS; i++)
{
QList<PendingMsg>::iterator it;
for (it = list[i].begin(); it != list[i].end(); )
{
quint64 t0 = it->request.getTimeStamp();
quint64 dift = t1 - t0;
if (dift >= it->timeout)
{
CMD cmd1 = it->cmd;
CMD cmd2 = it->request.getCmd();
it = list[i].erase(it);
emitTimeout((System)i, cmd1, cmd2);
}
else
it++;
}
}
stopIfEmpty();
}
void PendingList::checkTimeouts()
{
qint64 t1 = QDateTime::currentMSecsSinceEpoch();
for (int i = 0; i < MAX_CLIENTS; i++)
{
QList<PendingMsg>::iterator it;
for (it = list[i].begin(); it != list[i].end(); )
{
quint64 t0 = it->request.getTimeStamp();
quint64 dift = t1 - t0;
if (dift >= it->timeout)
{
CMD cmd1 = it->cmd;
CMD cmd2 = it->request.getCmd();
it = list[i].erase(it);
emitTimeout((System)i, cmd1, cmd2);
}
else
it++;
}
}
stopIfEmpty();
}
To copy to clipboard, switch view to plain text mode
#pragma once
#include "MM.h"
#include "Message.h"
#include <QTimer>
#include <QObject>
struct PendingMsg
{
Message request; //message pending to receive a response
CMD cmd; // type of the pending response {ACK or ORD_RESP}
int timeout; // Time that can be stored the message before emitting a timeout signal
PendingMsg(Message m, CMD c, int t)
{
request = m;
cmd = c;
timeout = t;
};
{
return "[" + cmdTags[cmd] + " (" + cmdTags[request.getCmd()] + ")]";
};
};
{
Q_OBJECT
public:
PendingList
(QObject* parent,
int time);
~PendingList(void);
bool add(System sys, Message req, CMD cmd, int time);
bool remove(System sys, Message msg);
void setCheckTimeInterval(int t) { checkTimeInterval = t;};
int size() const;
void display() const;
bool resumeTimer(){return false;};
bool pauseTimer(){return false;};
private:
int checkTimeInterval;
QList<PendingMsg> list[MAX_CLIENTS];
// finds the position of the command cmd inside list[sys]
int match(System sys, Message msg) const;
bool startIfEmpty();
bool stopIfEmpty();
// Reports that the system 'sys' has not sent a message of type 'cmd1' as answer of a message of type 'cmd2'
void emitTimeout(System sys, CMD cmd1, CMD cmd2);
void emitMatch(System sys, Message msg, Message req);
private slots:
void checkTimeouts();
signals:
void timeout(System);
void timeout_ack_unit_ctrl(System);
void timeout_ack_insp_mis(System);
void timeout_ack_mosaic(System);
void timeout_ack_weed_map(System);
void timeout_ack_tre_mis(System);
void timeout_ack_pause(System);
void timeout_ack_stop(System);
void timeout_ack_resume(System);
void timeout_resp_insp_mis(System);
void timeout_resp_mosaic(System);
void timeout_resp_weed_map(System);
void timeout_resp_tre_mis(System);
void timeout_resp_pause(System);
void timeout_resp_stop(System);
void timeout_resp_resume(System);
void ack_insp_mis(System);
void ack_mosaic(System);
void ack_weed_map(System);
void ack_tre_mis(System);
void ack_unit_ctrl(System);
void ack_stop(System);
void ack_resume(System);
void ack_pause(System);
void resp_insp_mis_ok(System);
void resp_mosaic_ok(System);
void resp_weed_map_ok(System);
void resp_tre_mis_ok(System);
void resp_stop_ok(System);
void resp_resume_ok(System);
void resp_pause_ok(System);
void resp_insp_mis_ko(System);
void resp_mosaic_ko(System);
void resp_weed_map_ko(System);
void resp_tre_mis_ko(System);
void resp_stop_ko(System);
void resp_resume_ko(System);
void resp_pause_ko(System);
};
#pragma once
#include "MM.h"
#include "Message.h"
#include <QTimer>
#include <QObject>
struct PendingMsg
{
Message request; //message pending to receive a response
CMD cmd; // type of the pending response {ACK or ORD_RESP}
int timeout; // Time that can be stored the message before emitting a timeout signal
PendingMsg(Message m, CMD c, int t)
{
request = m;
cmd = c;
timeout = t;
};
QString display() const
{
return "[" + cmdTags[cmd] + " (" + cmdTags[request.getCmd()] + ")]";
};
};
class PendingList : public QObject
{
Q_OBJECT
public:
PendingList(QObject* parent, int time);
~PendingList(void);
bool add(System sys, Message req, CMD cmd, int time);
bool remove(System sys, Message msg);
void setCheckTimeInterval(int t) { checkTimeInterval = t;};
int size() const;
void display() const;
bool resumeTimer(){return false;};
bool pauseTimer(){return false;};
private:
int checkTimeInterval;
QTimer timer;
QList<PendingMsg> list[MAX_CLIENTS];
// finds the position of the command cmd inside list[sys]
int match(System sys, Message msg) const;
bool startIfEmpty();
bool stopIfEmpty();
// Reports that the system 'sys' has not sent a message of type 'cmd1' as answer of a message of type 'cmd2'
void emitTimeout(System sys, CMD cmd1, CMD cmd2);
void emitMatch(System sys, Message msg, Message req);
private slots:
void checkTimeouts();
signals:
void timeout(System);
void timeout_ack_unit_ctrl(System);
void timeout_ack_insp_mis(System);
void timeout_ack_mosaic(System);
void timeout_ack_weed_map(System);
void timeout_ack_tre_mis(System);
void timeout_ack_pause(System);
void timeout_ack_stop(System);
void timeout_ack_resume(System);
void timeout_resp_insp_mis(System);
void timeout_resp_mosaic(System);
void timeout_resp_weed_map(System);
void timeout_resp_tre_mis(System);
void timeout_resp_pause(System);
void timeout_resp_stop(System);
void timeout_resp_resume(System);
void ack_insp_mis(System);
void ack_mosaic(System);
void ack_weed_map(System);
void ack_tre_mis(System);
void ack_unit_ctrl(System);
void ack_stop(System);
void ack_resume(System);
void ack_pause(System);
void resp_insp_mis_ok(System);
void resp_mosaic_ok(System);
void resp_weed_map_ok(System);
void resp_tre_mis_ok(System);
void resp_stop_ok(System);
void resp_resume_ok(System);
void resp_pause_ok(System);
void resp_insp_mis_ko(System);
void resp_mosaic_ko(System);
void resp_weed_map_ko(System);
void resp_tre_mis_ko(System);
void resp_stop_ko(System);
void resp_resume_ko(System);
void resp_pause_ko(System);
};
To copy to clipboard, switch view to plain text mode
#include "PendingList.h"
PendingList
::PendingList(QObject *parent,
int time){
this->setParent(parent);
checkTimeInterval = time;
connect(&timer, SIGNAL(timeout()), this, SLOT(checkTimeouts()));
}
PendingList::~PendingList(void)
{
}
bool PendingList::startIfEmpty()
{
if (this->size() > 0 && !timer.isActive()){
timer.start(checkTimeInterval);
return true;
}
return false;
}
bool PendingList::stopIfEmpty()
{
if (this->size() == 0 && timer.isActive()){
timer.stop();
return true;
}
return false;
}
void PendingList::display() const
{
printInfo(0, 0, false, false, "Pending List:");
for (int i = 0; i < MAX_CLIENTS; i++)
{
int n = list[i].size();
if (n > 0)
{
QString line
= " - " + sysNames
[i
] + ": ";
for (int j = 0; j < n; j++)
{
line += list[i][j].display();
}
printInfo(0, 0, false, false, line);
}
}
}
int PendingList::match(System sys, Message msg) const
{
int psys = int(sys);
int n = list[psys].size();
for (int i = 0; i < n; i++)
{
CMD stCmd = list[psys][i].cmd;
CMD cmd = msg.getCmd();
if ((list[psys][i].cmd == msg.getCmd()) &&
((msg.getCmd() == ACK) || (msg.getCmd() == RESP && (msg.getPldByte(0) == list[psys][i].request.getCmd()))))
return i;
}
return -1;
}
bool PendingList::add(System sys, Message req, CMD cmd, int time)
{
quint8 ba[] = {req.getCmd()};
Message msg(cmd, ba, 1);
int p = match(sys, msg);
if (p == -1)
{
int psys = int(sys);
PendingMsg pm(req, cmd, time);
list[psys].append(pm);
startIfEmpty();
return true;
}
return false;
}
bool PendingList::remove(System sys, Message msg)
{
int pos = this->match(sys, msg);
if (pos < 0)
return false;
emitMatch(sys, msg, list[sys][pos].request);
list[sys].removeAt(pos);
stopIfEmpty();
return true;
}
int PendingList::size() const
{
int n = 0;
for (int i = 0; i < MAX_CLIENTS; i++)
n = n + list[i].size();
return n;
}
void PendingList::checkTimeouts()
{
qint64 t1
= QDateTime::currentMSecsSinceEpoch();
for (int i = 0; i < MAX_CLIENTS; i++)
{
QList<PendingMsg>::iterator it;
for (it = list[i].begin(); it != list[i].end(); )
{
quint64 t0 = it->request.getTimeStamp();
quint64 dift = t1 - t0;
if (dift >= it->timeout)
{
CMD cmd1 = it->cmd;
CMD cmd2 = it->request.getCmd();
it = list[i].erase(it);
emitTimeout((System)i, cmd1, cmd2);
}
else
it++;
}
}
stopIfEmpty();
}
void PendingList::emitTimeout(System sys, CMD cmd1, CMD cmd2)
{
printInfo(1, 1, true, true, "Timeout: Pending message (" + cmdTags[cmd1] + " from " + sysNames[sys] + ") erased from the pending messages list");
if (cmd1 == ACK)
switch (cmd2
{
case INSP_MIS:
emit timeout_ack_insp_mis(sys);
break;
case MOSAIC:
emit timeout_ack_mosaic(sys);
break;
case WEED_MAP:
emit timeout_ack_weed_map(sys);
break;
case TRE_MIS:
emit timeout_ack_tre_mis(sys);
break;
case PAUSE_MIS:
emit timeout_ack_pause(sys);
break;
case STOP_MIS:
emit timeout_ack_stop(sys);
break;
case RES_MIS:
emit timeout_ack_resume(sys);
break;
}
else // ORD_RESP
switch (cmd2)
{
case INSP_MIS:
emit timeout_resp_insp_mis(sys);
break;
case MOSAIC:
emit timeout_resp_mosaic(sys);
break;
case WEED_MAP:
emit timeout_resp_weed_map(sys);
break;
case TRE_MIS:
emit timeout_resp_tre_mis(sys);
break;
case PAUSE_MIS:
emit timeout_resp_pause(sys);
break;
case STOP_MIS:
emit timeout_resp_stop(sys);
break;
case RES_MIS:
emit timeout_resp_resume(sys);
break;
}
}
void PendingList::emitMatch(System sys, Message msg, Message pendMsg)
{
CMD pendCmd = pendMsg.getCmd();
if (msg.getCmd() == ACK)
switch (pendMsg.getCmd())
{
case INSP_MIS:
emit ack_insp_mis(sys);
break;
case MOSAIC:
emit ack_mosaic(sys);
break;
case WEED_MAP:
emit ack_weed_map(sys);
break;
case TRE_MIS:
emit ack_tre_mis(sys);
break;
case PAUSE_MIS:
emit ack_pause(sys);
break;
case STOP_MIS:
emit ack_stop(sys);
break;
case RES_MIS:
emit ack_resume(sys);
break;
default:
if (pendMsg.is_UNIT_CTRL())
emit ack_unit_ctrl(sys);
break;
}
else // ORD_RESP
if (msg.getPldByte(1) == OK)
switch (pendCmd)
{
case INSP_MIS:
emit resp_insp_mis_ok(sys);
break;
case MOSAIC:
emit resp_mosaic_ok(sys);
break;
case WEED_MAP:
emit resp_weed_map_ok(sys);
break;
case TRE_MIS:
emit resp_tre_mis_ok(sys);
break;
case PAUSE_MIS:
emit resp_pause_ok(sys);
break;
case STOP_MIS:
emit resp_stop_ok(sys);
break;
case RES_MIS:
emit resp_resume_ok(sys);
break;
}
else
switch (pendCmd)
{
case INSP_MIS:
emit resp_insp_mis_ko(sys);
break;
case MOSAIC:
emit resp_mosaic_ko(sys);
break;
case WEED_MAP:
emit resp_weed_map_ko(sys);
break;
case TRE_MIS:
emit resp_tre_mis_ko(sys);
break;
case PAUSE_MIS:
emit resp_pause_ko(sys);
break;
case STOP_MIS:
emit resp_stop_ko(sys);
break;
case RES_MIS:
emit resp_resume_ko(sys);
break;
}
}
#include "PendingList.h"
PendingList::PendingList(QObject *parent, int time)
{
this->setParent(parent);
checkTimeInterval = time;
connect(&timer, SIGNAL(timeout()), this, SLOT(checkTimeouts()));
}
PendingList::~PendingList(void)
{
}
bool PendingList::startIfEmpty()
{
if (this->size() > 0 && !timer.isActive()){
timer.start(checkTimeInterval);
return true;
}
return false;
}
bool PendingList::stopIfEmpty()
{
if (this->size() == 0 && timer.isActive()){
timer.stop();
return true;
}
return false;
}
void PendingList::display() const
{
printInfo(0, 0, false, false, "Pending List:");
for (int i = 0; i < MAX_CLIENTS; i++)
{
int n = list[i].size();
if (n > 0)
{
QString line = " - " + sysNames[i] + ": ";
for (int j = 0; j < n; j++)
{
line += list[i][j].display();
}
printInfo(0, 0, false, false, line);
}
}
}
int PendingList::match(System sys, Message msg) const
{
int psys = int(sys);
int n = list[psys].size();
for (int i = 0; i < n; i++)
{
CMD stCmd = list[psys][i].cmd;
CMD cmd = msg.getCmd();
if ((list[psys][i].cmd == msg.getCmd()) &&
((msg.getCmd() == ACK) || (msg.getCmd() == RESP && (msg.getPldByte(0) == list[psys][i].request.getCmd()))))
return i;
}
return -1;
}
bool PendingList::add(System sys, Message req, CMD cmd, int time)
{
quint8 ba[] = {req.getCmd()};
Message msg(cmd, ba, 1);
int p = match(sys, msg);
if (p == -1)
{
int psys = int(sys);
PendingMsg pm(req, cmd, time);
list[psys].append(pm);
startIfEmpty();
return true;
}
return false;
}
bool PendingList::remove(System sys, Message msg)
{
int pos = this->match(sys, msg);
if (pos < 0)
return false;
emitMatch(sys, msg, list[sys][pos].request);
list[sys].removeAt(pos);
stopIfEmpty();
return true;
}
int PendingList::size() const
{
int n = 0;
for (int i = 0; i < MAX_CLIENTS; i++)
n = n + list[i].size();
return n;
}
void PendingList::checkTimeouts()
{
qint64 t1 = QDateTime::currentMSecsSinceEpoch();
for (int i = 0; i < MAX_CLIENTS; i++)
{
QList<PendingMsg>::iterator it;
for (it = list[i].begin(); it != list[i].end(); )
{
quint64 t0 = it->request.getTimeStamp();
quint64 dift = t1 - t0;
if (dift >= it->timeout)
{
CMD cmd1 = it->cmd;
CMD cmd2 = it->request.getCmd();
it = list[i].erase(it);
emitTimeout((System)i, cmd1, cmd2);
}
else
it++;
}
}
stopIfEmpty();
}
void PendingList::emitTimeout(System sys, CMD cmd1, CMD cmd2)
{
printInfo(1, 1, true, true, "Timeout: Pending message (" + cmdTags[cmd1] + " from " + sysNames[sys] + ") erased from the pending messages list");
if (cmd1 == ACK)
switch (cmd2
{
case INSP_MIS:
emit timeout_ack_insp_mis(sys);
break;
case MOSAIC:
emit timeout_ack_mosaic(sys);
break;
case WEED_MAP:
emit timeout_ack_weed_map(sys);
break;
case TRE_MIS:
emit timeout_ack_tre_mis(sys);
break;
case PAUSE_MIS:
emit timeout_ack_pause(sys);
break;
case STOP_MIS:
emit timeout_ack_stop(sys);
break;
case RES_MIS:
emit timeout_ack_resume(sys);
break;
}
else // ORD_RESP
switch (cmd2)
{
case INSP_MIS:
emit timeout_resp_insp_mis(sys);
break;
case MOSAIC:
emit timeout_resp_mosaic(sys);
break;
case WEED_MAP:
emit timeout_resp_weed_map(sys);
break;
case TRE_MIS:
emit timeout_resp_tre_mis(sys);
break;
case PAUSE_MIS:
emit timeout_resp_pause(sys);
break;
case STOP_MIS:
emit timeout_resp_stop(sys);
break;
case RES_MIS:
emit timeout_resp_resume(sys);
break;
}
}
void PendingList::emitMatch(System sys, Message msg, Message pendMsg)
{
CMD pendCmd = pendMsg.getCmd();
if (msg.getCmd() == ACK)
switch (pendMsg.getCmd())
{
case INSP_MIS:
emit ack_insp_mis(sys);
break;
case MOSAIC:
emit ack_mosaic(sys);
break;
case WEED_MAP:
emit ack_weed_map(sys);
break;
case TRE_MIS:
emit ack_tre_mis(sys);
break;
case PAUSE_MIS:
emit ack_pause(sys);
break;
case STOP_MIS:
emit ack_stop(sys);
break;
case RES_MIS:
emit ack_resume(sys);
break;
default:
if (pendMsg.is_UNIT_CTRL())
emit ack_unit_ctrl(sys);
break;
}
else // ORD_RESP
if (msg.getPldByte(1) == OK)
switch (pendCmd)
{
case INSP_MIS:
emit resp_insp_mis_ok(sys);
break;
case MOSAIC:
emit resp_mosaic_ok(sys);
break;
case WEED_MAP:
emit resp_weed_map_ok(sys);
break;
case TRE_MIS:
emit resp_tre_mis_ok(sys);
break;
case PAUSE_MIS:
emit resp_pause_ok(sys);
break;
case STOP_MIS:
emit resp_stop_ok(sys);
break;
case RES_MIS:
emit resp_resume_ok(sys);
break;
}
else
switch (pendCmd)
{
case INSP_MIS:
emit resp_insp_mis_ko(sys);
break;
case MOSAIC:
emit resp_mosaic_ko(sys);
break;
case WEED_MAP:
emit resp_weed_map_ko(sys);
break;
case TRE_MIS:
emit resp_tre_mis_ko(sys);
break;
case PAUSE_MIS:
emit resp_pause_ko(sys);
break;
case STOP_MIS:
emit resp_stop_ko(sys);
break;
case RES_MIS:
emit resp_resume_ko(sys);
break;
}
}
To copy to clipboard, switch view to plain text mode
Bookmarks