- PortTransmitter on Windows now uses the Win32 QueryPerformanceCounter() instead of QThread::usleep() for more accurate timing

- Port Stats limitations are now sent from the server to the client (as it should have always been!)
This commit is contained in:
Srivats P. 2010-01-03 13:57:47 +00:00
parent aac2229403
commit 984d65b27d
5 changed files with 73 additions and 34 deletions

View File

@ -45,6 +45,8 @@ public:
{ return QString().fromStdString(d.name()); }
const QString description() const
{ return QString().fromStdString(d.description()); }
const QString notes() const
{ return QString().fromStdString(d.notes()); }
AdminStatus adminStatus()
{ return (d.is_enabled()?AdminEnable:AdminDisable); }
ControlMode controlMode()

View File

@ -165,24 +165,23 @@ QVariant PortStatsModel::data(const QModelIndex &index, int role) const
QVariant PortStatsModel::headerData(int section, Qt::Orientation orientation, int role) const
{
#ifdef Q_OS_WIN32
// TODO(MED): The limitations should be the server's not the client's!
// Ideally we shd enhance the protocol to convey limitation(s), if any,
// from server to client
if (role == Qt::ToolTipRole)
{
if (orientation == Qt::Horizontal)
{
return QString("<b>Limitation(s)</b>"
"<p><i>Frames/Bytes Receieved</i>: Includes non Ostinato Tx pkts also (Tx by Ostinato are not included)<br>"
"<i>Frames/Bytes Sent</i>: Only Ostinato Tx pkts (Tx by others NOT included)</p>"
"<p>Rx/Tx Rates are derived from the above and hence subject to same limitations</p>"
);
QString notes;
uint portGroupIdx, portIdx;
getDomainIndexes(index(0, section), portGroupIdx, portIdx);
notes = pgl->mPortGroups.at(portGroupIdx)->mPorts[portIdx]->notes();
if (!notes.isEmpty())
return notes;
else
return QVariant();
}
else
return QVariant();
}
#endif
if (role != Qt::DisplayRole)
return QVariant();
@ -192,11 +191,7 @@ QVariant PortStatsModel::headerData(int section, Qt::Orientation orientation, in
uint portGroupIdx, portIdx;
getDomainIndexes(index(0, section), portGroupIdx, portIdx);
#ifdef Q_OS_WIN32
return QString("Port %1-%2 (*)").arg(portGroupIdx).arg(portIdx);
#else
return QString("Port %1-%2").arg(portGroupIdx).arg(portIdx);
#endif
}
else
return PortStatName.at(section);

View File

@ -15,18 +15,15 @@ message StreamCore {
}
// Basics
optional string name = 1;
optional bool is_enabled = 2;
optional uint32 ordinal = 3;
optional string name = 1;
optional bool is_enabled = 2;
optional uint32 ordinal = 3;
// Frame Length (includes CRC)
optional FrameLengthMode len_mode = 14 [default = e_fl_fixed];
optional uint32 frame_len = 15 [default = 64];
optional uint32 frame_len_min = 16 [default = 64];
optional uint32 frame_len_max = 17 [default = 1518];
// Currently Selected Protocols
//repeated uint32 frame_proto = 20;
optional FrameLengthMode len_mode = 14 [default = e_fl_fixed];
optional uint32 frame_len = 15 [default = 64];
optional uint32 frame_len_min = 16 [default = 64];
optional uint32 frame_len_max = 17 [default = 1518];
}
message StreamControl {
@ -46,14 +43,14 @@ message StreamControl {
e_nw_goto_id = 2;
}
optional SendUnit unit = 1 [default = e_su_packets];
optional SendMode mode = 2 [default = e_sm_fixed];
optional uint32 num_packets = 3 [default = 1];
optional uint32 num_bursts = 4 [default = 1];
optional uint32 packets_per_burst = 5 [default = 10];
optional NextWhat next = 6 [default = e_nw_goto_next];
optional uint32 packets_per_sec = 7 [default = 1];
optional uint32 bursts_per_sec = 8 [default = 1];
optional SendUnit unit = 1 [default = e_su_packets];
optional SendMode mode = 2 [default = e_sm_fixed];
optional uint32 num_packets = 3 [default = 1];
optional uint32 num_bursts = 4 [default = 1];
optional uint32 packets_per_burst = 5 [default = 10];
optional NextWhat next = 6 [default = e_nw_goto_next];
optional uint32 packets_per_sec = 7 [default = 1];
optional uint32 bursts_per_sec = 8 [default = 1];
}
message ProtocolId {
@ -129,7 +126,8 @@ message Port {
required PortId port_id = 1;
optional string name = 2;
optional string description = 3;
optional bool is_enabled = 4;
optional string notes = 4;
optional bool is_enabled = 5;
optional bool is_exclusive_control = 6;
}

View File

@ -2,6 +2,10 @@
#include <QtGlobal>
#ifdef Q_OS_WIN32
#include <windows.h>
#endif
pcap_if_t *PcapPort::deviceList_ = NULL;
PcapPort::PcapPort(int id, const char *device)
@ -40,11 +44,25 @@ PcapPort::PcapPort(int id, const char *device)
void PcapPort::init()
{
QString notes;
if (!monitorRx_->isDirectional() && !data_.is_exclusive_control())
notes.append("<i>Rx Frames/Bytes</i>: Includes non Ostinato Tx pkts also (Tx by Ostinato are not included)<br>");
if (!monitorTx_->isDirectional())
{
transmitter_->useExternalStats(&stats_);
notes.append("<i>Tx Frames/Bytes</i>: Only Ostinato Tx pkts (Tx by others NOT included)<br>");
}
transmitter_->setHandle(monitorRx_->handle());
if (!notes.isEmpty())
data_.set_notes(QString("<b>Limitation(s)</b>"
"<p>%1<br>"
"Rx/Tx Rates are also subject to above limitation(s)</p>").
arg(notes).toStdString());
monitorRx_->start();
monitorTx_->start();
}
@ -150,6 +168,14 @@ PcapPort::PortTransmitter::PortTransmitter(const char *device)
{
char errbuf[PCAP_ERRBUF_SIZE];
#ifdef Q_OS_WIN32
LARGE_INTEGER freq;
if (QueryPerformanceFrequency(&freq))
ticksFreq_ = freq.QuadPart;
else
Q_ASSERT_X(false, "PortTransmitter::PortTransmitter",
"This Win32 platform does not support performance counter");
#endif
returnToQIdx_ = -1;
stop_ = false;
stats_ = new AbstractPort::PortStats;
@ -316,13 +342,29 @@ int PcapPort::PortTransmitter::sendQueueTransmit(pcap_t *p,
if (usec)
{
QThread::usleep(usec);
udelay(usec);
ts = hdr->ts;
}
}
}
}
void PcapPort::PortTransmitter::udelay(long usec)
{
#ifdef Q_OS_WIN32
LARGE_INTEGER tgtTicks;
LARGE_INTEGER curTicks;
QueryPerformanceCounter(&curTicks);
tgtTicks.QuadPart = curTicks.QuadPart + (usec*ticksFreq_)/1000000;
while (curTicks.QuadPart < tgtTicks.QuadPart)
QueryPerformanceCounter(&curTicks);
#else
QThread::usleep(usec);
#endif
}
PcapPort::PortCapturer::PortCapturer(const char *device)
{
device_ = QString::fromAscii(device);

View File

@ -80,8 +80,10 @@ protected:
void run();
void stop();
private:
void udelay(long usec);
int sendQueueTransmit(pcap_t *p, pcap_send_queue *queue, int sync);
quint64 ticksFreq_;
QList<pcap_send_queue*> sendQueueList_;
int returnToQIdx_;
bool usingInternalStats_;