NOX: GMP, IGMP, MLD - Separated protocol and widget as per new framework

This commit is contained in:
Srivats P. 2014-04-10 18:24:30 +05:30
parent 21b606e9ea
commit 481e517fa6
16 changed files with 808 additions and 555 deletions

View File

@ -18,193 +18,17 @@ along with this program. If not, see <http://www.gnu.org/licenses/>
*/
#include "gmp.h"
#include <QHeaderView>
#include <qendian.h>
#include <QStringList>
QHash<int, int> GmpProtocol::frameFieldCountMap;
GmpConfigForm::GmpConfigForm(QWidget *parent)
: QWidget(parent)
{
setupUi(this);
auxData->setValidator(new QRegExpValidator(
QRegExp("[0-9A-Fa-f]*"), this));
}
GmpConfigForm::~GmpConfigForm()
{
}
void GmpConfigForm::update()
{
// save the current group Record by simulating a currentItemChanged()
on_groupList_currentItemChanged(groupList->currentItem(),
groupList->currentItem());
}
void GmpConfigForm::on_groupMode_currentIndexChanged(int index)
{
bool disabled = (index == 0);
groupCount->setDisabled(disabled);
groupPrefix->setDisabled(disabled);
}
void GmpConfigForm::on_addSource_clicked()
{
QListWidgetItem *item=new QListWidgetItem(_defaultSourceIp);
item->setFlags(item->flags() | Qt::ItemIsEditable);
sourceList->insertItem(sourceList->currentRow(), item);
if (!overrideSourceCount->isChecked())
sourceCount->setText(QString().setNum(sourceList->count()));
}
void GmpConfigForm::on_deleteSource_clicked()
{
delete sourceList->takeItem(sourceList->currentRow());
if (!overrideSourceCount->isChecked())
sourceCount->setText(QString().setNum(sourceList->count()));
}
void GmpConfigForm::on_addGroupRecord_clicked()
{
OstProto::Gmp::GroupRecord defRec;
QVariantMap grpRec;
QListWidgetItem *item = new QListWidgetItem;
grpRec["groupRecordType"] = defRec.type();
grpRec["groupRecordAddress"] = _defaultGroupIp;
grpRec["overrideGroupRecordSourceCount"] =defRec.is_override_source_count();
grpRec["groupRecordSourceCount"] = defRec.source_count();
grpRec["groupRecordSourceList"] = QStringList();
grpRec["overrideAuxDataLength"] = defRec.is_override_aux_data_length();
grpRec["auxDataLength"] = defRec.aux_data_length();
grpRec["auxData"] = QByteArray().append(
QString().fromStdString(defRec.aux_data()));
item->setData(Qt::UserRole, grpRec);
item->setText(QString("%1: %2")
.arg(groupRecordType->itemText(grpRec["groupRecordType"].toInt()))
.arg(grpRec["groupRecordAddress"].toString()));
groupList->insertItem(groupList->currentRow(), item);
if (!overrideGroupRecordCount->isChecked())
groupRecordCount->setText(QString().setNum(groupList->count()));
}
void GmpConfigForm::on_deleteGroupRecord_clicked()
{
delete groupList->takeItem(groupList->currentRow());
if (!overrideGroupRecordCount->isChecked())
groupRecordCount->setText(QString().setNum(groupList->count()));
}
void GmpConfigForm::on_groupList_currentItemChanged(QListWidgetItem *current,
QListWidgetItem *previous)
{
QVariantMap rec;
QStringList strList;
qDebug("in %s", __FUNCTION__);
// save previous record ...
if (previous == NULL)
goto _load_current_record;
rec["groupRecordType"] = groupRecordType->currentIndex();
rec["groupRecordAddress"] = groupRecordAddress->text();
strList.clear();
while (groupRecordSourceList->count())
{
QListWidgetItem *item = groupRecordSourceList->takeItem(0);
strList.append(item->text());
delete item;
}
rec["groupRecordSourceList"] = strList;
rec["overrideGroupRecordSourceCount"] =
overrideGroupRecordSourceCount->isChecked();
rec["groupRecordSourceCount"] = groupRecordSourceCount->text().toUInt();
rec["overrideAuxDataLength"] = overrideAuxDataLength->isChecked();
rec["auxDataLength"] = auxDataLength->text().toUInt();
rec["auxData"] = QByteArray().fromHex(QByteArray().append(auxData->text()));
previous->setData(Qt::UserRole, rec);
previous->setText(QString("%1: %2")
.arg(groupRecordType->itemText(rec["groupRecordType"].toInt()))
.arg(rec["groupRecordAddress"].toString()));
_load_current_record:
// ... and load current record
if (current == NULL)
goto _exit;
rec = current->data(Qt::UserRole).toMap();
groupRecordType->setCurrentIndex(rec["groupRecordType"].toInt());
groupRecordAddress->setText(rec["groupRecordAddress"].toString());
strList = rec["groupRecordSourceList"].toStringList();
groupRecordSourceList->clear();
foreach (QString str, strList)
{
QListWidgetItem *item = new QListWidgetItem(str, groupRecordSourceList);
item->setFlags(item->flags() | Qt::ItemIsEditable);
}
overrideGroupRecordSourceCount->setChecked(
rec["overrideGroupRecordSourceCount"].toBool());
groupRecordSourceCount->setText(QString().setNum(
rec["groupRecordSourceCount"].toUInt()));
overrideAuxDataLength->setChecked(rec["overrideAuxDataLength"].toBool());
auxDataLength->setText(QString().setNum(rec["auxDataLength"].toUInt()));
auxData->setText(QString(rec["auxData"].toByteArray().toHex()));
_exit:
groupRecord->setEnabled(current != NULL);
return;
}
void GmpConfigForm::on_addGroupRecordSource_clicked()
{
QListWidgetItem *item=new QListWidgetItem(_defaultSourceIp);
item->setFlags(item->flags() | Qt::ItemIsEditable);
groupRecordSourceList->insertItem(groupRecordSourceList->currentRow(),item);
if (!overrideGroupRecordSourceCount->isChecked())
groupRecordSourceCount->setText(QString().setNum(
groupRecordSourceList->count()));
}
void GmpConfigForm::on_deleteGroupRecordSource_clicked()
{
delete groupRecordSourceList->takeItem(groupRecordSourceList->currentRow());
if (!overrideGroupRecordSourceCount->isChecked())
groupRecordSourceCount->setText(QString().setNum(
groupRecordSourceList->count()));
}
void GmpConfigForm::on_auxData_textChanged(const QString &text)
{
// auxDataLength is in units of words and each byte is 2 chars in text()
if (!overrideAuxDataLength->isChecked())
auxDataLength->setText(QString().setNum((text.size()+7)/8));
}
GmpProtocol::GmpProtocol(StreamBase *stream, AbstractProtocol *parent)
: AbstractProtocol(stream, parent)
{
/* The configWidget is created lazily */
configForm = NULL;
}
GmpProtocol::~GmpProtocol()
{
delete configForm;
}
AbstractProtocol::ProtocolIdType GmpProtocol::protocolIdType() const
@ -943,113 +767,3 @@ int GmpProtocol::protocolFrameVariableCount() const
return count;
}
void GmpProtocol::loadConfigWidget()
{
configWidget();
configForm->msgTypeCombo->setValue(fieldData(kType, FieldValue).toUInt());
// XXX: configForm->maxResponseTime set by subclass
configForm->overrideChecksum->setChecked(
fieldData(kIsOverrideChecksum, FieldValue).toBool());
configForm->checksum->setText(uintToHexStr(
fieldData(kChecksum, FieldValue).toUInt(), 2));
configForm->groupAddress->setText(
fieldData(kGroupAddress, FieldValue).toString());
configForm->groupMode->setCurrentIndex(
fieldData(kGroupMode, FieldValue).toUInt());
configForm->groupCount->setText(
fieldData(kGroupCount, FieldValue).toString());
configForm->groupPrefix->setText(
fieldData(kGroupPrefix, FieldValue).toString());
configForm->sFlag->setChecked(fieldData(kSFlag, FieldValue).toBool());
configForm->qrv->setText(fieldData(kQrv, FieldValue).toString());
configForm->qqi->setText(fieldData(kQqic, FieldValue).toString());
QStringList sl = fieldData(kSources, FieldValue).toStringList();
configForm->sourceList->clear();
foreach(QString src, sl)
{
QListWidgetItem *item = new QListWidgetItem(src);
item->setFlags(item->flags() | Qt::ItemIsEditable);
configForm->sourceList->addItem(item);
}
// NOTE: SourceCount should be loaded after sourceList
configForm->overrideSourceCount->setChecked(
fieldData(kIsOverrideSourceCount, FieldValue).toBool());
configForm->sourceCount->setText(
fieldData(kSourceCount, FieldValue).toString());
QVariantList list = fieldData(kGroupRecords, FieldValue).toList();
configForm->groupList->clear();
foreach (QVariant rec, list)
{
QVariantMap grpRec = rec.toMap();
QListWidgetItem *item = new QListWidgetItem;
item->setData(Qt::UserRole, grpRec);
item->setText(QString("%1: %2")
.arg(configForm->groupRecordType->itemText(
grpRec["groupRecordType"].toInt()))
.arg(grpRec["groupRecordAddress"].toString()));
configForm->groupList->addItem(item);
}
// NOTE: recordCount should be loaded after recordList
configForm->overrideGroupRecordCount->setChecked(
fieldData(kIsOverrideGroupRecordCount, FieldValue).toBool());
configForm->groupRecordCount->setText(
fieldData(kGroupRecordCount, FieldValue).toString());
}
void GmpProtocol::storeConfigWidget()
{
bool isOk;
configWidget();
configForm->update();
setFieldData(kType, configForm->msgTypeCombo->currentValue());
// XXX: configForm->maxResponseTime handled by subclass
setFieldData(kIsOverrideChecksum,
configForm->overrideChecksum->isChecked());
setFieldData(kChecksum,
configForm->checksum->text().toUInt(&isOk, BASE_HEX));
setFieldData(kGroupAddress, configForm->groupAddress->text());
setFieldData(kGroupMode, configForm->groupMode->currentIndex());
setFieldData(kGroupCount, configForm->groupCount->text());
setFieldData(kGroupPrefix, configForm->groupPrefix->text().remove('/'));
setFieldData(kSFlag, configForm->sFlag->isChecked());
setFieldData(kQrv, configForm->qrv->text());
setFieldData(kQqic, configForm->qqi->text());
QStringList list;
for (int i = 0; i < configForm->sourceList->count(); i++)
list.append(configForm->sourceList->item(i)->text());
setFieldData(kSources, list);
// sourceCount should be AFTER sources
setFieldData(kIsOverrideSourceCount,
configForm->overrideSourceCount->isChecked());
setFieldData(kSourceCount, configForm->sourceCount->text());
QVariantList grpList;
for (int i = 0; i < configForm->groupList->count(); i++)
{
QVariant grp = configForm->groupList->item(i)->data(Qt::UserRole);
grpList.append(grp.toMap());
}
setFieldData(kGroupRecords, grpList);
// groupRecordCount should be AFTER groupRecords
setFieldData(kIsOverrideGroupRecordCount,
configForm->overrideGroupRecordCount->isChecked());
setFieldData(kGroupRecordCount, configForm->groupRecordCount->text());
}

View File

@ -20,72 +20,18 @@ along with this program. If not, see <http://www.gnu.org/licenses/>
#ifndef _GMP_H
#define _GMP_H
#include "gmp.pb.h"
#include "ui_gmp.h"
#include "abstractprotocol.h"
#include "gmp.pb.h"
#include <QHash>
/*
Gmp Protocol Frame Format - TODO: for now see the respective RFCs
*/
class GmpProtocol;
class GmpConfigForm : public QWidget, public Ui::Gmp
{
Q_OBJECT
public:
GmpConfigForm(QWidget *parent = 0);
~GmpConfigForm();
void update();
protected:
QString _defaultGroupIp;
QString _defaultSourceIp;
enum {
kSsmQueryPage = 0,
kSsmReportPage = 1
};
private slots:
void on_groupMode_currentIndexChanged(int index);
void on_addSource_clicked();
void on_deleteSource_clicked();
void on_addGroupRecord_clicked();
void on_deleteGroupRecord_clicked();
void on_groupList_currentItemChanged(QListWidgetItem *current,
QListWidgetItem *previous);
void on_addGroupRecordSource_clicked();
void on_deleteGroupRecordSource_clicked();
void on_auxData_textChanged(const QString &text);
};
class GmpProtocol : public AbstractProtocol
{
public:
GmpProtocol(StreamBase *stream, AbstractProtocol *parent = 0);
virtual ~GmpProtocol();
virtual ProtocolIdType protocolIdType() const;
virtual int fieldCount() const;
virtual int frameFieldCount() const;
virtual AbstractProtocol::FieldFlags fieldFlags(int index) const;
virtual QVariant fieldData(int index, FieldAttrib attrib,
int streamIndex = 0) const;
virtual bool setFieldData(int index, const QVariant &value,
FieldAttrib attrib = FieldValue);
virtual int protocolFrameSize(int streamIndex = 0) const;
virtual bool isProtocolFrameValueVariable() const;
virtual int protocolFrameVariableCount() const;
virtual void loadConfigWidget();
virtual void storeConfigWidget();
protected:
enum GmpField
{
// ------------
@ -134,8 +80,27 @@ protected:
FIELD_COUNT
};
GmpProtocol(StreamBase *stream, AbstractProtocol *parent = 0);
virtual ~GmpProtocol();
virtual ProtocolIdType protocolIdType() const;
virtual int fieldCount() const;
virtual int frameFieldCount() const;
virtual AbstractProtocol::FieldFlags fieldFlags(int index) const;
virtual QVariant fieldData(int index, FieldAttrib attrib,
int streamIndex = 0) const;
virtual bool setFieldData(int index, const QVariant &value,
FieldAttrib attrib = FieldValue);
virtual int protocolFrameSize(int streamIndex = 0) const;
virtual bool isProtocolFrameValueVariable() const;
virtual int protocolFrameVariableCount() const;
protected:
OstProto::Gmp data;
GmpConfigForm *configForm;
int msgType() const;
@ -146,6 +111,7 @@ protected:
int qqic(int value) const;
virtual quint16 checksum(int streamIndex) const = 0;
private:
static QHash<int, int> frameFieldCountMap;
};

