diff --git a/RELEASE_NOTES b/RELEASE_NOTES index b343bab69..c3212bf2f 100644 --- a/RELEASE_NOTES +++ b/RELEASE_NOTES @@ -31,6 +31,7 @@ Bugs fixed - bug 1318 - Asserts for IPv6 malformed packets - bug 1357 - IPv6 fragmentation fails due to checks about malformed extensions - bug 1378 - UdpEchoClient::SetFill () does not set packet size correctly + - bug 1351 and 1333 - TCP not able to take RTT samples on long delay network Known issues ------------ diff --git a/doc/manual/source/callbacks.rst b/doc/manual/source/callbacks.rst index 3a265761a..6164e86a4 100644 --- a/doc/manual/source/callbacks.rst +++ b/doc/manual/source/callbacks.rst @@ -239,7 +239,7 @@ Here is an example of the usage:: class A { public: - A (int ao) : a (a0) {} + A (int a0) : a (a0) {} int Hello (int b0) { std::cout << "Hello from A, a = " << a << " b0 = " << b0 << std::endl; diff --git a/doc/tutorial-pt-br/source/building-topologies.rst b/doc/tutorial-pt-br/source/building-topologies.rst index 8acbcd074..331a437b1 100644 --- a/doc/tutorial-pt-br/source/building-topologies.rst +++ b/doc/tutorial-pt-br/source/building-topologies.rst @@ -1127,12 +1127,13 @@ O c :: #include "ns3/core-module.h" +#include "ns3/point-to-point-module.h" #include "ns3/network-module.h" +#include "ns3/applications-module.h" +#include "ns3/wifi-module.h" +#include "ns3/mobility-module.h" #include "ns3/csma-module.h" #include "ns3/internet-module.h" -#include "ns3/point-to-point-module.h" -#include "ns3/applications-module.h" -#include "ns3/ipv4-global-routing-helper.h" .. The network topology illustration follows: @@ -1382,20 +1383,16 @@ J :: mac.SetType ("ns3::ApWifiMac", - "Ssid", SsidValue (ssid), - "BeaconGeneration", BooleanValue (true), - "BeaconInterval", TimeValue (Seconds (2.5))); + "Ssid", SsidValue (ssid))); .. In this case, the ``NqosWifiMacHelper`` is going to create MAC layers of the "ns3::ApWifiMac", the latter specifying that a MAC instance configured as an AP should be created, with the helper type implying that the "QosSupported" ``Attribute`` should be set to - false - disabling 802.11e/WMM-style QoS support at created APs. We - set the "BeaconGeneration" ``Attribute`` to true and also set an - interval between beacons of 2.5 seconds. + false - disabling 802.11e/WMM-style QoS support at created APs. -Neste caso, o ``NqosWifiMacHelper`` vai criar camadas MAC do "ns3::ApWifiMac", este último especificando que uma instância MAC configurado como um AP deve ser criado, com o tipo de assistente implicando que o atributo "QosSupported" deve ser definido como falso - desativando o suporte a Qos do tipo 802.11e/WMM nos APs criados. Definimos o atributo "BeaconGeneration" para verdadeiro e também definimos um intervalo entre *beacons* de 2,5 segundos. +Neste caso, o ``NqosWifiMacHelper`` vai criar camadas MAC do "ns3::ApWifiMac", este último especificando que uma instância MAC configurado como um AP deve ser criado, com o tipo de assistente implicando que o atributo "QosSupported" deve ser definido como falso - desativando o suporte a Qos do tipo 802.11e/WMM nos APs criados. .. The next lines create the single AP which shares the same set of PHY-level @@ -1683,34 +1680,23 @@ Voc :: reading from file third-0-1.pcap, link-type IEEE802_11 (802.11) - 0.000025 Beacon () [6.0* 9.0 12.0 18.0 24.0 36.0 48.0 54.0 Mbit] IBSS - 0.000263 Assoc Request () [6.0 9.0 12.0 18.0 24.0 36.0 48.0 54.0 Mbit] - 0.000279 Acknowledgment RA:00:00:00:00:00:07 - 0.000357 Assoc Response AID(0) :: Succesful - 0.000501 Acknowledgment RA:00:00:00:00:00:0a - 0.000748 Assoc Request () [6.0 9.0 12.0 18.0 24.0 36.0 48.0 54.0 Mbit] - 0.000764 Acknowledgment RA:00:00:00:00:00:08 - 0.000842 Assoc Response AID(0) :: Succesful - 0.000986 Acknowledgment RA:00:00:00:00:00:0a - 0.001242 Assoc Request () [6.0 9.0 12.0 18.0 24.0 36.0 48.0 54.0 Mbit] - 0.001258 Acknowledgment RA:00:00:00:00:00:09 - 0.001336 Assoc Response AID(0) :: Succesful - 0.001480 Acknowledgment RA:00:00:00:00:00:0a - 2.000112 arp who-has 10.1.3.4 (ff:ff:ff:ff:ff:ff) tell 10.1.3.3 - 2.000128 Acknowledgment RA:00:00:00:00:00:09 - 2.000206 arp who-has 10.1.3.4 (ff:ff:ff:ff:ff:ff) tell 10.1.3.3 - 2.000487 arp reply 10.1.3.4 is-at 00:00:00:00:00:0a - 2.000659 Acknowledgment RA:00:00:00:00:00:0a - 2.002169 IP 10.1.3.3.49153 > 10.1.2.4.9: UDP, length 1024 - 2.002185 Acknowledgment RA:00:00:00:00:00:09 - 2.009771 arp who-has 10.1.3.3 (ff:ff:ff:ff:ff:ff) tell 10.1.3.4 - 2.010029 arp reply 10.1.3.3 is-at 00:00:00:00:00:09 - 2.010045 Acknowledgment RA:00:00:00:00:00:09 - 2.010231 IP 10.1.2.4.9 > 10.1.3.3.49153: UDP, length 1024 - 2.011767 Acknowledgment RA:00:00:00:00:00:0a - 2.500000 Beacon () [6.0* 9.0 12.0 18.0 24.0 36.0 48.0 54.0 Mbit] IBSS - 5.000000 Beacon () [6.0* 9.0 12.0 18.0 24.0 36.0 48.0 54.0 Mbit] IBSS - 7.500000 Beacon () [6.0* 9.0 12.0 18.0 24.0 36.0 48.0 54.0 Mbit] IBSS + 0.000025 Beacon (ns-3-ssid) [6.0* 9.0 12.0 18.0 24.0 36.0 48.0 54.0 Mbit] IBSS + 0.000263 Assoc Request (ns-3-ssid) [6.0 9.0 12.0 18.0 24.0 36.0 48.0 54.0 Mbit] + 0.000279 Acknowledgment RA:00:00:00:00:00:09 + 0.000552 Assoc Request (ns-3-ssid) [6.0 9.0 12.0 18.0 24.0 36.0 48.0 54.0 Mbit] + 0.000568 Acknowledgment RA:00:00:00:00:00:07 + 0.000664 Assoc Response AID(0) :: Succesful + 0.001001 Assoc Response AID(0) :: Succesful + 0.001145 Acknowledgment RA:00:00:00:00:00:0a + 0.001233 Assoc Response AID(0) :: Succesful + 0.001377 Acknowledgment RA:00:00:00:00:00:0a + 0.001597 Assoc Request (ns-3-ssid) [6.0 9.0 12.0 18.0 24.0 36.0 48.0 54.0 Mbit] + 0.001613 Acknowledgment RA:00:00:00:00:00:08 + 0.001691 Assoc Response AID(0) :: Succesful + 0.001835 Acknowledgment RA:00:00:00:00:00:0a + 0.102400 Beacon (ns-3-ssid) [6.0* 9.0 12.0 18.0 24.0 36.0 48.0 54.0 Mbit] IBSS + 0.204800 Beacon (ns-3-ssid) [6.0* 9.0 12.0 18.0 24.0 36.0 48.0 54.0 Mbit] IBSS + 0.307200 Beacon (ns-3-ssid) [6.0* 9.0 12.0 18.0 24.0 36.0 48.0 54.0 Mbit] IBSS .. You can see that the link type is now 802.11 as you would expect. You can @@ -1737,8 +1723,8 @@ Novamente, temos algumas sa :: reading from file third-0-0.pcap, link-type PPP (PPP) - 2.002169 IP 10.1.3.3.49153 > 10.1.2.4.9: UDP, length 1024 - 2.009771 IP 10.1.2.4.9 > 10.1.3.3.49153: UDP, length 1024 + 2.002160 IP 10.1.3.3.49153 > 10.1.2.4.9: UDP, length 1024 + 2.009767 IP 10.1.2.4.9 > 10.1.3.3.49153: UDP, length 1024 .. This is the echo packet going from left to right (from Wifi to CSMA) and back @@ -1763,8 +1749,8 @@ Novamente, temos algumas sa :: reading from file third-1-0.pcap, link-type PPP (PPP) - 2.005855 IP 10.1.3.3.49153 > 10.1.2.4.9: UDP, length 1024 - 2.006084 IP 10.1.2.4.9 > 10.1.3.3.49153: UDP, length 1024 + 2.005846 IP 10.1.3.3.49153 > 10.1.2.4.9: UDP, length 1024 + 2.006081 IP 10.1.2.4.9 > 10.1.3.3.49153: UDP, length 1024 .. This is also the echo packet going from left to right (from Wifi to CSMA) and @@ -1791,12 +1777,12 @@ Temos algumas sa :: reading from file third-1-1.pcap, link-type EN10MB (Ethernet) - 2.005855 arp who-has 10.1.2.4 (ff:ff:ff:ff:ff:ff) tell 10.1.2.1 - 2.005877 arp reply 10.1.2.4 is-at 00:00:00:00:00:06 - 2.005877 IP 10.1.3.3.49153 > 10.1.2.4.9: UDP, length 1024 - 2.005980 arp who-has 10.1.2.1 (ff:ff:ff:ff:ff:ff) tell 10.1.2.4 - 2.005980 arp reply 10.1.2.1 is-at 00:00:00:00:00:03 - 2.006084 IP 10.1.2.4.9 > 10.1.3.3.49153: UDP, length 1024 + 2.005846 ARP, Request who-has 10.1.2.4 (ff:ff:ff:ff:ff:ff) tell 10.1.2.1, length 50 + 2.005870 ARP, Reply 10.1.2.4 is-at 00:00:00:00:00:06, length 50 + 2.005870 IP 10.1.3.3.49153 > 10.1.2.4.9: UDP, length 1024 + 2.005975 ARP, Request who-has 10.1.2.1 (ff:ff:ff:ff:ff:ff) tell 10.1.2.4, length 50 + 2.005975 ARP, Reply 10.1.2.1 is-at 00:00:00:00:00:03, length 50 + 2.006081 IP 10.1.2.4.9 > 10.1.3.3.49153: UDP, length 1024 .. This should be easily understood. If you've forgotten, go back and look at diff --git a/doc/tutorial/source/building-topologies.rst b/doc/tutorial/source/building-topologies.rst index 395e69616..0132ebcba 100644 --- a/doc/tutorial/source/building-topologies.rst +++ b/doc/tutorial/source/building-topologies.rst @@ -808,12 +808,13 @@ to the Wifi module and the mobility module which we will discuss below. :: #include "ns3/core-module.h" +#include "ns3/point-to-point-module.h" #include "ns3/network-module.h" +#include "ns3/applications-module.h" +#include "ns3/wifi-module.h" +#include "ns3/mobility-module.h" #include "ns3/csma-module.h" #include "ns3/internet-module.h" -#include "ns3/point-to-point-module.h" -#include "ns3/applications-module.h" -#include "ns3/ipv4-global-routing-helper.h" The network topology illustration follows: @@ -1006,17 +1007,13 @@ requirements of the AP. :: mac.SetType ("ns3::ApWifiMac", - "Ssid", SsidValue (ssid), - "BeaconGeneration", BooleanValue (true), - "BeaconInterval", TimeValue (Seconds (2.5))); + "Ssid", SsidValue (ssid)); In this case, the ``NqosWifiMacHelper`` is going to create MAC layers of the "ns3::ApWifiMac", the latter specifying that a MAC instance configured as an AP should be created, with the helper type implying that the "QosSupported" ``Attribute`` should be set to -false - disabling 802.11e/WMM-style QoS support at created APs. We -set the "BeaconGeneration" ``Attribute`` to true and also set an -interval between beacons of 2.5 seconds. +false - disabling 802.11e/WMM-style QoS support at created APs. The next lines create the single AP which shares the same set of PHY-level ``Attributes`` (and channel) as the stations: @@ -1236,34 +1233,23 @@ You should see some wifi-looking contents you haven't seen here before: :: reading from file third-0-1.pcap, link-type IEEE802_11 (802.11) - 0.000025 Beacon () [6.0* 9.0 12.0 18.0 24.0 36.0 48.0 54.0 Mbit] IBSS - 0.000263 Assoc Request () [6.0 9.0 12.0 18.0 24.0 36.0 48.0 54.0 Mbit] - 0.000279 Acknowledgment RA:00:00:00:00:00:07 - 0.000357 Assoc Response AID(0) :: Succesful - 0.000501 Acknowledgment RA:00:00:00:00:00:0a - 0.000748 Assoc Request () [6.0 9.0 12.0 18.0 24.0 36.0 48.0 54.0 Mbit] - 0.000764 Acknowledgment RA:00:00:00:00:00:08 - 0.000842 Assoc Response AID(0) :: Succesful - 0.000986 Acknowledgment RA:00:00:00:00:00:0a - 0.001242 Assoc Request () [6.0 9.0 12.0 18.0 24.0 36.0 48.0 54.0 Mbit] - 0.001258 Acknowledgment RA:00:00:00:00:00:09 - 0.001336 Assoc Response AID(0) :: Succesful - 0.001480 Acknowledgment RA:00:00:00:00:00:0a - 2.000112 arp who-has 10.1.3.4 (ff:ff:ff:ff:ff:ff) tell 10.1.3.3 - 2.000128 Acknowledgment RA:00:00:00:00:00:09 - 2.000206 arp who-has 10.1.3.4 (ff:ff:ff:ff:ff:ff) tell 10.1.3.3 - 2.000487 arp reply 10.1.3.4 is-at 00:00:00:00:00:0a - 2.000659 Acknowledgment RA:00:00:00:00:00:0a - 2.002169 IP 10.1.3.3.49153 > 10.1.2.4.9: UDP, length 1024 - 2.002185 Acknowledgment RA:00:00:00:00:00:09 - 2.009771 arp who-has 10.1.3.3 (ff:ff:ff:ff:ff:ff) tell 10.1.3.4 - 2.010029 arp reply 10.1.3.3 is-at 00:00:00:00:00:09 - 2.010045 Acknowledgment RA:00:00:00:00:00:09 - 2.010231 IP 10.1.2.4.9 > 10.1.3.3.49153: UDP, length 1024 - 2.011767 Acknowledgment RA:00:00:00:00:00:0a - 2.500000 Beacon () [6.0* 9.0 12.0 18.0 24.0 36.0 48.0 54.0 Mbit] IBSS - 5.000000 Beacon () [6.0* 9.0 12.0 18.0 24.0 36.0 48.0 54.0 Mbit] IBSS - 7.500000 Beacon () [6.0* 9.0 12.0 18.0 24.0 36.0 48.0 54.0 Mbit] IBSS + 0.000025 Beacon (ns-3-ssid) [6.0* 9.0 12.0 18.0 24.0 36.0 48.0 54.0 Mbit] IBSS + 0.000263 Assoc Request (ns-3-ssid) [6.0 9.0 12.0 18.0 24.0 36.0 48.0 54.0 Mbit] + 0.000279 Acknowledgment RA:00:00:00:00:00:09 + 0.000552 Assoc Request (ns-3-ssid) [6.0 9.0 12.0 18.0 24.0 36.0 48.0 54.0 Mbit] + 0.000568 Acknowledgment RA:00:00:00:00:00:07 + 0.000664 Assoc Response AID(0) :: Succesful + 0.001001 Assoc Response AID(0) :: Succesful + 0.001145 Acknowledgment RA:00:00:00:00:00:0a + 0.001233 Assoc Response AID(0) :: Succesful + 0.001377 Acknowledgment RA:00:00:00:00:00:0a + 0.001597 Assoc Request (ns-3-ssid) [6.0 9.0 12.0 18.0 24.0 36.0 48.0 54.0 Mbit] + 0.001613 Acknowledgment RA:00:00:00:00:00:08 + 0.001691 Assoc Response AID(0) :: Succesful + 0.001835 Acknowledgment RA:00:00:00:00:00:0a + 0.102400 Beacon (ns-3-ssid) [6.0* 9.0 12.0 18.0 24.0 36.0 48.0 54.0 Mbit] IBSS + 0.204800 Beacon (ns-3-ssid) [6.0* 9.0 12.0 18.0 24.0 36.0 48.0 54.0 Mbit] IBSS + 0.307200 Beacon (ns-3-ssid) [6.0* 9.0 12.0 18.0 24.0 36.0 48.0 54.0 Mbit] IBSS You can see that the link type is now 802.11 as you would expect. You can probably understand what is going on and find the IP echo request and response @@ -1281,8 +1267,8 @@ Again, you should see some familiar looking contents: :: reading from file third-0-0.pcap, link-type PPP (PPP) - 2.002169 IP 10.1.3.3.49153 > 10.1.2.4.9: UDP, length 1024 - 2.009771 IP 10.1.2.4.9 > 10.1.3.3.49153: UDP, length 1024 + 2.002160 IP 10.1.3.3.49153 > 10.1.2.4.9: UDP, length 1024 + 2.009767 IP 10.1.2.4.9 > 10.1.3.3.49153: UDP, length 1024 This is the echo packet going from left to right (from Wifi to CSMA) and back again across the point-to-point link. @@ -1298,8 +1284,8 @@ Again, you should see some familiar looking contents: :: reading from file third-1-0.pcap, link-type PPP (PPP) - 2.005855 IP 10.1.3.3.49153 > 10.1.2.4.9: UDP, length 1024 - 2.006084 IP 10.1.2.4.9 > 10.1.3.3.49153: UDP, length 1024 + 2.005846 IP 10.1.3.3.49153 > 10.1.2.4.9: UDP, length 1024 + 2.006081 IP 10.1.2.4.9 > 10.1.3.3.49153: UDP, length 1024 This is also the echo packet going from left to right (from Wifi to CSMA) and back again across the point-to-point link with slightly different timings @@ -1317,12 +1303,12 @@ You should see some familiar looking contents: :: reading from file third-1-1.pcap, link-type EN10MB (Ethernet) - 2.005855 arp who-has 10.1.2.4 (ff:ff:ff:ff:ff:ff) tell 10.1.2.1 - 2.005877 arp reply 10.1.2.4 is-at 00:00:00:00:00:06 - 2.005877 IP 10.1.3.3.49153 > 10.1.2.4.9: UDP, length 1024 - 2.005980 arp who-has 10.1.2.1 (ff:ff:ff:ff:ff:ff) tell 10.1.2.4 - 2.005980 arp reply 10.1.2.1 is-at 00:00:00:00:00:03 - 2.006084 IP 10.1.2.4.9 > 10.1.3.3.49153: UDP, length 1024 + 2.005846 ARP, Request who-has 10.1.2.4 (ff:ff:ff:ff:ff:ff) tell 10.1.2.1, length 50 + 2.005870 ARP, Reply 10.1.2.4 is-at 00:00:00:00:00:06, length 50 + 2.005870 IP 10.1.3.3.49153 > 10.1.2.4.9: UDP, length 1024 + 2.005975 ARP, Request who-has 10.1.2.1 (ff:ff:ff:ff:ff:ff) tell 10.1.2.4, length 50 + 2.005975 ARP, Reply 10.1.2.1 is-at 00:00:00:00:00:03, length 50 + 2.006081 IP 10.1.2.4.9 > 10.1.3.3.49153: UDP, length 1024 This should be easily understood. If you've forgotten, go back and look at the discussion in ``second.cc``. This is the same sequence. diff --git a/src/dsdv/model/dsdv-routing-protocol.cc b/src/dsdv/model/dsdv-routing-protocol.cc index 94e722e8f..06f1759c6 100644 --- a/src/dsdv/model/dsdv-routing-protocol.cc +++ b/src/dsdv/model/dsdv-routing-protocol.cc @@ -840,7 +840,7 @@ RoutingProtocol::SendPeriodicUpdate () m_routingTable.Purge (removedAddresses); MergeTriggerPeriodicUpdates (); m_routingTable.GetListOfAllRoutes (allRoutes); - if (allRoutes.size () < 0) + if (allRoutes.empty ()) { return; } diff --git a/src/internet/model/ipv4-packet-info-tag.cc b/src/internet/model/ipv4-packet-info-tag.cc index e9054268f..4d8780e75 100644 --- a/src/internet/model/ipv4-packet-info-tag.cc +++ b/src/internet/model/ipv4-packet-info-tag.cc @@ -121,9 +121,9 @@ Ipv4PacketInfoTag::Deserialize (TagBuffer i) { uint8_t buf[4]; i.Read (buf, 4); - m_addr.Deserialize (buf); + m_addr = Ipv4Address::Deserialize (buf); i.Read (buf, 4); - m_spec_dst.Deserialize (buf); + m_spec_dst = Ipv4Address::Deserialize (buf); m_ifindex = i.ReadU32 (); m_ttl = i.ReadU8 (); } diff --git a/src/internet/model/ipv4-static-routing.cc b/src/internet/model/ipv4-static-routing.cc index 278440352..305a55f87 100644 --- a/src/internet/model/ipv4-static-routing.cc +++ b/src/internet/model/ipv4-static-routing.cc @@ -413,11 +413,11 @@ Ipv4StaticRouting::GetRoute (uint32_t index) const } uint32_t -Ipv4StaticRouting::GetMetric (uint32_t index) +Ipv4StaticRouting::GetMetric (uint32_t index) const { NS_LOG_FUNCTION (this << index); uint32_t tmp = 0; - for (NetworkRoutesI j = m_networkRoutes.begin (); + for (NetworkRoutesCI j = m_networkRoutes.begin (); j != m_networkRoutes.end (); j++) { @@ -700,7 +700,6 @@ Ipv4StaticRouting::SetIpv4 (Ptr ipv4) } } } - // Formatted like output of "route -n" command void Ipv4StaticRouting::PrintRoutingTable (Ptr stream) const @@ -713,11 +712,11 @@ Ipv4StaticRouting::PrintRoutingTable (Ptr stream) const { std::ostringstream dest, gw, mask, flags; Ipv4RoutingTableEntry route = GetRoute (j); - dest << route.GetDest (); + dest << route.GetDest (); *os << std::setiosflags (std::ios::left) << std::setw (16) << dest.str (); - gw << route.GetGateway (); + gw << route.GetGateway (); *os << std::setiosflags (std::ios::left) << std::setw (16) << gw.str (); - mask << route.GetDestNetworkMask (); + mask << route.GetDestNetworkMask (); *os << std::setiosflags (std::ios::left) << std::setw (16) << mask.str (); flags << "U"; if (route.IsHost ()) @@ -729,8 +728,7 @@ Ipv4StaticRouting::PrintRoutingTable (Ptr stream) const flags << "GS"; } *os << std::setiosflags (std::ios::left) << std::setw (6) << flags.str (); - // Metric not implemented - *os << "-" << " "; + *os << std::setiosflags (std::ios::left) << std::setw (7) << GetMetric (j); // Ref ct not implemented *os << "-" << " "; // Use not implemented @@ -747,7 +745,6 @@ Ipv4StaticRouting::PrintRoutingTable (Ptr stream) const } } } - Ipv4Address Ipv4StaticRouting::SourceAddressSelection (uint32_t interfaceIdx, Ipv4Address dest) { diff --git a/src/internet/model/ipv4-static-routing.h b/src/internet/model/ipv4-static-routing.h index 8ae679790..879ad7bf2 100644 --- a/src/internet/model/ipv4-static-routing.h +++ b/src/internet/model/ipv4-static-routing.h @@ -213,7 +213,7 @@ public: * \return If route is set, the metric is returned. If not, an infinity metric (0xffffffff) is returned * */ - uint32_t GetMetric (uint32_t index); + uint32_t GetMetric (uint32_t index) const; /** * \brief Remove a route from the static unicast routing table. diff --git a/src/internet/model/ipv6-packet-info-tag.cc b/src/internet/model/ipv6-packet-info-tag.cc index 1d09e759b..766096745 100644 --- a/src/internet/model/ipv6-packet-info-tag.cc +++ b/src/internet/model/ipv6-packet-info-tag.cc @@ -120,7 +120,7 @@ Ipv6PacketInfoTag::Deserialize (TagBuffer i) { uint8_t buf[16]; i.Read (buf, 16); - m_addr.Deserialize (buf); + m_addr = Ipv6Address::Deserialize (buf); m_ifindex = i.ReadU8 (); m_hoplimit = i.ReadU8 (); m_tclass = i.ReadU8 (); diff --git a/src/internet/model/nsc-tcp-l4-protocol.cc b/src/internet/model/nsc-tcp-l4-protocol.cc index 61e7393f3..4064d7f1f 100644 --- a/src/internet/model/nsc-tcp-l4-protocol.cc +++ b/src/internet/model/nsc-tcp-l4-protocol.cc @@ -454,7 +454,7 @@ void NscTcpL4Protocol::AddInterface (void) // All we need is another address on the same network as the interface. This // will force the stack to output the packet out of the network interface. addrBytes[3]++; - addr.Deserialize (addrBytes); + addr = Ipv4Address::Deserialize (addrBytes); addrOss.str (""); addr.Print (addrOss); m_nscStack->add_default_gateway (addrOss.str ().c_str ()); diff --git a/src/internet/model/nsc-tcp-socket-impl.cc b/src/internet/model/nsc-tcp-socket-impl.cc index 3d1df4178..975741a23 100644 --- a/src/internet/model/nsc-tcp-socket-impl.cc +++ b/src/internet/model/nsc-tcp-socket-impl.cc @@ -497,7 +497,7 @@ void NscTcpSocketImpl::CompleteFork (void) if (0 == m_nscTcpSocket->getpeername ((struct sockaddr*) &sin, &sin_len)) { m_remotePort = ntohs (sin.sin_port); - m_remoteAddress = m_remoteAddress.Deserialize ((const uint8_t*) &sin.sin_addr); + m_remoteAddress = Ipv4Address::Deserialize ((const uint8_t*) &sin.sin_addr); m_peerAddress = InetSocketAddress (m_remoteAddress, m_remotePort); } @@ -510,7 +510,7 @@ void NscTcpSocketImpl::CompleteFork (void) sin_len = sizeof(sin); if (0 == m_nscTcpSocket->getsockname ((struct sockaddr *) &sin, &sin_len)) - m_localAddress = m_localAddress.Deserialize ((const uint8_t*) &sin.sin_addr); + m_localAddress = Ipv4Address::Deserialize ((const uint8_t*) &sin.sin_addr); NS_LOG_LOGIC ("NscTcpSocketImpl " << this << " accepted connection from " << m_remoteAddress << ":" << m_remotePort @@ -529,7 +529,7 @@ void NscTcpSocketImpl::ConnectionSucceeded () struct sockaddr_in sin; size_t sin_len = sizeof(sin); if (0 == m_nscTcpSocket->getsockname ((struct sockaddr *) &sin, &sin_len)) { - m_localAddress = m_localAddress.Deserialize ((const uint8_t*)&sin.sin_addr); + m_localAddress = Ipv4Address::Deserialize ((const uint8_t*)&sin.sin_addr); m_localPort = ntohs (sin.sin_port); } diff --git a/src/internet/model/rtt-estimator.cc b/src/internet/model/rtt-estimator.cc index b5ae0410d..372e2ee85 100644 --- a/src/internet/model/rtt-estimator.cc +++ b/src/internet/model/rtt-estimator.cc @@ -30,6 +30,7 @@ #include "rtt-estimator.h" #include "ns3/simulator.h" #include "ns3/double.h" +#include "ns3/integer.h" namespace ns3 { @@ -42,15 +43,14 @@ RttEstimator::GetTypeId (void) static TypeId tid = TypeId ("ns3::RttEstimator") .SetParent () .AddAttribute ("MaxMultiplier", - "XXX", - DoubleValue (64.0), + "Maximum RTO Multiplier", + IntegerValue (64), MakeDoubleAccessor (&RttEstimator::m_maxMultiplier), - MakeDoubleChecker ()) + MakeIntegerChecker ()) .AddAttribute ("InitialEstimation", - "XXX", + "Initial RTT estimation", TimeValue (Seconds (1.0)), - MakeTimeAccessor (&RttEstimator::SetEstimate, - &RttEstimator::GetEstimate), + MakeTimeAccessor (&RttEstimator::m_initialEstimatedRtt), MakeTimeChecker ()) .AddAttribute ("MinRTO", "Minimum retransmit timeout value", @@ -65,22 +65,22 @@ RttEstimator::GetTypeId (void) void RttEstimator::SetMinRto (Time minRto) { - minrto = minRto; + m_minRto = minRto; } Time RttEstimator::GetMinRto (void) const { - return Time (minrto); + return Time (m_minRto); } void -RttEstimator::SetEstimate (Time estimate) +RttEstimator::SetCurrentEstimate (Time estimate) { - est = estimate; + m_currentEstimatedRtt = estimate; } Time -RttEstimator::GetEstimate (void) const +RttEstimator::GetCurrentEstimate (void) const { - return Time (est); + return Time (m_currentEstimatedRtt); } @@ -97,43 +97,38 @@ RttHistory::RttHistory (const RttHistory& h) // Base class methods -RttEstimator::RttEstimator () : next (1), history (), - nSamples (0), multiplier (1.0) +RttEstimator::RttEstimator () + : m_next (1), m_history (), + m_currentEstimatedRtt(m_initialEstimatedRtt), + m_nSamples (0), + m_multiplier (1) { //note next=1 everywhere since first segment will have sequence 1 } -RttEstimator::RttEstimator(const RttEstimator& c) - : Object (c), next (c.next), history (c.history), - m_maxMultiplier (c.m_maxMultiplier), est (c.est), - minrto (c.minrto), nSamples (c.nSamples), - multiplier (c.multiplier) -{ -} - RttEstimator::~RttEstimator () { } -void RttEstimator::SentSeq (SequenceNumber32 s, uint32_t c) +void RttEstimator::SentSeq (SequenceNumber32 seq, uint32_t size) { // Note that a particular sequence has been sent - if (s == next) + if (seq == m_next) { // This is the next expected one, just log at end - history.push_back (RttHistory (s, c, Simulator::Now () )); - next = s + SequenceNumber32 (c); // Update next expected + m_history.push_back (RttHistory (seq, size, Simulator::Now () )); + m_next = seq + SequenceNumber32 (size); // Update next expected } else { // This is a retransmit, find in list and mark as re-tx - for (RttHistory_t::iterator i = history.begin (); i != history.end (); ++i) + for (RttHistory_t::iterator i = m_history.begin (); i != m_history.end (); ++i) { - if ((s >= i->seq) && (s < (i->seq + SequenceNumber32 (i->count)))) + if ((seq >= i->seq) && (seq < (i->seq + SequenceNumber32 (i->count)))) { // Found it i->retx = true; // One final test..be sure this re-tx does not extend "next" - if ((s + SequenceNumber32 (c)) > next) + if ((seq + SequenceNumber32 (size)) > m_next) { - next = s + SequenceNumber32 (c); - i->count = ((s + SequenceNumber32 (c)) - i->seq); // And update count in hist + m_next = seq + SequenceNumber32 (size); + i->count = ((seq + SequenceNumber32 (size)) - i->seq); // And update count in hist } break; } @@ -141,51 +136,51 @@ void RttEstimator::SentSeq (SequenceNumber32 s, uint32_t c) } } -Time RttEstimator::AckSeq (SequenceNumber32 a) +Time RttEstimator::AckSeq (SequenceNumber32 ackSeq) { // An ack has been received, calculate rtt and log this measurement // Note we use a linear search (O(n)) for this since for the common // case the ack'ed packet will be at the head of the list Time m = Seconds (0.0); - if (history.size () == 0) return (m); // No pending history, just exit - RttHistory& h = history.front (); - if (!h.retx && a >= (h.seq + SequenceNumber32 (h.count))) + if (m_history.size () == 0) return (m); // No pending history, just exit + RttHistory& h = m_history.front (); + if (!h.retx && ackSeq >= (h.seq + SequenceNumber32 (h.count))) { // Ok to use this sample m = Simulator::Now () - h.time; // Elapsed time Measurement (m); // Log the measurement ResetMultiplier (); // Reset multiplier on valid measurement } // Now delete all ack history with seq <= ack - while(history.size () > 0) + while(m_history.size () > 0) { - RttHistory& h = history.front (); - if ((h.seq + SequenceNumber32 (h.count)) > a) break; // Done removing - history.pop_front (); // Remove + RttHistory& h = m_history.front (); + if ((h.seq + SequenceNumber32 (h.count)) > ackSeq) break; // Done removing + m_history.pop_front (); // Remove } return m; } void RttEstimator::ClearSent () { // Clear all history entries - next = 1; - history.clear (); + m_next = 1; + m_history.clear (); } void RttEstimator::IncreaseMultiplier () { - multiplier = std::min (multiplier * 2.0, m_maxMultiplier); + m_multiplier = (m_multiplier*2 < m_maxMultiplier) ? m_multiplier*2 : m_maxMultiplier; } void RttEstimator::ResetMultiplier () { - multiplier = 1.0; + m_multiplier = 1; } void RttEstimator::Reset () { // Reset to initial state - next = 1; - est = 1; // XXX: we should go back to the 'initial value' here. Need to add support in Object for this. - history.clear (); // Remove all info from the history - nSamples = 0; + m_next = 1; + m_currentEstimatedRtt = m_initialEstimatedRtt; + m_history.clear (); // Remove all info from the history + m_nSamples = 0; ResetMultiplier (); } @@ -204,55 +199,55 @@ RttMeanDeviation::GetTypeId (void) .SetParent () .AddConstructor () .AddAttribute ("Gain", - "XXX", + "Gain used in estimating the RTT, must be 0 < Gain < 1", DoubleValue (0.1), - MakeDoubleAccessor (&RttMeanDeviation::gain), + MakeDoubleAccessor (&RttMeanDeviation::m_gain), MakeDoubleChecker ()) ; return tid; } RttMeanDeviation::RttMeanDeviation() : - variance (0) + m_variance (0) { } RttMeanDeviation::RttMeanDeviation (const RttMeanDeviation& c) - : RttEstimator (c), gain (c.gain), variance (c.variance) + : RttEstimator (c), m_gain (c.m_gain), m_variance (c.m_variance) { } void RttMeanDeviation::Measurement (Time m) { - if (nSamples) + if (m_nSamples) { // Not first - int64x64_t err = m - est; - est = est + gain * err; // estimated rtt - variance = variance + gain * (Abs (err) - variance); // variance of rtt + Time err(m - m_currentEstimatedRtt); + m_currentEstimatedRtt += m_gain * err; // estimated rtt + m_variance += m_gain * (Abs (err) - m_variance); // variance of rtt } else { // First sample - est = m; // Set estimate to current + m_currentEstimatedRtt = m; // Set estimate to current //variance = sample / 2; // And variance to current / 2 - variance = m; // try this + m_variance = m; // try this } - nSamples++; + m_nSamples++; } Time RttMeanDeviation::RetransmitTimeout () { - // If not enough samples, justjust return 2 times estimate + // If not enough samples, just return 2 times estimate //if (nSamples < 2) return est * 2; int64x64_t retval; - if (variance < est / 4.0) + if (m_variance < m_currentEstimatedRtt / 4.0) { - retval = est * 2 * multiplier; // At least twice current est + retval = m_currentEstimatedRtt * 2 * m_multiplier; // At least twice current est } else { - retval = (est + 4 * variance) * multiplier; // As suggested by Jacobson + retval = (m_currentEstimatedRtt + 4 * m_variance) * m_multiplier; // As suggested by Jacobson } - retval = Max (retval, minrto); + retval = Max (retval, m_minRto); return Time (retval); } @@ -263,7 +258,13 @@ Ptr RttMeanDeviation::Copy () const void RttMeanDeviation::Reset () { // Reset to initial state - variance = 0; + m_variance = 0; RttEstimator::Reset (); } +void RttMeanDeviation::Gain (double g) +{ + NS_ASSERT_MSG( (g > 0) && (g < 1), "RttMeanDeviation: Gain must be less than 1 and greater than 0" ); + m_gain = g; +} + } //namepsace ns3 diff --git a/src/internet/model/rtt-estimator.h b/src/internet/model/rtt-estimator.h index b5f83fee0..b1bdbc326 100644 --- a/src/internet/model/rtt-estimator.h +++ b/src/internet/model/rtt-estimator.h @@ -35,14 +35,14 @@ namespace ns3 { /** * \ingroup tcp * - * \brief Implements several variations of round trip time estimators + * \brief Helper class to store RTT measurements */ class RttHistory { public: RttHistory (SequenceNumber32 s, uint32_t c, Time t); RttHistory (const RttHistory& h); // Copy constructor public: - SequenceNumber32 seq; // First sequence number in packet sent + SequenceNumber32 seq; // First sequence number in packet sent uint32_t count; // Number of bytes sent Time time; // Time this one was sent bool retx; // True if this has been retransmitted @@ -50,68 +50,149 @@ public: typedef std::deque RttHistory_t; -class RttEstimator : public Object { // Base class for all RTT Estimators +/** + * \ingroup tcp + * + * \brief Base class for all RTT Estimators + */ +class RttEstimator : public Object { public: static TypeId GetTypeId (void); RttEstimator(); - RttEstimator(const RttEstimator&); // Copy constructor virtual ~RttEstimator(); - virtual void SentSeq (SequenceNumber32, uint32_t); - virtual Time AckSeq (SequenceNumber32); + /** + * \brief Note that a particular sequence has been sent + * \param seq the packet sequence number. + * \param size the packet size. + */ + virtual void SentSeq (SequenceNumber32 seq, uint32_t size); + + /** + * \brief Note that a particular ack sequence has been received + * \param ackSeq the ack sequence number. + * \return The measured RTT for this ack. + */ + virtual Time AckSeq (SequenceNumber32 ackSeq); + + /** + * \brief Clear all history entries + */ virtual void ClearSent (); - virtual void Measurement (Time t) = 0; + + /** + * \brief Add a new measurement to the estimator. Pure virtual function. + * \param t the new RTT measure. + */ + virtual void Measurement (Time t) = 0; + + /** + * \brief Returns the estimated RTO. Pure virtual function. + * \return the estimated RTO. + */ virtual Time RetransmitTimeout () = 0; - void Init (SequenceNumber32 s) { next = s; } + virtual Ptr Copy () const = 0; + + /** + * \brief Increase the estimation multiplier up to MaxMultiplier. + */ virtual void IncreaseMultiplier (); + + /** + * \brief Resets the estimation multiplier to 1. + */ virtual void ResetMultiplier (); + + /** + * \brief Resets the estimation to its initial state. + */ virtual void Reset (); + /** + * \brief Sets the Minimum RTO. + * \param minRto The minimum RTO returned by the estimator. + */ void SetMinRto (Time minRto); + + /** + * \brief Get the Minimum RTO. + * \return The minimum RTO returned by the estimator. + */ Time GetMinRto (void) const; - void SetEstimate (Time estimate); - Time GetEstimate (void) const; + + /** + * \brief Sets the current RTT estimate (forcefully). + * \param estimate The current RTT estimate. + */ + void SetCurrentEstimate (Time estimate); + + /** + * \brief gets the current RTT estimate. + * \return The current RTT estimate. + */ + Time GetCurrentEstimate (void) const; private: - SequenceNumber32 next; // Next expected sequence to be sent - RttHistory_t history; // List of sent packet - double m_maxMultiplier; -public: - int64x64_t est; // Current estimate - int64x64_t minrto; // minimum value of the timeout - uint32_t nSamples; // Number of samples - double multiplier; // RTO Multiplier + SequenceNumber32 m_next; // Next expected sequence to be sent + RttHistory_t m_history; // List of sent packet + u_int16_t m_maxMultiplier; + Time m_initialEstimatedRtt; + +protected: + int64x64_t m_currentEstimatedRtt; // Current estimate + int64x64_t m_minRto; // minimum value of the timeout + uint32_t m_nSamples; // Number of samples + u_int16_t m_multiplier; // RTO Multiplier }; -// The "Mean-Deviation" estimator, as discussed by Van Jacobson -// "Congestion Avoidance and Control", SIGCOMM 88, Appendix A - -//Doc:Class Class {\tt RttMeanDeviation} implements the "Mean--Deviation" estimator -//Doc:Class as described by Van Jacobson -//Doc:Class "Congestion Avoidance and Control", SIGCOMM 88, Appendix A +/** + * \ingroup tcp + * + * \brief The "Mean--Deviation" RTT estimator, as discussed by Van Jacobson + * + * This class implements the "Mean--Deviation" RTT estimator, as discussed + * by Van Jacobson and Michael J. Karels, in + * "Congestion Avoidance and Control", SIGCOMM 88, Appendix A + * + */ class RttMeanDeviation : public RttEstimator { public: static TypeId GetTypeId (void); RttMeanDeviation (); + RttMeanDeviation (const RttMeanDeviation&); - //Doc:Method - RttMeanDeviation (const RttMeanDeviation&); // Copy constructor - //Doc:Desc Copy constructor. - //Doc:Arg1 {\tt RttMeanDeviation} object to copy. + /** + * \brief Add a new measurement to the estimator. + * \param measure the new RTT measure. + */ + void Measurement (Time measure); - void Measurement (Time); + /** + * \brief Returns the estimated RTO. + * \return the estimated RTO. + */ Time RetransmitTimeout (); - Ptr Copy () const; - void Reset (); - void Gain (double g) { gain = g; } -public: - double gain; // Filter gain - int64x64_t variance; // Current variance + Ptr Copy () const; + + /** + * \brief Resets sthe estimator. + */ + void Reset (); + + /** + * \brief Sets the estimator Gain. + * \param g the gain, where 0 < g < 1. + */ + void Gain (double g); + +private: + double m_gain; // Filter gain + int64x64_t m_variance; // Current variance }; } // namespace ns3 diff --git a/src/lte/model/amc-module.cc b/src/lte/model/amc-module.cc index 828ba2684..db91ff6ff 100644 --- a/src/lte/model/amc-module.cc +++ b/src/lte/model/amc-module.cc @@ -120,7 +120,7 @@ AmcModule::GetCqiFromSpectralEfficiency (double s) { NS_LOG_FUNCTION (this << s); int cqi = 1; // == CqiIndex[0] - while (SpectralEfficiencyForCqiIndex[cqi] < s && cqi <= 14) + while (cqi < 15 && SpectralEfficiencyForCqiIndex[cqi] < s) { cqi++; } diff --git a/src/netanim/examples/wireless-animation.cc b/src/netanim/examples/wireless-animation.cc new file mode 100644 index 000000000..cf8020aa9 --- /dev/null +++ b/src/netanim/examples/wireless-animation.cc @@ -0,0 +1,158 @@ +/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */ +/* + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 as + * published by the Free Software Foundation; + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + * + * Author: Vikas Pushkar (Adapted from third.cc) + */ + + +#include "ns3/core-module.h" +#include "ns3/point-to-point-module.h" +#include "ns3/csma-module.h" +#include "ns3/network-module.h" +#include "ns3/applications-module.h" +#include "ns3/wifi-module.h" +#include "ns3/mobility-module.h" +#include "ns3/internet-module.h" +#include "ns3/netanim-module.h" + + + +using namespace ns3; + +NS_LOG_COMPONENT_DEFINE ("WirelessAnimationExample"); + +int +main (int argc, char *argv[]) +{ + uint32_t nWifi = 20; + CommandLine cmd; + cmd.AddValue ("nWifi", "Number of wifi STA devices", nWifi); + + + cmd.Parse (argc,argv); + NodeContainer allNodes; + NodeContainer wifiStaNodes; + wifiStaNodes.Create (nWifi); + allNodes.Add (wifiStaNodes); + NodeContainer wifiApNode ; + wifiApNode.Create (1); + allNodes.Add (wifiApNode); + + YansWifiChannelHelper channel = YansWifiChannelHelper::Default (); + YansWifiPhyHelper phy = YansWifiPhyHelper::Default (); + phy.SetChannel (channel.Create ()); + + WifiHelper wifi = WifiHelper::Default (); + wifi.SetRemoteStationManager ("ns3::AarfWifiManager"); + + NqosWifiMacHelper mac = NqosWifiMacHelper::Default (); + + Ssid ssid = Ssid ("ns-3-ssid"); + mac.SetType ("ns3::StaWifiMac", + "Ssid", SsidValue (ssid), + "ActiveProbing", BooleanValue (false)); + + NetDeviceContainer staDevices; + staDevices = wifi.Install (phy, mac, wifiStaNodes); + mac.SetType ("ns3::ApWifiMac", + "Ssid", SsidValue (ssid)); + + NetDeviceContainer apDevices; + apDevices = wifi.Install (phy, mac, wifiApNode); + + + NodeContainer p2pNodes; + p2pNodes.Add (wifiApNode); + p2pNodes.Create (1); + allNodes.Add (p2pNodes.Get (1)); + + PointToPointHelper pointToPoint; + pointToPoint.SetDeviceAttribute ("DataRate", StringValue ("5Mbps")); + pointToPoint.SetChannelAttribute ("Delay", StringValue ("2ms")); + + NetDeviceContainer p2pDevices; + p2pDevices = pointToPoint.Install (p2pNodes); + + NodeContainer csmaNodes; + csmaNodes.Add (p2pNodes.Get (1)); + csmaNodes.Create (1); + allNodes.Add (csmaNodes.Get (1)); + + CsmaHelper csma; + csma.SetChannelAttribute ("DataRate", StringValue ("100Mbps")); + csma.SetChannelAttribute ("Delay", TimeValue (NanoSeconds (6560))); + + NetDeviceContainer csmaDevices; + csmaDevices = csma.Install (csmaNodes); + + // Mobility + + MobilityHelper mobility; + mobility.SetPositionAllocator ("ns3::GridPositionAllocator", + "MinX", DoubleValue (10.0), + "MinY", DoubleValue (10.0), + "DeltaX", DoubleValue (5.0), + "DeltaY", DoubleValue (2.0), + "GridWidth", UintegerValue (5), + "LayoutType", StringValue ("RowFirst")); + mobility.SetMobilityModel ("ns3::RandomWalk2dMobilityModel", + "Bounds", RectangleValue (Rectangle (-50, 50, -25, 50))); + mobility.Install (wifiStaNodes); + mobility.SetMobilityModel ("ns3::ConstantPositionMobilityModel"); + mobility.Install (wifiApNode); + AnimationInterface::SetConstantPosition (p2pNodes.Get (1), 10, 30); + AnimationInterface::SetConstantPosition (csmaNodes.Get (1), 10, 33); + + // Install internet stack + + InternetStackHelper stack; + stack.Install (allNodes); + + // Install Ipv4 addresses + + Ipv4AddressHelper address; + address.SetBase ("10.1.1.0", "255.255.255.0"); + Ipv4InterfaceContainer p2pInterfaces; + p2pInterfaces = address.Assign (p2pDevices); + address.SetBase ("10.1.2.0", "255.255.255.0"); + Ipv4InterfaceContainer csmaInterfaces; + csmaInterfaces = address.Assign (csmaDevices); + address.SetBase ("10.1.3.0", "255.255.255.0"); + Ipv4InterfaceContainer staInterfaces; + staInterfaces = address.Assign (staDevices); + Ipv4InterfaceContainer apInterface; + apInterface = address.Assign (apDevices); + + // Install applications + + UdpEchoServerHelper echoServer (9); + ApplicationContainer serverApps = echoServer.Install (wifiApNode.Get (0)); + serverApps.Start (Seconds (1.0)); + serverApps.Stop (Seconds (15.0)); + UdpEchoClientHelper echoClient (csmaInterfaces.GetAddress (1), 9); + echoClient.SetAttribute ("MaxPackets", UintegerValue (10)); + echoClient.SetAttribute ("Interval", TimeValue (Seconds (1.))); + echoClient.SetAttribute ("PacketSize", UintegerValue (1024)); + ApplicationContainer clientApps = echoClient.Install (wifiStaNodes); + clientApps.Start (Seconds (2.0)); + clientApps.Stop (Seconds (15.0)); + + Ipv4GlobalRoutingHelper::PopulateRoutingTables (); + Simulator::Stop (Seconds (15.0)); + AnimationInterface anim ("wireless-animation.xml"); + Simulator::Run (); + Simulator::Destroy (); + return 0; +} diff --git a/src/netanim/examples/wscript b/src/netanim/examples/wscript index 271ae33bc..3b390fc89 100644 --- a/src/netanim/examples/wscript +++ b/src/netanim/examples/wscript @@ -12,3 +12,7 @@ def build(bld): obj = bld.create_ns3_program('star-animation', ['netanim', 'applications', 'point-to-point-layout']) obj.source = 'star-animation.cc' + + obj = bld.create_ns3_program('wireless-animation', + ['netanim', 'applications', 'point-to-point', 'csma', 'wifi', 'mobility', 'network']) + obj.source = 'wireless-animation.cc' diff --git a/src/netanim/model/animation-interface.cc b/src/netanim/model/animation-interface.cc index fce578e20..46fd5bbee 100644 --- a/src/netanim/model/animation-interface.cc +++ b/src/netanim/model/animation-interface.cc @@ -61,7 +61,8 @@ AnimationInterface::AnimationInterface () : m_fHandle (STDOUT_FILENO), m_xml (false), mobilitypollinterval (Seconds(0.25)), usingSockets (false), mport (0), outputfilename (""), OutputFileSet (false), ServerPortSet (false), gAnimUid (0),randomPosition (true), - m_writeCallback (0), m_started (false) + m_writeCallback (0), m_started (false), m_enforceWifiMacRx (true), + m_enablePacketMetadata (false) { initialized = true; StartAnimation (); @@ -71,7 +72,8 @@ AnimationInterface::AnimationInterface (const std::string fn, bool usingXML) : m_fHandle (STDOUT_FILENO), m_xml (usingXML), mobilitypollinterval (Seconds(0.25)), usingSockets (false), mport (0), outputfilename (fn), OutputFileSet (false), ServerPortSet (false), gAnimUid (0), randomPosition (true), - m_writeCallback (0), m_started (false) + m_writeCallback (0), m_started (false), m_enforceWifiMacRx (true), + m_enablePacketMetadata (false) { initialized = true; StartAnimation (); @@ -81,7 +83,8 @@ AnimationInterface::AnimationInterface (const uint16_t port, bool usingXML) : m_fHandle (STDOUT_FILENO), m_xml (usingXML), mobilitypollinterval (Seconds(0.25)), usingSockets (true), mport (port), outputfilename (""), OutputFileSet (false), ServerPortSet (false), gAnimUid (0), randomPosition (true), - m_writeCallback (0), m_started (false) + m_writeCallback (0), m_started (false), m_enforceWifiMacRx (true), + m_enablePacketMetadata (false) { initialized = true; StartAnimation (); @@ -123,6 +126,13 @@ bool AnimationInterface::SetOutputFile (const std::string& fn) return true; } +void AnimationInterface::EnablePacketMetadata (bool enable) +{ + m_enablePacketMetadata = enable; + if (enable) + Packet::EnablePrinting (); +} + bool AnimationInterface::IsInitialized () { return initialized; @@ -478,12 +488,10 @@ void AnimationInterface::ConnectCallbacks () MakeCallback (&AnimationInterface::DevTxTrace, this)); Config::Connect ("NodeList/*/DeviceList/*/$ns3::WifiNetDevice/Phy/PhyTxBegin", MakeCallback (&AnimationInterface::WifiPhyTxBeginTrace, this)); - Config::Connect ("NodeList/*/DeviceList/*/$ns3::WifiNetDevice/Phy/PhyTxEnd", - MakeCallback (&AnimationInterface::WifiPhyTxEndTrace, this)); Config::Connect ("NodeList/*/DeviceList/*/$ns3::WifiNetDevice/Phy/PhyRxBegin", MakeCallback (&AnimationInterface::WifiPhyRxBeginTrace, this)); Config::Connect ("NodeList/*/DeviceList/*/$ns3::WifiNetDevice/Phy/PhyRxEnd", - MakeCallback (&AnimationInterface::WifiPhyRxEndTrace, this)); + MakeCallback (&AnimationInterface::WifiPhyRxEndTrace, this)); Config::Connect ("NodeList/*/DeviceList/*/$ns3::WifiNetDevice/Mac/MacRx", MakeCallback (&AnimationInterface::WifiMacRxTrace, this)); Config::ConnectWithoutContext ("/NodeList/*/$ns3::MobilityModel/CourseChange", @@ -542,6 +550,10 @@ int AnimationInterface::WriteN (int h, const std::string& st) return WriteN (h, st.c_str (), st.length ()); } +void AnimationInterface::ShowAll802_11 (bool showAll) +{ + m_enforceWifiMacRx = !showAll; +} // Private methods void AnimationInterface::AddMargin () @@ -640,8 +652,8 @@ void AnimationInterface::WriteDummyPacket () double lbRx = now.GetSeconds (); if (m_xml) { - oss << GetXMLOpen_packet (0,0,fbTx,lbTx,"DummyPktIgnoreThis"); - oss << GetXMLOpenClose_rx (0,0,fbRx,lbRx); + oss << GetXMLOpen_packet (0, 0, fbTx, lbTx, "DummyPktIgnoreThis"); + oss << GetXMLOpenClose_rx (0, 0, fbRx, lbRx); oss << GetXMLClose ("packet"); } WriteN (m_fHandle, oss.str ()); @@ -664,8 +676,10 @@ void AnimationInterface::DevTxTrace (std::string context, Ptr p, double lbRx = (now + rxTime).GetSeconds (); if (m_xml) { - oss << GetXMLOpen_packet (0,tx->GetNode ()->GetId (),fbTx,lbTx); - oss << GetXMLOpenClose_rx (0,rx->GetNode ()->GetId (),fbRx,lbRx); + oss << GetXMLOpen_packet (0, tx->GetNode ()->GetId (), fbTx, lbTx); + oss << GetXMLOpenClose_rx (0, rx->GetNode ()->GetId (), fbRx, lbRx); + if (m_enablePacketMetadata) + oss << GetXMLOpenClose_meta (GetPacketMetadata (p)); oss << GetXMLClose ("packet"); } else @@ -778,6 +792,8 @@ void AnimationInterface::WifiPhyRxBeginTrace (std::string context, return; Ptr ndev = GetNetDeviceFromContext (context); NS_ASSERT (ndev); + Ptr n = ndev->GetNode (); + NS_ASSERT (n); uint64_t AnimUid = GetAnimUidFromPacket (p); NS_LOG_INFO ("RxBeginTrace for packet:" << AnimUid); if (!WifiPacketIsPending (AnimUid)) @@ -787,6 +803,10 @@ void AnimationInterface::WifiPhyRxBeginTrace (std::string context, } // TODO: NS_ASSERT (WifiPacketIsPending (AnimUid) == true); pendingWifiPackets[AnimUid].ProcessRxBegin (ndev, Simulator::Now ()); + if (m_enforceWifiMacRx) + return; + pendingWifiPackets[AnimUid].ProcessRxEnd (ndev, Simulator::Now (), UpdatePosition (n)); + OutputWirelessPacket (p, pendingWifiPackets[AnimUid], pendingWifiPackets[AnimUid].GetRxInfo (ndev)); } @@ -813,6 +833,8 @@ void AnimationInterface::WifiPhyRxEndTrace (std::string context, void AnimationInterface::WifiMacRxTrace (std::string context, Ptr p) { + if (!m_enforceWifiMacRx) + return; if (!m_started) return; Ptr ndev = GetNetDeviceFromContext (context); @@ -831,7 +853,7 @@ void AnimationInterface::WifiMacRxTrace (std::string context, if (pktrxInfo.IsPhyRxComplete ()) { NS_LOG_INFO ("MacRxTrace for packet:" << AnimUid << " complete"); - OutputWirelessPacket (pktInfo, pktrxInfo); + OutputWirelessPacket (p, pktInfo, pktrxInfo); } } @@ -875,7 +897,7 @@ void AnimationInterface::WimaxRxTrace (std::string context, Ptr p, pktInfo.ProcessRxEnd (ndev, Simulator::Now () + Seconds (0.001), UpdatePosition (n)); //TODO 0.001 is used until Wimax implements RxBegin and RxEnd traces AnimRxInfo pktrxInfo = pktInfo.GetRxInfo (ndev); - OutputWirelessPacket (pktInfo, pktrxInfo); + OutputWirelessPacket (p, pktInfo, pktrxInfo); } void AnimationInterface::LteTxTrace (std::string context, Ptr p, const Mac48Address & m) @@ -917,7 +939,7 @@ void AnimationInterface::LteRxTrace (std::string context, Ptr p, c pktInfo.ProcessRxEnd (ndev, Simulator::Now () + Seconds (0.001), UpdatePosition (n)); //TODO 0.001 is used until Lte implements RxBegin and RxEnd traces AnimRxInfo pktrxInfo = pktInfo.GetRxInfo (ndev); - OutputWirelessPacket (pktInfo, pktrxInfo); + OutputWirelessPacket (p, pktInfo, pktrxInfo); } @@ -1001,7 +1023,7 @@ void AnimationInterface::CsmaMacRxTrace (std::string context, if (pktrxInfo.IsPhyRxComplete ()) { NS_LOG_INFO ("MacRxTrace for packet:" << AnimUid << " complete"); - OutputCsmaPacket (pktInfo, pktrxInfo); + OutputCsmaPacket (p, pktInfo, pktrxInfo); } } @@ -1072,6 +1094,12 @@ void AnimationInterface::MobilityAutoCheck () } } +std::string AnimationInterface::GetPacketMetadata (Ptr p) +{ + std::ostringstream oss; + p->Print (oss); + return oss.str (); +} // Helper to output a wireless packet. // For now, only the XML interface is supported @@ -1124,7 +1152,7 @@ std::string AnimationInterface::GetPreamble () return s; } -void AnimationInterface::OutputWirelessPacket (AnimPacketInfo &pktInfo, AnimRxInfo pktrxInfo) +void AnimationInterface::OutputWirelessPacket (Ptr p, AnimPacketInfo &pktInfo, AnimRxInfo pktrxInfo) { NS_ASSERT (m_xml); std::ostringstream oss; @@ -1136,12 +1164,14 @@ void AnimationInterface::OutputWirelessPacket (AnimPacketInfo &pktInfo, AnimRxIn uint32_t rxId = pktrxInfo.m_rxnd->GetNode ()->GetId (); oss << GetXMLOpenClose_rx (0, rxId, pktrxInfo.m_fbRx, pktrxInfo.m_lbRx); + if (m_enablePacketMetadata) + oss << GetXMLOpenClose_meta (GetPacketMetadata (p)); oss << GetXMLClose ("wpacket"); WriteN (m_fHandle, oss.str ()); } -void AnimationInterface::OutputCsmaPacket (AnimPacketInfo &pktInfo, AnimRxInfo pktrxInfo) +void AnimationInterface::OutputCsmaPacket (Ptr p, AnimPacketInfo &pktInfo, AnimRxInfo pktrxInfo) { NS_ASSERT (m_xml); std::ostringstream oss; @@ -1151,6 +1181,8 @@ void AnimationInterface::OutputCsmaPacket (AnimPacketInfo &pktInfo, AnimRxInfo p oss << GetXMLOpen_packet (0, nodeId, pktInfo.m_fbTx, pktInfo.m_lbTx); uint32_t rxId = pktrxInfo.m_rxnd->GetNode ()->GetId (); oss << GetXMLOpenClose_rx (0, rxId, pktrxInfo.m_fbRx, pktrxInfo.m_lbRx); + if (m_enablePacketMetadata) + oss << GetXMLOpenClose_meta (GetPacketMetadata (p)); oss << GetXMLClose ("packet"); WriteN (m_fHandle, oss.str ()); } @@ -1241,6 +1273,14 @@ std::string AnimationInterface::GetXMLOpenClose_rx (uint32_t toLp, uint32_t toId return oss.str (); } +std::string AnimationInterface::GetXMLOpenClose_meta (std::string metaInfo) +{ + std::ostringstream oss; + oss << "" << std::endl; + return oss.str (); +} + std::vector AnimationInterface::GetElementsFromContext (std::string context) { std::vector elements; diff --git a/src/netanim/model/animation-interface.h b/src/netanim/model/animation-interface.h index 2e6727463..9c45c69a8 100644 --- a/src/netanim/model/animation-interface.h +++ b/src/netanim/model/animation-interface.h @@ -217,6 +217,22 @@ public: */ bool IsStarted (void); + /** + * \brief Show all 802.11 frames. Default: show only frames accepted by mac layer + * \param showAll if true shows all 802.11 frames including beacons, association + * request and acks (very chatty). if false only frames accepted by mac layer + * + */ + void ShowAll802_11 (bool showAll); + + /** + * + * \brief Enable Packet metadata + * \param enable if true enables writing the packet metadata to the XML trace file + * if false disables writing the packet metadata + */ + void EnablePacketMetadata (bool enable); + private: #ifndef WIN32 int m_fHandle; // File handle for output (-1 if none) @@ -281,8 +297,8 @@ private: // Write a string to the specified handle; int WriteN (int, const std::string&); - void OutputWirelessPacket (AnimPacketInfo& pktInfo, AnimRxInfo pktrxInfo); - void OutputCsmaPacket (AnimPacketInfo& pktInfo, AnimRxInfo pktrxInfo); + void OutputWirelessPacket (Ptr p, AnimPacketInfo& pktInfo, AnimRxInfo pktrxInfo); + void OutputCsmaPacket (Ptr p, AnimPacketInfo& pktInfo, AnimRxInfo pktrxInfo); void MobilityAutoCheck (); uint64_t gAnimUid ; // Packet unique identifier used by Animtion @@ -327,6 +343,8 @@ private: void ConnectCallbacks (); bool m_started; + bool m_enforceWifiMacRx; + bool m_enablePacketMetadata; // Path helper std::vector GetElementsFromContext (std::string context); @@ -340,6 +358,8 @@ private: double topo_maxX; double topo_maxY; + std::string GetPacketMetadata (Ptr p); + std::string GetXMLOpen_anim (uint32_t lp); std::string GetXMLOpen_topology (double minX,double minY,double maxX,double maxY); std::string GetXMLOpenClose_node (uint32_t lp,uint32_t id,double locX,double locY); @@ -348,6 +368,7 @@ private: std::string GetXMLOpenClose_rx (uint32_t toLp, uint32_t toId, double fbRx, double lbRx); std::string GetXMLOpen_wpacket (uint32_t fromLp,uint32_t fromId, double fbTx, double lbTx, double range); std::string GetXMLClose (std::string name) {return "\n"; } + std::string GetXMLOpenClose_meta (std::string metaInfo); }; diff --git a/src/stats/model/basic-data-calculators.h b/src/stats/model/basic-data-calculators.h index 75dd5c291..aa6ca4d1d 100644 --- a/src/stats/model/basic-data-calculators.h +++ b/src/stats/model/basic-data-calculators.h @@ -41,6 +41,7 @@ public: virtual ~MinMaxAvgTotalCalculator(); void Update (const T i); + void Reset (); virtual void Output (DataOutputCallback &callback) const; @@ -168,6 +169,24 @@ MinMaxAvgTotalCalculator::Update (const T i) // end MinMaxAvgTotalCalculator::Update } +template +void +MinMaxAvgTotalCalculator::Reset () +{ + m_count = 0; + + m_total = 0; + m_squareTotal = 0; + + m_meanCurr = NaN; + m_sCurr = NaN; + m_varianceCurr = NaN; + + m_meanPrev = NaN; + m_sPrev = NaN; + // end MinMaxAvgTotalCalculator::Reset +} + template void MinMaxAvgTotalCalculator::Output (DataOutputCallback &callback) const diff --git a/src/tools/model/average.h b/src/tools/model/average.h index 4c20a5f21..5c49c67aa 100644 --- a/src/tools/model/average.h +++ b/src/tools/model/average.h @@ -25,6 +25,7 @@ #include #include #include +#include "ns3/basic-data-calculators.h" namespace ns3 { @@ -45,28 +46,28 @@ class Average { public: Average () - : m_size (0), m_min (std::numeric_limits::max ()), m_max (0), - m_avg (0), m_avg2 (0) + : m_size (0), m_min (std::numeric_limits::max ()), m_max (0) { } /// Add new sample void Update (T const & x) { + // Give the variance calculator the next value. + m_varianceCalculator.Update (x); + m_min = std::min (x, m_min); m_max = std::max (x, m_max); - m_avg = (m_size * m_avg + x) / (m_size + 1); - m_avg2 = (m_size * m_avg2 + x * x) / (m_size + 1); m_size++; } /// Reset statistics void Reset () { + m_varianceCalculator.Reset (); + m_size = 0; m_min = std::numeric_limits::max (); m_max = 0; - m_avg = 0; - m_avg2 = 0; } ///\name Sample statistics @@ -78,11 +79,11 @@ public: /// Maximum T Max () const { return m_max; } /// Sample average - double Avg () const { return m_avg; } + double Avg () const { return m_varianceCalculator.getMean ();} /// Estimate of mean, alias to Avg double Mean () const { return Avg (); } /// Unbiased estimate of variance - double Var () const { return Count () / (double)(Count () - 1) * (m_avg2 - m_avg*m_avg); } + double Var () const { return m_varianceCalculator.getVariance ();} /// Standard deviation double Stddev () const { return sqrt (Var ()); } //\} @@ -107,7 +108,7 @@ public: private: uint32_t m_size; T m_min, m_max; - double m_avg, m_avg2; + MinMaxAvgTotalCalculator m_varianceCalculator; }; /// Print avg (err) [min, max] diff --git a/src/tools/test/average-test-suite.cc b/src/tools/test/average-test-suite.cc new file mode 100644 index 000000000..e7ca1374b --- /dev/null +++ b/src/tools/test/average-test-suite.cc @@ -0,0 +1,272 @@ +/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */ +/* + * Copyright (c) 2012 University of Washington + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 as + * published by the Free Software Foundation; + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + * + * Author: Mitch Watrous (watrous@u.washington.edu) + */ + +#include + +#include "ns3/test.h" +#include "ns3/average.h" + +using namespace ns3; + +const double TOLERANCE = 1e-14; + +// =========================================================================== +// Test case for a single integer. +// =========================================================================== + +class OneIntegerTestCase : public TestCase +{ +public: + OneIntegerTestCase (); + virtual ~OneIntegerTestCase (); + +private: + virtual void DoRun (void); +}; + +OneIntegerTestCase::OneIntegerTestCase () + : TestCase ("Average Object Test using One Integer") + +{ +} + +OneIntegerTestCase::~OneIntegerTestCase () +{ +} + +void +OneIntegerTestCase::DoRun (void) +{ + Average calculator; + + long count = 1; + + double sum = 0; + double sqrSum = 0; + double min; + double max; + double mean; + double stddev; + double variance; + + // Put all of the values into the calculator. + int multiple = 5; + int value; + for (long i = 0; i < count; i++) + { + value = multiple * (i + 1); + + calculator.Update (value); + + sum += value; + sqrSum += value * value; + } + + // Calculate the expected values for the statistical functions. + min = multiple; + max = multiple * count; + mean = sum / count; + if (count == 1) + { + variance = 0; + } + else + { + variance = (count * sqrSum - sum * sum) / (count * (count - 1)); + } + stddev = sqrt (variance); + + // Test the calculator. + NS_TEST_ASSERT_MSG_EQ_TOL (calculator.Count (), count, TOLERANCE, "Count value wrong"); + NS_TEST_ASSERT_MSG_EQ_TOL (calculator.Min (), min, TOLERANCE, "Min value wrong"); + NS_TEST_ASSERT_MSG_EQ_TOL (calculator.Max (), max, TOLERANCE, "Max value wrong"); + NS_TEST_ASSERT_MSG_EQ_TOL (calculator.Mean (), mean, TOLERANCE, "Mean value wrong"); + NS_TEST_ASSERT_MSG_EQ_TOL (calculator.Stddev (), stddev, TOLERANCE, "Stddev value wrong"); + NS_TEST_ASSERT_MSG_EQ_TOL (calculator.Var (), variance, TOLERANCE, "Variance value wrong"); +} + + +// =========================================================================== +// Test case for five integers. +// =========================================================================== + +class FiveIntegersTestCase : public TestCase +{ +public: + FiveIntegersTestCase (); + virtual ~FiveIntegersTestCase (); + +private: + virtual void DoRun (void); +}; + +FiveIntegersTestCase::FiveIntegersTestCase () + : TestCase ("Average Object Test using Five Integers") + +{ +} + +FiveIntegersTestCase::~FiveIntegersTestCase () +{ +} + +void +FiveIntegersTestCase::DoRun (void) +{ + Average calculator; + + long count = 5; + + double sum = 0; + double sqrSum = 0; + double min; + double max; + double mean; + double stddev; + double variance; + + // Put all of the values into the calculator. + int multiple = 5; + int value; + for (long i = 0; i < count; i++) + { + value = multiple * (i + 1); + + calculator.Update (value); + + sum += value; + sqrSum += value * value; + } + + // Calculate the expected values for the statistical functions. + min = multiple; + max = multiple * count; + mean = sum / count; + if (count == 1) + { + variance = 0; + } + else + { + variance = (count * sqrSum - sum * sum) / (count * (count - 1)); + } + stddev = sqrt (variance); + + // Test the calculator. + NS_TEST_ASSERT_MSG_EQ_TOL (calculator.Count (), count, TOLERANCE, "Count value wrong"); + NS_TEST_ASSERT_MSG_EQ_TOL (calculator.Min (), min, TOLERANCE, "Min value wrong"); + NS_TEST_ASSERT_MSG_EQ_TOL (calculator.Max (), max, TOLERANCE, "Max value wrong"); + NS_TEST_ASSERT_MSG_EQ_TOL (calculator.Mean (), mean, TOLERANCE, "Mean value wrong"); + NS_TEST_ASSERT_MSG_EQ_TOL (calculator.Stddev (), stddev, TOLERANCE, "Stddev value wrong"); + NS_TEST_ASSERT_MSG_EQ_TOL (calculator.Var (), variance, TOLERANCE, "Variance value wrong"); +} + + +// =========================================================================== +// Test case for five double values. +// =========================================================================== + +class FiveDoublesTestCase : public TestCase +{ +public: + FiveDoublesTestCase (); + virtual ~FiveDoublesTestCase (); + +private: + virtual void DoRun (void); +}; + +FiveDoublesTestCase::FiveDoublesTestCase () + : TestCase ("Average Object Test using Five Double Values") + +{ +} + +FiveDoublesTestCase::~FiveDoublesTestCase () +{ +} + +void +FiveDoublesTestCase::DoRun (void) +{ + Average calculator; + + long count = 5; + + double sum = 0; + double sqrSum = 0; + double min; + double max; + double mean; + double stddev; + double variance; + + // Put all of the values into the calculator. + double multiple = 3.14; + double value; + for (long i = 0; i < count; i++) + { + value = multiple * (i + 1); + + calculator.Update (value); + + sum += value; + sqrSum += value * value; + } + + // Calculate the expected values for the statistical functions. + min = multiple; + max = multiple * count; + mean = sum / count; + if (count == 1) + { + variance = 0; + } + else + { + variance = (count * sqrSum - sum * sum) / (count * (count - 1)); + } + stddev = sqrt (variance); + + // Test the calculator. + NS_TEST_ASSERT_MSG_EQ_TOL (calculator.Count (), count, TOLERANCE, "Count value wrong"); + NS_TEST_ASSERT_MSG_EQ_TOL (calculator.Min (), min, TOLERANCE, "Min value wrong"); + NS_TEST_ASSERT_MSG_EQ_TOL (calculator.Max (), max, TOLERANCE, "Max value wrong"); + NS_TEST_ASSERT_MSG_EQ_TOL (calculator.Mean (), mean, TOLERANCE, "Mean value wrong"); + NS_TEST_ASSERT_MSG_EQ_TOL (calculator.Stddev (), stddev, TOLERANCE, "Stddev value wrong"); + NS_TEST_ASSERT_MSG_EQ_TOL (calculator.Var (), variance, TOLERANCE, "Variance value wrong"); +} + + +class AverageTestSuite : public TestSuite +{ +public: + AverageTestSuite (); +}; + +AverageTestSuite::AverageTestSuite () + : TestSuite ("average", UNIT) +{ + AddTestCase (new OneIntegerTestCase); + AddTestCase (new FiveIntegersTestCase); + AddTestCase (new FiveDoublesTestCase); +} + +static AverageTestSuite averageTestSuite; diff --git a/src/tools/wscript b/src/tools/wscript index b036ee29e..dc901b264 100644 --- a/src/tools/wscript +++ b/src/tools/wscript @@ -2,7 +2,7 @@ def build(bld): - module = bld.create_ns3_module('tools', ['network']) + module = bld.create_ns3_module('tools', ['network', 'stats']) module.source = [ 'model/event-garbage-collector.cc', 'model/gnuplot.cc', @@ -11,6 +11,7 @@ def build(bld): module_test = bld.create_ns3_module_test_library('tools') module_test.source = [ + 'test/average-test-suite.cc', 'test/event-garbage-collector-test-suite.cc', ]