Converted all EOLs to unix-style '\n' only

This commit is contained in:
Srivats P. 2009-12-28 10:05:42 +00:00
parent a9e9a7db07
commit c5bcc2e0c2
46 changed files with 6981 additions and 6981 deletions

View File

@ -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);
}
}

View File

@ -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;
};

View File

@ -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

View File

@ -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

View File

@ -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();
}

View File

@ -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;
}

View File

@ -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

View File

@ -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)

View File

@ -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();
}

View File

@ -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

View File

@ -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);
}
}

View File

@ -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

File diff suppressed because it is too large Load Diff

View File

@ -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

View File

@ -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;
}

View File

@ -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

View File

@ -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();
}

View File

@ -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

View File

@ -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);
}
}

View File

@ -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

View File

@ -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);
}

View File

@ -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

View File

@ -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);
}
}
}

View File

@ -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

View File

@ -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");
}

View File

@ -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

View File

@ -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
}

View File

@ -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

View File

@ -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 &current, 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 &current, 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

View File

@ -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 &current)
{
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 &current)
{
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();
}

View File

@ -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 &current);
};
#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 &current);
};
#endif

View File

@ -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);
}

View File

@ -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

View File

@ -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

View File

@ -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);
}

View File

@ -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

View File

@ -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

View File

@ -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

View File

@ -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;
}

View File

@ -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

View File

@ -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();
}
}

View File

@ -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

View File

@ -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

View File

@ -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;
}

View File

@ -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();
}