merge with HEAD
This commit is contained in:
@@ -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
|
||||
------------
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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.
|
||||
|
||||
@@ -840,7 +840,7 @@ RoutingProtocol::SendPeriodicUpdate ()
|
||||
m_routingTable.Purge (removedAddresses);
|
||||
MergeTriggerPeriodicUpdates ();
|
||||
m_routingTable.GetListOfAllRoutes (allRoutes);
|
||||
if (allRoutes.size () < 0)
|
||||
if (allRoutes.empty ())
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
@@ -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 ();
|
||||
}
|
||||
|
||||
@@ -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> ipv4)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Formatted like output of "route -n" command
|
||||
void
|
||||
Ipv4StaticRouting::PrintRoutingTable (Ptr<OutputStreamWrapper> stream) const
|
||||
@@ -713,11 +712,11 @@ Ipv4StaticRouting::PrintRoutingTable (Ptr<OutputStreamWrapper> 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<OutputStreamWrapper> 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<OutputStreamWrapper> stream) const
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Ipv4Address
|
||||
Ipv4StaticRouting::SourceAddressSelection (uint32_t interfaceIdx, Ipv4Address dest)
|
||||
{
|
||||
|
||||
@@ -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.
|
||||
|
||||
@@ -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 ();
|
||||
|
||||
@@ -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 ());
|
||||
|
||||
@@ -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);
|
||||
}
|
||||
|
||||
|
||||
@@ -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<Object> ()
|
||||
.AddAttribute ("MaxMultiplier",
|
||||
"XXX",
|
||||
DoubleValue (64.0),
|
||||
"Maximum RTO Multiplier",
|
||||
IntegerValue (64),
|
||||
MakeDoubleAccessor (&RttEstimator::m_maxMultiplier),
|
||||
MakeDoubleChecker<double> ())
|
||||
MakeIntegerChecker<u_int16_t> ())
|
||||
.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<RttEstimator> ()
|
||||
.AddConstructor<RttMeanDeviation> ()
|
||||
.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<double> ())
|
||||
;
|
||||
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<RttEstimator> 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
|
||||
|
||||
@@ -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> 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<RttEstimator> 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<RttEstimator> Copy () const;
|
||||
void Reset ();
|
||||
void Gain (double g) { gain = g; }
|
||||
|
||||
public:
|
||||
double gain; // Filter gain
|
||||
int64x64_t variance; // Current variance
|
||||
Ptr<RttEstimator> 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
|
||||
|
||||
|
||||
@@ -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++;
|
||||
}
|
||||
|
||||
158
src/netanim/examples/wireless-animation.cc
Normal file
158
src/netanim/examples/wireless-animation.cc
Normal file
@@ -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;
|
||||
}
|
||||
@@ -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'
|
||||
|
||||
@@ -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<const Packet> 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 <NetDevice> ndev = GetNetDeviceFromContext (context);
|
||||
NS_ASSERT (ndev);
|
||||
Ptr <Node> 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<const Packet> p)
|
||||
{
|
||||
if (!m_enforceWifiMacRx)
|
||||
return;
|
||||
if (!m_started)
|
||||
return;
|
||||
Ptr <NetDevice> 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<const Packet> 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<const Packet> p, const Mac48Address & m)
|
||||
@@ -917,7 +939,7 @@ void AnimationInterface::LteRxTrace (std::string context, Ptr<const Packet> 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<const Packet> 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<const Packet> 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<const Packet> 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 << "<meta info=\""
|
||||
<< metaInfo << "\" />" << std::endl;
|
||||
return oss.str ();
|
||||
}
|
||||
|
||||
std::vector<std::string> AnimationInterface::GetElementsFromContext (std::string context)
|
||||
{
|
||||
std::vector <std::string> elements;
|
||||
|
||||
@@ -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<const Packet> p, AnimPacketInfo& pktInfo, AnimRxInfo pktrxInfo);
|
||||
void OutputCsmaPacket (Ptr<const Packet> 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<std::string> GetElementsFromContext (std::string context);
|
||||
@@ -340,6 +358,8 @@ private:
|
||||
double topo_maxX;
|
||||
double topo_maxY;
|
||||
|
||||
std::string GetPacketMetadata (Ptr<const Packet> 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 "</" + name + ">\n"; }
|
||||
std::string GetXMLOpenClose_meta (std::string metaInfo);
|
||||
|
||||
};
|
||||
|
||||
|
||||
@@ -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<T>::Update (const T i)
|
||||
// end MinMaxAvgTotalCalculator::Update
|
||||
}
|
||||
|
||||
template <typename T>
|
||||
void
|
||||
MinMaxAvgTotalCalculator<T>::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 <typename T>
|
||||
void
|
||||
MinMaxAvgTotalCalculator<T>::Output (DataOutputCallback &callback) const
|
||||
|
||||
@@ -25,6 +25,7 @@
|
||||
#include <ostream>
|
||||
#include <limits>
|
||||
#include <stdint.h>
|
||||
#include "ns3/basic-data-calculators.h"
|
||||
|
||||
namespace ns3 {
|
||||
|
||||
@@ -45,28 +46,28 @@ class Average
|
||||
{
|
||||
public:
|
||||
Average ()
|
||||
: m_size (0), m_min (std::numeric_limits<T>::max ()), m_max (0),
|
||||
m_avg (0), m_avg2 (0)
|
||||
: m_size (0), m_min (std::numeric_limits<T>::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<T>::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<double> m_varianceCalculator;
|
||||
};
|
||||
|
||||
/// Print avg (err) [min, max]
|
||||
|
||||
272
src/tools/test/average-test-suite.cc
Normal file
272
src/tools/test/average-test-suite.cc
Normal file
@@ -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 <math.h>
|
||||
|
||||
#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<int> 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<int> 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<double> 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;
|
||||
@@ -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',
|
||||
]
|
||||
|
||||
|
||||
Reference in New Issue
Block a user