merge with HEAD

This commit is contained in:
Mathieu Lacage
2012-03-22 19:38:33 +01:00
22 changed files with 810 additions and 242 deletions

View File

@@ -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
------------

View File

@@ -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;

View File

@@ -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

View File

@@ -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.

View File

@@ -840,7 +840,7 @@ RoutingProtocol::SendPeriodicUpdate ()
m_routingTable.Purge (removedAddresses);
MergeTriggerPeriodicUpdates ();
m_routingTable.GetListOfAllRoutes (allRoutes);
if (allRoutes.size () < 0)
if (allRoutes.empty ())
{
return;
}

View File

@@ -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 ();
}

View File

@@ -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)
{

View File

@@ -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.

View File

@@ -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 ();

View File

@@ -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 ());

View File

@@ -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);
}

View File

@@ -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

View File

@@ -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

View File

@@ -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++;
}

View 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;
}

View File

@@ -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'

View File

@@ -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;

View File

@@ -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);
};

View File

@@ -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

View File

@@ -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]

View 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;

View File

@@ -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',
]