From 984d65b27d9b3d703152390f1dd042ad7a7f78a7 Mon Sep 17 00:00:00 2001 From: "Srivats P." Date: Sun, 3 Jan 2010 13:57:47 +0000 Subject: [PATCH] - 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!) --- client/port.h | 2 ++ client/portstatsmodel.cpp | 23 ++++++++------------ common/protocol.proto | 36 +++++++++++++++----------------- server/pcapport.cpp | 44 ++++++++++++++++++++++++++++++++++++++- server/pcapport.h | 2 ++ 5 files changed, 73 insertions(+), 34 deletions(-) diff --git a/client/port.h b/client/port.h index 53842a5..06162a0 100644 --- a/client/port.h +++ b/client/port.h @@ -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() diff --git a/client/portstatsmodel.cpp b/client/portstatsmodel.cpp index 1958d8d..72b3d16 100644 --- a/client/portstatsmodel.cpp +++ b/client/portstatsmodel.cpp @@ -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("Limitation(s)" - "

Frames/Bytes Receieved: Includes non Ostinato Tx pkts also (Tx by Ostinato are not included)
" - "Frames/Bytes Sent: Only Ostinato Tx pkts (Tx by others NOT included)

" - "

Rx/Tx Rates are derived from the above and hence subject to same limitations

" - ); + 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); diff --git a/common/protocol.proto b/common/protocol.proto index 42caff1..86ceb59 100644 --- a/common/protocol.proto +++ b/common/protocol.proto @@ -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; } diff --git a/server/pcapport.cpp b/server/pcapport.cpp index 9d1e4fb..ced12ab 100644 --- a/server/pcapport.cpp +++ b/server/pcapport.cpp @@ -2,6 +2,10 @@ #include +#ifdef Q_OS_WIN32 +#include +#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("Rx Frames/Bytes: Includes non Ostinato Tx pkts also (Tx by Ostinato are not included)
"); + if (!monitorTx_->isDirectional()) + { transmitter_->useExternalStats(&stats_); + notes.append("Tx Frames/Bytes: Only Ostinato Tx pkts (Tx by others NOT included)
"); + } transmitter_->setHandle(monitorRx_->handle()); + if (!notes.isEmpty()) + data_.set_notes(QString("Limitation(s)" + "

%1
" + "Rx/Tx Rates are also subject to above limitation(s)

"). + 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); diff --git a/server/pcapport.h b/server/pcapport.h index 9f80e57..28e9499 100644 --- a/server/pcapport.h +++ b/server/pcapport.h @@ -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 sendQueueList_; int returnToQIdx_; bool usingInternalStats_;