diff --git a/common/gmp.cpp b/common/gmp.cpp index 63f1288..51ae7fa 100755 --- a/common/gmp.cpp +++ b/common/gmp.cpp @@ -19,6 +19,7 @@ along with this program. If not, see #include "gmp.h" +#include #include GmpConfigForm::GmpConfigForm(QWidget *parent) @@ -34,24 +35,26 @@ GmpConfigForm::GmpConfigForm(QWidget *parent) msgTypeCombo->addItem(kIgmpV2Leave, "IGMPv2 Leave"); msgTypeCombo->addItem(kIgmpV3Query, "IGMPv3 Query"); msgTypeCombo->addItem(kIgmpV3Report, "IGMPv3 Report"); + + auxData->setValidator(new QRegExpValidator( + QRegExp("[0-9A-Fa-f]*"), this)); } -void GmpConfigForm::on_addSource_clicked() +GmpConfigForm::~GmpConfigForm() { - QListWidgetItem *item=new QListWidgetItem("0.0.0.0"); - item->setFlags(item->flags() | Qt::ItemIsEditable); - sourceList->insertItem(sourceList->currentRow(), item); + // delete UserRole itemdata for grpRecords + for (int i = 0; i < groupList->count(); i++) + { + QListWidgetItem *item = groupList->item(i); - 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())); + if (item) + { + OstProto::Gmp::GroupRecord *rec = (OstProto::Gmp::GroupRecord*) + item->data(Qt::UserRole).value(); + item->setData(Qt::UserRole, QVariant()); + delete rec; + } + } } void GmpConfigForm::on_msgTypeCombo_currentIndexChanged(int /*index*/) @@ -91,6 +94,135 @@ void GmpConfigForm::on_msgTypeCombo_currentIndexChanged(int /*index*/) } } +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 *record = new OstProto::Gmp::GroupRecord; + QListWidgetItem *item = new QListWidgetItem; + + item->setData(Qt::UserRole, QVariant::fromValue((void*)record)); + item->setText("xxx"); // FIXME + + groupList->insertItem(groupList->currentRow(), item); + + if (!overrideGroupRecordCount->isChecked()) + groupRecordCount->setText(QString().setNum(groupList->count())); +} + +void GmpConfigForm::on_deleteGroupRecord_clicked() +{ + QListWidgetItem *item = groupList->takeItem(groupList->currentRow()); + if (item) + { + delete (OstProto::Gmp::GroupRecord*)item->data(Qt::UserRole) + .value(); + delete item; + } + + if (!overrideGroupRecordCount->isChecked()) + groupRecordCount->setText(QString().setNum(groupList->count())); +} + +void GmpConfigForm::on_groupList_currentItemChanged(QListWidgetItem *current, + QListWidgetItem *previous) +{ + OstProto::Gmp::GroupRecord *prevRec; + OstProto::Gmp::GroupRecord *currRec; + + qDebug("in %s", __FUNCTION__); + + // save previous record ... + if (previous == NULL) + goto _load_current_record; + + prevRec = (OstProto::Gmp::GroupRecord*)previous->data(Qt::UserRole) + .value(); + + prevRec->set_type(OstProto::Gmp::GroupRecord::RecordType( + groupRecordType->currentIndex()+1)); + // FIXME: groupRecordAddress, sources + + prevRec->set_is_override_source_count( + overrideGroupRecordSourceCount->isChecked()); + prevRec->set_source_count(groupRecordSourceCount->text().toUInt()); + + prevRec->set_is_override_aux_data_length( + overrideAuxDataLength->isChecked()); + prevRec->set_aux_data(QString(QByteArray::fromHex( + QByteArray().append(auxData->text()))).toStdString()); + +_load_current_record: + // ... and load current record + if (current == NULL) + goto _exit; + + currRec = (OstProto::Gmp::GroupRecord*)current->data(Qt::UserRole) + .value(); + + groupRecordType->setCurrentIndex(int(currRec->type()) - 1); + // FIXME: groupRecordAddress, sources + + overrideGroupRecordSourceCount->setChecked( + currRec->is_override_source_count()); + if (overrideGroupRecordSourceCount->isChecked()) + { + groupRecordSourceCount->setText( + QString().setNum(currRec->source_count())); + } + + overrideAuxDataLength->setChecked(currRec->is_override_aux_data_length()); + if (overrideAuxDataLength->isChecked()) + auxDataLength->setText(QString().setNum(currRec->aux_data_length())); + auxData->setText(QString(QByteArray().append( + QString().fromStdString(currRec->aux_data())).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) +{ + if (!overrideAuxDataLength->isChecked()) + auxDataLength->setText(QString().setNum(auxData->text().length()/2)); +} + GmpProtocol::GmpProtocol(StreamBase *stream, AbstractProtocol *parent) : AbstractProtocol(stream, parent) { @@ -115,6 +247,16 @@ int GmpProtocol::fieldCount() const int GmpProtocol::frameFieldCount() const { + int count = 0; + + // TODO: optimize!!!!! + for (int i = 0; i < FIELD_COUNT; i++) + { + if (fieldFlags(i).testFlag(AbstractProtocol::FrameField)) + count++; + } + return count; +#if 0 switch(msgType()) { // IGMP @@ -144,6 +286,7 @@ int GmpProtocol::frameFieldCount() const default: return FIELD_COUNT_ASM_ALL; } +#endif } AbstractProtocol::FieldFlags GmpProtocol::fieldFlags(int index) const @@ -225,7 +368,7 @@ QVariant GmpProtocol::fieldData(int index, FieldAttrib attrib, case FieldValue: return type; case FieldTextValue: - return QString("%1").arg(type); + return QString("%1").arg(quint8(type)); case FieldFrameValue: return QByteArray(1, quint8(type)); default: @@ -335,7 +478,7 @@ QVariant GmpProtocol::fieldData(int index, FieldAttrib attrib, switch(attrib) { case FieldName: - return QString("Querier's Robustness Variable (QRV)"); + return QString("QRV"); case FieldValue: return qrv; case FieldTextValue: @@ -356,7 +499,7 @@ QVariant GmpProtocol::fieldData(int index, FieldAttrib attrib, switch(attrib) { case FieldName: - return QString("Querier's Robustness Variable (QRV)"); + return QString("QQIC"); case FieldValue: return qqi; case FieldTextValue: @@ -690,18 +833,6 @@ bool GmpProtocol::isProtocolFrameValueVariable() const return true; } -QWidget* GmpProtocol::configWidget() -{ - /* Lazy creation of the configWidget */ - if (configForm == NULL) - { - configForm = new GmpConfigForm; - loadConfigWidget(); - } - - return configForm; -} - void GmpProtocol::loadConfigWidget() { configWidget(); @@ -727,11 +858,14 @@ void GmpProtocol::loadConfigWidget() configForm->qrv->setText(fieldData(kQrv, FieldValue).toString()); configForm->qqi->setText(fieldData(kQqic, FieldValue).toString()); + configForm->sourceList->clear(); + configForm->sourceList->addItems( + fieldData(kSources, FieldValue).toStringList()); + configForm->overrideSourceCount->setChecked( fieldData(kIsOverrideSourceCount, FieldValue).toBool()); configForm->sourceCount->setText( fieldData(kSourceCount, FieldValue).toString()); - // TODO: sources configForm->overrideGroupRecordCount->setChecked( fieldData(kIsOverrideGroupRecordCount, FieldValue).toBool()); @@ -756,21 +890,28 @@ void GmpProtocol::storeConfigWidget() setFieldData(kGroupAddress, configForm->groupAddress->text()); setFieldData(kGroupMode, configForm->groupMode->currentIndex()); setFieldData(kGroupCount, configForm->groupCount->text()); - setFieldData(kGroupPrefix, configForm->groupPrefix->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); + + // XXX: sourceCount should be AFTER sources setFieldData(kIsOverrideSourceCount, configForm->overrideSourceCount->isChecked()); setFieldData(kSourceCount, configForm->sourceCount->text()); - // TODO: Sources + // TODO: Group Records + + // XXX: groupRecordCount should be AFTER groupRecords setFieldData(kIsOverrideGroupRecordCount, configForm->overrideGroupRecordCount->isChecked()); setFieldData(kGroupRecordCount, configForm->groupRecordCount->text()); - // TODO: Group Records #if 0 setFieldData(kA, configForm->gmpA->text()); setFieldData(kB, configForm->gmpB->text()); diff --git a/common/gmp.h b/common/gmp.h index 2cbbd67..c382005 100755 --- a/common/gmp.h +++ b/common/gmp.h @@ -60,10 +60,21 @@ class GmpConfigForm : public QWidget, public Ui::Gmp Q_OBJECT public: GmpConfigForm(QWidget *parent = 0); + ~GmpConfigForm(); +protected: + QString _defaultSourceIp; private slots: void on_msgTypeCombo_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 @@ -87,7 +98,6 @@ public: virtual bool isProtocolFrameValueVariable() const; - virtual QWidget* configWidget(); virtual void loadConfigWidget(); virtual void storeConfigWidget(); diff --git a/common/gmp.ui b/common/gmp.ui index 73b4300..6e1f0d8 100755 --- a/common/gmp.ui +++ b/common/gmp.ui @@ -5,8 +5,8 @@ 0 0 - 586 - 281 + 497 + 355 @@ -182,7 +182,7 @@ - 0 + 1 @@ -297,14 +297,14 @@ - A + + - D + -- @@ -351,6 +351,19 @@ + + + + Qt::Vertical + + + + 20 + 40 + + + + @@ -359,7 +372,7 @@ - + 0 @@ -381,18 +394,48 @@ - - - - Type - - - - - Group Address - - - + + + + + Group Records + + + groupRecordAddress + + + + + + + Qt::Horizontal + + + + 16 + 20 + + + + + + + + + + + + + + + + -- + + + + + + + @@ -415,162 +458,218 @@ - - - - - Record Type - - - recordType - - - - - - - - Is Include - - - - - Is Exclude - - - - - To Include - - - - - To Exclude - - - - - Allow New - - - - - Block Old - - - - - - - - Group Address - - - groupRecordAddress - - - - - - - - - - - - Source List - - - groupRecordAddress - - - - - - - Qt::Horizontal - - - - 40 - 20 - - - - - - - - Count - - - - - - - false - - - - 0 - 0 - - - - - - - - - - - - - - - Aux Data - - - - - - - Qt::Horizontal - - - - 40 - 20 - - - - - - - - Length - - - - - - - false - - - - 0 - 0 - - - - - - - - - - + + + false + + + + 0 + + + 0 + + + 0 + + + 0 + + + + + + + Record Type + + + groupRecordType + + + + + + + + Is Include + + + + + Is Exclude + + + + + To Include + + + + + To Exclude + + + + + Allow New + + + + + Block Old + + + + + + + + Group Address + + + groupRecordAddress + + + + + + + + + + + + + + + + Source List + + + groupRecordAddress + + + + + + + Qt::Horizontal + + + + 191 + 20 + + + + + + + + + + + + + + + + -- + + + + + + + + + + + + + + Number of Sources + + + + + + + false + + + + 0 + 0 + + + + + + + + Qt::Horizontal + + + + 81 + 20 + + + + + + + + + + + + + + Aux Data + + + + + + + Qt::Horizontal + + + + 40 + 20 + + + + + + + + Length + + + + + + + false + + + + 0 + 0 + + + + + + + + + + + @@ -586,8 +685,8 @@ - 20 - 40 + 101 + 21 @@ -610,14 +709,12 @@ groupMode groupCount groupPrefix - groupList overrideGroupRecordCount groupRecordCount - recordType + groupRecordType groupRecordAddress overrideGroupRecordSourceCount groupRecordSourceCount - groupRecordSourceList overrideAuxDataLength auxDataLength auxData diff --git a/common/igmp.cpp b/common/igmp.cpp index ce7dd3e..f7c0329 100644 --- a/common/igmp.cpp +++ b/common/igmp.cpp @@ -20,12 +20,36 @@ along with this program. If not, see #include "igmp.h" #include +#include #include +class IpAddressDelegate : public QItemDelegate +{ +public: + IpAddressDelegate(QObject *parent = 0) + : QItemDelegate(parent) { } + ~IpAddressDelegate() {} + QWidget* createEditor(QWidget *parent, + const QStyleOptionViewItem &option, const QModelIndex &index) const + { + QLineEdit *ipEdit; + + ipEdit = static_cast(QItemDelegate::createEditor( + parent, option, index)); + + ipEdit->setInputMask("009.009.009.009;"); // FIXME: use validator + + return ipEdit; + } +}; IgmpConfigForm::IgmpConfigForm(QWidget *parent) : GmpConfigForm(parent) { + _defaultSourceIp = "0.0.0.0"; + + sourceList->setItemDelegate(new IpAddressDelegate(this)); + groupRecordSourceList->setItemDelegate(new IpAddressDelegate(this)); } IgmpProtocol::IgmpProtocol(StreamBase *stream, AbstractProtocol *parent) @@ -90,7 +114,7 @@ QVariant IgmpProtocol::fieldData(int index, FieldAttrib attrib, { case kRsvdMrtCode: { - quint8 mrt = 0, mrc; + quint8 mrt = 0, mrc = 0; if (msgType() == kIgmpV3Query) { @@ -111,7 +135,7 @@ QVariant IgmpProtocol::fieldData(int index, FieldAttrib attrib, case FieldValue: return mrt; case FieldTextValue: - return QString("%1 ms").arg(mrt); + return QString("%1").arg(mrt); case FieldFrameValue: return QByteArray(1, mrc); default: @@ -156,13 +180,19 @@ QVariant IgmpProtocol::fieldData(int index, FieldAttrib attrib, case FieldName: return QString("Source List"); case FieldValue: - return QVariant(); // FIXME + { + QStringList list; + + for (int i = 0; i < data.sources_size(); i++) + list.append(QHostAddress(data.sources(i).v4()).toString()); + return list; + } case FieldFrameValue: { QByteArray fv; fv.resize(4 * data.sources_size()); for (int i = 0; i < data.sources_size(); i++) - qToBigEndian(data.sources(i), (uchar*) (fv.data()+4*i)); + qToBigEndian(data.sources(i).v4(), (uchar*)(fv.data()+4*i)); return fv; } case FieldTextValue: @@ -292,8 +322,17 @@ bool IgmpProtocol::setFieldData(int index, const QVariant &value, break; } case kSources: - //TODO + { + QStringList list = value.toStringList(); + + data.clear_sources(); + foreach(QString str, list) + { + quint32 ip = QHostAddress(str).toIPv4Address(); + data.add_sources()->set_v4(ip); + } break; + } case kGroupRecords: //TODO @@ -308,6 +347,18 @@ _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(); diff --git a/common/igmp.h b/common/igmp.h index 0905ac3..c528fc8 100644 --- a/common/igmp.h +++ b/common/igmp.h @@ -52,6 +52,7 @@ public: virtual bool setFieldData(int index, const QVariant &value, FieldAttrib attrib = FieldValue); + virtual QWidget* configWidget(); virtual void loadConfigWidget(); virtual void storeConfigWidget(); diff --git a/common/mld.cpp b/common/mld.cpp index 5d9151c..2f50535 100644 --- a/common/mld.cpp +++ b/common/mld.cpp @@ -19,12 +19,39 @@ along with this program. If not, see #include "mld.h" +#include "ipv6addressvalidator.h" + #include +#include #include +class IpAddressDelegate : public QItemDelegate +{ +public: + IpAddressDelegate(QObject *parent = 0) + : QItemDelegate(parent) { } + ~IpAddressDelegate() {} + QWidget* createEditor(QWidget *parent, + const QStyleOptionViewItem &option, const QModelIndex &index) const + { + QLineEdit *ipEdit; + + ipEdit = static_cast(QItemDelegate::createEditor( + parent, option, index)); + + // FIXME: const problem!!! + //ipEdit->setValidator(new IPv6AddressValidator(this)); + + return ipEdit; + } +}; + MldConfigForm::MldConfigForm(QWidget *parent) : GmpConfigForm(parent) { + _defaultSourceIp = "::"; + sourceList->setItemDelegate(new IpAddressDelegate(this)); + groupRecordSourceList->setItemDelegate(new IpAddressDelegate(this)); } MldProtocol::MldProtocol(StreamBase *stream, AbstractProtocol *parent) @@ -292,6 +319,18 @@ _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(); diff --git a/common/mld.h b/common/mld.h index 77927fc..0d087c9 100644 --- a/common/mld.h +++ b/common/mld.h @@ -56,6 +56,7 @@ public: virtual bool setFieldData(int index, const QVariant &value, FieldAttrib attrib = FieldValue); + virtual QWidget* configWidget(); virtual void loadConfigWidget(); virtual void storeConfigWidget(); protected: