Implemented aggregate port rates, averaged across all active streams configured on the port.

Fixes issue 41
This commit is contained in:
Srivats P. 2011-08-14 14:03:57 +05:30
parent b3bc9e36a7
commit ca4a6cb103
12 changed files with 711 additions and 223 deletions

View File

@ -16,6 +16,7 @@
<file>icons/deco_exclusive.png</file>
<file>icons/delete.png</file>
<file>icons/exit.png</file>
<file>icons/gaps.png</file>
<file>icons/logo.png</file>
<file>icons/magnifier.png</file>
<file>icons/name.png</file>

View File

@ -69,6 +69,115 @@ void Port::reorderStreamsByOrdinals()
qSort(mStreams.begin(), mStreams.end(), StreamBase::StreamLessThan);
}
void Port::recalculateAverageRates()
{
double pps = 0;
double bps = 0;
int n = 0;
foreach (Stream* s, mStreams)
{
if (!s->isEnabled())
continue;
double r = s->averagePacketRate();
pps += r;
bps += r * s->frameLenAvg() * 8;
n++;
if (s->nextWhat() == Stream::e_nw_stop)
break;
}
if (n)
{
avgPacketsPerSec_ = pps/n;
avgBitsPerSec_ = bps/n;
}
else
avgPacketsPerSec_ = avgBitsPerSec_ = 0;
qDebug("%s: avgPps = %g avgBps = %g", __FUNCTION__,
avgPacketsPerSec_, avgBitsPerSec_);
emit portRateChanged(mPortGroupId, mPortId);
}
void Port::setAveragePacketRate(double packetsPerSec)
{
double pps = 0;
double bps = 0;
int n = 0;
foreach (Stream* s, mStreams)
{
if (!s->isEnabled())
continue;
s->setAveragePacketRate(packetsPerSec);
double r = s->averagePacketRate();
pps += r;
bps += r * s->frameLenAvg() * 8;
n++;
if (s->nextWhat() == Stream::e_nw_stop)
break;
}
if (n)
{
avgPacketsPerSec_ = pps/n;
avgBitsPerSec_ = bps/n;
}
else
avgPacketsPerSec_ = avgBitsPerSec_ = 0;
qDebug("%s: avgPps = %g avgBps = %g", __FUNCTION__,
avgPacketsPerSec_, avgBitsPerSec_);
emit portRateChanged(mPortGroupId, mPortId);
}
void Port::setAverageBitRate(double bitsPerSec)
{
double pps = 0;
double bps = 0;
int n = 0;
foreach (Stream* s, mStreams)
{
if (!s->isEnabled())
continue;
s->setAveragePacketRate(bitsPerSec/s->frameLenAvg());
double r = s->averagePacketRate();
pps += r;
bps += r * s->frameLenAvg() * 8;
n++;
if (s->nextWhat() == Stream::e_nw_stop)
break;
}
if (n)
{
avgPacketsPerSec_ = pps/n;
avgBitsPerSec_ = bps/n;
}
else
avgPacketsPerSec_ = avgBitsPerSec_ = 0;
qDebug("%s: avgPps = %g avgBps = %g", __FUNCTION__,
avgPacketsPerSec_, avgBitsPerSec_);
emit portRateChanged(mPortGroupId, mPortId);
}
bool Port::newStreamAt(int index, OstProto::Stream const *stream)
{
Stream *s = new Stream;
@ -82,6 +191,7 @@ bool Port::newStreamAt(int index, OstProto::Stream const *stream)
s->setId(newStreamId());
mStreams.insert(index, s);
updateStreamOrdinalsFromIndex();
recalculateAverageRates();
return true;
}
@ -93,6 +203,7 @@ bool Port::deleteStreamAt(int index)
delete mStreams.takeAt(index);
updateStreamOrdinalsFromIndex();
recalculateAverageRates();
return true;
}
@ -312,6 +423,7 @@ _user_opt_cancel:
_fail:
progress.close();
mainWindow->setEnabled(true);
recalculateAverageRates();
return ret;
}

View File

