Merge with code.nsnam.org

This commit is contained in:
Kirill Andreev
2009-07-16 14:57:43 +04:00
67 changed files with 1381 additions and 457 deletions

View File

@@ -35,3 +35,4 @@ dfd0bc16dc991313896f351530a3dc5a25f62e15 ns-3.3-RC4
13a5b15fbe3429a6c3d00c1bccffa2c156a0603b ns-3.5-rc1
8562a42accf6f715d312c037326ec7da48095e13 ns-3.5-rc2
a600c11ff8d40a40e88c2d692acad6512dde70c8 ns-3.5-rc3
c975274c9707b1f07d94cc51f205c351122131a5 ns-3.5

View File

@@ -43,6 +43,39 @@ the cracks, unfortunately. If you, as a user, can suggest improvements
to this file based on your experience, please contribute a patch or drop
us a note on ns-developers mailing list. </p>
<hr>
<h1>Changes from ns-3.5 to ns-3.6</h1>
<h2>Changes to build system:</h2>
<ul>
</ul>
<h2>New API:</h2>
<ul>
</ul>
<h2>Changes to existing API:</h2>
<ul>
<li><b>InterferenceHelper</b>
<p>The method InterferenceHelper::CalculateTxDuration (uint32_t size, WifiMode payloadMode, WifiPreamble preamble) has been made static, so that the frame duration depends only on the characteristics of the frame (i.e., the function parameters) and not on the particular standard which is used by the receiving PHY. This makes it now possible to correctly calculate the duration of incoming frames in scenarios in which devices using different PHY configurations coexist in the same channel (e.g., a BSS using short preamble and another BSS using long preamble). </p>
<p> The following member methods have been added to InterferenceHelper:</p>
<pre>
static WifiMode GetPlcpHeaderMode (WifiMode, WifiPreamble);
static uint32_t GetPlcpHeaderDurationMicroSeconds (WifiMode, WifiPreamble);
static uint32_t GetPlcpPreambleDurationMicroSeconds (WifiMode, WifiPreamble);
static uint32_t GetPayloadDurationMicroSeconds (size, WifiMode); </pre>
<p> The following member methods have been removed from InterferenceHelper:</p>
<pre>
void Configure80211aParameters (void);
void Configure80211bParameters (void);
void Configure80211_10MhzParameters (void);
void Configure80211_5MhzParameters (void);</pre>
</li>
<li><b>WifiMode</b>
<p>WifiMode now has a WifiPhyStandard attribute which identifies the standard the WifiMode belongs to. To properly set this attribute when creating a new WifiMode, it is now required to explicitly pass a WifiPhyStandard parameter to all WifiModeFactory::CreateXXXX() methods. The WifiPhyStandard value of an existing WifiMode can be retrieved using the new method WifiMode::GetStandard().</p>
</li>
</ul>
<hr>
<h1>Changes from ns-3.4 to ns-3.5</h1>
@@ -81,7 +114,24 @@ fragmentation and reassembly.
<li><b>Ipv4Interface::GetMtu () deleted</b>
<p>The Ipv4Interface API is private to internet-stack module; this method
was just a pass-through to GetDevice ()->GetMtu ().
was just a pass-through to GetDevice ()-&gt;GetMtu ().
</p>
</li>
<li><b>GlobalRouteManager::PopulateRoutingTables () and RecomputeRoutingTables () are deprecated </b>
<p>This API has been moved to the helper API and the above functions will
be removed in ns-3.6. The new API is:
<pre>
Ipv4GlobalRoutingHelper::PopulateRoutingTables ();
Ipv4GlobalRoutingHelper::RecomputeRoutingTables ();
</pre>
Additionally, these low-level functions in GlobalRouteManager are now public,
allowing more API flexibility at the low level ns-3 API:
<pre>
GlobalRouteManager::DeleteGlobalRoutes ();
GlobalRouteManager::BuildGlobalRoutingDatabase ();
GlobalRouteManager::InitializeRoutes ();
</pre>
</p>
</li>
@@ -141,16 +191,16 @@ GlobalValue::Bind ("ChecksumEnabled", BooleanValue (true));
<p>
To accommodate support for the radiotap and prism headers in PCAP traces, the interface for promiscuos mode sniff in the wifi device was changed. The new implementation was heavily inspired by the way the madwifi driver handles monitor mode. A distinction between TX and RX events is introduced, to account for the fact that different information is to be put in the radiotap/prism header (e.g., RSSI and noise make sense only for RX packets). The following are the relevant modifications to the WifiPhy class:
<pre>
- void NotifyPromiscSniff (Ptr<const Packet> packet);
+ void NotifyPromiscSniffRx (Ptr<const Packet> packet, uint16_t channelFreqMhz, uint32_t rate, bool isShortPreamble, double signalDbm, double noiseDbm);
+ void NotifyPromiscSniffTx (Ptr<const Packet> packet, uint16_t channelFreqMhz, uint32_t rate, bool isShortPreamble);
- TracedCallback<Ptr<const Packet> > m_phyPromiscSnifferTrace;
+ TracedCallback<Ptr<const Packet>, uint16_t, uint32_t, bool, double, double> m_phyPromiscSniffRxTrace;
+ TracedCallback<Ptr<const Packet>, uint16_t, uint32_t, bool> m_phyPromiscSniffTxTrace;
- void NotifyPromiscSniff (Ptr&lt;const Packet&gt; packet);
+ void NotifyPromiscSniffRx (Ptr&lt;const Packet&gt; packet, uint16_t channelFreqMhz, uint32_t rate, bool isShortPreamble, double signalDbm, double noiseDbm);
+ void NotifyPromiscSniffTx (Ptr&lt;const Packet&gt; packet, uint16_t channelFreqMhz, uint32_t rate, bool isShortPreamble);
- TracedCallback&lt;Ptr&lt;const Packet&gt; &gt; m_phyPromiscSnifferTrace;
+ TracedCallback&lt;Ptr&lt;const Packet&gt;, uint16_t, uint32_t, bool, double, double&gt; m_phyPromiscSniffRxTrace;
+ TracedCallback&lt;Ptr&lt;const Packet&gt;, uint16_t, uint32_t, bool&gt; m_phyPromiscSniffTxTrace;
</pre>
The above mentioned callbacks are expected to be used to call the following method to write Wifi PCAP traces in promiscuous mode:
<pre>
+ void WriteWifiMonitorPacket(Ptr<const Packet> packet, uint16_t channelFreqMhz, uint32_t rate, bool isShortPreamble, bool isTx, double signalDbm, double noiseDbm);
+ void WriteWifiMonitorPacket(Ptr&lt;const Packet&gt; packet, uint16_t channelFreqMhz, uint32_t rate, bool isShortPreamble, bool isTx, double signalDbm, double noiseDbm);
</pre>
In the above method, the isTx parameter is to be used to differentiate between TX and RX packets. For an example of how to implement these callbacks, see the implementation of PcapSniffTxEvent and PcapSniffRxEvent in src/helper/yans-wifi-helper.cc
</p>
@@ -181,18 +231,18 @@ the general nature of these calls (synchronous routing lookup for
locally originated packets, and an asynchronous, callback-based lookup
for forwarded packets) is still the same.
<pre>
- typedef Callback&lt;void, bool, const Ipv4Route&, Ptr&lt;Packet&gt;, const Ipv4Header&&gt; RouteReplyCallback;
+ typedef Callback&lt;void, Ptr&lt;Ipv4Route&gt;, Ptr&lt;const Packet&gt;, const Ipv4Header &&gt; UnicastForwardCallback;
+ typedef Callback&lt;void, Ptr&lt;Ipv4MulticastRoute&gt;, Ptr&lt;const Packet&gt;, const Ipv4Header &&gt; MulticastForwardCallback;
+ typedef Callback&lt;void, Ptr&lt;const Packet&gt;, const Ipv4Header &, uint32_t &gt; LocalDeliverCallback;
+ typedef Callback&lt;void, Ptr&lt;const Packet&gt;, const Ipv4Header &&gt; ErrorCallback;
- virtual bool RequestInterface (Ipv4Address destination, uint32_t& interface) = 0;
+ virtual Ptr&lt;Ipv4Route&gt; RouteOutput (Ptr&lt;Packet&gt; p, const Ipv4Header &header, uint32_t oif, Socket::SocketErrno &errno) = 0;
- typedef Callback&lt;void, bool, const Ipv4Route&amp;, Ptr&lt;Packet&gt;, const Ipv4Header&amp;&gt; RouteReplyCallback;
+ typedef Callback&lt;void, Ptr&lt;Ipv4Route&gt;, Ptr&lt;const Packet&gt;, const Ipv4Header &amp;&gt; UnicastForwardCallback;
+ typedef Callback&lt;void, Ptr&lt;Ipv4MulticastRoute&gt;, Ptr&lt;const Packet&gt;, const Ipv4Header &amp;&gt; MulticastForwardCallback;
+ typedef Callback&lt;void, Ptr&lt;const Packet&gt;, const Ipv4Header &amp;, uint32_t &gt; LocalDeliverCallback;
+ typedef Callback&lt;void, Ptr&lt;const Packet&gt;, const Ipv4Header &amp;&gt; ErrorCallback;
- virtual bool RequestInterface (Ipv4Address destination, uint32_t&amp; interface) = 0;
+ virtual Ptr&lt;Ipv4Route&gt; RouteOutput (Ptr&lt;Packet&gt; p, const Ipv4Header &amp;header, uint32_t oif, Socket::SocketErrno &amp;errno) = 0;
- virtual bool RequestRoute (uint32_t interface,
- const Ipv4Header &ipHeader,
- const Ipv4Header &amp;ipHeader,
- Ptr&lt;Packet&gt; packet,
- RouteReplyCallback routeReply) = 0;
+ virtual bool RouteInput (Ptr&lt;const Packet&gt; p, const Ipv4Header &header, Ptr&lt;const NetDevice&gt; idev,
+ virtual bool RouteInput (Ptr&lt;const Packet&gt; p, const Ipv4Header &amp;header, Ptr&lt;const NetDevice&gt; idev,
+ UnicastForwardCallback ucb, MulticastForwardCallback mcb,
+ LocalDeliverCallback lcb, ErrorCallback ecb) = 0;
</pre>
@@ -242,16 +292,16 @@ to an Ipv4 interface are instead named "interface".
- static const uint32_t Ipv4RoutingProtocol::IF_INDEX_ANY = 0xffffffff;
+ static const uint32_t Ipv4RoutingProtocol::INTERFACE_ANY = 0xffffffff;
- bool Ipv4RoutingProtocol::RequestIfIndex (Ipv4Address destination, uint32_t& ifIndex);
+ bool Ipv4RoutingProtocol::RequestInterface (Ipv4Address destination, uint32_t& interface);
- bool Ipv4RoutingProtocol::RequestIfIndex (Ipv4Address destination, uint32_t&amp; ifIndex);
+ bool Ipv4RoutingProtocol::RequestInterface (Ipv4Address destination, uint32_t&amp; interface);
(N.B. this particular function is planned to be renamed to RouteOutput() in the
proposed IPv4 routing refactoring)
- uint32_t Ipv4::GetIfIndexByAddress (Ipv4Address addr, Ipv4Mask mask);
+ int_32t Ipv4::GetInterfaceForAddress (Ipv4Address address, Ipv4Mask mask) const;
- bool Ipv4::GetIfIndexForDestination (Ipv4Address dest, uint32_t &ifIndex) const;
+ bool Ipv4::GetInterfaceForDestination (Ipv4Address dest, uint32_t &interface) const;
- bool Ipv4::GetIfIndexForDestination (Ipv4Address dest, uint32_t &amp;ifIndex) const;
+ bool Ipv4::GetInterfaceForDestination (Ipv4Address dest, uint32_t &amp;interface) const;
(N.B. this function is not needed in the proposed Ipv4 routing refactoring)
</pre>
@@ -269,13 +319,13 @@ proposed IPv4 routing refactoring)
<li>Regarding legacy API usage, typically where you once did the following,
using the public Ipv4 class interface (e.g.):
<pre>
ipv4A->SetAddress (ifIndexA, Ipv4Address ("172.16.1.1"));
ipv4A->SetNetworkMask (ifIndexA, Ipv4Mask ("255.255.255.255"));
ipv4A-&gt;SetAddress (ifIndexA, Ipv4Address ("172.16.1.1"));
ipv4A-&gt;SetNetworkMask (ifIndexA, Ipv4Mask ("255.255.255.255"));
</pre>
you now do:
<pre>
Ipv4InterfaceAddress ipv4IfAddrA = Ipv4InterfaceAddress (Ipv4Address ("172.16.1.1"), Ipv4Mask ("255.255.255.255"));
ipv4A->AddAddress (ifIndexA, ipv4IfAddrA);
ipv4A-&gt;AddAddress (ifIndexA, ipv4IfAddrA);
</pre>
<li> At the helper API level, one often gets an address from an interface
container. We preserve the legacy GetAddress (uint32_t i) but it
@@ -293,16 +343,16 @@ Ipv4Address Ipv4InterfaceContainer::GetAddress (uint32_t i)
<li><b>New WifiMacHelper objects</b>
<p>The type of wifi MAC is now set by two new specific helpers, NqosWifiMacHelper for non QoS MACs and QosWifiMacHelper for Qos MACs. They are passed as argument to WifiHelper::Install methods.</li>
<pre>
- void WifiHelper::SetMac (std::string type, std::string n0 = "", const AttributeValue &v0 = EmptyAttributeValue (),...)
- void WifiHelper::SetMac (std::string type, std::string n0 = "", const AttributeValue &amp;v0 = EmptyAttributeValue (),...)
- NetDeviceContainer WifiHelper::Install (const WifiPhyHelper &phyHelper, NodeContainer c) const
+ NetDeviceContainer WifiHelper::Install (const WifiPhyHelper &phyHelper, const WifiMacHelper &macHelper, NodeContainer c) const
- NetDeviceContainer WifiHelper::Install (const WifiPhyHelper &amp;phyHelper, NodeContainer c) const
+ NetDeviceContainer WifiHelper::Install (const WifiPhyHelper &amp;phyHelper, const WifiMacHelper &amp;macHelper, NodeContainer c) const
- NetDeviceContainer WifiHelper::Install (const WifiPhyHelper &phy, Ptr&lt;Node&gt; node) const
+ NetDeviceContainer WifiHelper::Install (const WifiPhyHelper &phy, const WifiMacHelper &mac, Ptr&lt;Node&gt; node) const
- NetDeviceContainer WifiHelper::Install (const WifiPhyHelper &amp;phy, Ptr&lt;Node&gt; node) const
+ NetDeviceContainer WifiHelper::Install (const WifiPhyHelper &amp;phy, const WifiMacHelper &amp;mac, Ptr&lt;Node&gt; node) const
- NetDeviceContainer WifiHelper::Install (const WifiPhyHelper &phy, std::string nodeName) const
+ NetDeviceContainer WifiHelper::Install (const WifiPhyHelper &phy, const WifiMacHelper &mac, std::string nodeName) const
- NetDeviceContainer WifiHelper::Install (const WifiPhyHelper &amp;phy, std::string nodeName) const
+ NetDeviceContainer WifiHelper::Install (const WifiPhyHelper &amp;phy, const WifiMacHelper &amp;mac, std::string nodeName) const
</pre>
See src/helper/nqos-wifi-mac-helper.h and src/helper/qos-wifi-mac-helper.h for more details.
</p>
@@ -334,7 +384,7 @@ the regression tests.</li>
<h2>New API:</h2>
<ul>
<li>XML support has been added to the ConfigStore in /src/contrib/config-store.cc</li>
<li>XML support has been added to the ConfigStore in src/contrib/config-store.cc</li>
<li>The ns-2 calendar queue scheduler option has been ported to src/simulator</li>
@@ -571,15 +621,15 @@ bug 273: constify packet pointers.<br>
The normal and the promiscuous receive callbacks of the NetDevice API
have been changed from:
<pre>
Callback<bool,Ptr<NetDevice>,Ptr<Packet>,uint16_t,const Address &>
Callback<bool,Ptr<NetDevice>, Ptr<Packet>, uint16_t,
const Address &, const Address &, enum PacketType >
Callback&lt;bool,Ptr&lt;NetDevice&gt;,Ptr&lt;Packet&gt;,uint16_t,const Address &amp;&gt;
Callback&lt;bool,Ptr&lt;NetDevice&gt;, Ptr&lt;Packet&gt;, uint16_t,
const Address &amp;, const Address &amp;, enum PacketType &gt;
</pre>
to:
<pre>
Callback<bool,Ptr<NetDevice>,Ptr<const Packet>,uint16_t,const Address &>
Callback<bool,Ptr<NetDevice>, Ptr<const Packet>, uint16_t,
const Address &, const Address &, enum PacketType >
Callback&lt;bool,Ptr&lt;NetDevice&gt;,Ptr&lt;const Packet&gt;,uint16_t,const Address &amp;&gt;
Callback&lt;bool,Ptr&lt;NetDevice&gt;, Ptr&lt;const Packet&gt;, uint16_t,
const Address &amp;, const Address &amp;, enum PacketType &gt;
</pre>
to avoid the kind of bugs reported in
<a href="http://www.nsnam.org/bugzilla/show_bug.cgi?id=273">bug 273</a>.
@@ -648,7 +698,7 @@ public:
- void SetPort (uint16_t port);
+ UdpEchoServerHelper (uint16_t port);
+
+ void SetAttribute (std::string name, const AttributeValue &value);
+ void SetAttribute (std::string name, const AttributeValue &amp;value);
ApplicationContainer Install (NodeContainer c);
class UdpEchoClientHelper
@@ -657,8 +707,8 @@ public:
- UdpEchoClientHelper ();
+ UdpEchoClientHelper (Ipv4Address ip, uint16_t port);
- void SetRemote (Ipv4Address ip, uint16_t port);
- void SetAppAttribute (std::string name, const AttributeValue &value);
+ void SetAttribute (std::string name, const AttributeValue &value);
- void SetAppAttribute (std::string name, const AttributeValue &amp;value);
+ void SetAttribute (std::string name, const AttributeValue &amp;value);
ApplicationContainer Install (NodeContainer c);
</pre>
</li>

