Implemented Interleaved streams transmit mode. Changed port rate averaging algo.
Fixes issue 12
This commit is contained in:
parent
ca4a6cb103
commit
ca7a264b36
@ -33,6 +33,7 @@ HEADERS += \
|
||||
mainwindow.h \
|
||||
packetmodel.h \
|
||||
port.h \
|
||||
portconfigdialog.h \
|
||||
portgroup.h \
|
||||
portgrouplist.h \
|
||||
portmodel.h \
|
||||
@ -49,6 +50,7 @@ HEADERS += \
|
||||
FORMS += \
|
||||
about.ui \
|
||||
mainwindow.ui \
|
||||
portconfigdialog.ui \
|
||||
portstatsfilter.ui \
|
||||
portstatswindow.ui \
|
||||
portswindow.ui \
|
||||
@ -63,6 +65,7 @@ SOURCES += \
|
||||
mainwindow.cpp \
|
||||
packetmodel.cpp \
|
||||
port.cpp \
|
||||
portconfigdialog.cpp \
|
||||
portgroup.cpp \
|
||||
portgrouplist.cpp \
|
||||
portmodel.cpp \
|
||||
|
124
client/port.cpp
124
client/port.cpp
@ -32,6 +32,8 @@ extern QMainWindow *mainWindow;
|
||||
|
||||
uint Port::mAllocStreamId = 0;
|
||||
|
||||
static const int kEthOverhead = 20;
|
||||
|
||||
uint Port::newStreamId()
|
||||
{
|
||||
return mAllocStreamId++;
|
||||
@ -82,23 +84,36 @@ void Port::recalculateAverageRates()
|
||||
|
||||
double r = s->averagePacketRate();
|
||||
pps += r;
|
||||
bps += r * s->frameLenAvg() * 8;
|
||||
bps += r * (s->frameLenAvg() + kEthOverhead) * 8;
|
||||
n++;
|
||||
|
||||
if (s->nextWhat() == Stream::e_nw_stop)
|
||||
if ((transmitMode() == OstProto::kSequentialTransmit)
|
||||
&& (s->nextWhat() == Stream::e_nw_stop))
|
||||
break;
|
||||
}
|
||||
|
||||
if (n)
|
||||
{
|
||||
switch (transmitMode())
|
||||
{
|
||||
case OstProto::kSequentialTransmit:
|
||||
avgPacketsPerSec_ = pps/n;
|
||||
avgBitsPerSec_ = bps/n;
|
||||
break;
|
||||
case OstProto::kInterleavedTransmit:
|
||||
avgPacketsPerSec_ = pps;
|
||||
avgBitsPerSec_ = bps;
|
||||
break;
|
||||
default:
|
||||
Q_ASSERT(false); // Unreachable!!
|
||||
}
|
||||
numActiveStreams_ = n;
|
||||
}
|
||||
else
|
||||
avgPacketsPerSec_ = avgBitsPerSec_ = 0;
|
||||
avgPacketsPerSec_ = avgBitsPerSec_ = numActiveStreams_ = 0;
|
||||
|
||||
qDebug("%s: avgPps = %g avgBps = %g", __FUNCTION__,
|
||||
avgPacketsPerSec_, avgBitsPerSec_);
|
||||
qDebug("%s: avgPps = %g avgBps = %g numActive = %d", __FUNCTION__,
|
||||
avgPacketsPerSec_, avgBitsPerSec_, numActiveStreams_);
|
||||
|
||||
emit portRateChanged(mPortGroupId, mPortId);
|
||||
|
||||
@ -106,76 +121,145 @@ void Port::recalculateAverageRates()
|
||||
|
||||
void Port::setAveragePacketRate(double packetsPerSec)
|
||||
{
|
||||
double rate;
|
||||
double pps = 0;
|
||||
double bps = 0;
|
||||
int n = 0;
|
||||
|
||||
qDebug("@%s: packetsPerSec = %g", __FUNCTION__, packetsPerSec);
|
||||
qDebug("@%s: avgPps = %g avgBps = %g numActive = %d", __FUNCTION__,
|
||||
avgPacketsPerSec_, avgBitsPerSec_, numActiveStreams_);
|
||||
foreach (Stream* s, mStreams)
|
||||
{
|
||||
if (!s->isEnabled())
|
||||
continue;
|
||||
|
||||
s->setAveragePacketRate(packetsPerSec);
|
||||
switch (transmitMode())
|
||||
{
|
||||
case OstProto::kSequentialTransmit:
|
||||
rate = s->averagePacketRate() * (packetsPerSec/avgPacketsPerSec_);
|
||||
break;
|
||||
case OstProto::kInterleavedTransmit:
|
||||
rate = s->averagePacketRate() +
|
||||
((s->averagePacketRate()/avgPacketsPerSec_) *
|
||||
(packetsPerSec - avgPacketsPerSec_));
|
||||
break;
|
||||
default:
|
||||
Q_ASSERT(false); // Unreachable!!
|
||||
}
|
||||
|
||||
qDebug("cur stream pps = %g", s->averagePacketRate());
|
||||
|
||||
s->setAveragePacketRate(rate);
|
||||
|
||||
qDebug("new stream pps = %g", s->averagePacketRate());
|
||||
|
||||
double r = s->averagePacketRate();
|
||||
pps += r;
|
||||
bps += r * s->frameLenAvg() * 8;
|
||||
bps += r * (s->frameLenAvg() + kEthOverhead) * 8;
|
||||
n++;
|
||||
|
||||
if (s->nextWhat() == Stream::e_nw_stop)
|
||||
if ((transmitMode() == OstProto::kSequentialTransmit)
|
||||
&& (s->nextWhat() == Stream::e_nw_stop))
|
||||
break;
|
||||
}
|
||||
|
||||
if (n)
|
||||
{
|
||||
switch (transmitMode())
|
||||
{
|
||||
case OstProto::kSequentialTransmit:
|
||||
avgPacketsPerSec_ = pps/n;
|
||||
avgBitsPerSec_ = bps/n;
|
||||
break;
|
||||
case OstProto::kInterleavedTransmit:
|
||||
avgPacketsPerSec_ = pps;
|
||||
avgBitsPerSec_ = bps;
|
||||
break;
|
||||
default:
|
||||
Q_ASSERT(false); // Unreachable!!
|
||||
}
|
||||
numActiveStreams_ = n;
|
||||
}
|
||||
else
|
||||
avgPacketsPerSec_ = avgBitsPerSec_ = 0;
|
||||
avgPacketsPerSec_ = avgBitsPerSec_ = numActiveStreams_ = 0;
|
||||
|
||||
qDebug("%s: avgPps = %g avgBps = %g", __FUNCTION__,
|
||||
avgPacketsPerSec_, avgBitsPerSec_);
|
||||
qDebug("%s: avgPps = %g avgBps = %g numActive = %d", __FUNCTION__,
|
||||
avgPacketsPerSec_, avgBitsPerSec_, numActiveStreams_);
|
||||
|
||||
emit portRateChanged(mPortGroupId, mPortId);
|
||||
|
||||
}
|
||||
|
||||
void Port::setAverageBitRate(double bitsPerSec)
|
||||
{
|
||||
double rate;
|
||||
double pps = 0;
|
||||
double bps = 0;
|
||||
int n = 0;
|
||||
|
||||
qDebug("@%s: bitsPerSec = %g", __FUNCTION__, bitsPerSec);
|
||||
qDebug("@%s: avgPps = %g avgBps = %g numActive = %d", __FUNCTION__,
|
||||
avgPacketsPerSec_, avgBitsPerSec_, numActiveStreams_);
|
||||
foreach (Stream* s, mStreams)
|
||||
{
|
||||
if (!s->isEnabled())
|
||||
continue;
|
||||
|
||||
s->setAveragePacketRate(bitsPerSec/s->frameLenAvg());
|
||||
switch (transmitMode())
|
||||
{
|
||||
case OstProto::kSequentialTransmit:
|
||||
rate = s->averagePacketRate() * (bitsPerSec/avgBitsPerSec_);
|
||||
qDebug("rate = %g", rate);
|
||||
break;
|
||||
case OstProto::kInterleavedTransmit:
|
||||
rate = s->averagePacketRate()
|
||||
+ ((s->averagePacketRate()/avgPacketsPerSec_)
|
||||
* ((bitsPerSec - avgBitsPerSec_)
|
||||
/ ((s->frameLenAvg()+kEthOverhead)*8)));
|
||||
break;
|
||||
default:
|
||||
Q_ASSERT(false); // Unreachable!!
|
||||
}
|
||||
|
||||
qDebug("cur stream pps = %g", s->averagePacketRate());
|
||||
|
||||
s->setAveragePacketRate(rate);
|
||||
|
||||
qDebug("new stream pps = %g", s->averagePacketRate());
|
||||
|
||||
double r = s->averagePacketRate();
|
||||
pps += r;
|
||||
bps += r * s->frameLenAvg() * 8;
|
||||
bps += r * (s->frameLenAvg() + kEthOverhead) * 8;
|
||||
n++;
|
||||
|
||||
if (s->nextWhat() == Stream::e_nw_stop)
|
||||
if ((transmitMode() == OstProto::kSequentialTransmit)
|
||||
&& (s->nextWhat() == Stream::e_nw_stop))
|
||||
break;
|
||||
}
|
||||
|
||||
if (n)
|
||||
{
|
||||
switch (transmitMode())
|
||||
{
|
||||
case OstProto::kSequentialTransmit:
|
||||
avgPacketsPerSec_ = pps/n;
|
||||
avgBitsPerSec_ = bps/n;
|
||||
break;
|
||||
case OstProto::kInterleavedTransmit:
|
||||
avgPacketsPerSec_ = pps;
|
||||
avgBitsPerSec_ = bps;
|
||||
break;
|
||||
default:
|
||||
Q_ASSERT(false); // Unreachable!!
|
||||
}
|
||||
numActiveStreams_ = n;
|
||||
}
|
||||
else
|
||||
avgPacketsPerSec_ = avgBitsPerSec_ = 0;
|
||||
|
||||
qDebug("%s: avgPps = %g avgBps = %g", __FUNCTION__,
|
||||
avgPacketsPerSec_, avgBitsPerSec_);
|
||||
avgPacketsPerSec_ = avgBitsPerSec_ = numActiveStreams_ = 0;
|
||||
|
||||
qDebug("%s: avgPps = %g avgBps = %g numActive = %d", __FUNCTION__,
|
||||
avgPacketsPerSec_, avgBitsPerSec_, numActiveStreams_);
|
||||
emit portRateChanged(mPortGroupId, mPortId);
|
||||
|
||||
}
|
||||
|
||||
bool Port::newStreamAt(int index, OstProto::Stream const *stream)
|
||||
|
@ -45,6 +45,7 @@ class Port : public QObject {
|
||||
|
||||
double avgPacketsPerSec_;
|
||||
double avgBitsPerSec_;
|
||||
int numActiveStreams_;
|
||||
|
||||
QList<quint32> mLastSyncStreamList;
|
||||
QList<Stream*> mStreams; // sorted by stream's ordinal value
|
||||
@ -76,6 +77,8 @@ public:
|
||||
{ return (d.is_enabled()?AdminEnable:AdminDisable); }
|
||||
bool hasExclusiveControl()
|
||||
{ return d.is_exclusive_control(); }
|
||||
OstProto::TransmitMode transmitMode()
|
||||
{ return d.transmit_mode(); }
|
||||
double averagePacketRate()
|
||||
{ return avgPacketsPerSec_; }
|
||||
double averageBitRate()
|
||||
|
57
client/portconfigdialog.cpp
Normal file
57
client/portconfigdialog.cpp
Normal file
@ -0,0 +1,57 @@
|
||||
/*
|
||||
Copyright (C) 2011 Srivats P.
|
||||
|
||||
This file is part of "Ostinato"
|
||||
|
||||
This is free software: you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation, either version 3 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
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, see <http://www.gnu.org/licenses/>
|
||||
*/
|
||||
|
||||
#include "portconfigdialog.h"
|
||||
|
||||
PortConfigDialog::PortConfigDialog(OstProto::Port &portConfig, QWidget *parent)
|
||||
: QDialog(parent), portConfig_(portConfig)
|
||||
{
|
||||
qDebug("In %s", __FUNCTION__);
|
||||
|
||||
setupUi(this);
|
||||
|
||||
switch(portConfig_.transmit_mode())
|
||||
{
|
||||
case OstProto::kSequentialTransmit:
|
||||
sequentialStreamsButton->setChecked(true);
|
||||
break;
|
||||
case OstProto::kInterleavedTransmit:
|
||||
interleavedStreamsButton->setChecked(true);
|
||||
break;
|
||||
default:
|
||||
Q_ASSERT(false); // Unreachable!!!
|
||||
break;
|
||||
}
|
||||
|
||||
exclusiveControlButton->setChecked(portConfig_.is_exclusive_control());
|
||||
}
|
||||
|
||||
void PortConfigDialog::accept()
|
||||
{
|
||||
if (sequentialStreamsButton->isChecked())
|
||||
portConfig_.set_transmit_mode(OstProto::kSequentialTransmit);
|
||||
else if (interleavedStreamsButton->isChecked())
|
||||
portConfig_.set_transmit_mode(OstProto::kInterleavedTransmit);
|
||||
else
|
||||
Q_ASSERT(false); // Unreachable!!!
|
||||
|
||||
portConfig_.set_is_exclusive_control(exclusiveControlButton->isChecked());
|
||||
|
||||
QDialog::accept();
|
||||
}
|
39
client/portconfigdialog.h
Normal file
39
client/portconfigdialog.h
Normal file
@ -0,0 +1,39 @@
|
||||
/*
|
||||
Copyright (C) 2011 Srivats P.
|
||||
|
||||
This file is part of "Ostinato"
|
||||
|
||||
This is free software: you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation, either version 3 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
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, see <http://www.gnu.org/licenses/>
|
||||
*/
|
||||
|
||||
#ifndef _PORT_CONFIG_DIALOG_H
|
||||
#define _PORT_CONFIG_DIALOG_H
|
||||
|
||||
#include "ui_portconfigdialog.h"
|
||||
#include "protocol.pb.h"
|
||||
#include <QDialog>
|
||||
|
||||
class PortConfigDialog : public QDialog, public Ui::PortConfigDialog
|
||||
{
|
||||
public:
|
||||
PortConfigDialog(OstProto::Port &portConfig, QWidget *parent);
|
||||
|
||||
private:
|
||||
virtual void accept();
|
||||
|
||||
OstProto::Port &portConfig_;
|
||||
};
|
||||
|
||||
#endif
|
||||
|
109
client/portconfigdialog.ui
Normal file
109
client/portconfigdialog.ui
Normal file
@ -0,0 +1,109 @@
|
||||
<ui version="4.0" >
|
||||
<class>PortConfigDialog</class>
|
||||
<widget class="QDialog" name="PortConfigDialog" >
|
||||
<property name="geometry" >
|
||||
<rect>
|
||||
<x>0</x>
|
||||
<y>0</y>
|
||||
<width>244</width>
|
||||
<height>160</height>
|
||||
</rect>
|
||||
</property>
|
||||
<property name="windowTitle" >
|
||||
<string>Port Config</string>
|
||||
</property>
|
||||
<layout class="QVBoxLayout" >
|
||||
<item>
|
||||
<widget class="QGroupBox" name="transmitModeBox" >
|
||||
<property name="title" >
|
||||
<string>Transmit Mode</string>
|
||||
</property>
|
||||
<layout class="QVBoxLayout" >
|
||||
<item>
|
||||
<widget class="QRadioButton" name="sequentialStreamsButton" >
|
||||
<property name="text" >
|
||||
<string>Sequential Streams</string>
|
||||
</property>
|
||||
<property name="checked" >
|
||||
<bool>true</bool>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<widget class="QRadioButton" name="interleavedStreamsButton" >
|
||||
<property name="text" >
|
||||
<string>Interleaved Streams</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
</layout>
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<widget class="QCheckBox" name="exclusiveControlButton" >
|
||||
<property name="text" >
|
||||
<string>Exclusive Control</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<spacer>
|
||||
<property name="orientation" >
|
||||
<enum>Qt::Vertical</enum>
|
||||
</property>
|
||||
<property name="sizeHint" >
|
||||
<size>
|
||||
<width>20</width>
|
||||
<height>40</height>
|
||||
</size>
|
||||
</property>
|
||||
</spacer>
|
||||
</item>
|
||||
<item>
|
||||
<widget class="QDialogButtonBox" name="buttonBox" >
|
||||
<property name="orientation" >
|
||||
<enum>Qt::Horizontal</enum>
|
||||
</property>
|
||||
<property name="standardButtons" >
|
||||
<set>QDialogButtonBox::Cancel|QDialogButtonBox::NoButton|QDialogButtonBox::Ok</set>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
</layout>
|
||||
</widget>
|
||||
<resources/>
|
||||
<connections>
|
||||
<connection>
|
||||
<sender>buttonBox</sender>
|
||||
<signal>accepted()</signal>
|
||||
<receiver>PortConfigDialog</receiver>
|
||||
<slot>accept()</slot>
|
||||
<hints>
|
||||
<hint type="sourcelabel" >
|
||||
<x>248</x>
|
||||
<y>254</y>
|
||||
</hint>
|
||||
<hint type="destinationlabel" >
|
||||
<x>157</x>
|
||||
<y>274</y>
|
||||
</hint>
|
||||
</hints>
|
||||
</connection>
|
||||
<connection>
|
||||
<sender>buttonBox</sender>
|
||||
<signal>rejected()</signal>
|
||||
<receiver>PortConfigDialog</receiver>
|
||||
<slot>reject()</slot>
|
||||
<hints>
|
||||
<hint type="sourcelabel" >
|
||||
<x>316</x>
|
||||
<y>260</y>
|
||||
</hint>
|
||||
<hint type="destinationlabel" >
|
||||
<x>286</x>
|
||||
<y>274</y>
|
||||
</hint>
|
||||
</hints>
|
||||
</connection>
|
||||
</connections>
|
||||
</ui>
|
@ -340,7 +340,7 @@ void PortGroup::processModifyStreamAck(int portIndex,
|
||||
delete controller;
|
||||
}
|
||||
|
||||
void PortGroup::modifyPort(int portIndex, bool isExclusive)
|
||||
void PortGroup::modifyPort(int portIndex, OstProto::Port portConfig)
|
||||
{
|
||||
OstProto::PortConfigList *portConfigList = new OstProto::PortConfigList;
|
||||
OstProto::Ack *ack = new OstProto::Ack;
|
||||
@ -353,8 +353,8 @@ void PortGroup::modifyPort(int portIndex, bool isExclusive)
|
||||
mainWindow->setDisabled(true);
|
||||
|
||||
OstProto::Port *port = portConfigList->add_port();
|
||||
port->CopyFrom(portConfig);
|
||||
port->mutable_port_id()->set_id(mPorts[portIndex]->id());
|
||||
port->set_is_exclusive_control(isExclusive);
|
||||
|
||||
PbRpcController *controller = new PbRpcController(portConfigList, ack);
|
||||
serviceStub->modifyPort(controller, portConfigList, ack,
|
||||
@ -412,9 +412,10 @@ void PortGroup::processUpdatedPortConfig(PbRpcController *controller)
|
||||
id = portConfigList->port(i).port_id().id();
|
||||
// FIXME: don't mix port id & index into mPorts[]
|
||||
mPorts[id]->updatePortConfig(portConfigList->mutable_port(i));
|
||||
|
||||
emit portGroupDataChanged(mPortGroupId, id);
|
||||
}
|
||||
|
||||
emit portGroupDataChanged(mPortGroupId);
|
||||
|
||||
_exit:
|
||||
mainWindow->setEnabled(true);
|
||||
|
@ -94,7 +94,7 @@ public:
|
||||
void processDeleteStreamAck(PbRpcController *controller);
|
||||
void processModifyStreamAck(int portIndex, PbRpcController *controller);
|
||||
|
||||
void modifyPort(int portId, bool isExclusive);
|
||||
void modifyPort(int portId, OstProto::Port portConfig);
|
||||
void processModifyPortAck(PbRpcController *controller);
|
||||
void processUpdatedPortConfig(PbRpcController *controller);
|
||||
|
||||
|
@ -296,6 +296,7 @@ void PortModel::when_portGroupDataChanged(int portGroupId, int portId)
|
||||
QModelIndex index;
|
||||
int row;
|
||||
|
||||
qDebug("portGroupId = %d, portId = %d", portGroupId, portId);
|
||||
if (portId == 0xFFFF)
|
||||
row = pgl->indexOfPortGroup(portGroupId);
|
||||
else
|
||||
|
@ -20,6 +20,7 @@ along with this program. If not, see <http://www.gnu.org/licenses/>
|
||||
#include "portswindow.h"
|
||||
|
||||
#include "abstractfileformat.h"
|
||||
#include "portconfigdialog.h"
|
||||
#include "streamconfigdialog.h"
|
||||
#include "streamlistdelegate.h"
|
||||
|
||||
@ -54,6 +55,7 @@ PortsWindow::PortsWindow(PortGroupList *pgl, QWidget *parent)
|
||||
tvPortList->addAction(actionDisconnect_Port_Group);
|
||||
|
||||
tvPortList->addAction(actionExclusive_Control);
|
||||
tvPortList->addAction(actionPort_Configuration);
|
||||
|
||||
// Populate StramList Context Menu Actions
|
||||
tvStreamList->addAction(actionNew_Stream);
|
||||
@ -156,6 +158,8 @@ void PortsWindow::when_portView_currentChanged(const QModelIndex& current,
|
||||
updatePortViewActions(current);
|
||||
updateStreamViewActions();
|
||||
|
||||
qDebug("In %s", __FUNCTION__);
|
||||
|
||||
if (previous.isValid() && plm->isPort(previous))
|
||||
{
|
||||
disconnect(&(plm->port(previous)), SIGNAL(portRateChanged(int, int)),
|
||||
@ -186,6 +190,7 @@ void PortsWindow::when_portView_currentChanged(const QModelIndex& current,
|
||||
void PortsWindow::when_portModel_dataChanged(const QModelIndex& topLeft,
|
||||
const QModelIndex& bottomRight)
|
||||
{
|
||||
qDebug("In %s", __FUNCTION__);
|
||||
#if 0 // not sure why the >= <= operators are not overloaded in QModelIndex
|
||||
if ((tvPortList->currentIndex() >= topLeft) &&
|
||||
(tvPortList->currentIndex() <= bottomRight))
|
||||
@ -195,7 +200,10 @@ void PortsWindow::when_portModel_dataChanged(const QModelIndex& topLeft,
|
||||
(((tvPortList->currentIndex() < bottomRight)) ||
|
||||
(tvPortList->currentIndex() == bottomRight)))
|
||||
{
|
||||
updatePortViewActions(tvPortList->currentIndex());
|
||||
// Update UI to reflect potential change in exclusive mode,
|
||||
// transmit mode et al
|
||||
when_portView_currentChanged(tvPortList->currentIndex(),
|
||||
tvPortList->currentIndex());
|
||||
}
|
||||
}
|
||||
|
||||
@ -223,7 +231,7 @@ void PortsWindow::on_averageBitsPerSec_editingFinished()
|
||||
Q_ASSERT(plm->isPort(current));
|
||||
|
||||
bool isOk;
|
||||
double bps = QLocale().toDouble(averageBitsPerSec->text(), &isOk)/8;
|
||||
double bps = QLocale().toDouble(averageBitsPerSec->text(), &isOk);
|
||||
|
||||
plm->port(current).setAverageBitRate(bps);
|
||||
}
|
||||
@ -300,6 +308,7 @@ void PortsWindow::updatePortViewActions(const QModelIndex& current)
|
||||
actionDisconnect_Port_Group->setDisabled(true);
|
||||
|
||||
actionExclusive_Control->setDisabled(true);
|
||||
actionPort_Configuration->setDisabled(true);
|
||||
|
||||
goto _EXIT;
|
||||
}
|
||||
@ -311,6 +320,7 @@ void PortsWindow::updatePortViewActions(const QModelIndex& current)
|
||||
actionDelete_Port_Group->setEnabled(true);
|
||||
|
||||
actionExclusive_Control->setDisabled(true);
|
||||
actionPort_Configuration->setDisabled(true);
|
||||
|
||||
switch(plm->portGroup(current).state())
|
||||
{
|
||||
@ -349,6 +359,7 @@ void PortsWindow::updatePortViewActions(const QModelIndex& current)
|
||||
actionExclusive_Control->setChecked(true);
|
||||
else
|
||||
actionExclusive_Control->setChecked(false);
|
||||
actionPort_Configuration->setEnabled(true);
|
||||
}
|
||||
|
||||
_EXIT:
|
||||
@ -458,7 +469,29 @@ void PortsWindow::on_actionExclusive_Control_triggered(bool checked)
|
||||
QModelIndex current = tvPortList->selectionModel()->currentIndex();
|
||||
|
||||
if (plm->isPort(current))
|
||||
plm->portGroup(current.parent()).modifyPort(current.row(), checked);
|
||||
{
|
||||
OstProto::Port config;
|
||||
|
||||
config.set_is_exclusive_control(checked);
|
||||
plm->portGroup(current.parent()).modifyPort(current.row(), config);
|
||||
}
|
||||
}
|
||||
|
||||
void PortsWindow::on_actionPort_Configuration_triggered()
|
||||
{
|
||||
QModelIndex current = tvPortList->selectionModel()->currentIndex();
|
||||
|
||||
if (!plm->isPort(current))
|
||||
return;
|
||||
|
||||
OstProto::Port config;
|
||||
config.set_transmit_mode(plm->port(current).transmitMode());
|
||||
config.set_is_exclusive_control(plm->port(current).hasExclusiveControl());
|
||||
|
||||
PortConfigDialog dialog(config, this);
|
||||
|
||||
if (dialog.exec() == QDialog::Accepted)
|
||||
plm->portGroup(current.parent()).modifyPort(current.row(), config);
|
||||
}
|
||||
|
||||
void PortsWindow::on_actionNew_Stream_triggered()
|
||||
|
@ -70,6 +70,7 @@ private slots:
|
||||
void on_actionDisconnect_Port_Group_triggered();
|
||||
|
||||
void on_actionExclusive_Control_triggered(bool checked);
|
||||
void on_actionPort_Configuration_triggered();
|
||||
|
||||
void on_actionNew_Stream_triggered();
|
||||
void on_actionEdit_Stream_triggered();
|
||||
|
@ -253,6 +253,11 @@
|
||||
<string>Save Streams ...</string>
|
||||
</property>
|
||||
</action>
|
||||
<action name="actionPort_Configuration" >
|
||||
<property name="text" >
|
||||
<string>Port Configuration ...</string>
|
||||
</property>
|
||||
</action>
|
||||
</widget>
|
||||
<resources>
|
||||
<include location="ostinato.qrc" />
|
||||
|
@ -165,8 +165,22 @@ StreamConfigDialog::StreamConfigDialog(Port &port, uint streamIndex,
|
||||
//! \todo Support Goto Stream Id
|
||||
leStreamId->setHidden(true);
|
||||
disconnect(rbActionGotoStream, SIGNAL(toggled(bool)), leStreamId, SLOT(setEnabled(bool)));
|
||||
//! \todo Support Continuous Mode
|
||||
|
||||
switch(mPort.transmitMode())
|
||||
{
|
||||
case OstProto::kSequentialTransmit:
|
||||
rbModeFixed->setChecked(true);
|
||||
rbModeContinuous->setDisabled(true);
|
||||
break;
|
||||
case OstProto::kInterleavedTransmit:
|
||||
rbModeContinuous->setChecked(true);
|
||||
rbModeFixed->setDisabled(true);
|
||||
|
||||
nextWhat->setHidden(true);
|
||||
break;
|
||||
default:
|
||||
Q_ASSERT(false); // Unreachable
|
||||
}
|
||||
|
||||
// Finally, restore the saved last geometry and selected tab for the
|
||||
// various tab widgets
|
||||
@ -1098,7 +1112,16 @@ void StreamConfigDialog::on_pbOk_clicked()
|
||||
// Store dialog contents into stream
|
||||
StoreCurrentStream();
|
||||
|
||||
if (!mpStream->preflightCheck(log))
|
||||
if ((mPort.transmitMode() == OstProto::kInterleavedTransmit)
|
||||
&& (mpStream->isFrameVariable()))
|
||||
{
|
||||
log += "In 'Interleaved Streams' transmit mode, the count for "
|
||||
"varying fields at transmit time may not be same as configured\n";
|
||||
}
|
||||
|
||||
mpStream->preflightCheck(log);
|
||||
|
||||
if (log.length())
|
||||
{
|
||||
if (QMessageBox::warning(this, "Preflight Check", log + "\nContinue?",
|
||||
QMessageBox::Yes | QMessageBox::No, QMessageBox::No)
|
||||
|
@ -42,7 +42,7 @@ QLineEdit:enabled[inputMask = "HH HH HH HH HH HH; "] { background-color: #ccccff
|
||||
<string/>
|
||||
</property>
|
||||
<property name="currentIndex" >
|
||||
<number>2</number>
|
||||
<number>0</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>586</width>
|
||||
<height>248</height>
|
||||
<width>592</width>
|
||||
<height>269</height>
|
||||
</rect>
|
||||
</property>
|
||||
<attribute name="label" >
|
||||
@ -940,7 +940,7 @@ QLineEdit:enabled[inputMask = "HH HH HH HH HH HH; "] { background-color: #ccccff
|
||||
</widget>
|
||||
</item>
|
||||
<item rowspan="2" row="0" column="3" >
|
||||
<widget class="QGroupBox" name="groupBox_11" >
|
||||
<widget class="QGroupBox" name="nextWhat" >
|
||||
<property name="title" >
|
||||
<string>After this stream</string>
|
||||
</property>
|
||||
@ -982,6 +982,19 @@ QLineEdit:enabled[inputMask = "HH HH HH HH HH HH; "] { background-color: #ccccff
|
||||
</layout>
|
||||
</widget>
|
||||
</item>
|
||||
<item rowspan="2" row="0" column="4" >
|
||||
<spacer>
|
||||
<property name="orientation" >
|
||||
<enum>Qt::Horizontal</enum>
|
||||
</property>
|
||||
<property name="sizeHint" >
|
||||
<size>
|
||||
<width>20</width>
|
||||
<height>41</height>
|
||||
</size>
|
||||
</property>
|
||||
</spacer>
|
||||
</item>
|
||||
<item row="1" column="0" >
|
||||
<widget class="QGroupBox" name="groupBox_5" >
|
||||
<property name="title" >
|
||||
@ -1008,14 +1021,7 @@ QLineEdit:enabled[inputMask = "HH HH HH HH HH HH; "] { background-color: #ccccff
|
||||
</layout>
|
||||
</widget>
|
||||
</item>
|
||||
<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="4" >
|
||||
<item row="3" column="0" colspan="5" >
|
||||
<widget class="QGroupBox" name="groupBox_12" >
|
||||
<property name="enabled" >
|
||||
<bool>true</bool>
|
||||
@ -1283,12 +1289,12 @@ QLineEdit:enabled[inputMask = "HH HH HH HH HH HH; "] { background-color: #ccccff
|
||||
<slot>setEnabled(bool)</slot>
|
||||
<hints>
|
||||
<hint type="sourcelabel" >
|
||||
<x>293</x>
|
||||
<y>137</y>
|
||||
<x>463</x>
|
||||
<y>143</y>
|
||||
</hint>
|
||||
<hint type="destinationlabel" >
|
||||
<x>293</x>
|
||||
<y>169</y>
|
||||
<x>463</x>
|
||||
<y>177</y>
|
||||
</hint>
|
||||
</hints>
|
||||
</connection>
|
||||
@ -1300,11 +1306,11 @@ QLineEdit:enabled[inputMask = "HH HH HH HH HH HH; "] { background-color: #ccccff
|
||||
<hints>
|
||||
<hint type="sourcelabel" >
|
||||
<x>30</x>
|
||||
<y>66</y>
|
||||
<y>68</y>
|
||||
</hint>
|
||||
<hint type="destinationlabel" >
|
||||
<x>71</x>
|
||||
<y>250</y>
|
||||
<x>299</x>
|
||||
<y>82</y>
|
||||
</hint>
|
||||
</hints>
|
||||
</connection>
|
||||
@ -1316,11 +1322,11 @@ QLineEdit:enabled[inputMask = "HH HH HH HH HH HH; "] { background-color: #ccccff
|
||||
<hints>
|
||||
<hint type="sourcelabel" >
|
||||
<x>30</x>
|
||||
<y>91</y>
|
||||
<y>95</y>
|
||||
</hint>
|
||||
<hint type="destinationlabel" >
|
||||
<x>71</x>
|
||||
<y>310</y>
|
||||
<x>299</x>
|
||||
<y>132</y>
|
||||
</hint>
|
||||
</hints>
|
||||
</connection>
|
||||
@ -1332,11 +1338,11 @@ QLineEdit:enabled[inputMask = "HH HH HH HH HH HH; "] { background-color: #ccccff
|
||||
<hints>
|
||||
<hint type="sourcelabel" >
|
||||
<x>30</x>
|
||||
<y>91</y>
|
||||
<y>95</y>
|
||||
</hint>
|
||||
<hint type="destinationlabel" >
|
||||
<x>134</x>
|
||||
<y>177</y>
|
||||
<y>189</y>
|
||||
</hint>
|
||||
</hints>
|
||||
</connection>
|
||||
@ -1347,12 +1353,12 @@ QLineEdit:enabled[inputMask = "HH HH HH HH HH HH; "] { background-color: #ccccff
|
||||
<slot>setEnabled(bool)</slot>
|
||||
<hints>
|
||||
<hint type="sourcelabel" >
|
||||
<x>48</x>
|
||||
<y>252</y>
|
||||
<x>299</x>
|
||||
<y>82</y>
|
||||
</hint>
|
||||
<hint type="destinationlabel" >
|
||||
<x>39</x>
|
||||
<y>278</y>
|
||||
<x>299</x>
|
||||
<y>108</y>
|
||||
</hint>
|
||||
</hints>
|
||||
</connection>
|
||||
@ -1363,12 +1369,12 @@ QLineEdit:enabled[inputMask = "HH HH HH HH HH HH; "] { background-color: #ccccff
|
||||
<slot>setEnabled(bool)</slot>
|
||||
<hints>
|
||||
<hint type="sourcelabel" >
|
||||
<x>51</x>
|
||||
<y>303</y>
|
||||
<x>299</x>
|
||||
<y>132</y>
|
||||
</hint>
|
||||
<hint type="destinationlabel" >
|
||||
<x>54</x>
|
||||
<y>339</y>
|
||||
<x>299</x>
|
||||
<y>158</y>
|
||||
</hint>
|
||||
</hints>
|
||||
</connection>
|
||||
@ -1379,12 +1385,12 @@ QLineEdit:enabled[inputMask = "HH HH HH HH HH HH; "] { background-color: #ccccff
|
||||
<slot>setEnabled(bool)</slot>
|
||||
<hints>
|
||||
<hint type="sourcelabel" >
|
||||
<x>82</x>
|
||||
<y>356</y>
|
||||
<x>299</x>
|
||||
<y>182</y>
|
||||
</hint>
|
||||
<hint type="destinationlabel" >
|
||||
<x>103</x>
|
||||
<y>372</y>
|
||||
<x>299</x>
|
||||
<y>208</y>
|
||||
</hint>
|
||||
</hints>
|
||||
</connection>
|
||||
@ -1399,8 +1405,8 @@ QLineEdit:enabled[inputMask = "HH HH HH HH HH HH; "] { background-color: #ccccff
|
||||
<y>70</y>
|
||||
</hint>
|
||||
<hint type="destinationlabel" >
|
||||
<x>154</x>
|
||||
<y>255</y>
|
||||
<x>299</x>
|
||||
<y>82</y>
|
||||
</hint>
|
||||
</hints>
|
||||
</connection>
|
||||
@ -1415,8 +1421,40 @@ QLineEdit:enabled[inputMask = "HH HH HH HH HH HH; "] { background-color: #ccccff
|
||||
<y>98</y>
|
||||
</hint>
|
||||
<hint type="destinationlabel" >
|
||||
<x>173</x>
|
||||
<y>299</y>
|
||||
<x>299</x>
|
||||
<y>132</y>
|
||||
</hint>
|
||||
</hints>
|
||||
</connection>
|
||||
<connection>
|
||||
<sender>rbModeContinuous</sender>
|
||||
<signal>toggled(bool)</signal>
|
||||
<receiver>leNumPackets</receiver>
|
||||
<slot>setDisabled(bool)</slot>
|
||||
<hints>
|
||||
<hint type="sourcelabel" >
|
||||
<x>73</x>
|
||||
<y>196</y>
|
||||
</hint>
|
||||
<hint type="destinationlabel" >
|
||||
<x>164</x>
|
||||
<y>108</y>
|
||||
</hint>
|
||||
</hints>
|
||||
</connection>
|
||||
<connection>
|
||||
<sender>rbModeContinuous</sender>
|
||||
<signal>toggled(bool)</signal>
|
||||
<receiver>leNumBursts</receiver>
|
||||
<slot>setDisabled(bool)</slot>
|
||||
<hints>
|
||||
<hint type="sourcelabel" >
|
||||
<x>96</x>
|
||||
<y>199</y>
|
||||
</hint>
|
||||
<hint type="destinationlabel" >
|
||||
<x>226</x>
|
||||
<y>155</y>
|
||||
</hint>
|
||||
</hints>
|
||||
</connection>
|
||||
|
@ -42,7 +42,12 @@ int StreamModel::rowCount(const QModelIndex &parent) const
|
||||
|
||||
int StreamModel::columnCount(const QModelIndex &/*parent*/) const
|
||||
{
|
||||
return (int) StreamMaxFields;
|
||||
int count = StreamMaxFields;
|
||||
if (mCurrentPort &&
|
||||
(mCurrentPort->transmitMode() == OstProto::kInterleavedTransmit))
|
||||
count--;
|
||||
|
||||
return count;
|
||||
}
|
||||
|
||||
Qt::ItemFlags StreamModel::flags(const QModelIndex &index) const
|
||||
|
@ -58,8 +58,8 @@ class StreamModel : public QAbstractTableModel
|
||||
public:
|
||||
enum StreamFields {
|
||||
StreamIcon = 0,
|
||||
StreamName,
|
||||
StreamStatus,
|
||||
StreamName,
|
||||
StreamNextWhat,
|
||||
|
||||
StreamMaxFields
|
||||
|
@ -151,6 +151,11 @@ message StreamIdList {
|
||||
repeated StreamId stream_id = 2;
|
||||
}
|
||||
|
||||
enum TransmitMode {
|
||||
kSequentialTransmit = 0;
|
||||
kInterleavedTransmit = 1;
|
||||
}
|
||||
|
||||
message Port {
|
||||
required PortId port_id = 1;
|
||||
optional string name = 2;
|
||||
@ -158,6 +163,7 @@ message Port {
|
||||
optional string notes = 4;
|
||||
optional bool is_enabled = 5;
|
||||
optional bool is_exclusive_control = 6;
|
||||
optional TransmitMode transmit_mode = 7 [default = kSequentialTransmit];
|
||||
}
|
||||
|
||||
message PortConfigList {
|
||||
|
@ -17,12 +17,16 @@ You should have received a copy of the GNU General Public License
|
||||
along with this program. If not, see <http://www.gnu.org/licenses/>
|
||||
*/
|
||||
|
||||
#define __STDC_FORMAT_MACROS
|
||||
|
||||
#include "abstractport.h"
|
||||
|
||||
#include <QString>
|
||||
#include <QIODevice>
|
||||
|
||||
#include "../common/streambase.h"
|
||||
#include <inttypes.h>
|
||||
#include <limits.h>
|
||||
#include <math.h>
|
||||
|
||||
AbstractPort::AbstractPort(int id, const char *device)
|
||||
@ -65,6 +69,9 @@ bool AbstractPort::modify(const OstProto::Port &port)
|
||||
data_.set_is_exclusive_control(val);
|
||||
}
|
||||
|
||||
if (port.has_transmit_mode())
|
||||
data_.set_transmit_mode(port.transmit_mode());
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
@ -112,6 +119,22 @@ bool AbstractPort::deleteStream(int streamId)
|
||||
}
|
||||
|
||||
void AbstractPort::updatePacketList()
|
||||
{
|
||||
switch(data_.transmit_mode())
|
||||
{
|
||||
case OstProto::kSequentialTransmit:
|
||||
updatePacketListSequential();
|
||||
break;
|
||||
case OstProto::kInterleavedTransmit:
|
||||
updatePacketListInterleaved();
|
||||
break;
|
||||
default:
|
||||
Q_ASSERT(false); // Unreachable!!!
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
void AbstractPort::updatePacketListSequential()
|
||||
{
|
||||
int len;
|
||||
bool isVariable;
|
||||
@ -237,7 +260,8 @@ void AbstractPort::updatePacketList()
|
||||
returnToQIdx = 0;
|
||||
*/
|
||||
|
||||
setPacketListLoopMode(true, streamList_[i]->sendUnit() ==
|
||||
setPacketListLoopMode(true, 0,
|
||||
streamList_[i]->sendUnit() ==
|
||||
StreamBase::e_su_bursts ? ibg1 : ipg1);
|
||||
goto _stop_no_more_pkts;
|
||||
|
||||
@ -257,6 +281,225 @@ _stop_no_more_pkts:
|
||||
isSendQueueDirty_ = false;
|
||||
}
|
||||
|
||||
void AbstractPort::updatePacketListInterleaved()
|
||||
{
|
||||
int numStreams = 0;
|
||||
quint64 minGap = ULONG_LONG_MAX;
|
||||
quint64 duration = quint64(1e9);
|
||||
QList<quint64> ibg1, ibg2;
|
||||
QList<quint64> nb1, nb2;
|
||||
QList<quint64> ipg1, ipg2;
|
||||
QList<quint64> np1, np2;
|
||||
QList<ulong> schedSec, schedNsec;
|
||||
QList<ulong> pktCount, burstCount;
|
||||
QList<ulong> burstSize;
|
||||
QList<bool> isVariable;
|
||||
QList<QByteArray> pktBuf;
|
||||
QList<ulong> pktLen;
|
||||
|
||||
qDebug("In %s", __FUNCTION__);
|
||||
|
||||
// First sort the streams by ordinalValue
|
||||
qSort(streamList_.begin(), streamList_.end(), StreamBase::StreamLessThan);
|
||||
|
||||
clearPacketList();
|
||||
|
||||
for (int i = 0; i < streamList_.size(); i++)
|
||||
{
|
||||
if (!streamList_[i]->isEnabled())
|
||||
continue;
|
||||
|
||||
double numBursts = 0;
|
||||
double numPackets = 0;
|
||||
|
||||
quint64 _burstSize;
|
||||
double ibg = 0;
|
||||
quint64 _ibg1 = 0, _ibg2 = 0;
|
||||
quint64 _nb1 = 0, _nb2 = 0;
|
||||
double ipg = 0;
|
||||
quint64 _ipg1 = 0, _ipg2 = 0;
|
||||
quint64 _np1 = 0, _np2 = 0;
|
||||
|
||||
switch (streamList_[i]->sendUnit())
|
||||
{
|
||||
case OstProto::StreamControl::e_su_bursts:
|
||||
numBursts = streamList_[i]->burstRate();
|
||||
if (streamList_[i]->burstRate() > 0)
|
||||
{
|
||||
ibg = 1e9/double(streamList_[i]->burstRate());
|
||||
_ibg1 = quint64(ceil(ibg));
|
||||
_ibg2 = quint64(floor(ibg));
|
||||
_nb1 = quint64((ibg - double(_ibg2)) * double(numBursts));
|
||||
_nb2 = quint64(numBursts) - _nb1;
|
||||
_burstSize = streamList_[i]->burstSize();
|
||||
}
|
||||
break;
|
||||
case OstProto::StreamControl::e_su_packets:
|
||||
numPackets = streamList_[i]->packetRate();
|
||||
if (streamList_[i]->packetRate() > 0)
|
||||
{
|
||||
ipg = 1e9/double(streamList_[i]->packetRate());
|
||||
_ipg1 = llrint(ceil(ipg));
|
||||
_ipg2 = quint64(floor(ipg));
|
||||
_np1 = quint64((ipg - double(_ipg2)) * double(numPackets));
|
||||
_np2 = quint64(numPackets) - _np1;
|
||||
_burstSize = 1;
|
||||
}
|
||||
break;
|
||||
default:
|
||||
qWarning("Unhandled stream control unit %d",
|
||||
streamList_[i]->sendUnit());
|
||||
continue;
|
||||
}
|
||||
qDebug("numBursts = %g, numPackets = %g\n", numBursts, numPackets);
|
||||
|
||||
qDebug("ibg = %g", ibg);
|
||||
qDebug("ibg1 = %" PRIu64, _ibg1);
|
||||
qDebug("nb1 = %" PRIu64, _nb1);
|
||||
qDebug("ibg2 = %" PRIu64, _ibg2);
|
||||
qDebug("nb2 = %" PRIu64 "\n", _nb2);
|
||||
|
||||
qDebug("ipg = %g", ipg);
|
||||
qDebug("ipg1 = %" PRIu64, _ipg1);
|
||||
qDebug("np1 = %" PRIu64, _np1);
|
||||
qDebug("ipg2 = %" PRIu64, _ipg2);
|
||||
qDebug("np2 = %" PRIu64 "\n", _np2);
|
||||
|
||||
|
||||
if (_ibg2 && (_ibg2 < minGap))
|
||||
minGap = _ibg2;
|
||||
|
||||
if (_ibg1 && (_ibg1 > duration))
|
||||
duration = _ibg1;
|
||||
|
||||
ibg1.append(_ibg1);
|
||||
ibg2.append(_ibg2);
|
||||
|
||||
nb1.append(_nb1);
|
||||
nb2.append(_nb1);
|
||||
|
||||
burstSize.append(_burstSize);
|
||||
|
||||
if (_ipg2 && (_ipg2 < minGap))
|
||||
minGap = _ipg2;
|
||||
|
||||
if (_np1)
|
||||
{
|
||||
if (_ipg1 && (_ipg1 > duration))
|
||||
duration = _ipg1;
|
||||
}
|
||||
else
|
||||
{
|
||||
if (_ipg2 && (_ipg2 > duration))
|
||||
duration = _ipg2;
|
||||
}
|
||||
|
||||
ipg1.append(_ipg1);
|
||||
ipg2.append(_ipg2);
|
||||
|
||||
np1.append(_np1);
|
||||
np2.append(_np1);
|
||||
|
||||
schedSec.append(0);
|
||||
schedNsec.append(0);
|
||||
|
||||
pktCount.append(0);
|
||||
burstCount.append(0);
|
||||
|
||||
if (streamList_[i]->isFrameVariable())
|
||||
{
|
||||
isVariable.append(true);
|
||||
pktBuf.append(QByteArray());
|
||||
pktLen.append(0);
|
||||
}
|
||||
else
|
||||
{
|
||||
isVariable.append(false);
|
||||
pktBuf.append(QByteArray());
|
||||
pktBuf.last().resize(kMaxPktSize);
|
||||
pktLen.append(streamList_[i]->frameValue(
|
||||
(uchar*)pktBuf.last().data(), pktBuf.last().size(), 0));
|
||||
}
|
||||
|
||||
numStreams++;
|
||||
} // for i
|
||||
|
||||
qDebug("minGap = %" PRIu64, minGap);
|
||||
qDebug("duration = %" PRIu64, duration);
|
||||
|
||||
uchar* buf;
|
||||
int len;
|
||||
quint64 durSec = duration/ulong(1e9);
|
||||
quint64 durNsec = duration % ulong(1e9);
|
||||
quint64 sec = 0;
|
||||
quint64 nsec = 0;
|
||||
quint64 lastPktTxSec = 0;
|
||||
quint64 lastPktTxNsec = 0;
|
||||
do
|
||||
{
|
||||
for (int i = 0; i < numStreams; i++)
|
||||
{
|
||||
// If a packet is not scheduled yet, look at the next stream
|
||||
if ((schedSec.at(i) > sec) || (schedNsec.at(i) > nsec))
|
||||
continue;
|
||||
|
||||
for (uint j = 0; j < burstSize[i]; j++)
|
||||
{
|
||||
if (isVariable.at(i))
|
||||
{
|
||||
buf = pktBuf_;
|
||||
len = streamList_[i]->frameValue(pktBuf_, sizeof(pktBuf_),
|
||||
pktCount[i]);
|
||||
}
|
||||
else
|
||||
{
|
||||
buf = (uchar*) pktBuf.at(i).data();
|
||||
len = pktLen.at(i);
|
||||
}
|
||||
|
||||
if (len <= 0)
|
||||
continue;
|
||||
|
||||
qDebug("q(%d) sec = %" PRIu64 " nsec = %" PRIu64, i, sec, nsec);
|
||||
appendToPacketList(sec, nsec, buf, len);
|
||||
lastPktTxSec = sec;
|
||||
lastPktTxNsec = nsec;
|
||||
|
||||
pktCount[i]++;
|
||||
schedNsec[i] += (pktCount.at(i) < np1.at(i)) ?
|
||||
ipg1.at(i) : ipg2.at(i);
|
||||
while (schedNsec.at(i) >= 1e9)
|
||||
{
|
||||
schedSec[i]++;
|
||||
schedNsec[i] -= long(1e9);
|
||||
}
|
||||
}
|
||||
|
||||
burstCount[i]++;
|
||||
schedNsec[i] += (burstCount.at(i) < nb1.at(i)) ?
|
||||
ibg1.at(i) : ibg2.at(i);
|
||||
while (schedNsec.at(i) >= 1e9)
|
||||
{
|
||||
schedSec[i]++;
|
||||
schedNsec[i] -= long(1e9);
|
||||
}
|
||||
}
|
||||
|
||||
nsec += minGap;
|
||||
while (nsec >= 1e9)
|
||||
{
|
||||
sec++;
|
||||
nsec -= long(1e9);
|
||||
}
|
||||
} while ((sec < durSec) || (nsec < durNsec));
|
||||
|
||||
quint64 delaySec = durSec - lastPktTxSec;
|
||||
quint64 delayNsec = durNsec - lastPktTxNsec;
|
||||
qDebug("loop Delay = %" PRIu64 "/%" PRIu64, delaySec, delayNsec);
|
||||
setPacketListLoopMode(true, durSec - lastPktTxSec, durNsec - lastPktTxNsec);
|
||||
isSendQueueDirty_ = false;
|
||||
}
|
||||
|
||||
void AbstractPort::stats(PortStats *stats)
|
||||
{
|
||||
stats->rxPkts = stats_.rxPkts - epochStats_.rxPkts;
|
||||
|
@ -73,7 +73,8 @@ public:
|
||||
virtual void clearPacketList() = 0;
|
||||
virtual bool appendToPacketList(long sec, long nsec, const uchar *packet,
|
||||
int length) = 0;
|
||||
virtual void setPacketListLoopMode(bool loop, long nsecDelay) = 0;
|
||||
virtual void setPacketListLoopMode(bool loop,
|
||||
long secDelay, long nsecDelay) = 0;
|
||||
void updatePacketList();
|
||||
|
||||
virtual void startTransmit() = 0;
|
||||
@ -89,6 +90,9 @@ public:
|
||||
void resetStats() { epochStats_ = stats_; }
|
||||
|
||||
protected:
|
||||
void updatePacketListSequential();
|
||||
void updatePacketListInterleaved();
|
||||
|
||||
bool isUsable_;
|
||||
OstProto::Port data_;
|
||||
OstProto::LinkState linkState_;
|
||||
|
@ -24,6 +24,7 @@ win32 {
|
||||
LIBS += -L"../rpc" -lpbrpc
|
||||
POST_TARGETDEPS += "../common/libostproto.a" "../rpc/libpbrpc.a"
|
||||
}
|
||||
LIBS += -lm
|
||||
LIBS += -lprotobuf
|
||||
LIBS += -L"../extra/qhexedit2/$(OBJECTS_DIR)/" -lqhexedit2
|
||||
RESOURCES += drone.qrc
|
||||
|
@ -295,7 +295,7 @@ void PcapPort::PortTransmitter::clearPacketList()
|
||||
pcap_send_queue *sq = sendQueueList_.takeFirst();
|
||||
pcap_sendqueue_destroy(sq);
|
||||
}
|
||||
setPacketListLoopMode(false, 0);
|
||||
setPacketListLoopMode(false, 0, 0);
|
||||
}
|
||||
|
||||
bool PcapPort::PortTransmitter::appendToPacketList(long sec, long nsec,
|
||||
|
@ -40,14 +40,15 @@ public:
|
||||
|
||||
virtual void clearPacketList() {
|
||||
transmitter_->clearPacketList();
|
||||
setPacketListLoopMode(false, 0);
|
||||
setPacketListLoopMode(false, 0, 0);
|
||||
}
|
||||
virtual bool appendToPacketList(long sec, long nsec, const uchar *packet,
|
||||
int length) {
|
||||
return transmitter_->appendToPacketList(sec, nsec, packet, length);
|
||||
}
|
||||
virtual void setPacketListLoopMode(bool loop, long nsecDelay) {
|
||||
transmitter_->setPacketListLoopMode(loop, nsecDelay);
|
||||
virtual void setPacketListLoopMode(bool loop, long secDelay, long nsecDelay)
|
||||
{
|
||||
transmitter_->setPacketListLoopMode(loop, secDelay, nsecDelay);
|
||||
}
|
||||
|
||||
virtual void startTransmit() {
|
||||
@ -97,9 +98,9 @@ protected:
|
||||
void clearPacketList();
|
||||
bool appendToPacketList(long sec, long usec, const uchar *packet,
|
||||
int length);
|
||||
void setPacketListLoopMode(bool loop, long nsecDelay) {
|
||||
void setPacketListLoopMode(bool loop, long secDelay, long nsecDelay) {
|
||||
returnToQIdx_ = loop ? 0 : -1;
|
||||
loopDelay_ = nsecDelay/1000;
|
||||
loopDelay_ = secDelay*long(1e6) + nsecDelay/1000;
|
||||
}
|
||||
void setHandle(pcap_t *handle);
|
||||
void useExternalStats(AbstractPort::PortStats *stats);
|
||||
|
Loading…
Reference in New Issue
Block a user