@ -43,6 +43,9 @@ class Port : public QObject {
quint32 mPortGroupId;
QString mUserAlias; // user defined
double avgPacketsPerSec_;
double avgBitsPerSec_;
QList<quint32> mLastSyncStreamList;
QList<Stream*> mStreams; // sorted by stream's ordinal value
@ -50,6 +53,7 @@ class Port : public QObject {
void updateStreamOrdinalsFromIndex();
void reorderStreamsByOrdinals();
public:
enum AdminStatus { AdminDisable, AdminEnable };
@ -72,6 +76,10 @@ public:
{ return (d.is_enabled()?AdminEnable:AdminDisable); }
bool hasExclusiveControl()
{ return d.is_exclusive_control(); }
double averagePacketRate()
{ return avgPacketsPerSec_; }
double averageBitRate()
{ return avgBitsPerSec_; }
//void setAdminEnable(AdminStatus status) { mAdminStatus = status; }
void setAlias(QString &alias) { mUserAlias = alias; }
@ -116,12 +124,18 @@ public:
void when_syncComplete();
void setAveragePacketRate(double packetsPerSec);
void setAverageBitRate(double bitsPerSec);
// FIXME(MED): Bad Hack! port should not need an external trigger to
// recalculate - refactor client side domain objects and model objects
void recalculateAverageRates();
void updateStats(OstProto::PortStats *portStats);
bool openStreams(QString fileName, bool append, QString &error);
bool saveStreams(QString fileName, QString fileType, QString &error);
signals:
void portRateChanged(int portGroupId, int portId);
void portDataChanged(int portGroupId, int portId);
void streamListChanged(int portGroupId, int portId);

View File

@ -109,8 +109,18 @@ PortsWindow::PortsWindow(PortGroupList *pgl, QWidget *parent)
when_portView_currentChanged(QModelIndex(), QModelIndex());
updateStreamViewActions();
//! \todo Hide the Aggregate Box till we add support
frAggregate->setHidden(true);
connect(plm->getStreamModel(),
SIGNAL(dataChanged(const QModelIndex&, const QModelIndex&)),
this, SLOT(streamModelDataChanged()));
connect(plm->getStreamModel(),
SIGNAL(modelReset()),
this, SLOT(streamModelDataChanged()));
}
void PortsWindow::streamModelDataChanged()
{
if (plm->isPort(tvPortList->currentIndex()))
plm->port(tvPortList->currentIndex()).recalculateAverageRates();
}
PortsWindow::~PortsWindow()
@ -121,6 +131,7 @@ PortsWindow::~PortsWindow()
void PortsWindow::on_tvStreamList_activated(const QModelIndex & index)
{
StreamConfigDialog *scd;
int ret;
if (!index.isValid())
{
@ -130,17 +141,27 @@ void PortsWindow::on_tvStreamList_activated(const QModelIndex & index)
scd = new StreamConfigDialog(plm->port(tvPortList->currentIndex()),
index.row(), this);
qDebug("stream list activated\n");
scd->exec(); // TODO: chk retval
ret = scd->exec();
if (ret == QDialog::Accepted)
plm->port(tvPortList->currentIndex()).recalculateAverageRates();
delete scd;
}
void PortsWindow::when_portView_currentChanged(const QModelIndex& current,
const QModelIndex& /*previous*/)
const QModelIndex& previous)
{
plm->getStreamModel()->setCurrentPortIndex(current);
updatePortViewActions(current);
updateStreamViewActions();
if (previous.isValid() && plm->isPort(previous))
{
disconnect(&(plm->port(previous)), SIGNAL(portRateChanged(int, int)),
this, SLOT(updatePortRates()));
}
if (!current.isValid())
{
qDebug("setting stacked widget to blank page");
@ -154,7 +175,10 @@ void PortsWindow::when_portView_currentChanged(const QModelIndex& current,
}
else if (plm->isPort(current))
{
swDetail->setCurrentIndex(0); // port detail page
swDetail->setCurrentIndex(0); // port detail page
updatePortRates();
connect(&(plm->port(current)), SIGNAL(portRateChanged(int, int)),
SLOT(updatePortRates()));
}
}
}
@ -180,6 +204,46 @@ void PortsWindow::when_portModel_reset()
when_portView_currentChanged(QModelIndex(), tvPortList->currentIndex());
}
void PortsWindow::on_averagePacketsPerSec_editingFinished()
{
QModelIndex current = tvPortList->currentIndex();
Q_ASSERT(plm->isPort(current));
bool isOk;
double pps = QLocale().toDouble(averagePacketsPerSec->text(), &isOk);
plm->port(current).setAveragePacketRate(pps);
}
void PortsWindow::on_averageBitsPerSec_editingFinished()
{
QModelIndex current = tvPortList->currentIndex();
Q_ASSERT(plm->isPort(current));
bool isOk;
double bps = QLocale().toDouble(averageBitsPerSec->text(), &isOk)/8;
plm->port(current).setAverageBitRate(bps);
}
void PortsWindow::updatePortRates()
{
QModelIndex current = tvPortList->currentIndex();
if (!current.isValid())
return;
if (!plm->isPort(current))
return;
averagePacketsPerSec->setText(QString("%L1")
.arg(plm->port(current).averagePacketRate(), 0, 'f', 4));
averageBitsPerSec->setText(QString("%L1")
.arg(plm->port(current).averageBitRate(), 0, 'f', 0));
}
void PortsWindow::updateStreamViewActions()
{
// For some reason hasSelection() returns true even if selection size is 0

View File

@ -52,6 +52,9 @@ private slots:
void updatePortViewActions(const QModelIndex& current);
void updateStreamViewActions();
void on_averagePacketsPerSec_editingFinished();
void on_averageBitsPerSec_editingFinished();
void updatePortRates();
void on_tvStreamList_activated(const QModelIndex & index);
void when_portView_currentChanged(const QModelIndex& current,
const QModelIndex& previous);
@ -74,6 +77,8 @@ private slots:
void on_actionOpen_Streams_triggered();
void on_actionSave_Streams_triggered();
void streamModelDataChanged();
};
#endif

View File

