Added streams save/restore; Ostinato file format specified; Protocol Field Numbering scheme changed - existing protocol field numbers changed accordingly
This commit is contained in:
parent
2e6503faad
commit
c2fac2db70
@ -24,6 +24,8 @@ along with this program. If not, see <http://www.gnu.org/licenses/>
|
|||||||
#include <QFile>
|
#include <QFile>
|
||||||
#include <QSettings>
|
#include <QSettings>
|
||||||
|
|
||||||
|
extern const char* version;
|
||||||
|
extern const char* revision;
|
||||||
extern ProtocolManager *OstProtocolManager;
|
extern ProtocolManager *OstProtocolManager;
|
||||||
|
|
||||||
QSettings *appSettings;
|
QSettings *appSettings;
|
||||||
@ -34,6 +36,11 @@ int main(int argc, char* argv[])
|
|||||||
QApplication app(argc, argv);
|
QApplication app(argc, argv);
|
||||||
int exitCode;
|
int exitCode;
|
||||||
|
|
||||||
|
app.setApplicationName("Ostinato");
|
||||||
|
app.setOrganizationName("Ostinato");
|
||||||
|
app.setProperty("version", version);
|
||||||
|
app.setProperty("revision", revision);
|
||||||
|
|
||||||
OstProtocolManager = new ProtocolManager();
|
OstProtocolManager = new ProtocolManager();
|
||||||
|
|
||||||
/* (Portable Mode) If we have a .ini file in the same directory as the
|
/* (Portable Mode) If we have a .ini file in the same directory as the
|
||||||
@ -44,7 +51,7 @@ int main(int argc, char* argv[])
|
|||||||
if (QFile::exists(portableIni))
|
if (QFile::exists(portableIni))
|
||||||
appSettings = new QSettings(portableIni, QSettings::IniFormat);
|
appSettings = new QSettings(portableIni, QSettings::IniFormat);
|
||||||
else
|
else
|
||||||
appSettings = new QSettings("Ostinato", "Ostinato");
|
appSettings = new QSettings();
|
||||||
|
|
||||||
mainWindow = new MainWindow;
|
mainWindow = new MainWindow;
|
||||||
mainWindow->show();
|
mainWindow->show();
|
||||||
|
@ -17,12 +17,14 @@ You should have received a copy of the GNU General Public License
|
|||||||
along with this program. If not, see <http://www.gnu.org/licenses/>
|
along with this program. If not, see <http://www.gnu.org/licenses/>
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#include <vector>
|
|
||||||
|
|
||||||
#include <google/protobuf/descriptor.h>
|
|
||||||
|
|
||||||
#include "port.h"
|
#include "port.h"
|
||||||
#include "pbhelper.h"
|
|
||||||
|
#include "fileformat.h"
|
||||||
|
|
||||||
|
#include <QApplication>
|
||||||
|
#include <QVariant>
|
||||||
|
#include <google/protobuf/descriptor.h>
|
||||||
|
#include <vector>
|
||||||
|
|
||||||
uint Port::mAllocStreamId = 0;
|
uint Port::mAllocStreamId = 0;
|
||||||
|
|
||||||
@ -218,3 +220,43 @@ void Port::updateStats(OstProto::PortStats *portStats)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
bool Port::openStreams(QString fileName, bool append, QString &error)
|
||||||
|
{
|
||||||
|
OstProto::StreamConfigList streams;
|
||||||
|
|
||||||
|
if (!fileFormat.openStreams(fileName, streams, error))
|
||||||
|
goto _fail;
|
||||||
|
|
||||||
|
if (!append)
|
||||||
|
{
|
||||||
|
while (numStreams())
|
||||||
|
deleteStreamAt(0);
|
||||||
|
}
|
||||||
|
|
||||||
|
for (int i = 0; i < streams.stream_size(); i++)
|
||||||
|
{
|
||||||
|
newStreamAt(mStreams.size());
|
||||||
|
streamByIndex(mStreams.size()-1)->protoDataCopyFrom(streams.stream(i));
|
||||||
|
}
|
||||||
|
|
||||||
|
emit streamListChanged(mPortGroupId, mPortId);
|
||||||
|
|
||||||
|
return true;
|
||||||
|
|
||||||
|
_fail:
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool Port::saveStreams(QString fileName, QString &error)
|
||||||
|
{
|
||||||
|
OstProto::StreamConfigList streams;
|
||||||
|
|
||||||
|
streams.mutable_port_id()->set_id(0);
|
||||||
|
for (int i = 0; i < mStreams.size(); i++)
|
||||||
|
{
|
||||||
|
OstProto::Stream *s = streams.add_stream();
|
||||||
|
mStreams[i]->protoDataCopyInto(*s);
|
||||||
|
}
|
||||||
|
|
||||||
|
return fileFormat.saveStreams(streams, fileName, error);
|
||||||
|
}
|
||||||
|
@ -114,13 +114,16 @@ public:
|
|||||||
void getModifiedStreamsSinceLastSync(
|
void getModifiedStreamsSinceLastSync(
|
||||||
OstProto::StreamConfigList &streamConfigList);
|
OstProto::StreamConfigList &streamConfigList);
|
||||||
|
|
||||||
|
|
||||||
void when_syncComplete();
|
void when_syncComplete();
|
||||||
|
|
||||||
void updateStats(OstProto::PortStats *portStats);
|
void updateStats(OstProto::PortStats *portStats);
|
||||||
|
|
||||||
|
bool openStreams(QString fileName, bool append, QString &error);
|
||||||
|
bool saveStreams(QString fileName, QString &error);
|
||||||
|
|
||||||
signals:
|
signals:
|
||||||
void portDataChanged(int portGroupId, int portId);
|
void portDataChanged(int portGroupId, int portId);
|
||||||
|
void streamListChanged(int portGroupId, int portId);
|
||||||
|
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -29,6 +29,8 @@ along with this program. If not, see <http://www.gnu.org/licenses/>
|
|||||||
PortsWindow::PortsWindow(PortGroupList *pgl, QWidget *parent)
|
PortsWindow::PortsWindow(PortGroupList *pgl, QWidget *parent)
|
||||||
: QWidget(parent)
|
: QWidget(parent)
|
||||||
{
|
{
|
||||||
|
QAction *sep;
|
||||||
|
|
||||||
delegate = new StreamListDelegate;
|
delegate = new StreamListDelegate;
|
||||||
//slm = new StreamListModel();
|
//slm = new StreamListModel();
|
||||||
//plm = new PortGroupList();
|
//plm = new PortGroupList();
|
||||||
@ -43,7 +45,7 @@ PortsWindow::PortsWindow(PortGroupList *pgl, QWidget *parent)
|
|||||||
tvStreamList->verticalHeader()->setDefaultSectionSize(
|
tvStreamList->verticalHeader()->setDefaultSectionSize(
|
||||||
tvStreamList->verticalHeader()->minimumSectionSize());
|
tvStreamList->verticalHeader()->minimumSectionSize());
|
||||||
|
|
||||||
// Populate Context Menu Actions
|
// Populate PortList Context Menu Actions
|
||||||
tvPortList->addAction(actionNew_Port_Group);
|
tvPortList->addAction(actionNew_Port_Group);
|
||||||
tvPortList->addAction(actionDelete_Port_Group);
|
tvPortList->addAction(actionDelete_Port_Group);
|
||||||
tvPortList->addAction(actionConnect_Port_Group);
|
tvPortList->addAction(actionConnect_Port_Group);
|
||||||
@ -51,12 +53,21 @@ PortsWindow::PortsWindow(PortGroupList *pgl, QWidget *parent)
|
|||||||
|
|
||||||
tvPortList->addAction(actionExclusive_Control);
|
tvPortList->addAction(actionExclusive_Control);
|
||||||
|
|
||||||
|
// Populate StramList Context Menu Actions
|
||||||
tvStreamList->addAction(actionNew_Stream);
|
tvStreamList->addAction(actionNew_Stream);
|
||||||
tvStreamList->addAction(actionEdit_Stream);
|
tvStreamList->addAction(actionEdit_Stream);
|
||||||
tvStreamList->addAction(actionDelete_Stream);
|
tvStreamList->addAction(actionDelete_Stream);
|
||||||
|
|
||||||
|
sep = new QAction(this);
|
||||||
|
sep->setSeparator(true);
|
||||||
|
tvStreamList->addAction(sep);
|
||||||
|
|
||||||
|
tvStreamList->addAction(actionOpen_Streams);
|
||||||
|
tvStreamList->addAction(actionSave_Streams);
|
||||||
|
|
||||||
|
// PortList and StreamList actions combined make this window's actions
|
||||||
addActions(tvPortList->actions());
|
addActions(tvPortList->actions());
|
||||||
QAction *sep = new QAction(this);
|
sep = new QAction(this);
|
||||||
sep->setSeparator(true);
|
sep->setSeparator(true);
|
||||||
addAction(sep);
|
addAction(sep);
|
||||||
addActions(tvStreamList->actions());
|
addActions(tvStreamList->actions());
|
||||||
@ -77,26 +88,24 @@ PortsWindow::PortsWindow(PortGroupList *pgl, QWidget *parent)
|
|||||||
this, SLOT(when_portView_currentChanged(const QModelIndex&,
|
this, SLOT(when_portView_currentChanged(const QModelIndex&,
|
||||||
const QModelIndex&)));
|
const QModelIndex&)));
|
||||||
|
|
||||||
connect( tvStreamList->selectionModel(),
|
connect(plm->getStreamModel(), SIGNAL(rowsInserted(QModelIndex, int, int)),
|
||||||
SIGNAL(currentChanged(const QModelIndex&, const QModelIndex&)),
|
SLOT(updateStreamViewActions()));
|
||||||
this, SLOT(when_streamView_currentChanged(const QModelIndex&,
|
connect(plm->getStreamModel(), SIGNAL(rowsRemoved(QModelIndex, int, int)),
|
||||||
const QModelIndex&)));
|
SLOT(updateStreamViewActions()));
|
||||||
connect( tvStreamList->selectionModel(),
|
|
||||||
SIGNAL(selectionChanged(const QItemSelection&, const QItemSelection&)),
|
|
||||||
this, SLOT(when_streamView_selectionChanged()));
|
|
||||||
|
|
||||||
#if 0
|
connect(tvStreamList->selectionModel(),
|
||||||
connect( tvPortList->selectionModel(),
|
|
||||||
SIGNAL(currentChanged(const QModelIndex&, const QModelIndex&)),
|
SIGNAL(currentChanged(const QModelIndex&, const QModelIndex&)),
|
||||||
plm->getStreamModel(), SLOT(setCurrentPortIndex(const QModelIndex&)));
|
SLOT(updateStreamViewActions()));
|
||||||
#endif
|
connect(tvStreamList->selectionModel(),
|
||||||
|
SIGNAL(selectionChanged(const QItemSelection&, const QItemSelection&)),
|
||||||
|
SLOT(updateStreamViewActions()));
|
||||||
|
|
||||||
tvStreamList->resizeColumnToContents(StreamModel::StreamIcon);
|
tvStreamList->resizeColumnToContents(StreamModel::StreamIcon);
|
||||||
tvStreamList->resizeColumnToContents(StreamModel::StreamStatus);
|
tvStreamList->resizeColumnToContents(StreamModel::StreamStatus);
|
||||||
|
|
||||||
// Initially we don't have any ports/streams - so send signal triggers
|
// Initially we don't have any ports/streams - so send signal triggers
|
||||||
when_portView_currentChanged(QModelIndex(), QModelIndex());
|
when_portView_currentChanged(QModelIndex(), QModelIndex());
|
||||||
when_streamView_currentChanged(QModelIndex(), QModelIndex());
|
updateStreamViewActions();
|
||||||
|
|
||||||
//! \todo Hide the Aggregate Box till we add support
|
//! \todo Hide the Aggregate Box till we add support
|
||||||
frAggregate->setHidden(true);
|
frAggregate->setHidden(true);
|
||||||
@ -148,19 +157,6 @@ void PortsWindow::when_portView_currentChanged(const QModelIndex& current,
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void PortsWindow::when_streamView_currentChanged(const QModelIndex& /*current*/,
|
|
||||||
const QModelIndex& /*previous*/)
|
|
||||||
{
|
|
||||||
qDebug("stream view current changed");
|
|
||||||
updateStreamViewActions();
|
|
||||||
}
|
|
||||||
|
|
||||||
void PortsWindow::when_streamView_selectionChanged()
|
|
||||||
{
|
|
||||||
qDebug("stream view selection changed");
|
|
||||||
updateStreamViewActions();
|
|
||||||
}
|
|
||||||
|
|
||||||
void PortsWindow::when_portModel_dataChanged(const QModelIndex& topLeft,
|
void PortsWindow::when_portModel_dataChanged(const QModelIndex& topLeft,
|
||||||
const QModelIndex& bottomRight)
|
const QModelIndex& bottomRight)
|
||||||
{
|
{
|
||||||
@ -182,16 +178,6 @@ void PortsWindow::when_portModel_reset()
|
|||||||
when_portView_currentChanged(QModelIndex(), tvPortList->currentIndex());
|
when_portView_currentChanged(QModelIndex(), tvPortList->currentIndex());
|
||||||
}
|
}
|
||||||
|
|
||||||
#if 0
|
|
||||||
void PortsWindow::updateStreamViewActions(const QModelIndex& current)
|
|
||||||
{
|
|
||||||
if (current.isValid())
|
|
||||||
actionDelete_Stream->setEnabled(true);
|
|
||||||
else
|
|
||||||
actionDelete_Stream->setDisabled(true);
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
|
|
||||||
void PortsWindow::updateStreamViewActions()
|
void PortsWindow::updateStreamViewActions()
|
||||||
{
|
{
|
||||||
// For some reason hasSelection() returns true even if selection size is 0
|
// For some reason hasSelection() returns true even if selection size is 0
|
||||||
@ -233,6 +219,9 @@ void PortsWindow::updateStreamViewActions()
|
|||||||
actionEdit_Stream->setDisabled(true);
|
actionEdit_Stream->setDisabled(true);
|
||||||
actionDelete_Stream->setDisabled(true);
|
actionDelete_Stream->setDisabled(true);
|
||||||
}
|
}
|
||||||
|
actionOpen_Streams->setEnabled(plm->isPort(
|
||||||
|
tvPortList->selectionModel()->currentIndex()));
|
||||||
|
actionSave_Streams->setEnabled(tvStreamList->model()->rowCount() > 0);
|
||||||
}
|
}
|
||||||
|
|
||||||
void PortsWindow::updatePortViewActions(const QModelIndex& current)
|
void PortsWindow::updatePortViewActions(const QModelIndex& current)
|
||||||
@ -406,26 +395,6 @@ void PortsWindow::on_actionExclusive_Control_triggered(bool checked)
|
|||||||
plm->portGroup(current.parent()).modifyPort(current.row(), checked);
|
plm->portGroup(current.parent()).modifyPort(current.row(), checked);
|
||||||
}
|
}
|
||||||
|
|
||||||
#if 0
|
|
||||||
void PortsWindow::on_actionNew_Stream_triggered()
|
|
||||||
{
|
|
||||||
qDebug("New Stream Action");
|
|
||||||
|
|
||||||
int row = 0;
|
|
||||||
|
|
||||||
if (tvStreamList->currentIndex().isValid())
|
|
||||||
row = tvStreamList->currentIndex().row();
|
|
||||||
plm->getStreamModel()->insertRows(row, 1);
|
|
||||||
}
|
|
||||||
|
|
||||||
void PortsWindow::on_actionDelete_Stream_triggered()
|
|
||||||
{
|
|
||||||
qDebug("Delete Stream Action");
|
|
||||||
if (tvStreamList->currentIndex().isValid())
|
|
||||||
plm->getStreamModel()->removeRows(tvStreamList->currentIndex().row(), 1);
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
|
|
||||||
void PortsWindow::on_actionNew_Stream_triggered()
|
void PortsWindow::on_actionNew_Stream_triggered()
|
||||||
{
|
{
|
||||||
qDebug("New Stream Action");
|
qDebug("New Stream Action");
|
||||||
@ -477,4 +446,73 @@ void PortsWindow::on_actionDelete_Stream_triggered()
|
|||||||
qDebug("No selection");
|
qDebug("No selection");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void PortsWindow::on_actionOpen_Streams_triggered()
|
||||||
|
{
|
||||||
|
qDebug("Open Streams Action");
|
||||||
|
|
||||||
|
QModelIndex current = tvPortList->selectionModel()->currentIndex();
|
||||||
|
QString fileName;
|
||||||
|
QString errorStr;
|
||||||
|
bool append = true;
|
||||||
|
|
||||||
|
Q_ASSERT(plm->isPort(current));
|
||||||
|
|
||||||
|
fileName = QFileDialog::getOpenFileName(this, tr("Open Streams"));
|
||||||
|
if (fileName.isEmpty())
|
||||||
|
goto _exit;
|
||||||
|
|
||||||
|
if (tvStreamList->model()->rowCount())
|
||||||
|
{
|
||||||
|
QMessageBox msgBox(QMessageBox::Question, qApp->applicationName(),
|
||||||
|
tr("Append to existing streams? Or overwrite?"));
|
||||||
|
QPushButton *appendBtn = msgBox.addButton(tr("Append"),
|
||||||
|
QMessageBox::ActionRole);
|
||||||
|
QPushButton *overwriteBtn = msgBox.addButton(tr("Overwrite"),
|
||||||
|
QMessageBox::ActionRole);
|
||||||
|
QPushButton *cancelBtn = msgBox.addButton(QMessageBox::Cancel);
|
||||||
|
|
||||||
|
msgBox.exec();
|
||||||
|
|
||||||
|
if (msgBox.clickedButton() == cancelBtn)
|
||||||
|
goto _exit;
|
||||||
|
else if (msgBox.clickedButton() == appendBtn)
|
||||||
|
append = true;
|
||||||
|
else if (msgBox.clickedButton() == overwriteBtn)
|
||||||
|
append = false;
|
||||||
|
else
|
||||||
|
Q_ASSERT(false);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!plm->port(current).openStreams(fileName, append, errorStr))
|
||||||
|
QMessageBox::critical(this, qApp->applicationName(), errorStr);
|
||||||
|
else if (!errorStr.isEmpty())
|
||||||
|
QMessageBox::warning(this, qApp->applicationName(), errorStr);
|
||||||
|
_exit:
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
void PortsWindow::on_actionSave_Streams_triggered()
|
||||||
|
{
|
||||||
|
qDebug("Save Streams Action");
|
||||||
|
|
||||||
|
QModelIndex current = tvPortList->selectionModel()->currentIndex();
|
||||||
|
QString fileName;
|
||||||
|
QString errorStr;
|
||||||
|
|
||||||
|
Q_ASSERT(plm->isPort(current));
|
||||||
|
|
||||||
|
fileName = QFileDialog::getSaveFileName(this, tr("Save Streams"));
|
||||||
|
if (fileName.isEmpty())
|
||||||
|
goto _exit;
|
||||||
|
|
||||||
|
// TODO: all or selected?
|
||||||
|
|
||||||
|
if (!plm->port(current).saveStreams(fileName, errorStr))
|
||||||
|
QMessageBox::critical(this, qApp->applicationName(), errorStr);
|
||||||
|
else if (!errorStr.isEmpty())
|
||||||
|
QMessageBox::warning(this, qApp->applicationName(), errorStr);
|
||||||
|
_exit:
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@ -48,17 +48,13 @@ private:
|
|||||||
QString lastNewPortGroup;
|
QString lastNewPortGroup;
|
||||||
QAbstractItemDelegate *delegate;
|
QAbstractItemDelegate *delegate;
|
||||||
|
|
||||||
|
private slots:
|
||||||
void updatePortViewActions(const QModelIndex& current);
|
void updatePortViewActions(const QModelIndex& current);
|
||||||
//void updateStreamViewActions(const QModelIndex& current);
|
|
||||||
void updateStreamViewActions();
|
void updateStreamViewActions();
|
||||||
|
|
||||||
private slots:
|
|
||||||
void on_tvStreamList_activated(const QModelIndex & index);
|
void on_tvStreamList_activated(const QModelIndex & index);
|
||||||
void when_portView_currentChanged(const QModelIndex& current,
|
void when_portView_currentChanged(const QModelIndex& current,
|
||||||
const QModelIndex& previous);
|
const QModelIndex& previous);
|
||||||
void when_streamView_currentChanged(const QModelIndex& current,
|
|
||||||
const QModelIndex& previous);
|
|
||||||
void when_streamView_selectionChanged();
|
|
||||||
void when_portModel_dataChanged(const QModelIndex& topLeft,
|
void when_portModel_dataChanged(const QModelIndex& topLeft,
|
||||||
const QModelIndex& bottomRight);
|
const QModelIndex& bottomRight);
|
||||||
void when_portModel_reset();
|
void when_portModel_reset();
|
||||||
@ -75,6 +71,9 @@ private slots:
|
|||||||
void on_actionNew_Stream_triggered();
|
void on_actionNew_Stream_triggered();
|
||||||
void on_actionEdit_Stream_triggered();
|
void on_actionEdit_Stream_triggered();
|
||||||
void on_actionDelete_Stream_triggered();
|
void on_actionDelete_Stream_triggered();
|
||||||
|
|
||||||
|
void on_actionOpen_Streams_triggered();
|
||||||
|
void on_actionSave_Streams_triggered();
|
||||||
};
|
};
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
@ -230,6 +230,16 @@
|
|||||||
<string>Exclusive Port Control (EXPERIMENTAL)</string>
|
<string>Exclusive Port Control (EXPERIMENTAL)</string>
|
||||||
</property>
|
</property>
|
||||||
</action>
|
</action>
|
||||||
|
<action name="actionOpen_Streams" >
|
||||||
|
<property name="text" >
|
||||||
|
<string>Open Streams ...</string>
|
||||||
|
</property>
|
||||||
|
</action>
|
||||||
|
<action name="actionSave_Streams" >
|
||||||
|
<property name="text" >
|
||||||
|
<string>Save Streams ...</string>
|
||||||
|
</property>
|
||||||
|
</action>
|
||||||
</widget>
|
</widget>
|
||||||
<resources>
|
<resources>
|
||||||
<include location="ostinato.qrc" />
|
<include location="ostinato.qrc" />
|
||||||
|
@ -254,8 +254,30 @@ void StreamModel::setCurrentPortIndex(const QModelIndex ¤t)
|
|||||||
else
|
else
|
||||||
{
|
{
|
||||||
qDebug("change to valid port");
|
qDebug("change to valid port");
|
||||||
|
// Disconnect any existing connection to avoid duplication
|
||||||
|
// Qt 4.6 has Qt::UniqueConnection, but we want to remain compatible
|
||||||
|
// with earlier Qt versions
|
||||||
|
if (mCurrentPort)
|
||||||
|
{
|
||||||
|
disconnect(mCurrentPort, SIGNAL(streamListChanged(int, int)),
|
||||||
|
this, SLOT(when_mCurrentPort_streamListChanged(int, int)));
|
||||||
|
}
|
||||||
quint16 pg = current.internalId() >> 16;
|
quint16 pg = current.internalId() >> 16;
|
||||||
mCurrentPort = pgl->mPortGroups[pgl->indexOfPortGroup(pg)]->mPorts[current.row()];
|
mCurrentPort = pgl->mPortGroups[pgl->indexOfPortGroup(pg)]->mPorts[current.row()];
|
||||||
|
connect(mCurrentPort, SIGNAL(streamListChanged(int, int)),
|
||||||
|
this, SLOT(when_mCurrentPort_streamListChanged(int, int)));
|
||||||
}
|
}
|
||||||
reset();
|
reset();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void StreamModel::when_mCurrentPort_streamListChanged(int portGroupId,
|
||||||
|
int portId)
|
||||||
|
{
|
||||||
|
qDebug("In %s", __FUNCTION__);
|
||||||
|
if (mCurrentPort)
|
||||||
|
{
|
||||||
|
if ((quint32(portGroupId) == mCurrentPort->portGroupId())
|
||||||
|
&& (quint32(portId) == mCurrentPort->id()))
|
||||||
|
reset();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
@ -71,6 +71,8 @@ class StreamModel : public QAbstractTableModel
|
|||||||
public slots:
|
public slots:
|
||||||
void setCurrentPortIndex(const QModelIndex ¤t);
|
void setCurrentPortIndex(const QModelIndex ¤t);
|
||||||
|
|
||||||
|
private slots:
|
||||||
|
void when_mCurrentPort_streamListChanged(int portGroupId, int portId);
|
||||||
};
|
};
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
@ -63,5 +63,5 @@ message Arp {
|
|||||||
}
|
}
|
||||||
|
|
||||||
extend Protocol {
|
extend Protocol {
|
||||||
optional Arp arp = 130;
|
optional Arp arp = 300;
|
||||||
}
|
}
|
||||||
|
134
common/crc32c.cpp
Normal file
134
common/crc32c.cpp
Normal file
@ -0,0 +1,134 @@
|
|||||||
|
/*
|
||||||
|
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/>
|
||||||
|
*/
|
||||||
|
|
||||||
|
/*******************************************************************
|
||||||
|
** IMPORTANT NOTE:
|
||||||
|
** This code is from RFC 4960 Stream Control Transmission Protocol
|
||||||
|
** It has been modified suitably while keeping the algorithm intact.
|
||||||
|
********************************************************************/
|
||||||
|
|
||||||
|
#include "crc32c.h"
|
||||||
|
|
||||||
|
#define CRC32C(c,d) (c=(c>>8)^crc_c[(c^(d))&0xFF])
|
||||||
|
|
||||||
|
quint32 crc_c[256] =
|
||||||
|
{
|
||||||
|
0x00000000L, 0xF26B8303L, 0xE13B70F7L, 0x1350F3F4L,
|
||||||
|
0xC79A971FL, 0x35F1141CL, 0x26A1E7E8L, 0xD4CA64EBL,
|
||||||
|
0x8AD958CFL, 0x78B2DBCCL, 0x6BE22838L, 0x9989AB3BL,
|
||||||
|
0x4D43CFD0L, 0xBF284CD3L, 0xAC78BF27L, 0x5E133C24L,
|
||||||
|
0x105EC76FL, 0xE235446CL, 0xF165B798L, 0x030E349BL,
|
||||||
|
0xD7C45070L, 0x25AFD373L, 0x36FF2087L, 0xC494A384L,
|
||||||
|
0x9A879FA0L, 0x68EC1CA3L, 0x7BBCEF57L, 0x89D76C54L,
|
||||||
|
0x5D1D08BFL, 0xAF768BBCL, 0xBC267848L, 0x4E4DFB4BL,
|
||||||
|
0x20BD8EDEL, 0xD2D60DDDL, 0xC186FE29L, 0x33ED7D2AL,
|
||||||
|
0xE72719C1L, 0x154C9AC2L, 0x061C6936L, 0xF477EA35L,
|
||||||
|
0xAA64D611L, 0x580F5512L, 0x4B5FA6E6L, 0xB93425E5L,
|
||||||
|
0x6DFE410EL, 0x9F95C20DL, 0x8CC531F9L, 0x7EAEB2FAL,
|
||||||
|
0x30E349B1L, 0xC288CAB2L, 0xD1D83946L, 0x23B3BA45L,
|
||||||
|
0xF779DEAEL, 0x05125DADL, 0x1642AE59L, 0xE4292D5AL,
|
||||||
|
0xBA3A117EL, 0x4851927DL, 0x5B016189L, 0xA96AE28AL,
|
||||||
|
0x7DA08661L, 0x8FCB0562L, 0x9C9BF696L, 0x6EF07595L,
|
||||||
|
0x417B1DBCL, 0xB3109EBFL, 0xA0406D4BL, 0x522BEE48L,
|
||||||
|
0x86E18AA3L, 0x748A09A0L, 0x67DAFA54L, 0x95B17957L,
|
||||||
|
0xCBA24573L, 0x39C9C670L, 0x2A993584L, 0xD8F2B687L,
|
||||||
|
0x0C38D26CL, 0xFE53516FL, 0xED03A29BL, 0x1F682198L,
|
||||||
|
0x5125DAD3L, 0xA34E59D0L, 0xB01EAA24L, 0x42752927L,
|
||||||
|
0x96BF4DCCL, 0x64D4CECFL, 0x77843D3BL, 0x85EFBE38L,
|
||||||
|
0xDBFC821CL, 0x2997011FL, 0x3AC7F2EBL, 0xC8AC71E8L,
|
||||||
|
0x1C661503L, 0xEE0D9600L, 0xFD5D65F4L, 0x0F36E6F7L,
|
||||||
|
0x61C69362L, 0x93AD1061L, 0x80FDE395L, 0x72966096L,
|
||||||
|
0xA65C047DL, 0x5437877EL, 0x4767748AL, 0xB50CF789L,
|
||||||
|
0xEB1FCBADL, 0x197448AEL, 0x0A24BB5AL, 0xF84F3859L,
|
||||||
|
0x2C855CB2L, 0xDEEEDFB1L, 0xCDBE2C45L, 0x3FD5AF46L,
|
||||||
|
0x7198540DL, 0x83F3D70EL, 0x90A324FAL, 0x62C8A7F9L,
|
||||||
|
0xB602C312L, 0x44694011L, 0x5739B3E5L, 0xA55230E6L,
|
||||||
|
0xFB410CC2L, 0x092A8FC1L, 0x1A7A7C35L, 0xE811FF36L,
|
||||||
|
0x3CDB9BDDL, 0xCEB018DEL, 0xDDE0EB2AL, 0x2F8B6829L,
|
||||||
|
0x82F63B78L, 0x709DB87BL, 0x63CD4B8FL, 0x91A6C88CL,
|
||||||
|
0x456CAC67L, 0xB7072F64L, 0xA457DC90L, 0x563C5F93L,
|
||||||
|
0x082F63B7L, 0xFA44E0B4L, 0xE9141340L, 0x1B7F9043L,
|
||||||
|
0xCFB5F4A8L, 0x3DDE77ABL, 0x2E8E845FL, 0xDCE5075CL,
|
||||||
|
0x92A8FC17L, 0x60C37F14L, 0x73938CE0L, 0x81F80FE3L,
|
||||||
|
0x55326B08L, 0xA759E80BL, 0xB4091BFFL, 0x466298FCL,
|
||||||
|
0x1871A4D8L, 0xEA1A27DBL, 0xF94AD42FL, 0x0B21572CL,
|
||||||
|
0xDFEB33C7L, 0x2D80B0C4L, 0x3ED04330L, 0xCCBBC033L,
|
||||||
|
0xA24BB5A6L, 0x502036A5L, 0x4370C551L, 0xB11B4652L,
|
||||||
|
0x65D122B9L, 0x97BAA1BAL, 0x84EA524EL, 0x7681D14DL,
|
||||||
|
0x2892ED69L, 0xDAF96E6AL, 0xC9A99D9EL, 0x3BC21E9DL,
|
||||||
|
0xEF087A76L, 0x1D63F975L, 0x0E330A81L, 0xFC588982L,
|
||||||
|
0xB21572C9L, 0x407EF1CAL, 0x532E023EL, 0xA145813DL,
|
||||||
|
0x758FE5D6L, 0x87E466D5L, 0x94B49521L, 0x66DF1622L,
|
||||||
|
0x38CC2A06L, 0xCAA7A905L, 0xD9F75AF1L, 0x2B9CD9F2L,
|
||||||
|
0xFF56BD19L, 0x0D3D3E1AL, 0x1E6DCDEEL, 0xEC064EEDL,
|
||||||
|
0xC38D26C4L, 0x31E6A5C7L, 0x22B65633L, 0xD0DDD530L,
|
||||||
|
0x0417B1DBL, 0xF67C32D8L, 0xE52CC12CL, 0x1747422FL,
|
||||||
|
0x49547E0BL, 0xBB3FFD08L, 0xA86F0EFCL, 0x5A048DFFL,
|
||||||
|
0x8ECEE914L, 0x7CA56A17L, 0x6FF599E3L, 0x9D9E1AE0L,
|
||||||
|
0xD3D3E1ABL, 0x21B862A8L, 0x32E8915CL, 0xC083125FL,
|
||||||
|
0x144976B4L, 0xE622F5B7L, 0xF5720643L, 0x07198540L,
|
||||||
|
0x590AB964L, 0xAB613A67L, 0xB831C993L, 0x4A5A4A90L,
|
||||||
|
0x9E902E7BL, 0x6CFBAD78L, 0x7FAB5E8CL, 0x8DC0DD8FL,
|
||||||
|
0xE330A81AL, 0x115B2B19L, 0x020BD8EDL, 0xF0605BEEL,
|
||||||
|
0x24AA3F05L, 0xD6C1BC06L, 0xC5914FF2L, 0x37FACCF1L,
|
||||||
|
0x69E9F0D5L, 0x9B8273D6L, 0x88D28022L, 0x7AB90321L,
|
||||||
|
0xAE7367CAL, 0x5C18E4C9L, 0x4F48173DL, 0xBD23943EL,
|
||||||
|
0xF36E6F75L, 0x0105EC76L, 0x12551F82L, 0xE03E9C81L,
|
||||||
|
0x34F4F86AL, 0xC69F7B69L, 0xD5CF889DL, 0x27A40B9EL,
|
||||||
|
0x79B737BAL, 0x8BDCB4B9L, 0x988C474DL, 0x6AE7C44EL,
|
||||||
|
0xBE2DA0A5L, 0x4C4623A6L, 0x5F16D052L, 0xAD7D5351L,
|
||||||
|
};
|
||||||
|
|
||||||
|
quint32 checksumCrc32C(quint8 *buffer, uint length)
|
||||||
|
{
|
||||||
|
uint i;
|
||||||
|
quint32 crc32 = ~0L;
|
||||||
|
quint32 result;
|
||||||
|
quint8 byte0,byte1,byte2,byte3;
|
||||||
|
|
||||||
|
for (i = 0; i < length; i++) {
|
||||||
|
CRC32C(crc32, buffer[i]);
|
||||||
|
}
|
||||||
|
|
||||||
|
result = ~crc32;
|
||||||
|
|
||||||
|
/* result now holds the negated polynomial remainder;
|
||||||
|
* since the table and algorithm is "reflected" [williams95].
|
||||||
|
* That is, result has the same value as if we mapped the message
|
||||||
|
* to a polynomial, computed the host-bit-order polynomial
|
||||||
|
* remainder, performed final negation, then did an end-for-end
|
||||||
|
* bit-reversal.
|
||||||
|
* Note that a 32-bit bit-reversal is identical to four inplace
|
||||||
|
* 8-bit reversals followed by an end-for-end byteswap.
|
||||||
|
* In other words, the bytes of each bit are in the right order,
|
||||||
|
* but the bytes have been byteswapped. So we now do an explicit
|
||||||
|
* byteswap. On a little-endian machine, this byteswap and
|
||||||
|
* the final ntohl cancel out and could be elided.
|
||||||
|
*/
|
||||||
|
|
||||||
|
byte0 = result & 0xff;
|
||||||
|
byte1 = (result>>8) & 0xff;
|
||||||
|
byte2 = (result>>16) & 0xff;
|
||||||
|
byte3 = (result>>24) & 0xff;
|
||||||
|
crc32 = ((byte0 << 24) |
|
||||||
|
(byte1 << 16) |
|
||||||
|
(byte2 << 8) |
|
||||||
|
byte3);
|
||||||
|
return ( crc32 );
|
||||||
|
}
|
23
common/crc32c.h
Normal file
23
common/crc32c.h
Normal file
@ -0,0 +1,23 @@
|
|||||||
|
/*
|
||||||
|
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 <QtGlobal>
|
||||||
|
|
||||||
|
quint32 checksumCrc32C(quint8 *buffer, uint length);
|
||||||
|
|
@ -29,5 +29,5 @@ message Dot2Llc {
|
|||||||
}
|
}
|
||||||
|
|
||||||
extend Protocol {
|
extend Protocol {
|
||||||
optional Dot2Llc dot2Llc = 127;
|
optional Dot2Llc dot2Llc = 206;
|
||||||
}
|
}
|
||||||
|
@ -27,5 +27,5 @@ message Dot2Snap {
|
|||||||
}
|
}
|
||||||
|
|
||||||
extend Protocol {
|
extend Protocol {
|
||||||
optional Dot2Snap dot2Snap = 128;
|
optional Dot2Snap dot2Snap = 207;
|
||||||
}
|
}
|
||||||
|
@ -27,5 +27,5 @@ message Dot3 {
|
|||||||
}
|
}
|
||||||
|
|
||||||
extend Protocol {
|
extend Protocol {
|
||||||
optional Dot3 dot3 = 122;
|
optional Dot3 dot3 = 201;
|
||||||
}
|
}
|
||||||
|
@ -27,5 +27,5 @@ message Eth2 {
|
|||||||
}
|
}
|
||||||
|
|
||||||
extend Protocol {
|
extend Protocol {
|
||||||
optional Eth2 eth2 = 121;
|
optional Eth2 eth2 = 200;
|
||||||
}
|
}
|
||||||
|
411
common/fileformat.cpp
Normal file
411
common/fileformat.cpp
Normal file
@ -0,0 +1,411 @@
|
|||||||
|
/*
|
||||||
|
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 "fileformat.h"
|
||||||
|
|
||||||
|
#include "crc32c.h"
|
||||||
|
|
||||||
|
#include <QApplication>
|
||||||
|
#include <QFile>
|
||||||
|
#include <QVariant>
|
||||||
|
|
||||||
|
#include <string>
|
||||||
|
|
||||||
|
const std::string FileFormat::kFileMagicValue = "\xa7\xb7OSTINATO";
|
||||||
|
|
||||||
|
FileFormat fileFormat;
|
||||||
|
|
||||||
|
const int kBaseHex = 16;
|
||||||
|
|
||||||
|
FileFormat::FileFormat()
|
||||||
|
{
|
||||||
|
/*
|
||||||
|
* We don't have any "real" work to do here in the constructor.
|
||||||
|
* What we do is run some "assert" tests so that these get caught
|
||||||
|
* at init itself instead of while saving/restoring when a user
|
||||||
|
* might lose some data!
|
||||||
|
*/
|
||||||
|
OstProto::FileMagic magic;
|
||||||
|
OstProto::FileChecksum cksum;
|
||||||
|
|
||||||
|
magic.set_value(kFileMagicValue);
|
||||||
|
cksum.set_value(quint32(0));
|
||||||
|
|
||||||
|
// TODO: convert Q_ASSERT to something that will run in RELEASE mode also
|
||||||
|
Q_ASSERT(magic.IsInitialized());
|
||||||
|
Q_ASSERT(cksum.IsInitialized());
|
||||||
|
Q_ASSERT(magic.ByteSize() == kFileMagicSize);
|
||||||
|
Q_ASSERT(cksum.ByteSize() == kFileChecksumSize);
|
||||||
|
}
|
||||||
|
|
||||||
|
FileFormat::~FileFormat()
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
bool FileFormat::openStreams(const QString fileName,
|
||||||
|
OstProto::StreamConfigList &streams, QString &error)
|
||||||
|
{
|
||||||
|
QFile file(fileName);
|
||||||
|
QByteArray buf;
|
||||||
|
int size, contentOffset, contentSize;
|
||||||
|
quint32 calcCksum;
|
||||||
|
OstProto::FileMagic magic;
|
||||||
|
OstProto::FileMeta meta;
|
||||||
|
OstProto::FileContent content;
|
||||||
|
OstProto::FileChecksum cksum, zeroCksum;
|
||||||
|
|
||||||
|
if (!file.open(QIODevice::ReadOnly))
|
||||||
|
goto _open_fail;
|
||||||
|
|
||||||
|
if (file.size() < kFileMagicSize)
|
||||||
|
goto _magic_missing;
|
||||||
|
|
||||||
|
if (file.size() < kFileMinSize)
|
||||||
|
goto _checksum_missing;
|
||||||
|
|
||||||
|
buf.resize(file.size());
|
||||||
|
size = file.read(buf.data(), buf.size());
|
||||||
|
if (size < 0)
|
||||||
|
goto _read_fail;
|
||||||
|
|
||||||
|
Q_ASSERT(file.atEnd());
|
||||||
|
file.close();
|
||||||
|
|
||||||
|
qDebug("%s: file.size() = %lld", __FUNCTION__, file.size());
|
||||||
|
qDebug("%s: size = %d", __FUNCTION__, size);
|
||||||
|
|
||||||
|
//qDebug("Read %d bytes", buf.size());
|
||||||
|
//qDebug("%s", QString(buf.toHex()).toAscii().constData());
|
||||||
|
|
||||||
|
// Parse and verify magic
|
||||||
|
if (!magic.ParseFromArray(
|
||||||
|
(void*)(buf.constData() + kFileMagicOffset),
|
||||||
|
kFileMagicSize))
|
||||||
|
{
|
||||||
|
goto _magic_parse_fail;
|
||||||
|
}
|
||||||
|
if (magic.value() != kFileMagicValue)
|
||||||
|
goto _magic_match_fail;
|
||||||
|
|
||||||
|
// Parse and verify checksum
|
||||||
|
if (!cksum.ParseFromArray(
|
||||||
|
(void*)(buf.constData() + size - kFileChecksumSize),
|
||||||
|
kFileChecksumSize))
|
||||||
|
{
|
||||||
|
goto _cksum_parse_fail;
|
||||||
|
}
|
||||||
|
|
||||||
|
zeroCksum.set_value(0);
|
||||||
|
if (!zeroCksum.SerializeToArray(
|
||||||
|
(void*) (buf.data() + size - kFileChecksumSize),
|
||||||
|
kFileChecksumSize))
|
||||||
|
{
|
||||||
|
goto _zero_cksum_serialize_fail;
|
||||||
|
}
|
||||||
|
|
||||||
|
calcCksum = checksumCrc32C((quint8*) buf.constData(), size);
|
||||||
|
|
||||||
|
qDebug("checksum \nExpected:%x Actual:%x",
|
||||||
|
calcCksum, cksum.value());
|
||||||
|
|
||||||
|
if (cksum.value() != calcCksum)
|
||||||
|
goto _cksum_verify_fail;
|
||||||
|
|
||||||
|
// Parse the metadata first before we parse the full contents
|
||||||
|
if (!meta.ParseFromArray(
|
||||||
|
(void*)(buf.constData() + kFileMetaDataOffset),
|
||||||
|
size - kFileMetaDataOffset))
|
||||||
|
{
|
||||||
|
goto _metadata_parse_fail;
|
||||||
|
}
|
||||||
|
|
||||||
|
qDebug("%s: File MetaData (INFORMATION) - \n%s", __FUNCTION__,
|
||||||
|
QString().fromStdString(meta.DebugString()).toAscii().constData());
|
||||||
|
|
||||||
|
// MetaData Validation(s)
|
||||||
|
if (meta.data().file_type() != OstProto::kStreamsFileType)
|
||||||
|
goto _unexpected_file_type;
|
||||||
|
|
||||||
|
if (meta.data().format_version_major() != kFileFormatVersionMajor)
|
||||||
|
goto _incompatible_file_version;
|
||||||
|
|
||||||
|
if (meta.data().format_version_minor() > kFileFormatVersionMinor)
|
||||||
|
goto _incompatible_file_version;
|
||||||
|
|
||||||
|
if (meta.data().format_version_minor() < kFileFormatVersionMinor)
|
||||||
|
{
|
||||||
|
// TODO: need to modify 'buf' such that we can parse successfully
|
||||||
|
// assuming the native minor version
|
||||||
|
}
|
||||||
|
|
||||||
|
if (meta.data().format_version_revision() > kFileFormatVersionRevision)
|
||||||
|
{
|
||||||
|
error = QString(tr("%1 was created using a newer version of Ostinato."
|
||||||
|
" New features/protocols will not be available.")).arg(fileName);
|
||||||
|
}
|
||||||
|
|
||||||
|
Q_ASSERT(meta.data().format_version_major() == kFileFormatVersionMajor);
|
||||||
|
Q_ASSERT(meta.data().format_version_minor() == kFileFormatVersionMinor);
|
||||||
|
|
||||||
|
// ByteSize() does not include the Tag/Key, so we add 2 for that
|
||||||
|
contentOffset = kFileMetaDataOffset + meta.data().ByteSize() + 2;
|
||||||
|
contentSize = size - contentOffset - kFileChecksumSize;
|
||||||
|
|
||||||
|
// Parse full contents
|
||||||
|
if (!content.ParseFromArray(
|
||||||
|
(void*)(buf.constData() + contentOffset),
|
||||||
|
contentSize))
|
||||||
|
{
|
||||||
|
goto _content_parse_fail;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!content.matter().has_streams())
|
||||||
|
goto _missing_streams;
|
||||||
|
|
||||||
|
streams.CopyFrom(content.matter().streams());
|
||||||
|
|
||||||
|
return true;
|
||||||
|
|
||||||
|
_missing_streams:
|
||||||
|
error = QString(tr("%1 does not contain any streams")).arg(fileName);
|
||||||
|
goto _fail;
|
||||||
|
_content_parse_fail:
|
||||||
|
error = QString(tr("Failed parsing %1 contents")).arg(fileName);
|
||||||
|
qDebug("Error: %s", QString().fromStdString(
|
||||||
|
content.matter().InitializationErrorString())
|
||||||
|
.toAscii().constData());
|
||||||
|
qDebug("Debug: %s", QString().fromStdString(
|
||||||
|
content.matter().DebugString()).toAscii().constData());
|
||||||
|
goto _fail;
|
||||||
|
_incompatible_file_version:
|
||||||
|
error = QString(tr("%1 is in an incompatible format version - %2.%3.%4"
|
||||||
|
" (Native version is %5.%6.%7)"))
|
||||||
|
.arg(fileName)
|
||||||
|
.arg(meta.data().format_version_major())
|
||||||
|
.arg(meta.data().format_version_minor())
|
||||||
|
.arg(meta.data().format_version_revision())
|
||||||
|
.arg(kFileFormatVersionMajor)
|
||||||
|
.arg(kFileFormatVersionMinor)
|
||||||
|
.arg(kFileFormatVersionRevision);
|
||||||
|
goto _fail;
|
||||||
|
_unexpected_file_type:
|
||||||
|
error = QString(tr("%1 is not a streams file")).arg(fileName);
|
||||||
|
goto _fail;
|
||||||
|
_metadata_parse_fail:
|
||||||
|
error = QString(tr("Failed parsing %1 meta data")).arg(fileName);
|
||||||
|
qDebug("Error: %s", QString().fromStdString(
|
||||||
|
meta.data().InitializationErrorString())
|
||||||
|
.toAscii().constData());
|
||||||
|
goto _fail;
|
||||||
|
_cksum_verify_fail:
|
||||||
|
error = QString(tr("%1 checksum validation failed!\nExpected:%2 Actual:%3"))
|
||||||
|
.arg(fileName)
|
||||||
|
.arg(calcCksum, 0, kBaseHex)
|
||||||
|
.arg(cksum.value(), 0, kBaseHex);
|
||||||
|
goto _fail;
|
||||||
|
_zero_cksum_serialize_fail:
|
||||||
|
error = QString(tr("Internal Error: Zero Checksum Serialize failed!\n"
|
||||||
|
"Error: %1\nDebug: %2"))
|
||||||
|
.arg(QString().fromStdString(
|
||||||
|
cksum.InitializationErrorString()))
|
||||||
|
.arg(QString().fromStdString(cksum.DebugString()));
|
||||||
|
goto _fail;
|
||||||
|
_cksum_parse_fail:
|
||||||
|
error = QString(tr("Failed parsing %1 checksum")).arg(fileName);
|
||||||
|
qDebug("Error: %s", QString().fromStdString(
|
||||||
|
cksum.InitializationErrorString())
|
||||||
|
.toAscii().constData());
|
||||||
|
goto _fail;
|
||||||
|
_magic_match_fail:
|
||||||
|
error = QString(tr("%1 is not an Ostinato file")).arg(fileName);
|
||||||
|
goto _fail;
|
||||||
|
_magic_parse_fail:
|
||||||
|
error = QString(tr("%1 does not look like an Ostinato file")).arg(fileName);
|
||||||
|
qDebug("Error: %s", QString().fromStdString(
|
||||||
|
magic.InitializationErrorString())
|
||||||
|
.toAscii().constData());
|
||||||
|
goto _fail;
|
||||||
|
_read_fail:
|
||||||
|
error = QString(tr("Error reading from %1")).arg(fileName);
|
||||||
|
goto _fail;
|
||||||
|
_checksum_missing:
|
||||||
|
error = QString(tr("%1 is too small (missing checksum)")).arg(fileName);
|
||||||
|
goto _fail;
|
||||||
|
_magic_missing:
|
||||||
|
error = QString(tr("%1 is too small (missing magic value)"))
|
||||||
|
.arg(fileName);
|
||||||
|
goto _fail;
|
||||||
|
_open_fail:
|
||||||
|
error = QString(tr("Error opening %1")).arg(fileName);
|
||||||
|
goto _fail;
|
||||||
|
_fail:
|
||||||
|
qDebug("%s", error.toAscii().constData());
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool FileFormat::saveStreams(const OstProto::StreamConfigList streams,
|
||||||
|
const QString fileName, QString &error)
|
||||||
|
{
|
||||||
|
OstProto::FileMagic magic;
|
||||||
|
OstProto::FileMeta meta;
|
||||||
|
OstProto::FileContent content;
|
||||||
|
OstProto::FileChecksum cksum;
|
||||||
|
QFile file(fileName);
|
||||||
|
int metaSize, contentSize;
|
||||||
|
int contentOffset, cksumOffset;
|
||||||
|
QByteArray buf;
|
||||||
|
quint32 calcCksum;
|
||||||
|
|
||||||
|
magic.set_value(kFileMagicValue);
|
||||||
|
Q_ASSERT(magic.IsInitialized());
|
||||||
|
|
||||||
|
cksum.set_value(0);
|
||||||
|
Q_ASSERT(cksum.IsInitialized());
|
||||||
|
|
||||||
|
initFileMetaData(*(meta.mutable_data()));
|
||||||
|
meta.mutable_data()->set_file_type(OstProto::kStreamsFileType);
|
||||||
|
Q_ASSERT(meta.IsInitialized());
|
||||||
|
|
||||||
|
if (!streams.IsInitialized())
|
||||||
|
goto _stream_not_init;
|
||||||
|
|
||||||
|
content.mutable_matter()->mutable_streams()->CopyFrom(streams);
|
||||||
|
Q_ASSERT(content.IsInitialized());
|
||||||
|
|
||||||
|
metaSize = meta.ByteSize();
|
||||||
|
contentSize = content.ByteSize();
|
||||||
|
contentOffset = kFileMetaDataOffset + metaSize;
|
||||||
|
cksumOffset = contentOffset + contentSize;
|
||||||
|
|
||||||
|
Q_ASSERT(magic.ByteSize() == kFileMagicSize);
|
||||||
|
Q_ASSERT(cksum.ByteSize() == kFileChecksumSize);
|
||||||
|
buf.resize(kFileMagicSize + metaSize + contentSize + kFileChecksumSize);
|
||||||
|
|
||||||
|
// Serialize everything
|
||||||
|
if (!magic.SerializeToArray((void*) (buf.data() + kFileMagicOffset),
|
||||||
|
kFileMagicSize))
|
||||||
|
{
|
||||||
|
goto _magic_serialize_fail;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!meta.SerializeToArray((void*) (buf.data() + kFileMetaDataOffset),
|
||||||
|
metaSize))
|
||||||
|
{
|
||||||
|
goto _meta_serialize_fail;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!content.SerializeToArray((void*) (buf.data() + contentOffset),
|
||||||
|
contentSize))
|
||||||
|
{
|
||||||
|
goto _content_serialize_fail;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!cksum.SerializeToArray((void*) (buf.data() + cksumOffset),
|
||||||
|
kFileChecksumSize))
|
||||||
|
{
|
||||||
|
goto _zero_cksum_serialize_fail;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Calculate and write checksum
|
||||||
|
calcCksum = checksumCrc32C((quint8*)buf.constData(), buf.size());
|
||||||
|
cksum.set_value(calcCksum);
|
||||||
|
if (!cksum.SerializeToArray(
|
||||||
|
(void*) (buf.data() + cksumOffset),
|
||||||
|
kFileChecksumSize))
|
||||||
|
{
|
||||||
|
goto _cksum_serialize_fail;
|
||||||
|
}
|
||||||
|
|
||||||
|
qDebug("Writing %d bytes", buf.size());
|
||||||
|
//qDebug("%s", QString(buf.toHex()).toAscii().constData());
|
||||||
|
|
||||||
|
if (!file.open(QIODevice::WriteOnly | QIODevice::Truncate))
|
||||||
|
goto _open_fail;
|
||||||
|
|
||||||
|
if (file.write(buf) < 0)
|
||||||
|
goto _write_fail;
|
||||||
|
|
||||||
|
file.close();
|
||||||
|
|
||||||
|
return true;
|
||||||
|
|
||||||
|
_write_fail:
|
||||||
|
error = QString(tr("Error writing to %1")).arg(fileName);
|
||||||
|
goto _fail;
|
||||||
|
_open_fail:
|
||||||
|
error = QString(tr("Error opening %1 (Error Code = %2)"))
|
||||||
|
.arg(fileName)
|
||||||
|
.arg(file.error());
|
||||||
|
goto _fail;
|
||||||
|
_cksum_serialize_fail:
|
||||||
|
error = QString(tr("Internal Error: Checksum Serialize failed\n%1\n%2"))
|
||||||
|
.arg(QString().fromStdString(
|
||||||
|
cksum.InitializationErrorString()))
|
||||||
|
.arg(QString().fromStdString(cksum.DebugString()));
|
||||||
|
goto _fail;
|
||||||
|
_zero_cksum_serialize_fail:
|
||||||
|
error = QString(tr("Internal Eror: Zero Checksum Serialize failed\n%1\n%2"))
|
||||||
|
.arg(QString().fromStdString(
|
||||||
|
cksum.InitializationErrorString()))
|
||||||
|
.arg(QString().fromStdString(cksum.DebugString()));
|
||||||
|
goto _fail;
|
||||||
|
_content_serialize_fail:
|
||||||
|
error = QString(tr("Internal Error: Content Serialize failed\n%1\n%2"))
|
||||||
|
.arg(QString().fromStdString(
|
||||||
|
content.InitializationErrorString()))
|
||||||
|
.arg(QString().fromStdString(content.DebugString()));
|
||||||
|
goto _fail;
|
||||||
|
_meta_serialize_fail:
|
||||||
|
error = QString(tr("Internal Error: Meta Data Serialize failed\n%1\n%2"))
|
||||||
|
.arg(QString().fromStdString(
|
||||||
|
meta.InitializationErrorString()))
|
||||||
|
.arg(QString().fromStdString(meta.DebugString()));
|
||||||
|
goto _fail;
|
||||||
|
_magic_serialize_fail:
|
||||||
|
error = QString(tr("Internal Error: Magic Serialize failed\n%1\n%2"))
|
||||||
|
.arg(QString().fromStdString(
|
||||||
|
magic.InitializationErrorString()))
|
||||||
|
.arg(QString().fromStdString(magic.DebugString()));
|
||||||
|
goto _fail;
|
||||||
|
_stream_not_init:
|
||||||
|
error = QString(tr("Internal Error: Streams not initialized\n%1\n%2"))
|
||||||
|
.arg(QString().fromStdString(
|
||||||
|
streams.InitializationErrorString()))
|
||||||
|
.arg(QString().fromStdString(streams.DebugString()));
|
||||||
|
goto _fail;
|
||||||
|
_fail:
|
||||||
|
qDebug("%s", error.toAscii().constData());
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
void FileFormat::initFileMetaData(OstProto::FileMetaData &metaData)
|
||||||
|
{
|
||||||
|
// Fill in the "native" file format version
|
||||||
|
metaData.set_format_version_major(kFileFormatVersionMajor);
|
||||||
|
metaData.set_format_version_minor(kFileFormatVersionMinor);
|
||||||
|
metaData.set_format_version_revision(kFileFormatVersionRevision);
|
||||||
|
|
||||||
|
metaData.set_generator_name(
|
||||||
|
qApp->applicationName().toUtf8().constData());
|
||||||
|
metaData.set_generator_version(
|
||||||
|
qApp->property("version").toString().toUtf8().constData());
|
||||||
|
metaData.set_generator_revision(
|
||||||
|
qApp->property("revision").toString().toUtf8().constData());
|
||||||
|
}
|
||||||
|
|
59
common/fileformat.h
Normal file
59
common/fileformat.h
Normal file
@ -0,0 +1,59 @@
|
|||||||
|
/*
|
||||||
|
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 _FILE_FORMAT_H
|
||||||
|
#define _FILE_FORMAT_H
|
||||||
|
|
||||||
|
#include "fileformat.pb.h"
|
||||||
|
|
||||||
|
#include <QString>
|
||||||
|
#include <QObject>
|
||||||
|
|
||||||
|
class FileFormat : public QObject
|
||||||
|
{
|
||||||
|
Q_OBJECT
|
||||||
|
public:
|
||||||
|
FileFormat();
|
||||||
|
~FileFormat();
|
||||||
|
|
||||||
|
bool openStreams(const QString fileName,
|
||||||
|
OstProto::StreamConfigList &streams, QString &error);
|
||||||
|
bool saveStreams(const OstProto::StreamConfigList streams,
|
||||||
|
const QString fileName, QString &error);
|
||||||
|
|
||||||
|
private:
|
||||||
|
static const int kFileMagicSize = 12;
|
||||||
|
static const int kFileChecksumSize = 5;
|
||||||
|
static const int kFileMinSize = kFileMagicSize + kFileChecksumSize;
|
||||||
|
|
||||||
|
static const int kFileMagicOffset = 0;
|
||||||
|
static const int kFileMetaDataOffset = kFileMagicSize;
|
||||||
|
|
||||||
|
static const std::string kFileMagicValue;
|
||||||
|
|
||||||
|
// Native file format version
|
||||||
|
static const uint kFileFormatVersionMajor = 0;
|
||||||
|
static const uint kFileFormatVersionMinor = 1;
|
||||||
|
static const uint kFileFormatVersionRevision = 0;
|
||||||
|
|
||||||
|
void initFileMetaData(OstProto::FileMetaData &metaData);
|
||||||
|
};
|
||||||
|
|
||||||
|
extern FileFormat fileFormat;
|
||||||
|
|
||||||
|
#endif
|
98
common/fileformat.proto
Normal file
98
common/fileformat.proto
Normal file
@ -0,0 +1,98 @@
|
|||||||
|
/*
|
||||||
|
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/>
|
||||||
|
*/
|
||||||
|
|
||||||
|
import "protocol.proto";
|
||||||
|
|
||||||
|
package OstProto;
|
||||||
|
|
||||||
|
enum FileType {
|
||||||
|
kReservedFileType = 0;
|
||||||
|
kStreamsFileType = 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
message FileMetaData {
|
||||||
|
required FileType file_type = 1;
|
||||||
|
required uint32 format_version_major = 2;
|
||||||
|
required uint32 format_version_minor = 3;
|
||||||
|
required uint32 format_version_revision = 4;
|
||||||
|
required string generator_name = 5;
|
||||||
|
required string generator_version = 6;
|
||||||
|
required string generator_revision = 7;
|
||||||
|
}
|
||||||
|
|
||||||
|
message FileContentMatter {
|
||||||
|
optional StreamConfigList streams = 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
An Ostinato file is the binary encoding of the File message below
|
||||||
|
STRICTLY in increasing order of field number for the top level fields
|
||||||
|
|
||||||
|
We do not use field number '1' for magic value because its encoded key
|
||||||
|
is '0a' (LF or \n) which occurs commonly in text files. Checksum should
|
||||||
|
be the last field, so top level field numbers greater than 15 are not
|
||||||
|
permitted. We use 15 as the checksum field number because it is the
|
||||||
|
largest field number that can fit in a 1-byte tag
|
||||||
|
|
||||||
|
The magic value is of a fixed length so that meta data has a fixed offset
|
||||||
|
from the start in the encoded message.
|
||||||
|
|
||||||
|
Checksum is fixed length so that it is at a fixed negative offset from
|
||||||
|
the end in the encoded message.
|
||||||
|
|
||||||
|
Because the protobuf serialization API does not _guarantee_
|
||||||
|
strict ordering, so we define wrapper messages for each top level field
|
||||||
|
and serialize the individual wrapper messages. The field numbers MUST
|
||||||
|
be the same in 'File' and the wrapper messages
|
||||||
|
*/
|
||||||
|
message File {
|
||||||
|
// FieldNumber 1 is reserved and MUST not be used!
|
||||||
|
required bytes magic_value = 2;
|
||||||
|
required FileMetaData meta_data = 3;
|
||||||
|
optional FileContent content_matter = 9;
|
||||||
|
required fixed32 checksum_value = 15;
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
The magic value is 10 bytes - "\xa7\xb7OSTINATO"
|
||||||
|
The 1st-2nd byte has the MSB set to avoid mixup with text files
|
||||||
|
The 3rd-10th byte spell OSTINATO (duh!)
|
||||||
|
|
||||||
|
Encoded Size : Key(1) + Length(1) + Value(10) = 12 bytes
|
||||||
|
Encoded Value: 120aa7b7 4f535449 4e41544f
|
||||||
|
*/
|
||||||
|
message FileMagic {
|
||||||
|
required bytes value = 2;
|
||||||
|
}
|
||||||
|
|
||||||
|
message FileMeta {
|
||||||
|
required FileMetaData data = 3;
|
||||||
|
}
|
||||||
|
|
||||||
|
message FileContent {
|
||||||
|
optional FileContentMatter matter = 9;
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
Encoded Size : Key(1) + Value(4) = 5 bytes
|
||||||
|
Encoded Value: 7d xxXXxxXX
|
||||||
|
*/
|
||||||
|
message FileChecksum {
|
||||||
|
required fixed32 value = 15; // should always be a fixed 32-bit size
|
||||||
|
}
|
@ -40,5 +40,5 @@ message Icmp {
|
|||||||
}
|
}
|
||||||
|
|
||||||
extend Protocol {
|
extend Protocol {
|
||||||
optional Icmp icmp = 142;
|
optional Icmp icmp = 402;
|
||||||
}
|
}
|
||||||
|
@ -61,5 +61,5 @@ message Ip4 {
|
|||||||
}
|
}
|
||||||
|
|
||||||
extend Protocol {
|
extend Protocol {
|
||||||
optional Ip4 ip4 = 131;
|
optional Ip4 ip4 = 301;
|
||||||
}
|
}
|
||||||
|
@ -33,5 +33,5 @@ extend Ip4over4 {
|
|||||||
}
|
}
|
||||||
|
|
||||||
extend Protocol {
|
extend Protocol {
|
||||||
optional Ip4over4 ip4over4 = 135;
|
optional Ip4over4 ip4over4 = 305;
|
||||||
}
|
}
|
||||||
|
@ -27,5 +27,5 @@ message Ip4over6 {
|
|||||||
}
|
}
|
||||||
|
|
||||||
extend Protocol {
|
extend Protocol {
|
||||||
optional Ip4over6 ip4over6 = 134;
|
optional Ip4over6 ip4over6 = 304;
|
||||||
}
|
}
|
||||||
|
@ -57,5 +57,5 @@ message Ip6 {
|
|||||||
}
|
}
|
||||||
|
|
||||||
extend Protocol {
|
extend Protocol {
|
||||||
optional Ip6 ip6 = 132;
|
optional Ip6 ip6 = 302;
|
||||||
}
|
}
|
||||||
|
@ -27,5 +27,5 @@ message Ip6over4 {
|
|||||||
}
|
}
|
||||||
|
|
||||||
extend Protocol {
|
extend Protocol {
|
||||||
optional Ip6over4 ip6over4 = 133;
|
optional Ip6over4 ip6over4 = 303;
|
||||||
}
|
}
|
||||||
|
@ -33,5 +33,5 @@ extend Ip6over6 {
|
|||||||
}
|
}
|
||||||
|
|
||||||
extend Protocol {
|
extend Protocol {
|
||||||
optional Ip6over6 ip6over6 = 136;
|
optional Ip6over6 ip6over6 = 306;
|
||||||
}
|
}
|
||||||
|
@ -28,5 +28,5 @@ message Llc {
|
|||||||
}
|
}
|
||||||
|
|
||||||
extend Protocol {
|
extend Protocol {
|
||||||
optional Llc llc = 123;
|
optional Llc llc = 202;
|
||||||
}
|
}
|
||||||
|
@ -44,5 +44,5 @@ message Mac {
|
|||||||
}
|
}
|
||||||
|
|
||||||
extend Protocol {
|
extend Protocol {
|
||||||
optional Mac mac = 51;
|
optional Mac mac = 100;
|
||||||
}
|
}
|
||||||
|
@ -22,6 +22,7 @@ FORMS += \
|
|||||||
sample.ui
|
sample.ui
|
||||||
PROTOS += \
|
PROTOS += \
|
||||||
protocol.proto \
|
protocol.proto \
|
||||||
|
fileformat.proto \
|
||||||
mac.proto \
|
mac.proto \
|
||||||
payload.proto \
|
payload.proto \
|
||||||
eth2.proto \
|
eth2.proto \
|
||||||
@ -49,6 +50,7 @@ PROTOS += \
|
|||||||
HEADERS += \
|
HEADERS += \
|
||||||
abstractprotocol.h \
|
abstractprotocol.h \
|
||||||
comboprotocol.h \
|
comboprotocol.h \
|
||||||
|
fileformat.h \
|
||||||
protocolmanager.h \
|
protocolmanager.h \
|
||||||
protocollist.h \
|
protocollist.h \
|
||||||
protocollistiterator.h \
|
protocollistiterator.h \
|
||||||
@ -79,6 +81,8 @@ HEADERS += \
|
|||||||
sample.h
|
sample.h
|
||||||
SOURCES += \
|
SOURCES += \
|
||||||
abstractprotocol.cpp \
|
abstractprotocol.cpp \
|
||||||
|
crc32c.cpp \
|
||||||
|
fileformat.cpp \
|
||||||
protocolmanager.cpp \
|
protocolmanager.cpp \
|
||||||
protocollist.cpp \
|
protocollist.cpp \
|
||||||
protocollistiterator.cpp \
|
protocollistiterator.cpp \
|
||||||
@ -101,19 +105,6 @@ SOURCES += \
|
|||||||
userscript.cpp \
|
userscript.cpp \
|
||||||
sample.cpp
|
sample.cpp
|
||||||
|
|
||||||
protobuf_decl.name = protobuf header
|
|
||||||
protobuf_decl.input = PROTOS
|
|
||||||
protobuf_decl.output = ${QMAKE_FILE_BASE}.pb.h
|
|
||||||
protobuf_decl.commands = protoc --cpp_out="." ${QMAKE_FILE_NAME}
|
|
||||||
protobuf_decl.variable_out = GENERATED_FILES
|
|
||||||
QMAKE_EXTRA_COMPILERS += protobuf_decl
|
|
||||||
|
|
||||||
protobuf_impl.name = protobuf implementation
|
|
||||||
protobuf_impl.input = PROTOS
|
|
||||||
protobuf_impl.output = ${QMAKE_FILE_BASE}.pb.cc
|
|
||||||
protobuf_impl.depends = ${QMAKE_FILE_BASE}.pb.h
|
|
||||||
protobuf_impl.commands = $$escape_expand(\n)
|
|
||||||
protobuf_impl.variable_out = GENERATED_SOURCES
|
|
||||||
QMAKE_EXTRA_COMPILERS += protobuf_impl
|
|
||||||
|
|
||||||
QMAKE_DISTCLEAN += object_script.*
|
QMAKE_DISTCLEAN += object_script.*
|
||||||
|
|
||||||
|
include(../protobuf.pri)
|
||||||
|
@ -37,5 +37,5 @@ message Payload {
|
|||||||
}
|
}
|
||||||
|
|
||||||
extend Protocol {
|
extend Protocol {
|
||||||
optional Payload payload = 52;
|
optional Payload payload = 101;
|
||||||
}
|
}
|
||||||
|
@ -78,41 +78,41 @@ message Protocol {
|
|||||||
|
|
||||||
required ProtocolId protocol_id = 1;
|
required ProtocolId protocol_id = 1;
|
||||||
|
|
||||||
extensions 51 to 100; // Reserved for Ostinato Use
|
extensions 100 to 199; // Reserved for Ostinato Use
|
||||||
extensions 101 to 200; // Available for use by protocols
|
extensions 200 to 500; // Available for use by protocols
|
||||||
|
|
||||||
enum k {
|
enum k {
|
||||||
kMacFieldNumber = 51;
|
kMacFieldNumber = 100;
|
||||||
kPayloadFieldNumber = 52;
|
kPayloadFieldNumber = 101;
|
||||||
kSampleFieldNumber = 53;
|
kSampleFieldNumber = 102;
|
||||||
kUserScriptFieldNumber = 54;
|
kUserScriptFieldNumber = 103;
|
||||||
|
|
||||||
kEth2FieldNumber = 121;
|
kEth2FieldNumber = 200;
|
||||||
kDot3FieldNumber = 122;
|
kDot3FieldNumber = 201;
|
||||||
kLlcFieldNumber = 123;
|
kLlcFieldNumber = 202;
|
||||||
kSnapFieldNumber = 124;
|
kSnapFieldNumber = 203;
|
||||||
|
|
||||||
kSvlanFieldNumber = 125;
|
kSvlanFieldNumber = 204;
|
||||||
kVlanFieldNumber = 126;
|
kVlanFieldNumber = 205;
|
||||||
|
|
||||||
kDot2LlcFieldNumber = 127;
|
kDot2LlcFieldNumber = 206;
|
||||||
kDot2SnapFieldNumber = 128;
|
kDot2SnapFieldNumber = 207;
|
||||||
kVlanStackFieldNumber = 129;
|
kVlanStackFieldNumber = 208;
|
||||||
|
|
||||||
kArpFieldNumber = 130;
|
kArpFieldNumber = 300;
|
||||||
kIp4FieldNumber = 131;
|
kIp4FieldNumber = 301;
|
||||||
kIp6FieldNumber = 132;
|
kIp6FieldNumber = 302;
|
||||||
kIp6over4FieldNumber = 133;
|
kIp6over4FieldNumber = 303;
|
||||||
kIp4over6FieldNumber = 134;
|
kIp4over6FieldNumber = 304;
|
||||||
kIp4over4FieldNumber = 135;
|
kIp4over4FieldNumber = 305;
|
||||||
kIp6over6FieldNumber = 136;
|
kIp6over6FieldNumber = 306;
|
||||||
|
|
||||||
kTcpFieldNumber = 140;
|
kTcpFieldNumber = 400;
|
||||||
kUdpFieldNumber = 141;
|
kUdpFieldNumber = 401;
|
||||||
kIcmpFieldNumber = 142;
|
kIcmpFieldNumber = 402;
|
||||||
kIgmpFieldNumber = 143;
|
kIgmpFieldNumber = 403;
|
||||||
|
|
||||||
kTextProtocolFieldNumber = 150;
|
kTextProtocolFieldNumber = 500;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -34,5 +34,5 @@ message Sample {
|
|||||||
}
|
}
|
||||||
|
|
||||||
extend Protocol {
|
extend Protocol {
|
||||||
optional Sample sample = 53;
|
optional Sample sample = 102;
|
||||||
}
|
}
|
||||||
|
@ -27,5 +27,5 @@ message Snap {
|
|||||||
}
|
}
|
||||||
|
|
||||||
extend Protocol {
|
extend Protocol {
|
||||||
optional Snap snap = 124;
|
optional Snap snap = 203;
|
||||||
}
|
}
|
||||||
|
@ -23,5 +23,5 @@ import "vlan.proto";
|
|||||||
package OstProto;
|
package OstProto;
|
||||||
|
|
||||||
extend Protocol {
|
extend Protocol {
|
||||||
optional Vlan svlan = 125;
|
optional Vlan svlan = 204;
|
||||||
}
|
}
|
||||||
|
@ -42,6 +42,6 @@ message Tcp {
|
|||||||
}
|
}
|
||||||
|
|
||||||
extend Protocol {
|
extend Protocol {
|
||||||
optional Tcp tcp = 140;
|
optional Tcp tcp = 400;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -33,5 +33,5 @@ message TextProtocol {
|
|||||||
}
|
}
|
||||||
|
|
||||||
extend Protocol {
|
extend Protocol {
|
||||||
optional TextProtocol textProtocol = 150;
|
optional TextProtocol textProtocol = 500;
|
||||||
}
|
}
|
||||||
|
@ -35,5 +35,5 @@ message Udp {
|
|||||||
}
|
}
|
||||||
|
|
||||||
extend Protocol {
|
extend Protocol {
|
||||||
optional Udp udp = 141;
|
optional Udp udp = 401;
|
||||||
}
|
}
|
||||||
|
@ -29,5 +29,5 @@ message UserScript {
|
|||||||
}
|
}
|
||||||
|
|
||||||
extend Protocol {
|
extend Protocol {
|
||||||
optional UserScript userScript = 54;
|
optional UserScript userScript = 103;
|
||||||
}
|
}
|
||||||
|
@ -30,5 +30,5 @@ message Vlan {
|
|||||||
}
|
}
|
||||||
|
|
||||||
extend Protocol {
|
extend Protocol {
|
||||||
optional Vlan vlan = 126;
|
optional Vlan vlan = 205;
|
||||||
}
|
}
|
||||||
|
@ -27,5 +27,5 @@ message VlanStack {
|
|||||||
}
|
}
|
||||||
|
|
||||||
extend Protocol {
|
extend Protocol {
|
||||||
optional VlanStack vlanStack = 129;
|
optional VlanStack vlanStack = 208;
|
||||||
}
|
}
|
||||||
|
33
protobuf.pri
Normal file
33
protobuf.pri
Normal file
@ -0,0 +1,33 @@
|
|||||||
|
#
|
||||||
|
# Qt qmake integration with Google Protocol Buffers compiler protoc
|
||||||
|
#
|
||||||
|
# To compile protocol buffers with qt qmake, specify PROTOS variable and
|
||||||
|
# include this file
|
||||||
|
#
|
||||||
|
# Example:
|
||||||
|
# PROTOS = a.proto b.proto
|
||||||
|
# include(protobuf.pri)
|
||||||
|
#
|
||||||
|
# By default protoc looks for .proto files (including the imported ones) in
|
||||||
|
# the current directory where protoc is run. If you need to include additional
|
||||||
|
# paths specify the PROTOPATH variable
|
||||||
|
#
|
||||||
|
|
||||||
|
PROTOPATH += .
|
||||||
|
PROTOPATHS =
|
||||||
|
for(p, PROTOPATH):PROTOPATHS += --proto_path=$${p}
|
||||||
|
|
||||||
|
protobuf_decl.name = protobuf header
|
||||||
|
protobuf_decl.input = PROTOS
|
||||||
|
protobuf_decl.output = ${QMAKE_FILE_BASE}.pb.h
|
||||||
|
protobuf_decl.commands = protoc --cpp_out="." $${PROTOPATHS} ${QMAKE_FILE_NAME}
|
||||||
|
protobuf_decl.variable_out = GENERATED_FILES
|
||||||
|
QMAKE_EXTRA_COMPILERS += protobuf_decl
|
||||||
|
|
||||||
|
protobuf_impl.name = protobuf implementation
|
||||||
|
protobuf_impl.input = PROTOS
|
||||||
|
protobuf_impl.output = ${QMAKE_FILE_BASE}.pb.cc
|
||||||
|
protobuf_impl.depends = ${QMAKE_FILE_BASE}.pb.h
|
||||||
|
protobuf_impl.commands = $$escape_expand(\n)
|
||||||
|
protobuf_impl.variable_out = GENERATED_SOURCES
|
||||||
|
QMAKE_EXTRA_COMPILERS += protobuf_impl
|
Loading…
Reference in New Issue
Block a user