22 #include "ns3/simulator.h"
24 #include "ns3/double.h"
28 #define INDENT(level) for (int __xpto = 0; __xpto < level; __xpto++) os << ' ';
30 #define PERIODIC_CHECK_INTERVAL (Seconds (1))
44 .AddConstructor<FlowMonitor> ()
45 .AddAttribute (
"MaxPerHopDelay", (
"The maximum per-hop delay that should be considered. "
46 "Packets still not received after this delay are to be considered lost."),
50 .AddAttribute (
"StartTime", (
"The time when the monitoring starts."),
54 .AddAttribute (
"DelayBinWidth", (
"The width used in the delay histogram."),
57 MakeDoubleChecker <double> ())
58 .AddAttribute (
"JitterBinWidth", (
"The width used in the jitter histogram."),
61 MakeDoubleChecker <double> ())
62 .AddAttribute (
"PacketSizeBinWidth", (
"The width used in the packetSize histogram."),
65 MakeDoubleChecker <double> ())
66 .AddAttribute (
"FlowInterruptionsBinWidth", (
"The width used in the flowInterruptions histogram."),
69 MakeDoubleChecker <double> ())
70 .AddAttribute (
"FlowInterruptionsMinTime", (
"The minimum inter-arrival time that is considered a flow interruption."),
105 std::map<FlowId, FlowStats>::iterator iter;
144 NS_LOG_DEBUG (
"ReportFirstTx: adding tracked packet (flowId=" << flowId <<
", packetId=" << packetId
167 std::pair<FlowId, FlowPacketId> key (flowId, packetId);
171 NS_LOG_WARN (
"Received packet forward report (flowId=" << flowId <<
", packetId=" << packetId
172 <<
") but not known to be transmitted.");
176 tracked->second.timesForwarded++;
191 TrackedPacketMap::iterator tracked =
m_trackedPackets.find (std::make_pair (flowId, packetId));
194 NS_LOG_WARN (
"Received packet last-tx report (flowId=" << flowId <<
", packetId=" << packetId
195 <<
") but not known to be transmitted.");
200 Time delay = (now - tracked->second.firstSeenTime);
241 NS_LOG_DEBUG (
"ReportLastTx: removing tracked packet (flowId="
242 << flowId <<
", packetId=" << packetId <<
").");
269 TrackedPacketMap::iterator tracked =
m_trackedPackets.find (std::make_pair (flowId, packetId));
274 NS_LOG_DEBUG (
"ReportDrop: removing tracked packet (flowId="
275 << flowId <<
", packetId=" << packetId <<
").");
280 std::map<FlowId, FlowMonitor::FlowStats>
295 if (now - iter->second.lastSeenTime >= maxDelay)
298 std::map<FlowId, FlowStats>::iterator
301 flow->second.lostPackets++;
339 std::vector< Ptr<FlowProbe> >
402 INDENT (indent); os <<
"<FlowMonitor>\n";
404 INDENT (indent); os <<
"<FlowStats>\n";
406 for (std::map<FlowId, FlowStats>::const_iterator flowI =
m_flowStats.begin ();
411 #define ATTRIB(name) << " " # name "=\"" << flowI->second.name << "\""
412 os <<
"<Flow flowId=\"" << flowI->first <<
"\""
413 ATTRIB (timeFirstTxPacket)
414 ATTRIB (timeFirstRxPacket)
431 for (uint32_t reasonCode = 0; reasonCode < flowI->second.packetsDropped.size (); reasonCode++)
434 os <<
"<packetsDropped reasonCode=\"" << reasonCode <<
"\""
435 <<
" number=\"" << flowI->second.packetsDropped[reasonCode]
438 for (uint32_t reasonCode = 0; reasonCode < flowI->second.bytesDropped.size (); reasonCode++)
441 os <<
"<bytesDropped reasonCode=\"" << reasonCode <<
"\""
442 <<
" bytes=\"" << flowI->second.bytesDropped[reasonCode]
445 if (enableHistograms)
447 flowI->second.delayHistogram.SerializeToXmlStream (os, indent,
"delayHistogram");
448 flowI->second.jitterHistogram.SerializeToXmlStream (os, indent,
"jitterHistogram");
449 flowI->second.packetSizeHistogram.SerializeToXmlStream (os, indent,
"packetSizeHistogram");
450 flowI->second.flowInterruptionsHistogram.SerializeToXmlStream (os, indent,
"flowInterruptionsHistogram");
454 INDENT (indent); os <<
"</Flow>\n";
457 INDENT (indent); os <<
"</FlowStats>\n";
463 INDENT (indent); os <<
"<FlowProbes>\n";
470 INDENT (indent); os <<
"</FlowProbes>\n";
474 INDENT (indent); os <<
"</FlowMonitor>\n";
481 std::ostringstream os;
490 std::ofstream os (fileName.c_str (), std::ios::out|std::ios::binary);
491 os <<
"<?xml version=\"1.0\" ?>\n";