@ -5,15 +5,15 @@
<rect>
<x>0</x>
<y>0</y>
<width>689</width>
<width>710</width>
<height>352</height>
</rect>
</property>
<property name="windowTitle" >
<string>Form</string>
</property>
<layout class="QHBoxLayout" >
<item>
<layout class="QGridLayout" >
<item row="0" column="0" >
<widget class="QSplitter" name="splitter" >
<property name="orientation" >
<enum>Qt::Horizontal</enum>
@ -34,10 +34,7 @@
<number>0</number>
</property>
<widget class="QWidget" name="portDetail" >
<layout class="QVBoxLayout" >
<property name="spacing" >
<number>6</number>
</property>
<layout class="QGridLayout" >
<property name="leftMargin" >
<number>0</number>
</property>
@ -50,84 +47,100 @@
<property name="bottomMargin" >
<number>0</number>
</property>
<item>
<item row="0" column="0" >
<layout class="QHBoxLayout" >
<item>
<spacer>
<property name="orientation" >
<enum>Qt::Horizontal</enum>
<widget class="QFrame" name="frAggregate" >
<property name="sizePolicy" >
<sizepolicy vsizetype="Fixed" hsizetype="Preferred" >
<horstretch>0</horstretch>
<verstretch>0</verstretch>
</sizepolicy>
</property>
<property name="sizeHint" >
<size>
<width>40</width>
<height>20</height>
</size>
<property name="frameShape" >
<enum>QFrame::StyledPanel</enum>
</property>
</spacer>
<property name="frameShadow" >
<enum>QFrame::Sunken</enum>
</property>
<layout class="QGridLayout" >
<item row="0" column="0" >
<widget class="QRadioButton" name="radioButton" >
<property name="text" >
<string>Avg pps</string>
</property>
<property name="checked" >
<bool>true</bool>
</property>
</widget>
</item>
<item row="0" column="1" >
<widget class="QLineEdit" name="averagePacketsPerSec" />
</item>
<item row="1" column="0" >
<widget class="QRadioButton" name="radioButton_2" >
<property name="text" >
<string>Avg bps</string>
</property>
</widget>
</item>
<item row="1" column="1" >
<widget class="QLineEdit" name="averageBitsPerSec" >
<property name="enabled" >
<bool>false</bool>
</property>
</widget>
</item>
<item row="0" column="2" >
<spacer>
<property name="orientation" >
<enum>Qt::Horizontal</enum>
</property>
<property name="sizeHint" >
<size>
<width>40</width>
<height>20</height>
</size>
</property>
</spacer>
</item>
</layout>
</widget>
</item>
<item>
<widget class="QPushButton" name="pbApply" >
<property name="text" >
<string>Apply</string>
</property>
</widget>
<layout class="QVBoxLayout" >
<item>
<widget class="QPushButton" name="pbApply" >
<property name="text" >
<string>Apply</string>
</property>
</widget>
</item>
<item>
<spacer>
<property name="orientation" >
<enum>Qt::Vertical</enum>
</property>
<property name="sizeHint" >
<size>
<width>20</width>
<height>0</height>
</size>
</property>
</spacer>
</item>
</layout>
</item>
</layout>
</item>
<item>
<widget class="QFrame" name="frAggregate" >
<property name="frameShape" >
<enum>QFrame::StyledPanel</enum>
</property>
<property name="frameShadow" >
<enum>QFrame::Raised</enum>
</property>
<layout class="QGridLayout" >
<item row="0" column="0" >
<widget class="QLabel" name="label" >
<property name="text" >
<string>Capacity</string>
</property>
</widget>
</item>
<item row="0" column="1" >
<widget class="QLineEdit" name="lineEdit_3" />
</item>
<item row="0" column="2" >
<widget class="QLabel" name="label_3" >
<property name="text" >
<string>Aggr fps</string>
</property>
</widget>
</item>
<item row="0" column="3" >
<widget class="QLineEdit" name="lineEdit" />
</item>
<item row="1" column="0" >
<widget class="QLabel" name="label_2" >
<property name="text" >
<string>% age</string>
</property>
</widget>
</item>
<item row="1" column="1" >
<widget class="QLineEdit" name="lineEdit_4" />
</item>
<item row="1" column="2" >
<widget class="QLabel" name="label_4" >
<property name="text" >
<string>Aggr bps</string>
</property>
</widget>
</item>
<item row="1" column="3" >
<widget class="QLineEdit" name="lineEdit_2" />
</item>
</layout>
</widget>
</item>
<item>
<item row="1" column="0" >
<widget class="QTableView" name="tvStreamList" >
<property name="sizePolicy" >
<sizepolicy vsizetype="Expanding" hsizetype="Expanding" >
<horstretch>0</horstretch>
<verstretch>1</verstretch>
</sizepolicy>
</property>
<property name="contextMenuPolicy" >
<enum>Qt::ActionsContextMenu</enum>
</property>
@ -244,5 +257,38 @@
<resources>
<include location="ostinato.qrc" />
</resources>
<connections/>
<connections>
<connection>
<sender>radioButton</sender>
<signal>toggled(bool)</signal>
<receiver>averagePacketsPerSec</receiver>
<slot>setEnabled(bool)</slot>
<hints>
<hint type="sourcelabel" >
<x>313</x>
<y>28</y>
</hint>
<hint type="destinationlabel" >
<x>380</x>
<y>28</y>
</hint>
</hints>
</connection>
<connection>
<sender>radioButton_2</sender>
<signal>toggled(bool)</signal>
<receiver>averageBitsPerSec</receiver>
<slot>setEnabled(bool)</slot>
<hints>
<hint type="sourcelabel" >
<x>333</x>
<y>55</y>
</hint>
<hint type="destinationlabel" >
<x>395</x>
<y>56</y>
</hint>
</hints>
</connection>
</connections>
</ui>

