d5365a25d4
Use Simple IMIX as defined in Wikipedia - Frame lengths 64, 594, 1518 in a 7:4:1 ratio
1334 lines
40 KiB
C++
1334 lines
40 KiB
C++
/*
|
|
Copyright (C) 2010-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 <QHostAddress>
|
|
|
|
#include "streamconfigdialog.h"
|
|
#include "stream.h"
|
|
#include "abstractprotocol.h"
|
|
#include "abstractprotocolconfig.h"
|
|
#include "protocollistiterator.h"
|
|
|
|
#include "modeltest.h"
|
|
|
|
#include "../common/protocolmanager.h"
|
|
#include "../common/protocolwidgetfactory.h"
|
|
|
|
#include "xqlocale.h"
|
|
|
|
#include <QButtonGroup>
|
|
#include <QMessageBox>
|
|
|
|
extern ProtocolManager *OstProtocolManager;
|
|
extern ProtocolWidgetFactory *OstProtocolWidgetFactory;
|
|
|
|
QRect StreamConfigDialog::lastGeometry;
|
|
int StreamConfigDialog::lastTopLevelTabIndex = 0;
|
|
int StreamConfigDialog::lastProtocolDataIndex = 0;
|
|
|
|
static const uint kEthFrameOverHead = 20;
|
|
|
|
StreamConfigDialog::StreamConfigDialog(
|
|
QList<Stream*> &streamList,
|
|
const Port &port,
|
|
QWidget *parent)
|
|
: QDialog (parent), _userStreamList(streamList), mPort(port)
|
|
{
|
|
mCurrentStreamIndex = 0;
|
|
|
|
Q_ASSERT(_userStreamList.size() > 0);
|
|
|
|
// Create a copy of the user provided stream list
|
|
// We need a copy because user may edit multiple streams and then
|
|
// discard the edit - in this case the user provided stream list
|
|
// should not be modified on return
|
|
foreach(Stream* stm, _userStreamList) {
|
|
OstProto::Stream s;
|
|
stm->protoDataCopyInto(s);
|
|
_streamList.append(new Stream());
|
|
_streamList.last()->protoDataCopyFrom(s);
|
|
}
|
|
|
|
mpStream = _streamList.at(mCurrentStreamIndex);
|
|
_iter = mpStream->createProtocolListIterator();
|
|
isUpdateInProgress = false;
|
|
|
|
setupUi(this);
|
|
setupUiExtra();
|
|
|
|
_windowTitle = windowTitle();
|
|
|
|
for (int i = ProtoMin; i < ProtoMax; i++)
|
|
{
|
|
bgProto[i]->setProperty("ProtocolLevel", i);
|
|
bgProto[i]->setProperty("ProtocolId", ButtonIdNone);
|
|
connect(bgProto[i], SIGNAL(buttonClicked(int)),
|
|
this, SLOT(updateProtocol(int)));
|
|
}
|
|
|
|
//! \todo causes a crash!
|
|
#if 0
|
|
connect(lePktLen, SIGNAL(textEdited(QString)),
|
|
this, SLOT(updateContents()));
|
|
#endif
|
|
|
|
// Time to play match the signals and slots!
|
|
|
|
// If L1/L2(FT)/L3/L4 = None,
|
|
// force subsequent protocol level(s) also to None
|
|
connect(rbL1None, SIGNAL(toggled(bool)), SLOT(forceProtocolNone(bool)));
|
|
connect(rbFtNone, SIGNAL(toggled(bool)), SLOT(forceProtocolNone(bool)));
|
|
connect(rbL3None, SIGNAL(toggled(bool)), SLOT(forceProtocolNone(bool)));
|
|
connect(rbL4None, SIGNAL(toggled(bool)), SLOT(forceProtocolNone(bool)));
|
|
|
|
// If L1/L2(FT)/L3/L4/L5 = Other, force subsequent protocol to Other and
|
|
// disable the subsequent protocol group as well
|
|
connect(rbL1Other, SIGNAL(toggled(bool)), rbFtOther, SLOT(setChecked(bool)));
|
|
connect(rbL1Other, SIGNAL(toggled(bool)), gbFrameType, SLOT(setDisabled(bool)));
|
|
connect(rbFtOther, SIGNAL(toggled(bool)), rbL3Other, SLOT(setChecked(bool)));
|
|
connect(rbFtOther, SIGNAL(toggled(bool)), gbL3Proto, SLOT(setDisabled(bool)));
|
|
connect(rbL3Other, SIGNAL(toggled(bool)), rbL4Other, SLOT(setChecked(bool)));
|
|
connect(rbL3Other, SIGNAL(toggled(bool)), gbL4Proto, SLOT(setDisabled(bool)));
|
|
connect(rbL4Other, SIGNAL(toggled(bool)), rbL5Other, SLOT(setChecked(bool)));
|
|
connect(rbL4Other, SIGNAL(toggled(bool)), gbL5Proto, SLOT(setDisabled(bool)));
|
|
connect(rbL5Other, SIGNAL(toggled(bool)), rbPayloadOther, SLOT(setChecked(bool)));
|
|
connect(rbL5Other, SIGNAL(toggled(bool)), gbPayloadProto, SLOT(setDisabled(bool)));
|
|
|
|
// Setup valid subsequent protocols for L2 to L4 protocols
|
|
for (int i = ProtoL2; i <= ProtoL4; i++)
|
|
{
|
|
foreach(QAbstractButton *btn1, bgProto[i]->buttons())
|
|
{
|
|
int id1 = bgProto[i]->id(btn1);
|
|
|
|
if (id1 != ButtonIdNone && id1 != ButtonIdOther)
|
|
{
|
|
int validProtocolCount = 0;
|
|
|
|
foreach(QAbstractButton *btn2, bgProto[i+1]->buttons())
|
|
{
|
|
int id2 = bgProto[i+1]->id(btn2);
|
|
|
|
if (id2 != ButtonIdNone && id2 != ButtonIdOther)
|
|
{
|
|
if (OstProtocolManager->isValidNeighbour(id1, id2))
|
|
{
|
|
connect(btn1, SIGNAL(toggled(bool)),
|
|
btn2, SLOT(setEnabled(bool)));
|
|
validProtocolCount++;
|
|
}
|
|
else
|
|
connect(btn1, SIGNAL(toggled(bool)),
|
|
btn2, SLOT(setDisabled(bool)));
|
|
}
|
|
}
|
|
|
|
// If btn1 has no subsequent valid protocols,
|
|
// force subsequent Protocol to 'None'
|
|
if (validProtocolCount == 0)
|
|
connect(btn1, SIGNAL(clicked(bool)),
|
|
bgProto[i+1]->button(ButtonIdNone), SLOT(click()));
|
|
|
|
// If the id1 protocol doesn't have a payload (e.g. IGMP)
|
|
// force payload protocol to 'None'
|
|
if (!OstProtocolManager->protocolHasPayload(id1))
|
|
{
|
|
connect(btn1, SIGNAL(clicked(bool)),
|
|
bgProto[ProtoPayload]->button(ButtonIdNone),
|
|
SLOT(click()));
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
mpAvailableProtocolsModel = new QStringListModel(
|
|
OstProtocolManager->protocolDatabase(), this);
|
|
lvAllProtocols->setModel(mpAvailableProtocolsModel);
|
|
lvAllProtocols->setEditTriggers(QAbstractItemView::NoEditTriggers);
|
|
mpSelectedProtocolsModel = new QStringListModel(this);
|
|
lvSelectedProtocols->setModel(mpSelectedProtocolsModel);
|
|
lvSelectedProtocols->setEditTriggers(QAbstractItemView::NoEditTriggers);
|
|
|
|
|
|
connect(lvAllProtocols->selectionModel(),
|
|
SIGNAL(selectionChanged(const QItemSelection&, const QItemSelection&)),
|
|
this, SLOT(when_lvAllProtocols_selectionChanged(
|
|
const QItemSelection&, const QItemSelection&)));
|
|
connect(lvSelectedProtocols->selectionModel(),
|
|
SIGNAL(currentChanged(const QModelIndex&, const QModelIndex&)),
|
|
this, SLOT(when_lvSelectedProtocols_currentChanged(const QModelIndex&,
|
|
const QModelIndex&)));
|
|
|
|
LoadCurrentStream();
|
|
mpPacketModel = new PacketModel(this);
|
|
tvPacketTree->setModel(mpPacketModel);
|
|
#if defined(QT_NO_DEBUG) || QT_VERSION < 0x050700
|
|
mpPacketModelTester = NULL;
|
|
#else
|
|
mpPacketModelTester = new ModelTest(mpPacketModel);
|
|
#endif
|
|
tvPacketTree->header()->hide();
|
|
vwPacketDump->setModel(mpPacketModel);
|
|
vwPacketDump->setSelectionModel(tvPacketTree->selectionModel());
|
|
|
|
pbPrev->setDisabled(mCurrentStreamIndex == 0);
|
|
pbNext->setDisabled(int(mCurrentStreamIndex) == (_streamList.size()-1));
|
|
|
|
//! \todo Support Goto Stream Id
|
|
leStreamId->setHidden(true);
|
|
disconnect(rbActionGotoStream, SIGNAL(toggled(bool)), leStreamId, SLOT(setEnabled(bool)));
|
|
|
|
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
|
|
if (!lastGeometry.isNull())
|
|
setGeometry(lastGeometry);
|
|
twTopLevel->setCurrentIndex(lastTopLevelTabIndex);
|
|
}
|
|
|
|
void StreamConfigDialog::setupUiExtra()
|
|
{
|
|
QRegExp reHex2B("[0-9,a-f,A-F]{1,4}");
|
|
QRegExp reHex4B("[0-9,a-f,A-F]{1,8}");
|
|
QRegExp reMac("([0-9,a-f,A-F]{2,2}[:-]){5,5}[0-9,a-f,A-F]{2,2}");
|
|
|
|
// ---- Setup default stuff that cannot be done in designer ----
|
|
bgProto[ProtoL1] = new QButtonGroup();
|
|
bgProto[ProtoL1]->addButton(rbL1None, ButtonIdNone);
|
|
bgProto[ProtoL1]->addButton(rbL1Mac, OstProto::Protocol::kMacFieldNumber);
|
|
bgProto[ProtoL1]->addButton(rbL1Other, ButtonIdOther);
|
|
|
|
bgProto[ProtoL2] = new QButtonGroup();
|
|
#if 0
|
|
foreach(QRadioButton *btn, gbFrameType->findChildren<QRadioButton*>())
|
|
bgL2Proto->addButton(btn);
|
|
#else
|
|
bgProto[ProtoL2]->addButton(rbFtNone, ButtonIdNone);
|
|
bgProto[ProtoL2]->addButton(rbFtEthernet2, OstProto::Protocol::kEth2FieldNumber);
|
|
bgProto[ProtoL2]->addButton(rbFt802Dot3Raw, OstProto::Protocol::kDot3FieldNumber);
|
|
bgProto[ProtoL2]->addButton(rbFt802Dot3Llc, OstProto::Protocol::kDot2LlcFieldNumber);
|
|
bgProto[ProtoL2]->addButton(rbFtLlcSnap, OstProto::Protocol::kDot2SnapFieldNumber);
|
|
bgProto[ProtoL2]->addButton(rbFtOther, ButtonIdOther);
|
|
#endif
|
|
|
|
bgProto[ProtoVlan] = new QButtonGroup();
|
|
bgProto[ProtoVlan]->addButton(rbVlanNone, ButtonIdNone);
|
|
bgProto[ProtoVlan]->addButton(rbVlanSingle, OstProto::Protocol::kVlanFieldNumber);
|
|
bgProto[ProtoVlan]->addButton(rbVlanDouble, OstProto::Protocol::kVlanStackFieldNumber);
|
|
|
|
bgProto[ProtoL3] = new QButtonGroup();
|
|
#if 0
|
|
foreach(QRadioButton *btn, gbL3Proto->findChildren<QRadioButton*>())
|
|
bgProto[ProtoL3]->addButton(btn);
|
|
#else
|
|
bgProto[ProtoL3]->addButton(rbL3None, ButtonIdNone);
|
|
bgProto[ProtoL3]->addButton(rbL3Arp, OstProto::Protocol::kArpFieldNumber);
|
|
bgProto[ProtoL3]->addButton(rbL3Ipv4, OstProto::Protocol::kIp4FieldNumber);
|
|
bgProto[ProtoL3]->addButton(rbL3Ipv6, OstProto::Protocol::kIp6FieldNumber);
|
|
bgProto[ProtoL3]->addButton(rbL3Ip6over4,
|
|
OstProto::Protocol::kIp6over4FieldNumber);
|
|
bgProto[ProtoL3]->addButton(rbL3Ip4over6,
|
|
OstProto::Protocol::kIp4over6FieldNumber);
|
|
bgProto[ProtoL3]->addButton(rbL3Ip4over4,
|
|
OstProto::Protocol::kIp4over4FieldNumber);
|
|
bgProto[ProtoL3]->addButton(rbL3Ip6over6,
|
|
OstProto::Protocol::kIp6over6FieldNumber);
|
|
bgProto[ProtoL3]->addButton(rbL3Other, ButtonIdOther);
|
|
#endif
|
|
|
|
bgProto[ProtoL4] = new QButtonGroup();
|
|
#if 0
|
|
foreach(QRadioButton *btn, gbL4Proto->findChildren<QRadioButton*>())
|
|
bgProto[ProtoL4]->addButton(btn);
|
|
#else
|
|
bgProto[ProtoL4]->addButton(rbL4None, ButtonIdNone);
|
|
bgProto[ProtoL4]->addButton(rbL4Tcp, OstProto::Protocol::kTcpFieldNumber);
|
|
bgProto[ProtoL4]->addButton(rbL4Udp, OstProto::Protocol::kUdpFieldNumber);
|
|
bgProto[ProtoL4]->addButton(rbL4Icmp, OstProto::Protocol::kIcmpFieldNumber);
|
|
bgProto[ProtoL4]->addButton(rbL4Igmp, OstProto::Protocol::kIgmpFieldNumber);
|
|
bgProto[ProtoL4]->addButton(rbL4Mld, OstProto::Protocol::kMldFieldNumber);
|
|
bgProto[ProtoL4]->addButton(rbL4Other, ButtonIdOther);
|
|
#endif
|
|
|
|
bgProto[ProtoL5] = new QButtonGroup();
|
|
#if 0
|
|
foreach(QRadioButton *btn, gbL5Proto->findChildren<QRadioButton*>())
|
|
bgProto[ProtoL5]->addButton(btn);
|
|
#else
|
|
bgProto[ProtoL5]->addButton(rbL5None, ButtonIdNone);
|
|
bgProto[ProtoL5]->addButton(rbL5Text,
|
|
OstProto::Protocol::kTextProtocolFieldNumber);
|
|
bgProto[ProtoL5]->addButton(rbL5Other, ButtonIdOther);
|
|
#endif
|
|
|
|
bgProto[ProtoPayload] = new QButtonGroup();
|
|
#if 0
|
|
foreach(QRadioButton *btn, gbPayloadProto->findChildren<QRadioButton*>())
|
|
bgProto[ProtoPayload]->addButton(btn);
|
|
#else
|
|
bgProto[ProtoPayload]->addButton(rbPayloadNone, ButtonIdNone);
|
|
bgProto[ProtoPayload]->addButton(rbPayloadPattern, OstProto::Protocol::kPayloadFieldNumber);
|
|
bgProto[ProtoPayload]->addButton(rbPayloadHexDump, OstProto::Protocol::kHexDumpFieldNumber);
|
|
bgProto[ProtoPayload]->addButton(rbPayloadOther, ButtonIdOther);
|
|
#endif
|
|
|
|
// Special
|
|
bgProto[ProtoSign] = new QButtonGroup();
|
|
bgProto[ProtoSign]->addButton(rbSpecialNone, ButtonIdNone);
|
|
bgProto[ProtoSign]->addButton(rbSignature,
|
|
OstProto::Protocol::kSignFieldNumber);
|
|
// Trailer
|
|
bgProto[ProtoTrailer] = new QButtonGroup();
|
|
bgProto[ProtoTrailer]->addButton(rbTrailerNone, ButtonIdNone);
|
|
bgProto[ProtoTrailer]->addButton(rbTrailerOther, ButtonIdOther);
|
|
|
|
/*
|
|
** Setup Validators
|
|
*/
|
|
// Meta Data
|
|
lePktLen->setValidator(new QIntValidator(MIN_PKT_LEN, MAX_PKT_LEN, this));
|
|
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
|
|
*/
|
|
connect(rbSendPackets, SIGNAL(toggled(bool)),
|
|
this, SLOT(update_NumPacketsAndNumBursts()));
|
|
connect(rbSendBursts, SIGNAL(toggled(bool)),
|
|
this, SLOT(update_NumPacketsAndNumBursts()));
|
|
connect(rbModeFixed, SIGNAL(toggled(bool)),
|
|
this, SLOT(update_NumPacketsAndNumBursts()));
|
|
connect(rbModeContinuous, SIGNAL(toggled(bool)),
|
|
this, SLOT(update_NumPacketsAndNumBursts()));
|
|
|
|
}
|
|
|
|
StreamConfigDialog::~StreamConfigDialog()
|
|
{
|
|
delete mpPacketModelTester;
|
|
delete mpPacketModel;
|
|
|
|
for (int i = ProtoMin; i < ProtoMax; i++)
|
|
delete bgProto[i];
|
|
|
|
foreach (AbstractProtocolConfigForm* w, _protocolWidgets) {
|
|
OstProtocolWidgetFactory->deleteConfigWidget(w);
|
|
}
|
|
|
|
delete _iter;
|
|
while (!_streamList.isEmpty())
|
|
delete _streamList.takeFirst();
|
|
}
|
|
|
|
void StreamConfigDialog::setWindowTitle(const QString &title)
|
|
{
|
|
_windowTitle = title;
|
|
QDialog::setWindowTitle(title);
|
|
}
|
|
|
|
void StreamConfigDialog::loadProtocolWidgets()
|
|
{
|
|
ProtocolListIterator *iter;
|
|
|
|
// NOTE: Protocol Widgets are created on demand. Once created we
|
|
// store them in _protocolWidgets indexed by the protocol
|
|
// object's address (to ensure unique widgets for multiple
|
|
// objects of the same class). Subsequently we check
|
|
// _protocolWidgets before creating a new widget
|
|
iter = mpStream->createProtocolListIterator();
|
|
while (iter->hasNext())
|
|
{
|
|
AbstractProtocol* p = iter->next();
|
|
AbstractProtocolConfigForm *w = _protocolWidgets.value(p);
|
|
if (!w) {
|
|
w = OstProtocolWidgetFactory->createConfigWidget(
|
|
p->protocolNumber());
|
|
_protocolWidgets.insert(p, w);
|
|
}
|
|
w->loadWidget(p);
|
|
}
|
|
delete iter;
|
|
}
|
|
|
|
void StreamConfigDialog::storeProtocolWidgets()
|
|
{
|
|
ProtocolListIterator *iter;
|
|
|
|
// NOTE: After creating a widget, we need to call loadWidget()
|
|
// to load the protocol's default values
|
|
iter = mpStream->createProtocolListIterator();
|
|
while (iter->hasNext())
|
|
{
|
|
AbstractProtocol* p = iter->next();
|
|
AbstractProtocolConfigForm *w = _protocolWidgets.value(p);
|
|
if (!w) {
|
|
w = OstProtocolWidgetFactory->createConfigWidget(
|
|
p->protocolNumber());
|
|
w->loadWidget(p);
|
|
_protocolWidgets.insert(p, w);
|
|
}
|
|
w->storeWidget(p);
|
|
}
|
|
delete iter;
|
|
}
|
|
|
|
void StreamConfigDialog::on_cmbPktLenMode_currentIndexChanged(QString mode)
|
|
{
|
|
if (mode == "Fixed")
|
|
{
|
|
lePktLen->setEnabled(true);
|
|
lePktLenMin->setDisabled(true);
|
|
lePktLenMax->setDisabled(true);
|
|
}
|
|
else if (mode == "Increment")
|
|
{
|
|
lePktLen->setDisabled(true);
|
|
lePktLenMin->setEnabled(true);
|
|
lePktLenMax->setEnabled(true);
|
|
}
|
|
else if (mode == "Decrement")
|
|
{
|
|
lePktLen->setDisabled(true);
|
|
lePktLenMin->setEnabled(true);
|
|
lePktLenMax->setEnabled(true);
|
|
}
|
|
else if (mode == "Random")
|
|
{
|
|
lePktLen->setDisabled(true);
|
|
lePktLenMin->setEnabled(true);
|
|
lePktLenMax->setEnabled(true);
|
|
}
|
|
else if (mode == "IMIX")
|
|
{
|
|
lePktLen->setDisabled(true);
|
|
lePktLenMin->setDisabled(true);
|
|
lePktLenMax->setDisabled(true);
|
|
}
|
|
else
|
|
{
|
|
qWarning("Unhandled/Unknown PktLenMode = %s", qPrintable(mode));
|
|
}
|
|
}
|
|
|
|
void StreamConfigDialog::on_tbSelectProtocols_currentChanged(int index)
|
|
{
|
|
qDebug("%s, index = %d", __FUNCTION__, index);
|
|
switch (index)
|
|
{
|
|
case 0:
|
|
updateSelectProtocolsSimpleWidget();
|
|
break;
|
|
case 1:
|
|
updateSelectProtocolsAdvancedWidget();
|
|
break;
|
|
default:
|
|
qFatal("%s: unexpected index = %d", __FUNCTION__, index);
|
|
}
|
|
}
|
|
|
|
void StreamConfigDialog::when_lvAllProtocols_selectionChanged(
|
|
const QItemSelection &/*selected*/, const QItemSelection &/*deselected*/)
|
|
{
|
|
int size = lvAllProtocols->selectionModel()->selectedIndexes().size();
|
|
|
|
qDebug("%s: selected.indexes().size = %d\n", __FUNCTION__, size);
|
|
|
|
tbAdd->setEnabled(size > 0);
|
|
}
|
|
|
|
void StreamConfigDialog::when_lvSelectedProtocols_currentChanged(
|
|
const QModelIndex ¤t, const QModelIndex &/*previous*/)
|
|
{
|
|
qDebug("%s: currentRow = %d\n", __FUNCTION__, current.row());
|
|
|
|
tbDelete->setEnabled(current.isValid());
|
|
tbUp->setEnabled(current.isValid() && (current.row() != 0));
|
|
tbDown->setEnabled(current.isValid() &&
|
|
(current.row() != (current.model()->rowCount() - 1)));
|
|
}
|
|
|
|
void StreamConfigDialog::on_tbAdd_clicked()
|
|
{
|
|
int n = 0;
|
|
QModelIndex idx2;
|
|
QModelIndexList selection;
|
|
|
|
selection = lvAllProtocols->selectionModel()->selectedIndexes();
|
|
|
|
// Validation
|
|
if (selection.size() == 0)
|
|
return;
|
|
|
|
idx2 = lvSelectedProtocols->currentIndex();
|
|
if (idx2.isValid())
|
|
n = idx2.row();
|
|
|
|
_iter->toFront();
|
|
while (n--)
|
|
{
|
|
if (!_iter->hasNext())
|
|
return;
|
|
|
|
_iter->next();
|
|
}
|
|
|
|
foreach(QModelIndex idx, selection)
|
|
_iter->insert(OstProtocolManager->createProtocol(
|
|
mpAvailableProtocolsModel->stringList().at(idx.row()), mpStream));
|
|
|
|
updateSelectProtocolsAdvancedWidget();
|
|
lvSelectedProtocols->setCurrentIndex(idx2);
|
|
}
|
|
|
|
void StreamConfigDialog::on_tbDelete_clicked()
|
|
{
|
|
int n;
|
|
QModelIndex idx;
|
|
AbstractProtocol *p = NULL;
|
|
|
|
idx = lvSelectedProtocols->currentIndex();
|
|
|
|
// Validation
|
|
if (!idx.isValid())
|
|
return;
|
|
|
|
n = idx.row() + 1;
|
|
|
|
_iter->toFront();
|
|
while (n--)
|
|
{
|
|
if (!_iter->hasNext())
|
|
return;
|
|
|
|
p = _iter->next();
|
|
}
|
|
|
|
Q_CHECK_PTR(p);
|
|
_iter->remove();
|
|
// Free both protocol and associated widget
|
|
delete _protocolWidgets.take(p);
|
|
delete p;
|
|
|
|
updateSelectProtocolsAdvancedWidget();
|
|
lvSelectedProtocols->setCurrentIndex(idx);
|
|
}
|
|
|
|
void StreamConfigDialog::on_tbUp_clicked()
|
|
{
|
|
int m, n;
|
|
QModelIndex idx;
|
|
AbstractProtocol *p = NULL;
|
|
|
|
idx = lvSelectedProtocols->currentIndex();
|
|
|
|
// Validation
|
|
if (!idx.isValid() || idx.row() == 0)
|
|
return;
|
|
|
|
m = n = idx.row() + 1;
|
|
|
|
_iter->toFront();
|
|
while (n--)
|
|
{
|
|
if (!_iter->hasNext())
|
|
return;
|
|
|
|
p = _iter->next();
|
|
}
|
|
|
|
Q_CHECK_PTR(p);
|
|
_iter->remove();
|
|
_iter->previous();
|
|
_iter->insert(p);
|
|
|
|
updateSelectProtocolsAdvancedWidget();
|
|
lvSelectedProtocols->setCurrentIndex(idx.sibling(m-2, 0));
|
|
}
|
|
|
|
void StreamConfigDialog::on_tbDown_clicked()
|
|
{
|
|
int m, n;
|
|
QModelIndex idx;
|
|
AbstractProtocol *p = NULL;
|
|
|
|
idx = lvSelectedProtocols->currentIndex();
|
|
|
|
// Validation
|
|
if (!idx.isValid() || idx.row() == idx.model()->rowCount())
|
|
return;
|
|
|
|
m = n = idx.row() + 1;
|
|
|
|
_iter->toFront();
|
|
while (n--)
|
|
{
|
|
if (!_iter->hasNext())
|
|
return;
|
|
|
|
p = _iter->next();
|
|
}
|
|
|
|
Q_CHECK_PTR(p);
|
|
_iter->remove();
|
|
_iter->next();
|
|
_iter->insert(p);
|
|
|
|
updateSelectProtocolsAdvancedWidget();
|
|
lvSelectedProtocols->setCurrentIndex(idx.sibling(m,0));
|
|
}
|
|
|
|
void StreamConfigDialog::updateSelectProtocolsAdvancedWidget()
|
|
{
|
|
QStringList selProtoList;
|
|
|
|
qDebug("%s", __FUNCTION__);
|
|
|
|
_iter->toFront();
|
|
while(_iter->hasNext())
|
|
{
|
|
AbstractProtocol* p = _iter->next();
|
|
qDebug("%p -- %d", p, p->protocolNumber());
|
|
selProtoList.append(p->shortName());
|
|
}
|
|
mpSelectedProtocolsModel->setStringList(selProtoList);
|
|
}
|
|
|
|
void StreamConfigDialog::on_twTopLevel_currentChanged(int index)
|
|
{
|
|
switch (index)
|
|
{
|
|
// Protocol Data
|
|
case 1:
|
|
{
|
|
// Hide the ToolBox before modifying it - else we have a crash !!!
|
|
tbProtocolData->hide();
|
|
|
|
// Remove all existing protocol widgets
|
|
while (tbProtocolData->count() > 0)
|
|
{
|
|
QWidget* w = tbProtocolData->widget(0);
|
|
tbProtocolData->removeItem(0);
|
|
w->setParent(0);
|
|
}
|
|
|
|
// Repopulate the widgets - create new ones, if required
|
|
_iter->toFront();
|
|
while (_iter->hasNext())
|
|
{
|
|
AbstractProtocol* p = _iter->next();
|
|
AbstractProtocolConfigForm *w = _protocolWidgets.value(p);
|
|
if (!w) {
|
|
w = OstProtocolWidgetFactory->createConfigWidget(
|
|
p->protocolNumber());
|
|
w->loadWidget(p);
|
|
_protocolWidgets.insert(p, w);
|
|
}
|
|
tbProtocolData->addItem(w, p->name());
|
|
}
|
|
|
|
if (lastProtocolDataIndex < tbProtocolData->count())
|
|
tbProtocolData->setCurrentIndex(lastProtocolDataIndex);
|
|
|
|
tbProtocolData->show();
|
|
break;
|
|
}
|
|
|
|
// Variable Fields
|
|
case 2:
|
|
{
|
|
StoreCurrentStream();
|
|
|
|
// Stream protocols may have changed - clear and reload
|
|
variableFieldsWidget->clear();
|
|
variableFieldsWidget->load();
|
|
break;
|
|
}
|
|
|
|
// Stream Control
|
|
case 3:
|
|
{
|
|
StoreCurrentStream();
|
|
break;
|
|
}
|
|
|
|
// Packet View
|
|
case 4:
|
|
{
|
|
StoreCurrentStream();
|
|
mpPacketModel->setSelectedProtocols(*_iter);
|
|
break;
|
|
}
|
|
|
|
default:
|
|
break;
|
|
}
|
|
|
|
lastProtocolDataIndex = tbProtocolData->currentIndex();
|
|
}
|
|
|
|
void StreamConfigDialog::update_NumPacketsAndNumBursts()
|
|
{
|
|
if (rbSendPackets->isChecked() && rbModeFixed->isChecked())
|
|
leNumPackets->setEnabled(true);
|
|
else
|
|
leNumPackets->setEnabled(false);
|
|
|
|
if (rbSendBursts->isChecked() && rbModeFixed->isChecked())
|
|
leNumBursts->setEnabled(true);
|
|
else
|
|
leNumBursts->setEnabled(false);
|
|
}
|
|
|
|
#if 0
|
|
void StreamConfigDialog::on_lePattern_editingFinished()
|
|
{
|
|
ulong num = 0;
|
|
bool isOk;
|
|
QString str;
|
|
|
|
num = lePattern->text().remove(QChar(' ')).toULong(&isOk, 16);
|
|
qDebug("editfinished (%s | %x)\n", qPrintable(lePattern->text()));
|
|
lePattern->setText(uintToHexStr(num, str, 4));
|
|
qDebug("editfinished (%s | %x)\n", qPrintable(lePattern->text()));
|
|
}
|
|
#endif
|
|
|
|
/*!
|
|
Skip protocols upto and including the layer specified.
|
|
*/
|
|
bool StreamConfigDialog::skipProtocols(int layer)
|
|
{
|
|
_iter->toFront();
|
|
|
|
for (int i = ProtoMin; i <= layer; i++)
|
|
{
|
|
if(_iter->hasNext())
|
|
{
|
|
int id;
|
|
QAbstractButton *btn;
|
|
|
|
id = _iter->peekNext()->protocolNumber();
|
|
btn = bgProto[i]->button(id);
|
|
if (btn)
|
|
_iter->next();
|
|
}
|
|
}
|
|
|
|
return true;
|
|
}
|
|
|
|
/*!
|
|
Protocol choices (except "None" and "Other") for a protocol button group are disabled if checked is true, else they are enabled
|
|
*/
|
|
void StreamConfigDialog::disableProtocols(QButtonGroup *protocolGroup, bool checked)
|
|
{
|
|
qDebug("%s: btnGrp = %p, chk? = %d", __FUNCTION__, protocolGroup, checked);
|
|
foreach(QAbstractButton *btn, protocolGroup->buttons())
|
|
{
|
|
int id = protocolGroup->id(btn);
|
|
|
|
if ((id != ButtonIdNone) && (id != ButtonIdOther))
|
|
btn->setDisabled(checked);
|
|
}
|
|
}
|
|
|
|
void StreamConfigDialog::forceProtocolNone(bool checked)
|
|
{
|
|
QObject *btn;
|
|
|
|
btn = sender();
|
|
Q_ASSERT(btn != NULL);
|
|
|
|
qDebug("%s: chk? = %d, btn = %p, L1 = %p, L2 = %p, L3 = %p", __FUNCTION__,
|
|
checked, btn, rbL1None, rbFtNone, rbL3None);
|
|
|
|
if (btn == rbL1None)
|
|
{
|
|
if (checked)
|
|
{
|
|
bgProto[ProtoVlan]->button(ButtonIdNone)->click();
|
|
bgProto[ProtoL2]->button(ButtonIdNone)->click();
|
|
bgProto[ProtoPayload]->button(ButtonIdNone)->click();
|
|
}
|
|
|
|
disableProtocols(bgProto[ProtoVlan], checked);
|
|
disableProtocols(bgProto[ProtoL2], checked);
|
|
disableProtocols(bgProto[ProtoPayload], checked);
|
|
}
|
|
else if (btn == rbFtNone)
|
|
{
|
|
if (checked)
|
|
bgProto[ProtoL3]->button(ButtonIdNone)->click();
|
|
disableProtocols(bgProto[ProtoL3], checked);
|
|
}
|
|
else if (btn == rbL3None)
|
|
{
|
|
if (checked)
|
|
bgProto[ProtoL4]->button(ButtonIdNone)->click();
|
|
disableProtocols(bgProto[ProtoL4], checked);
|
|
}
|
|
else if (btn == rbL4None)
|
|
{
|
|
if (checked)
|
|
bgProto[ProtoL5]->button(ButtonIdNone)->click();
|
|
disableProtocols(bgProto[ProtoL5], checked);
|
|
}
|
|
else
|
|
{
|
|
Q_ASSERT(1 == 0); // Unreachable code!
|
|
}
|
|
}
|
|
|
|
// Button 'newId' has been clicked
|
|
// - update the protocol list correspondingly
|
|
void StreamConfigDialog::updateProtocol(int newId)
|
|
{
|
|
int level;
|
|
QButtonGroup *btnGrp;
|
|
|
|
btnGrp = static_cast<QButtonGroup*>(sender());
|
|
Q_ASSERT(btnGrp != NULL);
|
|
|
|
level = btnGrp->property("ProtocolLevel").toInt();
|
|
Q_ASSERT(btnGrp == bgProto[level]);
|
|
|
|
__updateProtocol(level, newId);
|
|
}
|
|
|
|
// Button 'newId' belonging to layer 'level' has been clicked
|
|
// - update the protocol list correspondingly
|
|
void StreamConfigDialog::__updateProtocol(int level, int newId)
|
|
{
|
|
int oldId;
|
|
QButtonGroup *btnGrp;
|
|
|
|
Q_ASSERT((level >= ProtoMin) && (level <= ProtoMax));
|
|
btnGrp = bgProto[level];
|
|
oldId = btnGrp->property("ProtocolId").toInt();
|
|
|
|
qDebug("%s: level = %d old id = %d new id = %d upd? = %d", __FUNCTION__,
|
|
level, oldId, newId, isUpdateInProgress);
|
|
|
|
if (newId == oldId)
|
|
return;
|
|
|
|
if (!isUpdateInProgress)
|
|
{
|
|
int ret;
|
|
AbstractProtocol *p;
|
|
|
|
ret = skipProtocols(level-1);
|
|
Q_ASSERT(ret == true);
|
|
Q_UNUSED(ret);
|
|
|
|
Q_ASSERT(oldId != newId);
|
|
Q_ASSERT(newId != ButtonIdOther);
|
|
|
|
switch (oldId)
|
|
{
|
|
case ButtonIdNone:
|
|
_iter->insert(OstProtocolManager->createProtocol(
|
|
newId, mpStream));
|
|
break;
|
|
|
|
case ButtonIdOther:
|
|
default:
|
|
Q_ASSERT(_iter->hasNext());
|
|
p =_iter->next();
|
|
|
|
if (newId)
|
|
_iter->setValue(OstProtocolManager->createProtocol(
|
|
newId, mpStream));
|
|
else
|
|
_iter->remove();
|
|
// Free both protocol and associated widget
|
|
delete _protocolWidgets.take(p);
|
|
delete p;
|
|
if (level == ProtoTrailer)
|
|
{
|
|
while (_iter->hasNext())
|
|
{
|
|
p = _iter->next();
|
|
_iter->remove();
|
|
// Free both protocol and associated widget
|
|
delete _protocolWidgets.take(p);
|
|
delete p;
|
|
}
|
|
}
|
|
break;
|
|
}
|
|
}
|
|
|
|
btnGrp->setProperty("ProtocolId", newId);
|
|
return;
|
|
}
|
|
|
|
//! Traverse the ProtocolList and update the SelectProtocols (Simple) widget
|
|
void StreamConfigDialog::updateSelectProtocolsSimpleWidget()
|
|
{
|
|
int i;
|
|
quint32 id;
|
|
QAbstractButton *btn;
|
|
|
|
qDebug("%s", __FUNCTION__);
|
|
|
|
isUpdateInProgress = true;
|
|
|
|
// Reset to default state ...
|
|
for (i = ProtoMin; i < ProtoMax; i++)
|
|
bgProto[i]->button(ButtonIdNone)->click();
|
|
|
|
// ... now iterate and update
|
|
_iter->toFront();
|
|
|
|
for (i = ProtoMin; i < ProtoMax; i++)
|
|
{
|
|
if (!_iter->hasNext())
|
|
goto _done;
|
|
|
|
id = _iter->next()->protocolNumber();
|
|
btn = bgProto[i]->button(id);
|
|
|
|
if (btn) // we have a button for this protocol
|
|
{
|
|
if (btn->isEnabled())
|
|
btn->click();
|
|
else
|
|
{
|
|
btn->setChecked(true);
|
|
__updateProtocol(i, id);
|
|
}
|
|
}
|
|
else // we don't have a button for this protocol
|
|
{
|
|
switch (i)
|
|
{
|
|
case ProtoVlan:
|
|
// No vlan - proto may belong to next layer
|
|
_iter->previous();
|
|
break;
|
|
|
|
case ProtoSign:
|
|
// No sign - but we have a trailer
|
|
_iter->previous();
|
|
break;
|
|
|
|
case ProtoPayload:
|
|
goto _other;
|
|
|
|
default: // viz. L1, L2, L3, L4, L5, Trailer
|
|
// Is this a Payload layer protocol?
|
|
// (maybe intermediate layers are not present)
|
|
btn = bgProto[ProtoPayload]->button(id);
|
|
if (btn && btn->isEnabled())
|
|
{
|
|
btn->click();
|
|
i = ProtoPayload;
|
|
continue;
|
|
}
|
|
else
|
|
goto _other;
|
|
}
|
|
}
|
|
}
|
|
|
|
// If more protocol(s) beyond trailer ...
|
|
if (_iter->hasNext())
|
|
{
|
|
i = ProtoTrailer;
|
|
goto _other;
|
|
}
|
|
|
|
Q_ASSERT(!_iter->hasNext()); // At end of the ProtocolList
|
|
goto _done;
|
|
|
|
_other:
|
|
// Set remaining protocols as 'Other'
|
|
for (int j = i; j < ProtoMax; j++)
|
|
{
|
|
// VLAN/Sign doesn't have a "Other" button
|
|
if ((j == ProtoVlan) || (j == ProtoSign))
|
|
continue;
|
|
|
|
bgProto[j]->button(ButtonIdOther)->setChecked(true);
|
|
__updateProtocol(j, ButtonIdOther);
|
|
}
|
|
|
|
_done:
|
|
isUpdateInProgress = false;
|
|
}
|
|
|
|
void StreamConfigDialog::LoadCurrentStream()
|
|
{
|
|
QString str;
|
|
|
|
qDebug("loading mpStream %p", mpStream);
|
|
variableFieldsWidget->setStream(mpStream);
|
|
|
|
QDialog::setWindowTitle(QString("%1 [%2]").arg(_windowTitle)
|
|
.arg(mpStream->name().isEmpty() ?
|
|
tr("<unnamed>") : mpStream->name()));
|
|
|
|
// Meta Data
|
|
{
|
|
name->setText(mpStream->name());
|
|
enabled->setChecked(mpStream->isEnabled());
|
|
cmbPktLenMode->setCurrentIndex(mpStream->lenMode());
|
|
lePktLen->setText(str.setNum(mpStream->frameLen()));
|
|
lePktLenMin->setText(str.setNum(mpStream->frameLenMin()));
|
|
lePktLenMax->setText(str.setNum(mpStream->frameLenMax()));
|
|
}
|
|
|
|
// Protocols
|
|
{
|
|
updateSelectProtocolsSimpleWidget();
|
|
updateSelectProtocolsAdvancedWidget();
|
|
|
|
loadProtocolWidgets();
|
|
}
|
|
|
|
// Variable Fields
|
|
{
|
|
variableFieldsWidget->clear();
|
|
variableFieldsWidget->load();
|
|
}
|
|
|
|
// Stream Control
|
|
{
|
|
switch (mpStream->sendUnit())
|
|
{
|
|
case Stream::e_su_packets:
|
|
rbSendPackets->setChecked(true);
|
|
break;
|
|
case Stream::e_su_bursts:
|
|
rbSendBursts->setChecked(true);
|
|
break;
|
|
default:
|
|
qWarning("Unhandled sendUnit = %d\n", mpStream->sendUnit());
|
|
}
|
|
|
|
switch (mpStream->sendMode())
|
|
{
|
|
case Stream::e_sm_fixed:
|
|
rbModeFixed->setChecked(true);
|
|
break;
|
|
case Stream::e_sm_continuous:
|
|
rbModeContinuous->setChecked(true);
|
|
break;
|
|
default:
|
|
qWarning("Unhandled sendMode = %d\n", mpStream->sendMode());
|
|
}
|
|
|
|
switch(mpStream->nextWhat())
|
|
{
|
|
case Stream::e_nw_stop:
|
|
rbActionStop->setChecked(true);
|
|
break;
|
|
case Stream::e_nw_goto_next:
|
|
rbActionGotoNext->setChecked(true);
|
|
break;
|
|
case Stream::e_nw_goto_id:
|
|
rbActionGotoStream->setChecked(true);
|
|
break;
|
|
default:
|
|
qWarning("Unhandled nextAction = %d\n", mpStream->nextWhat());
|
|
}
|
|
|
|
leNumPackets->setText(QString().setNum(mpStream->numPackets()));
|
|
leNumBursts->setText(QString().setNum(mpStream->numBursts()));
|
|
lePacketsPerBurst->setText(QString().setNum(mpStream->burstSize()));
|
|
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");
|
|
}
|
|
|
|
void StreamConfigDialog::StoreCurrentStream()
|
|
{
|
|
QString str;
|
|
bool isOk;
|
|
Stream *pStream = mpStream;
|
|
|
|
qDebug("storing pStream %p", pStream);
|
|
|
|
// Meta Data
|
|
pStream->setName(name->text());
|
|
pStream->setEnabled(enabled->isChecked());
|
|
pStream->setLenMode((Stream::FrameLengthMode) cmbPktLenMode->currentIndex());
|
|
pStream->setFrameLen(lePktLen->text().toULong(&isOk));
|
|
pStream->setFrameLenMin(lePktLenMin->text().toULong(&isOk));
|
|
pStream->setFrameLenMax(lePktLenMax->text().toULong(&isOk));
|
|
|
|
// Protocols
|
|
{
|
|
storeProtocolWidgets();
|
|
}
|
|
|
|
// Variable Fields
|
|
{
|
|
variableFieldsWidget->store();
|
|
}
|
|
|
|
// Stream Control
|
|
{
|
|
if (rbSendPackets->isChecked())
|
|
pStream->setSendUnit(Stream::e_su_packets);
|
|
if (rbSendBursts->isChecked())
|
|
pStream->setSendUnit(Stream::e_su_bursts);
|
|
|
|
if (rbModeFixed->isChecked())
|
|
pStream->setSendMode(Stream::e_sm_fixed);
|
|
if (rbModeContinuous->isChecked())
|
|
pStream->setSendMode(Stream::e_sm_continuous);
|
|
|
|
if (rbActionStop->isChecked())
|
|
pStream->setNextWhat(Stream::e_nw_stop);
|
|
if (rbActionGotoNext->isChecked())
|
|
pStream->setNextWhat(Stream::e_nw_goto_next);
|
|
if (rbActionGotoStream->isChecked())
|
|
pStream->setNextWhat(Stream::e_nw_goto_id);
|
|
|
|
pStream->setNumPackets(leNumPackets->text().toULong(&isOk));
|
|
pStream->setNumBursts(leNumBursts->text().toULong(&isOk));
|
|
pStream->setBurstSize(lePacketsPerBurst->text().toULong(&isOk));
|
|
pStream->setPacketRate(
|
|
XLocale().toDouble(lePacketsPerSec->text(), &isOk));
|
|
pStream->setBurstRate(
|
|
XLocale().toDouble(leBurstsPerSec->text(), &isOk));
|
|
}
|
|
}
|
|
|
|
void StreamConfigDialog::on_tbProtocolData_currentChanged(int /*index*/)
|
|
{
|
|
// Refresh protocol widgets in case there is any dependent data between
|
|
// protocols e.g. TCP/UDP port numbers are dependent on Port/Protocol
|
|
// selection in TextProtocol
|
|
#if 0 // FIXME: temp mask to avoid crash till we fix it
|
|
storeProtocolWidgets();
|
|
loadProtocolWidgets();
|
|
#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 = pStream->frameLenAvg();
|
|
|
|
if (rbSendPackets->isChecked())
|
|
{
|
|
double pktsPerSec = XLocale().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 = pStream->frameLenAvg();
|
|
|
|
qDebug("start of %s(%s)", __FUNCTION__, qPrintable(text));
|
|
|
|
if (rbSendBursts->isChecked())
|
|
{
|
|
double burstsPerSec = XLocale().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 = pStream->frameLenAvg();
|
|
|
|
if (rbSendPackets->isChecked())
|
|
{
|
|
double pktsPerSec = XLocale().toDouble(text, &isOk)/
|
|
double((frameLen+kEthFrameOverHead)*8);
|
|
lePacketsPerSec->setText(QString("%L1").arg(pktsPerSec, 0, 'f', 4));
|
|
}
|
|
else if (rbSendBursts->isChecked())
|
|
{
|
|
double burstsPerSec = XLocale().toDouble(text, &isOk)/
|
|
double(burstSize * (frameLen + kEthFrameOverHead) * 8);
|
|
leBurstsPerSec->setText(QString("%L1").arg(burstsPerSec, 0, 'f', 4));
|
|
}
|
|
}
|
|
|
|
bool StreamConfigDialog::isCurrentStreamValid()
|
|
{
|
|
QStringList log;
|
|
|
|
if ((mPort.transmitMode() == OstProto::kInterleavedTransmit)
|
|
&& (mpStream->isFrameVariable()))
|
|
{
|
|
log << tr("In 'Interleaved Streams' transmit mode, the count for "
|
|
"varying fields at transmit time may not be same as configured");
|
|
}
|
|
|
|
if (!mPort.trackStreamStats()
|
|
&& mpStream->hasProtocol(OstProto::Protocol::kSignFieldNumber))
|
|
{
|
|
log << tr("Stream contains special signature, but per stream statistics "
|
|
"will not be available till it is enabled on the port");
|
|
}
|
|
|
|
mpStream->preflightCheck(log);
|
|
|
|
if (log.size())
|
|
{
|
|
if (QMessageBox::warning(this, "Preflight Check",
|
|
tr("<p>We found possible problems with this stream -</p>")
|
|
+ "<ul>"
|
|
+ log.replaceInStrings(QRegExp("(.*)"), "<li>\\1</li>")
|
|
.join("\n")
|
|
+ "</ul>"
|
|
+ tr("<p>Ignore?</p>"),
|
|
QMessageBox::Yes | QMessageBox::No, QMessageBox::No)
|
|
== QMessageBox::No)
|
|
return false;
|
|
}
|
|
|
|
return true;
|
|
}
|
|
|
|
void StreamConfigDialog::on_pbPrev_clicked()
|
|
{
|
|
Q_ASSERT(mCurrentStreamIndex > 0);
|
|
|
|
StoreCurrentStream();
|
|
|
|
if (!isCurrentStreamValid())
|
|
return;
|
|
|
|
delete _iter;
|
|
mpStream = _streamList.at(--mCurrentStreamIndex);
|
|
_iter = mpStream->createProtocolListIterator();
|
|
|
|
LoadCurrentStream();
|
|
on_twTopLevel_currentChanged(twTopLevel->currentIndex());
|
|
|
|
pbPrev->setDisabled(mCurrentStreamIndex == 0);
|
|
pbNext->setDisabled(int(mCurrentStreamIndex) == (_streamList.size()-1));
|
|
}
|
|
|
|
void StreamConfigDialog::on_pbNext_clicked()
|
|
{
|
|
Q_ASSERT(int(mCurrentStreamIndex) < (_streamList.size()-1));
|
|
|
|
StoreCurrentStream();
|
|
|
|
if (!isCurrentStreamValid())
|
|
return;
|
|
|
|
delete _iter;
|
|
mpStream = _streamList.at(++mCurrentStreamIndex);
|
|
_iter = mpStream->createProtocolListIterator();
|
|
|
|
LoadCurrentStream();
|
|
on_twTopLevel_currentChanged(twTopLevel->currentIndex());
|
|
|
|
pbPrev->setDisabled(mCurrentStreamIndex == 0);
|
|
pbNext->setDisabled(int(mCurrentStreamIndex) == (_streamList.size()-1));
|
|
|
|
}
|
|
|
|
void StreamConfigDialog::on_pbOk_clicked()
|
|
{
|
|
// Store dialog contents into current stream
|
|
StoreCurrentStream();
|
|
|
|
if (!isCurrentStreamValid())
|
|
return;
|
|
|
|
// Copy the working copy of streams to user provided streams
|
|
Q_ASSERT(_userStreamList.size() == _streamList.size());
|
|
for (int i = 0; i < _streamList.size(); i++) {
|
|
OstProto::Stream s;
|
|
_streamList.at(i)->protoDataCopyInto(s);
|
|
_userStreamList[i]->protoDataCopyFrom(s);
|
|
}
|
|
|
|
qDebug("stream stored");
|
|
|
|
lastGeometry = geometry();
|
|
lastTopLevelTabIndex = twTopLevel->currentIndex();
|
|
lastProtocolDataIndex = tbProtocolData->currentIndex();
|
|
|
|
accept();
|
|
}
|
|
|