View File

@@ -4,9 +4,7 @@
This file contains ns-3 release notes (most recent releases first).
All of the ns-3 documentation is accessible from the ns-3 website:
http://www.nsnam.org
including tutorials:
http://www.nsnam.org/tutorials.html
http://www.nsnam.org including tutorials: http://www.nsnam.org/tutorials.html
Release 3.5
===========
@@ -14,11 +12,11 @@ Release 3.5
Availability
------------
This release is immediately available from:
http://www.nsnam.org/releases/ns-3.5.tar.bz2
http://www.nsnam.org/releases/ns-allinone-3.5.tar.bz2
Supported platforms
-------------------
ns-3.4 has been tested on the following platforms:
ns-3.5 has been tested on the following platforms:
- linux x86 gcc 4.2, 4.1, and, 3.4.6.
- linux x86_64 gcc 4.4.0, 4.3.2, 4.2.3, 4.2.1, 4.1.3, 3.4.6
- MacOS X ppc and x86 (gcc 4.0.x and 4.2.x)
@@ -64,8 +62,8 @@ Future releases
---------------
Our next release, which is expected to happen in 2 to 4 months from now, will
feature the merging of some of our projects currently in development including
fuller IPv6 support, and some smaller features such as a new Global ARP package
and possibly a new Testing and Validation suite.
fuller IPv6 support, some smaller features such as a new Global ARP
package, and possibly a new Testing and Validation suite.
Release 3.4
===========
@@ -73,7 +71,7 @@ Release 3.4
Availability
------------
This release is immediately available from:
http://www.nsnam.org/releases/ns-3.4.tar.bz2
http://www.nsnam.org/releases/ns-allinone-3.4.tar.bz2
Supported platforms
-------------------

View File

@@ -514,7 +514,8 @@ INPUT_ENCODING = UTF-8
# *.hpp *.h++ *.idl *.odl *.cs *.php *.php3 *.inc *.m *.mm *.py *.f90
FILE_PATTERNS = *.h \
*.tcc
*.tcc \
node-list.cc
# The RECURSIVE tag can be used to turn specify whether or not subdirectories
# should be searched for input files as well. Possible values are YES and NO.

View File

@@ -114,6 +114,7 @@ example: @code{class ns3::Node}.
The public header file node.h has a declaration that includes
a static GetTypeId function call:
@verbatim
class Node : public Object
{
@@ -123,21 +124,72 @@ public:
@end verbatim
This is defined in the node.cc file as follows:
@verbatim
TypeId
Node::GetTypeId (void)
{
static TypeId tid = TypeId ("ns3::Node")
.SetParent<Object> ()
.AddConstructor<Node> ()
.AddAttribute ("DeviceList", "The list of devices associated to this Node.",
ObjectVectorValue (),
MakeObjectVectorAccessor (&Node::m_devices),
MakeObjectVectorChecker<NetDevice> ())
.AddAttribute ("ApplicationList", "The list of applications associated to this Node.",
ObjectVectorValue (),
MakeObjectVectorAccessor (&Node::m_applications),
MakeObjectVectorChecker<Application> ())
.AddAttribute ("Id", "The id (unique integer) of this Node.",
TypeId::ATTR_GET, // allow only getting it.
UintegerValue (0),
MakeUintegerAccessor (&Node::m_id),
MakeUintegerChecker<uint32_t> ())
;
return tid;
}
@end verbatim
Finally, when users want to create Nodes, they call:
Look at the TypeId of an ns-3 @code{Object} class as an extended form of run
time type information (RTTI). The C++ language includes simple kind of RTTI
in order to support @code{dynamic_cast} and @code{typeid} operators.
The ``@code{.SetParent<Object> ()}'' call in the declaration above is used in
conjunction with our object aggregation mechanisms to allow safe up- and
down-casing in inheritance trees during @code{GetObject}.
The ``@code{.AddConstructor<Node> ()}'' call is used in conjunction with our
abstract object factory mechanisms to allow us to construct C++ objects without
forcing a user to know the concrete class of the object she is building.
The three calls to ``@code{.AddAttribute}'' associate a given string with a
strongly typed value in the class. Notice that you must provide a help string
which may be displayed, for example, via command line processors. Each
@code{Attribute} is associated with mechanisms for accessing the underlying
member variable in the object (for example, @code{MakeUintegerAccessor} tells
the generic @code{Attribute} code how to get to the node ID above). There are
also ``Checker'' methods which are used to validate values.
When users want to create Nodes, they will usually call some form of
@code{CreateObject},
@verbatim
Ptr<Node> n = CreateObject<Node> ();
@end verbatim
or more abstractly, using an object factory, you can create a @code{Node} object
without even knowing the concrete C++ type
@verbatim
ObjectFactory factory;
const std::string typeId = "ns3::Node'';
factory.SetTypeId(typeId);
Ptr<Object> node = factory.Create <Object> ();
@end verbatim
Both of these methods result in fully initialized attributes being available
in the resulting @code{Object} instances.
We next discuss how attributes (values associated with member variables
or functions of the class) are plumbed into the above TypeId.
@@ -206,6 +258,7 @@ and some type of global default value.
In the ns-3 attribute system, these value definitions and accessor
functions are moved into the TypeId class; e.g.:
@verbatim
NS_OBJECT_ENSURE_REGISTERED (DropTailQueue);
@@ -358,11 +411,11 @@ Now, let's set it to another value (60 packets)
@subsubsection Namespace-based access
An alternative way to get at the attribute is to use the configuration
namespace. Here, this attribute resides on a known path in this
namespace; this approach is useful if one doesn't have access to
the underlying pointers and would like to configure a specific
attribute with a single statement.
An alternative way to get at the attribute is to use the configuration namespace.
Here, this attribute resides on a known path in this namespace; this approach
is useful if one doesn't have access to the underlying pointers and would like
to configure a specific attribute with a single statement.
@verbatim
Config::Set ("/NodeList/0/DeviceList/0/TxQueue/MaxPackets", UintegerValue (25));
txQueue->GetAttribute ("MaxPackets", limit);
@@ -370,9 +423,8 @@ attribute with a single statement.
limit.Get () << " packets");
@end verbatim
We could have also used wildcards to set this value for all nodes
and all net devices (which in this simple example has the same
effect as the previous Set())
We could have also used wildcards to set this value for all nodes and all net
devices (which in this simple example has the same effect as the previous Set())
@verbatim
Config::Set ("/NodeList/*/DeviceList/*/TxQueue/MaxPackets", UintegerValue (15));
txQueue->GetAttribute ("MaxPackets", limit);
@@ -380,6 +432,22 @@ effect as the previous Set())
limit.Get () << " packets");
@end verbatim
@subsubsection Object Name Service-based access
Another way to get at the attribute is to use the object name service facility.
Here, this attribute is found using a name string. This approach is useful if
one doesn't have access to the underlying pointers and it is difficult to
determine the required concrete configuration namespaced path.
@verbatim
Names::Add ("server", serverNode);
Names::Add ("server/eth0", serverDevice);
...
Config::Set ("/Names/server/eth0/TxQueue/MaxPackets", UintegerValue (25));
@end verbatim
@subsection Setting through constructors helper classes
Arbitrary combinations of attributes can be set and fetched from
@@ -438,13 +506,13 @@ Consider this variable in class TcpSocket:
Suppose that someone working with Tcp wanted to get or set the
value of that variable using the metadata system. If it were not
already provided by ns-3, the user could declare the following addition
in the metadata system (to the TypeId declaration for TcpSocket):
in the runtime metadata system (to the TypeId declaration for TcpSocket):
@verbatim
.AddParameter ("Congestion window",
.AddAttribute ("Congestion window",
"Tcp congestion window (bytes)",
Uinteger (1),
UintegerValue (1),
MakeUintegerAccessor (&TcpSocket::m_cWnd),
MakeUintegerChecker<uint16_t> ());
MakeUintegerChecker<uint16_t> ())
@end verbatim
@@ -511,21 +579,26 @@ wants to hook it in to the attribute system, there is mainly the matter
of writing
the conversions to/from strings and attribute values. Most of this can be
copy/pasted with macro-ized code. For instance, consider class
Rectangle in the @code{src/mobility/} directory:
delcaration for Rectangle in the @code{src/mobility/} directory:
One line is added to the class declaration:
@verbatim
/**
* \brief a 2d rectangle
*/
class Rectangle
{
...
...
double xMin;
double xMax;
double yMin;
double yMax;
};
@end verbatim
One macro call and two operators, are added below the class declaration:
One macro call and two operators, must be added below the class declaration
in order to turn a Rectangle into a value usable by the @code{Attribute}
system:
@verbatim
std::ostream &operator << (std::ostream &os, const Rectangle &rectangle);
@@ -534,7 +607,7 @@ std::istream &operator >> (std::istream &is, Rectangle &rectangle);
ATTRIBUTE_HELPER_HEADER (Rectangle);
@end verbatim
In the class definition, the code looks like this:
In the class definition (@code{.cc} file), the code looks like this:
@verbatim
ATTRIBUTE_HELPER_CPP (Rectangle);
@@ -568,9 +641,9 @@ of an instance of the new class.
@node ConfigStore
@section ConfigStore
@strong{Feedback requested:} This is an experimental feature of ns-3.
It is not in the main tree. If you like this feature and would like
to provide feedback on it, please email us.
@strong{Feedback requested:} This is an experimental feature of ns-3. It is
found in @code{src/contrib} and not in the main tree. If you like this feature
and would like to provide feedback on it, please email us.
Values for ns-3 attributes can be stored in an ascii text file and
loaded into a future simulation. This feature is known as the

View File