384
common/gmpconfig.cpp Normal file
View File

@ -0,0 +1,384 @@
/*
Copyright (C) 2010 Srivats P.
This file is part of "Ostinato"
This is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program. If not, see <http://www.gnu.org/licenses/>
*/
#include "gmpconfig.h"
#include "gmp.h"
GmpConfigForm::GmpConfigForm(QWidget *parent)
: AbstractProtocolConfigForm(parent)
{
setupUi(this);
auxData->setValidator(new QRegExpValidator(
QRegExp("[0-9A-Fa-f]*"), this));
}
GmpConfigForm::~GmpConfigForm()
{
}
void GmpConfigForm::loadWidget(AbstractProtocol *proto)
{
msgTypeCombo->setValue(
proto->fieldData(
GmpProtocol::kType,
AbstractProtocol::FieldValue
).toUInt());
// XXX: maxResponseTime set by subclass
overrideChecksum->setChecked(
proto->fieldData(
GmpProtocol::kIsOverrideChecksum,
AbstractProtocol::FieldValue
).toBool());
checksum->setText(uintToHexStr(
proto->fieldData(
GmpProtocol::kChecksum,
AbstractProtocol::FieldValue
).toUInt(), 2));
groupAddress->setText(
proto->fieldData(
GmpProtocol::kGroupAddress,
AbstractProtocol::FieldValue
).toString());
groupMode->setCurrentIndex(
proto->fieldData(
GmpProtocol::kGroupMode,
AbstractProtocol::FieldValue
).toUInt());
groupCount->setText(
proto->fieldData(
GmpProtocol::kGroupCount,
AbstractProtocol::FieldValue
).toString());
groupPrefix->setText(
proto->fieldData(
GmpProtocol::kGroupPrefix,
AbstractProtocol::FieldValue
).toString());
sFlag->setChecked(
proto->fieldData(
GmpProtocol::kSFlag,
AbstractProtocol::FieldValue
).toBool());
qrv->setText(
proto->fieldData(
GmpProtocol::kQrv,
AbstractProtocol::FieldValue
).toString());
qqi->setText(
proto->fieldData(
GmpProtocol::kQqic,
AbstractProtocol::FieldValue
).toString());
QStringList sl =
proto->fieldData(
GmpProtocol::kSources,
AbstractProtocol::FieldValue
).toStringList();
sourceList->clear();
foreach(QString src, sl)
{
QListWidgetItem *item = new QListWidgetItem(src);
item->setFlags(item->flags() | Qt::ItemIsEditable);
sourceList->addItem(item);
}
// NOTE: SourceCount should be loaded after sourceList
overrideSourceCount->setChecked(
proto->fieldData(
GmpProtocol::kIsOverrideSourceCount,
AbstractProtocol::FieldValue
).toBool());
sourceCount->setText(
proto->fieldData(
GmpProtocol::kSourceCount,
AbstractProtocol::FieldValue
).toString());
QVariantList list =
proto->fieldData(
GmpProtocol::kGroupRecords,
AbstractProtocol::FieldValue
).toList();
groupList->clear();
foreach (QVariant rec, list)
{
QVariantMap grpRec = rec.toMap();
QListWidgetItem *item = new QListWidgetItem;
item->setData(Qt::UserRole, grpRec);
item->setText(QString("%1: %2")
.arg(groupRecordType->itemText(
grpRec["groupRecordType"].toInt()))
.arg(grpRec["groupRecordAddress"].toString()));
groupList->addItem(item);
}
// NOTE: recordCount should be loaded after recordList
overrideGroupRecordCount->setChecked(
proto->fieldData(
GmpProtocol::kIsOverrideGroupRecordCount,
AbstractProtocol::FieldValue
).toBool());
groupRecordCount->setText(
proto->fieldData(
GmpProtocol::kGroupRecordCount,
AbstractProtocol::FieldValue
).toString());
}
void GmpConfigForm::storeWidget(AbstractProtocol *proto)
{
update();
proto->setFieldData(
GmpProtocol::kType,
msgTypeCombo->currentValue());
// XXX: maxResponseTime handled by subclass
proto->setFieldData(
GmpProtocol::kIsOverrideChecksum,
overrideChecksum->isChecked());
proto->setFieldData(
GmpProtocol::kChecksum,
hexStrToUInt(checksum->text()));
proto->setFieldData(
GmpProtocol::kGroupAddress,
groupAddress->text());
proto->setFieldData(
GmpProtocol::kGroupMode,
groupMode->currentIndex());
proto->setFieldData(
GmpProtocol::kGroupCount,
groupCount->text());
proto->setFieldData(
GmpProtocol::kGroupPrefix,
groupPrefix->text().remove('/'));
proto->setFieldData(
GmpProtocol::kSFlag,
sFlag->isChecked());
proto->setFieldData(
GmpProtocol::kQrv,
qrv->text());
proto->setFieldData(
GmpProtocol::kQqic,
qqi->text());
QStringList list;
for (int i = 0; i < sourceList->count(); i++)
list.append(sourceList->item(i)->text());
proto->setFieldData(
GmpProtocol::kSources,
list);
// sourceCount should be AFTER sources
proto->setFieldData(
GmpProtocol::kIsOverrideSourceCount,
overrideSourceCount->isChecked());
proto->setFieldData(
GmpProtocol::kSourceCount,
sourceCount->text());
QVariantList grpList;
for (int i = 0; i < groupList->count(); i++)
{
QVariant grp = groupList->item(i)->data(Qt::UserRole);
grpList.append(grp.toMap());
}
proto->setFieldData(GmpProtocol::kGroupRecords, grpList);
// groupRecordCount should be AFTER groupRecords
proto->setFieldData(
GmpProtocol::kIsOverrideGroupRecordCount,
overrideGroupRecordCount->isChecked());
proto->setFieldData(
GmpProtocol::kGroupRecordCount,
groupRecordCount->text());
}
void GmpConfigForm::update()
{
// save the current group Record by simulating a currentItemChanged()
on_groupList_currentItemChanged(groupList->currentItem(),
groupList->currentItem());
}
//
// -- private slots
//
void GmpConfigForm::on_groupMode_currentIndexChanged(int index)
{
bool disabled = (index == 0);
groupCount->setDisabled(disabled);
groupPrefix->setDisabled(disabled);
}
void GmpConfigForm::on_addSource_clicked()
{
QListWidgetItem *item=new QListWidgetItem(_defaultSourceIp);
item->setFlags(item->flags() | Qt::ItemIsEditable);
sourceList->insertItem(sourceList->currentRow(), item);
if (!overrideSourceCount->isChecked())
sourceCount->setText(QString().setNum(sourceList->count()));
}
void GmpConfigForm::on_deleteSource_clicked()
{
delete sourceList->takeItem(sourceList->currentRow());
if (!overrideSourceCount->isChecked())
sourceCount->setText(QString().setNum(sourceList->count()));
}
void GmpConfigForm::on_addGroupRecord_clicked()
{
OstProto::Gmp::GroupRecord defRec;
QVariantMap grpRec;
QListWidgetItem *item = new QListWidgetItem;
grpRec["groupRecordType"] = defRec.type();
grpRec["groupRecordAddress"] = _defaultGroupIp;
grpRec["overrideGroupRecordSourceCount"] =defRec.is_override_source_count();
grpRec["groupRecordSourceCount"] = defRec.source_count();
grpRec["groupRecordSourceList"] = QStringList();
grpRec["overrideAuxDataLength"] = defRec.is_override_aux_data_length();
grpRec["auxDataLength"] = defRec.aux_data_length();
grpRec["auxData"] = QByteArray().append(
QString().fromStdString(defRec.aux_data()));
item->setData(Qt::UserRole, grpRec);
item->setText(QString("%1: %2")
.arg(groupRecordType->itemText(grpRec["groupRecordType"].toInt()))
.arg(grpRec["groupRecordAddress"].toString()));
groupList->insertItem(groupList->currentRow(), item);
if (!overrideGroupRecordCount->isChecked())
groupRecordCount->setText(QString().setNum(groupList->count()));
}
void GmpConfigForm::on_deleteGroupRecord_clicked()
{
delete groupList->takeItem(groupList->currentRow());
if (!overrideGroupRecordCount->isChecked())
groupRecordCount->setText(QString().setNum(groupList->count()));
}
void GmpConfigForm::on_groupList_currentItemChanged(QListWidgetItem *current,
QListWidgetItem *previous)
{
QVariantMap rec;
QStringList strList;
qDebug("in %s", __FUNCTION__);
// save previous record ...
if (previous == NULL)
goto _load_current_record;
rec["groupRecordType"] = groupRecordType->currentIndex();
rec["groupRecordAddress"] = groupRecordAddress->text();
strList.clear();
while (groupRecordSourceList->count())
{
QListWidgetItem *item = groupRecordSourceList->takeItem(0);
strList.append(item->text());
delete item;
}
rec["groupRecordSourceList"] = strList;
rec["overrideGroupRecordSourceCount"] =
overrideGroupRecordSourceCount->isChecked();
rec["groupRecordSourceCount"] = groupRecordSourceCount->text().toUInt();
rec["overrideAuxDataLength"] = overrideAuxDataLength->isChecked();
rec["auxDataLength"] = auxDataLength->text().toUInt();
rec["auxData"] = QByteArray().fromHex(QByteArray().append(auxData->text()));
previous->setData(Qt::UserRole, rec);
previous->setText(QString("%1: %2")
.arg(groupRecordType->itemText(rec["groupRecordType"].toInt()))
.arg(rec["groupRecordAddress"].toString()));
_load_current_record:
// ... and load current record
if (current == NULL)
goto _exit;
rec = current->data(Qt::UserRole).toMap();
groupRecordType->setCurrentIndex(rec["groupRecordType"].toInt());
groupRecordAddress->setText(rec["groupRecordAddress"].toString());
strList = rec["groupRecordSourceList"].toStringList();
groupRecordSourceList->clear();
foreach (QString str, strList)
{
QListWidgetItem *item = new QListWidgetItem(str, groupRecordSourceList);
item->setFlags(item->flags() | Qt::ItemIsEditable);
}
overrideGroupRecordSourceCount->setChecked(
rec["overrideGroupRecordSourceCount"].toBool());
groupRecordSourceCount->setText(QString().setNum(
rec["groupRecordSourceCount"].toUInt()));
overrideAuxDataLength->setChecked(rec["overrideAuxDataLength"].toBool());
auxDataLength->setText(QString().setNum(rec["auxDataLength"].toUInt()));
auxData->setText(QString(rec["auxData"].toByteArray().toHex()));
_exit:
groupRecord->setEnabled(current != NULL);
return;
}
void GmpConfigForm::on_addGroupRecordSource_clicked()
{
QListWidgetItem *item=new QListWidgetItem(_defaultSourceIp);
item->setFlags(item->flags() | Qt::ItemIsEditable);
groupRecordSourceList->insertItem(groupRecordSourceList->currentRow(),item);
if (!overrideGroupRecordSourceCount->isChecked())
groupRecordSourceCount->setText(QString().setNum(
groupRecordSourceList->count()));
}
void GmpConfigForm::on_deleteGroupRecordSource_clicked()
{
delete groupRecordSourceList->takeItem(groupRecordSourceList->currentRow());
if (!overrideGroupRecordSourceCount->isChecked())
groupRecordSourceCount->setText(QString().setNum(
groupRecordSourceList->count()));
}
void GmpConfigForm::on_auxData_textChanged(const QString &text)
{
// auxDataLength is in units of words and each byte is 2 chars in text()
if (!overrideAuxDataLength->isChecked())
auxDataLength->setText(QString().setNum((text.size()+7)/8));
}

