- Implemented the "Stop" and "Goto Stream" per stream "nextWhat" options (Goto can only go to first stream for now - not any arbitrary stream)
- StreamListView now has a delegate to display a combobox for "nextWhat" and a checkbox for "status" - StreamListView now has reasonable default widths for its columns
This commit is contained in:
parent
f13b0915d5
commit
53bcc077da
@ -20,6 +20,7 @@ HEADERS += \
|
||||
portstatswindow.h \
|
||||
portswindow.h \
|
||||
streamconfigdialog.h \
|
||||
streamlistdelegate.h \
|
||||
streammodel.h
|
||||
|
||||
FORMS += \
|
||||
@ -45,6 +46,7 @@ SOURCES += \
|
||||
portstatswindow.cpp \
|
||||
portswindow.cpp \
|
||||
streamconfigdialog.cpp \
|
||||
streamlistdelegate.cpp \
|
||||
streammodel.cpp
|
||||
|
||||
# Protocol Buffer Sources
|
||||
|
@ -1,18 +1,20 @@
|
||||
#include "portswindow.h"
|
||||
#include "streamlistdelegate.h"
|
||||
#include "streamconfigdialog.h"
|
||||
#include <QInputDialog>
|
||||
#include <QItemSelectionModel>
|
||||
|
||||
PortsWindow::PortsWindow(PortGroupList *pgl, QWidget *parent)
|
||||
{
|
||||
StreamListDelegate *delegate = new StreamListDelegate;
|
||||
//slm = new StreamListModel();
|
||||
//plm = new PortGroupList();
|
||||
plm = pgl;
|
||||
|
||||
setupUi(this);
|
||||
|
||||
tvStreamList->horizontalHeader()->resizeSections(
|
||||
QHeaderView::ResizeToContents);
|
||||
tvStreamList->setItemDelegate(delegate);
|
||||
|
||||
tvStreamList->verticalHeader()->setDefaultSectionSize(
|
||||
tvStreamList->verticalHeader()->minimumSectionSize());
|
||||
|
||||
@ -53,6 +55,9 @@ PortsWindow::PortsWindow(PortGroupList *pgl, QWidget *parent)
|
||||
plm->getStreamModel(), SLOT(setCurrentPortIndex(const QModelIndex&)));
|
||||
#endif
|
||||
|
||||
tvStreamList->resizeColumnToContents(StreamModel::StreamIcon);
|
||||
tvStreamList->resizeColumnToContents(StreamModel::StreamStatus);
|
||||
|
||||
// Initially we don't have any ports/streams - so send signal triggers
|
||||
when_portView_currentChanged(QModelIndex(), QModelIndex());
|
||||
when_streamView_currentChanged(QModelIndex(), QModelIndex());
|
||||
|
@ -173,7 +173,8 @@ StreamConfigDialog::StreamConfigDialog(Port &port, uint streamIndex,
|
||||
pbPrev->setDisabled(true);
|
||||
pbNext->setDisabled(true);
|
||||
//! \todo Support Goto Stream Id
|
||||
rbActionGotoStream->setDisabled(true);
|
||||
leStreamId->setDisabled(true);
|
||||
disconnect(rbActionGotoStream, SIGNAL(toggled(bool)), leStreamId, SLOT(setEnabled(bool)));
|
||||
//! \todo Support Continuous Mode
|
||||
rbModeContinuous->setDisabled(true);
|
||||
}
|
||||
@ -824,10 +825,11 @@ void StreamConfigDialog::LoadCurrentStream()
|
||||
|
||||
leNumPackets->setText(QString().setNum(pStream->numPackets()));
|
||||
leNumBursts->setText(QString().setNum(pStream->numBursts()));
|
||||
lePacketsPerBurst->setText(QString().setNum(
|
||||
pStream->burstSize()));
|
||||
lePacketsPerBurst->setText(QString().setNum(pStream->burstSize()));
|
||||
lePacketsPerSec->setText(QString().setNum(pStream->packetRate()));
|
||||
leBurstsPerSec->setText(QString().setNum(pStream->burstRate()));
|
||||
// TODO(MED): Change this when we support goto to specific stream
|
||||
leStreamId->setText(QString("0"));
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -1915,6 +1915,9 @@ QLineEdit:enabled[inputMask = "HH HH HH HH HH HH; "] { background-color: #ccccff
|
||||
</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>
|
||||
|
175
client/streamlistdelegate.cpp
Normal file
175
client/streamlistdelegate.cpp
Normal file
@ -0,0 +1,175 @@
|
||||
#include <QComboBox>
|
||||
#include <QCheckBox>
|
||||
#include <QApplication>
|
||||
#include <QMouseEvent>
|
||||
|
||||
#include "streammodel.h"
|
||||
#include "streamlistdelegate.h"
|
||||
|
||||
StreamListDelegate::StreamListDelegate(QObject *parent)
|
||||
: QItemDelegate(parent)
|
||||
{
|
||||
}
|
||||
|
||||
|
||||
QWidget *StreamListDelegate::createEditor(QWidget *parent,
|
||||
const QStyleOptionViewItem &option,
|
||||
const QModelIndex &index) const
|
||||
{
|
||||
QWidget *editor = NULL;
|
||||
|
||||
switch ((StreamModel::StreamFields) index.column())
|
||||
{
|
||||
case StreamModel::StreamStatus:
|
||||
{
|
||||
editor = new QCheckBox(parent);
|
||||
goto _handled;
|
||||
}
|
||||
case StreamModel::StreamNextWhat:
|
||||
{
|
||||
editor = new QComboBox(parent);
|
||||
static_cast<QComboBox*>(editor)->insertItems(0,
|
||||
StreamModel::nextWhatOptionList());
|
||||
goto _handled;
|
||||
}
|
||||
|
||||
case StreamModel::StreamIcon:
|
||||
case StreamModel::StreamName:
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
||||
editor = QItemDelegate::createEditor(parent, option, index);
|
||||
|
||||
_handled:
|
||||
return editor;
|
||||
|
||||
}
|
||||
|
||||
|
||||
void StreamListDelegate::setEditorData(QWidget *editor,
|
||||
const QModelIndex &index) const
|
||||
{
|
||||
switch ((StreamModel::StreamFields) index.column())
|
||||
{
|
||||
case StreamModel::StreamStatus:
|
||||
{
|
||||
QCheckBox *cb = static_cast<QCheckBox*>(editor);
|
||||
cb->setChecked(
|
||||
index.model()->data(index, Qt::EditRole).toBool());
|
||||
goto _handled;
|
||||
}
|
||||
case StreamModel::StreamNextWhat:
|
||||
{
|
||||
QComboBox *cb = static_cast<QComboBox*>(editor);
|
||||
cb->setCurrentIndex(
|
||||
index.model()->data(index, Qt::EditRole).toInt());
|
||||
goto _handled;
|
||||
}
|
||||
|
||||
case StreamModel::StreamIcon:
|
||||
case StreamModel::StreamName:
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
||||
QItemDelegate::setEditorData(editor, index);
|
||||
|
||||
_handled:
|
||||
return;
|
||||
}
|
||||
|
||||
|
||||
void StreamListDelegate::setModelData(QWidget *editor,
|
||||
QAbstractItemModel *model, const QModelIndex &index) const
|
||||
{
|
||||
switch ((StreamModel::StreamFields) index.column())
|
||||
{
|
||||
case StreamModel::StreamStatus:
|
||||
{
|
||||
QCheckBox *cb = static_cast<QCheckBox*>(editor);
|
||||
model->setData(index, cb->isChecked(), Qt::EditRole);
|
||||
goto _handled;
|
||||
}
|
||||
|
||||
case StreamModel::StreamNextWhat:
|
||||
{
|
||||
QComboBox *cb = static_cast<QComboBox*>(editor);
|
||||
model->setData(index, cb->currentIndex(), Qt::EditRole);
|
||||
goto _handled;
|
||||
}
|
||||
|
||||
case StreamModel::StreamIcon:
|
||||
case StreamModel::StreamName:
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
||||
QItemDelegate::setModelData(editor, model, index);
|
||||
|
||||
_handled:
|
||||
return;
|
||||
}
|
||||
|
||||
|
||||
void StreamListDelegate::updateEditorGeometry(QWidget *editor,
|
||||
const QStyleOptionViewItem &option, const QModelIndex &index) const
|
||||
{
|
||||
switch ((StreamModel::StreamFields) index.column())
|
||||
{
|
||||
case StreamModel::StreamStatus:
|
||||
{
|
||||
/*
|
||||
* extra 'coz QItemDelegate does it - otherwise the editor
|
||||
* placement is incorrect
|
||||
*/
|
||||
int extra = 2 * (qApp->style()->pixelMetric(
|
||||
QStyle::PM_FocusFrameHMargin, 0) + 1);
|
||||
|
||||
editor->setGeometry(option.rect.translated(extra, 0));
|
||||
goto _handled;
|
||||
}
|
||||
case StreamModel::StreamIcon:
|
||||
case StreamModel::StreamName:
|
||||
case StreamModel::StreamNextWhat:
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
||||
QItemDelegate::updateEditorGeometry(editor, option, index);
|
||||
|
||||
_handled:
|
||||
return;
|
||||
}
|
||||
|
||||
|
||||
bool StreamListDelegate::editorEvent(QEvent *event, QAbstractItemModel *model,
|
||||
const QStyleOptionViewItem &option, const QModelIndex &index)
|
||||
{
|
||||
/*
|
||||
* Special Handling so that user can use the "Stream status" checkbox
|
||||
* without double clicking first. Copied from QItemDelegate::editorEvent()
|
||||
* and modified suitably
|
||||
*/
|
||||
if ((StreamModel::StreamFields)index.column() ==
|
||||
StreamModel::StreamStatus)
|
||||
{
|
||||
// make sure that we have the right event type
|
||||
if ((event->type() == QEvent::MouseButtonRelease)
|
||||
|| (event->type() == QEvent::MouseButtonDblClick))
|
||||
{
|
||||
QRect checkRect = check(option, option.rect, Qt::Checked);
|
||||
QRect emptyRect;
|
||||
doLayout(option, &checkRect, &emptyRect, &emptyRect, false);
|
||||
if (!checkRect.contains(static_cast<QMouseEvent*>(event)->pos()))
|
||||
return false;
|
||||
|
||||
Qt::CheckState state = (static_cast<Qt::CheckState>(index.data(
|
||||
Qt::CheckStateRole).toInt()) == Qt::Checked ? Qt::Unchecked : Qt::Checked);
|
||||
return model->setData(index, state, Qt::CheckStateRole);
|
||||
}
|
||||
}
|
||||
|
||||
return QItemDelegate::editorEvent(event, model, option, index);
|
||||
}
|
||||
|
29
client/streamlistdelegate.h
Normal file
29
client/streamlistdelegate.h
Normal file
@ -0,0 +1,29 @@
|
||||
#ifndef STREAM_LIST_DELEGATE_H
|
||||
#define STREAM_LIST_DELEGATE_H
|
||||
|
||||
#include <QItemDelegate>
|
||||
#include <QModelIndex>
|
||||
|
||||
class StreamListDelegate : public QItemDelegate
|
||||
{
|
||||
Q_OBJECT
|
||||
|
||||
public:
|
||||
StreamListDelegate(QObject *parent = 0);
|
||||
|
||||
QWidget *createEditor(QWidget *parent, const QStyleOptionViewItem &option,
|
||||
const QModelIndex &index) const;
|
||||
|
||||
void setEditorData(QWidget *editor, const QModelIndex &index) const;
|
||||
void setModelData(QWidget *editor, QAbstractItemModel *model,
|
||||
const QModelIndex &index) const;
|
||||
|
||||
void updateEditorGeometry(QWidget *editor,
|
||||
const QStyleOptionViewItem &option, const QModelIndex &index) const;
|
||||
|
||||
bool editorEvent(QEvent *event, QAbstractItemModel *model,
|
||||
const QStyleOptionViewItem &option, const QModelIndex &index);
|
||||
};
|
||||
|
||||
#endif
|
||||
|
@ -1,3 +1,4 @@
|
||||
#include "stream.h"
|
||||
#include "streammodel.h"
|
||||
#include "portgrouplist.h"
|
||||
#include "qicon.h"
|
||||
@ -38,17 +39,19 @@ Qt::ItemFlags StreamModel::flags(const QModelIndex &index) const
|
||||
flags |= Qt::ItemIsEditable;
|
||||
break;
|
||||
case StreamStatus:
|
||||
#if 0
|
||||
flags |= Qt::ItemIsUserCheckable | Qt::ItemIsEditable;
|
||||
#endif
|
||||
flags |= Qt::ItemIsUserCheckable;
|
||||
break;
|
||||
case StreamNextWhat:
|
||||
flags |= Qt::ItemIsEditable;
|
||||
break;
|
||||
default:
|
||||
//qFatal("Missed case in switch!");
|
||||
break;
|
||||
}
|
||||
|
||||
return flags;
|
||||
}
|
||||
|
||||
QVariant StreamModel::data(const QModelIndex &index, int role) const
|
||||
{
|
||||
// Check for a valid index
|
||||
@ -72,10 +75,6 @@ QVariant StreamModel::data(const QModelIndex &index, int role) const
|
||||
{
|
||||
if (role == Qt::DecorationRole)
|
||||
return QIcon(":/icons/stream_edit.png");
|
||||
#if 0
|
||||
else if ((role == Qt::DisplayRole))
|
||||
return QString("EDIT");
|
||||
#endif
|
||||
else
|
||||
return QVariant();
|
||||
break;
|
||||
@ -90,12 +89,7 @@ QVariant StreamModel::data(const QModelIndex &index, int role) const
|
||||
}
|
||||
case StreamStatus:
|
||||
{
|
||||
if ((role == Qt::DisplayRole) || (role == Qt::EditRole))
|
||||
return mCurrentPort->streamByIndex(index.row()).isEnabled();
|
||||
else
|
||||
return QVariant();
|
||||
#if 0
|
||||
if ((role == Qt::CheckStateRole) || (role == Qt::EditRole))
|
||||
if ((role == Qt::CheckStateRole))
|
||||
{
|
||||
if (mCurrentPort->streamByIndex(index.row()).isEnabled())
|
||||
return Qt::Checked;
|
||||
@ -104,11 +98,23 @@ QVariant StreamModel::data(const QModelIndex &index, int role) const
|
||||
}
|
||||
else
|
||||
return QVariant();
|
||||
#endif
|
||||
break;
|
||||
}
|
||||
case StreamNextWhat:
|
||||
{
|
||||
int val = mCurrentPort->streamByIndex(index.row()).nextWhat();
|
||||
|
||||
if (role == Qt::DisplayRole)
|
||||
return nextWhatOptionList().at(val);
|
||||
else if (role == Qt::EditRole)
|
||||
return val;
|
||||
else
|
||||
return QVariant();
|
||||
|
||||
break;
|
||||
}
|
||||
default:
|
||||
qDebug("-------------UNHANDLED STREAM FIELD----------------");
|
||||
qFatal("-------------UNHANDLED STREAM FIELD----------------");
|
||||
}
|
||||
|
||||
return QVariant();
|
||||
@ -119,24 +125,35 @@ bool StreamModel::setData(const QModelIndex &index, const QVariant &value, int r
|
||||
if (mCurrentPort == NULL)
|
||||
return false;
|
||||
|
||||
if (index.isValid() && role == Qt::EditRole)
|
||||
if (index.isValid())
|
||||
{
|
||||
// Edit Supported Fields
|
||||
switch (index.column())
|
||||
{
|
||||
// Edit Supported Fields
|
||||
case StreamName:
|
||||
mCurrentPort->streamByIndex(index.row()).setName(value.toString());
|
||||
emit(dataChanged(index, index));
|
||||
return true;
|
||||
break;
|
||||
|
||||
case StreamStatus:
|
||||
mCurrentPort->streamByIndex(index.row()).setIsEnabled(value.toBool());
|
||||
emit(dataChanged(index, index));
|
||||
return true;
|
||||
break;
|
||||
|
||||
case StreamNextWhat:
|
||||
if (role == Qt::EditRole)
|
||||
{
|
||||
mCurrentPort->streamByIndex(index.row()).setNextWhat(
|
||||
(Stream::NextWhat)value.toInt());
|
||||
emit(dataChanged(index, index));
|
||||
return true;
|
||||
}
|
||||
else
|
||||
return false;
|
||||
|
||||
// Edit Not Supported Fields
|
||||
case StreamIcon:
|
||||
return false;
|
||||
break;
|
||||
|
||||
// Unhandled Stream Field
|
||||
default:
|
||||
@ -144,6 +161,7 @@ bool StreamModel::setData(const QModelIndex &index, const QVariant &value, int r
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
@ -157,13 +175,16 @@ QVariant StreamModel::headerData(int section, Qt::Orientation orientation, int r
|
||||
switch(section)
|
||||
{
|
||||
case StreamIcon:
|
||||
return QString("Icon");
|
||||
return QString("");
|
||||
break;
|
||||
case StreamName:
|
||||
return QString("Name");
|
||||
break;
|
||||
case StreamStatus:
|
||||
return QString("Enabled");
|
||||
return QString("");
|
||||
break;
|
||||
case StreamNextWhat:
|
||||
return QString("Goto");
|
||||
break;
|
||||
default:
|
||||
qDebug("-------------UNHANDLED STREAM FIELD----------------");
|
||||
|
@ -1,6 +1,7 @@
|
||||
#ifndef _STREAM_MODEL_H
|
||||
#define _STREAM_MODEL_H
|
||||
|
||||
#include <QStringList>
|
||||
#include <QAbstractTableModel>
|
||||
#include "port.h"
|
||||
|
||||
@ -10,14 +11,6 @@ class StreamModel : public QAbstractTableModel
|
||||
{
|
||||
Q_OBJECT
|
||||
|
||||
enum StreamFields {
|
||||
StreamIcon = 0,
|
||||
StreamName,
|
||||
StreamStatus,
|
||||
|
||||
StreamMaxFields
|
||||
};
|
||||
|
||||
Port *mCurrentPort;
|
||||
PortGroupList *pgl;
|
||||
|
||||
@ -43,6 +36,19 @@ class StreamModel : public QAbstractTableModel
|
||||
{ return &mCurrentPort->mStreams; }
|
||||
#endif
|
||||
|
||||
public:
|
||||
enum StreamFields {
|
||||
StreamIcon = 0,
|
||||
StreamName,
|
||||
StreamStatus,
|
||||
StreamNextWhat,
|
||||
|
||||
StreamMaxFields
|
||||
};
|
||||
|
||||
static QStringList nextWhatOptionList()
|
||||
{ return QStringList() << "Stop" << "Next" << "Goto first"; }
|
||||
|
||||
public slots:
|
||||
void setCurrentPortIndex(const QModelIndex ¤t);
|
||||
|
||||
|
@ -559,6 +559,7 @@ PortInfo::PortInfo(uint id, pcap_if_t *dev)
|
||||
|
||||
// We'll create sendqueue later when required
|
||||
sendQueueList.clear();
|
||||
returnToQIdx = -1;
|
||||
pcapExtra.txPkts = 0;
|
||||
pcapExtra.txBytes = 0;
|
||||
isSendQueueDirty=true;
|
||||
@ -581,6 +582,8 @@ void PortInfo::update()
|
||||
foreach(sendQ, sendQueueList)
|
||||
pcap_sendqueue_destroy(sendQ.sendQueue);
|
||||
}
|
||||
sendQueueList.clear();
|
||||
returnToQIdx = -1;
|
||||
|
||||
// TODO(LOW): calculate sendqueue size
|
||||
sendQ.sendQueue = pcap_sendqueue_alloc(1*MB);
|
||||
@ -589,8 +592,11 @@ void PortInfo::update()
|
||||
// First sort the streams by ordinalValue
|
||||
qSort(streamList);
|
||||
|
||||
pktHdr.ts.tv_sec = 0;
|
||||
pktHdr.ts.tv_usec = 0;
|
||||
for (int i = 0; i < streamList.size(); i++)
|
||||
{
|
||||
//_restart:
|
||||
if (streamList[i].d.core().is_enabled())
|
||||
{
|
||||
long numPackets, numBursts;
|
||||
@ -619,8 +625,6 @@ void PortInfo::update()
|
||||
numBursts, numPackets);
|
||||
qDebug("ibg = %ld, ipg = %ld\n", ibg, ipg);
|
||||
|
||||
pktHdr.ts.tv_sec = 0;
|
||||
pktHdr.ts.tv_usec = 0;
|
||||
for (int j = 0; j < numBursts; j++)
|
||||
{
|
||||
for (int k = 0; k < numPackets; k++)
|
||||
@ -655,6 +659,9 @@ void PortInfo::update()
|
||||
#endif
|
||||
}
|
||||
|
||||
qDebug("q(%d, %d, %d) sec = %lu usec = %lu",
|
||||
i, j, k, pktHdr.ts.tv_sec, pktHdr.ts.tv_usec);
|
||||
|
||||
if (-1 == pcap_sendqueue_queue(sendQ.sendQueue, &pktHdr,
|
||||
(u_char*) pktBuf))
|
||||
{
|
||||
@ -664,17 +671,48 @@ void PortInfo::update()
|
||||
else
|
||||
sendQ.sendQueueCumLen.append(sendQ.sendQueue->len);
|
||||
}
|
||||
}
|
||||
} // for (numPackets)
|
||||
pktHdr.ts.tv_usec += ibg;
|
||||
if (pktHdr.ts.tv_usec > 1000000)
|
||||
{
|
||||
pktHdr.ts.tv_sec++;
|
||||
pktHdr.ts.tv_usec -= 1000000;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
} // for (numBursts)
|
||||
|
||||
switch(streamList[i].d.control().next())
|
||||
{
|
||||
case ::OstProto::StreamControl::e_nw_stop:
|
||||
goto _stop_no_more_pkts;
|
||||
|
||||
case ::OstProto::StreamControl::e_nw_goto_id:
|
||||
// TODO(MED): define and use
|
||||
// streamList[i].d.control().goto_stream_id();
|
||||
|
||||
// TODO(MED): assumes goto Id is less than current!!!!
|
||||
// To support goto to any id, do
|
||||
// if goto_id > curr_id then
|
||||
// i = goto_id;
|
||||
// goto restart;
|
||||
// else
|
||||
// returnToQIdx = 0;
|
||||
|
||||
returnToQIdx=0;
|
||||
goto _stop_no_more_pkts;
|
||||
|
||||
case ::OstProto::StreamControl::e_nw_goto_next:
|
||||
break;
|
||||
|
||||
default:
|
||||
qFatal("---------- %s: Unhandled case (%d) -----------",
|
||||
__FUNCTION__, streamList[i].d.control().next() );
|
||||
break;
|
||||
}
|
||||
|
||||
} // if (stream is enabled)
|
||||
} // for (numStreams)
|
||||
|
||||
_stop_no_more_pkts:
|
||||
// The last alloc'ed sendQ appended here
|
||||
sendQueueList.append(sendQ);
|
||||
|
||||
@ -1061,8 +1099,9 @@ void PortInfo::PortTransmitter::run()
|
||||
|
||||
m_stop = 0;
|
||||
ost_pcap_sendqueue_list_transmit(port->devHandleRx, port->sendQueueList,
|
||||
true, &m_stop, &port->pcapExtra.txPkts, &port->pcapExtra.txBytes,
|
||||
QThread::usleep);
|
||||
port->returnToQIdx, true, &m_stop,
|
||||
&port->pcapExtra.txPkts, &port->pcapExtra.txBytes,
|
||||
QThread::usleep);
|
||||
m_stop = 0;
|
||||
}
|
||||
|
||||
|
@ -133,6 +133,7 @@ class PortInfo
|
||||
pcap_t *devHandleRx;
|
||||
pcap_t *devHandleTx;
|
||||
QList<ost_pcap_send_queue> sendQueueList;
|
||||
int returnToQIdx; // FIXME(MED): combine with sendQList
|
||||
bool isSendQueueDirty;
|
||||
PcapExtra pcapExtra;
|
||||
PortMonitorRx monitorRx;
|
||||
|
@ -62,20 +62,32 @@ int pcap_sendqueue_queue (pcap_send_queue *queue,
|
||||
#endif
|
||||
|
||||
u_int ost_pcap_sendqueue_list_transmit(pcap_t *p,
|
||||
QList<ost_pcap_send_queue> sendQueueList, int sync,
|
||||
QList<ost_pcap_send_queue> sendQueueList, int returnToQIdx, int sync,
|
||||
int *p_stop, quint64* p_pkts, quint64* p_bytes,
|
||||
void (*pf_usleep)(ulong))
|
||||
{
|
||||
uint ret = 0;
|
||||
uint i, ret = 0;
|
||||
ost_pcap_send_queue sq;
|
||||
|
||||
foreach(ost_pcap_send_queue sq, sendQueueList)
|
||||
for(i = 0; i < sendQueueList.size(); i++)
|
||||
{
|
||||
_restart:
|
||||
sq = sendQueueList.at(i);
|
||||
ret += ost_pcap_sendqueue_transmit(p, sq.sendQueue, sync,
|
||||
p_stop, p_pkts, p_bytes, pf_usleep);
|
||||
|
||||
if (*p_stop)
|
||||
return ret;
|
||||
|
||||
// TODO(HI): Timing between subsequent sendQueues
|
||||
}
|
||||
|
||||
if (returnToQIdx >= 0)
|
||||
{
|
||||
i = returnToQIdx;
|
||||
goto _restart;
|
||||
}
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
|
@ -17,7 +17,7 @@ struct ost_pcap_send_queue
|
||||
|
||||
// Common for all OS - *nix or Win32
|
||||
u_int ost_pcap_sendqueue_list_transmit(pcap_t *p,
|
||||
QList<ost_pcap_send_queue> sendQueueList, int sync,
|
||||
QList<ost_pcap_send_queue> sendQueueList, int returnToQIdx, int sync,
|
||||
int *p_stop, quint64* p_pkts, quint64* p_bytes,
|
||||
void (*pf_usleep)(ulong));
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user