Sample Protocol completed - can be used as a template while implementing a new protocol
This commit is contained in:
Srivats P. 2009-11-16 13:09:20 +00:00
parent 3602d24767
commit c9563b50eb
8 changed files with 568 additions and 35 deletions

View File

@ -88,7 +88,7 @@ public:
quint32 payloadProtocolId(ProtocolIdType type) const;
virtual int fieldCount() const;
virtual int metaFieldCount() const;
int metaFieldCount() const;
int frameFieldCount() const;
virtual FieldFlags fieldFlags(int index) const;

View File

@ -13,7 +13,8 @@ FORMS += \
vlan.ui \
ip4.ui \
tcp.ui \
udp.ui
udp.ui \
sample.ui
PROTOS += \
protocol.proto \
mac.proto \
@ -29,7 +30,8 @@ PROTOS += \
vlanstack.proto \
ip4.proto \
tcp.proto \
udp.proto
udp.proto \
sample.proto
HEADERS += \
abstractprotocol.h \
comboprotocol.h \
@ -50,7 +52,8 @@ HEADERS += \
vlanstack.h \
ip4.h \
tcp.h \
udp.h
udp.h \
sample.h
SOURCES += \
abstractprotocol.cpp \
protocolmanager.cpp \
@ -67,7 +70,8 @@ SOURCES += \
svlan.cpp \
ip4.cpp \
tcp.cpp \
udp.cpp
udp.cpp \
sample.cpp
protobuf_decl.name = protobuf header
protobuf_decl.input = PROTOS

View File