63
common/gmpconfig.h Normal file
View File

@ -0,0 +1,63 @@
/*
Copyright (C) 2010 Srivats P.
This file is part of "Ostinato"
This is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program. If not, see <http://www.gnu.org/licenses/>
*/
#ifndef _GMP_CONFIG_H
#define _GMP_CONFIG_H
#include "abstractprotocolconfig.h"
#include "ui_gmp.h"
class GmpConfigForm :
public AbstractProtocolConfigForm,
protected Ui::Gmp
{
Q_OBJECT
public:
GmpConfigForm(QWidget *parent = 0);
~GmpConfigForm();
virtual void loadWidget(AbstractProtocol *proto);
virtual void storeWidget(AbstractProtocol *proto);
protected:
QString _defaultGroupIp;
QString _defaultSourceIp;
enum {
kSsmQueryPage = 0,
kSsmReportPage = 1
};
private:
void update();
private slots:
void on_groupMode_currentIndexChanged(int index);
void on_addSource_clicked();
void on_deleteSource_clicked();
void on_addGroupRecord_clicked();
void on_deleteGroupRecord_clicked();
void on_groupList_currentItemChanged(QListWidgetItem *current,
QListWidgetItem *previous);
void on_addGroupRecordSource_clicked();
void on_deleteGroupRecordSource_clicked();
void on_auxData_textChanged(const QString &text);
};
#endif

