Converted all EOLs to unix-style '\n' only
This commit is contained in:
parent
a9e9a7db07
commit
c5bcc2e0c2
@ -1,387 +1,387 @@
|
||||
#include "dumpview.h"
|
||||
|
||||
//! \todo Enable Scrollbars
|
||||
|
||||
DumpView::DumpView(QWidget *parent)
|
||||
{
|
||||
int w, h;
|
||||
|
||||
// NOTE: Monospaced fonts only !!!!!!!!!!!
|
||||
setFont(QFont("Courier"));
|
||||
w = fontMetrics().width('X');
|
||||
h = fontMetrics().height();
|
||||
|
||||
mLineHeight = h;
|
||||
mCharWidth = w;
|
||||
|
||||
mSelectedRow = mSelectedCol = -1;
|
||||
|
||||
// calculate width for offset column and the whitespace that follows it
|
||||
// 0010 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ........ ........
|
||||
mOffsetPaneTopRect = QRect(0, 0, w*4, h);
|
||||
mDumpPaneTopRect = QRect(mOffsetPaneTopRect.right()+w*3, 0,
|
||||
w*((8*3-1)+2+(8*3-1)), h);
|
||||
mAsciiPaneTopRect = QRect(mDumpPaneTopRect.right()+w*3, 0,
|
||||
w*(8+1+8), h);
|
||||
qDebug("DumpView::DumpView");
|
||||
}
|
||||
|
||||
QModelIndex DumpView::indexAt( const QPoint &point ) const
|
||||
{
|
||||
#if 0
|
||||
int x = point.x();
|
||||
int row, col;
|
||||
|
||||
if (x > mAsciiPaneTopRect.left())
|
||||
{
|
||||
col = (x - mAsciiPaneTopRect.left()) / mCharWidth;
|
||||
if (col == 8) // don't select whitespace
|
||||
goto _exit;
|
||||
else if (col > 8) // adjust for whitespace
|
||||
col--;
|
||||
}
|
||||
else if (x > mDumpPaneTopRect.left())
|
||||
{
|
||||
col = (x - mDumpPaneTopRect.left()) / (mCharWidth*3);
|
||||
}
|
||||
row = point.y()/mLineHeight;
|
||||
|
||||
if ((col < 16) && (row < ((data.size()+16)/16)))
|
||||
{
|
||||
selrow = row;
|
||||
selcol = col;
|
||||
}
|
||||
else
|
||||
goto _exit;
|
||||
|
||||
// last row check col
|
||||
if ((row == (((data.size()+16)/16) - 1)) && (col >= (data.size() % 16)))
|
||||
goto _exit;
|
||||
|
||||
qDebug("dumpview::selection(%d, %d)", selrow, selcol);
|
||||
|
||||
offset = selrow * 16 + selcol;
|
||||
#if 0
|
||||
for(int i = 0; i < model()->rowCount(parent); i++)
|
||||
{
|
||||
QModelIndex index = model()->index(i, 0, parent);
|
||||
|
||||
if (model()->hasChildren(index))
|
||||
indexAtOffset(offset, index); // Non Leaf
|
||||
else
|
||||
if (
|
||||
dump.append(model()->data(index, Qt::UserRole).toByteArray()); // Leaf
|
||||
// FIXME: Use RawValueRole instead of UserRole
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
_exit:
|
||||
// Clear existing selection
|
||||
selrow = -1;
|
||||
|
||||
#endif
|
||||
return QModelIndex();
|
||||
}
|
||||
|
||||
void DumpView::scrollTo( const QModelIndex &index, ScrollHint hint )
|
||||
{
|
||||
// FIXME: implement scrolling
|
||||
}
|
||||
|
||||
QRect DumpView::visualRect( const QModelIndex &index ) const
|
||||
{
|
||||
// FIXME: calculate actual rect
|
||||
return rect();
|
||||
}
|
||||
|
||||
//protected:
|
||||
int DumpView::horizontalOffset() const
|
||||
{
|
||||
return horizontalScrollBar()->value();
|
||||
}
|
||||
|
||||
bool DumpView::isIndexHidden( const QModelIndex &index ) const
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
QModelIndex DumpView::moveCursor( CursorAction cursorAction,
|
||||
Qt::KeyboardModifiers modifiers )
|
||||
{
|
||||
// FIXME(MED): need to implement movement using cursor
|
||||
return currentIndex();
|
||||
}
|
||||
|
||||
void DumpView::setSelection( const QRect &rect,
|
||||
QItemSelectionModel::SelectionFlags flags )
|
||||
{
|
||||
// FIXME(HI): calculate indexes using rect
|
||||
selectionModel()->select(QModelIndex(), flags);
|
||||
}
|
||||
|
||||
int DumpView::verticalOffset() const
|
||||
{
|
||||
return verticalScrollBar()->value();
|
||||
}
|
||||
|
||||
QRegion DumpView::visualRegionForSelection( const QItemSelection &selection ) const
|
||||
{
|
||||
// FIXME(HI)
|
||||
return QRegion(rect());
|
||||
}
|
||||
|
||||
//protected slots:
|
||||
void DumpView::dataChanged( const QModelIndex &topLeft,
|
||||
const QModelIndex &bottomRight )
|
||||
{
|
||||
// FIXME(HI)
|
||||
update();
|
||||
}
|
||||
|
||||
void DumpView::selectionChanged( const QItemSelection &selected,
|
||||
const QItemSelection &deselected )
|
||||
{
|
||||
// FIXME(HI)
|
||||
update();
|
||||
}
|
||||
|
||||
void DumpView::populateDump(QByteArray &dump, int &selOfs, int &selSize,
|
||||
QModelIndex parent)
|
||||
{
|
||||
// FIXME: Use new enum instead of Qt::UserRole
|
||||
//! \todo (low): generalize this for any model not just our pkt model
|
||||
|
||||
Q_ASSERT(!parent.isValid());
|
||||
|
||||
qDebug("!!!! %d $$$$", dump.size());
|
||||
|
||||
for(int i = 0; i < model()->rowCount(parent); i++)
|
||||
{
|
||||
QModelIndex index = model()->index(i, 0, parent);
|
||||
|
||||
Q_ASSERT(index.isValid());
|
||||
|
||||
// Assumption: protocol data is in bytes (not bits)
|
||||
qDebug("%d: %d bytes", i, model()->data(index, Qt::UserRole).toByteArray().size());
|
||||
dump.append(model()->data(index, Qt::UserRole).toByteArray());
|
||||
|
||||
}
|
||||
|
||||
if (selectionModel()->selectedIndexes().size())
|
||||
{
|
||||
int j, bits;
|
||||
QModelIndex index;
|
||||
|
||||
Q_ASSERT(selectionModel()->selectedIndexes().size() == 1);
|
||||
index = selectionModel()->selectedIndexes().at(0);
|
||||
|
||||
if (index.parent().isValid())
|
||||
{
|
||||
// Field
|
||||
|
||||
// SelOfs = SUM(protocol sizes before selected field's protocol) +
|
||||
// SUM(field sizes before selected field)
|
||||
|
||||
selOfs = 0;
|
||||
j = index.parent().row() - 1;
|
||||
while (j >= 0)
|
||||
{
|
||||
selOfs += model()->data(index.parent().sibling(j,0),
|
||||
Qt::UserRole).toByteArray().size();
|
||||
j--;
|
||||
}
|
||||
|
||||
bits = 0;
|
||||
j = index.row() - 1;
|
||||
while (j >= 0)
|
||||
{
|
||||
bits += model()->data(index.sibling(j,0), Qt::UserRole+1).
|
||||
toInt();
|
||||
j--;
|
||||
}
|
||||
selOfs += bits/8;
|
||||
selSize = model()->data(index, Qt::UserRole).toByteArray().size();
|
||||
}
|
||||
else
|
||||
{
|
||||
// Protocol
|
||||
selOfs = 0;
|
||||
j = index.row() - 1;
|
||||
while (j >= 0)
|
||||
{
|
||||
selOfs += model()->data(index.sibling(j,0), Qt::UserRole).
|
||||
toByteArray().size();
|
||||
j--;
|
||||
}
|
||||
selSize = model()->data(index, Qt::UserRole).toByteArray().size();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// TODO(LOW): rewrite this function - it's a mess!
|
||||
void DumpView::paintEvent(QPaintEvent* event)
|
||||
{
|
||||
QStylePainter painter(viewport());
|
||||
QRect offsetRect = mOffsetPaneTopRect;
|
||||
QRect dumpRect = mDumpPaneTopRect;
|
||||
QRect asciiRect = mAsciiPaneTopRect;
|
||||
QPalette pal = palette();
|
||||
static QByteArray data;
|
||||
//QByteArray ba;
|
||||
int selOfs = -1, selSize;
|
||||
int curSelOfs, curSelSize;
|
||||
|
||||
qDebug("dumpview::paintEvent");
|
||||
|
||||
// FIXME(LOW): unable to set the self widget's font in constructor
|
||||
painter.setFont(QFont("Courier"));
|
||||
|
||||
// set a white background
|
||||
painter.fillRect(rect(), QBrush(QColor(Qt::white)));
|
||||
|
||||
if (model())
|
||||
{
|
||||
data.clear();
|
||||
populateDump(data, selOfs, selSize);
|
||||
}
|
||||
|
||||
// display the offset, dump and ascii panes 8 + 8 bytes on a line
|
||||
for (int i = 0; i < data.size(); i+=16)
|
||||
{
|
||||
QString dumpStr, asciiStr;
|
||||
|
||||
//ba = data.mid(i, 16);
|
||||
|
||||
// display offset
|
||||
painter.drawItemText(offsetRect, Qt::AlignLeft | Qt::AlignTop, pal,
|
||||
true, QString("%1").arg(i, 4, 16, QChar('0')), QPalette::WindowText);
|
||||
// construct the dumpStr and asciiStr
|
||||
for (int j = i; (j < (i+16)) && (j < data.size()); j++)
|
||||
{
|
||||
unsigned char c = data.at(j);
|
||||
|
||||
// extra space after 8 bytes
|
||||
if (((j+8) % 16) == 0)
|
||||
{
|
||||
dumpStr.append(" ");
|
||||
asciiStr.append(" ");
|
||||
}
|
||||
|
||||
dumpStr.append(QString("%1").arg((uint)c, 2, 16, QChar('0')).
|
||||
toUpper()).append(" ");
|
||||
|
||||
if (isPrintable(c))
|
||||
asciiStr.append(QChar(c));
|
||||
else
|
||||
asciiStr.append(QChar('.'));
|
||||
}
|
||||
|
||||
// display dump
|
||||
painter.drawItemText(dumpRect, Qt::AlignLeft | Qt::AlignTop, pal,
|
||||
true, dumpStr, QPalette::WindowText);
|
||||
|
||||
// display ascii
|
||||
painter.drawItemText(asciiRect, Qt::AlignLeft | Qt::AlignTop, pal,
|
||||
true, asciiStr, QPalette::WindowText);
|
||||
|
||||
// if no selection, skip selection painting
|
||||
if (selOfs < 0)
|
||||
goto _next;
|
||||
|
||||
// Check overlap between current row and selection
|
||||
{
|
||||
QRect r1(i, 0, qMin(16, data.size()-i), 8);
|
||||
QRect s1(selOfs, 0, selSize, 8);
|
||||
if (r1.intersects(s1))
|
||||
{
|
||||
QRect t = r1.intersected(s1);
|
||||
|
||||
curSelOfs = t.x();
|
||||
curSelSize = t.width();
|
||||
}
|
||||
else
|
||||
curSelSize = 0;
|
||||
|
||||
}
|
||||
|
||||
// overpaint selection on current row (if any)
|
||||
if (curSelSize > 0)
|
||||
{
|
||||
QRect r;
|
||||
QString selectedAsciiStr, selectedDumpStr;
|
||||
|
||||
qDebug("dumpview::paintEvent - Highlighted (%d, %d)",
|
||||
curSelOfs, curSelSize);
|
||||
|
||||
// construct the dumpStr and asciiStr
|
||||
for (int k = curSelOfs; (k < (curSelOfs + curSelSize)); k++)
|
||||
{
|
||||
unsigned char c = data.at(k);
|
||||
|
||||
// extra space after 8 bytes
|
||||
if (((k+8) % 16) == 0)
|
||||
{
|
||||
// Avoid adding space at the start for fields starting
|
||||
// at second column 8 byte boundary
|
||||
if (k!=curSelOfs)
|
||||
{
|
||||
selectedDumpStr.append(" ");
|
||||
selectedAsciiStr.append(" ");
|
||||
}
|
||||
}
|
||||
|
||||
selectedDumpStr.append(QString("%1").arg((uint)c, 2, 16,
|
||||
QChar('0')).toUpper()).append(" ");
|
||||
|
||||
if (isPrintable(c))
|
||||
selectedAsciiStr.append(QChar(c));
|
||||
else
|
||||
selectedAsciiStr.append(QChar('.'));
|
||||
}
|
||||
|
||||
// display dump
|
||||
r = dumpRect;
|
||||
if ((curSelOfs - i) < 8)
|
||||
r.translate(mCharWidth*(curSelOfs-i)*3, 0);
|
||||
else
|
||||
r.translate(mCharWidth*((curSelOfs-i)*3+1), 0);
|
||||
|
||||
// adjust width taking care of selection stretching between
|
||||
// the two 8byte columns
|
||||
if (( (curSelOfs-i) < 8 ) && ( (curSelOfs-i+curSelSize) > 8 ))
|
||||
r.setWidth((curSelSize * 3 + 1) * mCharWidth);
|
||||
else
|
||||
r.setWidth((curSelSize * 3) * mCharWidth);
|
||||
|
||||
painter.fillRect(r, pal.highlight());
|
||||
painter.drawItemText(r, Qt::AlignLeft | Qt::AlignTop, pal,
|
||||
true, selectedDumpStr, QPalette::HighlightedText);
|
||||
|
||||
// display ascii
|
||||
r = asciiRect;
|
||||
if ((curSelOfs - i) < 8)
|
||||
r.translate(mCharWidth*(curSelOfs-i)*1, 0);
|
||||
else
|
||||
r.translate(mCharWidth*((curSelOfs-i)*1+1), 0);
|
||||
|
||||
// adjust width taking care of selection stretching between
|
||||
// the two 8byte columns
|
||||
if (( (curSelOfs-i) < 8 ) && ( (curSelOfs-i+curSelSize) > 8 ))
|
||||
r.setWidth((curSelSize * 1 + 1) * mCharWidth);
|
||||
else
|
||||
r.setWidth((curSelSize * 1) * mCharWidth);
|
||||
|
||||
painter.fillRect(r, pal.highlight());
|
||||
painter.drawItemText(r, Qt::AlignLeft | Qt::AlignTop, pal,
|
||||
true, selectedAsciiStr, QPalette::HighlightedText);
|
||||
}
|
||||
|
||||
_next:
|
||||
// move the rects down
|
||||
offsetRect.translate(0, mLineHeight);
|
||||
dumpRect.translate(0, mLineHeight);
|
||||
asciiRect.translate(0, mLineHeight);
|
||||
}
|
||||
}
|
||||
|
||||
#include "dumpview.h"
|
||||
|
||||
//! \todo Enable Scrollbars
|
||||
|
||||
DumpView::DumpView(QWidget *parent)
|
||||
{
|
||||
int w, h;
|
||||
|
||||
// NOTE: Monospaced fonts only !!!!!!!!!!!
|
||||
setFont(QFont("Courier"));
|
||||
w = fontMetrics().width('X');
|
||||
h = fontMetrics().height();
|
||||
|
||||
mLineHeight = h;
|
||||
mCharWidth = w;
|
||||
|
||||
mSelectedRow = mSelectedCol = -1;
|
||||
|
||||
// calculate width for offset column and the whitespace that follows it
|
||||
// 0010 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ........ ........
|
||||
mOffsetPaneTopRect = QRect(0, 0, w*4, h);
|
||||
mDumpPaneTopRect = QRect(mOffsetPaneTopRect.right()+w*3, 0,
|
||||
w*((8*3-1)+2+(8*3-1)), h);
|
||||
mAsciiPaneTopRect = QRect(mDumpPaneTopRect.right()+w*3, 0,
|
||||
w*(8+1+8), h);
|
||||
qDebug("DumpView::DumpView");
|
||||
}
|
||||
|
||||
QModelIndex DumpView::indexAt( const QPoint &point ) const
|
||||
{
|
||||
#if 0
|
||||
int x = point.x();
|
||||
int row, col;
|
||||
|
||||
if (x > mAsciiPaneTopRect.left())
|
||||
{
|
||||
col = (x - mAsciiPaneTopRect.left()) / mCharWidth;
|
||||
if (col == 8) // don't select whitespace
|
||||
goto _exit;
|
||||
else if (col > 8) // adjust for whitespace
|
||||
col--;
|
||||
}
|
||||
else if (x > mDumpPaneTopRect.left())
|
||||
{
|
||||
col = (x - mDumpPaneTopRect.left()) / (mCharWidth*3);
|
||||
}
|
||||
row = point.y()/mLineHeight;
|
||||
|
||||
if ((col < 16) && (row < ((data.size()+16)/16)))
|
||||
{
|
||||
selrow = row;
|
||||
selcol = col;
|
||||
}
|
||||
else
|
||||
goto _exit;
|
||||
|
||||
// last row check col
|
||||
if ((row == (((data.size()+16)/16) - 1)) && (col >= (data.size() % 16)))
|
||||
goto _exit;
|
||||
|
||||
qDebug("dumpview::selection(%d, %d)", selrow, selcol);
|
||||
|
||||
offset = selrow * 16 + selcol;
|
||||
#if 0
|
||||
for(int i = 0; i < model()->rowCount(parent); i++)
|
||||
{
|
||||
QModelIndex index = model()->index(i, 0, parent);
|
||||
|
||||
if (model()->hasChildren(index))
|
||||
indexAtOffset(offset, index); // Non Leaf
|
||||
else
|
||||
if (
|
||||
dump.append(model()->data(index, Qt::UserRole).toByteArray()); // Leaf
|
||||
// FIXME: Use RawValueRole instead of UserRole
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
_exit:
|
||||
// Clear existing selection
|
||||
selrow = -1;
|
||||
|
||||
#endif
|
||||
return QModelIndex();
|
||||
}
|
||||
|
||||
void DumpView::scrollTo( const QModelIndex &index, ScrollHint hint )
|
||||
{
|
||||
// FIXME: implement scrolling
|
||||
}
|
||||
|
||||
QRect DumpView::visualRect( const QModelIndex &index ) const
|
||||
{
|
||||
// FIXME: calculate actual rect
|
||||
return rect();
|
||||
}
|
||||
|
||||
//protected:
|
||||
int DumpView::horizontalOffset() const
|
||||
{
|
||||
return horizontalScrollBar()->value();
|
||||
}
|
||||
|
||||
bool DumpView::isIndexHidden( const QModelIndex &index ) const
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
QModelIndex DumpView::moveCursor( CursorAction cursorAction,
|
||||
Qt::KeyboardModifiers modifiers )
|
||||
{
|
||||
// FIXME(MED): need to implement movement using cursor
|
||||
return currentIndex();
|
||||
}
|
||||
|
||||
void DumpView::setSelection( const QRect &rect,
|
||||
QItemSelectionModel::SelectionFlags flags )
|
||||
{
|
||||
// FIXME(HI): calculate indexes using rect
|
||||
selectionModel()->select(QModelIndex(), flags);
|
||||
}
|
||||
|
||||
int DumpView::verticalOffset() const
|
||||
{
|
||||
return verticalScrollBar()->value();
|
||||
}
|
||||
|
||||
QRegion DumpView::visualRegionForSelection( const QItemSelection &selection ) const
|
||||
{
|
||||
// FIXME(HI)
|
||||
return QRegion(rect());
|
||||
}
|
||||
|
||||
//protected slots:
|
||||
void DumpView::dataChanged( const QModelIndex &topLeft,
|
||||
const QModelIndex &bottomRight )
|
||||
{
|
||||
// FIXME(HI)
|
||||
update();
|
||||
}
|
||||
|
||||
void DumpView::selectionChanged( const QItemSelection &selected,
|
||||
const QItemSelection &deselected )
|
||||
{
|
||||
// FIXME(HI)
|
||||
update();
|
||||
}
|
||||
|
||||
void DumpView::populateDump(QByteArray &dump, int &selOfs, int &selSize,
|
||||
QModelIndex parent)
|
||||
{
|
||||
// FIXME: Use new enum instead of Qt::UserRole
|
||||
//! \todo (low): generalize this for any model not just our pkt model
|
||||
|
||||
Q_ASSERT(!parent.isValid());
|
||||
|
||||
qDebug("!!!! %d $$$$", dump.size());
|
||||
|
||||
for(int i = 0; i < model()->rowCount(parent); i++)
|
||||
{
|
||||
QModelIndex index = model()->index(i, 0, parent);
|
||||
|
||||
Q_ASSERT(index.isValid());
|
||||
|
||||
// Assumption: protocol data is in bytes (not bits)
|
||||
qDebug("%d: %d bytes", i, model()->data(index, Qt::UserRole).toByteArray().size());
|
||||
dump.append(model()->data(index, Qt::UserRole).toByteArray());
|
||||
|
||||
}
|
||||
|
||||
if (selectionModel()->selectedIndexes().size())
|
||||
{
|
||||
int j, bits;
|
||||
QModelIndex index;
|
||||
|
||||
Q_ASSERT(selectionModel()->selectedIndexes().size() == 1);
|
||||
index = selectionModel()->selectedIndexes().at(0);
|
||||
|
||||
if (index.parent().isValid())
|
||||
{
|
||||
// Field
|
||||
|
||||
// SelOfs = SUM(protocol sizes before selected field's protocol) +
|
||||
// SUM(field sizes before selected field)
|
||||
|
||||
selOfs = 0;
|
||||
j = index.parent().row() - 1;
|
||||
while (j >= 0)
|
||||
{
|
||||
selOfs += model()->data(index.parent().sibling(j,0),
|
||||
Qt::UserRole).toByteArray().size();
|
||||
j--;
|
||||
}
|
||||
|
||||
bits = 0;
|
||||
j = index.row() - 1;
|
||||
while (j >= 0)
|
||||
{
|
||||
bits += model()->data(index.sibling(j,0), Qt::UserRole+1).
|
||||
toInt();
|
||||
j--;
|
||||
}
|
||||
selOfs += bits/8;
|
||||
selSize = model()->data(index, Qt::UserRole).toByteArray().size();
|
||||
}
|
||||
else
|
||||
{
|
||||
// Protocol
|
||||
selOfs = 0;
|
||||
j = index.row() - 1;
|
||||
while (j >= 0)
|
||||
{
|
||||
selOfs += model()->data(index.sibling(j,0), Qt::UserRole).
|
||||
toByteArray().size();
|
||||
j--;
|
||||
}
|
||||
selSize = model()->data(index, Qt::UserRole).toByteArray().size();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// TODO(LOW): rewrite this function - it's a mess!
|
||||
void DumpView::paintEvent(QPaintEvent* event)
|
||||
{
|
||||
QStylePainter painter(viewport());
|
||||
QRect offsetRect = mOffsetPaneTopRect;
|
||||
QRect dumpRect = mDumpPaneTopRect;
|
||||
QRect asciiRect = mAsciiPaneTopRect;
|
||||
QPalette pal = palette();
|
||||
static QByteArray data;
|
||||
//QByteArray ba;
|
||||
int selOfs = -1, selSize;
|
||||
int curSelOfs, curSelSize;
|
||||
|
||||
qDebug("dumpview::paintEvent");
|
||||
|
||||
// FIXME(LOW): unable to set the self widget's font in constructor
|
||||
painter.setFont(QFont("Courier"));
|
||||
|
||||
// set a white background
|
||||
painter.fillRect(rect(), QBrush(QColor(Qt::white)));
|
||||
|
||||
if (model())
|
||||
{
|
||||
data.clear();
|
||||
populateDump(data, selOfs, selSize);
|
||||
}
|
||||
|
||||
// display the offset, dump and ascii panes 8 + 8 bytes on a line
|
||||
for (int i = 0; i < data.size(); i+=16)
|
||||
{
|
||||
QString dumpStr, asciiStr;
|
||||
|
||||
//ba = data.mid(i, 16);
|
||||
|
||||
// display offset
|
||||
painter.drawItemText(offsetRect, Qt::AlignLeft | Qt::AlignTop, pal,
|
||||
true, QString("%1").arg(i, 4, 16, QChar('0')), QPalette::WindowText);
|
||||
// construct the dumpStr and asciiStr
|
||||
for (int j = i; (j < (i+16)) && (j < data.size()); j++)
|
||||
{
|
||||
unsigned char c = data.at(j);
|
||||
|
||||
// extra space after 8 bytes
|
||||
if (((j+8) % 16) == 0)
|
||||
{
|
||||
dumpStr.append(" ");
|
||||
asciiStr.append(" ");
|
||||
}
|
||||
|
||||
dumpStr.append(QString("%1").arg((uint)c, 2, 16, QChar('0')).
|
||||
toUpper()).append(" ");
|
||||
|
||||
if (isPrintable(c))
|
||||
asciiStr.append(QChar(c));
|
||||
else
|
||||
asciiStr.append(QChar('.'));
|
||||
}
|
||||
|
||||
// display dump
|
||||
painter.drawItemText(dumpRect, Qt::AlignLeft | Qt::AlignTop, pal,
|
||||
true, dumpStr, QPalette::WindowText);
|
||||
|
||||
// display ascii
|
||||
painter.drawItemText(asciiRect, Qt::AlignLeft | Qt::AlignTop, pal,
|
||||
true, asciiStr, QPalette::WindowText);
|
||||
|
||||
// if no selection, skip selection painting
|
||||
if (selOfs < 0)
|
||||
goto _next;
|
||||
|
||||
// Check overlap between current row and selection
|
||||
{
|
||||
QRect r1(i, 0, qMin(16, data.size()-i), 8);
|
||||
QRect s1(selOfs, 0, selSize, 8);
|
||||
if (r1.intersects(s1))
|
||||
{
|
||||
QRect t = r1.intersected(s1);
|
||||
|
||||
curSelOfs = t.x();
|
||||
curSelSize = t.width();
|
||||
}
|
||||
else
|
||||
curSelSize = 0;
|
||||
|
||||
}
|
||||
|
||||
// overpaint selection on current row (if any)
|
||||
if (curSelSize > 0)
|
||||
{
|
||||
QRect r;
|
||||
QString selectedAsciiStr, selectedDumpStr;
|
||||
|
||||
qDebug("dumpview::paintEvent - Highlighted (%d, %d)",
|
||||
curSelOfs, curSelSize);
|
||||
|
||||
// construct the dumpStr and asciiStr
|
||||
for (int k = curSelOfs; (k < (curSelOfs + curSelSize)); k++)
|
||||
{
|
||||
unsigned char c = data.at(k);
|
||||
|
||||
// extra space after 8 bytes
|
||||
if (((k+8) % 16) == 0)
|
||||
{
|
||||
// Avoid adding space at the start for fields starting
|
||||
// at second column 8 byte boundary
|
||||
if (k!=curSelOfs)
|
||||
{
|
||||
selectedDumpStr.append(" ");
|
||||
selectedAsciiStr.append(" ");
|
||||
}
|
||||
}
|
||||
|
||||
selectedDumpStr.append(QString("%1").arg((uint)c, 2, 16,
|
||||
QChar('0')).toUpper()).append(" ");
|
||||
|
||||
if (isPrintable(c))
|
||||
selectedAsciiStr.append(QChar(c));
|
||||
else
|
||||
selectedAsciiStr.append(QChar('.'));
|
||||
}
|
||||
|
||||
// display dump
|
||||
r = dumpRect;
|
||||
if ((curSelOfs - i) < 8)
|
||||
r.translate(mCharWidth*(curSelOfs-i)*3, 0);
|
||||
else
|
||||
r.translate(mCharWidth*((curSelOfs-i)*3+1), 0);
|
||||
|
||||
// adjust width taking care of selection stretching between
|
||||
// the two 8byte columns
|
||||
if (( (curSelOfs-i) < 8 ) && ( (curSelOfs-i+curSelSize) > 8 ))
|
||||
r.setWidth((curSelSize * 3 + 1) * mCharWidth);
|
||||
else
|
||||
r.setWidth((curSelSize * 3) * mCharWidth);
|
||||
|
||||
painter.fillRect(r, pal.highlight());
|
||||
painter.drawItemText(r, Qt::AlignLeft | Qt::AlignTop, pal,
|
||||
true, selectedDumpStr, QPalette::HighlightedText);
|
||||
|
||||
// display ascii
|
||||
r = asciiRect;
|
||||
if ((curSelOfs - i) < 8)
|
||||
r.translate(mCharWidth*(curSelOfs-i)*1, 0);
|
||||
else
|
||||
r.translate(mCharWidth*((curSelOfs-i)*1+1), 0);
|
||||
|
||||
// adjust width taking care of selection stretching between
|
||||
// the two 8byte columns
|
||||
if (( (curSelOfs-i) < 8 ) && ( (curSelOfs-i+curSelSize) > 8 ))
|
||||
r.setWidth((curSelSize * 1 + 1) * mCharWidth);
|
||||
else
|
||||
r.setWidth((curSelSize * 1) * mCharWidth);
|
||||
|
||||
painter.fillRect(r, pal.highlight());
|
||||
painter.drawItemText(r, Qt::AlignLeft | Qt::AlignTop, pal,
|
||||
true, selectedAsciiStr, QPalette::HighlightedText);
|
||||
}
|
||||
|
||||
_next:
|
||||
// move the rects down
|
||||
offsetRect.translate(0, mLineHeight);
|
||||
dumpRect.translate(0, mLineHeight);
|
||||
asciiRect.translate(0, mLineHeight);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -1,42 +1,42 @@
|
||||
#include <QtGui> // FIXME: High
|
||||
|
||||
|
||||
class DumpView: public QAbstractItemView
|
||||
{
|
||||
public:
|
||||
DumpView(QWidget *parent=0);
|
||||
|
||||
QModelIndex indexAt( const QPoint &point ) const;
|
||||
void scrollTo( const QModelIndex &index, ScrollHint hint = EnsureVisible );
|
||||
QRect visualRect( const QModelIndex &index ) const;
|
||||
|
||||
protected:
|
||||
int horizontalOffset() const;
|
||||
bool isIndexHidden( const QModelIndex &index ) const;
|
||||
QModelIndex moveCursor( CursorAction cursorAction,
|
||||
Qt::KeyboardModifiers modifiers );
|
||||
void setSelection( const QRect &rect, QItemSelectionModel::SelectionFlags flags );
|
||||
int verticalOffset() const;
|
||||
QRegion visualRegionForSelection( const QItemSelection &selection ) const;
|
||||
protected slots:
|
||||
void dataChanged( const QModelIndex &topLeft,
|
||||
const QModelIndex &bottomRight );
|
||||
void selectionChanged( const QItemSelection &selected,
|
||||
const QItemSelection &deselected );
|
||||
void paintEvent(QPaintEvent *event);
|
||||
|
||||
private:
|
||||
void populateDump(QByteArray &dump, int &selOfs, int &selSize,
|
||||
QModelIndex parent = QModelIndex());
|
||||
bool inline isPrintable(char c)
|
||||
{if ((c > 48) && (c < 126)) return true; else return false; }
|
||||
|
||||
private:
|
||||
QRect mOffsetPaneTopRect;
|
||||
QRect mDumpPaneTopRect;
|
||||
QRect mAsciiPaneTopRect;
|
||||
int mSelectedRow, mSelectedCol;
|
||||
int mLineHeight;
|
||||
int mCharWidth;
|
||||
};
|
||||
|
||||
#include <QtGui> // FIXME: High
|
||||
|
||||
|
||||
class DumpView: public QAbstractItemView
|
||||
{
|
||||
public:
|
||||
DumpView(QWidget *parent=0);
|
||||
|
||||
QModelIndex indexAt( const QPoint &point ) const;
|
||||
void scrollTo( const QModelIndex &index, ScrollHint hint = EnsureVisible );
|
||||
QRect visualRect( const QModelIndex &index ) const;
|
||||
|
||||
protected:
|
||||
int horizontalOffset() const;
|
||||
bool isIndexHidden( const QModelIndex &index ) const;
|
||||
QModelIndex moveCursor( CursorAction cursorAction,
|
||||
Qt::KeyboardModifiers modifiers );
|
||||
void setSelection( const QRect &rect, QItemSelectionModel::SelectionFlags flags );
|
||||
int verticalOffset() const;
|
||||
QRegion visualRegionForSelection( const QItemSelection &selection ) const;
|
||||
protected slots:
|
||||
void dataChanged( const QModelIndex &topLeft,
|
||||
const QModelIndex &bottomRight );
|
||||
void selectionChanged( const QItemSelection &selected,
|
||||
const QItemSelection &deselected );
|
||||
void paintEvent(QPaintEvent *event);
|
||||
|
||||
private:
|
||||
void populateDump(QByteArray &dump, int &selOfs, int &selSize,
|
||||
QModelIndex parent = QModelIndex());
|
||||
bool inline isPrintable(char c)
|
||||
{if ((c > 48) && (c < 126)) return true; else return false; }
|
||||
|
||||
private:
|
||||
QRect mOffsetPaneTopRect;
|
||||
QRect mDumpPaneTopRect;
|
||||
QRect mAsciiPaneTopRect;
|
||||
int mSelectedRow, mSelectedCol;
|
||||
int mLineHeight;
|
||||
int mCharWidth;
|
||||
};
|
||||
|
||||
|
@ -1,72 +1,72 @@
|
||||
#include "hexlineedit.h"
|
||||
#include "qdebug.h"
|
||||
|
||||
QString & uintToHexStr(quint64 num, QString &hexStr, quint8 octets);
|
||||
|
||||
HexLineEdit::HexLineEdit( QWidget * parent)
|
||||
: QLineEdit(parent)
|
||||
{
|
||||
//QLineEdit::QLineEdit(parent);
|
||||
}
|
||||
|
||||
void HexLineEdit::focusOutEvent( QFocusEvent *e )
|
||||
{
|
||||
#if 0
|
||||
const QValidator *v = validator();
|
||||
if ( v )
|
||||
{
|
||||
int curpos = cursorPosition();
|
||||
QString str = text();
|
||||
if ( v->validate( str, curpos ) == QValidator::Acceptable )
|
||||
{
|
||||
if ( curpos != cursorPosition() )
|
||||
setCursorPosition( curpos );
|
||||
if ( str != text() )
|
||||
setText( str );
|
||||
}
|
||||
else
|
||||
{
|
||||
if ( curpos != cursorPosition() )
|
||||
setCursorPosition( curpos );
|
||||
str = text();
|
||||
v->fixup( str );
|
||||
if ( str != text() )
|
||||
{
|
||||
setText( str );
|
||||
}
|
||||
}
|
||||
}
|
||||
QLineEdit::focusOutEvent( e );
|
||||
emit focusOut();
|
||||
#else
|
||||
#define uintToHexStr(num, bytesize) \
|
||||
QString("%1").arg((num), (bytesize)*2 , 16, QChar('0'))
|
||||
|
||||
bool isOk;
|
||||
ulong num;
|
||||
|
||||
qDebug("before = %s\n", text().toAscii().data());
|
||||
num = text().remove(QChar(' ')).toULong(&isOk, 16);
|
||||
setText(uintToHexStr(num, 4));
|
||||
qDebug("after = %s\n", text().toAscii().data());
|
||||
#undef uintToHexStr
|
||||
#endif
|
||||
}
|
||||
|
||||
#if 0
|
||||
void HexLineEdit::focusInEvent( QFocusEvent *e )
|
||||
{
|
||||
QLineEdit::focusInEvent( e );
|
||||
emit focusIn();
|
||||
}
|
||||
|
||||
void HexLineEdit::keyPressEvent( QKeyEvent *e )
|
||||
{
|
||||
QLineEdit::keyPressEvent( e );
|
||||
if ( e->key() == Key_Enter || e->key() == Key_Return )
|
||||
{
|
||||
setSelection( 0, text().length() );
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
#include "hexlineedit.h"
|
||||
#include "qdebug.h"
|
||||
|
||||
QString & uintToHexStr(quint64 num, QString &hexStr, quint8 octets);
|
||||
|
||||
HexLineEdit::HexLineEdit( QWidget * parent)
|
||||
: QLineEdit(parent)
|
||||
{
|
||||
//QLineEdit::QLineEdit(parent);
|
||||
}
|
||||
|
||||
void HexLineEdit::focusOutEvent( QFocusEvent *e )
|
||||
{
|
||||
#if 0
|
||||
const QValidator *v = validator();
|
||||
if ( v )
|
||||
{
|
||||
int curpos = cursorPosition();
|
||||
QString str = text();
|
||||
if ( v->validate( str, curpos ) == QValidator::Acceptable )
|
||||
{
|
||||
if ( curpos != cursorPosition() )
|
||||
setCursorPosition( curpos );
|
||||
if ( str != text() )
|
||||
setText( str );
|
||||
}
|
||||
else
|
||||
{
|
||||
if ( curpos != cursorPosition() )
|
||||
setCursorPosition( curpos );
|
||||
str = text();
|
||||
v->fixup( str );
|
||||
if ( str != text() )
|
||||
{
|
||||
setText( str );
|
||||
}
|
||||
}
|
||||
}
|
||||
QLineEdit::focusOutEvent( e );
|
||||
emit focusOut();
|
||||
#else
|
||||
#define uintToHexStr(num, bytesize) \
|
||||
QString("%1").arg((num), (bytesize)*2 , 16, QChar('0'))
|
||||
|
||||
bool isOk;
|
||||
ulong num;
|
||||
|
||||
qDebug("before = %s\n", text().toAscii().data());
|
||||
num = text().remove(QChar(' ')).toULong(&isOk, 16);
|
||||
setText(uintToHexStr(num, 4));
|
||||
qDebug("after = %s\n", text().toAscii().data());
|
||||
#undef uintToHexStr
|
||||
#endif
|
||||
}
|
||||
|
||||
#if 0
|
||||
void HexLineEdit::focusInEvent( QFocusEvent *e )
|
||||
{
|
||||
QLineEdit::focusInEvent( e );
|
||||
emit focusIn();
|
||||
}
|
||||
|
||||
void HexLineEdit::keyPressEvent( QKeyEvent *e )
|
||||
{
|
||||
QLineEdit::keyPressEvent( e );
|
||||
if ( e->key() == Key_Enter || e->key() == Key_Return )
|
||||
{
|
||||
setSelection( 0, text().length() );
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
|
@ -1,24 +1,24 @@
|
||||
#ifndef _HEXLINEEDIT
|
||||
#define _HEXLINEEDIT
|
||||
|
||||
#include <QLineEdit>
|
||||
|
||||
class HexLineEdit : public QLineEdit
|
||||
{
|
||||
Q_OBJECT
|
||||
public:
|
||||
// Constructors
|
||||
HexLineEdit ( QWidget * parent);
|
||||
|
||||
protected:
|
||||
void focusOutEvent( QFocusEvent *e );
|
||||
//void focusInEvent( QFocusEvent *e );
|
||||
//void keyPressEvent( QKeyEvent *e );
|
||||
|
||||
signals:
|
||||
//void focusIn();
|
||||
void focusOut();
|
||||
};
|
||||
|
||||
#endif
|
||||
|
||||
#ifndef _HEXLINEEDIT
|
||||
#define _HEXLINEEDIT
|
||||
|
||||
#include <QLineEdit>
|
||||
|
||||
class HexLineEdit : public QLineEdit
|
||||
{
|
||||
Q_OBJECT
|
||||
public:
|
||||
// Constructors
|
||||
HexLineEdit ( QWidget * parent);
|
||||
|
||||
protected:
|
||||
void focusOutEvent( QFocusEvent *e );
|
||||
//void focusInEvent( QFocusEvent *e );
|
||||
//void keyPressEvent( QKeyEvent *e );
|
||||
|
||||
signals:
|
||||
//void focusIn();
|
||||
void focusOut();
|
||||
};
|
||||
|
||||
#endif
|
||||
|
||||
|
@ -1,12 +1,12 @@
|
||||
#include "mainwindow.h"
|
||||
|
||||
#include <QApplication>
|
||||
|
||||
int main(int argc, char* argv[])
|
||||
{
|
||||
QApplication app(argc, argv);
|
||||
MainWindow mainWin;
|
||||
|
||||
mainWin.show();
|
||||
return app.exec();
|
||||
}
|
||||
#include "mainwindow.h"
|
||||
|
||||
#include <QApplication>
|
||||
|
||||
int main(int argc, char* argv[])
|
||||
{
|
||||
QApplication app(argc, argv);
|
||||
MainWindow mainWin;
|
||||
|
||||
mainWin.show();
|
||||
return app.exec();
|
||||
}
|
||||
|
@ -1,65 +1,65 @@
|
||||
#include "mainwindow.h"
|
||||
|
||||
#if 0
|
||||
#include "dbgthread.h"
|
||||
#endif
|
||||
|
||||
#include "portgrouplist.h"
|
||||
#include "portstatswindow.h"
|
||||
#include "portswindow.h"
|
||||
#include "ui_about.h"
|
||||
|
||||
#include <QDockWidget>
|
||||
#include <QProcess>
|
||||
|
||||
PortGroupList *pgl;
|
||||
|
||||
MainWindow::MainWindow(QWidget *parent)
|
||||
: QMainWindow (parent)
|
||||
{
|
||||
localServer_ = new QProcess(this);
|
||||
localServer_->start("drone.exe");
|
||||
|
||||
pgl = new PortGroupList;
|
||||
|
||||
portsWindow = new PortsWindow(pgl, this);
|
||||
statsWindow = new PortStatsWindow(pgl, this);
|
||||
portsDock = new QDockWidget(tr("Ports"), this);
|
||||
statsDock = new QDockWidget(tr("Stats"), this);
|
||||
|
||||
setupUi(this);
|
||||
|
||||
statsDock->setWidget(statsWindow);
|
||||
addDockWidget(Qt::BottomDockWidgetArea, statsDock);
|
||||
portsDock->setWidget(portsWindow);
|
||||
addDockWidget(Qt::TopDockWidgetArea, portsDock);
|
||||
|
||||
connect(actionFileExit, SIGNAL(triggered()), this, SLOT(close()));
|
||||
#if 0
|
||||
{
|
||||
DbgThread *dbg = new DbgThread(pgl);
|
||||
dbg->start();
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
MainWindow::~MainWindow()
|
||||
{
|
||||
delete pgl;
|
||||
localServer_->terminate();
|
||||
localServer_->waitForFinished();
|
||||
delete localServer_;
|
||||
}
|
||||
|
||||
void MainWindow::on_actionHelpAbout_triggered()
|
||||
{
|
||||
QDialog *aboutDialog = new QDialog;
|
||||
|
||||
Ui::About about;
|
||||
about.setupUi(aboutDialog);
|
||||
|
||||
aboutDialog->exec();
|
||||
|
||||
delete aboutDialog;
|
||||
}
|
||||
|
||||
#include "mainwindow.h"
|
||||
|
||||
#if 0
|
||||
#include "dbgthread.h"
|
||||
#endif
|
||||
|
||||
#include "portgrouplist.h"
|
||||
#include "portstatswindow.h"
|
||||
#include "portswindow.h"
|
||||
#include "ui_about.h"
|
||||
|
||||
#include <QDockWidget>
|
||||
#include <QProcess>
|
||||
|
||||
PortGroupList *pgl;
|
||||
|
||||
MainWindow::MainWindow(QWidget *parent)
|
||||
: QMainWindow (parent)
|
||||
{
|
||||
localServer_ = new QProcess(this);
|
||||
localServer_->start("drone.exe");
|
||||
|
||||
pgl = new PortGroupList;
|
||||
|
||||
portsWindow = new PortsWindow(pgl, this);
|
||||
statsWindow = new PortStatsWindow(pgl, this);
|
||||
portsDock = new QDockWidget(tr("Ports"), this);
|
||||
statsDock = new QDockWidget(tr("Stats"), this);
|
||||
|
||||
setupUi(this);
|
||||
|
||||
statsDock->setWidget(statsWindow);
|
||||
addDockWidget(Qt::BottomDockWidgetArea, statsDock);
|
||||
portsDock->setWidget(portsWindow);
|
||||
addDockWidget(Qt::TopDockWidgetArea, portsDock);
|
||||
|
||||
connect(actionFileExit, SIGNAL(triggered()), this, SLOT(close()));
|
||||
#if 0
|
||||
{
|
||||
DbgThread *dbg = new DbgThread(pgl);
|
||||
dbg->start();
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
MainWindow::~MainWindow()
|
||||
{
|
||||
delete pgl;
|
||||
localServer_->terminate();
|
||||
localServer_->waitForFinished();
|
||||
delete localServer_;
|
||||
}
|
||||
|
||||
void MainWindow::on_actionHelpAbout_triggered()
|
||||
{
|
||||
QDialog *aboutDialog = new QDialog;
|
||||
|
||||
Ui::About about;
|
||||
about.setupUi(aboutDialog);
|
||||
|
||||
aboutDialog->exec();
|
||||
|
||||
delete aboutDialog;
|
||||
}
|
||||
|
||||
|
@ -1,33 +1,33 @@
|
||||
#ifndef _MAIN_WINDOW_H
|
||||
#define _MAIN_WINDOW_H
|
||||
|
||||
#include "ui_mainwindow.h"
|
||||
#include <QMainWindow>
|
||||
|
||||
class PortsWindow;
|
||||
class PortStatsWindow;
|
||||
|
||||
class QDockWidget;
|
||||
class QProcess;
|
||||
|
||||
class MainWindow : public QMainWindow, private Ui::MainWindow
|
||||
{
|
||||
Q_OBJECT
|
||||
|
||||
private:
|
||||
QProcess *localServer_;
|
||||
PortsWindow *portsWindow;
|
||||
PortStatsWindow *statsWindow;
|
||||
QDockWidget *portsDock;
|
||||
QDockWidget *statsDock;
|
||||
|
||||
public:
|
||||
MainWindow(QWidget *parent = 0);
|
||||
~MainWindow();
|
||||
|
||||
public slots:
|
||||
void on_actionHelpAbout_triggered();
|
||||
};
|
||||
|
||||
#endif
|
||||
|
||||
#ifndef _MAIN_WINDOW_H
|
||||
#define _MAIN_WINDOW_H
|
||||
|
||||
#include "ui_mainwindow.h"
|
||||
#include <QMainWindow>
|
||||
|
||||
class PortsWindow;
|
||||
class PortStatsWindow;
|
||||
|
||||
class QDockWidget;
|
||||
class QProcess;
|
||||
|
||||
class MainWindow : public QMainWindow, private Ui::MainWindow
|
||||
{
|
||||
Q_OBJECT
|
||||
|
||||
private:
|
||||
QProcess *localServer_;
|
||||
PortsWindow *portsWindow;
|
||||
PortStatsWindow *statsWindow;
|
||||
QDockWidget *portsDock;
|
||||
QDockWidget *statsDock;
|
||||
|
||||
public:
|
||||
MainWindow(QWidget *parent = 0);
|
||||
~MainWindow();
|
||||
|
||||
public slots:
|
||||
void on_actionHelpAbout_triggered();
|
||||
};
|
||||
|
||||
#endif
|
||||
|
||||
|
@ -1,57 +1,57 @@
|
||||
TEMPLATE = app
|
||||
CONFIG += qt debug
|
||||
QT += network script
|
||||
INCLUDEPATH += "../rpc/" "../common/"
|
||||
LIBS += -lprotobuf
|
||||
win32:LIBS += -L"../common/debug" -lostproto
|
||||
unix: LIBS += -L"../common" -lostproto
|
||||
win32:LIBS += -L"../rpc/debug" -lpbrpc
|
||||
unix:LIBS += -L"../rpc" -lpbrpc
|
||||
POST_TARGETDEPS += "../common/debug/libostproto.a" "../rpc/debug/libpbrpc.a"
|
||||
RESOURCES += ostinato.qrc
|
||||
HEADERS += \
|
||||
dumpview.h \
|
||||
hexlineedit.h \
|
||||
mainwindow.h \
|
||||
packetmodel.h \
|
||||
port.h \
|
||||
portgroup.h \
|
||||
portgrouplist.h \
|
||||
portmodel.h \
|
||||
portstatsmodel.h \
|
||||
portstatsfilterdialog.h \
|
||||
portstatswindow.h \
|
||||
portswindow.h \
|
||||
streamconfigdialog.h \
|
||||
streamlistdelegate.h \
|
||||
streammodel.h
|
||||
|
||||
FORMS += \
|
||||
about.ui \
|
||||
mainwindow.ui \
|
||||
portstatsfilter.ui \
|
||||
portstatswindow.ui \
|
||||
portswindow.ui \
|
||||
streamconfigdialog.ui
|
||||
|
||||
SOURCES += \
|
||||
dumpview.cpp \
|
||||
stream.cpp \
|
||||
hexlineedit.cpp \
|
||||
main.cpp \
|
||||
mainwindow.cpp \
|
||||
packetmodel.cpp \
|
||||
port.cpp \
|
||||
portgroup.cpp \
|
||||
portgrouplist.cpp \
|
||||
portmodel.cpp \
|
||||
portstatsmodel.cpp \
|
||||
portstatsfilterdialog.cpp \
|
||||
portstatswindow.cpp \
|
||||
portswindow.cpp \
|
||||
streamconfigdialog.cpp \
|
||||
streamlistdelegate.cpp \
|
||||
streammodel.cpp
|
||||
|
||||
# TODO(LOW): Test only
|
||||
include(modeltest.pri)
|
||||
TEMPLATE = app
|
||||
CONFIG += qt debug
|
||||
QT += network script
|
||||
INCLUDEPATH += "../rpc/" "../common/"
|
||||
LIBS += -lprotobuf
|
||||
win32:LIBS += -L"../common/debug" -lostproto
|
||||
unix: LIBS += -L"../common" -lostproto
|
||||
win32:LIBS += -L"../rpc/debug" -lpbrpc
|
||||
unix:LIBS += -L"../rpc" -lpbrpc
|
||||
POST_TARGETDEPS += "../common/debug/libostproto.a" "../rpc/debug/libpbrpc.a"
|
||||
RESOURCES += ostinato.qrc
|
||||
HEADERS += \
|
||||
dumpview.h \
|
||||
hexlineedit.h \
|
||||
mainwindow.h \
|
||||
packetmodel.h \
|
||||
port.h \
|
||||
portgroup.h \
|
||||
portgrouplist.h \
|
||||
portmodel.h \
|
||||
portstatsmodel.h \
|
||||
portstatsfilterdialog.h \
|
||||
portstatswindow.h \
|
||||
portswindow.h \
|
||||
streamconfigdialog.h \
|
||||
streamlistdelegate.h \
|
||||
streammodel.h
|
||||
|
||||
FORMS += \
|
||||
about.ui \
|
||||
mainwindow.ui \
|
||||
portstatsfilter.ui \
|
||||
portstatswindow.ui \
|
||||
portswindow.ui \
|
||||
streamconfigdialog.ui
|
||||
|
||||
SOURCES += \
|
||||
dumpview.cpp \
|
||||
stream.cpp \
|
||||
hexlineedit.cpp \
|
||||
main.cpp \
|
||||
mainwindow.cpp \
|
||||
packetmodel.cpp \
|
||||
port.cpp \
|
||||
portgroup.cpp \
|
||||
portgrouplist.cpp \
|
||||
portmodel.cpp \
|
||||
portstatsmodel.cpp \
|
||||
portstatsfilterdialog.cpp \
|
||||
portstatswindow.cpp \
|
||||
portswindow.cpp \
|
||||
streamconfigdialog.cpp \
|
||||
streamlistdelegate.cpp \
|
||||
streammodel.cpp
|
||||
|
||||
# TODO(LOW): Test only
|
||||
include(modeltest.pri)
|
||||
|
@ -1,220 +1,220 @@
|
||||
#include <QHostAddress>
|
||||
|
||||
#include "packetmodel.h"
|
||||
#include "../common/protocollistiterator.h"
|
||||
#include "../common/abstractprotocol.h"
|
||||
|
||||
PacketModel::PacketModel(QObject *parent)
|
||||
{
|
||||
}
|
||||
|
||||
void PacketModel::setSelectedProtocols(ProtocolListIterator &iter)
|
||||
{
|
||||
QList<const AbstractProtocol*> currentProtocols;
|
||||
|
||||
iter.toFront();
|
||||
while (iter.hasNext())
|
||||
currentProtocols.append(iter.next());
|
||||
|
||||
if (mSelectedProtocols != currentProtocols)
|
||||
{
|
||||
mSelectedProtocols = currentProtocols;
|
||||
reset();
|
||||
}
|
||||
}
|
||||
|
||||
int PacketModel::rowCount(const QModelIndex &parent) const
|
||||
{
|
||||
IndexId parentId;
|
||||
|
||||
// qDebug("in %s", __FUNCTION__);
|
||||
|
||||
// Parent == Invalid i.e. Invisible Root.
|
||||
// ==> Children are Protocol (Top Level) Items
|
||||
if (!parent.isValid())
|
||||
return mSelectedProtocols.size();
|
||||
|
||||
// Parent - Valid Item
|
||||
parentId.w = parent.internalId();
|
||||
switch(parentId.ws.type)
|
||||
{
|
||||
case ITYP_PROTOCOL:
|
||||
return mSelectedProtocols.at(parentId.ws.protocol)->frameFieldCount();
|
||||
case ITYP_FIELD:
|
||||
return 0;
|
||||
default:
|
||||
qWarning("%s: Unhandled ItemType", __FUNCTION__);
|
||||
}
|
||||
|
||||
Q_ASSERT(1 == 0); // Unreachable code
|
||||
qWarning("%s: Catch all - need to investigate", __FUNCTION__);
|
||||
return 0; // catch all
|
||||
}
|
||||
|
||||
int PacketModel::columnCount(const QModelIndex &parent) const
|
||||
{
|
||||
return 1;
|
||||
}
|
||||
|
||||
QModelIndex PacketModel::index(int row, int col, const QModelIndex &parent) const
|
||||
{
|
||||
QModelIndex index;
|
||||
IndexId id, parentId;
|
||||
|
||||
if (!hasIndex(row, col, parent))
|
||||
goto _exit;
|
||||
|
||||
// Parent is Invisible Root
|
||||
// Request for a Protocol Item
|
||||
if (!parent.isValid())
|
||||
{
|
||||
id.w = 0;
|
||||
id.ws.type = ITYP_PROTOCOL;
|
||||
id.ws.protocol = row;
|
||||
index = createIndex(row, col, id.w);
|
||||
goto _exit;
|
||||
}
|
||||
|
||||
// Parent is a Valid Item
|
||||
parentId.w = parent.internalId();
|
||||
id.w = parentId.w;
|
||||
switch(parentId.ws.type)
|
||||
{
|
||||
case ITYP_PROTOCOL:
|
||||
id.ws.type = ITYP_FIELD;
|
||||
index = createIndex(row, col, id.w);
|
||||
goto _exit;
|
||||
|
||||
case ITYP_FIELD:
|
||||
Q_ASSERT(1 == 0); // Unreachable code
|
||||
goto _exit;
|
||||
|
||||
default:
|
||||
qWarning("%s: Unhandled ItemType", __FUNCTION__);
|
||||
}
|
||||
|
||||
Q_ASSERT(1 == 0); // Unreachable code
|
||||
|
||||
_exit:
|
||||
return index;
|
||||
}
|
||||
|
||||
QModelIndex PacketModel::parent(const QModelIndex &index) const
|
||||
{
|
||||
QModelIndex parentIndex;
|
||||
IndexId id, parentId;
|
||||
|
||||
if (!index.isValid())
|
||||
return QModelIndex();
|
||||
|
||||
id.w = index.internalId();
|
||||
parentId.w = id.w;
|
||||
switch(id.ws.type)
|
||||
{
|
||||
case ITYP_PROTOCOL:
|
||||
// return invalid index for invisible root
|
||||
goto _exit;
|
||||
|
||||
case ITYP_FIELD:
|
||||
parentId.ws.type = ITYP_PROTOCOL;
|
||||
parentIndex = createIndex(id.ws.protocol, 0, parentId.w);
|
||||
goto _exit;
|
||||
|
||||
default:
|
||||
qWarning("%s: Unhandled ItemType", __FUNCTION__);
|
||||
}
|
||||
|
||||
Q_ASSERT(1 == 1); // Unreachable code
|
||||
|
||||
_exit:
|
||||
return parentIndex;
|
||||
}
|
||||
|
||||
QVariant PacketModel::data(const QModelIndex &index, int role) const
|
||||
{
|
||||
IndexId id;
|
||||
int fieldIdx = 0;
|
||||
|
||||
if (!index.isValid())
|
||||
return QVariant();
|
||||
|
||||
id.w = index.internalId();
|
||||
|
||||
if (id.ws.type == ITYP_FIELD)
|
||||
{
|
||||
const AbstractProtocol *p = mSelectedProtocols.at(id.ws.protocol);
|
||||
int n = index.row() + 1;
|
||||
|
||||
while (n)
|
||||
{
|
||||
if (!(p->fieldFlags(fieldIdx).testFlag(
|
||||
AbstractProtocol::FieldIsMeta)))
|
||||
n--;
|
||||
fieldIdx++;
|
||||
}
|
||||
fieldIdx--;
|
||||
}
|
||||
|
||||
// FIXME(HI): Relook at this completely
|
||||
if (role == Qt::UserRole)
|
||||
{
|
||||
switch(id.ws.type)
|
||||
{
|
||||
case ITYP_PROTOCOL:
|
||||
qDebug("*** %d/%d", id.ws.protocol, mSelectedProtocols.size());
|
||||
return mSelectedProtocols.at(id.ws.protocol)->
|
||||
protocolFrameValue();
|
||||
|
||||
case ITYP_FIELD:
|
||||
return mSelectedProtocols.at(id.ws.protocol)->fieldData(
|
||||
fieldIdx, AbstractProtocol::FieldFrameValue);
|
||||
|
||||
default:
|
||||
qWarning("%s: Unhandled ItemType", __FUNCTION__);
|
||||
}
|
||||
return QByteArray();
|
||||
}
|
||||
|
||||
// FIXME: Use a new enum here instead of UserRole
|
||||
if (role == (Qt::UserRole+1))
|
||||
{
|
||||
switch(id.ws.type)
|
||||
{
|
||||
case ITYP_PROTOCOL:
|
||||
return mSelectedProtocols.at(id.ws.protocol)->
|
||||
protocolFrameValue().size();
|
||||
|
||||
case ITYP_FIELD:
|
||||
return mSelectedProtocols.at(id.ws.protocol)->fieldData(
|
||||
fieldIdx, AbstractProtocol::FieldBitSize);
|
||||
|
||||
default:
|
||||
qWarning("%s: Unhandled ItemType", __FUNCTION__);
|
||||
}
|
||||
return QVariant();
|
||||
}
|
||||
|
||||
if (role != Qt::DisplayRole)
|
||||
return QVariant();
|
||||
|
||||
switch(id.ws.type)
|
||||
{
|
||||
case ITYP_PROTOCOL:
|
||||
return QString("%1 (%2)")
|
||||
.arg(mSelectedProtocols.at(id.ws.protocol)->shortName())
|
||||
.arg(mSelectedProtocols.at(id.ws.protocol)->name());
|
||||
|
||||
case ITYP_FIELD:
|
||||
return mSelectedProtocols.at(id.ws.protocol)->fieldData(fieldIdx,
|
||||
AbstractProtocol::FieldName).toString() + QString(" : ") +
|
||||
mSelectedProtocols.at(id.ws.protocol)->fieldData(fieldIdx,
|
||||
AbstractProtocol::FieldTextValue).toString();
|
||||
|
||||
default:
|
||||
qWarning("%s: Unhandled ItemType", __FUNCTION__);
|
||||
}
|
||||
|
||||
Q_ASSERT(1 == 1); // Unreachable code
|
||||
|
||||
return QVariant();
|
||||
}
|
||||
#include <QHostAddress>
|
||||
|
||||
#include "packetmodel.h"
|
||||
#include "../common/protocollistiterator.h"
|
||||
#include "../common/abstractprotocol.h"
|
||||
|
||||
PacketModel::PacketModel(QObject *parent)
|
||||
{
|
||||
}
|
||||
|
||||
void PacketModel::setSelectedProtocols(ProtocolListIterator &iter)
|
||||
{
|
||||
QList<const AbstractProtocol*> currentProtocols;
|
||||
|
||||
iter.toFront();
|
||||
while (iter.hasNext())
|
||||
currentProtocols.append(iter.next());
|
||||
|
||||
if (mSelectedProtocols != currentProtocols)
|
||||
{
|
||||
mSelectedProtocols = currentProtocols;
|
||||
reset();
|
||||
}
|
||||
}
|
||||
|
||||
int PacketModel::rowCount(const QModelIndex &parent) const
|
||||
{
|
||||
IndexId parentId;
|
||||
|
||||
// qDebug("in %s", __FUNCTION__);
|
||||
|
||||
// Parent == Invalid i.e. Invisible Root.
|
||||
// ==> Children are Protocol (Top Level) Items
|
||||
if (!parent.isValid())
|
||||
return mSelectedProtocols.size();
|
||||
|
||||
// Parent - Valid Item
|
||||
parentId.w = parent.internalId();
|
||||
switch(parentId.ws.type)
|
||||
{
|
||||
case ITYP_PROTOCOL:
|
||||
return mSelectedProtocols.at(parentId.ws.protocol)->frameFieldCount();
|
||||
case ITYP_FIELD:
|
||||
return 0;
|
||||
default:
|
||||
qWarning("%s: Unhandled ItemType", __FUNCTION__);
|
||||
}
|
||||
|
||||
Q_ASSERT(1 == 0); // Unreachable code
|
||||
qWarning("%s: Catch all - need to investigate", __FUNCTION__);
|
||||
return 0; // catch all
|
||||
}
|
||||
|
||||
int PacketModel::columnCount(const QModelIndex &parent) const
|
||||
{
|
||||
return 1;
|
||||
}
|
||||
|
||||
QModelIndex PacketModel::index(int row, int col, const QModelIndex &parent) const
|
||||
{
|
||||
QModelIndex index;
|
||||
IndexId id, parentId;
|
||||
|
||||
if (!hasIndex(row, col, parent))
|
||||
goto _exit;
|
||||
|
||||
// Parent is Invisible Root
|
||||
// Request for a Protocol Item
|
||||
if (!parent.isValid())
|
||||
{
|
||||
id.w = 0;
|
||||
id.ws.type = ITYP_PROTOCOL;
|
||||
id.ws.protocol = row;
|
||||
index = createIndex(row, col, id.w);
|
||||
goto _exit;
|
||||
}
|
||||
|
||||
// Parent is a Valid Item
|
||||
parentId.w = parent.internalId();
|
||||
id.w = parentId.w;
|
||||
switch(parentId.ws.type)
|
||||
{
|
||||
case ITYP_PROTOCOL:
|
||||
id.ws.type = ITYP_FIELD;
|
||||
index = createIndex(row, col, id.w);
|
||||
goto _exit;
|
||||
|
||||
case ITYP_FIELD:
|
||||
Q_ASSERT(1 == 0); // Unreachable code
|
||||
goto _exit;
|
||||
|
||||
default:
|
||||
qWarning("%s: Unhandled ItemType", __FUNCTION__);
|
||||
}
|
||||
|
||||
Q_ASSERT(1 == 0); // Unreachable code
|
||||
|
||||
_exit:
|
||||
return index;
|
||||
}
|
||||
|
||||
QModelIndex PacketModel::parent(const QModelIndex &index) const
|
||||
{
|
||||
QModelIndex parentIndex;
|
||||
IndexId id, parentId;
|
||||
|
||||
if (!index.isValid())
|
||||
return QModelIndex();
|
||||
|
||||
id.w = index.internalId();
|
||||
parentId.w = id.w;
|
||||
switch(id.ws.type)
|
||||
{
|
||||
case ITYP_PROTOCOL:
|
||||
// return invalid index for invisible root
|
||||
goto _exit;
|
||||
|
||||
case ITYP_FIELD:
|
||||
parentId.ws.type = ITYP_PROTOCOL;
|
||||
parentIndex = createIndex(id.ws.protocol, 0, parentId.w);
|
||||
goto _exit;
|
||||
|
||||
default:
|
||||
qWarning("%s: Unhandled ItemType", __FUNCTION__);
|
||||
}
|
||||
|
||||
Q_ASSERT(1 == 1); // Unreachable code
|
||||
|
||||
_exit:
|
||||
return parentIndex;
|
||||
}
|
||||
|
||||
QVariant PacketModel::data(const QModelIndex &index, int role) const
|
||||
{
|
||||
IndexId id;
|
||||
int fieldIdx = 0;
|
||||
|
||||
if (!index.isValid())
|
||||
return QVariant();
|
||||
|
||||
id.w = index.internalId();
|
||||
|
||||
if (id.ws.type == ITYP_FIELD)
|
||||
{
|
||||
const AbstractProtocol *p = mSelectedProtocols.at(id.ws.protocol);
|
||||
int n = index.row() + 1;
|
||||
|
||||
while (n)
|
||||
{
|
||||
if (!(p->fieldFlags(fieldIdx).testFlag(
|
||||
AbstractProtocol::FieldIsMeta)))
|
||||
n--;
|
||||
fieldIdx++;
|
||||
}
|
||||
fieldIdx--;
|
||||
}
|
||||
|
||||
// FIXME(HI): Relook at this completely
|
||||
if (role == Qt::UserRole)
|
||||
{
|
||||
switch(id.ws.type)
|
||||
{
|
||||
case ITYP_PROTOCOL:
|
||||
qDebug("*** %d/%d", id.ws.protocol, mSelectedProtocols.size());
|
||||
return mSelectedProtocols.at(id.ws.protocol)->
|
||||
protocolFrameValue();
|
||||
|
||||
case ITYP_FIELD:
|
||||
return mSelectedProtocols.at(id.ws.protocol)->fieldData(
|
||||
fieldIdx, AbstractProtocol::FieldFrameValue);
|
||||
|
||||
default:
|
||||
qWarning("%s: Unhandled ItemType", __FUNCTION__);
|
||||
}
|
||||
return QByteArray();
|
||||
}
|
||||
|
||||
// FIXME: Use a new enum here instead of UserRole
|
||||
if (role == (Qt::UserRole+1))
|
||||
{
|
||||
switch(id.ws.type)
|
||||
{
|
||||
case ITYP_PROTOCOL:
|
||||
return mSelectedProtocols.at(id.ws.protocol)->
|
||||
protocolFrameValue().size();
|
||||
|
||||
case ITYP_FIELD:
|
||||
return mSelectedProtocols.at(id.ws.protocol)->fieldData(
|
||||
fieldIdx, AbstractProtocol::FieldBitSize);
|
||||
|
||||
default:
|
||||
qWarning("%s: Unhandled ItemType", __FUNCTION__);
|
||||
}
|
||||
return QVariant();
|
||||
}
|
||||
|
||||
if (role != Qt::DisplayRole)
|
||||
return QVariant();
|
||||
|
||||
switch(id.ws.type)
|
||||
{
|
||||
case ITYP_PROTOCOL:
|
||||
return QString("%1 (%2)")
|
||||
.arg(mSelectedProtocols.at(id.ws.protocol)->shortName())
|
||||
.arg(mSelectedProtocols.at(id.ws.protocol)->name());
|
||||
|
||||
case ITYP_FIELD:
|
||||
return mSelectedProtocols.at(id.ws.protocol)->fieldData(fieldIdx,
|
||||
AbstractProtocol::FieldName).toString() + QString(" : ") +
|
||||
mSelectedProtocols.at(id.ws.protocol)->fieldData(fieldIdx,
|
||||
AbstractProtocol::FieldTextValue).toString();
|
||||
|
||||
default:
|
||||
qWarning("%s: Unhandled ItemType", __FUNCTION__);
|
||||
}
|
||||
|
||||
Q_ASSERT(1 == 1); // Unreachable code
|
||||
|
||||
return QVariant();
|
||||
}
|
||||
|
@ -1,40 +1,40 @@
|
||||
#ifndef _PACKET_MODEL_H
|
||||
#define _PACKET_MODEL_H
|
||||
|
||||
#include <QAbstractItemModel>
|
||||
|
||||
class ProtocolListIterator;
|
||||
class AbstractProtocol;
|
||||
|
||||
class PacketModel: public QAbstractItemModel
|
||||
{
|
||||
|
||||
public:
|
||||
PacketModel(QObject *parent = 0);
|
||||
void setSelectedProtocols(ProtocolListIterator &iter);
|
||||
|
||||
int rowCount(const QModelIndex &parent = QModelIndex()) const;
|
||||
int columnCount(const QModelIndex &parent = QModelIndex()) const;
|
||||
QVariant data(const QModelIndex &index, int role) const;
|
||||
QVariant headerData(int section, Qt::Orientation orientation,
|
||||
int role = Qt::DisplayRole) const { return QVariant(); } ;
|
||||
QModelIndex index (int row, int col, const QModelIndex & parent = QModelIndex() ) const;
|
||||
QModelIndex parent(const QModelIndex &index) const;
|
||||
|
||||
private:
|
||||
typedef union _IndexId
|
||||
{
|
||||
quint32 w;
|
||||
struct
|
||||
{
|
||||
quint16 type;
|
||||
#define ITYP_PROTOCOL 1
|
||||
#define ITYP_FIELD 2
|
||||
quint16 protocol; // protocol is valid for both ITYPs
|
||||
} ws;
|
||||
} IndexId;
|
||||
|
||||
QList<const AbstractProtocol*> mSelectedProtocols;
|
||||
};
|
||||
#endif
|
||||
|
||||
#ifndef _PACKET_MODEL_H
|
||||
#define _PACKET_MODEL_H
|
||||
|
||||
#include <QAbstractItemModel>
|
||||
|
||||
class ProtocolListIterator;
|
||||
class AbstractProtocol;
|
||||
|
||||
class PacketModel: public QAbstractItemModel
|
||||
{
|
||||
|
||||
public:
|
||||
PacketModel(QObject *parent = 0);
|
||||
void setSelectedProtocols(ProtocolListIterator &iter);
|
||||
|
||||
int rowCount(const QModelIndex &parent = QModelIndex()) const;
|
||||
int columnCount(const QModelIndex &parent = QModelIndex()) const;
|
||||
QVariant data(const QModelIndex &index, int role) const;
|
||||
QVariant headerData(int section, Qt::Orientation orientation,
|
||||
int role = Qt::DisplayRole) const { return QVariant(); } ;
|
||||
QModelIndex index (int row, int col, const QModelIndex & parent = QModelIndex() ) const;
|
||||
QModelIndex parent(const QModelIndex &index) const;
|
||||
|
||||
private:
|
||||
typedef union _IndexId
|
||||
{
|
||||
quint32 w;
|
||||
struct
|
||||
{
|
||||
quint16 type;
|
||||
#define ITYP_PROTOCOL 1
|
||||
#define ITYP_FIELD 2
|
||||
quint16 protocol; // protocol is valid for both ITYPs
|
||||
} ws;
|
||||
} IndexId;
|
||||
|
||||
QList<const AbstractProtocol*> mSelectedProtocols;
|
||||
};
|
||||
#endif
|
||||
|
||||
|
394
client/port.cpp
394
client/port.cpp
@ -1,197 +1,197 @@
|
||||
#include <vector>
|
||||
|
||||
#include <google/protobuf/descriptor.h>
|
||||
|
||||
#include "port.h"
|
||||
#include "pbhelper.h"
|
||||
|
||||
uint Port::mAllocStreamId = 0;
|
||||
|
||||
uint Port::newStreamId()
|
||||
{
|
||||
return mAllocStreamId++;
|
||||
}
|
||||
|
||||
Port::Port(quint32 id, quint32 portGroupId)
|
||||
{
|
||||
mPortId = id;
|
||||
d.mutable_port_id()->set_id(id);
|
||||
stats.mutable_port_id()->set_id(id);
|
||||
mPortGroupId = portGroupId;
|
||||
}
|
||||
|
||||
Port::~Port()
|
||||
{
|
||||
}
|
||||
|
||||
void Port::updatePortConfig(OstProto::Port *port)
|
||||
{
|
||||
d.MergeFrom(*port);
|
||||
}
|
||||
|
||||
void Port::updateStreamOrdinalsFromIndex()
|
||||
{
|
||||
for (int i=0; i < mStreams.size(); i++)
|
||||
mStreams[i]->setOrdinal(i);
|
||||
}
|
||||
|
||||
void Port::reorderStreamsByOrdinals()
|
||||
{
|
||||
qSort(mStreams);
|
||||
}
|
||||
|
||||
bool Port::newStreamAt(int index)
|
||||
{
|
||||
Stream *s = new Stream;
|
||||
|
||||
if (index > mStreams.size())
|
||||
return false;
|
||||
|
||||
s->setId(newStreamId());
|
||||
mStreams.insert(index, s);
|
||||
updateStreamOrdinalsFromIndex();
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
bool Port::deleteStreamAt(int index)
|
||||
{
|
||||
if (index >= mStreams.size())
|
||||
return false;
|
||||
|
||||
delete mStreams.takeAt(index);
|
||||
updateStreamOrdinalsFromIndex();
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
bool Port::insertStream(uint streamId)
|
||||
{
|
||||
Stream *s = new Stream;
|
||||
|
||||
s->setId(streamId);
|
||||
|
||||
// FIXME(MED): If a stream with id already exists, what do we do?
|
||||
mStreams.append(s);
|
||||
|
||||
// Update mAllocStreamId to take into account the stream id received
|
||||
// from server
|
||||
if (mAllocStreamId <= streamId)
|
||||
mAllocStreamId = streamId + 1;
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
bool Port::updateStream(uint streamId, OstProto::Stream *stream)
|
||||
{
|
||||
int i, streamIndex;
|
||||
|
||||
for (i = 0; i < mStreams.size(); i++)
|
||||
{
|
||||
if (streamId == mStreams[i]->id())
|
||||
goto _found;
|
||||
}
|
||||
|
||||
qDebug("%s: Invalid stream id %d", __FUNCTION__, streamId);
|
||||
return false;
|
||||
|
||||
_found:
|
||||
streamIndex = i;
|
||||
|
||||
mStreams[streamIndex]->protoDataCopyFrom(*stream);
|
||||
reorderStreamsByOrdinals();
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
void Port::getDeletedStreamsSinceLastSync(
|
||||
OstProto::StreamIdList &streamIdList)
|
||||
{
|
||||
streamIdList.clear_stream_id();
|
||||
for (int i = 0; i < mLastSyncStreamList.size(); i++)
|
||||
{
|
||||
int j;
|
||||
|
||||
for (j = 0; j < mStreams.size(); j++)
|
||||
{
|
||||
if (mLastSyncStreamList[i] == mStreams[j]->id())
|
||||
break;
|
||||
}
|
||||
|
||||
if (j < mStreams.size())
|
||||
{
|
||||
// stream still exists!
|
||||
continue;
|
||||
}
|
||||
else
|
||||
{
|
||||
// stream has been deleted since last sync
|
||||
OstProto::StreamId *s;
|
||||
|
||||
s = streamIdList.add_stream_id();
|
||||
s->set_id(mLastSyncStreamList.at(i));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void Port::getNewStreamsSinceLastSync(
|
||||
OstProto::StreamIdList &streamIdList)
|
||||
{
|
||||
streamIdList.clear_stream_id();
|
||||
for (int i = 0; i < mStreams.size(); i++)
|
||||
{
|
||||
if (mLastSyncStreamList.contains(mStreams[i]->id()))
|
||||
{
|
||||
// existing stream!
|
||||
continue;
|
||||
}
|
||||
else
|
||||
{
|
||||
// new stream!
|
||||
OstProto::StreamId *s;
|
||||
|
||||
s = streamIdList.add_stream_id();
|
||||
s->set_id(mStreams[i]->id());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void Port::getModifiedStreamsSinceLastSync(
|
||||
OstProto::StreamConfigList &streamConfigList)
|
||||
{
|
||||
qDebug("In %s", __FUNCTION__);
|
||||
|
||||
//streamConfigList.mutable_port_id()->set_id(mPortId);
|
||||
for (int i = 0; i < mStreams.size(); i++)
|
||||
{
|
||||
OstProto::Stream *s;
|
||||
|
||||
s = streamConfigList.add_stream();
|
||||
mStreams[i]->protoDataCopyInto(*s);
|
||||
}
|
||||
qDebug("Done %s", __FUNCTION__);
|
||||
}
|
||||
|
||||
void Port::when_syncComplete()
|
||||
{
|
||||
qSort(mStreams);
|
||||
|
||||
mLastSyncStreamList.clear();
|
||||
for (int i=0; i<mStreams.size(); i++)
|
||||
mLastSyncStreamList.append(mStreams[i]->id());
|
||||
}
|
||||
|
||||
void Port::updateStats(OstProto::PortStats *portStats)
|
||||
{
|
||||
OstProto::PortState oldState;
|
||||
|
||||
oldState = stats.state();
|
||||
stats.MergeFrom(*portStats);
|
||||
|
||||
if (oldState.link_state() != stats.state().link_state())
|
||||
{
|
||||
qDebug("portstate changed");
|
||||
emit portDataChanged(mPortGroupId, mPortId);
|
||||
}
|
||||
}
|
||||
|
||||
#include <vector>
|
||||
|
||||
#include <google/protobuf/descriptor.h>
|
||||
|
||||
#include "port.h"
|
||||
#include "pbhelper.h"
|
||||
|
||||
uint Port::mAllocStreamId = 0;
|
||||
|
||||
uint Port::newStreamId()
|
||||
{
|
||||
return mAllocStreamId++;
|
||||
}
|
||||
|
||||
Port::Port(quint32 id, quint32 portGroupId)
|
||||
{
|
||||
mPortId = id;
|
||||
d.mutable_port_id()->set_id(id);
|
||||
stats.mutable_port_id()->set_id(id);
|
||||
mPortGroupId = portGroupId;
|
||||
}
|
||||
|
||||
Port::~Port()
|
||||
{
|
||||
}
|
||||
|
||||
void Port::updatePortConfig(OstProto::Port *port)
|
||||
{
|
||||
d.MergeFrom(*port);
|
||||
}
|
||||
|
||||
void Port::updateStreamOrdinalsFromIndex()
|
||||
{
|
||||
for (int i=0; i < mStreams.size(); i++)
|
||||
mStreams[i]->setOrdinal(i);
|
||||
}
|
||||
|
||||
void Port::reorderStreamsByOrdinals()
|
||||
{
|
||||
qSort(mStreams);
|
||||
}
|
||||
|
||||
bool Port::newStreamAt(int index)
|
||||
{
|
||||
Stream *s = new Stream;
|
||||
|
||||
if (index > mStreams.size())
|
||||
return false;
|
||||
|
||||
s->setId(newStreamId());
|
||||
mStreams.insert(index, s);
|
||||
updateStreamOrdinalsFromIndex();
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
bool Port::deleteStreamAt(int index)
|
||||
{
|
||||
if (index >= mStreams.size())
|
||||
return false;
|
||||
|
||||
delete mStreams.takeAt(index);
|
||||
updateStreamOrdinalsFromIndex();
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
bool Port::insertStream(uint streamId)
|
||||
{
|
||||
Stream *s = new Stream;
|
||||
|
||||
s->setId(streamId);
|
||||
|
||||
// FIXME(MED): If a stream with id already exists, what do we do?
|
||||
mStreams.append(s);
|
||||
|
||||
// Update mAllocStreamId to take into account the stream id received
|
||||
// from server
|
||||
if (mAllocStreamId <= streamId)
|
||||
mAllocStreamId = streamId + 1;
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
bool Port::updateStream(uint streamId, OstProto::Stream *stream)
|
||||
{
|
||||
int i, streamIndex;
|
||||
|
||||
for (i = 0; i < mStreams.size(); i++)
|
||||
{
|
||||
if (streamId == mStreams[i]->id())
|
||||
goto _found;
|
||||
}
|
||||
|
||||
qDebug("%s: Invalid stream id %d", __FUNCTION__, streamId);
|
||||
return false;
|
||||
|
||||
_found:
|
||||
streamIndex = i;
|
||||
|
||||
mStreams[streamIndex]->protoDataCopyFrom(*stream);
|
||||
reorderStreamsByOrdinals();
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
void Port::getDeletedStreamsSinceLastSync(
|
||||
OstProto::StreamIdList &streamIdList)
|
||||
{
|
||||
streamIdList.clear_stream_id();
|
||||
for (int i = 0; i < mLastSyncStreamList.size(); i++)
|
||||
{
|
||||
int j;
|
||||
|
||||
for (j = 0; j < mStreams.size(); j++)
|
||||
{
|
||||
if (mLastSyncStreamList[i] == mStreams[j]->id())
|
||||
break;
|
||||
}
|
||||
|
||||
if (j < mStreams.size())
|
||||
{
|
||||
// stream still exists!
|
||||
continue;
|
||||
}
|
||||
else
|
||||
{
|
||||
// stream has been deleted since last sync
|
||||
OstProto::StreamId *s;
|
||||
|
||||
s = streamIdList.add_stream_id();
|
||||
s->set_id(mLastSyncStreamList.at(i));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void Port::getNewStreamsSinceLastSync(
|
||||
OstProto::StreamIdList &streamIdList)
|
||||
{
|
||||
streamIdList.clear_stream_id();
|
||||
for (int i = 0; i < mStreams.size(); i++)
|
||||
{
|
||||
if (mLastSyncStreamList.contains(mStreams[i]->id()))
|
||||
{
|
||||
// existing stream!
|
||||
continue;
|
||||
}
|
||||
else
|
||||
{
|
||||
// new stream!
|
||||
OstProto::StreamId *s;
|
||||
|
||||
s = streamIdList.add_stream_id();
|
||||
s->set_id(mStreams[i]->id());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void Port::getModifiedStreamsSinceLastSync(
|
||||
OstProto::StreamConfigList &streamConfigList)
|
||||
{
|
||||
qDebug("In %s", __FUNCTION__);
|
||||
|
||||
//streamConfigList.mutable_port_id()->set_id(mPortId);
|
||||
for (int i = 0; i < mStreams.size(); i++)
|
||||
{
|
||||
OstProto::Stream *s;
|
||||
|
||||
s = streamConfigList.add_stream();
|
||||
mStreams[i]->protoDataCopyInto(*s);
|
||||
}
|
||||
qDebug("Done %s", __FUNCTION__);
|
||||
}
|
||||
|
||||
void Port::when_syncComplete()
|
||||
{
|
||||
qSort(mStreams);
|
||||
|
||||
mLastSyncStreamList.clear();
|
||||
for (int i=0; i<mStreams.size(); i++)
|
||||
mLastSyncStreamList.append(mStreams[i]->id());
|
||||
}
|
||||
|
||||
void Port::updateStats(OstProto::PortStats *portStats)
|
||||
{
|
||||
OstProto::PortState oldState;
|
||||
|
||||
oldState = stats.state();
|
||||
stats.MergeFrom(*portStats);
|
||||
|
||||
if (oldState.link_state() != stats.state().link_state())
|
||||
{
|
||||
qDebug("portstate changed");
|
||||
emit portDataChanged(mPortGroupId, mPortId);
|
||||
}
|
||||
}
|
||||
|
||||
|
196
client/port.h
196
client/port.h
@ -1,98 +1,98 @@
|
||||
#ifndef _PORT_H
|
||||
#define _PORT_H
|
||||
|
||||
#include <QObject>
|
||||
#include <QString>
|
||||
#include <QList>
|
||||
#include "stream.h"
|
||||
|
||||
//class StreamModel;
|
||||
|
||||
class Port : public QObject {
|
||||
|
||||
Q_OBJECT
|
||||
|
||||
static uint mAllocStreamId;
|
||||
OstProto::Port d;
|
||||
OstProto::PortStats stats;
|
||||
|
||||
// FIXME(HI): consider removing mPortId as it is duplicated inside 'd'
|
||||
quint32 mPortId;
|
||||
quint32 mPortGroupId;
|
||||
QString mUserAlias; // user defined
|
||||
|
||||
QList<quint32> mLastSyncStreamList;
|
||||
QList<Stream*> mStreams; // sorted by stream's ordinal value
|
||||
|
||||
uint newStreamId();
|
||||
void updateStreamOrdinalsFromIndex();
|
||||
void reorderStreamsByOrdinals();
|
||||
|
||||
public:
|
||||
enum AdminStatus { AdminDisable, AdminEnable };
|
||||
enum ControlMode { ControlShared, ControlExclusive };
|
||||
|
||||
// FIXME(HIGH): default args is a hack for QList operations on Port
|
||||
Port(quint32 id = 0xFFFFFFFF, quint32 pgId = 0xFFFFFFFF);
|
||||
~Port();
|
||||
|
||||
quint32 portGroupId() const { return mPortGroupId; }
|
||||
const QString& userAlias() const { return mUserAlias; }
|
||||
|
||||
quint32 id() const
|
||||
{ return d.port_id().id(); }
|
||||
const QString name() const
|
||||
{ return QString().fromStdString(d.name()); }
|
||||
const QString description() const
|
||||
{ return QString().fromStdString(d.description()); }
|
||||
AdminStatus adminStatus()
|
||||
{ return (d.is_enabled()?AdminEnable:AdminDisable); }
|
||||
ControlMode controlMode()
|
||||
{ return (d.is_exclusive_control()?ControlExclusive:ControlShared); }
|
||||
|
||||
//void setAdminEnable(AdminStatus status) { mAdminStatus = status; }
|
||||
void setAlias(QString &alias) { mUserAlias = alias; }
|
||||
//void setExclusive(bool flag);
|
||||
|
||||
int numStreams() { return mStreams.size(); }
|
||||
Stream* streamByIndex(int index)
|
||||
{
|
||||
Q_ASSERT(index < mStreams.size());
|
||||
return mStreams[index];
|
||||
}
|
||||
OstProto::LinkState linkState()
|
||||
{ return stats.state().link_state(); }
|
||||
|
||||
OstProto::PortStats getStats() { return stats; }
|
||||
|
||||
// FIXME(MED): naming inconsistency - PortConfig/Stream; also retVal
|
||||
void updatePortConfig(OstProto::Port *port);
|
||||
|
||||
//! Used by StreamModel
|
||||
//@{
|
||||
bool newStreamAt(int index);
|
||||
bool deleteStreamAt(int index);
|
||||
//@}
|
||||
|
||||
//! Used by MyService::Stub to update from config received from server
|
||||
//@{
|
||||
bool insertStream(uint streamId);
|
||||
bool updateStream(uint streamId, OstProto::Stream *stream);
|
||||
//@}
|
||||
|
||||
void getDeletedStreamsSinceLastSync(OstProto::StreamIdList &streamIdList);
|
||||
void getNewStreamsSinceLastSync(OstProto::StreamIdList &streamIdList);
|
||||
void getModifiedStreamsSinceLastSync(
|
||||
OstProto::StreamConfigList &streamConfigList);
|
||||
|
||||
|
||||
void when_syncComplete();
|
||||
|
||||
void updateStats(OstProto::PortStats *portStats);
|
||||
|
||||
signals:
|
||||
void portDataChanged(int portGroupId, int portId);
|
||||
|
||||
};
|
||||
|
||||
#endif
|
||||
#ifndef _PORT_H
|
||||
#define _PORT_H
|
||||
|
||||
#include <QObject>
|
||||
#include <QString>
|
||||
#include <QList>
|
||||
#include "stream.h"
|
||||
|
||||
//class StreamModel;
|
||||
|
||||
class Port : public QObject {
|
||||
|
||||
Q_OBJECT
|
||||
|
||||
static uint mAllocStreamId;
|
||||
OstProto::Port d;
|
||||
OstProto::PortStats stats;
|
||||
|
||||
// FIXME(HI): consider removing mPortId as it is duplicated inside 'd'
|
||||
quint32 mPortId;
|
||||
quint32 mPortGroupId;
|
||||
QString mUserAlias; // user defined
|
||||
|
||||
QList<quint32> mLastSyncStreamList;
|
||||
QList<Stream*> mStreams; // sorted by stream's ordinal value
|
||||
|
||||
uint newStreamId();
|
||||
void updateStreamOrdinalsFromIndex();
|
||||
void reorderStreamsByOrdinals();
|
||||
|
||||
public:
|
||||
enum AdminStatus { AdminDisable, AdminEnable };
|
||||
enum ControlMode { ControlShared, ControlExclusive };
|
||||
|
||||
// FIXME(HIGH): default args is a hack for QList operations on Port
|
||||
Port(quint32 id = 0xFFFFFFFF, quint32 pgId = 0xFFFFFFFF);
|
||||
~Port();
|
||||
|
||||
quint32 portGroupId() const { return mPortGroupId; }
|
||||
const QString& userAlias() const { return mUserAlias; }
|
||||
|
||||
quint32 id() const
|
||||
{ return d.port_id().id(); }
|
||||
const QString name() const
|
||||
{ return QString().fromStdString(d.name()); }
|
||||
const QString description() const
|
||||
{ return QString().fromStdString(d.description()); }
|
||||
AdminStatus adminStatus()
|
||||
{ return (d.is_enabled()?AdminEnable:AdminDisable); }
|
||||
ControlMode controlMode()
|
||||
{ return (d.is_exclusive_control()?ControlExclusive:ControlShared); }
|
||||
|
||||
//void setAdminEnable(AdminStatus status) { mAdminStatus = status; }
|
||||
void setAlias(QString &alias) { mUserAlias = alias; }
|
||||
//void setExclusive(bool flag);
|
||||
|
||||
int numStreams() { return mStreams.size(); }
|
||||
Stream* streamByIndex(int index)
|
||||
{
|
||||
Q_ASSERT(index < mStreams.size());
|
||||
return mStreams[index];
|
||||
}
|
||||
OstProto::LinkState linkState()
|
||||
{ return stats.state().link_state(); }
|
||||
|
||||
OstProto::PortStats getStats() { return stats; }
|
||||
|
||||
// FIXME(MED): naming inconsistency - PortConfig/Stream; also retVal
|
||||
void updatePortConfig(OstProto::Port *port);
|
||||
|
||||
//! Used by StreamModel
|
||||
//@{
|
||||
bool newStreamAt(int index);
|
||||
bool deleteStreamAt(int index);
|
||||
//@}
|
||||
|
||||
//! Used by MyService::Stub to update from config received from server
|
||||
//@{
|
||||
bool insertStream(uint streamId);
|
||||
bool updateStream(uint streamId, OstProto::Stream *stream);
|
||||
//@}
|
||||
|
||||
void getDeletedStreamsSinceLastSync(OstProto::StreamIdList &streamIdList);
|
||||
void getNewStreamsSinceLastSync(OstProto::StreamIdList &streamIdList);
|
||||
void getModifiedStreamsSinceLastSync(
|
||||
OstProto::StreamConfigList &streamConfigList);
|
||||
|
||||
|
||||
void when_syncComplete();
|
||||
|
||||
void updateStats(OstProto::PortStats *portStats);
|
||||
|
||||
signals:
|
||||
void portDataChanged(int portGroupId, int portId);
|
||||
|
||||
};
|
||||
|
||||
#endif
|
||||
|
1436
client/portgroup.cpp
1436
client/portgroup.cpp
File diff suppressed because it is too large
Load Diff
@ -1,119 +1,119 @@
|
||||
#ifndef _PORT_GROUP_H
|
||||
#define _PORT_GROUP_H
|
||||
|
||||
#include "port.h"
|
||||
#include <QHostAddress>
|
||||
#include <QTcpSocket>
|
||||
|
||||
#include "../common/protocol.pb.h"
|
||||
#include "pbrpcchannel.h"
|
||||
|
||||
/* TODO
|
||||
HIGH
|
||||
MED
|
||||
LOW
|
||||
- Allow hostnames in addition to IP Address as "server address"
|
||||
*/
|
||||
|
||||
#define DEFAULT_SERVER_PORT 7878
|
||||
|
||||
class QFile;
|
||||
|
||||
class PortGroup : public QObject {
|
||||
Q_OBJECT
|
||||
|
||||
private:
|
||||
quint32 mPortGroupId;
|
||||
static quint32 mPortGroupAllocId;
|
||||
QString mUserAlias; // user defined
|
||||
#if 0 // PB
|
||||
QTcpSocket *mpSocket;
|
||||
QHostAddress mServerAddress;
|
||||
quint16 mServerPort;
|
||||
#endif
|
||||
PbRpcChannel *rpcChannel;
|
||||
PbRpcController *rpcController;
|
||||
PbRpcController *rpcControllerStats;
|
||||
bool isGetStatsPending_;
|
||||
::OstProto::OstService::Stub *serviceStub;
|
||||
|
||||
::OstProto::PortIdList portIdList;
|
||||
public: // FIXME(HIGH): member access
|
||||
QList<Port*> mPorts;
|
||||
|
||||
public:
|
||||
PortGroup(QHostAddress ip = QHostAddress::LocalHost,
|
||||
quint16 port = DEFAULT_SERVER_PORT);
|
||||
~PortGroup();
|
||||
|
||||
void connectToHost() { rpcChannel->establish(); }
|
||||
void connectToHost(QHostAddress ip, quint16 port)
|
||||
{ rpcChannel->establish(ip, port); }
|
||||
void disconnectFromHost() { rpcChannel->tearDown(); }
|
||||
|
||||
int numPorts() const { return mPorts.size(); }
|
||||
quint32 id() const { return mPortGroupId; }
|
||||
|
||||
const QString& userAlias() const { return mUserAlias; }
|
||||
void setUserAlias(QString alias) { mUserAlias = alias; };
|
||||
|
||||
const QHostAddress& serverAddress() const
|
||||
{ return rpcChannel->serverAddress(); }
|
||||
quint16 serverPort() const
|
||||
{ return rpcChannel->serverPort(); }
|
||||
QAbstractSocket::SocketState state() const
|
||||
{ return rpcChannel->state(); }
|
||||
|
||||
void processPortIdList(OstProto::PortIdList *portIdList);
|
||||
void processPortConfigList(OstProto::PortConfigList *portConfigList);
|
||||
|
||||
void getStreamIdList(int portIndex = 0,
|
||||
OstProto::StreamIdList *streamIdList = NULL);
|
||||
void getStreamConfigList(int portIndex = 0,
|
||||
OstProto::StreamConfigList *streamConfigList = NULL);
|
||||
|
||||
void processModifyStreamAck(OstProto::Ack *ack);
|
||||
|
||||
void startTx(QList<uint> *portList = NULL);
|
||||
void processStartTxAck(OstProto::Ack *ack);
|
||||
void stopTx(QList<uint> *portList = NULL);
|
||||
void processStopTxAck(OstProto::Ack *ack);
|
||||
|
||||
void startCapture(QList<uint> *portList = NULL);
|
||||
void processStartCaptureAck(OstProto::Ack *ack);
|
||||
void stopCapture(QList<uint> *portList = NULL);
|
||||
void processStopCaptureAck(OstProto::Ack *ack);
|
||||
void viewCapture(QList<uint> *portList = NULL);
|
||||
void processViewCaptureAck(OstProto::CaptureBuffer *buf, QFile *capFile);
|
||||
|
||||
void getPortStats();
|
||||
void processPortStatsList(OstProto::PortStatsList *portStatsList);
|
||||
void clearPortStats(QList<uint> *portList = NULL);
|
||||
void processClearStatsAck(OstProto::Ack *ack);
|
||||
|
||||
signals:
|
||||
void portGroupDataChanged(int portGroupId, int portId = 0xFFFF);
|
||||
void portListAboutToBeChanged(quint32 portGroupId);
|
||||
void portListChanged(quint32 portGroupId);
|
||||
void statsChanged(quint32 portGroupId);
|
||||
|
||||
private slots:
|
||||
void on_rpcChannel_stateChanged();
|
||||
void on_rpcChannel_connected();
|
||||
void on_rpcChannel_disconnected();
|
||||
void on_rpcChannel_error(QAbstractSocket::SocketError socketError);
|
||||
|
||||
public slots:
|
||||
void when_configApply(int portIndex, uint *cookie = NULL);
|
||||
#if 0 // PB
|
||||
void on_rpcChannel_when_dataAvail();
|
||||
#endif
|
||||
|
||||
private:
|
||||
#if 0 // PB
|
||||
void ProcessCapabilityInfo(const char *msg, qint32 size);
|
||||
void ProcessMsg(const char *msg, quint32 size);
|
||||
#endif
|
||||
};
|
||||
|
||||
#endif
|
||||
#ifndef _PORT_GROUP_H
|
||||
#define _PORT_GROUP_H
|
||||
|
||||
#include "port.h"
|
||||
#include <QHostAddress>
|
||||
#include <QTcpSocket>
|
||||
|
||||
#include "../common/protocol.pb.h"
|
||||
#include "pbrpcchannel.h"
|
||||
|
||||
/* TODO
|
||||
HIGH
|
||||
MED
|
||||
LOW
|
||||
- Allow hostnames in addition to IP Address as "server address"
|
||||
*/
|
||||
|
||||
#define DEFAULT_SERVER_PORT 7878
|
||||
|
||||
class QFile;
|
||||
|
||||
class PortGroup : public QObject {
|
||||
Q_OBJECT
|
||||
|
||||
private:
|
||||
quint32 mPortGroupId;
|
||||
static quint32 mPortGroupAllocId;
|
||||
QString mUserAlias; // user defined
|
||||
#if 0 // PB
|
||||
QTcpSocket *mpSocket;
|
||||
QHostAddress mServerAddress;
|
||||
quint16 mServerPort;
|
||||
#endif
|
||||
PbRpcChannel *rpcChannel;
|
||||
PbRpcController *rpcController;
|
||||
PbRpcController *rpcControllerStats;
|
||||
bool isGetStatsPending_;
|
||||
::OstProto::OstService::Stub *serviceStub;
|
||||
|
||||
::OstProto::PortIdList portIdList;
|
||||
public: // FIXME(HIGH): member access
|
||||
QList<Port*> mPorts;
|
||||
|
||||
public:
|
||||
PortGroup(QHostAddress ip = QHostAddress::LocalHost,
|
||||
quint16 port = DEFAULT_SERVER_PORT);
|
||||
~PortGroup();
|
||||
|
||||
void connectToHost() { rpcChannel->establish(); }
|
||||
void connectToHost(QHostAddress ip, quint16 port)
|
||||
{ rpcChannel->establish(ip, port); }
|
||||
void disconnectFromHost() { rpcChannel->tearDown(); }
|
||||
|
||||
int numPorts() const { return mPorts.size(); }
|
||||
quint32 id() const { return mPortGroupId; }
|
||||
|
||||
const QString& userAlias() const { return mUserAlias; }
|
||||
void setUserAlias(QString alias) { mUserAlias = alias; };
|
||||
|
||||
const QHostAddress& serverAddress() const
|
||||
{ return rpcChannel->serverAddress(); }
|
||||
quint16 serverPort() const
|
||||
{ return rpcChannel->serverPort(); }
|
||||
QAbstractSocket::SocketState state() const
|
||||
{ return rpcChannel->state(); }
|
||||
|
||||
void processPortIdList(OstProto::PortIdList *portIdList);
|
||||
void processPortConfigList(OstProto::PortConfigList *portConfigList);
|
||||
|
||||
void getStreamIdList(int portIndex = 0,
|
||||
OstProto::StreamIdList *streamIdList = NULL);
|
||||
void getStreamConfigList(int portIndex = 0,
|
||||
OstProto::StreamConfigList *streamConfigList = NULL);
|
||||
|
||||
void processModifyStreamAck(OstProto::Ack *ack);
|
||||
|
||||
void startTx(QList<uint> *portList = NULL);
|
||||
void processStartTxAck(OstProto::Ack *ack);
|
||||
void stopTx(QList<uint> *portList = NULL);
|
||||
void processStopTxAck(OstProto::Ack *ack);
|
||||
|
||||
void startCapture(QList<uint> *portList = NULL);
|
||||
void processStartCaptureAck(OstProto::Ack *ack);
|
||||
void stopCapture(QList<uint> *portList = NULL);
|
||||
void processStopCaptureAck(OstProto::Ack *ack);
|
||||
void viewCapture(QList<uint> *portList = NULL);
|
||||
void processViewCaptureAck(OstProto::CaptureBuffer *buf, QFile *capFile);
|
||||
|
||||
void getPortStats();
|
||||
void processPortStatsList(OstProto::PortStatsList *portStatsList);
|
||||
void clearPortStats(QList<uint> *portList = NULL);
|
||||
void processClearStatsAck(OstProto::Ack *ack);
|
||||
|
||||
signals:
|
||||
void portGroupDataChanged(int portGroupId, int portId = 0xFFFF);
|
||||
void portListAboutToBeChanged(quint32 portGroupId);
|
||||
void portListChanged(quint32 portGroupId);
|
||||
void statsChanged(quint32 portGroupId);
|
||||
|
||||
private slots:
|
||||
void on_rpcChannel_stateChanged();
|
||||
void on_rpcChannel_connected();
|
||||
void on_rpcChannel_disconnected();
|
||||
void on_rpcChannel_error(QAbstractSocket::SocketError socketError);
|
||||
|
||||
public slots:
|
||||
void when_configApply(int portIndex, uint *cookie = NULL);
|
||||
#if 0 // PB
|
||||
void on_rpcChannel_when_dataAvail();
|
||||
#endif
|
||||
|
||||
private:
|
||||
#if 0 // PB
|
||||
void ProcessCapabilityInfo(const char *msg, qint32 size);
|
||||
void ProcessMsg(const char *msg, quint32 size);
|
||||
#endif
|
||||
};
|
||||
|
||||
#endif
|
||||
|
@ -1,98 +1,98 @@
|
||||
#include "portgrouplist.h"
|
||||
|
||||
// TODO(LOW): Remove
|
||||
#include <modeltest.h>
|
||||
|
||||
PortGroupList::PortGroupList()
|
||||
: mPortGroupListModel(this),
|
||||
mStreamListModel(this),
|
||||
mPortStatsModel(this, this)
|
||||
{
|
||||
PortGroup *pg;
|
||||
|
||||
// TODO(LOW): Remove
|
||||
new ModelTest(getStreamModel());
|
||||
new ModelTest(getPortModel());
|
||||
new ModelTest(getPortStatsModel());
|
||||
|
||||
// Add the "Local" Port Group
|
||||
pg = new PortGroup;
|
||||
addPortGroup(*pg);
|
||||
}
|
||||
|
||||
bool PortGroupList::isPortGroup(const QModelIndex& index)
|
||||
{
|
||||
return mPortGroupListModel.isPortGroup(index);
|
||||
}
|
||||
|
||||
bool PortGroupList::isPort(const QModelIndex& index)
|
||||
{
|
||||
return mPortGroupListModel.isPort(index);
|
||||
}
|
||||
|
||||
PortGroup& PortGroupList::portGroup(const QModelIndex& index)
|
||||
{
|
||||
Q_ASSERT(mPortGroupListModel.isPortGroup(index));
|
||||
|
||||
return *(mPortGroups[index.row()]);
|
||||
}
|
||||
|
||||
Port& PortGroupList::port(const QModelIndex& index)
|
||||
{
|
||||
Q_ASSERT(mPortGroupListModel.isPort(index));
|
||||
return (*mPortGroups.at(index.parent().row())->mPorts[index.row()]);
|
||||
}
|
||||
|
||||
void PortGroupList::addPortGroup(PortGroup &portGroup)
|
||||
{
|
||||
mPortGroupListModel.portGroupAboutToBeAppended();
|
||||
|
||||
connect(&portGroup, SIGNAL(portGroupDataChanged(int, int)),
|
||||
&mPortGroupListModel, SLOT(when_portGroupDataChanged(int, int)));
|
||||
#if 0
|
||||
connect(&portGroup, SIGNAL(portListAboutToBeChanged(quint32)),
|
||||
&mPortGroupListModel, SLOT(triggerLayoutAboutToBeChanged()));
|
||||
connect(&portGroup, SIGNAL(portListChanged(quint32)),
|
||||
&mPortGroupListModel, SLOT(triggerLayoutChanged()));
|
||||
#endif
|
||||
connect(&portGroup, SIGNAL(portListChanged(quint32)),
|
||||
&mPortGroupListModel, SLOT(when_portListChanged()));
|
||||
|
||||
connect(&portGroup, SIGNAL(portListChanged(quint32)),
|
||||
&mPortStatsModel, SLOT(when_portListChanged()));
|
||||
|
||||
connect(&portGroup, SIGNAL(statsChanged(quint32)),
|
||||
&mPortStatsModel, SLOT(when_portGroup_stats_update(quint32)));
|
||||
|
||||
mPortGroups.append(&portGroup);
|
||||
portGroup.connectToHost();
|
||||
|
||||
mPortGroupListModel.portGroupAppended();
|
||||
|
||||
mPortStatsModel.when_portListChanged();
|
||||
}
|
||||
|
||||
void PortGroupList::removePortGroup(PortGroup &portGroup)
|
||||
{
|
||||
mPortGroupListModel.portGroupAboutToBeRemoved(&portGroup);
|
||||
|
||||
PortGroup* pg = mPortGroups.takeAt(mPortGroups.indexOf(&portGroup));
|
||||
qDebug("after takeAt()");
|
||||
mPortGroupListModel.portGroupRemoved();
|
||||
|
||||
delete pg;
|
||||
|
||||
mPortStatsModel.when_portListChanged();
|
||||
}
|
||||
|
||||
//....................
|
||||
// Private Methods
|
||||
//....................
|
||||
int PortGroupList::indexOfPortGroup(quint32 portGroupId)
|
||||
{
|
||||
for (int i = 0; i < mPortGroups.size(); i++) {
|
||||
if (mPortGroups.value(i)->id() == portGroupId)
|
||||
return i;
|
||||
}
|
||||
return -1;
|
||||
}
|
||||
#include "portgrouplist.h"
|
||||
|
||||
// TODO(LOW): Remove
|
||||
#include <modeltest.h>
|
||||
|
||||
PortGroupList::PortGroupList()
|
||||
: mPortGroupListModel(this),
|
||||
mStreamListModel(this),
|
||||
mPortStatsModel(this, this)
|
||||
{
|
||||
PortGroup *pg;
|
||||
|
||||
// TODO(LOW): Remove
|
||||
new ModelTest(getStreamModel());
|
||||
new ModelTest(getPortModel());
|
||||
new ModelTest(getPortStatsModel());
|
||||
|
||||
// Add the "Local" Port Group
|
||||
pg = new PortGroup;
|
||||
addPortGroup(*pg);
|
||||
}
|
||||
|
||||
bool PortGroupList::isPortGroup(const QModelIndex& index)
|
||||
{
|
||||
return mPortGroupListModel.isPortGroup(index);
|
||||
}
|
||||
|
||||
bool PortGroupList::isPort(const QModelIndex& index)
|
||||
{
|
||||
return mPortGroupListModel.isPort(index);
|
||||
}
|
||||
|
||||
PortGroup& PortGroupList::portGroup(const QModelIndex& index)
|
||||
{
|
||||
Q_ASSERT(mPortGroupListModel.isPortGroup(index));
|
||||
|
||||
return *(mPortGroups[index.row()]);
|
||||
}
|
||||
|
||||
Port& PortGroupList::port(const QModelIndex& index)
|
||||
{
|
||||
Q_ASSERT(mPortGroupListModel.isPort(index));
|
||||
return (*mPortGroups.at(index.parent().row())->mPorts[index.row()]);
|
||||
}
|
||||
|
||||
void PortGroupList::addPortGroup(PortGroup &portGroup)
|
||||
{
|
||||
mPortGroupListModel.portGroupAboutToBeAppended();
|
||||
|
||||
connect(&portGroup, SIGNAL(portGroupDataChanged(int, int)),
|
||||
&mPortGroupListModel, SLOT(when_portGroupDataChanged(int, int)));
|
||||
#if 0
|
||||
connect(&portGroup, SIGNAL(portListAboutToBeChanged(quint32)),
|
||||
&mPortGroupListModel, SLOT(triggerLayoutAboutToBeChanged()));
|
||||
connect(&portGroup, SIGNAL(portListChanged(quint32)),
|
||||
&mPortGroupListModel, SLOT(triggerLayoutChanged()));
|
||||
#endif
|
||||
connect(&portGroup, SIGNAL(portListChanged(quint32)),
|
||||
&mPortGroupListModel, SLOT(when_portListChanged()));
|
||||
|
||||
connect(&portGroup, SIGNAL(portListChanged(quint32)),
|
||||
&mPortStatsModel, SLOT(when_portListChanged()));
|
||||
|
||||
connect(&portGroup, SIGNAL(statsChanged(quint32)),
|
||||
&mPortStatsModel, SLOT(when_portGroup_stats_update(quint32)));
|
||||
|
||||
mPortGroups.append(&portGroup);
|
||||
portGroup.connectToHost();
|
||||
|
||||
mPortGroupListModel.portGroupAppended();
|
||||
|
||||
mPortStatsModel.when_portListChanged();
|
||||
}
|
||||
|
||||
void PortGroupList::removePortGroup(PortGroup &portGroup)
|
||||
{
|
||||
mPortGroupListModel.portGroupAboutToBeRemoved(&portGroup);
|
||||
|
||||
PortGroup* pg = mPortGroups.takeAt(mPortGroups.indexOf(&portGroup));
|
||||
qDebug("after takeAt()");
|
||||
mPortGroupListModel.portGroupRemoved();
|
||||
|
||||
delete pg;
|
||||
|
||||
mPortStatsModel.when_portListChanged();
|
||||
}
|
||||
|
||||
//....................
|
||||
// Private Methods
|
||||
//....................
|
||||
int PortGroupList::indexOfPortGroup(quint32 portGroupId)
|
||||
{
|
||||
for (int i = 0; i < mPortGroups.size(); i++) {
|
||||
if (mPortGroups.value(i)->id() == portGroupId)
|
||||
return i;
|
||||
}
|
||||
return -1;
|
||||
}
|
||||
|
@ -1,52 +1,52 @@
|
||||
#ifndef _PORT_GROUP_LIST_H
|
||||
#define _PORT_GROUP_LIST_H
|
||||
|
||||
#include "portgroup.h"
|
||||
#include <QAbstractItemModel>
|
||||
#include <QItemSelection>
|
||||
#include "portmodel.h"
|
||||
#include "streammodel.h"
|
||||
#include "portstatsmodel.h"
|
||||
|
||||
class PortModel;
|
||||
class StreamModel;
|
||||
|
||||
class PortGroupList : public QObject {
|
||||
|
||||
Q_OBJECT
|
||||
|
||||
friend class PortModel;
|
||||
friend class StreamModel;
|
||||
friend class PortStatsModel;
|
||||
|
||||
QList<PortGroup*> mPortGroups;
|
||||
PortModel mPortGroupListModel;
|
||||
StreamModel mStreamListModel;
|
||||
PortStatsModel mPortStatsModel;
|
||||
|
||||
// Methods
|
||||
public:
|
||||
PortGroupList();
|
||||
|
||||
|
||||
PortModel* getPortModel() { return &mPortGroupListModel; }
|
||||
PortStatsModel* getPortStatsModel() { return &mPortStatsModel; }
|
||||
StreamModel* getStreamModel() { return &mStreamListModel; }
|
||||
|
||||
bool isPortGroup(const QModelIndex& index);
|
||||
bool isPort(const QModelIndex& index);
|
||||
PortGroup& portGroup(const QModelIndex& index);
|
||||
Port& port(const QModelIndex& index);
|
||||
|
||||
int numPortGroups() { return mPortGroups.size(); }
|
||||
PortGroup& portGroupByIndex(int index) { return *(mPortGroups[index]); }
|
||||
|
||||
void addPortGroup(PortGroup &portGroup);
|
||||
void removePortGroup(PortGroup &portGroup);
|
||||
|
||||
private:
|
||||
int indexOfPortGroup(quint32 portGroupId);
|
||||
|
||||
};
|
||||
|
||||
#endif
|
||||
#ifndef _PORT_GROUP_LIST_H
|
||||
#define _PORT_GROUP_LIST_H
|
||||
|
||||
#include "portgroup.h"
|
||||
#include <QAbstractItemModel>
|
||||
#include <QItemSelection>
|
||||
#include "portmodel.h"
|
||||
#include "streammodel.h"
|
||||
#include "portstatsmodel.h"
|
||||
|
||||
class PortModel;
|
||||
class StreamModel;
|
||||
|
||||
class PortGroupList : public QObject {
|
||||
|
||||
Q_OBJECT
|
||||
|
||||
friend class PortModel;
|
||||
friend class StreamModel;
|
||||
friend class PortStatsModel;
|
||||
|
||||
QList<PortGroup*> mPortGroups;
|
||||
PortModel mPortGroupListModel;
|
||||
StreamModel mStreamListModel;
|
||||
PortStatsModel mPortStatsModel;
|
||||
|
||||
// Methods
|
||||
public:
|
||||
PortGroupList();
|
||||
|
||||
|
||||
PortModel* getPortModel() { return &mPortGroupListModel; }
|
||||
PortStatsModel* getPortStatsModel() { return &mPortStatsModel; }
|
||||
StreamModel* getStreamModel() { return &mStreamListModel; }
|
||||
|
||||
bool isPortGroup(const QModelIndex& index);
|
||||
bool isPort(const QModelIndex& index);
|
||||
PortGroup& portGroup(const QModelIndex& index);
|
||||
Port& port(const QModelIndex& index);
|
||||
|
||||
int numPortGroups() { return mPortGroups.size(); }
|
||||
PortGroup& portGroupByIndex(int index) { return *(mPortGroups[index]); }
|
||||
|
||||
void addPortGroup(PortGroup &portGroup);
|
||||
void removePortGroup(PortGroup &portGroup);
|
||||
|
||||
private:
|
||||
int indexOfPortGroup(quint32 portGroupId);
|
||||
|
||||
};
|
||||
|
||||
#endif
|
||||
|
@ -1,311 +1,311 @@
|
||||
#include "portmodel.h"
|
||||
#include "portgrouplist.h"
|
||||
#include <QIcon>
|
||||
|
||||
#if 0
|
||||
#define DBG0(x) qDebug(x)
|
||||
#define DBG1(x, p1) qDebug(x, (p1))
|
||||
#else
|
||||
#define DBG0(x) {}
|
||||
#define DBG1(x, p1) {}
|
||||
#endif
|
||||
|
||||
PortModel::PortModel(PortGroupList *p, QObject *parent)
|
||||
: QAbstractItemModel(parent)
|
||||
{
|
||||
pgl = p;
|
||||
}
|
||||
|
||||
int PortModel::rowCount(const QModelIndex &parent) const
|
||||
{
|
||||
// qDebug("RowCount Enter\n");
|
||||
if (!parent.isValid())
|
||||
{
|
||||
// Top Level Item
|
||||
//qDebug("RowCount (Top) Exit: %d\n", pgl->mPortGroups.size());
|
||||
return pgl->mPortGroups.size();
|
||||
}
|
||||
// qDebug("RowCount non top %d, %d, %llx\n",
|
||||
// parent.row(), parent.column(), parent.internalId());
|
||||
|
||||
quint16 pg = (parent.internalId() >> 16) & 0xFFFF;
|
||||
quint16 p = parent.internalId() & 0xFFFF;
|
||||
if (p == 0xFFFF)
|
||||
{
|
||||
#if 0 // wrong code?
|
||||
int count = 0;
|
||||
foreach(PortGroup *pg, pgl->mPortGroups)
|
||||
{
|
||||
count += pg->numPorts();
|
||||
}
|
||||
//qDebug("RowCount (Mid) Exit: %d\n", count);
|
||||
return count;
|
||||
#endif
|
||||
if (parent.column() == 0)
|
||||
return pgl->mPortGroups.value(pgl->indexOfPortGroup(pg))->numPorts();
|
||||
else
|
||||
return 0;
|
||||
}
|
||||
else
|
||||
{
|
||||
// Leaf Item
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
||||
int PortModel::columnCount(const QModelIndex &parent ) const
|
||||
{
|
||||
return 1; // FIXME: hardcoding
|
||||
}
|
||||
|
||||
Qt::ItemFlags PortModel::flags(const QModelIndex &index) const
|
||||
{
|
||||
return QAbstractItemModel::flags(index); // FIXME: no need for this func
|
||||
}
|
||||
QVariant PortModel::data(const QModelIndex &index, int role) const
|
||||
{
|
||||
|
||||
DBG0("Enter PortModel data\n");
|
||||
|
||||
// Check for a valid index
|
||||
if (!index.isValid())
|
||||
return QVariant();
|
||||
|
||||
DBG1("PortModel::data(index).row = %d", index.row());
|
||||
DBG1("PortModel::data(index).column = %0d", index.column());
|
||||
DBG1("PortModel::data(index).internalId = %08llx", index.internalId());
|
||||
|
||||
QModelIndex parent = index.parent();
|
||||
|
||||
if (!parent.isValid())
|
||||
{
|
||||
// Top Level Item - PortGroup
|
||||
if ((role == Qt::DisplayRole))
|
||||
{
|
||||
DBG0("Exit PortModel data 1\n");
|
||||
return QString("Port Group %1: %2 [%3:%4] (%5)").
|
||||
arg(pgl->mPortGroups.at(index.row())->id()).
|
||||
arg(pgl->mPortGroups.at(index.row())->userAlias()).
|
||||
arg(pgl->mPortGroups.at(index.row())->serverAddress().toString()).
|
||||
arg(pgl->mPortGroups.at(index.row())->serverPort()).
|
||||
arg(pgl->mPortGroups.value(index.row())->numPorts());
|
||||
}
|
||||
else if ((role == Qt::DecorationRole))
|
||||
{
|
||||
DBG0("Exit PortModel data 2\n");
|
||||
switch(pgl->mPortGroups.at(index.row())->state())
|
||||
{
|
||||
case QAbstractSocket::UnconnectedState:
|
||||
return QIcon(":/icons/bullet_red.png");
|
||||
|
||||
case QAbstractSocket::HostLookupState:
|
||||
return QIcon(":/icons/bullet_yellow.png");
|
||||
|
||||
case QAbstractSocket::ConnectingState:
|
||||
case QAbstractSocket::ClosingState:
|
||||
return QIcon(":/icons/bullet_orange.png");
|
||||
|
||||
case QAbstractSocket::ConnectedState:
|
||||
return QIcon(":/icons/bullet_green.png");
|
||||
|
||||
|
||||
case QAbstractSocket::BoundState:
|
||||
case QAbstractSocket::ListeningState:
|
||||
default:
|
||||
return QIcon(":/icons/bullet_error.png");
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
DBG0("Exit PortModel data 3\n");
|
||||
return QVariant();
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
// Non Top Level - Port
|
||||
if ((role == Qt::DisplayRole))
|
||||
{
|
||||
DBG0("Exit PortModel data 4\n");
|
||||
if (pgl->mPortGroups.at(parent.row())->numPorts() == 0)
|
||||
return QVariant();
|
||||
|
||||
return QString("Port %1: %2 [%3] (%4)").
|
||||
arg(pgl->mPortGroups.at(
|
||||
parent.row())->mPorts[index.row()]->id()).
|
||||
arg(pgl->mPortGroups.at(
|
||||
parent.row())->mPorts[index.row()]->name()).
|
||||
arg(QHostAddress("0.0.0.0").toString()). // FIXME(LOW)
|
||||
arg(pgl->mPortGroups.at(
|
||||
parent.row())->mPorts[index.row()]->description());
|
||||
}
|
||||
else if ((role == Qt::DecorationRole))
|
||||
{
|
||||
DBG0("Exit PortModel data 5\n");
|
||||
if (pgl->mPortGroups.at(parent.row())->numPorts() == 0)
|
||||
return QVariant();
|
||||
switch(pgl->mPortGroups.at(parent.row())->mPorts[index.row()]->linkState())
|
||||
{
|
||||
case OstProto::LinkStateUnknown:
|
||||
return QIcon(":/icons/bullet_white.png");
|
||||
case OstProto::LinkStateDown:
|
||||
return QIcon(":/icons/bullet_red.png");
|
||||
case OstProto::LinkStateUp:
|
||||
return QIcon(":/icons/bullet_green.png");
|
||||
default:
|
||||
qFatal("unexpected/unimplemented port oper state");
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
DBG0("Exit PortModel data 6\n");
|
||||
return QVariant();
|
||||
}
|
||||
}
|
||||
|
||||
return QVariant();
|
||||
}
|
||||
|
||||
QVariant PortModel::headerData(int section, Qt::Orientation orientation, int role) const
|
||||
{
|
||||
if (role != Qt::DisplayRole)
|
||||
return QVariant();
|
||||
|
||||
if (orientation == Qt::Horizontal)
|
||||
return QVariant();
|
||||
else
|
||||
return QString("Name");
|
||||
}
|
||||
|
||||
QModelIndex PortModel::index (int row, int col,
|
||||
const QModelIndex & parent) const
|
||||
{
|
||||
if (!hasIndex(row, col, parent))
|
||||
return QModelIndex();
|
||||
|
||||
//qDebug("index: R=%d, C=%d, PR=%d, PC=%d, PID=%llx\n",
|
||||
// row, col, parent.row(), parent.column(), parent.internalId());
|
||||
|
||||
if (!parent.isValid())
|
||||
{
|
||||
// Top Level Item
|
||||
quint16 pg = pgl->mPortGroups.value(row)->id(), p = 0xFFFF;
|
||||
quint32 id = (pg << 16) | p;
|
||||
//qDebug("index (top) dbg: PG=%d, P=%d, ID=%x\n", pg, p, id);
|
||||
|
||||
return createIndex(row, col, id);
|
||||
}
|
||||
else
|
||||
{
|
||||
quint16 pg = parent.internalId() >> 16;
|
||||
quint16 p = pgl->mPortGroups.value(parent.row())->mPorts.value(row)->id();
|
||||
quint32 id = (pg << 16) | p;
|
||||
//qDebug("index (nontop) dbg: PG=%d, P=%d, ID=%x\n", pg, p, id);
|
||||
|
||||
return createIndex(row, col, id);
|
||||
}
|
||||
}
|
||||
|
||||
QModelIndex PortModel::parent(const QModelIndex &index) const
|
||||
{
|
||||
if (!index.isValid())
|
||||
return QModelIndex();
|
||||
|
||||
//qDebug("parent: R=%d, C=%d ID=%llx\n",
|
||||
// index.row(), index.column(), index.internalId());
|
||||
|
||||
quint16 pg = index.internalId() >> 16;
|
||||
quint16 p = index.internalId() & 0x0000FFFF;
|
||||
|
||||
//qDebug("parent dbg: PG=%d, P=%d\n", pg, p);
|
||||
|
||||
if (p == 0xFFFF)
|
||||
{
|
||||
//qDebug("parent ret: NULL\n");
|
||||
// Top Level Item - PG
|
||||
return QModelIndex();
|
||||
}
|
||||
|
||||
quint32 id = (pg << 16) | 0xFFFF;
|
||||
//qDebug("parent ret: R=%d, C=%d, ID=%x\n", pg, 0, id);
|
||||
|
||||
return createIndex(pgl->indexOfPortGroup(pg), 0, id);
|
||||
|
||||
}
|
||||
|
||||
bool PortModel::isPortGroup(const QModelIndex& index)
|
||||
{
|
||||
if ((index.internalId() & 0xFFFF) == 0xFFFF)
|
||||
return true;
|
||||
else
|
||||
return false;
|
||||
}
|
||||
|
||||
bool PortModel::isPort(const QModelIndex& index)
|
||||
{
|
||||
if ((index.internalId() & 0xFFFF) != 0xFFFF)
|
||||
return true;
|
||||
else
|
||||
return false;
|
||||
}
|
||||
|
||||
quint32 PortModel::portGroupId(const QModelIndex& index)
|
||||
{
|
||||
return (index.internalId()) >> 16 & 0xFFFF;
|
||||
}
|
||||
|
||||
quint32 PortModel::portId(const QModelIndex& index)
|
||||
{
|
||||
return (index.internalId()) & 0xFFFF;
|
||||
}
|
||||
|
||||
|
||||
|
||||
// ----------------------------------------------
|
||||
// Slots
|
||||
// ----------------------------------------------
|
||||
void PortModel::when_portGroupDataChanged(int portGroupId, int portId)
|
||||
{
|
||||
QModelIndex index;
|
||||
int row;
|
||||
|
||||
if (portId == 0xFFFF)
|
||||
row = pgl->indexOfPortGroup(portGroupId);
|
||||
else
|
||||
row = portId;
|
||||
|
||||
index = createIndex(row, 0, (portGroupId << 16) | portId);
|
||||
|
||||
emit dataChanged(index, index);
|
||||
}
|
||||
|
||||
void PortModel::portGroupAboutToBeAppended()
|
||||
{
|
||||
int row;
|
||||
|
||||
row = pgl->mPortGroups.size();
|
||||
beginInsertRows(QModelIndex(), row, row);
|
||||
}
|
||||
|
||||
void PortModel::portGroupAppended()
|
||||
{
|
||||
endInsertRows();
|
||||
}
|
||||
|
||||
void PortModel::portGroupAboutToBeRemoved(PortGroup *portGroup)
|
||||
{
|
||||
int row;
|
||||
|
||||
row = pgl->mPortGroups.indexOf(portGroup);
|
||||
beginRemoveRows(QModelIndex(), row, row);
|
||||
}
|
||||
|
||||
void PortModel::portGroupRemoved()
|
||||
{
|
||||
endRemoveRows();
|
||||
}
|
||||
|
||||
void PortModel::when_portListChanged()
|
||||
{
|
||||
reset();
|
||||
}
|
||||
#include "portmodel.h"
|
||||
#include "portgrouplist.h"
|
||||
#include <QIcon>
|
||||
|
||||
#if 0
|
||||
#define DBG0(x) qDebug(x)
|
||||
#define DBG1(x, p1) qDebug(x, (p1))
|
||||
#else
|
||||
#define DBG0(x) {}
|
||||
#define DBG1(x, p1) {}
|
||||
#endif
|
||||
|
||||
PortModel::PortModel(PortGroupList *p, QObject *parent)
|
||||
: QAbstractItemModel(parent)
|
||||
{
|
||||
pgl = p;
|
||||
}
|
||||
|
||||
int PortModel::rowCount(const QModelIndex &parent) const
|
||||
{
|
||||
// qDebug("RowCount Enter\n");
|
||||
if (!parent.isValid())
|
||||
{
|
||||
// Top Level Item
|
||||
//qDebug("RowCount (Top) Exit: %d\n", pgl->mPortGroups.size());
|
||||
return pgl->mPortGroups.size();
|
||||
}
|
||||
// qDebug("RowCount non top %d, %d, %llx\n",
|
||||
// parent.row(), parent.column(), parent.internalId());
|
||||
|
||||
quint16 pg = (parent.internalId() >> 16) & 0xFFFF;
|
||||
quint16 p = parent.internalId() & 0xFFFF;
|
||||
if (p == 0xFFFF)
|
||||
{
|
||||
#if 0 // wrong code?
|
||||
int count = 0;
|
||||
foreach(PortGroup *pg, pgl->mPortGroups)
|
||||
{
|
||||
count += pg->numPorts();
|
||||
}
|
||||
//qDebug("RowCount (Mid) Exit: %d\n", count);
|
||||
return count;
|
||||
#endif
|
||||
if (parent.column() == 0)
|
||||
return pgl->mPortGroups.value(pgl->indexOfPortGroup(pg))->numPorts();
|
||||
else
|
||||
return 0;
|
||||
}
|
||||
else
|
||||
{
|
||||
// Leaf Item
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
||||
int PortModel::columnCount(const QModelIndex &parent ) const
|
||||
{
|
||||
return 1; // FIXME: hardcoding
|
||||
}
|
||||
|
||||
Qt::ItemFlags PortModel::flags(const QModelIndex &index) const
|
||||
{
|
||||
return QAbstractItemModel::flags(index); // FIXME: no need for this func
|
||||
}
|
||||
QVariant PortModel::data(const QModelIndex &index, int role) const
|
||||
{
|
||||
|
||||
DBG0("Enter PortModel data\n");
|
||||
|
||||
// Check for a valid index
|
||||
if (!index.isValid())
|
||||
return QVariant();
|
||||
|
||||
DBG1("PortModel::data(index).row = %d", index.row());
|
||||
DBG1("PortModel::data(index).column = %0d", index.column());
|
||||
DBG1("PortModel::data(index).internalId = %08llx", index.internalId());
|
||||
|
||||
QModelIndex parent = index.parent();
|
||||
|
||||
if (!parent.isValid())
|
||||
{
|
||||
// Top Level Item - PortGroup
|
||||
if ((role == Qt::DisplayRole))
|
||||
{
|
||||
DBG0("Exit PortModel data 1\n");
|
||||
return QString("Port Group %1: %2 [%3:%4] (%5)").
|
||||
arg(pgl->mPortGroups.at(index.row())->id()).
|
||||
arg(pgl->mPortGroups.at(index.row())->userAlias()).
|
||||
arg(pgl->mPortGroups.at(index.row())->serverAddress().toString()).
|
||||
arg(pgl->mPortGroups.at(index.row())->serverPort()).
|
||||
arg(pgl->mPortGroups.value(index.row())->numPorts());
|
||||
}
|
||||
else if ((role == Qt::DecorationRole))
|
||||
{
|
||||
DBG0("Exit PortModel data 2\n");
|
||||
switch(pgl->mPortGroups.at(index.row())->state())
|
||||
{
|
||||
case QAbstractSocket::UnconnectedState:
|
||||
return QIcon(":/icons/bullet_red.png");
|
||||
|
||||
case QAbstractSocket::HostLookupState:
|
||||
return QIcon(":/icons/bullet_yellow.png");
|
||||
|
||||
case QAbstractSocket::ConnectingState:
|
||||
case QAbstractSocket::ClosingState:
|
||||
return QIcon(":/icons/bullet_orange.png");
|
||||
|
||||
case QAbstractSocket::ConnectedState:
|
||||
return QIcon(":/icons/bullet_green.png");
|
||||
|
||||
|
||||
case QAbstractSocket::BoundState:
|
||||
case QAbstractSocket::ListeningState:
|
||||
default:
|
||||
return QIcon(":/icons/bullet_error.png");
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
DBG0("Exit PortModel data 3\n");
|
||||
return QVariant();
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
// Non Top Level - Port
|
||||
if ((role == Qt::DisplayRole))
|
||||
{
|
||||
DBG0("Exit PortModel data 4\n");
|
||||
if (pgl->mPortGroups.at(parent.row())->numPorts() == 0)
|
||||
return QVariant();
|
||||
|
||||
return QString("Port %1: %2 [%3] (%4)").
|
||||
arg(pgl->mPortGroups.at(
|
||||
parent.row())->mPorts[index.row()]->id()).
|
||||
arg(pgl->mPortGroups.at(
|
||||
parent.row())->mPorts[index.row()]->name()).
|
||||
arg(QHostAddress("0.0.0.0").toString()). // FIXME(LOW)
|
||||
arg(pgl->mPortGroups.at(
|
||||
parent.row())->mPorts[index.row()]->description());
|
||||
}
|
||||
else if ((role == Qt::DecorationRole))
|
||||
{
|
||||
DBG0("Exit PortModel data 5\n");
|
||||
if (pgl->mPortGroups.at(parent.row())->numPorts() == 0)
|
||||
return QVariant();
|
||||
switch(pgl->mPortGroups.at(parent.row())->mPorts[index.row()]->linkState())
|
||||
{
|
||||
case OstProto::LinkStateUnknown:
|
||||
return QIcon(":/icons/bullet_white.png");
|
||||
case OstProto::LinkStateDown:
|
||||
return QIcon(":/icons/bullet_red.png");
|
||||
case OstProto::LinkStateUp:
|
||||
return QIcon(":/icons/bullet_green.png");
|
||||
default:
|
||||
qFatal("unexpected/unimplemented port oper state");
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
DBG0("Exit PortModel data 6\n");
|
||||
return QVariant();
|
||||
}
|
||||
}
|
||||
|
||||
return QVariant();
|
||||
}
|
||||
|
||||
QVariant PortModel::headerData(int section, Qt::Orientation orientation, int role) const
|
||||
{
|
||||
if (role != Qt::DisplayRole)
|
||||
return QVariant();
|
||||
|
||||
if (orientation == Qt::Horizontal)
|
||||
return QVariant();
|
||||
else
|
||||
return QString("Name");
|
||||
}
|
||||
|
||||
QModelIndex PortModel::index (int row, int col,
|
||||
const QModelIndex & parent) const
|
||||
{
|
||||
if (!hasIndex(row, col, parent))
|
||||
return QModelIndex();
|
||||
|
||||
//qDebug("index: R=%d, C=%d, PR=%d, PC=%d, PID=%llx\n",
|
||||
// row, col, parent.row(), parent.column(), parent.internalId());
|
||||
|
||||
if (!parent.isValid())
|
||||
{
|
||||
// Top Level Item
|
||||
quint16 pg = pgl->mPortGroups.value(row)->id(), p = 0xFFFF;
|
||||
quint32 id = (pg << 16) | p;
|
||||
//qDebug("index (top) dbg: PG=%d, P=%d, ID=%x\n", pg, p, id);
|
||||
|
||||
return createIndex(row, col, id);
|
||||
}
|
||||
else
|
||||
{
|
||||
quint16 pg = parent.internalId() >> 16;
|
||||
quint16 p = pgl->mPortGroups.value(parent.row())->mPorts.value(row)->id();
|
||||
quint32 id = (pg << 16) | p;
|
||||
//qDebug("index (nontop) dbg: PG=%d, P=%d, ID=%x\n", pg, p, id);
|
||||
|
||||
return createIndex(row, col, id);
|
||||
}
|
||||
}
|
||||
|
||||
QModelIndex PortModel::parent(const QModelIndex &index) const
|
||||
{
|
||||
if (!index.isValid())
|
||||
return QModelIndex();
|
||||
|
||||
//qDebug("parent: R=%d, C=%d ID=%llx\n",
|
||||
// index.row(), index.column(), index.internalId());
|
||||
|
||||
quint16 pg = index.internalId() >> 16;
|
||||
quint16 p = index.internalId() & 0x0000FFFF;
|
||||
|
||||
//qDebug("parent dbg: PG=%d, P=%d\n", pg, p);
|
||||
|
||||
if (p == 0xFFFF)
|
||||
{
|
||||
//qDebug("parent ret: NULL\n");
|
||||
// Top Level Item - PG
|
||||
return QModelIndex();
|
||||
}
|
||||
|
||||
quint32 id = (pg << 16) | 0xFFFF;
|
||||
//qDebug("parent ret: R=%d, C=%d, ID=%x\n", pg, 0, id);
|
||||
|
||||
return createIndex(pgl->indexOfPortGroup(pg), 0, id);
|
||||
|
||||
}
|
||||
|
||||
bool PortModel::isPortGroup(const QModelIndex& index)
|
||||
{
|
||||
if ((index.internalId() & 0xFFFF) == 0xFFFF)
|
||||
return true;
|
||||
else
|
||||
return false;
|
||||
}
|
||||
|
||||
bool PortModel::isPort(const QModelIndex& index)
|
||||
{
|
||||
if ((index.internalId() & 0xFFFF) != 0xFFFF)
|
||||
return true;
|
||||
else
|
||||
return false;
|
||||
}
|
||||
|
||||
quint32 PortModel::portGroupId(const QModelIndex& index)
|
||||
{
|
||||
return (index.internalId()) >> 16 & 0xFFFF;
|
||||
}
|
||||
|
||||
quint32 PortModel::portId(const QModelIndex& index)
|
||||
{
|
||||
return (index.internalId()) & 0xFFFF;
|
||||
}
|
||||
|
||||
|
||||
|
||||
// ----------------------------------------------
|
||||
// Slots
|
||||
// ----------------------------------------------
|
||||
void PortModel::when_portGroupDataChanged(int portGroupId, int portId)
|
||||
{
|
||||
QModelIndex index;
|
||||
int row;
|
||||
|
||||
if (portId == 0xFFFF)
|
||||
row = pgl->indexOfPortGroup(portGroupId);
|
||||
else
|
||||
row = portId;
|
||||
|
||||
index = createIndex(row, 0, (portGroupId << 16) | portId);
|
||||
|
||||
emit dataChanged(index, index);
|
||||
}
|
||||
|
||||
void PortModel::portGroupAboutToBeAppended()
|
||||
{
|
||||
int row;
|
||||
|
||||
row = pgl->mPortGroups.size();
|
||||
beginInsertRows(QModelIndex(), row, row);
|
||||
}
|
||||
|
||||
void PortModel::portGroupAppended()
|
||||
{
|
||||
endInsertRows();
|
||||
}
|
||||
|
||||
void PortModel::portGroupAboutToBeRemoved(PortGroup *portGroup)
|
||||
{
|
||||
int row;
|
||||
|
||||
row = pgl->mPortGroups.indexOf(portGroup);
|
||||
beginRemoveRows(QModelIndex(), row, row);
|
||||
}
|
||||
|
||||
void PortModel::portGroupRemoved()
|
||||
{
|
||||
endRemoveRows();
|
||||
}
|
||||
|
||||
void PortModel::when_portListChanged()
|
||||
{
|
||||
reset();
|
||||
}
|
||||
|
@ -1,51 +1,51 @@
|
||||
#ifndef _PORT_MODEL_H
|
||||
#define _PORT_MODEL_H
|
||||
|
||||
#include <QAbstractItemModel>
|
||||
|
||||
class PortGroupList;
|
||||
class PortGroup;
|
||||
|
||||
class PortModel : public QAbstractItemModel
|
||||
{
|
||||
Q_OBJECT
|
||||
|
||||
friend class PortGroupList;
|
||||
|
||||
PortGroupList *pgl;
|
||||
|
||||
public:
|
||||
PortModel(PortGroupList *p, QObject *parent = 0);
|
||||
|
||||
int rowCount(const QModelIndex &parent = QModelIndex()) const;
|
||||
int columnCount(const QModelIndex &parent = QModelIndex()) const;
|
||||
Qt::ItemFlags flags(const QModelIndex &index) const;
|
||||
QVariant data(const QModelIndex &index, int role) const;
|
||||
QVariant headerData(int section, Qt::Orientation orientation, int role = Qt::DisplayRole) const;
|
||||
QModelIndex index (int row, int col, const QModelIndex & parent = QModelIndex() ) const;
|
||||
QModelIndex parent(const QModelIndex &index) const;
|
||||
|
||||
bool isPortGroup(const QModelIndex& index);
|
||||
bool isPort(const QModelIndex& index);
|
||||
quint32 portGroupId(const QModelIndex& index);
|
||||
quint32 portId(const QModelIndex& index);
|
||||
|
||||
|
||||
private slots:
|
||||
void when_portGroupDataChanged(int portGroupId, int portId);
|
||||
|
||||
void portGroupAboutToBeAppended();
|
||||
void portGroupAppended();
|
||||
void portGroupAboutToBeRemoved(PortGroup *portGroup);
|
||||
void portGroupRemoved();
|
||||
|
||||
void when_portListChanged();
|
||||
|
||||
#if 0
|
||||
void triggerLayoutAboutToBeChanged();
|
||||
void triggerLayoutChanged();
|
||||
#endif
|
||||
|
||||
};
|
||||
|
||||
#endif
|
||||
#ifndef _PORT_MODEL_H
|
||||
#define _PORT_MODEL_H
|
||||
|
||||
#include <QAbstractItemModel>
|
||||
|
||||
class PortGroupList;
|
||||
class PortGroup;
|
||||
|
||||
class PortModel : public QAbstractItemModel
|
||||
{
|
||||
Q_OBJECT
|
||||
|
||||
friend class PortGroupList;
|
||||
|
||||
PortGroupList *pgl;
|
||||
|
||||
public:
|
||||
PortModel(PortGroupList *p, QObject *parent = 0);
|
||||
|
||||
int rowCount(const QModelIndex &parent = QModelIndex()) const;
|
||||
int columnCount(const QModelIndex &parent = QModelIndex()) const;
|
||||
Qt::ItemFlags flags(const QModelIndex &index) const;
|
||||
QVariant data(const QModelIndex &index, int role) const;
|
||||
QVariant headerData(int section, Qt::Orientation orientation, int role = Qt::DisplayRole) const;
|
||||
QModelIndex index (int row, int col, const QModelIndex & parent = QModelIndex() ) const;
|
||||
QModelIndex parent(const QModelIndex &index) const;
|
||||
|
||||
bool isPortGroup(const QModelIndex& index);
|
||||
bool isPort(const QModelIndex& index);
|
||||
quint32 portGroupId(const QModelIndex& index);
|
||||
quint32 portId(const QModelIndex& index);
|
||||
|
||||
|
||||
private slots:
|
||||
void when_portGroupDataChanged(int portGroupId, int portId);
|
||||
|
||||
void portGroupAboutToBeAppended();
|
||||
void portGroupAppended();
|
||||
void portGroupAboutToBeRemoved(PortGroup *portGroup);
|
||||
void portGroupRemoved();
|
||||
|
||||
void when_portListChanged();
|
||||
|
||||
#if 0
|
||||
void triggerLayoutAboutToBeChanged();
|
||||
void triggerLayoutChanged();
|
||||
#endif
|
||||
|
||||
};
|
||||
|
||||
#endif
|
||||
|
@ -1,111 +1,111 @@
|
||||
#include "portstatsfilterdialog.h"
|
||||
|
||||
PortStatsFilterDialog::PortStatsFilterDialog(QWidget *parent)
|
||||
{
|
||||
setupUi(this);
|
||||
|
||||
mUnselected.setSortRole(PositionRole);
|
||||
|
||||
lvUnselected->setModel(&mUnselected);
|
||||
lvSelected->setModel(&mSelected);
|
||||
}
|
||||
|
||||
QList<uint> PortStatsFilterDialog::getItemList(bool* ok,
|
||||
QAbstractItemModel *model, Qt::Orientation orientation,
|
||||
QList<uint> initial)
|
||||
{
|
||||
QList<uint> ret;
|
||||
|
||||
uint count = (orientation == Qt::Vertical) ?
|
||||
model->rowCount() : model->columnCount();
|
||||
|
||||
*ok = false;
|
||||
|
||||
mUnselected.clear();
|
||||
mSelected.clear();
|
||||
|
||||
for (uint i = 0; i < count; i++)
|
||||
{
|
||||
QStandardItem *item;
|
||||
|
||||
item = new QStandardItem(model->headerData(i, orientation).toString());
|
||||
item->setData(i, PositionRole);
|
||||
item->setFlags(Qt::ItemIsSelectable
|
||||
| Qt::ItemIsDragEnabled
|
||||
//| Qt::ItemIsDropEnabled
|
||||
| Qt::ItemIsEnabled);
|
||||
|
||||
if (initial.contains(i))
|
||||
mSelected.appendRow(item);
|
||||
else
|
||||
mUnselected.appendRow(item);
|
||||
}
|
||||
|
||||
// No need to sort right now 'coz we have inserted items in order
|
||||
|
||||
if (exec() == QDialog::Accepted)
|
||||
{
|
||||
uint count = mSelected.rowCount();
|
||||
for (uint i = 0; i < count; i++)
|
||||
{
|
||||
QModelIndex index = mSelected.index(i, 0, QModelIndex());
|
||||
QStandardItem *item = mSelected.itemFromIndex(index);
|
||||
ret.append(item->data(PositionRole).toInt());
|
||||
}
|
||||
*ok = true;
|
||||
}
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
void PortStatsFilterDialog::on_tbSelectIn_clicked()
|
||||
{
|
||||
QStandardItem *item;
|
||||
while (lvUnselected->selectionModel()->selectedIndexes().size())
|
||||
{
|
||||
item = mUnselected.takeItem(lvUnselected->selectionModel()->
|
||||
selectedIndexes().at(0).row());
|
||||
if (mUnselected.removeRow(lvUnselected->selectionModel()->
|
||||
selectedIndexes().at(0).row()))
|
||||
mSelected.appendRow(item);
|
||||
}
|
||||
}
|
||||
|
||||
void PortStatsFilterDialog::on_tbSelectOut_clicked()
|
||||
{
|
||||
QStandardItem *item;
|
||||
|
||||
while (lvSelected->selectionModel()->selectedIndexes().size())
|
||||
{
|
||||
item = mSelected.takeItem(lvSelected->selectionModel()->
|
||||
selectedIndexes().at(0).row());
|
||||
if (mSelected.removeRow(lvSelected->selectionModel()->
|
||||
selectedIndexes().at(0).row()))
|
||||
{
|
||||
mUnselected.appendRow(item);
|
||||
mUnselected.sort(0);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void PortStatsFilterDialog::on_lvUnselected_doubleClicked(const QModelIndex &index)
|
||||
{
|
||||
QStandardItem *item;
|
||||
|
||||
item = mUnselected.takeItem(lvUnselected->currentIndex().row());
|
||||
if (mUnselected.removeRow(lvUnselected->currentIndex().row()))
|
||||
mSelected.appendRow(item);
|
||||
}
|
||||
|
||||
void PortStatsFilterDialog::on_lvSelected_doubleClicked(const QModelIndex &index)
|
||||
{
|
||||
QStandardItem *item;
|
||||
|
||||
item = mSelected.takeItem(lvSelected->currentIndex().row());
|
||||
if (mSelected.removeRow(lvSelected->currentIndex().row()))
|
||||
{
|
||||
mUnselected.appendRow(item);
|
||||
mUnselected.sort(0);
|
||||
}
|
||||
}
|
||||
|
||||
#include "portstatsfilterdialog.h"
|
||||
|
||||
PortStatsFilterDialog::PortStatsFilterDialog(QWidget *parent)
|
||||
{
|
||||
setupUi(this);
|
||||
|
||||
mUnselected.setSortRole(PositionRole);
|
||||
|
||||
lvUnselected->setModel(&mUnselected);
|
||||
lvSelected->setModel(&mSelected);
|
||||
}
|
||||
|
||||
QList<uint> PortStatsFilterDialog::getItemList(bool* ok,
|
||||
QAbstractItemModel *model, Qt::Orientation orientation,
|
||||
QList<uint> initial)
|
||||
{
|
||||
QList<uint> ret;
|
||||
|
||||
uint count = (orientation == Qt::Vertical) ?
|
||||
model->rowCount() : model->columnCount();
|
||||
|
||||
*ok = false;
|
||||
|
||||
mUnselected.clear();
|
||||
mSelected.clear();
|
||||
|
||||
for (uint i = 0; i < count; i++)
|
||||
{
|
||||
QStandardItem *item;
|
||||
|
||||
item = new QStandardItem(model->headerData(i, orientation).toString());
|
||||
item->setData(i, PositionRole);
|
||||
item->setFlags(Qt::ItemIsSelectable
|
||||
| Qt::ItemIsDragEnabled
|
||||
//| Qt::ItemIsDropEnabled
|
||||
| Qt::ItemIsEnabled);
|
||||
|
||||
if (initial.contains(i))
|
||||
mSelected.appendRow(item);
|
||||
else
|
||||
mUnselected.appendRow(item);
|
||||
}
|
||||
|
||||
// No need to sort right now 'coz we have inserted items in order
|
||||
|
||||
if (exec() == QDialog::Accepted)
|
||||
{
|
||||
uint count = mSelected.rowCount();
|
||||
for (uint i = 0; i < count; i++)
|
||||
{
|
||||
QModelIndex index = mSelected.index(i, 0, QModelIndex());
|
||||
QStandardItem *item = mSelected.itemFromIndex(index);
|
||||
ret.append(item->data(PositionRole).toInt());
|
||||
}
|
||||
*ok = true;
|
||||
}
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
void PortStatsFilterDialog::on_tbSelectIn_clicked()
|
||||
{
|
||||
QStandardItem *item;
|
||||
while (lvUnselected->selectionModel()->selectedIndexes().size())
|
||||
{
|
||||
item = mUnselected.takeItem(lvUnselected->selectionModel()->
|
||||
selectedIndexes().at(0).row());
|
||||
if (mUnselected.removeRow(lvUnselected->selectionModel()->
|
||||
selectedIndexes().at(0).row()))
|
||||
mSelected.appendRow(item);
|
||||
}
|
||||
}
|
||||
|
||||
void PortStatsFilterDialog::on_tbSelectOut_clicked()
|
||||
{
|
||||
QStandardItem *item;
|
||||
|
||||
while (lvSelected->selectionModel()->selectedIndexes().size())
|
||||
{
|
||||
item = mSelected.takeItem(lvSelected->selectionModel()->
|
||||
selectedIndexes().at(0).row());
|
||||
if (mSelected.removeRow(lvSelected->selectionModel()->
|
||||
selectedIndexes().at(0).row()))
|
||||
{
|
||||
mUnselected.appendRow(item);
|
||||
mUnselected.sort(0);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void PortStatsFilterDialog::on_lvUnselected_doubleClicked(const QModelIndex &index)
|
||||
{
|
||||
QStandardItem *item;
|
||||
|
||||
item = mUnselected.takeItem(lvUnselected->currentIndex().row());
|
||||
if (mUnselected.removeRow(lvUnselected->currentIndex().row()))
|
||||
mSelected.appendRow(item);
|
||||
}
|
||||
|
||||
void PortStatsFilterDialog::on_lvSelected_doubleClicked(const QModelIndex &index)
|
||||
{
|
||||
QStandardItem *item;
|
||||
|
||||
item = mSelected.takeItem(lvSelected->currentIndex().row());
|
||||
if (mSelected.removeRow(lvSelected->currentIndex().row()))
|
||||
{
|
||||
mUnselected.appendRow(item);
|
||||
mUnselected.sort(0);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -1,35 +1,35 @@
|
||||
#ifndef _PORT_STATS_FILTER_DIALOG_H
|
||||
#define _PORT_STATS_FILTER_DIALOG_H
|
||||
|
||||
#include <QDialog>
|
||||
#include <QAbstractItemModel>
|
||||
#include <QStandardItemModel>
|
||||
#include "ui_portstatsfilter.h"
|
||||
#include "portgrouplist.h"
|
||||
|
||||
class PortStatsFilterDialog : public QDialog, public Ui::PortStatsFilterDialog
|
||||
{
|
||||
Q_OBJECT
|
||||
|
||||
public:
|
||||
PortStatsFilterDialog(QWidget *parent = 0);
|
||||
QList<uint> getItemList(bool* ok, QAbstractItemModel *model,
|
||||
Qt::Orientation orientation = Qt::Vertical,
|
||||
QList<uint> initial = QList<uint>());
|
||||
|
||||
private:
|
||||
enum ItemRole {
|
||||
PositionRole = Qt::UserRole + 1
|
||||
};
|
||||
QStandardItemModel mUnselected;
|
||||
QStandardItemModel mSelected;
|
||||
|
||||
private slots:
|
||||
void on_tbSelectIn_clicked();
|
||||
void on_tbSelectOut_clicked();
|
||||
void on_lvUnselected_doubleClicked(const QModelIndex &index);
|
||||
void on_lvSelected_doubleClicked(const QModelIndex &index);
|
||||
};
|
||||
|
||||
#endif
|
||||
|
||||
#ifndef _PORT_STATS_FILTER_DIALOG_H
|
||||
#define _PORT_STATS_FILTER_DIALOG_H
|
||||
|
||||
#include <QDialog>
|
||||
#include <QAbstractItemModel>
|
||||
#include <QStandardItemModel>
|
||||
#include "ui_portstatsfilter.h"
|
||||
#include "portgrouplist.h"
|
||||
|
||||
class PortStatsFilterDialog : public QDialog, public Ui::PortStatsFilterDialog
|
||||
{
|
||||
Q_OBJECT
|
||||
|
||||
public:
|
||||
PortStatsFilterDialog(QWidget *parent = 0);
|
||||
QList<uint> getItemList(bool* ok, QAbstractItemModel *model,
|
||||
Qt::Orientation orientation = Qt::Vertical,
|
||||
QList<uint> initial = QList<uint>());
|
||||
|
||||
private:
|
||||
enum ItemRole {
|
||||
PositionRole = Qt::UserRole + 1
|
||||
};
|
||||
QStandardItemModel mUnselected;
|
||||
QStandardItemModel mSelected;
|
||||
|
||||
private slots:
|
||||
void on_tbSelectIn_clicked();
|
||||
void on_tbSelectOut_clicked();
|
||||
void on_lvUnselected_doubleClicked(const QModelIndex &index);
|
||||
void on_lvSelected_doubleClicked(const QModelIndex &index);
|
||||
};
|
||||
|
||||
#endif
|
||||
|
||||
|
@ -1,288 +1,288 @@
|
||||
#include "portstatsmodel.h"
|
||||
#include "portgrouplist.h"
|
||||
|
||||
#include <QTimer>
|
||||
|
||||
PortStatsModel::PortStatsModel(PortGroupList *p, QObject *parent)
|
||||
: QAbstractTableModel(parent)
|
||||
{
|
||||
QTimer *timer;
|
||||
|
||||
pgl = p;
|
||||
|
||||
timer = new QTimer();
|
||||
connect(timer, SIGNAL(timeout()), this, SLOT(updateStats()));
|
||||
timer->start(1000);
|
||||
}
|
||||
|
||||
int PortStatsModel::rowCount(const QModelIndex &parent) const
|
||||
{
|
||||
if (parent.isValid())
|
||||
return 0;
|
||||
|
||||
if (numPorts.isEmpty())
|
||||
return 0;
|
||||
|
||||
if (numPorts.last() == 0)
|
||||
return 0;
|
||||
|
||||
return (int) e_STAT_MAX;
|
||||
}
|
||||
|
||||
int PortStatsModel::columnCount(const QModelIndex &parent ) const
|
||||
{
|
||||
if (parent.isValid())
|
||||
return 0;
|
||||
else
|
||||
if (numPorts.isEmpty())
|
||||
return 0;
|
||||
else
|
||||
return numPorts.last();
|
||||
}
|
||||
|
||||
void PortStatsModel::getDomainIndexes(const QModelIndex &index,
|
||||
uint &portGroupIdx, uint &portIdx) const
|
||||
{
|
||||
int portNum;
|
||||
|
||||
// TODO(LOW): Optimize using binary search: see qLowerBound()
|
||||
portNum = index.column() + 1;
|
||||
for (portGroupIdx = 0; portGroupIdx < (uint) numPorts.size(); portGroupIdx++)
|
||||
if (portNum <= numPorts.at(portGroupIdx))
|
||||
break;
|
||||
|
||||
if (portGroupIdx)
|
||||
{
|
||||
if (numPorts.at(portGroupIdx -1))
|
||||
portIdx = (portNum - 1) % numPorts.at(portGroupIdx - 1);
|
||||
else
|
||||
portIdx = portNum - 1;
|
||||
}
|
||||
else
|
||||
portIdx = portNum - 1;
|
||||
|
||||
//qDebug("PSM: %d - %d, %d", index.column(), portGroupIdx, portIdx);
|
||||
}
|
||||
|
||||
QVariant PortStatsModel::data(const QModelIndex &index, int role) const
|
||||
{
|
||||
uint pgidx, pidx;
|
||||
int row;
|
||||
|
||||
// Check for a valid index
|
||||
if (!index.isValid())
|
||||
return QVariant();
|
||||
|
||||
// Check for row/column limits
|
||||
row = index.row();
|
||||
if (row >= e_STAT_MAX)
|
||||
return QVariant();
|
||||
|
||||
if (numPorts.isEmpty())
|
||||
return QVariant();
|
||||
|
||||
if (index.column() >= (numPorts.last()))
|
||||
return QVariant();
|
||||
|
||||
getDomainIndexes(index, pgidx, pidx);
|
||||
|
||||
// Check role
|
||||
if (role == Qt::DisplayRole)
|
||||
{
|
||||
OstProto::PortStats stats;
|
||||
|
||||
stats = pgl->mPortGroups.at(pgidx)->mPorts[pidx]->getStats();
|
||||
|
||||
switch(row)
|
||||
{
|
||||
// States
|
||||
case e_LINK_STATE:
|
||||
return LinkStateName.at(stats.state().link_state());
|
||||
|
||||
case e_TRANSMIT_STATE:
|
||||
return BoolStateName.at(stats.state().is_transmit_on());
|
||||
|
||||
case e_CAPTURE_STATE:
|
||||
return BoolStateName.at(stats.state().is_capture_on());
|
||||
|
||||
// Statistics
|
||||
case e_STAT_FRAMES_RCVD:
|
||||
return stats.rx_pkts();
|
||||
|
||||
case e_STAT_FRAMES_SENT:
|
||||
return stats.tx_pkts();
|
||||
|
||||
case e_STAT_FRAME_SEND_RATE:
|
||||
return stats.tx_pps();
|
||||
|
||||
case e_STAT_FRAME_RECV_RATE:
|
||||
return stats.rx_pps();
|
||||
|
||||
case e_STAT_BYTES_RCVD:
|
||||
return stats.rx_bytes();
|
||||
|
||||
case e_STAT_BYTES_SENT:
|
||||
return stats.tx_bytes();
|
||||
|
||||
case e_STAT_BYTE_SEND_RATE:
|
||||
return stats.tx_bps();
|
||||
|
||||
case e_STAT_BYTE_RECV_RATE:
|
||||
return stats.rx_bps();
|
||||
|
||||
#if 0
|
||||
case e_STAT_FRAMES_RCVD_NIC:
|
||||
return stats.rx_pkts_nic();
|
||||
|
||||
case e_STAT_FRAMES_SENT_NIC:
|
||||
return stats.tx_pkts_nic();
|
||||
|
||||
case e_STAT_BYTES_RCVD_NIC:
|
||||
return stats.rx_bytes_nic();
|
||||
|
||||
case e_STAT_BYTES_SENT_NIC:
|
||||
return stats.tx_bytes_nic();
|
||||
#endif
|
||||
default:
|
||||
qWarning("%s: Unhandled stats id %d\n", __FUNCTION__,
|
||||
index.row());
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
else if (role == Qt::TextAlignmentRole)
|
||||
{
|
||||
if (row >= e_STATE_START && row <= e_STATE_END)
|
||||
return Qt::AlignHCenter;
|
||||
else if (row >= e_STATISTICS_START && row <= e_STATISTICS_END)
|
||||
return Qt::AlignRight;
|
||||
else
|
||||
return QVariant();
|
||||
}
|
||||
else
|
||||
return QVariant();
|
||||
|
||||
}
|
||||
|
||||
QVariant PortStatsModel::headerData(int section, Qt::Orientation orientation, int role) const
|
||||
{
|
||||
#ifdef Q_OS_WIN32
|
||||
// TODO(MED): The limitations should be the server's not the client's!
|
||||
// Ideally we shd enhance the protocol to convey limitation(s), if any,
|
||||
// from server to client
|
||||
if (role == Qt::ToolTipRole)
|
||||
{
|
||||
if (orientation == Qt::Horizontal)
|
||||
{
|
||||
return QString("<b>Limitation(s)</b>"
|
||||
"<p><i>Frames/Bytes Receieved</i>: Includes non Ostinato Tx pkts also (Tx by Ostinato are not included)<br>"
|
||||
"<i>Frames/Bytes Sent</i>: Only Ostinato Tx pkts (Tx by others NOT included)</p>"
|
||||
"<p>Rx/Tx Rates are derived from the above and hence subject to same limitations</p>"
|
||||
);
|
||||
}
|
||||
else
|
||||
return QVariant();
|
||||
}
|
||||
#endif
|
||||
|
||||
if (role != Qt::DisplayRole)
|
||||
return QVariant();
|
||||
|
||||
if (orientation == Qt::Horizontal)
|
||||
{
|
||||
uint portGroupIdx, portIdx;
|
||||
|
||||
getDomainIndexes(index(0, section), portGroupIdx, portIdx);
|
||||
#ifdef Q_OS_WIN32
|
||||
return QString("Port %1-%2 (*)").arg(portGroupIdx).arg(portIdx);
|
||||
#else
|
||||
return QString("Port %1-%2").arg(portGroupIdx).arg(portIdx);
|
||||
#endif
|
||||
}
|
||||
else
|
||||
return PortStatName.at(section);
|
||||
}
|
||||
|
||||
void PortStatsModel::portListFromIndex(QModelIndexList indices,
|
||||
QList<PortGroupAndPortList> &portList)
|
||||
{
|
||||
int i, j;
|
||||
QModelIndexList selectedCols(indices);
|
||||
|
||||
portList.clear();
|
||||
|
||||
//selectedCols = indices.selectedColumns();
|
||||
for (i = 0; i < selectedCols.size(); i++)
|
||||
{
|
||||
uint portGroupIdx, portIdx;
|
||||
|
||||
getDomainIndexes(selectedCols.at(i), portGroupIdx, portIdx);
|
||||
for (j = 0; j < portList.size(); j++)
|
||||
{
|
||||
if (portList[j].portGroupId == portGroupIdx)
|
||||
break;
|
||||
}
|
||||
|
||||
if (j >= portList.size())
|
||||
{
|
||||
// PortGroup Not found
|
||||
PortGroupAndPortList p;
|
||||
|
||||
p.portGroupId = portGroupIdx;
|
||||
p.portList.append(portIdx);
|
||||
|
||||
portList.append(p);
|
||||
}
|
||||
else
|
||||
{
|
||||
// PortGroup found
|
||||
|
||||
portList[j].portList.append(portIdx);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
//
|
||||
// Slots
|
||||
//
|
||||
void PortStatsModel::when_portListChanged()
|
||||
{
|
||||
int i, count = 0;
|
||||
|
||||
// recalc numPorts
|
||||
while (numPorts.size())
|
||||
numPorts.removeFirst();
|
||||
|
||||
for (i = 0; i < pgl->mPortGroups.size(); i++)
|
||||
{
|
||||
count += pgl->mPortGroups.at(i)->numPorts();
|
||||
numPorts.append(count);
|
||||
}
|
||||
|
||||
reset();
|
||||
}
|
||||
|
||||
void PortStatsModel::on_portStatsUpdate(int port, void*stats)
|
||||
{
|
||||
QModelIndex topLeft = index(port, 0, QModelIndex());
|
||||
QModelIndex bottomRight = index(port, e_STAT_MAX, QModelIndex());
|
||||
|
||||
emit dataChanged(topLeft, bottomRight);
|
||||
}
|
||||
|
||||
void PortStatsModel::updateStats()
|
||||
{
|
||||
// Request each portgroup to fetch updated stats - the port group
|
||||
// raises a signal once updated stats are available
|
||||
for (int i = 0; i < pgl->mPortGroups.size(); i++)
|
||||
pgl->mPortGroups[i]->getPortStats();
|
||||
}
|
||||
|
||||
void PortStatsModel::when_portGroup_stats_update(quint32 portGroupId)
|
||||
{
|
||||
// FIXME(MED): update only the changed ports, not all
|
||||
|
||||
QModelIndex topLeft = index(0, 0, QModelIndex());
|
||||
QModelIndex bottomRight = index(rowCount(), columnCount(), QModelIndex());
|
||||
|
||||
emit dataChanged(topLeft, bottomRight);
|
||||
}
|
||||
#include "portstatsmodel.h"
|
||||
#include "portgrouplist.h"
|
||||
|
||||
#include <QTimer>
|
||||
|
||||
PortStatsModel::PortStatsModel(PortGroupList *p, QObject *parent)
|
||||
: QAbstractTableModel(parent)
|
||||
{
|
||||
QTimer *timer;
|
||||
|
||||
pgl = p;
|
||||
|
||||
timer = new QTimer();
|
||||
connect(timer, SIGNAL(timeout()), this, SLOT(updateStats()));
|
||||
timer->start(1000);
|
||||
}
|
||||
|
||||
int PortStatsModel::rowCount(const QModelIndex &parent) const
|
||||
{
|
||||
if (parent.isValid())
|
||||
return 0;
|
||||
|
||||
if (numPorts.isEmpty())
|
||||
return 0;
|
||||
|
||||
if (numPorts.last() == 0)
|
||||
return 0;
|
||||
|
||||
return (int) e_STAT_MAX;
|
||||
}
|
||||
|
||||
int PortStatsModel::columnCount(const QModelIndex &parent ) const
|
||||
{
|
||||
if (parent.isValid())
|
||||
return 0;
|
||||
else
|
||||
if (numPorts.isEmpty())
|
||||
return 0;
|
||||
else
|
||||
return numPorts.last();
|
||||
}
|
||||
|
||||
void PortStatsModel::getDomainIndexes(const QModelIndex &index,
|
||||
uint &portGroupIdx, uint &portIdx) const
|
||||
{
|
||||
int portNum;
|
||||
|
||||
// TODO(LOW): Optimize using binary search: see qLowerBound()
|
||||
portNum = index.column() + 1;
|
||||
for (portGroupIdx = 0; portGroupIdx < (uint) numPorts.size(); portGroupIdx++)
|
||||
if (portNum <= numPorts.at(portGroupIdx))
|
||||
break;
|
||||
|
||||
if (portGroupIdx)
|
||||
{
|
||||
if (numPorts.at(portGroupIdx -1))
|
||||
portIdx = (portNum - 1) % numPorts.at(portGroupIdx - 1);
|
||||
else
|
||||
portIdx = portNum - 1;
|
||||
}
|
||||
else
|
||||
portIdx = portNum - 1;
|
||||
|
||||
//qDebug("PSM: %d - %d, %d", index.column(), portGroupIdx, portIdx);
|
||||
}
|
||||
|
||||
QVariant PortStatsModel::data(const QModelIndex &index, int role) const
|
||||
{
|
||||
uint pgidx, pidx;
|
||||
int row;
|
||||
|
||||
// Check for a valid index
|
||||
if (!index.isValid())
|
||||
return QVariant();
|
||||
|
||||
// Check for row/column limits
|
||||
row = index.row();
|
||||
if (row >= e_STAT_MAX)
|
||||
return QVariant();
|
||||
|
||||
if (numPorts.isEmpty())
|
||||
return QVariant();
|
||||
|
||||
if (index.column() >= (numPorts.last()))
|
||||
return QVariant();
|
||||
|
||||
getDomainIndexes(index, pgidx, pidx);
|
||||
|
||||
// Check role
|
||||
if (role == Qt::DisplayRole)
|
||||
{
|
||||
OstProto::PortStats stats;
|
||||
|
||||
stats = pgl->mPortGroups.at(pgidx)->mPorts[pidx]->getStats();
|
||||
|
||||
switch(row)
|
||||
{
|
||||
// States
|
||||
case e_LINK_STATE:
|
||||
return LinkStateName.at(stats.state().link_state());
|
||||
|
||||
case e_TRANSMIT_STATE:
|
||||
return BoolStateName.at(stats.state().is_transmit_on());
|
||||
|
||||
case e_CAPTURE_STATE:
|
||||
return BoolStateName.at(stats.state().is_capture_on());
|
||||
|
||||
// Statistics
|
||||
case e_STAT_FRAMES_RCVD:
|
||||
return stats.rx_pkts();
|
||||
|
||||
case e_STAT_FRAMES_SENT:
|
||||
return stats.tx_pkts();
|
||||
|
||||
case e_STAT_FRAME_SEND_RATE:
|
||||
return stats.tx_pps();
|
||||
|
||||
case e_STAT_FRAME_RECV_RATE:
|
||||
return stats.rx_pps();
|
||||
|
||||
case e_STAT_BYTES_RCVD:
|
||||
return stats.rx_bytes();
|
||||
|
||||
case e_STAT_BYTES_SENT:
|
||||
return stats.tx_bytes();
|
||||
|
||||
case e_STAT_BYTE_SEND_RATE:
|
||||
return stats.tx_bps();
|
||||
|
||||
case e_STAT_BYTE_RECV_RATE:
|
||||
return stats.rx_bps();
|
||||
|
||||
#if 0
|
||||
case e_STAT_FRAMES_RCVD_NIC:
|
||||
return stats.rx_pkts_nic();
|
||||
|
||||
case e_STAT_FRAMES_SENT_NIC:
|
||||
return stats.tx_pkts_nic();
|
||||
|
||||
case e_STAT_BYTES_RCVD_NIC:
|
||||
return stats.rx_bytes_nic();
|
||||
|
||||
case e_STAT_BYTES_SENT_NIC:
|
||||
return stats.tx_bytes_nic();
|
||||
#endif
|
||||
default:
|
||||
qWarning("%s: Unhandled stats id %d\n", __FUNCTION__,
|
||||
index.row());
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
else if (role == Qt::TextAlignmentRole)
|
||||
{
|
||||
if (row >= e_STATE_START && row <= e_STATE_END)
|
||||
return Qt::AlignHCenter;
|
||||
else if (row >= e_STATISTICS_START && row <= e_STATISTICS_END)
|
||||
return Qt::AlignRight;
|
||||
else
|
||||
return QVariant();
|
||||
}
|
||||
else
|
||||
return QVariant();
|
||||
|
||||
}
|
||||
|
||||
QVariant PortStatsModel::headerData(int section, Qt::Orientation orientation, int role) const
|
||||
{
|
||||
#ifdef Q_OS_WIN32
|
||||
// TODO(MED): The limitations should be the server's not the client's!
|
||||
// Ideally we shd enhance the protocol to convey limitation(s), if any,
|
||||
// from server to client
|
||||
if (role == Qt::ToolTipRole)
|
||||
{
|
||||
if (orientation == Qt::Horizontal)
|
||||
{
|
||||
return QString("<b>Limitation(s)</b>"
|
||||
"<p><i>Frames/Bytes Receieved</i>: Includes non Ostinato Tx pkts also (Tx by Ostinato are not included)<br>"
|
||||
"<i>Frames/Bytes Sent</i>: Only Ostinato Tx pkts (Tx by others NOT included)</p>"
|
||||
"<p>Rx/Tx Rates are derived from the above and hence subject to same limitations</p>"
|
||||
);
|
||||
}
|
||||
else
|
||||
return QVariant();
|
||||
}
|
||||
#endif
|
||||
|
||||
if (role != Qt::DisplayRole)
|
||||
return QVariant();
|
||||
|
||||
if (orientation == Qt::Horizontal)
|
||||
{
|
||||
uint portGroupIdx, portIdx;
|
||||
|
||||
getDomainIndexes(index(0, section), portGroupIdx, portIdx);
|
||||
#ifdef Q_OS_WIN32
|
||||
return QString("Port %1-%2 (*)").arg(portGroupIdx).arg(portIdx);
|
||||
#else
|
||||
return QString("Port %1-%2").arg(portGroupIdx).arg(portIdx);
|
||||
#endif
|
||||
}
|
||||
else
|
||||
return PortStatName.at(section);
|
||||
}
|
||||
|
||||
void PortStatsModel::portListFromIndex(QModelIndexList indices,
|
||||
QList<PortGroupAndPortList> &portList)
|
||||
{
|
||||
int i, j;
|
||||
QModelIndexList selectedCols(indices);
|
||||
|
||||
portList.clear();
|
||||
|
||||
//selectedCols = indices.selectedColumns();
|
||||
for (i = 0; i < selectedCols.size(); i++)
|
||||
{
|
||||
uint portGroupIdx, portIdx;
|
||||
|
||||
getDomainIndexes(selectedCols.at(i), portGroupIdx, portIdx);
|
||||
for (j = 0; j < portList.size(); j++)
|
||||
{
|
||||
if (portList[j].portGroupId == portGroupIdx)
|
||||
break;
|
||||
}
|
||||
|
||||
if (j >= portList.size())
|
||||
{
|
||||
// PortGroup Not found
|
||||
PortGroupAndPortList p;
|
||||
|
||||
p.portGroupId = portGroupIdx;
|
||||
p.portList.append(portIdx);
|
||||
|
||||
portList.append(p);
|
||||
}
|
||||
else
|
||||
{
|
||||
// PortGroup found
|
||||
|
||||
portList[j].portList.append(portIdx);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
//
|
||||
// Slots
|
||||
//
|
||||
void PortStatsModel::when_portListChanged()
|
||||
{
|
||||
int i, count = 0;
|
||||
|
||||
// recalc numPorts
|
||||
while (numPorts.size())
|
||||
numPorts.removeFirst();
|
||||
|
||||
for (i = 0; i < pgl->mPortGroups.size(); i++)
|
||||
{
|
||||
count += pgl->mPortGroups.at(i)->numPorts();
|
||||
numPorts.append(count);
|
||||
}
|
||||
|
||||
reset();
|
||||
}
|
||||
|
||||
void PortStatsModel::on_portStatsUpdate(int port, void*stats)
|
||||
{
|
||||
QModelIndex topLeft = index(port, 0, QModelIndex());
|
||||
QModelIndex bottomRight = index(port, e_STAT_MAX, QModelIndex());
|
||||
|
||||
emit dataChanged(topLeft, bottomRight);
|
||||
}
|
||||
|
||||
void PortStatsModel::updateStats()
|
||||
{
|
||||
// Request each portgroup to fetch updated stats - the port group
|
||||
// raises a signal once updated stats are available
|
||||
for (int i = 0; i < pgl->mPortGroups.size(); i++)
|
||||
pgl->mPortGroups[i]->getPortStats();
|
||||
}
|
||||
|
||||
void PortStatsModel::when_portGroup_stats_update(quint32 portGroupId)
|
||||
{
|
||||
// FIXME(MED): update only the changed ports, not all
|
||||
|
||||
QModelIndex topLeft = index(0, 0, QModelIndex());
|
||||
QModelIndex bottomRight = index(rowCount(), columnCount(), QModelIndex());
|
||||
|
||||
emit dataChanged(topLeft, bottomRight);
|
||||
}
|
||||
|
@ -1,117 +1,117 @@
|
||||
#ifndef _PORT_STATS_MODEL_H
|
||||
#define _PORT_STATS_MODEL_H
|
||||
|
||||
#include <QAbstractTableModel>
|
||||
#include <QStringList>
|
||||
|
||||
typedef enum {
|
||||
// State
|
||||
e_STATE_START = 0,
|
||||
|
||||
e_LINK_STATE = e_STATE_START,
|
||||
e_TRANSMIT_STATE,
|
||||
e_CAPTURE_STATE,
|
||||
|
||||
e_STATE_END = e_CAPTURE_STATE,
|
||||
|
||||
// Statistics
|
||||
e_STATISTICS_START,
|
||||
|
||||
e_STAT_FRAMES_RCVD = e_STATISTICS_START,
|
||||
e_STAT_FRAMES_SENT,
|
||||
e_STAT_FRAME_SEND_RATE,
|
||||
e_STAT_FRAME_RECV_RATE,
|
||||
e_STAT_BYTES_RCVD,
|
||||
e_STAT_BYTES_SENT,
|
||||
e_STAT_BYTE_SEND_RATE,
|
||||
e_STAT_BYTE_RECV_RATE,
|
||||
#if 0
|
||||
e_STAT_FRAMES_RCVD_NIC,
|
||||
e_STAT_FRAMES_SENT_NIC,
|
||||
e_STAT_BYTES_RCVD_NIC,
|
||||
e_STAT_BYTES_SENT_NIC,
|
||||
#endif
|
||||
|
||||
e_STATISTICS_END = e_STAT_BYTE_RECV_RATE,
|
||||
|
||||
e_STAT_MAX
|
||||
} PortStat;
|
||||
|
||||
static QStringList PortStatName = (QStringList()
|
||||
<< "Link State"
|
||||
<< "Transmit State"
|
||||
<< "Capture State"
|
||||
|
||||
<< "Frames Received"
|
||||
<< "Frames Sent"
|
||||
<< "Frame Send Rate (fps)"
|
||||
<< "Frame Receive Rate (fps)"
|
||||
<< "Bytes Received"
|
||||
<< "Bytes Sent"
|
||||
<< "Byte Send Rate (Bps)"
|
||||
<< "Byte Receive Rate (Bps)"
|
||||
#if 0
|
||||
<< "Frames Received (NIC)"
|
||||
<< "Frames Sent (NIC)"
|
||||
<< "Bytes Received (NIC)"
|
||||
<< "Bytes Sent (NIC)"
|
||||
#endif
|
||||
);
|
||||
|
||||
static QStringList LinkStateName = (QStringList()
|
||||
<< "Unknown"
|
||||
<< "Down"
|
||||
<< "Up"
|
||||
);
|
||||
|
||||
static QStringList BoolStateName = (QStringList()
|
||||
<< "Off"
|
||||
<< "On"
|
||||
);
|
||||
|
||||
class PortGroupList;
|
||||
|
||||
class PortStatsModel : public QAbstractTableModel
|
||||
{
|
||||
Q_OBJECT
|
||||
|
||||
public:
|
||||
|
||||
PortStatsModel(PortGroupList *p, QObject *parent = 0);
|
||||
|
||||
int rowCount(const QModelIndex &parent = QModelIndex()) const;
|
||||
int columnCount(const QModelIndex &parent = QModelIndex()) const;
|
||||
QVariant data(const QModelIndex &index, int role) const;
|
||||
QVariant headerData(int section, Qt::Orientation orientation,
|
||||
int role = Qt::DisplayRole) const;
|
||||
|
||||
class PortGroupAndPortList {
|
||||
public:
|
||||
uint portGroupId;
|
||||
QList<uint> portList;
|
||||
};
|
||||
void portListFromIndex(QModelIndexList indices,
|
||||
QList<PortGroupAndPortList> &portList);
|
||||
|
||||
public slots:
|
||||
void when_portListChanged();
|
||||
void on_portStatsUpdate(int port, void*stats);
|
||||
void when_portGroup_stats_update(quint32 portGroupId);
|
||||
|
||||
private slots:
|
||||
void updateStats();
|
||||
|
||||
private:
|
||||
PortGroupList *pgl;
|
||||
|
||||
// numPorts stores the num of ports per portgroup
|
||||
// in the same order as the portgroups are index in the pgl
|
||||
// Also it stores them as cumulative totals
|
||||
QList<quint16> numPorts;
|
||||
|
||||
void getDomainIndexes(const QModelIndex &index,
|
||||
uint &portGroupIdx, uint &portIdx) const;
|
||||
|
||||
};
|
||||
|
||||
#endif
|
||||
#ifndef _PORT_STATS_MODEL_H
|
||||
#define _PORT_STATS_MODEL_H
|
||||
|
||||
#include <QAbstractTableModel>
|
||||
#include <QStringList>
|
||||
|
||||
typedef enum {
|
||||
// State
|
||||
e_STATE_START = 0,
|
||||
|
||||
e_LINK_STATE = e_STATE_START,
|
||||
e_TRANSMIT_STATE,
|
||||
e_CAPTURE_STATE,
|
||||
|
||||
e_STATE_END = e_CAPTURE_STATE,
|
||||
|
||||
// Statistics
|
||||
e_STATISTICS_START,
|
||||
|
||||
e_STAT_FRAMES_RCVD = e_STATISTICS_START,
|
||||
e_STAT_FRAMES_SENT,
|
||||
e_STAT_FRAME_SEND_RATE,
|
||||
e_STAT_FRAME_RECV_RATE,
|
||||
e_STAT_BYTES_RCVD,
|
||||
e_STAT_BYTES_SENT,
|
||||
e_STAT_BYTE_SEND_RATE,
|
||||
e_STAT_BYTE_RECV_RATE,
|
||||
#if 0
|
||||
e_STAT_FRAMES_RCVD_NIC,
|
||||
e_STAT_FRAMES_SENT_NIC,
|
||||
e_STAT_BYTES_RCVD_NIC,
|
||||
e_STAT_BYTES_SENT_NIC,
|
||||
#endif
|
||||
|
||||
e_STATISTICS_END = e_STAT_BYTE_RECV_RATE,
|
||||
|
||||
e_STAT_MAX
|
||||
} PortStat;
|
||||
|
||||
static QStringList PortStatName = (QStringList()
|
||||
<< "Link State"
|
||||
<< "Transmit State"
|
||||
<< "Capture State"
|
||||
|
||||
<< "Frames Received"
|
||||
<< "Frames Sent"
|
||||
<< "Frame Send Rate (fps)"
|
||||
<< "Frame Receive Rate (fps)"
|
||||
<< "Bytes Received"
|
||||
<< "Bytes Sent"
|
||||
<< "Byte Send Rate (Bps)"
|
||||
<< "Byte Receive Rate (Bps)"
|
||||
#if 0
|
||||
<< "Frames Received (NIC)"
|
||||
<< "Frames Sent (NIC)"
|
||||
<< "Bytes Received (NIC)"
|
||||
<< "Bytes Sent (NIC)"
|
||||
#endif
|
||||
);
|
||||
|
||||
static QStringList LinkStateName = (QStringList()
|
||||
<< "Unknown"
|
||||
<< "Down"
|
||||
<< "Up"
|
||||
);
|
||||
|
||||
static QStringList BoolStateName = (QStringList()
|
||||
<< "Off"
|
||||
<< "On"
|
||||
);
|
||||
|
||||
class PortGroupList;
|
||||
|
||||
class PortStatsModel : public QAbstractTableModel
|
||||
{
|
||||
Q_OBJECT
|
||||
|
||||
public:
|
||||
|
||||
PortStatsModel(PortGroupList *p, QObject *parent = 0);
|
||||
|
||||
int rowCount(const QModelIndex &parent = QModelIndex()) const;
|
||||
int columnCount(const QModelIndex &parent = QModelIndex()) const;
|
||||
QVariant data(const QModelIndex &index, int role) const;
|
||||
QVariant headerData(int section, Qt::Orientation orientation,
|
||||
int role = Qt::DisplayRole) const;
|
||||
|
||||
class PortGroupAndPortList {
|
||||
public:
|
||||
uint portGroupId;
|
||||
QList<uint> portList;
|
||||
};
|
||||
void portListFromIndex(QModelIndexList indices,
|
||||
QList<PortGroupAndPortList> &portList);
|
||||
|
||||
public slots:
|
||||
void when_portListChanged();
|
||||
void on_portStatsUpdate(int port, void*stats);
|
||||
void when_portGroup_stats_update(quint32 portGroupId);
|
||||
|
||||
private slots:
|
||||
void updateStats();
|
||||
|
||||
private:
|
||||
PortGroupList *pgl;
|
||||
|
||||
// numPorts stores the num of ports per portgroup
|
||||
// in the same order as the portgroups are index in the pgl
|
||||
// Also it stores them as cumulative totals
|
||||
QList<quint16> numPorts;
|
||||
|
||||
void getDomainIndexes(const QModelIndex &index,
|
||||
uint &portGroupIdx, uint &portIdx) const;
|
||||
|
||||
};
|
||||
|
||||
#endif
|
||||
|
@ -1,161 +1,161 @@
|
||||
|
||||
#include "portstatswindow.h"
|
||||
#include "portstatsmodel.h"
|
||||
#include "portstatsfilterdialog.h"
|
||||
|
||||
#include "QHeaderView"
|
||||
|
||||
PortStatsWindow::PortStatsWindow(PortGroupList *pgl, QWidget *parent)
|
||||
: QWidget(parent)
|
||||
{
|
||||
setupUi(this);
|
||||
|
||||
this->pgl = pgl;
|
||||
model = pgl->getPortStatsModel();
|
||||
tvPortStats->setModel(model);
|
||||
|
||||
tvPortStats->verticalHeader()->setHighlightSections(false);
|
||||
tvPortStats->verticalHeader()->setDefaultSectionSize(
|
||||
tvPortStats->verticalHeader()->minimumSectionSize());
|
||||
|
||||
}
|
||||
|
||||
PortStatsWindow::~PortStatsWindow()
|
||||
{
|
||||
}
|
||||
|
||||
/* ------------- SLOTS -------------- */
|
||||
|
||||
void PortStatsWindow::on_tbStartTransmit_clicked()
|
||||
{
|
||||
QList<PortStatsModel::PortGroupAndPortList> pgpl;
|
||||
|
||||
// Get selected ports
|
||||
model->portListFromIndex(tvPortStats->selectionModel()->selectedColumns(),
|
||||
pgpl);
|
||||
|
||||
// Clear selected ports, portgroup by portgroup
|
||||
for (int i = 0; i < pgpl.size(); i++)
|
||||
{
|
||||
pgl->portGroupByIndex(pgpl.at(i).portGroupId).
|
||||
startTx(&pgpl[i].portList);
|
||||
}
|
||||
}
|
||||
|
||||
void PortStatsWindow::on_tbStopTransmit_clicked()
|
||||
{
|
||||
QList<PortStatsModel::PortGroupAndPortList> pgpl;
|
||||
|
||||
// Get selected ports
|
||||
model->portListFromIndex(tvPortStats->selectionModel()->selectedColumns(),
|
||||
pgpl);
|
||||
|
||||
// Clear selected ports, portgroup by portgroup
|
||||
for (int i = 0; i < pgpl.size(); i++)
|
||||
{
|
||||
pgl->portGroupByIndex(pgpl.at(i).portGroupId).
|
||||
stopTx(&pgpl[i].portList);
|
||||
}
|
||||
}
|
||||
|
||||
void PortStatsWindow::on_tbStartCapture_clicked()
|
||||
{
|
||||
// TODO(MED)
|
||||
QList<PortStatsModel::PortGroupAndPortList> pgpl;
|
||||
|
||||
// Get selected ports
|
||||
model->portListFromIndex(tvPortStats->selectionModel()->selectedColumns(),
|
||||
pgpl);
|
||||
|
||||
// Clear selected ports, portgroup by portgroup
|
||||
for (int i = 0; i < pgpl.size(); i++)
|
||||
{
|
||||
pgl->portGroupByIndex(pgpl.at(i).portGroupId).
|
||||
startCapture(&pgpl[i].portList);
|
||||
}
|
||||
}
|
||||
|
||||
void PortStatsWindow::on_tbStopCapture_clicked()
|
||||
{
|
||||
// TODO(MED)
|
||||
QList<PortStatsModel::PortGroupAndPortList> pgpl;
|
||||
|
||||
// Get selected ports
|
||||
model->portListFromIndex(tvPortStats->selectionModel()->selectedColumns(),
|
||||
pgpl);
|
||||
|
||||
// Clear selected ports, portgroup by portgroup
|
||||
for (int i = 0; i < pgpl.size(); i++)
|
||||
{
|
||||
pgl->portGroupByIndex(pgpl.at(i).portGroupId).
|
||||
stopCapture(&pgpl[i].portList);
|
||||
}
|
||||
}
|
||||
|
||||
void PortStatsWindow::on_tbViewCapture_clicked()
|
||||
{
|
||||
// TODO(MED)
|
||||
QList<PortStatsModel::PortGroupAndPortList> pgpl;
|
||||
|
||||
// Get selected ports
|
||||
model->portListFromIndex(tvPortStats->selectionModel()->selectedColumns(),
|
||||
pgpl);
|
||||
|
||||
// Clear selected ports, portgroup by portgroup
|
||||
for (int i = 0; i < pgpl.size(); i++)
|
||||
{
|
||||
pgl->portGroupByIndex(pgpl.at(i).portGroupId).
|
||||
viewCapture(&pgpl[i].portList);
|
||||
}
|
||||
}
|
||||
|
||||
void PortStatsWindow::on_tbClear_clicked()
|
||||
{
|
||||
QList<PortStatsModel::PortGroupAndPortList> portList;
|
||||
|
||||
// Get selected ports
|
||||
model->portListFromIndex(tvPortStats->selectionModel()->selectedColumns(),
|
||||
portList);
|
||||
|
||||
// Clear selected ports, portgroup by portgroup
|
||||
for (int i = 0; i < portList.size(); i++)
|
||||
{
|
||||
pgl->portGroupByIndex(portList.at(i).portGroupId).
|
||||
clearPortStats(&portList[i].portList);
|
||||
}
|
||||
}
|
||||
|
||||
void PortStatsWindow::on_tbClearAll_clicked()
|
||||
{
|
||||
for (int i = 0; i < pgl->numPortGroups(); i++)
|
||||
{
|
||||
pgl->portGroupByIndex(0).clearPortStats();
|
||||
}
|
||||
}
|
||||
|
||||
void PortStatsWindow::on_tbFilter_clicked()
|
||||
{
|
||||
bool ok;
|
||||
QList<uint> currentColumns, newColumns;
|
||||
PortStatsFilterDialog dialog;
|
||||
|
||||
for(int i = 0; i < model->columnCount(); i++)
|
||||
if (!tvPortStats->isColumnHidden(i))
|
||||
currentColumns.append(i);
|
||||
|
||||
newColumns = dialog.getItemList(&ok, model, Qt::Horizontal, currentColumns);
|
||||
|
||||
if (ok)
|
||||
{
|
||||
// hide/show sections first ...
|
||||
for(int i = 0; i < model->columnCount(); i++)
|
||||
tvPortStats->setColumnHidden(i, !newColumns.contains(i));
|
||||
|
||||
// ... then for the 'shown' columns, set the visual index
|
||||
for(int i = 0; i < newColumns.size(); i++)
|
||||
{
|
||||
tvPortStats->horizontalHeader()->moveSection(tvPortStats->
|
||||
horizontalHeader()->visualIndex(newColumns.at(i)), i);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#include "portstatswindow.h"
|
||||
#include "portstatsmodel.h"
|
||||
#include "portstatsfilterdialog.h"
|
||||
|
||||
#include "QHeaderView"
|
||||
|
||||
PortStatsWindow::PortStatsWindow(PortGroupList *pgl, QWidget *parent)
|
||||
: QWidget(parent)
|
||||
{
|
||||
setupUi(this);
|
||||
|
||||
this->pgl = pgl;
|
||||
model = pgl->getPortStatsModel();
|
||||
tvPortStats->setModel(model);
|
||||
|
||||
tvPortStats->verticalHeader()->setHighlightSections(false);
|
||||
tvPortStats->verticalHeader()->setDefaultSectionSize(
|
||||
tvPortStats->verticalHeader()->minimumSectionSize());
|
||||
|
||||
}
|
||||
|
||||
PortStatsWindow::~PortStatsWindow()
|
||||
{
|
||||
}
|
||||
|
||||
/* ------------- SLOTS -------------- */
|
||||
|
||||
void PortStatsWindow::on_tbStartTransmit_clicked()
|
||||
{
|
||||
QList<PortStatsModel::PortGroupAndPortList> pgpl;
|
||||
|
||||
// Get selected ports
|
||||
model->portListFromIndex(tvPortStats->selectionModel()->selectedColumns(),
|
||||
pgpl);
|
||||
|
||||
// Clear selected ports, portgroup by portgroup
|
||||
for (int i = 0; i < pgpl.size(); i++)
|
||||
{
|
||||
pgl->portGroupByIndex(pgpl.at(i).portGroupId).
|
||||
startTx(&pgpl[i].portList);
|
||||
}
|
||||
}
|
||||
|
||||
void PortStatsWindow::on_tbStopTransmit_clicked()
|
||||
{
|
||||
QList<PortStatsModel::PortGroupAndPortList> pgpl;
|
||||
|
||||
// Get selected ports
|
||||
model->portListFromIndex(tvPortStats->selectionModel()->selectedColumns(),
|
||||
pgpl);
|
||||
|
||||
// Clear selected ports, portgroup by portgroup
|
||||
for (int i = 0; i < pgpl.size(); i++)
|
||||
{
|
||||
pgl->portGroupByIndex(pgpl.at(i).portGroupId).
|
||||
stopTx(&pgpl[i].portList);
|
||||
}
|
||||
}
|
||||
|
||||
void PortStatsWindow::on_tbStartCapture_clicked()
|
||||
{
|
||||
// TODO(MED)
|
||||
QList<PortStatsModel::PortGroupAndPortList> pgpl;
|
||||
|
||||
// Get selected ports
|
||||
model->portListFromIndex(tvPortStats->selectionModel()->selectedColumns(),
|
||||
pgpl);
|
||||
|
||||
// Clear selected ports, portgroup by portgroup
|
||||
for (int i = 0; i < pgpl.size(); i++)
|
||||
{
|
||||
pgl->portGroupByIndex(pgpl.at(i).portGroupId).
|
||||
startCapture(&pgpl[i].portList);
|
||||
}
|
||||
}
|
||||
|
||||
void PortStatsWindow::on_tbStopCapture_clicked()
|
||||
{
|
||||
// TODO(MED)
|
||||
QList<PortStatsModel::PortGroupAndPortList> pgpl;
|
||||
|
||||
// Get selected ports
|
||||
model->portListFromIndex(tvPortStats->selectionModel()->selectedColumns(),
|
||||
pgpl);
|
||||
|
||||
// Clear selected ports, portgroup by portgroup
|
||||
for (int i = 0; i < pgpl.size(); i++)
|
||||
{
|
||||
pgl->portGroupByIndex(pgpl.at(i).portGroupId).
|
||||
stopCapture(&pgpl[i].portList);
|
||||
}
|
||||
}
|
||||
|
||||
void PortStatsWindow::on_tbViewCapture_clicked()
|
||||
{
|
||||
// TODO(MED)
|
||||
QList<PortStatsModel::PortGroupAndPortList> pgpl;
|
||||
|
||||
// Get selected ports
|
||||
model->portListFromIndex(tvPortStats->selectionModel()->selectedColumns(),
|
||||
pgpl);
|
||||
|
||||
// Clear selected ports, portgroup by portgroup
|
||||
for (int i = 0; i < pgpl.size(); i++)
|
||||
{
|
||||
pgl->portGroupByIndex(pgpl.at(i).portGroupId).
|
||||
viewCapture(&pgpl[i].portList);
|
||||
}
|
||||
}
|
||||
|
||||
void PortStatsWindow::on_tbClear_clicked()
|
||||
{
|
||||
QList<PortStatsModel::PortGroupAndPortList> portList;
|
||||
|
||||
// Get selected ports
|
||||
model->portListFromIndex(tvPortStats->selectionModel()->selectedColumns(),
|
||||
portList);
|
||||
|
||||
// Clear selected ports, portgroup by portgroup
|
||||
for (int i = 0; i < portList.size(); i++)
|
||||
{
|
||||
pgl->portGroupByIndex(portList.at(i).portGroupId).
|
||||
clearPortStats(&portList[i].portList);
|
||||
}
|
||||
}
|
||||
|
||||
void PortStatsWindow::on_tbClearAll_clicked()
|
||||
{
|
||||
for (int i = 0; i < pgl->numPortGroups(); i++)
|
||||
{
|
||||
pgl->portGroupByIndex(0).clearPortStats();
|
||||
}
|
||||
}
|
||||
|
||||
void PortStatsWindow::on_tbFilter_clicked()
|
||||
{
|
||||
bool ok;
|
||||
QList<uint> currentColumns, newColumns;
|
||||
PortStatsFilterDialog dialog;
|
||||
|
||||
for(int i = 0; i < model->columnCount(); i++)
|
||||
if (!tvPortStats->isColumnHidden(i))
|
||||
currentColumns.append(i);
|
||||
|
||||
newColumns = dialog.getItemList(&ok, model, Qt::Horizontal, currentColumns);
|
||||
|
||||
if (ok)
|
||||
{
|
||||
// hide/show sections first ...
|
||||
for(int i = 0; i < model->columnCount(); i++)
|
||||
tvPortStats->setColumnHidden(i, !newColumns.contains(i));
|
||||
|
||||
// ... then for the 'shown' columns, set the visual index
|
||||
for(int i = 0; i < newColumns.size(); i++)
|
||||
{
|
||||
tvPortStats->horizontalHeader()->moveSection(tvPortStats->
|
||||
horizontalHeader()->visualIndex(newColumns.at(i)), i);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -1,37 +1,37 @@
|
||||
#ifndef _PORT_STATS_WINDOW_H
|
||||
#define _PORT_STATS_WINDOW_H
|
||||
|
||||
#include <QDialog>
|
||||
#include <QAbstractItemModel>
|
||||
#include "ui_portstatswindow.h"
|
||||
#include "portgrouplist.h"
|
||||
#include "portstatsmodel.h"
|
||||
|
||||
class PortStatsWindow : public QWidget, public Ui::PortStatsWindow
|
||||
{
|
||||
Q_OBJECT
|
||||
|
||||
public:
|
||||
PortStatsWindow(PortGroupList *pgl, QWidget *parent = 0);
|
||||
~PortStatsWindow();
|
||||
|
||||
private:
|
||||
PortGroupList *pgl;
|
||||
PortStatsModel *model;
|
||||
|
||||
private slots:
|
||||
void on_tbStartTransmit_clicked();
|
||||
void on_tbStopTransmit_clicked();
|
||||
|
||||
void on_tbStartCapture_clicked();
|
||||
void on_tbStopCapture_clicked();
|
||||
void on_tbViewCapture_clicked();
|
||||
|
||||
void on_tbClear_clicked();
|
||||
void on_tbClearAll_clicked();
|
||||
|
||||
void on_tbFilter_clicked();
|
||||
};
|
||||
|
||||
#endif
|
||||
|
||||
#ifndef _PORT_STATS_WINDOW_H
|
||||
#define _PORT_STATS_WINDOW_H
|
||||
|
||||
#include <QDialog>
|
||||
#include <QAbstractItemModel>
|
||||
#include "ui_portstatswindow.h"
|
||||
#include "portgrouplist.h"
|
||||
#include "portstatsmodel.h"
|
||||
|
||||
class PortStatsWindow : public QWidget, public Ui::PortStatsWindow
|
||||
{
|
||||
Q_OBJECT
|
||||
|
||||
public:
|
||||
PortStatsWindow(PortGroupList *pgl, QWidget *parent = 0);
|
||||
~PortStatsWindow();
|
||||
|
||||
private:
|
||||
PortGroupList *pgl;
|
||||
PortStatsModel *model;
|
||||
|
||||
private slots:
|
||||
void on_tbStartTransmit_clicked();
|
||||
void on_tbStopTransmit_clicked();
|
||||
|
||||
void on_tbStartCapture_clicked();
|
||||
void on_tbStopCapture_clicked();
|
||||
void on_tbViewCapture_clicked();
|
||||
|
||||
void on_tbClear_clicked();
|
||||
void on_tbClearAll_clicked();
|
||||
|
||||
void on_tbFilter_clicked();
|
||||
};
|
||||
|
||||
#endif
|
||||
|
||||
|
@ -1,416 +1,416 @@
|
||||
#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->setItemDelegate(delegate);
|
||||
|
||||
tvStreamList->verticalHeader()->setDefaultSectionSize(
|
||||
tvStreamList->verticalHeader()->minimumSectionSize());
|
||||
|
||||
// Populate Context Menu Actions
|
||||
tvPortList->addAction(actionNew_Port_Group);
|
||||
tvPortList->addAction(actionDelete_Port_Group);
|
||||
tvPortList->addAction(actionConnect_Port_Group);
|
||||
tvPortList->addAction(actionDisconnect_Port_Group);
|
||||
|
||||
tvStreamList->addAction(actionNew_Stream);
|
||||
tvStreamList->addAction(actionEdit_Stream);
|
||||
tvStreamList->addAction(actionDelete_Stream);
|
||||
|
||||
tvStreamList->setModel(plm->getStreamModel());
|
||||
tvPortList->setModel(plm->getPortModel());
|
||||
|
||||
connect( plm->getPortModel(),
|
||||
SIGNAL(dataChanged(const QModelIndex&, const QModelIndex&)),
|
||||
this, SLOT(when_portModel_dataChanged(const QModelIndex&,
|
||||
const QModelIndex&)));
|
||||
|
||||
connect(plm->getPortModel(), SIGNAL(modelReset()),
|
||||
SLOT(when_portModel_reset()));
|
||||
|
||||
connect( tvPortList->selectionModel(),
|
||||
SIGNAL(currentChanged(const QModelIndex&, const QModelIndex&)),
|
||||
this, SLOT(when_portView_currentChanged(const QModelIndex&,
|
||||
const QModelIndex&)));
|
||||
|
||||
connect( tvStreamList->selectionModel(),
|
||||
SIGNAL(currentChanged(const QModelIndex&, const QModelIndex&)),
|
||||
this, SLOT(when_streamView_currentChanged(const QModelIndex&,
|
||||
const QModelIndex&)));
|
||||
connect( tvStreamList->selectionModel(),
|
||||
SIGNAL(selectionChanged(const QItemSelection&, const QItemSelection&)),
|
||||
this, SLOT(when_streamView_selectionChanged()));
|
||||
|
||||
#if 0
|
||||
connect( tvPortList->selectionModel(),
|
||||
SIGNAL(currentChanged(const QModelIndex&, const QModelIndex&)),
|
||||
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());
|
||||
|
||||
//! \todo Hide the Aggregate Box till we add support
|
||||
frAggregate->setHidden(true);
|
||||
}
|
||||
|
||||
PortsWindow::~PortsWindow()
|
||||
{
|
||||
}
|
||||
|
||||
void PortsWindow::on_tvStreamList_activated(const QModelIndex & index)
|
||||
{
|
||||
StreamConfigDialog *scd;
|
||||
|
||||
if (!index.isValid())
|
||||
{
|
||||
qDebug("%s: invalid index", __FUNCTION__);
|
||||
return;
|
||||
}
|
||||
scd = new StreamConfigDialog(plm->port(tvPortList->currentIndex()),
|
||||
index.row(), this);
|
||||
qDebug("stream list activated\n");
|
||||
scd->exec(); // TODO: chk retval
|
||||
delete scd;
|
||||
}
|
||||
|
||||
void PortsWindow::when_portView_currentChanged(const QModelIndex& current,
|
||||
const QModelIndex& previous)
|
||||
{
|
||||
plm->getStreamModel()->setCurrentPortIndex(current);
|
||||
updatePortViewActions(current);
|
||||
updateStreamViewActions();
|
||||
|
||||
if (!current.isValid())
|
||||
{
|
||||
qDebug("setting stacked widget to blank page");
|
||||
swDetail->setCurrentIndex(2); // blank page
|
||||
}
|
||||
else
|
||||
{
|
||||
if (plm->isPortGroup(current))
|
||||
{
|
||||
swDetail->setCurrentIndex(1); // portGroup detail page
|
||||
}
|
||||
else if (plm->isPort(current))
|
||||
{
|
||||
swDetail->setCurrentIndex(0); // port detail page
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void PortsWindow::when_streamView_currentChanged(const QModelIndex& current,
|
||||
const QModelIndex& previous)
|
||||
{
|
||||
qDebug("stream view current changed");
|
||||
updateStreamViewActions();
|
||||
}
|
||||
|
||||
void PortsWindow::when_streamView_selectionChanged()
|
||||
{
|
||||
qDebug("stream view selection changed");
|
||||
updateStreamViewActions();
|
||||
}
|
||||
|
||||
void PortsWindow::when_portModel_dataChanged(const QModelIndex& topLeft,
|
||||
const QModelIndex& bottomRight)
|
||||
{
|
||||
#if 0 // not sure why the >= <= operators are not overloaded in QModelIndex
|
||||
if ((tvPortList->currentIndex() >= topLeft) &&
|
||||
(tvPortList->currentIndex() <= bottomRight))
|
||||
#endif
|
||||
if ((topLeft < tvPortList->currentIndex()) ||
|
||||
(topLeft == tvPortList->currentIndex()) &&
|
||||
((tvPortList->currentIndex() < bottomRight)) ||
|
||||
(tvPortList->currentIndex() == bottomRight))
|
||||
{
|
||||
updatePortViewActions(tvPortList->currentIndex());
|
||||
}
|
||||
}
|
||||
|
||||
void PortsWindow::when_portModel_reset()
|
||||
{
|
||||
when_portView_currentChanged(QModelIndex(), tvPortList->currentIndex());
|
||||
}
|
||||
|
||||
#if 0
|
||||
void PortsWindow::updateStreamViewActions(const QModelIndex& current)
|
||||
{
|
||||
if (current.isValid())
|
||||
actionDelete_Stream->setEnabled(true);
|
||||
else
|
||||
actionDelete_Stream->setDisabled(true);
|
||||
}
|
||||
#endif
|
||||
|
||||
void PortsWindow::updateStreamViewActions()
|
||||
{
|
||||
// For some reason hasSelection() returns true even if selection size is 0
|
||||
// so additional check for size introduced
|
||||
if (tvStreamList->selectionModel()->hasSelection() &&
|
||||
(tvStreamList->selectionModel()->selection().size() > 0))
|
||||
{
|
||||
qDebug("Has selection %d",
|
||||
tvStreamList->selectionModel()->selection().size());
|
||||
|
||||
// If more than one non-contiguous ranges selected,
|
||||
// disable "New" and "Edit"
|
||||
if (tvStreamList->selectionModel()->selection().size() > 1)
|
||||
{
|
||||
actionNew_Stream->setDisabled(true);
|
||||
actionEdit_Stream->setDisabled(true);
|
||||
}
|
||||
else
|
||||
{
|
||||
actionNew_Stream->setEnabled(true);
|
||||
|
||||
// Enable "Edit" only if the single range has a single row
|
||||
if (tvStreamList->selectionModel()->selection().at(0).height() > 1)
|
||||
actionEdit_Stream->setDisabled(true);
|
||||
else
|
||||
actionEdit_Stream->setEnabled(true);
|
||||
}
|
||||
|
||||
// Delete is always enabled as long as we have a selection
|
||||
actionDelete_Stream->setEnabled(true);
|
||||
}
|
||||
else
|
||||
{
|
||||
qDebug("No selection");
|
||||
actionNew_Stream->setEnabled(true);
|
||||
actionEdit_Stream->setDisabled(true);
|
||||
actionDelete_Stream->setDisabled(true);
|
||||
}
|
||||
}
|
||||
|
||||
void PortsWindow::updatePortViewActions(const QModelIndex& current)
|
||||
{
|
||||
if (!current.isValid())
|
||||
{
|
||||
qDebug("current is now invalid");
|
||||
actionDelete_Port_Group->setDisabled(true);
|
||||
actionConnect_Port_Group->setDisabled(true);
|
||||
actionDisconnect_Port_Group->setDisabled(true);
|
||||
|
||||
goto _EXIT;
|
||||
}
|
||||
|
||||
qDebug("currentChanged %llx", current.internalId());
|
||||
|
||||
if (plm->isPortGroup(current))
|
||||
{
|
||||
actionDelete_Port_Group->setEnabled(true);
|
||||
switch(plm->portGroup(current).state())
|
||||
{
|
||||
case QAbstractSocket::UnconnectedState:
|
||||
case QAbstractSocket::ClosingState:
|
||||
qDebug("state = unconnected|closing");
|
||||
actionConnect_Port_Group->setEnabled(true);
|
||||
actionDisconnect_Port_Group->setDisabled(true);
|
||||
break;
|
||||
|
||||
case QAbstractSocket::HostLookupState:
|
||||
case QAbstractSocket::ConnectingState:
|
||||
case QAbstractSocket::ConnectedState:
|
||||
qDebug("state = lookup|connecting|connected");
|
||||
actionConnect_Port_Group->setDisabled(true);
|
||||
actionDisconnect_Port_Group->setEnabled(true);
|
||||
break;
|
||||
|
||||
|
||||
case QAbstractSocket::BoundState:
|
||||
case QAbstractSocket::ListeningState:
|
||||
default:
|
||||
// FIXME(LOW): indicate error
|
||||
qDebug("unexpected state");
|
||||
break;
|
||||
}
|
||||
}
|
||||
else if (plm->isPort(current))
|
||||
{
|
||||
actionDelete_Port_Group->setEnabled(false);
|
||||
actionConnect_Port_Group->setEnabled(false);
|
||||
actionDisconnect_Port_Group->setEnabled(false);
|
||||
}
|
||||
|
||||
_EXIT:
|
||||
return;
|
||||
}
|
||||
|
||||
void PortsWindow::on_pbApply_clicked()
|
||||
{
|
||||
QModelIndex curPort;
|
||||
QModelIndex curPortGroup;
|
||||
|
||||
curPort = tvPortList->selectionModel()->currentIndex();
|
||||
if (!curPort.isValid())
|
||||
{
|
||||
qDebug("%s: curPort is invalid", __FUNCTION__);
|
||||
goto _exit;
|
||||
}
|
||||
|
||||
if (!plm->isPort(curPort))
|
||||
{
|
||||
qDebug("%s: curPort is not a port", __FUNCTION__);
|
||||
goto _exit;
|
||||
}
|
||||
|
||||
curPortGroup = plm->getPortModel()->parent(curPort);
|
||||
if (!curPortGroup.isValid())
|
||||
{
|
||||
qDebug("%s: curPortGroup is invalid", __FUNCTION__);
|
||||
goto _exit;
|
||||
}
|
||||
if (!plm->isPortGroup(curPortGroup))
|
||||
{
|
||||
qDebug("%s: curPortGroup is not a portGroup", __FUNCTION__);
|
||||
goto _exit;
|
||||
}
|
||||
|
||||
// FIXME(HI): shd this be a signal?
|
||||
//portGroup.when_configApply(port);
|
||||
// FIXME(MED): mixing port id and index!!!
|
||||
plm->portGroup(curPortGroup).when_configApply(plm->port(curPort).id());
|
||||
|
||||
_exit:
|
||||
return;
|
||||
|
||||
#if 0
|
||||
// TODO (LOW): This block is for testing only
|
||||
QModelIndex current = tvPortList->selectionModel()->currentIndex();
|
||||
|
||||
if (current.isValid())
|
||||
qDebug("current = %llx", current.internalId());
|
||||
else
|
||||
qDebug("current is invalid");
|
||||
#endif
|
||||
}
|
||||
|
||||
void PortsWindow::on_actionNew_Port_Group_triggered()
|
||||
{
|
||||
bool ok;
|
||||
QString text = QInputDialog::getText(this,
|
||||
"Add Port Group", "Port Group Address (IP[:Port])",
|
||||
QLineEdit::Normal, lastNewPortGroup, &ok);
|
||||
|
||||
if (ok)
|
||||
{
|
||||
QStringList addr = text.split(":");
|
||||
if (addr.size() == 1) // Port unspecified
|
||||
addr.append(QString().setNum(DEFAULT_SERVER_PORT));
|
||||
PortGroup *pg = new PortGroup(QHostAddress(addr[0]),addr[1].toUShort());
|
||||
plm->addPortGroup(*pg);
|
||||
lastNewPortGroup = text;
|
||||
}
|
||||
}
|
||||
|
||||
void PortsWindow::on_actionDelete_Port_Group_triggered()
|
||||
{
|
||||
QModelIndex current = tvPortList->selectionModel()->currentIndex();
|
||||
|
||||
if (current.isValid())
|
||||
plm->removePortGroup(plm->portGroup(current));
|
||||
}
|
||||
|
||||
void PortsWindow::on_actionConnect_Port_Group_triggered()
|
||||
{
|
||||
QModelIndex current = tvPortList->selectionModel()->currentIndex();
|
||||
|
||||
if (current.isValid())
|
||||
plm->portGroup(current).connectToHost();
|
||||
}
|
||||
|
||||
void PortsWindow::on_actionDisconnect_Port_Group_triggered()
|
||||
{
|
||||
QModelIndex current = tvPortList->selectionModel()->currentIndex();
|
||||
|
||||
if (current.isValid())
|
||||
plm->portGroup(current).disconnectFromHost();
|
||||
}
|
||||
#if 0
|
||||
void PortsWindow::on_actionNew_Stream_triggered()
|
||||
{
|
||||
qDebug("New Stream Action");
|
||||
|
||||
int row = 0;
|
||||
|
||||
if (tvStreamList->currentIndex().isValid())
|
||||
row = tvStreamList->currentIndex().row();
|
||||
plm->getStreamModel()->insertRows(row, 1);
|
||||
}
|
||||
|
||||
void PortsWindow::on_actionDelete_Stream_triggered()
|
||||
{
|
||||
qDebug("Delete Stream Action");
|
||||
if (tvStreamList->currentIndex().isValid())
|
||||
plm->getStreamModel()->removeRows(tvStreamList->currentIndex().row(), 1);
|
||||
}
|
||||
#endif
|
||||
|
||||
void PortsWindow::on_actionNew_Stream_triggered()
|
||||
{
|
||||
qDebug("New Stream Action");
|
||||
|
||||
// In case nothing is selected, insert 1 row at the top
|
||||
int row = 0, count = 1;
|
||||
|
||||
// In case we have a single range selected; insert as many rows as
|
||||
// in the singe selected range before the top of the selected range
|
||||
if (tvStreamList->selectionModel()->selection().size() == 1)
|
||||
{
|
||||
row = tvStreamList->selectionModel()->selection().at(0).top();
|
||||
count = tvStreamList->selectionModel()->selection().at(0).height();
|
||||
}
|
||||
|
||||
plm->getStreamModel()->insertRows(row, count);
|
||||
}
|
||||
|
||||
void PortsWindow::on_actionEdit_Stream_triggered()
|
||||
{
|
||||
qDebug("Edit Stream Action");
|
||||
|
||||
// Ensure we have only one range selected which contains only one row
|
||||
if ((tvStreamList->selectionModel()->selection().size() == 1) &&
|
||||
(tvStreamList->selectionModel()->selection().at(0).height() == 1))
|
||||
{
|
||||
on_tvStreamList_activated(tvStreamList->selectionModel()->
|
||||
selection().at(0).topLeft());
|
||||
}
|
||||
}
|
||||
|
||||
void PortsWindow::on_actionDelete_Stream_triggered()
|
||||
{
|
||||
qDebug("Delete Stream Action");
|
||||
|
||||
QModelIndex index;
|
||||
|
||||
if (tvStreamList->selectionModel()->hasSelection())
|
||||
{
|
||||
qDebug("SelectedIndexes %d",
|
||||
tvStreamList->selectionModel()->selectedRows().size());
|
||||
while(tvStreamList->selectionModel()->selectedRows().size())
|
||||
{
|
||||
index = tvStreamList->selectionModel()->selectedRows().at(0);
|
||||
plm->getStreamModel()->removeRows(index.row(), 1);
|
||||
}
|
||||
}
|
||||
else
|
||||
qDebug("No selection");
|
||||
}
|
||||
|
||||
|
||||
#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->setItemDelegate(delegate);
|
||||
|
||||
tvStreamList->verticalHeader()->setDefaultSectionSize(
|
||||
tvStreamList->verticalHeader()->minimumSectionSize());
|
||||
|
||||
// Populate Context Menu Actions
|
||||
tvPortList->addAction(actionNew_Port_Group);
|
||||
tvPortList->addAction(actionDelete_Port_Group);
|
||||
tvPortList->addAction(actionConnect_Port_Group);
|
||||
tvPortList->addAction(actionDisconnect_Port_Group);
|
||||
|
||||
tvStreamList->addAction(actionNew_Stream);
|
||||
tvStreamList->addAction(actionEdit_Stream);
|
||||
tvStreamList->addAction(actionDelete_Stream);
|
||||
|
||||
tvStreamList->setModel(plm->getStreamModel());
|
||||
tvPortList->setModel(plm->getPortModel());
|
||||
|
||||
connect( plm->getPortModel(),
|
||||
SIGNAL(dataChanged(const QModelIndex&, const QModelIndex&)),
|
||||
this, SLOT(when_portModel_dataChanged(const QModelIndex&,
|
||||
const QModelIndex&)));
|
||||
|
||||
connect(plm->getPortModel(), SIGNAL(modelReset()),
|
||||
SLOT(when_portModel_reset()));
|
||||
|
||||
connect( tvPortList->selectionModel(),
|
||||
SIGNAL(currentChanged(const QModelIndex&, const QModelIndex&)),
|
||||
this, SLOT(when_portView_currentChanged(const QModelIndex&,
|
||||
const QModelIndex&)));
|
||||
|
||||
connect( tvStreamList->selectionModel(),
|
||||
SIGNAL(currentChanged(const QModelIndex&, const QModelIndex&)),
|
||||
this, SLOT(when_streamView_currentChanged(const QModelIndex&,
|
||||
const QModelIndex&)));
|
||||
connect( tvStreamList->selectionModel(),
|
||||
SIGNAL(selectionChanged(const QItemSelection&, const QItemSelection&)),
|
||||
this, SLOT(when_streamView_selectionChanged()));
|
||||
|
||||
#if 0
|
||||
connect( tvPortList->selectionModel(),
|
||||
SIGNAL(currentChanged(const QModelIndex&, const QModelIndex&)),
|
||||
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());
|
||||
|
||||
//! \todo Hide the Aggregate Box till we add support
|
||||
frAggregate->setHidden(true);
|
||||
}
|
||||
|
||||
PortsWindow::~PortsWindow()
|
||||
{
|
||||
}
|
||||
|
||||
void PortsWindow::on_tvStreamList_activated(const QModelIndex & index)
|
||||
{
|
||||
StreamConfigDialog *scd;
|
||||
|
||||
if (!index.isValid())
|
||||
{
|
||||
qDebug("%s: invalid index", __FUNCTION__);
|
||||
return;
|
||||
}
|
||||
scd = new StreamConfigDialog(plm->port(tvPortList->currentIndex()),
|
||||
index.row(), this);
|
||||
qDebug("stream list activated\n");
|
||||
scd->exec(); // TODO: chk retval
|
||||
delete scd;
|
||||
}
|
||||
|
||||
void PortsWindow::when_portView_currentChanged(const QModelIndex& current,
|
||||
const QModelIndex& previous)
|
||||
{
|
||||
plm->getStreamModel()->setCurrentPortIndex(current);
|
||||
updatePortViewActions(current);
|
||||
updateStreamViewActions();
|
||||
|
||||
if (!current.isValid())
|
||||
{
|
||||
qDebug("setting stacked widget to blank page");
|
||||
swDetail->setCurrentIndex(2); // blank page
|
||||
}
|
||||
else
|
||||
{
|
||||
if (plm->isPortGroup(current))
|
||||
{
|
||||
swDetail->setCurrentIndex(1); // portGroup detail page
|
||||
}
|
||||
else if (plm->isPort(current))
|
||||
{
|
||||
swDetail->setCurrentIndex(0); // port detail page
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void PortsWindow::when_streamView_currentChanged(const QModelIndex& current,
|
||||
const QModelIndex& previous)
|
||||
{
|
||||
qDebug("stream view current changed");
|
||||
updateStreamViewActions();
|
||||
}
|
||||
|
||||
void PortsWindow::when_streamView_selectionChanged()
|
||||
{
|
||||
qDebug("stream view selection changed");
|
||||
updateStreamViewActions();
|
||||
}
|
||||
|
||||
void PortsWindow::when_portModel_dataChanged(const QModelIndex& topLeft,
|
||||
const QModelIndex& bottomRight)
|
||||
{
|
||||
#if 0 // not sure why the >= <= operators are not overloaded in QModelIndex
|
||||
if ((tvPortList->currentIndex() >= topLeft) &&
|
||||
(tvPortList->currentIndex() <= bottomRight))
|
||||
#endif
|
||||
if ((topLeft < tvPortList->currentIndex()) ||
|
||||
(topLeft == tvPortList->currentIndex()) &&
|
||||
((tvPortList->currentIndex() < bottomRight)) ||
|
||||
(tvPortList->currentIndex() == bottomRight))
|
||||
{
|
||||
updatePortViewActions(tvPortList->currentIndex());
|
||||
}
|
||||
}
|
||||
|
||||
void PortsWindow::when_portModel_reset()
|
||||
{
|
||||
when_portView_currentChanged(QModelIndex(), tvPortList->currentIndex());
|
||||
}
|
||||
|
||||
#if 0
|
||||
void PortsWindow::updateStreamViewActions(const QModelIndex& current)
|
||||
{
|
||||
if (current.isValid())
|
||||
actionDelete_Stream->setEnabled(true);
|
||||
else
|
||||
actionDelete_Stream->setDisabled(true);
|
||||
}
|
||||
#endif
|
||||
|
||||
void PortsWindow::updateStreamViewActions()
|
||||
{
|
||||
// For some reason hasSelection() returns true even if selection size is 0
|
||||
// so additional check for size introduced
|
||||
if (tvStreamList->selectionModel()->hasSelection() &&
|
||||
(tvStreamList->selectionModel()->selection().size() > 0))
|
||||
{
|
||||
qDebug("Has selection %d",
|
||||
tvStreamList->selectionModel()->selection().size());
|
||||
|
||||
// If more than one non-contiguous ranges selected,
|
||||
// disable "New" and "Edit"
|
||||
if (tvStreamList->selectionModel()->selection().size() > 1)
|
||||
{
|
||||
actionNew_Stream->setDisabled(true);
|
||||
actionEdit_Stream->setDisabled(true);
|
||||
}
|
||||
else
|
||||
{
|
||||
actionNew_Stream->setEnabled(true);
|
||||
|
||||
// Enable "Edit" only if the single range has a single row
|
||||
if (tvStreamList->selectionModel()->selection().at(0).height() > 1)
|
||||
actionEdit_Stream->setDisabled(true);
|
||||
else
|
||||
actionEdit_Stream->setEnabled(true);
|
||||
}
|
||||
|
||||
// Delete is always enabled as long as we have a selection
|
||||
actionDelete_Stream->setEnabled(true);
|
||||
}
|
||||
else
|
||||
{
|
||||
qDebug("No selection");
|
||||
actionNew_Stream->setEnabled(true);
|
||||
actionEdit_Stream->setDisabled(true);
|
||||
actionDelete_Stream->setDisabled(true);
|
||||
}
|
||||
}
|
||||
|
||||
void PortsWindow::updatePortViewActions(const QModelIndex& current)
|
||||
{
|
||||
if (!current.isValid())
|
||||
{
|
||||
qDebug("current is now invalid");
|
||||
actionDelete_Port_Group->setDisabled(true);
|
||||
actionConnect_Port_Group->setDisabled(true);
|
||||
actionDisconnect_Port_Group->setDisabled(true);
|
||||
|
||||
goto _EXIT;
|
||||
}
|
||||
|
||||
qDebug("currentChanged %llx", current.internalId());
|
||||
|
||||
if (plm->isPortGroup(current))
|
||||
{
|
||||
actionDelete_Port_Group->setEnabled(true);
|
||||
switch(plm->portGroup(current).state())
|
||||
{
|
||||
case QAbstractSocket::UnconnectedState:
|
||||
case QAbstractSocket::ClosingState:
|
||||
qDebug("state = unconnected|closing");
|
||||
actionConnect_Port_Group->setEnabled(true);
|
||||
actionDisconnect_Port_Group->setDisabled(true);
|
||||
break;
|
||||
|
||||
case QAbstractSocket::HostLookupState:
|
||||
case QAbstractSocket::ConnectingState:
|
||||
case QAbstractSocket::ConnectedState:
|
||||
qDebug("state = lookup|connecting|connected");
|
||||
actionConnect_Port_Group->setDisabled(true);
|
||||
actionDisconnect_Port_Group->setEnabled(true);
|
||||
break;
|
||||
|
||||
|
||||
case QAbstractSocket::BoundState:
|
||||
case QAbstractSocket::ListeningState:
|
||||
default:
|
||||
// FIXME(LOW): indicate error
|
||||
qDebug("unexpected state");
|
||||
break;
|
||||
}
|
||||
}
|
||||
else if (plm->isPort(current))
|
||||
{
|
||||
actionDelete_Port_Group->setEnabled(false);
|
||||
actionConnect_Port_Group->setEnabled(false);
|
||||
actionDisconnect_Port_Group->setEnabled(false);
|
||||
}
|
||||
|
||||
_EXIT:
|
||||
return;
|
||||
}
|
||||
|
||||
void PortsWindow::on_pbApply_clicked()
|
||||
{
|
||||
QModelIndex curPort;
|
||||
QModelIndex curPortGroup;
|
||||
|
||||
curPort = tvPortList->selectionModel()->currentIndex();
|
||||
if (!curPort.isValid())
|
||||
{
|
||||
qDebug("%s: curPort is invalid", __FUNCTION__);
|
||||
goto _exit;
|
||||
}
|
||||
|
||||
if (!plm->isPort(curPort))
|
||||
{
|
||||
qDebug("%s: curPort is not a port", __FUNCTION__);
|
||||
goto _exit;
|
||||
}
|
||||
|
||||
curPortGroup = plm->getPortModel()->parent(curPort);
|
||||
if (!curPortGroup.isValid())
|
||||
{
|
||||
qDebug("%s: curPortGroup is invalid", __FUNCTION__);
|
||||
goto _exit;
|
||||
}
|
||||
if (!plm->isPortGroup(curPortGroup))
|
||||
{
|
||||
qDebug("%s: curPortGroup is not a portGroup", __FUNCTION__);
|
||||
goto _exit;
|
||||
}
|
||||
|
||||
// FIXME(HI): shd this be a signal?
|
||||
//portGroup.when_configApply(port);
|
||||
// FIXME(MED): mixing port id and index!!!
|
||||
plm->portGroup(curPortGroup).when_configApply(plm->port(curPort).id());
|
||||
|
||||
_exit:
|
||||
return;
|
||||
|
||||
#if 0
|
||||
// TODO (LOW): This block is for testing only
|
||||
QModelIndex current = tvPortList->selectionModel()->currentIndex();
|
||||
|
||||
if (current.isValid())
|
||||
qDebug("current = %llx", current.internalId());
|
||||
else
|
||||
qDebug("current is invalid");
|
||||
#endif
|
||||
}
|
||||
|
||||
void PortsWindow::on_actionNew_Port_Group_triggered()
|
||||
{
|
||||
bool ok;
|
||||
QString text = QInputDialog::getText(this,
|
||||
"Add Port Group", "Port Group Address (IP[:Port])",
|
||||
QLineEdit::Normal, lastNewPortGroup, &ok);
|
||||
|
||||
if (ok)
|
||||
{
|
||||
QStringList addr = text.split(":");
|
||||
if (addr.size() == 1) // Port unspecified
|
||||
addr.append(QString().setNum(DEFAULT_SERVER_PORT));
|
||||
PortGroup *pg = new PortGroup(QHostAddress(addr[0]),addr[1].toUShort());
|
||||
plm->addPortGroup(*pg);
|
||||
lastNewPortGroup = text;
|
||||
}
|
||||
}
|
||||
|
||||
void PortsWindow::on_actionDelete_Port_Group_triggered()
|
||||
{
|
||||
QModelIndex current = tvPortList->selectionModel()->currentIndex();
|
||||
|
||||
if (current.isValid())
|
||||
plm->removePortGroup(plm->portGroup(current));
|
||||
}
|
||||
|
||||
void PortsWindow::on_actionConnect_Port_Group_triggered()
|
||||
{
|
||||
QModelIndex current = tvPortList->selectionModel()->currentIndex();
|
||||
|
||||
if (current.isValid())
|
||||
plm->portGroup(current).connectToHost();
|
||||
}
|
||||
|
||||
void PortsWindow::on_actionDisconnect_Port_Group_triggered()
|
||||
{
|
||||
QModelIndex current = tvPortList->selectionModel()->currentIndex();
|
||||
|
||||
if (current.isValid())
|
||||
plm->portGroup(current).disconnectFromHost();
|
||||
}
|
||||
#if 0
|
||||
void PortsWindow::on_actionNew_Stream_triggered()
|
||||
{
|
||||
qDebug("New Stream Action");
|
||||
|
||||
int row = 0;
|
||||
|
||||
if (tvStreamList->currentIndex().isValid())
|
||||
row = tvStreamList->currentIndex().row();
|
||||
plm->getStreamModel()->insertRows(row, 1);
|
||||
}
|
||||
|
||||
void PortsWindow::on_actionDelete_Stream_triggered()
|
||||
{
|
||||
qDebug("Delete Stream Action");
|
||||
if (tvStreamList->currentIndex().isValid())
|
||||
plm->getStreamModel()->removeRows(tvStreamList->currentIndex().row(), 1);
|
||||
}
|
||||
#endif
|
||||
|
||||
void PortsWindow::on_actionNew_Stream_triggered()
|
||||
{
|
||||
qDebug("New Stream Action");
|
||||
|
||||
// In case nothing is selected, insert 1 row at the top
|
||||
int row = 0, count = 1;
|
||||
|
||||
// In case we have a single range selected; insert as many rows as
|
||||
// in the singe selected range before the top of the selected range
|
||||
if (tvStreamList->selectionModel()->selection().size() == 1)
|
||||
{
|
||||
row = tvStreamList->selectionModel()->selection().at(0).top();
|
||||
count = tvStreamList->selectionModel()->selection().at(0).height();
|
||||
}
|
||||
|
||||
plm->getStreamModel()->insertRows(row, count);
|
||||
}
|
||||
|
||||
void PortsWindow::on_actionEdit_Stream_triggered()
|
||||
{
|
||||
qDebug("Edit Stream Action");
|
||||
|
||||
// Ensure we have only one range selected which contains only one row
|
||||
if ((tvStreamList->selectionModel()->selection().size() == 1) &&
|
||||
(tvStreamList->selectionModel()->selection().at(0).height() == 1))
|
||||
{
|
||||
on_tvStreamList_activated(tvStreamList->selectionModel()->
|
||||
selection().at(0).topLeft());
|
||||
}
|
||||
}
|
||||
|
||||
void PortsWindow::on_actionDelete_Stream_triggered()
|
||||
{
|
||||
qDebug("Delete Stream Action");
|
||||
|
||||
QModelIndex index;
|
||||
|
||||
if (tvStreamList->selectionModel()->hasSelection())
|
||||
{
|
||||
qDebug("SelectedIndexes %d",
|
||||
tvStreamList->selectionModel()->selectedRows().size());
|
||||
while(tvStreamList->selectionModel()->selectedRows().size())
|
||||
{
|
||||
index = tvStreamList->selectionModel()->selectedRows().at(0);
|
||||
plm->getStreamModel()->removeRows(index.row(), 1);
|
||||
}
|
||||
}
|
||||
else
|
||||
qDebug("No selection");
|
||||
}
|
||||
|
||||
|
||||
|
@ -1,58 +1,58 @@
|
||||
#ifndef _PORTS_WINDOW_H
|
||||
#define _PORTS_WINDOW_H
|
||||
|
||||
#include <QWidget>
|
||||
#include <QAbstractItemModel>
|
||||
#include "ui_portswindow.h"
|
||||
#include "portgrouplist.h"
|
||||
|
||||
/* TODO
|
||||
HIGH
|
||||
MED
|
||||
LOW
|
||||
*/
|
||||
|
||||
|
||||
class PortsWindow : public QWidget, private Ui::PortsWindow
|
||||
{
|
||||
Q_OBJECT
|
||||
|
||||
//QAbstractItemModel *slm; // stream list model
|
||||
PortGroupList *plm;
|
||||
|
||||
public:
|
||||
PortsWindow(PortGroupList *pgl, QWidget *parent = 0);
|
||||
~PortsWindow();
|
||||
|
||||
private:
|
||||
QString lastNewPortGroup;
|
||||
|
||||
void updatePortViewActions(const QModelIndex& current);
|
||||
//void updateStreamViewActions(const QModelIndex& current);
|
||||
void updateStreamViewActions();
|
||||
|
||||
private slots:
|
||||
void on_tvStreamList_activated(const QModelIndex & index);
|
||||
void when_portView_currentChanged(const QModelIndex& current,
|
||||
const QModelIndex& previous);
|
||||
void when_streamView_currentChanged(const QModelIndex& current,
|
||||
const QModelIndex& previous);
|
||||
void when_streamView_selectionChanged();
|
||||
void when_portModel_dataChanged(const QModelIndex& topLeft,
|
||||
const QModelIndex& bottomRight);
|
||||
void when_portModel_reset();
|
||||
|
||||
void on_pbApply_clicked();
|
||||
|
||||
void on_actionNew_Port_Group_triggered();
|
||||
void on_actionDelete_Port_Group_triggered();
|
||||
void on_actionConnect_Port_Group_triggered();
|
||||
void on_actionDisconnect_Port_Group_triggered();
|
||||
|
||||
void on_actionNew_Stream_triggered();
|
||||
void on_actionEdit_Stream_triggered();
|
||||
void on_actionDelete_Stream_triggered();
|
||||
};
|
||||
|
||||
#endif
|
||||
|
||||
#ifndef _PORTS_WINDOW_H
|
||||
#define _PORTS_WINDOW_H
|
||||
|
||||
#include <QWidget>
|
||||
#include <QAbstractItemModel>
|
||||
#include "ui_portswindow.h"
|
||||
#include "portgrouplist.h"
|
||||
|
||||
/* TODO
|
||||
HIGH
|
||||
MED
|
||||
LOW
|
||||
*/
|
||||
|
||||
|
||||
class PortsWindow : public QWidget, private Ui::PortsWindow
|
||||
{
|
||||
Q_OBJECT
|
||||
|
||||
//QAbstractItemModel *slm; // stream list model
|
||||
PortGroupList *plm;
|
||||
|
||||
public:
|
||||
PortsWindow(PortGroupList *pgl, QWidget *parent = 0);
|
||||
~PortsWindow();
|
||||
|
||||
private:
|
||||
QString lastNewPortGroup;
|
||||
|
||||
void updatePortViewActions(const QModelIndex& current);
|
||||
//void updateStreamViewActions(const QModelIndex& current);
|
||||
void updateStreamViewActions();
|
||||
|
||||
private slots:
|
||||
void on_tvStreamList_activated(const QModelIndex & index);
|
||||
void when_portView_currentChanged(const QModelIndex& current,
|
||||
const QModelIndex& previous);
|
||||
void when_streamView_currentChanged(const QModelIndex& current,
|
||||
const QModelIndex& previous);
|
||||
void when_streamView_selectionChanged();
|
||||
void when_portModel_dataChanged(const QModelIndex& topLeft,
|
||||
const QModelIndex& bottomRight);
|
||||
void when_portModel_reset();
|
||||
|
||||
void on_pbApply_clicked();
|
||||
|
||||
void on_actionNew_Port_Group_triggered();
|
||||
void on_actionDelete_Port_Group_triggered();
|
||||
void on_actionConnect_Port_Group_triggered();
|
||||
void on_actionDisconnect_Port_Group_triggered();
|
||||
|
||||
void on_actionNew_Stream_triggered();
|
||||
void on_actionEdit_Stream_triggered();
|
||||
void on_actionDelete_Stream_triggered();
|
||||
};
|
||||
|
||||
#endif
|
||||
|
||||
|
@ -1,60 +1,60 @@
|
||||
#include <qendian.h>
|
||||
#include <QHostAddress>
|
||||
|
||||
#include "stream.h"
|
||||
//#include "../common/protocollist.h"
|
||||
#include "../common/protocollistiterator.h"
|
||||
#include "../common/abstractprotocol.h"
|
||||
|
||||
Stream::Stream()
|
||||
{
|
||||
//mId = 0xFFFFFFFF;
|
||||
setEnabled(true);
|
||||
}
|
||||
|
||||
Stream::~Stream()
|
||||
{
|
||||
}
|
||||
|
||||
void Stream::loadProtocolWidgets()
|
||||
{
|
||||
#if 0
|
||||
//protocols.loadConfigWidgets();
|
||||
foreach(AbstractProtocol* proto, *currentFrameProtocols)
|
||||
{
|
||||
proto->loadConfigWidget();
|
||||
}
|
||||
#else
|
||||
ProtocolListIterator *iter;
|
||||
|
||||
iter = createProtocolListIterator();
|
||||
while (iter->hasNext())
|
||||
{
|
||||
AbstractProtocol* p = iter->next();
|
||||
p->loadConfigWidget();
|
||||
}
|
||||
delete iter;
|
||||
#endif
|
||||
}
|
||||
|
||||
void Stream::storeProtocolWidgets()
|
||||
{
|
||||
#if 0
|
||||
//protocols.storeConfigWidgets();
|
||||
foreach(const AbstractProtocol* proto, frameProtocol())
|
||||
{
|
||||
proto->storeConfigWidget();
|
||||
_iter->toFront();
|
||||
}
|
||||
#else
|
||||
ProtocolListIterator *iter;
|
||||
|
||||
iter = createProtocolListIterator();
|
||||
while (iter->hasNext())
|
||||
{
|
||||
AbstractProtocol* p = iter->next();
|
||||
p->storeConfigWidget();
|
||||
}
|
||||
delete iter;
|
||||
#endif
|
||||
}
|
||||
#include <qendian.h>
|
||||
#include <QHostAddress>
|
||||
|
||||
#include "stream.h"
|
||||
//#include "../common/protocollist.h"
|
||||
#include "../common/protocollistiterator.h"
|
||||
#include "../common/abstractprotocol.h"
|
||||
|
||||
Stream::Stream()
|
||||
{
|
||||
//mId = 0xFFFFFFFF;
|
||||
setEnabled(true);
|
||||
}
|
||||
|
||||
Stream::~Stream()
|
||||
{
|
||||
}
|
||||
|
||||
void Stream::loadProtocolWidgets()
|
||||
{
|
||||
#if 0
|
||||
//protocols.loadConfigWidgets();
|
||||
foreach(AbstractProtocol* proto, *currentFrameProtocols)
|
||||
{
|
||||
proto->loadConfigWidget();
|
||||
}
|
||||
#else
|
||||
ProtocolListIterator *iter;
|
||||
|
||||
iter = createProtocolListIterator();
|
||||
while (iter->hasNext())
|
||||
{
|
||||
AbstractProtocol* p = iter->next();
|
||||
p->loadConfigWidget();
|
||||
}
|
||||
delete iter;
|
||||
#endif
|
||||
}
|
||||
|
||||
void Stream::storeProtocolWidgets()
|
||||
{
|
||||
#if 0
|
||||
//protocols.storeConfigWidgets();
|
||||
foreach(const AbstractProtocol* proto, frameProtocol())
|
||||
{
|
||||
proto->storeConfigWidget();
|
||||
_iter->toFront();
|
||||
}
|
||||
#else
|
||||
ProtocolListIterator *iter;
|
||||
|
||||
iter = createProtocolListIterator();
|
||||
while (iter->hasNext())
|
||||
{
|
||||
AbstractProtocol* p = iter->next();
|
||||
p->storeConfigWidget();
|
||||
}
|
||||
delete iter;
|
||||
#endif
|
||||
}
|
||||
|
@ -1,23 +1,23 @@
|
||||
#ifndef _STREAM_H
|
||||
#define _STREAM_H
|
||||
|
||||
#include <QtGlobal>
|
||||
#include <QString>
|
||||
#include <QList>
|
||||
|
||||
#include "../common/protocol.pb.h"
|
||||
#include "../common/streambase.h"
|
||||
|
||||
class Stream : public StreamBase {
|
||||
|
||||
//quint32 mId;
|
||||
|
||||
public:
|
||||
Stream();
|
||||
~Stream();
|
||||
|
||||
void loadProtocolWidgets();
|
||||
void storeProtocolWidgets();
|
||||
};
|
||||
|
||||
#endif
|
||||
#ifndef _STREAM_H
|
||||
#define _STREAM_H
|
||||
|
||||
#include <QtGlobal>
|
||||
#include <QString>
|
||||
#include <QList>
|
||||
|
||||
#include "../common/protocol.pb.h"
|
||||
#include "../common/streambase.h"
|
||||
|
||||
class Stream : public StreamBase {
|
||||
|
||||
//quint32 mId;
|
||||
|
||||
public:
|
||||
Stream();
|
||||
~Stream();
|
||||
|
||||
void loadProtocolWidgets();
|
||||
void storeProtocolWidgets();
|
||||
};
|
||||
|
||||
#endif
|
||||
|
File diff suppressed because it is too large
Load Diff
@ -1,113 +1,113 @@
|
||||
#ifndef _STREAM_CONFIG_DIALOG_H
|
||||
#define _STREAM_CONFIG_DIALOG_H
|
||||
|
||||
#include <QDialog>
|
||||
#include "ui_streamconfigdialog.h"
|
||||
#include "port.h"
|
||||
#include "stream.h"
|
||||
#include "packetmodel.h"
|
||||
#include "modeltest.h"
|
||||
|
||||
#define MAX_MAC_ITER_COUNT 256
|
||||
#define MIN_PKT_LEN 64
|
||||
#define MAX_PKT_LEN 1522
|
||||
|
||||
/*
|
||||
** TODO
|
||||
** \todo Improve HexStr handling
|
||||
**
|
||||
*/
|
||||
|
||||
|
||||
class StreamConfigDialog : public QDialog, public Ui::StreamConfigDialog
|
||||
{
|
||||
Q_OBJECT
|
||||
public:
|
||||
StreamConfigDialog(Port &port, uint streamIndex, QWidget *parent = 0);
|
||||
~StreamConfigDialog();
|
||||
|
||||
private:
|
||||
|
||||
enum ButtonId
|
||||
{
|
||||
ButtonIdNone = 0,
|
||||
ButtonIdOther = -2
|
||||
};
|
||||
|
||||
enum ProtoButtonGroup
|
||||
{
|
||||
ProtoMin,
|
||||
ProtoL1 = 0,
|
||||
ProtoVlan = 1,
|
||||
ProtoL2 = 2,
|
||||
ProtoL3 = 3,
|
||||
ProtoL4 = 4,
|
||||
ProtoPayload = 5,
|
||||
ProtoMax
|
||||
};
|
||||
|
||||
QButtonGroup *bgProto[ProtoMax];
|
||||
|
||||
QStringListModel *mpAvailableProtocolsModel;
|
||||
QStringListModel *mpSelectedProtocolsModel;
|
||||
|
||||
Port& mPort;
|
||||
uint mCurrentStreamIndex;
|
||||
|
||||
Stream *mpStream;
|
||||
ProtocolListIterator *_iter;
|
||||
|
||||
bool isUpdateInProgress;
|
||||
|
||||
PacketModel *mpPacketModel;
|
||||
ModelTest *mpPacketModelTester;
|
||||
|
||||
// The following static variables are used to track the "selected" tab
|
||||
// for the various tab widgets so that it can be restored when the dialog
|
||||
// is opened the next time
|
||||
static int lastTopLevelTabIndex;
|
||||
|
||||
void setupUiExtra();
|
||||
void updateSelectedProtocols();
|
||||
void LoadCurrentStream();
|
||||
void StoreCurrentStream();
|
||||
|
||||
private slots:
|
||||
void on_cmbPktLenMode_currentIndexChanged(QString mode);
|
||||
void update_NumPacketsAndNumBursts();
|
||||
|
||||
void on_twTopLevel_currentChanged(int index);
|
||||
void on_tbSelectProtocols_currentChanged(int index);
|
||||
|
||||
// "Simple" Protocol Selection related
|
||||
bool skipProtocols(int layer);
|
||||
|
||||
void disableProtocols(QButtonGroup *protocolGroup, bool checked);
|
||||
void forceProtocolNone(bool checked);
|
||||
|
||||
void updateProtocol(int newId);
|
||||
void __updateProtocol(int level, int newId);
|
||||
|
||||
void updateSelectProtocolsSimpleWidget();
|
||||
|
||||
// "Advanced" Protocol Selection related
|
||||
void when_lvAllProtocols_selectionChanged(
|
||||
const QItemSelection &selected, const QItemSelection &deselected);
|
||||
void when_lvSelectedProtocols_currentChanged(
|
||||
const QModelIndex ¤t, const QModelIndex &previous);
|
||||
|
||||
void on_tbAdd_clicked();
|
||||
void on_tbDelete_clicked();
|
||||
void on_tbUp_clicked();
|
||||
void on_tbDown_clicked();
|
||||
|
||||
void updateSelectProtocolsAdvancedWidget();
|
||||
|
||||
void on_pbPrev_clicked();
|
||||
void on_pbNext_clicked();
|
||||
|
||||
void on_pbOk_clicked();
|
||||
};
|
||||
|
||||
#endif
|
||||
|
||||
#ifndef _STREAM_CONFIG_DIALOG_H
|
||||
#define _STREAM_CONFIG_DIALOG_H
|
||||
|
||||
#include <QDialog>
|
||||
#include "ui_streamconfigdialog.h"
|
||||
#include "port.h"
|
||||
#include "stream.h"
|
||||
#include "packetmodel.h"
|
||||
#include "modeltest.h"
|
||||
|
||||
#define MAX_MAC_ITER_COUNT 256
|
||||
#define MIN_PKT_LEN 64
|
||||
#define MAX_PKT_LEN 1522
|
||||
|
||||
/*
|
||||
** TODO
|
||||
** \todo Improve HexStr handling
|
||||
**
|
||||
*/
|
||||
|
||||
|
||||
class StreamConfigDialog : public QDialog, public Ui::StreamConfigDialog
|
||||
{
|
||||
Q_OBJECT
|
||||
public:
|
||||
StreamConfigDialog(Port &port, uint streamIndex, QWidget *parent = 0);
|
||||
~StreamConfigDialog();
|
||||
|
||||
private:
|
||||
|
||||
enum ButtonId
|
||||
{
|
||||
ButtonIdNone = 0,
|
||||
ButtonIdOther = -2
|
||||
};
|
||||
|
||||
enum ProtoButtonGroup
|
||||
{
|
||||
ProtoMin,
|
||||
ProtoL1 = 0,
|
||||
ProtoVlan = 1,
|
||||
ProtoL2 = 2,
|
||||
ProtoL3 = 3,
|
||||
ProtoL4 = 4,
|
||||
ProtoPayload = 5,
|
||||
ProtoMax
|
||||
};
|
||||
|
||||
QButtonGroup *bgProto[ProtoMax];
|
||||
|
||||
QStringListModel *mpAvailableProtocolsModel;
|
||||
QStringListModel *mpSelectedProtocolsModel;
|
||||
|
||||
Port& mPort;
|
||||
uint mCurrentStreamIndex;
|
||||
|
||||
Stream *mpStream;
|
||||
ProtocolListIterator *_iter;
|
||||
|
||||
bool isUpdateInProgress;
|
||||
|
||||
PacketModel *mpPacketModel;
|
||||
ModelTest *mpPacketModelTester;
|
||||
|
||||
// The following static variables are used to track the "selected" tab
|
||||
// for the various tab widgets so that it can be restored when the dialog
|
||||
// is opened the next time
|
||||
static int lastTopLevelTabIndex;
|
||||
|
||||
void setupUiExtra();
|
||||
void updateSelectedProtocols();
|
||||
void LoadCurrentStream();
|
||||
void StoreCurrentStream();
|
||||
|
||||
private slots:
|
||||
void on_cmbPktLenMode_currentIndexChanged(QString mode);
|
||||
void update_NumPacketsAndNumBursts();
|
||||
|
||||
void on_twTopLevel_currentChanged(int index);
|
||||
void on_tbSelectProtocols_currentChanged(int index);
|
||||
|
||||
// "Simple" Protocol Selection related
|
||||
bool skipProtocols(int layer);
|
||||
|
||||
void disableProtocols(QButtonGroup *protocolGroup, bool checked);
|
||||
void forceProtocolNone(bool checked);
|
||||
|
||||
void updateProtocol(int newId);
|
||||
void __updateProtocol(int level, int newId);
|
||||
|
||||
void updateSelectProtocolsSimpleWidget();
|
||||
|
||||
// "Advanced" Protocol Selection related
|
||||
void when_lvAllProtocols_selectionChanged(
|
||||
const QItemSelection &selected, const QItemSelection &deselected);
|
||||
void when_lvSelectedProtocols_currentChanged(
|
||||
const QModelIndex ¤t, const QModelIndex &previous);
|
||||
|
||||
void on_tbAdd_clicked();
|
||||
void on_tbDelete_clicked();
|
||||
void on_tbUp_clicked();
|
||||
void on_tbDown_clicked();
|
||||
|
||||
void updateSelectProtocolsAdvancedWidget();
|
||||
|
||||
void on_pbPrev_clicked();
|
||||
void on_pbNext_clicked();
|
||||
|
||||
void on_pbOk_clicked();
|
||||
};
|
||||
|
||||
#endif
|
||||
|
||||
|
@ -1,242 +1,242 @@
|
||||
#include "stream.h"
|
||||
#include "streammodel.h"
|
||||
#include "portgrouplist.h"
|
||||
#include "qicon.h"
|
||||
|
||||
StreamModel::StreamModel(PortGroupList *p, QObject *parent)
|
||||
: QAbstractTableModel(parent)
|
||||
{
|
||||
pgl = p;
|
||||
mCurrentPort = NULL;
|
||||
}
|
||||
|
||||
int StreamModel::rowCount(const QModelIndex &parent) const
|
||||
{
|
||||
if (parent.isValid())
|
||||
return 0;
|
||||
|
||||
if (mCurrentPort)
|
||||
return mCurrentPort->numStreams();
|
||||
else
|
||||
return 0;
|
||||
}
|
||||
|
||||
int StreamModel::columnCount(const QModelIndex &parent ) const
|
||||
{
|
||||
return (int) StreamMaxFields;
|
||||
}
|
||||
|
||||
Qt::ItemFlags StreamModel::flags(const QModelIndex &index) const
|
||||
{
|
||||
Qt::ItemFlags flags = QAbstractTableModel::flags(index);
|
||||
|
||||
|
||||
switch (index.column())
|
||||
{
|
||||
case StreamIcon:
|
||||
break;
|
||||
case StreamName:
|
||||
flags |= Qt::ItemIsEditable;
|
||||
break;
|
||||
case StreamStatus:
|
||||
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
|
||||
if (!index.isValid())
|
||||
return QVariant();
|
||||
|
||||
// Check for row/column limits
|
||||
if (index.row() >= mCurrentPort->numStreams())
|
||||
return QVariant();
|
||||
|
||||
if (index.column() >= StreamMaxFields)
|
||||
return QVariant();
|
||||
|
||||
if (mCurrentPort == NULL)
|
||||
return QVariant();
|
||||
|
||||
// Return data based on field and role
|
||||
switch(index.column())
|
||||
{
|
||||
case StreamIcon:
|
||||
{
|
||||
if (role == Qt::DecorationRole)
|
||||
return QIcon(":/icons/stream_edit.png");
|
||||
else
|
||||
return QVariant();
|
||||
break;
|
||||
}
|
||||
case StreamName:
|
||||
{
|
||||
if ((role == Qt::DisplayRole) || (role == Qt::EditRole))
|
||||
return mCurrentPort->streamByIndex(index.row())->name();
|
||||
else
|
||||
return QVariant();
|
||||
break;
|
||||
}
|
||||
case StreamStatus:
|
||||
{
|
||||
if ((role == Qt::CheckStateRole))
|
||||
{
|
||||
if (mCurrentPort->streamByIndex(index.row())->isEnabled())
|
||||
return Qt::Checked;
|
||||
else
|
||||
return Qt::Unchecked;
|
||||
}
|
||||
else
|
||||
return QVariant();
|
||||
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:
|
||||
qFatal("-------------UNHANDLED STREAM FIELD----------------");
|
||||
}
|
||||
|
||||
return QVariant();
|
||||
}
|
||||
|
||||
bool StreamModel::setData(const QModelIndex &index, const QVariant &value, int role)
|
||||
{
|
||||
if (mCurrentPort == NULL)
|
||||
return false;
|
||||
|
||||
if (index.isValid())
|
||||
{
|
||||
switch (index.column())
|
||||
{
|
||||
// Edit Supported Fields
|
||||
case StreamName:
|
||||
mCurrentPort->streamByIndex(index.row())->setName(value.toString());
|
||||
emit(dataChanged(index, index));
|
||||
return true;
|
||||
|
||||
case StreamStatus:
|
||||
mCurrentPort->streamByIndex(index.row())->setEnabled(value.toBool());
|
||||
emit(dataChanged(index, index));
|
||||
return true;
|
||||
|
||||
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;
|
||||
|
||||
// Unhandled Stream Field
|
||||
default:
|
||||
qDebug("-------------UNHANDLED STREAM FIELD----------------");
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
QVariant StreamModel::headerData(int section, Qt::Orientation orientation, int role) const
|
||||
{
|
||||
if (role != Qt::DisplayRole)
|
||||
return QVariant();
|
||||
|
||||
if (orientation == Qt::Horizontal)
|
||||
{
|
||||
switch(section)
|
||||
{
|
||||
case StreamIcon:
|
||||
return QString("");
|
||||
break;
|
||||
case StreamName:
|
||||
return QString("Name");
|
||||
break;
|
||||
case StreamStatus:
|
||||
return QString("");
|
||||
break;
|
||||
case StreamNextWhat:
|
||||
return QString("Goto");
|
||||
break;
|
||||
default:
|
||||
qDebug("-------------UNHANDLED STREAM FIELD----------------");
|
||||
break;
|
||||
}
|
||||
}
|
||||
else
|
||||
return QString("%1").arg(section+1);
|
||||
|
||||
return QVariant();
|
||||
}
|
||||
|
||||
bool StreamModel::insertRows(int row, int count, const QModelIndex &parent)
|
||||
{
|
||||
qDebug("insertRows() row = %d", row);
|
||||
qDebug("insertRows() count = %d", count);
|
||||
beginInsertRows(QModelIndex(), row, row+count-1);
|
||||
for (int i = 0; i < count; i++)
|
||||
mCurrentPort->newStreamAt(row);
|
||||
endInsertRows();
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
bool StreamModel::removeRows(int row, int count, const QModelIndex &parent)
|
||||
{
|
||||
qDebug("removeRows() row = %d", row);
|
||||
qDebug("removeRows() count = %d", count);
|
||||
beginRemoveRows(QModelIndex(), row, row+count-1);
|
||||
for (int i = 0; i < count; i++)
|
||||
{
|
||||
mCurrentPort->deleteStreamAt(row);
|
||||
}
|
||||
endRemoveRows();
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
// --------------------- SLOTS ------------------------
|
||||
|
||||
void StreamModel::setCurrentPortIndex(const QModelIndex ¤t)
|
||||
{
|
||||
if (!current.isValid() || !pgl->isPort(current))
|
||||
{
|
||||
qDebug("current is either invalid or not a port");
|
||||
mCurrentPort = NULL;
|
||||
}
|
||||
else
|
||||
{
|
||||
qDebug("change to valid port");
|
||||
quint16 pg = current.internalId() >> 16;
|
||||
mCurrentPort = pgl->mPortGroups[pgl->indexOfPortGroup(pg)]->mPorts[current.row()];
|
||||
}
|
||||
reset();
|
||||
}
|
||||
#include "stream.h"
|
||||
#include "streammodel.h"
|
||||
#include "portgrouplist.h"
|
||||
#include "qicon.h"
|
||||
|
||||
StreamModel::StreamModel(PortGroupList *p, QObject *parent)
|
||||
: QAbstractTableModel(parent)
|
||||
{
|
||||
pgl = p;
|
||||
mCurrentPort = NULL;
|
||||
}
|
||||
|
||||
int StreamModel::rowCount(const QModelIndex &parent) const
|
||||
{
|
||||
if (parent.isValid())
|
||||
return 0;
|
||||
|
||||
if (mCurrentPort)
|
||||
return mCurrentPort->numStreams();
|
||||
else
|
||||
return 0;
|
||||
}
|
||||
|
||||
int StreamModel::columnCount(const QModelIndex &parent ) const
|
||||
{
|
||||
return (int) StreamMaxFields;
|
||||
}
|
||||
|
||||
Qt::ItemFlags StreamModel::flags(const QModelIndex &index) const
|
||||
{
|
||||
Qt::ItemFlags flags = QAbstractTableModel::flags(index);
|
||||
|
||||
|
||||
switch (index.column())
|
||||
{
|
||||
case StreamIcon:
|
||||
break;
|
||||
case StreamName:
|
||||
flags |= Qt::ItemIsEditable;
|
||||
break;
|
||||
case StreamStatus:
|
||||
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
|
||||
if (!index.isValid())
|
||||
return QVariant();
|
||||
|
||||
// Check for row/column limits
|
||||
if (index.row() >= mCurrentPort->numStreams())
|
||||
return QVariant();
|
||||
|
||||
if (index.column() >= StreamMaxFields)
|
||||
return QVariant();
|
||||
|
||||
if (mCurrentPort == NULL)
|
||||
return QVariant();
|
||||
|
||||
// Return data based on field and role
|
||||
switch(index.column())
|
||||
{
|
||||
case StreamIcon:
|
||||
{
|
||||
if (role == Qt::DecorationRole)
|
||||
return QIcon(":/icons/stream_edit.png");
|
||||
else
|
||||
return QVariant();
|
||||
break;
|
||||
}
|
||||
case StreamName:
|
||||
{
|
||||
if ((role == Qt::DisplayRole) || (role == Qt::EditRole))
|
||||
return mCurrentPort->streamByIndex(index.row())->name();
|
||||
else
|
||||
return QVariant();
|
||||
break;
|
||||
}
|
||||
case StreamStatus:
|
||||
{
|
||||
if ((role == Qt::CheckStateRole))
|
||||
{
|
||||
if (mCurrentPort->streamByIndex(index.row())->isEnabled())
|
||||
return Qt::Checked;
|
||||
else
|
||||
return Qt::Unchecked;
|
||||
}
|
||||
else
|
||||
return QVariant();
|
||||
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:
|
||||
qFatal("-------------UNHANDLED STREAM FIELD----------------");
|
||||
}
|
||||
|
||||
return QVariant();
|
||||
}
|
||||
|
||||
bool StreamModel::setData(const QModelIndex &index, const QVariant &value, int role)
|
||||
{
|
||||
if (mCurrentPort == NULL)
|
||||
return false;
|
||||
|
||||
if (index.isValid())
|
||||
{
|
||||
switch (index.column())
|
||||
{
|
||||
// Edit Supported Fields
|
||||
case StreamName:
|
||||
mCurrentPort->streamByIndex(index.row())->setName(value.toString());
|
||||
emit(dataChanged(index, index));
|
||||
return true;
|
||||
|
||||
case StreamStatus:
|
||||
mCurrentPort->streamByIndex(index.row())->setEnabled(value.toBool());
|
||||
emit(dataChanged(index, index));
|
||||
return true;
|
||||
|
||||
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;
|
||||
|
||||
// Unhandled Stream Field
|
||||
default:
|
||||
qDebug("-------------UNHANDLED STREAM FIELD----------------");
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
QVariant StreamModel::headerData(int section, Qt::Orientation orientation, int role) const
|
||||
{
|
||||
if (role != Qt::DisplayRole)
|
||||
return QVariant();
|
||||
|
||||
if (orientation == Qt::Horizontal)
|
||||
{
|
||||
switch(section)
|
||||
{
|
||||
case StreamIcon:
|
||||
return QString("");
|
||||
break;
|
||||
case StreamName:
|
||||
return QString("Name");
|
||||
break;
|
||||
case StreamStatus:
|
||||
return QString("");
|
||||
break;
|
||||
case StreamNextWhat:
|
||||
return QString("Goto");
|
||||
break;
|
||||
default:
|
||||
qDebug("-------------UNHANDLED STREAM FIELD----------------");
|
||||
break;
|
||||
}
|
||||
}
|
||||
else
|
||||
return QString("%1").arg(section+1);
|
||||
|
||||
return QVariant();
|
||||
}
|
||||
|
||||
bool StreamModel::insertRows(int row, int count, const QModelIndex &parent)
|
||||
{
|
||||
qDebug("insertRows() row = %d", row);
|
||||
qDebug("insertRows() count = %d", count);
|
||||
beginInsertRows(QModelIndex(), row, row+count-1);
|
||||
for (int i = 0; i < count; i++)
|
||||
mCurrentPort->newStreamAt(row);
|
||||
endInsertRows();
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
bool StreamModel::removeRows(int row, int count, const QModelIndex &parent)
|
||||
{
|
||||
qDebug("removeRows() row = %d", row);
|
||||
qDebug("removeRows() count = %d", count);
|
||||
beginRemoveRows(QModelIndex(), row, row+count-1);
|
||||
for (int i = 0; i < count; i++)
|
||||
{
|
||||
mCurrentPort->deleteStreamAt(row);
|
||||
}
|
||||
endRemoveRows();
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
// --------------------- SLOTS ------------------------
|
||||
|
||||
void StreamModel::setCurrentPortIndex(const QModelIndex ¤t)
|
||||
{
|
||||
if (!current.isValid() || !pgl->isPort(current))
|
||||
{
|
||||
qDebug("current is either invalid or not a port");
|
||||
mCurrentPort = NULL;
|
||||
}
|
||||
else
|
||||
{
|
||||
qDebug("change to valid port");
|
||||
quint16 pg = current.internalId() >> 16;
|
||||
mCurrentPort = pgl->mPortGroups[pgl->indexOfPortGroup(pg)]->mPorts[current.row()];
|
||||
}
|
||||
reset();
|
||||
}
|
||||
|
@ -1,57 +1,57 @@
|
||||
#ifndef _STREAM_MODEL_H
|
||||
#define _STREAM_MODEL_H
|
||||
|
||||
#include <QStringList>
|
||||
#include <QAbstractTableModel>
|
||||
#include "port.h"
|
||||
|
||||
class PortGroupList;
|
||||
|
||||
class StreamModel : public QAbstractTableModel
|
||||
{
|
||||
Q_OBJECT
|
||||
|
||||
Port *mCurrentPort;
|
||||
PortGroupList *pgl;
|
||||
|
||||
public:
|
||||
StreamModel(PortGroupList *p, QObject *parent = 0);
|
||||
|
||||
int rowCount(const QModelIndex &parent = QModelIndex()) const;
|
||||
int columnCount(const QModelIndex &parent = QModelIndex()) const;
|
||||
Qt::ItemFlags flags(const QModelIndex &index) const;
|
||||
QVariant data(const QModelIndex &index, int role) const;
|
||||
bool setData(const QModelIndex &index, const QVariant &value,
|
||||
int role = Qt::EditRole);
|
||||
QVariant headerData(int section, Qt::Orientation orientation,
|
||||
int role = Qt::DisplayRole) const;
|
||||
bool insertRows (int row, int count,
|
||||
const QModelIndex & parent = QModelIndex());
|
||||
bool removeRows (int row, int count,
|
||||
const QModelIndex & parent = QModelIndex());
|
||||
|
||||
#if 0 // CleanedUp!
|
||||
// FIXME(HIGH): This *is* like a kludge
|
||||
QList<Stream>* currentPortStreamList()
|
||||
{ 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);
|
||||
|
||||
};
|
||||
|
||||
#endif
|
||||
#ifndef _STREAM_MODEL_H
|
||||
#define _STREAM_MODEL_H
|
||||
|
||||
#include <QStringList>
|
||||
#include <QAbstractTableModel>
|
||||
#include "port.h"
|
||||
|
||||
class PortGroupList;
|
||||
|
||||
class StreamModel : public QAbstractTableModel
|
||||
{
|
||||
Q_OBJECT
|
||||
|
||||
Port *mCurrentPort;
|
||||
PortGroupList *pgl;
|
||||
|
||||
public:
|
||||
StreamModel(PortGroupList *p, QObject *parent = 0);
|
||||
|
||||
int rowCount(const QModelIndex &parent = QModelIndex()) const;
|
||||
int columnCount(const QModelIndex &parent = QModelIndex()) const;
|
||||
Qt::ItemFlags flags(const QModelIndex &index) const;
|
||||
QVariant data(const QModelIndex &index, int role) const;
|
||||
bool setData(const QModelIndex &index, const QVariant &value,
|
||||
int role = Qt::EditRole);
|
||||
QVariant headerData(int section, Qt::Orientation orientation,
|
||||
int role = Qt::DisplayRole) const;
|
||||
bool insertRows (int row, int count,
|
||||
const QModelIndex & parent = QModelIndex());
|
||||
bool removeRows (int row, int count,
|
||||
const QModelIndex & parent = QModelIndex());
|
||||
|
||||
#if 0 // CleanedUp!
|
||||
// FIXME(HIGH): This *is* like a kludge
|
||||
QList<Stream>* currentPortStreamList()
|
||||
{ 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);
|
||||
|
||||
};
|
||||
|
||||
#endif
|
||||
|
@ -1,210 +1,210 @@
|
||||
// stream.proto
|
||||
|
||||
package OstProto;
|
||||
|
||||
message StreamId {
|
||||
required uint32 id = 1;
|
||||
}
|
||||
|
||||
message StreamCore {
|
||||
enum FrameLengthMode {
|
||||
e_fl_fixed = 0;
|
||||
e_fl_inc = 1;
|
||||
e_fl_dec = 2;
|
||||
e_fl_random = 3;
|
||||
}
|
||||
|
||||
// Basics
|
||||
optional string name = 1;
|
||||
optional bool is_enabled = 2;
|
||||
optional uint32 ordinal = 3;
|
||||
|
||||
// Frame Length (includes CRC)
|
||||
optional FrameLengthMode len_mode = 14 [default = e_fl_fixed];
|
||||
optional uint32 frame_len = 15 [default = 64];
|
||||
optional uint32 frame_len_min = 16 [default = 64];
|
||||
optional uint32 frame_len_max = 17 [default = 1518];
|
||||
|
||||
// Currently Selected Protocols
|
||||
//repeated uint32 frame_proto = 20;
|
||||
}
|
||||
|
||||
message StreamControl {
|
||||
enum SendUnit {
|
||||
e_su_packets = 0;
|
||||
e_su_bursts = 1;
|
||||
}
|
||||
|
||||
enum SendMode {
|
||||
e_sm_fixed = 0;
|
||||
e_sm_continuous = 1;
|
||||
}
|
||||
|
||||
enum NextWhat {
|
||||
e_nw_stop = 0;
|
||||
e_nw_goto_next = 1;
|
||||
e_nw_goto_id = 2;
|
||||
}
|
||||
|
||||
optional SendUnit unit = 1 [default = e_su_packets];
|
||||
optional SendMode mode = 2 [default = e_sm_fixed];
|
||||
optional uint32 num_packets = 3 [default = 1];
|
||||
optional uint32 num_bursts = 4 [default = 1];
|
||||
optional uint32 packets_per_burst = 5 [default = 10];
|
||||
optional NextWhat next = 6 [default = e_nw_goto_next];
|
||||
optional uint32 packets_per_sec = 7 [default = 1];
|
||||
optional uint32 bursts_per_sec = 8 [default = 1];
|
||||
}
|
||||
|
||||
message ProtocolId {
|
||||
required uint32 id = 1;
|
||||
}
|
||||
|
||||
message Protocol {
|
||||
|
||||
required ProtocolId protocol_id = 1;
|
||||
|
||||
extensions 51 to 100; // Reserved for Ostinato Use
|
||||
extensions 101 to 200; // Available for use by protocols
|
||||
|
||||
enum k {
|
||||
kMacFieldNumber = 51;
|
||||
kPayloadFieldNumber = 52;
|
||||
kSampleFieldNumber = 53;
|
||||
kUserScriptFieldNumber = 54;
|
||||
|
||||
kEth2FieldNumber = 121;
|
||||
kDot3FieldNumber = 122;
|
||||
kLlcFieldNumber = 123;
|
||||
kSnapFieldNumber = 124;
|
||||
|
||||
kSvlanFieldNumber = 125;
|
||||
kVlanFieldNumber = 126;
|
||||
|
||||
kDot2LlcFieldNumber = 127;
|
||||
kDot2SnapFieldNumber = 128;
|
||||
kVlanStackFieldNumber = 129;
|
||||
|
||||
kIp4FieldNumber = 130;
|
||||
kArpFieldNumber = 131;
|
||||
|
||||
kTcpFieldNumber = 140;
|
||||
kUdpFieldNumber = 141;
|
||||
kIcmpFieldNumber = 142;
|
||||
kIgmpFieldNumber = 143;
|
||||
}
|
||||
}
|
||||
|
||||
message Stream {
|
||||
|
||||
required StreamId stream_id = 1;
|
||||
optional StreamCore core = 2;
|
||||
optional StreamControl control = 3;
|
||||
|
||||
repeated Protocol protocol = 4;
|
||||
}
|
||||
|
||||
message Void {
|
||||
// nothing!
|
||||
}
|
||||
|
||||
message Ack {
|
||||
//! \todo (LOW) do we need any fields in 'Ack'
|
||||
}
|
||||
|
||||
message PortId {
|
||||
required uint32 id = 1;
|
||||
}
|
||||
|
||||
message PortIdList {
|
||||
repeated PortId port_id = 1;
|
||||
}
|
||||
|
||||
message StreamIdList {
|
||||
required PortId port_id = 1;
|
||||
repeated StreamId stream_id = 2;
|
||||
}
|
||||
|
||||
message Port {
|
||||
required PortId port_id = 1;
|
||||
optional string name = 2;
|
||||
optional string description = 3;
|
||||
optional bool is_enabled = 4;
|
||||
optional bool is_exclusive_control = 6;
|
||||
}
|
||||
|
||||
message PortConfigList {
|
||||
repeated Port port = 1;
|
||||
}
|
||||
|
||||
message StreamConfigList {
|
||||
required PortId port_id = 1;
|
||||
repeated Stream stream = 2;
|
||||
}
|
||||
|
||||
message CaptureBuffer {
|
||||
//! \todo (HIGH) define CaptureBuffer
|
||||
}
|
||||
|
||||
message CaptureBufferList {
|
||||
repeated CaptureBuffer list = 1;
|
||||
}
|
||||
|
||||
enum LinkState {
|
||||
LinkStateUnknown = 0;
|
||||
LinkStateDown = 1;
|
||||
LinkStateUp = 2;
|
||||
}
|
||||
|
||||
message PortState {
|
||||
optional LinkState link_state = 1 [default = LinkStateUnknown];
|
||||
optional bool is_transmit_on = 2 [default = false];
|
||||
optional bool is_capture_on = 3 [default = false];
|
||||
}
|
||||
|
||||
message PortStats {
|
||||
|
||||
required PortId port_id = 1;
|
||||
|
||||
optional PortState state = 2;
|
||||
|
||||
optional uint64 rx_pkts = 11;
|
||||
optional uint64 rx_bytes = 12;
|
||||
optional uint64 rx_pkts_nic = 13;
|
||||
optional uint64 rx_bytes_nic = 14;
|
||||
optional uint64 rx_pps = 15;
|
||||
optional uint64 rx_bps = 16;
|
||||
|
||||
optional uint64 tx_pkts = 21;
|
||||
optional uint64 tx_bytes = 22;
|
||||
optional uint64 tx_pkts_nic = 23;
|
||||
optional uint64 tx_bytes_nic = 24;
|
||||
optional uint64 tx_pps = 25;
|
||||
optional uint64 tx_bps = 26;
|
||||
}
|
||||
|
||||
message PortStatsList {
|
||||
repeated PortStats port_stats = 1;
|
||||
}
|
||||
|
||||
service OstService {
|
||||
rpc getPortIdList(Void) returns (PortIdList);
|
||||
rpc getPortConfig(PortIdList) returns (PortConfigList);
|
||||
|
||||
rpc getStreamIdList(PortId) returns (StreamIdList);
|
||||
rpc getStreamConfig(StreamIdList) returns (StreamConfigList);
|
||||
rpc addStream(StreamIdList) returns (Ack);
|
||||
rpc deleteStream(StreamIdList) returns (Ack);
|
||||
rpc modifyStream(StreamConfigList) returns (Ack);
|
||||
|
||||
rpc startTx(PortIdList) returns (Ack);
|
||||
rpc stopTx(PortIdList) returns (Ack);
|
||||
|
||||
rpc startCapture(PortIdList) returns (Ack);
|
||||
rpc stopCapture(PortIdList) returns (Ack);
|
||||
rpc getCaptureBuffer(PortId) returns (CaptureBuffer);
|
||||
|
||||
rpc getStats(PortIdList) returns (PortStatsList);
|
||||
rpc clearStats(PortIdList) returns (Ack);
|
||||
}
|
||||
|
||||
// stream.proto
|
||||
|
||||
package OstProto;
|
||||
|
||||
message StreamId {
|
||||
required uint32 id = 1;
|
||||
}
|
||||
|
||||
message StreamCore {
|
||||
enum FrameLengthMode {
|
||||
e_fl_fixed = 0;
|
||||
e_fl_inc = 1;
|
||||
e_fl_dec = 2;
|
||||
e_fl_random = 3;
|
||||
}
|
||||
|
||||
// Basics
|
||||
optional string name = 1;
|
||||
optional bool is_enabled = 2;
|
||||
optional uint32 ordinal = 3;
|
||||
|
||||
// Frame Length (includes CRC)
|
||||
optional FrameLengthMode len_mode = 14 [default = e_fl_fixed];
|
||||
optional uint32 frame_len = 15 [default = 64];
|
||||
optional uint32 frame_len_min = 16 [default = 64];
|
||||
optional uint32 frame_len_max = 17 [default = 1518];
|
||||
|
||||
// Currently Selected Protocols
|
||||
//repeated uint32 frame_proto = 20;
|
||||
}
|
||||
|
||||
message StreamControl {
|
||||
enum SendUnit {
|
||||
e_su_packets = 0;
|
||||
e_su_bursts = 1;
|
||||
}
|
||||
|
||||
enum SendMode {
|
||||
e_sm_fixed = 0;
|
||||
e_sm_continuous = 1;
|
||||
}
|
||||
|
||||
enum NextWhat {
|
||||
e_nw_stop = 0;
|
||||
e_nw_goto_next = 1;
|
||||
e_nw_goto_id = 2;
|
||||
}
|
||||
|
||||
optional SendUnit unit = 1 [default = e_su_packets];
|
||||
optional SendMode mode = 2 [default = e_sm_fixed];
|
||||
optional uint32 num_packets = 3 [default = 1];
|
||||
optional uint32 num_bursts = 4 [default = 1];
|
||||
optional uint32 packets_per_burst = 5 [default = 10];
|
||||
optional NextWhat next = 6 [default = e_nw_goto_next];
|
||||
optional uint32 packets_per_sec = 7 [default = 1];
|
||||
optional uint32 bursts_per_sec = 8 [default = 1];
|
||||
}
|
||||
|
||||
message ProtocolId {
|
||||
required uint32 id = 1;
|
||||
}
|
||||
|
||||
message Protocol {
|
||||
|
||||
required ProtocolId protocol_id = 1;
|
||||
|
||||
extensions 51 to 100; // Reserved for Ostinato Use
|
||||
extensions 101 to 200; // Available for use by protocols
|
||||
|
||||
enum k {
|
||||
kMacFieldNumber = 51;
|
||||
kPayloadFieldNumber = 52;
|
||||
kSampleFieldNumber = 53;
|
||||
kUserScriptFieldNumber = 54;
|
||||
|
||||
kEth2FieldNumber = 121;
|
||||
kDot3FieldNumber = 122;
|
||||
kLlcFieldNumber = 123;
|
||||
kSnapFieldNumber = 124;
|
||||
|
||||
kSvlanFieldNumber = 125;
|
||||
kVlanFieldNumber = 126;
|
||||
|
||||
kDot2LlcFieldNumber = 127;
|
||||
kDot2SnapFieldNumber = 128;
|
||||
kVlanStackFieldNumber = 129;
|
||||
|
||||
kIp4FieldNumber = 130;
|
||||
kArpFieldNumber = 131;
|
||||
|
||||
kTcpFieldNumber = 140;
|
||||
kUdpFieldNumber = 141;
|
||||
kIcmpFieldNumber = 142;
|
||||
kIgmpFieldNumber = 143;
|
||||
}
|
||||
}
|
||||
|
||||
message Stream {
|
||||
|
||||
required StreamId stream_id = 1;
|
||||
optional StreamCore core = 2;
|
||||
optional StreamControl control = 3;
|
||||
|
||||
repeated Protocol protocol = 4;
|
||||
}
|
||||
|
||||
message Void {
|
||||
// nothing!
|
||||
}
|
||||
|
||||
message Ack {
|
||||
//! \todo (LOW) do we need any fields in 'Ack'
|
||||
}
|
||||
|
||||
message PortId {
|
||||
required uint32 id = 1;
|
||||
}
|
||||
|
||||
message PortIdList {
|
||||
repeated PortId port_id = 1;
|
||||
}
|
||||
|
||||
message StreamIdList {
|
||||
required PortId port_id = 1;
|
||||
repeated StreamId stream_id = 2;
|
||||
}
|
||||
|
||||
message Port {
|
||||
required PortId port_id = 1;
|
||||
optional string name = 2;
|
||||
optional string description = 3;
|
||||
optional bool is_enabled = 4;
|
||||
optional bool is_exclusive_control = 6;
|
||||
}
|
||||
|
||||
message PortConfigList {
|
||||
repeated Port port = 1;
|
||||
}
|
||||
|
||||
message StreamConfigList {
|
||||
required PortId port_id = 1;
|
||||
repeated Stream stream = 2;
|
||||
}
|
||||
|
||||
message CaptureBuffer {
|
||||
//! \todo (HIGH) define CaptureBuffer
|
||||
}
|
||||
|
||||
message CaptureBufferList {
|
||||
repeated CaptureBuffer list = 1;
|
||||
}
|
||||
|
||||
enum LinkState {
|
||||
LinkStateUnknown = 0;
|
||||
LinkStateDown = 1;
|
||||
LinkStateUp = 2;
|
||||
}
|
||||
|
||||
message PortState {
|
||||
optional LinkState link_state = 1 [default = LinkStateUnknown];
|
||||
optional bool is_transmit_on = 2 [default = false];
|
||||
optional bool is_capture_on = 3 [default = false];
|
||||
}
|
||||
|
||||
message PortStats {
|
||||
|
||||
required PortId port_id = 1;
|
||||
|
||||
optional PortState state = 2;
|
||||
|
||||
optional uint64 rx_pkts = 11;
|
||||
optional uint64 rx_bytes = 12;
|
||||
optional uint64 rx_pkts_nic = 13;
|
||||
optional uint64 rx_bytes_nic = 14;
|
||||
optional uint64 rx_pps = 15;
|
||||
optional uint64 rx_bps = 16;
|
||||
|
||||
optional uint64 tx_pkts = 21;
|
||||
optional uint64 tx_bytes = 22;
|
||||
optional uint64 tx_pkts_nic = 23;
|
||||
optional uint64 tx_bytes_nic = 24;
|
||||
optional uint64 tx_pps = 25;
|
||||
optional uint64 tx_bps = 26;
|
||||
}
|
||||
|
||||
message PortStatsList {
|
||||
repeated PortStats port_stats = 1;
|
||||
}
|
||||
|
||||
service OstService {
|
||||
rpc getPortIdList(Void) returns (PortIdList);
|
||||
rpc getPortConfig(PortIdList) returns (PortConfigList);
|
||||
|
||||
rpc getStreamIdList(PortId) returns (StreamIdList);
|
||||
rpc getStreamConfig(StreamIdList) returns (StreamConfigList);
|
||||
rpc addStream(StreamIdList) returns (Ack);
|
||||
rpc deleteStream(StreamIdList) returns (Ack);
|
||||
rpc modifyStream(StreamConfigList) returns (Ack);
|
||||
|
||||
rpc startTx(PortIdList) returns (Ack);
|
||||
rpc stopTx(PortIdList) returns (Ack);
|
||||
|
||||
rpc startCapture(PortIdList) returns (Ack);
|
||||
rpc stopCapture(PortIdList) returns (Ack);
|
||||
rpc getCaptureBuffer(PortId) returns (CaptureBuffer);
|
||||
|
||||
rpc getStats(PortIdList) returns (PortStatsList);
|
||||
rpc clearStats(PortIdList) returns (Ack);
|
||||
}
|
||||
|
||||
|
302
rpc/pbhelper.h
302
rpc/pbhelper.h
@ -1,151 +1,151 @@
|
||||
#ifndef _PB_HELPER_H
|
||||
#define _PB_HELPER_H
|
||||
|
||||
#include <google/protobuf/message.h>
|
||||
#include <google/protobuf/descriptor.h>
|
||||
|
||||
#include <qdebug.h>
|
||||
|
||||
#if 0 // not reqd. any longer?
|
||||
class PbHelper
|
||||
{
|
||||
public:
|
||||
|
||||
// FIXME: Change msg from * to &
|
||||
void ForceSetSingularDefault(::google::protobuf::Message *msg)
|
||||
{
|
||||
const ::google::protobuf::Descriptor *desc;
|
||||
::google::protobuf::Message::Reflection *refl;
|
||||
|
||||
qDebug("In %s", __FUNCTION__);
|
||||
|
||||
desc = msg->GetDescriptor();
|
||||
refl = msg->GetReflection();
|
||||
|
||||
for (int i=0; i < desc->field_count(); i++)
|
||||
{
|
||||
const ::google::protobuf::FieldDescriptor *f;
|
||||
|
||||
f = desc->field(i);
|
||||
|
||||
// Ensure field is singular and not already set
|
||||
if (f->label() ==
|
||||
::google::protobuf::FieldDescriptor::LABEL_REPEATED)
|
||||
continue;
|
||||
if (refl->HasField(f))
|
||||
continue;
|
||||
|
||||
switch(f->type())
|
||||
{
|
||||
case ::google::protobuf::FieldDescriptor::TYPE_DOUBLE:
|
||||
refl->SetDouble(f, refl->GetDouble(f));
|
||||
break;
|
||||
|
||||
case ::google::protobuf::FieldDescriptor::TYPE_FLOAT:
|
||||
refl->SetFloat(f, refl->GetFloat(f));
|
||||
break;
|
||||
|
||||
case ::google::protobuf::FieldDescriptor::TYPE_INT32:
|
||||
case ::google::protobuf::FieldDescriptor::TYPE_SINT32:
|
||||
case ::google::protobuf::FieldDescriptor::TYPE_SFIXED32:
|
||||
refl->SetInt32(f, refl->GetInt32(f));
|
||||
break;
|
||||
|
||||
case ::google::protobuf::FieldDescriptor::TYPE_INT64:
|
||||
case ::google::protobuf::FieldDescriptor::TYPE_SINT64:
|
||||
case ::google::protobuf::FieldDescriptor::TYPE_SFIXED64:
|
||||
refl->SetInt64(f, refl->GetInt64(f));
|
||||
break;
|
||||
|
||||
case ::google::protobuf::FieldDescriptor::TYPE_UINT32:
|
||||
case ::google::protobuf::FieldDescriptor::TYPE_FIXED32:
|
||||
refl->SetUInt32(f, refl->GetUInt32(f));
|
||||
break;
|
||||
|
||||
case ::google::protobuf::FieldDescriptor::TYPE_UINT64:
|
||||
case ::google::protobuf::FieldDescriptor::TYPE_FIXED64:
|
||||
refl->SetUInt64(f, refl->GetUInt64(f));
|
||||
break;
|
||||
|
||||
case ::google::protobuf::FieldDescriptor::TYPE_BOOL:
|
||||
refl->SetBool(f, refl->GetBool(f));
|
||||
break;
|
||||
|
||||
case ::google::protobuf::FieldDescriptor::TYPE_ENUM:
|
||||
refl->SetEnum(f, refl->GetEnum(f));
|
||||
break;
|
||||
|
||||
case ::google::protobuf::FieldDescriptor::TYPE_STRING:
|
||||
case ::google::protobuf::FieldDescriptor::TYPE_BYTES:
|
||||
refl->SetString(f, refl->GetString(f));
|
||||
break;
|
||||
|
||||
case ::google::protobuf::FieldDescriptor::TYPE_MESSAGE:
|
||||
case ::google::protobuf::FieldDescriptor::TYPE_GROUP:
|
||||
ForceSetSingularDefault(refl->MutableMessage(f)); // recursion!
|
||||
break;
|
||||
|
||||
default:
|
||||
qDebug("unhandled Field Type");
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
bool update(
|
||||
::google::protobuf::Message *target,
|
||||
::google::protobuf::Message *source)
|
||||
{
|
||||
// FIXME(HI): Depracate: use MergeFrom() directly
|
||||
qDebug("In %s", __FUNCTION__);
|
||||
target->MergeFrom(*source);
|
||||
return true;
|
||||
#if 0
|
||||
::google::protobuf::Message::Reflection *sourceRef;
|
||||
::google::protobuf::Message::Reflection *targetRef;
|
||||
std::vector<const ::google::protobuf::FieldDescriptor*> srcFieldList;
|
||||
|
||||
|
||||
if (source->GetDescriptor()->full_name() !=
|
||||
target->GetDescriptor()->full_name())
|
||||
goto _error_exit;
|
||||
|
||||
sourceRef = source->GetReflection();
|
||||
targetRef = target->GetReflection();
|
||||
|
||||
sourceRef->ListFields(&srcFieldList);
|
||||
for (uint i=0; i < srcFieldList.size(); i++)
|
||||
{
|
||||
const ::google::protobuf::FieldDescriptor *srcField, *targetField;
|
||||
|
||||
srcField = srcFieldList[i];
|
||||
targetField = target->GetDescriptor()->FindFieldByName(
|
||||
srcField->name());
|
||||
|
||||
switch(targetField->type())
|
||||
{
|
||||
case ::google::protobuf::FieldDescriptor::TYPE_UINT32:
|
||||
targetRef->SetUInt32(targetField,
|
||||
sourceRef->GetUInt32(srcField));
|
||||
break;
|
||||
case ::google::protobuf::FieldDescriptor::TYPE_BOOL:
|
||||
targetRef->SetBool(targetField,
|
||||
sourceRef->GetBool(srcField));
|
||||
break;
|
||||
case ::google::protobuf::FieldDescriptor::TYPE_STRING:
|
||||
targetRef->SetString(targetField,
|
||||
sourceRef->GetString(srcField));
|
||||
break;
|
||||
default:
|
||||
qDebug("unhandled Field Type");
|
||||
break;
|
||||
}
|
||||
}
|
||||
_error_exit:
|
||||
qDebug("%s: error!", __FUNCTION__);
|
||||
return false;
|
||||
#endif
|
||||
}
|
||||
};
|
||||
#endif
|
||||
#endif
|
||||
#ifndef _PB_HELPER_H
|
||||
#define _PB_HELPER_H
|
||||
|
||||
#include <google/protobuf/message.h>
|
||||
#include <google/protobuf/descriptor.h>
|
||||
|
||||
#include <qdebug.h>
|
||||
|
||||
#if 0 // not reqd. any longer?
|
||||
class PbHelper
|
||||
{
|
||||
public:
|
||||
|
||||
// FIXME: Change msg from * to &
|
||||
void ForceSetSingularDefault(::google::protobuf::Message *msg)
|
||||
{
|
||||
const ::google::protobuf::Descriptor *desc;
|
||||
::google::protobuf::Message::Reflection *refl;
|
||||
|
||||
qDebug("In %s", __FUNCTION__);
|
||||
|
||||
desc = msg->GetDescriptor();
|
||||
refl = msg->GetReflection();
|
||||
|
||||
for (int i=0; i < desc->field_count(); i++)
|
||||
{
|
||||
const ::google::protobuf::FieldDescriptor *f;
|
||||
|
||||
f = desc->field(i);
|
||||
|
||||
// Ensure field is singular and not already set
|
||||
if (f->label() ==
|
||||
::google::protobuf::FieldDescriptor::LABEL_REPEATED)
|
||||
continue;
|
||||
if (refl->HasField(f))
|
||||
continue;
|
||||
|
||||
switch(f->type())
|
||||
{
|
||||
case ::google::protobuf::FieldDescriptor::TYPE_DOUBLE:
|
||||
refl->SetDouble(f, refl->GetDouble(f));
|
||||
break;
|
||||
|
||||
case ::google::protobuf::FieldDescriptor::TYPE_FLOAT:
|
||||
refl->SetFloat(f, refl->GetFloat(f));
|
||||
break;
|
||||
|
||||
case ::google::protobuf::FieldDescriptor::TYPE_INT32:
|
||||
case ::google::protobuf::FieldDescriptor::TYPE_SINT32:
|
||||
case ::google::protobuf::FieldDescriptor::TYPE_SFIXED32:
|
||||
refl->SetInt32(f, refl->GetInt32(f));
|
||||
break;
|
||||
|
||||
case ::google::protobuf::FieldDescriptor::TYPE_INT64:
|
||||
case ::google::protobuf::FieldDescriptor::TYPE_SINT64:
|
||||
case ::google::protobuf::FieldDescriptor::TYPE_SFIXED64:
|
||||
refl->SetInt64(f, refl->GetInt64(f));
|
||||
break;
|
||||
|
||||
case ::google::protobuf::FieldDescriptor::TYPE_UINT32:
|
||||
case ::google::protobuf::FieldDescriptor::TYPE_FIXED32:
|
||||
refl->SetUInt32(f, refl->GetUInt32(f));
|
||||
break;
|
||||
|
||||
case ::google::protobuf::FieldDescriptor::TYPE_UINT64:
|
||||
case ::google::protobuf::FieldDescriptor::TYPE_FIXED64:
|
||||
refl->SetUInt64(f, refl->GetUInt64(f));
|
||||
break;
|
||||
|
||||
case ::google::protobuf::FieldDescriptor::TYPE_BOOL:
|
||||
refl->SetBool(f, refl->GetBool(f));
|
||||
break;
|
||||
|
||||
case ::google::protobuf::FieldDescriptor::TYPE_ENUM:
|
||||
refl->SetEnum(f, refl->GetEnum(f));
|
||||
break;
|
||||
|
||||
case ::google::protobuf::FieldDescriptor::TYPE_STRING:
|
||||
case ::google::protobuf::FieldDescriptor::TYPE_BYTES:
|
||||
refl->SetString(f, refl->GetString(f));
|
||||
break;
|
||||
|
||||
case ::google::protobuf::FieldDescriptor::TYPE_MESSAGE:
|
||||
case ::google::protobuf::FieldDescriptor::TYPE_GROUP:
|
||||
ForceSetSingularDefault(refl->MutableMessage(f)); // recursion!
|
||||
break;
|
||||
|
||||
default:
|
||||
qDebug("unhandled Field Type");
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
bool update(
|
||||
::google::protobuf::Message *target,
|
||||
::google::protobuf::Message *source)
|
||||
{
|
||||
// FIXME(HI): Depracate: use MergeFrom() directly
|
||||
qDebug("In %s", __FUNCTION__);
|
||||
target->MergeFrom(*source);
|
||||
return true;
|
||||
#if 0
|
||||
::google::protobuf::Message::Reflection *sourceRef;
|
||||
::google::protobuf::Message::Reflection *targetRef;
|
||||
std::vector<const ::google::protobuf::FieldDescriptor*> srcFieldList;
|
||||
|
||||
|
||||
if (source->GetDescriptor()->full_name() !=
|
||||
target->GetDescriptor()->full_name())
|
||||
goto _error_exit;
|
||||
|
||||
sourceRef = source->GetReflection();
|
||||
targetRef = target->GetReflection();
|
||||
|
||||
sourceRef->ListFields(&srcFieldList);
|
||||
for (uint i=0; i < srcFieldList.size(); i++)
|
||||
{
|
||||
const ::google::protobuf::FieldDescriptor *srcField, *targetField;
|
||||
|
||||
srcField = srcFieldList[i];
|
||||
targetField = target->GetDescriptor()->FindFieldByName(
|
||||
srcField->name());
|
||||
|
||||
switch(targetField->type())
|
||||
{
|
||||
case ::google::protobuf::FieldDescriptor::TYPE_UINT32:
|
||||
targetRef->SetUInt32(targetField,
|
||||
sourceRef->GetUInt32(srcField));
|
||||
break;
|
||||
case ::google::protobuf::FieldDescriptor::TYPE_BOOL:
|
||||
targetRef->SetBool(targetField,
|
||||
sourceRef->GetBool(srcField));
|
||||
break;
|
||||
case ::google::protobuf::FieldDescriptor::TYPE_STRING:
|
||||
targetRef->SetString(targetField,
|
||||
sourceRef->GetString(srcField));
|
||||
break;
|
||||
default:
|
||||
qDebug("unhandled Field Type");
|
||||
break;
|
||||
}
|
||||
}
|
||||
_error_exit:
|
||||
qDebug("%s: error!", __FUNCTION__);
|
||||
return false;
|
||||
#endif
|
||||
}
|
||||
};
|
||||
#endif
|
||||
#endif
|
||||
|
@ -1,8 +1,8 @@
|
||||
TEMPLATE = lib
|
||||
CONFIG += qt staticlib
|
||||
QT += network
|
||||
DEFINES += HAVE_REMOTE
|
||||
INCLUDEPATH += "c:\msys\1.0\local\include"
|
||||
LIBS += -L"C:\msys\1.0\local\lib" -lprotobuf
|
||||
HEADERS += rpcserver.h pbrpccontroller.h pbrpcchannel.h
|
||||
SOURCES += rpcserver.cpp pbrpcchannel.cpp
|
||||
TEMPLATE = lib
|
||||
CONFIG += qt staticlib
|
||||
QT += network
|
||||
DEFINES += HAVE_REMOTE
|
||||
INCLUDEPATH += "c:\msys\1.0\local\include"
|
||||
LIBS += -L"C:\msys\1.0\local\lib" -lprotobuf
|
||||
HEADERS += rpcserver.h pbrpccontroller.h pbrpcchannel.h
|
||||
SOURCES += rpcserver.cpp pbrpcchannel.cpp
|
||||
|
@ -1,310 +1,310 @@
|
||||
#include "pbrpcchannel.h"
|
||||
|
||||
PbRpcChannel::PbRpcChannel(QHostAddress ip, quint16 port)
|
||||
{
|
||||
isPending = false;
|
||||
pendingMethodId = -1; // don't care as long as isPending is false
|
||||
|
||||
controller = NULL;
|
||||
done = NULL;
|
||||
response = NULL;
|
||||
|
||||
mServerAddress = ip;
|
||||
mServerPort = port;
|
||||
mpSocket = new QTcpSocket(this);
|
||||
|
||||
// FIXME: Not quite sure why this ain't working!
|
||||
// QMetaObject::connectSlotsByName(this);
|
||||
|
||||
connect(mpSocket, SIGNAL(connected()),
|
||||
this, SLOT(on_mpSocket_connected()));
|
||||
connect(mpSocket, SIGNAL(disconnected()),
|
||||
this, SLOT(on_mpSocket_disconnected()));
|
||||
connect(mpSocket, SIGNAL(stateChanged(QAbstractSocket::SocketState)),
|
||||
this, SLOT(on_mpSocket_stateChanged(QAbstractSocket::SocketState)));
|
||||
connect(mpSocket, SIGNAL(error(QAbstractSocket::SocketError)),
|
||||
this, SLOT(on_mpSocket_error(QAbstractSocket::SocketError)));
|
||||
|
||||
connect(mpSocket, SIGNAL(readyRead()),
|
||||
this, SLOT(on_mpSocket_readyRead()));
|
||||
|
||||
}
|
||||
|
||||
PbRpcChannel::~PbRpcChannel()
|
||||
{
|
||||
delete mpSocket;
|
||||
}
|
||||
|
||||
void PbRpcChannel::establish()
|
||||
{
|
||||
qDebug("In %s", __FUNCTION__);
|
||||
|
||||
mpSocket->connectToHost(mServerAddress, mServerPort);
|
||||
}
|
||||
|
||||
void PbRpcChannel::establish(QHostAddress ip, quint16 port)
|
||||
{
|
||||
mServerAddress = ip;
|
||||
mServerPort = port;
|
||||
establish();
|
||||
}
|
||||
|
||||
void PbRpcChannel::tearDown()
|
||||
{
|
||||
qDebug("In %s", __FUNCTION__);
|
||||
|
||||
mpSocket->disconnectFromHost();
|
||||
}
|
||||
|
||||
void PbRpcChannel::CallMethod(
|
||||
const ::google::protobuf::MethodDescriptor *method,
|
||||
::google::protobuf::RpcController *controller,
|
||||
const ::google::protobuf::Message *req,
|
||||
::google::protobuf::Message *response,
|
||||
::google::protobuf::Closure* done)
|
||||
{
|
||||
char msg[MSGBUF_SIZE];
|
||||
int len;
|
||||
bool ret;
|
||||
|
||||
if (isPending)
|
||||
{
|
||||
RpcCall call;
|
||||
qDebug("RpcChannel: queueing method %d since %d is pending",
|
||||
method->index(), pendingMethodId);
|
||||
|
||||
call.method = method;
|
||||
call.controller = controller;
|
||||
call.request = req;
|
||||
call.response = response;
|
||||
call.done = done;
|
||||
|
||||
pendingCallList.append(call);
|
||||
|
||||
Q_ASSERT(pendingCallList.size() < 100);
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
if (!req->IsInitialized())
|
||||
{
|
||||
qWarning("RpcChannel: missing required fields in request");
|
||||
qDebug(req->InitializationErrorString().c_str());
|
||||
|
||||
qFatal("exiting");
|
||||
|
||||
controller->SetFailed("Required fields missing");
|
||||
done->Run();
|
||||
return;
|
||||
}
|
||||
|
||||
pendingMethodId = method->index();
|
||||
this->controller=controller;
|
||||
this->done=done;
|
||||
this->response=response;
|
||||
isPending = true;
|
||||
|
||||
ret = req->SerializeToArray((void*) (&msg[PB_HDR_SIZE]), sizeof(msg));
|
||||
Q_ASSERT(ret == true);
|
||||
|
||||
len = req->ByteSize();
|
||||
*((quint16*)(&msg[0])) = HTONS(PB_MSG_TYPE_REQUEST); // type
|
||||
*((quint16*)(&msg[2])) = HTONS(method->index()); // method id
|
||||
*((quint32*)(&msg[4])) = HTONL(len); // len
|
||||
|
||||
// Avoid printing stats since it happens every couple of seconds
|
||||
if (pendingMethodId != 12)
|
||||
{
|
||||
qDebug("client(%s) sending %d bytes encoding <%s>", __FUNCTION__,
|
||||
PB_HDR_SIZE + len, req->DebugString().c_str());
|
||||
BUFDUMP(msg, PB_HDR_SIZE + len);
|
||||
}
|
||||
|
||||
mpSocket->write(msg, PB_HDR_SIZE + len);
|
||||
}
|
||||
|
||||
void PbRpcChannel::on_mpSocket_readyRead()
|
||||
{
|
||||
char msg[MSGBUF_SIZE];
|
||||
char *p = (char*)&msg;
|
||||
int msgLen;
|
||||
static bool parsing = false;
|
||||
static quint16 type, method;
|
||||
static quint32 len;
|
||||
|
||||
//qDebug("%s: bytesAvail = %d", __FUNCTION__, mpSocket->bytesAvailable());
|
||||
|
||||
if (!parsing)
|
||||
{
|
||||
// Do we have an entire header? If not, we'll wait ...
|
||||
if (mpSocket->bytesAvailable() < PB_HDR_SIZE)
|
||||
{
|
||||
qDebug("client: not enough data available for a complete header");
|
||||
return;
|
||||
}
|
||||
|
||||
msgLen = mpSocket->read(msg, PB_HDR_SIZE);
|
||||
|
||||
Q_ASSERT(msgLen == PB_HDR_SIZE);
|
||||
|
||||
type = NTOHS(GET16(p+0));
|
||||
method = NTOHS(GET16(p+2));
|
||||
len = NTOHL(GET32(p+4));
|
||||
|
||||
//BUFDUMP(msg, PB_HDR_SIZE);
|
||||
//qDebug("type = %hu, method = %hu, len = %u", type, method, len);
|
||||
|
||||
parsing = true;
|
||||
}
|
||||
|
||||
switch (type)
|
||||
{
|
||||
case PB_MSG_TYPE_BINBLOB:
|
||||
{
|
||||
static quint32 cumLen = 0;
|
||||
QIODevice *blob;
|
||||
|
||||
blob = static_cast<PbRpcController*>(controller)->binaryBlob();
|
||||
Q_ASSERT(blob != NULL);
|
||||
|
||||
while ((cumLen < len) && mpSocket->bytesAvailable())
|
||||
{
|
||||
int l;
|
||||
|
||||
l = mpSocket->read(msg, sizeof(msg));
|
||||
blob->write(msg, l);
|
||||
cumLen += l;
|
||||
}
|
||||
|
||||
qDebug("%s: bin blob rcvd %d/%d", __PRETTY_FUNCTION__, cumLen, len);
|
||||
|
||||
if (cumLen < len)
|
||||
return;
|
||||
|
||||
cumLen = 0;
|
||||
|
||||
if (!isPending)
|
||||
{
|
||||
qDebug("not waiting for response");
|
||||
goto _error_exit;
|
||||
}
|
||||
|
||||
if (pendingMethodId != method)
|
||||
{
|
||||
qDebug("invalid method id %d (expected = %d)", method,
|
||||
pendingMethodId);
|
||||
goto _error_exit;
|
||||
}
|
||||
|
||||
break;
|
||||
}
|
||||
|
||||
case PB_MSG_TYPE_RESPONSE:
|
||||
// Wait till we have the entire message
|
||||
if (mpSocket->bytesAvailable() < len)
|
||||
{
|
||||
qDebug("client: not enough data available for a complete msg");
|
||||
return;
|
||||
}
|
||||
|
||||
msgLen = mpSocket->read(msg, sizeof(msg));
|
||||
|
||||
Q_ASSERT((unsigned) msgLen == len);
|
||||
|
||||
//qDebug("client(%s) rcvd %d bytes", __FUNCTION__, msgLen);
|
||||
//BUFDUMP(msg, msgLen);
|
||||
|
||||
if (!isPending)
|
||||
{
|
||||
qDebug("not waiting for response");
|
||||
goto _error_exit;
|
||||
}
|
||||
|
||||
if (pendingMethodId != method)
|
||||
{
|
||||
qDebug("invalid method id %d (expected = %d)", method,
|
||||
pendingMethodId);
|
||||
goto _error_exit;
|
||||
}
|
||||
|
||||
response->ParseFromArray((void*) msg, len);
|
||||
|
||||
// Avoid printing stats
|
||||
if (method != 12)
|
||||
{
|
||||
qDebug("client(%s): Parsed as %s", __FUNCTION__,
|
||||
response->DebugString().c_str());
|
||||
}
|
||||
|
||||
if (!response->IsInitialized())
|
||||
{
|
||||
qWarning("RpcChannel: missing required fields in response");
|
||||
qDebug(response->InitializationErrorString().c_str());
|
||||
|
||||
controller->SetFailed("Required fields missing");
|
||||
}
|
||||
break;
|
||||
|
||||
default:
|
||||
qFatal("%s: unexpected type %d", __PRETTY_FUNCTION__, type);
|
||||
goto _error_exit;
|
||||
|
||||
}
|
||||
|
||||
pendingMethodId = -1;
|
||||
controller = NULL;
|
||||
response = NULL;
|
||||
isPending = false;
|
||||
parsing = false;
|
||||
|
||||
done->Run();
|
||||
|
||||
if (pendingCallList.size())
|
||||
{
|
||||
RpcCall call = pendingCallList.takeFirst();
|
||||
CallMethod(call.method, call.controller, call.request, call.response,
|
||||
call.done);
|
||||
}
|
||||
|
||||
return;
|
||||
|
||||
_error_exit:
|
||||
parsing = false;
|
||||
qDebug("client(%s) discarding received msg", __FUNCTION__);
|
||||
return;
|
||||
}
|
||||
|
||||
void PbRpcChannel::on_mpSocket_stateChanged(
|
||||
QAbstractSocket::SocketState socketState)
|
||||
{
|
||||
qDebug("In %s", __FUNCTION__);
|
||||
emit stateChanged(socketState);
|
||||
}
|
||||
|
||||
void PbRpcChannel::on_mpSocket_connected()
|
||||
{
|
||||
qDebug("In %s", __FUNCTION__);
|
||||
emit connected();
|
||||
}
|
||||
|
||||
void PbRpcChannel::on_mpSocket_disconnected()
|
||||
{
|
||||
qDebug("In %s", __FUNCTION__);
|
||||
|
||||
pendingMethodId = -1;
|
||||
controller = NULL;
|
||||
response = NULL;
|
||||
isPending = false;
|
||||
// \todo convert parsing from static to data member
|
||||
//parsing = false
|
||||
pendingCallList.clear();
|
||||
|
||||
emit disconnected();
|
||||
}
|
||||
|
||||
void PbRpcChannel::on_mpSocket_error(QAbstractSocket::SocketError socketError)
|
||||
{
|
||||
qDebug("In %s", __FUNCTION__);
|
||||
emit error(socketError);
|
||||
}
|
||||
|
||||
#include "pbrpcchannel.h"
|
||||
|
||||
PbRpcChannel::PbRpcChannel(QHostAddress ip, quint16 port)
|
||||
{
|
||||
isPending = false;
|
||||
pendingMethodId = -1; // don't care as long as isPending is false
|
||||
|
||||
controller = NULL;
|
||||
done = NULL;
|
||||
response = NULL;
|
||||
|
||||
mServerAddress = ip;
|
||||
mServerPort = port;
|
||||
mpSocket = new QTcpSocket(this);
|
||||
|
||||
// FIXME: Not quite sure why this ain't working!
|
||||
// QMetaObject::connectSlotsByName(this);
|
||||
|
||||
connect(mpSocket, SIGNAL(connected()),
|
||||
this, SLOT(on_mpSocket_connected()));
|
||||
connect(mpSocket, SIGNAL(disconnected()),
|
||||
this, SLOT(on_mpSocket_disconnected()));
|
||||
connect(mpSocket, SIGNAL(stateChanged(QAbstractSocket::SocketState)),
|
||||
this, SLOT(on_mpSocket_stateChanged(QAbstractSocket::SocketState)));
|
||||
connect(mpSocket, SIGNAL(error(QAbstractSocket::SocketError)),
|
||||
this, SLOT(on_mpSocket_error(QAbstractSocket::SocketError)));
|
||||
|
||||
connect(mpSocket, SIGNAL(readyRead()),
|
||||
this, SLOT(on_mpSocket_readyRead()));
|
||||
|
||||
}
|
||||
|
||||
PbRpcChannel::~PbRpcChannel()
|
||||
{
|
||||
delete mpSocket;
|
||||
}
|
||||
|
||||
void PbRpcChannel::establish()
|
||||
{
|
||||
qDebug("In %s", __FUNCTION__);
|
||||
|
||||
mpSocket->connectToHost(mServerAddress, mServerPort);
|
||||
}
|
||||
|
||||
void PbRpcChannel::establish(QHostAddress ip, quint16 port)
|
||||
{
|
||||
mServerAddress = ip;
|
||||
mServerPort = port;
|
||||
establish();
|
||||
}
|
||||
|
||||
void PbRpcChannel::tearDown()
|
||||
{
|
||||
qDebug("In %s", __FUNCTION__);
|
||||
|
||||
mpSocket->disconnectFromHost();
|
||||
}
|
||||
|
||||
void PbRpcChannel::CallMethod(
|
||||
const ::google::protobuf::MethodDescriptor *method,
|
||||
::google::protobuf::RpcController *controller,
|
||||
const ::google::protobuf::Message *req,
|
||||
::google::protobuf::Message *response,
|
||||
::google::protobuf::Closure* done)
|
||||
{
|
||||
char msg[MSGBUF_SIZE];
|
||||
int len;
|
||||
bool ret;
|
||||
|
||||
if (isPending)
|
||||
{
|
||||
RpcCall call;
|
||||
qDebug("RpcChannel: queueing method %d since %d is pending",
|
||||
method->index(), pendingMethodId);
|
||||
|
||||
call.method = method;
|
||||
call.controller = controller;
|
||||
call.request = req;
|
||||
call.response = response;
|
||||
call.done = done;
|
||||
|
||||
pendingCallList.append(call);
|
||||
|
||||
Q_ASSERT(pendingCallList.size() < 100);
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
if (!req->IsInitialized())
|
||||
{
|
||||
qWarning("RpcChannel: missing required fields in request");
|
||||
qDebug(req->InitializationErrorString().c_str());
|
||||
|
||||
qFatal("exiting");
|
||||
|
||||
controller->SetFailed("Required fields missing");
|
||||
done->Run();
|
||||
return;
|
||||
}
|
||||
|
||||
pendingMethodId = method->index();
|
||||
this->controller=controller;
|
||||
this->done=done;
|
||||
this->response=response;
|
||||
isPending = true;
|
||||
|
||||
ret = req->SerializeToArray((void*) (&msg[PB_HDR_SIZE]), sizeof(msg));
|
||||
Q_ASSERT(ret == true);
|
||||
|
||||
len = req->ByteSize();
|
||||
*((quint16*)(&msg[0])) = HTONS(PB_MSG_TYPE_REQUEST); // type
|
||||
*((quint16*)(&msg[2])) = HTONS(method->index()); // method id
|
||||
*((quint32*)(&msg[4])) = HTONL(len); // len
|
||||
|
||||
// Avoid printing stats since it happens every couple of seconds
|
||||
if (pendingMethodId != 12)
|
||||
{
|
||||
qDebug("client(%s) sending %d bytes encoding <%s>", __FUNCTION__,
|
||||
PB_HDR_SIZE + len, req->DebugString().c_str());
|
||||
BUFDUMP(msg, PB_HDR_SIZE + len);
|
||||
}
|
||||
|
||||
mpSocket->write(msg, PB_HDR_SIZE + len);
|
||||
}
|
||||
|
||||
void PbRpcChannel::on_mpSocket_readyRead()
|
||||
{
|
||||
char msg[MSGBUF_SIZE];
|
||||
char *p = (char*)&msg;
|
||||
int msgLen;
|
||||
static bool parsing = false;
|
||||
static quint16 type, method;
|
||||
static quint32 len;
|
||||
|
||||
//qDebug("%s: bytesAvail = %d", __FUNCTION__, mpSocket->bytesAvailable());
|
||||
|
||||
if (!parsing)
|
||||
{
|
||||
// Do we have an entire header? If not, we'll wait ...
|
||||
if (mpSocket->bytesAvailable() < PB_HDR_SIZE)
|
||||
{
|
||||
qDebug("client: not enough data available for a complete header");
|
||||
return;
|
||||
}
|
||||
|
||||
msgLen = mpSocket->read(msg, PB_HDR_SIZE);
|
||||
|
||||
Q_ASSERT(msgLen == PB_HDR_SIZE);
|
||||
|
||||
type = NTOHS(GET16(p+0));
|
||||
method = NTOHS(GET16(p+2));
|
||||
len = NTOHL(GET32(p+4));
|
||||
|
||||
//BUFDUMP(msg, PB_HDR_SIZE);
|
||||
//qDebug("type = %hu, method = %hu, len = %u", type, method, len);
|
||||
|
||||
parsing = true;
|
||||
}
|
||||
|
||||
switch (type)
|
||||
{
|
||||
case PB_MSG_TYPE_BINBLOB:
|
||||
{
|
||||
static quint32 cumLen = 0;
|
||||
QIODevice *blob;
|
||||
|
||||
blob = static_cast<PbRpcController*>(controller)->binaryBlob();
|
||||
Q_ASSERT(blob != NULL);
|
||||
|
||||
while ((cumLen < len) && mpSocket->bytesAvailable())
|
||||
{
|
||||
int l;
|
||||
|
||||
l = mpSocket->read(msg, sizeof(msg));
|
||||
blob->write(msg, l);
|
||||
cumLen += l;
|
||||
}
|
||||
|
||||
qDebug("%s: bin blob rcvd %d/%d", __PRETTY_FUNCTION__, cumLen, len);
|
||||
|
||||
if (cumLen < len)
|
||||
return;
|
||||
|
||||
cumLen = 0;
|
||||
|
||||
if (!isPending)
|
||||
{
|
||||
qDebug("not waiting for response");
|
||||
goto _error_exit;
|
||||
}
|
||||
|
||||
if (pendingMethodId != method)
|
||||
{
|
||||
qDebug("invalid method id %d (expected = %d)", method,
|
||||
pendingMethodId);
|
||||
goto _error_exit;
|
||||
}
|
||||
|
||||
break;
|
||||
}
|
||||
|
||||
case PB_MSG_TYPE_RESPONSE:
|
||||
// Wait till we have the entire message
|
||||
if (mpSocket->bytesAvailable() < len)
|
||||
{
|
||||
qDebug("client: not enough data available for a complete msg");
|
||||
return;
|
||||
}
|
||||
|
||||
msgLen = mpSocket->read(msg, sizeof(msg));
|
||||
|
||||
Q_ASSERT((unsigned) msgLen == len);
|
||||
|
||||
//qDebug("client(%s) rcvd %d bytes", __FUNCTION__, msgLen);
|
||||
//BUFDUMP(msg, msgLen);
|
||||
|
||||
if (!isPending)
|
||||
{
|
||||
qDebug("not waiting for response");
|
||||
goto _error_exit;
|
||||
}
|
||||
|
||||
if (pendingMethodId != method)
|
||||
{
|
||||
qDebug("invalid method id %d (expected = %d)", method,
|
||||
pendingMethodId);
|
||||
goto _error_exit;
|
||||
}
|
||||
|
||||
response->ParseFromArray((void*) msg, len);
|
||||
|
||||
// Avoid printing stats
|
||||
if (method != 12)
|
||||
{
|
||||
qDebug("client(%s): Parsed as %s", __FUNCTION__,
|
||||
response->DebugString().c_str());
|
||||
}
|
||||
|
||||
if (!response->IsInitialized())
|
||||
{
|
||||
qWarning("RpcChannel: missing required fields in response");
|
||||
qDebug(response->InitializationErrorString().c_str());
|
||||
|
||||
controller->SetFailed("Required fields missing");
|
||||
}
|
||||
break;
|
||||
|
||||
default:
|
||||
qFatal("%s: unexpected type %d", __PRETTY_FUNCTION__, type);
|
||||
goto _error_exit;
|
||||
|
||||
}
|
||||
|
||||
pendingMethodId = -1;
|
||||
controller = NULL;
|
||||
response = NULL;
|
||||
isPending = false;
|
||||
parsing = false;
|
||||
|
||||
done->Run();
|
||||
|
||||
if (pendingCallList.size())
|
||||
{
|
||||
RpcCall call = pendingCallList.takeFirst();
|
||||
CallMethod(call.method, call.controller, call.request, call.response,
|
||||
call.done);
|
||||
}
|
||||
|
||||
return;
|
||||
|
||||
_error_exit:
|
||||
parsing = false;
|
||||
qDebug("client(%s) discarding received msg", __FUNCTION__);
|
||||
return;
|
||||
}
|
||||
|
||||
void PbRpcChannel::on_mpSocket_stateChanged(
|
||||
QAbstractSocket::SocketState socketState)
|
||||
{
|
||||
qDebug("In %s", __FUNCTION__);
|
||||
emit stateChanged(socketState);
|
||||
}
|
||||
|
||||
void PbRpcChannel::on_mpSocket_connected()
|
||||
{
|
||||
qDebug("In %s", __FUNCTION__);
|
||||
emit connected();
|
||||
}
|
||||
|
||||
void PbRpcChannel::on_mpSocket_disconnected()
|
||||
{
|
||||
qDebug("In %s", __FUNCTION__);
|
||||
|
||||
pendingMethodId = -1;
|
||||
controller = NULL;
|
||||
response = NULL;
|
||||
isPending = false;
|
||||
// \todo convert parsing from static to data member
|
||||
//parsing = false
|
||||
pendingCallList.clear();
|
||||
|
||||
emit disconnected();
|
||||
}
|
||||
|
||||
void PbRpcChannel::on_mpSocket_error(QAbstractSocket::SocketError socketError)
|
||||
{
|
||||
qDebug("In %s", __FUNCTION__);
|
||||
emit error(socketError);
|
||||
}
|
||||
|
||||
|
@ -1,83 +1,83 @@
|
||||
#ifndef _PB_RPC_CHANNEL_H
|
||||
#define _PB_RPC_CHANNEL_H
|
||||
|
||||
#include <QTcpServer>
|
||||
#include <QTcpSocket>
|
||||
|
||||
#include <google/protobuf/message.h>
|
||||
#include <google/protobuf/descriptor.h>
|
||||
#include <google/protobuf/service.h>
|
||||
|
||||
#include "pbrpccommon.h"
|
||||
#include "pbrpccontroller.h"
|
||||
|
||||
class PbRpcChannel : public QObject, public ::google::protobuf::RpcChannel
|
||||
{
|
||||
Q_OBJECT
|
||||
|
||||
// If isPending is TRUE, then controller, done, response
|
||||
// and pendingMethodId correspond to the last method called by
|
||||
// the service stub
|
||||
bool isPending;
|
||||
int pendingMethodId;
|
||||
|
||||
// controller, done, response are set to the corresponding values
|
||||
// passed by the stub to CallMethod(). They are reset to NULL when
|
||||
// we get a response back from the server in on_mpSocket_readyRead()
|
||||
// after calling done->Run().
|
||||
|
||||
/*! \todo (MED) : change controller, done and response to references
|
||||
instead of pointers? */
|
||||
::google::protobuf::RpcController *controller;
|
||||
::google::protobuf::Closure *done;
|
||||
::google::protobuf::Message *response;
|
||||
|
||||
typedef struct _RpcCall {
|
||||
const ::google::protobuf::MethodDescriptor *method;
|
||||
::google::protobuf::RpcController *controller;
|
||||
const ::google::protobuf::Message *request;
|
||||
::google::protobuf::Message *response;
|
||||
::google::protobuf::Closure *done;
|
||||
} RpcCall;
|
||||
QList<RpcCall> pendingCallList;
|
||||
|
||||
QHostAddress mServerAddress;
|
||||
quint16 mServerPort;
|
||||
QTcpSocket *mpSocket;
|
||||
|
||||
public:
|
||||
PbRpcChannel(QHostAddress ip, quint16 port);
|
||||
~PbRpcChannel();
|
||||
|
||||
void establish();
|
||||
void establish(QHostAddress ip, quint16 port);
|
||||
void tearDown();
|
||||
|
||||
const QHostAddress& serverAddress() const { return mServerAddress; }
|
||||
quint16 serverPort() const { return mServerPort; }
|
||||
|
||||
QAbstractSocket::SocketState state() const
|
||||
{ return mpSocket->state(); }
|
||||
|
||||
void CallMethod(const ::google::protobuf::MethodDescriptor *method,
|
||||
::google::protobuf::RpcController *controller,
|
||||
const ::google::protobuf::Message *req,
|
||||
::google::protobuf::Message *response,
|
||||
::google::protobuf::Closure* done);
|
||||
|
||||
signals:
|
||||
void connected();
|
||||
void disconnected();
|
||||
void error(QAbstractSocket::SocketError socketError);
|
||||
void stateChanged(QAbstractSocket::SocketState socketState);
|
||||
|
||||
private slots:
|
||||
void on_mpSocket_connected();
|
||||
void on_mpSocket_disconnected();
|
||||
void on_mpSocket_stateChanged(QAbstractSocket::SocketState socketState);
|
||||
void on_mpSocket_error(QAbstractSocket::SocketError socketError);
|
||||
|
||||
void on_mpSocket_readyRead();
|
||||
};
|
||||
|
||||
#endif
|
||||
#ifndef _PB_RPC_CHANNEL_H
|
||||
#define _PB_RPC_CHANNEL_H
|
||||
|
||||
#include <QTcpServer>
|
||||
#include <QTcpSocket>
|
||||
|
||||
#include <google/protobuf/message.h>
|
||||
#include <google/protobuf/descriptor.h>
|
||||
#include <google/protobuf/service.h>
|
||||
|
||||
#include "pbrpccommon.h"
|
||||
#include "pbrpccontroller.h"
|
||||
|
||||
class PbRpcChannel : public QObject, public ::google::protobuf::RpcChannel
|
||||
{
|
||||
Q_OBJECT
|
||||
|
||||
// If isPending is TRUE, then controller, done, response
|
||||
// and pendingMethodId correspond to the last method called by
|
||||
// the service stub
|
||||
bool isPending;
|
||||
int pendingMethodId;
|
||||
|
||||
// controller, done, response are set to the corresponding values
|
||||
// passed by the stub to CallMethod(). They are reset to NULL when
|
||||
// we get a response back from the server in on_mpSocket_readyRead()
|
||||
// after calling done->Run().
|
||||
|
||||
/*! \todo (MED) : change controller, done and response to references
|
||||
instead of pointers? */
|
||||
::google::protobuf::RpcController *controller;
|
||||
::google::protobuf::Closure *done;
|
||||
::google::protobuf::Message *response;
|
||||
|
||||
typedef struct _RpcCall {
|
||||
const ::google::protobuf::MethodDescriptor *method;
|
||||
::google::protobuf::RpcController *controller;
|
||||
const ::google::protobuf::Message *request;
|
||||
::google::protobuf::Message *response;
|
||||
::google::protobuf::Closure *done;
|
||||
} RpcCall;
|
||||
QList<RpcCall> pendingCallList;
|
||||
|
||||
QHostAddress mServerAddress;
|
||||
quint16 mServerPort;
|
||||
QTcpSocket *mpSocket;
|
||||
|
||||
public:
|
||||
PbRpcChannel(QHostAddress ip, quint16 port);
|
||||
~PbRpcChannel();
|
||||
|
||||
void establish();
|
||||
void establish(QHostAddress ip, quint16 port);
|
||||
void tearDown();
|
||||
|
||||
const QHostAddress& serverAddress() const { return mServerAddress; }
|
||||
quint16 serverPort() const { return mServerPort; }
|
||||
|
||||
QAbstractSocket::SocketState state() const
|
||||
{ return mpSocket->state(); }
|
||||
|
||||
void CallMethod(const ::google::protobuf::MethodDescriptor *method,
|
||||
::google::protobuf::RpcController *controller,
|
||||
const ::google::protobuf::Message *req,
|
||||
::google::protobuf::Message *response,
|
||||
::google::protobuf::Closure* done);
|
||||
|
||||
signals:
|
||||
void connected();
|
||||
void disconnected();
|
||||
void error(QAbstractSocket::SocketError socketError);
|
||||
void stateChanged(QAbstractSocket::SocketState socketState);
|
||||
|
||||
private slots:
|
||||
void on_mpSocket_connected();
|
||||
void on_mpSocket_disconnected();
|
||||
void on_mpSocket_stateChanged(QAbstractSocket::SocketState socketState);
|
||||
void on_mpSocket_error(QAbstractSocket::SocketError socketError);
|
||||
|
||||
void on_mpSocket_readyRead();
|
||||
};
|
||||
|
||||
#endif
|
||||
|
@ -1,61 +1,61 @@
|
||||
#ifndef _PB_RPC_COMMON_H
|
||||
#define _PB_RPC_COMMON_H
|
||||
|
||||
//! \todo (LOW) check which one is right - wrong one seems to be working!!!!!
|
||||
#if 0
|
||||
#define GET16(p) (quint16)( \
|
||||
(*((quint8*)(p)+0) << 8 ) \
|
||||
| (*((quint8*)(p)+1)))
|
||||
#else
|
||||
#define GET16(p) (quint16)( \
|
||||
(*((quint8*)(p)+1) << 8 ) \
|
||||
| (*((quint8*)(p)+0)))
|
||||
#define GET32(p) (quint32)( \
|
||||
(*((quint8*)(p)+3) << 24) \
|
||||
| (*((quint8*)(p)+2) << 16) \
|
||||
| (*((quint8*)(p)+1) << 8 ) \
|
||||
| (*((quint8*)(p)+0)))
|
||||
#endif
|
||||
|
||||
#define BYTESWAP4(x) \
|
||||
(((x & 0xFF000000) >> 24) | \
|
||||
((x & 0x00FF0000) >> 8) | \
|
||||
((x & 0x0000FF00) << 8) | \
|
||||
((x & 0x000000FF) << 24))
|
||||
|
||||
#define BYTESWAP2(x) \
|
||||
(((x & 0xFF00) >> 8) | \
|
||||
((x & 0x00FF) << 8))
|
||||
|
||||
//! \todo (LOW) : portability
|
||||
#if 1
|
||||
#define HTONL(x) BYTESWAP4(x)
|
||||
#define NTOHL(x) BYTESWAP4(x)
|
||||
#define HTONS(x) BYTESWAP2(x)
|
||||
#define NTOHS(x) BYTESWAP2(x)
|
||||
#else
|
||||
#define HTONL(x) (x)
|
||||
#define NTOHL(x) (x)
|
||||
#define HTONS(x) (x)
|
||||
#define NTOHS(x) (x)
|
||||
#endif
|
||||
|
||||
// Print a HexDump
|
||||
#define BUFDUMP(ptr, len) qDebug("%s", QString(QByteArray((char*)(ptr), \
|
||||
(len)).toHex()).toAscii().data());
|
||||
|
||||
/*
|
||||
** RPC Header (8)
|
||||
** - MSG_TYPE (2)
|
||||
** - METHOD_ID (2)
|
||||
** - LEN (4) [not including this header]
|
||||
*/
|
||||
#define PB_HDR_SIZE 8
|
||||
|
||||
#define PB_MSG_TYPE_REQUEST 1
|
||||
#define PB_MSG_TYPE_RESPONSE 2
|
||||
#define PB_MSG_TYPE_BINBLOB 3
|
||||
|
||||
#define MSGBUF_SIZE 4096
|
||||
|
||||
#endif
|
||||
#ifndef _PB_RPC_COMMON_H
|
||||
#define _PB_RPC_COMMON_H
|
||||
|
||||
//! \todo (LOW) check which one is right - wrong one seems to be working!!!!!
|
||||
#if 0
|
||||
#define GET16(p) (quint16)( \
|
||||
(*((quint8*)(p)+0) << 8 ) \
|
||||
| (*((quint8*)(p)+1)))
|
||||
#else
|
||||
#define GET16(p) (quint16)( \
|
||||
(*((quint8*)(p)+1) << 8 ) \
|
||||
| (*((quint8*)(p)+0)))
|
||||
#define GET32(p) (quint32)( \
|
||||
(*((quint8*)(p)+3) << 24) \
|
||||
| (*((quint8*)(p)+2) << 16) \
|
||||
| (*((quint8*)(p)+1) << 8 ) \
|
||||
| (*((quint8*)(p)+0)))
|
||||
#endif
|
||||
|
||||
#define BYTESWAP4(x) \
|
||||
(((x & 0xFF000000) >> 24) | \
|
||||
((x & 0x00FF0000) >> 8) | \
|
||||
((x & 0x0000FF00) << 8) | \
|
||||
((x & 0x000000FF) << 24))
|
||||
|
||||
#define BYTESWAP2(x) \
|
||||
(((x & 0xFF00) >> 8) | \
|
||||
((x & 0x00FF) << 8))
|
||||
|
||||
//! \todo (LOW) : portability
|
||||
#if 1
|
||||
#define HTONL(x) BYTESWAP4(x)
|
||||
#define NTOHL(x) BYTESWAP4(x)
|
||||
#define HTONS(x) BYTESWAP2(x)
|
||||
#define NTOHS(x) BYTESWAP2(x)
|
||||
#else
|
||||
#define HTONL(x) (x)
|
||||
#define NTOHL(x) (x)
|
||||
#define HTONS(x) (x)
|
||||
#define NTOHS(x) (x)
|
||||
#endif
|
||||
|
||||
// Print a HexDump
|
||||
#define BUFDUMP(ptr, len) qDebug("%s", QString(QByteArray((char*)(ptr), \
|
||||
(len)).toHex()).toAscii().data());
|
||||
|
||||
/*
|
||||
** RPC Header (8)
|
||||
** - MSG_TYPE (2)
|
||||
** - METHOD_ID (2)
|
||||
** - LEN (4) [not including this header]
|
||||
*/
|
||||
#define PB_HDR_SIZE 8
|
||||
|
||||
#define PB_MSG_TYPE_REQUEST 1
|
||||
#define PB_MSG_TYPE_RESPONSE 2
|
||||
#define PB_MSG_TYPE_BINBLOB 3
|
||||
|
||||
#define MSGBUF_SIZE 4096
|
||||
|
||||
#endif
|
||||
|
@ -1,34 +1,34 @@
|
||||
#ifndef _PB_RPC_CONTROLLER_H
|
||||
#define _PB_RPC_CONTROLLER_H
|
||||
|
||||
#include <google/protobuf/service.h>
|
||||
|
||||
class QIODevice;
|
||||
|
||||
class PbRpcController : public ::google::protobuf::RpcController
|
||||
{
|
||||
bool failed;
|
||||
QIODevice *blob;
|
||||
std::string errStr;
|
||||
|
||||
public:
|
||||
PbRpcController() { Reset(); }
|
||||
|
||||
// Client Side Methods
|
||||
void Reset() { failed=false; blob = NULL; }
|
||||
bool Failed() const { return failed; }
|
||||
void StartCancel() { /*! \todo (MED) */}
|
||||
std::string ErrorText() const { return errStr; }
|
||||
|
||||
// Server Side Methods
|
||||
void SetFailed(const std::string &reason)
|
||||
{ failed = true; errStr = reason; }
|
||||
bool IsCanceled() const { return false; };
|
||||
void NotifyOnCancel(::google::protobuf::Closure *callback) { /*! \todo (MED) */ }
|
||||
|
||||
// srivatsp added
|
||||
QIODevice* binaryBlob() { return blob; };
|
||||
void setBinaryBlob(QIODevice *binaryBlob) { blob = binaryBlob; };
|
||||
};
|
||||
|
||||
#endif
|
||||
#ifndef _PB_RPC_CONTROLLER_H
|
||||
#define _PB_RPC_CONTROLLER_H
|
||||
|
||||
#include <google/protobuf/service.h>
|
||||
|
||||
class QIODevice;
|
||||
|
||||
class PbRpcController : public ::google::protobuf::RpcController
|
||||
{
|
||||
bool failed;
|
||||
QIODevice *blob;
|
||||
std::string errStr;
|
||||
|
||||
public:
|
||||
PbRpcController() { Reset(); }
|
||||
|
||||
// Client Side Methods
|
||||
void Reset() { failed=false; blob = NULL; }
|
||||
bool Failed() const { return failed; }
|
||||
void StartCancel() { /*! \todo (MED) */}
|
||||
std::string ErrorText() const { return errStr; }
|
||||
|
||||
// Server Side Methods
|
||||
void SetFailed(const std::string &reason)
|
||||
{ failed = true; errStr = reason; }
|
||||
bool IsCanceled() const { return false; };
|
||||
void NotifyOnCancel(::google::protobuf::Closure *callback) { /*! \todo (MED) */ }
|
||||
|
||||
// srivatsp added
|
||||
QIODevice* binaryBlob() { return blob; };
|
||||
void setBinaryBlob(QIODevice *binaryBlob) { blob = binaryBlob; };
|
||||
};
|
||||
|
||||
#endif
|
||||
|
@ -1,256 +1,256 @@
|
||||
//#include "pbhelper.h"
|
||||
#include "rpcserver.h"
|
||||
|
||||
RpcServer::RpcServer()
|
||||
{
|
||||
server = NULL;
|
||||
clientSock = NULL;
|
||||
|
||||
service = NULL;
|
||||
|
||||
isPending = false;
|
||||
pendingMethodId = -1; // don't care as long as isPending is false
|
||||
}
|
||||
|
||||
RpcServer::~RpcServer()
|
||||
{
|
||||
if (server)
|
||||
delete server;
|
||||
}
|
||||
|
||||
bool RpcServer::registerService(::google::protobuf::Service *service,
|
||||
quint16 tcpPortNum)
|
||||
{
|
||||
this->service = service;
|
||||
|
||||
server = new QTcpServer();
|
||||
connect(server, SIGNAL(newConnection()), this, SLOT(when_newConnection()));
|
||||
if (!server->listen(QHostAddress::Any, tcpPortNum))
|
||||
{
|
||||
qDebug("Unable to start the server: %s",
|
||||
server->errorString().toAscii().constData());
|
||||
errorString_ = QString("Error starting Ostinato server: %1").arg(
|
||||
server->errorString());
|
||||
return false;
|
||||
}
|
||||
|
||||
qDebug("The server is running on %s: %d",
|
||||
server->serverAddress().toString().toAscii().constData(),
|
||||
server->serverPort());
|
||||
errorString_ = QString();
|
||||
return true;
|
||||
}
|
||||
|
||||
QString RpcServer::errorString()
|
||||
{
|
||||
return errorString_;
|
||||
}
|
||||
|
||||
void RpcServer::done(::google::protobuf::Message *resp, PbRpcController *PbRpcController)
|
||||
{
|
||||
QIODevice *blob;
|
||||
char msg[MSGBUF_SIZE];
|
||||
int len;
|
||||
|
||||
//qDebug("In RpcServer::done");
|
||||
|
||||
if (PbRpcController->Failed())
|
||||
{
|
||||
qDebug("rpc failed");
|
||||
goto _exit;
|
||||
}
|
||||
|
||||
blob = PbRpcController->binaryBlob();
|
||||
if (blob)
|
||||
{
|
||||
len = blob->size();
|
||||
qDebug("is binary blob of len %d", len);
|
||||
|
||||
*((quint16*)(&msg[0])) = HTONS(PB_MSG_TYPE_BINBLOB); // type
|
||||
*((quint16*)(&msg[2])) = HTONS(pendingMethodId); // method
|
||||
(*(quint32*)(&msg[4])) = HTONL(len); // len
|
||||
|
||||
clientSock->write(msg, PB_HDR_SIZE);
|
||||
|
||||
blob->seek(0);
|
||||
while (!blob->atEnd())
|
||||
{
|
||||
int l;
|
||||
|
||||
len = blob->read(msg, sizeof(msg));
|
||||
l = clientSock->write(msg, len);
|
||||
Q_ASSERT(l == len);
|
||||
}
|
||||
|
||||
goto _exit;
|
||||
}
|
||||
|
||||
if (!resp->IsInitialized())
|
||||
{
|
||||
qWarning("response missing required fields!!");
|
||||
qDebug(resp->InitializationErrorString().c_str());
|
||||
qFatal("exiting");
|
||||
goto _exit;
|
||||
}
|
||||
|
||||
resp->SerializeToArray((void*) &msg[PB_HDR_SIZE], sizeof(msg));
|
||||
|
||||
len = resp->ByteSize();
|
||||
|
||||
*((quint16*)(&msg[0])) = HTONS(PB_MSG_TYPE_RESPONSE); // type
|
||||
*((quint16*)(&msg[2])) = HTONS(pendingMethodId); // method
|
||||
*((quint32*)(&msg[4])) = HTONL(len); // len
|
||||
|
||||
// Avoid printing stats since it happens once every couple of seconds
|
||||
if (pendingMethodId != 12)
|
||||
{
|
||||
qDebug("Server(%s): sending %d bytes to client encoding <%s>",
|
||||
__FUNCTION__, len + PB_HDR_SIZE, resp->DebugString().c_str());
|
||||
//BUFDUMP(msg, len + 8);
|
||||
}
|
||||
|
||||
clientSock->write(msg, PB_HDR_SIZE + len);
|
||||
|
||||
_exit:
|
||||
delete PbRpcController;
|
||||
isPending = false;
|
||||
}
|
||||
|
||||
void RpcServer::when_newConnection()
|
||||
{
|
||||
if (clientSock)
|
||||
{
|
||||
QTcpSocket *sock;
|
||||
|
||||
qDebug("already connected, no new connections will be accepted");
|
||||
|
||||
// Accept and close connection
|
||||
//! \todo (MED) Send reason msg to client
|
||||
sock = server->nextPendingConnection();
|
||||
sock->disconnectFromHost();
|
||||
sock->deleteLater();
|
||||
goto _exit;
|
||||
}
|
||||
|
||||
clientSock = server->nextPendingConnection();
|
||||
qDebug("accepting new connection from %s: %d",
|
||||
clientSock->peerAddress().toString().toAscii().constData(),
|
||||
clientSock->peerPort());
|
||||
|
||||
connect(clientSock, SIGNAL(readyRead()),
|
||||
this, SLOT(when_dataAvail()));
|
||||
connect(clientSock, SIGNAL(disconnected()),
|
||||
this, SLOT(when_disconnected()));
|
||||
connect(clientSock, SIGNAL(error(QAbstractSocket::SocketError)),
|
||||
this, SLOT(when_error(QAbstractSocket::SocketError)));
|
||||
|
||||
_exit:
|
||||
return;
|
||||
}
|
||||
|
||||
void RpcServer::when_disconnected()
|
||||
{
|
||||
qDebug("connection closed from %s: %d",
|
||||
clientSock->peerAddress().toString().toAscii().constData(),
|
||||
clientSock->peerPort());
|
||||
|
||||
clientSock->deleteLater();
|
||||
clientSock = NULL;
|
||||
}
|
||||
|
||||
void RpcServer::when_error(QAbstractSocket::SocketError socketError)
|
||||
{
|
||||
qDebug("%s", clientSock->errorString().toAscii().constData());
|
||||
}
|
||||
|
||||
void RpcServer::when_dataAvail()
|
||||
{
|
||||
char msg[MSGBUF_SIZE];
|
||||
int msgLen;
|
||||
static bool parsing = false;
|
||||
static quint16 type, method;
|
||||
static quint32 len;
|
||||
const ::google::protobuf::MethodDescriptor *methodDesc;
|
||||
::google::protobuf::Message *req, *resp;
|
||||
PbRpcController *controller;
|
||||
|
||||
if (!parsing)
|
||||
{
|
||||
if (clientSock->bytesAvailable() < PB_HDR_SIZE)
|
||||
return;
|
||||
|
||||
msgLen = clientSock->read(msg, PB_HDR_SIZE);
|
||||
|
||||
Q_ASSERT(msgLen == PB_HDR_SIZE);
|
||||
|
||||
type = NTOHS(GET16(&msg[0]));
|
||||
method = NTOHS(GET16(&msg[2]));
|
||||
len = NTOHL(GET32(&msg[4]));
|
||||
//qDebug("type = %d, method = %d, len = %d", type, method, len);
|
||||
|
||||
parsing = true;
|
||||
}
|
||||
|
||||
if (clientSock->bytesAvailable() < len)
|
||||
return;
|
||||
|
||||
msgLen = clientSock->read(msg, sizeof(msg));
|
||||
Q_ASSERT((unsigned) msgLen == len);
|
||||
|
||||
if (type != PB_MSG_TYPE_REQUEST)
|
||||
{
|
||||
qDebug("server(%s): unexpected msg type %d (expected %d)", __FUNCTION__,
|
||||
type, PB_MSG_TYPE_REQUEST);
|
||||
goto _error_exit;
|
||||
}
|
||||
|
||||
methodDesc = service->GetDescriptor()->method(method);
|
||||
if (!methodDesc)
|
||||
{
|
||||
qDebug("server(%s): invalid method id %d", __FUNCTION__, method);
|
||||
goto _error_exit; //! \todo Return Error to client
|
||||
}
|
||||
|
||||
if (isPending)
|
||||
{
|
||||
qDebug("server(%s): rpc pending, try again", __FUNCTION__);
|
||||
goto _error_exit; //! \todo Return Error to client
|
||||
}
|
||||
|
||||
pendingMethodId = method;
|
||||
isPending = true;
|
||||
|
||||
req = service->GetRequestPrototype(methodDesc).New();
|
||||
resp = service->GetResponsePrototype(methodDesc).New();
|
||||
|
||||
req->ParseFromArray((void*)msg, len);
|
||||
if (!req->IsInitialized())
|
||||
{
|
||||
qWarning("Missing required fields in request");
|
||||
qDebug(req->InitializationErrorString().c_str());
|
||||
qFatal("exiting");
|
||||
delete req;
|
||||
delete resp;
|
||||
|
||||
goto _error_exit;
|
||||
}
|
||||
//qDebug("Server(%s): successfully parsed as <%s>", __FUNCTION__,
|
||||
//resp->DebugString().c_str());
|
||||
|
||||
controller = new PbRpcController;
|
||||
|
||||
//qDebug("before service->callmethod()");
|
||||
|
||||
service->CallMethod(methodDesc, controller, req, resp,
|
||||
NewCallback(this, &RpcServer::done, resp, controller));
|
||||
|
||||
parsing = false;
|
||||
|
||||
return;
|
||||
|
||||
_error_exit:
|
||||
parsing = false;
|
||||
qDebug("server(%s): discarding msg from client", __FUNCTION__);
|
||||
return;
|
||||
}
|
||||
|
||||
//#include "pbhelper.h"
|
||||
#include "rpcserver.h"
|
||||
|
||||
RpcServer::RpcServer()
|
||||
{
|
||||
server = NULL;
|
||||
clientSock = NULL;
|
||||
|
||||
service = NULL;
|
||||
|
||||
isPending = false;
|
||||
pendingMethodId = -1; // don't care as long as isPending is false
|
||||
}
|
||||
|
||||
RpcServer::~RpcServer()
|
||||
{
|
||||
if (server)
|
||||
delete server;
|
||||
}
|
||||
|
||||
bool RpcServer::registerService(::google::protobuf::Service *service,
|
||||
quint16 tcpPortNum)
|
||||
{
|
||||
this->service = service;
|
||||
|
||||
server = new QTcpServer();
|
||||
connect(server, SIGNAL(newConnection()), this, SLOT(when_newConnection()));
|
||||
if (!server->listen(QHostAddress::Any, tcpPortNum))
|
||||
{
|
||||
qDebug("Unable to start the server: %s",
|
||||
server->errorString().toAscii().constData());
|
||||
errorString_ = QString("Error starting Ostinato server: %1").arg(
|
||||
server->errorString());
|
||||
return false;
|
||||
}
|
||||
|
||||
qDebug("The server is running on %s: %d",
|
||||
server->serverAddress().toString().toAscii().constData(),
|
||||
server->serverPort());
|
||||
errorString_ = QString();
|
||||
return true;
|
||||
}
|
||||
|
||||
QString RpcServer::errorString()
|
||||
{
|
||||
return errorString_;
|
||||
}
|
||||
|
||||
void RpcServer::done(::google::protobuf::Message *resp, PbRpcController *PbRpcController)
|
||||
{
|
||||
QIODevice *blob;
|
||||
char msg[MSGBUF_SIZE];
|
||||
int len;
|
||||
|
||||
//qDebug("In RpcServer::done");
|
||||
|
||||
if (PbRpcController->Failed())
|
||||
{
|
||||
qDebug("rpc failed");
|
||||
goto _exit;
|
||||
}
|
||||
|
||||
blob = PbRpcController->binaryBlob();
|
||||
if (blob)
|
||||
{
|
||||
len = blob->size();
|
||||
qDebug("is binary blob of len %d", len);
|
||||
|
||||
*((quint16*)(&msg[0])) = HTONS(PB_MSG_TYPE_BINBLOB); // type
|
||||
*((quint16*)(&msg[2])) = HTONS(pendingMethodId); // method
|
||||
(*(quint32*)(&msg[4])) = HTONL(len); // len
|
||||
|
||||
clientSock->write(msg, PB_HDR_SIZE);
|
||||
|
||||
blob->seek(0);
|
||||
while (!blob->atEnd())
|
||||
{
|
||||
int l;
|
||||
|
||||
len = blob->read(msg, sizeof(msg));
|
||||
l = clientSock->write(msg, len);
|
||||
Q_ASSERT(l == len);
|
||||
}
|
||||
|
||||
goto _exit;
|
||||
}
|
||||
|
||||
if (!resp->IsInitialized())
|
||||
{
|
||||
qWarning("response missing required fields!!");
|
||||
qDebug(resp->InitializationErrorString().c_str());
|
||||
qFatal("exiting");
|
||||
goto _exit;
|
||||
}
|
||||
|
||||
resp->SerializeToArray((void*) &msg[PB_HDR_SIZE], sizeof(msg));
|
||||
|
||||
len = resp->ByteSize();
|
||||
|
||||
*((quint16*)(&msg[0])) = HTONS(PB_MSG_TYPE_RESPONSE); // type
|
||||
*((quint16*)(&msg[2])) = HTONS(pendingMethodId); // method
|
||||
*((quint32*)(&msg[4])) = HTONL(len); // len
|
||||
|
||||
// Avoid printing stats since it happens once every couple of seconds
|
||||
if (pendingMethodId != 12)
|
||||
{
|
||||
qDebug("Server(%s): sending %d bytes to client encoding <%s>",
|
||||
__FUNCTION__, len + PB_HDR_SIZE, resp->DebugString().c_str());
|
||||
//BUFDUMP(msg, len + 8);
|
||||
}
|
||||
|
||||
clientSock->write(msg, PB_HDR_SIZE + len);
|
||||
|
||||
_exit:
|
||||
delete PbRpcController;
|
||||
isPending = false;
|
||||
}
|
||||
|
||||
void RpcServer::when_newConnection()
|
||||
{
|
||||
if (clientSock)
|
||||
{
|
||||
QTcpSocket *sock;
|
||||
|
||||
qDebug("already connected, no new connections will be accepted");
|
||||
|
||||
// Accept and close connection
|
||||
//! \todo (MED) Send reason msg to client
|
||||
sock = server->nextPendingConnection();
|
||||
sock->disconnectFromHost();
|
||||
sock->deleteLater();
|
||||
goto _exit;
|
||||
}
|
||||
|
||||
clientSock = server->nextPendingConnection();
|
||||
qDebug("accepting new connection from %s: %d",
|
||||
clientSock->peerAddress().toString().toAscii().constData(),
|
||||
clientSock->peerPort());
|
||||
|
||||
connect(clientSock, SIGNAL(readyRead()),
|
||||
this, SLOT(when_dataAvail()));
|
||||
connect(clientSock, SIGNAL(disconnected()),
|
||||
this, SLOT(when_disconnected()));
|
||||
connect(clientSock, SIGNAL(error(QAbstractSocket::SocketError)),
|
||||
this, SLOT(when_error(QAbstractSocket::SocketError)));
|
||||
|
||||
_exit:
|
||||
return;
|
||||
}
|
||||
|
||||
void RpcServer::when_disconnected()
|
||||
{
|
||||
qDebug("connection closed from %s: %d",
|
||||
clientSock->peerAddress().toString().toAscii().constData(),
|
||||
clientSock->peerPort());
|
||||
|
||||
clientSock->deleteLater();
|
||||
clientSock = NULL;
|
||||
}
|
||||
|
||||
void RpcServer::when_error(QAbstractSocket::SocketError socketError)
|
||||
{
|
||||
qDebug("%s", clientSock->errorString().toAscii().constData());
|
||||
}
|
||||
|
||||
void RpcServer::when_dataAvail()
|
||||
{
|
||||
char msg[MSGBUF_SIZE];
|
||||
int msgLen;
|
||||
static bool parsing = false;
|
||||
static quint16 type, method;
|
||||
static quint32 len;
|
||||
const ::google::protobuf::MethodDescriptor *methodDesc;
|
||||
::google::protobuf::Message *req, *resp;
|
||||
PbRpcController *controller;
|
||||
|
||||
if (!parsing)
|
||||
{
|
||||
if (clientSock->bytesAvailable() < PB_HDR_SIZE)
|
||||
return;
|
||||
|
||||
msgLen = clientSock->read(msg, PB_HDR_SIZE);
|
||||
|
||||
Q_ASSERT(msgLen == PB_HDR_SIZE);
|
||||
|
||||
type = NTOHS(GET16(&msg[0]));
|
||||
method = NTOHS(GET16(&msg[2]));
|
||||
len = NTOHL(GET32(&msg[4]));
|
||||
//qDebug("type = %d, method = %d, len = %d", type, method, len);
|
||||
|
||||
parsing = true;
|
||||
}
|
||||
|
||||
if (clientSock->bytesAvailable() < len)
|
||||
return;
|
||||
|
||||
msgLen = clientSock->read(msg, sizeof(msg));
|
||||
Q_ASSERT((unsigned) msgLen == len);
|
||||
|
||||
if (type != PB_MSG_TYPE_REQUEST)
|
||||
{
|
||||
qDebug("server(%s): unexpected msg type %d (expected %d)", __FUNCTION__,
|
||||
type, PB_MSG_TYPE_REQUEST);
|
||||
goto _error_exit;
|
||||
}
|
||||
|
||||
methodDesc = service->GetDescriptor()->method(method);
|
||||
if (!methodDesc)
|
||||
{
|
||||
qDebug("server(%s): invalid method id %d", __FUNCTION__, method);
|
||||
goto _error_exit; //! \todo Return Error to client
|
||||
}
|
||||
|
||||
if (isPending)
|
||||
{
|
||||
qDebug("server(%s): rpc pending, try again", __FUNCTION__);
|
||||
goto _error_exit; //! \todo Return Error to client
|
||||
}
|
||||
|
||||
pendingMethodId = method;
|
||||
isPending = true;
|
||||
|
||||
req = service->GetRequestPrototype(methodDesc).New();
|
||||
resp = service->GetResponsePrototype(methodDesc).New();
|
||||
|
||||
req->ParseFromArray((void*)msg, len);
|
||||
if (!req->IsInitialized())
|
||||
{
|
||||
qWarning("Missing required fields in request");
|
||||
qDebug(req->InitializationErrorString().c_str());
|
||||
qFatal("exiting");
|
||||
delete req;
|
||||
delete resp;
|
||||
|
||||
goto _error_exit;
|
||||
}
|
||||
//qDebug("Server(%s): successfully parsed as <%s>", __FUNCTION__,
|
||||
//resp->DebugString().c_str());
|
||||
|
||||
controller = new PbRpcController;
|
||||
|
||||
//qDebug("before service->callmethod()");
|
||||
|
||||
service->CallMethod(methodDesc, controller, req, resp,
|
||||
NewCallback(this, &RpcServer::done, resp, controller));
|
||||
|
||||
parsing = false;
|
||||
|
||||
return;
|
||||
|
||||
_error_exit:
|
||||
parsing = false;
|
||||
qDebug("server(%s): discarding msg from client", __FUNCTION__);
|
||||
return;
|
||||
}
|
||||
|
||||
|
@ -1,44 +1,44 @@
|
||||
#ifndef _RPC_SERVER_H
|
||||
#define _RPC_SERVER_H
|
||||
|
||||
#include <google/protobuf/message.h>
|
||||
#include <google/protobuf/descriptor.h>
|
||||
#include <google/protobuf/service.h>
|
||||
|
||||
#include <QTcpServer>
|
||||
#include <QTcpSocket>
|
||||
|
||||
#include "pbrpccommon.h"
|
||||
#include "pbrpccontroller.h"
|
||||
|
||||
|
||||
class RpcServer : public QObject
|
||||
{
|
||||
Q_OBJECT
|
||||
|
||||
QTcpServer *server;
|
||||
QTcpSocket *clientSock;
|
||||
|
||||
::google::protobuf::Service *service;
|
||||
|
||||
bool isPending;
|
||||
int pendingMethodId;
|
||||
QString errorString_;
|
||||
|
||||
public:
|
||||
RpcServer(); //! \todo (LOW) use 'parent' param
|
||||
virtual ~RpcServer();
|
||||
|
||||
bool registerService(::google::protobuf::Service *service,
|
||||
quint16 tcpPortNum);
|
||||
QString errorString();
|
||||
void done(::google::protobuf::Message *resp, PbRpcController *controller);
|
||||
|
||||
private slots:
|
||||
void when_newConnection();
|
||||
void when_disconnected();
|
||||
void when_dataAvail();
|
||||
void when_error(QAbstractSocket::SocketError socketError);
|
||||
};
|
||||
|
||||
#endif
|
||||
#ifndef _RPC_SERVER_H
|
||||
#define _RPC_SERVER_H
|
||||
|
||||
#include <google/protobuf/message.h>
|
||||
#include <google/protobuf/descriptor.h>
|
||||
#include <google/protobuf/service.h>
|
||||
|
||||
#include <QTcpServer>
|
||||
#include <QTcpSocket>
|
||||
|
||||
#include "pbrpccommon.h"
|
||||
#include "pbrpccontroller.h"
|
||||
|
||||
|
||||
class RpcServer : public QObject
|
||||
{
|
||||
Q_OBJECT
|
||||
|
||||
QTcpServer *server;
|
||||
QTcpSocket *clientSock;
|
||||
|
||||
::google::protobuf::Service *service;
|
||||
|
||||
bool isPending;
|
||||
int pendingMethodId;
|
||||
QString errorString_;
|
||||
|
||||
public:
|
||||
RpcServer(); //! \todo (LOW) use 'parent' param
|
||||
virtual ~RpcServer();
|
||||
|
||||
bool registerService(::google::protobuf::Service *service,
|
||||
quint16 tcpPortNum);
|
||||
QString errorString();
|
||||
void done(::google::protobuf::Message *resp, PbRpcController *controller);
|
||||
|
||||
private slots:
|
||||
void when_newConnection();
|
||||
void when_disconnected();
|
||||
void when_dataAvail();
|
||||
void when_error(QAbstractSocket::SocketError socketError);
|
||||
};
|
||||
|
||||
#endif
|
||||
|
152
server/drone.cpp
152
server/drone.cpp
@ -1,76 +1,76 @@
|
||||
#include "drone.h"
|
||||
|
||||
#include "rpcserver.h"
|
||||
#include "myservice.h"
|
||||
|
||||
#include <QCloseEvent>
|
||||
#include <QMessageBox>
|
||||
|
||||
extern int myport;
|
||||
|
||||
Drone::Drone(QWidget *parent)
|
||||
: QWidget(parent)
|
||||
{
|
||||
setupUi(this);
|
||||
|
||||
rpcServer = new RpcServer();
|
||||
service = new MyService();
|
||||
}
|
||||
|
||||
Drone::~Drone()
|
||||
{
|
||||
trayIcon_->hide();
|
||||
delete rpcServer;
|
||||
delete service;
|
||||
}
|
||||
|
||||
bool Drone::init()
|
||||
{
|
||||
Q_ASSERT(rpcServer);
|
||||
|
||||
if (!rpcServer->registerService(service, myport ? myport : 7878))
|
||||
{
|
||||
QMessageBox::critical(0, qApp->applicationName(),
|
||||
rpcServer->errorString());
|
||||
return false;
|
||||
}
|
||||
|
||||
trayIconMenu_ = new QMenu(this);
|
||||
|
||||
trayIconMenu_->addAction(actionShow);
|
||||
trayIconMenu_->addAction(actionExit);
|
||||
trayIconMenu_->setDefaultAction(actionShow);
|
||||
trayIcon_ = new QSystemTrayIcon();
|
||||
trayIcon_->setIcon(QIcon(":/icons/portgroup.png"));
|
||||
trayIcon_->setToolTip(qApp->applicationName());
|
||||
trayIcon_->setContextMenu(trayIconMenu_);
|
||||
trayIcon_->show();
|
||||
|
||||
connect(trayIcon_, SIGNAL(activated(QSystemTrayIcon::ActivationReason)),
|
||||
this, SLOT(trayIconActivated(QSystemTrayIcon::ActivationReason)));
|
||||
connect(this, SIGNAL(hideMe(bool)), this, SLOT(setHidden(bool)),
|
||||
Qt::QueuedConnection);
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
void Drone::changeEvent(QEvent *event)
|
||||
{
|
||||
if (event->type() == QEvent::WindowStateChange && isMinimized())
|
||||
{
|
||||
emit hideMe(true);
|
||||
event->ignore();
|
||||
return;
|
||||
}
|
||||
|
||||
QWidget::changeEvent(event);
|
||||
}
|
||||
|
||||
void Drone::trayIconActivated(QSystemTrayIcon::ActivationReason reason)
|
||||
{
|
||||
if (reason == QSystemTrayIcon::DoubleClick)
|
||||
{
|
||||
showNormal();
|
||||
activateWindow();
|
||||
}
|
||||
}
|
||||
#include "drone.h"
|
||||
|
||||
#include "rpcserver.h"
|
||||
#include "myservice.h"
|
||||
|
||||
#include <QCloseEvent>
|
||||
#include <QMessageBox>
|
||||
|
||||
extern int myport;
|
||||
|
||||
Drone::Drone(QWidget *parent)
|
||||
: QWidget(parent)
|
||||
{
|
||||
setupUi(this);
|
||||
|
||||
rpcServer = new RpcServer();
|
||||
service = new MyService();
|
||||
}
|
||||
|
||||
Drone::~Drone()
|
||||
{
|
||||
trayIcon_->hide();
|
||||
delete rpcServer;
|
||||
delete service;
|
||||
}
|
||||
|
||||
bool Drone::init()
|
||||
{
|
||||
Q_ASSERT(rpcServer);
|
||||
|
||||
if (!rpcServer->registerService(service, myport ? myport : 7878))
|
||||
{
|
||||
QMessageBox::critical(0, qApp->applicationName(),
|
||||
rpcServer->errorString());
|
||||
return false;
|
||||
}
|
||||
|
||||
trayIconMenu_ = new QMenu(this);
|
||||
|
||||
trayIconMenu_->addAction(actionShow);
|
||||
trayIconMenu_->addAction(actionExit);
|
||||
trayIconMenu_->setDefaultAction(actionShow);
|
||||
trayIcon_ = new QSystemTrayIcon();
|
||||
trayIcon_->setIcon(QIcon(":/icons/portgroup.png"));
|
||||
trayIcon_->setToolTip(qApp->applicationName());
|
||||
trayIcon_->setContextMenu(trayIconMenu_);
|
||||
trayIcon_->show();
|
||||
|
||||
connect(trayIcon_, SIGNAL(activated(QSystemTrayIcon::ActivationReason)),
|
||||
this, SLOT(trayIconActivated(QSystemTrayIcon::ActivationReason)));
|
||||
connect(this, SIGNAL(hideMe(bool)), this, SLOT(setHidden(bool)),
|
||||
Qt::QueuedConnection);
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
void Drone::changeEvent(QEvent *event)
|
||||
{
|
||||
if (event->type() == QEvent::WindowStateChange && isMinimized())
|
||||
{
|
||||
emit hideMe(true);
|
||||
event->ignore();
|
||||
return;
|
||||
}
|
||||
|
||||
QWidget::changeEvent(event);
|
||||
}
|
||||
|
||||
void Drone::trayIconActivated(QSystemTrayIcon::ActivationReason reason)
|
||||
{
|
||||
if (reason == QSystemTrayIcon::DoubleClick)
|
||||
{
|
||||
showNormal();
|
||||
activateWindow();
|
||||
}
|
||||
}
|
||||
|
@ -1,37 +1,37 @@
|
||||
#ifndef _DRONE_H
|
||||
#define _DRONE_H
|
||||
|
||||
#include "ui_drone.h"
|
||||
|
||||
#include <QMenu>
|
||||
#include <QSystemTrayIcon>
|
||||
|
||||
class RpcServer;
|
||||
namespace OstProto { class OstService; }
|
||||
|
||||
class Drone : public QWidget, Ui::Drone
|
||||
{
|
||||
Q_OBJECT
|
||||
|
||||
public:
|
||||
Drone(QWidget *parent = 0);
|
||||
~Drone();
|
||||
bool init();
|
||||
|
||||
signals:
|
||||
void hideMe(bool hidden);
|
||||
|
||||
protected:
|
||||
void changeEvent(QEvent *event);
|
||||
|
||||
private:
|
||||
QSystemTrayIcon *trayIcon_;
|
||||
QMenu *trayIconMenu_;
|
||||
RpcServer *rpcServer;
|
||||
OstProto::OstService *service;
|
||||
|
||||
private slots:
|
||||
void trayIconActivated(QSystemTrayIcon::ActivationReason reason);
|
||||
|
||||
};
|
||||
#endif
|
||||
#ifndef _DRONE_H
|
||||
#define _DRONE_H
|
||||
|
||||
#include "ui_drone.h"
|
||||
|
||||
#include <QMenu>
|
||||
#include <QSystemTrayIcon>
|
||||
|
||||
class RpcServer;
|
||||
namespace OstProto { class OstService; }
|
||||
|
||||
class Drone : public QWidget, Ui::Drone
|
||||
{
|
||||
Q_OBJECT
|
||||
|
||||
public:
|
||||
Drone(QWidget *parent = 0);
|
||||
~Drone();
|
||||
bool init();
|
||||
|
||||
signals:
|
||||
void hideMe(bool hidden);
|
||||
|
||||
protected:
|
||||
void changeEvent(QEvent *event);
|
||||
|
||||
private:
|
||||
QSystemTrayIcon *trayIcon_;
|
||||
QMenu *trayIconMenu_;
|
||||
RpcServer *rpcServer;
|
||||
OstProto::OstService *service;
|
||||
|
||||
private slots:
|
||||
void trayIconActivated(QSystemTrayIcon::ActivationReason reason);
|
||||
|
||||
};
|
||||
#endif
|
||||
|
@ -1,26 +1,26 @@
|
||||
TEMPLATE = app
|
||||
CONFIG += qt debug
|
||||
QT += network script
|
||||
DEFINES += HAVE_REMOTE WPCAP
|
||||
INCLUDEPATH += "../rpc"
|
||||
win32:LIBS += -lwpcap -lpacket
|
||||
unix:LIBS += -lpcap
|
||||
win32:LIBS += -L"../common/debug" -lostproto
|
||||
unix:LIBS += -L"../common" -lostproto
|
||||
win32:LIBS += -L"../rpc/debug" -lpbrpc
|
||||
unix:LIBS += -L"../rpc" -lpbrpc
|
||||
LIBS += -lprotobuf
|
||||
POST_TARGETDEPS += "../common/debug/libostproto.a" "../rpc/debug/libpbrpc.a"
|
||||
RESOURCES += drone.qrc
|
||||
HEADERS += drone.h
|
||||
FORMS += drone.ui
|
||||
SOURCES += \
|
||||
drone_main.cpp \
|
||||
drone.cpp \
|
||||
portmanager.cpp \
|
||||
abstractport.cpp \
|
||||
pcapport.cpp \
|
||||
winpcapport.cpp
|
||||
SOURCES += myservice.cpp
|
||||
SOURCES += pcapextra.cpp
|
||||
|
||||
TEMPLATE = app
|
||||
CONFIG += qt debug
|
||||
QT += network script
|
||||
DEFINES += HAVE_REMOTE WPCAP
|
||||
INCLUDEPATH += "../rpc"
|
||||
win32:LIBS += -lwpcap -lpacket
|
||||
unix:LIBS += -lpcap
|
||||
win32:LIBS += -L"../common/debug" -lostproto
|
||||
unix:LIBS += -L"../common" -lostproto
|
||||
win32:LIBS += -L"../rpc/debug" -lpbrpc
|
||||
unix:LIBS += -L"../rpc" -lpbrpc
|
||||
LIBS += -lprotobuf
|
||||
POST_TARGETDEPS += "../common/debug/libostproto.a" "../rpc/debug/libpbrpc.a"
|
||||
RESOURCES += drone.qrc
|
||||
HEADERS += drone.h
|
||||
FORMS += drone.ui
|
||||
SOURCES += \
|
||||
drone_main.cpp \
|
||||
drone.cpp \
|
||||
portmanager.cpp \
|
||||
abstractport.cpp \
|
||||
pcapport.cpp \
|
||||
winpcapport.cpp
|
||||
SOURCES += myservice.cpp
|
||||
SOURCES += pcapextra.cpp
|
||||
|
||||
|
@ -1,25 +1,25 @@
|
||||
#include "drone.h"
|
||||
|
||||
int myport;
|
||||
|
||||
int main(int argc, char *argv[])
|
||||
{
|
||||
QApplication app(argc, argv);
|
||||
Drone drone;
|
||||
|
||||
app.setApplicationName(drone.objectName());
|
||||
|
||||
if (argc > 1)
|
||||
myport = atoi(argv[1]);
|
||||
|
||||
if (!drone.init())
|
||||
exit(-1);
|
||||
|
||||
drone.setWindowFlags(drone.windowFlags()
|
||||
| Qt::WindowMaximizeButtonHint
|
||||
| Qt::WindowMinimizeButtonHint);
|
||||
drone.showMinimized();
|
||||
app.exec();
|
||||
return 0;
|
||||
}
|
||||
|
||||
#include "drone.h"
|
||||
|
||||
int myport;
|
||||
|
||||
int main(int argc, char *argv[])
|
||||
{
|
||||
QApplication app(argc, argv);
|
||||
Drone drone;
|
||||
|
||||
app.setApplicationName(drone.objectName());
|
||||
|
||||
if (argc > 1)
|
||||
myport = atoi(argv[1]);
|
||||
|
||||
if (!drone.init())
|
||||
exit(-1);
|
||||
|
||||
drone.setWindowFlags(drone.windowFlags()
|
||||
| Qt::WindowMaximizeButtonHint
|
||||
| Qt::WindowMinimizeButtonHint);
|
||||
drone.showMinimized();
|
||||
app.exec();
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
@ -1,421 +1,421 @@
|
||||
|
||||
#include "myservice.h"
|
||||
|
||||
#if 0
|
||||
#include <qglobal.h>
|
||||
#include <qendian.h>
|
||||
#include "qdebug.h"
|
||||
|
||||
#include "../common/protocollistiterator.h"
|
||||
#include "../common/abstractprotocol.h"
|
||||
#endif
|
||||
|
||||
#include "../common/streambase.h"
|
||||
#include "../rpc/pbrpccontroller.h"
|
||||
#include "portmanager.h"
|
||||
|
||||
MyService::MyService()
|
||||
{
|
||||
PortManager *portManager = PortManager::instance();
|
||||
int n = portManager->portCount();
|
||||
|
||||
for (int i = 0; i < n; i++)
|
||||
portInfo.append(portManager->port(i));
|
||||
}
|
||||
|
||||
MyService::~MyService()
|
||||
{
|
||||
}
|
||||
|
||||
void MyService::getPortIdList(::google::protobuf::RpcController* controller,
|
||||
const ::OstProto::Void* request,
|
||||
::OstProto::PortIdList* response,
|
||||
::google::protobuf::Closure* done)
|
||||
{
|
||||
qDebug("In %s", __PRETTY_FUNCTION__);
|
||||
|
||||
for (int i = 0; i < portInfo.size(); i++)
|
||||
{
|
||||
::OstProto::PortId *p;
|
||||
|
||||
p = response->add_port_id();
|
||||
p->set_id(portInfo[i]->id());
|
||||
}
|
||||
|
||||
done->Run();
|
||||
}
|
||||
|
||||
void MyService::getPortConfig(::google::protobuf::RpcController* controller,
|
||||
const ::OstProto::PortIdList* request,
|
||||
::OstProto::PortConfigList* response,
|
||||
::google::protobuf::Closure* done)
|
||||
{
|
||||
qDebug("In %s", __PRETTY_FUNCTION__);
|
||||
|
||||
for (int i = 0; i < request->port_id_size(); i++)
|
||||
{
|
||||
int id;
|
||||
|
||||
id = request->port_id(i).id();
|
||||
if (id < portInfo.size())
|
||||
{
|
||||
OstProto::Port *p;
|
||||
|
||||
p = response->add_port();
|
||||
portInfo[id]->protoDataCopyInto(p);
|
||||
}
|
||||
}
|
||||
|
||||
done->Run();
|
||||
}
|
||||
|
||||
void MyService::getStreamIdList(::google::protobuf::RpcController* controller,
|
||||
const ::OstProto::PortId* request,
|
||||
::OstProto::StreamIdList* response,
|
||||
::google::protobuf::Closure* done)
|
||||
{
|
||||
int portId;
|
||||
|
||||
qDebug("In %s", __PRETTY_FUNCTION__);
|
||||
|
||||
portId = request->id();
|
||||
if ((portId < 0) || (portId >= portInfo.size()))
|
||||
goto _invalid_port;
|
||||
|
||||
response->mutable_port_id()->set_id(portId);
|
||||
for (int i = 0; i < portInfo[portId]->streamCount(); i++)
|
||||
{
|
||||
OstProto::StreamId *s;
|
||||
|
||||
s = response->add_stream_id();
|
||||
s->set_id(portInfo[portId]->stream(i)->id());
|
||||
}
|
||||
done->Run();
|
||||
return;
|
||||
|
||||
_invalid_port:
|
||||
controller->SetFailed("Invalid Port Id");
|
||||
done->Run();
|
||||
}
|
||||
|
||||
void MyService::getStreamConfig(::google::protobuf::RpcController* controller,
|
||||
const ::OstProto::StreamIdList* request,
|
||||
::OstProto::StreamConfigList* response,
|
||||
::google::protobuf::Closure* done)
|
||||
{
|
||||
int portId;
|
||||
|
||||
qDebug("In %s", __PRETTY_FUNCTION__);
|
||||
|
||||
portId = request->port_id().id();
|
||||
if ((portId < 0) || (portId >= portInfo.size()))
|
||||
goto _invalid_port;
|
||||
|
||||
response->mutable_port_id()->set_id(portId);
|
||||
for (int i = 0; i < request->stream_id_size(); i++)
|
||||
{
|
||||
StreamBase *stream;
|
||||
OstProto::Stream *s;
|
||||
|
||||
stream = portInfo[portId]->stream(request->stream_id(i).id());
|
||||
if (!stream)
|
||||
continue; //! \todo(LOW): Partial status of RPC
|
||||
|
||||
s = response->add_stream();
|
||||
stream->protoDataCopyInto(*s);
|
||||
}
|
||||
done->Run();
|
||||
return;
|
||||
|
||||
_invalid_port:
|
||||
controller->SetFailed("invalid portid");
|
||||
done->Run();
|
||||
}
|
||||
|
||||
void MyService::addStream(::google::protobuf::RpcController* controller,
|
||||
const ::OstProto::StreamIdList* request,
|
||||
::OstProto::Ack* response,
|
||||
::google::protobuf::Closure* done)
|
||||
{
|
||||
int portId;
|
||||
|
||||
qDebug("In %s", __PRETTY_FUNCTION__);
|
||||
|
||||
portId = request->port_id().id();
|
||||
if ((portId < 0) || (portId >= portInfo.size()))
|
||||
goto _invalid_port;
|
||||
|
||||
for (int i = 0; i < request->stream_id_size(); i++)
|
||||
{
|
||||
StreamBase *stream;
|
||||
|
||||
// If stream with same id as in request exists already ==> error!!
|
||||
stream = portInfo[portId]->stream(request->stream_id(i).id());
|
||||
if (stream)
|
||||
continue; //! \todo (LOW): Partial status of RPC
|
||||
|
||||
// Append a new "default" stream - actual contents of the new stream is
|
||||
// expected in a subsequent "modifyStream" request - set the stream id
|
||||
// now itself however!!!
|
||||
stream = new StreamBase;
|
||||
stream->setId(request->stream_id(i).id());
|
||||
portInfo[portId]->addStream(stream);
|
||||
|
||||
}
|
||||
|
||||
//! \todo (LOW): fill-in response "Ack"????
|
||||
|
||||
done->Run();
|
||||
return;
|
||||
|
||||
_invalid_port:
|
||||
controller->SetFailed("invalid portid");
|
||||
done->Run();
|
||||
}
|
||||
|
||||
void MyService::deleteStream(::google::protobuf::RpcController* controller,
|
||||
const ::OstProto::StreamIdList* request,
|
||||
::OstProto::Ack* response,
|
||||
::google::protobuf::Closure* done)
|
||||
{
|
||||
int portId;
|
||||
|
||||
qDebug("In %s", __PRETTY_FUNCTION__);
|
||||
|
||||
portId = request->port_id().id();
|
||||
if ((portId < 0) || (portId >= portInfo.size()))
|
||||
goto _invalid_port;
|
||||
|
||||
for (int i = 0; i < request->stream_id_size(); i++)
|
||||
portInfo[portId]->deleteStream(request->stream_id(i).id());
|
||||
|
||||
//! \todo (LOW): fill-in response "Ack"????
|
||||
|
||||
done->Run();
|
||||
return;
|
||||
|
||||
_invalid_port:
|
||||
controller->SetFailed("invalid portid");
|
||||
done->Run();
|
||||
}
|
||||
|
||||
void MyService::modifyStream(::google::protobuf::RpcController* controller,
|
||||
const ::OstProto::StreamConfigList* request,
|
||||
::OstProto::Ack* response,
|
||||
::google::protobuf::Closure* done)
|
||||
{
|
||||
int portId;
|
||||
|
||||
qDebug("In %s", __PRETTY_FUNCTION__);
|
||||
|
||||
portId = request->port_id().id();
|
||||
if ((portId < 0) || (portId >= portInfo.size()))
|
||||
goto _invalid_port;
|
||||
|
||||
for (int i = 0; i < request->stream_size(); i++)
|
||||
{
|
||||
StreamBase *stream;
|
||||
|
||||
stream = portInfo[portId]->stream(request->stream(i).stream_id().id());
|
||||
if (stream)
|
||||
{
|
||||
stream->protoDataCopyFrom(request->stream(i));
|
||||
portInfo[portId]->setDirty();
|
||||
}
|
||||
}
|
||||
|
||||
//! \todo(LOW): fill-in response "Ack"????
|
||||
|
||||
done->Run();
|
||||
return;
|
||||
|
||||
_invalid_port:
|
||||
controller->SetFailed("invalid portid");
|
||||
done->Run();
|
||||
}
|
||||
|
||||
void MyService::startTx(::google::protobuf::RpcController* controller,
|
||||
const ::OstProto::PortIdList* request,
|
||||
::OstProto::Ack* response,
|
||||
::google::protobuf::Closure* done)
|
||||
{
|
||||
qDebug("In %s", __PRETTY_FUNCTION__);
|
||||
|
||||
for (int i = 0; i < request->port_id_size(); i++)
|
||||
{
|
||||
int portId;
|
||||
|
||||
portId = request->port_id(i).id();
|
||||
if ((portId < 0) || (portId >= portInfo.size()))
|
||||
continue; //! \todo (LOW): partial RPC?
|
||||
|
||||
portInfo[portId]->startTransmit();
|
||||
}
|
||||
|
||||
//! \todo (LOW): fill-in response "Ack"????
|
||||
|
||||
done->Run();
|
||||
}
|
||||
|
||||
void MyService::stopTx(::google::protobuf::RpcController* controller,
|
||||
const ::OstProto::PortIdList* request,
|
||||
::OstProto::Ack* response,
|
||||
::google::protobuf::Closure* done)
|
||||
{
|
||||
qDebug("In %s", __PRETTY_FUNCTION__);
|
||||
|
||||
for (int i = 0; i < request->port_id_size(); i++)
|
||||
{
|
||||
int portId;
|
||||
|
||||
portId = request->port_id(i).id();
|
||||
if ((portId < 0) || (portId >= portInfo.size()))
|
||||
continue; //! \todo (LOW): partial RPC?
|
||||
|
||||
portInfo[portId]->stopTransmit();
|
||||
}
|
||||
|
||||
//! \todo (LOW): fill-in response "Ack"????
|
||||
|
||||
done->Run();
|
||||
}
|
||||
|
||||
void MyService::startCapture(::google::protobuf::RpcController* controller,
|
||||
const ::OstProto::PortIdList* request,
|
||||
::OstProto::Ack* response,
|
||||
::google::protobuf::Closure* done)
|
||||
{
|
||||
qDebug("In %s", __PRETTY_FUNCTION__);
|
||||
|
||||
for (int i = 0; i < request->port_id_size(); i++)
|
||||
{
|
||||
int portId;
|
||||
|
||||
portId = request->port_id(i).id();
|
||||
if ((portId < 0) || (portId >= portInfo.size()))
|
||||
continue; //! \todo (LOW): partial RPC?
|
||||
|
||||
portInfo[portId]->startCapture();
|
||||
}
|
||||
|
||||
//! \todo (LOW): fill-in response "Ack"????
|
||||
|
||||
done->Run();
|
||||
}
|
||||
|
||||
void MyService::stopCapture(::google::protobuf::RpcController* controller,
|
||||
const ::OstProto::PortIdList* request,
|
||||
::OstProto::Ack* response,
|
||||
::google::protobuf::Closure* done)
|
||||
{
|
||||
qDebug("In %s", __PRETTY_FUNCTION__);
|
||||
for (int i=0; i < request->port_id_size(); i++)
|
||||
{
|
||||
int portId;
|
||||
|
||||
portId = request->port_id(i).id();
|
||||
if ((portId < 0) || (portId >= portInfo.size()))
|
||||
continue; //! \todo (LOW): partial RPC?
|
||||
|
||||
portInfo[portId]->stopCapture();
|
||||
}
|
||||
|
||||
//! \todo (LOW): fill-in response "Ack"????
|
||||
|
||||
done->Run();
|
||||
}
|
||||
|
||||
void MyService::getCaptureBuffer(::google::protobuf::RpcController* controller,
|
||||
const ::OstProto::PortId* request,
|
||||
::OstProto::CaptureBuffer* response,
|
||||
::google::protobuf::Closure* done)
|
||||
{
|
||||
int portId;
|
||||
|
||||
qDebug("In %s", __PRETTY_FUNCTION__);
|
||||
|
||||
portId = request->id();
|
||||
if ((portId < 0) || (portId >= portInfo.size()))
|
||||
goto _invalid_port;
|
||||
|
||||
portInfo[portId]->stopCapture();
|
||||
static_cast<PbRpcController*>(controller)->setBinaryBlob(
|
||||
portInfo[portId]->captureData());
|
||||
|
||||
done->Run();
|
||||
return;
|
||||
|
||||
_invalid_port:
|
||||
controller->SetFailed("invalid portid");
|
||||
done->Run();
|
||||
}
|
||||
|
||||
void MyService::getStats(::google::protobuf::RpcController* controller,
|
||||
const ::OstProto::PortIdList* request,
|
||||
::OstProto::PortStatsList* response,
|
||||
::google::protobuf::Closure* done)
|
||||
{
|
||||
//qDebug("In %s", __PRETTY_FUNCTION__);
|
||||
|
||||
for (int i = 0; i < request->port_id_size(); i++)
|
||||
{
|
||||
int portId;
|
||||
AbstractPort::PortStats stats;
|
||||
OstProto::PortStats *s;
|
||||
OstProto::PortState *st;
|
||||
|
||||
portId = request->port_id(i).id();
|
||||
if ((portId < 0) || (portId >= portInfo.size()))
|
||||
continue; //! \todo(LOW): partial rpc?
|
||||
|
||||
s = response->add_port_stats();
|
||||
s->mutable_port_id()->set_id(request->port_id(i).id());
|
||||
|
||||
st = s->mutable_state();
|
||||
st->set_link_state(portInfo[portId]->linkState());
|
||||
st->set_is_transmit_on(portInfo[portId]->isTransmitOn());
|
||||
st->set_is_capture_on(portInfo[portId]->isCaptureOn());
|
||||
|
||||
portInfo[portId]->stats(&stats);
|
||||
|
||||
#if 0
|
||||
if (portId == 2)
|
||||
qDebug(">%llu", stats.rxPkts);
|
||||
#endif
|
||||
|
||||
s->set_rx_pkts(stats.rxPkts);
|
||||
s->set_rx_bytes(stats.rxBytes);
|
||||
s->set_rx_pps(stats.rxPps);
|
||||
s->set_rx_bps(stats.rxBps);
|
||||
|
||||
s->set_tx_pkts(stats.txPkts);
|
||||
s->set_tx_bytes(stats.txBytes);
|
||||
s->set_tx_pps(stats.txPps);
|
||||
s->set_tx_bps(stats.txBps);
|
||||
}
|
||||
|
||||
done->Run();
|
||||
}
|
||||
|
||||
void MyService::clearStats(::google::protobuf::RpcController* controller,
|
||||
const ::OstProto::PortIdList* request,
|
||||
::OstProto::Ack* response,
|
||||
::google::protobuf::Closure* done)
|
||||
{
|
||||
qDebug("In %s", __PRETTY_FUNCTION__);
|
||||
|
||||
for (int i = 0; i < request->port_id_size(); i++)
|
||||
{
|
||||
int portId;
|
||||
|
||||
portId = request->port_id(i).id();
|
||||
if ((portId < 0) || (portId >= portInfo.size()))
|
||||
continue; //! \todo (LOW): partial RPC?
|
||||
|
||||
portInfo[portId]->resetStats();
|
||||
}
|
||||
|
||||
//! \todo (LOW): fill-in response "Ack"????
|
||||
|
||||
done->Run();
|
||||
}
|
||||
|
||||
#include "myservice.h"
|
||||
|
||||
#if 0
|
||||
#include <qglobal.h>
|
||||
#include <qendian.h>
|
||||
#include "qdebug.h"
|
||||
|
||||
#include "../common/protocollistiterator.h"
|
||||
#include "../common/abstractprotocol.h"
|
||||
#endif
|
||||
|
||||
#include "../common/streambase.h"
|
||||
#include "../rpc/pbrpccontroller.h"
|
||||
#include "portmanager.h"
|
||||
|
||||
MyService::MyService()
|
||||
{
|
||||
PortManager *portManager = PortManager::instance();
|
||||
int n = portManager->portCount();
|
||||
|
||||
for (int i = 0; i < n; i++)
|
||||
portInfo.append(portManager->port(i));
|
||||
}
|
||||
|
||||
MyService::~MyService()
|
||||
{
|
||||
}
|
||||
|
||||
void MyService::getPortIdList(::google::protobuf::RpcController* controller,
|
||||
const ::OstProto::Void* request,
|
||||
::OstProto::PortIdList* response,
|
||||
::google::protobuf::Closure* done)
|
||||
{
|
||||
qDebug("In %s", __PRETTY_FUNCTION__);
|
||||
|
||||
for (int i = 0; i < portInfo.size(); i++)
|
||||
{
|
||||
::OstProto::PortId *p;
|
||||
|
||||
p = response->add_port_id();
|
||||
p->set_id(portInfo[i]->id());
|
||||
}
|
||||
|
||||
done->Run();
|
||||
}
|
||||
|
||||
void MyService::getPortConfig(::google::protobuf::RpcController* controller,
|
||||
const ::OstProto::PortIdList* request,
|
||||
::OstProto::PortConfigList* response,
|
||||
::google::protobuf::Closure* done)
|
||||
{
|
||||
qDebug("In %s", __PRETTY_FUNCTION__);
|
||||
|
||||
for (int i = 0; i < request->port_id_size(); i++)
|
||||
{
|
||||
int id;
|
||||
|
||||
id = request->port_id(i).id();
|
||||
if (id < portInfo.size())
|
||||
{
|
||||
OstProto::Port *p;
|
||||
|
||||
p = response->add_port();
|
||||
portInfo[id]->protoDataCopyInto(p);
|
||||
}
|
||||
}
|
||||
|
||||
done->Run();
|
||||
}
|
||||
|
||||
void MyService::getStreamIdList(::google::protobuf::RpcController* controller,
|
||||
const ::OstProto::PortId* request,
|
||||
::OstProto::StreamIdList* response,
|
||||
::google::protobuf::Closure* done)
|
||||
{
|
||||
int portId;
|
||||
|
||||
qDebug("In %s", __PRETTY_FUNCTION__);
|
||||
|
||||
portId = request->id();
|
||||
if ((portId < 0) || (portId >= portInfo.size()))
|
||||
goto _invalid_port;
|
||||
|
||||
response->mutable_port_id()->set_id(portId);
|
||||
for (int i = 0; i < portInfo[portId]->streamCount(); i++)
|
||||
{
|
||||
OstProto::StreamId *s;
|
||||
|
||||
s = response->add_stream_id();
|
||||
s->set_id(portInfo[portId]->stream(i)->id());
|
||||
}
|
||||
done->Run();
|
||||
return;
|
||||
|
||||
_invalid_port:
|
||||
controller->SetFailed("Invalid Port Id");
|
||||
done->Run();
|
||||
}
|
||||
|
||||
void MyService::getStreamConfig(::google::protobuf::RpcController* controller,
|
||||
const ::OstProto::StreamIdList* request,
|
||||
::OstProto::StreamConfigList* response,
|
||||
::google::protobuf::Closure* done)
|
||||
{
|
||||
int portId;
|
||||
|
||||
qDebug("In %s", __PRETTY_FUNCTION__);
|
||||
|
||||
portId = request->port_id().id();
|
||||
if ((portId < 0) || (portId >= portInfo.size()))
|
||||
goto _invalid_port;
|
||||
|
||||
response->mutable_port_id()->set_id(portId);
|
||||
for (int i = 0; i < request->stream_id_size(); i++)
|
||||
{
|
||||
StreamBase *stream;
|
||||
OstProto::Stream *s;
|
||||
|
||||
stream = portInfo[portId]->stream(request->stream_id(i).id());
|
||||
if (!stream)
|
||||
continue; //! \todo(LOW): Partial status of RPC
|
||||
|
||||
s = response->add_stream();
|
||||
stream->protoDataCopyInto(*s);
|
||||
}
|
||||
done->Run();
|
||||
return;
|
||||
|
||||
_invalid_port:
|
||||
controller->SetFailed("invalid portid");
|
||||
done->Run();
|
||||
}
|
||||
|
||||
void MyService::addStream(::google::protobuf::RpcController* controller,
|
||||
const ::OstProto::StreamIdList* request,
|
||||
::OstProto::Ack* response,
|
||||
::google::protobuf::Closure* done)
|
||||
{
|
||||
int portId;
|
||||
|
||||
qDebug("In %s", __PRETTY_FUNCTION__);
|
||||
|
||||
portId = request->port_id().id();
|
||||
if ((portId < 0) || (portId >= portInfo.size()))
|
||||
goto _invalid_port;
|
||||
|
||||
for (int i = 0; i < request->stream_id_size(); i++)
|
||||
{
|
||||
StreamBase *stream;
|
||||
|
||||
// If stream with same id as in request exists already ==> error!!
|
||||
stream = portInfo[portId]->stream(request->stream_id(i).id());
|
||||
if (stream)
|
||||
continue; //! \todo (LOW): Partial status of RPC
|
||||
|
||||
// Append a new "default" stream - actual contents of the new stream is
|
||||
// expected in a subsequent "modifyStream" request - set the stream id
|
||||
// now itself however!!!
|
||||
stream = new StreamBase;
|
||||
stream->setId(request->stream_id(i).id());
|
||||
portInfo[portId]->addStream(stream);
|
||||
|
||||
}
|
||||
|
||||
//! \todo (LOW): fill-in response "Ack"????
|
||||
|
||||
done->Run();
|
||||
return;
|
||||
|
||||
_invalid_port:
|
||||
controller->SetFailed("invalid portid");
|
||||
done->Run();
|
||||
}
|
||||
|
||||
void MyService::deleteStream(::google::protobuf::RpcController* controller,
|
||||
const ::OstProto::StreamIdList* request,
|
||||
::OstProto::Ack* response,
|
||||
::google::protobuf::Closure* done)
|
||||
{
|
||||
int portId;
|
||||
|
||||
qDebug("In %s", __PRETTY_FUNCTION__);
|
||||
|
||||
portId = request->port_id().id();
|
||||
if ((portId < 0) || (portId >= portInfo.size()))
|
||||
goto _invalid_port;
|
||||
|
||||
for (int i = 0; i < request->stream_id_size(); i++)
|
||||
portInfo[portId]->deleteStream(request->stream_id(i).id());
|
||||
|
||||
//! \todo (LOW): fill-in response "Ack"????
|
||||
|
||||
done->Run();
|
||||
return;
|
||||
|
||||
_invalid_port:
|
||||
controller->SetFailed("invalid portid");
|
||||
done->Run();
|
||||
}
|
||||
|
||||
void MyService::modifyStream(::google::protobuf::RpcController* controller,
|
||||
const ::OstProto::StreamConfigList* request,
|
||||
::OstProto::Ack* response,
|
||||
::google::protobuf::Closure* done)
|
||||
{
|
||||
int portId;
|
||||
|
||||
qDebug("In %s", __PRETTY_FUNCTION__);
|
||||
|
||||
portId = request->port_id().id();
|
||||
if ((portId < 0) || (portId >= portInfo.size()))
|
||||
goto _invalid_port;
|
||||
|
||||
for (int i = 0; i < request->stream_size(); i++)
|
||||
{
|
||||
StreamBase *stream;
|
||||
|
||||
stream = portInfo[portId]->stream(request->stream(i).stream_id().id());
|
||||
if (stream)
|
||||
{
|
||||
stream->protoDataCopyFrom(request->stream(i));
|
||||
portInfo[portId]->setDirty();
|
||||
}
|
||||
}
|
||||
|
||||
//! \todo(LOW): fill-in response "Ack"????
|
||||
|
||||
done->Run();
|
||||
return;
|
||||
|
||||
_invalid_port:
|
||||
controller->SetFailed("invalid portid");
|
||||
done->Run();
|
||||
}
|
||||
|
||||
void MyService::startTx(::google::protobuf::RpcController* controller,
|
||||
const ::OstProto::PortIdList* request,
|
||||
::OstProto::Ack* response,
|
||||
::google::protobuf::Closure* done)
|
||||
{
|
||||
qDebug("In %s", __PRETTY_FUNCTION__);
|
||||
|
||||
for (int i = 0; i < request->port_id_size(); i++)
|
||||
{
|
||||
int portId;
|
||||
|
||||
portId = request->port_id(i).id();
|
||||
if ((portId < 0) || (portId >= portInfo.size()))
|
||||
continue; //! \todo (LOW): partial RPC?
|
||||
|
||||
portInfo[portId]->startTransmit();
|
||||
}
|
||||
|
||||
//! \todo (LOW): fill-in response "Ack"????
|
||||
|
||||
done->Run();
|
||||
}
|
||||
|
||||
void MyService::stopTx(::google::protobuf::RpcController* controller,
|
||||
const ::OstProto::PortIdList* request,
|
||||
::OstProto::Ack* response,
|
||||
::google::protobuf::Closure* done)
|
||||
{
|
||||
qDebug("In %s", __PRETTY_FUNCTION__);
|
||||
|
||||
for (int i = 0; i < request->port_id_size(); i++)
|
||||
{
|
||||
int portId;
|
||||
|
||||
portId = request->port_id(i).id();
|
||||
if ((portId < 0) || (portId >= portInfo.size()))
|
||||
continue; //! \todo (LOW): partial RPC?
|
||||
|
||||
portInfo[portId]->stopTransmit();
|
||||
}
|
||||
|
||||
//! \todo (LOW): fill-in response "Ack"????
|
||||
|
||||
done->Run();
|
||||
}
|
||||
|
||||
void MyService::startCapture(::google::protobuf::RpcController* controller,
|
||||
const ::OstProto::PortIdList* request,
|
||||
::OstProto::Ack* response,
|
||||
::google::protobuf::Closure* done)
|
||||
{
|
||||
qDebug("In %s", __PRETTY_FUNCTION__);
|
||||
|
||||
for (int i = 0; i < request->port_id_size(); i++)
|
||||
{
|
||||
int portId;
|
||||
|
||||
portId = request->port_id(i).id();
|
||||
if ((portId < 0) || (portId >= portInfo.size()))
|
||||
continue; //! \todo (LOW): partial RPC?
|
||||
|
||||
portInfo[portId]->startCapture();
|
||||
}
|
||||
|
||||
//! \todo (LOW): fill-in response "Ack"????
|
||||
|
||||
done->Run();
|
||||
}
|
||||
|
||||
void MyService::stopCapture(::google::protobuf::RpcController* controller,
|
||||
const ::OstProto::PortIdList* request,
|
||||
::OstProto::Ack* response,
|
||||
::google::protobuf::Closure* done)
|
||||
{
|
||||
qDebug("In %s", __PRETTY_FUNCTION__);
|
||||
for (int i=0; i < request->port_id_size(); i++)
|
||||
{
|
||||
int portId;
|
||||
|
||||
portId = request->port_id(i).id();
|
||||
if ((portId < 0) || (portId >= portInfo.size()))
|
||||
continue; //! \todo (LOW): partial RPC?
|
||||
|
||||
portInfo[portId]->stopCapture();
|
||||
}
|
||||
|
||||
//! \todo (LOW): fill-in response "Ack"????
|
||||
|
||||
done->Run();
|
||||
}
|
||||
|
||||
void MyService::getCaptureBuffer(::google::protobuf::RpcController* controller,
|
||||
const ::OstProto::PortId* request,
|
||||
::OstProto::CaptureBuffer* response,
|
||||
::google::protobuf::Closure* done)
|
||||
{
|
||||
int portId;
|
||||
|
||||
qDebug("In %s", __PRETTY_FUNCTION__);
|
||||
|
||||
portId = request->id();
|
||||
if ((portId < 0) || (portId >= portInfo.size()))
|
||||
goto _invalid_port;
|
||||
|
||||
portInfo[portId]->stopCapture();
|
||||
static_cast<PbRpcController*>(controller)->setBinaryBlob(
|
||||
portInfo[portId]->captureData());
|
||||
|
||||
done->Run();
|
||||
return;
|
||||
|
||||
_invalid_port:
|
||||
controller->SetFailed("invalid portid");
|
||||
done->Run();
|
||||
}
|
||||
|
||||
void MyService::getStats(::google::protobuf::RpcController* controller,
|
||||
const ::OstProto::PortIdList* request,
|
||||
::OstProto::PortStatsList* response,
|
||||
::google::protobuf::Closure* done)
|
||||
{
|
||||
//qDebug("In %s", __PRETTY_FUNCTION__);
|
||||
|
||||
for (int i = 0; i < request->port_id_size(); i++)
|
||||
{
|
||||
int portId;
|
||||
AbstractPort::PortStats stats;
|
||||
OstProto::PortStats *s;
|
||||
OstProto::PortState *st;
|
||||
|
||||
portId = request->port_id(i).id();
|
||||
if ((portId < 0) || (portId >= portInfo.size()))
|
||||
continue; //! \todo(LOW): partial rpc?
|
||||
|
||||
s = response->add_port_stats();
|
||||
s->mutable_port_id()->set_id(request->port_id(i).id());
|
||||
|
||||
st = s->mutable_state();
|
||||
st->set_link_state(portInfo[portId]->linkState());
|
||||
st->set_is_transmit_on(portInfo[portId]->isTransmitOn());
|
||||
st->set_is_capture_on(portInfo[portId]->isCaptureOn());
|
||||
|
||||
portInfo[portId]->stats(&stats);
|
||||
|
||||
#if 0
|
||||
if (portId == 2)
|
||||
qDebug(">%llu", stats.rxPkts);
|
||||
#endif
|
||||
|
||||
s->set_rx_pkts(stats.rxPkts);
|
||||
s->set_rx_bytes(stats.rxBytes);
|
||||
s->set_rx_pps(stats.rxPps);
|
||||
s->set_rx_bps(stats.rxBps);
|
||||
|
||||
s->set_tx_pkts(stats.txPkts);
|
||||
s->set_tx_bytes(stats.txBytes);
|
||||
s->set_tx_pps(stats.txPps);
|
||||
s->set_tx_bps(stats.txBps);
|
||||
}
|
||||
|
||||
done->Run();
|
||||
}
|
||||
|
||||
void MyService::clearStats(::google::protobuf::RpcController* controller,
|
||||
const ::OstProto::PortIdList* request,
|
||||
::OstProto::Ack* response,
|
||||
::google::protobuf::Closure* done)
|
||||
{
|
||||
qDebug("In %s", __PRETTY_FUNCTION__);
|
||||
|
||||
for (int i = 0; i < request->port_id_size(); i++)
|
||||
{
|
||||
int portId;
|
||||
|
||||
portId = request->port_id(i).id();
|
||||
if ((portId < 0) || (portId >= portInfo.size()))
|
||||
continue; //! \todo (LOW): partial RPC?
|
||||
|
||||
portInfo[portId]->resetStats();
|
||||
}
|
||||
|
||||
//! \todo (LOW): fill-in response "Ack"????
|
||||
|
||||
done->Run();
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user