View File

@ -34,6 +34,8 @@ QRect StreamConfigDialog::lastGeometry;
int StreamConfigDialog::lastTopLevelTabIndex = 0;
int StreamConfigDialog::lastProtocolDataIndex = 0;
static const uint kEthFrameOverHead = 20;
StreamConfigDialog::StreamConfigDialog(Port &port, uint streamIndex,
QWidget *parent) : QDialog (parent), mPort(port)
{
@ -158,8 +160,8 @@ StreamConfigDialog::StreamConfigDialog(Port &port, uint streamIndex,
// TODO(MED):
//! \todo Enable navigation of streams
pbPrev->setDisabled(true);
pbNext->setDisabled(true);
pbPrev->setHidden(true);
pbNext->setHidden(true);
//! \todo Support Goto Stream Id
leStreamId->setHidden(true);
disconnect(rbActionGotoStream, SIGNAL(toggled(bool)), leStreamId, SLOT(setEnabled(bool)));
@ -266,6 +268,8 @@ void StreamConfigDialog::setupUiExtra()
lePktLenMin->setValidator(new QIntValidator(MIN_PKT_LEN, MAX_PKT_LEN,this));
lePktLenMax->setValidator(new QIntValidator(MIN_PKT_LEN, MAX_PKT_LEN,this));
lePacketsPerBurst->setValidator(new QIntValidator(1, 0x7FFFFFFF,this));
/*
** Setup Connections
*/
@ -563,6 +567,13 @@ void StreamConfigDialog::on_twTopLevel_currentChanged(int index)
break;
}
// Stream Control
case 2:
{
StoreCurrentStream();
break;
}
// Packet View
case 3:
{
@ -915,10 +926,14 @@ void StreamConfigDialog::LoadCurrentStream()
leNumPackets->setText(QString().setNum(mpStream->numPackets()));
leNumBursts->setText(QString().setNum(mpStream->numBursts()));
lePacketsPerBurst->setText(QString().setNum(mpStream->burstSize()));
lePacketsPerSec->setText(QString().setNum(mpStream->packetRate()));
leBurstsPerSec->setText(QString().setNum(mpStream->burstRate()));
lePacketsPerSec->setText(
QString("%L1").arg(mpStream->packetRate(), 0, 'f', 4));
leBurstsPerSec->setText(
QString("%L1").arg(mpStream->burstRate(), 0, 'f', 4));
// TODO(MED): Change this when we support goto to specific stream
leStreamId->setText(QString("0"));
leGapIsg->setText("0.0");
}
qDebug("loading stream done");
}
@ -964,8 +979,10 @@ void StreamConfigDialog::StoreCurrentStream()
pStream->setNumPackets(leNumPackets->text().toULong(&isOk));
pStream->setNumBursts(leNumBursts->text().toULong(&isOk));
pStream->setBurstSize(lePacketsPerBurst->text().toULong(&isOk));
pStream->setPacketRate(lePacketsPerSec->text().toDouble(&isOk));
pStream->setBurstRate(leBurstsPerSec->text().toDouble(&isOk));
pStream->setPacketRate(
QLocale().toDouble(lePacketsPerSec->text(), &isOk));
pStream->setBurstRate(
QLocale().toDouble(leBurstsPerSec->text(), &isOk));
}
}
@ -980,6 +997,99 @@ void StreamConfigDialog::on_tbProtocolData_currentChanged(int /*index*/)
#endif
}
void StreamConfigDialog::on_rbPacketsPerSec_toggled(bool checked)
{
if (checked)
on_lePacketsPerSec_textChanged(lePacketsPerSec->text());
}
void StreamConfigDialog::on_rbBurstsPerSec_toggled(bool checked)
{
if (checked)
on_leBurstsPerSec_textChanged(leBurstsPerSec->text());
}
void StreamConfigDialog::on_lePacketsPerBurst_textChanged(const QString &text)
{
if (rbSendBursts->isChecked())
on_leBurstsPerSec_textChanged(leBurstsPerSec->text());
}
void StreamConfigDialog::on_lePacketsPerSec_textChanged(const QString &text)
{
bool isOk;
Stream *pStream = mpStream;
uint frameLen;
if (pStream->lenMode() == Stream::e_fl_fixed)
frameLen = pStream->frameLen();
else
frameLen = (pStream->frameLenMin() + pStream->frameLenMax())/2;
if (rbSendPackets->isChecked())
{
double pktsPerSec = QLocale().toDouble(text, &isOk);
double bitsPerSec = pktsPerSec * double((frameLen+kEthFrameOverHead)*8);
if (rbPacketsPerSec->isChecked())
leBitsPerSec->setText(QString("%L1").arg(bitsPerSec, 0, 'f', 0));
leGapIbg->setText(QString("0.0"));
leGapIpg->setText(QString("%L1").arg(1/double(pktsPerSec), 0, 'f', 9));
}
}
void StreamConfigDialog::on_leBurstsPerSec_textChanged(const QString &text)
{
bool isOk;
Stream *pStream = mpStream;
uint burstSize = lePacketsPerBurst->text().toULong(&isOk);
uint frameLen;
qDebug("start of %s(%s)", __FUNCTION__, text.toAscii().constData());
if (pStream->lenMode() == Stream::e_fl_fixed)
frameLen = pStream->frameLen();
else
frameLen = (pStream->frameLenMin() + pStream->frameLenMax())/2;
if (rbSendBursts->isChecked())
{
double burstsPerSec = QLocale().toDouble(text, &isOk);
double bitsPerSec = burstsPerSec *
double(burstSize * (frameLen + kEthFrameOverHead) * 8);
if (rbBurstsPerSec->isChecked())
leBitsPerSec->setText(QString("%L1").arg(bitsPerSec, 0, 'f', 0));
leGapIbg->setText(QString("%L1").arg(1/double(burstsPerSec), 0, 'f',9));
leGapIpg->setText(QString("0.0"));
}
qDebug("end of %s", __FUNCTION__);
}
void StreamConfigDialog::on_leBitsPerSec_textEdited(const QString &text)
{
bool isOk;
Stream *pStream = mpStream;
uint burstSize = lePacketsPerBurst->text().toULong(&isOk);
uint frameLen;
if (pStream->lenMode() == Stream::e_fl_fixed)
frameLen = pStream->frameLen();
else
frameLen = (pStream->frameLenMin() + pStream->frameLenMax())/2;
if (rbSendPackets->isChecked())
{
double pktsPerSec = QLocale().toDouble(text, &isOk)/
double((frameLen+kEthFrameOverHead)*8);
lePacketsPerSec->setText(QString("%L1").arg(pktsPerSec, 0, 'f', 4));
}
else if (rbSendBursts->isChecked())
{
double burstsPerSec = QLocale().toDouble(text, &isOk)/
double(burstSize * (frameLen + kEthFrameOverHead) * 8);
leBurstsPerSec->setText(QString("%L1").arg(burstsPerSec, 0, 'f', 4));
}
}
void StreamConfigDialog::on_pbOk_clicked()
{
QString log;

View File

@ -127,6 +127,15 @@ private slots:
// "Protocol Data" related
void on_tbProtocolData_currentChanged(int index);
// "Stream Control" related
void on_rbPacketsPerSec_toggled(bool checked);
void on_rbBurstsPerSec_toggled(bool checked);
void on_lePacketsPerBurst_textChanged(const QString &text);
void on_lePacketsPerSec_textChanged(const QString &text);
void on_leBurstsPerSec_textChanged(const QString &text);
void on_leBitsPerSec_textEdited(const QString &text);
void on_pbPrev_clicked();
void on_pbNext_clicked();

View File

@ -42,7 +42,7 @@ QLineEdit:enabled[inputMask = "HH HH HH HH HH HH; "] { background-color: #ccccff
<string/>
</property>
<property name="currentIndex" >
<number>0</number>
<number>2</number>
</property>
<widget class="QWidget" name="packetConfigTab" >
<attribute name="title" >
@ -146,8 +146,8 @@ QLineEdit:enabled[inputMask = "HH HH HH HH HH HH; "] { background-color: #ccccff
<rect>
<x>0</x>
<y>0</y>
<width>592</width>
<height>269</height>
<width>586</width>
<height>248</height>
</rect>
</property>
<attribute name="label" >
@ -798,7 +798,7 @@ QLineEdit:enabled[inputMask = "HH HH HH HH HH HH; "] { background-color: #ccccff
</layout>
</widget>
</item>
<item rowspan="2" row="0" column="1" colspan="2" >
<item rowspan="2" row="0" column="1" >
<widget class="QGroupBox" name="groupBox_13" >
<property name="title" >
<string>Numbers</string>
@ -833,7 +833,7 @@ QLineEdit:enabled[inputMask = "HH HH HH HH HH HH; "] { background-color: #ccccff
<string>Number of Bursts</string>
</property>
<property name="buddy" >
<cstring>leNumPackets</cstring>
<cstring>leNumBursts</cstring>
</property>
</widget>
</item>
@ -853,7 +853,7 @@ QLineEdit:enabled[inputMask = "HH HH HH HH HH HH; "] { background-color: #ccccff
<string>Packets per Burst</string>
</property>
<property name="buddy" >
<cstring>leNumPackets</cstring>
<cstring>lePacketsPerBurst</cstring>
</property>
</widget>
</item>
@ -870,6 +870,75 @@ QLineEdit:enabled[inputMask = "HH HH HH HH HH HH; "] { background-color: #ccccff
</layout>
</widget>
</item>
<item rowspan="2" row="0" column="2" >
<widget class="QGroupBox" name="groupBox_14" >
<property name="title" >
<string>Rate</string>
</property>
<property name="checkable" >
<bool>false</bool>
</property>
<property name="checked" >
<bool>false</bool>
</property>
<layout class="QVBoxLayout" >
<item>
<widget class="QRadioButton" name="rbPacketsPerSec" >
<property name="text" >
<string>Packets/Sec</string>
</property>
<property name="checked" >
<bool>true</bool>
</property>
</widget>
</item>
<item>
<widget class="QLineEdit" name="lePacketsPerSec" >
<property name="alignment" >
<set>Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter</set>
</property>
</widget>
</item>
<item>
<widget class="QRadioButton" name="rbBurstsPerSec" >
<property name="enabled" >
<bool>false</bool>
</property>
<property name="text" >
<string>Bursts/Sec</string>
</property>
</widget>
</item>
<item>
<widget class="QLineEdit" name="leBurstsPerSec" >
<property name="enabled" >
<bool>false</bool>
</property>
<property name="alignment" >
<set>Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter</set>
</property>
</widget>
</item>
<item>
<widget class="QRadioButton" name="rbBitsPerSec" >
<property name="text" >
<string>Bits/Sec</string>
</property>
</widget>
</item>
<item>
<widget class="QLineEdit" name="leBitsPerSec" >
<property name="enabled" >
<bool>false</bool>
</property>
<property name="alignment" >
<set>Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter</set>
</property>
</widget>
</item>
</layout>
</widget>
</item>
<item rowspan="2" row="0" column="3" >
<widget class="QGroupBox" name="groupBox_11" >
<property name="title" >
@ -939,85 +1008,20 @@ QLineEdit:enabled[inputMask = "HH HH HH HH HH HH; "] { background-color: #ccccff
</layout>
</widget>
</item>
<item row="1" column="4" >
<spacer>
<property name="orientation" >
<enum>Qt::Horizontal</enum>
</property>
<property name="sizeHint" >
<size>
<width>41</width>
<height>20</height>
</size>
</property>
</spacer>
</item>
<item row="2" column="0" colspan="5" >
<item row="2" column="0" colspan="4" >
<widget class="Line" name="line_4" >
<property name="orientation" >
<enum>Qt::Horizontal</enum>
</property>
</widget>
</item>
<item row="3" column="0" colspan="2" >
<widget class="QGroupBox" name="groupBox_14" >
<property name="title" >
<string>Rate</string>
</property>
<property name="checkable" >
<bool>false</bool>
</property>
<property name="checked" >
<bool>false</bool>
</property>
<layout class="QVBoxLayout" >
<item>
<widget class="QLabel" name="label_43" >
<property name="text" >
<string>Packets/Sec</string>
</property>
<property name="buddy" >
<cstring>leNumPackets</cstring>
</property>
</widget>
</item>
<item>
<widget class="QLineEdit" name="lePacketsPerSec" >
<property name="alignment" >
<set>Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter</set>
</property>
</widget>
</item>
<item>
<widget class="QLabel" name="label_44" >
<property name="text" >
<string>Bursts/Sec</string>
</property>
<property name="buddy" >
<cstring>leNumPackets</cstring>
</property>
</widget>
</item>
<item>
<widget class="QLineEdit" name="leBurstsPerSec" >
<property name="enabled" >
<bool>false</bool>
</property>
<property name="alignment" >
<set>Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter</set>
</property>
</widget>
</item>
</layout>
</widget>
</item>
<item rowspan="2" row="3" column="2" colspan="3" >
<item row="3" column="0" colspan="4" >
<widget class="QGroupBox" name="groupBox_12" >
<property name="enabled" >
<bool>true</bool>
</property>
<property name="title" >
<string>Gaps</string>
<string>Gaps (in seconds)</string>
</property>
<property name="checkable" >
<bool>false</bool>
@ -1026,13 +1030,13 @@ QLineEdit:enabled[inputMask = "HH HH HH HH HH HH; "] { background-color: #ccccff
<bool>false</bool>
</property>
<layout class="QGridLayout" >
<item row="0" column="0" colspan="2" >
<item row="0" column="0" colspan="4" >
<widget class="QLabel" name="label_45" >
<property name="text" >
<string/>
</property>
<property name="pixmap" >
<pixmap>icons/gaps.png</pixmap>
<pixmap resource="ostinato.qrc" >:/icons/gaps.png</pixmap>
</property>
</widget>
</item>
@ -1042,11 +1046,11 @@ QLineEdit:enabled[inputMask = "HH HH HH HH HH HH; "] { background-color: #ccccff
<string>ISG</string>
</property>
<property name="buddy" >
<cstring>leNumPackets</cstring>
<cstring>leGapIsg</cstring>
</property>
</widget>
</item>
<item row="2" column="0" >
<item row="1" column="1" >
<widget class="QLineEdit" name="leGapIsg" >
<property name="enabled" >
<bool>false</bool>
@ -1056,28 +1060,18 @@ QLineEdit:enabled[inputMask = "HH HH HH HH HH HH; "] { background-color: #ccccff
</property>
</widget>
</item>
<item row="3" column="0" >
<widget class="QLabel" name="label_15" >
<property name="text" >
<string>IPG</string>
</property>
<property name="buddy" >
<cstring>leNumPackets</cstring>
</property>
</widget>
</item>
<item row="3" column="1" >
<item row="1" column="2" >
<widget class="QLabel" name="label_42" >
<property name="text" >
<string>IBG</string>
</property>
<property name="buddy" >
<cstring>leNumPackets</cstring>
<cstring>leGapIbg</cstring>
</property>
</widget>
</item>
<item row="4" column="0" >
<widget class="QLineEdit" name="leGapIpg" >
<item row="1" column="3" >
<widget class="QLineEdit" name="leGapIbg" >
<property name="enabled" >
<bool>false</bool>
</property>
@ -1086,8 +1080,18 @@ QLineEdit:enabled[inputMask = "HH HH HH HH HH HH; "] { background-color: #ccccff
</property>
</widget>
</item>
<item row="4" column="1" >
<widget class="QLineEdit" name="leGapIbg" >
<item row="1" column="4" >
<widget class="QLabel" name="label_15" >
<property name="text" >
<string>IPG</string>
</property>
<property name="buddy" >
<cstring>leGapIpg</cstring>
</property>
</widget>
</item>
<item row="1" column="5" >
<widget class="QLineEdit" name="leGapIpg" >
<property name="enabled" >
<bool>false</bool>
</property>
@ -1099,28 +1103,15 @@ QLineEdit:enabled[inputMask = "HH HH HH HH HH HH; "] { background-color: #ccccff
</layout>
</widget>
</item>
<item rowspan="2" row="4" column="0" >
<item row="4" column="1" colspan="2" >
<spacer>
<property name="orientation" >
<enum>Qt::Vertical</enum>
</property>
<property name="sizeHint" >
<size>
<width>20</width>
<height>40</height>
</size>
</property>
</spacer>
</item>
<item row="5" column="3" >
<spacer>
<property name="orientation" >
<enum>Qt::Vertical</enum>
</property>
<property name="sizeHint" >
<size>
<width>20</width>
<height>40</height>
<width>153</width>
<height>21</height>
</size>
</property>
</spacer>
@ -1276,8 +1267,8 @@ QLineEdit:enabled[inputMask = "HH HH HH HH HH HH; "] { background-color: #ccccff
<slot>reject()</slot>
<hints>
<hint type="sourcelabel" >
<x>558</x>
<y>453</y>
<x>623</x>
<y>496</y>
</hint>
<hint type="destinationlabel" >
<x>533</x>
@ -1292,44 +1283,44 @@ QLineEdit:enabled[inputMask = "HH HH HH HH HH HH; "] { background-color: #ccccff
<slot>setEnabled(bool)</slot>
<hints>
<hint type="sourcelabel" >
<x>169</x>
<y>207</y>
<x>293</x>
<y>137</y>
</hint>
<hint type="destinationlabel" >
<x>169</x>
<y>207</y>
<x>293</x>
<y>169</y>
</hint>
</hints>
</connection>
<connection>
<sender>rbSendPackets</sender>
<signal>toggled(bool)</signal>
<receiver>lePacketsPerSec</receiver>
<receiver>rbPacketsPerSec</receiver>
<slot>setEnabled(bool)</slot>
<hints>
<hint type="sourcelabel" >
<x>125</x>
<y>207</y>
<x>30</x>
<y>66</y>
</hint>
<hint type="destinationlabel" >
<x>125</x>
<y>207</y>
<x>71</x>
<y>250</y>
</hint>
</hints>
</connection>
<connection>
<sender>rbSendBursts</sender>
<signal>toggled(bool)</signal>
<receiver>leBurstsPerSec</receiver>
<receiver>rbBurstsPerSec</receiver>
<slot>setEnabled(bool)</slot>
<hints>
<hint type="sourcelabel" >
<x>125</x>
<y>207</y>
<x>30</x>
<y>91</y>
</hint>
<hint type="destinationlabel" >
<x>125</x>
<y>207</y>
<x>71</x>
<y>310</y>
</hint>
</hints>
</connection>
@ -1340,12 +1331,92 @@ QLineEdit:enabled[inputMask = "HH HH HH HH HH HH; "] { background-color: #ccccff
<slot>setEnabled(bool)</slot>
<hints>
<hint type="sourcelabel" >
<x>125</x>
<y>207</y>
<x>30</x>
<y>91</y>
</hint>
<hint type="destinationlabel" >
<x>156</x>
<y>207</y>
<x>134</x>
<y>177</y>
</hint>
</hints>
</connection>
<connection>
<sender>rbPacketsPerSec</sender>
<signal>toggled(bool)</signal>
<receiver>lePacketsPerSec</receiver>
<slot>setEnabled(bool)</slot>
<hints>
<hint type="sourcelabel" >
<x>48</x>
<y>252</y>
</hint>
<hint type="destinationlabel" >
<x>39</x>
<y>278</y>
</hint>
</hints>
</connection>
<connection>
<sender>rbBurstsPerSec</sender>
<signal>toggled(bool)</signal>
<receiver>leBurstsPerSec</receiver>
<slot>setEnabled(bool)</slot>
<hints>
<hint type="sourcelabel" >
<x>51</x>
<y>303</y>
</hint>
<hint type="destinationlabel" >
<x>54</x>
<y>339</y>
</hint>
</hints>
</connection>
<connection>
<sender>rbBitsPerSec</sender>
<signal>toggled(bool)</signal>
<receiver>leBitsPerSec</receiver>
<slot>setEnabled(bool)</slot>
<hints>
<hint type="sourcelabel" >
<x>82</x>
<y>356</y>
</hint>
<hint type="destinationlabel" >
<x>103</x>
<y>372</y>
</hint>
</hints>
</connection>
<connection>
<sender>rbSendPackets</sender>
<signal>toggled(bool)</signal>
<receiver>rbPacketsPerSec</receiver>
<slot>setChecked(bool)</slot>
<hints>
<hint type="sourcelabel" >
<x>95</x>
<y>70</y>
</hint>
<hint type="destinationlabel" >
<x>154</x>
<y>255</y>
</hint>
</hints>
</connection>
<connection>
<sender>rbSendBursts</sender>
<signal>toggled(bool)</signal>
<receiver>rbBurstsPerSec</receiver>
<slot>setChecked(bool)</slot>
<hints>
<hint type="sourcelabel" >
<x>96</x>
<y>98</y>
</hint>
<hint type="destinationlabel" >
<x>173</x>
<y>299</y>
</hint>
</hints>
</connection>

View File

@ -258,6 +258,19 @@ bool StreamBase::setFrameLenMax(quint16 frameLenMax)
return true;
}
/*! Convenience Function */
quint16 StreamBase::frameLenAvg() const
{
quint16 avgFrameLen;
if (lenMode() == e_fl_fixed)
avgFrameLen = frameLen();
else
avgFrameLen = (frameLenMin() + frameLenMax())/2;
return avgFrameLen;
}
StreamBase::SendUnit StreamBase::sendUnit() const
{
return (StreamBase::SendUnit) mControl->unit();
@ -347,6 +360,44 @@ bool StreamBase::setBurstRate(double burstsPerSec)
return true;
}
/*! Convenience Function */
double StreamBase::averagePacketRate() const
{
double avgPacketRate;
switch (sendUnit())
{
case e_su_bursts:
avgPacketRate = burstRate() * burstSize();
break;
case e_su_packets:
avgPacketRate = packetRate();
break;
default:
Q_ASSERT(false); // Unreachable!!
}
return avgPacketRate;
}
/*! Convenience Function */
bool StreamBase::setAveragePacketRate(double packetsPerSec)
{
switch (sendUnit())
{
case e_su_bursts:
setBurstRate(packetsPerSec/double(burstSize()));
break;
case e_su_packets:
setPacketRate(packetsPerSec);
break;
default:
Q_ASSERT(false); // Unreachable!!
}
return true;
}
bool StreamBase::isFrameVariable() const
{
ProtocolListIterator *iter;

View File

@ -107,6 +107,8 @@ public:
quint16 frameLenMax() const;
bool setFrameLenMax(quint16 frameLenMax);
quint16 frameLenAvg() const;
SendUnit sendUnit() const;
bool setSendUnit(SendUnit sendUnit);
@ -131,6 +133,9 @@ public:
double burstRate() const;
bool setBurstRate(double burstsPerSec);
double averagePacketRate() const;
bool setAveragePacketRate(double packetsPerSec);
bool isFrameVariable() const;
bool isFrameSizeVariable() const;
int frameProtocolLength(int frameIndex) const;

View File

@ -145,8 +145,8 @@ void AbstractPort::updatePacketList()
if (streamList_[i]->burstRate() > 0)
{
ibg = 1e9/double(streamList_[i]->burstRate());
ibg1 = ceil(ibg);
ibg2 = floor(ibg);
ibg1 = long(ceil(ibg));
ibg2 = long(floor(ibg));
nb1 = long((ibg - double(ibg2)) * double(numBursts));
nb2= numBursts - nb1;
}
@ -157,8 +157,8 @@ void AbstractPort::updatePacketList()
if (streamList_[i]->packetRate() > 0)
{
ipg = 1e9/double(streamList_[i]->packetRate());
ipg1 = ceil(ipg);
ipg2 = floor(ipg);
ipg1 = long(ceil(ipg));
ipg2 = long(floor(ipg));
np1 = long((ipg - double(ipg2)) * double(numPackets));
np2= numPackets - np1;
}
@ -207,7 +207,7 @@ void AbstractPort::updatePacketList()
while (nsec >= 1e9)
{
sec++;
nsec -= 1e9;
nsec -= long(1e9);
}
} // for (numPackets)
@ -215,7 +215,7 @@ void AbstractPort::updatePacketList()
while (nsec >= 1e9)
{
sec++;
nsec -= 1e9;
nsec -= long(1e9);
}
} // for (numBursts)