View File

@ -18,68 +18,10 @@ along with this program. If not, see <http://www.gnu.org/licenses/>
*/
#include "igmp.h"
#include "ipv4addressdelegate.h"
#include "iputils.h"
#include <QHostAddress>
#include <qendian.h>
IgmpConfigForm::IgmpConfigForm(QWidget *parent)
: GmpConfigForm(parent)
{
connect(msgTypeCombo, SIGNAL(currentIndexChanged(int)),
SLOT(on_msgTypeCombo_currentIndexChanged(int)));
msgTypeCombo->setValueMask(0xFF);
msgTypeCombo->addItem(kIgmpV1Query, "IGMPv1 Query");
msgTypeCombo->addItem(kIgmpV1Report, "IGMPv1 Report");
msgTypeCombo->addItem(kIgmpV2Query, "IGMPv2 Query");
msgTypeCombo->addItem(kIgmpV2Report, "IGMPv2 Report");
msgTypeCombo->addItem(kIgmpV2Leave, "IGMPv2 Leave");
msgTypeCombo->addItem(kIgmpV3Query, "IGMPv3 Query");
msgTypeCombo->addItem(kIgmpV3Report, "IGMPv3 Report");
_defaultGroupIp = "0.0.0.0";
_defaultSourceIp = "0.0.0.0";
groupAddress->setInputMask("009.009.009.009;"); // FIXME: use validator
groupRecordAddress->setInputMask("009.009.009.009;"); // FIXME:use validator
sourceList->setItemDelegate(new IPv4AddressDelegate(this));
groupRecordSourceList->setItemDelegate(new IPv4AddressDelegate(this));
}
void IgmpConfigForm::on_msgTypeCombo_currentIndexChanged(int /*index*/)
{
switch(msgTypeCombo->currentValue())
{
case kIgmpV1Query:
case kIgmpV1Report:
case kIgmpV2Query:
case kIgmpV2Report:
case kIgmpV2Leave:
asmGroup->show();
ssmWidget->hide();
break;
case kIgmpV3Query:
asmGroup->hide();
ssmWidget->setCurrentIndex(kSsmQueryPage);
ssmWidget->show();
break;
case kIgmpV3Report:
asmGroup->hide();
ssmWidget->setCurrentIndex(kSsmReportPage);
ssmWidget->show();
break;
default:
asmGroup->hide();
ssmWidget->hide();
break;
}
}
#include <QStringList>
IgmpProtocol::IgmpProtocol(StreamBase *stream, AbstractProtocol *parent)
: GmpProtocol(stream, parent)
@ -403,33 +345,6 @@ _exit:
return isOk;
}
QWidget* IgmpProtocol::configWidget()
{
/* Lazy creation of the configWidget */
if (configForm == NULL)
{
configForm = new IgmpConfigForm;
loadConfigWidget();
}
return configForm;
}
void IgmpProtocol::loadConfigWidget()
{
GmpProtocol::loadConfigWidget();
configForm->maxResponseTime->setText(
fieldData(kRsvdMrtCode, FieldValue).toString());
}
void IgmpProtocol::storeConfigWidget()
{
GmpProtocol::storeConfigWidget();
setFieldData(kRsvdMrtCode, configForm->maxResponseTime->text());
}
quint16 IgmpProtocol::checksum(int streamIndex) const
{
quint16 cks;

View File

@ -19,8 +19,8 @@ along with this program. If not, see <http://www.gnu.org/licenses/>
#ifndef _IGMP_H
#define _IGMP_H
#include "igmp.pb.h"
#include "gmp.h"
#include "igmp.pb.h"
// IGMP uses the same msg type value for 'Query' messages across
// versions despite the fields being different. To distinguish
@ -39,15 +39,6 @@ enum IgmpMsgType
kIgmpV3Report = 0x22,
};
class IgmpConfigForm : public GmpConfigForm
{
Q_OBJECT
public:
IgmpConfigForm(QWidget *parent = 0);
private slots:
void on_msgTypeCombo_currentIndexChanged(int index);
};
class IgmpProtocol : public GmpProtocol
{
public:
@ -71,10 +62,6 @@ public:
virtual bool setFieldData(int index, const QVariant &value,
FieldAttrib attrib = FieldValue);
virtual QWidget* configWidget();
virtual void loadConfigWidget();
virtual void storeConfigWidget();
protected:
virtual bool isSsmReport() const;
virtual bool isQuery() const;

112
common/igmpconfig.cpp Normal file
View File

@ -0,0 +1,112 @@
/*
Copyright (C) 2010 Srivats P.
This file is part of "Ostinato"
This is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program. If not, see <http://www.gnu.org/licenses/>
*/
#include "igmpconfig.h"
#include "igmp.h"
#include "ipv4addressdelegate.h"
IgmpConfigForm::IgmpConfigForm(QWidget *parent)
: GmpConfigForm(parent)
{
connect(msgTypeCombo, SIGNAL(currentIndexChanged(int)),
SLOT(on_msgTypeCombo_currentIndexChanged(int)));
msgTypeCombo->setValueMask(0xFF);
msgTypeCombo->addItem(kIgmpV1Query, "IGMPv1 Query");
msgTypeCombo->addItem(kIgmpV1Report, "IGMPv1 Report");
msgTypeCombo->addItem(kIgmpV2Query, "IGMPv2 Query");
msgTypeCombo->addItem(kIgmpV2Report, "IGMPv2 Report");
msgTypeCombo->addItem(kIgmpV2Leave, "IGMPv2 Leave");
msgTypeCombo->addItem(kIgmpV3Query, "IGMPv3 Query");
msgTypeCombo->addItem(kIgmpV3Report, "IGMPv3 Report");
_defaultGroupIp = "0.0.0.0";
_defaultSourceIp = "0.0.0.0";
groupAddress->setInputMask("009.009.009.009;"); // FIXME: use validator
groupRecordAddress->setInputMask("009.009.009.009;"); // FIXME:use validator
sourceList->setItemDelegate(new IPv4AddressDelegate(this));
groupRecordSourceList->setItemDelegate(new IPv4AddressDelegate(this));
}
IgmpConfigForm::~IgmpConfigForm()
{
}
IgmpConfigForm* IgmpConfigForm::createInstance()
{
return new IgmpConfigForm;
}
void IgmpConfigForm::loadWidget(AbstractProtocol *proto)
{
GmpConfigForm::loadWidget(proto);
maxResponseTime->setText(
proto->fieldData(
IgmpProtocol::kRsvdMrtCode,
AbstractProtocol::FieldValue
).toString());
}
void IgmpConfigForm::storeWidget(AbstractProtocol *proto)
{
GmpConfigForm::storeWidget(proto);
proto->setFieldData(
IgmpProtocol::kRsvdMrtCode,
maxResponseTime->text());
}
//
// -- private slots
//
void IgmpConfigForm::on_msgTypeCombo_currentIndexChanged(int /*index*/)
{
switch(msgTypeCombo->currentValue())
{
case kIgmpV1Query:
case kIgmpV1Report:
case kIgmpV2Query:
case kIgmpV2Report:
case kIgmpV2Leave:
asmGroup->show();
ssmWidget->hide();
break;
case kIgmpV3Query:
asmGroup->hide();
ssmWidget->setCurrentIndex(kSsmQueryPage);
ssmWidget->show();
break;
case kIgmpV3Report:
asmGroup->hide();
ssmWidget->setCurrentIndex(kSsmReportPage);
ssmWidget->show();
break;
default:
asmGroup->hide();
ssmWidget->hide();
break;
}
}

40
common/igmpconfig.h Normal file
View File

@ -0,0 +1,40 @@
/*
Copyright (C) 2010 Srivats P.
This file is part of "Ostinato"
This is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program. If not, see <http://www.gnu.org/licenses/>
*/
#ifndef _IGMP_CONFIG_H
#define _IGMP_CONFIG_H
#include "gmpconfig.h"
class IgmpConfigForm : public GmpConfigForm
{
Q_OBJECT
public:
IgmpConfigForm(QWidget *parent = 0);
virtual ~IgmpConfigForm();
static IgmpConfigForm* createInstance();
virtual void loadWidget(AbstractProtocol *proto);
virtual void storeWidget(AbstractProtocol *proto);
private slots:
void on_msgTypeCombo_currentIndexChanged(int index);
};
#endif

View File

@ -19,64 +19,10 @@ along with this program. If not, see <http://www.gnu.org/licenses/>
#include "mld.h"
#include "ipv6addressdelegate.h"
#include "ipv6addressvalidator.h"
#include "iputils.h"
#include <QHostAddress>
#include <qendian.h>
MldConfigForm::MldConfigForm(QWidget *parent)
: GmpConfigForm(parent)
{
connect(msgTypeCombo, SIGNAL(currentIndexChanged(int)),
SLOT(on_msgTypeCombo_currentIndexChanged(int)));
msgTypeCombo->setValueMask(0xFF);
msgTypeCombo->addItem(kMldV1Query, "MLDv1 Query");
msgTypeCombo->addItem(kMldV1Report, "MLDv1 Report");
msgTypeCombo->addItem(kMldV1Done, "MLDv1 Done");
msgTypeCombo->addItem(kMldV2Query, "MLDv2 Query");
msgTypeCombo->addItem(kMldV2Report, "MLDv2 Report");
_defaultGroupIp = "::";
_defaultSourceIp = "::";
groupAddress->setValidator(new IPv6AddressValidator(this));
groupRecordAddress->setValidator(new IPv6AddressValidator(this));
sourceList->setItemDelegate(new IPv6AddressDelegate(this));
groupRecordSourceList->setItemDelegate(new IPv6AddressDelegate(this));
}
void MldConfigForm::on_msgTypeCombo_currentIndexChanged(int /*index*/)
{
switch(msgTypeCombo->currentValue())
{
case kMldV1Query:
case kMldV1Report:
case kMldV1Done:
asmGroup->show();
ssmWidget->hide();
break;
case kMldV2Query:
asmGroup->hide();
ssmWidget->setCurrentIndex(kSsmQueryPage);
ssmWidget->show();
break;
case kMldV2Report:
asmGroup->hide();
ssmWidget->setCurrentIndex(kSsmReportPage);
ssmWidget->show();
break;
default:
asmGroup->hide();
ssmWidget->hide();
break;
}
}
#include <QStringList>
MldProtocol::MldProtocol(StreamBase *stream, AbstractProtocol *parent)
: GmpProtocol(stream, parent)
@ -591,33 +537,6 @@ _exit:
return isOk;
}
QWidget* MldProtocol::configWidget()
{
/* Lazy creation of the configWidget */
if (configForm == NULL)
{
configForm = new MldConfigForm;
loadConfigWidget();
}
return configForm;
}
void MldProtocol::loadConfigWidget()
{
GmpProtocol::loadConfigWidget();
configForm->maxResponseTime->setText(
fieldData(kMldMrt, FieldValue).toString());
}
void MldProtocol::storeConfigWidget()
{
GmpProtocol::storeConfigWidget();
setFieldData(kMldMrt, configForm->maxResponseTime->text());
}
quint16 MldProtocol::checksum(int streamIndex) const
{
return AbstractProtocol::protocolFrameCksum(streamIndex, CksumTcpUdp);

View File

@ -19,8 +19,8 @@ along with this program. If not, see <http://www.gnu.org/licenses/>
#ifndef _MLD_H
#define _MLD_H
#include "mld.pb.h"
#include "gmp.h"
#include "mld.pb.h"
// MLD uses the same msg type value for 'Query' messages across
// versions despite the fields being different. To distinguish
@ -36,15 +36,6 @@ enum MldMsgType
kMldV2Report = 0x8F
};
class MldConfigForm : public GmpConfigForm
{
Q_OBJECT
public:
MldConfigForm(QWidget *parent = 0);
private slots:
void on_msgTypeCombo_currentIndexChanged(int index);
};
class MldProtocol : public GmpProtocol
{
public:
@ -69,10 +60,6 @@ public:
virtual bool setFieldData(int index, const QVariant &value,
FieldAttrib attrib = FieldValue);
virtual QWidget* configWidget();
virtual void loadConfigWidget();
virtual void storeConfigWidget();
protected:
virtual bool isSsmReport() const;
virtual bool isQuery() const;

109
common/mldconfig.cpp Normal file
View File

@ -0,0 +1,109 @@
/*
Copyright (C) 2010 Srivats P.
This file is part of "Ostinato"
This is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program. If not, see <http://www.gnu.org/licenses/>
*/
#include "mldconfig.h"
#include "mld.h"
#include "ipv6addressdelegate.h"
#include "ipv6addressvalidator.h"
MldConfigForm::MldConfigForm(QWidget *parent)
: GmpConfigForm(parent)
{
connect(msgTypeCombo, SIGNAL(currentIndexChanged(int)),
SLOT(on_msgTypeCombo_currentIndexChanged(int)));
msgTypeCombo->setValueMask(0xFF);
msgTypeCombo->addItem(kMldV1Query, "MLDv1 Query");
msgTypeCombo->addItem(kMldV1Report, "MLDv1 Report");
msgTypeCombo->addItem(kMldV1Done, "MLDv1 Done");
msgTypeCombo->addItem(kMldV2Query, "MLDv2 Query");
msgTypeCombo->addItem(kMldV2Report, "MLDv2 Report");
_defaultGroupIp = "::";
_defaultSourceIp = "::";
groupAddress->setValidator(new IPv6AddressValidator(this));
groupRecordAddress->setValidator(new IPv6AddressValidator(this));
sourceList->setItemDelegate(new IPv6AddressDelegate(this));
groupRecordSourceList->setItemDelegate(new IPv6AddressDelegate(this));
}
MldConfigForm::~MldConfigForm()
{
}
MldConfigForm* MldConfigForm::createInstance()
{
return new MldConfigForm;
}
void MldConfigForm::loadWidget(AbstractProtocol *proto)
{
GmpConfigForm::loadWidget(proto);
maxResponseTime->setText(
proto->fieldData(
MldProtocol::kMldMrt,
AbstractProtocol::FieldValue
).toString());
}
void MldConfigForm::storeWidget(AbstractProtocol *proto)
{
GmpConfigForm::storeWidget(proto);
proto->setFieldData(
MldProtocol::kMldMrt,
maxResponseTime->text());
}
//
// -- private slots
//
void MldConfigForm::on_msgTypeCombo_currentIndexChanged(int /*index*/)
{
switch(msgTypeCombo->currentValue())
{
case kMldV1Query:
case kMldV1Report:
case kMldV1Done:
asmGroup->show();
ssmWidget->hide();
break;
case kMldV2Query:
asmGroup->hide();
ssmWidget->setCurrentIndex(kSsmQueryPage);
ssmWidget->show();
break;
case kMldV2Report:
asmGroup->hide();
ssmWidget->setCurrentIndex(kSsmReportPage);
ssmWidget->show();
break;
default:
asmGroup->hide();
ssmWidget->hide();
break;
}
}

41
common/mldconfig.h Normal file
View File

@ -0,0 +1,41 @@
/*
Copyright (C) 2010 Srivats P.
This file is part of "Ostinato"
This is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program. If not, see <http://www.gnu.org/licenses/>
*/
#ifndef _MLD_CONFIG_H
#define _MLD_CONFIG_H
#include "gmpconfig.h"
class MldConfigForm : public GmpConfigForm
{
Q_OBJECT
public:
MldConfigForm(QWidget *parent = 0);
virtual ~MldConfigForm();
static MldConfigForm* createInstance();
virtual void loadWidget(AbstractProtocol *proto);
virtual void storeWidget(AbstractProtocol *proto);
private slots:
void on_msgTypeCombo_currentIndexChanged(int index);
};
#endif

View File

@ -63,15 +63,13 @@ HEADERS += \
ip4over6.h \
ip6over4.h \
ip6over6.h \
tcp.h
HEADERS1 += \
ipv4addressdelegate.h \
ipv6addressdelegate.h \
icmp.h \
gmp.h \
igmp.h \
mld.h \
tcp.h
HEADERS1 += \
icmp.h \
udp.h \
textproto.h \
userscript.h \
@ -98,13 +96,13 @@ SOURCES += \
arp.cpp \
ip4.cpp \
ip6.cpp \
gmp.cpp \
igmp.cpp \
mld.cpp \
tcp.cpp
SOURCES1 += \
icmp.cpp \
gmp.cpp \
igmp.cpp \
mld.cpp \
udp.cpp \
textproto.cpp \
userscript.cpp \

View File

@ -18,11 +18,11 @@ FORMS += \
arp.ui \
ip4.ui \
ip6.ui \
gmp.ui \
tcp.ui
FORMS1 += \
icmp.ui \
gmp.ui \
udp.ui \
textproto.ui \
userscript.ui \
@ -37,6 +37,8 @@ HEADERS = \
ostprotolib.h \
abstractfileformat.h \
fileformat.h \
ipv4addressdelegate.h \
ipv6addressdelegate.h \
pcapfileformat.h \
pdmlfileformat.h \
pdmlprotocol.h \
@ -62,6 +64,9 @@ HEADERS += \
ip4config.h \
ip6config.h \
ip4over4config.h \
gmpconfig.h \
igmpconfig.h \
mldconfig.h \
tcpconfig.h
SOURCES += \
@ -86,6 +91,9 @@ SOURCES += \
arpconfig.cpp \
ip4config.cpp \
ip6config.cpp \
gmpconfig.cpp \
igmpconfig.cpp \
mldconfig.cpp \
tcpconfig.cpp
QMAKE_DISTCLEAN += object_script.*

View File

@ -23,8 +23,6 @@ along with this program. If not, see <http://www.gnu.org/licenses/>
#include "protocol.pb.h"
#if 0
#include "icmp.h"
#include "igmp.h"
#include "mld.h"
#include "udp.h"
#include "textproto.h"
#include "userscript.h"
@ -51,6 +49,8 @@ along with this program. If not, see <http://www.gnu.org/licenses/>
#include "ip6over4.h"
#include "ip6over6.h"
// L4 Protos
#include "igmp.h"
#include "mld.h"
#include "tcp.h"
#endif
@ -64,10 +64,6 @@ ProtocolManager::ProtocolManager()
#if 0
registerProtocol(OstProto::Protocol::kIcmpFieldNumber,
(void*) IcmpProtocol::createInstance);
registerProtocol(OstProto::Protocol::kIgmpFieldNumber,
(void*) IgmpProtocol::createInstance);
registerProtocol(OstProto::Protocol::kMldFieldNumber,
(void*) MldProtocol::createInstance);
registerProtocol(OstProto::Protocol::kUdpFieldNumber,
(void*) UdpProtocol::createInstance);
registerProtocol(OstProto::Protocol::kTextProtocolFieldNumber,
@ -124,6 +120,10 @@ ProtocolManager::ProtocolManager()
(void*) Ip6over6Protocol::createInstance);
// Layer 4 Protocols
registerProtocol(OstProto::Protocol::kIgmpFieldNumber,
(void*) IgmpProtocol::createInstance);
registerProtocol(OstProto::Protocol::kMldFieldNumber,
(void*) MldProtocol::createInstance);
registerProtocol(OstProto::Protocol::kTcpFieldNumber,
(void*) TcpProtocol::createInstance);
#endif

View File

@ -30,6 +30,7 @@ along with this program. If not, see <http://www.gnu.org/licenses/>
#include "dot2llcconfig.h"
#include "snapconfig.h"
#include "dot2snapconfig.h"
// L3 Protocol Widgets
#include "arpconfig.h"
#include "ip4config.h"
#include "ip6config.h"
@ -37,6 +38,9 @@ along with this program. If not, see <http://www.gnu.org/licenses/>
#include "ip4over6config.h"
#include "ip6over4config.h"
#include "ip6over6config.h"
// L4 Protocol Widgets
#include "igmpconfig.h"
#include "mldconfig.h"
#include "tcpconfig.h"
ProtocolWidgetFactory *OstProtocolWidgetFactory;
@ -109,6 +113,12 @@ ProtocolWidgetFactory::ProtocolWidgetFactory()
(void*) Ip6over6ConfigForm::createInstance);
// Layer 4 Protocols
OstProtocolWidgetFactory->registerProtocolConfigWidget(
OstProto::Protocol::kIgmpFieldNumber,
(void*) IgmpConfigForm::createInstance);
OstProtocolWidgetFactory->registerProtocolConfigWidget(
OstProto::Protocol::kMldFieldNumber,
(void*) MldConfigForm::createInstance);
OstProtocolWidgetFactory->registerProtocolConfigWidget(
OstProto::Protocol::kTcpFieldNumber,
(void*) TcpConfigForm::createInstance);