Enhancements

- (Abs/Pcap/WinPcap)Port: Inter SendQueue Timing implemented using a dummy packet length of zero (this is not supported by the winpcap pcap_sendqueue_transmit() but since we don't use that API we are not affected)
- (Abs/Pcap/WinPcap)Port: Loop Mode Timing across loop iterations implemented
- Added the year 2010 to Copyright notice in the About dialog

Fixes
- (Win)PcapPort: Fixed the wrong rates when packets sent in 'burst' mode
This commit is contained in:
Srivats P. 2010-01-10 06:21:39 +00:00
parent c97ae3bc55
commit 78a2de040b
5 changed files with 41 additions and 38 deletions

View File

@ -51,7 +51,7 @@ p, li { white-space: pre-wrap; }
<item>
<widget class="QLabel" name="label_3" >
<property name="text" >
<string>Copyright (c) 2007-2009 Srivats P.</string>
<string>Copyright (c) 2007-2010 Srivats P.</string>
</property>
<property name="alignment" >
<set>Qt::AlignCenter</set>

View File

@ -73,22 +73,18 @@ void AbstractPort::updatePacketList()
int len;
bool isVariable;
uchar pktBuf[2000];
long sec;
long usec;
long sec = 0;
long usec = 0;
qDebug("In %s", __FUNCTION__);
clearPacketList();
//returnToQIdx = -1;
// First sort the streams by ordinalValue
qSort(streamList_);
sec = 0;
usec = 0;
clearPacketList();
for (int i = 0; i < streamList_.size(); i++)
{
//_restart:
if (streamList_[i]->isEnabled())
{
long numPackets, numBursts;
@ -139,18 +135,17 @@ void AbstractPort::updatePacketList()
if (len <= 0)
continue;
qDebug("q(%d, %d, %d) sec = %lu usec = %lu",
i, j, k, sec, usec);
appendToPacketList(sec, usec, pktBuf, len);
usec += ipg;
if (usec > 1000000)
{
sec++;
usec -= 1000000;
}
qDebug("q(%d, %d, %d) sec = %lu usec = %lu",
i, j, k, sec, usec);
appendToPacketList(sec, usec, pktBuf, len);
} // for (numPackets)
usec += ibg;
@ -179,7 +174,8 @@ void AbstractPort::updatePacketList()
returnToQIdx = 0;
*/
setPacketListLoopMode(true);
setPacketListLoopMode(true, streamList_[i]->sendUnit() ==
OstProto::StreamControl::e_su_bursts ? ibg : ipg);
goto _stop_no_more_pkts;
case ::OstProto::StreamControl::e_nw_goto_next:

View File

@ -46,7 +46,7 @@ public:
virtual void clearPacketList() = 0;
virtual bool appendToPacketList(long sec, long usec, const uchar *packet,
int length) = 0;
virtual void setPacketListLoopMode(bool loop) = 0;
virtual void setPacketListLoopMode(bool loop, long usecDelay) = 0;
void updatePacketList();
virtual void startTransmit() = 0;

View File

@ -177,6 +177,7 @@ PcapPort::PortTransmitter::PortTransmitter(const char *device)
"This Win32 platform does not support performance counter");
#endif
returnToQIdx_ = -1;
loopDelay_ = 0;
stop_ = false;
stats_ = new AbstractPort::PortStats;
usingInternalStats_ = true;
@ -210,6 +211,7 @@ void PcapPort::PortTransmitter::clearPacketList()
pcap_send_queue *sq = sendQueueList_.takeFirst();
pcap_sendqueue_destroy(sq);
}
setPacketListLoopMode(false, 0);
}
bool PcapPort::PortTransmitter::appendToPacketList(long sec, long usec,
@ -223,24 +225,22 @@ bool PcapPort::PortTransmitter::appendToPacketList(long sec, long usec,
pktHdr.ts.tv_sec = sec;
pktHdr.ts.tv_usec = usec;
if (sendQueueList_.size())
sendQ = sendQueueList_.last();
else
sendQ = pcap_sendqueue_alloc(1*1024*1024);
sendQ = sendQueueList_.isEmpty() ? NULL : sendQueueList_.last();
// Not enough space? Alloc another one!
if ((sendQ->len + length + sizeof(pcap_pkthdr)) > sendQ->maxlen)
if ((sendQ == NULL) ||
(sendQ->len + sizeof(pcap_pkthdr) + length) > sendQ->maxlen)
{
sendQueueList_.append(sendQ);
//! \todo (LOW): calculate sendqueue size
sendQ = pcap_sendqueue_alloc(1*1024*1024);
sendQueueList_.append(sendQ);
// Validate that the pkt will fit inside the new sendQ
Q_ASSERT((length + sizeof(pcap_pkthdr)) < sendQ->maxlen);
}
if (pcap_sendqueue_queue(sendQ, &pktHdr, (u_char*) packet) < 0)
op = false;
sendQueueList_.append(sendQ);
return op;
}
@ -279,6 +279,8 @@ void PcapPort::PortTransmitter::run()
const int kSyncTransmit = 1;
int i;
qDebug("sendQueueList_.size = %d", sendQueueList_.size());
for(i = 0; i < sendQueueList_.size(); i++)
{
int ret;
@ -286,17 +288,17 @@ _restart:
ret = sendQueueTransmit(handle_, sendQueueList_.at(i), kSyncTransmit);
if (ret < 0)
{
qDebug("error in sendQueueTransmit()");
return;
//! \todo (HIGH): Timing between subsequent sendQueues
}
}
if (returnToQIdx_ >= 0)
{
i = returnToQIdx_;
//! \todo (HIGH) 1s fixed; Change this to ipg of last stream
QThread::usleep(1000000);
udelay(loopDelay_);
goto _restart;
}
}
@ -327,11 +329,14 @@ int PcapPort::PortTransmitter::sendQueueTransmit(pcap_t *p,
return -2;
}
// A pktLen of size 0 is used at the end of a sendQueue and before
// the next sendQueue - i.e. for inter sendQueue timing
if(pktLen > 0)
{
pcap_sendpacket(p, pkt, pktLen);
stats_->txPkts++;
stats_->txBytes += pktLen;
}
// Step to the next packet in the buffer
hdr = (struct pcap_pkthdr*) ((uchar*)hdr + sizeof(*hdr) + pktLen);

