- added PortStatsFilter
- added PacketDump (test code) - added PacketTree (not complete) - Protocol stuff (not complete)
This commit is contained in:
parent
7e8d8308e3
commit
8251383351
175
client/dumpview.cpp
Normal file
175
client/dumpview.cpp
Normal file
@ -0,0 +1,175 @@
|
||||
#include "dumpview.h"
|
||||
|
||||
DumpView::DumpView(QWidget *parent)
|
||||
{
|
||||
int w, h;
|
||||
|
||||
data.resize(73);
|
||||
|
||||
// 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
|
||||
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");
|
||||
}
|
||||
|
||||
#if 0
|
||||
QSize DumpView::sizeHint() const
|
||||
{
|
||||
}
|
||||
#endif
|
||||
|
||||
void DumpView::mousePressEvent(QMouseEvent *event)
|
||||
{
|
||||
int x = event->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 = event->y()/mLineHeight;
|
||||
|
||||
if ((col < 16) && (row < ((data.size()+16)/16)))
|
||||
{
|
||||
mSelectedRow = row;
|
||||
mSelectedCol = 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)", mSelectedRow, mSelectedCol);
|
||||
update();
|
||||
return;
|
||||
|
||||
_exit:
|
||||
// Clear existing selection
|
||||
mSelectedRow = -1;
|
||||
update();
|
||||
}
|
||||
|
||||
void DumpView::paintEvent(QPaintEvent* event)
|
||||
{
|
||||
QStylePainter painter(this);
|
||||
QRect offsetRect = mOffsetPaneTopRect;
|
||||
QRect dumpRect = mDumpPaneTopRect;
|
||||
QRect asciiRect = mAsciiPaneTopRect;
|
||||
QPalette pal = palette();
|
||||
QByteArray ba;
|
||||
|
||||
//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)));
|
||||
|
||||
// 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);
|
||||
|
||||
// overpaint selection (if any)
|
||||
if ((i/16) == mSelectedRow)
|
||||
{
|
||||
QRect r;
|
||||
unsigned char c = data.at(mSelectedRow*16+mSelectedCol);
|
||||
QString selectedAsciiStr, selectedDumpStr;
|
||||
|
||||
qDebug("dumpview::paintEvent - Highlighted");
|
||||
|
||||
selectedDumpStr.append(QString("%1").arg((uint) c, 2, 16, QChar('0')).toUpper());
|
||||
|
||||
if (isPrintable(c))
|
||||
selectedAsciiStr.append(QChar(c));
|
||||
else
|
||||
selectedAsciiStr.append(QChar('.'));
|
||||
|
||||
// display dump
|
||||
r = dumpRect;
|
||||
if (mSelectedCol < 8)
|
||||
r.translate(mCharWidth*(mSelectedCol*3), 0);
|
||||
else
|
||||
r.translate(mCharWidth*(mSelectedCol*3+1), 0);
|
||||
r.setWidth(mCharWidth*2);
|
||||
painter.fillRect(r, pal.highlight());
|
||||
painter.drawItemText(r, Qt::AlignLeft | Qt::AlignTop, pal,
|
||||
true, selectedDumpStr, QPalette::HighlightedText);
|
||||
|
||||
// display ascii
|
||||
r = asciiRect;
|
||||
if (mSelectedCol < 8)
|
||||
r.translate(mCharWidth*(mSelectedCol), 0);
|
||||
else
|
||||
r.translate(mCharWidth*(mSelectedCol+1), 0);
|
||||
r.setWidth(mCharWidth);
|
||||
painter.fillRect(r, pal.highlight());
|
||||
painter.drawItemText(r, Qt::AlignLeft | Qt::AlignTop, pal,
|
||||
true, selectedAsciiStr, QPalette::HighlightedText);
|
||||
}
|
||||
|
||||
// move the rects down
|
||||
offsetRect.translate(0, mLineHeight);
|
||||
dumpRect.translate(0, mLineHeight);
|
||||
asciiRect.translate(0, mLineHeight);
|
||||
}
|
||||
}
|
34
client/dumpview.h
Normal file
34
client/dumpview.h
Normal file
@ -0,0 +1,34 @@
|
||||
#include <QtGui> // FIXME: High
|
||||
|
||||
class DumpView: public QWidget // QAbstractItemView // FIXME
|
||||
{
|
||||
public:
|
||||
DumpView(QWidget *parent=0);
|
||||
// bool setBase(uint base); // valid values: 16, 8, 10, 2 etc.
|
||||
// void hideAsciiPane(void);
|
||||
// void showAsciiPane(void);
|
||||
// void hideOffsetPane(void);
|
||||
// void showOffsetPane(void);
|
||||
|
||||
|
||||
//QSize sizeHint() const;
|
||||
|
||||
protected:
|
||||
void mousePressEvent(QMouseEvent *event);
|
||||
//void mouseMoveEvent(QMouseEvent *event);
|
||||
void paintEvent(QPaintEvent *event);
|
||||
|
||||
private:
|
||||
QString toAscii(QByteArray ba);
|
||||
bool inline isPrintable(char c)
|
||||
{if ((c > 48) && (c < 126)) return true; else return false; }
|
||||
|
||||
private:
|
||||
QRect mOffsetPaneTopRect;
|
||||
QRect mDumpPaneTopRect;
|
||||
QRect mAsciiPaneTopRect;
|
||||
QByteArray data;
|
||||
int mSelectedRow, mSelectedCol;
|
||||
int mLineHeight;
|
||||
int mCharWidth;
|
||||
};
|
BIN
client/icons/portstats_filter.png
Normal file
BIN
client/icons/portstats_filter.png
Normal file
Binary file not shown.
After Width: | Height: | Size: 432 B |
@ -3,14 +3,17 @@ CONFIG += qt debug
|
||||
QT += network
|
||||
RESOURCES += ostinato.qrc
|
||||
HEADERS += \
|
||||
dumpview.h \
|
||||
hexlineedit.h \
|
||||
mainwindow.h \
|
||||
mythread.h \
|
||||
packetmodel.h \
|
||||
port.h \
|
||||
portgroup.h \
|
||||
portgrouplist.h \
|
||||
portmodel.h \
|
||||
portstatsmodel.h \
|
||||
portstatsfilterdialog.h \
|
||||
portstatswindow.h \
|
||||
portswindow.h \
|
||||
streamconfigdialog.h \
|
||||
@ -18,21 +21,25 @@ HEADERS += \
|
||||
|
||||
FORMS += \
|
||||
mainwindow.ui \
|
||||
portstatsfilter.ui \
|
||||
portstatswindow.ui \
|
||||
portswindow.ui \
|
||||
streamconfigdialog.ui
|
||||
|
||||
SOURCES += \
|
||||
dumpview.cpp \
|
||||
stream.cpp \
|
||||
hexlineedit.cpp \
|
||||
main.cpp \
|
||||
mainwindow.cpp \
|
||||
mythread.cpp \
|
||||
packetmodel.cpp \
|
||||
port.cpp \
|
||||
portgroup.cpp \
|
||||
portgrouplist.cpp \
|
||||
portmodel.cpp \
|
||||
portstatsmodel.cpp \
|
||||
portstatsfilterdialog.cpp \
|
||||
portstatswindow.cpp \
|
||||
portswindow.cpp \
|
||||
streamconfigdialog.cpp \
|
||||
|
@ -12,6 +12,7 @@
|
||||
<file>icons/portgroup_connect.png</file>
|
||||
<file>icons/portgroup_delete.png</file>
|
||||
<file>icons/portgroup_disconnect.png</file>
|
||||
<file>icons/portstats_filter.png</file>
|
||||
<file>icons/sound_mute.png</file>
|
||||
<file>icons/sound_none.png</file>
|
||||
<file>icons/stream_add.png</file>
|
||||
|
440
client/packetmodel.cpp
Normal file
440
client/packetmodel.cpp
Normal file
@ -0,0 +1,440 @@
|
||||
#include "packetmodel.h"
|
||||
|
||||
|
||||
PacketModel::PacketModel(Stream *pStream, QObject *parent)
|
||||
{
|
||||
mpStream = pStream;
|
||||
}
|
||||
|
||||
int PacketModel::rowCount(const QModelIndex &parent) const
|
||||
{
|
||||
// Parent - Invisible Root.
|
||||
// Children - Top Level Items
|
||||
if (!parent.isValid())
|
||||
{
|
||||
int v = 0;
|
||||
|
||||
if (mpStream->l2.eth.vlanMask & VM_SVLAN_TAGGED)
|
||||
v++;
|
||||
if (mpStream->l2.eth.vlanMask & VM_CVLAN_TAGGED)
|
||||
v++;
|
||||
|
||||
if (mpStream->proto.protoMask & PM_L3_PROTO_NONE)
|
||||
return v+2; // L2, Data
|
||||
if (mpStream->proto.protoMask & PM_L4_PROTO_NONE)
|
||||
return v+3; // L2, L3, Data
|
||||
else
|
||||
return v+4; // L2, L3, L4, Data
|
||||
}
|
||||
|
||||
// Parent - Top Level Item (L2)
|
||||
// Children(count) - Second Level Items (L2 fields)
|
||||
if (isIndexL2Container(parent))
|
||||
{
|
||||
switch(mpStream->proto.ft)
|
||||
{
|
||||
case Stream::e_ft_none:
|
||||
return 2; // DstMac, SrcMac
|
||||
break;
|
||||
|
||||
case Stream::e_ft_eth_2:
|
||||
case Stream::e_ft_802_3_raw:
|
||||
return 3; // DstMac, SrcMac, Type/Len
|
||||
break;
|
||||
|
||||
case Stream::e_ft_802_3_llc:
|
||||
case Stream::e_ft_snap:
|
||||
return 5; // DstMac, SrcMac, Type, DSAP, SSAP, CTL, OUI, Type
|
||||
break;
|
||||
|
||||
default:
|
||||
qDebug("%s: Unsupported frametype", __FUNCTION__);
|
||||
return -1;
|
||||
}
|
||||
}
|
||||
|
||||
// Parent - Top Level Item (SVLAN)
|
||||
// Children(count) - Second Level Items (SVLAN fields)
|
||||
if (isIndexSvlanContainer(parent))
|
||||
{
|
||||
return 4; // TPID, PCP, DE, VlanId
|
||||
}
|
||||
|
||||
// Parent - Top Level Item (CVLAN)
|
||||
// Children(count) - Second Level Items (CVLAN fields)
|
||||
if (isIndexCvlanContainer(parent))
|
||||
{
|
||||
return 4; // TPID, Prio, CFI, VlanId
|
||||
}
|
||||
|
||||
// Parent - Top Level Item (L3)
|
||||
// Children(count) - Second Level Items (L3 fields)
|
||||
if (isIndexL3Container(parent))
|
||||
{
|
||||
// L3 cannot be "None"
|
||||
Q_ASSERT(mpStream->proto.protoMask & PM_L3_PROTO_NONE);
|
||||
|
||||
switch(mpStream->proto.etherType)
|
||||
{
|
||||
case ETH_TYP_IP:
|
||||
return 12; // Ver, HdrLen, TOS, TotLen, Id, Flags,
|
||||
// FragOfs, TTL, Proto, Cksum, SrcIp, DstIp
|
||||
break;
|
||||
case ETH_TYP_ARP:
|
||||
return 0; // TODO(LOW)
|
||||
break;
|
||||
default:
|
||||
qDebug("%s: Unsupported ethtype", __FUNCTION__);
|
||||
return -1;
|
||||
}
|
||||
}
|
||||
|
||||
// Parent - Top Level Item (L4)
|
||||
// Children(count) - Second Level Items (L4 fields)
|
||||
if (isIndexL4Container(parent))
|
||||
{
|
||||
// L4 cannot be "None"
|
||||
Q_ASSERT(mpStream->proto.protoMask & PM_L4_PROTO_NONE);
|
||||
|
||||
switch(mpStream->proto.ipProto)
|
||||
{
|
||||
case IP_PROTO_TCP:
|
||||
return 10; // SrcPort, DstPort, SeqNum, AckNum, HdrLen,
|
||||
// Rsvd, Flags, Window, Cksum, UrgPtr,
|
||||
break;
|
||||
case IP_PROTO_UDP:
|
||||
return 4; // SrcPort, DstPort, TotLen, Cksum
|
||||
break;
|
||||
case IP_PROTO_ICMP:
|
||||
case IP_PROTO_IGMP:
|
||||
return 0; // TODO(LOW)
|
||||
break;
|
||||
default:
|
||||
qDebug("%s: Unsupported ethtype", __FUNCTION__);
|
||||
return -1;
|
||||
}
|
||||
}
|
||||
|
||||
// Parent - Second Level Item (L2 field)
|
||||
// Children(count) - Third Level Items (L2 subfield)
|
||||
if (isIndexL2Field(parent))
|
||||
{
|
||||
return 0; // No subfields for any L2 field
|
||||
}
|
||||
|
||||
// Parent - Second Level Item (L3 field)
|
||||
// Children(count) - Third Level Items (L3 subfield)
|
||||
if (isIndexL3Field(parent))
|
||||
{
|
||||
if (isIndexIpField(parent))
|
||||
return 0; // TODO (MED)
|
||||
if (isIndexArpField(parent))
|
||||
return 0; // TODO (LOW)
|
||||
|
||||
qDebug("%s: Unknown L3 Field", __FUNCTION__);
|
||||
return 0; // catch all
|
||||
}
|
||||
|
||||
// Parent - Second Level Item (L4 field)
|
||||
// Children(count) - Third Level Items (L4 subfield)
|
||||
if (isIndexL4Field(parent))
|
||||
{
|
||||
if (isIndexTcpField(parent))
|
||||
return 0; // TODO (MED)
|
||||
if (isIndexUdpField(parent))
|
||||
return 0; // No subfields for any UDP fields
|
||||
if (isIndexIcmpField(parent))
|
||||
return 0; // TODO (LOW)
|
||||
if (isIndexIgmpField(parent))
|
||||
return 0; // TODO (LOW)
|
||||
|
||||
qDebug("%s: Unknown L4 Field", __FUNCTION__);
|
||||
return 0; // catch all
|
||||
}
|
||||
|
||||
//qDebug("%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;
|
||||
uint vlanMask = mpStream->l2.eth.vlanMask;
|
||||
|
||||
if (!hasIndex(row, col, parent))
|
||||
goto _exit;
|
||||
|
||||
parentId.w = parent.internalId();
|
||||
|
||||
// Parent - Invisible Root
|
||||
// Requested child - First/Top Level Item
|
||||
if (parentId.ws.b2 == 0xFF)
|
||||
{
|
||||
Q_ASSERT(!parent.isValid());
|
||||
|
||||
if (mpStream->l2.eth.vlanMask & VM_UNTAGGED)
|
||||
id.ws.b1 = row+2; // Only L2, L3, L4
|
||||
else if (VM_SINGLE_TAGGED(vlanMask))
|
||||
{
|
||||
switch (row)
|
||||
{
|
||||
case 0: id.ws.b1 = 2; break; // L2
|
||||
case 1: id.ws.b1 = (vlanMask & VM_SVLAN_TAGGED)?0x88:0x81; break;
|
||||
case 2: id.ws.b1 = 3; break; // L3
|
||||
case 3: id.ws.b1 = 4; break; // L4
|
||||
case 4: id.ws.b1 = 0; break; // Data
|
||||
default: qWarning("%s: Unexpected row (%d)", __FUNCTION__, row);
|
||||
}
|
||||
}
|
||||
else if (VM_DOUBLE_TAGGED(vlanMask))
|
||||
{
|
||||
switch (row)
|
||||
{
|
||||
case 0: id.ws.b1 = 2; break; // L2
|
||||
case 1: id.ws.b1 = 0x88; break; // SVLAN
|
||||
case 2: id.ws.b1 = 0x81; break; // CVLAN
|
||||
case 3: id.ws.b1 = 3; break; // L3
|
||||
case 4: id.ws.b1 = 4; break; // L4
|
||||
case 5: id.ws.b1 = 0; break; // Data
|
||||
default: qWarning("%s: Unexpected row (%d)", __FUNCTION__, row);
|
||||
}
|
||||
}
|
||||
id.ws.b2 = 0xFF;
|
||||
index = createIndex(row, col, id.w);
|
||||
goto _exit;
|
||||
}
|
||||
|
||||
// Parent - First Level Item
|
||||
// Requested child - Second Level Item
|
||||
if (parentId.ws.b3 == 0xFF)
|
||||
{
|
||||
Q_ASSERT(parentId.ws.b1 != 0xFF);
|
||||
Q_ASSERT(parentId.ws.b2 != 0xFF);
|
||||
|
||||
id.ws.b1 = parentId.ws.b1;
|
||||
id.ws.b2 = 0; // TODO(MED): Set Field Id for subfields
|
||||
index = createIndex(row, col, id.w);
|
||||
goto _exit;
|
||||
}
|
||||
|
||||
// Parent - Second Level Item (Field)
|
||||
// Requested child - Third Level Item (Subfield)
|
||||
// TODO(MED): Support subfields
|
||||
// Till then we return an invalid index
|
||||
|
||||
_exit:
|
||||
return index;
|
||||
}
|
||||
|
||||
QModelIndex PacketModel::parent(const QModelIndex &index) const
|
||||
{
|
||||
IndexId id, parentId;
|
||||
|
||||
id.w = index.internalId();
|
||||
parentId = id;
|
||||
|
||||
// 1st/Top Level Item - Protocol
|
||||
// Requested Parent => Invisible Root
|
||||
if (id.ws.b2 == 0xFF)
|
||||
return QModelIndex();
|
||||
|
||||
// Second Level Item - Field
|
||||
// Requested Parent => 1st Level Item (Protocol)
|
||||
if (id.ws.b3 == 0xFF)
|
||||
{
|
||||
uint vlanMask = mpStream->l2.eth.vlanMask;
|
||||
int row = -1;
|
||||
|
||||
parentId.ws.b2 = 0xFF;
|
||||
|
||||
if (vlanMask & VM_UNTAGGED)
|
||||
{
|
||||
row = parentId.ws.b1 - 2;
|
||||
}
|
||||
else if (VM_SINGLE_TAGGED(vlanMask))
|
||||
{
|
||||
switch (parentId.ws.b1)
|
||||
{
|
||||
case 2: row = 0; break; // L2
|
||||
case 0x88:
|
||||
case 0x81: row = 1; break; // SVlan/CVlan
|
||||
case 3: row = 2; break; // L3
|
||||
case 4: row = 3; break; // L4
|
||||
case 0: row = 4; break; // Data
|
||||
default: qWarning("%s: Unexpected b1 (%d)", __FUNCTION__, parentId.ws.b1);
|
||||
}
|
||||
}
|
||||
else if (VM_DOUBLE_TAGGED(vlanMask))
|
||||
{
|
||||
switch (parentId.ws.b1)
|
||||
{
|
||||
case 2: row = 0; break; // L2
|
||||
case 0x88: row = 1; break; // Svlan
|
||||
case 0x81: row = 2; break; // CVlan
|
||||
case 3: row = 3; break; // L3
|
||||
case 4: row = 4; break; // L4
|
||||
case 0: row = 5; break; // Data
|
||||
default: qWarning("%s: Unexpected b1 (%d)", __FUNCTION__, parentId.ws.b1);
|
||||
}
|
||||
}
|
||||
else
|
||||
qWarning("%s: Unhandled leg", __FUNCTION__);
|
||||
|
||||
return createIndex(row, 0, parentId.w);
|
||||
}
|
||||
|
||||
// Third Level Item - Subfield
|
||||
// Requested Parent => 2nd Level Item (Field)
|
||||
// TODO(Med)
|
||||
qWarning("%s: Unexpected leg", __FUNCTION__);
|
||||
return QModelIndex();
|
||||
}
|
||||
|
||||
QVariant PacketModel::data(const QModelIndex &index, int role) const
|
||||
{
|
||||
IndexId id;
|
||||
|
||||
id.w = index.internalId();
|
||||
|
||||
if (id.ws.b2 == 0xFF)
|
||||
return QString("Protocol Header");
|
||||
else
|
||||
return QString("Field: Value");
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
** --------------- Private Stuff -----------------
|
||||
*/
|
||||
typedef union
|
||||
{
|
||||
quint32 w;
|
||||
struct
|
||||
{
|
||||
quint8 b1;
|
||||
quint8 b2;
|
||||
quint8 b3;
|
||||
quint8 b4;
|
||||
} ws;
|
||||
} IndexId;
|
||||
|
||||
bool PacketModel::isIndexContainer(const QModelIndex& index, int level) const
|
||||
{
|
||||
IndexId id;
|
||||
|
||||
id.w = index.internalId();
|
||||
if ((id.ws.b1 == level) && (id.ws.b2 == 0xFF))
|
||||
return true;
|
||||
else
|
||||
return false;
|
||||
}
|
||||
|
||||
bool PacketModel::isIndexL2Container(const QModelIndex& index) const
|
||||
{
|
||||
return isIndexContainer(index, 2);
|
||||
}
|
||||
|
||||
bool PacketModel::isIndexSvlanContainer(const QModelIndex& index) const
|
||||
{
|
||||
return isIndexContainer(index, 0x88);
|
||||
}
|
||||
|
||||
bool PacketModel::isIndexCvlanContainer(const QModelIndex& index) const
|
||||
{
|
||||
return isIndexContainer(index, 0x81);
|
||||
}
|
||||
|
||||
bool PacketModel::isIndexL3Container(const QModelIndex& index) const
|
||||
{
|
||||
return isIndexContainer(index, 3);
|
||||
}
|
||||
|
||||
bool PacketModel::isIndexL4Container(const QModelIndex& index) const
|
||||
{
|
||||
return isIndexContainer(index, 4);
|
||||
}
|
||||
|
||||
bool PacketModel::isIndexField(const QModelIndex& index, int level) const
|
||||
{
|
||||
IndexId id;
|
||||
|
||||
id.w = index.internalId();
|
||||
if ((id.ws.b1 == level) && (id.ws.b2 != 0xFF) && (id.ws.b3 == 0xFF))
|
||||
return true;
|
||||
else
|
||||
return false;
|
||||
}
|
||||
|
||||
bool PacketModel::isIndexL2Field(const QModelIndex& index) const
|
||||
{
|
||||
return isIndexField(index, 2);
|
||||
}
|
||||
|
||||
bool PacketModel::isIndexL3Field(const QModelIndex& index) const
|
||||
{
|
||||
return isIndexField(index, 3);
|
||||
}
|
||||
|
||||
bool PacketModel::isIndexL4Field(const QModelIndex& index) const
|
||||
{
|
||||
return isIndexField(index, 4);
|
||||
}
|
||||
|
||||
bool PacketModel::isIndexIpField(const QModelIndex& index) const
|
||||
{
|
||||
IndexId id;
|
||||
|
||||
id.w = index.internalId();
|
||||
if ((id.ws.b1 == 3) && (id.ws.b2 == 1) && (id.ws.b3 == 0xFF))
|
||||
return true;
|
||||
else
|
||||
return false;
|
||||
}
|
||||
|
||||
bool PacketModel::isIndexArpField(const QModelIndex& index) const
|
||||
{
|
||||
IndexId id;
|
||||
|
||||
id.w = index.internalId();
|
||||
if ((id.ws.b1 == 3) && (id.ws.b2 == 2) && (id.ws.b3 == 0xFF))
|
||||
return true;
|
||||
else
|
||||
return false;
|
||||
}
|
||||
|
||||
bool PacketModel::isIndexL4ProtoField(const QModelIndex& index, int proto) const
|
||||
{
|
||||
IndexId id;
|
||||
|
||||
id.w = index.internalId();
|
||||
if ((id.ws.b1 == 4) && (id.ws.b2 == proto) && (id.ws.b3 == 0xFF))
|
||||
return true;
|
||||
else
|
||||
return false;
|
||||
}
|
||||
|
||||
bool PacketModel::isIndexTcpField(const QModelIndex& index) const
|
||||
{
|
||||
return isIndexL4ProtoField(index, IP_PROTO_TCP);
|
||||
}
|
||||
|
||||
bool PacketModel::isIndexUdpField(const QModelIndex& index) const
|
||||
{
|
||||
return isIndexL4ProtoField(index, IP_PROTO_UDP);
|
||||
}
|
||||
|
||||
bool PacketModel::isIndexIcmpField(const QModelIndex& index) const
|
||||
{
|
||||
return isIndexL4ProtoField(index, IP_PROTO_ICMP);
|
||||
}
|
||||
|
||||
bool PacketModel::isIndexIgmpField(const QModelIndex& index) const
|
||||
{
|
||||
return isIndexL4ProtoField(index, IP_PROTO_IGMP);
|
||||
}
|
52
client/packetmodel.h
Normal file
52
client/packetmodel.h
Normal file
@ -0,0 +1,52 @@
|
||||
#ifndef _PACKET_MODEL_H
|
||||
#define _PACKET_MODEL_H
|
||||
|
||||
#include <QAbstractItemModel>
|
||||
#include "stream.h"
|
||||
|
||||
class PacketModel: public QAbstractItemModel
|
||||
{
|
||||
|
||||
public:
|
||||
PacketModel(Stream *pStream, 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;
|
||||
QModelIndex index (int row, int col, const QModelIndex & parent = QModelIndex() ) const;
|
||||
QModelIndex parent(const QModelIndex &index) const;
|
||||
|
||||
private:
|
||||
Stream *mpStream;
|
||||
typedef union _IndexId
|
||||
{
|
||||
quint32 w;
|
||||
struct
|
||||
{
|
||||
quint8 b1; // 1st Level
|
||||
quint8 b2; // 2nd Level
|
||||
quint8 b3; // 3rd Level
|
||||
quint8 b4; // Reserved
|
||||
} ws;
|
||||
} IndexId;
|
||||
|
||||
bool PacketModel::isIndexContainer(const QModelIndex& index, int level) const;
|
||||
bool PacketModel::isIndexL2Container(const QModelIndex& index) const;
|
||||
bool PacketModel::isIndexSvlanContainer(const QModelIndex& index) const;
|
||||
bool PacketModel::isIndexCvlanContainer(const QModelIndex& index) const;
|
||||
bool PacketModel::isIndexL3Container(const QModelIndex& index) const;
|
||||
bool PacketModel::isIndexL4Container(const QModelIndex& index) const;
|
||||
bool PacketModel::isIndexField(const QModelIndex& index, int level) const;
|
||||
bool PacketModel::isIndexL2Field(const QModelIndex& index) const;
|
||||
bool PacketModel::isIndexL3Field(const QModelIndex& index) const;
|
||||
bool PacketModel::isIndexL4Field(const QModelIndex& index) const;
|
||||
bool PacketModel::isIndexIpField(const QModelIndex& index) const;
|
||||
bool PacketModel::isIndexArpField(const QModelIndex& index) const;
|
||||
bool PacketModel::isIndexL4ProtoField(const QModelIndex& index, int proto) const;
|
||||
bool PacketModel::isIndexTcpField(const QModelIndex& index) const;
|
||||
bool PacketModel::isIndexUdpField(const QModelIndex& index) const;
|
||||
bool PacketModel::isIndexIcmpField(const QModelIndex& index) const;
|
||||
bool PacketModel::isIndexIgmpField(const QModelIndex& index) const;
|
||||
};
|
||||
#endif
|
||||
|
@ -18,7 +18,9 @@ void Port::insertDummyStreams()
|
||||
{
|
||||
mStreams.append(*(new Stream));
|
||||
mStreams[0].setName(QString("%1:%2:0").arg(portGroupId()).arg(id()));
|
||||
#if 1
|
||||
mStreams.append(*(new Stream));
|
||||
mStreams[1].setName(QString("%1:%2:1").arg(portGroupId()).arg(id()));
|
||||
#endif
|
||||
}
|
||||
|
||||
|
@ -100,9 +100,9 @@ void PortGroup::ProcessCapabilityInfo(const char *msg, qint32 size)
|
||||
goto _next;
|
||||
}
|
||||
|
||||
p = new Port(NTOHL(cap->port), mPortGroupId);
|
||||
p->setName(cap->name);
|
||||
p->setDescription(cap->desc);
|
||||
p = new Port(NTOHL(cap->portId), mPortGroupId);
|
||||
p->setName(cap->portName);
|
||||
p->setDescription(cap->portDesc);
|
||||
p->insertDummyStreams(); // FIXME: only for testing
|
||||
qDebug("before port append\n");
|
||||
mPorts.append(*p);
|
||||
@ -137,7 +137,7 @@ void PortGroup::when_connected()
|
||||
pkt.ver = 1;
|
||||
pkt.resv1 = 0;
|
||||
pkt.resv2 = 0;
|
||||
pkt.msgType = HTONS(e_MT_CapabilityReq);
|
||||
pkt.msgType = HTONS(e_MT_GetCapability);
|
||||
pkt.msgLen = HTONS(8);
|
||||
|
||||
mpSocket->write((char*) &pkt, sizeof(pkt));
|
||||
|
@ -1,6 +1,6 @@
|
||||
<ui version="4.0" >
|
||||
<class>Dialog</class>
|
||||
<widget class="QDialog" name="Dialog" >
|
||||
<class>PortStatsFilterDialog</class>
|
||||
<widget class="QDialog" name="PortStatsFilterDialog" >
|
||||
<property name="geometry" >
|
||||
<rect>
|
||||
<x>0</x>
|
||||
@ -16,7 +16,11 @@
|
||||
<item>
|
||||
<layout class="QHBoxLayout" >
|
||||
<item>
|
||||
<widget class="QListView" name="lvAllPorts" />
|
||||
<widget class="QListView" name="lvUnselected" >
|
||||
<property name="selectionMode" >
|
||||
<enum>QAbstractItemView::ExtendedSelection</enum>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<layout class="QVBoxLayout" >
|
||||
@ -34,14 +38,14 @@
|
||||
</spacer>
|
||||
</item>
|
||||
<item>
|
||||
<widget class="QToolButton" name="tbFilterIn" >
|
||||
<widget class="QToolButton" name="tbSelectIn" >
|
||||
<property name="text" >
|
||||
<string>></string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<widget class="QToolButton" name="tbFilterOut" >
|
||||
<widget class="QToolButton" name="tbSelectOut" >
|
||||
<property name="text" >
|
||||
<string><</string>
|
||||
</property>
|
||||
@ -63,7 +67,11 @@
|
||||
</layout>
|
||||
</item>
|
||||
<item>
|
||||
<widget class="QListView" name="lvFilteredPorts" />
|
||||
<widget class="QListView" name="lvSelected" >
|
||||
<property name="selectionMode" >
|
||||
<enum>QAbstractItemView::ExtendedSelection</enum>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
</layout>
|
||||
</item>
|
||||
@ -80,10 +88,10 @@
|
||||
</layout>
|
||||
</widget>
|
||||
<tabstops>
|
||||
<tabstop>lvAllPorts</tabstop>
|
||||
<tabstop>tbFilterIn</tabstop>
|
||||
<tabstop>tbFilterOut</tabstop>
|
||||
<tabstop>lvFilteredPorts</tabstop>
|
||||
<tabstop>lvUnselected</tabstop>
|
||||
<tabstop>tbSelectIn</tabstop>
|
||||
<tabstop>tbSelectOut</tabstop>
|
||||
<tabstop>lvSelected</tabstop>
|
||||
<tabstop>buttonBox</tabstop>
|
||||
</tabstops>
|
||||
<resources/>
|
||||
@ -91,7 +99,7 @@
|
||||
<connection>
|
||||
<sender>buttonBox</sender>
|
||||
<signal>accepted()</signal>
|
||||
<receiver>Dialog</receiver>
|
||||
<receiver>PortStatsFilterDialog</receiver>
|
||||
<slot>accept()</slot>
|
||||
<hints>
|
||||
<hint type="sourcelabel" >
|
||||
@ -107,7 +115,7 @@
|
||||
<connection>
|
||||
<sender>buttonBox</sender>
|
||||
<signal>rejected()</signal>
|
||||
<receiver>Dialog</receiver>
|
||||
<receiver>PortStatsFilterDialog</receiver>
|
||||
<slot>reject()</slot>
|
||||
<hints>
|
||||
<hint type="sourcelabel" >
|
||||
|
@ -1,9 +1,84 @@
|
||||
#include "portstatsfilterdialog.h"
|
||||
|
||||
PortStatsFilterDialog::PortStatsFilterDialog(AbstractItemModel *allPortsModel,
|
||||
QWidget *parent)
|
||||
PortStatsFilterDialog::PortStatsFilterDialog(QWidget *parent)
|
||||
{
|
||||
setupUi(this);
|
||||
|
||||
lvAllPorts->setModel(allPortsModel);
|
||||
// TODO(MED): Use ExtendedSelection and use "selected" instead of
|
||||
// "current" for selecting in/out
|
||||
// TODO(MED): Ensure items are READ-ONLY not editable
|
||||
// TODO(MED): Enable "double-click" on items
|
||||
lvUnselected->setSelectionMode(QAbstractItemView::SingleSelection);
|
||||
lvSelected->setSelectionMode(QAbstractItemView::SingleSelection);
|
||||
|
||||
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);
|
||||
|
||||
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;
|
||||
|
||||
item = mUnselected.takeItem(lvUnselected->currentIndex().row());
|
||||
if (mUnselected.removeRow(lvUnselected->currentIndex().row()))
|
||||
mSelected.appendRow(item);
|
||||
}
|
||||
|
||||
void PortStatsFilterDialog::on_tbSelectOut_clicked()
|
||||
{
|
||||
QStandardItem *item;
|
||||
|
||||
item = mSelected.takeItem(lvSelected->currentIndex().row());
|
||||
if (mSelected.removeRow(lvSelected->currentIndex().row()))
|
||||
{
|
||||
mUnselected.appendRow(item);
|
||||
mUnselected.sort(0);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -3,7 +3,8 @@
|
||||
|
||||
#include <QDialog>
|
||||
#include <QAbstractItemModel>
|
||||
#include "ui_portstatsfilterdialog.h"
|
||||
#include <QStandardItemModel>
|
||||
#include "ui_portstatsfilter.h"
|
||||
#include "portgrouplist.h"
|
||||
|
||||
class PortStatsFilterDialog : public QDialog, public Ui::PortStatsFilterDialog
|
||||
@ -11,8 +12,21 @@ class PortStatsFilterDialog : public QDialog, public Ui::PortStatsFilterDialog
|
||||
Q_OBJECT
|
||||
|
||||
public:
|
||||
PortStatsFilterDialog(AbstractItemModel *allPortsModel,
|
||||
QWidget *parent = 0);
|
||||
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();
|
||||
};
|
||||
|
||||
#endif
|
||||
|
@ -1,15 +1,37 @@
|
||||
|
||||
#include "portstatswindow.h"
|
||||
#include "portstatsmodel.h"
|
||||
#include "portstatsfilterdialog.h"
|
||||
|
||||
#include "QHeaderView"
|
||||
|
||||
//PortStatsWindow::PortStatsWindow(QWidget *parent) : QDialog (parent)
|
||||
PortStatsWindow::PortStatsWindow(PortGroupList *pgl, QWidget *parent)
|
||||
{
|
||||
setupUi(this);
|
||||
|
||||
tvPortStats->setModel(pgl->getPortStatsModel());
|
||||
|
||||
model = pgl->getPortStatsModel();
|
||||
tvPortStats->setModel(model);
|
||||
tvPortStats->horizontalHeader()->setMovable(true);
|
||||
}
|
||||
|
||||
PortStatsWindow::~PortStatsWindow()
|
||||
{
|
||||
}
|
||||
|
||||
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)
|
||||
for(int i = 0; i < model->columnCount(); i++)
|
||||
tvPortStats->setColumnHidden(i, !newColumns.contains(i));
|
||||
}
|
||||
|
@ -15,6 +15,9 @@ public:
|
||||
~PortStatsWindow();
|
||||
private:
|
||||
QAbstractItemModel *model;
|
||||
|
||||
private slots:
|
||||
void on_tbFilter_clicked();
|
||||
};
|
||||
|
||||
#endif
|
||||
|
@ -1,133 +1,192 @@
|
||||
<ui version="4.0" >
|
||||
<class>PortStatsWindow</class>
|
||||
<widget class="QWidget" name="PortStatsWindow" >
|
||||
<property name="geometry" >
|
||||
<rect>
|
||||
<x>0</x>
|
||||
<y>0</y>
|
||||
<width>502</width>
|
||||
<height>415</height>
|
||||
</rect>
|
||||
</property>
|
||||
<property name="windowTitle" >
|
||||
<string>Form</string>
|
||||
</property>
|
||||
<layout class="QVBoxLayout" >
|
||||
<item>
|
||||
<widget class="QFrame" name="frame" >
|
||||
<property name="frameShape" >
|
||||
<enum>QFrame::StyledPanel</enum>
|
||||
</property>
|
||||
<property name="frameShadow" >
|
||||
<enum>QFrame::Raised</enum>
|
||||
</property>
|
||||
<layout class="QHBoxLayout" >
|
||||
<item>
|
||||
<widget class="QToolButton" name="tbStartTransmit" >
|
||||
<property name="toolTip" >
|
||||
<string>Start Transmit</string>
|
||||
</property>
|
||||
<property name="statusTip" >
|
||||
<string>Stop Transmit</string>
|
||||
</property>
|
||||
<property name="text" >
|
||||
<string>Start Transmit</string>
|
||||
</property>
|
||||
<property name="icon" >
|
||||
<iconset resource="ostinato.qrc" >:/icons/control_play.png</iconset>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<widget class="QToolButton" name="tbStopTransmit" >
|
||||
<property name="toolTip" >
|
||||
<string>Stop Transmit</string>
|
||||
</property>
|
||||
<property name="statusTip" >
|
||||
<string>Stop Transmit</string>
|
||||
</property>
|
||||
<property name="text" >
|
||||
<string>Stop Trasmit</string>
|
||||
</property>
|
||||
<property name="icon" >
|
||||
<iconset resource="ostinato.qrc" >:/icons/control_stop.png</iconset>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<widget class="QToolButton" name="tbClear" >
|
||||
<property name="text" >
|
||||
<string>Clear</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<widget class="QToolButton" name="tbClearAll" >
|
||||
<property name="text" >
|
||||
<string>Clear All</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<widget class="QToolButton" name="tbStartCapture" >
|
||||
<property name="text" >
|
||||
<string>Start Capture</string>
|
||||
</property>
|
||||
<property name="icon" >
|
||||
<iconset resource="ostinato.qrc" >:/icons/sound_none.png</iconset>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<widget class="QToolButton" name="tbStopCapture" >
|
||||
<property name="text" >
|
||||
<string>Stop Capture</string>
|
||||
</property>
|
||||
<property name="icon" >
|
||||
<iconset resource="ostinato.qrc" >:/icons/sound_mute.png</iconset>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<widget class="QToolButton" name="tbViewCapture" >
|
||||
<property name="text" >
|
||||
<string>View Capture</string>
|
||||
</property>
|
||||
<property name="icon" >
|
||||
<iconset resource="ostinato.qrc" >:/icons/magnifier.png</iconset>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<widget class="Line" name="line" >
|
||||
<property name="orientation" >
|
||||
<enum>Qt::Vertical</enum>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<spacer>
|
||||
<property name="orientation" >
|
||||
<enum>Qt::Horizontal</enum>
|
||||
</property>
|
||||
<property name="sizeHint" >
|
||||
<size>
|
||||
<width>40</width>
|
||||
<height>20</height>
|
||||
</size>
|
||||
</property>
|
||||
</spacer>
|
||||
</item>
|
||||
</layout>
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<widget class="QTableView" name="tvPortStats" />
|
||||
</item>
|
||||
</layout>
|
||||
</widget>
|
||||
<resources>
|
||||
<include location="ostinato.qrc" />
|
||||
</resources>
|
||||
<connections/>
|
||||
</ui>
|
||||
<ui version="4.0" >
|
||||
<class>PortStatsWindow</class>
|
||||
<widget class="QWidget" name="PortStatsWindow" >
|
||||
<property name="geometry" >
|
||||
<rect>
|
||||
<x>0</x>
|
||||
<y>0</y>
|
||||
<width>502</width>
|
||||
<height>415</height>
|
||||
</rect>
|
||||
</property>
|
||||
<property name="windowTitle" >
|
||||
<string>Form</string>
|
||||
</property>
|
||||
<layout class="QVBoxLayout" >
|
||||
<item>
|
||||
<widget class="QFrame" name="frame" >
|
||||
<property name="toolTip" >
|
||||
<string>Clear All</string>
|
||||
</property>
|
||||
<property name="frameShape" >
|
||||
<enum>QFrame::StyledPanel</enum>
|
||||
</property>
|
||||
<property name="frameShadow" >
|
||||
<enum>QFrame::Raised</enum>
|
||||
</property>
|
||||
<layout class="QHBoxLayout" >
|
||||
<item>
|
||||
<widget class="QToolButton" name="tbStartTransmit" >
|
||||
<property name="toolTip" >
|
||||
<string>Clear All</string>
|
||||
</property>
|
||||
<property name="statusTip" >
|
||||
<string>Starts transmit on selected port(s)</string>
|
||||
</property>
|
||||
<property name="text" >
|
||||
<string>Start Transmit</string>
|
||||
</property>
|
||||
<property name="icon" >
|
||||
<iconset resource="ostinato.qrc" >:/icons/control_play.png</iconset>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<widget class="QToolButton" name="tbStopTransmit" >
|
||||
<property name="toolTip" >
|
||||
<string>Clear All</string>
|
||||
</property>
|
||||
<property name="statusTip" >
|
||||
<string>Stops transmit on selected port(s)</string>
|
||||
</property>
|
||||
<property name="text" >
|
||||
<string>Stop Trasmit</string>
|
||||
</property>
|
||||
<property name="icon" >
|
||||
<iconset resource="ostinato.qrc" >:/icons/control_stop.png</iconset>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<widget class="QToolButton" name="tbClear" >
|
||||
<property name="toolTip" >
|
||||
<string>Clear All</string>
|
||||
</property>
|
||||
<property name="statusTip" >
|
||||
<string>Clears statistics of the selected port(s)</string>
|
||||
</property>
|
||||
<property name="text" >
|
||||
<string>Clear</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<widget class="QToolButton" name="tbClearAll" >
|
||||
<property name="toolTip" >
|
||||
<string>Clear All</string>
|
||||
</property>
|
||||
<property name="statusTip" >
|
||||
<string>Clears statistics of all ports</string>
|
||||
</property>
|
||||
<property name="text" >
|
||||
<string>Clear All</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<widget class="QToolButton" name="tbStartCapture" >
|
||||
<property name="toolTip" >
|
||||
<string>Clear All</string>
|
||||
</property>
|
||||
<property name="statusTip" >
|
||||
<string>Captures packets on the selected port(s)</string>
|
||||
</property>
|
||||
<property name="text" >
|
||||
<string>Start Capture</string>
|
||||
</property>
|
||||
<property name="icon" >
|
||||
<iconset resource="ostinato.qrc" >:/icons/sound_none.png</iconset>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<widget class="QToolButton" name="tbStopCapture" >
|
||||
<property name="toolTip" >
|
||||
<string>Clear All</string>
|
||||
</property>
|
||||
<property name="statusTip" >
|
||||
<string>End capture on selecteed port(s)</string>
|
||||
</property>
|
||||
<property name="text" >
|
||||
<string>Stop Capture</string>
|
||||
</property>
|
||||
<property name="icon" >
|
||||
<iconset resource="ostinato.qrc" >:/icons/sound_mute.png</iconset>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<widget class="QToolButton" name="tbViewCapture" >
|
||||
<property name="toolTip" >
|
||||
<string>Clear All</string>
|
||||
</property>
|
||||
<property name="statusTip" >
|
||||
<string>View captured packets on selected port(s)</string>
|
||||
</property>
|
||||
<property name="text" >
|
||||
<string>View Capture</string>
|
||||
</property>
|
||||
<property name="icon" >
|
||||
<iconset resource="ostinato.qrc" >:/icons/magnifier.png</iconset>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<widget class="Line" name="line" >
|
||||
<property name="toolTip" >
|
||||
<string>Clear All</string>
|
||||
</property>
|
||||
<property name="orientation" >
|
||||
<enum>Qt::Vertical</enum>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<spacer>
|
||||
<property name="toolTip" >
|
||||
<string>Clear All</string>
|
||||
</property>
|
||||
<property name="orientation" >
|
||||
<enum>Qt::Horizontal</enum>
|
||||
</property>
|
||||
<property name="sizeHint" >
|
||||
<size>
|
||||
<width>40</width>
|
||||
<height>20</height>
|
||||
</size>
|
||||
</property>
|
||||
</spacer>
|
||||
</item>
|
||||
<item>
|
||||
<widget class="QToolButton" name="tbFilter" >
|
||||
<property name="toolTip" >
|
||||
<string>Clear All</string>
|
||||
</property>
|
||||
<property name="statusTip" >
|
||||
<string>Select which ports to view</string>
|
||||
</property>
|
||||
<property name="text" >
|
||||
<string>Filter</string>
|
||||
</property>
|
||||
<property name="icon" >
|
||||
<iconset resource="ostinato.qrc" >:/icons/portstats_filter.png</iconset>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
</layout>
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<widget class="QTableView" name="tvPortStats" >
|
||||
<property name="toolTip" >
|
||||
<string>Clear All</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
</layout>
|
||||
</widget>
|
||||
<resources>
|
||||
<include location="ostinato.qrc" />
|
||||
</resources>
|
||||
<connections/>
|
||||
</ui>
|
||||
|
@ -6,11 +6,13 @@
|
||||
|
||||
class StreamConfigDialog;
|
||||
class StreamModel;
|
||||
class PacketModel;
|
||||
|
||||
class Stream {
|
||||
|
||||
friend class StreamConfigDialog;
|
||||
friend class StreamModel;
|
||||
friend class PacketModel;
|
||||
|
||||
enum FrameType {
|
||||
e_ft_none,
|
||||
@ -114,6 +116,13 @@ class Stream {
|
||||
#define VM_SVLAN_TAGGED 0x0100
|
||||
#define VM_SVLAN_TPID_OVERRIDE 0x0200
|
||||
|
||||
#define VM_SINGLE_TAGGED(mask) \
|
||||
((mask & VM_CVLAN_TAGGED ) | (mask & VM_SVLAN_TAGGED))
|
||||
#define VM_DOUBLE_TAGGED(mask) \
|
||||
(mask & (VM_CVLAN_TAGGED | VM_SVLAN_TAGGED))
|
||||
|
||||
|
||||
|
||||
quint16 ctpid;
|
||||
quint16 cvlanPrio : 3;
|
||||
quint16 cvlanCfi : 1;
|
||||
|
@ -2,6 +2,9 @@
|
||||
#include "streamconfigdialog.h"
|
||||
#include "stream.h"
|
||||
|
||||
// TODO(LOW): Remove
|
||||
#include "modeltest.h"
|
||||
|
||||
StreamConfigDialog::StreamConfigDialog(QList<Stream> *streamList,
|
||||
uint streamIndex, QWidget *parent) : QDialog (parent)
|
||||
{
|
||||
@ -13,6 +16,12 @@ StreamConfigDialog::StreamConfigDialog(QList<Stream> *streamList,
|
||||
mCurrentStreamIndex = streamIndex;
|
||||
LoadCurrentStream();
|
||||
|
||||
mpPacketModel = new PacketModel(&((*mpStreamList)[mCurrentStreamIndex]),
|
||||
this);
|
||||
tvPacketTree->setModel(mpPacketModel);
|
||||
mpPacketModelTester = new ModelTest(mpPacketModel);
|
||||
tvPacketTree->header()->hide();
|
||||
|
||||
qDebug("stream %p %d/%d loaded",
|
||||
mpStreamList, mCurrentStreamIndex, mpStreamList->size());
|
||||
|
||||
@ -66,6 +75,8 @@ void StreamConfigDialog::setupUiExtra()
|
||||
|
||||
StreamConfigDialog::~StreamConfigDialog()
|
||||
{
|
||||
delete mpPacketModelTester;
|
||||
delete mpPacketModel;
|
||||
}
|
||||
|
||||
void StreamConfigDialog::on_cmbDstMacMode_currentIndexChanged(QString mode)
|
||||
|
@ -3,7 +3,9 @@
|
||||
|
||||
#include <QDialog>
|
||||
#include "ui_streamconfigdialog.h"
|
||||
#include <stream.h>
|
||||
#include "stream.h"
|
||||
#include "packetmodel.h"
|
||||
#include "modeltest.h"
|
||||
|
||||
#define MAX_MAC_ITER_COUNT 256
|
||||
#define MIN_PKT_LEN 64
|
||||
@ -26,6 +28,8 @@ public:
|
||||
private:
|
||||
QList<Stream> *mpStreamList;
|
||||
uint mCurrentStreamIndex;
|
||||
PacketModel *mpPacketModel;
|
||||
ModelTest *mpPacketModelTester;
|
||||
|
||||
void setupUiExtra();
|
||||
void LoadCurrentStream();
|
||||
|
@ -33,9 +33,9 @@ QLineEdit:enabled[inputMask = "HH HH HH HH HH HH; "] { background-color: #ccccff
|
||||
<string/>
|
||||
</property>
|
||||
<property name="currentIndex" >
|
||||
<number>0</number>
|
||||
<number>2</number>
|
||||
</property>
|
||||
<widget class="QWidget" name="" >
|
||||
<widget class="QWidget" name="widget" >
|
||||
<attribute name="title" >
|
||||
<string>Packet Config</string>
|
||||
</attribute>
|
||||
@ -2023,66 +2023,18 @@ QLineEdit:enabled[inputMask = "HH HH HH HH HH HH; "] { background-color: #ccccff
|
||||
<attribute name="title" >
|
||||
<string>Packet View</string>
|
||||
</attribute>
|
||||
<layout class="QVBoxLayout" >
|
||||
<layout class="QHBoxLayout" >
|
||||
<item>
|
||||
<widget class="QSplitter" name="splitter" >
|
||||
<property name="orientation" >
|
||||
<enum>Qt::Vertical</enum>
|
||||
</property>
|
||||
<widget class="QTreeWidget" name="treeWidget" >
|
||||
<property name="uniformRowHeights" >
|
||||
<bool>true</bool>
|
||||
</property>
|
||||
<column>
|
||||
<property name="text" >
|
||||
<string>New Column</string>
|
||||
</property>
|
||||
</column>
|
||||
<item>
|
||||
<property name="text" >
|
||||
<string>Ethernet</string>
|
||||
</property>
|
||||
<item>
|
||||
<property name="text" >
|
||||
<string>DstMac: 00:00:00:00:00:00</string>
|
||||
</property>
|
||||
</item>
|
||||
<item>
|
||||
<property name="text" >
|
||||
<string>SrcMac: 00:00:00:00:00:00</string>
|
||||
</property>
|
||||
</item>
|
||||
<item>
|
||||
<property name="text" >
|
||||
<string>EtherType: IP (0800)</string>
|
||||
</property>
|
||||
</item>
|
||||
</item>
|
||||
<item>
|
||||
<property name="text" >
|
||||
<string>IP</string>
|
||||
</property>
|
||||
<item>
|
||||
<property name="text" >
|
||||
<string>Version: 4</string>
|
||||
</property>
|
||||
</item>
|
||||
<item>
|
||||
<property name="text" >
|
||||
<string>Header Length: 20</string>
|
||||
</property>
|
||||
</item>
|
||||
</item>
|
||||
</widget>
|
||||
<widget class="QTextEdit" name="textEdit" >
|
||||
<property name="html" >
|
||||
<string><html><head><meta name="qrichtext" content="1" /><style type="text/css">
|
||||
p, li { white-space: pre-wrap; }
|
||||
</style></head><body style=" font-family:'MS Shell Dlg 2'; font-size:8.25pt; font-weight:400; font-style:normal;">
|
||||
<p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px; font-size:8pt;">0004 00 00 00 00 00 00</p>
|
||||
<p style="-qt-paragraph-type:empty; margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px; font-size:8pt;"></p></body></html></string>
|
||||
<widget class="QTreeView" name="tvPacketTree" >
|
||||
<property name="selectionBehavior" >
|
||||
<enum>QAbstractItemView::SelectItems</enum>
|
||||
</property>
|
||||
</widget>
|
||||
<widget class="DumpView" native="1" name="vwPacketDump" />
|
||||
</widget>
|
||||
</item>
|
||||
</layout>
|
||||
@ -2145,6 +2097,12 @@ p, li { white-space: pre-wrap; }
|
||||
<extends>QLineEdit</extends>
|
||||
<header location="global" >hexlineedit.h</header>
|
||||
</customwidget>
|
||||
<customwidget>
|
||||
<class>DumpView</class>
|
||||
<extends>QWidget</extends>
|
||||
<header>dumpview.h</header>
|
||||
<container>1</container>
|
||||
</customwidget>
|
||||
</customwidgets>
|
||||
<tabstops>
|
||||
<tabstop>twTopLevel</tabstop>
|
||||
@ -2347,12 +2305,12 @@ p, li { white-space: pre-wrap; }
|
||||
<slot>setEnabled(bool)</slot>
|
||||
<hints>
|
||||
<hint type="sourcelabel" >
|
||||
<x>79</x>
|
||||
<y>247</y>
|
||||
<x>101</x>
|
||||
<y>276</y>
|
||||
</hint>
|
||||
<hint type="destinationlabel" >
|
||||
<x>99</x>
|
||||
<y>247</y>
|
||||
<x>101</x>
|
||||
<y>276</y>
|
||||
</hint>
|
||||
</hints>
|
||||
</connection>
|
||||
@ -2363,12 +2321,12 @@ p, li { white-space: pre-wrap; }
|
||||
<slot>setEnabled(bool)</slot>
|
||||
<hints>
|
||||
<hint type="sourcelabel" >
|
||||
<x>79</x>
|
||||
<y>247</y>
|
||||
<x>101</x>
|
||||
<y>276</y>
|
||||
</hint>
|
||||
<hint type="destinationlabel" >
|
||||
<x>99</x>
|
||||
<y>247</y>
|
||||
<x>101</x>
|
||||
<y>276</y>
|
||||
</hint>
|
||||
</hints>
|
||||
</connection>
|
||||
@ -2443,12 +2401,12 @@ p, li { white-space: pre-wrap; }
|
||||
<slot>setEnabled(bool)</slot>
|
||||
<hints>
|
||||
<hint type="sourcelabel" >
|
||||
<x>79</x>
|
||||
<y>247</y>
|
||||
<x>101</x>
|
||||
<y>276</y>
|
||||
</hint>
|
||||
<hint type="destinationlabel" >
|
||||
<x>99</x>
|
||||
<y>247</y>
|
||||
<x>101</x>
|
||||
<y>276</y>
|
||||
</hint>
|
||||
</hints>
|
||||
</connection>
|
||||
@ -2459,44 +2417,44 @@ p, li { white-space: pre-wrap; }
|
||||
<slot>setEnabled(bool)</slot>
|
||||
<hints>
|
||||
<hint type="sourcelabel" >
|
||||
<x>79</x>
|
||||
<y>247</y>
|
||||
<x>101</x>
|
||||
<y>276</y>
|
||||
</hint>
|
||||
<hint type="destinationlabel" >
|
||||
<x>101</x>
|
||||
<y>276</y>
|
||||
</hint>
|
||||
</hints>
|
||||
</connection>
|
||||
<connection>
|
||||
<sender>rbFtNone</sender>
|
||||
<signal>toggled(bool)</signal>
|
||||
<receiver>lblDsap</receiver>
|
||||
<slot>setHidden(bool)</slot>
|
||||
<hints>
|
||||
<hint type="sourcelabel" >
|
||||
<x>57</x>
|
||||
<y>218</y>
|
||||
</hint>
|
||||
<hint type="destinationlabel" >
|
||||
<x>58</x>
|
||||
<y>218</y>
|
||||
</hint>
|
||||
</hints>
|
||||
</connection>
|
||||
<connection>
|
||||
<sender>rbFtNone</sender>
|
||||
<signal>toggled(bool)</signal>
|
||||
<receiver>leDsap</receiver>
|
||||
<slot>setHidden(bool)</slot>
|
||||
<hints>
|
||||
<hint type="sourcelabel" >
|
||||
<x>57</x>
|
||||
<y>218</y>
|
||||
</hint>
|
||||
<hint type="destinationlabel" >
|
||||
<x>99</x>
|
||||
<y>247</y>
|
||||
</hint>
|
||||
</hints>
|
||||
</connection>
|
||||
<connection>
|
||||
<sender>rbFtNone</sender>
|
||||
<signal>toggled(bool)</signal>
|
||||
<receiver>lblDsap</receiver>
|
||||
<slot>setHidden(bool)</slot>
|
||||
<hints>
|
||||
<hint type="sourcelabel" >
|
||||
<x>43</x>
|
||||
<y>186</y>
|
||||
</hint>
|
||||
<hint type="destinationlabel" >
|
||||
<x>137</x>
|
||||
<y>185</y>
|
||||
</hint>
|
||||
</hints>
|
||||
</connection>
|
||||
<connection>
|
||||
<sender>rbFtNone</sender>
|
||||
<signal>toggled(bool)</signal>
|
||||
<receiver>leDsap</receiver>
|
||||
<slot>setHidden(bool)</slot>
|
||||
<hints>
|
||||
<hint type="sourcelabel" >
|
||||
<x>43</x>
|
||||
<y>186</y>
|
||||
</hint>
|
||||
<hint type="destinationlabel" >
|
||||
<x>178</x>
|
||||
<y>185</y>
|
||||
<y>218</y>
|
||||
</hint>
|
||||
</hints>
|
||||
</connection>
|
||||
@ -2507,12 +2465,12 @@ p, li { white-space: pre-wrap; }
|
||||
<slot>setHidden(bool)</slot>
|
||||
<hints>
|
||||
<hint type="sourcelabel" >
|
||||
<x>43</x>
|
||||
<y>186</y>
|
||||
<x>57</x>
|
||||
<y>218</y>
|
||||
</hint>
|
||||
<hint type="destinationlabel" >
|
||||
<x>137</x>
|
||||
<y>211</y>
|
||||
<x>58</x>
|
||||
<y>218</y>
|
||||
</hint>
|
||||
</hints>
|
||||
</connection>
|
||||
@ -2523,12 +2481,12 @@ p, li { white-space: pre-wrap; }
|
||||
<slot>setHidden(bool)</slot>
|
||||
<hints>
|
||||
<hint type="sourcelabel" >
|
||||
<x>43</x>
|
||||
<y>186</y>
|
||||
<x>57</x>
|
||||
<y>218</y>
|
||||
</hint>
|
||||
<hint type="destinationlabel" >
|
||||
<x>178</x>
|
||||
<y>211</y>
|
||||
<x>99</x>
|
||||
<y>218</y>
|
||||
</hint>
|
||||
</hints>
|
||||
</connection>
|
||||
@ -2539,8 +2497,8 @@ p, li { white-space: pre-wrap; }
|
||||
<slot>setHidden(bool)</slot>
|
||||
<hints>
|
||||
<hint type="sourcelabel" >
|
||||
<x>43</x>
|
||||
<y>186</y>
|
||||
<x>57</x>
|
||||
<y>218</y>
|
||||
</hint>
|
||||
<hint type="destinationlabel" >
|
||||
<x>137</x>
|
||||
@ -2555,12 +2513,12 @@ p, li { white-space: pre-wrap; }
|
||||
<slot>setHidden(bool)</slot>
|
||||
<hints>
|
||||
<hint type="sourcelabel" >
|
||||
<x>43</x>
|
||||
<y>186</y>
|
||||
<x>57</x>
|
||||
<y>218</y>
|
||||
</hint>
|
||||
<hint type="destinationlabel" >
|
||||
<x>178</x>
|
||||
<y>237</y>
|
||||
<x>99</x>
|
||||
<y>218</y>
|
||||
</hint>
|
||||
</hints>
|
||||
</connection>
|
||||
@ -2571,12 +2529,12 @@ p, li { white-space: pre-wrap; }
|
||||
<slot>setHidden(bool)</slot>
|
||||
<hints>
|
||||
<hint type="sourcelabel" >
|
||||
<x>43</x>
|
||||
<y>186</y>
|
||||
<x>57</x>
|
||||
<y>218</y>
|
||||
</hint>
|
||||
<hint type="destinationlabel" >
|
||||
<x>137</x>
|
||||
<y>263</y>
|
||||
<x>58</x>
|
||||
<y>218</y>
|
||||
</hint>
|
||||
</hints>
|
||||
</connection>
|
||||
@ -2587,12 +2545,12 @@ p, li { white-space: pre-wrap; }
|
||||
<slot>setHidden(bool)</slot>
|
||||
<hints>
|
||||
<hint type="sourcelabel" >
|
||||
<x>43</x>
|
||||
<y>186</y>
|
||||
<x>57</x>
|
||||
<y>218</y>
|
||||
</hint>
|
||||
<hint type="destinationlabel" >
|
||||
<x>178</x>
|
||||
<y>263</y>
|
||||
<x>99</x>
|
||||
<y>218</y>
|
||||
</hint>
|
||||
</hints>
|
||||
</connection>
|
||||
@ -2603,12 +2561,12 @@ p, li { white-space: pre-wrap; }
|
||||
<slot>setHidden(bool)</slot>
|
||||
<hints>
|
||||
<hint type="sourcelabel" >
|
||||
<x>43</x>
|
||||
<y>186</y>
|
||||
<x>57</x>
|
||||
<y>218</y>
|
||||
</hint>
|
||||
<hint type="destinationlabel" >
|
||||
<x>137</x>
|
||||
<y>289</y>
|
||||
<x>58</x>
|
||||
<y>218</y>
|
||||
</hint>
|
||||
</hints>
|
||||
</connection>
|
||||
@ -2619,12 +2577,12 @@ p, li { white-space: pre-wrap; }
|
||||
<slot>setHidden(bool)</slot>
|
||||
<hints>
|
||||
<hint type="sourcelabel" >
|
||||
<x>43</x>
|
||||
<y>186</y>
|
||||
<x>57</x>
|
||||
<y>218</y>
|
||||
</hint>
|
||||
<hint type="destinationlabel" >
|
||||
<x>178</x>
|
||||
<y>289</y>
|
||||
<x>99</x>
|
||||
<y>218</y>
|
||||
</hint>
|
||||
</hints>
|
||||
</connection>
|
||||
@ -2635,12 +2593,12 @@ p, li { white-space: pre-wrap; }
|
||||
<slot>setHidden(bool)</slot>
|
||||
<hints>
|
||||
<hint type="sourcelabel" >
|
||||
<x>43</x>
|
||||
<y>211</y>
|
||||
<x>57</x>
|
||||
<y>218</y>
|
||||
</hint>
|
||||
<hint type="destinationlabel" >
|
||||
<x>137</x>
|
||||
<y>185</y>
|
||||
<x>58</x>
|
||||
<y>218</y>
|
||||
</hint>
|
||||
</hints>
|
||||
</connection>
|
||||
@ -2651,12 +2609,12 @@ p, li { white-space: pre-wrap; }
|
||||
<slot>setHidden(bool)</slot>
|
||||
<hints>
|
||||
<hint type="sourcelabel" >
|
||||
<x>43</x>
|
||||
<y>211</y>
|
||||
<x>57</x>
|
||||
<y>218</y>
|
||||
</hint>
|
||||
<hint type="destinationlabel" >
|
||||
<x>178</x>
|
||||
<y>185</y>
|
||||
<x>99</x>
|
||||
<y>218</y>
|
||||
</hint>
|
||||
</hints>
|
||||
</connection>
|
||||
@ -2667,12 +2625,12 @@ p, li { white-space: pre-wrap; }
|
||||
<slot>setHidden(bool)</slot>
|
||||
<hints>
|
||||
<hint type="sourcelabel" >
|
||||
<x>43</x>
|
||||
<y>211</y>
|
||||
<x>57</x>
|
||||
<y>218</y>
|
||||
</hint>
|
||||
<hint type="destinationlabel" >
|
||||
<x>137</x>
|
||||
<y>211</y>
|
||||
<x>58</x>
|
||||
<y>218</y>
|
||||
</hint>
|
||||
</hints>
|
||||
</connection>
|
||||
@ -2683,12 +2641,12 @@ p, li { white-space: pre-wrap; }
|
||||
<slot>setHidden(bool)</slot>
|
||||
<hints>
|
||||
<hint type="sourcelabel" >
|
||||
<x>43</x>
|
||||
<y>211</y>
|
||||
<x>57</x>
|
||||
<y>218</y>
|
||||
</hint>
|
||||
<hint type="destinationlabel" >
|
||||
<x>178</x>
|
||||
<y>211</y>
|
||||
<x>99</x>
|
||||
<y>218</y>
|
||||
</hint>
|
||||
</hints>
|
||||
</connection>
|
||||
@ -2699,8 +2657,8 @@ p, li { white-space: pre-wrap; }
|
||||
<slot>setHidden(bool)</slot>
|
||||
<hints>
|
||||
<hint type="sourcelabel" >
|
||||
<x>43</x>
|
||||
<y>236</y>
|
||||
<x>57</x>
|
||||
<y>218</y>
|
||||
</hint>
|
||||
<hint type="destinationlabel" >
|
||||
<x>137</x>
|
||||
@ -2715,12 +2673,12 @@ p, li { white-space: pre-wrap; }
|
||||
<slot>setHidden(bool)</slot>
|
||||
<hints>
|
||||
<hint type="sourcelabel" >
|
||||
<x>43</x>
|
||||
<y>236</y>
|
||||
<x>57</x>
|
||||
<y>218</y>
|
||||
</hint>
|
||||
<hint type="destinationlabel" >
|
||||
<x>178</x>
|
||||
<y>237</y>
|
||||
<x>99</x>
|
||||
<y>218</y>
|
||||
</hint>
|
||||
</hints>
|
||||
</connection>
|
||||
@ -2731,8 +2689,8 @@ p, li { white-space: pre-wrap; }
|
||||
<slot>setHidden(bool)</slot>
|
||||
<hints>
|
||||
<hint type="sourcelabel" >
|
||||
<x>43</x>
|
||||
<y>211</y>
|
||||
<x>57</x>
|
||||
<y>218</y>
|
||||
</hint>
|
||||
<hint type="destinationlabel" >
|
||||
<x>137</x>
|
||||
@ -2747,12 +2705,12 @@ p, li { white-space: pre-wrap; }
|
||||
<slot>setHidden(bool)</slot>
|
||||
<hints>
|
||||
<hint type="sourcelabel" >
|
||||
<x>43</x>
|
||||
<y>211</y>
|
||||
<x>57</x>
|
||||
<y>218</y>
|
||||
</hint>
|
||||
<hint type="destinationlabel" >
|
||||
<x>178</x>
|
||||
<y>237</y>
|
||||
<x>99</x>
|
||||
<y>218</y>
|
||||
</hint>
|
||||
</hints>
|
||||
</connection>
|
||||
@ -2763,12 +2721,12 @@ p, li { white-space: pre-wrap; }
|
||||
<slot>setHidden(bool)</slot>
|
||||
<hints>
|
||||
<hint type="sourcelabel" >
|
||||
<x>43</x>
|
||||
<y>211</y>
|
||||
<x>57</x>
|
||||
<y>218</y>
|
||||
</hint>
|
||||
<hint type="destinationlabel" >
|
||||
<x>137</x>
|
||||
<y>263</y>
|
||||
<x>58</x>
|
||||
<y>218</y>
|
||||
</hint>
|
||||
</hints>
|
||||
</connection>
|
||||
@ -2779,12 +2737,12 @@ p, li { white-space: pre-wrap; }
|
||||
<slot>setHidden(bool)</slot>
|
||||
<hints>
|
||||
<hint type="sourcelabel" >
|
||||
<x>43</x>
|
||||
<y>211</y>
|
||||
<x>57</x>
|
||||
<y>218</y>
|
||||
</hint>
|
||||
<hint type="destinationlabel" >
|
||||
<x>178</x>
|
||||
<y>263</y>
|
||||
<x>99</x>
|
||||
<y>218</y>
|
||||
</hint>
|
||||
</hints>
|
||||
</connection>
|
||||
@ -2795,12 +2753,12 @@ p, li { white-space: pre-wrap; }
|
||||
<slot>setHidden(bool)</slot>
|
||||
<hints>
|
||||
<hint type="sourcelabel" >
|
||||
<x>43</x>
|
||||
<y>236</y>
|
||||
<x>57</x>
|
||||
<y>218</y>
|
||||
</hint>
|
||||
<hint type="destinationlabel" >
|
||||
<x>137</x>
|
||||
<y>185</y>
|
||||
<x>58</x>
|
||||
<y>218</y>
|
||||
</hint>
|
||||
</hints>
|
||||
</connection>
|
||||
@ -2811,12 +2769,12 @@ p, li { white-space: pre-wrap; }
|
||||
<slot>setHidden(bool)</slot>
|
||||
<hints>
|
||||
<hint type="sourcelabel" >
|
||||
<x>43</x>
|
||||
<y>236</y>
|
||||
<x>57</x>
|
||||
<y>218</y>
|
||||
</hint>
|
||||
<hint type="destinationlabel" >
|
||||
<x>178</x>
|
||||
<y>185</y>
|
||||
<x>99</x>
|
||||
<y>218</y>
|
||||
</hint>
|
||||
</hints>
|
||||
</connection>
|
||||
@ -2827,12 +2785,12 @@ p, li { white-space: pre-wrap; }
|
||||
<slot>setHidden(bool)</slot>
|
||||
<hints>
|
||||
<hint type="sourcelabel" >
|
||||
<x>43</x>
|
||||
<y>236</y>
|
||||
<x>57</x>
|
||||
<y>218</y>
|
||||
</hint>
|
||||
<hint type="destinationlabel" >
|
||||
<x>137</x>
|
||||
<y>211</y>
|
||||
<x>58</x>
|
||||
<y>218</y>
|
||||
</hint>
|
||||
</hints>
|
||||
</connection>
|
||||
@ -2843,12 +2801,12 @@ p, li { white-space: pre-wrap; }
|
||||
<slot>setHidden(bool)</slot>
|
||||
<hints>
|
||||
<hint type="sourcelabel" >
|
||||
<x>43</x>
|
||||
<y>236</y>
|
||||
<x>57</x>
|
||||
<y>218</y>
|
||||
</hint>
|
||||
<hint type="destinationlabel" >
|
||||
<x>178</x>
|
||||
<y>211</y>
|
||||
<x>99</x>
|
||||
<y>218</y>
|
||||
</hint>
|
||||
</hints>
|
||||
</connection>
|
||||
@ -2859,8 +2817,8 @@ p, li { white-space: pre-wrap; }
|
||||
<slot>setHidden(bool)</slot>
|
||||
<hints>
|
||||
<hint type="sourcelabel" >
|
||||
<x>43</x>
|
||||
<y>236</y>
|
||||
<x>57</x>
|
||||
<y>218</y>
|
||||
</hint>
|
||||
<hint type="destinationlabel" >
|
||||
<x>137</x>
|
||||
@ -2875,12 +2833,12 @@ p, li { white-space: pre-wrap; }
|
||||
<slot>setHidden(bool)</slot>
|
||||
<hints>
|
||||
<hint type="sourcelabel" >
|
||||
<x>43</x>
|
||||
<y>236</y>
|
||||
<x>57</x>
|
||||
<y>218</y>
|
||||
</hint>
|
||||
<hint type="destinationlabel" >
|
||||
<x>178</x>
|
||||
<y>237</y>
|
||||
<x>99</x>
|
||||
<y>218</y>
|
||||
</hint>
|
||||
</hints>
|
||||
</connection>
|
||||
@ -2891,12 +2849,12 @@ p, li { white-space: pre-wrap; }
|
||||
<slot>setHidden(bool)</slot>
|
||||
<hints>
|
||||
<hint type="sourcelabel" >
|
||||
<x>43</x>
|
||||
<y>236</y>
|
||||
<x>57</x>
|
||||
<y>218</y>
|
||||
</hint>
|
||||
<hint type="destinationlabel" >
|
||||
<x>137</x>
|
||||
<y>263</y>
|
||||
<x>58</x>
|
||||
<y>218</y>
|
||||
</hint>
|
||||
</hints>
|
||||
</connection>
|
||||
@ -2907,12 +2865,12 @@ p, li { white-space: pre-wrap; }
|
||||
<slot>setHidden(bool)</slot>
|
||||
<hints>
|
||||
<hint type="sourcelabel" >
|
||||
<x>43</x>
|
||||
<y>236</y>
|
||||
<x>57</x>
|
||||
<y>218</y>
|
||||
</hint>
|
||||
<hint type="destinationlabel" >
|
||||
<x>178</x>
|
||||
<y>263</y>
|
||||
<x>99</x>
|
||||
<y>218</y>
|
||||
</hint>
|
||||
</hints>
|
||||
</connection>
|
||||
@ -2923,12 +2881,12 @@ p, li { white-space: pre-wrap; }
|
||||
<slot>setHidden(bool)</slot>
|
||||
<hints>
|
||||
<hint type="sourcelabel" >
|
||||
<x>43</x>
|
||||
<y>236</y>
|
||||
<x>57</x>
|
||||
<y>218</y>
|
||||
</hint>
|
||||
<hint type="destinationlabel" >
|
||||
<x>137</x>
|
||||
<y>289</y>
|
||||
<x>58</x>
|
||||
<y>218</y>
|
||||
</hint>
|
||||
</hints>
|
||||
</connection>
|
||||
@ -2939,12 +2897,12 @@ p, li { white-space: pre-wrap; }
|
||||
<slot>setHidden(bool)</slot>
|
||||
<hints>
|
||||
<hint type="sourcelabel" >
|
||||
<x>43</x>
|
||||
<y>236</y>
|
||||
<x>57</x>
|
||||
<y>218</y>
|
||||
</hint>
|
||||
<hint type="destinationlabel" >
|
||||
<x>178</x>
|
||||
<y>289</y>
|
||||
<x>99</x>
|
||||
<y>218</y>
|
||||
</hint>
|
||||
</hints>
|
||||
</connection>
|
||||
@ -2987,12 +2945,12 @@ p, li { white-space: pre-wrap; }
|
||||
<slot>setDisabled(bool)</slot>
|
||||
<hints>
|
||||
<hint type="sourcelabel" >
|
||||
<x>43</x>
|
||||
<y>286</y>
|
||||
<x>57</x>
|
||||
<y>218</y>
|
||||
</hint>
|
||||
<hint type="destinationlabel" >
|
||||
<x>178</x>
|
||||
<y>185</y>
|
||||
<x>99</x>
|
||||
<y>218</y>
|
||||
</hint>
|
||||
</hints>
|
||||
</connection>
|
||||
@ -3003,12 +2961,12 @@ p, li { white-space: pre-wrap; }
|
||||
<slot>setDisabled(bool)</slot>
|
||||
<hints>
|
||||
<hint type="sourcelabel" >
|
||||
<x>43</x>
|
||||
<y>286</y>
|
||||
<x>57</x>
|
||||
<y>218</y>
|
||||
</hint>
|
||||
<hint type="destinationlabel" >
|
||||
<x>178</x>
|
||||
<y>211</y>
|
||||
<x>99</x>
|
||||
<y>218</y>
|
||||
</hint>
|
||||
</hints>
|
||||
</connection>
|
||||
@ -3019,12 +2977,12 @@ p, li { white-space: pre-wrap; }
|
||||
<slot>setDisabled(bool)</slot>
|
||||
<hints>
|
||||
<hint type="sourcelabel" >
|
||||
<x>43</x>
|
||||
<y>286</y>
|
||||
<x>57</x>
|
||||
<y>218</y>
|
||||
</hint>
|
||||
<hint type="destinationlabel" >
|
||||
<x>178</x>
|
||||
<y>237</y>
|
||||
<x>99</x>
|
||||
<y>218</y>
|
||||
</hint>
|
||||
</hints>
|
||||
</connection>
|
||||
@ -3035,12 +2993,12 @@ p, li { white-space: pre-wrap; }
|
||||
<slot>setEnabled(bool)</slot>
|
||||
<hints>
|
||||
<hint type="sourcelabel" >
|
||||
<x>355</x>
|
||||
<y>196</y>
|
||||
<x>570</x>
|
||||
<y>218</y>
|
||||
</hint>
|
||||
<hint type="destinationlabel" >
|
||||
<x>300</x>
|
||||
<y>291</y>
|
||||
<x>570</x>
|
||||
<y>302</y>
|
||||
</hint>
|
||||
</hints>
|
||||
</connection>
|
||||
@ -3051,12 +3009,12 @@ p, li { white-space: pre-wrap; }
|
||||
<slot>setEnabled(bool)</slot>
|
||||
<hints>
|
||||
<hint type="sourcelabel" >
|
||||
<x>355</x>
|
||||
<y>196</y>
|
||||
<x>570</x>
|
||||
<y>218</y>
|
||||
</hint>
|
||||
<hint type="destinationlabel" >
|
||||
<x>372</x>
|
||||
<y>291</y>
|
||||
<x>570</x>
|
||||
<y>302</y>
|
||||
</hint>
|
||||
</hints>
|
||||
</connection>
|
||||
@ -3067,12 +3025,12 @@ p, li { white-space: pre-wrap; }
|
||||
<slot>setEnabled(bool)</slot>
|
||||
<hints>
|
||||
<hint type="sourcelabel" >
|
||||
<x>355</x>
|
||||
<y>196</y>
|
||||
<x>570</x>
|
||||
<y>218</y>
|
||||
</hint>
|
||||
<hint type="destinationlabel" >
|
||||
<x>443</x>
|
||||
<y>291</y>
|
||||
<x>570</x>
|
||||
<y>302</y>
|
||||
</hint>
|
||||
</hints>
|
||||
</connection>
|
||||
@ -3083,12 +3041,12 @@ p, li { white-space: pre-wrap; }
|
||||
<slot>setEnabled(bool)</slot>
|
||||
<hints>
|
||||
<hint type="sourcelabel" >
|
||||
<x>355</x>
|
||||
<y>196</y>
|
||||
<x>570</x>
|
||||
<y>218</y>
|
||||
</hint>
|
||||
<hint type="destinationlabel" >
|
||||
<x>372</x>
|
||||
<y>267</y>
|
||||
<x>570</x>
|
||||
<y>302</y>
|
||||
</hint>
|
||||
</hints>
|
||||
</connection>
|
||||
@ -3099,12 +3057,12 @@ p, li { white-space: pre-wrap; }
|
||||
<slot>setEnabled(bool)</slot>
|
||||
<hints>
|
||||
<hint type="sourcelabel" >
|
||||
<x>355</x>
|
||||
<y>196</y>
|
||||
<x>570</x>
|
||||
<y>218</y>
|
||||
</hint>
|
||||
<hint type="destinationlabel" >
|
||||
<x>443</x>
|
||||
<y>267</y>
|
||||
<x>570</x>
|
||||
<y>302</y>
|
||||
</hint>
|
||||
</hints>
|
||||
</connection>
|
||||
@ -3115,12 +3073,12 @@ p, li { white-space: pre-wrap; }
|
||||
<slot>click()</slot>
|
||||
<hints>
|
||||
<hint type="sourcelabel" >
|
||||
<x>300</x>
|
||||
<y>196</y>
|
||||
<x>570</x>
|
||||
<y>218</y>
|
||||
</hint>
|
||||
<hint type="destinationlabel" >
|
||||
<x>300</x>
|
||||
<y>267</y>
|
||||
<x>570</x>
|
||||
<y>302</y>
|
||||
</hint>
|
||||
</hints>
|
||||
</connection>
|
||||
@ -3131,12 +3089,12 @@ p, li { white-space: pre-wrap; }
|
||||
<slot>click()</slot>
|
||||
<hints>
|
||||
<hint type="sourcelabel" >
|
||||
<x>407</x>
|
||||
<y>196</y>
|
||||
<x>570</x>
|
||||
<y>218</y>
|
||||
</hint>
|
||||
<hint type="destinationlabel" >
|
||||
<x>300</x>
|
||||
<y>267</y>
|
||||
<x>570</x>
|
||||
<y>302</y>
|
||||
</hint>
|
||||
</hints>
|
||||
</connection>
|
||||
@ -3147,12 +3105,12 @@ p, li { white-space: pre-wrap; }
|
||||
<slot>click()</slot>
|
||||
<hints>
|
||||
<hint type="sourcelabel" >
|
||||
<x>457</x>
|
||||
<y>196</y>
|
||||
<x>570</x>
|
||||
<y>218</y>
|
||||
</hint>
|
||||
<hint type="destinationlabel" >
|
||||
<x>300</x>
|
||||
<y>267</y>
|
||||
<x>570</x>
|
||||
<y>302</y>
|
||||
</hint>
|
||||
</hints>
|
||||
</connection>
|
||||
@ -3163,12 +3121,12 @@ p, li { white-space: pre-wrap; }
|
||||
<slot>setEnabled(bool)</slot>
|
||||
<hints>
|
||||
<hint type="sourcelabel" >
|
||||
<x>334</x>
|
||||
<y>147</y>
|
||||
<x>224</x>
|
||||
<y>207</y>
|
||||
</hint>
|
||||
<hint type="destinationlabel" >
|
||||
<x>411</x>
|
||||
<y>177</y>
|
||||
<x>224</x>
|
||||
<y>209</y>
|
||||
</hint>
|
||||
</hints>
|
||||
</connection>
|
||||
@ -3179,12 +3137,12 @@ p, li { white-space: pre-wrap; }
|
||||
<slot>setEnabled(bool)</slot>
|
||||
<hints>
|
||||
<hint type="sourcelabel" >
|
||||
<x>38</x>
|
||||
<y>73</y>
|
||||
<x>125</x>
|
||||
<y>207</y>
|
||||
</hint>
|
||||
<hint type="destinationlabel" >
|
||||
<x>180</x>
|
||||
<y>284</y>
|
||||
<x>191</x>
|
||||
<y>236</y>
|
||||
</hint>
|
||||
</hints>
|
||||
</connection>
|
||||
@ -3195,12 +3153,12 @@ p, li { white-space: pre-wrap; }
|
||||
<slot>setEnabled(bool)</slot>
|
||||
<hints>
|
||||
<hint type="sourcelabel" >
|
||||
<x>46</x>
|
||||
<y>98</y>
|
||||
<x>125</x>
|
||||
<y>207</y>
|
||||
</hint>
|
||||
<hint type="destinationlabel" >
|
||||
<x>162</x>
|
||||
<y>313</y>
|
||||
<x>173</x>
|
||||
<y>236</y>
|
||||
</hint>
|
||||
</hints>
|
||||
</connection>
|
||||
@ -3211,12 +3169,12 @@ p, li { white-space: pre-wrap; }
|
||||
<slot>setEnabled(bool)</slot>
|
||||
<hints>
|
||||
<hint type="sourcelabel" >
|
||||
<x>73</x>
|
||||
<y>108</y>
|
||||
<x>125</x>
|
||||
<y>207</y>
|
||||
</hint>
|
||||
<hint type="destinationlabel" >
|
||||
<x>225</x>
|
||||
<y>184</y>
|
||||
<x>224</x>
|
||||
<y>216</y>
|
||||
</hint>
|
||||
</hints>
|
||||
</connection>
|
||||
|
@ -31,23 +31,139 @@ typedef struct {
|
||||
} tCommHdr;
|
||||
|
||||
typedef enum {
|
||||
e_MT_CapabilityReq=1,
|
||||
e_MT_CapabilityInfo
|
||||
e_MT_GetCapability=1, // C-->S
|
||||
e_MT_CapabilityInfo, // C<--S
|
||||
|
||||
e_MT_ChangePortConfig, // C-->S
|
||||
e_MT_GetPortConfig, // C-->S
|
||||
e_MT_PortInfo, // C<--S
|
||||
|
||||
e_MT_StartTx, // C-->S
|
||||
e_MT_StopTx, // C-->S
|
||||
e_MT_StartCapture, // C-->S
|
||||
e_MT_StopCapture, // C-->S
|
||||
e_MT_GetCaptureBuffer, // C-->S
|
||||
e_MT_CaptureBufferInfo, // C-->S
|
||||
|
||||
e_MT_GetStats, // C-->S
|
||||
e_MT_StatsInfo, // C<--S
|
||||
e_MT_ClearStats, // C-->S
|
||||
|
||||
} eMsgType;
|
||||
|
||||
typedef enum {
|
||||
e_TT_PortCapability
|
||||
e_TT_PortCapability=0x0000,
|
||||
|
||||
e_TT_StreamOper = 0x0100,
|
||||
e_TT_StreamName,
|
||||
e_TT_StreamStatus,
|
||||
e_TT_StreamFrameLength,
|
||||
e_TT_StreamDataPattern,
|
||||
e_TT_StreamHeaderData,
|
||||
} eTlvType;
|
||||
|
||||
typedef struct {
|
||||
UINT16 tlvType;
|
||||
UINT16 tlvLen;
|
||||
UINT32 port;
|
||||
UINT32 speed;
|
||||
} tTlv;
|
||||
|
||||
typedef struct {
|
||||
UINT16 tlvType;
|
||||
UINT16 tlvLen;
|
||||
UINT32 portId;
|
||||
UINT32 portSpeed;
|
||||
#define TLV_MAX_PORT_NAME 64
|
||||
#define TLV_MAX_PORT_DESC 64
|
||||
char name[TLV_MAX_PORT_NAME];
|
||||
char desc[TLV_MAX_PORT_DESC];
|
||||
char portName[TLV_MAX_PORT_NAME];
|
||||
char portDesc[TLV_MAX_PORT_DESC];
|
||||
} tTlvPortCapability;
|
||||
|
||||
typedef struct {
|
||||
UINT16 tlvType;
|
||||
UINT16 tlvLen;
|
||||
UINT32 portId;
|
||||
UINT32 streamId;
|
||||
} tTlvStream;
|
||||
|
||||
typedef struct {
|
||||
UINT16 tlvType;
|
||||
UINT16 tlvLen;
|
||||
UINT32 portId;
|
||||
UINT32 streamId;
|
||||
UINT16 rsvd;
|
||||
UINT16 streamOper;
|
||||
#define TLV_STREAM_OPER_INSERT_HEAD 0x0001
|
||||
#define TLV_STREAM_OPER_INSERT_TAIL 0x0002
|
||||
#define TLV_STREAM_OPER_INSERT_BEFORE 0x0003
|
||||
#define TLV_STREAM_OPER_DELETE 0x0010
|
||||
UINT32 StreamId;
|
||||
} tTlvStreamOper;
|
||||
|
||||
typedef struct {
|
||||
UINT16 tlvType;
|
||||
UINT16 tlvLen;
|
||||
UINT32 portId;
|
||||
UINT32 streamId;
|
||||
char streamName[0];
|
||||
} tTlvStreamName;
|
||||
|
||||
typedef struct {
|
||||
UINT16 tlvType;
|
||||
UINT16 tlvLen;
|
||||
UINT32 portId;
|
||||
UINT32 streamId;
|
||||
UINT32 streamStatus;
|
||||
#define TLV_STREAM_STATUS_DISABLED 0
|
||||
#define TLV_STREAM_STATUS_ENABLED 1
|
||||
} tTlvStreamStatus;
|
||||
|
||||
typedef struct {
|
||||
UINT16 tlvType;
|
||||
UINT16 tlvLen;
|
||||
UINT32 portId;
|
||||
UINT32 streamId;
|
||||
UINT16 frameLenMode;
|
||||
#define TLV_STREAM_FRAME_LEN_MODE_FIXED 0x0000
|
||||
#define TLV_STREAM_FRAME_LEN_MODE_RANDOM 0x0001
|
||||
#define TLV_STREAM_FRAME_LEN_MODE_INCREMENT 0x0002
|
||||
#define TLV_STREAM_FRAME_LEN_MODE_DECREMENT 0x0003
|
||||
UINT16 frameLen;
|
||||
UINT16 frameLenMin;
|
||||
UINT16 frameLenMax;
|
||||
} tTlvStreamFrameLength;
|
||||
|
||||
typedef struct {
|
||||
UINT16 tlvType;
|
||||
UINT16 tlvLen;
|
||||
UINT32 portId;
|
||||
UINT32 streamId;
|
||||
UINT16 dataPatternMode;
|
||||
#define TLV_STREAM_DATA_PATTERN_MODE_FIXED 0x0000
|
||||
#define TLV_STREAM_DATA_PATTERN_MODE_RANDOM 0x0001
|
||||
#define TLV_STREAM_DATA_PATTERN_MODE_INCREMENT 0x0002
|
||||
#define TLV_STREAM_DATA_PATTERN_MODE_DECREMENT 0x0003
|
||||
UINT16 rsvd;
|
||||
UINT32 dataPattern;
|
||||
} tTlvStreamDataPattern;
|
||||
|
||||
typedef struct {
|
||||
UINT16 tlvType;
|
||||
UINT16 tlvLen;
|
||||
UINT32 portId;
|
||||
UINT32 streamId;
|
||||
UINT16 rsvd;
|
||||
UINT16 headerLen;
|
||||
UINT8 header[0];
|
||||
} tTlvStreamHeaderData;
|
||||
|
||||
typedef union {
|
||||
tTlvStream tlv;
|
||||
tTlvStreamOper oper;
|
||||
tTlvStreamName name;
|
||||
tTlvStreamStatus status;
|
||||
tTlvStreamFrameLength frameLen;
|
||||
tTlvStreamDataPattern dataPattern;
|
||||
tTlvStreamHeaderData headerData;
|
||||
} uTlvStream;
|
||||
|
||||
#endif
|
||||
|
379
server/rxtx.cpp
379
server/rxtx.cpp
@ -1,6 +1,8 @@
|
||||
#include "qtglobal" // FIXME: needed only for qdebug
|
||||
#include "rxtx.h"
|
||||
#include "../common/protocol.h"
|
||||
#include "qtglobal" // FIXME: needed only for qdebug
|
||||
|
||||
|
||||
|
||||
//#define LOG(...) drone->ui.teLOG->append(QString().sprintf( __VA_ARGS__))
|
||||
//#define LOG(...) drone->LOG(QString().sprintf( __VA_ARGS__))
|
||||
@ -36,6 +38,8 @@ RxTx::RxTx(AbstractHost *host)
|
||||
{
|
||||
portInfo[i].portId = i;
|
||||
portInfo[i].dev = d;
|
||||
portInfo[i].streamHead = NULL;
|
||||
portInfo[i].streamTail = NULL;
|
||||
#if 1
|
||||
LOG("%d. %s", i, d->name);
|
||||
if (d->description)
|
||||
@ -67,13 +71,17 @@ RxTx::LOG(char* fmt, ...)
|
||||
|
||||
RxTx::~RxTx()
|
||||
{
|
||||
unsigned int i;
|
||||
|
||||
for (i = 0; i < numPorts; i++)
|
||||
DeleteAllStreams(i);
|
||||
pcap_freealldevs(alldevs);
|
||||
}
|
||||
|
||||
void RxTx::ProcessMsg(const char* msg, int len)
|
||||
{
|
||||
tCommHdr *hdr;
|
||||
// TODO: For now, assuming we'll get a complete msg
|
||||
// TODO: For now assuming we'll get a complete msg
|
||||
// but need to fix this as this is a TCP stream
|
||||
|
||||
hdr = (tCommHdr*) msg;
|
||||
@ -87,9 +95,15 @@ void RxTx::ProcessMsg(const char* msg, int len)
|
||||
qDebug("msgType - %x: %x\n", hdr->msgType, NTOHS(hdr->msgType));
|
||||
switch (NTOHS(hdr->msgType))
|
||||
{
|
||||
case e_MT_CapabilityReq:
|
||||
case e_MT_GetCapability:
|
||||
SendCapabilityInfo();
|
||||
break;
|
||||
case e_MT_ChangePortConfig:
|
||||
ProcessPortConfig(msg+sizeof(tCommHdr), len - sizeof(tCommHdr));
|
||||
break;
|
||||
case e_MT_GetPortConfig:
|
||||
SendPortInfo();
|
||||
break;
|
||||
|
||||
default:
|
||||
LOG("Rcvd msg with unrecognized msgType %d\n", NTOHS(hdr->msgType));
|
||||
@ -114,20 +128,20 @@ void RxTx::SendCapabilityInfo(void)
|
||||
// TLV: Port Capability
|
||||
((tTlvPortCapability*)(p))->tlvType = HTONS(e_TT_PortCapability);
|
||||
((tTlvPortCapability*)(p))->tlvLen = HTONS(sizeof(tTlvPortCapability));
|
||||
((tTlvPortCapability*)(p))->port = HTONL(portInfo[i].portId);
|
||||
((tTlvPortCapability*)(p))->speed = 0; // TODO
|
||||
((tTlvPortCapability*)(p))->portId = HTONL(portInfo[i].portId);
|
||||
((tTlvPortCapability*)(p))->portSpeed = 0; // TODO
|
||||
#if 0
|
||||
strncpy(((tTlvPortCapability*)(p))->name,
|
||||
portInfo[i].dev->name, TLV_MAX_PORT_NAME);
|
||||
((tTlvPortCapability*)(p))->name[TLV_MAX_PORT_NAME-1] = 0;
|
||||
#else
|
||||
strcpy(((tTlvPortCapability*)(p))->name, "eth");
|
||||
strcpy(((tTlvPortCapability*)(p))->portName, "eth");
|
||||
//strcat(((tTlvPortCapability*)(p))->name, itoa(portInfo[i].portId, NULL, 10));
|
||||
itoa(portInfo[i].portId, &(((tTlvPortCapability*)(p))->name[3]), 10);
|
||||
itoa(portInfo[i].portId, &(((tTlvPortCapability*)(p))->portName[3]), 10);
|
||||
#endif
|
||||
strncpy(((tTlvPortCapability*)(p))->desc,
|
||||
strncpy(((tTlvPortCapability*)(p))->portDesc,
|
||||
portInfo[i].dev->description, TLV_MAX_PORT_DESC);
|
||||
((tTlvPortCapability*)(p))->desc[TLV_MAX_PORT_DESC -1] = 0;
|
||||
((tTlvPortCapability*)(p))->portDesc[TLV_MAX_PORT_DESC -1] = 0;
|
||||
p += sizeof(tTlvPortCapability);
|
||||
}
|
||||
msgLen = (p - msg);
|
||||
@ -145,3 +159,350 @@ void RxTx::SendCapabilityInfo(void)
|
||||
host->Log(logStr);
|
||||
host->SendMsg(pktBuff, msgLen);
|
||||
}
|
||||
|
||||
void RxTx::ProcessPortConfig(const char* msg, int len)
|
||||
{
|
||||
// ASSUMPTION: msg points to start of first TLV
|
||||
UINT8 *p = (UINT8*) msg;
|
||||
uTlvStream u;
|
||||
Stream *s;
|
||||
|
||||
// Extract and process each TLV
|
||||
while (len)
|
||||
{
|
||||
if (len < 12)
|
||||
{
|
||||
LOG("Length (%d) Error - not enough to fit a TLV", len);
|
||||
goto _exit;
|
||||
}
|
||||
|
||||
u.tlv.tlvType = NTOHS(GET16(p));
|
||||
u.tlv.tlvLen = NTOHS(GET16(p+2));
|
||||
u.tlv.portId = NTOHL(GET32(p+4));
|
||||
u.tlv.streamId = NTOHL(GET32(p+8));
|
||||
|
||||
p += 12;
|
||||
len -= 12;
|
||||
|
||||
// Locate the correct node for processing
|
||||
if (u.tlv.portId >= numPorts)
|
||||
goto _next_tlv;
|
||||
|
||||
s = GetStream(u.tlv.portId, u.tlv.streamId);
|
||||
if ((s == NULL) && (u.tlv.tlvType!= e_TT_StreamOper))
|
||||
{
|
||||
LOG("Unrecognized stream Id %d\n", u.tlv.streamId);
|
||||
goto _next_tlv;
|
||||
}
|
||||
|
||||
switch(u.tlv.tlvType)
|
||||
{
|
||||
case e_TT_StreamOper:
|
||||
u.oper.streamOper = NTOHS(GET16(p+2));
|
||||
switch (u.oper.streamOper)
|
||||
{
|
||||
case TLV_STREAM_OPER_DELETE:
|
||||
if (!DeleteStream(u.tlv.portId, u.tlv.streamId))
|
||||
{
|
||||
LOG("No Stream with id %d currently in list\n",
|
||||
u.tlv.streamId);
|
||||
goto _next_tlv;
|
||||
}
|
||||
break;
|
||||
case TLV_STREAM_OPER_INSERT_HEAD:
|
||||
s = new Stream;
|
||||
s->id = u.tlv.streamId;
|
||||
|
||||
InsertStreamAtHead(u.tlv.portId, s);
|
||||
break;
|
||||
case TLV_STREAM_OPER_INSERT_TAIL:
|
||||
s = new Stream;
|
||||
s->id = u.tlv.streamId;
|
||||
|
||||
InsertStreamAtTail(u.tlv.portId, s);
|
||||
break;
|
||||
case TLV_STREAM_OPER_INSERT_BEFORE:
|
||||
{
|
||||
UINT32 nextStreamId;
|
||||
|
||||
s = new Stream;
|
||||
s->id = u.tlv.streamId;
|
||||
|
||||
nextStreamId = NTOHS(GET32(p+4));
|
||||
|
||||
if (!InsertStreamBefore(u.tlv.portId, s, nextStreamId))
|
||||
{
|
||||
LOG("List Empty or No stream with id %d "
|
||||
"currently in list\n", nextStreamId);
|
||||
goto _next_tlv;
|
||||
}
|
||||
break;
|
||||
}
|
||||
default:
|
||||
LOG("Unrecognized Stream Oper %d\n",
|
||||
u.oper.streamOper);
|
||||
goto _next_tlv;
|
||||
}
|
||||
break;
|
||||
case e_TT_StreamName:
|
||||
strncpy(s->name, (char*) p, MAX_STREAM_NAME_SIZE);
|
||||
break;
|
||||
|
||||
case e_TT_StreamStatus:
|
||||
u.status.streamStatus = NTOHL(GET32(p));
|
||||
if (u.status.streamStatus == TLV_STREAM_STATUS_DISABLED)
|
||||
s->flags |= STREAM_FLAG_VALUE_STATUS_DISABLED; // FIXME
|
||||
else if (u.status.streamStatus == TLV_STREAM_STATUS_ENABLED)
|
||||
s->flags |= STREAM_FLAG_VALUE_STATUS_ENABLED; // FIXME
|
||||
else
|
||||
goto _next_tlv;
|
||||
break;
|
||||
|
||||
case e_TT_StreamFrameLength:
|
||||
u.frameLen.frameLenMode = NTOHS(GET16(p));
|
||||
u.frameLen.frameLen = NTOHS(GET16(p+2));
|
||||
u.frameLen.frameLenMin = NTOHS(GET16(p+4));
|
||||
u.frameLen.frameLenMax = NTOHS(GET16(p+6));
|
||||
|
||||
s->pktLen = u.frameLen.frameLen;
|
||||
|
||||
// FIXME: other frameLen params
|
||||
break;
|
||||
|
||||
case e_TT_StreamDataPattern:
|
||||
u.dataPattern.dataPatternMode = NTOHS(GET16(p));
|
||||
u.dataPattern.dataPattern = NTOHS(GET32(p+4));
|
||||
|
||||
s->dataPattern = u.dataPattern.dataPattern;
|
||||
|
||||
// FIXME: other dataPattern params
|
||||
break;
|
||||
|
||||
case e_TT_StreamHeaderData:
|
||||
u.headerData.headerLen = NTOHS(GET16(p+2));
|
||||
|
||||
s->hdrLen = u.headerData.headerLen;
|
||||
memcpy(s->pktHdr, p+4, u.headerData.headerLen);
|
||||
break;
|
||||
|
||||
default:
|
||||
LOG("Unrecognizeed/Unexpected TLV %d\n", u.tlv.tlvType);
|
||||
}
|
||||
|
||||
_next_tlv:
|
||||
p += u.tlv.tlvLen;
|
||||
len -= u.tlv.tlvLen;
|
||||
}
|
||||
|
||||
_exit:
|
||||
return;
|
||||
}
|
||||
|
||||
void RxTx::SendPortInfo(unsigned int port)
|
||||
{
|
||||
// Assumption: port is valid
|
||||
assert(port < numPorts);
|
||||
|
||||
}
|
||||
|
||||
/*
|
||||
** --------------------- STREAM LIST OPERATIONS -------------------------
|
||||
*/
|
||||
|
||||
void RxTx::InsertStreamAtHead(unsigned int port, Stream *s)
|
||||
{
|
||||
if (portInfo[port].streamHead == NULL)
|
||||
{
|
||||
// list empty - first entry being added
|
||||
s->next = NULL;
|
||||
portInfo[port].streamHead = portInfo[port].streamTail = s;
|
||||
}
|
||||
else
|
||||
{
|
||||
// at least one entry in list, so tail does not change
|
||||
s->next = portInfo[port].streamHead;
|
||||
portInfo[port].streamHead = s;
|
||||
}
|
||||
}
|
||||
|
||||
void RxTx::InsertStreamAtTail(unsigned int port, Stream *s)
|
||||
{
|
||||
s->next = NULL;
|
||||
if (portInfo[port].streamHead == NULL)
|
||||
{
|
||||
// list empty - first entry being added
|
||||
portInfo[port].streamHead = portInfo[port].streamTail = s;
|
||||
}
|
||||
else
|
||||
{
|
||||
// at least one entry in list, so head does not change
|
||||
portInfo[port].streamTail->next = s;
|
||||
portInfo[port].streamTail = s;
|
||||
}
|
||||
}
|
||||
|
||||
bool RxTx::InsertStreamBefore(unsigned int port, Stream *s,
|
||||
unsigned int nextStreamId)
|
||||
{
|
||||
Stream *q, *r;
|
||||
|
||||
// For an "Insert Before", list cannot be empty
|
||||
if (portInfo[port].streamHead == NULL)
|
||||
{
|
||||
LOG("Cannot 'insert before' in an empty list");
|
||||
return false;
|
||||
}
|
||||
|
||||
// Traverse with 'r' and keep track of previous with 'q'
|
||||
q = NULL;
|
||||
r = portInfo[port].streamHead;
|
||||
while (r != NULL)
|
||||
{
|
||||
if (r->id == nextStreamId)
|
||||
{
|
||||
if (r == portInfo[port].streamHead)
|
||||
{
|
||||
// Insert at Head
|
||||
s->next = portInfo[port].streamHead;
|
||||
portInfo[port].streamHead = s;
|
||||
}
|
||||
else if (r == portInfo[port].streamTail)
|
||||
{
|
||||
// Insert one before Tail
|
||||
s->next = portInfo[port].streamTail;
|
||||
q->next = s;
|
||||
}
|
||||
else
|
||||
{
|
||||
s->next = r;
|
||||
q->next = s;
|
||||
}
|
||||
|
||||
break;
|
||||
}
|
||||
q = r;
|
||||
r = r->next;
|
||||
}
|
||||
|
||||
if (r == NULL)
|
||||
return false;
|
||||
else
|
||||
return true;
|
||||
}
|
||||
|
||||
bool RxTx::DeleteStream(unsigned int port, Stream *s)
|
||||
{
|
||||
Stream *q, *r;
|
||||
|
||||
// Traverse with 'r' and keep track of prev with 'q'
|
||||
q = NULL;
|
||||
r = portInfo[port].streamHead;
|
||||
while (r != NULL)
|
||||
{
|
||||
if (r == s)
|
||||
{
|
||||
if (r == portInfo[port].streamHead)
|
||||
{
|
||||
if (portInfo[port].streamHead == portInfo[port].streamTail)
|
||||
{
|
||||
portInfo[port].streamHead = NULL;
|
||||
portInfo[port].streamTail = NULL;
|
||||
}
|
||||
else
|
||||
portInfo[port].streamHead = portInfo[port].streamHead->next;
|
||||
}
|
||||
else if (r == portInfo[port].streamTail)
|
||||
{
|
||||
q->next = NULL;
|
||||
portInfo[port].streamTail = q;
|
||||
}
|
||||
else
|
||||
{
|
||||
q->next = r->next;
|
||||
}
|
||||
|
||||
delete r;
|
||||
break;
|
||||
}
|
||||
q = r;
|
||||
r = r->next;
|
||||
}
|
||||
|
||||
if (r == NULL)
|
||||
return false;
|
||||
else
|
||||
return true;
|
||||
}
|
||||
|
||||
bool RxTx::DeleteStream(unsigned int port, unsigned int streamId)
|
||||
{
|
||||
Stream *q, *r;
|
||||
|
||||
// Traverse with 'r' and keep track of prev with 'q'
|
||||
q = NULL;
|
||||
r = portInfo[port].streamHead;
|
||||
while (r != NULL)
|
||||
{
|
||||
if (r->id == streamId)
|
||||
{
|
||||
if (r == portInfo[port].streamHead)
|
||||
{
|
||||
if (portInfo[port].streamHead == portInfo[port].streamTail)
|
||||
{
|
||||
portInfo[port].streamHead = NULL;
|
||||
portInfo[port].streamTail = NULL;
|
||||
}
|
||||
else
|
||||
portInfo[port].streamHead = portInfo[port].streamHead->next;
|
||||
}
|
||||
else if (r == portInfo[port].streamTail)
|
||||
{
|
||||
q->next = NULL;
|
||||
portInfo[port].streamTail = q;
|
||||
}
|
||||
else
|
||||
{
|
||||
q->next = r->next;
|
||||
}
|
||||
|
||||
delete r;
|
||||
break;
|
||||
}
|
||||
q = r;
|
||||
r = r->next;
|
||||
}
|
||||
|
||||
if (r == NULL)
|
||||
return false;
|
||||
else
|
||||
return true;
|
||||
}
|
||||
|
||||
void RxTx::DeleteAllStreams(unsigned int port)
|
||||
{
|
||||
Stream *r, *q;
|
||||
|
||||
r = portInfo[port].streamHead;
|
||||
while (r != NULL)
|
||||
{
|
||||
q = r;
|
||||
r = r->next;
|
||||
delete q;
|
||||
}
|
||||
}
|
||||
|
||||
Stream* RxTx::GetStream(unsigned int port, unsigned int streamId)
|
||||
{
|
||||
Stream *r;
|
||||
|
||||
r = portInfo[port].streamHead;
|
||||
while (r != NULL)
|
||||
{
|
||||
if (r->id == streamId)
|
||||
return r;
|
||||
r = r->next;
|
||||
}
|
||||
|
||||
return NULL;
|
||||
}
|
||||
|
||||
|
@ -4,11 +4,41 @@
|
||||
#include "pcap.h"
|
||||
#include "abstracthost.h"
|
||||
|
||||
#define GET16(x) (UINT16)( \
|
||||
(*((UINT8*)x+0) << 16 ) \
|
||||
| (*((UINT8*)x+1)))
|
||||
|
||||
#define GET32(x) (UINT32)( \
|
||||
(*((UINT8*)x+0) << 24) \
|
||||
| (*((UINT8*)x+1) << 16) \
|
||||
| (*((UINT8*)x+2) << 8 ) \
|
||||
| (*((UINT8*)x+3)))
|
||||
|
||||
#define MAX_PKT_HDR_SIZE 1536
|
||||
#define MAX_STREAM_NAME_SIZE 64
|
||||
|
||||
typedef struct _Stream
|
||||
{
|
||||
unsigned int id;
|
||||
char name[MAX_STREAM_NAME_SIZE];
|
||||
unsigned char pktHdr[MAX_PKT_HDR_SIZE];
|
||||
unsigned short hdrLen;
|
||||
unsigned short pktLen;
|
||||
unsigned int dataPattern;
|
||||
unsigned int flags;
|
||||
#define STREAM_FLAG_MASK_STATUS 0x00000001
|
||||
#define STREAM_FLAG_VALUE_STATUS_DISABLED 0x00000000
|
||||
#define STREAM_FLAG_VALUE_STATUS_ENABLED 0x00000001
|
||||
|
||||
struct _Stream *next;
|
||||
} Stream;
|
||||
|
||||
typedef struct
|
||||
{
|
||||
unsigned int portId;
|
||||
pcap_if_t *dev;
|
||||
Stream *streamHead;
|
||||
Stream *streamTail;
|
||||
} PortInfo;
|
||||
|
||||
class RxTx
|
||||
@ -28,8 +58,19 @@ class RxTx
|
||||
PortInfo *portInfo;
|
||||
pcap_if_t *alldevs;
|
||||
|
||||
void InsertStreamAtHead(unsigned int port, Stream *s);
|
||||
void InsertStreamAtTail(unsigned int port, Stream *s);
|
||||
bool InsertStreamBefore(unsigned int port, Stream *s,
|
||||
unsigned int nextStreamId);
|
||||
bool DeleteStream(unsigned int port, Stream *s);
|
||||
bool DeleteStream(unsigned int port, unsigned int streamId);
|
||||
void DeleteAllStreams(unsigned int port);
|
||||
Stream* GetStream(unsigned int port, unsigned int streamId);
|
||||
|
||||
//void Log(char *fmt, ...);
|
||||
void SendCapabilityInfo(void);
|
||||
void SendPortInfo(unsigned int port);
|
||||
void ProcessPortConfig(const char* msg, int len);
|
||||
};
|
||||
|
||||
#endif
|
||||
|
Loading…
Reference in New Issue
Block a user