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."),
94 std::map<FlowId, FlowStats>::iterator iter;
133 NS_LOG_DEBUG (
"ReportFirstTx: adding tracked packet (flowId=" << flowId <<
", packetId=" << packetId
156 std::pair<FlowId, FlowPacketId> key (flowId, packetId);
160 NS_LOG_WARN (
"Received packet forward report (flowId=" << flowId <<
", packetId=" << packetId
161 <<
") but not known to be transmitted.");
165 tracked->second.timesForwarded++;
180 TrackedPacketMap::iterator tracked =
m_trackedPackets.find (std::make_pair (flowId, packetId));
183 NS_LOG_WARN (
"Received packet last-tx report (flowId=" << flowId <<
", packetId=" << packetId
184 <<
") but not known to be transmitted.");
189 Time delay = (now - tracked->second.firstSeenTime);
230 NS_LOG_DEBUG (
"ReportLastTx: removing tracked packet (flowId="
231 << flowId <<
", packetId=" << packetId <<
").");
258 TrackedPacketMap::iterator tracked =
m_trackedPackets.find (std::make_pair (flowId, packetId));
263 NS_LOG_DEBUG (
"ReportDrop: removing tracked packet (flowId="
264 << flowId <<
", packetId=" << packetId <<
").");
269 std::map<FlowId, FlowMonitor::FlowStats>
284 if (now - iter->second.lastSeenTime >= maxDelay)
287 std::map<FlowId, FlowStats>::iterator
290 flow->second.lostPackets++;
328 std::vector< Ptr<FlowProbe> >
391 INDENT (indent); os <<
"<FlowMonitor>\n";
393 INDENT (indent); os <<
"<FlowStats>\n";
395 for (std::map<FlowId, FlowStats>::const_iterator flowI =
m_flowStats.begin ();
400 #define ATTRIB(name) << " " # name "=\"" << flowI->second.name << "\""
401 os <<
"<Flow flowId=\"" << flowI->first <<
"\""
402 ATTRIB (timeFirstTxPacket)
403 ATTRIB (timeFirstRxPacket)
420 for (uint32_t reasonCode = 0; reasonCode < flowI->second.packetsDropped.size (); reasonCode++)
423 os <<
"<packetsDropped reasonCode=\"" << reasonCode <<
"\""
424 <<
" number=\"" << flowI->second.packetsDropped[reasonCode]
427 for (uint32_t reasonCode = 0; reasonCode < flowI->second.bytesDropped.size (); reasonCode++)
430 os <<
"<bytesDropped reasonCode=\"" << reasonCode <<
"\""
431 <<
" bytes=\"" << flowI->second.bytesDropped[reasonCode]
434 if (enableHistograms)
436 flowI->second.delayHistogram.SerializeToXmlStream (os, indent,
"delayHistogram");
437 flowI->second.jitterHistogram.SerializeToXmlStream (os, indent,
"jitterHistogram");
438 flowI->second.packetSizeHistogram.SerializeToXmlStream (os, indent,
"packetSizeHistogram");
439 flowI->second.flowInterruptionsHistogram.SerializeToXmlStream (os, indent,
"flowInterruptionsHistogram");
443 INDENT (indent); os <<
"</Flow>\n";
446 INDENT (indent); os <<
"</FlowStats>\n";
452 INDENT (indent); os <<
"<FlowProbes>\n";
459 INDENT (indent); os <<
"</FlowProbes>\n";
463 INDENT (indent); os <<
"</FlowMonitor>\n";
470 std::ostringstream os;
479 std::ofstream os (fileName.c_str (), std::ios::out|std::ios::binary);
480 os <<
"<?xml version=\"1.0\" ?>\n";