View File

@ -18,14 +18,14 @@ public:
virtual void clearPacketList() {
transmitter_->clearPacketList();
setPacketListLoopMode(false);
setPacketListLoopMode(false, 0);
}
virtual bool appendToPacketList(long sec, long usec, const uchar *packet,
int length) {
return transmitter_->appendToPacketList(sec, usec, packet, length);
}
virtual void setPacketListLoopMode(bool loop) {
transmitter_->setPacketListLoopMode(loop);
virtual void setPacketListLoopMode(bool loop, long usecDelay) {
transmitter_->setPacketListLoopMode(loop, usecDelay);
}
virtual void startTransmit() {
@ -73,8 +73,9 @@ protected:
void clearPacketList();
bool appendToPacketList(long sec, long usec, const uchar *packet,
int length);
void setPacketListLoopMode(bool loop) {
void setPacketListLoopMode(bool loop, long usecDelay) {
returnToQIdx_ = loop ? 0 : -1;
loopDelay_ = usecDelay;
}
void setHandle(pcap_t *handle);
void useExternalStats(AbstractPort::PortStats *stats);
@ -87,6 +88,7 @@ protected:
quint64 ticksFreq_;
QList<pcap_send_queue*> sendQueueList_;
int returnToQIdx_;
long loopDelay_;
bool usingInternalStats_;
AbstractPort::PortStats *stats_;
bool usingInternalHandle_;