@@ -121,86 +121,74 @@ ARP, UDP, TCP, and other related protocols.
Internet Nodes are not subclasses of class Node; they are simply Nodes
that have had a bunch of IPv4-related
objects aggregated to them. They can be put together by hand, or
via a helper function @code{AddInternetStack ()} which does the
following:
via a helper function @code{InternetStackHelper::Install ()} which does the
following to all nodes passed in as arguments:
@verbatim
void AddInternetStack (Ptr<Node> node)
void
InternetStackHelper::Install (Ptr<Node> node) const
{
// Create layer-3 protocols
Ptr<Ipv4L3Protocol> ipv4 = CreateObject<Ipv4L3Protocol> ();
Ptr<ArpL3Protocol> arp = CreateObject<ArpL3Protocol> ();
ipv4->SetNode (node);
arp->SetNode (node);
if (node->GetObject<Ipv4> () != 0)
{
NS_FATAL_ERROR ("InternetStackHelper::Install(): Aggregating "
"an InternetStack to a node with an existing Ipv4 object");
return;
}
// Create an L4 demux
Ptr<Ipv4L4Demux> ipv4L4Demux = CreateObject<Ipv4L4Demux> ();
CreateAndAggregateObjectFromTypeId (node, "ns3::ArpL3Protocol");
CreateAndAggregateObjectFromTypeId (node, "ns3::Ipv4L3Protocol");
CreateAndAggregateObjectFromTypeId (node, "ns3::Icmpv4L4Protocol");
CreateAndAggregateObjectFromTypeId (node, "ns3::UdpL4Protocol");
node->AggregateObject (m_tcpFactory.Create<Object> ());
Ptr<PacketSocketFactory> factory = CreateObject<PacketSocketFactory> ();
node->AggregateObject (factory);
// Set routing
Ptr<Ipv4> ipv4 = node->GetObject<Ipv4> ();
Ptr<Ipv4RoutingProtocol> ipv4Routing = m_routing->Create (node);
ipv4->SetRoutingProtocol (ipv4Routing);
}
@end verbatim
// Create transport protocols and insert them into the demux
Ptr<UdpL4Protocol> udp = CreateObject<UdpL4Protocol> ();
Ptr<TcpL4Protocol> tcp = CreateObject<TcpL4Protocol> ();
ipv4L4Demux->SetNode (node);
udp->SetNode (node);
tcp->SetNode (node);
ipv4L4Demux->Insert (udp);
ipv4L4Demux->Insert (tcp);
// Add factories for instantiating transport protocol sockets
Ptr<UdpSocketFactoryImpl> udpFactory = CreateObject<UdpSocketFactoryImpl> ();
Ptr<TcpSocketFactoryImpl> tcpFactory = CreateObject<TcpSocketFactoryImpl> ();
Ptr<Ipv4Impl> ipv4Impl = CreateObject<Ipv4Impl> ();
udpFactory->SetUdp (udp);
tcpFactory->SetTcp (tcp);
ipv4Impl->SetIpv4 (ipv4);
// Aggregate all of these new objects to the node
node->AggregateObject (ipv4);
node->AggregateObject (arp);
node->AggregateObject (ipv4Impl);
node->AggregateObject (udpFactory);
node->AggregateObject (tcpFactory);
node->AggregateObject (ipv4L4Demux);
Note that the Ipv4 routing protocol is configured and set outside this
function. By default, the following protocols are added to Ipv4:
@verbatim
InternetStackHelper::InternetStackHelper ()
{
SetTcp ("ns3::TcpL4Protocol");
static Ipv4StaticRoutingHelper staticRouting;
static Ipv4GlobalRoutingHelper globalRouting;
static Ipv4ListRoutingHelper listRouting;
listRouting.Add (staticRouting, 0);
listRouting.Add (globalRouting, -10);
SetRoutingHelper (listRouting);
}
@end verbatim
@subsection Internet Node structure
The Internet Node (an ns-3 Node augmented by aggregation to have one or more
An IPv4-capable Node (an ns-3 Node augmented by aggregation to have one or more
IP stacks) has the following internal structure.
@subsubsection Layer-3 protocols
At the lowest layer, sitting above the NetDevices, are the "layer 3"
protocols, including IPv4, IPv6, and ARP. These protocols provide
the following key methods and data members:
protocols, including IPv4, IPv6 (in the future), and ARP. The
@code{class Ipv4L3Protocol} is an
implementation class whose public interface is
typically @code{class Ipv4} (found in src/node directory), but the
Ipv4L3Protocol public API is also used internally in the
src/internet-stack directory at present.
In class Ipv4L3Protocol, one method described below is @code{Receive ()}:
@verbatim
class Ipv4L3Protocol : public Object
{
public:
// Add an Ipv4 interface corresponding to the provided NetDevice
uint32_t AddInterface (Ptr<NetDevice> device);
// Receive function that can be bound to a callback, for receiving
// packets up the stack
void Receive( Ptr<NetDevice> device, Ptr<Packet> p, uint16_t protocol,
const Address &from);
// Higher-level layers call this method to send a packet
// down the stack to the MAC and PHY layers
//
void Send (Ptr<Packet> packet, Ipv4Address source,
Ipv4Address destination, uint8_t protocol);
private:
Ipv4InterfaceList m_interfaces;
// Protocol handlers
}
/**
* Lower layer calls this method after calling L3Demux::Lookup
* The ARP subclass needs to know from which NetDevice this
* packet is coming to:
* - implement a per-NetDevice ARP cache
* - send back arp replies on the right device
*/
void Receive( Ptr<NetDevice> device, Ptr<const Packet> p, uint16_t protocol, const Address &from,
const Address &to, NetDevice::PacketType packetType);
@end verbatim
There are many more functions (such as @code{Forward ()}) but we will
focus on the above four items from an architectural perspective.
First, note that the @code{Receive ()} function has a matching signature
to the ReceiveCallback in the @code{class Node}. This function pointer
@@ -228,24 +216,15 @@ to send down to the Ipv4L3Protocol object can call
This class nicely demonstrates two techniques we exploit in
ns-3 to bind objects together: callbacks, and object aggregation.
Once IPv4 has determined that a packet is for the local node, it
Once IPv4 routing has determined that a packet is for the local node, it
forwards it up the stack. This is done with the following function:
@verbatim
void
Ipv4L3Protocol::ForwardUp (Ptr<Packet> p, Ipv4Header const&ip,
Ptr<Ipv4Interface> incomingInterface)
{
NS_LOG_FUNCTION (this << p << &ip);
Ptr<Ipv4L4Demux> demux = m_node->GetObject<Ipv4L4Demux> ();
Ptr<Ipv4L4Protocol> protocol = demux->GetProtocol (ip.GetProtocol ());
protocol->Receive (p, ip.GetSource (), ip.GetDestination (), incomingInterface);
}
Ipv4L3Protocol::LocalDeliver (Ptr<const Packet> packet, Ipv4Header const&ip, uint32_t iif)
@end verbatim
The first step is to find the aggregated Ipv4L4Demux object. Then, this
object is consulted to look up the right Ipv4L4Protocol, based on IP protocol
The first step is to find the right Ipv4L4Protocol object , based on IP protocol
number. For instance, TCP is registered in the demux as protocol number 6.
Finally, the @code{Receive()} function on the Ipv4L4Protocol (such as
@code{TcpL4Protocol::Receive} is called.
@@ -321,10 +300,10 @@ addressing tuple (local port, local address, destination port, destination
address) associated with the socket, and a receive callback for the socket.
@end itemize
@subsection Internet Node interfaces
@subsection Ipv4-capable node interfaces
Many of the implementation details, or internal objects themselves,
of Internet Node objects are not exposed at the simulator public
of Ipv4-capable Node objects are not exposed at the simulator public
API. This allows for different implementations; for instance,
replacing the native ns-3 models with ported TCP/IP stack code.

View File

@@ -106,18 +106,26 @@ reduce computations and runtime performance.
Presently, global centralized IPv4 unicast routing over both
point-to-point and shared (CSMA) links is supported.
By default, when using the ns-3 helper API and the default InternetStackHelper,
global routing capability will be added to the node, and global routing
will be inserted as a routing protocol with lower priority than the
static routes (i.e., users can insert routes via Ipv4StaticRouting API
and they will take precedence over routes found by global routing).
@subsection Global Unicast Routing API
The public API is very minimal. User scripts include the following:
@verbatim
#include "ns3/global-route-manager.h"
#include "ns3/helper-module.h"
@end verbatim
If the default InternetStackHelper is used, then an instance of
global routing will be aggregated to each node.
After IP addresses are configured, the following function call will
cause all of the nodes that have an Ipv4 interface to receive
forwarding tables entered automatically by the GlobalRouteManager:
@verbatim
GlobalRouteManager::PopulateRoutingTables ();
Ipv4GlobalRoutingHelper::PopulateRoutingTables ();
@end verbatim
@emph{Note:} A reminder that the wifi NetDevice will work but does not
@@ -127,7 +135,7 @@ OLSR dynamic routing described below.
It is possible to call this function again in the midst of a simulation
using the following additional public function:
@verbatim
GlobalRouteManager::RecomputeRoutingTables ();
Ipv4GlobalRoutingHelper::RecomputeRoutingTables ();
@end verbatim
which flushes the old tables, queries the nodes for new interface information,
and rebuilds the routes.
@@ -135,7 +143,7 @@ and rebuilds the routes.
For instance, this scheduling call will cause the tables to be rebuilt
at time 5 seconds:
@verbatim
Simulator::Schedule (Seconds (5),&GlobalRouteManager::RecomputeRoutingTables);
Simulator::Schedule (Seconds (5),&Ipv4GlobalRoutingHelper::RecomputeRoutingTables);
@end verbatim
@subsection Global Routing Implementation

View File

@@ -49,14 +49,14 @@
* - an ARP module
* - a UDP and a TCP implementation
*
* @defgroup routing Routing
*
* @defgroup helper Helpers
*
* @defgroup applications Applications
*
* @defgroup mobility Mobility
*
* @defgroup routing Routing
*
* @defgroup constants Constants
* @brief Constants you can change
*

View File

@@ -78,23 +78,33 @@ class Tunnel
bool
N0N1VirtualSend (Ptr<Packet> packet, const Address& source, const Address& dest, uint16_t protocolNumber)
N0VirtualSend (Ptr<Packet> packet, const Address& source, const Address& dest, uint16_t protocolNumber)
{
m_n3Socket->SendTo (packet, 0, InetSocketAddress (m_n3Address, 667));
NS_LOG_DEBUG ("Send to " << m_n3Address << ": " << *packet);
m_n0Socket->SendTo (packet, 0, InetSocketAddress (m_n3Address, 667));
return true;
}
bool
N1VirtualSend (Ptr<Packet> packet, const Address& source, const Address& dest, uint16_t protocolNumber)
{
NS_LOG_DEBUG ("Send to " << m_n3Address << ": " << *packet);
m_n1Socket->SendTo (packet, 0, InetSocketAddress (m_n3Address, 667));
return true;
}
bool
N3VirtualSend (Ptr<Packet> packet, const Address& source, const Address& dest, uint16_t protocolNumber)
{
if (m_rng.GetValue () < 0.25)
{
m_n0Socket->SendTo (packet, 0, InetSocketAddress (m_n0Address, 667));
NS_LOG_DEBUG ("Send to " << m_n0Address << ": " << *packet);
m_n3Socket->SendTo (packet, 0, InetSocketAddress (m_n0Address, 667));
}
else
{
m_n1Socket->SendTo (packet, 0, InetSocketAddress (m_n1Address, 667));
NS_LOG_DEBUG ("Send to " << m_n1Address << ": " << *packet);
m_n3Socket->SendTo (packet, 0, InetSocketAddress (m_n1Address, 667));
}
return true;
}
@@ -102,6 +112,7 @@ class Tunnel
void N3SocketRecv (Ptr<Socket> socket)
{
Ptr<Packet> packet = socket->Recv (65535, 0);
NS_LOG_DEBUG ("N3SocketRecv: " << *packet);
SocketAddressTag socketAddressTag;
packet->RemovePacketTag (socketAddressTag);
m_n3Tap->Receive (packet, 0x0800, m_n3Tap->GetAddress (), m_n3Tap->GetAddress (), NetDevice::PACKET_HOST);
@@ -110,6 +121,7 @@ class Tunnel
void N0SocketRecv (Ptr<Socket> socket)
{
Ptr<Packet> packet = socket->Recv (65535, 0);
NS_LOG_DEBUG ("N0SocketRecv: " << *packet);
SocketAddressTag socketAddressTag;
packet->RemovePacketTag (socketAddressTag);
m_n0Tap->Receive (packet, 0x0800, m_n0Tap->GetAddress (), m_n0Tap->GetAddress (), NetDevice::PACKET_HOST);
@@ -118,6 +130,7 @@ class Tunnel
void N1SocketRecv (Ptr<Socket> socket)
{
Ptr<Packet> packet = socket->Recv (65535, 0);
NS_LOG_DEBUG ("N1SocketRecv: " << *packet);
SocketAddressTag socketAddressTag;
packet->RemovePacketTag (socketAddressTag);
m_n1Tap->Receive (packet, 0x0800, m_n1Tap->GetAddress (), m_n1Tap->GetAddress (), NetDevice::PACKET_HOST);
@@ -144,7 +157,7 @@ public:
// n0 tap device
m_n0Tap = CreateObject<VirtualNetDevice> ();
m_n0Tap->SetAddress (Mac48Address ("11:00:01:02:03:01"));
m_n0Tap->SetSendCallback (MakeCallback (&Tunnel::N0N1VirtualSend, this));
m_n0Tap->SetSendCallback (MakeCallback (&Tunnel::N0VirtualSend, this));
n0->AddDevice (m_n0Tap);
Ptr<Ipv4> ipv4 = n0->GetObject<Ipv4> ();
uint32_t i = ipv4->AddInterface (m_n0Tap);
@@ -154,7 +167,7 @@ public:
// n1 tap device
m_n1Tap = CreateObject<VirtualNetDevice> ();
m_n1Tap->SetAddress (Mac48Address ("11:00:01:02:03:02"));
m_n1Tap->SetSendCallback (MakeCallback (&Tunnel::N0N1VirtualSend, this));
m_n1Tap->SetSendCallback (MakeCallback (&Tunnel::N1VirtualSend, this));
n1->AddDevice (m_n1Tap);
ipv4 = n1->GetObject<Ipv4> ();
i = ipv4->AddInterface (m_n1Tap);
@@ -186,6 +199,8 @@ main (int argc, char *argv[])
#if 0
LogComponentEnable ("VirtualNetDeviceExample", LOG_LEVEL_INFO);
#endif
Packet::EnablePrinting ();
// Set up some default values for the simulation. Use the
Config::SetDefault ("ns3::OnOffApplication::PacketSize", UintegerValue (210));
@@ -260,11 +275,11 @@ main (int argc, char *argv[])
Address (InetSocketAddress (Ipv4Address::GetAny (), port)));
apps = sink.Install (c.Get (3));
apps.Start (Seconds (1.0));
apps.Stop (Seconds (10.0));
//apps.Stop (Seconds (10.0));
// Create a similar flow from n3 to n1, starting at time 1.1 seconds
onoff.SetAttribute ("Remote",
AddressValue (InetSocketAddress (Ipv4Address ("11.0.0.2"), port)));
AddressValue (InetSocketAddress (Ipv4Address ("11.0.0.1"), port)));
apps = onoff.Install (c.Get (3));
apps.Start (Seconds (1.1));
apps.Stop (Seconds (10.0));
@@ -272,7 +287,7 @@ main (int argc, char *argv[])
// Create a packet sink to receive these packets
apps = sink.Install (c.Get (1));
apps.Start (Seconds (1.1));
apps.Stop (Seconds (10.0));
//apps.Stop (Seconds (10.0));
std::ofstream ascii;
ascii.open ("virtual-net-device.tr");

View File

@@ -51,7 +51,7 @@ public:
* to the server). The contents of the data are set to unspecified (don't
* care) by this call.
*
* \warn If you have set the fill data for the echo client using one of the
* \warning If you have set the fill data for the echo client using one of the
* SetFill calls, this will undo those effects.
*
* \param dataSize The size of the echo data you want to sent.
@@ -61,7 +61,7 @@ public:
/**
* Get the number of data bytes that will be sent to the server.
*
* \warn The number of bytes may be modified by calling any one of the
* \warning The number of bytes may be modified by calling any one of the
* SetFill methods. If you have called SetFill, then the number of
* data bytes will correspond to the size of an initialized data buffer.
* If you have not called a SetFill method, the number of data bytes will
@@ -75,7 +75,7 @@ public:
* Set the data fill of the packet (what is sent as data to the server) to
* the zero-terminated contents of the fill string string.
*
* \warn The size of resulting echo packets will be automatically adjusted
* \warning The size of resulting echo packets will be automatically adjusted
* to reflect the size of the fill string -- this means that the PacketSize
* attribute may be changed as a result of this call.
*
@@ -88,7 +88,7 @@ public:
* the repeated contents of the fill byte. i.e., the fill byte will be
* used to initialize the contents of the data packet.
*
* \warn The size of resulting echo packets will be automatically adjusted
* \warning The size of resulting echo packets will be automatically adjusted
* to reflect the dataSize parameter -- this means that the PacketSize
* attribute may be changed as a result of this call.
*
@@ -105,7 +105,7 @@ public:
* accomplished by setting the fillSize set to your desired dataSize
* (and providing an appropriate buffer).
*
* \warn The size of resulting echo packets will be automatically adjusted
* \warning The size of resulting echo packets will be automatically adjusted
* to reflect the dataSize parameter -- this means that the PacketSize
* attribute of the Application may be changed as a result of this call.
*

View File

@@ -118,7 +118,7 @@ public:
* on a nearby channel.
* @param rate the PHY data rate in units of 500kbps (i.e., the same
* units used both for the radiotap and for the prism header)
* @param isPreambleShort true if short preamble is used, false otherwise
* @param isShortPreamble true if short preamble is used, false otherwise
* @param isTx true if packet is being transmitted, false when
* packet is being received
* @param signalDbm signal power in dBm

View File

@@ -174,6 +174,30 @@ GlobalValue::End (void)
{
return GetVector ()->end ();
}
bool
GlobalValue::GetValueByNameFailSafe (std::string name, AttributeValue &value)
{
for (GlobalValue::Iterator gvit = GlobalValue::Begin (); gvit != GlobalValue::End (); ++gvit)
{
if ((*gvit)->GetName () == name)
{
(*gvit)->GetValue (value);
return true;
}
}
return false; // not found
}
void
GlobalValue::GetValueByName (std::string name, AttributeValue &value)
{
if (! GetValueByNameFailSafe (name, value))
{
NS_FATAL_ERROR ("Could not find GlobalValue named \"" << name << "\"");
}
}
GlobalValue::Vector *
GlobalValue::GetVector (void)
{

View File

@@ -35,6 +35,14 @@ namespace ns3 {
*
* Instances of this class are expected to be allocated as static
* global variables and should be used to store configurable global state.
* GlobalValues can be set directly by calling ns3::GlobalValue::SetValue
* but they can also be set through the NS_GLOBAL_VALUE environment variable.
* For example, NS_GLOBAL_VALUE='Name=Value;OtherName=OtherValue;' would set
* global values Name and OtherName to Value and OtherValue respectively.
*
* Users of the ns3::CommandLine class also get the ability to set global
* values through commandline arguments to their program: --Name=Value will
* set global value Name to Value.
*/
class GlobalValue
{
@@ -106,6 +114,30 @@ public:
* \returns an iterator which represents a pointer to the last GlobalValue registered.
*/
static Iterator End (void);
/**
* finds the GlobalValue with the given name and returns its value
*
* @param name the name of the GlobalValue to be found
* @param value where to store the value of the found GlobalValue
*
* @return true if the GlobalValue was found, false otherwise
*/
static bool GetValueByNameFailSafe (std::string name, AttributeValue &value);
/**
* finds the GlobalValue with the given name and returns its
* value. This method cannot fail, i.e., it will trigger a
* NS_FATAL_ERROR if the requested GlobalValue is not found.
*
* @param name the name of the GlobalValue to be found
* @param value where to store the value of the found GlobalValue
*
*/
static void GetValueByName (std::string name, AttributeValue &value);
private:
friend class GlobalValueTests;
static Vector *GetVector (void);

View File

@@ -373,6 +373,13 @@ DynamicCast (Ptr<T2> const&p)
return Ptr<T1> (dynamic_cast<T1 *> (PeekPointer (p)));
}
template <typename T1, typename T2>
Ptr<T1>
StaticCast (Ptr<T2> const&p)
{
return Ptr<T1> (static_cast<T1 *> (PeekPointer (p)));
}
/****************************************************
* Member method implementations.

View File

@@ -115,9 +115,8 @@ public:
* NS-3 has a rich set of random number generators.
* Class RandomVariable defines the base class functionalty
* required for all random number generators. By default, the underlying
* generator is seeded with the time of day, and then deterministically
* creates a sequence of seeds for each subsequent generator that is created.
* The rest of the documentation outlines how to change this behavior.
* generator is seeded all the time with the same seed value and run number
* coming from the ns3::GlobalValue \ref GlobalValueRngSeed "RngSeed" and \ref GlobalValueRngRun "RngRun".
*/
class RandomVariable
{

View File

@@ -115,7 +115,7 @@ private:
#define NS_TEST_ASSERT_EQUAL_FILELINE(got, expected, file, line) \
do { \
if (! ((got) == (expected))) \
if (! ((got) == (expected))) \
{ \
Failure () << file << ":" <<line \
<< ": expected " << (expected) \

View File

@@ -259,14 +259,14 @@ public:
* \return Returns the DataRate to be used by device transmitters.
* with deviceId i.
*/
virtual DataRate GetDataRate (void);
DataRate GetDataRate (void);
/**
* Get the assigned speed-of-light delay of the channel
*
* \return Returns the delay used by the channel.
*/
virtual Time GetDelay (void);
Time GetDelay (void);
private:

View File

@@ -612,6 +612,19 @@ EmuNetDevice::ForwardUp (uint8_t *buf, uint32_t len)
Ptr<Packet> originalPacket = packet->Copy ();
EthernetHeader header (false);
//
// This device could be running in an environment where completely unexpected
// kinds of packets are flying around, so we need to harden things a bit and
// filter out packets we think are completely bogus, so we always check to see
// that the packet is long enough to contain the header we want to remove.
//
if (packet->GetSize() < header.GetSerializedSize())
{
m_phyRxDropTrace (originalPacket);
return;
}
packet->RemoveHeader (header);
NS_LOG_LOGIC ("Pkt source is " << header.GetSource ());
@@ -628,6 +641,16 @@ EmuNetDevice::ForwardUp (uint8_t *buf, uint32_t len)
if (header.GetLengthType () <= 1500)
{
LlcSnapHeader llc;
//
// Check to see that the packet is long enough to possibly contain the
// header we want to remove before just naively calling.
//
if (packet->GetSize() < llc.GetSerializedSize())
{
m_phyRxDropTrace (originalPacket);
return;
}
packet->RemoveHeader (llc);
protocol = llc.GetType ();
}
@@ -787,10 +810,6 @@ EmuNetDevice::SendFrom (Ptr<Packet> packet, const Address &src, const Address &d
header.SetLengthType (packet->GetSize ());
packet->AddHeader (header);
EthernetTrailer trailer;
trailer.CalcFcs (packet);
packet->AddTrailer (trailer);
//
// there's not much meaning associated with the different layers in this
// device, so don't be surprised when they're all stacked together in

View File

@@ -115,6 +115,7 @@ VirtualNetDevice::~VirtualNetDevice()
void VirtualNetDevice::DoDispose()
{
NS_LOG_FUNCTION_NOARGS ();
m_node = 0;
NetDevice::DoDispose ();
}

View File

@@ -379,6 +379,21 @@ DcfManagerTest::RunTests (void)
AddAccessRequest (30, 2, 70, 0);
ExpectCollision (30, 0, 0); // backoff: 0 slots
EndTest ();
// Test shows when two frames are received without interval between
// them:
// 20 60 100 106 110 112
// | rx | rx |sifs | aifsn | tx |
// |
// 30 request access. backoff slots: 0
StartTest (4, 6 , 10);
AddDcfState (1);
AddRxOkEvt (20, 40);
AddRxOkEvt (60, 40);
AddAccessRequest (30, 2, 110, 0);
ExpectCollision (30, 0, 0); // backoff: 0 slots
EndTest ();
// The test below is subject to some discussion because I am
// not sure I understand the intent of the spec here.

View File

@@ -433,7 +433,7 @@ Time
DcfManager::GetAccessGrantStart (void) const
{
Time rxAccessStart;
if (m_lastRxEnd >= m_lastRxStart)
if (!m_rxing)
{
rxAccessStart = m_lastRxEnd;
if (!m_lastRxReceivedOk)

View File

@@ -0,0 +1,193 @@
/* -*- Mode: C++; c-file-style: "gnu"; indent-tabs-mode:nil; -*- */
/*
* Copyright (c) 2009 CTTC
*
* 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: Nicola Baldo <nbaldo@cttc.es>
*/
#include<ns3/object.h>
#include<ns3/log.h>
#include <ns3/test.h>
#include<iostream>
#include"interference-helper.h"
#include"wifi-phy.h"
NS_LOG_COMPONENT_DEFINE ("InterferenceHelperTxDurationTest");
#ifdef RUN_SELF_TESTS
namespace ns3 {
class InterferenceHelperTxDurationTest : public Test {
public:
InterferenceHelperTxDurationTest ();
virtual ~InterferenceHelperTxDurationTest ();
virtual bool RunTests (void);
private:
/**
* Check if the payload tx duration returned by InterferenceHelper
* corresponds to a known value of the pay
*
* @param size size of payload in octets (includes everything after the PLCP header)
* @param payloadMode the WifiMode used
* @param knownPlcpLengthFieldValue the known value of the Length field in the PLCP header
*
* @return true if values correspond, false otherwise
*/
bool CheckPayloadDuration(uint32_t size, WifiMode payloadMode, uint32_t knownDurationMicroSeconds);
/**
* Check if the overall tx duration returned by InterferenceHelper
* corresponds to a known value of the pay
*
* @param size size of payload in octets (includes everything after the PLCP header)
* @param payloadMode the WifiMode used
* @param preamble the WifiPreamble used
* @param knownPlcpLengthFieldValue the known value of the Length field in the PLCP header
*
* @return true if values correspond, false otherwise
*/
bool CheckTxDuration(uint32_t size, WifiMode payloadMode, WifiPreamble preamble, uint32_t knownDurationMicroSeconds);
};
// we need to create one instance of InterferenceHelperTxDurationTest
static InterferenceHelperTxDurationTest interferenceHelperTxDurationTestInstance;
InterferenceHelperTxDurationTest::InterferenceHelperTxDurationTest ()
: Test ("InterferenceHelperTxDuration")
{
}
InterferenceHelperTxDurationTest::~InterferenceHelperTxDurationTest ()
{
}
bool
InterferenceHelperTxDurationTest::CheckPayloadDuration(uint32_t size, WifiMode payloadMode, uint32_t knownDurationMicroSeconds)
{
uint32_t calculatedDurationMicroSeconds = InterferenceHelper::GetPayloadDurationMicroSeconds (size, payloadMode);
if (calculatedDurationMicroSeconds != knownDurationMicroSeconds)
{
std::cerr << " size=" << size
<< " mode=" << payloadMode
<< " known=" << knownDurationMicroSeconds
<< " calculated=" << calculatedDurationMicroSeconds
<< std::endl;
return false;
}
return true;
}
bool
InterferenceHelperTxDurationTest::CheckTxDuration(uint32_t size, WifiMode payloadMode, WifiPreamble preamble, uint32_t knownDurationMicroSeconds)
{
uint32_t calculatedDurationMicroSeconds = InterferenceHelper::CalculateTxDuration (size, payloadMode, preamble).GetMicroSeconds ();
if (calculatedDurationMicroSeconds != knownDurationMicroSeconds)
{
std::cerr << " size=" << size
<< " mode=" << payloadMode
<< " preamble=" << preamble
<< " known=" << knownDurationMicroSeconds
<< " calculated=" << calculatedDurationMicroSeconds
<< std::endl;
return false;
}
return true;
}
bool
InterferenceHelperTxDurationTest::RunTests (void)
{
bool retval = true;
// IEEE Std 802.11-2007 Table 18-2 "Example of LENGTH calculations for CCK"
retval = retval
&& CheckPayloadDuration (1023, WifiPhy::Get11mbb (), 744)
&& CheckPayloadDuration (1024, WifiPhy::Get11mbb (), 745)
&& CheckPayloadDuration (1025, WifiPhy::Get11mbb (), 746)
&& CheckPayloadDuration (1026, WifiPhy::Get11mbb (), 747);
// Similar, but we add PLCP preamble and header durations
// and we test different rates.
// The payload durations for modes other than 11mbb have been
// calculated by hand according to IEEE Std 802.11-2007 18.2.3.5
retval = retval
&& CheckTxDuration (1023, WifiPhy::Get11mbb (), WIFI_PREAMBLE_SHORT, 744 + 96)
&& CheckTxDuration (1024, WifiPhy::Get11mbb (), WIFI_PREAMBLE_SHORT, 745 + 96)
&& CheckTxDuration (1025, WifiPhy::Get11mbb (), WIFI_PREAMBLE_SHORT, 746 + 96)
&& CheckTxDuration (1026, WifiPhy::Get11mbb (), WIFI_PREAMBLE_SHORT, 747 + 96)
&& CheckTxDuration (1023, WifiPhy::Get11mbb (), WIFI_PREAMBLE_LONG, 744 + 192)
&& CheckTxDuration (1024, WifiPhy::Get11mbb (), WIFI_PREAMBLE_LONG, 745 + 192)
&& CheckTxDuration (1025, WifiPhy::Get11mbb (), WIFI_PREAMBLE_LONG, 746 + 192)
&& CheckTxDuration (1026, WifiPhy::Get11mbb (), WIFI_PREAMBLE_LONG, 747 + 192)
&& CheckTxDuration (1023, WifiPhy::Get5_5mbb (), WIFI_PREAMBLE_SHORT, 1488 + 96)
&& CheckTxDuration (1024, WifiPhy::Get5_5mbb (), WIFI_PREAMBLE_SHORT, 1490 + 96)
&& CheckTxDuration (1025, WifiPhy::Get5_5mbb (), WIFI_PREAMBLE_SHORT, 1491 + 96)
&& CheckTxDuration (1026, WifiPhy::Get5_5mbb (), WIFI_PREAMBLE_SHORT, 1493 + 96)
&& CheckTxDuration (1023, WifiPhy::Get5_5mbb (), WIFI_PREAMBLE_LONG, 1488 + 192)
&& CheckTxDuration (1024, WifiPhy::Get5_5mbb (), WIFI_PREAMBLE_LONG, 1490 + 192)
&& CheckTxDuration (1025, WifiPhy::Get5_5mbb (), WIFI_PREAMBLE_LONG, 1491 + 192)
&& CheckTxDuration (1026, WifiPhy::Get5_5mbb (), WIFI_PREAMBLE_LONG, 1493 + 192)
&& CheckTxDuration (1023, WifiPhy::Get2mbb (), WIFI_PREAMBLE_SHORT, 4092 + 96)
&& CheckTxDuration (1024, WifiPhy::Get2mbb (), WIFI_PREAMBLE_SHORT, 4096 + 96)
&& CheckTxDuration (1025, WifiPhy::Get2mbb (), WIFI_PREAMBLE_SHORT, 4100 + 96)
&& CheckTxDuration (1026, WifiPhy::Get2mbb (), WIFI_PREAMBLE_SHORT, 4104 + 96)
&& CheckTxDuration (1023, WifiPhy::Get2mbb (), WIFI_PREAMBLE_LONG, 4092 + 192)
&& CheckTxDuration (1024, WifiPhy::Get2mbb (), WIFI_PREAMBLE_LONG, 4096 + 192)
&& CheckTxDuration (1025, WifiPhy::Get2mbb (), WIFI_PREAMBLE_LONG, 4100 + 192)
&& CheckTxDuration (1026, WifiPhy::Get2mbb (), WIFI_PREAMBLE_LONG, 4104 + 192)
&& CheckTxDuration (1023, WifiPhy::Get1mbb (), WIFI_PREAMBLE_SHORT, 8184 + 96)
&& CheckTxDuration (1024, WifiPhy::Get1mbb (), WIFI_PREAMBLE_SHORT, 8192 + 96)
&& CheckTxDuration (1025, WifiPhy::Get1mbb (), WIFI_PREAMBLE_SHORT, 8200 + 96)
&& CheckTxDuration (1026, WifiPhy::Get1mbb (), WIFI_PREAMBLE_SHORT, 8208 + 96)
&& CheckTxDuration (1023, WifiPhy::Get1mbb (), WIFI_PREAMBLE_LONG, 8184 + 192)
&& CheckTxDuration (1024, WifiPhy::Get1mbb (), WIFI_PREAMBLE_LONG, 8192 + 192)
&& CheckTxDuration (1025, WifiPhy::Get1mbb (), WIFI_PREAMBLE_LONG, 8200 + 192)
&& CheckTxDuration (1026, WifiPhy::Get1mbb (), WIFI_PREAMBLE_LONG, 8208 + 192);
// values from http://mailman.isi.edu/pipermail/ns-developers/2009-July/006226.html
retval = retval && CheckTxDuration (14, WifiPhy::Get1mbb (), WIFI_PREAMBLE_LONG, 304);
// values from
// http://www.oreillynet.com/pub/a/wireless/2003/08/08/wireless_throughput.html
retval = retval
&& CheckTxDuration (1536, WifiPhy::Get11mbb (), WIFI_PREAMBLE_LONG, 1310)
&& CheckTxDuration (76, WifiPhy::Get11mbb (), WIFI_PREAMBLE_LONG, 248)
&& CheckTxDuration (14, WifiPhy::Get11mbb (), WIFI_PREAMBLE_LONG, 203)
&& CheckTxDuration (1536, WifiPhy::Get54mba (), WIFI_PREAMBLE_LONG, 248)
&& CheckTxDuration (76, WifiPhy::Get54mba (), WIFI_PREAMBLE_LONG, 32)
&& CheckTxDuration (14, WifiPhy::Get54mba (), WIFI_PREAMBLE_LONG, 24);
return retval;
}
} //namespace ns3
#endif /* RUN_SELF_TESTS */

View File

@@ -123,8 +123,8 @@ InterferenceHelper::NiChange::operator < (InterferenceHelper::NiChange const &o)
****************************************************************/
InterferenceHelper::InterferenceHelper ()
: m_80211_standard (WIFI_PHY_STANDARD_80211a),
m_errorRateModel (0)
: m_maxPacketDuration (Seconds(0)),
m_errorRateModel (0)
{}
InterferenceHelper::~InterferenceHelper ()
{
@@ -145,6 +145,7 @@ InterferenceHelper::Add (uint32_t size, WifiMode payloadMode,
duration,
rxPowerW);
m_maxPacketDuration = std::max(duration, m_maxPacketDuration);
AppendEvent (event);
return event;
}
@@ -224,57 +225,186 @@ InterferenceHelper::GetEnergyDuration (double energyW)
return end - now;
}
Time
InterferenceHelper::CalculateTxDuration (uint32_t size, WifiMode payloadMode, WifiPreamble preamble) const
WifiMode
InterferenceHelper::GetPlcpHeaderMode (WifiMode payloadMode, WifiPreamble preamble)
{
uint64_t delay = 0;
switch (m_80211_standard)
{
switch (payloadMode.GetStandard ())
{
case WIFI_PHY_STANDARD_holland:
case WIFI_PHY_STANDARD_80211a:
// IEEE Std 802.11-2007, 17.3.2
// actually this is only the first part of the PlcpHeader,
// because the last 16 bits of the PlcpHeader are using the
// same mode of the payload
return WifiPhy::Get6mba ();
case WIFI_PHY_STANDARD_80211b:
if (preamble == WIFI_PREAMBLE_LONG)
{
// IEEE Std 802.11-2007, sections 15.2.3 and 18.2.2.1
return WifiPhy::Get1mbb ();
}
else // WIFI_PREAMBLE_SHORT
{
// IEEE Std 802.11-2007, section 18.2.2.2
return WifiPhy::Get2mbb ();
}
case WIFI_PHY_STANDARD_80211_10Mhz:
return WifiPhy::Get3mb10Mhz ();
case WIFI_PHY_STANDARD_80211_5Mhz:
return WifiPhy::Get1_5mb5Mhz ();
default:
NS_FATAL_ERROR("unknown standard");
return WifiMode ();
}
}
uint32_t
InterferenceHelper::GetPlcpHeaderDurationMicroSeconds (WifiMode payloadMode, WifiPreamble preamble)
{
switch (payloadMode.GetStandard ())
{
case WIFI_PHY_STANDARD_holland:
case WIFI_PHY_STANDARD_80211a:
// IEEE Std 802.11-2007, section 17.3.3 and figure 17-4
// also section 17.3.2.3, table 17-4
// We return the duration of the SIGNAL field only, since the
// SERVICE field (which strictly speaking belongs to the PLCP
// header, see section 17.3.2 and figure 17-1) is sent using the
// payload mode.
return 4;
case WIFI_PHY_STANDARD_80211_10Mhz:
// IEEE Std 802.11-2007, section 17.3.2.3, table 17-4
return 8;
case WIFI_PHY_STANDARD_80211_5Mhz:
// IEEE Std 802.11-2007, section 17.3.2.3, table 17-4
return 16;
case WIFI_PHY_STANDARD_80211b:
if (preamble == WIFI_PREAMBLE_SHORT)
{
// IEEE Std 802.11-2007, section 18.2.2.2 and figure 18-2
return 24;
}
else // WIFI_PREAMBLE_LONG
{
// IEEE Std 802.11-2007, sections 18.2.2.1 and figure 18-1
return 48;
}
default:
NS_FATAL_ERROR("unknown standard");
return 0;
}
}
uint32_t
InterferenceHelper::GetPlcpPreambleDurationMicroSeconds (WifiMode payloadMode, WifiPreamble preamble)
{
switch (payloadMode.GetStandard ())
{
case WIFI_PHY_STANDARD_holland:
case WIFI_PHY_STANDARD_80211a:
// IEEE Std 802.11-2007, section 17.3.3, figure 17-4
// also section 17.3.2.3, table 17-4
return 16;
case WIFI_PHY_STANDARD_80211_10Mhz:
// IEEE Std 802.11-2007, section 17.3.3, table 17-4
// also section 17.3.2.3, table 17-4
return 32;
case WIFI_PHY_STANDARD_80211_5Mhz:
// IEEE Std 802.11-2007, section 17.3.3
// also section 17.3.2.3, table 17-4
return 64;
case WIFI_PHY_STANDARD_80211b:
if (preamble == WIFI_PREAMBLE_SHORT)
{
// IEEE Std 802.11-2007, section 18.2.2.2 and figure 18-2
return 72;
}
else // WIFI_PREAMBLE_LONG
{
// IEEE Std 802.11-2007, sections 18.2.2.1 and figure 18-1
return 144;
}
default:
NS_FATAL_ERROR("unknown standard");
return 0;
}
}
uint32_t
InterferenceHelper::GetPayloadDurationMicroSeconds (uint32_t size, WifiMode payloadMode)
{
NS_LOG_FUNCTION(size << payloadMode);
switch (payloadMode.GetStandard ())
{
case WIFI_PHY_STANDARD_80211a:
case WIFI_PHY_STANDARD_holland:
delay += m_plcpLongPreambleDelayUs;
// symbol duration is 4us
delay += 4;
delay += lrint (ceil ((size * 8.0 + 16.0 + 6.0) / payloadMode.GetDataRate () / 4e-6) * 4);
break;
case WIFI_PHY_STANDARD_80211_10Mhz:
case WIFI_PHY_STANDARD_80211_5Mhz:
{
// IEEE Std 802.11-2007, section 17.3.2.3, table 17-4
// corresponds to T_{SYM} in the table
uint32_t symbolDurationUs;
switch (payloadMode.GetStandard ())
{
case WIFI_PHY_STANDARD_holland:
case WIFI_PHY_STANDARD_80211a:
symbolDurationUs = 4;
break;
case WIFI_PHY_STANDARD_80211_10Mhz:
symbolDurationUs = 8;
break;
case WIFI_PHY_STANDARD_80211_5Mhz:
symbolDurationUs = 16;
break;
case WIFI_PHY_STANDARD_80211b:
NS_FATAL_ERROR("can't happen here");
symbolDurationUs = 0; // quiet compiler
default:
NS_FATAL_ERROR("unknown standard");
}
// IEEE Std 802.11-2007, section 17.3.2.2, table 17-3
// corresponds to N_{DBPS} in the table
double numDataBitsPerSymbol = payloadMode.GetDataRate () * symbolDurationUs / 1e6;
// IEEE Std 802.11-2007, section 17.3.5.3, equation (17-11)
uint32_t numSymbols = lrint (ceil ((16 + size * 8.0 + 6.0)/numDataBitsPerSymbol));
return numSymbols*symbolDurationUs;
}
case WIFI_PHY_STANDARD_80211b:
delay += m_plcpLongPreambleDelayUs;
delay += lrint (ceil ((size * 8.0 + 48.0) / payloadMode.GetDataRate () / 4e-6) * 4);
break;
// IEEE Std 802.11-2007, section 18.2.3.5
NS_LOG_LOGIC(" size=" << size
<< " mode=" << payloadMode
<< " rate=" << payloadMode.GetDataRate () );
return lrint(ceil ((size * 8.0) / (payloadMode.GetDataRate () / 1.0e6)));
default:
NS_ASSERT (false);
break;
}
return MicroSeconds (delay);
NS_FATAL_ERROR("unknown standard");
return 0;
}
}
void
InterferenceHelper::Configure80211aParameters (void)
Time
InterferenceHelper::CalculateTxDuration (uint32_t size, WifiMode payloadMode, WifiPreamble preamble)
{
NS_LOG_FUNCTION (this);
m_80211_standard = WIFI_PHY_STANDARD_80211a;
m_plcpLongPreambleDelayUs = 16;
m_plcpShortPreambleDelayUs = 16;
m_longPlcpHeaderMode = WifiPhy::Get6mba ();
m_shortPlcpHeaderMode = WifiPhy::Get6mba ();
m_plcpHeaderLength = 4 + 1 + 12 + 1 + 6;
/* 4095 bytes at a 6Mb/s rate with a 1/2 coding rate. */
m_maxPacketDuration = CalculateTxDuration (4095, WifiPhy::Get6mba (), WIFI_PREAMBLE_LONG);
}
void
InterferenceHelper::Configure80211bParameters (void)
{
NS_LOG_FUNCTION (this);
m_80211_standard = WIFI_PHY_STANDARD_80211b;
m_plcpLongPreambleDelayUs = 144;
m_plcpShortPreambleDelayUs = 144; // fixed preamable for 802.11b
m_longPlcpHeaderMode = WifiPhy::Get1mbb ();
m_shortPlcpHeaderMode = WifiPhy::Get1mbb ();
// PLCP Header: signal 8, service 8, length 16, CRC 16 bits
m_plcpHeaderLength = 8 + 8 + 16 + 16;
m_maxPacketDuration = CalculateTxDuration (4095, WifiPhy::Get1mbb (), WIFI_PREAMBLE_LONG);
uint32_t duration = GetPlcpPreambleDurationMicroSeconds (payloadMode, preamble)
+ GetPlcpHeaderDurationMicroSeconds (payloadMode, preamble)
+ GetPayloadDurationMicroSeconds (size, payloadMode);
return MicroSeconds (duration);
}
void
@@ -367,29 +497,12 @@ InterferenceHelper::CalculatePer (Ptr<const InterferenceHelper::Event> event, Ni
{
double psr = 1.0; /* Packet Success Rate */
NiChanges::iterator j = ni->begin ();
Time previous = (*j).GetTime ();
uint64_t plcpPreambleDelayUs;
Time previous = (*j).GetTime ();
WifiMode payloadMode = event->GetPayloadMode ();
WifiMode headerMode;
switch (event->GetPreambleType ()) {
case WIFI_PREAMBLE_LONG:
plcpPreambleDelayUs = m_plcpLongPreambleDelayUs;
headerMode = m_longPlcpHeaderMode;
break;
case WIFI_PREAMBLE_SHORT:
plcpPreambleDelayUs = m_plcpShortPreambleDelayUs;
headerMode = m_shortPlcpHeaderMode;
break;
default:
NS_ASSERT (false);
// only to quiet compiler. Really stupid.
plcpPreambleDelayUs = 0;
headerMode = m_shortPlcpHeaderMode;
break;
}
Time plcpHeaderStart = (*j).GetTime () + MicroSeconds (plcpPreambleDelayUs);
Time plcpPayloadStart = plcpHeaderStart +
Seconds ((m_plcpHeaderLength + 0.0) / headerMode.GetDataRate ());
WifiPreamble preamble = event->GetPreambleType ();
WifiMode headerMode = GetPlcpHeaderMode (payloadMode, preamble);
Time plcpHeaderStart = (*j).GetTime () + MicroSeconds (GetPlcpPreambleDurationMicroSeconds (payloadMode, preamble));
Time plcpPayloadStart = plcpHeaderStart + MicroSeconds (GetPlcpHeaderDurationMicroSeconds (payloadMode, preamble));
double noiseInterferenceW = (*j).GetDelta ();
double powerW = event->GetRxPowerW ();

View File

@@ -69,8 +69,6 @@ public:
InterferenceHelper ();
~InterferenceHelper ();
void Configure80211aParameters (void);
void Configure80211bParameters (void);
void SetNoiseFigure (double value);
void SetErrorRateModel (Ptr<ErrorRateModel> rate);
@@ -85,7 +83,13 @@ public:
* the requested threshold.
*/
Time GetEnergyDuration (double energyW);
Time CalculateTxDuration (uint32_t size, WifiMode payloadMode, WifiPreamble preamble) const;
static WifiMode GetPlcpHeaderMode (WifiMode payloadMode, WifiPreamble preamble);
static uint32_t GetPlcpHeaderDurationMicroSeconds (WifiMode payloadMode, WifiPreamble preamble);
static uint32_t GetPlcpPreambleDurationMicroSeconds (WifiMode mode, WifiPreamble preamble);
static uint32_t GetPayloadDurationMicroSeconds (uint32_t size, WifiMode payloadMode);
static Time CalculateTxDuration (uint32_t size, WifiMode payloadMode, WifiPreamble preamble);
Ptr<InterferenceHelper::Event> Add (uint32_t size, WifiMode payloadMode,
enum WifiPreamble preamble,
Time duration, double rxPower);
@@ -114,15 +118,9 @@ private:
double CalculatePer (Ptr<const Event> event, NiChanges *ni) const;
Time GetMaxPacketDuration (void) const;
uint64_t m_plcpLongPreambleDelayUs;
uint64_t m_plcpShortPreambleDelayUs;
WifiMode m_longPlcpHeaderMode;
WifiMode m_shortPlcpHeaderMode;
uint32_t m_plcpHeaderLength;
Time m_maxPacketDuration;
double m_noiseFigure; /**< noise figure (linear) */
Events m_events;
enum WifiPhyStandard m_80211_standard;
Ptr<ErrorRateModel> m_errorRateModel;
};

View File

@@ -138,13 +138,15 @@ JakesPropagationLossModel::GetTypeId (void)
.AddAttribute ("NumberOfRaysPerPath",
"The number of rays to use by default for compute the fading coeficent for a given path (default is 1)",
UintegerValue (1),
MakeUintegerAccessor (&JakesPropagationLossModel::m_nRays),
MakeUintegerAccessor (&JakesPropagationLossModel::SetNRays,
&JakesPropagationLossModel::GetNRays),
MakeUintegerChecker<uint8_t> ())
.AddAttribute ("NumberOfOscillatorsPerRay",
"The number of oscillators to use by default for compute the coeficent for a given ray of a given "
"path (default is 4)",
UintegerValue (4),
MakeUintegerAccessor (&JakesPropagationLossModel::m_nOscillators),
MakeUintegerAccessor (&JakesPropagationLossModel::SetNOscillators,
&JakesPropagationLossModel::GetNOscillators),
MakeUintegerChecker<uint8_t> ())
.AddAttribute ("DopplerFreq",
"The doppler frequency in Hz (f_d = v / lambda = v * f / c), the default is 0)",
@@ -161,9 +163,10 @@ JakesPropagationLossModel::GetTypeId (void)
}
JakesPropagationLossModel::JakesPropagationLossModel ()
{
DoConstruct ();
}
: m_amp (0),
m_nRays (0),
m_nOscillators (0)
{}
JakesPropagationLossModel::~JakesPropagationLossModel ()
{
@@ -181,8 +184,16 @@ JakesPropagationLossModel::~JakesPropagationLossModel ()
}
void
JakesPropagationLossModel::DoConstruct ()
JakesPropagationLossModel::SetNRays (uint8_t nRays)
{
m_nRays = nRays;
}
void
JakesPropagationLossModel::SetNOscillators (uint8_t nOscillators)
{
m_nOscillators = nOscillators;
delete [] m_amp;
uint16_t N = 4 * m_nOscillators + 2;
m_amp = new ComplexNumber[m_nOscillators + 1];
m_amp[0].real = 2.0 * sqrt(2.0 / N) * cos (PI / 4.0);
@@ -195,17 +206,17 @@ JakesPropagationLossModel::DoConstruct ()
}
}
void
JakesPropagationLossModel::SetNRays (uint8_t nRays)
uint8_t
JakesPropagationLossModel::GetNRays (void) const
{
m_nRays = nRays;
return m_nRays;
}
uint8_t
JakesPropagationLossModel::GetNOscillators (void) const
{
return m_nOscillators;
}
void
JakesPropagationLossModel::SetNOscillators (uint8_t nOscillators)
{
m_nOscillators = nOscillators;
}
double
JakesPropagationLossModel::DoCalcRxPower (double txPowerDbm,

View File

@@ -96,6 +96,9 @@ public:
*/
void SetNOscillators (uint8_t nOscillators);
uint8_t GetNRays (void) const;
uint8_t GetNOscillators (void) const;
private:
JakesPropagationLossModel (const JakesPropagationLossModel &o);
JakesPropagationLossModel & operator = (const JakesPropagationLossModel &o);

View File

@@ -584,11 +584,11 @@ MacLow::ReceiveOk (Ptr<Packet> packet, double rxSnr, WifiMode txMode, WifiPreamb
{
m_listener->GotAck (rxSnr, txMode);
}
if (m_txParams.HasNextPacket ())
{
m_waitSifsEvent = Simulator::Schedule (GetSifs (),
&MacLow::WaitSifsAfterEndTx, this);
}
if (m_txParams.HasNextPacket ())
{
m_waitSifsEvent = Simulator::Schedule (GetSifs (),
&MacLow::WaitSifsAfterEndTx, this);
}
}
else if (hdr.IsCtl ())
{

View File

@@ -97,6 +97,7 @@ NqapWifiMac::DoDispose (void)
NS_LOG_FUNCTION (this);
delete m_rxMiddle;
delete m_dcfManager;
m_low->Dispose ();
m_rxMiddle = 0;
m_low = 0;
m_dcfManager = 0;

View File

@@ -128,6 +128,7 @@ NqstaWifiMac::DoDispose (void)
NS_LOG_FUNCTION (this);
delete m_rxMiddle;
delete m_dcfManager;
m_low->Dispose ();
m_rxMiddle = 0;
m_low = 0;
m_dcfManager = 0;

View File

@@ -119,10 +119,11 @@ void
QapWifiMac::DoDispose ()
{
delete m_rxMiddle;
m_rxMiddle = 0;
delete m_txMiddle;
m_txMiddle = 0;
delete m_dcfManager;
m_low->Dispose ();
m_rxMiddle = 0;
m_txMiddle = 0;
m_dcfManager = 0;
m_low = 0;
m_phy = 0;

View File

@@ -125,6 +125,7 @@ QstaWifiMac::DoDispose ()
delete m_rxMiddle;
delete m_txMiddle;
delete m_dcfManager;
m_low->Dispose ();
m_rxMiddle = 0;
m_txMiddle = 0;
m_low = 0;

View File

@@ -117,6 +117,14 @@ WifiMac::GetTypeId (void)
MakeSsidAccessor (&WifiMac::GetSsid,
&WifiMac::SetSsid),
MakeSsidChecker ())
.AddAttribute ("Standard", "The standard chosen configures some MAC-specific constants",
EnumValue (WIFI_PHY_STANDARD_80211a),
MakeEnumAccessor (&WifiMac::SetStandard),
MakeEnumChecker (WIFI_PHY_STANDARD_80211a, "802.11a",
WIFI_PHY_STANDARD_80211b, "802.11b",
WIFI_PHY_STANDARD_80211_10Mhz,"802.11_10Mhz",
WIFI_PHY_STANDARD_80211_5Mhz,"802-11_5Mhz",
WIFI_PHY_STANDARD_holland, "holland"))
.AddTraceSource ("MacTx",
"A packet has been received from higher layers and is being processed in preparation for "
"queueing for transmission.",
@@ -200,4 +208,74 @@ WifiMac::NotifyRxDrop (Ptr<const Packet> packet)
m_macRxDropTrace (packet);
}
void
WifiMac::SetStandard (enum WifiPhyStandard standard)
{
m_standard = standard;
switch (standard) {
case WIFI_PHY_STANDARD_80211a:
Configure80211a ();
break;
case WIFI_PHY_STANDARD_80211b:
Configure80211b ();
break;
case WIFI_PHY_STANDARD_80211_10Mhz:
Configure80211_10Mhz ();
break;
case WIFI_PHY_STANDARD_80211_5Mhz:
Configure80211_5Mhz ();
break;
case WIFI_PHY_STANDARD_holland:
Configure80211a ();
break;
default:
NS_ASSERT (false);
break;
}
}
void
WifiMac::Configure80211a (void)
{
SetSifs(MicroSeconds(16));
SetSlot(MicroSeconds(9));
SetEifsNoDifs(MicroSeconds(16+44));
SetPifs(MicroSeconds(16+9));
SetCtsTimeout(MicroSeconds(16+44+9+GetDefaultMaxPropagationDelay().GetMicroSeconds ()*2));
SetAckTimeout(MicroSeconds(16+44+9+GetDefaultMaxPropagationDelay().GetMicroSeconds ()*2));
}
void
WifiMac::Configure80211b (void)
{
SetSifs(MicroSeconds(10));
SetSlot(MicroSeconds(20));
SetEifsNoDifs(MicroSeconds(10+304));
SetPifs(MicroSeconds(10+20));
SetCtsTimeout(MicroSeconds(10+304+20+GetDefaultMaxPropagationDelay().GetMicroSeconds ()*2));
SetAckTimeout(MicroSeconds(10+304+20+GetDefaultMaxPropagationDelay().GetMicroSeconds ()*2));
}
void
WifiMac::Configure80211_10Mhz (void)
{
SetSifs(MicroSeconds(32));
SetSlot(MicroSeconds(13));
SetEifsNoDifs(MicroSeconds(32+88));
SetPifs(MicroSeconds(32+13));
SetCtsTimeout(MicroSeconds(32+88+13+GetDefaultMaxPropagationDelay().GetMicroSeconds ()*2));
SetAckTimeout(MicroSeconds(32+88+13+GetDefaultMaxPropagationDelay().GetMicroSeconds ()*2));
}
void
WifiMac::Configure80211_5Mhz (void)
{
SetSifs(MicroSeconds(64));
SetSlot(MicroSeconds(21));
SetEifsNoDifs(MicroSeconds(64+176));
SetPifs(MicroSeconds(64+21));
SetCtsTimeout(MicroSeconds(64+176+21+GetDefaultMaxPropagationDelay().GetMicroSeconds ()*2));
SetAckTimeout(MicroSeconds(64+176+21+GetDefaultMaxPropagationDelay().GetMicroSeconds ()*2));
}
} // namespace ns3

View File

@@ -206,6 +206,10 @@ public:
* purposes.
*/
void NotifyRxDrop (Ptr<const Packet> packet);
/**
* \param standard the wifi standard to be configured
*/
void SetStandard (enum WifiPhyStandard standard);
private:
static Time GetDefaultMaxPropagationDelay (void);
@@ -217,6 +221,12 @@ private:
Time m_maxPropagationDelay;
uint32_t m_maxMsduSize;
WifiPhyStandard m_standard;
void Configure80211a (void);
void Configure80211b (void);
void Configure80211_10Mhz (void);
void Configure80211_5Mhz ();
/**
* The trace source fired when packets come into the "top" of the device

View File

@@ -107,6 +107,12 @@ WifiMode::GetUid (void) const
{
return m_uid;
}
enum WifiPhyStandard
WifiMode::GetStandard () const
{
struct WifiModeFactory::WifiModeItem *item = WifiModeFactory::GetFactory ()->Get (m_uid);
return item->standard;
}
WifiMode::WifiMode ()
: m_uid (0)
{}
@@ -131,7 +137,8 @@ WifiModeFactory::CreateBpsk (std::string uniqueName,
bool isMandatory,
uint32_t bandwidth,
uint32_t dataRate,
uint32_t phyRate)
uint32_t phyRate,
enum WifiPhyStandard standard)
{
WifiModeFactory *factory = GetFactory ();
uint32_t uid = factory->AllocateUid (uniqueName);
@@ -143,6 +150,7 @@ WifiModeFactory::CreateBpsk (std::string uniqueName,
item->modulation = WifiMode::BPSK;
item->constellationSize = 2;
item->isMandatory = isMandatory;
item->standard = standard;
return WifiMode (uid);
}
WifiMode
@@ -151,7 +159,8 @@ WifiModeFactory::CreateQam (std::string uniqueName,
uint32_t bandwidth,
uint32_t dataRate,
uint32_t phyRate,
uint8_t constellationSize)
uint8_t constellationSize,
enum WifiPhyStandard standard)
{
WifiModeFactory *factory = GetFactory ();
uint32_t uid = factory->AllocateUid (uniqueName);
@@ -163,6 +172,7 @@ WifiModeFactory::CreateQam (std::string uniqueName,
item->modulation = WifiMode::QAM;
item->constellationSize = constellationSize;
item->isMandatory = isMandatory;
item->standard = standard;
return WifiMode (uid);
}
WifiMode
@@ -170,7 +180,8 @@ WifiModeFactory::CreateDbpsk (std::string uniqueName,
bool isMandatory,
uint32_t bandwidth,
uint32_t dataRate,
uint32_t phyRate)
uint32_t phyRate,
enum WifiPhyStandard standard)
{
WifiModeFactory *factory = GetFactory ();
uint32_t uid = factory->AllocateUid (uniqueName);
@@ -182,6 +193,7 @@ WifiModeFactory::CreateDbpsk (std::string uniqueName,
item->modulation = WifiMode::DBPSK;
item->constellationSize = 2;
item->isMandatory = isMandatory;
item->standard = standard;
return WifiMode (uid);
}
WifiMode
@@ -189,7 +201,8 @@ WifiModeFactory::CreateDqpsk (std::string uniqueName,
bool isMandatory,
uint32_t bandwidth,
uint32_t dataRate,
uint32_t phyRate)
uint32_t phyRate,
enum WifiPhyStandard standard)
{
WifiModeFactory *factory = GetFactory ();
uint32_t uid = factory->AllocateUid (uniqueName);
@@ -201,6 +214,7 @@ WifiModeFactory::CreateDqpsk (std::string uniqueName,
item->modulation = WifiMode::DQPSK;
item->constellationSize = 4;
item->isMandatory = isMandatory;
item->standard = standard;
return WifiMode (uid);
}
bool

View File

@@ -25,6 +25,7 @@
#include <vector>
#include <ostream>
#include "ns3/attribute-helper.h"
#include "ns3/wifi-phy-standard.h"
namespace ns3 {
@@ -101,6 +102,12 @@ class WifiMode
*/
uint32_t GetUid (void) const;
/**
*
* @return the WifiPhyStandard to which the WifiMode belongs
*/
enum WifiPhyStandard GetStandard () const;
/**
* Create an invalid WifiMode. Calling any method on the
* instance created will trigger an assert. This is useful
@@ -151,7 +158,8 @@ public:
bool isMandatory,
uint32_t bandwidth,
uint32_t dataRate,
uint32_t phyRate);
uint32_t phyRate,
enum WifiPhyStandard standard);
/**
* \param uniqueName the name of the associated WifiMode. This name
* must be unique accross _all_ instances.
@@ -170,7 +178,8 @@ public:
uint32_t bandwidth,
uint32_t dataRate,
uint32_t phyRate,
uint8_t constellationSize);
uint8_t constellationSize,
enum WifiPhyStandard standard);
/**
* \param uniqueName the name of the associated WifiMode. This name
@@ -188,7 +197,8 @@ public:
bool isMandatory,
uint32_t bandwidth,
uint32_t dataRate,
uint32_t phyRate);
uint32_t phyRate,
enum WifiPhyStandard standard);
/**
* \param uniqueName the name of the associated WifiMode. This name
* must be unique accross _all_ instances.
@@ -205,7 +215,8 @@ public:
bool isMandatory,
uint32_t bandwidth,
uint32_t dataRate,
uint32_t phyRate);
uint32_t phyRate,
enum WifiPhyStandard standard);
private:
friend class WifiMode;
friend std::istream & operator >> (std::istream &is, WifiMode &mode);
@@ -225,6 +236,7 @@ private:
enum WifiMode::ModulationType modulation;
uint8_t constellationSize;
bool isMandatory;
enum WifiPhyStandard standard;
};
bool Search (std::string name, WifiMode *mode);

View File

@@ -25,6 +25,8 @@ namespace ns3 {
enum WifiPhyStandard {
WIFI_PHY_STANDARD_80211a,
WIFI_PHY_STANDARD_80211b,
WIFI_PHY_STANDARD_80211_10Mhz,
WIFI_PHY_STANDARD_80211_5Mhz,
WIFI_PHY_STANDARD_holland
};

View File

@@ -98,7 +98,8 @@ WifiPhy::Get6mba (void)
{
static WifiMode mode = WifiModeFactory::CreateBpsk ("wifia-6mbs",
true,
20000000, 6000000, 12000000);
20000000, 6000000, 12000000,
WIFI_PHY_STANDARD_80211a);
return mode;
}
WifiMode
@@ -106,7 +107,8 @@ WifiPhy::Get9mba (void)
{
static WifiMode mode = WifiModeFactory::CreateBpsk ("wifia-9mbs",
false,
20000000, 9000000, 12000000);
20000000, 9000000, 12000000,
WIFI_PHY_STANDARD_80211a);
return mode;
}
WifiMode
@@ -114,7 +116,8 @@ WifiPhy::Get12mba (void)
{
static WifiMode mode = WifiModeFactory::CreateBpsk ("wifia-12mbs",
true,
20000000, 12000000, 24000000);
20000000, 12000000, 24000000,
WIFI_PHY_STANDARD_80211a);
return mode;
}
WifiMode
@@ -122,7 +125,8 @@ WifiPhy::Get18mba (void)
{
static WifiMode mode = WifiModeFactory::CreateBpsk ("wifia-18mbs",
false,
20000000, 18000000, 24000000);
20000000, 18000000, 24000000,
WIFI_PHY_STANDARD_80211a);
return mode;
}
WifiMode
@@ -130,7 +134,8 @@ WifiPhy::Get24mba (void)
{
static WifiMode mode = WifiModeFactory::CreateBpsk ("wifia-24mbs",
true,
20000000, 24000000, 48000000);
20000000, 24000000, 48000000,
WIFI_PHY_STANDARD_80211a);
return mode;
}
WifiMode
@@ -138,7 +143,8 @@ WifiPhy::Get36mba (void)
{
static WifiMode mode = WifiModeFactory::CreateBpsk ("wifia-36mbs",
false,
20000000, 36000000, 48000000);
20000000, 36000000, 48000000,
WIFI_PHY_STANDARD_80211a);
return mode;
}
@@ -147,7 +153,8 @@ WifiPhy::Get48mba (void)
{
static WifiMode mode = WifiModeFactory::CreateBpsk ("wifia-48mbs",
false,
20000000, 48000000, 72000000);
20000000, 48000000, 72000000,
WIFI_PHY_STANDARD_80211a);
return mode;
}
@@ -156,7 +163,8 @@ WifiPhy::Get54mba (void)
{
static WifiMode mode = WifiModeFactory::CreateBpsk ("wifia-54mbs",
false,
20000000, 54000000, 72000000);
20000000, 54000000, 72000000,
WIFI_PHY_STANDARD_80211a);
return mode;
}
@@ -213,7 +221,8 @@ WifiPhy::Get1mbb (void)
{
static WifiMode mode = WifiModeFactory::CreateDbpsk ("wifib-1mbs",
true,
22000000, 1000000, 1000000);
22000000, 1000000, 1000000,
WIFI_PHY_STANDARD_80211b);
return mode;
}
@@ -222,7 +231,8 @@ WifiPhy::Get2mbb (void)
{
static WifiMode mode = WifiModeFactory::CreateDqpsk ("wifib-2mbs",
true,
22000000, 2000000, 2000000);
22000000, 2000000, 2000000,
WIFI_PHY_STANDARD_80211b);
return mode;
}
@@ -231,7 +241,8 @@ WifiPhy::Get5_5mbb (void)
{
static WifiMode mode = WifiModeFactory::CreateDqpsk ("wifib-5.5mbs",
true,
22000000, 5500000, 5500000);
22000000, 5500000, 5500000,
WIFI_PHY_STANDARD_80211b);
return mode;
}
@@ -240,7 +251,168 @@ WifiPhy::Get11mbb (void)
{
static WifiMode mode = WifiModeFactory::CreateDqpsk ("wifib-11mbs",
true,
22000000, 11000000, 11000000);
22000000, 11000000, 11000000,
WIFI_PHY_STANDARD_80211b);
return mode;
}
WifiMode
WifiPhy::Get3mb10Mhz (void)
{
static WifiMode mode = WifiModeFactory::CreateBpsk ("wifi-3mbs-10Mhz",
true,
10000000, 3000000, 6000000,
WIFI_PHY_STANDARD_80211_10Mhz);
return mode;
}
WifiMode
WifiPhy::Get4_5mb10Mhz (void)
{
static WifiMode mode = WifiModeFactory::CreateBpsk ("wifi-4.5mbs-10Mhz",
false,
10000000, 4500000, 6000000,
WIFI_PHY_STANDARD_80211_10Mhz);
return mode;
}
WifiMode
WifiPhy::Get6mb10Mhz (void)
{
static WifiMode mode = WifiModeFactory::CreateBpsk ("wifi-6mbs-10Mhz",
true,
10000000, 6000000, 12000000,
WIFI_PHY_STANDARD_80211_10Mhz);
return mode;
}
WifiMode
WifiPhy::Get9mb10Mhz (void)
{
static WifiMode mode = WifiModeFactory::CreateBpsk ("wifi-9mbs-10Mhz",
false,
10000000, 9000000, 12000000,
WIFI_PHY_STANDARD_80211_10Mhz);
return mode;
}
WifiMode
WifiPhy::Get12mb10Mhz (void)
{
static WifiMode mode = WifiModeFactory::CreateBpsk ("wifi-12mbs-10Mhz",
true,
10000000, 12000000, 24000000,
WIFI_PHY_STANDARD_80211_10Mhz);
return mode;
}
WifiMode
WifiPhy::Get18mb10Mhz (void)
{
static WifiMode mode = WifiModeFactory::CreateBpsk ("wifi-18mbs-10Mhz",
false,
10000000, 18000000, 24000000,
WIFI_PHY_STANDARD_80211_10Mhz);
return mode;
}
WifiMode
WifiPhy::Get24mb10Mhz (void)
{
static WifiMode mode = WifiModeFactory::CreateBpsk ("wifi-24mbs-10Mhz",
false,
10000000, 24000000, 36000000,
WIFI_PHY_STANDARD_80211_10Mhz);
return mode;
}
WifiMode
WifiPhy::Get27mb10Mhz (void)
{
static WifiMode mode = WifiModeFactory::CreateBpsk ("wifi-27mbs-10Mhz",
false,
10000000, 27000000, 36000000,
WIFI_PHY_STANDARD_80211_10Mhz);
return mode;
}
WifiMode
WifiPhy::Get1_5mb5Mhz (void)
{
static WifiMode mode = WifiModeFactory::CreateBpsk ("wifi-1_5mbs-5Mhz",
true,
5000000, 1500000, 3000000,
WIFI_PHY_STANDARD_80211_5Mhz);
return mode;
}
WifiMode
WifiPhy::Get2_25mb5Mhz (void)
{
static WifiMode mode = WifiModeFactory::CreateBpsk ("wifi-2.25mbs-5Mhz",
false,
5000000, 2250000, 3000000,
WIFI_PHY_STANDARD_80211_5Mhz);
return mode;
}
WifiMode
WifiPhy::Get3mb5Mhz (void)
{
static WifiMode mode = WifiModeFactory::CreateBpsk ("wifi-3mbs-5Mhz",
true,
5000000, 3000000, 6000000,
WIFI_PHY_STANDARD_80211_5Mhz);
return mode;
}
WifiMode
WifiPhy::Get4_5mb5Mhz (void)
{
static WifiMode mode = WifiModeFactory::CreateBpsk ("wifi-4.5mbs-5Mhz",
false,
5000000, 4500000, 6000000,
WIFI_PHY_STANDARD_80211_5Mhz);
return mode;
}
WifiMode
WifiPhy::Get6mb5Mhz (void)
{
static WifiMode mode = WifiModeFactory::CreateBpsk ("wifi-6mbs-5Mhz",
true,
5000000, 6000000, 12000000,
WIFI_PHY_STANDARD_80211_5Mhz);
return mode;
}
WifiMode
WifiPhy::Get9mb5Mhz (void)
{
static WifiMode mode = WifiModeFactory::CreateBpsk ("wifi-9mbs-5Mhz",
false,
10000000, 9000000, 12000000,
WIFI_PHY_STANDARD_80211_5Mhz);
return mode;
}
WifiMode
WifiPhy::Get12mb5Mhz (void)
{
static WifiMode mode = WifiModeFactory::CreateBpsk ("wifi-12mbs-5Mhz",
false,
10000000, 12000000, 18000000,
WIFI_PHY_STANDARD_80211_5Mhz);
return mode;
}
WifiMode
WifiPhy::Get13_5mb5Mhz (void)
{
static WifiMode mode = WifiModeFactory::CreateBpsk ("wifi-13.5mbs-5Mhz",
false,
10000000, 13500000, 18000000,
WIFI_PHY_STANDARD_80211_5Mhz);
return mode;
}
@@ -265,6 +437,22 @@ public:
ns3::WifiPhy::Get2mbb ();
ns3::WifiPhy::Get5_5mbb ();
ns3::WifiPhy::Get11mbb ();
ns3::WifiPhy::Get3mb10Mhz ();
ns3::WifiPhy::Get4_5mb10Mhz ();
ns3::WifiPhy::Get6mb10Mhz ();
ns3::WifiPhy::Get9mb10Mhz ();
ns3::WifiPhy::Get12mb10Mhz ();
ns3::WifiPhy::Get18mb10Mhz ();
ns3::WifiPhy::Get24mb10Mhz ();
ns3::WifiPhy::Get27mb10Mhz ();
ns3::WifiPhy::Get1_5mb5Mhz ();
ns3::WifiPhy::Get2_25mb5Mhz ();
ns3::WifiPhy::Get3mb5Mhz ();
ns3::WifiPhy::Get4_5mb5Mhz ();
ns3::WifiPhy::Get6mb5Mhz ();
ns3::WifiPhy::Get9mb5Mhz ();
ns3::WifiPhy::Get12mb5Mhz ();
ns3::WifiPhy::Get13_5mb5Mhz ();
}
} g_constructor;
}

View File

@@ -256,6 +256,22 @@ public:
static WifiMode Get2mbb (void);
static WifiMode Get5_5mbb (void);
static WifiMode Get11mbb (void);
static WifiMode Get3mb10Mhz (void);
static WifiMode Get4_5mb10Mhz (void);
static WifiMode Get6mb10Mhz (void);
static WifiMode Get9mb10Mhz (void);
static WifiMode Get12mb10Mhz (void);
static WifiMode Get18mb10Mhz (void);
static WifiMode Get24mb10Mhz (void);
static WifiMode Get27mb10Mhz (void);
static WifiMode Get1_5mb5Mhz (void);
static WifiMode Get2_25mb5Mhz (void);
static WifiMode Get3mb5Mhz (void);
static WifiMode Get4_5mb5Mhz (void);
static WifiMode Get6mb5Mhz (void);
static WifiMode Get9mb5Mhz (void);
static WifiMode Get12mb5Mhz (void);
static WifiMode Get13_5mb5Mhz (void);
/**
@@ -309,7 +325,7 @@ public:
* on a nearby channel.
* @param rate the PHY data rate in units of 500kbps (i.e., the same
* units used both for the radiotap and for the prism header)
* @param isPreambleShort true if short preamble is used, false otherwise
* @param isShortPreamble true if short preamble is used, false otherwise
* @param signalDbm signal power in dBm
* @param noiseDbm noise power in dBm
*/
@@ -331,7 +347,7 @@ public:
* on a nearby channel.
* @param rate the PHY data rate in units of 500kbps (i.e., the same
* units used both for the radiotap and for the prism header)
* @param isPreambleShort true if short preamble is used, false otherwise
* @param isShortPreamble true if short preamble is used, false otherwise
*/
void NotifyPromiscSniffTx (Ptr<const Packet> packet, uint16_t channelFreqMhz, uint32_t rate, bool isShortPreamble);

View File

@@ -21,6 +21,7 @@ def build(bld):
'error-rate-model.cc',
'yans-error-rate-model.cc',
'interference-helper.cc',
'interference-helper-tx-duration-test.cc',
'yans-wifi-phy.cc',
'yans-wifi-channel.cc',
'wifi-mac-header.cc',

View File

@@ -176,7 +176,7 @@ YansErrorRateModel::GetFecQamBer (double snr, uint32_t nbits,
double
YansErrorRateModel::GetChunkSuccessRate (WifiMode mode, double snr, uint32_t nbits) const
{
if (mode == WifiPhy::Get6mba ())
if (mode == WifiPhy::Get6mba () || mode == WifiPhy::Get3mb10Mhz () || mode == WifiPhy::Get1_5mb5Mhz ())
{
return GetFecBpskBer (snr,
nbits,
@@ -186,7 +186,7 @@ YansErrorRateModel::GetChunkSuccessRate (WifiMode mode, double snr, uint32_t nbi
11 // adFree
);
}
else if (mode == WifiPhy::Get9mba ())
else if (mode == WifiPhy::Get9mba () || mode == WifiPhy::Get4_5mb10Mhz () || mode == WifiPhy::Get2_25mb5Mhz ())
{
return GetFecBpskBer (snr,
nbits,
@@ -196,7 +196,7 @@ YansErrorRateModel::GetChunkSuccessRate (WifiMode mode, double snr, uint32_t nbi
8 // adFree
);
}
else if (mode == WifiPhy::Get12mba ())
else if (mode == WifiPhy::Get12mba () || mode == WifiPhy::Get6mb10Mhz () || mode == WifiPhy::Get3mb5Mhz ())
{
return GetFecQamBer (snr,
nbits,
@@ -208,7 +208,7 @@ YansErrorRateModel::GetChunkSuccessRate (WifiMode mode, double snr, uint32_t nbi
0 // adFreePlusOne
);
}
else if (mode == WifiPhy::Get18mba ())
else if (mode == WifiPhy::Get18mba () || mode == WifiPhy::Get9mb10Mhz () || mode == WifiPhy::Get4_5mb5Mhz ())
{
return GetFecQamBer (snr,
nbits,
@@ -220,7 +220,7 @@ YansErrorRateModel::GetChunkSuccessRate (WifiMode mode, double snr, uint32_t nbi
31 // adFreePlusOne
);
}
else if (mode == WifiPhy::Get24mba ())
else if (mode == WifiPhy::Get24mba () || mode == WifiPhy::Get12mb10Mhz () || mode == WifiPhy::Get6mb5Mhz ())
{
return GetFecQamBer (snr,
nbits,
@@ -232,7 +232,7 @@ YansErrorRateModel::GetChunkSuccessRate (WifiMode mode, double snr, uint32_t nbi
0 // adFreePlusOne
);
}
else if (mode == WifiPhy::Get36mba ())
else if (mode == WifiPhy::Get36mba () || mode == WifiPhy::Get18mb10Mhz () || mode == WifiPhy::Get9mb5Mhz ())
{
return GetFecQamBer (snr,
nbits,
@@ -244,7 +244,7 @@ YansErrorRateModel::GetChunkSuccessRate (WifiMode mode, double snr, uint32_t nbi
31 // adFreePlusOne
);
}
else if (mode == WifiPhy::Get48mba ())
else if (mode == WifiPhy::Get48mba () || mode == WifiPhy::Get24mb10Mhz () || mode == WifiPhy::Get12mb5Mhz ())
{
return GetFecQamBer (snr,
nbits,
@@ -256,7 +256,7 @@ YansErrorRateModel::GetChunkSuccessRate (WifiMode mode, double snr, uint32_t nbi
16 // adFreePlusOne
);
}
else if (mode == WifiPhy::Get54mba ())
else if (mode == WifiPhy::Get54mba () || mode == WifiPhy::Get27mb10Mhz () || mode == WifiPhy::Get13_5mb5Mhz ())
{
return GetFecQamBer (snr,
nbits,

View File

@@ -111,6 +111,8 @@ YansWifiPhy::GetTypeId (void)
MakeEnumAccessor (&YansWifiPhy::SetStandard),
MakeEnumChecker (WIFI_PHY_STANDARD_80211a, "802.11a",
WIFI_PHY_STANDARD_80211b, "802.11b",
WIFI_PHY_STANDARD_80211_10Mhz,"802.11_10Mhz",
WIFI_PHY_STANDARD_80211_5Mhz,"802-11_5Mhz",
WIFI_PHY_STANDARD_holland, "holland"))
.AddAttribute ("State", "The state of the PHY layer",
PointerValue (),
@@ -156,6 +158,12 @@ YansWifiPhy::SetStandard (enum WifiPhyStandard standard)
case WIFI_PHY_STANDARD_80211b:
Configure80211b ();
break;
case WIFI_PHY_STANDARD_80211_10Mhz:
Configure80211_10Mhz ();
break;
case WIFI_PHY_STANDARD_80211_5Mhz:
Configure80211_5Mhz ();
break;
case WIFI_PHY_STANDARD_holland:
ConfigureHolland ();
break;
@@ -437,7 +445,6 @@ void
YansWifiPhy::Configure80211a (void)
{
NS_LOG_FUNCTION (this);
m_interference.Configure80211aParameters ();
m_modes.push_back (WifiPhy::Get6mba ());
m_modes.push_back (WifiPhy::Get9mba ());
m_modes.push_back (WifiPhy::Get12mba ());
@@ -453,18 +460,44 @@ void
YansWifiPhy::Configure80211b (void)
{
NS_LOG_FUNCTION (this);
m_interference.Configure80211bParameters ();
m_modes.push_back (WifiPhy::Get1mbb ());
m_modes.push_back (WifiPhy::Get2mbb ());
m_modes.push_back (WifiPhy::Get5_5mbb ());
m_modes.push_back (WifiPhy::Get11mbb ());
}
void
YansWifiPhy::Configure80211_10Mhz (void)
{
NS_LOG_FUNCTION (this);
m_modes.push_back (WifiPhy::Get3mb10Mhz ());
m_modes.push_back (WifiPhy::Get4_5mb10Mhz ());
m_modes.push_back (WifiPhy::Get6mb10Mhz ());
m_modes.push_back (WifiPhy::Get9mb10Mhz ());
m_modes.push_back (WifiPhy::Get12mb10Mhz ());
m_modes.push_back (WifiPhy::Get18mb10Mhz ());
m_modes.push_back (WifiPhy::Get24mb10Mhz ());
m_modes.push_back (WifiPhy::Get27mb10Mhz ());
}
void
YansWifiPhy::Configure80211_5Mhz (void)
{
NS_LOG_FUNCTION (this);
m_modes.push_back (WifiPhy::Get1_5mb5Mhz ());
m_modes.push_back (WifiPhy::Get2_25mb5Mhz ());
m_modes.push_back (WifiPhy::Get3mb5Mhz ());
m_modes.push_back (WifiPhy::Get4_5mb5Mhz ());
m_modes.push_back (WifiPhy::Get6mb5Mhz ());
m_modes.push_back (WifiPhy::Get9mb5Mhz ());
m_modes.push_back (WifiPhy::Get12mb5Mhz ());
m_modes.push_back (WifiPhy::Get13_5mb5Mhz ());
}
void
YansWifiPhy::ConfigureHolland (void)
{
NS_LOG_FUNCTION (this);
m_interference.Configure80211aParameters ();
m_modes.push_back (WifiPhy::Get6mba ());
m_modes.push_back (WifiPhy::Get12mba ());
m_modes.push_back (WifiPhy::Get18mba ());

View File

@@ -125,6 +125,8 @@ private:
virtual void DoDispose (void);
void Configure80211a (void);
void Configure80211b (void);
void Configure80211_10Mhz (void);
void Configure80211_5Mhz ();
void ConfigureHolland (void);
double GetEdThresholdW (void) const;
double DbmToW (double dbm) const;

View File

@@ -1,3 +1,23 @@
/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
/*
* Copyright (c) 2008 INRIA
*
* 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: Mathieu Lacage <mathieu.lacage@sophia.inria.fr>
* Author: Gustavo Carneiro <gjc@inescporto.pt>
*/
#ifndef BRIDGE_HELPER_H
#define BRIDGE_HELPER_H
@@ -10,12 +30,42 @@ namespace ns3 {
class Node;
class AttributeValue;
/**
* \brief Add capability to bridge multiple LAN segments (IEEE 802.1D bridging)
*/
class BridgeHelper
{
public:
BridgeHelper ();
/**
* \param n1 the name of the attribute to set
* \param v1 the value of the attribute to set
*
* Set an attribute on each ns3::BridgeNetDevice created by
* BridgeHelper::Install
*/
void SetDeviceAttribute (std::string n1, const AttributeValue &v1);
/**
* This method creates an ns3::BridgeNetDevice with the attributes
* configured by BridgeHelper::SetDeviceAttribute, adds the device
* to the node, and attaches the given NetDevices as ports of the
* bridge.
*
* \param node The node to install the device in
* \param c Container of NetDevices to add as bridge ports
* \returns A containter holding the added net device.
*/
NetDeviceContainer Install (Ptr<Node> node, NetDeviceContainer c);
/**
* This method creates an ns3::BridgeNetDevice with the attributes
* configured by BridgeHelper::SetDeviceAttribute, adds the device
* to the node, and attaches the given NetDevices as ports of the
* bridge.
*
* \param nodeName The name of the node to install the device in
* \param c Container of NetDevices to add as bridge ports
* \returns A containter holding the added net device.
*/
NetDeviceContainer Install (std::string nodeName, NetDeviceContainer c);
private:
ObjectFactory m_deviceFactory;

View File

@@ -28,6 +28,9 @@ namespace ns3 {
/**
* \brief Helper class that adds ns3::Ipv4ListRouting objects
*
* This class is expected to be used in conjunction with
* ns3::InternetStackHelper::SetRoutingHelper
*/
class Ipv4ListRoutingHelper : public Ipv4RoutingHelper
{

View File

@@ -33,7 +33,7 @@ class Node;
* For each new routing protocol created as a subclass of
* ns3::Ipv4RoutingProtocol, you need to create a subclass of
* ns3::Ipv4RoutingHelper which can be used by
* ns3::InternetStackHelper::SetRoutingProtocol and
* ns3::InternetStackHelper::SetRoutingHelper and
* ns3::InternetStackHelper::Install.
*/
class Ipv4RoutingHelper

View File

@@ -33,6 +33,9 @@ namespace ns3 {
/**
* \brief Helper class that adds ns3::Ipv4StaticRouting objects
*
* This class is expected to be used in conjunction with
* ns3::InternetStackHelper::SetRoutingHelper
*/
class Ipv4StaticRoutingHelper : public Ipv4RoutingHelper
{

View File

@@ -24,6 +24,10 @@
namespace ns3 {
/**
* \brief create non-qos MAC layers for a ns3::WifiNetDevice.
* This class can create MACs of type ns3::NqapWifiMac, ns3::NqstaWifiMac, and, ns3::AdhocWifiMac
*/
class NqosWifiMacHelper : public WifiMacHelper
{
public:
@@ -66,7 +70,6 @@ public:
std::string n6 = "", const AttributeValue &v6 = EmptyAttributeValue (),
std::string n7 = "", const AttributeValue &v7 = EmptyAttributeValue ());
/**
* \param type the type of ns3::WifiMac to create.
* \param n0 the name of the attribute to set
* \param v0 the value of the attribute to set
* \param n1 the name of the attribute to set
@@ -74,6 +77,7 @@ public:
* \param n2 the name of the attribute to set
* \param v2 the value of the attribute to set
* \param n3 the name of the attribute to set
* \param v3 the value of the attribute to set
*/
void SetDcaParameters (std::string n0 = "", const AttributeValue &v0 = EmptyAttributeValue (),
std::string n1 = "", const AttributeValue &v1 = EmptyAttributeValue (),

View File

@@ -29,6 +29,9 @@ namespace ns3 {
/**
* \brief Helper class that adds OLSR routing to nodes.
*
* This class is expected to be used in conjunction with
* ns3::InternetStackHelper::SetRoutingHelper
*/
class OlsrHelper : public Ipv4RoutingHelper
{

View File

@@ -27,6 +27,10 @@
namespace ns3 {
/**
* \brief create qos MAC layers for a ns3::WifiNetDevice.
* This class can create MACs of type ns3::QapWifiMac, ns3::QstaWifiMac, and, ns3::QadhocWifiMac
*/
class QosWifiMacHelper : public WifiMacHelper
{
public:
@@ -70,7 +74,7 @@ public:
/**
* \param accessClass access class for which we are setting aggregator. Possibilities
* are: AC_BK, AC_BE, AC_VI, AC_VO.
* \param aggregatorType type of aggregator.
* \param type the type of ns3::WifiMac to create.
* \param n0 the name of the attribute to set
* \param v0 the value of the attribute to set
* \param n1 the name of the attribute to set

View File

@@ -81,12 +81,15 @@ ArpL3Protocol::SetNode (Ptr<Node> node)
void
ArpL3Protocol::NotifyNewAggregate ()
{
Ptr<Node>node = this->GetObject<Node> ();
//verify that it's a valid node and that
//the node was not set before
if (node!= 0 && m_node == 0)
if (m_node == 0)
{
this->SetNode (node);
Ptr<Node>node = this->GetObject<Node> ();
//verify that it's a valid node and that
//the node was not set before
if (node != 0)
{
this->SetNode (node);
}
}
Object::NotifyNewAggregate ();
}

View File

@@ -50,15 +50,20 @@ Icmpv4L4Protocol::SetNode (Ptr<Node> node)
void
Icmpv4L4Protocol::NotifyNewAggregate ()
{
bool is_not_initialized = (m_node == 0);
Ptr<Node>node = this->GetObject<Node> ();
Ptr<Ipv4L3Protocol> ipv4 = this->GetObject<Ipv4L3Protocol> ();
if (is_not_initialized && node!= 0 && ipv4 != 0)
if (m_node == 0)
{
this->SetNode (node);
ipv4->Insert (this);
Ptr<Ipv4RawSocketFactoryImpl> rawFactory = CreateObject<Ipv4RawSocketFactoryImpl> ();
ipv4->AggregateObject (rawFactory);
Ptr<Node> node = this->GetObject<Node> ();
if (node != 0)
{
Ptr<Ipv4L3Protocol> ipv4 = this->GetObject<Ipv4L3Protocol> ();
if (ipv4 != 0)
{
this->SetNode (node);
ipv4->Insert (this);
Ptr<Ipv4RawSocketFactoryImpl> rawFactory = CreateObject<Ipv4RawSocketFactoryImpl> ();
ipv4->AggregateObject (rawFactory);
}
}
}
Object::NotifyNewAggregate ();
}

View File

@@ -1,52 +0,0 @@
/* -*- Mode: C++; c-file-style: "gnu"; indent-tabs-mode:nil; -*- */
/*
* Copyright (c) 2005,2006,2007 INRIA
*
* 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: Mathieu Lacage <mathieu.lacage@sophia.inria.fr>
*/
#include "ipv4-checksum.h"
namespace ns3 {
uint16_t
Ipv4ChecksumCalculate (uint16_t checksum, uint8_t *buffer, uint16_t size)
{
/* see RFC 1071 to understand this code. */
uint32_t sum = checksum;
uint16_t *data = (uint16_t *) buffer;
for (uint16_t i = 0; i < (size/2); i++) {
sum += data[i];
}
if ((size % 2) != 0) {
uint8_t tmpBuf[2];
tmpBuf[0] = buffer[size-1];
tmpBuf[1] = 0;
data = (uint16_t *)tmpBuf;
sum += *data;
}
while (sum >> 16) {
sum = (sum & 0xffff) + (sum >> 16);
}
return sum;
}
uint16_t
Ipv4ChecksumComplete (uint16_t checksum)
{
return ~checksum;
}
}; //namespace ns3

View File

@@ -1,33 +0,0 @@
/* -*- Mode: C++; c-file-style: "gnu"; indent-tabs-mode:nil; -*- */
/*
* Copyright (c) 2005,2006,2007 INRIA
*
* 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: Mathieu Lacage <mathieu.lacage@sophia.inria.fr>
*/
#ifndef IPV4_CHECKSUM_H
#define IPV4_CHECKSUM_H
#include <stdint.h>
namespace ns3 {
uint16_t Ipv4ChecksumCalculate (uint16_t checksum, uint8_t *buffer, uint16_t size);
uint16_t Ipv4ChecksumComplete (uint16_t checksum);
}; //namespace ns3
#endif /* IPV4_CHECKSUM_H */

View File

@@ -178,7 +178,7 @@ Ipv4Interface::SetForwarding (bool val)
void
Ipv4Interface::Send (Ptr<Packet> p, Ipv4Address dest)
{
NS_LOG_FUNCTION_NOARGS ();
NS_LOG_FUNCTION (dest << *p);
if (!IsUp())
{
return;
@@ -199,7 +199,7 @@ Ipv4Interface::Send (Ptr<Packet> p, Ipv4Address dest)
{
Ptr<Ipv4L3Protocol> ipv4 = m_node->GetObject<Ipv4L3Protocol> ();
ipv4->Receive (0, p, Ipv4L3Protocol::PROT_NUMBER,
ipv4->Receive (m_device, p, Ipv4L3Protocol::PROT_NUMBER,
m_device->GetBroadcast (),
m_device->GetBroadcast (),
NetDevice::PACKET_HOST // note: linux uses PACKET_LOOPBACK here

View File

@@ -146,12 +146,15 @@ Ipv4L3Protocol::DeleteRawSocket (Ptr<Socket> socket)
void
Ipv4L3Protocol::NotifyNewAggregate ()
{
Ptr<Node>node = this->GetObject<Node>();
// verify that it's a valid node and that
// the node has not been set before
if (node!= 0 && m_node == 0)
if (m_node == 0)
{
this->SetNode (node);
Ptr<Node>node = this->GetObject<Node>();
// verify that it's a valid node and that
// the node has not been set before
if (node != 0)
{
this->SetNode (node);
}
}
Object::NotifyNewAggregate ();
}

View File

@@ -164,16 +164,21 @@ NscTcpL4Protocol::SetNode (Ptr<Node> node)
void
NscTcpL4Protocol::NotifyNewAggregate ()
{
bool is_not_initialized = (m_node == 0);
Ptr<Node>node = this->GetObject<Node> ();
Ptr<Ipv4L3Protocol> ipv4 = this->GetObject<Ipv4L3Protocol> ();
if (is_not_initialized && node!= 0 && ipv4 != 0)
if (m_node == 0)
{
this->SetNode (node);
ipv4->Insert (this);
Ptr<NscTcpSocketFactoryImpl> tcpFactory = CreateObject<NscTcpSocketFactoryImpl> ();
tcpFactory->SetTcp (this);
node->AggregateObject (tcpFactory);
Ptr<Node>node = this->GetObject<Node> ();
if (node != 0)
{
Ptr<Ipv4L3Protocol> ipv4 = this->GetObject<Ipv4L3Protocol> ();
if (ipv4 != 0)
{
this->SetNode (node);
ipv4->Insert (this);
Ptr<NscTcpSocketFactoryImpl> tcpFactory = CreateObject<NscTcpSocketFactoryImpl> ();
tcpFactory->SetTcp (this);
node->AggregateObject (tcpFactory);
}
}
}
Object::NotifyNewAggregate ();
}

View File

@@ -366,16 +366,21 @@ TcpL4Protocol::SetNode (Ptr<Node> node)
void
TcpL4Protocol::NotifyNewAggregate ()
{
bool is_not_initialized = (m_node == 0);
Ptr<Node>node = this->GetObject<Node> ();
Ptr<Ipv4L3Protocol> ipv4 = this->GetObject<Ipv4L3Protocol> ();
if (is_not_initialized && node!= 0 && ipv4 != 0)
if (m_node == 0)
{
this->SetNode (node);
ipv4->Insert (this);
Ptr<TcpSocketFactoryImpl> tcpFactory = CreateObject<TcpSocketFactoryImpl> ();
tcpFactory->SetTcp (this);
node->AggregateObject (tcpFactory);
Ptr<Node> node = this->GetObject<Node> ();
if (node != 0)
{
Ptr<Ipv4L3Protocol> ipv4 = this->GetObject<Ipv4L3Protocol> ();
if (ipv4 != 0)
{
this->SetNode (node);
ipv4->Insert (this);
Ptr<TcpSocketFactoryImpl> tcpFactory = CreateObject<TcpSocketFactoryImpl> ();
tcpFactory->SetTcp (this);
node->AggregateObject (tcpFactory);
}
}
}
Object::NotifyNewAggregate ();
}

View File

@@ -77,16 +77,21 @@ UdpL4Protocol::SetNode (Ptr<Node> node)
void
UdpL4Protocol::NotifyNewAggregate ()
{
bool is_not_initialized = (m_node == 0);
Ptr<Node>node = this->GetObject<Node> ();
Ptr<Ipv4L3Protocol> ipv4 = this->GetObject<Ipv4L3Protocol> ();
if (is_not_initialized && node!= 0 && ipv4 != 0)
if (m_node == 0)
{
this->SetNode (node);
ipv4->Insert (this);
Ptr<UdpSocketFactoryImpl> udpFactory = CreateObject<UdpSocketFactoryImpl> ();
udpFactory->SetUdp (this);
node->AggregateObject (udpFactory);
Ptr<Node> node = this->GetObject<Node> ();
if (node != 0)
{
Ptr<Ipv4L3Protocol> ipv4 = this->GetObject<Ipv4L3Protocol> ();
if (ipv4 != 0)
{
this->SetNode (node);
ipv4->Insert (this);
Ptr<UdpSocketFactoryImpl> udpFactory = CreateObject<UdpSocketFactoryImpl> ();
udpFactory->SetUdp (this);
node->AggregateObject (udpFactory);
}
}
}
Object::NotifyNewAggregate ();
}

View File

@@ -78,7 +78,6 @@ def build(bld):
'ipv4-l4-protocol.cc',
'udp-header.cc',
'tcp-header.cc',
'ipv4-checksum.cc',
'ipv4-interface.cc',
'ipv4-l3-protocol.cc',
'ipv4-end-point.cc',

View File

@@ -34,10 +34,13 @@ class NetDevice;
/**
* \ingroup node
* \defgroup ipv4Routing Ipv4 Routing
*
* Abstract base class for Ipv4 routing protocols. Defines two
* virtual functions for packet routing and forwarding. The first,
* \defgroup ipv4Routing Ipv4RoutingProtocol
*/
/**
* \ingroup ipv4Routing
* \brief Abstract base class for IPv4 routing protocols.
*
* Defines two virtual functions for packet routing and forwarding. The first,
* RouteOutput(), is used for locally originated packets, and the second,
* RouteInput(), is used for forwarding and/or delivering received packets.
* Also defines the signatures of four callbacks used in RouteInput().

View File

@@ -25,7 +25,11 @@
namespace ns3 {
/**
* \ingroup ipv4Routing
* \ingroup routing
* \defgroup ipv4ListRouting Ipv4 List Routing
*/
/**
* \ingroup ipv4ListRouting
*
* This class is a specialization of Ipv4RoutingProtocol that allows
* other instances of Ipv4RoutingProtocol to be inserted in a

View File

@@ -29,7 +29,7 @@
namespace ns3 {
/**
* \ingroup ipv4Routing
* \ingroup routing
*
* A record of an IPv4 routing table entry for Ipv4GlobalRouting and
* Ipv4StaticRouting. This is not a reference counted object.
@@ -155,7 +155,7 @@ private:
std::ostream& operator<< (std::ostream& os, Ipv4RoutingTableEntry const& route);
/**
* \ingroup ipv4Routing
* \ingroup routing
*
* \brief A record of an IPv4 multicast route for Ipv4GlobalRouting and Ipv4StaticRouting
*/

View File

@@ -43,7 +43,11 @@ class Ipv4MulticastRoutingTableEntry;
class Node;
/**
* \ingroup ipv4Routing
* \ingroup routing
* \defgroup ipv4StaticRouting Ipv4StaticRouting
*/
/**
* \ingroup ipv4StaticRouting
*
* \brief Static routing protocol for IP version 4 stacks.
*

View File

@@ -33,6 +33,7 @@ bool g_debug = false;
class Bench
{
public:
Bench ();
void ReadDistribution (std::istream &istream);
void SetTotal (uint32_t total);
void RunBench (void);
@@ -44,6 +45,11 @@ private:
uint32_t m_total;
};
Bench::Bench ()
: m_n (0),
m_total (0)
{}
void
Bench::SetTotal (uint32_t total)
{

View File

@@ -402,7 +402,7 @@ int main (int argc, char *argv[])
{
StringValue val;
(*i)->GetValue (val);
std::cout << " <li><b>" << (*i)->GetName () << "</b>: " << (*i)->GetHelp () << "(" << val.Get () << ")</li>" << std::endl;
std::cout << " <li><b>\\anchor GlobalValue" << (*i)->GetName () << " " << (*i)->GetName () << "</b>: " << (*i)->GetHelp () << "(" << val.Get () << ")</li>" << std::endl;
}
std::cout << "</ul>" << std::endl
<< "*/" << std::endl;