@ -70,6 +70,7 @@ message Protocol {
enum k {
kMacFieldNumber = 51;
kPayloadFieldNumber = 52;
kSampleFieldNumber = 53;
kEth2FieldNumber = 121;
kDot3FieldNumber = 122;

View File

@ -2,6 +2,7 @@
#include "abstractprotocol.h"
#include "protocol.pb.h"
#include "sample.h"
#include "mac.h"
#include "payload.h"
#include "eth2.h"
@ -52,6 +53,9 @@ ProtocolManager::ProtocolManager()
registerProtocol(OstProto::Protocol::kUdpFieldNumber,
(void*) UdpProtocol::createInstance);
registerProtocol(OstProto::Protocol::kSampleFieldNumber,
(void*) SampleProtocol::createInstance);
populateNeighbourProtocols();
}

View File

@ -1,19 +1,14 @@
#include <qendian.h>
#include <QHostAddress>
#include "sample.h"
/*! \todo (MED) Complete the "sample" protocol and make it compilable so that
it can be used as an example for new protocols
*/
SampleConfigForm::SampleConfigForm(QWidget *parent)
: QWidget(parent)
{
setupUi(this);
}
SampleProtocol::SampleProtocol(StreamBase *stream, AbstractProtocol *parent);
SampleProtocol::SampleProtocol(StreamBase *stream, AbstractProtocol *parent)
: AbstractProtocol(stream, parent)
{
configForm = NULL;
@ -38,24 +33,55 @@ quint32 SampleProtocol::protocolNumber() const
void SampleProtocol::protoDataCopyInto(OstProto::Protocol &protocol) const
{
protocol.MutableExtension(OstProto::sample)->CopyFrom(data);
protocol.mutable_protocol_id()->set_id(protocolNumber())
protocol.mutable_protocol_id()->set_id(protocolNumber());
}
void SampleProtocol::protoDataCopyFrom(const OstProto::Protocol &protocol)
{
if (protocol.protocol_id()->id() == protocolNumber() &&
if (protocol.protocol_id().id() == protocolNumber() &&
protocol.HasExtension(OstProto::sample))
data.MergeFrom(protocol.GetExtension(OstProto::sample));
}
QString SampleProtocol::name() const
{
return QString("Sample");
return QString("Sample Protocol");
}
QString SampleProtocol::shortName() const
{
return QString("Sample");
return QString("SAMPLE");
}
/*!
Return the ProtocolIdType for your protocol \n
If your protocol doesn't have a protocolId field, you don't need to
reimplement this method - the base class implementation will do the
right thing
*/
AbstractProtocol::ProtocolIdType SampleProtocol::protocolIdType() const
{
return ProtocolIdIp;
}
/*!
Return the protocolId for your protoocol based on the 'type' requested \n
If not all types are valid for your protocol, handle the valid type(s)
and for the remaining fallback to the base class implementation; if your
protocol doesn't have a protocolId at all, you don't need to reimplement
this method - the base class will do the right thing
*/
quint32 SampleProtocol::protocolId(ProtocolIdType type) const
{
switch(type)
{
case ProtocolIdIp: return 1234;
default:break;
}
return AbstractProtocol::protocolId(type);
}
int SampleProtocol::fieldCount() const
@ -71,18 +97,26 @@ AbstractProtocol::FieldFlags SampleProtocol::fieldFlags(int index) const
switch (index)
{
case sample_normal:
case sample_a:
case sample_b:
case sample_payloadLength:
break;
case sample_cksum:
case sample_checksum:
flags |= FieldIsCksum;
break;
case sample_meta:
case sample_x:
case sample_y:
break;
case sample_is_override_checksum:
flags |= FieldIsMeta;
break;
default:
qFatal("%s: unimplemented case %d in switch", __PRETTY_FUNCTION__,
index);
break;
}
@ -94,57 +128,190 @@ QVariant SampleProtocol::fieldData(int index, FieldAttrib attrib,
{
switch (index)
{
case sample_one:
case sample_a:
{
int a = data.ab() >> 13;
switch(attrib)
{
case FieldName:
return QString("ONE");
return QString("A");
case FieldValue:
return data.one();
return a;
case FieldTextValue:
return QString("%1").arg(data.one());
return QString("%1").arg(a);
case FieldFrameValue:
return QByteArray(1, (char)(data.one() & 0xF0));
return QByteArray(1, (char) a);
case FieldBitSize:
return 4;
return 3;
default:
break;
}
break;
}
case sample_two:
case sample_b:
{
int b = data.ab() & 0x1FFF;
switch(attrib)
{
case FieldName:
return QString("TWO");
return QString("B");
case FieldValue:
return data.two();
return b;
case FieldTextValue:
return QString("%1").arg(data.two());
return QString("%1").arg(b, 4, BASE_HEX, QChar('0'));
case FieldFrameValue:
{
QByteArray fv;
fv.resize(0);
qToBigEndian(FIXME, (uchar*) fv.data());
fv.resize(2);
qToBigEndian((quint16) b, (uchar*) fv.data());
return fv;
}
return QByteArray(1, (char)(FIXME() & 0xF0));
case FieldBitSize:
return 4;
return 13;
default:
break;
}
break;
}
// Meta fields
case sample_FIXME:
case sample_payloadLength:
{
switch(attrib)
{
case FieldName:
return QString("Payload Length");
case FieldValue:
return protocolFramePayloadSize(streamIndex);
case FieldFrameValue:
{
QByteArray fv;
int totlen;
totlen = protocolFramePayloadSize(streamIndex);
fv.resize(2);
qToBigEndian((quint16) totlen, (uchar*) fv.data());
return fv;
}
case FieldTextValue:
return QString("%1").arg(
protocolFramePayloadSize(streamIndex));
case FieldBitSize:
return 16;
default:
break;
}
break;
}
case sample_checksum:
{
quint16 cksum;
switch(attrib)
{
case FieldValue:
case FieldFrameValue:
case FieldTextValue:
{
if (data.is_override_checksum())
cksum = data.checksum();
else
cksum = protocolFrameCksum(streamIndex, CksumIp);
}
default:
break;
}
switch(attrib)
{
case FieldName:
return QString("Checksum");
case FieldValue:
return cksum;
case FieldFrameValue:
{
QByteArray fv;
fv.resize(2);
qToBigEndian(cksum, (uchar*) fv.data());
return fv;
}
case FieldTextValue:
return QString("0x%1").arg(
cksum, 4, BASE_HEX, QChar('0'));;
case FieldBitSize:
return 16;
default:
break;
}
break;
}
case sample_x:
{
switch(attrib)
{
case FieldName:
return QString("X");
case FieldValue:
return data.x();
case FieldTextValue:
return QString("%1").arg(data.x());
//return QString("%1").arg(data.x(), 8, BASE_HEX, QChar('0'));
case FieldFrameValue:
{
QByteArray fv;
fv.resize(4);
qToBigEndian((quint32) data.x(), (uchar*) fv.data());
return fv;
}
default:
break;
}
break;
}
case sample_y:
{
switch(attrib)
{
case FieldName:
return QString("Y");
case FieldValue:
return data.y();
case FieldTextValue:
//return QString("%1").arg(data.y());
return QString("%1").arg(data.y(), 8, BASE_HEX, QChar('0'));
case FieldFrameValue:
{
QByteArray fv;
fv.resize(4);
qToBigEndian((quint32) data.y(), (uchar*) fv.data());
return fv;
}
default:
break;
}
break;
}
// Meta fields
case sample_is_override_checksum:
{
switch(attrib)
{
case FieldValue:
return data.is_override_checksum();
default:
break;
}
break;
}
default:
qFatal("%s: unimplemented case %d in switch", __PRETTY_FUNCTION__,
index);
break;
}
return AbstractProtocol::fieldData(index, attrib, streamIndex);
}
@ -152,10 +319,105 @@ QVariant SampleProtocol::fieldData(int index, FieldAttrib attrib,
bool SampleProtocol::setFieldData(int index, const QVariant &value,
FieldAttrib attrib)
{
// FIXME
bool isOk = false;
if (attrib != FieldValue)
goto _exit;
switch (index)
{
case sample_a:
{
uint a = value.toUInt(&isOk);
if (isOk)
data.set_ab((data.ab() & 0xe000) | (a << 13));
break;
}
case sample_b:
{
uint b = value.toUInt(&isOk);
if (isOk)
data.set_ab((data.ab() & 0x1FFF) | b);
break;
}
case sample_payloadLength:
{
uint len = value.toUInt(&isOk);
if (isOk)
data.set_payload_length(len);
break;
}
case sample_checksum:
{
uint csum = value.toUInt(&isOk);
if (isOk)
data.set_checksum(csum);
break;
}
case sample_x:
{
uint x = value.toUInt(&isOk);
if (isOk)
data.set_x(x);
break;
}
case sample_y:
{
uint y = value.toUInt(&isOk);
if (isOk)
data.set_y(y);
break;
}
case sample_is_override_checksum:
{
bool ovr = value.toBool();
data.set_is_override_checksum(ovr);
isOk = true;
break;
}
default:
qFatal("%s: unimplemented case %d in switch", __PRETTY_FUNCTION__,
index);
break;
}
_exit:
return isOk;
}
/*!
Return the protocol frame size in bytes\n
If your protocol has a fixed size - you don't need to reimplement this; the
base class implementation is good enough
*/
int SampleProtocol::protocolFrameSize(int streamIndex) const
{
return AbstractProtocol::protocolFrameSize(streamIndex);
}
/*!
If your protocol has any variable fields, return true \n
Otherwise you don't need to reimplement this method - the base class always
returns false
*/
bool SampleProtocol::isProtocolFrameValueVariable() const
{
return false;
}
/*!
If your protocol frame size can vary across pkts of the same stream,
return true \n
Otherwise you don't need to reimplement this method - the base class always
returns false
*/
bool SampleProtocol::isProtocolFrameSizeVariable() const
{
return false;
}
QWidget* SampleProtocol::configWidget()
{
@ -171,6 +433,21 @@ QWidget* SampleProtocol::configWidget()
void SampleProtocol::loadConfigWidget()
{
configWidget();
configForm->sampleA->setText(fieldData(sample_a, FieldValue).toString());
configForm->sampleB->setText(fieldData(sample_b, FieldValue).toString());
configForm->samplePayloadLength->setText(
fieldData(sample_payloadLength, FieldValue).toString());
configForm->isChecksumOverride->setChecked(
fieldData(sample_is_override_checksum, FieldValue).toBool());
configForm->sampleChecksum->setText(uintToHexStr(
fieldData(sample_checksum, FieldValue).toUInt(), 2));
configForm->sampleX->setText(fieldData(sample_x, FieldValue).toString());
configForm->sampleY->setText(fieldData(sample_y, FieldValue).toString());
}
void SampleProtocol::storeConfigWidget()
@ -178,5 +455,15 @@ void SampleProtocol::storeConfigWidget()
bool isOk;
configWidget();
setFieldData(sample_a, configForm->sampleA->text());
setFieldData(sample_b, configForm->sampleB->text());
setFieldData(sample_payloadLength, configForm->samplePayloadLength->text());
setFieldData(sample_is_override_checksum,
configForm->isChecksumOverride->isChecked());
setFieldData(sample_checksum, configForm->sampleChecksum->text().toUInt(&isOk, BASE_HEX));
setFieldData(sample_x, configForm->sampleX->text());
setFieldData(sample_y, configForm->sampleY->text());
}

View File

@ -6,6 +6,15 @@
#include "sample.pb.h"
#include "ui_sample.h"
/*
Sample Protocol Frame Format -
+-----+------+------+------+------+------+
| A | B | LEN | CSUM | X | Y |
| (3) | (13) | (16) | (16) | (32) | (32) |
+-----+------+------+------+------+------+
Figures in brackets represent field width in bits
*/
class SampleConfigForm : public QWidget, public Ui::Sample
{
Q_OBJECT
@ -21,6 +30,16 @@ private:
SampleConfigForm *configForm;
enum samplefield
{
// Frame Fields
sample_a = 0,
sample_b,
sample_payloadLength,
sample_checksum,
sample_x,
sample_y,
// Meta Fields
sample_is_override_checksum,
sample_fieldCount
};
@ -36,6 +55,9 @@ public:
virtual void protoDataCopyInto(OstProto::Protocol &protocol) const;
virtual void protoDataCopyFrom(const OstProto::Protocol &protocol);
virtual ProtocolIdType protocolIdType() const;
virtual quint32 protocolId(ProtocolIdType type) const;
virtual QString name() const;
virtual QString shortName() const;
@ -47,6 +69,11 @@ public:
virtual bool setFieldData(int index, const QVariant &value,
FieldAttrib attrib = FieldValue);
virtual int protocolFrameSize(int streamIndex = 0) const;
virtual bool isProtocolFrameValueVariable() const;
virtual bool isProtocolFrameSizeVariable() const;
virtual QWidget* configWidget();
virtual void loadConfigWidget();
virtual void storeConfigWidget();

19
common/sample.proto Normal file
View File

@ -0,0 +1,19 @@
import "protocol.proto";
package OstProto;
// Sample Protocol
message Sample {
optional bool is_override_checksum = 1;
optional uint32 ab = 2;
optional uint32 payload_length = 3;
optional uint32 checksum = 4;
optional uint32 x = 5 [default = 1234];
optional uint32 y = 6;
}
extend Protocol {
optional Sample sample = 53;
}

191
common/sample.ui Normal file
View File

@ -0,0 +1,191 @@
<ui version="4.0" >
<class>Sample</class>
<widget class="QWidget" name="Sample" >
<property name="geometry" >
<rect>
<x>0</x>
<y>0</y>
<width>263</width>
<height>116</height>
</rect>
</property>
<property name="windowTitle" >
<string>Form</string>
</property>
<layout class="QGridLayout" >
<item row="0" column="0" >
<widget class="QLabel" name="label_22" >
<property name="text" >
<string>Field A</string>
</property>
<property name="alignment" >
<set>Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter</set>
</property>
<property name="buddy" >
<cstring>sampleA</cstring>
</property>
</widget>
</item>
<item row="0" column="1" >
<widget class="QLineEdit" name="sampleA" >
<property name="inputMask" >
<string>>HH; </string>
</property>
<property name="text" >
<string/>
</property>
</widget>
</item>
<item row="0" column="2" >
<widget class="QCheckBox" name="isChecksumOverride" >
<property name="text" >
<string>Checksum</string>
</property>
</widget>
</item>
<item row="0" column="3" >
<widget class="QLineEdit" name="sampleChecksum" >
<property name="enabled" >
<bool>false</bool>
</property>
<property name="inputMask" >
<string>>HH HH; </string>
</property>
</widget>
</item>
<item row="1" column="0" >
<widget class="QLabel" name="label_24" >
<property name="text" >
<string>Field B</string>
</property>
<property name="alignment" >
<set>Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter</set>
</property>
<property name="buddy" >
<cstring>sampleB</cstring>
</property>
</widget>
</item>
<item row="1" column="1" >
<widget class="QLineEdit" name="sampleB" >
<property name="inputMask" >
<string>>HH HH; </string>
</property>
</widget>
</item>
<item row="1" column="2" >
<widget class="QLabel" name="label_25" >
<property name="text" >
<string>Field X</string>
</property>
<property name="alignment" >
<set>Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter</set>
</property>
<property name="buddy" >
<cstring>sampleX</cstring>
</property>
</widget>
</item>
<item row="1" column="3" >
<widget class="QLineEdit" name="sampleX" />
</item>
<item row="1" column="4" >
<spacer>
<property name="orientation" >
<enum>Qt::Horizontal</enum>
</property>
<property name="sizeHint" >
<size>
<width>40</width>
<height>20</height>
</size>
</property>
</spacer>
</item>
<item row="2" column="0" >
<widget class="QLabel" name="label_27" >
<property name="text" >
<string>Length</string>
</property>
<property name="alignment" >
<set>Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter</set>
</property>
<property name="buddy" >
<cstring>samplePayloadLength</cstring>
</property>
</widget>
</item>
<item row="2" column="1" >
<widget class="QLineEdit" name="samplePayloadLength" >
<property name="enabled" >
<bool>false</bool>
</property>
<property name="text" >
<string/>
</property>
</widget>
</item>
<item row="2" column="2" >
<widget class="QLabel" name="label_26" >
<property name="text" >
<string>Field Y</string>
</property>
<property name="alignment" >
<set>Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter</set>
</property>
<property name="buddy" >
<cstring>sampleY</cstring>
</property>
</widget>
</item>
<item row="2" column="3" >
<widget class="QLineEdit" name="sampleY" >
<property name="text" >
<string/>
</property>
</widget>
</item>
<item row="3" column="2" >
<spacer>
<property name="orientation" >
<enum>Qt::Vertical</enum>
</property>
<property name="sizeHint" >
<size>
<width>20</width>
<height>40</height>
</size>
</property>
</spacer>
</item>
</layout>
</widget>
<tabstops>
<tabstop>sampleA</tabstop>
<tabstop>sampleB</tabstop>
<tabstop>samplePayloadLength</tabstop>
<tabstop>isChecksumOverride</tabstop>
<tabstop>sampleChecksum</tabstop>
<tabstop>sampleX</tabstop>
<tabstop>sampleY</tabstop>
</tabstops>
<resources/>
<connections>
<connection>
<sender>isChecksumOverride</sender>
<signal>toggled(bool)</signal>
<receiver>sampleChecksum</receiver>
<slot>setEnabled(bool)</slot>
<hints>
<hint type="sourcelabel" >
<x>345</x>
<y>122</y>
</hint>
<hint type="destinationlabel" >
<x>406</x>
<y>122</y>
</hint>
</hints>
</connection>
</connections>
</ui>