diff --git a/doc/contributing/source/coding-style.rst b/doc/contributing/source/coding-style.rst index c7e6d07a1..e6dd0a9bb 100644 --- a/doc/contributing/source/coding-style.rst +++ b/doc/contributing/source/coding-style.rst @@ -326,8 +326,8 @@ Indent constructor's initialization list with 4 spaces. .. sourcecode:: cpp MyClass::MyClass(int x, int y) - : m_x (x), - m_y (y) + : m_x(x), + m_y(y) { } @@ -837,7 +837,7 @@ Casts ===== Where casts are necessary, use the Google C++ guidance: "Use C++-style casts -like ``static_cast (double_value)``, or brace initialization for +like ``static_cast(double_value)``, or brace initialization for conversion of arithmetic types like ``int64 y = int64{1} << 42``." Do not use C-style casts, since they can be unsafe. @@ -1047,13 +1047,13 @@ the |ns3| smart pointer class ``Ptr`` should be used in boolean comparisons as f if (p == NULL) {...} if (p == 0) {...} - NS_ASSERT... (p != nullptr, ...) NS_ASSERT... (p, ...) - NS_ABORT... (p != nullptr, ...) NS_ABORT... (p, ...) + NS_ASSERT...(p != nullptr, ...) NS_ASSERT...(p, ...) + NS_ABORT... (p != nullptr, ...) NS_ABORT... (p, ...) - NS_ASSERT... (p == nullptr, ...) NS_ASSERT... (!p, ...) - NS_ABORT... (p == nullptr, ...) NS_ABORT... (!p, ...) + NS_ASSERT...(p == nullptr, ...) NS_ASSERT...(!p, ...) + NS_ABORT... (p == nullptr, ...) NS_ABORT... (!p, ...) - NS_TEST... (p, nullptr, ...) NS_TEST... (p, nullptr, ...) + NS_TEST... (p, nullptr, ...) NS_TEST... (p, nullptr, ...) C++ standard ============ @@ -1069,9 +1069,9 @@ Miscellaneous items =================== - ``NS_LOG_COMPONENT_DEFINE("log-component-name");`` statements should be - placed within namespace ns3 (for module code) and after the + placed within ``namespace ns3`` (for module code) and after the ``using namespace ns3;``. In examples, - ``NS_OBJECT_ENSURE_REGISTERED()`` should also be placed within namespace ``ns3``. + ``NS_OBJECT_ENSURE_REGISTERED()`` should also be placed within ``namespace ns3``. - Pointers and references are left-aligned: diff --git a/doc/manual/source/attributes.rst b/doc/manual/source/attributes.rst index 7b93dcb4f..4b5225b8e 100644 --- a/doc/manual/source/attributes.rst +++ b/doc/manual/source/attributes.rst @@ -32,7 +32,7 @@ specificity, these are: +=====================================+====================================+ | Default Attribute values set when | Affect all instances of the class. | | Attributes are defined in | | -| :cpp:func:`GetTypeId ()`. | | +| :cpp:func:`GetTypeId()`. | | +-------------------------------------+------------------------------------+ | :cpp:class:`CommandLine` | Affect all future instances. | | :cpp:func:`Config::SetDefault()` | | @@ -44,8 +44,8 @@ specificity, these are: | Helper methods with (string/ | Affects all instances created by | | AttributeValue) parameter pairs | the helper. | +-------------------------------------+------------------------------------+ -| :cpp:func:`MyClass::SetX ()` | Alters this particular instance. | -| :cpp:func:`Object::SetAttribute ()` | Generally this is the only form | +| :cpp:func:`MyClass::SetX()` | Alters this particular instance. | +| :cpp:func:`Object::SetAttribute()` | Generally this is the only form | | :cpp:func:`Config::Set()` | which can be scheduled to alter | | | an instance once the simulation | | | is running. | @@ -99,7 +99,7 @@ references to heap-allocated objects that may cause memory leaks. For most basic usage (syntax), treat a smart pointer like a regular pointer:: Ptr nd = ...; - nd->CallSomeFunction (); + nd->CallSomeFunction(); // etc. So how do you get a smart pointer to an object, as in the first line @@ -111,24 +111,24 @@ CreateObject As we discussed above in :ref:`Memory-management-and-class-Ptr`, at the lowest-level API, objects of type :cpp:class:`Object` are not instantiated using ``operator new`` as usual but instead by a templated function called -:cpp:func:`CreateObject ()`. +:cpp:func:`CreateObject()`. A typical way to create such an object is as follows:: - Ptr nd = CreateObject (); + Ptr nd = CreateObject(); You can think of this as being functionally equivalent to:: - WifiNetDevice* nd = new WifiNetDevice (); + WifiNetDevice* nd = new WifiNetDevice(); Objects that derive from :cpp:class:`Object` must be allocated on the heap -using :cpp:func:`CreateObject ()`. Those deriving from :cpp:class:`ObjectBase`, +using :cpp:func:`CreateObject()`. Those deriving from :cpp:class:`ObjectBase`, such as |ns3| helper functions and packet headers and trailers, can be allocated on the stack. -In some scripts, you may not see a lot of :cpp:func:`CreateObject ()` calls +In some scripts, you may not see a lot of :cpp:func:`CreateObject()` calls in the code; this is because there are some helper objects in effect -that are doing the :cpp:func:`CreateObject ()` calls for you. +that are doing the :cpp:func:`CreateObject()` calls for you. TypeId ++++++ @@ -150,39 +150,39 @@ Putting all of these concepts together, let's look at a specific example: class :cpp:class:`Node`. The public header file ``node.h`` has a declaration that includes -a static :cpp:func:`GetTypeId ()` function call:: +a static :cpp:func:`GetTypeId()` function call:: class Node : public Object { public: - static TypeId GetTypeId (); + static TypeId GetTypeId(); ... This is defined in the ``node.cc`` file as follows:: TypeId - Node::GetTypeId () + Node::GetTypeId() { - static TypeId tid = TypeId ("ns3::Node") - .SetParent () - .SetGroupName ("Network") - .AddConstructor () - .AddAttribute ("DeviceList", - "The list of devices associated to this Node.", - ObjectVectorValue (), - MakeObjectVectorAccessor (&Node::m_devices), - MakeObjectVectorChecker ()) - .AddAttribute ("ApplicationList", - "The list of applications associated to this Node.", - ObjectVectorValue (), - MakeObjectVectorAccessor (&Node::m_applications), - MakeObjectVectorChecker ()) - .AddAttribute ("Id", - "The id (unique integer) of this Node.", - TypeId::ATTR_GET, // allow only getting it. - UintegerValue (0), - MakeUintegerAccessor (&Node::m_id), - MakeUintegerChecker ()) + static TypeId tid = TypeId("ns3::Node") + .SetParent() + .SetGroupName("Network") + .AddConstructor() + .AddAttribute("DeviceList", + "The list of devices associated to this Node.", + ObjectVectorValue(), + MakeObjectVectorAccessor(&Node::m_devices), + MakeObjectVectorChecker()) + .AddAttribute("ApplicationList", + "The list of applications associated to this Node.", + ObjectVectorValue(), + MakeObjectVectorAccessor(&Node::m_applications), + MakeObjectVectorChecker()) + .AddAttribute("Id", + "The id(unique integer) of this Node.", + TypeId::ATTR_GET, // allow only getting it. + UintegerValue(0), + MakeUintegerAccessor(&Node::m_id), + MakeUintegerChecker()) ; return tid; } @@ -192,38 +192,38 @@ as an extended form of run time type information (RTTI). The C++ language includes a simple kind of RTTI in order to support ``dynamic_cast`` and ``typeid`` operators. -The :cpp:func:`SetParent ()` call in the definition above is used in +The :cpp:func:`SetParent()` call in the definition above is used in conjunction with our object aggregation mechanisms to allow safe up- and -down-casting in inheritance trees during :cpp:func:`GetObject ()`. +down-casting in inheritance trees during :cpp:func:`GetObject()`. It also enables subclasses to inherit the Attributes of their parent class. -The :cpp:func:`AddConstructor ()` call is used in conjunction +The :cpp:func:`AddConstructor()` 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 :cpp:func:`AddAttribute ()` associate a given string +The three calls to :cpp:func:`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 :cpp:class:`Attribute` is associated with mechanisms for accessing the underlying member variable in the object (for example, -:cpp:func:`MakeUintegerAccessor ()` tells the generic :cpp:class:`Attribute` +:cpp:func:`MakeUintegerAccessor()` tells the generic :cpp:class:`Attribute` code how to get to the node ID above). There are also "Checker" methods which are used to validate values against range limitations, such as maximum and minimum allowed values. When users want to create Nodes, they will usually call some form of -:cpp:func:`CreateObject ()`,:: +:cpp:func:`CreateObject()`,:: - Ptr n = CreateObject (); + Ptr n = CreateObject(); or more abstractly, using an object factory, you can create a :cpp:class:`Node` object without even knowing the concrete C++ type:: ObjectFactory factory; const std::string typeId = "ns3::Node''; - factory.SetTypeId (typeId); - Ptr node = factory.Create (); + factory.SetTypeId(typeId); + Ptr node = factory.Create (); Both of these methods result in fully initialized attributes being available in the resulting :cpp:class:`Object` instances. @@ -359,7 +359,7 @@ the following:: class QueueBase : public Object { public: - static TypeId GetTypeId (); + static TypeId GetTypeId(); ... private: @@ -408,34 +408,34 @@ Let's consider things that a user may want to do with the value of to that default. * Set or get the value on an already instantiated queue. -The above things typically require providing ``Set ()`` and ``Get ()`` +The above things typically require providing ``Set()`` and ``Get()`` functions, and some type of global default value. In the |ns3| attribute system, these value definitions and accessor function registrations are moved into the :cpp:class:`TypeId` class; *e.g*.:: - NS_OBJECT_ENSURE_REGISTERED (QueueBase); + NS_OBJECT_ENSURE_REGISTERED(QueueBase); TypeId - QueueBase::GetTypeId () + QueueBase::GetTypeId() { - static TypeId tid = TypeId ("ns3::DropTailQueue") - .SetParent () - .SetGroupName ("Network") + static TypeId tid = TypeId("ns3::DropTailQueue") + .SetParent() + .SetGroupName("Network") ... - .AddAttribute ("MaxSize", - "The max queue size", - QueueSizeValue (QueueSize ("100p")), - MakeQueueSizeAccessor (&QueueBase::SetMaxSize, - &QueueBase::GetMaxSize), - MakeQueueSizeChecker ()) + .AddAttribute("MaxSize", + "The max queue size", + QueueSizeValue(QueueSize("100p")), + MakeQueueSizeAccessor(&QueueBase::SetMaxSize, + &QueueBase::GetMaxSize), + MakeQueueSizeChecker()) ... ; return tid; } -The :cpp:func:`AddAttribute ()` method is performing a number of things for the +The :cpp:func:`AddAttribute()` method is performing a number of things for the :cpp:member:`m_maxSize` value: * Binding the (usually private) member variable :cpp:member:`m_maxSize` @@ -452,7 +452,7 @@ we will provide an example script that shows how users may manipulate these values. Note that initialization of the attribute relies on the macro -``NS_OBJECT_ENSURE_REGISTERED (QueueBase)`` being called; if you leave this +``NS_OBJECT_ENSURE_REGISTERED(QueueBase)`` being called; if you leave this out of your new class implementation, your attributes will not be initialized correctly. @@ -486,13 +486,13 @@ function begins:: // int - main (int argc, char *argv[]) + main(int argc, char *argv[]) { // Queues in ns-3 are objects that hold items (other objects) in // a queue structure. The C++ implementation uses templates to // allow queues to hold various types of items, but the most - // common is a pointer to a packet (Ptr). + // common is a pointer to a packet(Ptr). // // The maximum queue size can either be enforced in bytes ('b') or // packets ('p'). A special type called the ns3::QueueSize can @@ -505,12 +505,12 @@ function begins:: // // Here, we set it to 80 packets. We could use one of two value types: // a string-based value or a QueueSizeValue value - Config::SetDefault ("ns3::QueueBase::MaxSize", StringValue ("80p")); + Config::SetDefault("ns3::QueueBase::MaxSize", StringValue("80p")); // The below function call is redundant - Config::SetDefault ("ns3::QueueBase::MaxSize", QueueSizeValue (QueueSize (QueueSizeUnit::PACKETS, 80))); + Config::SetDefault("ns3::QueueBase::MaxSize", QueueSizeValue(QueueSize(QueueSizeUnit::PACKETS, 80))); The main thing to notice in the above are the two equivalent calls to -:cpp:func:`Config::SetDefault ()`. This is how we set the default value +:cpp:func:`Config::SetDefault()`. This is how we set the default value for all subsequently instantiated :cpp:class:`DropTailQueue`\s. We illustrate that two types of ``Value`` classes, a :cpp:class:`StringValue` and a :cpp:class:`QueueSizeValue` class, can be used to assign the value @@ -532,21 +532,21 @@ the :cpp:class:`CommandLine` API documentation. // For example, via "--ns3::QueueBase::MaxSize=80p" CommandLine cmd; // This provides yet another way to set the value from the command line: - cmd.AddValue ("maxSize", "ns3::QueueBase::MaxSize"); - cmd.Parse (argc, argv); + cmd.AddValue("maxSize", "ns3::QueueBase::MaxSize"); + cmd.Parse(argc, argv); Now, we will create a few objects using the low-level API. Our newly created queues will not have :cpp:member:`m_maxSize` initialized to -0 packets, as defined in the :cpp:func:`QueueBase::GetTypeId ()` +0 packets, as defined in the :cpp:func:`QueueBase::GetTypeId()` function, but to 80 packets, because of what we did above with default values.:: - Ptr n0 = CreateObject (); + Ptr n0 = CreateObject(); - Ptr net0 = CreateObject (); - n0->AddDevice (net0); + Ptr net0 = CreateObject(); + n0->AddDevice(net0); - Ptr > q = CreateObject > (); + Ptr > q = CreateObject >(); net0->AddQueue(q); At this point, we have created a single :cpp:class:`Node` (``n0``) @@ -569,23 +569,23 @@ the helper and low-level APIs; either from the constructors themselves:: Ptr p = CreateObjectWithAttributes - ("MinX", DoubleValue (-100.0), - "MinY", DoubleValue (-100.0), - "DeltaX", DoubleValue (5.0), - "DeltaY", DoubleValue (20.0), - "GridWidth", UintegerValue (20), - "LayoutType", StringValue ("RowFirst")); + ("MinX", DoubleValue(-100.0), + "MinY", DoubleValue(-100.0), + "DeltaX", DoubleValue(5.0), + "DeltaY", DoubleValue(20.0), + "GridWidth", UintegerValue(20), + "LayoutType", StringValue("RowFirst")); or from the higher-level helper APIs, such as:: mobility.SetPositionAllocator - ("ns3::GridPositionAllocator", - "MinX", DoubleValue (-100.0), - "MinY", DoubleValue (-100.0), - "DeltaX", DoubleValue (5.0), - "DeltaY", DoubleValue (20.0), - "GridWidth", UintegerValue (20), - "LayoutType", StringValue ("RowFirst")); + ("ns3::GridPositionAllocator", + "MinX", DoubleValue(-100.0), + "MinY", DoubleValue(-100.0), + "DeltaX", DoubleValue(5.0), + "DeltaY", DoubleValue(20.0), + "GridWidth", UintegerValue(20), + "LayoutType", StringValue("RowFirst")); We don't illustrate it here, but you can also configure an :cpp:class:`ObjectFactory` with new values for specific attributes. @@ -596,9 +596,9 @@ one of the helper APIs for the class. To review, there are several ways to set values for attributes for class instances *to be created in the future:* -* :cpp:func:`Config::SetDefault ()` -* :cpp:func:`CommandLine::AddValue ()` -* :cpp:func:`CreateObjectWithAttributes<> ()` +* :cpp:func:`Config::SetDefault()` +* :cpp:func:`CommandLine::AddValue()` +* :cpp:func:`CreateObjectWithAttributes<>()` * Various helper APIs But what if you've already created an instance, and you want @@ -624,35 +624,35 @@ First, we observe that we can get a pointer to the (base class) ``"TxQueue"``:: PointerValue ptr; - net0->GetAttribute ("TxQueue", ptr); - Ptr > txQueue = ptr.Get > (); + net0->GetAttribute("TxQueue", ptr); + Ptr > txQueue = ptr.Get >(); -Using the :cpp:func:`GetObject ()` function, we can perform a safe downcast +Using the :cpp:func:`GetObject()` function, we can perform a safe downcast to a :cpp:class:`DropTailQueue`. The `NS_ASSERT` checks that the pointer is valid. :: - Ptr > dtq = txQueue->GetObject > (); - NS_ASSERT (dtq != 0); + Ptr > dtq = txQueue->GetObject >(); + NS_ASSERT(dtq); Next, we can get the value of an attribute on this queue. We have introduced wrapper ``Value`` classes for the underlying data types, similar to Java wrappers around these types, since the attribute system stores values serialized to strings, and not disparate types. Here, the attribute value -is assigned to a :cpp:class:`QueueSizeValue`, and the :cpp:func:`Get ()` method on this value produces the (unwrapped) ``QueueSize``. That is, +is assigned to a :cpp:class:`QueueSizeValue`, and the :cpp:func:`Get()` the variable `limit` is written into by the GetAttribute method.:: QueueSizeValue limit; - dtq->GetAttribute ("MaxSize", limit); - NS_LOG_INFO ("1. dtq limit: " << limit.Get ()); + dtq->GetAttribute("MaxSize", limit); + NS_LOG_INFO("1. dtq limit: " << limit.Get()); Note that the above downcast is not really needed; we could have gotten the attribute value directly from ``txQueue``:: - txQueue->GetAttribute ("MaxSize", limit); - NS_LOG_INFO ("2. txQueue limit: " << limit.Get ()); + txQueue->GetAttribute("MaxSize", limit); + NS_LOG_INFO("2. txQueue limit: " << limit.Get()); Now, let's set it to another value (60 packets). Let's also make use of the StringValue shorthand notation to set the size by @@ -661,9 +661,9 @@ by either the `p` or `b` character). :: - txQueue->SetAttribute ("MaxSize", StringValue ("60p")); - txQueue->GetAttribute ("MaxSize", limit); - NS_LOG_INFO ("3. txQueue limit changed: " << limit.Get ()); + txQueue->SetAttribute("MaxSize", StringValue("60p")); + txQueue->GetAttribute("MaxSize", limit); + NS_LOG_INFO("3. txQueue limit changed: " << limit.Get()); Config Namespace Path ===================== @@ -675,11 +675,11 @@ would like to configure a specific attribute with a single statement. :: - Config::Set ("/NodeList/0/DeviceList/0/TxQueue/MaxSize", - StringValue ("25p")); - txQueue->GetAttribute ("MaxSize", limit); - NS_LOG_INFO ("4. txQueue limit changed through namespace: " - << limit.Get ()); + Config::Set("/NodeList/0/DeviceList/0/TxQueue/MaxSize", + StringValue("25p")); + txQueue->GetAttribute("MaxSize", limit); + NS_LOG_INFO("4. txQueue limit changed through namespace: " + << limit.Get()); The configuration path often has the form of ``"...///...//"`` @@ -691,14 +691,14 @@ ends with a succession of member attributes, in this case the ``"MaxSize"`` attribute of the ``"TxQueue"`` of the chosen :cpp:class:`NetDevice`. 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 -:cpp:func:`Config::Set ()`):: +devices(which in this simple example has the same effect as the previous +:cpp:func:`Config::Set()`):: - Config::Set ("/NodeList/*/DeviceList/*/TxQueue/MaxSize", - StringValue ("15p")); - txQueue->GetAttribute ("MaxSize", limit); - NS_LOG_INFO ("5. txQueue limit changed through wildcarded namespace: " - << limit.Get ()); + Config::Set("/NodeList/*/DeviceList/*/TxQueue/MaxSize", + StringValue("15p")); + txQueue->GetAttribute("MaxSize", limit); + NS_LOG_INFO("5. txQueue limit changed through wildcarded namespace: " + << limit.Get()); If you run this program from the command line, you should see the following output corresponding to the steps we took above: @@ -724,12 +724,12 @@ namespace path. :: - Names::Add ("server", n0); - Names::Add ("server/eth0", net0); + Names::Add("server", n0); + Names::Add("server/eth0", net0); ... - Config::Set ("/Names/server/eth0/TxQueue/MaxPackets", UintegerValue (25)); + Config::Set("/Names/server/eth0/TxQueue/MaxPackets", UintegerValue(25)); Here we've added the path elements ``"server"`` and ``"eth0"`` under the ``"/Names/"`` namespace, then used the resulting configuration path @@ -755,8 +755,8 @@ or *via* strings. Direct implicit conversion of types to :cpp:class:`AttributeValue` is not really practical. So in the above, users have a choice of using strings or values:: - p->Set ("cwnd", StringValue ("100")); // string-based setter - p->Set ("cwnd", IntegerValue (100)); // integer-based setter + p->Set("cwnd", StringValue("100")); // string-based setter + p->Set("cwnd", IntegerValue(100)); // integer-based setter The system provides some macros that help users declare and define new AttributeValue subclasses for new types that they want to introduce into @@ -792,18 +792,18 @@ In general, the attribute code to assign values to the underlying class member variables is executed after an object is constructed. But what if you need the values assigned before the constructor body executes, because you need them in the logic of the constructor? There is a way to do this, used for example in the -class :cpp:class:`ConfigStore`: call :cpp:func:`ObjectBase::ConstructSelf ()` as +class :cpp:class:`ConfigStore`: call :cpp:func:`ObjectBase::ConstructSelf()` as follows:: - ConfigStore::ConfigStore () + ConfigStore::ConfigStore() { - ObjectBase::ConstructSelf (AttributeConstructionList ()); + ObjectBase::ConstructSelf(AttributeConstructionList()); // continue on with constructor. } Beware that the object and all its derived classes must also implement -a :cpp:func:`GetInstanceTypeId ()` method. Otherwise -the :cpp:func:`ObjectBase::ConstructSelf ()` will not be able to read +a :cpp:func:`GetInstanceTypeId()` method. Otherwise +the :cpp:func:`ObjectBase::ConstructSelf()` will not be able to read the attributes. Adding Attributes @@ -834,11 +834,11 @@ variable using the metadata system. If it were not already provided by |ns3|, the user could declare the following addition in the runtime metadata system (to the :cpp:func:`GetTypeId` definition for :cpp:class:`TcpSocket`):: - .AddAttribute ("Congestion window", - "Tcp congestion window (bytes)", - UintegerValue (1), - MakeUintegerAccessor (&TcpSocket::m_cWnd), - MakeUintegerChecker ()) + .AddAttribute("Congestion window", + "Tcp congestion window(bytes)", + UintegerValue(1), + MakeUintegerAccessor(&TcpSocket::m_cWnd), + MakeUintegerChecker()) Now, the user with a pointer to a :cpp:class:`TcpSocket` instance can perform operations such as @@ -863,7 +863,7 @@ In the ``my-mobility.h`` header file:: class MyMobility : public MobilityModel { -This requires we declare the :cpp:func:`GetTypeId ()` function. +This requires we declare the :cpp:func:`GetTypeId()` function. This is a one-line public function declaration:: public: @@ -871,31 +871,31 @@ This is a one-line public function declaration:: * Register this type. * \return The object TypeId. */ - static TypeId GetTypeId (); + static TypeId GetTypeId(); We've already introduced what a :cpp:class:`TypeId` definition will look like in the ``my-mobility.cc`` implementation file:: - NS_OBJECT_ENSURE_REGISTERED (MyMobility); + NS_OBJECT_ENSURE_REGISTERED(MyMobility); TypeId - MyMobility::GetTypeId () + MyMobility::GetTypeId() { - static TypeId tid = TypeId ("ns3::MyMobility") - .SetParent () - .SetGroupName ("Mobility") - .AddConstructor () - .AddAttribute ("Bounds", - "Bounds of the area to cruise.", - RectangleValue (Rectangle (0.0, 0.0, 100.0, 100.0)), - MakeRectangleAccessor (&MyMobility::m_bounds), - MakeRectangleChecker ()) - .AddAttribute ("Time", - "Change current direction and speed after moving for this delay.", - TimeValue (Seconds (1.0)), - MakeTimeAccessor (&MyMobility::m_modeTime), - MakeTimeChecker ()) - // etc (more parameters). + static TypeId tid = TypeId("ns3::MyMobility") + .SetParent() + .SetGroupName("Mobility") + .AddConstructor() + .AddAttribute("Bounds", + "Bounds of the area to cruise.", + RectangleValue(Rectangle(0.0, 0.0, 100.0, 100.0)), + MakeRectangleAccessor(&MyMobility::m_bounds), + MakeRectangleChecker()) + .AddAttribute("Time", + "Change current direction and speed after moving for this delay.", + // etc (more parameters). + TimeValue(Seconds(1.0)), + MakeTimeAccessor(&MyMobility::m_modeTime), + MakeTimeChecker()) ; return tid; } @@ -903,14 +903,14 @@ in the ``my-mobility.cc`` implementation file:: If we don't want to subclass from an existing class, in the header file we just inherit from :cpp:class:`ns3::Object`, and in the object file we set the parent class to :cpp:class:`ns3::Object` with -``.SetParent ()``. +``.SetParent()``. Typical mistakes here involve: -* Not calling ``NS_OBJECT_ENSURE_REGISTERED ()`` -* Not calling the :cpp:func:`SetParent ()` method, +* Not calling ``NS_OBJECT_ENSURE_REGISTERED()`` +* Not calling the :cpp:func:`SetParent()` method, or calling it with the wrong type. -* Not calling the :cpp:func:`AddConstructor ()` method, +* Not calling the :cpp:func:`AddConstructor()` method, or calling it with the wrong type. * Introducing a typographical error in the name of the :cpp:class:`TypeId` in its constructor. @@ -950,27 +950,27 @@ Header File 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 ``Attribute`` system:: - std::ostream &operator << (std::ostream &os, const Rectangle &rectangle); - std::istream &operator >> (std::istream &is, Rectangle &rectangle); + std::ostream &operator <<(std::ostream &os, const Rectangle &rectangle); + std::istream &operator >>(std::istream &is, Rectangle &rectangle); - ATTRIBUTE_HELPER_HEADER (Rectangle); + ATTRIBUTE_HELPER_HEADER(Rectangle); Implementation File ~~~~~~~~~~~~~~~~~~~ In the class definition (``.cc`` file), the code looks like this:: - ATTRIBUTE_HELPER_CPP (Rectangle); + ATTRIBUTE_HELPER_CPP(Rectangle); std::ostream & - operator << (std::ostream &os, const Rectangle &rectangle) + operator <<(std::ostream &os, const Rectangle &rectangle) { os << rectangle.xMin << "|" << rectangle.xMax << "|" << rectangle.yMin << "|" << rectangle.yMax; return os; } std::istream & - operator >> (std::istream &is, Rectangle &rectangle) + operator >>(std::istream &is, Rectangle &rectangle) { char c1, c2, c3; is >> rectangle.xMin >> c1 >> rectangle.xMax >> c2 >> rectangle.yMin >> c3 @@ -979,13 +979,13 @@ In the class definition (``.cc`` file), the code looks like this:: c2 != '|' || c3 != '|') { - is.setstate (std::ios_base::failbit); + is.setstate(std::ios_base::failbit); } return is; } These stream operators simply convert from a string representation of the -Rectangle (``"xMin|xMax|yMin|yMax"``) to the underlying Rectangle. The modeler +Rectangle(``"xMin|xMax|yMin|yMax"``) to the underlying Rectangle. The modeler must specify these operators and the string syntactical representation of an instance of the new class. @@ -1014,36 +1014,36 @@ to show how the system is extended:: class ConfigExample : public Object { public: - static TypeId GetTypeId () { - static TypeId tid = TypeId ("ns3::A") - .SetParent () - .AddAttribute ("TestInt16", "help text", - IntegerValue (-2), - MakeIntegerAccessor (&A::m_int16), - MakeIntegerChecker ()) + static TypeId GetTypeId() { + static TypeId tid = TypeId("ns3::A") + .SetParent() + .AddAttribute("TestInt16", "help text", + IntegerValue(-2), + MakeIntegerAccessor(&A::m_int16), + MakeIntegerChecker()) ; return tid; } int16_t m_int16; }; - NS_OBJECT_ENSURE_REGISTERED (ConfigExample); + NS_OBJECT_ENSURE_REGISTERED(ConfigExample); Next, we use the Config subsystem to override the defaults in a couple of ways:: - Config::SetDefault ("ns3::ConfigExample::TestInt16", IntegerValue (-5)); + Config::SetDefault("ns3::ConfigExample::TestInt16", IntegerValue(-5)); - Ptr a_obj = CreateObject (); - NS_ABORT_MSG_UNLESS (a_obj->m_int16 == -5, - "Cannot set ConfigExample's integer attribute via Config::SetDefault"); + Ptr a_obj = CreateObject(); + NS_ABORT_MSG_UNLESS(a_obj->m_int16 == -5, + "Cannot set ConfigExample's integer attribute via Config::SetDefault"); - Ptr a2_obj = CreateObject (); - a2_obj->SetAttribute ("TestInt16", IntegerValue (-3)); + Ptr a2_obj = CreateObject(); + a2_obj->SetAttribute("TestInt16", IntegerValue(-3)); IntegerValue iv; - a2_obj->GetAttribute ("TestInt16", iv); - NS_ABORT_MSG_UNLESS (iv.Get () == -3, - "Cannot set ConfigExample's integer attribute via SetAttribute"); + a2_obj->GetAttribute("TestInt16", iv); + NS_ABORT_MSG_UNLESS(iv.Get() == -3, + "Cannot set ConfigExample's integer attribute via SetAttribute"); The next statement is necessary to make sure that (one of) the objects created is rooted in the configuration namespace as an object instance. @@ -1052,14 +1052,14 @@ or :cpp:class:`ns3::Channel` instance, but here, since we are working at the core level, we need to create a new root namespace object:: - Config::RegisterRootNamespaceObject (a2_obj); + Config::RegisterRootNamespaceObject(a2_obj); Writing +++++++ Next, we want to output the configuration store. The examples show how to do it in two formats, XML and raw text. In practice, one should perform -this step just before calling :cpp:func:`Simulator::Run ()` to save the +this step just before calling :cpp:func:`Simulator::Run()` to save the final configuration just before running the simulation. There are three Attributes that govern the behavior of the ConfigStore: @@ -1072,27 +1072,26 @@ the ConfigStore format is plain text or Xml (``"FileFormat=Xml"``) The example shows:: - Config::SetDefault ("ns3::ConfigStore::Filename", StringValue ("output-attributes.xml")); - Config::SetDefault ("ns3::ConfigStore::FileFormat", StringValue ("Xml")); - Config::SetDefault ("ns3::ConfigStore::Mode", StringValue ("Save")); + Config::SetDefault("ns3::ConfigStore::Filename", StringValue("output-attributes.xml")); + Config::SetDefault("ns3::ConfigStore::FileFormat", StringValue("Xml")); + Config::SetDefault("ns3::ConfigStore::Mode", StringValue("Save")); ConfigStore outputConfig; - outputConfig.ConfigureDefaults (); - outputConfig.ConfigureAttributes (); + outputConfig.ConfigureDefaults(); + outputConfig.ConfigureAttributes(); // Output config store to txt format - Config::SetDefault ("ns3::ConfigStore::Filename", StringValue ("output-attributes.txt")); - Config::SetDefault ("ns3::ConfigStore::FileFormat", StringValue ("RawText")); - Config::SetDefault ("ns3::ConfigStore::Mode", StringValue ("Save")); + Config::SetDefault("ns3::ConfigStore::Filename", StringValue("output-attributes.txt")); + Config::SetDefault("ns3::ConfigStore::FileFormat", StringValue("RawText")); + Config::SetDefault("ns3::ConfigStore::Mode", StringValue("Save")); ConfigStore outputConfig2; - outputConfig2.ConfigureDefaults (); - outputConfig2.ConfigureAttributes (); + outputConfig2.ConfigureDefaults(); + outputConfig2.ConfigureAttributes(); - Simulator::Run (); + Simulator::Run(); - Simulator::Destroy (); + Simulator::Destroy(); Note the placement of these statements just prior to the -:cpp:func:`Simulator::Run ()` statement. This output logs all of the values in place just prior to starting the simulation (*i.e*. after all of the configuration has taken place). @@ -1184,11 +1183,11 @@ are registered before being used in object construction). :: - Config::SetDefault ("ns3::ConfigStore::Filename", StringValue ("input-defaults.xml")); - Config::SetDefault ("ns3::ConfigStore::Mode", StringValue ("Load")); - Config::SetDefault ("ns3::ConfigStore::FileFormat", StringValue ("Xml")); + Config::SetDefault("ns3::ConfigStore::Filename", StringValue("input-defaults.xml")); + Config::SetDefault("ns3::ConfigStore::Mode", StringValue("Load")); + Config::SetDefault("ns3::ConfigStore::FileFormat", StringValue("Xml")); ConfigStore inputConfig; - inputConfig.ConfigureDefaults (); + inputConfig.ConfigureDefaults(); Next, note that loading of input configuration data is limited to Attribute default (*i.e*. not instance) values, and global values. Attribute instance @@ -1219,31 +1218,31 @@ write out the resulting attributes to a separate file called #include "ns3/config-store-module.h" ... - int main (...) + int main(...) { - Config::SetDefault ("ns3::ConfigStore::Filename", StringValue ("input-defaults.xml")); - Config::SetDefault ("ns3::ConfigStore::Mode", StringValue ("Load")); - Config::SetDefault ("ns3::ConfigStore::FileFormat", StringValue ("Xml")); + Config::SetDefault("ns3::ConfigStore::Filename", StringValue("input-defaults.xml")); + Config::SetDefault("ns3::ConfigStore::Mode", StringValue("Load")); + Config::SetDefault("ns3::ConfigStore::FileFormat", StringValue("Xml")); ConfigStore inputConfig; - inputConfig.ConfigureDefaults (); + inputConfig.ConfigureDefaults(); // - // Allow the user to override any of the defaults and the above Bind () at + // Allow the user to override any of the defaults and the above Bind() at // run-time, viacommand-line arguments // CommandLine cmd; - cmd.Parse (argc, argv); + cmd.Parse(argc, argv); // setup topology ... - // Invoke just before entering Simulator::Run () - Config::SetDefault ("ns3::ConfigStore::Filename", StringValue ("output-attributes.xml")); - Config::SetDefault ("ns3::ConfigStore::Mode", StringValue ("Save")); + // Invoke just before entering Simulator::Run() + Config::SetDefault("ns3::ConfigStore::Filename", StringValue("output-attributes.xml")); + Config::SetDefault("ns3::ConfigStore::Mode", StringValue("Save")); ConfigStore outputConfig; - outputConfig.ConfigureAttributes (); - Simulator::Run (); + outputConfig.ConfigureAttributes(); + Simulator::Run(); } ConfigStore use cases (pre- and post-simulation) @@ -1262,13 +1261,13 @@ As a matter of fact, some Objects might be created when the simulation starts. Hence, ConfigStore will not "report" their attributes if invoked earlier in the code. A typical workflow might involve running the simulation, calling ConfigStore -at the end of the simulation (after ``Simulator::Run ()`` and before ``Simulator::Destroy ()``) +at the end of the simulation (after ``Simulator::Run()`` and before ``Simulator::Destroy()``) This will show all the attributes in the Objects, both those with default values, and those with values changed during the simulation execution. To change these values, you'll need to either change the default (class-wide) attribute values (in this case call ConfigStore before the Object creation), or specific object attribute -(in this case call ConfigStore after the Object creation, typically just before ``Simulator::Run ()``. +(in this case call ConfigStore after the Object creation, typically just before ``Simulator::Run()``. ConfigStore GUI @@ -1278,7 +1277,7 @@ There is a GTK-based front end for the ConfigStore. This allows users to use a GUI to access and change variables. Some screenshots are presented here. They are the result of using GtkConfig on -``src/lte/examples/lena-dual-stripe.cc`` after ``Simulator::Run ()``. +``src/lte/examples/lena-dual-stripe.cc`` after ``Simulator::Run()``. .. _GtkConfig: @@ -1327,15 +1326,15 @@ is rerun. Usage is almost the same as the non-GTK-based version, but there are no :cpp:class:`ConfigStore` attributes involved:: - // Invoke just before entering Simulator::Run () + // Invoke just before entering Simulator::Run() GtkConfigStore config; - config.ConfigureDefaults (); - config.ConfigureAttributes (); + config.ConfigureDefaults(); + config.ConfigureAttributes(); Now, when you run the script, a GUI should pop up, allowing you to open menus of attributes on different nodes/objects, and then launch the simulation execution when you are done. Note that "launch the simulation" means to proceed with the simulation script. -If GtkConfigStore has been called after ``Simulator::Run ()`` the simulation will +If GtkConfigStore has been called after ``Simulator::Run()`` the simulation will not be started again - it will just end. diff --git a/doc/manual/source/callbacks.rst b/doc/manual/source/callbacks.rst index 2100fdc37..33a68f590 100644 --- a/doc/manual/source/callbacks.rst +++ b/doc/manual/source/callbacks.rst @@ -19,15 +19,15 @@ so that they can invoke methods on each other:: class A { public: - void ReceiveInput ( // parameters ); + void ReceiveInput( /* parameters */ ); ... } - (in another source file:) +and in another source file:: class B { public: - void DoSomething (); + void DoSomething(); ... private: @@ -38,7 +38,7 @@ so that they can invoke methods on each other:: B::DoSomething() { // Tell a_instance that something happened - a_instance->ReceiveInput ( // parameters); + a_instance->ReceiveInput( /* parameters */ ); ... } @@ -58,7 +58,9 @@ This is not an abstract problem for network simulation research, but rather it has been a source of problems in previous simulators, when researchers want to extend or modify the system to do different things (as they are apt to do in research). Consider, for example, a user who wants to add an IPsec security -protocol sublayer between TCP and IP:: +protocol sublayer between TCP and IP: + +.. code-block::text ------------ ----------- | TCP | | TCP | @@ -104,7 +106,7 @@ What you get from this is a variable named simply ``pfi`` that is initialized to the value 0. If you want to initialize this pointer to something meaningful, you have to have a function with a matching signature. In this case:: - int MyFunction (int arg) {} + int MyFunction(int arg) {} If you have this target, you can initialize the variable to point to your function like:: @@ -114,14 +116,14 @@ function like:: You can then call MyFunction indirectly using the more suggestive form of the call:: - int result = (*pfi) (1234); + int result = (*pfi)(1234); This is suggestive since it looks like you are dereferencing the function pointer just like you would dereference any pointer. Typically, however, people take advantage of the fact that the compiler knows what is going on and will just use a shorter form:: - int result = pfi (1234); + int result = pfi(1234); Notice that the function pointer obeys value semantics, so you can pass it around like any other value. Typically, when you use an asynchronous interface @@ -136,7 +138,7 @@ the pointer to function returning an int (PFI). The declaration of the variable providing the indirection looks only slightly different:: - int (MyClass::*pmi) (int arg) = 0; + int (MyClass::*pmi)(int arg) = 0; This declares a variable named ``pmi`` just as the previous example declared a variable named ``pfi``. Since the will be to call a method of an instance of a @@ -144,7 +146,7 @@ particular class, one must declare that method in a class:: class MyClass { public: - int MyMethod (int arg); + int MyMethod(int arg); }; Given this class declaration, one would then initialize that variable like @@ -158,18 +160,18 @@ pointer. This, in turn, means there must be an object of MyClass to refer to. A simplistic example of this is just calling a method indirectly (think virtual function):: - int (MyClass::*pmi) (int arg) = 0; // Declare a PMI + int (MyClass::*pmi)(int arg) = 0; // Declare a PMI pmi = &MyClass::MyMethod; // Point at the implementation code MyClass myClass; // Need an instance of the class - (myClass.*pmi) (1234); // Call the method with an object ptr + (myClass.*pmi)(1234); // Call the method with an object ptr Just like in the C example, you can use this in an asynchronous call to another module which will *call back* using a method and an object pointer. The straightforward extension one might consider is to pass a pointer to the object and the PMI variable. The module would just do:: - (*objectPtr.*pmi) (1234); + (*objectPtr.*pmi)(1234); to execute the callback on the desired object. @@ -186,12 +188,12 @@ It is basically just a packaged-up function call, possibly with some state. A functor has two parts, a specific part and a generic part, related through inheritance. The calling code (the code that executes the callback) will execute -a generic overloaded ``operator ()`` of a generic functor to cause the callback +a generic overloaded ``operator()`` of a generic functor to cause the callback to be called. The called code (the code that wants to be called back) will have -to provide a specialized implementation of the ``operator ()`` that performs the +to provide a specialized implementation of the ``operator()`` that performs the class-specific work that caused the close-coupling problem above. -With the specific functor and its overloaded ``operator ()`` created, the called +With the specific functor and its overloaded ``operator()`` created, the called code then gives the specialized code to the module that will execute the callback (the calling code). @@ -210,7 +212,7 @@ of the functor:: class Functor { public: - virtual int operator() (T arg) = 0; + virtual int operator()(T arg) = 0; }; The caller defines a specific part of the functor that really is just there to @@ -226,7 +228,7 @@ implement the specific ``operator()`` method:: m_pmi = _pmi; } - virtual int operator() (ARG arg) + virtual int operator()(ARG arg) { (*m_p.*m_pmi)(arg); } @@ -240,8 +242,8 @@ Here is an example of the usage:: class A { public: - A (int a0) : a (a0) {} - int Hello (int b0) + A(int a0) : a(a0) {} + int Hello(int b0) { std::cout << "Hello from A, a = " << a << " b0 = " << b0 << std::endl; } @@ -269,19 +271,19 @@ with the object pointer using the C++ PMI syntax. To use this, one could then declare some model code that takes a generic functor as a parameter:: - void LibraryFunction (Functor functor); + void LibraryFunction(Functor functor); The code that will talk to the model would build a specific functor and pass it to ``LibraryFunction``:: MyClass myClass; - SpecificFunctor functor (&myclass, MyClass::MyMethod); + SpecificFunctor functor(&myclass, MyClass::MyMethod); When ``LibraryFunction`` is done, it executes the callback using the ``operator()`` on the generic functor it was passed, and in this particular case, provides the integer argument:: void - LibraryFunction (Functor functor) + LibraryFunction(Functor functor) { // Execute the library function functor(1234); @@ -319,7 +321,7 @@ Using the Callback API with static functions Consider a function:: static double - CbOne (double a, double b) + CbOne(double a, double b) { std::cout << "invoke cbOne a=" << a << ", b=" << b << std::endl; return a; @@ -327,7 +329,7 @@ Consider a function:: Consider also the following main program snippet:: - int main (int argc, char *argv[]) + int main(int argc, char *argv[]) { // return type: double // first arg type: double @@ -365,7 +367,7 @@ Now, we need to tie together this callback instance and the actual target functi callback-- this is important. We can pass in any such properly-typed function to this callback. Let's look at this more closely:: - static double CbOne (double a, double b) {} + static double CbOne(double a, double b) {} ^ ^ ^ | | | | | | @@ -378,21 +380,21 @@ arguments are the types of the arguments of the function signature. Now, let's bind our callback "one" to the function that matches its signature:: // build callback instance which points to cbOne function - one = MakeCallback (&CbOne); + one = MakeCallback(&CbOne); This call to ``MakeCallback`` is, in essence, creating one of the specialized functors mentioned above. The variable declared using the ``Callback`` template function is going to be playing the part of the generic functor. The -assignment ``one = MakeCallback (&CbOne)`` is the cast that converts the +assignment ``one = MakeCallback(&CbOne)`` is the cast that converts the specialized functor known to the callee to a generic functor known to the caller. Then, later in the program, if the callback is needed, it can be used as follows:: - NS_ASSERT (!one.IsNull ()); + NS_ASSERT(!one.IsNull()); // invoke cbOne function through callback instance double retOne; - retOne = one (10.0, 20.0); + retOne = one(10.0, 20.0); The check for ``IsNull()`` ensures that the callback is not null -- that there is a function to call behind this callback. Then, ``one()`` executes the @@ -410,13 +412,13 @@ invoked. Consider this example, also from main-callback.cc:: class MyCb { public: - int CbTwo (double a) { + int CbTwo(double a) { std::cout << "invoke cbTwo a=" << a << std::endl; return -5; } }; - int main () + int main() { ... // return type: int @@ -424,7 +426,7 @@ invoked. Consider this example, also from main-callback.cc:: Callback two; MyCb cb; // build callback instance which points to MyCb::cbTwo - two = MakeCallback (&MyCb::CbTwo, &cb); + two = MakeCallback(&MyCb::CbTwo, &cb); ... } @@ -432,7 +434,7 @@ Here, we pass an additional object pointer to the ``MakeCallback<>`` function. Recall from the background section above that ``Operator()`` will use the pointer to member syntax when it executes on an object:: - virtual int operator() (ARG arg) + virtual int operator()(ARG arg) { (*m_p.*m_pmi)(arg); } @@ -440,11 +442,11 @@ member syntax when it executes on an object:: And so we needed to provide the two variables (``m_p`` and ``m_pmi``) when we made the specific functor. The line:: - two = MakeCallback (&MyCb::CbTwo, &cb); + two = MakeCallback(&MyCb::CbTwo, &cb); -does precisely that. In this case, when ``two ()`` is invoked:: +does precisely that. In this case, when ``two()`` is invoked:: - int result = two (1.0); + int result = two(1.0); will result in a call to the ``CbTwo`` member function (method) on the object pointed to by ``&cb``. @@ -457,8 +459,8 @@ check before using them. There is a special construct for a null callback, which is preferable to simply passing "0" as an argument; it is the ``MakeNullCallback<>`` construct:: - two = MakeNullCallback (); - NS_ASSERT (two.IsNull ()); + two = MakeNullCallback(); + NS_ASSERT(two.IsNull()); Invoking a null callback is just like invoking a null function pointer: it will crash at runtime. @@ -484,14 +486,14 @@ function that needs to be called whenever a packet is received. This function calls an object that actually writes the packet to disk in the pcap file format. The signature of one of these functions will be:: - static void DefaultSink (Ptr file, Ptr p); + static void DefaultSink(Ptr file, Ptr p); The static keyword means this is a static function which does not need a ``this`` pointer, so it will be using C-style callbacks. We don't want the calling code to have to know about anything but the Packet. What we want in the calling code is just a call that looks like:: - m_promiscSnifferTrace (m_currentPkt); + m_promiscSnifferTrace(m_currentPkt); What we want to do is to *bind* the ``Ptr file`` to the specific callback implementation when it is created and arrange for the @@ -501,7 +503,7 @@ We provide the ``MakeBoundCallback`` template function for that purpose. It takes the same parameters as the ``MakeCallback`` template function but also takes the parameters to be bound. In the case of the example above:: - MakeBoundCallback (&DefaultSink, file); + MakeBoundCallback(&DefaultSink, file); will create a specific callback implementation that knows to add in the extra bound arguments. Conceptually, it extends the specific functor described above @@ -518,7 +520,7 @@ with one or more bound arguments:: m_boundArg = boundArg; } - virtual int operator() (ARG arg) + virtual int operator()(ARG arg) { (*m_p.*m_pmi)(m_boundArg, arg); } @@ -532,7 +534,7 @@ You can see that when the specific functor is created, the bound argument is sav in the functor / callback object itself. When the ``operator()`` is invoked with the single parameter, as in:: - m_promiscSnifferTrace (m_currentPkt); + m_promiscSnifferTrace(m_currentPkt); the implementation of ``operator()`` adds the bound parameter into the actual function call:: @@ -542,20 +544,20 @@ function call:: It's possible to bind two or three arguments as well. Say we have a function with signature:: - static void NotifyEvent (Ptr a, Ptr b, MyEventType e); + static void NotifyEvent(Ptr a, Ptr b, MyEventType e); One can create bound callback binding first two arguments like:: - MakeBoundCallback (&NotifyEvent, a1, b1); + MakeBoundCallback(&NotifyEvent, a1, b1); assuming `a1` and `b1` are objects of type `A` and `B` respectively. Similarly for three arguments one would have function with a signature:: - static void NotifyEvent (Ptr a, Ptr b, MyEventType e); + static void NotifyEvent(Ptr a, Ptr b, MyEventType e); Binding three arguments in done with:: - MakeBoundCallback (&NotifyEvent, a1, b1, c1); + MakeBoundCallback(&NotifyEvent, a1, b1, c1); again assuming `a1`, `b1` and `c1` are objects of type `A`, `B` and `C` respectively. diff --git a/doc/manual/source/documentation.rst b/doc/manual/source/documentation.rst index cd3a5161d..2395d0fb5 100644 --- a/doc/manual/source/documentation.rst +++ b/doc/manual/source/documentation.rst @@ -213,7 +213,7 @@ the basics here, instead focusing on preferred usage for |ns3|. | The ``Frobnitz`` is accessed by:: | The ``Frobnitz`` is accessed by:: | | | | | Foo::Frobnitz frob; | Foo::Frobnitz frob; | - | frob.Set (...); | frob.Set (...); | + | frob.Set(...); | frob.Set(...); | +--------------------------------------+------------------------------------+ To use a specific syntax highlighter, for example, ``bash`` shell commands: @@ -315,7 +315,7 @@ The preferred style for Doxygen comments is the JavaDoc style:: * Understanding this material shouldn't be necessary to using * the class or method. */ - void ExampleFunction (const int foo, double & bar, const bool baz); + void ExampleFunction(const int foo, double & bar, const bool baz); In this style the Doxygen comment block begins with two \`*' characters: ``/**``, and precedes the item being documented. @@ -324,7 +324,7 @@ For items needing only a brief description, either of these short forms is appropriate:: /** Destructor implementation. */ - void DoDispose (); + void DoDispose(); int m_count; //!< Count of ... @@ -355,8 +355,8 @@ Useful Features #. In the sub class mark inherited functions with an ordinary comment:: // Inherited methods - virtual void FooBar (); - virtual int BarFoo (double baz); + virtual void FooBar(); + virtual int BarFoo(double baz); This doesn't work for static functions; see ``GetTypeId``, below, for an example. @@ -596,7 +596,7 @@ usage for |ns3|. * \tparam U \deduced The argument type. * \param [in] a The argument. */ - template T Function (U a); + template T Function(U a); * Use ``\tparam U \deduced`` because the type ``U`` can be deduced at the site where the template is invoked. Basically deduction can only @@ -604,7 +604,7 @@ usage for |ns3|. * Use ``\tparam T \explicit`` because the type ``T`` can't be deduced; it must be given explicitly at the invocation site, as in - ``Create (...)`` + ``Create(...)`` * ``\internal`` should be used only to set off a discussion of implementation details, not to mark ``private`` functions (they are already marked, @@ -621,16 +621,16 @@ cases is: * Default constructor/destructor:: - MyClass (); //!< Default constructor - ~MyClass (); //!< Destructor + MyClass(); //!< Default constructor + ~MyClass(); //!< Destructor * Dummy destructor and DoDispose:: /** Dummy destructor, see DoDispose. */ - ~MyClass (); + ~MyClass(); /** Destructor implementation */ - virtual void DoDispose (); + virtual void DoDispose(); * GetTypeId:: @@ -638,4 +638,4 @@ cases is: * Register this type. * \return The object TypeId. */ - static TypeId GetTypeId (); + static TypeId GetTypeId(); diff --git a/doc/manual/source/events.rst b/doc/manual/source/events.rst index 0a7d6c373..b32f01c64 100644 --- a/doc/manual/source/events.rst +++ b/doc/manual/source/events.rst @@ -62,7 +62,7 @@ might write this: :: - void handler (int arg0, int arg1) + void handler(int arg0, int arg1) { std::cout << "handler called with argument arg0=" << arg0 << " and arg1=" << arg1 << std::endl; @@ -115,13 +115,13 @@ What does this mean? :: - Simulator::Schedule (Time const &time, MEM mem_ptr, OBJ obj); + Simulator::Schedule(Time const &time, MEM mem_ptr, OBJ obj); vs. :: - Simulator::ScheduleWithContext (uint32_t context, Time const &time, MEM mem_ptr, OBJ obj); + Simulator::ScheduleWithContext(uint32_t context, Time const &time, MEM mem_ptr, OBJ obj); Readers who invest time and effort in developing or using a non-trivial simulation model will know the value of the |ns3| logging framework to @@ -212,8 +212,8 @@ event execution. These are derived from the abstract base class `SimulatorImpl` You can choose which simulator engine to use by setting a global variable, for example:: - GlobalValue::Bind ("SimulatorImplementationType", - StringValue ("ns3::DistributedSimulatorImpl")); + GlobalValue::Bind("SimulatorImplementationType", + StringValue("ns3::DistributedSimulatorImpl")); or by using a command line argument:: @@ -306,8 +306,8 @@ The main job of the `Scheduler` classes is to maintain the priority queue of future events. The scheduler can be set with a global variable, similar to choosing the `SimulatorImpl`:: - GlobalValue::Bind ("SchedulerType", - StringValue ("ns3::DistributedSimulatorImpl")); + GlobalValue::Bind("SchedulerType", + StringValue("ns3::DistributedSimulatorImpl")); The scheduler can be changed at any time via `Simulator::SetScheduler()`. The default scheduler is `MapScheduler` which uses a `std::map<>` to @@ -343,6 +343,3 @@ complexity of the other API calls. +-----------------------+-------------------------------------+-------------+--------------+----------+--------------+ | PriorityQueueSchduler | `std::priority_queue<,std::vector>` | Logarithimc | Logarithims | 24 bytes | 0 | +-----------------------+-------------------------------------+-------------+--------------+----------+--------------+ - - - diff --git a/doc/manual/source/gnuplot.rst b/doc/manual/source/gnuplot.rst index 7e885bb31..aa8e0435b 100644 --- a/doc/manual/source/gnuplot.rst +++ b/doc/manual/source/gnuplot.rst @@ -88,24 +88,24 @@ was created using the following code from gnuplot-example.cc: :: std::string dataTitle = "2-D Data"; // Instantiate the plot and set its title. - Gnuplot plot (graphicsFileName); - plot.SetTitle (plotTitle); + Gnuplot plot(graphicsFileName); + plot.SetTitle(plotTitle); // Make the graphics file, which the plot file will create when it // is used with Gnuplot, be a PNG file. - plot.SetTerminal ("png"); + plot.SetTerminal("png"); // Set the labels for each axis. - plot.SetLegend ("X Values", "Y Values"); + plot.SetLegend("X Values", "Y Values"); // Set the range for the x axis. - plot.AppendExtra ("set xrange [-6:+6]"); + plot.AppendExtra("set xrange [-6:+6]"); // Instantiate the dataset, set its title, and make the points be // plotted along with connecting lines. Gnuplot2dDataset dataset; - dataset.SetTitle (dataTitle); - dataset.SetStyle (Gnuplot2dDataset::LINES_POINTS); + dataset.SetTitle(dataTitle); + dataset.SetStyle(Gnuplot2dDataset::LINES_POINTS); double x; double y; @@ -121,20 +121,20 @@ was created using the following code from gnuplot-example.cc: :: y = x * x; // Add this point. - dataset.Add (x, y); + dataset.Add(x, y); } // Add the dataset to the plot. - plot.AddDataset (dataset); + plot.AddDataset(dataset); // Open the plot file. - std::ofstream plotFile (plotFileName.c_str()); + std::ofstream plotFile(plotFileName.c_str()); // Write the plot file. - plot.GenerateOutput (plotFile); + plot.GenerateOutput(plotFile); // Close the plot file. - plotFile.close (); + plotFile.close(); An Example 2-Dimensional Plot with Error Bars ********************************************* @@ -154,27 +154,27 @@ was created using the following code from gnuplot-example.cc: :: std::string dataTitle = "2-D Data With Error Bars"; // Instantiate the plot and set its title. - Gnuplot plot (graphicsFileName); - plot.SetTitle (plotTitle); + Gnuplot plot(graphicsFileName); + plot.SetTitle(plotTitle); // Make the graphics file, which the plot file will create when it // is used with Gnuplot, be a PNG file. - plot.SetTerminal ("png"); + plot.SetTerminal("png"); // Set the labels for each axis. - plot.SetLegend ("X Values", "Y Values"); + plot.SetLegend("X Values", "Y Values"); // Set the range for the x axis. - plot.AppendExtra ("set xrange [-6:+6]"); + plot.AppendExtra("set xrange [-6:+6]"); // Instantiate the dataset, set its title, and make the points be // plotted with no connecting lines. Gnuplot2dDataset dataset; - dataset.SetTitle (dataTitle); - dataset.SetStyle (Gnuplot2dDataset::POINTS); + dataset.SetTitle(dataTitle); + dataset.SetStyle(Gnuplot2dDataset::POINTS); // Make the dataset have error bars in both the x and y directions. - dataset.SetErrorBars (Gnuplot2dDataset::XY); + dataset.SetErrorBars(Gnuplot2dDataset::XY); double x; double xErrorDelta; @@ -199,20 +199,20 @@ was created using the following code from gnuplot-example.cc: :: // Add this point with uncertainties in both the x and y // direction. - dataset.Add (x, y, xErrorDelta, yErrorDelta); + dataset.Add(x, y, xErrorDelta, yErrorDelta); } // Add the dataset to the plot. - plot.AddDataset (dataset); + plot.AddDataset(dataset); // Open the plot file. - std::ofstream plotFile (plotFileName.c_str()); + std::ofstream plotFile(plotFileName.c_str()); // Write the plot file. - plot.GenerateOutput (plotFile); + plot.GenerateOutput(plotFile); // Close the plot file. - plotFile.close (); + plotFile.close(); An Example 3-Dimensional Plot ***************************** @@ -232,34 +232,34 @@ was created using the following code from gnuplot-example.cc: :: std::string dataTitle = "3-D Data"; // Instantiate the plot and set its title. - Gnuplot plot (graphicsFileName); - plot.SetTitle (plotTitle); + Gnuplot plot(graphicsFileName); + plot.SetTitle(plotTitle); // Make the graphics file, which the plot file will create when it // is used with Gnuplot, be a PNG file. - plot.SetTerminal ("png"); + plot.SetTerminal("png"); // Rotate the plot 30 degrees around the x axis and then rotate the // plot 120 degrees around the new z axis. - plot.AppendExtra ("set view 30, 120, 1.0, 1.0"); + plot.AppendExtra("set view 30, 120, 1.0, 1.0"); // Make the zero for the z-axis be in the x-axis and y-axis plane. - plot.AppendExtra ("set ticslevel 0"); + plot.AppendExtra("set ticslevel 0"); // Set the labels for each axis. - plot.AppendExtra ("set xlabel 'X Values'"); - plot.AppendExtra ("set ylabel 'Y Values'"); - plot.AppendExtra ("set zlabel 'Z Values'"); + plot.AppendExtra("set xlabel 'X Values'"); + plot.AppendExtra("set ylabel 'Y Values'"); + plot.AppendExtra("set zlabel 'Z Values'"); // Set the ranges for the x and y axis. - plot.AppendExtra ("set xrange [-5:+5]"); - plot.AppendExtra ("set yrange [-5:+5]"); + plot.AppendExtra("set xrange [-5:+5]"); + plot.AppendExtra("set yrange [-5:+5]"); // Instantiate the dataset, set its title, and make the points be // connected by lines. Gnuplot3dDataset dataset; - dataset.SetTitle (dataTitle); - dataset.SetStyle ("with lines"); + dataset.SetTitle(dataTitle); + dataset.SetStyle("with lines"); double x; double y; @@ -278,22 +278,22 @@ was created using the following code from gnuplot-example.cc: :: z = x * x * y * y; // Add this point. - dataset.Add (x, y, z); + dataset.Add(x, y, z); } // The blank line is necessary at the end of each x value's data // points for the 3-D surface grid to work. - dataset.AddEmptyLine (); + dataset.AddEmptyLine(); } // Add the dataset to the plot. - plot.AddDataset (dataset); + plot.AddDataset(dataset); // Open the plot file. - std::ofstream plotFile (plotFileName.c_str()); + std::ofstream plotFile(plotFileName.c_str()); // Write the plot file. - plot.GenerateOutput (plotFile); + plot.GenerateOutput(plotFile); // Close the plot file. - plotFile.close (); + plotFile.close(); diff --git a/doc/manual/source/hash-functions.rst b/doc/manual/source/hash-functions.rst index 4d52f9313..221ea3544 100644 --- a/doc/manual/source/hash-functions.rst +++ b/doc/manual/source/hash-functions.rst @@ -99,7 +99,7 @@ To add the hash function ``foo``, follow the ``hash-murmur3.h``/``.cc`` pattern: * ``include`` the declaration in ``hash.h`` (at the point where ``hash-murmur3.h`` is included. * In your own code, instantiate a ``Hasher`` object via the constructor - ``Hasher (Ptr ())`` + ``Hasher(Ptr())`` If your hash function is a single function, e.g. ``hashf``, you don't diff --git a/doc/manual/source/how-to-write-tests.rst b/doc/manual/source/how-to-write-tests.rst index 626968a74..5a560cedf 100644 --- a/doc/manual/source/how-to-write-tests.rst +++ b/doc/manual/source/how-to-write-tests.rst @@ -60,8 +60,8 @@ is called "router" such as here: :: - RouterTestSuite::RouterTestSuite () - : TestSuite ("router", UNIT) + RouterTestSuite::RouterTestSuite() + : TestSuite("router", UNIT) Try this command: @@ -154,8 +154,8 @@ which looks like this: :: #include "ns3/example-as-test.h" - static ns3::ExampleAsTestSuite g_modExampleOne ("mymodule-example-mod-example-one", "mod-example", NS_TEST_SOURCEDIR, "--arg-one"); - static ns3::ExampleAsTestSuite g_modExampleTwo ("mymodule-example-mod-example-two", "mod-example", NS_TEST_SOURCEDIR, "--arg-two"); + static ns3::ExampleAsTestSuite g_modExampleOne("mymodule-example-mod-example-one", "mod-example", NS_TEST_SOURCEDIR, "--arg-one"); + static ns3::ExampleAsTestSuite g_modExampleTwo("mymodule-example-mod-example-two", "mod-example", NS_TEST_SOURCEDIR, "--arg-two"); The arguments to the constructor are the name of the test suite, the example to run, the directory that contains the "good" reference file @@ -240,11 +240,11 @@ the wifi Information Elements. ... }; void - BasicMultiLinkElementTest::DoRun () + BasicMultiLinkElementTest::DoRun() { - MultiLinkElement mle (WIFI_MAC_MGT_BEACON); + MultiLinkElement mle(WIFI_MAC_MGT_BEACON); // Fill in the Multi-Link Element - TestHeaderSerialization (mle, WIFI_MAC_MGT_BEACON); + TestHeaderSerialization(mle, WIFI_MAC_MGT_BEACON); } Examples of this approach are found, e.g., in ``src/wifi/test/wifi-eht-info-elems-test.cc`` diff --git a/doc/manual/source/logging.rst b/doc/manual/source/logging.rst index 6cd54ef45..e7ff93db6 100644 --- a/doc/manual/source/logging.rst +++ b/doc/manual/source/logging.rst @@ -31,9 +31,9 @@ use of a particular function. For example, this code snippet is from ``Ipv4L3Protocol::IsDestinationAddress()``:: - if (address == iaddr.GetBroadcast ()) + if (address == iaddr.GetBroadcast()) { - NS_LOG_LOGIC ("For me (interface broadcast address)"); + NS_LOG_LOGIC("For me (interface broadcast address)"); return true; } @@ -66,10 +66,10 @@ The second way to enable logging is to use explicit statements in your program, such as in the ``first`` tutorial program:: int - main (int argc, char *argv[]) + main(int argc, char *argv[]) { - LogComponentEnable ("UdpEchoClientApplication", LOG_LEVEL_INFO); - LogComponentEnable ("UdpEchoServerApplication", LOG_LEVEL_INFO); + LogComponentEnable("UdpEchoClientApplication", LOG_LEVEL_INFO); + LogComponentEnable("UdpEchoServerApplication", LOG_LEVEL_INFO); ... (The meaning of ``LOG_LEVEL_INFO``, and other possible values, @@ -107,7 +107,7 @@ in a module, spanning different compilation units, but logically grouped together, such as the |ns3| wifi code:: WifiHelper wifiHelper; - wifiHelper.EnableLogComponents (); + wifiHelper.EnableLogComponents(); The ``NS_LOG`` log component wildcard \`*' will enable all components. @@ -319,7 +319,7 @@ How to add logging to your code Adding logging to your code is very simple: -1. Invoke the ``NS_LOG_COMPONENT_DEFINE (...);`` macro +1. Invoke the ``NS_LOG_COMPONENT_DEFINE(...);`` macro inside of ``namespace ns3``. Create a unique string identifier (usually based on the name of the file @@ -330,7 +330,7 @@ Adding logging to your code is very simple: namespace ns3 { - NS_LOG_COMPONENT_DEFINE ("Ipv4L3Protocol"); + NS_LOG_COMPONENT_DEFINE("Ipv4L3Protocol"); ... This registers ``Ipv4L3Protocol`` as a log component. @@ -361,15 +361,15 @@ In case you want to add logging statements to the methods of your template class This requires you to perform these steps for all the subclasses of your class. -2. Invoke the ``NS_LOG_TEMPLATE_DEFINE (...);`` macro in the constructor of +2. Invoke the ``NS_LOG_TEMPLATE_DEFINE(...);`` macro in the constructor of your class by providing the name of a log component registered by calling - the ``NS_LOG_COMPONENT_DEFINE (...);`` macro in some module. For instance: + the ``NS_LOG_COMPONENT_DEFINE(...);`` macro in some module. For instance: :: template - Queue::Queue () - : NS_LOG_TEMPLATE_DEFINE ("Queue") + Queue::Queue() + : NS_LOG_TEMPLATE_DEFINE("Queue") { } @@ -380,18 +380,18 @@ In case you want to add logging statements to a static member template 1. Invoke the ``NS_LOG_STATIC_TEMPLATE_DEFINE (...);`` macro in your static method by providing the name of a log component registered by calling - the ``NS_LOG_COMPONENT_DEFINE (...);`` macro in some module. For instance: + the ``NS_LOG_COMPONENT_DEFINE(...);`` macro in some module. For instance: :: template void - NetDeviceQueue::PacketEnqueued (Ptr > queue, - Ptr ndqi, - uint8_t txq, Ptr item) + NetDeviceQueue::PacketEnqueued(Ptr > queue, + Ptr ndqi, + uint8_t txq, Ptr item) { - NS_LOG_STATIC_TEMPLATE_DEFINE ("NetDeviceQueueInterface"); + NS_LOG_STATIC_TEMPLATE_DEFINE("NetDeviceQueueInterface"); ... 2. Add logging statements (macro calls) to your static method. @@ -433,24 +433,24 @@ Logging Macros Severity Class Macro ================ ========================== ``LOG_NONE`` (none needed) - ``LOG_ERROR`` ``NS_LOG_ERROR (...);`` - ``LOG_WARN`` ``NS_LOG_WARN (...);`` - ``LOG_DEBUG`` ``NS_LOG_DEBUG (...);`` - ``LOG_INFO`` ``NS_LOG_INFO (...);`` - ``LOG_FUNCTION`` ``NS_LOG_FUNCTION (...);`` - ``LOG_LOGIC`` ``NS_LOG_LOGIC (...);`` + ``LOG_ERROR`` ``NS_LOG_ERROR(...);`` + ``LOG_WARN`` ``NS_LOG_WARN(...);`` + ``LOG_DEBUG`` ``NS_LOG_DEBUG(...);`` + ``LOG_INFO`` ``NS_LOG_INFO(...);`` + ``LOG_FUNCTION`` ``NS_LOG_FUNCTION(...);`` + ``LOG_LOGIC`` ``NS_LOG_LOGIC(...);`` ================ ========================== The macros function as output streamers, so anything you can send to ``std::cout``, joined by ``<<`` operators, is allowed:: - void MyClass::Check (int value, char * item) + void MyClass::Check(int value, char * item) { - NS_LOG_FUNCTION (this << arg << item); + NS_LOG_FUNCTION(this << arg << item); if (arg > 10) { - NS_LOG_ERROR ("encountered bad value " << value << - " while checking " << name << "!"); + NS_LOG_ERROR("encountered bad value " << value << + " while checking " << name << "!"); } ... } @@ -463,7 +463,7 @@ Logging Macros Unconditional Logging ===================== -As a convenience, the ``NS_LOG_UNCOND (...);`` macro will always log its +As a convenience, the ``NS_LOG_UNCOND(...);`` macro will always log its arguments, even if the associated log-component is not enabled at any severity. This macro does not use any of the prefix options. Note that logging is only enabled in debug builds; this macro won't produce @@ -473,19 +473,19 @@ output in optimized builds. Guidelines ========== -* Start every class method with ``NS_LOG_FUNCTION (this << args...);`` +* Start every class method with ``NS_LOG_FUNCTION(this << args...);`` This enables easy function call tracing. * Except: don't log operators or explicit copy constructors, since these will cause infinite recursion and stack overflow. * For methods without arguments use the same form: - ``NS_LOG_FUNCTION (this);`` + ``NS_LOG_FUNCTION(this);`` * For static functions: - * With arguments use ``NS_LOG_FUNCTION (...);`` as normal. - * Without arguments use ``NS_LOG_FUNCTION_NOARGS ();`` + * With arguments use ``NS_LOG_FUNCTION(...);`` as normal. + * Without arguments use ``NS_LOG_FUNCTION_NOARGS();`` * Use ``NS_LOG_ERROR`` for serious error conditions that probably invalidate the simulation execution. @@ -507,10 +507,7 @@ Guidelines ``NS_LOG="***"``). * Use an explicit cast for any variable of type uint8_t or int8_t, - e.g., ``NS_LOG_LOGIC ("Variable i is " << static_cast (i));``. + e.g., ``NS_LOG_LOGIC("Variable i is " << static_cast(i));``. Without the cast, the integer is interpreted as a char, and the result will be most likely not in line with the expectations. This is a well documented C++ 'feature'. - - - diff --git a/doc/manual/source/new-models.rst b/doc/manual/source/new-models.rst index 93ded3a14..db813d2c1 100644 --- a/doc/manual/source/new-models.rst +++ b/doc/manual/source/new-models.rst @@ -62,7 +62,7 @@ So far, in our design, we have:: * \returns true if the Packet is to be considered as errored/corrupted * \param pkt Packet to apply error model to */ - bool IsCorrupt (Ptr pkt); + bool IsCorrupt(Ptr pkt); }; Note that we do not pass a const pointer, thereby allowing the function to @@ -109,16 +109,16 @@ a base class and first subclass that could be posted for initial review:: class ErrorModel { public: - ErrorModel (); - virtual ~ErrorModel (); - bool IsCorrupt (Ptr pkt); - void Reset (); - void Enable (); - void Disable (); - bool IsEnabled () const; + ErrorModel(); + virtual ~ErrorModel(); + bool IsCorrupt(Ptr pkt); + void Reset(); + void Enable(); + void Disable(); + bool IsEnabled() const; private: - virtual bool DoCorrupt (Ptr pkt) = 0; - virtual void DoReset () = 0; + virtual bool DoCorrupt(Ptr pkt) = 0; + virtual void DoReset() = 0; }; enum ErrorUnit @@ -133,16 +133,16 @@ a base class and first subclass that could be posted for initial review:: class RateErrorModel : public ErrorModel { public: - RateErrorModel (); - virtual ~RateErrorModel (); - enum ErrorUnit GetUnit () const; - void SetUnit (enum ErrorUnit error_unit); - double GetRate () const; - void SetRate (double rate); - void SetRandomVariable (const RandomVariable &ranvar); + RateErrorModel(); + virtual ~RateErrorModel(); + enum ErrorUnit GetUnit() const; + void SetUnit(enum ErrorUnit error_unit); + double GetRate() const; + void SetRate(double rate); + void SetRandomVariable(const RandomVariable &ranvar); private: - virtual bool DoCorrupt (Ptr pkt); - virtual void DoReset (); + virtual bool DoCorrupt(Ptr pkt); + virtual void DoReset(); }; @@ -294,19 +294,19 @@ from class Object.:: class ErrorModel : public Object { public: - static TypeId GetTypeId (); + static TypeId GetTypeId(); - ErrorModel (); - virtual ~ErrorModel (); + ErrorModel(); + virtual ~ErrorModel(); }; class RateErrorModel : public ErrorModel { public: - static TypeId GetTypeId (); + static TypeId GetTypeId(); - RateErrorModel (); - virtual ~RateErrorModel (); + RateErrorModel(); + virtual ~RateErrorModel(); }; #endif @@ -319,7 +319,7 @@ But we are in ``src/network/model``, so we must include it as "``#include "ns3/object.h"``". Note also that this goes outside the namespace declaration. Second, each class must implement a static public member function called -``GetTypeId ()``. +``GetTypeId()``. Third, it is a good idea to implement constructors and destructors rather than to let the compiler generate them, and to make the destructor virtual. In C++, @@ -335,52 +335,52 @@ file.:: namespace ns3 { - NS_OBJECT_ENSURE_REGISTERED (ErrorModel); + NS_OBJECT_ENSURE_REGISTERED(ErrorModel); - TypeId ErrorModel::GetTypeId () + TypeId ErrorModel::GetTypeId() { - static TypeId tid = TypeId ("ns3::ErrorModel") - .SetParent () - .SetGroupName ("Network") + static TypeId tid = TypeId("ns3::ErrorModel") + .SetParent() + .SetGroupName("Network") ; return tid; } - ErrorModel::ErrorModel () + ErrorModel::ErrorModel() { } - ErrorModel::~ErrorModel () + ErrorModel::~ErrorModel() { } - NS_OBJECT_ENSURE_REGISTERED (RateErrorModel); + NS_OBJECT_ENSURE_REGISTERED(RateErrorModel); - TypeId RateErrorModel::GetTypeId () + TypeId RateErrorModel::GetTypeId() { - static TypeId tid = TypeId ("ns3::RateErrorModel") - .SetParent () - .SetGroupName ("Network") - .AddConstructor () + static TypeId tid = TypeId("ns3::RateErrorModel") + .SetParent() + .SetGroupName("Network") + .AddConstructor() ; return tid; } - RateErrorModel::RateErrorModel () + RateErrorModel::RateErrorModel() { } - RateErrorModel::~RateErrorModel () + RateErrorModel::~RateErrorModel() { } -What is the ``GetTypeId ()`` function? This function does a few things. It +What is the ``GetTypeId()`` function? This function does a few things. It registers a unique string into the TypeId system. It establishes the hierarchy of objects in the attribute system (via ``SetParent``). It also declares that certain objects can be created via the object creation framework (``AddConstructor``). -The macro ``NS_OBJECT_ENSURE_REGISTERED (classname)`` is needed also once for +The macro ``NS_OBJECT_ENSURE_REGISTERED(classname)`` is needed also once for every class that defines a new GetTypeId method, and it does the actual registration of the class into the system. The :ref:`Object-model` chapter discusses this in more detail. @@ -434,35 +434,35 @@ Add Accessor :: void - PointToPointNetDevice::SetReceiveErrorModel (Ptr em) + PointToPointNetDevice::SetReceiveErrorModel(Ptr em) { - NS_LOG_FUNCTION (this << em); + NS_LOG_FUNCTION(this << em); m_receiveErrorModel = em; } - .AddAttribute ("ReceiveErrorModel", + .AddAttribute("ReceiveErrorModel", "The receiver error model used to simulate packet loss", - PointerValue (), - MakePointerAccessor (&PointToPointNetDevice::m_receiveErrorModel), - MakePointerChecker ()) + PointerValue(), + MakePointerAccessor(&PointToPointNetDevice::m_receiveErrorModel), + MakePointerChecker()) Plumb Into the System +++++++++++++++++++++ :: - void PointToPointNetDevice::Receive (Ptr packet) + void PointToPointNetDevice::Receive(Ptr packet) { - NS_LOG_FUNCTION (this << packet); + NS_LOG_FUNCTION(this << packet); uint16_t protocol = 0; - if (m_receiveErrorModel && m_receiveErrorModel->IsCorrupt (packet) ) + if(m_receiveErrorModel && m_receiveErrorModel->IsCorrupt(packet) ) { // // If we have an error model and it indicates that it is time to lose a // corrupted packet, don't forward this packet up, let it go. // - m_dropTrace (packet); + m_dropTrace(packet); } else { @@ -470,12 +470,12 @@ Plumb Into the System // Hit the receive trace hook, strip off the point-to-point protocol header // and forward this packet up the protocol stack. // - m_rxTrace (packet); + m_rxTrace(packet); ProcessHeader(packet, protocol); - m_rxCallback (this, packet, protocol, GetRemote ()); - if (!m_promiscCallback.IsNull ()) - { m_promiscCallback (this, packet, protocol, GetRemote (), - GetAddress (), NetDevice::PACKET_HOST); + m_rxCallback(this, packet, protocol, GetRemote()); + if(!m_promiscCallback.IsNull()) + { m_promiscCallback(this, packet, protocol, GetRemote(), + GetAddress(), NetDevice::PACKET_HOST); } } } @@ -492,13 +492,13 @@ Create Null Functional Script // We can obtain a handle to the NetDevice via the channel and node // pointers Ptr nd3 = PointToPointTopology::GetNetDevice - (n3, channel2); - Ptr em = Create (); - nd3->SetReceiveErrorModel (em); + (n3, channel2); + Ptr em = Create(); + nd3->SetReceiveErrorModel(em); bool - ErrorModel::DoCorrupt (Packet& p) + ErrorModel::DoCorrupt(Packet& p) { NS_LOG_FUNCTION; NS_LOG_UNCOND("Corrupt!"); @@ -514,7 +514,7 @@ Add a Subclass ************** The trivial base class ErrorModel does not do anything interesting, but it -provides a useful base class interface (Corrupt () and Reset ()), forwarded to +provides a useful base class interface (``Corrupt()`` and ``Reset()``), forwarded to virtual functions that can be subclassed. Let's next consider what we call a BasicErrorModel which is based on the |ns2| ErrorModel class (in ``ns-2/queue/errmodel.{cc,h}``). @@ -542,24 +542,24 @@ We declare BasicErrorModel to be a subclass of ErrorModel as follows,:: class BasicErrorModel : public ErrorModel { public: - static TypeId GetTypeId (); + static TypeId GetTypeId(); ... private: // Implement base class pure virtual functions - virtual bool DoCorrupt (Ptr p); - virtual bool DoReset (); + virtual bool DoCorrupt(Ptr p); + virtual bool DoReset(); ... } and configure the subclass GetTypeId function by setting a unique TypeId string and setting the Parent to ErrorModel:: - TypeId RateErrorModel::GetTypeId () + TypeId RateErrorModel::GetTypeId() { - static TypeId tid = TypeId ("ns3::RateErrorModel") - .SetParent () - .SetGroupName ("Network") - .AddConstructor () + static TypeId tid = TypeId("ns3::RateErrorModel") + .SetParent() + .SetGroupName("Network") + .AddConstructor() ... Build Core Functions and Unit Tests diff --git a/doc/manual/source/new-modules.rst b/doc/manual/source/new-modules.rst index 21405f4a8..f5a24db67 100644 --- a/doc/manual/source/new-modules.rst +++ b/doc/manual/source/new-modules.rst @@ -161,10 +161,10 @@ The skeleton test suite will contain the below constructor, which declares a new unit test named ``new-module``, with a single test case consisting of the class ``NewModuleTestCase1``:: - NewModuleTestSuite::NewModuleTestSuite () - : TestSuite ("new-module", UNIT) + NewModuleTestSuite::NewModuleTestSuite() + : TestSuite("new-module", UNIT) { - AddTestCase (new NewModuleTestCase1); + AddTestCase(new NewModuleTestCase1); } Step 3 - Declare Source Files diff --git a/doc/manual/source/object-model.rst b/doc/manual/source/object-model.rst index 1571e4dba..2cb661862 100644 --- a/doc/manual/source/object-model.rst +++ b/doc/manual/source/object-model.rst @@ -32,10 +32,10 @@ properties; for instance:: class Address { public: - Address (); - Address (uint8_t type, const uint8_t *buffer, uint8_t len); - Address (const Address & address); - Address &operator = (const Address &address); + Address(); + Address(uint8_t type, const uint8_t *buffer, uint8_t len); + Address(const Address & address); + Address &operator=(const Address &address); ... private: uint8_t m_type; @@ -132,7 +132,7 @@ allocated using a templated Create or CreateObject method, as follows. For objects deriving from class :cpp:class:`Object`:: - Ptr device = CreateObject (); + Ptr device = CreateObject(); Please do not create such objects using ``operator new``; create them using :cpp:func:`CreateObject()` instead. @@ -141,7 +141,7 @@ For objects deriving from class :cpp:class:`SimpleRefCount`, or other objects that support usage of the smart pointer class, a templated helper function is available and recommended to be used:: - Ptr b = Create (); + Ptr b = Create(); This is simply a wrapper around operator new that correctly handles the reference counting system. @@ -190,12 +190,12 @@ node. Let's look at how some Ipv4 protocols are added to a node.:: static void AddIpv4Stack(Ptr node) { - Ptr ipv4 = CreateObject (); - ipv4->SetNode (node); - node->AggregateObject (ipv4); - Ptr ipv4Impl = CreateObject (); - ipv4Impl->SetIpv4 (ipv4); - node->AggregateObject (ipv4Impl); + Ptr ipv4 = CreateObject(); + ipv4->SetNode(node); + node->AggregateObject(ipv4); + Ptr ipv4Impl = CreateObject(); + ipv4Impl->SetIpv4(ipv4); + node->AggregateObject(ipv4Impl); } Note that the Ipv4 protocols are created using :cpp:func:`CreateObject()`. @@ -220,7 +220,7 @@ configure a default route. To do so, it must access an object within the node that has an interface to the IP forwarding configuration. It performs the following:: - Ptr ipv4 = m_node->GetObject (); + Ptr ipv4 = m_node->GetObject(); If the node in fact does not have an Ipv4 object aggregated to it, then the method will return null. Therefore, it is good practice to check the return @@ -248,9 +248,9 @@ pattern in use in the |ns3| system. It is heavily used in the "helper" API. Class :cpp:class:`ObjectFactory` can be used to instantiate objects and to configure the attributes on those objects:: - void SetTypeId (TypeId tid); - void Set (std::string name, const AttributeValue &value); - Ptr Create () const; + void SetTypeId(TypeId tid); + void Set(std::string name, const AttributeValue &value); + Ptr Create() const; The first method allows one to use the |ns3| TypeId system to specify the type of objects created. The second allows one to set attributes on the objects to be @@ -260,15 +260,15 @@ For example: :: ObjectFactory factory; // Make this factory create objects of type FriisPropagationLossModel - factory.SetTypeId ("ns3::FriisPropagationLossModel") + factory.SetTypeId("ns3::FriisPropagationLossModel") // Make this factory object change a default value of an attribute, for // subsequently created objects - factory.Set ("SystemLoss", DoubleValue (2.0)); + factory.Set("SystemLoss", DoubleValue(2.0)); // Create one such object - Ptr object = factory.Create (); - factory.Set ("SystemLoss", DoubleValue (3.0)); + Ptr object = factory.Create(); + factory.Set("SystemLoss", DoubleValue(3.0)); // Create another object with a different SystemLoss - Ptr object = factory.Create (); + Ptr object = factory.Create(); Downcasting *********** @@ -285,9 +285,9 @@ dynamic casting much more user friendly:: template Ptr - DynamicCast (Ptr const&p) + DynamicCast(Ptr const&p) { - return Ptr (dynamic_cast (PeekPointer (p))); + return Ptr(dynamic_cast(PeekPointer(p))); } DynamicCast works when the programmer has a base type pointer and is testing diff --git a/doc/manual/source/random-variables.rst b/doc/manual/source/random-variables.rst index b92aff130..a42f9666a 100644 --- a/doc/manual/source/random-variables.rst +++ b/doc/manual/source/random-variables.rst @@ -117,20 +117,20 @@ The correct way to create these objects is to use the templated :: - Ptr x = CreateObject (); + Ptr x = CreateObject(); then you can access values by calling methods on the object such as: :: - myRandomNo = x->GetInteger (); + myRandomNo = x->GetInteger(); If you try to instead do something like this: :: - myRandomNo = UniformRandomVariable().GetInteger (); + myRandomNo = UniformRandomVariable().GetInteger(); your program will encounter a segmentation fault, because the implementation relies on some attribute construction that occurs only when `CreateObject` @@ -160,11 +160,11 @@ A class :cpp:class:`ns3::RngSeedManager` provides an API to control the seeding run number behavior. This seeding and substream state setting must be called before any random variables are created; e.g:: - RngSeedManager::SetSeed (3); // Changes seed from default of 1 to 3 - RngSeedManager::SetRun (7); // Changes run number from default of 1 to 7 + RngSeedManager::SetSeed(3); // Changes seed from default of 1 to 3 + RngSeedManager::SetRun(7); // Changes run number from default of 1 to 7 // Now, create random variables - Ptr x = CreateObject (); - Ptr y = CreateObject (); + Ptr x = CreateObject(); + Ptr y = CreateObject(); ... Which is better, setting a new seed or advancing the substream state? There is @@ -227,13 +227,13 @@ that access the next value in the substream. * \brief Returns a random double from the underlying distribution * \return A floating point random value */ - double GetValue () const; + double GetValue() const; /** * \brief Returns a random integer from the underlying distribution * \return Integer cast of ::GetValue() */ - uint32_t GetInteger () const; + uint32_t GetInteger() const; We have already described the seeding configuration above. Different RandomVariable subclasses may have additional API. @@ -273,17 +273,17 @@ that values can be set for them through the |ns3| attribute system. An example is in the propagation models for WifiNetDevice:: TypeId - RandomPropagationDelayModel::GetTypeId () + RandomPropagationDelayModel::GetTypeId() { - static TypeId tid = TypeId ("ns3::RandomPropagationDelayModel") - .SetParent () - .SetGroupName ("Propagation") - .AddConstructor () - .AddAttribute ("Variable", - "The random variable which generates random delays (s).", - StringValue ("ns3::UniformRandomVariable"), - MakePointerAccessor (&RandomPropagationDelayModel::m_variable), - MakePointerChecker ()) + static TypeId tid = TypeId("ns3::RandomPropagationDelayModel") + .SetParent() + .SetGroupName("Propagation") + .AddConstructor() + .AddAttribute("Variable", + "The random variable which generates random delays (s).", + StringValue("ns3::UniformRandomVariable"), + MakePointerAccessor(&RandomPropagationDelayModel::m_variable), + MakePointerChecker()) ; return tid; } diff --git a/doc/manual/source/realtime.rst b/doc/manual/source/realtime.rst index d0c3db463..0f37f402d 100644 --- a/doc/manual/source/realtime.rst +++ b/doc/manual/source/realtime.rst @@ -58,8 +58,8 @@ The usage of the realtime simulator is straightforward, from a scripting perspective. Users just need to set the attribute ``SimulatorImplementationType`` to the Realtime simulator, such as follows: :: - GlobalValue::Bind ("SimulatorImplementationType", - StringValue ("ns3::RealtimeSimulatorImpl")); + GlobalValue::Bind("SimulatorImplementationType", + StringValue("ns3::RealtimeSimulatorImpl")); There is a script in ``examples/realtime/realtime-udp-echo.cc`` that has an example of how to configure the realtime behavior. Try: diff --git a/doc/manual/source/test-framework.rst b/doc/manual/source/test-framework.rst index a6ff68e70..a7c8107c5 100644 --- a/doc/manual/source/test-framework.rst +++ b/doc/manual/source/test-framework.rst @@ -707,7 +707,7 @@ arguments as needed, but basedir is the minimum needed):: (gdb) r --suite= Starting program: <..>/build/utils/ns3-dev-test-runner-debug --suite=wifi-interference [Thread debugging using libthread_db enabled] - assert failed. file=../src/core/model/type-id.cc, line=138, cond="uid <= m_information.size () && uid != 0" + assert failed. file=../src/core/model/type-id.cc, line=138, cond="uid <= m_information.size() && uid != 0" ... Here is another example of how to use valgrind to debug a memory problem @@ -757,13 +757,13 @@ as a ''unit'' test with the display name, ``my-test-suite-name``. class MySuite : public TestSuite { public: - MyTestSuite (); + MyTestSuite(); }; - MyTestSuite::MyTestSuite () - : TestSuite ("my-test-suite-name", UNIT) + MyTestSuite::MyTestSuite() + : TestSuite("my-test-suite-name", UNIT) { - AddTestCase (new MyTestCase, TestCase::QUICK); + AddTestCase(new MyTestCase, TestCase::QUICK); } static MyTestSuite myTestSuite; @@ -794,20 +794,20 @@ override also the ``DoSetup`` method. class MyTestCase : public TestCase { - MyTestCase (); - virtual void DoSetup (); - virtual void DoRun (); + MyTestCase(); + virtual void DoSetup(); + virtual void DoRun(); }; - MyTestCase::MyTestCase () - : TestCase ("Check some bit of functionality") + MyTestCase::MyTestCase() + : TestCase("Check some bit of functionality") { } void - MyTestCase::DoRun () + MyTestCase::DoRun() { - NS_TEST_ASSERT_MSG_EQ (true, true, "Some failure message"); + NS_TEST_ASSERT_MSG_EQ(true, true, "Some failure message"); } Utilities diff --git a/doc/manual/source/tracing.rst b/doc/manual/source/tracing.rst index 32c2a5e92..be791ecd7 100644 --- a/doc/manual/source/tracing.rst +++ b/doc/manual/source/tracing.rst @@ -24,7 +24,7 @@ output, as in, :: #include ... - int main () + int main() { ... std::cout << "The value of x is " << x << std::endl; @@ -139,19 +139,19 @@ made using those operators.:: class MyObject : public Object { public: - static TypeId GetTypeId () + static TypeId GetTypeId() { - static TypeId tid = TypeId ("MyObject") - .SetParent (Object::GetTypeId ()) - .AddConstructor () - .AddTraceSource ("MyInteger", - "An integer value to trace.", - MakeTraceSourceAccessor (&MyObject::m_myInt)) + static TypeId tid = TypeId("MyObject") + .SetParent(Object::GetTypeId()) + .AddConstructor() + .AddTraceSource("MyInteger", + "An integer value to trace.", + MakeTraceSourceAccessor(&MyObject::m_myInt)) ; return tid; } - MyObject () {} + MyObject() {} TracedValue m_myInt; }; @@ -166,7 +166,7 @@ infrastructure that overloads the operators mentioned above and drives the callback process.:: void - IntTrace (Int oldValue, Int newValue) + IntTrace(Int oldValue, Int newValue) { std::cout << "Traced " << oldValue << " to " << newValue << std::endl; } @@ -176,11 +176,11 @@ function. This function will be called whenever one of the operators of the ``TracedValue`` is executed.:: int - main (int argc, char *argv[]) + main(int argc, char *argv[]) { - Ptr myObject = CreateObject (); + Ptr myObject = CreateObject(); - myObject->TraceConnectWithoutContext ("MyInteger", MakeCallback(&IntTrace)); + myObject->TraceConnectWithoutContext("MyInteger", MakeCallback(&IntTrace)); myObject->m_myInt = 1234; } @@ -228,13 +228,13 @@ called a *config path*. For example, one might find something that looks like the following in the system (taken from ``examples/tcp-large-transfer.cc``):: - void CwndTracer (uint32_t oldval, uint32_t newval) {} + void CwndTracer(uint32_t oldval, uint32_t newval) {} ... - Config::ConnectWithoutContext ( - "/NodeList/0/$ns3::TcpL4Protocol/SocketList/0/CongestionWindow", - MakeCallback (&CwndTracer)); + Config::ConnectWithoutContext( + "/NodeList/0/$ns3::TcpL4Protocol/SocketList/0/CongestionWindow", + MakeCallback(&CwndTracer)); This should look very familiar. It is the same thing as the previous example, except that a static member function of class ``Config`` is being called instead @@ -246,11 +246,11 @@ must be an ``Attribute`` of an ``Object``. In fact, if you had a pointer to the ``Object`` that has the "CongestionWindow" ``Attribute`` handy (call it ``theObject``), you could write this just like the previous example:: - void CwndTracer (uint32_t oldval, uint32_t newval) {} + void CwndTracer(uint32_t oldval, uint32_t newval) {} ... - theObject->TraceConnectWithoutContext ("CongestionWindow", MakeCallback (&CwndTracer)); + theObject->TraceConnectWithoutContext("CongestionWindow", MakeCallback(&CwndTracer)); It turns out that the code for ``Config::ConnectWithoutContext`` does exactly that. This function takes a path that represents a chain of ``Object`` pointers @@ -284,7 +284,7 @@ This socket, the type of which turns out to be an ``ns3::TcpSocketImpl`` defines an attribute called "CongestionWindow" which is a ``TracedValue``. The ``Config::ConnectWithoutContext`` now does a,:: - object->TraceConnectWithoutContext ("CongestionWindow", MakeCallback (&CwndTracer)); + object->TraceConnectWithoutContext("CongestionWindow", MakeCallback(&CwndTracer)); using the object pointer from "SocketList/0" which makes the connection between the trace source defined in the socket to the callback -- ``CwndTracer``. @@ -323,10 +323,10 @@ helper methods designed for use inside other (device) helpers. Perhaps you will recall seeing some of these variations:: - pointToPoint.EnablePcapAll ("second"); - pointToPoint.EnablePcap ("second", p2pNodes.Get (0)->GetId (), 0); - csma.EnablePcap ("third", csmaDevices.Get (0), true); - pointToPoint.EnableAsciiAll (ascii.CreateFileStream ("myfirst.tr")); + pointToPoint.EnablePcapAll("second"); + pointToPoint.EnablePcap("second", p2pNodes.Get(0)->GetId(), 0); + csma.EnablePcap("third", csmaDevices.Get(0), true); + pointToPoint.EnableAsciiAll(ascii.CreateFileStream("myfirst.tr")); What may not be obvious, though, is that there is a consistent model for all of the trace-related methods found in the system. We will now take a little time @@ -381,14 +381,14 @@ The class ``PcapHelperForDevice`` is a ``mixin`` provides the high level functionality for using pcap tracing in an |ns3| device. Every device must implement a single virtual method inherited from this class.:: - virtual void EnablePcapInternal (std::string prefix, Ptr nd, bool promiscuous) = 0; + virtual void EnablePcapInternal(std::string prefix, Ptr nd, bool promiscuous) = 0; The signature of this method reflects the device-centric view of the situation at this level. All of the public methods inherited from class ``PcapUserHelperForDevice`` reduce to calling this single device-dependent implementation method. For example, the lowest level pcap method,:: - void EnablePcap (std::string prefix, Ptr nd, bool promiscuous = false, bool explicitFilename = false); + void EnablePcap(std::string prefix, Ptr nd, bool promiscuous = false, bool explicitFilename = false); will call the device implementation of ``EnablePcapInternal`` directly. All other public pcap tracing methods build on this implementation to provide @@ -402,17 +402,17 @@ Pcap Tracing Device Helper Methods :: - void EnablePcap (std::string prefix, Ptr nd, - bool promiscuous = false, bool explicitFilename = false); - void EnablePcap (std::string prefix, std::string ndName, - bool promiscuous = false, bool explicitFilename = false); - void EnablePcap (std::string prefix, NetDeviceContainer d, - bool promiscuous = false); - void EnablePcap (std::string prefix, NodeContainer n, - bool promiscuous = false); - void EnablePcap (std::string prefix, uint32_t nodeid, uint32_t deviceid, - bool promiscuous = false); - void EnablePcapAll (std::string prefix, bool promiscuous = false); + void EnablePcap(std::string prefix, Ptr nd, + bool promiscuous = false, bool explicitFilename = false); + void EnablePcap(std::string prefix, std::string ndName, + bool promiscuous = false, bool explicitFilename = false); + void EnablePcap(std::string prefix, NetDeviceContainer d, + bool promiscuous = false); + void EnablePcap(std::string prefix, NodeContainer n, + bool promiscuous = false); + void EnablePcap(std::string prefix, uint32_t nodeid, uint32_t deviceid, + bool promiscuous = false); + void EnablePcapAll(std::string prefix, bool promiscuous = false); In each of the methods shown above, there is a default parameter called ``promiscuous`` that defaults to false. This parameter indicates that the trace @@ -422,7 +422,7 @@ mode) simply add a true parameter to any of the calls above. For example,:: Ptr nd; ... - helper.EnablePcap ("prefix", nd, true); + helper.EnablePcap("prefix", nd, true); will enable promiscuous mode captures on the ``NetDevice`` specified by ``nd``. @@ -438,7 +438,7 @@ since the net device must belong to exactly one ``Node``. For example,:: Ptr nd; ... - helper.EnablePcap ("prefix", nd); + helper.EnablePcap("prefix", nd); You can enable pcap tracing on a particular node/net-device pair by providing a ``std::string`` representing an object name service string to an ``EnablePcap`` @@ -446,10 +446,10 @@ method. The ``Ptr`` is looked up from the name string. Again, the ```` is implicit since the named net device must belong to exactly one ``Node``. For example,:: - Names::Add ("server" ...); - Names::Add ("server/eth0" ...); + Names::Add("server" ...); + Names::Add("server/eth0" ...); ... - helper.EnablePcap ("prefix", "server/ath0"); + helper.EnablePcap("prefix", "server/ath0"); You can enable pcap tracing on a collection of node/net-device pairs by providing a ``NetDeviceContainer``. For each ``NetDevice`` in the container the @@ -460,7 +460,7 @@ example,:: NetDeviceContainer d = ...; ... - helper.EnablePcap ("prefix", d); + helper.EnablePcap("prefix", d); You can enable pcap tracing on a collection of node/net-device pairs by providing a ``NodeContainer``. For each ``Node`` in the ``NodeContainer`` its @@ -471,18 +471,18 @@ enabled.:: NodeContainer n; ... - helper.EnablePcap ("prefix", n); + helper.EnablePcap("prefix", n); You can enable pcap tracing on the basis of node ID and device ID as well as with explicit ``Ptr``. Each ``Node`` in the system has an integer node ID and each device connected to a node has an integer device ID.:: - helper.EnablePcap ("prefix", 21, 1); + helper.EnablePcap("prefix", 21, 1); Finally, you can enable pcap tracing for all devices in the system, with the same type as that managed by the device helper.:: - helper.EnablePcapAll ("prefix"); + helper.EnablePcapAll("prefix"); Pcap Tracing Device Helper Filename Selection ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ @@ -506,8 +506,8 @@ your pcap file name will automatically pick this up and be called Finally, two of the methods shown above,:: - void EnablePcap (std::string prefix, Ptr nd, bool promiscuous = false, bool explicitFilename = false); - void EnablePcap (std::string prefix, std::string ndName, bool promiscuous = false, bool explicitFilename = false); + void EnablePcap(std::string prefix, Ptr nd, bool promiscuous = false, bool explicitFilename = false); + void EnablePcap(std::string prefix, std::string ndName, bool promiscuous = false, bool explicitFilename = false); have a default parameter called ``explicitFilename``. When set to true, this parameter disables the automatic filename completion mechanism and allows you to @@ -520,7 +520,7 @@ given device, one could:: Ptr nd; ... - helper.EnablePcap ("my-pcap-file.pcap", nd, true, true); + helper.EnablePcap("my-pcap-file.pcap", nd, true, true); The first ``true`` parameter enables promiscuous mode traces and the second tells the helper to interpret the ``prefix`` parameter as a complete filename. @@ -537,7 +537,7 @@ using ASCII tracing to a device helper class. As in the pcap case, every device must implement a single virtual method inherited from the ASCII trace ``mixin``.:: - virtual void EnableAsciiInternal (Ptr stream, std::string prefix, Ptr nd) = 0; + virtual void EnableAsciiInternal(Ptr stream, std::string prefix, Ptr nd) = 0; The signature of this method reflects the device-centric view of the situation at this level; and also the fact that the helper may be writing to a shared @@ -546,8 +546,8 @@ class ``AsciiTraceHelperForDevice`` reduce to calling this single device- dependent implementation method. For example, the lowest level ASCII trace methods,:: - void EnableAscii (std::string prefix, Ptr nd); - void EnableAscii (Ptr stream, Ptr nd); + void EnableAscii(std::string prefix, Ptr nd); + void EnableAscii(Ptr stream, Ptr nd); will call the device implementation of ``EnableAsciiInternal`` directly, providing either a valid prefix or stream. All other public ASCII tracing @@ -562,23 +562,23 @@ Ascii Tracing Device Helper Methods :: - void EnableAscii (std::string prefix, Ptr nd); - void EnableAscii (Ptr stream, Ptr nd); + void EnableAscii(std::string prefix, Ptr nd); + void EnableAscii(Ptr stream, Ptr nd); - void EnableAscii (std::string prefix, std::string ndName); - void EnableAscii (Ptr stream, std::string ndName); + void EnableAscii(std::string prefix, std::string ndName); + void EnableAscii(Ptr stream, std::string ndName); - void EnableAscii (std::string prefix, NetDeviceContainer d); - void EnableAscii (Ptr stream, NetDeviceContainer d); + void EnableAscii(std::string prefix, NetDeviceContainer d); + void EnableAscii(Ptr stream, NetDeviceContainer d); - void EnableAscii (std::string prefix, NodeContainer n); - void EnableAscii (Ptr stream, NodeContainer n); + void EnableAscii(std::string prefix, NodeContainer n); + void EnableAscii(Ptr stream, NodeContainer n); - void EnableAscii (std::string prefix, uint32_t nodeid, uint32_t deviceid); - void EnableAscii (Ptr stream, uint32_t nodeid, uint32_t deviceid); + void EnableAscii(std::string prefix, uint32_t nodeid, uint32_t deviceid); + void EnableAscii(Ptr stream, uint32_t nodeid, uint32_t deviceid); - void EnableAsciiAll (std::string prefix); - void EnableAsciiAll (Ptr stream); + void EnableAsciiAll(std::string prefix); + void EnableAsciiAll(Ptr stream); You are encouraged to peruse the Doxygen for class ``TraceHelperForDevice`` to find the details of these methods; but to summarize ... @@ -598,7 +598,7 @@ exactly one ``Node``. For example,:: Ptr nd; ... - helper.EnableAscii ("prefix", nd); + helper.EnableAscii("prefix", nd); In this case, no trace contexts are written to the ASCII trace file since they would be redundant. The system will pick the file name to be created using the @@ -612,10 +612,10 @@ refer to a single file:: Ptr nd1; Ptr nd2; ... - Ptr stream = asciiTraceHelper.CreateFileStream ("trace-file-name.tr"); + Ptr stream = asciiTraceHelper.CreateFileStream("trace-file-name.tr"); ... - helper.EnableAscii (stream, nd1); - helper.EnableAscii (stream, nd2); + helper.EnableAscii(stream, nd1); + helper.EnableAscii(stream, nd2); In this case, trace contexts are written to the ASCII trace file since they are required to disambiguate traces from the two devices. Note that since the @@ -628,28 +628,28 @@ You can enable ASCII tracing on a particular node/net-device pair by providing a string. Again, the ```` is implicit since the named net device must belong to exactly one ``Node``. For example,:: - Names::Add ("client" ...); - Names::Add ("client/eth0" ...); - Names::Add ("server" ...); - Names::Add ("server/eth0" ...); + Names::Add("client" ...); + Names::Add("client/eth0" ...); + Names::Add("server" ...); + Names::Add("server/eth0" ...); ... - helper.EnableAscii ("prefix", "client/eth0"); - helper.EnableAscii ("prefix", "server/eth0"); + helper.EnableAscii("prefix", "client/eth0"); + helper.EnableAscii("prefix", "server/eth0"); This would result in two files named ``prefix-client-eth0.tr`` and ``prefix-server-eth0.tr`` with traces for each device in the respective trace file. Since all of the EnableAscii functions are overloaded to take a stream wrapper, you can use that form as well:: - Names::Add ("client" ...); - Names::Add ("client/eth0" ...); - Names::Add ("server" ...); - Names::Add ("server/eth0" ...); + Names::Add("client" ...); + Names::Add("client/eth0" ...); + Names::Add("server" ...); + Names::Add("server/eth0" ...); ... - Ptr stream = asciiTraceHelper.CreateFileStream ("trace-file-name.tr"); + Ptr stream = asciiTraceHelper.CreateFileStream("trace-file-name.tr"); ... - helper.EnableAscii (stream, "client/eth0"); - helper.EnableAscii (stream, "server/eth0"); + helper.EnableAscii(stream, "client/eth0"); + helper.EnableAscii(stream, "server/eth0"); This would result in a single trace file called ``trace-file-name.tr`` that contains all of the trace events for both devices. The events would be @@ -663,7 +663,7 @@ since the found net device must belong to exactly one ``Node``. For example,:: NetDeviceContainer d = ...; ... - helper.EnableAscii ("prefix", d); + helper.EnableAscii("prefix", d); This would result in a number of ASCII trace files being created, each of which follows the --.tr convention. Combining all of the @@ -671,9 +671,9 @@ traces into a single file is accomplished similarly to the examples above:: NetDeviceContainer d = ...; ... - Ptr stream = asciiTraceHelper.CreateFileStream ("trace-file-name.tr"); + Ptr stream = asciiTraceHelper.CreateFileStream("trace-file-name.tr"); ... - helper.EnableAscii (stream, d); + helper.EnableAscii(stream, d); You can enable ascii tracing on a collection of node/net-device pairs by providing a ``NodeContainer``. For each ``Node`` in the ``NodeContainer`` its @@ -684,7 +684,7 @@ enabled.:: NodeContainer n; ... - helper.EnableAscii ("prefix", n); + helper.EnableAscii("prefix", n); This would result in a number of ASCII trace files being created, each of which follows the --.tr convention. Combining all of the @@ -694,14 +694,14 @@ You can enable pcap tracing on the basis of node ID and device ID as well as with explicit ``Ptr``. Each ``Node`` in the system has an integer node ID and each device connected to a node has an integer device ID.:: - helper.EnableAscii ("prefix", 21, 1); + helper.EnableAscii("prefix", 21, 1); Of course, the traces can be combined into a single file as shown above. Finally, you can enable pcap tracing for all devices in the system, with the same type as that managed by the device helper.:: - helper.EnableAsciiAll ("prefix"); + helper.EnableAsciiAll("prefix"); This would result in a number of ASCII trace files being created, one for every device in the system of the type managed by the helper. All of these @@ -751,14 +751,14 @@ difference will be in the method names and signatures. Different method names are required to disambiguate class ``Ipv4`` from ``Ipv6`` which are both derived from class ``Object``, and methods that share the same signature.:: - virtual void EnablePcapIpv4Internal (std::string prefix, Ptr ipv4, uint32_t interface) = 0; + virtual void EnablePcapIpv4Internal(std::string prefix, Ptr ipv4, uint32_t interface) = 0; The signature of this method reflects the protocol and interface-centric view of the situation at this level. All of the public methods inherited from class ``PcapHelperForIpv4`` reduce to calling this single device-dependent implementation method. For example, the lowest level pcap method,:: - void EnablePcapIpv4 (std::string prefix, Ptr ipv4, uint32_t interface); + void EnablePcapIpv4(std::string prefix, Ptr ipv4, uint32_t interface); will call the device implementation of ``EnablePcapIpv4Internal`` directly. All other public pcap tracing methods build on this implementation to provide @@ -777,12 +777,12 @@ constraints. Note that just like in the device version, there are six methods:: - void EnablePcapIpv4 (std::string prefix, Ptr ipv4, uint32_t interface); - void EnablePcapIpv4 (std::string prefix, std::string ipv4Name, uint32_t interface); - void EnablePcapIpv4 (std::string prefix, Ipv4InterfaceContainer c); - void EnablePcapIpv4 (std::string prefix, NodeContainer n); - void EnablePcapIpv4 (std::string prefix, uint32_t nodeid, uint32_t interface); - void EnablePcapIpv4All (std::string prefix); + void EnablePcapIpv4(std::string prefix, Ptr ipv4, uint32_t interface); + void EnablePcapIpv4(std::string prefix, std::string ipv4Name, uint32_t interface); + void EnablePcapIpv4(std::string prefix, Ipv4InterfaceContainer c); + void EnablePcapIpv4(std::string prefix, NodeContainer n); + void EnablePcapIpv4(std::string prefix, uint32_t nodeid, uint32_t interface); + void EnablePcapIpv4All(std::string prefix); You are encouraged to peruse the Doxygen for class ``PcapHelperForIpv4`` to find the details of these methods; but to summarize ... @@ -790,17 +790,17 @@ the details of these methods; but to summarize ... You can enable pcap tracing on a particular protocol/interface pair by providing a ``Ptr`` and ``interface`` to an ``EnablePcap`` method. For example,:: - Ptr ipv4 = node->GetObject (); + Ptr ipv4 = node->GetObject(); ... - helper.EnablePcapIpv4 ("prefix", ipv4, 0); + helper.EnablePcapIpv4("prefix", ipv4, 0); You can enable pcap tracing on a particular node/net-device pair by providing a ``std::string`` representing an object name service string to an ``EnablePcap`` method. The ``Ptr`` is looked up from the name string. For example,:: - Names::Add ("serverIPv4" ...); + Names::Add("serverIPv4" ...); ... - helper.EnablePcapIpv4 ("prefix", "serverIpv4", 1); + helper.EnablePcapIpv4("prefix", "serverIpv4", 1); You can enable pcap tracing on a collection of protocol/interface pairs by providing an ``Ipv4InterfaceContainer``. For each ``Ipv4`` / interface pair in @@ -810,13 +810,13 @@ corresponding interface. For example,:: NodeContainer nodes; ... - NetDeviceContainer devices = deviceHelper.Install (nodes); + NetDeviceContainer devices = deviceHelper.Install(nodes); ... Ipv4AddressHelper ipv4; - ipv4.SetBase ("10.1.1.0", "255.255.255.0"); - Ipv4InterfaceContainer interfaces = ipv4.Assign (devices); + ipv4.SetBase("10.1.1.0", "255.255.255.0"); + Ipv4InterfaceContainer interfaces = ipv4.Assign(devices); ... - helper.EnablePcapIpv4 ("prefix", interfaces); + helper.EnablePcapIpv4("prefix", interfaces); You can enable pcap tracing on a collection of protocol/interface pairs by providing a ``NodeContainer``. For each ``Node`` in the ``NodeContainer`` the @@ -825,19 +825,19 @@ and tracing is enabled on the resulting pairs. For example,:: NodeContainer n; ... - helper.EnablePcapIpv4 ("prefix", n); + helper.EnablePcapIpv4("prefix", n); You can enable pcap tracing on the basis of node ID and interface as well. In this case, the node-id is translated to a ``Ptr`` and the appropriate protocol is looked up in the node. The resulting protocol and interface are used to specify the resulting trace source.:: - helper.EnablePcapIpv4 ("prefix", 21, 1); + helper.EnablePcapIpv4("prefix", 21, 1); Finally, you can enable pcap tracing for all interfaces in the system, with associated protocol being the same type as that managed by the device helper.:: - helper.EnablePcapIpv4All ("prefix"); + helper.EnablePcapIpv4All("prefix"); Pcap Tracing Protocol Helper Filename Selection ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ @@ -884,8 +884,8 @@ The class ``AsciiTraceHelperForIpv4`` adds the high level functionality for using ASCII tracing to a protocol helper. Each protocol that enables these methods must implement a single virtual method inherited from this class.:: - virtual void EnableAsciiIpv4Internal (Ptr stream, std::string prefix, - Ptr ipv4, uint32_t interface) = 0; + virtual void EnableAsciiIpv4Internal(Ptr stream, std::string prefix, + Ptr ipv4, uint32_t interface) = 0; The signature of this method reflects the protocol- and interface-centric view of the situation at this level; and also the fact that the helper may be writing @@ -894,8 +894,8 @@ to a shared output stream. All of the public methods inherited from class dependent implementation method. For example, the lowest level ascii trace methods,:: - void EnableAsciiIpv4 (std::string prefix, Ptr ipv4, uint32_t interface); - void EnableAsciiIpv4 (Ptr stream, Ptr ipv4, uint32_t interface); + void EnableAsciiIpv4(std::string prefix, Ptr ipv4, uint32_t interface); + void EnableAsciiIpv4(Ptr stream, Ptr ipv4, uint32_t interface); will call the device implementation of ``EnableAsciiIpv4Internal`` directly, providing either the prefix or the stream. All other public ascii tracing @@ -910,23 +910,23 @@ Ascii Tracing Device Helper Methods :: - void EnableAsciiIpv4 (std::string prefix, Ptr ipv4, uint32_t interface); - void EnableAsciiIpv4 (Ptr stream, Ptr ipv4, uint32_t interface); + void EnableAsciiIpv4(std::string prefix, Ptr ipv4, uint32_t interface); + void EnableAsciiIpv4(Ptr stream, Ptr ipv4, uint32_t interface); - void EnableAsciiIpv4 (std::string prefix, std::string ipv4Name, uint32_t interface); - void EnableAsciiIpv4 (Ptr stream, std::string ipv4Name, uint32_t interface); + void EnableAsciiIpv4(std::string prefix, std::string ipv4Name, uint32_t interface); + void EnableAsciiIpv4(Ptr stream, std::string ipv4Name, uint32_t interface); - void EnableAsciiIpv4 (std::string prefix, Ipv4InterfaceContainer c); - void EnableAsciiIpv4 (Ptr stream, Ipv4InterfaceContainer c); + void EnableAsciiIpv4(std::string prefix, Ipv4InterfaceContainer c); + void EnableAsciiIpv4(Ptr stream, Ipv4InterfaceContainer c); - void EnableAsciiIpv4 (std::string prefix, NodeContainer n); - void EnableAsciiIpv4 (Ptr stream, NodeContainer n); + void EnableAsciiIpv4(std::string prefix, NodeContainer n); + void EnableAsciiIpv4(Ptr stream, NodeContainer n); - void EnableAsciiIpv4 (std::string prefix, uint32_t nodeid, uint32_t deviceid); - void EnableAsciiIpv4 (Ptr stream, uint32_t nodeid, uint32_t interface); + void EnableAsciiIpv4(std::string prefix, uint32_t nodeid, uint32_t deviceid); + void EnableAsciiIpv4(Ptr stream, uint32_t nodeid, uint32_t interface); - void EnableAsciiIpv4All (std::string prefix); - void EnableAsciiIpv4All (Ptr stream); + void EnableAsciiIpv4All(std::string prefix); + void EnableAsciiIpv4All(Ptr stream); You are encouraged to peruse the Doxygen for class ``PcapAndAsciiHelperForIpv4`` to find the details of these methods; but to summarize ... @@ -945,7 +945,7 @@ protocol/interface pair by providing a ``Ptr`` and an ``interface`` to an Ptr ipv4; ... - helper.EnableAsciiIpv4 ("prefix", ipv4, 1); + helper.EnableAsciiIpv4("prefix", ipv4, 1); In this case, no trace contexts are written to the ASCII trace file since they would be redundant. The system will pick the file name to be created using the @@ -957,13 +957,13 @@ traces sent to a single file, you can do that as well by using an object to refer to a single file. We have already something similar to this in the "cwnd" example above:: - Ptr protocol1 = node1->GetObject (); - Ptr protocol2 = node2->GetObject (); + Ptr protocol1 = node1->GetObject(); + Ptr protocol2 = node2->GetObject(); ... - Ptr stream = asciiTraceHelper.CreateFileStream ("trace-file-name.tr"); + Ptr stream = asciiTraceHelper.CreateFileStream("trace-file-name.tr"); ... - helper.EnableAsciiIpv4 (stream, protocol1, 1); - helper.EnableAsciiIpv4 (stream, protocol2, 1); + helper.EnableAsciiIpv4(stream, protocol1, 1); + helper.EnableAsciiIpv4(stream, protocol2, 1); In this case, trace contexts are written to the ASCII trace file since they are required to disambiguate traces from the two interfaces. Note that since the @@ -976,24 +976,24 @@ method. The ``Ptr`` is looked up from the name string. The ```` in the resulting filenames is implicit since there is a one-to-one correspondence between protocol instances and nodes, For example,:: - Names::Add ("node1Ipv4" ...); - Names::Add ("node2Ipv4" ...); + Names::Add("node1Ipv4" ...); + Names::Add("node2Ipv4" ...); ... - helper.EnableAsciiIpv4 ("prefix", "node1Ipv4", 1); - helper.EnableAsciiIpv4 ("prefix", "node2Ipv4", 1); + helper.EnableAsciiIpv4("prefix", "node1Ipv4", 1); + helper.EnableAsciiIpv4("prefix", "node2Ipv4", 1); This would result in two files named "prefix-nnode1Ipv4-i1.tr" and "prefix-nnode2Ipv4-i1.tr" with traces for each interface in the respective trace file. Since all of the EnableAscii functions are overloaded to take a stream wrapper, you can use that form as well:: - Names::Add ("node1Ipv4" ...); - Names::Add ("node2Ipv4" ...); + Names::Add("node1Ipv4" ...); + Names::Add("node2Ipv4" ...); ... - Ptr stream = asciiTraceHelper.CreateFileStream ("trace-file-name.tr"); + Ptr stream = asciiTraceHelper.CreateFileStream("trace-file-name.tr"); ... - helper.EnableAsciiIpv4 (stream, "node1Ipv4", 1); - helper.EnableAsciiIpv4 (stream, "node2Ipv4", 1); + helper.EnableAsciiIpv4(stream, "node1Ipv4", 1); + helper.EnableAsciiIpv4(stream, "node2Ipv4", 1); This would result in a single trace file called "trace-file-name.tr" that contains all of the trace events for both interfaces. The events would be @@ -1007,14 +1007,14 @@ one-to-one correspondence between each protocol and its node. For example,:: NodeContainer nodes; ... - NetDeviceContainer devices = deviceHelper.Install (nodes); + NetDeviceContainer devices = deviceHelper.Install(nodes); ... Ipv4AddressHelper ipv4; - ipv4.SetBase ("10.1.1.0", "255.255.255.0"); - Ipv4InterfaceContainer interfaces = ipv4.Assign (devices); + ipv4.SetBase("10.1.1.0", "255.255.255.0"); + Ipv4InterfaceContainer interfaces = ipv4.Assign(devices); ... ... - helper.EnableAsciiIpv4 ("prefix", interfaces); + helper.EnableAsciiIpv4("prefix", interfaces); This would result in a number of ASCII trace files being created, each of which follows the -n-i.tr convention. Combining all of the @@ -1022,15 +1022,15 @@ traces into a single file is accomplished similarly to the examples above:: NodeContainer nodes; ... - NetDeviceContainer devices = deviceHelper.Install (nodes); + NetDeviceContainer devices = deviceHelper.Install(nodes); ... Ipv4AddressHelper ipv4; - ipv4.SetBase ("10.1.1.0", "255.255.255.0"); - Ipv4InterfaceContainer interfaces = ipv4.Assign (devices); + ipv4.SetBase("10.1.1.0", "255.255.255.0"); + Ipv4InterfaceContainer interfaces = ipv4.Assign(devices); ... - Ptr stream = asciiTraceHelper.CreateFileStream ("trace-file-name.tr"); + Ptr stream = asciiTraceHelper.CreateFileStream("trace-file-name.tr"); ... - helper.EnableAsciiIpv4 (stream, interfaces); + helper.EnableAsciiIpv4(stream, interfaces); You can enable ASCII tracing on a collection of protocol/interface pairs by providing a ``NodeContainer``. For each ``Node`` in the ``NodeContainer`` the @@ -1039,7 +1039,7 @@ and tracing is enabled on the resulting pairs. For example,:: NodeContainer n; ... - helper.EnableAsciiIpv4 ("prefix", n); + helper.EnableAsciiIpv4("prefix", n); This would result in a number of ASCII trace files being created, each of which follows the --.tr convention. Combining all of the @@ -1050,14 +1050,14 @@ this case, the node-id is translated to a ``Ptr`` and the appropriate protocol is looked up in the node. The resulting protocol and interface are used to specify the resulting trace source.:: - helper.EnableAsciiIpv4 ("prefix", 21, 1); + helper.EnableAsciiIpv4("prefix", 21, 1); Of course, the traces can be combined into a single file as shown above. Finally, you can enable ASCII tracing for all interfaces in the system, with associated protocol being the same type as that managed by the device helper.:: - helper.EnableAsciiIpv4All ("prefix"); + helper.EnableAsciiIpv4All("prefix"); This would result in a number of ASCII trace files being created, one for every interface in the system related to a protocol of the type managed by the diff --git a/doc/manual/source/troubleshoot.rst b/doc/manual/source/troubleshoot.rst index bb0cc5597..046db3685 100644 --- a/doc/manual/source/troubleshoot.rst +++ b/doc/manual/source/troubleshoot.rst @@ -55,7 +55,7 @@ closely, try running it under the `gdb debugger Program received signal SIGSEGV, Segmentation fault. 0x0804aa12 in main (argc=1, argv=0xbfdfefa4) at ../examples/tcp-point-to-point.cc:136 - 136 Ptr localSocket = socketFactory->CreateSocket (); + 136 Ptr localSocket = socketFactory->CreateSocket(); (gdb) p localSocket $1 = {m_ptr = 0x3c5d65} (gdb) p socketFactory @@ -73,9 +73,9 @@ Let's look around line 136 of tcp-point-to-point, as gdb suggests: .. sourcecode:: cpp - Ptr socketFactory = n2->GetObject (Tcp::iid); - Ptr localSocket = socketFactory->CreateSocket (); - localSocket->Bind (); + Ptr socketFactory = n2->GetObject(Tcp::iid); + Ptr localSocket = socketFactory->CreateSocket(); + localSocket->Bind(); The culprit here is that the return value of GetObject is not being checked and may be null. diff --git a/doc/tutorial/source/building-topologies.rst b/doc/tutorial/source/building-topologies.rst index 2b39c08ed..435a56d8b 100644 --- a/doc/tutorial/source/building-topologies.rst +++ b/doc/tutorial/source/building-topologies.rst @@ -76,7 +76,7 @@ This is all just as it was in ``first.cc``, so there is nothing new yet. using namespace ns3; - NS_LOG_COMPONENT_DEFINE ("SecondScriptExample"); + NS_LOG_COMPONENT_DEFINE("SecondScriptExample"); The main program begins with a slightly different twist. We use a verbose flag to determine whether or not the ``UdpEchoClientApplication`` and @@ -99,10 +99,10 @@ entirely comfortable with the following code at this point in the tutorial. uint32_t nCsma = 3; CommandLine cmd; - cmd.AddValue ("nCsma", "Number of \"extra\" CSMA nodes/devices", nCsma); - cmd.AddValue ("verbose", "Tell echo applications to log if true", verbose); + cmd.AddValue("nCsma", "Number of \"extra\" CSMA nodes/devices", nCsma); + cmd.AddValue("verbose", "Tell echo applications to log if true", verbose); - cmd.Parse (argc, argv); + cmd.Parse(argc, argv); if (verbose) { @@ -119,7 +119,7 @@ done in ``first.cc``. :: NodeContainer p2pNodes; - p2pNodes.Create (2); + p2pNodes.Create(2); Next, we declare another ``NodeContainer`` to hold the nodes that will be part of the bus (CSMA) network. First, we just instantiate the container @@ -128,8 +128,8 @@ object itself. :: NodeContainer csmaNodes; - csmaNodes.Add (p2pNodes.Get (1)); - csmaNodes.Create (nCsma); + csmaNodes.Add(p2pNodes.Get(1)); + csmaNodes.Create(nCsma); The next line of code ``Gets`` the first node (as in having an index of one) from the point-to-point node container and adds it to the container of nodes @@ -148,11 +148,11 @@ the helper and a two millisecond delay on channels created by the helper. :: PointToPointHelper pointToPoint; - pointToPoint.SetDeviceAttribute ("DataRate", StringValue ("5Mbps")); - pointToPoint.SetChannelAttribute ("Delay", StringValue ("2ms")); + pointToPoint.SetDeviceAttribute("DataRate", StringValue("5Mbps")); + pointToPoint.SetChannelAttribute("Delay", StringValue("2ms")); NetDeviceContainer p2pDevices; - p2pDevices = pointToPoint.Install (p2pNodes); + p2pDevices = pointToPoint.Install(p2pNodes); We then instantiate a ``NetDeviceContainer`` to keep track of the point-to-point net devices and we ``Install`` devices on the @@ -173,11 +173,11 @@ its native data type. :: CsmaHelper csma; - csma.SetChannelAttribute ("DataRate", StringValue ("100Mbps")); - csma.SetChannelAttribute ("Delay", TimeValue (NanoSeconds (6560))); + csma.SetChannelAttribute("DataRate", StringValue("100Mbps")); + csma.SetChannelAttribute("Delay", TimeValue(NanoSeconds(6560))); NetDeviceContainer csmaDevices; - csmaDevices = csma.Install (csmaNodes); + csmaDevices = csma.Install(csmaNodes); Just as we created a ``NetDeviceContainer`` to hold the devices created by the ``PointToPointHelper`` we create a ``NetDeviceContainer`` to hold @@ -192,8 +192,8 @@ stacks present. Just as in the ``first.cc`` script, we will use the :: InternetStackHelper stack; - stack.Install (p2pNodes.Get (0)); - stack.Install (csmaNodes); + stack.Install(p2pNodes.Get(0)); + stack.Install(csmaNodes); Recall that we took one of the nodes from the ``p2pNodes`` container and added it to the ``csmaNodes`` container. Thus we only need to install @@ -208,9 +208,9 @@ two point-to-point devices. :: Ipv4AddressHelper address; - address.SetBase ("10.1.1.0", "255.255.255.0"); + address.SetBase("10.1.1.0", "255.255.255.0"); Ipv4InterfaceContainer p2pInterfaces; - p2pInterfaces = address.Assign (p2pDevices); + p2pInterfaces = address.Assign(p2pDevices); Recall that we save the created interfaces in a container to make it easy to pull out addressing information later for use in setting up the applications. @@ -224,9 +224,9 @@ from network number 10.1.2.0 in this case, as seen below. :: - address.SetBase ("10.1.2.0", "255.255.255.0"); + address.SetBase("10.1.2.0", "255.255.255.0"); Ipv4InterfaceContainer csmaInterfaces; - csmaInterfaces = address.Assign (csmaDevices); + csmaInterfaces = address.Assign(csmaDevices); Now we have a topology built, but we need applications. This section is going to be fundamentally similar to the applications section of @@ -242,11 +242,11 @@ the constructor. :: - UdpEchoServerHelper echoServer (9); + UdpEchoServerHelper echoServer(9); - ApplicationContainer serverApps = echoServer.Install (csmaNodes.Get (nCsma)); - serverApps.Start (Seconds (1.0)); - serverApps.Stop (Seconds (10.0)); + ApplicationContainer serverApps = echoServer.Install(csmaNodes.Get(nCsma)); + serverApps.Start(Seconds(1.0)); + serverApps.Stop(Seconds(10.0)); Recall that the ``csmaNodes NodeContainer`` contains one of the nodes created for the point-to-point network and ``nCsma`` "extra" nodes. @@ -267,14 +267,14 @@ leftmost point-to-point node seen in the topology illustration. :: - UdpEchoClientHelper echoClient (csmaInterfaces.GetAddress (nCsma), 9); - echoClient.SetAttribute ("MaxPackets", UintegerValue (1)); - echoClient.SetAttribute ("Interval", TimeValue (Seconds (1.0))); - echoClient.SetAttribute ("PacketSize", UintegerValue (1024)); + UdpEchoClientHelper echoClient(csmaInterfaces.GetAddress(nCsma), 9); + echoClient.SetAttribute("MaxPackets", UintegerValue(1)); + echoClient.SetAttribute("Interval", TimeValue(Seconds(1.0))); + echoClient.SetAttribute("PacketSize", UintegerValue(1024)); - ApplicationContainer clientApps = echoClient.Install (p2pNodes.Get (0)); - clientApps.Start (Seconds (2.0)); - clientApps.Stop (Seconds (10.0)); + ApplicationContainer clientApps = echoClient.Install(p2pNodes.Get(0)); + clientApps.Start(Seconds(2.0)); + clientApps.Stop(Seconds(10.0)); Since we have actually built an internetwork here, we need some form of internetwork routing. |ns3| provides what we call global routing to @@ -292,7 +292,7 @@ is a one-liner: :: - Ipv4GlobalRoutingHelper::PopulateRoutingTables (); + Ipv4GlobalRoutingHelper::PopulateRoutingTables(); Next we enable pcap tracing. The first line of code to enable pcap tracing in the point-to-point helper should be familiar to you by now. The second @@ -301,8 +301,8 @@ you haven't encountered yet. :: - pointToPoint.EnablePcapAll ("second"); - csma.EnablePcap ("second", csmaDevices.Get (1), true); + pointToPoint.EnablePcapAll("second"); + csma.EnablePcap("second", csmaDevices.Get(1), true); The CSMA network is a multi-point-to-point network. This means that there can (and are in this case) multiple endpoints on a shared medium. Each of @@ -329,8 +329,8 @@ the ``first.cc`` example. :: - Simulator::Run (); - Simulator::Destroy (); + Simulator::Run(); + Simulator::Destroy(); return 0; } @@ -564,9 +564,9 @@ number and device number as parameters. Go ahead and replace the :: - pointToPoint.EnablePcap ("second", p2pNodes.Get (0)->GetId (), 0); - csma.EnablePcap ("second", csmaNodes.Get (nCsma)->GetId (), 0, false); - csma.EnablePcap ("second", csmaNodes.Get (nCsma-1)->GetId (), 0, false); + pointToPoint.EnablePcap("second", p2pNodes.Get(0)->GetId(), 0); + csma.EnablePcap("second", csmaNodes.Get(nCsma)->GetId(), 0, false); + csma.EnablePcap("second", csmaNodes.Get(nCsma-1)->GetId(), 0, false); We know that we want to create a pcap file with the base name "second" and we also know that the device of interest in both cases is going to be zero, @@ -610,14 +610,14 @@ On line 110, notice the following command to enable tracing on one node .. sourcecode:: bash - csma.EnablePcap ("second", csmaDevices.Get (1), true); + csma.EnablePcap("second", csmaDevices.Get(1), true); Change the index to the quantity ``nCsma``, corresponding to the last node in the topology-- the node that contains the echo server: .. sourcecode:: bash - csma.EnablePcap ("second", csmaDevices.Get (nCsma), true); + csma.EnablePcap("second", csmaDevices.Get(nCsma), true); If you build the new script and run the simulation setting ``nCsma`` to 100, @@ -657,7 +657,7 @@ argument of ``false`` indicates that you would like a non-promiscuous trace: .. sourcecode:: bash - csma.EnablePcap ("second", csmaDevices.Get (nCsma - 1), false); + csma.EnablePcap("second", csmaDevices.Get(nCsma - 1), false); Now build and run as before: @@ -872,7 +872,7 @@ component is defined. This should all be quite familiar by now. using namespace ns3; - NS_LOG_COMPONENT_DEFINE ("ThirdScriptExample"); + NS_LOG_COMPONENT_DEFINE("ThirdScriptExample"); The main program begins just like ``second.cc`` by adding some command line parameters for enabling or disabling logging components and for changing the @@ -885,11 +885,11 @@ number of devices created. uint32_t nWifi = 3; CommandLine cmd; - cmd.AddValue ("nCsma", "Number of \"extra\" CSMA nodes/devices", nCsma); - cmd.AddValue ("nWifi", "Number of wifi STA devices", nWifi); - cmd.AddValue ("verbose", "Tell echo applications to log if true", verbose); + cmd.AddValue("nCsma", "Number of \"extra\" CSMA nodes/devices", nCsma); + cmd.AddValue("nWifi", "Number of wifi STA devices", nWifi); + cmd.AddValue("verbose", "Tell echo applications to log if true", verbose); - cmd.Parse (argc,argv); + cmd.Parse(argc,argv); if (verbose) { @@ -903,7 +903,7 @@ that we will connect via the point-to-point link. :: NodeContainer p2pNodes; - p2pNodes.Create (2); + p2pNodes.Create(2); Next, we see an old friend. We instantiate a ``PointToPointHelper`` and set the associated default ``Attributes`` so that we create a five megabit @@ -914,11 +914,11 @@ on the nodes and the channel between them. :: PointToPointHelper pointToPoint; - pointToPoint.SetDeviceAttribute ("DataRate", StringValue ("5Mbps")); - pointToPoint.SetChannelAttribute ("Delay", StringValue ("2ms")); + pointToPoint.SetDeviceAttribute("DataRate", StringValue("5Mbps")); + pointToPoint.SetChannelAttribute("Delay", StringValue("2ms")); NetDeviceContainer p2pDevices; - p2pDevices = pointToPoint.Install (p2pNodes); + p2pDevices = pointToPoint.Install(p2pNodes); Next, we declare another ``NodeContainer`` to hold the nodes that will be part of the bus (CSMA) network. @@ -926,8 +926,8 @@ part of the bus (CSMA) network. :: NodeContainer csmaNodes; - csmaNodes.Add (p2pNodes.Get (1)); - csmaNodes.Create (nCsma); + csmaNodes.Add(p2pNodes.Get(1)); + csmaNodes.Create(nCsma); The next line of code ``Gets`` the first node (as in having an index of one) from the point-to-point node container and adds it to the container of nodes @@ -943,11 +943,11 @@ selected nodes. :: CsmaHelper csma; - csma.SetChannelAttribute ("DataRate", StringValue ("100Mbps")); - csma.SetChannelAttribute ("Delay", TimeValue (NanoSeconds (6560))); + csma.SetChannelAttribute("DataRate", StringValue("100Mbps")); + csma.SetChannelAttribute("Delay", TimeValue(NanoSeconds(6560))); NetDeviceContainer csmaDevices; - csmaDevices = csma.Install (csmaNodes); + csmaDevices = csma.Install(csmaNodes); Next, we are going to create the nodes that will be part of the Wi-Fi network. We are going to create a number of "station" nodes as specified by the @@ -957,8 +957,8 @@ point-to-point link as the node for the access point. :: NodeContainer wifiStaNodes; - wifiStaNodes.Create (nWifi); - NodeContainer wifiApNode = p2pNodes.Get (0); + wifiStaNodes.Create(nWifi); + NodeContainer wifiApNode = p2pNodes.Get(0); The next bit of code constructs the wifi devices and the interconnection channel between these wifi nodes. First, we configure the PHY and channel @@ -966,8 +966,8 @@ helpers: :: - YansWifiChannelHelper channel = YansWifiChannelHelper::Default (); - YansWifiPhyHelper phy = YansWifiPhyHelper::Default (); + YansWifiChannelHelper channel = YansWifiChannelHelper::Default(); + YansWifiPhyHelper phy = YansWifiPhyHelper::Default(); For simplicity, this code uses the default PHY layer configuration and channel models which are documented in the API doxygen documentation for @@ -980,7 +980,7 @@ wireless medium and can communicate and interfere: :: - phy.SetChannel (channel.Create ()); + phy.SetChannel(channel.Create()); Once the PHY helper is configured, we can focus on the MAC layer. The WifiMacHelper object is used to set MAC parameters. @@ -992,7 +992,7 @@ the MAC layer implementation. :: WifiMacHelper mac; - Ssid ssid = Ssid ("ns-3-ssid"); + Ssid ssid = Ssid("ns-3-ssid"); WifiHelper will, by default, configure the standard in use to be 802.11ax (known commercially as Wi-Fi 6) and configure @@ -1013,9 +1013,9 @@ the WifiNetDevice objects that the helper create. :: NetDeviceContainer staDevices - mac.SetType ("ns3::StaWifiMac", - "Ssid", SsidValue (ssid), - "ActiveProbing", BooleanValue (false)); + mac.SetType("ns3::StaWifiMac", + "Ssid", SsidValue(ssid), + "ActiveProbing", BooleanValue(false)); In the above code, the specific kind of MAC layer that will be created by the helper is specified by the TypeId value @@ -1035,7 +1035,7 @@ create the Wi-Fi devices of these stations: :: NetDeviceContainer staDevices; - staDevices = wifi.Install (phy, mac, wifiStaNodes); + staDevices = wifi.Install(phy, mac, wifiStaNodes); We have configured Wi-Fi for all of our STA nodes, and now we need to configure the AP (access point) node. We begin this process by changing @@ -1044,8 +1044,8 @@ requirements of the AP. :: - mac.SetType ("ns3::ApWifiMac", - "Ssid", SsidValue (ssid)); + mac.SetType("ns3::ApWifiMac", + "Ssid", SsidValue(ssid)); In this case, the ``WifiMacHelper`` is going to create MAC layers of the "ns3::ApWifiMac", the latter specifying that a MAC @@ -1057,7 +1057,7 @@ The next lines create the single AP which shares the same set of PHY-level :: NetDeviceContainer apDevices; - apDevices = wifi.Install (phy, mac, wifiApNode); + apDevices = wifi.Install(phy, mac, wifiApNode); Now, we are going to add mobility models. We want the STA nodes to be mobile, wandering around inside a bounding box, and we want to make the AP node @@ -1069,13 +1069,13 @@ First, we instantiate a ``MobilityHelper`` object and set some MobilityHelper mobility; - mobility.SetPositionAllocator ("ns3::GridPositionAllocator", - "MinX", DoubleValue (0.0), - "MinY", DoubleValue (0.0), - "DeltaX", DoubleValue (5.0), - "DeltaY", DoubleValue (10.0), - "GridWidth", UintegerValue (3), - "LayoutType", StringValue ("RowFirst")); + mobility.SetPositionAllocator("ns3::GridPositionAllocator", + "MinX", DoubleValue(0.0), + "MinY", DoubleValue(0.0), + "DeltaX", DoubleValue(5.0), + "DeltaY", DoubleValue(10.0), + "GridWidth", UintegerValue(3), + "LayoutType", StringValue("RowFirst")); This code tells the mobility helper to use a two-dimensional grid to initially place the STA nodes. Feel free to explore the Doxygen for class @@ -1088,15 +1088,15 @@ box. :: - mobility.SetMobilityModel ("ns3::RandomWalk2dMobilityModel", - "Bounds", RectangleValue (Rectangle (-50, 50, -50, 50))); + mobility.SetMobilityModel("ns3::RandomWalk2dMobilityModel", + "Bounds", RectangleValue(Rectangle(-50, 50, -50, 50))); We now tell the ``MobilityHelper`` to install the mobility models on the STA nodes. :: - mobility.Install (wifiStaNodes); + mobility.Install(wifiStaNodes); We want the access point to remain in a fixed position during the simulation. We accomplish this by setting the mobility model for this node to be the @@ -1104,8 +1104,8 @@ We accomplish this by setting the mobility model for this node to be the :: - mobility.SetMobilityModel ("ns3::ConstantPositionMobilityModel"); - mobility.Install (wifiApNode); + mobility.SetMobilityModel("ns3::ConstantPositionMobilityModel"); + mobility.Install(wifiApNode); We now have our nodes, devices and channels created, and mobility models chosen for the Wi-Fi nodes, but we have no protocol stacks present. Just as @@ -1115,9 +1115,9 @@ to install these stacks. :: InternetStackHelper stack; - stack.Install (csmaNodes); - stack.Install (wifiApNode); - stack.Install (wifiStaNodes); + stack.Install(csmaNodes); + stack.Install(wifiApNode); + stack.Install(wifiStaNodes); Just as in the ``second.cc`` example script, we are going to use the ``Ipv4AddressHelper`` to assign IP addresses to our device interfaces. @@ -1130,50 +1130,50 @@ both the STA devices and the AP on the wireless network. Ipv4AddressHelper address; - address.SetBase ("10.1.1.0", "255.255.255.0"); + address.SetBase("10.1.1.0", "255.255.255.0"); Ipv4InterfaceContainer p2pInterfaces; - p2pInterfaces = address.Assign (p2pDevices); + p2pInterfaces = address.Assign(p2pDevices); - address.SetBase ("10.1.2.0", "255.255.255.0"); + address.SetBase("10.1.2.0", "255.255.255.0"); Ipv4InterfaceContainer csmaInterfaces; - csmaInterfaces = address.Assign (csmaDevices); + csmaInterfaces = address.Assign(csmaDevices); - address.SetBase ("10.1.3.0", "255.255.255.0"); - address.Assign (staDevices); - address.Assign (apDevices); + address.SetBase("10.1.3.0", "255.255.255.0"); + address.Assign(staDevices); + address.Assign(apDevices); We put the echo server on the "rightmost" node in the illustration at the start of the file. We have done this before. :: - UdpEchoServerHelper echoServer (9); + UdpEchoServerHelper echoServer(9); - ApplicationContainer serverApps = echoServer.Install (csmaNodes.Get (nCsma)); - serverApps.Start (Seconds (1.0)); - serverApps.Stop (Seconds (10.0)); + ApplicationContainer serverApps = echoServer.Install(csmaNodes.Get(nCsma)); + serverApps.Start(Seconds(1.0)); + serverApps.Stop(Seconds(10.0)); And we put the echo client on the last STA node we created, pointing it to the server on the CSMA network. We have also seen similar operations before. :: - UdpEchoClientHelper echoClient (csmaInterfaces.GetAddress (nCsma), 9); - echoClient.SetAttribute ("MaxPackets", UintegerValue (1)); - echoClient.SetAttribute ("Interval", TimeValue (Seconds (1.0))); - echoClient.SetAttribute ("PacketSize", UintegerValue (1024)); + UdpEchoClientHelper echoClient(csmaInterfaces.GetAddress(nCsma), 9); + echoClient.SetAttribute("MaxPackets", UintegerValue(1)); + echoClient.SetAttribute("Interval", TimeValue(Seconds(1.0))); + echoClient.SetAttribute("PacketSize", UintegerValue(1024)); ApplicationContainer clientApps = - echoClient.Install (wifiStaNodes.Get (nWifi - 1)); - clientApps.Start (Seconds (2.0)); - clientApps.Stop (Seconds (10.0)); + echoClient.Install(wifiStaNodes.Get(nWifi - 1)); + clientApps.Start(Seconds(2.0)); + clientApps.Stop(Seconds(10.0)); Since we have built an internetwork here, we need to enable internetwork routing just as we did in the ``second.cc`` example script. :: - Ipv4GlobalRoutingHelper::PopulateRoutingTables (); + Ipv4GlobalRoutingHelper::PopulateRoutingTables(); One thing that can surprise some users is the fact that the simulation we just created will never "naturally" stop. This is because we asked the wireless @@ -1186,15 +1186,15 @@ loop. :: - Simulator::Stop (Seconds (10.0)); + Simulator::Stop(Seconds(10.0)); We create just enough tracing to cover all three networks: :: - pointToPoint.EnablePcapAll ("third"); - phy.EnablePcap ("third", apDevices.Get (0)); - csma.EnablePcap ("third", csmaDevices.Get (0), true); + pointToPoint.EnablePcapAll("third"); + phy.EnablePcap("third", apDevices.Get(0)); + csma.EnablePcap("third", csmaDevices.Get(0), true); These three lines of code will start pcap tracing on both of the point-to-point nodes that serves as our backbone, will start a promiscuous (monitor) mode @@ -1206,8 +1206,8 @@ Finally, we actually run the simulation, clean up and then exit the program. :: - Simulator::Run (); - Simulator::Destroy (); + Simulator::Run(); + Simulator::Destroy(); return 0; } @@ -1357,11 +1357,11 @@ following function: :: void - CourseChange (std::string context, Ptr model) + CourseChange(std::string context, Ptr model) { - Vector position = model->GetPosition (); - NS_LOG_UNCOND (context << - " x = " << position.x << ", y = " << position.y); + Vector position = model->GetPosition(); + NS_LOG_UNCOND(context << + " x = " << position.x << ", y = " << position.y); } This code just pulls the position information from the mobility model and @@ -1374,11 +1374,10 @@ script just before the ``Simulator::Run`` call. :: std::ostringstream oss; - oss << - "/NodeList/" << wifiStaNodes.Get (nWifi - 1)->GetId () << - "/$ns3::MobilityModel/CourseChange"; + oss << "/NodeList/" << wifiStaNodes.Get(nWifi - 1)->GetId() + << "/$ns3::MobilityModel/CourseChange"; - Config::Connect (oss.str (), MakeCallback (&CourseChange)); + Config::Connect(oss.str(), MakeCallback(&CourseChange)); What we do here is to create a string containing the tracing namespace path of the event to which we want to connect. First, we have to figure out which @@ -1535,29 +1534,29 @@ Changing from the defaults * The type of queue used by a NetDevice can be usually modified through the device helper:: NodeContainer nodes; - nodes.Create (2); + nodes.Create(2); PointToPointHelper p2p; - p2p.SetQueue ("ns3::DropTailQueue", "MaxSize", StringValue ("50p")); + p2p.SetQueue("ns3::DropTailQueue", "MaxSize", StringValue("50p")); - NetDeviceContainer devices = p2p.Install (nodes); + NetDeviceContainer devices = p2p.Install(nodes); * The type of queue disc installed on a NetDevice can be modified through the traffic control helper:: InternetStackHelper stack; - stack.Install (nodes); + stack.Install(nodes); TrafficControlHelper tch; - tch.SetRootQueueDisc ("ns3::CoDelQueueDisc", "MaxSize", StringValue ("1000p")); - tch.Install (devices); + tch.SetRootQueueDisc("ns3::CoDelQueueDisc", "MaxSize", StringValue("1000p")); + tch.Install(devices); * BQL can be enabled on a device that supports it through the traffic control helper:: InternetStackHelper stack; - stack.Install (nodes); + stack.Install(nodes); TrafficControlHelper tch; - tch.SetRootQueueDisc ("ns3::CoDelQueueDisc", "MaxSize", StringValue ("1000p")); - tch.SetQueueLimits ("ns3::DynamicQueueLimits", "HoldTime", StringValue ("4ms")); - tch.Install (devices); + tch.SetRootQueueDisc("ns3::CoDelQueueDisc", "MaxSize", StringValue("1000p")); + tch.SetQueueLimits("ns3::DynamicQueueLimits", "HoldTime", StringValue("4ms")); + tch.Install(devices); diff --git a/doc/tutorial/source/conceptual-overview.rst b/doc/tutorial/source/conceptual-overview.rst index 6a8fbd992..e55960937 100644 --- a/doc/tutorial/source/conceptual-overview.rst +++ b/doc/tutorial/source/conceptual-overview.rst @@ -292,7 +292,7 @@ The next line of the script is the following, :: - NS_LOG_COMPONENT_DEFINE ("FirstScriptExample"); + NS_LOG_COMPONENT_DEFINE("FirstScriptExample"); We will use this statement as a convenient place to talk about our Doxygen documentation system. If you look at the project web site, @@ -334,7 +334,7 @@ The next lines of the script you will find are, :: int - main (int argc, char *argv[]) + main(int argc, char *argv[]) { This is just the declaration of the main function of your program (script). @@ -347,7 +347,7 @@ to be the default value: :: - Time::SetResolution (Time::NS); + Time::SetResolution(Time::NS); The resolution is the smallest time value that can be represented (as well as the smallest representable difference between two time values). @@ -386,7 +386,7 @@ simulation. :: NodeContainer nodes; - nodes.Create (2); + nodes.Create(2); Let's find the documentation for the ``NodeContainer`` class before we continue. Another way to get into the documentation for a given class is via @@ -433,8 +433,8 @@ The next three lines in the script are, :: PointToPointHelper pointToPoint; - pointToPoint.SetDeviceAttribute ("DataRate", StringValue ("5Mbps")); - pointToPoint.SetChannelAttribute ("Delay", StringValue ("2ms")); + pointToPoint.SetDeviceAttribute("DataRate", StringValue("5Mbps")); + pointToPoint.SetChannelAttribute("Delay", StringValue("2ms")); The first line, @@ -447,7 +447,7 @@ high-level perspective the next line, :: - pointToPoint.SetDeviceAttribute ("DataRate", StringValue ("5Mbps")); + pointToPoint.SetDeviceAttribute("DataRate", StringValue("5Mbps")); tells the ``PointToPointHelper`` object to use the value "5Mbps" (five megabits per second) as the "DataRate" when it creates a @@ -468,7 +468,7 @@ final line, :: - pointToPoint.SetChannelAttribute ("Delay", StringValue ("2ms")); + pointToPoint.SetChannelAttribute("Delay", StringValue("2ms")); tells the ``PointToPointHelper`` to use the value "2ms" (two milliseconds) as the value of the propagation delay of every point to point channel it @@ -490,7 +490,7 @@ following two lines of code, :: NetDeviceContainer devices; - devices = pointToPoint.Install (nodes); + devices = pointToPoint.Install(nodes); will finish configuring the devices and channel. The first line declares the device container mentioned above and the second does the heavy lifting. The @@ -504,7 +504,7 @@ by the ``PointToPointHelper``, the ``Attributes`` previously set in the helper are used to initialize the corresponding ``Attributes`` in the created objects. -After executing the ``pointToPoint.Install (nodes)`` call we will have +After executing the ``pointToPoint.Install(nodes)`` call we will have two nodes, each with an installed point-to-point net device and a single point-to-point channel between them. Both devices will be configured to transmit data at five megabits per second over the channel which has a two @@ -518,7 +518,7 @@ installed on our nodes. The next two lines of code will take care of that. :: InternetStackHelper stack; - stack.Install (nodes); + stack.Install(nodes); The ``InternetStackHelper`` is a topology helper that is to internet stacks what the ``PointToPointHelper`` is to point-to-point net devices. The @@ -539,7 +539,7 @@ The next two lines of code in our example script, ``first.cc``, :: Ipv4AddressHelper address; - address.SetBase ("10.1.1.0", "255.255.255.0"); + address.SetBase("10.1.1.0", "255.255.255.0"); declare an address helper object and tell it that it should begin allocating IP addresses from the network 10.1.1.0 using the mask 255.255.255.0 to define @@ -554,7 +554,7 @@ The next line of code, :: - Ipv4InterfaceContainer interfaces = address.Assign (devices); + Ipv4InterfaceContainer interfaces = address.Assign(devices); performs the actual address assignment. In |ns3| we make the association between an IP address and a device using an ``Ipv4Interface`` @@ -584,11 +584,11 @@ created. :: - UdpEchoServerHelper echoServer (9); + UdpEchoServerHelper echoServer(9); - ApplicationContainer serverApps = echoServer.Install (nodes.Get (1)); - serverApps.Start (Seconds (1.0)); - serverApps.Stop (Seconds (10.0)); + ApplicationContainer serverApps = echoServer.Install(nodes.Get(1)); + serverApps.Start(Seconds(1.0)); + serverApps.Stop(Seconds(10.0)); The first line of code in the above snippet declares the ``UdpEchoServerHelper``. As usual, this isn't the application itself, it @@ -608,7 +608,7 @@ to a node. Interestingly, the ``Install`` method takes a ``NodeContainter`` as a parameter just as the other ``Install`` methods we have seen. This is actually what is passed to the method even though it doesn't look so in this case. There is a C++ *implicit conversion* at -work here that takes the result of ``nodes.Get (1)`` (which returns a smart +work here that takes the result of ``nodes.Get(1)`` (which returns a smart pointer to a node object --- ``Ptr``) and uses that in a constructor for an unnamed ``NodeContainer`` that is then passed to ``Install``. If you are ever at a loss to find a particular method signature in C++ code @@ -633,8 +633,8 @@ converted for you. The two lines, :: - serverApps.Start (Seconds (1.0)); - serverApps.Stop (Seconds (10.0)); + serverApps.Start(Seconds(1.0)); + serverApps.Stop(Seconds(10.0)); will cause the echo server application to ``Start`` (enable itself) at one second into the simulation and to ``Stop`` (disable itself) at ten seconds @@ -651,14 +651,14 @@ that is managed by an ``UdpEchoClientHelper``. :: - UdpEchoClientHelper echoClient (interfaces.GetAddress (1), 9); - echoClient.SetAttribute ("MaxPackets", UintegerValue (1)); - echoClient.SetAttribute ("Interval", TimeValue (Seconds (1.0))); - echoClient.SetAttribute ("PacketSize", UintegerValue (1024)); + UdpEchoClientHelper echoClient(interfaces.GetAddress(1), 9); + echoClient.SetAttribute("MaxPackets", UintegerValue(1)); + echoClient.SetAttribute("Interval", TimeValue(Seconds(1.0))); + echoClient.SetAttribute("PacketSize", UintegerValue(1024)); - ApplicationContainer clientApps = echoClient.Install (nodes.Get (0)); - clientApps.Start (Seconds (2.0)); - clientApps.Stop (Seconds (10.0)); + ApplicationContainer clientApps = echoClient.Install(nodes.Get(0)); + clientApps.Start(Seconds(2.0)); + clientApps.Stop(Seconds(10.0)); For the echo client, however, we need to set five different ``Attributes``. The first two ``Attributes`` are set during construction of the @@ -695,17 +695,17 @@ done using the global function ``Simulator::Run``. :: - Simulator::Run (); + Simulator::Run(); When we previously called the methods, :: - serverApps.Start (Seconds (1.0)); - serverApps.Stop (Seconds (10.0)); + serverApps.Start(Seconds(1.0)); + serverApps.Stop(Seconds(10.0)); ... - clientApps.Start (Seconds (2.0)); - clientApps.Stop (Seconds (10.0)); + clientApps.Start(Seconds(2.0)); + clientApps.Stop(Seconds(10.0)); we actually scheduled events in the simulator at 1.0 seconds, 2.0 seconds and two events at 10.0 seconds. When ``Simulator::Run`` is called, the system @@ -741,7 +741,7 @@ took care of the hard part for you. The remaining lines of our first :: - Simulator::Destroy (); + Simulator::Destroy(); return 0; } @@ -764,7 +764,7 @@ not) be generated. The simulation will stop automatically when no further events are in the event queue, or when a special Stop event is found. The Stop event is created through the -``Simulator::Stop (stopTime);`` function. +``Simulator::Stop(stopTime);`` function. There is a typical case where ``Simulator::Stop`` is absolutely necessary to stop the simulation: when there is a self-sustaining event. @@ -791,9 +791,9 @@ in the first example program will schedule an explicit stop at 11 seconds: :: - + Simulator::Stop (Seconds (11.0)); - Simulator::Run (); - Simulator::Destroy (); + + Simulator::Stop(Seconds(11.0)); + Simulator::Run(); + Simulator::Destroy(); return 0; } diff --git a/doc/tutorial/source/data-collection.rst b/doc/tutorial/source/data-collection.rst index ba95465e8..4d5351efe 100644 --- a/doc/tutorial/source/data-collection.rst +++ b/doc/tutorial/source/data-collection.rst @@ -50,8 +50,8 @@ First, it has been enabled for IPv6 support with a command-line option: :: CommandLine cmd; - cmd.AddValue ("useIpv6", "Use Ipv6", useV6); - cmd.Parse (argc, argv); + cmd.AddValue("useIpv6", "Use Ipv6", useV6); + cmd.Parse(argc, argv); If the user specifies ``useIpv6``, option, the program will be run using IPv6 instead of IPv4. The ``help`` option, available on all |ns3| @@ -124,40 +124,40 @@ some of the new lines of this diff: + // Configure the plot. The first argument is the file name prefix + // for the output files generated. The second, third, and fourth + // arguments are, respectively, the plot title, x-axis, and y-axis labels - + plotHelper.ConfigurePlot ("seventh-packet-byte-count", - + "Packet Byte Count vs. Time", - + "Time (Seconds)", - + "Packet Byte Count"); + + plotHelper.ConfigurePlot("seventh-packet-byte-count", + + "Packet Byte Count vs. Time", + + "Time(Seconds)", + + "Packet Byte Count"); + + // Specify the probe type, trace source path (in configuration namespace), and + // probe output trace source ("OutputBytes") to plot. The fourth argument + // specifies the name of the data series label on the plot. The last + // argument formats the plot by specifying where the key should be placed. - + plotHelper.PlotProbe (probeType, - + tracePath, - + "OutputBytes", - + "Packet Byte Count", - + GnuplotAggregator::KEY_BELOW); + + plotHelper.PlotProbe(probeType, + + tracePath, + + "OutputBytes", + + "Packet Byte Count", + + GnuplotAggregator::KEY_BELOW); + + // Use FileHelper to write out the packet byte count over time + FileHelper fileHelper; + + // Configure the file to be written, and the formatting of output data. - + fileHelper.ConfigureFile ("seventh-packet-byte-count", - + FileAggregator::FORMATTED); + + fileHelper.ConfigureFile("seventh-packet-byte-count", + + FileAggregator::FORMATTED); + + // Set the labels for this formatted output file. - + fileHelper.Set2dFormat ("Time (Seconds) = %.3e\tPacket Byte Count = %.0f"); + + fileHelper.Set2dFormat("Time (Seconds) = %.3e\tPacket Byte Count = %.0f"); + + // Specify the probe type, probe path (in configuration namespace), and + // probe output trace source ("OutputBytes") to write. - + fileHelper.WriteProbe (probeType, - + tracePath, - + "OutputBytes"); + + fileHelper.WriteProbe(probeType, + + tracePath, + + "OutputBytes"); + - Simulator::Stop (Seconds (20)); - Simulator::Run (); - Simulator::Destroy (); + Simulator::Stop(Seconds(20)); + Simulator::Run(); + Simulator::Destroy(); The careful reader will have noticed, when testing the IPv6 command @@ -243,10 +243,10 @@ the GnuplotHelper object must be declared and configured: + // Configure the plot. The first argument is the file name prefix + // for the output files generated. The second, third, and fourth + // arguments are, respectively, the plot title, x-axis, and y-axis labels - + plotHelper.ConfigurePlot ("seventh-packet-byte-count", - + "Packet Byte Count vs. Time", - + "Time (Seconds)", - + "Packet Byte Count"); + + plotHelper.ConfigurePlot("seventh-packet-byte-count", + + "Packet Byte Count vs. Time", + + "Time (Seconds)", + + "Packet Byte Count"); To this point, an empty plot has been configured. The filename prefix @@ -272,11 +272,11 @@ We use them here: + // probe output trace source ("OutputBytes") to plot. The fourth argument + // specifies the name of the data series label on the plot. The last + // argument formats the plot by specifying where the key should be placed. - + plotHelper.PlotProbe (probeType, - + tracePath, - + "OutputBytes", - + "Packet Byte Count", - + GnuplotAggregator::KEY_BELOW); + + plotHelper.PlotProbe(probeType, + + tracePath, + + "OutputBytes", + + "Packet Byte Count", + + GnuplotAggregator::KEY_BELOW); The first two arguments are the name of the probe type and the trace source path. These two are probably the hardest to determine when you try to use @@ -287,8 +287,8 @@ observe: :: - .AddTraceSource ("Tx", "Send IPv6 packet to outgoing interface.", - MakeTraceSourceAccessor (&Ipv6L3Protocol::m_txTrace)) + .AddTraceSource("Tx", "Send IPv6 packet to outgoing interface.", + MakeTraceSourceAccessor(&Ipv6L3Protocol::m_txTrace)) This says that ``Tx`` is a name for variable ``m_txTrace``, which has a declaration of: @@ -317,18 +317,18 @@ the data out of the probed Packet object: :: TypeId - Ipv6PacketProbe::GetTypeId () + Ipv6PacketProbe::GetTypeId() { - static TypeId tid = TypeId ("ns3::Ipv6PacketProbe") - .SetParent () - .SetGroupName ("Stats") - .AddConstructor () - .AddTraceSource ( "Output", - "The packet plus its IPv6 object and interface that serve as the output for this probe", - MakeTraceSourceAccessor (&Ipv6PacketProbe::m_output)) - .AddTraceSource ( "OutputBytes", - "The number of bytes in the packet", - MakeTraceSourceAccessor (&Ipv6PacketProbe::m_outputBytes)) + static TypeId tid = TypeId("ns3::Ipv6PacketProbe") + .SetParent() + .SetGroupName("Stats") + .AddConstructor() + .AddTraceSource("Output", + "The packet plus its IPv6 object and interface that serve as the output for this probe", + MakeTraceSourceAccessor(&Ipv6PacketProbe::m_output)) + .AddTraceSource("OutputBytes", + "The number of bytes in the packet", + MakeTraceSourceAccessor(&Ipv6PacketProbe::m_outputBytes)) ; return tid; } @@ -407,8 +407,8 @@ be seen in the filenames. Let's look at the code piece-by-piece: + FileHelper fileHelper; + + // Configure the file to be written, and the formatting of output data. - + fileHelper.ConfigureFile ("seventh-packet-byte-count", - + FileAggregator::FORMATTED); + + fileHelper.ConfigureFile("seventh-packet-byte-count", + + FileAggregator::FORMATTED); The file helper file prefix is the first argument, and a format specifier is next. @@ -420,7 +420,7 @@ FORMATTED is specified) with a format string such as follows: + + // Set the labels for this formatted output file. - + fileHelper.Set2dFormat ("Time (Seconds) = %.3e\tPacket Byte Count = %.0f"); + + fileHelper.Set2dFormat("Time (Seconds) = %.3e\tPacket Byte Count = %.0f"); Finally, the trace source of interest must be hooked. Again, the probeType and tracePath variables in this example are used, and the probe's output @@ -431,9 +431,9 @@ trace source "OutputBytes" is hooked: + + // Specify the probe type, trace source path (in configuration namespace), and + // probe output trace source ("OutputBytes") to write. - + fileHelper.WriteProbe (probeType, - + tracePath, - + "OutputBytes"); + + fileHelper.WriteProbe(probeType, + + tracePath, + + "OutputBytes"); + The wildcard fields in this trace source specifier match two trace sources. @@ -448,4 +448,3 @@ providing time series output has been added. The basic pattern described above may be replicated within the scope of support of the existing probes and trace sources. More capabilities including statistics processing will be added in future releases. - diff --git a/doc/tutorial/source/getting-started.rst b/doc/tutorial/source/getting-started.rst index 054b26a91..a034ea757 100644 --- a/doc/tutorial/source/getting-started.rst +++ b/doc/tutorial/source/getting-started.rst @@ -822,9 +822,9 @@ use the indicated Code Wrapper macro: .. sourcecode:: cpp - NS_BUILD_DEBUG (std::cout << "Part of an output line..." << std::flush; timer.Start ()); - DoLongInvolvedComputation (); - NS_BUILD_DEBUG (timer.Stop (); std::cout << "Done: " << timer << std::endl;) + NS_BUILD_DEBUG(std::cout << "Part of an output line..." << std::flush; timer.Start()); + DoLongInvolvedComputation(); + NS_BUILD_DEBUG(timer.Stop(); std::cout << "Done: " << timer << std::endl;) By default ns3 puts the build artifacts in the ``build`` directory. You can specify a different output directory with the ``--out`` @@ -1626,4 +1626,3 @@ The resulting text file can then be saved with any corresponding then echo "$gitDiff" >> version.txt fi - diff --git a/doc/tutorial/source/tracing.rst b/doc/tutorial/source/tracing.rst index 599a2abed..7f93b61ab 100644 --- a/doc/tutorial/source/tracing.rst +++ b/doc/tutorial/source/tracing.rst @@ -71,7 +71,7 @@ standard output, as in:: #include ... void - SomeFunction () + SomeFunction() { uint32_t x = SOME_INTERESTING_VALUE; ... @@ -107,16 +107,16 @@ other people as a patch to the existing core. Let's pick a random example. If you wanted to add more logging to the |ns3| TCP socket (``tcp-socket-base.cc``) you could just add a new message down in the implementation. Notice that in -``TcpSocketBase::ProcessEstablished ()`` there is no log message for the +``TcpSocketBase::ProcessEstablished()`` there is no log message for the reception of a SYN+ACK in ESTABLISHED state. You could simply add one, changing the code. Here is the original:: /* Received a packet upon ESTABLISHED state. This function is mimicking the role of tcp_rcv_established() in tcp_input.c in Linux kernel. */ void - TcpSocketBase::ProcessEstablished (Ptr packet, const TcpHeader& tcpHeader) + TcpSocketBase::ProcessEstablished(Ptr packet, const TcpHeader& tcpHeader) { - NS_LOG_FUNCTION (this << tcpHeader); + NS_LOG_FUNCTION(this << tcpHeader); ... else if (tcpflags == (TcpHeader::SYN | TcpHeader::ACK)) @@ -130,13 +130,13 @@ To log the SYN+ACK case, you can add a new ``NS_LOG_LOGIC`` in the /* Received a packet upon ESTABLISHED state. This function is mimicking the role of tcp_rcv_established() in tcp_input.c in Linux kernel. */ void - TcpSocketBase::ProcessEstablished (Ptr packet, const TcpHeader& tcpHeader) + TcpSocketBase::ProcessEstablished(Ptr packet, const TcpHeader& tcpHeader) { - NS_LOG_FUNCTION (this << tcpHeader); + NS_LOG_FUNCTION(this << tcpHeader); ... else if (tcpflags == (TcpHeader::SYN | TcpHeader::ACK)) { // No action for received SYN+ACK, it is probably a duplicated packet - NS_LOG_LOGIC ("TcpSocketBase " << this << " ignoring SYN+ACK"); + NS_LOG_LOGIC("TcpSocketBase " << this << " ignoring SYN+ACK"); } ... @@ -261,7 +261,7 @@ initialize this pointer to something meaningful, you need to have a function with a matching signature. In this case, you could provide a function that looks like:: - int MyFunction (int arg) {} + int MyFunction(int arg) {} If you have this target, you can initialize the variable to point to your function:: @@ -271,14 +271,14 @@ your function:: You can then call MyFunction indirectly using the more suggestive form of the call:: - int result = (*pfi) (1234); + int result = (*pfi)(1234); This is suggestive since it looks like you are dereferencing the function pointer just like you would dereference any pointer. Typically, however, people take advantage of the fact that the compiler knows what is going on and will just use a shorter form:: - int result = pfi (1234); + int result = pfi(1234); This looks like you are calling a function named ``pfi``, but the compiler is smart enough to know to call through the variable ``pfi`` @@ -363,21 +363,21 @@ simple Object we can work with. class MyObject : public Object { public: - static TypeId GetTypeId () + static TypeId GetTypeId() { - static TypeId tid = TypeId ("MyObject") - .SetParent (Object::GetTypeId ()) - .SetGroupName ("MyGroup") - .AddConstructor () - .AddTraceSource ("MyInteger", - "An integer value to trace.", - MakeTraceSourceAccessor (&MyObject::m_myInt), - "ns3::TracedValueCallback::Int32") + static TypeId tid = TypeId("MyObject") + .SetParent(Object::GetTypeId()) + .SetGroupName("MyGroup") + .AddConstructor() + .AddTraceSource("MyInteger", + "An integer value to trace.", + MakeTraceSourceAccessor(&MyObject::m_myInt), + "ns3::TracedValueCallback::Int32") ; return tid; } - MyObject () {} + MyObject() {} TracedValue m_myInt; }; @@ -405,7 +405,7 @@ sink function ``traceSink`` for this TracedValue will need the signature :: - void (* traceSink)(int32_t oldValue, int32_t newValue); + void (*traceSink)(int32_t oldValue, int32_t newValue); All trace sinks hooking this trace source must have this signature. We'll discuss below how you can determine the required callback @@ -414,7 +414,7 @@ signature in other cases. Sure enough, continuing through ``fourth.cc`` we see:: void - IntTrace (int32_t oldValue, int32_t newValue) + IntTrace(int32_t oldValue, int32_t newValue) { std::cout << "Traced " << oldValue << " to " << newValue << std::endl; } @@ -427,10 +427,10 @@ We have now seen the trace source and the trace sink. What remains is code to connect the source to the sink, which happens in ``main``:: int - main (int argc, char *argv[]) + main(int argc, char *argv[]) { - Ptr myObject = CreateObject (); - myObject->TraceConnectWithoutContext ("MyInteger", MakeCallback(&IntTrace)); + Ptr myObject = CreateObject(); + myObject->TraceConnectWithoutContext("MyInteger", MakeCallback(&IntTrace)); myObject->m_myInt = 1234; } @@ -519,10 +519,10 @@ from the mobility models of our simulation. It should now be a lot more clear to you what this function is doing:: void - CourseChange (std::string context, Ptr model) + CourseChange(std::string context, Ptr model) { - Vector position = model->GetPosition (); - NS_LOG_UNCOND (context << + Vector position = model->GetPosition(); + NS_LOG_UNCOND(context << " x = " << position.x << ", y = " << position.y); } @@ -533,10 +533,10 @@ sink:: std::ostringstream oss; oss << "/NodeList/" - << wifiStaNodes.Get (nWifi - 1)->GetId () + << wifiStaNodes.Get(nWifi - 1)->GetId() << "/$ns3::MobilityModel/CourseChange"; - Config::Connect (oss.str (), MakeCallback (&CourseChange)); + Config::Connect(oss.str(), MakeCallback(&CourseChange)); Let's try and make some sense of what is sometimes considered relatively mysterious code. For the purposes of discussion, assume @@ -558,16 +558,16 @@ container to get a ``Ptr`` which we used to call ``GetId()``. We could have used this ``Ptr`` to call a Connect method directly:: - Ptr theObject = wifiStaNodes.Get (nWifi - 1); - theObject->TraceConnectWithoutContext ("CourseChange", MakeCallback (&CourseChange)); + Ptr theObject = wifiStaNodes.Get(nWifi - 1); + theObject->TraceConnectWithoutContext("CourseChange", MakeCallback(&CourseChange)); In the ``third.cc`` example, we actually wanted an additional "context" to be delivered along with the Callback parameters (which will be explained below) so we could actually use the following equivalent code:: - Ptr theObject = wifiStaNodes.Get (nWifi - 1); - theObject->TraceConnect ("CourseChange", MakeCallback (&CourseChange)); + Ptr theObject = wifiStaNodes.Get(nWifi - 1); + theObject->TraceConnect("CourseChange", MakeCallback(&CourseChange)); It turns out that the internal code for ``Config::ConnectWithoutContext`` and ``Config::Connect`` actually @@ -613,7 +613,7 @@ mobility model --- which is of type ``ns3::MobilityModel``. If you are familiar with ``GetObject``, we have asked the system to do the following:: - Ptr mobilityModel = node->GetObject () + Ptr mobilityModel = node->GetObject() We are now at the last Object in the path, so we turn our attention to the Attributes of that Object. The ``MobilityModel`` class defines an @@ -623,10 +623,10 @@ for "CourseChange" in your favorite editor. You should find :: - .AddTraceSource ("CourseChange", - "The value of the position and/or velocity vector changed", - MakeTraceSourceAccessor (&MobilityModel::m_courseChangeTrace), - "ns3::MobilityModel::CourseChangeCallback") + .AddTraceSource("CourseChange", + "The value of the position and/or velocity vector changed", + MakeTraceSourceAccessor(&MobilityModel::m_courseChangeTrace), + "ns3::MobilityModel::CourseChangeCallback") which should look very familiar at this point. @@ -650,7 +650,7 @@ down to the end of the file, you will see a method defined called ``NotifyCourseChange()``:: void - MobilityModel::NotifyCourseChange () const + MobilityModel::NotifyCourseChange() const { m_courseChangeTrace(this); } @@ -843,8 +843,8 @@ and you may find your answer along with working code. For example, in this case, ``src/mobility/examples/main-random-topology.cc`` has something just waiting for you to use:: - Config::Connect ("/NodeList/*/$ns3::MobilityModel/CourseChange", - MakeCallback (&CourseChange)); + Config::Connect("/NodeList/*/$ns3::MobilityModel/CourseChange", + MakeCallback(&CourseChange)); We'll return to this example in a moment. @@ -889,7 +889,7 @@ an example. The example above, from same file:: static void - CourseChange (std::string context, Ptr model) + CourseChange(std::string context, Ptr model) { ... } @@ -925,7 +925,7 @@ that returns void and takes a ``Ptr``. For example:: void - CourseChange (Ptr model) + CourseChange(Ptr model) { ... } @@ -936,7 +936,7 @@ Callback function that takes a string context, then the template arguments:: void - CourseChange (std::string context, Ptr model) + CourseChange(std::string context, Ptr model) { ... } @@ -946,7 +946,7 @@ visible in your local file, you can add the keyword ``static`` and come up with:: static void - CourseChange (std::string path, Ptr model) + CourseChange(std::string path, Ptr model) { ... } @@ -995,19 +995,19 @@ stuff. :: - TracedCallback::TracedCallback () - TracedCallback::ConnectWithoutContext (c ... - TracedCallback::Connect (const CallbackB ... + TracedCallback::TracedCallback() + TracedCallback::ConnectWithoutContext(c ... + TracedCallback::Connect(const CallbackB ... TracedCallback::DisconnectWithoutContext ... - TracedCallback::Disconnect (const Callba ... - TracedCallback::operator() () const ... - TracedCallback::operator() (T1 a1) const ... - TracedCallback::operator() (T1 a1, T2 a2 ... - TracedCallback::operator() (T1 a1, T2 a2 ... - TracedCallback::operator() (T1 a1, T2 a2 ... - TracedCallback::operator() (T1 a1, T2 a2 ... - TracedCallback::operator() (T1 a1, T2 a2 ... - TracedCallback::operator() (T1 a1, T2 a2 ... + TracedCallback::Disconnect(const Callba ... + TracedCallback::operator()() const ... + TracedCallback::operator()(T1 a1) const ... + TracedCallback::operator()(T1 a1, T2 a2 ... + TracedCallback::operator()(T1 a1, T2 a2 ... + TracedCallback::operator()(T1 a1, T2 a2 ... + TracedCallback::operator()(T1 a1, T2 a2 ... + TracedCallback::operator()(T1 a1, T2 a2 ... + TracedCallback::operator()(T1 a1, T2 a2 ... It turns out that all of this comes from the header file ``traced-callback.h`` which sounds very promising. You can then take @@ -1071,8 +1071,8 @@ functions. If you scroll down, you will see a TracedCallback::ConnectWithoutContext ... { Callback cb; - cb.Assign (callback); - m_callbackList.push_back (cb); + cb.Assign(callback); + m_callbackList.push_back(cb); } You are now in the belly of the beast. When the template is @@ -1085,8 +1085,8 @@ instantiated for the declaration above, the compiler will replace TracedCallback::ConnectWithoutContext ... cb { Callback > cb; - cb.Assign (callback); - m_callbackList.push_back (cb); + cb.Assign(callback); + m_callbackList.push_back(cb); } You can now see the implementation of everything we've been talking @@ -1130,7 +1130,7 @@ and takes a ``Ptr``. For example, :: void - CourseChangeCallback (Ptr model) + CourseChangeCallback(Ptr model) { ... } @@ -1141,7 +1141,7 @@ Callback function that takes a string context. This is because the ``Connect`` function will provide the context for you. You'll need:: void - CourseChangeCallback (std::string context, Ptr model) + CourseChangeCallback(std::string context, Ptr model) { ... } @@ -1151,7 +1151,7 @@ visible in your local file, you can add the keyword ``static`` and come up with:: static void - CourseChangeCallback (std::string path, Ptr model) + CourseChangeCallback(std::string path, Ptr model) { ... } @@ -1316,15 +1316,15 @@ and search for "CongestionWindow". You will find, :: - ns3TcpSocket->TraceConnectWithoutContext ("CongestionWindow", - MakeCallback (&Ns3TcpCwndTestCase1::CwndChange, this)); + ns3TcpSocket->TraceConnectWithoutContext("CongestionWindow", + MakeCallback(&Ns3TcpCwndTestCase1::CwndChange, this)); This should look very familiar to you. We mentioned above that if we had a pointer to the ``TcpSocketBase``, we could ``TraceConnect`` to the "CongestionWindow" trace source. That's exactly what we have here; so it turns out that this line of code does exactly what we want. Let's go ahead and extract the code we need from this function -(``Ns3TcpCwndTestCase1::DoRun ()``). If you look at this +(``Ns3TcpCwndTestCase1::DoRun()``). If you look at this function, you will find that it looks just like an |ns3| script. It turns out that is exactly what it is. It is a script run by the test framework, so we can just pull it out and wrap it in ``main`` instead @@ -1415,7 +1415,7 @@ see some familiar looking code:: using namespace ns3; - NS_LOG_COMPONENT_DEFINE ("FifthScriptExample"); + NS_LOG_COMPONENT_DEFINE("FifthScriptExample"); This has all been covered, so we won't rehash it. The next lines of source are the network illustration and a comment addressing the @@ -1470,18 +1470,18 @@ time. { public: - MyApp (); + MyApp(); virtual ~MyApp(); - void Setup (Ptr socket, Address address, uint32_t packetSize, + void Setup(Ptr socket, Address address, uint32_t packetSize, uint32_t nPackets, DataRate dataRate); private: - virtual void StartApplication (); - virtual void StopApplication (); + virtual void StartApplication(); + virtual void StopApplication(); - void ScheduleTx (); - void SendPacket (); + void ScheduleTx(); + void SendPacket(); Ptr m_socket; Address m_peer; @@ -1516,8 +1516,8 @@ The most common way to start pumping events is to start an (hopefully) familiar lines of an |ns3| script:: ApplicationContainer apps = ... - apps.Start (Seconds (1.0)); - apps.Stop (Seconds (10.0)); + apps.Start(Seconds(1.0)); + apps.Stop(Seconds(10.0)); The application container code (see ``src/network/helper/application-container.h`` if you are interested) @@ -1525,13 +1525,13 @@ loops through its contained applications and calls, :: - app->SetStartTime (startTime); + app->SetStartTime(startTime); as a result of the ``apps.Start`` call and :: - app->SetStopTime (stopTime); + app->SetStopTime(stopTime); as a result of the ``apps.Stop`` call. @@ -1571,7 +1571,7 @@ relatively common idom in |ns3|. So, take a look at :: - Simulator::ScheduleWithContext (index, TimeStep (0), &Node::Initialize, node); + Simulator::ScheduleWithContext(index, TimeStep(0), &Node::Initialize, node); This tells you that whenever a Node is created in a simulation, as a side-effect, a call to that node's ``Initialize`` method is @@ -1616,14 +1616,14 @@ what happens when ``Application::DoInitialize`` is called. Take a look at ``src/network/model/application.cc`` and you will find:: void - Application::DoInitialize () + Application::DoInitialize() { - m_startEvent = Simulator::Schedule (m_startTime, &Application::StartApplication, this); - if (m_stopTime != TimeStep (0)) + m_startEvent = Simulator::Schedule(m_startTime, &Application::StartApplication, this); + if (m_stopTime != TimeStep(0)) { - m_stopEvent = Simulator::Schedule (m_stopTime, &Application::StopApplication, this); + m_stopEvent = Simulator::Schedule(m_stopTime, &Application::StopApplication, this); } - Object::DoInitialize (); + Object::DoInitialize(); } Here, we finally come to the end of the trail. If you have kept it @@ -1658,15 +1658,15 @@ The MyApp Application The ``MyApp`` ``Application`` needs a constructor and a destructor, of course:: - MyApp::MyApp () - : m_socket (0), - m_peer (), - m_packetSize (0), - m_nPackets (0), - m_dataRate (0), - m_sendEvent (), - m_running (false), - m_packetsSent (0) + MyApp::MyApp() + : m_socket(0), + m_peer(), + m_packetSize(0), + m_nPackets(0), + m_dataRate(0), + m_sendEvent(), + m_running(false), + m_packetsSent(0) { } @@ -1681,8 +1681,8 @@ this ``Application`` in the first place. :: void - MyApp::Setup (Ptr socket, Address address, uint32_t packetSize, - uint32_t nPackets, DataRate dataRate) + MyApp::Setup(Ptr socket, Address address, uint32_t packetSize, + uint32_t nPackets, DataRate dataRate) { m_socket = socket; m_peer = address; @@ -1702,13 +1702,13 @@ passing it to the ``Setup`` method. :: void - MyApp::StartApplication () + MyApp::StartApplication() { m_running = true; m_packetsSent = 0; - m_socket->Bind (); - m_socket->Connect (m_peer); - SendPacket (); + m_socket->Bind(); + m_socket->Connect(m_peer); + SendPacket(); } The above code is the overridden implementation @@ -1731,18 +1731,18 @@ creating simulation events. :: void - MyApp::StopApplication () + MyApp::StopApplication() { m_running = false; - if (m_sendEvent.IsRunning ()) + if (m_sendEvent.IsRunning()) { - Simulator::Cancel (m_sendEvent); + Simulator::Cancel(m_sendEvent); } if (m_socket) { - m_socket->Close (); + m_socket->Close(); } } @@ -1765,14 +1765,14 @@ chain of events that describes the ``Application`` behavior. :: void - MyApp::SendPacket () + MyApp::SendPacket() { - Ptr packet = Create (m_packetSize); - m_socket->Send (packet); + Ptr packet = Create(m_packetSize); + m_socket->Send(packet); if (++m_packetsSent < m_nPackets) { - ScheduleTx (); + ScheduleTx(); } } @@ -1788,12 +1788,12 @@ decides it has sent enough. :: void - MyApp::ScheduleTx () + MyApp::ScheduleTx() { if (m_running) { - Time tNext (Seconds (m_packetSize * 8 / static_cast (m_dataRate.GetBitRate ()))); - m_sendEvent = Simulator::Schedule (tNext, &MyApp::SendPacket, this); + Time tNext(Seconds(m_packetSize * 8 / static_cast(m_dataRate.GetBitRate()))); + m_sendEvent = Simulator::Schedule(tNext, &MyApp::SendPacket, this); } } @@ -1817,9 +1817,9 @@ indicating the congestion window has been updated. The next piece of code implements the corresponding trace sink:: static void - CwndChange (uint32_t oldCwnd, uint32_t newCwnd) + CwndChange(uint32_t oldCwnd, uint32_t newCwnd) { - NS_LOG_UNCOND (Simulator::Now ().GetSeconds () << "\t" << newCwnd); + NS_LOG_UNCOND(Simulator::Now().GetSeconds() << "\t" << newCwnd); } This should be very familiar to you now, so we won't dwell on the @@ -1836,9 +1836,9 @@ demonstrate this working. :: static void - RxDrop (Ptr p) + RxDrop(Ptr p) { - NS_LOG_UNCOND ("RxDrop at " << Simulator::Now ().GetSeconds ()); + NS_LOG_UNCOND("RxDrop at " << Simulator::Now().GetSeconds()); } This trace sink will be connected to the "PhyRxDrop" trace source of @@ -1861,17 +1861,17 @@ Main Program The following code should be very familiar to you by now:: int - main (int argc, char *argv[]) + main(int argc, char *argv[]) { NodeContainer nodes; - nodes.Create (2); + nodes.Create(2); PointToPointHelper pointToPoint; - pointToPoint.SetDeviceAttribute ("DataRate", StringValue ("5Mbps")); - pointToPoint.SetChannelAttribute ("Delay", StringValue ("2ms")); + pointToPoint.SetDeviceAttribute("DataRate", StringValue("5Mbps")); + pointToPoint.SetChannelAttribute("Delay", StringValue("2ms")); NetDeviceContainer devices; - devices = pointToPoint.Install (nodes); + devices = pointToPoint.Install(nodes); This creates two nodes with a point-to-point channel between them, just as shown in the illustration at the start of the file. @@ -1890,9 +1890,9 @@ into a ``Channel`` at a given *rate*. :: - Ptr em = CreateObject (); - em->SetAttribute ("ErrorRate", DoubleValue (0.00001)); - devices.Get (1)->SetAttribute ("ReceiveErrorModel", PointerValue (em)); + Ptr em = CreateObject(); + em->SetAttribute("ErrorRate", DoubleValue(0.00001)); + devices.Get(1)->SetAttribute("ReceiveErrorModel", PointerValue(em)); The above code instantiates a ``RateErrorModel`` Object, and we set the "ErrorRate" ``Attribute`` to the desired value. We then set the @@ -1903,11 +1903,11 @@ retransmissions and make our plot a little more interesting. :: InternetStackHelper stack; - stack.Install (nodes); + stack.Install(nodes); Ipv4AddressHelper address; - address.SetBase ("10.1.1.0", "255.255.255.252"); - Ipv4InterfaceContainer interfaces = address.Assign (devices); + address.SetBase("10.1.1.0", "255.255.255.252"); + Ipv4InterfaceContainer interfaces = address.Assign(devices); The above code should be familiar. It installs internet stacks on our two nodes and creates interfaces and assigns IP addresses for the @@ -1920,19 +1920,19 @@ is commonly used in |ns3| for that purpose. :: uint16_t sinkPort = 8080; - Address sinkAddress (InetSocketAddress(interfaces.GetAddress (1), sinkPort)); - PacketSinkHelper packetSinkHelper ("ns3::TcpSocketFactory", - InetSocketAddress (Ipv4Address::GetAny (), sinkPort)); - ApplicationContainer sinkApps = packetSinkHelper.Install (nodes.Get (1)); - sinkApps.Start (Seconds (0.)); - sinkApps.Stop (Seconds (20.)); + Address sinkAddress(InetSocketAddress(interfaces.GetAddress(1), sinkPort)); + PacketSinkHelper packetSinkHelper("ns3::TcpSocketFactory", + InetSocketAddress(Ipv4Address::GetAny(), sinkPort)); + ApplicationContainer sinkApps = packetSinkHelper.Install(nodes.Get(1)); + sinkApps.Start(Seconds(0.)); + sinkApps.Stop(Seconds(20.)); This should all be familiar, with the exception of, :: - PacketSinkHelper packetSinkHelper ("ns3::TcpSocketFactory", - InetSocketAddress (Ipv4Address::GetAny (), sinkPort)); + PacketSinkHelper packetSinkHelper("ns3::TcpSocketFactory", + InetSocketAddress(Ipv4Address::GetAny(), sinkPort)); This code instantiates a ``PacketSinkHelper`` and tells it to create sockets using the class ``ns3::TcpSocketFactory``. This class @@ -1952,10 +1952,10 @@ trace source. :: - Ptr ns3TcpSocket = Socket::CreateSocket (nodes.Get (0), - TcpSocketFactory::GetTypeId ()); - ns3TcpSocket->TraceConnectWithoutContext ("CongestionWindow", - MakeCallback (&CwndChange)); + Ptr ns3TcpSocket = Socket::CreateSocket(nodes.Get(0), + TcpSocketFactory::GetTypeId()); + ns3TcpSocket->TraceConnectWithoutContext("CongestionWindow", + MakeCallback(&CwndChange)); The first statement calls the static member function ``Socket::CreateSocket`` and provides a Node and an explicit @@ -1975,11 +1975,11 @@ didn't go to any trouble to create a helper to manage the ``Application`` so we are going to have to create and install it "manually". This is actually quite easy:: - Ptr app = CreateObject (); - app->Setup (ns3TcpSocket, sinkAddress, 1040, 1000, DataRate ("1Mbps")); - nodes.Get (0)->AddApplication (app); - app->Start (Seconds (1.)); - app->Stop (Seconds (20.)); + Ptr app = CreateObject(); + app->Setup(ns3TcpSocket, sinkAddress, 1040, 1000, DataRate("1Mbps")); + nodes.Get(0)->AddApplication(app); + app->Start(Seconds(1.)); + app->Stop(Seconds(20.)); The first line creates an ``Object`` of type ``MyApp`` -- our ``Application``. The second line tells the ``Application`` what @@ -1996,7 +1996,7 @@ We need to actually do the connect from the receiver point-to-point :: - devices.Get (1)->TraceConnectWithoutContext("PhyRxDrop", MakeCallback (&RxDrop)); + devices.Get(1)->TraceConnectWithoutContext("PhyRxDrop", MakeCallback(&RxDrop)); It should now be obvious that we are getting a reference to the receiving ``Node NetDevice`` from its container and connecting the @@ -2008,9 +2008,9 @@ just stop processing events at 20 seconds into the simulation. :: - Simulator::Stop (Seconds(20)); - Simulator::Run (); - Simulator::Destroy (); + Simulator::Stop(Seconds(20)); + Simulator::Run(); + Simulator::Destroy(); return 0; } @@ -2061,7 +2061,7 @@ of all of this work. Let's redirect that output to a file called Now edit up "cwnd.dat" in your favorite editor and remove the ns3 build status and drop lines, leaving only the traced data (you could also comment out the ``TraceConnectWithoutContext("PhyRxDrop", -MakeCallback (&RxDrop));`` in the script to get rid of the drop prints +MakeCallback(&RxDrop));`` in the script to get rid of the drop prints just as easily. You can now run gnuplot (if you have it installed) and tell it to @@ -2119,16 +2119,16 @@ information to a stream representing a file. :: static void - CwndChange (Ptr stream, uint32_t oldCwnd, uint32_t newCwnd) + CwndChange(Ptr stream, uint32_t oldCwnd, uint32_t newCwnd) { - NS_LOG_UNCOND (Simulator::Now ().GetSeconds () << "\t" << newCwnd); - *stream->GetStream () << Simulator::Now ().GetSeconds () << "\t" << oldCwnd << "\t" << newCwnd << std::endl; + NS_LOG_UNCOND(Simulator::Now().GetSeconds() << "\t" << newCwnd); + *stream->GetStream() << Simulator::Now().GetSeconds() << "\t" << oldCwnd << "\t" << newCwnd << std::endl; } static void - RxDrop (Ptr file, Ptr p) + RxDrop(Ptr file, Ptr p) { - NS_LOG_UNCOND ("RxDrop at " << Simulator::Now ().GetSeconds ()); + NS_LOG_UNCOND("RxDrop at " << Simulator::Now().GetSeconds()); file->Write(Simulator::Now(), p); } @@ -2144,12 +2144,11 @@ the |ns3| callback system, which as you may recall, requires objects that obey value semantics. Further notice that we have added the following line in the ``CwndChange`` trace sink implementation:: - *stream->GetStream () << Simulator::Now ().GetSeconds () << "\t" << oldCwnd << "\t" << newCwnd << std::endl; + *stream->GetStream() << Simulator::Now().GetSeconds() << "\t" << oldCwnd << "\t" << newCwnd << std::endl; -This would be very familiar code if you replaced ``*stream->GetStream -()`` with ``std::cout``, as in:: +This would be very familiar code if you replaced ``*stream->GetStream()`` with ``std::cout``, as in:: - std::cout << Simulator::Now ().GetSeconds () << "\t" << oldCwnd << "\t" << newCwnd << std::endl; + std::cout << Simulator::Now().GetSeconds() << "\t" << oldCwnd << "\t" << newCwnd << std::endl; This illustrates that the ``Ptr`` is really just carrying around a ``std::ofstream`` for you, and you can use it here @@ -2168,14 +2167,14 @@ sinks. If you look in the ``main`` function, you will find new code to do just that:: AsciiTraceHelper asciiTraceHelper; - Ptr stream = asciiTraceHelper.CreateFileStream ("sixth.cwnd"); - ns3TcpSocket->TraceConnectWithoutContext ("CongestionWindow", MakeBoundCallback (&CwndChange, stream)); + Ptr stream = asciiTraceHelper.CreateFileStream("sixth.cwnd"); + ns3TcpSocket->TraceConnectWithoutContext("CongestionWindow", MakeBoundCallback(&CwndChange, stream)); ... PcapHelper pcapHelper; - Ptr file = pcapHelper.CreateFile ("sixth.pcap", std::ios::out, PcapHelper::DLT_PPP); - devices.Get (1)->TraceConnectWithoutContext("PhyRxDrop", MakeBoundCallback (&RxDrop, file)); + Ptr file = pcapHelper.CreateFile("sixth.pcap", std::ios::out, PcapHelper::DLT_PPP); + devices.Get(1)->TraceConnectWithoutContext("PhyRxDrop", MakeBoundCallback(&RxDrop, file)); In the first section of the code snippet above, we are creating the ASCII trace file, creating an object responsible for managing it and @@ -2208,7 +2207,7 @@ did with the ``AsciiTraceHelper``. The line of code, :: - Ptr file = pcapHelper.CreateFile ("sixth.pcap", + Ptr file = pcapHelper.CreateFile("sixth.pcap", "w", PcapHelper::DLT_PPP); creates a PCAP file named "sixth.pcap" with file mode "w". This means @@ -2325,32 +2324,32 @@ tools. We did this without modifying any of the core code involved, and we did this in only 18 lines of code:: static void - CwndChange (Ptr stream, uint32_t oldCwnd, uint32_t newCwnd) + CwndChange(Ptr stream, uint32_t oldCwnd, uint32_t newCwnd) { - NS_LOG_UNCOND (Simulator::Now ().GetSeconds () << "\t" << newCwnd); - *stream->GetStream () << Simulator::Now ().GetSeconds () << "\t" << oldCwnd << "\t" << newCwnd << std::endl; + NS_LOG_UNCOND(Simulator::Now().GetSeconds() << "\t" << newCwnd); + *stream->GetStream() << Simulator::Now().GetSeconds() << "\t" << oldCwnd << "\t" << newCwnd << std::endl; } ... AsciiTraceHelper asciiTraceHelper; - Ptr stream = asciiTraceHelper.CreateFileStream ("sixth.cwnd"); - ns3TcpSocket->TraceConnectWithoutContext ("CongestionWindow", MakeBoundCallback (&CwndChange, stream)); + Ptr stream = asciiTraceHelper.CreateFileStream("sixth.cwnd"); + ns3TcpSocket->TraceConnectWithoutContext("CongestionWindow", MakeBoundCallback(&CwndChange, stream)); ... static void - RxDrop (Ptr file, Ptr p) + RxDrop(Ptr file, Ptr p) { - NS_LOG_UNCOND ("RxDrop at " << Simulator::Now ().GetSeconds ()); + NS_LOG_UNCOND("RxDrop at " << Simulator::Now().GetSeconds()); file->Write(Simulator::Now(), p); } ... PcapHelper pcapHelper; - Ptr file = pcapHelper.CreateFile ("sixth.pcap", "w", PcapHelper::DLT_PPP); - devices.Get (1)->TraceConnectWithoutContext("PhyRxDrop", MakeBoundCallback (&RxDrop, file)); + Ptr file = pcapHelper.CreateFile("sixth.pcap", "w", PcapHelper::DLT_PPP); + devices.Get(1)->TraceConnectWithoutContext("PhyRxDrop", MakeBoundCallback(&RxDrop, file)); Trace Helpers ************* @@ -2365,10 +2364,10 @@ Perhaps you will recall seeing some of these variations: :: - pointToPoint.EnablePcapAll ("second"); - pointToPoint.EnablePcap ("second", p2pNodes.Get (0)->GetId (), 0); - csma.EnablePcap ("third", csmaDevices.Get (0), true); - pointToPoint.EnableAsciiAll (ascii.CreateFileStream ("myfirst.tr")); + pointToPoint.EnablePcapAll("second"); + pointToPoint.EnablePcap("second", p2pNodes.Get(0)->GetId(), 0); + csma.EnablePcap("third", csmaDevices.Get(0), true); + pointToPoint.EnableAsciiAll(ascii.CreateFileStream("myfirst.tr")); What may not be obvious, though, is that there is a consistent model for all of the trace-related methods found in the system. We will now @@ -2433,7 +2432,7 @@ class. :: - virtual void EnablePcapInternal (std::string prefix, Ptr nd, bool promiscuous, bool explicitFilename) = 0; + virtual void EnablePcapInternal(std::string prefix, Ptr nd, bool promiscuous, bool explicitFilename) = 0; The signature of this method reflects the device-centric view of the situation at this level. All of the public methods inherited from @@ -2443,7 +2442,7 @@ PCAP method, :: - void EnablePcap (std::string prefix, Ptr nd, bool promiscuous = false, bool explicitFilename = false); + void EnablePcap(std::string prefix, Ptr nd, bool promiscuous = false, bool explicitFilename = false); will call the device implementation of ``EnablePcapInternal`` directly. All other public PCAP tracing methods build on this @@ -2458,12 +2457,12 @@ Methods :: - void EnablePcap (std::string prefix, Ptr nd, bool promiscuous = false, bool explicitFilename = false); - void EnablePcap (std::string prefix, std::string ndName, bool promiscuous = false, bool explicitFilename = false); - void EnablePcap (std::string prefix, NetDeviceContainer d, bool promiscuous = false); - void EnablePcap (std::string prefix, NodeContainer n, bool promiscuous = false); - void EnablePcap (std::string prefix, uint32_t nodeid, uint32_t deviceid, bool promiscuous = false); - void EnablePcapAll (std::string prefix, bool promiscuous = false); + void EnablePcap(std::string prefix, Ptr nd, bool promiscuous = false, bool explicitFilename = false); + void EnablePcap(std::string prefix, std::string ndName, bool promiscuous = false, bool explicitFilename = false); + void EnablePcap(std::string prefix, NetDeviceContainer d, bool promiscuous = false); + void EnablePcap(std::string prefix, NodeContainer n, bool promiscuous = false); + void EnablePcap(std::string prefix, uint32_t nodeid, uint32_t deviceid, bool promiscuous = false); + void EnablePcapAll(std::string prefix, bool promiscuous = false); In each of the methods shown above, there is a default parameter called ``promiscuous`` that defaults to ``false``. This parameter @@ -2476,7 +2475,7 @@ parameter to any of the calls above. For example, Ptr nd; ... - helper.EnablePcap ("prefix", nd, true); + helper.EnablePcap("prefix", nd, true); will enable promiscuous mode captures on the ``NetDevice`` specified by ``nd``. @@ -2497,7 +2496,7 @@ summarize ... Ptr nd; ... - helper.EnablePcap ("prefix", nd); + helper.EnablePcap("prefix", nd); * You can enable PCAP tracing on a particular node/net-device pair by providing a ``std::string`` representing an object name service string @@ -2507,10 +2506,10 @@ summarize ... :: - Names::Add ("server" ...); - Names::Add ("server/eth0" ...); + Names::Add("server" ...); + Names::Add("server/eth0" ...); ... - helper.EnablePcap ("prefix", "server/ath0"); + helper.EnablePcap("prefix", "server/ath0"); * You can enable PCAP tracing on a collection of node/net-device pairs by providing a ``NetDeviceContainer``. For each ``NetDevice`` in the @@ -2523,7 +2522,7 @@ summarize ... NetDeviceContainer d = ...; ... - helper.EnablePcap ("prefix", d); + helper.EnablePcap("prefix", d); * You can enable PCAP tracing on a collection of node/net-device pairs by providing a ``NodeContainer``. For each Node in the @@ -2536,7 +2535,7 @@ summarize ... NodeContainer n; ... - helper.EnablePcap ("prefix", n); + helper.EnablePcap("prefix", n); * You can enable PCAP tracing on the basis of Node ID and device ID as well as with explicit ``Ptr``. Each Node in the system has an @@ -2545,14 +2544,14 @@ summarize ... :: - helper.EnablePcap ("prefix", 21, 1); + helper.EnablePcap("prefix", 21, 1); * Finally, you can enable PCAP tracing for all devices in the system, with the same type as that managed by the device helper. :: - helper.EnablePcapAll ("prefix"); + helper.EnablePcapAll("prefix"); Filenames ######### @@ -2580,8 +2579,8 @@ Finally, two of the methods shown above, :: - void EnablePcap (std::string prefix, Ptr nd, bool promiscuous = false, bool explicitFilename = false); - void EnablePcap (std::string prefix, std::string ndName, bool promiscuous = false, bool explicitFilename = false); + void EnablePcap(std::string prefix, Ptr nd, bool promiscuous = false, bool explicitFilename = false); + void EnablePcap(std::string prefix, std::string ndName, bool promiscuous = false, bool explicitFilename = false); have a default parameter called ``explicitFilename``. When set to true, this parameter disables the automatic filename completion @@ -2595,7 +2594,7 @@ single promiscuous PCAP capture file of a specific name Ptr nd; ... - helper.EnablePcap ("my-pcap-file.pcap", nd, true, true); + helper.EnablePcap("my-pcap-file.pcap", nd, true, true); The first ``true`` parameter enables promiscuous mode traces and the second tells the helper to interpret the ``prefix`` parameter as a @@ -2616,10 +2615,10 @@ inherited from the ASCII trace ``mixin``. :: - virtual void EnableAsciiInternal (Ptr stream, - std::string prefix, - Ptr nd, - bool explicitFilename) = 0; + virtual void EnableAsciiInternal(Ptr stream, + std::string prefix, + Ptr nd, + bool explicitFilename) = 0; The signature of this method reflects the device-centric view of the @@ -2632,8 +2631,8 @@ trace methods, :: - void EnableAscii (std::string prefix, Ptr nd, bool explicitFilename = false); - void EnableAscii (Ptr stream, Ptr nd); + void EnableAscii(std::string prefix, Ptr nd, bool explicitFilename = false); + void EnableAscii(Ptr stream, Ptr nd); will call the device implementation of ``EnableAsciiInternal`` @@ -2650,23 +2649,23 @@ Methods :: - void EnableAscii (std::string prefix, Ptr nd, bool explicitFilename = false); - void EnableAscii (Ptr stream, Ptr nd); + void EnableAscii(std::string prefix, Ptr nd, bool explicitFilename = false); + void EnableAscii(Ptr stream, Ptr nd); - void EnableAscii (std::string prefix, std::string ndName, bool explicitFilename = false); - void EnableAscii (Ptr stream, std::string ndName); + void EnableAscii(std::string prefix, std::string ndName, bool explicitFilename = false); + void EnableAscii(Ptr stream, std::string ndName); - void EnableAscii (std::string prefix, NetDeviceContainer d); - void EnableAscii (Ptr stream, NetDeviceContainer d); + void EnableAscii(std::string prefix, NetDeviceContainer d); + void EnableAscii(Ptr stream, NetDeviceContainer d); - void EnableAscii (std::string prefix, NodeContainer n); - void EnableAscii (Ptr stream, NodeContainer n); + void EnableAscii(std::string prefix, NodeContainer n); + void EnableAscii(Ptr stream, NodeContainer n); - void EnableAsciiAll (std::string prefix); - void EnableAsciiAll (Ptr stream); + void EnableAsciiAll(std::string prefix); + void EnableAsciiAll(Ptr stream); - void EnableAscii (std::string prefix, uint32_t nodeid, uint32_t deviceid, bool explicitFilename); - void EnableAscii (Ptr stream, uint32_t nodeid, uint32_t deviceid); + void EnableAscii(std::string prefix, uint32_t nodeid, uint32_t deviceid, bool explicitFilename); + void EnableAscii(Ptr stream, uint32_t nodeid, uint32_t deviceid); You are encouraged to peruse the API Documentation for class ``AsciiTraceHelperForDevice`` to find the details of these methods; @@ -2690,7 +2689,7 @@ but to summarize ... Ptr nd; ... - helper.EnableAscii ("prefix", nd); + helper.EnableAscii("prefix", nd); * The first four methods also include a default parameter called ``explicitFilename`` that operate similar to equivalent parameters @@ -2710,10 +2709,10 @@ but to summarize ... Ptr nd1; Ptr nd2; ... - Ptr stream = asciiTraceHelper.CreateFileStream ("trace-file-name.tr"); + Ptr stream = asciiTraceHelper.CreateFileStream("trace-file-name.tr"); ... - helper.EnableAscii (stream, nd1); - helper.EnableAscii (stream, nd2); + helper.EnableAscii(stream, nd1); + helper.EnableAscii(stream, nd2); In this case, trace contexts *are* written to the ASCII trace file @@ -2730,13 +2729,13 @@ but to summarize ... :: - Names::Add ("client" ...); - Names::Add ("client/eth0" ...); - Names::Add ("server" ...); - Names::Add ("server/eth0" ...); + Names::Add("client" ...); + Names::Add("client/eth0" ...); + Names::Add("server" ...); + Names::Add("server/eth0" ...); ... - helper.EnableAscii ("prefix", "client/eth0"); - helper.EnableAscii ("prefix", "server/eth0"); + helper.EnableAscii("prefix", "client/eth0"); + helper.EnableAscii("prefix", "server/eth0"); This would result in two files named ``prefix-client-eth0.tr`` and ``prefix-server-eth0.tr`` with traces for each device in the @@ -2744,15 +2743,15 @@ but to summarize ... are overloaded to take a stream wrapper, you can use that form as well:: - Names::Add ("client" ...); - Names::Add ("client/eth0" ...); - Names::Add ("server" ...); - Names::Add ("server/eth0" ...); + Names::Add("client" ...); + Names::Add("client/eth0" ...); + Names::Add("server" ...); + Names::Add("server/eth0" ...); ... - Ptr stream = asciiTraceHelper.CreateFileStream ("trace-file-name.tr"); + Ptr stream = asciiTraceHelper.CreateFileStream("trace-file-name.tr"); ... - helper.EnableAscii (stream, "client/eth0"); - helper.EnableAscii (stream, "server/eth0"); + helper.EnableAscii(stream, "client/eth0"); + helper.EnableAscii(stream, "server/eth0"); This would result in a single trace file called ``trace-file-name.tr`` that contains all of the trace events for @@ -2770,7 +2769,7 @@ but to summarize ... NetDeviceContainer d = ...; ... - helper.EnableAscii ("prefix", d); + helper.EnableAscii("prefix", d); This would result in a number of ASCII trace files being created, each of which follows the ``--.tr`` @@ -2781,9 +2780,9 @@ but to summarize ... NetDeviceContainer d = ...; ... - Ptr stream = asciiTraceHelper.CreateFileStream ("trace-file-name.tr"); + Ptr stream = asciiTraceHelper.CreateFileStream("trace-file-name.tr"); ... - helper.EnableAscii (stream, d); + helper.EnableAscii(stream, d); * You can enable ASCII tracing on a collection of (node, net-device) pairs by providing a ``NodeContainer``. For each Node in the @@ -2796,7 +2795,7 @@ but to summarize ... NodeContainer n; ... - helper.EnableAscii ("prefix", n); + helper.EnableAscii("prefix", n); This would result in a number of ASCII trace files being created, each of which follows the ``--.tr`` @@ -2810,7 +2809,7 @@ but to summarize ... :: - helper.EnableAscii ("prefix", 21, 1); + helper.EnableAscii("prefix", 21, 1); Of course, the traces can be combined into a single file as shown above. @@ -2820,7 +2819,7 @@ but to summarize ... :: - helper.EnableAsciiAll ("prefix"); + helper.EnableAsciiAll("prefix"); This would result in a number of ASCII trace files being created, one for every device in the system of the type managed by the @@ -2886,10 +2885,10 @@ class ``Object``, and methods that share the same signature. :: - virtual void EnablePcapIpv4Internal (std::string prefix, - Ptr ipv4, - uint32_t interface, - bool explicitFilename) = 0; + virtual void EnablePcapIpv4Internal(std::string prefix, + Ptr ipv4, + uint32_t interface, + bool explicitFilename) = 0; The signature of this method reflects the protocol and interface-centric view of the situation at this level. All of the @@ -2899,7 +2898,7 @@ example, the lowest level PCAP method, :: - void EnablePcapIpv4 (std::string prefix, Ptr ipv4, uint32_t interface, bool explicitFilename = false); + void EnablePcapIpv4(std::string prefix, Ptr ipv4, uint32_t interface, bool explicitFilename = false); will call the device implementation of ``EnablePcapIpv4Internal`` @@ -2920,12 +2919,12 @@ protocol and interface constraints. Note that just like in the device version, there are six methods:: - void EnablePcapIpv4 (std::string prefix, Ptr ipv4, uint32_t interface, bool explicitFilename = false); - void EnablePcapIpv4 (std::string prefix, std::string ipv4Name, uint32_t interface, bool explicitFilename = false); - void EnablePcapIpv4 (std::string prefix, Ipv4InterfaceContainer c); - void EnablePcapIpv4 (std::string prefix, NodeContainer n); - void EnablePcapIpv4 (std::string prefix, uint32_t nodeid, uint32_t interface, bool explicitFilename); - void EnablePcapIpv4All (std::string prefix); + void EnablePcapIpv4(std::string prefix, Ptr ipv4, uint32_t interface, bool explicitFilename = false); + void EnablePcapIpv4(std::string prefix, std::string ipv4Name, uint32_t interface, bool explicitFilename = false); + void EnablePcapIpv4(std::string prefix, Ipv4InterfaceContainer c); + void EnablePcapIpv4(std::string prefix, NodeContainer n); + void EnablePcapIpv4(std::string prefix, uint32_t nodeid, uint32_t interface, bool explicitFilename); + void EnablePcapIpv4All(std::string prefix); You are encouraged to peruse the API Documentation for class ``PcapHelperForIpv4`` to find the details of these methods; but to @@ -2937,9 +2936,9 @@ summarize ... :: - Ptr ipv4 = node->GetObject (); + Ptr ipv4 = node->GetObject(); ... - helper.EnablePcapIpv4 ("prefix", ipv4, 0); + helper.EnablePcapIpv4("prefix", ipv4, 0); * You can enable PCAP tracing on a particular node/net-device pair by providing a ``std::string`` representing an object name service string @@ -2948,9 +2947,9 @@ summarize ... :: - Names::Add ("serverIPv4" ...); + Names::Add("serverIPv4" ...); ... - helper.EnablePcapIpv4 ("prefix", "serverIpv4", 1); + helper.EnablePcapIpv4("prefix", "serverIpv4", 1); * You can enable PCAP tracing on a collection of protocol/interface pairs by providing an ``Ipv4InterfaceContainer``. For each ``Ipv4`` / @@ -2963,13 +2962,13 @@ summarize ... NodeContainer nodes; ... - NetDeviceContainer devices = deviceHelper.Install (nodes); + NetDeviceContainer devices = deviceHelper.Install(nodes); ... Ipv4AddressHelper ipv4; - ipv4.SetBase ("10.1.1.0", "255.255.255.0"); - Ipv4InterfaceContainer interfaces = ipv4.Assign (devices); + ipv4.SetBase("10.1.1.0", "255.255.255.0"); + Ipv4InterfaceContainer interfaces = ipv4.Assign(devices); ... - helper.EnablePcapIpv4 ("prefix", interfaces); + helper.EnablePcapIpv4("prefix", interfaces); * You can enable PCAP tracing on a collection of protocol/interface pairs by providing a ``NodeContainer``. For each Node in the @@ -2981,7 +2980,7 @@ summarize ... NodeContainer n; ... - helper.EnablePcapIpv4 ("prefix", n); + helper.EnablePcapIpv4("prefix", n); * You can enable PCAP tracing on the basis of Node ID and interface as well. In this case, the node-id is translated to a ``Ptr`` and @@ -2990,7 +2989,7 @@ summarize ... :: - helper.EnablePcapIpv4 ("prefix", 21, 1); + helper.EnablePcapIpv4("prefix", 21, 1); * Finally, you can enable PCAP tracing for all interfaces in the system, with associated protocol being the same type as that managed @@ -2998,7 +2997,7 @@ summarize ... :: - helper.EnablePcapIpv4All ("prefix"); + helper.EnablePcapIpv4All("prefix"); Filenames ######### @@ -3058,11 +3057,11 @@ method inherited from this class. :: - virtual void EnableAsciiIpv4Internal (Ptr stream, - std::string prefix, - Ptr ipv4, - uint32_t interface, - bool explicitFilename) = 0; + virtual void EnableAsciiIpv4Internal(Ptr stream, + std::string prefix, + Ptr ipv4, + uint32_t interface, + bool explicitFilename) = 0; The signature of this method reflects the protocol- and interface-centric view of the situation at this level; and also the @@ -3074,8 +3073,8 @@ level ASCII trace methods, :: - void EnableAsciiIpv4 (std::string prefix, Ptr ipv4, uint32_t interface, bool explicitFilename = false); - void EnableAsciiIpv4 (Ptr stream, Ptr ipv4, uint32_t interface); + void EnableAsciiIpv4(std::string prefix, Ptr ipv4, uint32_t interface, bool explicitFilename = false); + void EnableAsciiIpv4(Ptr stream, Ptr ipv4, uint32_t interface); will call the device implementation of ``EnableAsciiIpv4Internal`` @@ -3092,23 +3091,23 @@ Methods :: - void EnableAsciiIpv4 (std::string prefix, Ptr ipv4, uint32_t interface, bool explicitFilename = false); - void EnableAsciiIpv4 (Ptr stream, Ptr ipv4, uint32_t interface); + void EnableAsciiIpv4(std::string prefix, Ptr ipv4, uint32_t interface, bool explicitFilename = false); + void EnableAsciiIpv4(Ptr stream, Ptr ipv4, uint32_t interface); - void EnableAsciiIpv4 (std::string prefix, std::string ipv4Name, uint32_t interface, bool explicitFilename = false); - void EnableAsciiIpv4 (Ptr stream, std::string ipv4Name, uint32_t interface); + void EnableAsciiIpv4(std::string prefix, std::string ipv4Name, uint32_t interface, bool explicitFilename = false); + void EnableAsciiIpv4(Ptr stream, std::string ipv4Name, uint32_t interface); - void EnableAsciiIpv4 (std::string prefix, Ipv4InterfaceContainer c); - void EnableAsciiIpv4 (Ptr stream, Ipv4InterfaceContainer c); + void EnableAsciiIpv4(std::string prefix, Ipv4InterfaceContainer c); + void EnableAsciiIpv4(Ptr stream, Ipv4InterfaceContainer c); - void EnableAsciiIpv4 (std::string prefix, NodeContainer n); - void EnableAsciiIpv4 (Ptr stream, NodeContainer n); + void EnableAsciiIpv4(std::string prefix, NodeContainer n); + void EnableAsciiIpv4(Ptr stream, NodeContainer n); - void EnableAsciiIpv4All (std::string prefix); - void EnableAsciiIpv4All (Ptr stream); + void EnableAsciiIpv4All(std::string prefix); + void EnableAsciiIpv4All(Ptr stream); - void EnableAsciiIpv4 (std::string prefix, uint32_t nodeid, uint32_t deviceid, bool explicitFilename); - void EnableAsciiIpv4 (Ptr stream, uint32_t nodeid, uint32_t interface); + void EnableAsciiIpv4(std::string prefix, uint32_t nodeid, uint32_t deviceid, bool explicitFilename); + void EnableAsciiIpv4(Ptr stream, uint32_t nodeid, uint32_t interface); You are encouraged to peruse the API Documentation for class ``PcapAndAsciiHelperForIpv4`` to find the details of these methods; @@ -3132,7 +3131,7 @@ but to summarize ... Ptr ipv4; ... - helper.EnableAsciiIpv4 ("prefix", ipv4, 1); + helper.EnableAsciiIpv4("prefix", ipv4, 1); In this case, no trace contexts are written to the ASCII trace file since they would be redundant. The system will pick the file name to @@ -3144,13 +3143,13 @@ but to summarize ... using an object to refer to a single file. We have already something similar to this in the "cwnd" example above:: - Ptr protocol1 = node1->GetObject (); - Ptr protocol2 = node2->GetObject (); + Ptr protocol1 = node1->GetObject(); + Ptr protocol2 = node2->GetObject(); ... - Ptr stream = asciiTraceHelper.CreateFileStream ("trace-file-name.tr"); + Ptr stream = asciiTraceHelper.CreateFileStream("trace-file-name.tr"); ... - helper.EnableAsciiIpv4 (stream, protocol1, 1); - helper.EnableAsciiIpv4 (stream, protocol2, 1); + helper.EnableAsciiIpv4(stream, protocol1, 1); + helper.EnableAsciiIpv4(stream, protocol2, 1); In this case, trace contexts are written to the ASCII trace file since they are required to disambiguate traces from the two interfaces. @@ -3166,24 +3165,24 @@ but to summarize ... :: - Names::Add ("node1Ipv4" ...); - Names::Add ("node2Ipv4" ...); + Names::Add("node1Ipv4" ...); + Names::Add("node2Ipv4" ...); ... - helper.EnableAsciiIpv4 ("prefix", "node1Ipv4", 1); - helper.EnableAsciiIpv4 ("prefix", "node2Ipv4", 1); + helper.EnableAsciiIpv4("prefix", "node1Ipv4", 1); + helper.EnableAsciiIpv4("prefix", "node2Ipv4", 1); This would result in two files named "prefix-nnode1Ipv4-i1.tr" and "prefix-nnode2Ipv4-i1.tr" with traces for each interface in the respective trace file. Since all of the EnableAscii functions are overloaded to take a stream wrapper, you can use that form as well:: - Names::Add ("node1Ipv4" ...); - Names::Add ("node2Ipv4" ...); + Names::Add("node1Ipv4" ...); + Names::Add("node2Ipv4" ...); ... - Ptr stream = asciiTraceHelper.CreateFileStream ("trace-file-name.tr"); + Ptr stream = asciiTraceHelper.CreateFileStream("trace-file-name.tr"); ... - helper.EnableAsciiIpv4 (stream, "node1Ipv4", 1); - helper.EnableAsciiIpv4 (stream, "node2Ipv4", 1); + helper.EnableAsciiIpv4(stream, "node1Ipv4", 1); + helper.EnableAsciiIpv4(stream, "node2Ipv4", 1); This would result in a single trace file called "trace-file-name.tr" that contains all of the trace events for both interfaces. The events @@ -3200,14 +3199,14 @@ but to summarize ... NodeContainer nodes; ... - NetDeviceContainer devices = deviceHelper.Install (nodes); + NetDeviceContainer devices = deviceHelper.Install(nodes); ... Ipv4AddressHelper ipv4; - ipv4.SetBase ("10.1.1.0", "255.255.255.0"); - Ipv4InterfaceContainer interfaces = ipv4.Assign (devices); + ipv4.SetBase("10.1.1.0", "255.255.255.0"); + Ipv4InterfaceContainer interfaces = ipv4.Assign(devices); ... ... - helper.EnableAsciiIpv4 ("prefix", interfaces); + helper.EnableAsciiIpv4("prefix", interfaces); This would result in a number of ASCII trace files being created, each of which follows the -n-i.tr convention. @@ -3216,15 +3215,15 @@ but to summarize ... NodeContainer nodes; ... - NetDeviceContainer devices = deviceHelper.Install (nodes); + NetDeviceContainer devices = deviceHelper.Install(nodes); ... Ipv4AddressHelper ipv4; - ipv4.SetBase ("10.1.1.0", "255.255.255.0"); - Ipv4InterfaceContainer interfaces = ipv4.Assign (devices); + ipv4.SetBase("10.1.1.0", "255.255.255.0"); + Ipv4InterfaceContainer interfaces = ipv4.Assign(devices); ... - Ptr stream = asciiTraceHelper.CreateFileStream ("trace-file-name.tr"); + Ptr stream = asciiTraceHelper.CreateFileStream("trace-file-name.tr"); ... - helper.EnableAsciiIpv4 (stream, interfaces); + helper.EnableAsciiIpv4(stream, interfaces); * You can enable ASCII tracing on a collection of protocol/interface pairs by providing a ``NodeContainer``. For each Node in the @@ -3236,7 +3235,7 @@ but to summarize ... NodeContainer n; ... - helper.EnableAsciiIpv4 ("prefix", n); + helper.EnableAsciiIpv4("prefix", n); This would result in a number of ASCII trace files being created, each of which follows the --.tr @@ -3250,7 +3249,7 @@ but to summarize ... :: - helper.EnableAsciiIpv4 ("prefix", 21, 1); + helper.EnableAsciiIpv4("prefix", 21, 1); Of course, the traces can be combined into a single file as shown above. @@ -3261,7 +3260,7 @@ but to summarize ... :: - helper.EnableAsciiIpv4All ("prefix"); + helper.EnableAsciiIpv4All("prefix"); This would result in a number of ASCII trace files being created, one for every interface in the system related to a protocol of the type diff --git a/doc/tutorial/source/tweaking.rst b/doc/tutorial/source/tweaking.rst index 84a68390a..f3b0cb6c7 100644 --- a/doc/tutorial/source/tweaking.rst +++ b/doc/tutorial/source/tweaking.rst @@ -350,7 +350,7 @@ Recall that we have defined a logging component in that script: :: - NS_LOG_COMPONENT_DEFINE ("FirstScriptExample"); + NS_LOG_COMPONENT_DEFINE("FirstScriptExample"); You now know that you can enable all of the logging for this component by setting the ``NS_LOG`` environment variable to the various levels. Let's @@ -363,14 +363,14 @@ Open ``scratch/myfirst.cc`` in your favorite editor and add the line, :: - NS_LOG_INFO ("Creating Topology"); + NS_LOG_INFO("Creating Topology"); right before the lines, :: NodeContainer nodes; - nodes.Create (2); + nodes.Create(2); Now build the script using ns3 and clear the ``NS_LOG`` variable to turn off the torrent of logging we previously enabled: @@ -426,12 +426,12 @@ in the following code, :: int - main (int argc, char *argv[]) + main(int argc, char *argv[]) { ... CommandLine cmd; - cmd.Parse (argc, argv); + cmd.Parse(argc, argv); ... } @@ -470,8 +470,8 @@ at the |ns3| ``Attribute`` system while walking through the :: PointToPointHelper pointToPoint; - pointToPoint.SetDeviceAttribute ("DataRate", StringValue ("5Mbps")); - pointToPoint.SetChannelAttribute ("Delay", StringValue ("2ms")); + pointToPoint.SetDeviceAttribute("DataRate", StringValue("5Mbps")); + pointToPoint.SetChannelAttribute("Delay", StringValue("2ms")); and mentioned that ``DataRate`` was actually an ``Attribute`` of the ``PointToPointNetDevice``. Let's use the command line argument parser @@ -507,12 +507,12 @@ any ``set`` operations as in the following example, ... NodeContainer nodes; - nodes.Create (2); + nodes.Create(2); PointToPointHelper pointToPoint; NetDeviceContainer devices; - devices = pointToPoint.Install (nodes); + devices = pointToPoint.Install(nodes); ... @@ -680,13 +680,13 @@ start with the following code, :: int - main (int argc, char *argv[]) + main(int argc, char *argv[]) { uint32_t nPackets = 1; CommandLine cmd; cmd.AddValue("nPackets", "Number of packets to echo", nPackets); - cmd.Parse (argc, argv); + cmd.Parse(argc, argv); ... @@ -696,7 +696,7 @@ instead of the constant ``1`` as is shown below. :: - echoClient.SetAttribute ("MaxPackets", UintegerValue (nPackets)); + echoClient.SetAttribute("MaxPackets", UintegerValue(nPackets)); Now if you run the script and provide the ``--PrintHelp`` argument, you should see your new ``User Argument`` listed in the help display. @@ -778,7 +778,7 @@ from C++ programs could be used: #include ... - int main () + int main() { ... std::cout << "The value of x is " << x << std::endl; @@ -838,12 +838,12 @@ generated by many scripts. Let's just jump right in and add some ASCII tracing output to our ``scratch/myfirst.cc`` script. Right before the call to -``Simulator::Run ()``, add the following lines of code: +``Simulator::Run()``, add the following lines of code: :: AsciiTraceHelper ascii; - pointToPoint.EnableAsciiAll (ascii.CreateFileStream ("myfirst.tr")); + pointToPoint.EnableAsciiAll(ascii.CreateFileStream("myfirst.tr")); Like in many other |ns3| idioms, this code uses a helper object to help create ASCII traces. The second line contains two nested method calls. @@ -998,7 +998,7 @@ The code used to enable pcap tracing is a one-liner. :: - pointToPoint.EnablePcapAll ("myfirst"); + pointToPoint.EnablePcapAll("myfirst"); Go ahead and insert this line of code after the ASCII tracing code we just added to ``scratch/myfirst.cc``. Notice that we only passed the string diff --git a/src/buildings/doc/source/buildings-user.rst b/src/buildings/doc/source/buildings-user.rst index 362a91d0b..5b495f8a9 100644 --- a/src/buildings/doc/source/buildings-user.rst +++ b/src/buildings/doc/source/buildings-user.rst @@ -30,13 +30,13 @@ As an example, let's create a residential 10 x 20 x 10 building:: double y_max = 20.0; double z_min = 0.0; double z_max = 10.0; - Ptr b = CreateObject (); - b->SetBoundaries (Box (x_min, x_max, y_min, y_max, z_min, z_max)); - b->SetBuildingType (Building::Residential); - b->SetExtWallsType (Building::ConcreteWithWindows); - b->SetNFloors (3); - b->SetNRoomsX (3); - b->SetNRoomsY (2); + Ptr b = CreateObject (); + b->SetBoundaries(Box(x_min, x_max, y_min, y_max, z_min, z_max)); + b->SetBuildingType(Building::Residential); + b->SetExtWallsType(Building::ConcreteWithWindows); + b->SetNFloors(3); + b->SetNRoomsX(3); + b->SetNRoomsY(2); This building has three floors and an internal 3 x 2 grid of rooms of equal size. @@ -45,19 +45,19 @@ create a set of buildings with identical characteristics placed on a rectangular grid. Here's an example of how to use it:: Ptr gridBuildingAllocator; - gridBuildingAllocator = CreateObject (); - gridBuildingAllocator->SetAttribute ("GridWidth", UintegerValue (3)); - gridBuildingAllocator->SetAttribute ("LengthX", DoubleValue (7)); - gridBuildingAllocator->SetAttribute ("LengthY", DoubleValue (13)); - gridBuildingAllocator->SetAttribute ("DeltaX", DoubleValue (3)); - gridBuildingAllocator->SetAttribute ("DeltaY", DoubleValue (3)); - gridBuildingAllocator->SetAttribute ("Height", DoubleValue (6)); - gridBuildingAllocator->SetBuildingAttribute ("NRoomsX", UintegerValue (2)); - gridBuildingAllocator->SetBuildingAttribute ("NRoomsY", UintegerValue (4)); - gridBuildingAllocator->SetBuildingAttribute ("NFloors", UintegerValue (2)); - gridBuildingAllocator->SetAttribute ("MinX", DoubleValue (0)); - gridBuildingAllocator->SetAttribute ("MinY", DoubleValue (0)); - gridBuildingAllocator->Create (6); + gridBuildingAllocator = CreateObject(); + gridBuildingAllocator->SetAttribute("GridWidth", UintegerValue(3)); + gridBuildingAllocator->SetAttribute("LengthX", DoubleValue(7)); + gridBuildingAllocator->SetAttribute("LengthY", DoubleValue(13)); + gridBuildingAllocator->SetAttribute("DeltaX", DoubleValue(3)); + gridBuildingAllocator->SetAttribute("DeltaY", DoubleValue(3)); + gridBuildingAllocator->SetAttribute("Height", DoubleValue(6)); + gridBuildingAllocator->SetBuildingAttribute("NRoomsX", UintegerValue(2)); + gridBuildingAllocator->SetBuildingAttribute("NRoomsY", UintegerValue(4)); + gridBuildingAllocator->SetBuildingAttribute("NFloors", UintegerValue(2)); + gridBuildingAllocator->SetAttribute("MinX", DoubleValue(0)); + gridBuildingAllocator->SetAttribute("MinY", DoubleValue(0)); + gridBuildingAllocator->Create(6); This will create a 3x2 grid of 6 buildings, each 7 x 13 x 6 m with 2 x @@ -74,10 +74,10 @@ use them with the buildings model you need an additional call to the information on their position w.r.t. the buildings. Here is an example:: MobilityHelper mobility; - mobility.SetMobilityModel ("ns3::ConstantPositionMobilityModel"); - ueNodes.Create (2); - mobility.Install (ueNodes); - BuildingsHelper::Install (ueNodes); + mobility.SetMobilityModel("ns3::ConstantPositionMobilityModel"); + ueNodes.Create(2); + mobility.Install(ueNodes); + BuildingsHelper::Install(ueNodes); It is to be noted that any mobility model can be used. However, the user is advised to make sure that the behavior of the mobility model @@ -120,18 +120,18 @@ Any legacy ns-3 positioning method can be used to place node in the simulation. The important additional step is to For example, you can place nodes manually like this:: - Ptr mm0 = enbNodes.Get (0)->GetObject (); - Ptr mm1 = enbNodes.Get (1)->GetObject (); - mm0->SetPosition (Vector (5.0, 5.0, 1.5)); - mm1->SetPosition (Vector (30.0, 40.0, 1.5)); + Ptr mm0 = enbNodes.Get(0)->GetObject(); + Ptr mm1 = enbNodes.Get(1)->GetObject(); + mm0->SetPosition(Vector(5.0, 5.0, 1.5)); + mm1->SetPosition(Vector(30.0, 40.0, 1.5)); MobilityHelper mobility; - mobility.SetMobilityModel ("ns3::ConstantPositionMobilityModel"); - ueNodes.Create (2); - mobility.Install (ueNodes); - BuildingsHelper::Install (ueNodes); - mm0->SetPosition (Vector (5.0, 5.0, 1.5)); - mm1->SetPosition (Vector (30.0, 40.0, 1.5)); + mobility.SetMobilityModel("ns3::ConstantPositionMobilityModel"); + ueNodes.Create(2); + mobility.Install(ueNodes); + BuildingsHelper::Install(ueNodes); + mm0->SetPosition(Vector(5.0, 5.0, 1.5)); + mm1->SetPosition(Vector(30.0, 40.0, 1.5)); Alternatively, you could use any existing PositionAllocator class. The coordinates of the node will determine whether it is placed diff --git a/src/click/doc/click.rst b/src/click/doc/click.rst index 3d248b18c..221377b43 100644 --- a/src/click/doc/click.rst +++ b/src/click/doc/click.rst @@ -142,9 +142,9 @@ class in your simulation script. For instance: .. sourcecode:: cpp ClickInternetStackHelper click; - click.SetClickFile (myNodeContainer, "nsclick-simple-lan.click"); - click.SetRoutingTableElement (myNodeContainer, "u/rt"); - click.Install (myNodeContainer); + click.SetClickFile(myNodeContainer, "nsclick-simple-lan.click"); + click.SetRoutingTableElement(myNodeContainer, "u/rt"); + click.Install(myNodeContainer); The example scripts inside ``src/click/examples/`` demonstrate the use of Click based nodes in different scenarios. The helper source can be found inside ``src/click/helper/click-internet-stack-helper.{h,cc}`` diff --git a/src/csma/doc/csma.rst b/src/csma/doc/csma.rst index 647a2c295..13cc3c876 100644 --- a/src/csma/doc/csma.rst +++ b/src/csma/doc/csma.rst @@ -210,24 +210,24 @@ helper. You just ask this helper to create as many computers (we call them ``Nodes``) as you need on your network:: NodeContainer csmaNodes; - csmaNodes.Create (nCsmaNodes); + csmaNodes.Create(nCsmaNodes); Once you have your nodes, you need to instantiate a ``CsmaHelper`` and set any attributes you may want to change.:: CsmaHelper csma; - csma.SetChannelAttribute ("DataRate", StringValue ("100Mbps")); - csma.SetChannelAttribute ("Delay", TimeValue (NanoSeconds (6560))); + csma.SetChannelAttribute("DataRate", StringValue("100Mbps")); + csma.SetChannelAttribute("Delay", TimeValue(NanoSeconds(6560))); - csma.SetDeviceAttribute ("EncapsulationMode", StringValue ("Dix")); - csma.SetDeviceAttribute ("FrameSize", UintegerValue (2000)); + csma.SetDeviceAttribute("EncapsulationMode", StringValue("Dix")); + csma.SetDeviceAttribute("FrameSize", UintegerValue(2000)); Once the attributes are set, all that remains is to create the devices and install them on the required nodes, and to connect the devices together using a CSMA channel. When we create the net devices, we add them to a container to allow you to use them in the future. This all takes just one line of code.:: - NetDeviceContainer csmaDevices = csma.Install (csmaNodes); + NetDeviceContainer csmaDevices = csma.Install(csmaNodes); We recommend thinking carefully about changing these Attributes, since it can result in behavior that surprises users. We allow this because @@ -370,4 +370,3 @@ Although the ns-3 CsmaChannel and CsmaNetDevice does not model any kind of network you could build or buy, it does provide us with some useful functionality. You should, however, understand that it is explicitly not Ethernet or any flavor of IEEE 802.3 but an interesting subset. - diff --git a/src/dsr/doc/dsr.rst b/src/dsr/doc/dsr.rst index 6cd91411b..de1286748 100644 --- a/src/dsr/doc/dsr.rst +++ b/src/dsr/doc/dsr.rst @@ -162,7 +162,7 @@ and DsrMainHelpers in your simulation script. For instance: DsrHelper dsr; DsrMainHelper dsrMain; - dsrMain.Install (dsr, adhocNodes); + dsrMain.Install(dsr, adhocNodes); The example scripts inside ``src/dsr/examples/`` demonstrate the use of DSR based nodes in different scenarios. The helper source can be found inside ``src/dsr/helper/dsr-main-helper.{h,cc}`` diff --git a/src/fd-net-device/doc/dpdk-net-device.rst b/src/fd-net-device/doc/dpdk-net-device.rst index 601d50c20..0384da563 100644 --- a/src/fd-net-device/doc/dpdk-net-device.rst +++ b/src/fd-net-device/doc/dpdk-net-device.rst @@ -271,14 +271,14 @@ Initialization of DPDK driver requires initialization of EAL. EAL requires PMD ( .. sourcecode:: text - DpdkNetDeviceHelper* dpdk = new DpdkNetDeviceHelper (); + DpdkNetDeviceHelper* dpdk = new DpdkNetDeviceHelper(); dpdk->SetPmdLibrary("librte_pmd_e1000.so"); Also, NIC should be bound to DPDK Driver in order to be used with EAL. The default driver used is ``uio_pci_generic`` which supports most of the NICs. You can change it using ``DpdkNetDeviceHelper::SetDpdkDriver``, as follows: .. sourcecode:: text - DpdkNetDeviceHelper* dpdk = new DpdkNetDeviceHelper (); + DpdkNetDeviceHelper* dpdk = new DpdkNetDeviceHelper(); dpdk->SetDpdkDriver("igb_uio"); Attributes diff --git a/src/fd-net-device/doc/fd-net-device.rst b/src/fd-net-device/doc/fd-net-device.rst index d8f27dd71..57c6e139d 100644 --- a/src/fd-net-device/doc/fd-net-device.rst +++ b/src/fd-net-device/doc/fd-net-device.rst @@ -167,12 +167,12 @@ creating and setting the file descriptor by himself. :: FdNetDeviceHelper fd; - NetDeviceContainer devices = fd.Install (nodes); + NetDeviceContainer devices = fd.Install(nodes); // file descriptor generation ... - device->SetFileDescriptor (fd); + device->SetFileDescriptor(fd); Most commonly a FdNetDevice will be used to interact with the host system. @@ -182,8 +182,8 @@ The typical program statements are as follows: :: - GlobalValue::Bind ("SimulatorImplementationType", StringValue ("ns3::RealtimeSimulatorImpl")); - GlobalValue::Bind ("ChecksumEnabled", BooleanValue (true)); + GlobalValue::Bind("SimulatorImplementationType", StringValue("ns3::RealtimeSimulatorImpl")); + GlobalValue::Bind("ChecksumEnabled", BooleanValue(true)); The easiest way to set up an experiment that interacts with a Linux host system is to user the ``Emu`` and ``Tap`` helpers. @@ -285,10 +285,10 @@ identify which physical device should be used to open the raw socket. :: EmuFdNetDeviceHelper emu; - emu.SetDeviceName (deviceName); - NetDeviceContainer devices = emu.Install (node); - Ptr device = devices.Get (0); - device->SetAttribute ("Address", Mac48AddressValue (Mac48Address::Allocate ())); + emu.SetDeviceName(deviceName); + NetDeviceContainer devices = emu.Install(node); + Ptr device = devices.Get(0); + device->SetAttribute("Address", Mac48AddressValue(Mac48Address::Allocate())); TapFdNetDeviceHelper @@ -366,12 +366,12 @@ on the device, and the PI header if needed. For example: :: TapFdNetDeviceHelper helper; - helper.SetDeviceName (deviceName); - helper.SetModePi (modePi); - helper.SetTapIpv4Address (tapIp); - helper.SetTapIpv4Mask (tapMask); + helper.SetDeviceName(deviceName); + helper.SetModePi(modePi); + helper.SetTapIpv4Address(tapIp); + helper.SetTapIpv4Mask(tapMask); ... - helper.Install (node); + helper.Install(node); Attributes @@ -394,7 +394,7 @@ real MAC addresses. Typical code: :: - device->SetAttribute ("Address", Mac48AddressValue (Mac48Address::Allocate ())); + device->SetAttribute("Address", Mac48AddressValue(Mac48Address::Allocate())); Output ====== @@ -404,9 +404,9 @@ types, through the helpers, such as (e.g.): :: EmuFdNetDeviceHelper emu; - NetDeviceContainer devices = emu.Install (node); + NetDeviceContainer devices = emu.Install(node); ... - emu.EnablePcap ("emu-ping", device, true); + emu.EnablePcap("emu-ping", device, true); The standard set of Mac-level NetDevice trace sources is provided. @@ -443,4 +443,3 @@ Several examples are provided: traffic over a real channel. * ``fd-tap-ping.cc``: This example uses the TapFdNetDeviceHelper to send ICMP traffic over a real channel. - diff --git a/src/flow-monitor/doc/flow-monitor.rst b/src/flow-monitor/doc/flow-monitor.rst index f83911257..91a725bee 100644 --- a/src/flow-monitor/doc/flow-monitor.rst +++ b/src/flow-monitor/doc/flow-monitor.rst @@ -125,13 +125,13 @@ The typical use is:: FlowMonitorHelper flowHelper; flowMonitor = flowHelper.InstallAll(); - -yourApplicationsContainer-.Stop (Seconds (stop_time));; - Simulator::Stop (Seconds(stop_time+cleanup_time)); - Simulator::Run (); + -yourApplicationsContainer-.Stop(Seconds(stop_time));; + Simulator::Stop(Seconds(stop_time+cleanup_time)); + Simulator::Run(); flowMonitor->SerializeToXmlFile("NameOfFile.xml", true, true); -the ``SerializeToXmlFile ()`` function 2nd and 3rd parameters are used respectively to +the ``SerializeToXmlFile()`` function 2nd and 3rd parameters are used respectively to activate/deactivate the histograms and the per-probe detailed stats. Other possible alternatives can be found in the Doxygen documentation, while ``cleanup_time`` is the time needed by in-flight packets to reach their destinations. diff --git a/src/internet/doc/internet-stack.rst b/src/internet/doc/internet-stack.rst index 81700ec10..11c43f8b3 100644 --- a/src/internet/doc/internet-stack.rst +++ b/src/internet/doc/internet-stack.rst @@ -20,56 +20,56 @@ by hand, or via a helper function :cpp:func:`InternetStackHelper::Install ()` which does the following to all nodes passed in as arguments:: void - InternetStackHelper::Install (Ptr node) const + InternetStackHelper::Install(Ptr node) const { if (m_ipv4Enabled) { /* IPv4 stack */ - if (node->GetObject () != 0) + if (node->GetObject() != 0) { - NS_FATAL_ERROR ("InternetStackHelper::Install (): Aggregating " - "an InternetStack to a node with an existing Ipv4 object"); + NS_FATAL_ERROR("InternetStackHelper::Install(): Aggregating " + "an InternetStack to a node with an existing Ipv4 object"); return; } - CreateAndAggregateObjectFromTypeId (node, "ns3::ArpL3Protocol"); - CreateAndAggregateObjectFromTypeId (node, "ns3::Ipv4L3Protocol"); - CreateAndAggregateObjectFromTypeId (node, "ns3::Icmpv4L4Protocol"); + CreateAndAggregateObjectFromTypeId(node, "ns3::ArpL3Protocol"); + CreateAndAggregateObjectFromTypeId(node, "ns3::Ipv4L3Protocol"); + CreateAndAggregateObjectFromTypeId(node, "ns3::Icmpv4L4Protocol"); // Set routing - Ptr ipv4 = node->GetObject (); - Ptr ipv4Routing = m_routing->Create (node); - ipv4->SetRoutingProtocol (ipv4Routing); + Ptr ipv4 = node->GetObject(); + Ptr ipv4Routing = m_routing->Create(node); + ipv4->SetRoutingProtocol(ipv4Routing); } if (m_ipv6Enabled) { /* IPv6 stack */ - if (node->GetObject () != 0) + if (node->GetObject() != 0) { - NS_FATAL_ERROR ("InternetStackHelper::Install (): Aggregating " - "an InternetStack to a node with an existing Ipv6 object"); + NS_FATAL_ERROR("InternetStackHelper::Install(): Aggregating " + "an InternetStack to a node with an existing Ipv6 object"); return; } - CreateAndAggregateObjectFromTypeId (node, "ns3::Ipv6L3Protocol"); - CreateAndAggregateObjectFromTypeId (node, "ns3::Icmpv6L4Protocol"); + CreateAndAggregateObjectFromTypeId(node, "ns3::Ipv6L3Protocol"); + CreateAndAggregateObjectFromTypeId(node, "ns3::Icmpv6L4Protocol"); // Set routing - Ptr ipv6 = node->GetObject (); - Ptr ipv6Routing = m_routingv6->Create (node); - ipv6->SetRoutingProtocol (ipv6Routing); + Ptr ipv6 = node->GetObject(); + Ptr ipv6Routing = m_routingv6->Create(node); + ipv6->SetRoutingProtocol(ipv6Routing); /* register IPv6 extensions and options */ - ipv6->RegisterExtensions (); - ipv6->RegisterOptions (); + ipv6->RegisterExtensions(); + ipv6->RegisterOptions(); } if (m_ipv4Enabled || m_ipv6Enabled) { /* UDP and TCP stacks */ - CreateAndAggregateObjectFromTypeId (node, "ns3::UdpL4Protocol"); - node->AggregateObject (m_tcpFactory.Create ()); - Ptr factory = CreateObject (); - node->AggregateObject (factory); + CreateAndAggregateObjectFromTypeId(node, "ns3::UdpL4Protocol"); + node->AggregateObject(m_tcpFactory.Create()); + Ptr factory = CreateObject(); + node->AggregateObject(factory); } } @@ -79,19 +79,19 @@ are added by a factory object (TCP) or by a routing helper (m_routing). Note that the routing protocol is configured and set outside this function. By default, the following protocols are added:: - void InternetStackHelper::Initialize () + void InternetStackHelper::Initialize() { - SetTcp ("ns3::TcpL4Protocol"); + SetTcp("ns3::TcpL4Protocol"); Ipv4StaticRoutingHelper staticRouting; Ipv4GlobalRoutingHelper globalRouting; Ipv4ListRoutingHelper listRouting; Ipv6ListRoutingHelper listRoutingv6; Ipv6StaticRoutingHelper staticRoutingv6; - listRouting.Add (staticRouting, 0); - listRouting.Add (globalRouting, -10); - listRoutingv6.Add (staticRoutingv6, 0); - SetRoutingHelper (listRouting); - SetRoutingHelper (listRoutingv6); + listRouting.Add(staticRouting, 0); + listRouting.Add(globalRouting, -10); + listRoutingv6.Add(staticRoutingv6, 0); + SetRoutingHelper(listRouting); + SetRoutingHelper(listRoutingv6); } By default, IPv4 and IPv6 are enabled. @@ -129,18 +129,18 @@ inserted into the Node's protocol handler when ``AddInterface ()`` is called. The actual registration is done with a statement such as follows:: - RegisterProtocolHandler ( MakeCallback (&Ipv4Protocol::Receive, ipv4), - Ipv4L3Protocol::PROT_NUMBER, 0); + RegisterProtocolHandler( MakeCallback(&Ipv4Protocol::Receive, ipv4), + Ipv4L3Protocol::PROT_NUMBER, 0); The Ipv4L3Protocol object is aggregated to the Node; there is only one such Ipv4L3Protocol object. Higher-layer protocols that have a packet to send down to -the Ipv4L3Protocol object can call ``GetObject ()`` to obtain a +the Ipv4L3Protocol object can call ``GetObject()`` to obtain a pointer, as follows:: - Ptr ipv4 = m_node->GetObject (); + Ptr ipv4 = m_node->GetObject(); if (ipv4 != 0) { - ipv4->Send (packet, saddr, daddr, PROT_NUMBER); + ipv4->Send(packet, saddr, daddr, PROT_NUMBER); } This class nicely demonstrates two techniques we exploit in |ns3| to bind @@ -150,7 +150,7 @@ 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:: void - Ipv4L3Protocol::LocalDeliver (Ptr packet, Ipv4Header const&ip, uint32_t iif) + Ipv4L3Protocol::LocalDeliver(Ptr packet, Ipv4Header const&ip, uint32_t iif) 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. @@ -171,7 +171,7 @@ The ARP cache pending queue is limited (3 datagrams) and IP packets might be fra overfilling the ARP cache queue size. In those cases it is useful to increase the ARP cache pending size to a proper value, e.g.:: - Config::SetDefault ("ns3::ArpCache::PendingQueueSize", UintegerValue (MAX_BURST_SIZE/L2MTU*3)); + Config::SetDefault("ns3::ArpCache::PendingQueueSize", UintegerValue(MAX_BURST_SIZE/L2MTU*3)); The IPv6 implementation follows a similar architecture. Dual-stacked nodes (one with support for both IPv4 and IPv6) will allow an IPv6 socket to receive IPv4 connections @@ -190,47 +190,47 @@ factory. An application that needs a new socket For instance, to create a UDP socket, an application would use a code snippet such as the following:: - Ptr udpSocketFactory = GetNode ()->GetObject (); - Ptr m_socket = socketFactory->CreateSocket (); - m_socket->Bind (m_local_address); + Ptr udpSocketFactory = GetNode()->GetObject(); + Ptr m_socket = socketFactory->CreateSocket(); + m_socket->Bind(m_local_address); ... The above will query the node to get a pointer to its UDP socket factory, will create one such socket, and will use the socket with an API similar to the -C-based sockets API, such as ``Connect ()`` and ``Send ()``. The address passed -to the ``Bind ()``, ``Connect ()``, or ``Send ()`` functions may be a +C-based sockets API, such as ``Connect()`` and ``Send()``. The address passed +to the ``Bind()``, ``Connect()``, or ``Send()`` functions may be a :cpp:class:`Ipv4Address`, :cpp:class:`Ipv6Address`, or :cpp:class:`Address`. If a :cpp:class:`Address` is passed in and contains anything other than a :cpp:class:`Ipv4Address` or :cpp:class:`Ipv6Address`, these functions will -return an error. The ``Bind ()`` and ``Bind6 ()`` functions bind to +return an error. The ``Bind()`` and ``Bind6()`` functions bind to "0.0.0.0" and "::" respectively. The socket can also be bound to a specific NetDevice though the -``BindToNetDevice (Ptr netdevice)`` function. -``BindToNetDevice (Ptr netdevice)`` will bind the socket -to "0.0.0.0" and "::" (equivalent to calling ``Bind ()`` and ``Bind6 ()``, +``BindToNetDevice(Ptr netdevice)`` function. +``BindToNetDevice(Ptr netdevice)`` will bind the socket +to "0.0.0.0" and "::"(equivalent to calling ``Bind()`` and ``Bind6()``, unless the socket has been already bound to a specific address. Summarizing, the correct sequence is:: - Ptr udpSocketFactory = GetNode ()->GetObject (); - Ptr m_socket = socketFactory->CreateSocket (); - m_socket->BindToNetDevice (n_netDevice); + Ptr udpSocketFactory = GetNode()->GetObject(); + Ptr m_socket = socketFactory->CreateSocket(); + m_socket->BindToNetDevice(n_netDevice); ... or:: - Ptr udpSocketFactory = GetNode ()->GetObject (); - Ptr m_socket = socketFactory->CreateSocket (); - m_socket->Bind (m_local_address); - m_socket->BindToNetDevice (n_netDevice); + Ptr udpSocketFactory = GetNode()->GetObject(); + Ptr m_socket = socketFactory->CreateSocket(); + m_socket->Bind(m_local_address); + m_socket->BindToNetDevice(n_netDevice); ... The following raises an error:: - Ptr udpSocketFactory = GetNode ()->GetObject (); - Ptr m_socket = socketFactory->CreateSocket (); - m_socket->BindToNetDevice (n_netDevice); - m_socket->Bind (m_local_address); + Ptr udpSocketFactory = GetNode()->GetObject(); + Ptr m_socket = socketFactory->CreateSocket(); + m_socket->BindToNetDevice(n_netDevice); + m_socket->Bind(m_local_address); ... See the chapter on |ns3| sockets for more information. @@ -243,11 +243,11 @@ to one or more receiving sockets. The key object in this task is class :cpp:class:`Ipv4EndPoint`. This class holds the addressing/port tuple (local port, local address, destination port, destination address) associated with the socket, and a receive callback. This receive callback has a receive function -registered by the socket. The ``Lookup ()`` function to Ipv4EndPointDemux -returns a list of Ipv4EndPoint objects (there may be a list since more than one +registered by the socket. The ``Lookup()`` function to Ipv4EndPointDemux +returns a list of Ipv4EndPoint objects(there may be a list since more than one socket may match the packet). The layer-4 protocol copies the packet to each -Ipv4EndPoint and calls its ``ForwardUp ()`` method, which then calls the -``Receive ()`` function registered by the socket. +Ipv4EndPoint and calls its ``ForwardUp()`` method, which then calls the +``Receive()`` function registered by the socket. An issue that arises when working with the sockets API on real systems is the need to manage the reading from a socket, using @@ -257,14 +257,14 @@ sets a callback to be notified of received data ready to be read, and the callback is invoked by the transport protocol when data is available. This callback is specified as follows:: - void Socket::SetRecvCallback (Callback, - Ptr, - const Address&> receivedData); + void Socket::SetRecvCallback(Callback, + Ptr, + const Address&> receivedData); The data being received is conveyed in the Packet data buffer. An example usage is in class :cpp:class:`PacketSink`:: - m_socket->SetRecvCallback (MakeCallback(&PacketSink::HandleRead, this)); + m_socket->SetRecvCallback(MakeCallback(&PacketSink::HandleRead, this)); To summarize, internally, the UDP implementation is organized as follows: diff --git a/src/internet/doc/ipv4.rst b/src/internet/doc/ipv4.rst index 171fd7d02..1c41af1e4 100644 --- a/src/internet/doc/ipv4.rst +++ b/src/internet/doc/ipv4.rst @@ -40,16 +40,16 @@ This is probably the easiest and most used method. As an example: :: - Ptr n0 = CreateObject (); - Ptr n1 = CreateObject (); - NodeContainer net (n0, n1); + Ptr n0 = CreateObject(); + Ptr n1 = CreateObject(); + NodeContainer net(n0, n1); CsmaHelper csma; - NetDeviceContainer ndc = csma.Install (net); + NetDeviceContainer ndc = csma.Install(net); - NS_LOG_INFO ("Assign IPv4 Addresses."); + NS_LOG_INFO("Assign IPv4 Addresses."); Ipv4AddressHelper ipv4; - ipv4.SetBase (Ipv4Address ("192.168.1.0"), NetMask ("/24")); - Ipv4InterfaceContainer ic = ipv4.Assign (ndc); + ipv4.SetBase(Ipv4Address("192.168.1.0"), NetMask("/24")); + Ipv4InterfaceContainer ic = ipv4.Assign(ndc); This method will add two global IPv4 addresses to the nodes. @@ -64,20 +64,20 @@ Alternatively, it is possible to assign a specific address to a node: :: - Ptr n0 = CreateObject (); - NodeContainer net (n0); + Ptr n0 = CreateObject(); + NodeContainer net(n0); CsmaHelper csma; - NetDeviceContainer ndc = csma.Install (net); + NetDeviceContainer ndc = csma.Install(net); - NS_LOG_INFO ("Specifically Assign an IPv4 Address."); + NS_LOG_INFO("Specifically Assign an IPv4 Address."); Ipv4AddressHelper ipv4; - Ptr device = ndc.Get (0); - Ptr node = device->GetNode (); - Ptr ipv4proto = node->GetObject (); + Ptr device = ndc.Get(0); + Ptr node = device->GetNode(); + Ptr ipv4proto = node->GetObject(); int32_t ifIndex = 0; - ifIndex = ipv4proto->GetInterfaceForDevice (device); - Ipv4InterfaceAddress ipv4Addr = Ipv4InterfaceAddress (Ipv4Address ("192.168.1.42"), NetMask ("/24")); - ipv4proto->AddAddress (ifIndex, ipv4Addr); + ifIndex = ipv4proto->GetInterfaceForDevice(device); + Ipv4InterfaceAddress ipv4Addr = Ipv4InterfaceAddress(Ipv4Address("192.168.1.42"), NetMask("/24")); + ipv4proto->AddAddress(ifIndex, ipv4Addr); DHCP assigned IPv4 addresses @@ -264,25 +264,25 @@ The typical usages are:: .. code-block:: c++ NeighborCacheHelper neighborCache; - neighborCache.PopulateNeighborCache (); + neighborCache.PopulateNeighborCache(); * Populate neighbor ARP caches for a given channel: .. code-block:: c++ NeighborCacheHelper neighborCache; - neighborCache.PopulateNeighborCache (channel); // channel is the Ptr want to generate ARP caches + neighborCache.PopulateNeighborCache(channel); // channel is the Ptr want to generate ARP caches * Populate neighbor ARP caches for devices in a given NetDeviceContainer: .. code-block:: c++ NeighborCacheHelper neighborCache; - neighborCache.PopulateNeighborCache (netDevices); // netDevices is the NetDeviceContainer want to generate ARP caches + neighborCache.PopulateNeighborCache(netDevices); // netDevices is the NetDeviceContainer want to generate ARP caches * Populate neighbor ARP caches for a given Ipv4InterfaceContainer: .. code-block:: c++ NeighborCacheHelper neighborCache; - neighborCache.PopulateNeighborCache (interfaces); // interfaces is the Ipv4InterfaceContainer want to generate ARP caches + neighborCache.PopulateNeighborCache(interfaces); // interfaces is the Ipv4InterfaceContainer want to generate ARP caches diff --git a/src/internet/doc/ipv6.rst b/src/internet/doc/ipv6.rst index 8dc72e154..b83e471ef 100644 --- a/src/internet/doc/ipv6.rst +++ b/src/internet/doc/ipv6.rst @@ -98,18 +98,18 @@ only IPv6 and node 2 only IPv4: :: NodeContainer n; - n.Create (3); + n.Create(3); InternetStackHelper internet; InternetStackHelper internetV4only; InternetStackHelper internetV6only; - internetV4only.SetIpv6StackInstall (false); - internetV6only.SetIpv4StackInstall (false); + internetV4only.SetIpv6StackInstall(false); + internetV6only.SetIpv4StackInstall(false); - internet.Install (n.Get (0)); - internetV6only.Install (n.Get (1)); - internetV4only.Install (n.Get (2)); + internet.Install(n.Get(0)); + internetV6only.Install(n.Get(1)); + internetV4only.Install(n.Get(2)); @@ -142,16 +142,16 @@ This is probably the easiest and most used method. As an example: :: - Ptr n0 = CreateObject (); - Ptr n1 = CreateObject (); - NodeContainer net (n0, n1); + Ptr n0 = CreateObject(); + Ptr n1 = CreateObject(); + NodeContainer net(n0, n1); CsmaHelper csma; - NetDeviceContainer ndc = csma.Install (net); + NetDeviceContainer ndc = csma.Install(net); - NS_LOG_INFO ("Assign IPv6 Addresses."); + NS_LOG_INFO("Assign IPv6 Addresses."); Ipv6AddressHelper ipv6; - ipv6.SetBase (Ipv6Address ("2001:db8::"), Ipv6Prefix (64)); - Ipv6InterfaceContainer ic = ipv6.Assign (ndc); + ipv6.SetBase(Ipv6Address("2001:db8::"), Ipv6Prefix(64)); + Ipv6InterfaceContainer ic = ipv6.Assign(ndc); This method will add two global IPv6 addresses to the nodes. Note that, as usual for IPv6, all the nodes will also have a link-local address. Typically the first address on an @@ -168,20 +168,20 @@ Alternatively, it is possible to assign a specific address to a node: :: - Ptr n0 = CreateObject (); - NodeContainer net (n0); + Ptr n0 = CreateObject(); + NodeContainer net(n0); CsmaHelper csma; - NetDeviceContainer ndc = csma.Install (net); + NetDeviceContainer ndc = csma.Install(net); - NS_LOG_INFO ("Specifically Assign an IPv6 Address."); + NS_LOG_INFO("Specifically Assign an IPv6 Address."); Ipv6AddressHelper ipv6; - Ptr device = ndc.Get (0); - Ptr node = device->GetNode (); - Ptr ipv6proto = node->GetObject (); + Ptr device = ndc.Get(0); + Ptr node = device->GetNode(); + Ptr ipv6proto = node->GetObject(); int32_t ifIndex = 0; - ifIndex = ipv6proto->GetInterfaceForDevice (device); - Ipv6InterfaceAddress ipv6Addr = Ipv6InterfaceAddress (Ipv6Address ("2001:db8:f00d:cafe::42"), Ipv6Prefix (64)); - ipv6proto->AddAddress (ifIndex, ipv6Addr); + ifIndex = ipv6proto->GetInterfaceForDevice(device); + Ipv6InterfaceAddress ipv6Addr = Ipv6InterfaceAddress(Ipv6Address("2001:db8:f00d:cafe::42"), Ipv6Prefix(64)); + ipv6proto->AddAddress(ifIndex, ipv6Addr); Auto-generated IPv6 addresses @@ -213,8 +213,8 @@ This is accomplished using :cpp:class:`Ipv6AddressHelper::AssignWithoutAddress`, Ipv6AddressHelper ipv6; NetDeviceContainer tmp; - tmp.Add (d1.Get (0)); /* n0 */ - Ipv6InterfaceContainer iic1 = ipv6.AssignWithoutAddress (tmp); /* n0 interface */ + tmp.Add (d1.Get(0)); /* n0 */ + Ipv6InterfaceContainer iic1 = ipv6.AssignWithoutAddress(tmp); /* n0 interface */ Random-generated IPv6 addresses @@ -341,28 +341,28 @@ The use is almost identical to the corresponding IPv4 case, e.g.: :: NodeContainer n; - n.Create (4); + n.Create(4); - NS_LOG_INFO ("Create IPv6 Internet Stack"); + NS_LOG_INFO("Create IPv6 Internet Stack"); InternetStackHelper internetv6; - internetv6.Install (n); + internetv6.Install(n); - NS_LOG_INFO ("Create channels."); + NS_LOG_INFO("Create channels."); CsmaHelper csma; - NetDeviceContainer d = csma.Install (n); + NetDeviceContainer d = csma.Install(n); - NS_LOG_INFO ("Create networks and assign IPv6 Addresses."); + NS_LOG_INFO("Create networks and assign IPv6 Addresses."); Ipv6AddressHelper ipv6; - ipv6.SetBase (Ipv6Address ("2001:db8::"), Ipv6Prefix (64)); - Ipv6InterfaceContainer iic = ipv6.Assign (d); + ipv6.SetBase(Ipv6Address("2001:db8::"), Ipv6Prefix(64)); + Ipv6InterfaceContainer iic = ipv6.Assign(d); Additionally, a common task is to enable forwarding on one of the nodes and to setup a default route toward it in the other nodes, e.g.: :: - iic.SetForwarding (0, true); - iic.SetDefaultRouteInAllNodes (0); + iic.SetForwarding(0, true); + iic.SetDefaultRouteInAllNodes(0); This will enable forwarding on the node *0* and will setup a default route in :cpp:class:`ns3::Ipv6StaticRouting` on all the other nodes. Note that this @@ -522,4 +522,4 @@ The usages for generating NDISC cache is almost the same as generating ARP cache .. code-block:: c++ NeighborCacheHelper neighborCache; - neighborCache.PopulateNeighborCache (interfaces); // interfaces is the Ipv6InterfaceContainer want to generate ARP caches + neighborCache.PopulateNeighborCache(interfaces); // interfaces is the Ipv6InterfaceContainer want to generate ARP caches diff --git a/src/internet/doc/routing-overview.rst b/src/internet/doc/routing-overview.rst index abff3b31c..967379156 100644 --- a/src/internet/doc/routing-overview.rst +++ b/src/internet/doc/routing-overview.rst @@ -130,11 +130,11 @@ Ipv[4,6]ListRouting::AddRoutingProtocol Classes Ipv4ListRouting and Ipv6ListRouting provides a pure virtual function declaration for the method that allows one to add a routing protocol:: - void AddRoutingProtocol (Ptr routingProtocol, - int16_t priority); + void AddRoutingProtocol(Ptr routingProtocol, + int16_t priority); - void AddRoutingProtocol (Ptr routingProtocol, - int16_t priority); + void AddRoutingProtocol(Ptr routingProtocol, + int16_t priority); These methods are implemented respectively by class Ipv4ListRoutingImpl and by class Ipv6ListRoutingImpl in the internet module. @@ -148,8 +148,8 @@ in decreasing order of priority to see whether a match is found. Therefore, if you want your Ipv4RoutingProtocol to have priority lower than the static routing, insert it with priority less than 0; e.g.:: - Ptr myRoutingProto = CreateObject (); - listRoutingPtr->AddRoutingProtocol (myRoutingProto, -10); + Ptr myRoutingProto = CreateObject(); + listRoutingPtr->AddRoutingProtocol(myRoutingProto, -10); Upon calls to RouteOutput() or RouteInput(), the list routing object will search the list of routing protocols, in priority order, until a route is found. Such @@ -195,7 +195,7 @@ 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:: - Ipv4GlobalRoutingHelper::PopulateRoutingTables (); + Ipv4GlobalRoutingHelper::PopulateRoutingTables(); *Note:* A reminder that the wifi NetDevice will work but does not take any wireless effects into account. For wireless, we recommend OLSR dynamic routing @@ -204,7 +204,7 @@ described below. It is possible to call this function again in the midst of a simulation using the following additional public function:: - Ipv4GlobalRoutingHelper::RecomputeRoutingTables (); + Ipv4GlobalRoutingHelper::RecomputeRoutingTables(); which flushes the old tables, queries the nodes for new interface information, and rebuilds the routes. @@ -212,8 +212,8 @@ and rebuilds the routes. For instance, this scheduling call will cause the tables to be rebuilt at time 5 seconds:: - Simulator::Schedule (Seconds (5), - &Ipv4GlobalRoutingHelper::RecomputeRoutingTables); + Simulator::Schedule(Seconds(5), + &Ipv4GlobalRoutingHelper::RecomputeRoutingTables); There are two attributes that govern the behavior. The first is @@ -273,11 +273,11 @@ The GlobalRouteManager first walks the list of nodes and aggregates a GlobalRouter interface to each one as follows:: typedef std::vector < Ptr >::iterator Iterator; - for (Iterator i = NodeList::Begin (); i != NodeList::End (); i++) + for (Iterator i = NodeList::Begin(); i != NodeList::End(); i++) { Ptr node = *i; - Ptr globalRouter = CreateObject (node); - node->AggregateObject (globalRouter); + Ptr globalRouter = CreateObject(node); + node->AggregateObject(globalRouter); } This interface is later queried and used to generate a Link State @@ -429,10 +429,10 @@ The following function is used to add a static multicast route to a node:: void - Ipv4StaticRouting::AddMulticastRoute (Ipv4Address origin, - Ipv4Address group, - uint32_t inputInterface, - std::vector outputInterfaces); + Ipv4StaticRouting::AddMulticastRoute(Ipv4Address origin, + Ipv4Address group, + uint32_t inputInterface, + std::vector outputInterfaces); A multicast route must specify an origin IP address, a multicast group and an input network interface index as conditions and provide a vector of output @@ -452,7 +452,7 @@ through `Ipv4StaticRouting::AddHostRouteTo`. Another command sets the default multicast route:: void - Ipv4StaticRouting::SetDefaultMulticastRoute (uint32_t outputInterface); + Ipv4StaticRouting::SetDefaultMulticastRoute(uint32_t outputInterface); This is the multicast equivalent of the unicast version SetDefaultRoute. We tell the routing system what to do in the case where a specific route to a @@ -472,14 +472,14 @@ found. Finally, a number of additional functions are provided to fetch and remove multicast routes:: - uint32_t GetNMulticastRoutes () const; + uint32_t GetNMulticastRoutes() const; - Ipv4MulticastRoute *GetMulticastRoute (uint32_t i) const; + Ipv4MulticastRoute *GetMulticastRoute(uint32_t i) const; - Ipv4MulticastRoute *GetDefaultMulticastRoute () const; + Ipv4MulticastRoute *GetDefaultMulticastRoute() const; - bool RemoveMulticastRoute (Ipv4Address origin, - Ipv4Address group, - uint32_t inputInterface); + bool RemoveMulticastRoute(Ipv4Address origin, + Ipv4Address group, + uint32_t inputInterface); - void RemoveMulticastRoute (uint32_t index); + void RemoveMulticastRoute(uint32_t index); diff --git a/src/internet/doc/tcp.rst b/src/internet/doc/tcp.rst index 3f0b8f0e8..eb1ea8533 100644 --- a/src/internet/doc/tcp.rst +++ b/src/internet/doc/tcp.rst @@ -117,17 +117,17 @@ Using the helper functions defined in ``src/applications/helper`` and // Create a packet sink on the star "hub" to receive these packets uint16_t port = 50000; - Address sinkLocalAddress(InetSocketAddress (Ipv4Address::GetAny (), port)); - PacketSinkHelper sinkHelper ("ns3::TcpSocketFactory", sinkLocalAddress); - ApplicationContainer sinkApp = sinkHelper.Install (serverNode); - sinkApp.Start (Seconds (1.0)); - sinkApp.Stop (Seconds (10.0)); + Address sinkLocalAddress(InetSocketAddress(Ipv4Address::GetAny(), port)); + PacketSinkHelper sinkHelper("ns3::TcpSocketFactory", sinkLocalAddress); + ApplicationContainer sinkApp = sinkHelper.Install(serverNode); + sinkApp.Start(Seconds(1.0)); + sinkApp.Stop(Seconds(10.0)); Similarly, the below snippet configures OnOffApplication traffic source to use TCP:: // Create the OnOff applications to send TCP to the server - OnOffHelper clientHelper ("ns3::TcpSocketFactory", Address ()); + OnOffHelper clientHelper("ns3::TcpSocketFactory", Address()); The careful reader will note above that we have specified the TypeId of an abstract base class :cpp:class:`TcpSocketFactory`. How does the script tell @@ -147,7 +147,7 @@ To set the default socket type before any internet stack-related objects are created, one may put the following statement at the top of the simulation program:: - Config::SetDefault ("ns3::TcpL4Protocol::SocketType", StringValue ("ns3::TcpNewReno")); + Config::SetDefault("ns3::TcpL4Protocol::SocketType", StringValue("ns3::TcpNewReno")); For users who wish to have a pointer to the actual socket (so that socket operations like Bind(), setting socket options, etc. can be @@ -161,10 +161,10 @@ the Node container "n0n1" is accessed to get the zeroth element, and a socket is created on this node:: // Create and bind the socket... - TypeId tid = TypeId::LookupByName ("ns3::TcpNewReno"); - Config::Set ("/NodeList/*/$ns3::TcpL4Protocol/SocketType", TypeIdValue (tid)); + TypeId tid = TypeId::LookupByName("ns3::TcpNewReno"); + Config::Set("/NodeList/*/$ns3::TcpL4Protocol/SocketType", TypeIdValue(tid)); Ptr localSocket = - Socket::CreateSocket (n0n1.Get (0), TcpSocketFactory::GetTypeId ()); + Socket::CreateSocket(n0n1.Get(0), TcpSocketFactory::GetTypeId()); Above, the "*" wild card for node number is passed to the attribute configuration system, so that all future sockets on all nodes are set to @@ -172,13 +172,13 @@ NewReno, not just on node 'n0n1.Get (0)'. If one wants to limit it to just the specified node, one would have to do something like:: // Create and bind the socket... - TypeId tid = TypeId::LookupByName ("ns3::TcpNewReno"); + TypeId tid = TypeId::LookupByName("ns3::TcpNewReno"); std::stringstream nodeId; - nodeId << n0n1.Get (0)->GetId (); - std::string specificNode = "/NodeList/" + nodeId.str () + "/$ns3::TcpL4Protocol/SocketType"; - Config::Set (specificNode, TypeIdValue (tid)); + nodeId << n0n1.Get(0)->GetId(); + std::string specificNode = "/NodeList/" + nodeId.str() + "/$ns3::TcpL4Protocol/SocketType"; + Config::Set(specificNode, TypeIdValue(tid)); Ptr localSocket = - Socket::CreateSocket (n0n1.Get (0), TcpSocketFactory::GetTypeId ()); + Socket::CreateSocket(n0n1.Get(0), TcpSocketFactory::GetTypeId()); Once a TCP socket is created, one will want to follow conventional socket logic and either connect() and send() (for a TCP client) or bind(), listen(), and @@ -458,29 +458,31 @@ by (1/cwnd) with a rounding off due to type casting into int. :: + :label: linuxrenocongavoid + if (m_cWndCnt >= w) { uint32_t delta = m_cWndCnt / w; m_cWndCnt -= delta * w; tcb->m_cWnd += delta * tcb->m_segmentSize; - NS_LOG_DEBUG ("Subtracting delta * w from m_cWndCnt " << delta * w); + NS_LOG_DEBUG("Subtracting delta * w from m_cWndCnt " << delta * w); } - :label: linuxrenocongavoid :: + :label: newrenocongavoid + if (segmentsAcked > 0) { - double adder = static_cast (tcb->m_segmentSize * tcb->m_segmentSize) / tcb->m_cWnd.Get (); - adder = std::max (1.0, adder); - tcb->m_cWnd += static_cast (adder); - NS_LOG_INFO ("In CongAvoid, updated to cwnd " << tcb->m_cWnd << + double adder = static_cast(tcb->m_segmentSize * tcb->m_segmentSize) / tcb->m_cWnd.Get(); + adder = std::max(1.0, adder); + tcb->m_cWnd += static_cast(adder); + NS_LOG_INFO("In CongAvoid, updated to cwnd " << tcb->m_cWnd << " ssthresh " << tcb->m_ssThresh); } - :label: newrenocongavoid So, there are two main difference between the TCP Linux Reno and TCP NewReno in ns-3: @@ -525,7 +527,7 @@ event, the slow start threshold is decreased by a value that depends on the size of the slow start threshold itself. Then, the congestion window is set to such value. -.. math:: cWnd = (1-b(cWnd)) \cdot cWnd +.. math:: cWnd = (1 - b(cWnd)) \cdot cWnd :label: highspeedcwnddecrement The lookup table for the function b() is taken from the same RFC. @@ -842,9 +844,9 @@ As a first approximation, the LEDBAT sender operates as shown below: On receipt of an ACK:: currentdelay = acknowledgement.delay - basedelay = min (basedelay, currentdelay) + basedelay = min(basedelay, currentdelay) queuingdelay = currentdelay - basedelay - offtarget = (TARGET - queuingdelay) / TARGET + offtarget =(TARGET - queuingdelay) / TARGET cWnd += GAIN * offtarget * bytesnewlyacked * MSS / cWnd ``TARGET`` is the maximum queueing delay that LEDBAT itself may introduce in the @@ -863,11 +865,11 @@ Following the recommendation of RFC 6817, the default values of the parameters a To enable LEDBAT on all TCP sockets, the following configuration can be used:: - Config::SetDefault ("ns3::TcpL4Protocol::SocketType", TypeIdValue (TcpLedbat::GetTypeId ())); + Config::SetDefault("ns3::TcpL4Protocol::SocketType", TypeIdValue(TcpLedbat::GetTypeId())); To enable LEDBAT on a chosen TCP socket, the following configuration can be used:: - Config::Set ("$ns3::NodeListPriv/NodeList/1/$ns3::TcpL4Protocol/SocketType", TypeIdValue (TcpLedbat::GetTypeId ())); + Config::Set("$ns3::NodeListPriv/NodeList/1/$ns3::TcpL4Protocol/SocketType", TypeIdValue(TcpLedbat::GetTypeId())); The following unit tests have been written to validate the implementation of LEDBAT: @@ -971,7 +973,7 @@ Following the recommendation of RFC 8257, the default values of the parameters a To enable DCTCP on all TCP sockets, the following configuration can be used:: - Config::SetDefault ("ns3::TcpL4Protocol::SocketType", TypeIdValue (TcpDctcp::GetTypeId ())); + Config::SetDefault("ns3::TcpL4Protocol::SocketType", TypeIdValue(TcpDctcp::GetTypeId())); To enable DCTCP on a selected node, one can set the "SocketType" attribute on the TcpL4Protocol object of that node to the TcpDctcp TypeId. @@ -986,17 +988,17 @@ configuration to achieve the behavior of desired queue management algorithm. To configure RED router for DCTCP:: - Config::SetDefault ("ns3::RedQueueDisc::UseEcn", BooleanValue (true)); - Config::SetDefault ("ns3::RedQueueDisc::QW", DoubleValue (1.0)); - Config::SetDefault ("ns3::RedQueueDisc::MinTh", DoubleValue (16)); - Config::SetDefault ("ns3::RedQueueDisc::MaxTh", DoubleValue (16)); + Config::SetDefault("ns3::RedQueueDisc::UseEcn", BooleanValue(true)); + Config::SetDefault("ns3::RedQueueDisc::QW", DoubleValue(1.0)); + Config::SetDefault("ns3::RedQueueDisc::MinTh", DoubleValue(16)); + Config::SetDefault("ns3::RedQueueDisc::MaxTh", DoubleValue(16)); There is also the option, when running CoDel or FqCoDel, to enable ECN on the queue and to set the "CeThreshold" value to a low value such as 1ms. The following example uses CoDel:: - Config::SetDefault ("ns3::CoDelQueueDisc::UseEcn", BooleanValue (true)); - Config::SetDefault ("ns3::CoDelQueueDisc::CeThreshold", TimeValue (MilliSeconds (1))); + Config::SetDefault("ns3::CoDelQueueDisc::UseEcn", BooleanValue(true)); + Config::SetDefault("ns3::CoDelQueueDisc::CeThreshold", TimeValue(MilliSeconds(1))); The following unit tests have been written to validate the implementation of DCTCP: @@ -1054,9 +1056,9 @@ The following is a high level overview of BBR congestion control algorithm: On receiving an ACK:: rtt = now - packet.sent_time - update_minimum_rtt (rtt) - delivery_rate = estimate_delivery_rate (packet) - update_maximum_bandwidth (delivery_rate) + update_minimum_rtt(rtt) + delivery_rate = estimate_delivery_rate(packet) + update_maximum_bandwidth(delivery_rate) After transmitting a data packet:: @@ -1065,21 +1067,21 @@ After transmitting a data packet:: return if (now > nextSendTime) { - transmit (packet) - nextSendTime = now + packet.size / (pacing_gain * max_bandwidth) + transmit(packet) + nextSendTime = now + packet.size /(pacing_gain * max_bandwidth) } else return - Schedule (nextSendTime, Send) + Schedule(nextSendTime, Send) To enable BBR on all TCP sockets, the following configuration can be used:: - Config::SetDefault ("ns3::TcpL4Protocol::SocketType", TypeIdValue (TcpBbr::GetTypeId ())); + Config::SetDefault("ns3::TcpL4Protocol::SocketType", TypeIdValue(TcpBbr::GetTypeId())); To enable BBR on a chosen TCP socket, the following configuration can be used (note that an appropriate Node ID must be used instead of 1):: - Config::Set ("$ns3::NodeListPriv/NodeList/1/$ns3::TcpL4Protocol/SocketType", TypeIdValue (TcpBbr::GetTypeId ())); + Config::Set("$ns3::NodeListPriv/NodeList/1/$ns3::TcpL4Protocol/SocketType", TypeIdValue(TcpBbr::GetTypeId())); The ns-3 implementation of BBR is based on its Linux implementation. Linux 5.4 kernel implementation has been used to validate the behavior of ns-3 @@ -1167,11 +1169,9 @@ Linux: https://www.kernel.org/doc/Documentation/networking/ip-sysctl.txt AcceptOnly = 2, //!< Enable only when the peer endpoint is ECN capable } UseEcn_t; -For example: +For example:: -:: - - Config::SetDefault ("ns3::TcpSocketBase::UseEcn", StringValue ("On")) + Config::SetDefault("ns3::TcpSocketBase::UseEcn", StringValue("On")) ECN negotiation ^^^^^^^^^^^^^^^ @@ -1184,11 +1184,11 @@ ECN capability is negotiated during the three-way TCP handshake: if (m_useEcn == UseEcn_t::On) { - SendEmptyPacket (TcpHeader::SYN | TcpHeader::ECE | TcpHeader::CWR); + SendEmptyPacket(TcpHeader::SYN | TcpHeader::ECE | TcpHeader::CWR); } else { - SendEmptyPacket (TcpHeader::SYN); + SendEmptyPacket(TcpHeader::SYN); } m_ecnState = ECN_DISABLED; @@ -1196,14 +1196,14 @@ ECN capability is negotiated during the three-way TCP handshake: :: - if (m_useEcn != UseEcn_t::Off && (tcpHeader.GetFlags () & (TcpHeader::CWR | TcpHeader::ECE)) == (TcpHeader::CWR | TcpHeader::ECE)) + if (m_useEcn != UseEcn_t::Off &&(tcpHeader.GetFlags() &(TcpHeader::CWR | TcpHeader::ECE)) == (TcpHeader::CWR | TcpHeader::ECE)) { - SendEmptyPacket (TcpHeader::SYN | TcpHeader::ACK |TcpHeader::ECE); + SendEmptyPacket(TcpHeader::SYN | TcpHeader::ACK |TcpHeader::ECE); m_ecnState = ECN_IDLE; } else { - SendEmptyPacket (TcpHeader::SYN | TcpHeader::ACK); + SendEmptyPacket(TcpHeader::SYN | TcpHeader::ACK); m_ecnState = ECN_DISABLED; } @@ -1211,7 +1211,7 @@ ECN capability is negotiated during the three-way TCP handshake: :: - if (m_useEcn != UseEcn_t::Off && (tcpHeader.GetFlags () & (TcpHeader::CWR | TcpHeader::ECE)) == (TcpHeader::ECE)) + if (m_useEcn != UseEcn_t::Off && (tcpHeader.GetFlags() &(TcpHeader::CWR | TcpHeader::ECE)) == (TcpHeader::ECE)) { m_ecnState = ECN_IDLE; } @@ -1541,12 +1541,12 @@ Linux, and the following operations are defined: :: - virtual std::string GetName () const; - virtual uint32_t GetSsThresh (Ptr tcb, uint32_t bytesInFlight); - virtual void IncreaseWindow (Ptr tcb, uint32_t segmentsAcked); - virtual void PktsAcked (Ptr tcb, uint32_t segmentsAcked,const Time& rtt); - virtual Ptr Fork (); - virtual void CwndEvent (Ptr tcb, const TcpSocketState::TcpCaEvent_t event); + virtual std::string GetName() const; + virtual uint32_t GetSsThresh(Ptr tcb, uint32_t bytesInFlight); + virtual void IncreaseWindow(Ptr tcb, uint32_t segmentsAcked); + virtual void PktsAcked(Ptr tcb, uint32_t segmentsAcked,const Time& rtt); + virtual Ptr Fork(); + virtual void CwndEvent(Ptr tcb, const TcpSocketState::TcpCaEvent_t event); The most interesting methods to write are GetSsThresh and IncreaseWindow. The latter is called when TcpSocketBase decides that it is time to increase @@ -1665,16 +1665,16 @@ the class TcpRecoveryOps and are given below: :: - virtual std::string GetName () const; - virtual void EnterRecovery (Ptr tcb, uint32_t unAckDataCount, - bool isSackEnabled, uint32_t dupAckCount, - uint32_t bytesInFlight, uint32_t lastDeliveredBytes); - virtual void DoRecovery (Ptr tcb, uint32_t unAckDataCount, - bool isSackEnabled, uint32_t dupAckCount, - uint32_t bytesInFlight, uint32_t lastDeliveredBytes); - virtual void ExitRecovery (Ptr tcb, uint32_t bytesInFlight); - virtual void UpdateBytesSent (uint32_t bytesSent); - virtual Ptr Fork (); + virtual std::string GetName() const; + virtual void EnterRecovery(Ptr tcb, uint32_t unAckDataCount, + bool isSackEnabled, uint32_t dupAckCount, + uint32_t bytesInFlight, uint32_t lastDeliveredBytes); + virtual void DoRecovery(Ptr tcb, uint32_t unAckDataCount, + bool isSackEnabled, uint32_t dupAckCount, + uint32_t bytesInFlight, uint32_t lastDeliveredBytes); + virtual void ExitRecovery(Ptr tcb, uint32_t bytesInFlight); + virtual void UpdateBytesSent(uint32_t bytesSent); + virtual Ptr Fork(); EnterRecovery is called when packet loss is detected and recovery is triggered. While in recovery phase, each time when an ACK arrives, DoRecovery is called which @@ -1771,8 +1771,8 @@ The code is the following: :: - TcpZeroWindowTest::TcpZeroWindowTest (const std::string &desc) - : TcpGeneralTest (desc) + TcpZeroWindowTest::TcpZeroWindowTest(const std::string &desc) + : TcpGeneralTest(desc) { } @@ -1801,13 +1801,13 @@ the method ConfigureEnvironment: :: void - TcpZeroWindowTest::ConfigureEnvironment () + TcpZeroWindowTest::ConfigureEnvironment() { - TcpGeneralTest::ConfigureEnvironment (); - SetAppPktCount (20); - SetMTU (500); - SetTransmitStart (Seconds (2.0)); - SetPropagationDelay (MilliSeconds (50)); + TcpGeneralTest::ConfigureEnvironment(); + SetAppPktCount(20); + SetMTU(500); + SetTransmitStart(Seconds(2.0)); + SetPropagationDelay(MilliSeconds(50)); } For other properties, set after the object creation, one can use @@ -1821,10 +1821,10 @@ documentation for an exhaustive list of the tunable properties. :: void - TcpZeroWindowTest::ConfigureProperties () + TcpZeroWindowTest::ConfigureProperties() { - TcpGeneralTest::ConfigureProperties (); - SetInitialCwnd (SENDER, 10); + TcpGeneralTest::ConfigureProperties(); + SetInitialCwnd(SENDER, 10); } To see the default value for the experiment, please see the implementation of @@ -1842,20 +1842,19 @@ advertises a zero window. This can be accomplished by implementing the method CreateReceiverSocket, setting an Rx buffer value of 0 bytes (at line 6 of the following code): - :: :linenos: :emphasize-lines: 6,7,8 Ptr - TcpZeroWindowTest::CreateReceiverSocket (Ptr node) + TcpZeroWindowTest::CreateReceiverSocket(Ptr node) { - Ptr socket = TcpGeneralTest::CreateReceiverSocket (node); + Ptr socket = TcpGeneralTest::CreateReceiverSocket(node); - socket->SetAttribute("RcvBufSize", UintegerValue (0)); - Simulator::Schedule (Seconds (10.0), - &TcpZeroWindowTest::IncreaseBufSize, this); + socket->SetAttribute("RcvBufSize", UintegerValue(0)); + Simulator::Schedule(Seconds(10.0), + &TcpZeroWindowTest::IncreaseBufSize, this); return socket; } @@ -1867,9 +1866,9 @@ IncreaseBufSize. :: void - TcpZeroWindowTest::IncreaseBufSize () + TcpZeroWindowTest::IncreaseBufSize() { - SetRcvBufSize (RECEIVER, 2500); + SetRcvBufSize(RECEIVER, 2500); } Which utilizes the SetRcvBufSize method to edit the RxBuffer object of the @@ -1888,19 +1887,19 @@ to be aware of the various possibilities that it offers. :: void - TcpGeneralTest::SetRcvBufSize (SocketWho who, uint32_t size) + TcpGeneralTest::SetRcvBufSize(SocketWho who, uint32_t size) { if (who == SENDER) { - m_senderSocket->SetRcvBufSize (size); + m_senderSocket->SetRcvBufSize(size); } else if (who == RECEIVER) { - m_receiverSocket->SetRcvBufSize (size); + m_receiverSocket->SetRcvBufSize(size); } else { - NS_FATAL_ERROR ("Not defined"); + NS_FATAL_ERROR("Not defined"); } } @@ -1929,12 +1928,12 @@ the first SYN-ACK has 0 as advertised window size: ... else if (who == RECEIVER) { - NS_LOG_INFO ("\tRECEIVER TX " << h << " size " << p->GetSize()); + NS_LOG_INFO("\tRECEIVER TX " << h << " size " << p->GetSize()); - if (h.GetFlags () & TcpHeader::SYN) + if (h.GetFlags() & TcpHeader::SYN) { - NS_TEST_ASSERT_MSG_EQ (h.GetWindowSize(), 0, - "RECEIVER window size is not 0 in the SYN-ACK"); + NS_TEST_ASSERT_MSG_EQ(h.GetWindowSize(), 0, + "RECEIVER window size is not 0 in the SYN-ACK"); } } .... @@ -1972,16 +1971,16 @@ processing of the SYN-ACK: :: void - TcpZeroWindowTest::ProcessedAck (const Ptr tcb, - const TcpHeader& h, SocketWho who) + TcpZeroWindowTest::ProcessedAck(const Ptr tcb, + const TcpHeader& h, SocketWho who) { if (who == SENDER) { - if (h.GetFlags () & TcpHeader::SYN) + if (h.GetFlags() & TcpHeader::SYN) { - EventId persistentEvent = GetPersistentEvent (SENDER); - NS_TEST_ASSERT_MSG_EQ (persistentEvent.IsRunning (), true, - "Persistent event not started"); + EventId persistentEvent = GetPersistentEvent(SENDER); + NS_TEST_ASSERT_MSG_EQ(persistentEvent.IsRunning(), true, + "Persistent event not started"); } } } @@ -1996,22 +1995,22 @@ again a zero window situation. At first, we investigates on what the sender send :linenos: :emphasize-lines: 1,6,7,11 - if (Simulator::Now ().GetSeconds () <= 6.0) + if (Simulator::Now().GetSeconds() <= 6.0) { - NS_TEST_ASSERT_MSG_EQ (p->GetSize () - h.GetSerializedSize(), 0, - "Data packet sent anyway"); + NS_TEST_ASSERT_MSG_EQ(p->GetSize() - h.GetSerializedSize(), 0, + "Data packet sent anyway"); } - else if (Simulator::Now ().GetSeconds () > 6.0 && - Simulator::Now ().GetSeconds () <= 7.0) + else if (Simulator::Now().GetSeconds() > 6.0 && + Simulator::Now().GetSeconds() <= 7.0) { - NS_TEST_ASSERT_MSG_EQ (m_zeroWindowProbe, false, "Sent another probe"); + NS_TEST_ASSERT_MSG_EQ(m_zeroWindowProbe, false, "Sent another probe"); if (! m_zeroWindowProbe) { - NS_TEST_ASSERT_MSG_EQ (p->GetSize () - h.GetSerializedSize(), 1, - "Data packet sent instead of window probe"); - NS_TEST_ASSERT_MSG_EQ (h.GetSequenceNumber(), SequenceNumber32 (1), - "Data packet sent instead of window probe"); + NS_TEST_ASSERT_MSG_EQ(p->GetSize() - h.GetSerializedSize(), 1, + "Data packet sent instead of window probe"); + NS_TEST_ASSERT_MSG_EQ(h.GetSequenceNumber(), SequenceNumber32(1), + "Data packet sent instead of window probe"); m_zeroWindowProbe = true; } } @@ -2030,13 +2029,13 @@ Only one probe is allowed, and this is the reason for the check at line 11. :linenos: :emphasize-lines: 6,7 - if (Simulator::Now ().GetSeconds () > 6.0 && - Simulator::Now ().GetSeconds () <= 7.0) + if (Simulator::Now().GetSeconds() > 6.0 && + Simulator::Now().GetSeconds() <= 7.0) { - NS_TEST_ASSERT_MSG_EQ (h.GetSequenceNumber(), SequenceNumber32 (1), - "Data packet sent instead of window probe"); - NS_TEST_ASSERT_MSG_EQ (h.GetWindowSize(), 0, - "No zero window advertised by RECEIVER"); + NS_TEST_ASSERT_MSG_EQ(h.GetSequenceNumber(), SequenceNumber32(1), + "Data packet sent instead of window probe"); + NS_TEST_ASSERT_MSG_EQ(h.GetWindowSize(), 0, + "No zero window advertised by RECEIVER"); } For the RECEIVER, the interval between 6 and 7 seconds is when the zero-window @@ -2047,10 +2046,10 @@ exchange between the 7 and 10 seconds mark. :: - else if (Simulator::Now ().GetSeconds () > 7.0 && - Simulator::Now ().GetSeconds () < 10.0) + else if (Simulator::Now().GetSeconds() > 7.0 && + Simulator::Now().GetSeconds() < 10.0) { - NS_FATAL_ERROR ("No packets should be sent before the window update"); + NS_FATAL_ERROR("No packets should be sent before the window update"); } The state checks are performed at the end of the methods, since they are valid @@ -2058,10 +2057,10 @@ in every condition: :: - NS_TEST_ASSERT_MSG_EQ (GetCongStateFrom (GetTcb(SENDER)), TcpSocketState::CA_OPEN, - "Sender State is not OPEN"); - NS_TEST_ASSERT_MSG_EQ (GetCongStateFrom (GetTcb(RECEIVER)), TcpSocketState::CA_OPEN, - "Receiver State is not OPEN"); + NS_TEST_ASSERT_MSG_EQ(GetCongStateFrom(GetTcb(SENDER)), TcpSocketState::CA_OPEN, + "Sender State is not OPEN"); + NS_TEST_ASSERT_MSG_EQ(GetCongStateFrom(GetTcb(RECEIVER)), TcpSocketState::CA_OPEN, + "Receiver State is not OPEN"); Now, the interesting part in the Tx method is to check that after the 10.0 seconds mark (when the RECEIVER sends the active window update) the value of @@ -2071,8 +2070,8 @@ the window should be greater than zero (and precisely, set to 2500): else if (Simulator::Now().GetSeconds() >= 10.0) { - NS_TEST_ASSERT_MSG_EQ (h.GetWindowSize(), 2500, - "Receiver window not updated"); + NS_TEST_ASSERT_MSG_EQ(h.GetWindowSize(), 2500, + "Receiver window not updated"); } To be sure that the sender receives the window update, we can use the Rx @@ -2085,8 +2084,8 @@ method: if (Simulator::Now().GetSeconds() >= 10.0) { - NS_TEST_ASSERT_MSG_EQ (h.GetWindowSize(), 2500, - "Receiver window not updated"); + NS_TEST_ASSERT_MSG_EQ(h.GetWindowSize(), 2500, + "Receiver window not updated"); m_windowUpdated = true; } @@ -2100,7 +2099,7 @@ the connection ends with a success: :: void - TcpZeroWindowTest::NormalClose (SocketWho who) + TcpZeroWindowTest::NormalClose(SocketWho who) { if (who == SENDER) { @@ -2119,16 +2118,16 @@ indicates that we have perfectly closed the connection). :: void - TcpZeroWindowTest::FinalChecks () + TcpZeroWindowTest::FinalChecks() { - NS_TEST_ASSERT_MSG_EQ (m_zeroWindowProbe, true, - "Zero window probe not sent"); - NS_TEST_ASSERT_MSG_EQ (m_windowUpdated, true, - "Window has not updated during the connection"); - NS_TEST_ASSERT_MSG_EQ (m_senderFinished, true, - "Connection not closed successfully (SENDER)"); - NS_TEST_ASSERT_MSG_EQ (m_receiverFinished, true, - "Connection not closed successfully (RECEIVER)"); + NS_TEST_ASSERT_MSG_EQ(m_zeroWindowProbe, true, + "Zero window probe not sent"); + NS_TEST_ASSERT_MSG_EQ(m_windowUpdated, true, + "Window has not updated during the connection"); + NS_TEST_ASSERT_MSG_EQ(m_senderFinished, true, + "Connection not closed successfully(SENDER)"); + NS_TEST_ASSERT_MSG_EQ(m_receiverFinished, true, + "Connection not closed successfully(RECEIVER)"); } To run the test, the usual way is diff --git a/src/internet/doc/udp.rst b/src/internet/doc/udp.rst index c11b69509..5c613959c 100644 --- a/src/internet/doc/udp.rst +++ b/src/internet/doc/udp.rst @@ -63,34 +63,34 @@ is how one would create a UDP receiver:: // Create a packet sink on the receiver uint16_t port = 50000; - Address sinkLocalAddress(InetSocketAddress (Ipv4Address::GetAny (), port)); - PacketSinkHelper sinkHelper ("ns3::UdpSocketFactory", sinkLocalAddress); - ApplicationContainer sinkApp = sinkHelper.Install (serverNode); - sinkApp.Start (Seconds (1.0)); - sinkApp.Stop (Seconds (10.0)); + Address sinkLocalAddress(InetSocketAddress(Ipv4Address::GetAny(), port)); + PacketSinkHelper sinkHelper("ns3::UdpSocketFactory", sinkLocalAddress); + ApplicationContainer sinkApp = sinkHelper.Install(serverNode); + sinkApp.Start(Seconds(1.0)); + sinkApp.Stop(Seconds(10.0)); Similarly, the below snippet configures OnOffApplication traffic source to use UDP:: // Create the OnOff applications to send data to the UDP receiver - OnOffHelper clientHelper ("ns3::UdpSocketFactory", Address ()); - clientHelper.SetAttribute ("Remote", remoteAddress); - ApplicationContainer clientApps = (clientHelper.Install (clientNode); - clientApps.Start (Seconds (2.0)); - clientApps.Stop (Seconds (9.0)); + OnOffHelper clientHelper("ns3::UdpSocketFactory", Address()); + clientHelper.SetAttribute("Remote", remoteAddress); + ApplicationContainer clientApps =(clientHelper.Install(clientNode); + clientApps.Start(Seconds(2.0)); + clientApps.Stop(Seconds(9.0)); -For users who wish to have a pointer to the actual socket (so that +For users who wish to have a pointer to the actual socket(so that socket operations like ``Bind()``, setting socket options, etc. can be done on a per-socket basis), UDP sockets can be created by using the ``Socket::CreateSocket()`` method as given below:: - Ptr node = CreateObject (); + Ptr node = CreateObject(); InternetStackHelper internet; - internet.Install (node); + internet.Install(node); - Ptr socketFactory = node->GetObject (); - Ptr socket = socketFactory->CreateSocket (); - socket->Bind (InetSocketAddress (Ipv4Address::GetAny (), 80)); + Ptr socketFactory = node->GetObject(); + Ptr socket = socketFactory->CreateSocket(); + socket->Bind(InetSocketAddress(Ipv4Address::GetAny(), 80)); Once a UDP socket is created, we do not need an explicit connection setup before sending and receiving data. Being a connectionless protocol, all we need to do diff --git a/src/lr-wpan/doc/lr-wpan.rst b/src/lr-wpan/doc/lr-wpan.rst index 8c92a2f5a..8be73e8cc 100644 --- a/src/lr-wpan/doc/lr-wpan.rst +++ b/src/lr-wpan/doc/lr-wpan.rst @@ -60,20 +60,20 @@ points (SAP): In general, primitives are standardized as follows (e.g. Sec 7.1.1.1.1 of IEEE 802.15.4-2006)::: - MCPS-DATA.request ( - SrcAddrMode, - DstAddrMode, - DstPANId, - DstAddr, - msduLength, - msdu, - msduHandle, - TxOptions, - SecurityLevel, - KeyIdMode, - KeySource, - KeyIndex - ) + MCPS-DATA.request( + SrcAddrMode, + DstAddrMode, + DstPANId, + DstAddr, + msduLength, + msdu, + msduHandle, + TxOptions, + SecurityLevel, + KeyIdMode, + KeySource, + KeyIndex + ) This maps to |ns3| classes and methods such as::: @@ -85,7 +85,7 @@ This maps to |ns3| classes and methods such as::: }; void - LrWpanMac::McpsDataRequest (McpsDataRequestParameters params) + LrWpanMac::McpsDataRequest(McpsDataRequestParameters params) { ... } @@ -405,5 +405,3 @@ of the error model validation and can be reproduced by running .. figure:: figures/802-15-4-ber.* Default output of the program ``lr-wpan-error-model-plot.cc`` - - diff --git a/src/lte/doc/source/lte-design.rst b/src/lte/doc/source/lte-design.rst index ed267ff2e..ae2a30197 100644 --- a/src/lte/doc/source/lte-design.rst +++ b/src/lte/doc/source/lte-design.rst @@ -511,7 +511,7 @@ In downlink, the SINR used to generate CQI feedback can be calculated in two dif To switch between this two CQI generation approaches, ``LteHelper::UsePdschForCqiGeneration`` needs to be configured: false for first approach and true for second approach (true is default value):: - Config::SetDefault ("ns3::LteHelper::UsePdschForCqiGeneration", BooleanValue (true)); + Config::SetDefault("ns3::LteHelper::UsePdschForCqiGeneration", BooleanValue(true)); In uplink, two types of CQIs are implemented: @@ -683,7 +683,7 @@ The model implemented uses the curves for the LSM of the recently LTE PHY Error The model can be disabled for working with a zero-losses channel by setting the ``DataErrorModelEnabled`` attribute of the ``LteSpectrumPhy`` class (by default is active). This can be done according to the standard ns3 attribute system procedure, that is:: - Config::SetDefault ("ns3::LteSpectrumPhy::DataErrorModelEnabled", BooleanValue (false)); + Config::SetDefault("ns3::LteSpectrumPhy::DataErrorModelEnabled", BooleanValue(false)); .. _sec-control-channles-phy-error-model: @@ -1000,7 +1000,7 @@ available resources among the active flows, i.e., those logical channels which h For what concern the HARQ, RR implements the non adaptive version, which implies that in allocating the retransmission attempts RR uses the same allocation configuration of the original block, which means maintaining the same RBGs and MCS. UEs that are allocated for HARQ retransmissions are not considered for the transmission of new data in case they have a transmission opportunity available in the same TTI. Finally, HARQ can be disabled with ns3 attribute system for maintaining backward compatibility with old test cases and code, in detail:: - Config::SetDefault ("ns3::RrFfMacScheduler::HarqEnabled", BooleanValue (false)); + Config::SetDefault("ns3::RrFfMacScheduler::HarqEnabled", BooleanValue(false)); The scheduler implements the filtering of the uplink CQIs according to their nature with ``UlCqiFilter`` attribute, in detail: @@ -1079,7 +1079,7 @@ where :math:`|\cdot|` indicates the cardinality of the set; finally, For what concern the HARQ, PF implements the non adaptive version, which implies that in allocating the retransmission attempts the scheduler uses the same allocation configuration of the original block, which means maintaining the same RBGs and MCS. UEs that are allocated for HARQ retransmissions are not considered for the transmission of new data in case they have a transmission opportunity available in the same TTI. Finally, HARQ can be disabled with ns3 attribute system for maintaining backward compatibility with old test cases and code, in detail:: - Config::SetDefault ("ns3::PfFfMacScheduler::HarqEnabled", BooleanValue (false)); + Config::SetDefault("ns3::PfFfMacScheduler::HarqEnabled", BooleanValue(false)); @@ -1256,7 +1256,7 @@ quality UE tend towards the TBR. :: - Config::SetDefault ("ns3::PfFfMacScheduler::HarqEnabled", BooleanValue (false)); + Config::SetDefault("ns3::PfFfMacScheduler::HarqEnabled", BooleanValue(false)); The scheduler implements the filtering of the uplink CQIs according to their nature with ``UlCqiFilter`` attribute, in detail: @@ -3667,8 +3667,8 @@ implementation in order to send a load information primitive:: EpcX2Sap::LoadInformationParams params; params.targetCellId = cellId; - params.cellInformationList.push_back (cii); - m_x2SapProvider->SendLoadInformation (params); + params.cellInformationList.push_back(cii); + m_x2SapProvider->SendLoadInformation(params); The above code allows the source eNB to send the message. The method @@ -3691,8 +3691,8 @@ send a resource status update:: EpcX2Sap::ResourceStatusUpdateParams params; params.targetCellId = cellId; - params.cellMeasurementResultList.push_back (m_cmri); - m_x2SapProvider->SendResourceStatusUpdate (params); + params.cellMeasurementResultList.push_back(m_cmri); + m_x2SapProvider->SendResourceStatusUpdate(params); The method ``eEnbRrc::DoRecvResourceStatusUpdate`` will be called when @@ -3805,7 +3805,7 @@ channels. This functionality is described in 3GPP TS 36.213 section 5. Uplink Power Control is enabled by default, and can be disabled by attribute system:: - Config::SetDefault ("ns3::LteUePhy::EnableUplinkPowerControl", BooleanValue (false)); + Config::SetDefault("ns3::LteUePhy::EnableUplinkPowerControl", BooleanValue(false)); Two Uplink Power Control mechanisms are implemented: @@ -3818,7 +3818,7 @@ Two Uplink Power Control mechanisms are implemented: To switch between these two mechanism types, one should change parameter:: - Config::SetDefault ("ns3::LteUePowerControl::ClosedLoop", BooleanValue (true)); + Config::SetDefault("ns3::LteUePowerControl::ClosedLoop", BooleanValue(true)); By default, Closed Loop Power Control is enabled. @@ -3829,7 +3829,7 @@ Two modes of Closed Loop Uplink Power Control are available: To switch between these two modes, one should change parameter:: - Config::SetDefault ("ns3::LteUePowerControl::AccumulationEnabled", BooleanValue (true)); + Config::SetDefault("ns3::LteUePowerControl::AccumulationEnabled", BooleanValue(true)); By default, Accumulation Mode is enabled and TPC commands in DL-DCI are set by all schedulers to 1, what is mapped to value of 0 in Accumulation Mode. @@ -3894,15 +3894,15 @@ where: layers for :math:`j={0,1}` for serving cell :math:`c`. SIB2 message needs to be extended to carry these two components, but currently they can be set via attribute system:: - Config::SetDefault ("ns3::LteUePowerControl::PoNominalPusch", IntegerValue (-90)); - Config::SetDefault ("ns3::LteUePowerControl::PoUePusch", IntegerValue (7)); + Config::SetDefault("ns3::LteUePowerControl::PoNominalPusch", IntegerValue(-90)); + Config::SetDefault("ns3::LteUePowerControl::PoUePusch", IntegerValue(7)); * :math:`\alpha_{c} (j)` is a 3-bit parameter provided by higher layers for serving cell :math:`c`. For :math:`j=0,1`, :math:`\alpha_c \in \left \{ 0, 0.4, 0.5, 0.6, 0.7, 0.8, 0.9, 1 \right \}` For :math:`j=2`, :math:`\alpha_{c} (j) = 1`. This parameter is configurable by attribute system:: - Config::SetDefault ("ns3::LteUePowerControl::Alpha", DoubleValue (0.8)); + Config::SetDefault("ns3::LteUePowerControl::Alpha", DoubleValue(0.8)); * :math:`PL_{c}` is the downlink pathloss estimate calculated in the UE for serving cell :math:`c` in dB and :math:`PL_{c} = referenceSignalPower – higher layer filtered RSRP`, where :math:`referenceSignalPower` @@ -3979,7 +3979,7 @@ where: This parameter is configurable by attribute system:: - Config::SetDefault ("ns3::LteUePowerControl::PsrsOffset", IntegerValue (7)); + Config::SetDefault("ns3::LteUePowerControl::PsrsOffset", IntegerValue(7)); * :math:`M_{SRS,c}` is the bandwidth of the SRS transmission in subframe :math:`i` for serving cell :math:`c` expressed in number of resource blocks. In current implementation SRS is sent @@ -4742,4 +4742,3 @@ called by the ``LteHelper``. The exact interactions are displayed in the Figure :align: center Sequence diagram of the interaction between ``LteHelper`` and ``EpcHelper``. - diff --git a/src/lte/doc/source/lte-user.rst b/src/lte/doc/source/lte-user.rst index 204aaadab..94525a42a 100644 --- a/src/lte/doc/source/lte-user.rst +++ b/src/lte/doc/source/lte-user.rst @@ -57,14 +57,14 @@ Here is the minimal simulation program that is needed to do an LTE-only simulati using namespace ns3; - int main (int argc, char *argv[]) + int main(int argc, char *argv[]) { // the rest of the simulation program follows #. Create an ``LteHelper`` object:: - Ptr lteHelper = CreateObject (); + Ptr lteHelper = CreateObject(); This will instantiate some common objects (e.g., the Channel object) and provide the methods to add @@ -73,9 +73,9 @@ Here is the minimal simulation program that is needed to do an LTE-only simulati #. Create ``Node`` objects for the eNB(s) and the UEs:: NodeContainer enbNodes; - enbNodes.Create (1); + enbNodes.Create(1); NodeContainer ueNodes; - ueNodes.Create (2); + ueNodes.Create(2); Note that the above Node instances at this point still don't have an LTE protocol stack installed; they're just empty nodes. @@ -83,10 +83,10 @@ Here is the minimal simulation program that is needed to do an LTE-only simulati #. Configure the Mobility model for all the nodes:: MobilityHelper mobility; - mobility.SetMobilityModel ("ns3::ConstantPositionMobilityModel"); - mobility.Install (enbNodes); - mobility.SetMobilityModel ("ns3::ConstantPositionMobilityModel"); - mobility.Install (ueNodes); + mobility.SetMobilityModel("ns3::ConstantPositionMobilityModel"); + mobility.Install(enbNodes); + mobility.SetMobilityModel("ns3::ConstantPositionMobilityModel"); + mobility.Install(ueNodes); The above will place all nodes at the coordinates (0,0,0). Please refer to the documentation of the ns-3 mobility model for how to @@ -95,31 +95,31 @@ Here is the minimal simulation program that is needed to do an LTE-only simulati #. Install an LTE protocol stack on the eNB(s):: NetDeviceContainer enbDevs; - enbDevs = lteHelper->InstallEnbDevice (enbNodes); + enbDevs = lteHelper->InstallEnbDevice(enbNodes); #. Install an LTE protocol stack on the UEs:: NetDeviceContainer ueDevs; - ueDevs = lteHelper->InstallUeDevice (ueNodes); + ueDevs = lteHelper->InstallUeDevice(ueNodes); #. Attach the UEs to an eNB. This will configure each UE according to the eNB configuration, and create an RRC connection between them:: - lteHelper->Attach (ueDevs, enbDevs.Get (0)); + lteHelper->Attach(ueDevs, enbDevs.Get(0)); #. Activate a data radio bearer between each UE and the eNB it is attached to:: enum EpsBearer::Qci q = EpsBearer::GBR_CONV_VOICE; - EpsBearer bearer (q); - lteHelper->ActivateDataRadioBearer (ueDevs, bearer); + EpsBearer bearer(q); + lteHelper->ActivateDataRadioBearer(ueDevs, bearer); this method will also activate two saturation traffic generators for that bearer, one in uplink and one in downlink. #. Set the stop time:: - Simulator::Stop (Seconds (0.005)); + Simulator::Stop(Seconds(0.005)); This is needed otherwise the simulation will last forever, because (among others) the start-of-subframe event is scheduled repeatedly, and the @@ -127,12 +127,11 @@ Here is the minimal simulation program that is needed to do an LTE-only simulati #. Run the simulation:: - Simulator::Run (); + Simulator::Run(); #. Cleanup and exit:: - - Simulator::Destroy (); + Simulator::Destroy(); return 0; } @@ -152,12 +151,12 @@ how to do it using input files together with the ns-3 ConfigStore. First of all, you need to put the following in your simulation program, right after ``main ()`` starts:: - CommandLine cmd (__FILE__); - cmd.Parse (argc, argv); + CommandLine cmd(__FILE__); + cmd.Parse(argc, argv); ConfigStore inputConfig; - inputConfig.ConfigureDefaults (); + inputConfig.ConfigureDefaults(); // parse again so you can override default values from the command line - cmd.Parse (argc, argv); + cmd.Parse(argc, argv); for the above to work, make sure you also ``#include "ns3/config-store.h"``. Now create a text file named (for example) ``input-defaults.txt`` @@ -199,29 +198,29 @@ Configure LTE MAC Scheduler There are several types of LTE MAC scheduler user can choose here. User can use following codes to define scheduler type:: - Ptr lteHelper = CreateObject (); - lteHelper->SetSchedulerType ("ns3::FdMtFfMacScheduler"); // FD-MT scheduler - lteHelper->SetSchedulerType ("ns3::TdMtFfMacScheduler"); // TD-MT scheduler - lteHelper->SetSchedulerType ("ns3::TtaFfMacScheduler"); // TTA scheduler - lteHelper->SetSchedulerType ("ns3::FdBetFfMacScheduler"); // FD-BET scheduler - lteHelper->SetSchedulerType ("ns3::TdBetFfMacScheduler"); // TD-BET scheduler - lteHelper->SetSchedulerType ("ns3::FdTbfqFfMacScheduler"); // FD-TBFQ scheduler - lteHelper->SetSchedulerType ("ns3::TdTbfqFfMacScheduler"); // TD-TBFQ scheduler - lteHelper->SetSchedulerType ("ns3::PssFfMacScheduler"); //PSS scheduler + Ptr lteHelper = CreateObject(); + lteHelper->SetSchedulerType("ns3::FdMtFfMacScheduler"); // FD-MT scheduler + lteHelper->SetSchedulerType("ns3::TdMtFfMacScheduler"); // TD-MT scheduler + lteHelper->SetSchedulerType("ns3::TtaFfMacScheduler"); // TTA scheduler + lteHelper->SetSchedulerType("ns3::FdBetFfMacScheduler"); // FD-BET scheduler + lteHelper->SetSchedulerType("ns3::TdBetFfMacScheduler"); // TD-BET scheduler + lteHelper->SetSchedulerType("ns3::FdTbfqFfMacScheduler"); // FD-TBFQ scheduler + lteHelper->SetSchedulerType("ns3::TdTbfqFfMacScheduler"); // TD-TBFQ scheduler + lteHelper->SetSchedulerType("ns3::PssFfMacScheduler"); //PSS scheduler TBFQ and PSS have more parameters than other schedulers. Users can define those parameters in following way:: * TBFQ scheduler:: - Ptr lteHelper = CreateObject (); - lteHelper->SetSchedulerAttribute("DebtLimit", IntegerValue(yourvalue)); // default value -625000 bytes (-5Mb) - lteHelper->SetSchedulerAttribute("CreditLimit", UintegerValue(yourvalue)); // default value 625000 bytes (5Mb) + Ptr lteHelper = CreateObject(); + lteHelper->SetSchedulerAttribute("DebtLimit", IntegerValue(yourvalue)); // default value -625000 bytes(-5Mb) + lteHelper->SetSchedulerAttribute("CreditLimit", UintegerValue(yourvalue)); // default value 625000 bytes(5Mb) lteHelper->SetSchedulerAttribute("TokenPoolSize", UintegerValue(yourvalue)); // default value 1 byte lteHelper->SetSchedulerAttribute("CreditableThreshold", UintegerValue(yourvalue)); // default value 0 * PSS scheduler:: - Ptr lteHelper = CreateObject (); + Ptr lteHelper = CreateObject(); lteHelper->SetSchedulerAttribute("nMux", UIntegerValue(yourvalue)); // the maximum number of UE selected by TD scheduler lteHelper->SetSchedulerAttribute("PssFdSchedulerType", StringValue("CoItA")); // PF scheduler type in PSS @@ -232,15 +231,15 @@ PSS will set this value to half of total UE. The default FD scheduler is PFsch. In addition, token generation rate in TBFQ and target bit rate in PSS need to be configured by Guarantee Bit Rate (GBR) or Maximum Bit Rate (MBR) in epc bearer QoS parameters. Users can use following codes to define GBR and MBR in both downlink and uplink:: - Ptr lteHelper = CreateObject (); + Ptr lteHelper = CreateObject(); enum EpsBearer::Qci q = EpsBearer::yourvalue; // define Qci type GbrQosInformation qos; qos.gbrDl = yourvalue; // Downlink GBR qos.gbrUl = yourvalue; // Uplink GBR qos.mbrDl = yourvalue; // Downlink MBR qos.mbrUl = yourvalue; // Uplink MBR - EpsBearer bearer (q, qos); - lteHelper->ActivateDedicatedEpsBearer (ueDevs, bearer, EpcTft::Default ()); + EpsBearer bearer(q, qos); + lteHelper->ActivateDedicatedEpsBearer(ueDevs, bearer, EpcTft::Default()); In PSS, TBR is obtained from GBR in bearer level QoS parameters. In TBFQ, token generation rate is obtained from the MBR setting in bearer level QoS parameters, which therefore needs to be configured consistently. @@ -280,16 +279,16 @@ The ns-3 LTE model currently supports the output to file of PHY, MAC, RLC and PDCP level Key Performance Indicators (KPIs). You can enable it in the following way:: - Ptr lteHelper = CreateObject (); + Ptr lteHelper = CreateObject(); // configure all the simulation scenario here... - lteHelper->EnablePhyTraces (); - lteHelper->EnableMacTraces (); - lteHelper->EnableRlcTraces (); - lteHelper->EnablePdcpTraces (); + lteHelper->EnablePhyTraces(); + lteHelper->EnableMacTraces(); + lteHelper->EnableRlcTraces(); + lteHelper->EnablePdcpTraces(); - Simulator::Run (); + Simulator::Run(); RLC and PDCP KPIs are calculated over a time interval and stored on ASCII @@ -476,16 +475,16 @@ The default configuration of the matlab script provides a trace 10 seconds long, In order to activate the fading module (which is not active by default) the following code should be included in the simulation program:: - Ptr lteHelper = CreateObject (); + Ptr lteHelper = CreateObject(); lteHelper->SetFadingModel("ns3::TraceFadingLossModel"); And for setting the parameters:: - lteHelper->SetFadingModelAttribute ("TraceFilename", StringValue ("src/lte/model/fading-traces/fading_trace_EPA_3kmph.fad")); - lteHelper->SetFadingModelAttribute ("TraceLength", TimeValue (Seconds (10.0))); - lteHelper->SetFadingModelAttribute ("SamplesNum", UintegerValue (10000)); - lteHelper->SetFadingModelAttribute ("WindowSize", TimeValue (Seconds (0.5))); - lteHelper->SetFadingModelAttribute ("RbNum", UintegerValue (100)); + lteHelper->SetFadingModelAttribute("TraceFilename", StringValue("src/lte/model/fading-traces/fading_trace_EPA_3kmph.fad")); + lteHelper->SetFadingModelAttribute("TraceLength", TimeValue(Seconds(10.0))); + lteHelper->SetFadingModelAttribute("SamplesNum", UintegerValue(10000)); + lteHelper->SetFadingModelAttribute("WindowSize", TimeValue(Seconds(0.5))); + lteHelper->SetFadingModelAttribute("RbNum", UintegerValue(100)); It has to be noted that, ``TraceFilename`` does not have a default value, therefore is has to be always set explicitly. @@ -533,23 +532,23 @@ We now explain by examples how to use the buildings model (in particular, the `` #. Pathloss model selection:: - Ptr lteHelper = CreateObject (); + Ptr lteHelper = CreateObject(); - lteHelper->SetAttribute ("PathlossModel", StringValue ("ns3::BuildingsPropagationLossModel")); + lteHelper->SetAttribute("PathlossModel", StringValue("ns3::BuildingsPropagationLossModel")); #. EUTRA Band Selection The selection of the working frequency of the propagation model has to be done with the standard ns-3 attribute system as described in the correspond section ("Configuration of LTE model parameters") by means of the DlEarfcn and UlEarfcn parameters, for instance:: - lteHelper->SetEnbDeviceAttribute ("DlEarfcn", UintegerValue (100)); - lteHelper->SetEnbDeviceAttribute ("UlEarfcn", UintegerValue (18100)); + lteHelper->SetEnbDeviceAttribute("DlEarfcn", UintegerValue(100)); + lteHelper->SetEnbDeviceAttribute("UlEarfcn", UintegerValue(18100)); It is to be noted that using other means to configure the frequency used by the propagation model (i.e., configuring the corresponding BuildingsPropagationLossModel attributes directly) might generates conflicts in the frequencies definition in the modules during the simulation, and is therefore not advised. #. Mobility model selection:: MobilityHelper mobility; - mobility.SetMobilityModel ("ns3::ConstantPositionMobilityModel"); + mobility.SetMobilityModel("ns3::ConstantPositionMobilityModel"); It is to be noted that any mobility model can be used. @@ -561,31 +560,31 @@ It is to be noted that using other means to configure the frequency used by the double y_max = 20.0; double z_min = 0.0; double z_max = 10.0; - Ptr b = CreateObject (); - b->SetBoundaries (Box (x_min, x_max, y_min, y_max, z_min, z_max)); - b->SetBuildingType (Building::Residential); - b->SetExtWallsType (Building::ConcreteWithWindows); - b->SetNFloors (3); - b->SetNRoomsX (3); - b->SetNRoomsY (2); + Ptr b = CreateObject (); + b->SetBoundaries(Box(x_min, x_max, y_min, y_max, z_min, z_max)); + b->SetBuildingType(Building::Residential); + b->SetExtWallsType(Building::ConcreteWithWindows); + b->SetNFloors(3); + b->SetNRoomsX(3); + b->SetNRoomsY(2); This will instantiate a residential building with base of 10 x 20 meters and height of 10 meters whose external walls are of concrete with windows; the building has three floors and has an internal 3 x 2 grid of rooms of equal size. #. Node creation and positioning:: - ueNodes.Create (2); - mobility.Install (ueNodes); - BuildingsHelper::Install (ueNodes); + ueNodes.Create(2); + mobility.Install(ueNodes); + BuildingsHelper::Install(ueNodes); NetDeviceContainer ueDevs; - ueDevs = lteHelper->InstallUeDevice (ueNodes); - Ptr mm0 = enbNodes.Get (0)->GetObject (); - Ptr mm1 = enbNodes.Get (1)->GetObject (); - mm0->SetPosition (Vector (5.0, 5.0, 1.5)); - mm1->SetPosition (Vector (30.0, 40.0, 1.5)); + ueDevs = lteHelper->InstallUeDevice(ueNodes); + Ptr mm0 = enbNodes.Get(0)->GetObject(); + Ptr mm1 = enbNodes.Get(1)->GetObject(); + mm0->SetPosition(Vector(5.0, 5.0, 1.5)); + mm1->SetPosition(Vector(30.0, 40.0, 1.5)); #. Finalize the building and mobility model configuration:: - BuildingsHelper::MakeMobilityModelConsistent (); + BuildingsHelper::MakeMobilityModelConsistent(); See the documentation of the *buildings* module for more detailed information. @@ -595,8 +594,8 @@ PHY Error Model The Physical error model consists of the data error model and the downlink control error model, both of them active by default. It is possible to deactivate them with the ns3 attribute system, in detail:: - Config::SetDefault ("ns3::LteSpectrumPhy::CtrlErrorModelEnabled", BooleanValue (false)); - Config::SetDefault ("ns3::LteSpectrumPhy::DataErrorModelEnabled", BooleanValue (false)); + Config::SetDefault("ns3::LteSpectrumPhy::CtrlErrorModelEnabled", BooleanValue(false)); + Config::SetDefault("ns3::LteSpectrumPhy::DataErrorModelEnabled", BooleanValue(false)); @@ -616,21 +615,21 @@ Is this subsection we illustrate how to configure the MIMO parameters. LTE defin According to model implemented, the simulator includes the first three transmission modes types. The default one is the Transmission Mode 1 (SISO). In order to change the default Transmission Mode to be used, the attribute ``DefaultTransmissionMode`` of the ``LteEnbRrc`` can be used, as shown in the following:: - Config::SetDefault ("ns3::LteEnbRrc::DefaultTransmissionMode", UintegerValue (0)); // SISO - Config::SetDefault ("ns3::LteEnbRrc::DefaultTransmissionMode", UintegerValue (1)); // MIMO Tx diversity (1 layer) - Config::SetDefault ("ns3::LteEnbRrc::DefaultTransmissionMode", UintegerValue (2)); // MIMO Spatial Multiplexity (2 layers) + Config::SetDefault("ns3::LteEnbRrc::DefaultTransmissionMode", UintegerValue(0)); // SISO + Config::SetDefault("ns3::LteEnbRrc::DefaultTransmissionMode", UintegerValue(1)); // MIMO Tx diversity(1 layer) + Config::SetDefault("ns3::LteEnbRrc::DefaultTransmissionMode", UintegerValue(2)); // MIMO Spatial Multiplexity(2 layers) For changing the transmission mode of a certain user during the simulation a specific interface has been implemented in both standard schedulers:: - void TransmissionModeConfigurationUpdate (uint16_t rnti, uint8_t txMode); + void TransmissionModeConfigurationUpdate(uint16_t rnti, uint8_t txMode); This method can be used both for developing transmission mode decision engine (i.e., for optimizing the transmission mode according to channel condition and/or user's requirements) and for manual switching from simulation script. In the latter case, the switching can be done as shown in the following:: - Ptr lteEnbDev = enbDevs.Get (0)->GetObject (); + Ptr lteEnbDev = enbDevs.Get(0)->GetObject(); PointerValue ptrval; - enbNetDev->GetAttribute ("FfMacScheduler", ptrval); - Ptr rrsched = ptrval.Get (); - Simulator::Schedule (Seconds (0.2), &RrFfMacScheduler::TransmissionModeConfigurationUpdate, rrsched, rnti, 1); + enbNetDev->GetAttribute("FfMacScheduler", ptrval); + Ptr rrsched = ptrval.Get(); + Simulator::Schedule(Seconds(0.2), &RrFfMacScheduler::TransmissionModeConfigurationUpdate, rrsched, rnti, 1); Finally, the model implemented can be reconfigured according to different MIMO models by updating the gain values (the only constraints is that the gain has to be constant during simulation run-time and common for the layers). The gain of each Transmission Mode can be changed according to the standard ns3 attribute system, where the attributes are: ``TxMode1Gain``, ``TxMode2Gain``, ``TxMode3Gain``, ``TxMode4Gain``, ``TxMode5Gain``, ``TxMode6Gain`` and ``TxMode7Gain``. By default only ``TxMode1Gain``, ``TxMode2Gain`` and ``TxMode3Gain`` have a meaningful value, that are the ones derived by _[CatreuxMIMO] (i.e., respectively 0.0, 4.2 and -2.8 dB). @@ -649,10 +648,10 @@ antenna module. The configuration of the eNB is to be done via the ``LteHelper`` instance right before the creation of the ``EnbNetDevice``, as shown in the following:: - lteHelper->SetEnbAntennaModelType ("ns3::CosineAntennaModel"); - lteHelper->SetEnbAntennaModelAttribute ("Orientation", DoubleValue (0)); - lteHelper->SetEnbAntennaModelAttribute ("Beamwidth", DoubleValue (60)); - lteHelper->SetEnbAntennaModelAttribute ("MaxGain", DoubleValue (0.0)); + lteHelper->SetEnbAntennaModelType("ns3::CosineAntennaModel"); + lteHelper->SetEnbAntennaModelAttribute("Orientation", DoubleValue(0)); + lteHelper->SetEnbAntennaModelAttribute("Beamwidth", DoubleValue(60)); + lteHelper->SetEnbAntennaModelAttribute("MaxGain", DoubleValue(0.0)); the above code will generate an antenna model with a 60 degrees beamwidth pointing along the X axis. The orientation is measured @@ -681,21 +680,21 @@ can set the RbId, for which REM will be generated. Default RbId is -1, what means that REM will generated with averaged Signal-to-noise ratio from all RBs. To do this, you just need to add the following code to your simulation -program towards the end, right before the call to Simulator::Run ():: +program towards the end, right before the call to Simulator::Run():: - Ptr remHelper = CreateObject (); - remHelper->SetAttribute ("Channel", PointerValue (lteHelper->GetDownlinkSpectrumChannel ())); - remHelper->SetAttribute ("OutputFile", StringValue ("rem.out")); - remHelper->SetAttribute ("XMin", DoubleValue (-400.0)); - remHelper->SetAttribute ("XMax", DoubleValue (400.0)); - remHelper->SetAttribute ("XRes", UintegerValue (100)); - remHelper->SetAttribute ("YMin", DoubleValue (-300.0)); - remHelper->SetAttribute ("YMax", DoubleValue (300.0)); - remHelper->SetAttribute ("YRes", UintegerValue (75)); - remHelper->SetAttribute ("Z", DoubleValue (0.0)); - remHelper->SetAttribute ("UseDataChannel", BooleanValue (true)); - remHelper->SetAttribute ("RbId", IntegerValue (10)); - remHelper->Install (); + Ptr remHelper = CreateObject(); + remHelper->SetAttribute("Channel", PointerValue(lteHelper->GetDownlinkSpectrumChannel())); + remHelper->SetAttribute("OutputFile", StringValue("rem.out")); + remHelper->SetAttribute("XMin", DoubleValue(-400.0)); + remHelper->SetAttribute("XMax", DoubleValue(400.0)); + remHelper->SetAttribute("XRes", UintegerValue(100)); + remHelper->SetAttribute("YMin", DoubleValue(-300.0)); + remHelper->SetAttribute("YMax", DoubleValue(300.0)); + remHelper->SetAttribute("YRes", UintegerValue(75)); + remHelper->SetAttribute("Z", DoubleValue(0.0)); + remHelper->SetAttribute("UseDataChannel", BooleanValue(true)); + remHelper->SetAttribute("RbId", IntegerValue(10)); + remHelper->Install(); By configuring the attributes of the ``RadioEnvironmentMapHelper`` object as shown above, you can tune the parameters of the REM to be @@ -770,15 +769,15 @@ correspondingly the generation of the CQIs. The first one is based on the GSoC m and works per RB basis. This model can be activated with the ns3 attribute system, as presented in the following:: - Config::SetDefault ("ns3::LteAmc::AmcModel", EnumValue (LteAmc::PiroEW2010)); + Config::SetDefault("ns3::LteAmc::AmcModel", EnumValue(LteAmc::PiroEW2010)); While, the solution based on the physical error model can be controlled with:: - Config::SetDefault ("ns3::LteAmc::AmcModel", EnumValue (LteAmc::MiErrorModel)); + Config::SetDefault("ns3::LteAmc::AmcModel", EnumValue(LteAmc::MiErrorModel)); -Finally, the required efficiency of the ``PiroEW2010`` AMC module can be tuned thanks to the ``Ber`` attribute (), for instance:: +Finally, the required efficiency of the ``PiroEW2010`` AMC module can be tuned thanks to the ``Ber`` attribute(), for instance:: - Config::SetDefault ("ns3::LteAmc::Ber", DoubleValue (0.00005)); + Config::SetDefault("ns3::LteAmc::Ber", DoubleValue(0.00005)); @@ -804,12 +803,12 @@ this example we will consider ``PointToPointEpcHelper``, which implements an EPC based on point-to-point links. To use it, you need first to insert this code in your simulation program:: - Ptr lteHelper = CreateObject (); - Ptr epcHelper = CreateObject (); + Ptr lteHelper = CreateObject(); + Ptr epcHelper = CreateObject(); Then, you need to tell the LTE helper that the EPC will be used:: - lteHelper->SetEpcHelper (epcHelper); + lteHelper->SetEpcHelper(epcHelper); the above step is necessary so that the LTE helper will trigger the appropriate EPC configuration in correspondence with some important @@ -819,7 +818,7 @@ automatically take care of the necessary setup, such as S1 link creation and S1 bearer setup. All this will be done without the intervention of the user. -Calling ``lteHelper->SetEpcHelper (epcHelper)`` enables the use of +Calling ``lteHelper->SetEpcHelper(epcHelper)`` enables the use of EPC, and has the side effect that any new ``LteEnbRrc`` that is created will have the ``EpsBearerToRlcMapping`` attribute set to ``RLC_UM_ALWAYS`` instead of ``RLC_SM_ALWAYS`` if the latter was @@ -834,33 +833,33 @@ IPv4/IPv6 networks (e.g., the internet, another EPC). Here is a very simple example about how to connect a single remote host (IPv4 type) to the PGW via a point-to-point link:: - Ptr pgw = epcHelper->GetPgwNode (); + Ptr pgw = epcHelper->GetPgwNode(); // Create a single RemoteHost NodeContainer remoteHostContainer; - remoteHostContainer.Create (1); - Ptr remoteHost = remoteHostContainer.Get (0); + remoteHostContainer.Create(1); + Ptr remoteHost = remoteHostContainer.Get(0); InternetStackHelper internet; - internet.Install (remoteHostContainer); + internet.Install(remoteHostContainer); // Create the internet PointToPointHelper p2ph; - p2ph.SetDeviceAttribute ("DataRate", DataRateValue (DataRate ("100Gb/s"))); - p2ph.SetDeviceAttribute ("Mtu", UintegerValue (1500)); - p2ph.SetChannelAttribute ("Delay", TimeValue (Seconds (0.010))); - NetDeviceContainer internetDevices = p2ph.Install (pgw, remoteHost); + p2ph.SetDeviceAttribute("DataRate", DataRateValue(DataRate("100Gb/s"))); + p2ph.SetDeviceAttribute("Mtu", UintegerValue(1500)); + p2ph.SetChannelAttribute("Delay", TimeValue(Seconds(0.010))); + NetDeviceContainer internetDevices = p2ph.Install(pgw, remoteHost); Ipv4AddressHelper ipv4h; - ipv4h.SetBase ("1.0.0.0", "255.0.0.0"); - Ipv4InterfaceContainer internetIpIfaces = ipv4h.Assign (internetDevices); + ipv4h.SetBase("1.0.0.0", "255.0.0.0"); + Ipv4InterfaceContainer internetIpIfaces = ipv4h.Assign(internetDevices); // interface 0 is localhost, 1 is the p2p device - Ipv4Address remoteHostAddr = internetIpIfaces.GetAddress (1); + Ipv4Address remoteHostAddr = internetIpIfaces.GetAddress(1); Ipv4StaticRoutingHelper ipv4RoutingHelper; Ptr remoteHostStaticRouting; - remoteHostStaticRouting = ipv4RoutingHelper.GetStaticRouting (remoteHost->GetObject ()); - remoteHostStaticRouting->AddNetworkRouteTo (epcHelper->GetEpcIpv4NetworkAddress (), - Ipv4Mask ("255.255.0.0"), 1); + remoteHostStaticRouting = ipv4RoutingHelper.GetStaticRouting(remoteHost->GetObject()); + remoteHostStaticRouting->AddNetworkRouteTo(epcHelper->GetEpcIpv4NetworkAddress(), + Ipv4Mask("255.255.0.0"), 1); Now, you should go on and create LTE eNBs and UEs as explained in the previous sections. You can of course configure other LTE aspects such @@ -874,49 +873,49 @@ follows. We assume you have a container for UE and eNodeB nodes like this:: to configure an LTE-only simulation, you would then normally do something like this:: - NetDeviceContainer ueLteDevs = lteHelper->InstallUeDevice (ueNodes); - lteHelper->Attach (ueLteDevs, enbLteDevs.Get (0)); + NetDeviceContainer ueLteDevs = lteHelper->InstallUeDevice(ueNodes); + lteHelper->Attach(ueLteDevs, enbLteDevs.Get(0)); in order to configure the UEs for IP networking, you just need to additionally do like this:: // we install the IP stack on the UEs InternetStackHelper internet; - internet.Install (ueNodes); + internet.Install(ueNodes); // assign IP address to UEs - for (uint32_t u = 0; u < ueNodes.GetN (); ++u) + for (uint32_t u = 0; u < ueNodes.GetN(); ++u) { - Ptr ue = ueNodes.Get (u); - Ptr ueLteDevice = ueLteDevs.Get (u); + Ptr ue = ueNodes.Get(u); + Ptr ueLteDevice = ueLteDevs.Get(u); Ipv4InterfaceContainer ueIpIface; - ueIpIface = epcHelper->AssignUeIpv4Address (NetDeviceContainer (ueLteDevice)); + ueIpIface = epcHelper->AssignUeIpv4Address(NetDeviceContainer(ueLteDevice)); // set the default gateway for the UE Ptr ueStaticRouting; - ueStaticRouting = ipv4RoutingHelper.GetStaticRouting (ue->GetObject ()); - ueStaticRouting->SetDefaultRoute (epcHelper->GetUeDefaultGatewayAddress (), 1); + ueStaticRouting = ipv4RoutingHelper.GetStaticRouting(ue->GetObject()); + ueStaticRouting->SetDefaultRoute(epcHelper->GetUeDefaultGatewayAddress(), 1); } The activation of bearers is done in a slightly different way with respect to what done for an LTE-only simulation. First, the method ActivateDataRadioBearer is not to be used when the EPC is used. Second, when EPC is used, the default EPS bearer will be -activated automatically when you call ``LteHelper::Attach ()``. Third, if +activated automatically when you call ``LteHelper::Attach()``. Third, if you want to setup dedicated EPS bearer, you can do so using the method -``LteHelper::ActivateDedicatedEpsBearer ()``. This method takes as a -parameter the Traffic Flow Template (TFT), which is a struct that +``LteHelper::ActivateDedicatedEpsBearer()``. This method takes as a +parameter the Traffic Flow Template(TFT), which is a struct that identifies the type of traffic that will be mapped to the dedicated EPS bearer. Here is an example for how to setup a dedicated bearer for an application at the UE communicating on port 1234:: - Ptr tft = Create (); + Ptr tft = Create(); EpcTft::PacketFilter pf; pf.localPortStart = 1234; pf.localPortEnd = 1234; - tft->Add (pf); - lteHelper->ActivateDedicatedEpsBearer (ueLteDevs, - EpsBearer (EpsBearer::NGBR_VIDEO_TCP_DEFAULT), - tft); + tft->Add(pf); + lteHelper->ActivateDedicatedEpsBearer(ueLteDevs, + EpsBearer(EpsBearer::NGBR_VIDEO_TCP_DEFAULT), + tft); you can of course use custom EpsBearer and EpcTft configurations, please refer to the doxygen documentation for how to do it. @@ -930,18 +929,18 @@ UdpClient application on the remote host, and a PacketSink on the LTE UE (using the same variable names of the previous code snippets) :: uint16_t dlPort = 1234; - PacketSinkHelper packetSinkHelper ("ns3::UdpSocketFactory", - InetSocketAddress (Ipv4Address::GetAny (), dlPort)); - ApplicationContainer serverApps = packetSinkHelper.Install (ue); - serverApps.Start (Seconds (0.01)); - UdpClientHelper client (ueIpIface.GetAddress (0), dlPort); - ApplicationContainer clientApps = client.Install (remoteHost); - clientApps.Start (Seconds (0.01)); + PacketSinkHelper packetSinkHelper("ns3::UdpSocketFactory", + InetSocketAddress(Ipv4Address::GetAny(), dlPort)); + ApplicationContainer serverApps = packetSinkHelper.Install(ue); + serverApps.Start(Seconds(0.01)); + UdpClientHelper client(ueIpIface.GetAddress(0), dlPort); + ApplicationContainer clientApps = client.Install(remoteHost); + clientApps.Start(Seconds(0.01)); That's all! You can now start your simulation as usual:: - Simulator::Stop (Seconds (10.0)); - Simulator::Run (); + Simulator::Stop(Seconds(10.0)); + Simulator::Run(); @@ -950,10 +949,10 @@ Using the EPC with emulation mode In the previous section we used PointToPoint links for the connection between the eNBs and the SGW (S1-U interface) and among eNBs (X2-U and X2-C interfaces). The LTE module supports using emulated links instead of PointToPoint links. This is achieved by just replacing the creation of ``LteHelper`` and ``EpcHelper`` with the following code:: - Ptr lteHelper = CreateObject (); - Ptr epcHelper = CreateObject (); - lteHelper->SetEpcHelper (epcHelper); - epcHelper->Initialize (); + Ptr lteHelper = CreateObject(); + Ptr epcHelper = CreateObject(); + lteHelper->SetEpcHelper(epcHelper); + epcHelper->Initialize(); The attributes ``ns3::EmuEpcHelper::sgwDeviceName`` and ``ns3::EmuEpcHelper::enbDeviceName`` are used to set the name of the devices used for transporting the S1-U, X2-U and X2-C interfaces at the SGW and eNB, respectively. We will now show how this is done in an example where we execute the example program ``lena-simple-epc-emu`` using two virtual ethernet interfaces. @@ -1054,13 +1053,13 @@ First of all, in addition to ``LteHelper``, you need to use the ``NoBackhaulEpcH implements an EPC but without connecting the eNBs with the core network. It just creates the network elements of the core network:: - Ptr lteHelper = CreateObject (); - Ptr epcHelper = CreateObject (); + Ptr lteHelper = CreateObject(); + Ptr epcHelper = CreateObject(); Then, as usual, you need to tell the LTE helper that the EPC will be used:: - lteHelper->SetEpcHelper (epcHelper); + lteHelper->SetEpcHelper(epcHelper); Now, you should create the backhaul network. Here we create point-to-point links as it is done @@ -1070,68 +1069,68 @@ by the ``PointToPointEpcHelper``. We assume you have a container for eNB nodes l We get the SGW node:: - Ptr sgw = epcHelper->GetSgwNode (); + Ptr sgw = epcHelper->GetSgwNode(); And we connect every eNB from the container with the SGW with a point-to-point link. We also assign -IPv4 addresses to the interfaces of eNB and SGW with ``s1uIpv4AddressHelper.Assign (sgwEnbDevices)`` +IPv4 addresses to the interfaces of eNB and SGW with ``s1uIpv4AddressHelper.Assign(sgwEnbDevices)`` and finally we tell the EpcHelper that this ``enb`` has a new S1 interface with -``epcHelper->AddS1Interface (enb, enbS1uAddress, sgwS1uAddress)``, where ``enbS1uAddress`` and +``epcHelper->AddS1Interface(enb, enbS1uAddress, sgwS1uAddress)``, where ``enbS1uAddress`` and ``sgwS1uAddress`` are the IPv4 addresses of the eNB and the SGW, respectively:: Ipv4AddressHelper s1uIpv4AddressHelper; // Create networks of the S1 interfaces - s1uIpv4AddressHelper.SetBase ("10.0.0.0", "255.255.255.252"); + s1uIpv4AddressHelper.SetBase("10.0.0.0", "255.255.255.252"); - for (uint16_t i = 0; i < enbNodes.GetN (); ++i) + for (uint16_t i = 0; i < enbNodes.GetN(); ++i) { - Ptr enb = enbNodes.Get (i); + Ptr enb = enbNodes.Get(i); // Create a point to point link between the eNB and the SGW with // the corresponding new NetDevices on each side PointToPointHelper p2ph; - DataRate s1uLinkDataRate = DataRate ("10Gb/s"); + DataRate s1uLinkDataRate = DataRate("10Gb/s"); uint16_t s1uLinkMtu = 2000; - Time s1uLinkDelay = Time (0); - p2ph.SetDeviceAttribute ("DataRate", DataRateValue (s1uLinkDataRate)); - p2ph.SetDeviceAttribute ("Mtu", UintegerValue (s1uLinkMtu)); - p2ph.SetChannelAttribute ("Delay", TimeValue (s1uLinkDelay)); - NetDeviceContainer sgwEnbDevices = p2ph.Install (sgw, enb); + Time s1uLinkDelay = Time(0); + p2ph.SetDeviceAttribute("DataRate", DataRateValue(s1uLinkDataRate)); + p2ph.SetDeviceAttribute("Mtu", UintegerValue(s1uLinkMtu)); + p2ph.SetChannelAttribute("Delay", TimeValue(s1uLinkDelay)); + NetDeviceContainer sgwEnbDevices = p2ph.Install(sgw, enb); - Ipv4InterfaceContainer sgwEnbIpIfaces = s1uIpv4AddressHelper.Assign (sgwEnbDevices); - s1uIpv4AddressHelper.NewNetwork (); + Ipv4InterfaceContainer sgwEnbIpIfaces = s1uIpv4AddressHelper.Assign(sgwEnbDevices); + s1uIpv4AddressHelper.NewNetwork(); - Ipv4Address sgwS1uAddress = sgwEnbIpIfaces.GetAddress (0); - Ipv4Address enbS1uAddress = sgwEnbIpIfaces.GetAddress (1); + Ipv4Address sgwS1uAddress = sgwEnbIpIfaces.GetAddress(0); + Ipv4Address enbS1uAddress = sgwEnbIpIfaces.GetAddress(1); // Create S1 interface between the SGW and the eNB - epcHelper->AddS1Interface (enb, enbS1uAddress, sgwS1uAddress); + epcHelper->AddS1Interface(enb, enbS1uAddress, sgwS1uAddress); } This is just an example how to create a custom backhaul network. In this other example, we connect all eNBs and the SGW to the same CSMA network:: // Create networks of the S1 interfaces - s1uIpv4AddressHelper.SetBase ("10.0.0.0", "255.255.255.0"); + s1uIpv4AddressHelper.SetBase("10.0.0.0", "255.255.255.0"); NodeContainer sgwEnbNodes; - sgwEnbNodes.Add (sgw); - sgwEnbNodes.Add (enbNodes); + sgwEnbNodes.Add(sgw); + sgwEnbNodes.Add(enbNodes); CsmaHelper csmah; - NetDeviceContainer sgwEnbDevices = csmah.Install (sgwEnbNodes); - Ptr sgwDev = sgwEnbDevices.Get (0); + NetDeviceContainer sgwEnbDevices = csmah.Install(sgwEnbNodes); + Ptr sgwDev = sgwEnbDevices.Get(0); - Ipv4InterfaceContainer sgwEnbIpIfaces = s1uIpv4AddressHelper.Assign (sgwEnbDevices); - Ipv4Address sgwS1uAddress = sgwEnbIpIfaces.GetAddress (0); + Ipv4InterfaceContainer sgwEnbIpIfaces = s1uIpv4AddressHelper.Assign(sgwEnbDevices); + Ipv4Address sgwS1uAddress = sgwEnbIpIfaces.GetAddress(0); - for (uint16_t i = 0; i < enbNodes.GetN (); ++i) + for (uint16_t i = 0; i < enbNodes.GetN(); ++i) { - Ptr enb = enbNodes.Get (i); - Ipv4Address enbS1uAddress = sgwEnbIpIfaces.GetAddress (i + 1); + Ptr enb = enbNodes.Get(i); + Ipv4Address enbS1uAddress = sgwEnbIpIfaces.GetAddress(i + 1); // Create S1 interface between the SGW and the eNB - epcHelper->AddS1Interface (enb, enbS1uAddress, sgwS1uAddress); + epcHelper->AddS1Interface(enb, enbS1uAddress, sgwS1uAddress); } As you can see, apart from how you create the backhaul network, i.e. the point-to-point links or @@ -1163,7 +1162,7 @@ This method uses the ``LteHelper::Attach`` function mentioned above. It has been the only available network attachment method in earlier versions of LTE module. It is typically invoked before the simulation begins:: - lteHelper->Attach (ueDevs, enbDev); // attach one or more UEs to a single eNodeB + lteHelper->Attach(ueDevs, enbDev); // attach one or more UEs to a single eNodeB ``LteHelper::InstallEnbDevice`` and ``LteHelper::InstallUeDevice`` functions must have been called before attaching. In an EPC-enabled simulation, it is also @@ -1196,7 +1195,7 @@ the best cell to attach to. The use of this criterion is implemented in the `initial cell selection` process, which can be invoked by calling another version of the ``LteHelper::Attach`` function, as shown below:: - lteHelper->Attach (ueDevs); // attach one or more UEs to a strongest cell + lteHelper->Attach(ueDevs); // attach one or more UEs to a strongest cell The difference with the manual method is that the destination eNodeB is not specified. The procedure will find the best cell for the UEs, based on several @@ -1226,19 +1225,19 @@ same CSG ID. This is done through the attributes in both eNodeB and UE, for example using the following ``LteHelper`` functions:: // label the following eNodeBs with CSG identity of 1 and CSG indication enabled - lteHelper->SetEnbDeviceAttribute ("CsgId", UintegerValue (1)); - lteHelper->SetEnbDeviceAttribute ("CsgIndication", BooleanValue (true)); + lteHelper->SetEnbDeviceAttribute("CsgId", UintegerValue(1)); + lteHelper->SetEnbDeviceAttribute("CsgIndication", BooleanValue(true)); // label one or more UEs with CSG identity of 1 - lteHelper->SetUeDeviceAttribute ("CsgId", UintegerValue (1)); + lteHelper->SetUeDeviceAttribute("CsgId", UintegerValue(1)); // install the eNodeBs and UEs - NetDeviceContainer csgEnbDevs = lteHelper->InstallEnbDevice (csgEnbNodes); - NetDeviceContainer csgUeDevs = lteHelper->InstallUeDevice (csgUeNodes); + NetDeviceContainer csgEnbDevs = lteHelper->InstallEnbDevice(csgEnbNodes); + NetDeviceContainer csgUeDevs = lteHelper->InstallUeDevice(csgUeNodes); Then enable the initial cell selection procedure on the UEs:: - lteHelper->Attach (csgUeDevs); + lteHelper->Attach(csgUeDevs); This is necessary because the CSG restriction only works with automatic method of network attachment, but not in the manual method. @@ -1294,18 +1293,18 @@ within the container ``devs``:: std::vector measIdList; NetDeviceContainer::Iterator it; - for (it = devs.Begin (); it != devs.End (); it++) + for (it = devs.Begin(); it != devs.End(); it++) { Ptr dev = *it; - Ptr enbDev = dev->GetObject (); - Ptr enbRrc = enbDev->GetRrc (); + Ptr enbDev = dev->GetObject(); + Ptr enbRrc = enbDev->GetRrc(); - uint8_t measId = enbRrc->AddUeMeasReportConfig (config); - measIdList.push_back (measId); // remember the measId created + uint8_t measId = enbRrc->AddUeMeasReportConfig(config); + measIdList.push_back(measId); // remember the measId created - enbRrc->TraceConnect ("RecvMeasurementReport", - "context", - MakeCallback (&RecvMeasurementReportCallback)); + enbRrc->TraceConnect("RecvMeasurementReport", + "context", + MakeCallback(&RecvMeasurementReportCallback)); } Note that thresholds are expressed as range. In the example above, the range 41 @@ -1316,11 +1315,11 @@ class has several static functions that can be used for this purpose. The corresponding callback function would have a definition similar as below:: void - RecvMeasurementReportCallback (std::string context, - uint64_t imsi, - uint16_t cellId, - uint16_t rnti, - LteRrcSap::MeasurementReport measReport); + RecvMeasurementReportCallback(std::string context, + uint64_t imsi, + uint16_t cellId, + uint16_t rnti, + LteRrcSap::MeasurementReport measReport); This method will register the callback function as a consumer of UE measurements. In the case where there are more than one consumers in the @@ -1371,7 +1370,7 @@ simulation (see :ref:`sec-evolved-packet-core`). Secondly, an X2 interface must be configured between the two eNodeBs, which needs to be done explicitly within the simulation program:: - lteHelper->AddX2Interface (enbNodes); + lteHelper->AddX2Interface(enbNodes); where ``enbNodes`` is a ``NodeContainer`` that contains the two eNodeBs between which the X2 interface is to be configured. If the container has more than two @@ -1402,10 +1401,10 @@ is to be handed over, and that ``enbLteDevs`` is another ``NetDeviceContainer`` that contains the source and the target eNB. Then, a handover at 0.1s can be scheduled like this:: - lteHelper->HandoverRequest (Seconds (0.100), - ueLteDevs.Get (0), - enbLteDevs.Get (0), - enbLteDevs.Get (1)); + lteHelper->HandoverRequest(Seconds(0.100), + ueLteDevs.Get(0), + enbLteDevs.Get(0), + enbLteDevs.Get(1)); Note that the UE needs to be already connected to the source eNB, otherwise the simulation will terminate with an error message. @@ -1430,16 +1429,16 @@ Design Documentation. Selecting a handover algorithm is done via the ``LteHelper`` object and its ``SetHandoverAlgorithmType`` method as shown below:: - Ptr lteHelper = CreateObject (); - lteHelper->SetHandoverAlgorithmType ("ns3::A2A4RsrqHandoverAlgorithm"); + Ptr lteHelper = CreateObject(); + lteHelper->SetHandoverAlgorithmType("ns3::A2A4RsrqHandoverAlgorithm"); The selected handover algorithm may also provide several configurable attributes, which can be set as follows:: - lteHelper->SetHandoverAlgorithmAttribute ("ServingCellThreshold", - UintegerValue (30)); - lteHelper->SetHandoverAlgorithmAttribute ("NeighbourCellOffset", - UintegerValue (1)); + lteHelper->SetHandoverAlgorithmAttribute("ServingCellThreshold", + UintegerValue(30)); + lteHelper->SetHandoverAlgorithmAttribute("NeighbourCellOffset", + UintegerValue(1)); Three options of handover algorithm are included in the LTE module. The *A2-A4-RSRQ* handover algorithm (named as ``ns3::A2A4RsrqHandoverAlgorithm``) is @@ -1449,11 +1448,11 @@ Another option is the *strongest cell* handover algorithm (named as ``ns3::A3RsrpHandoverAlgorithm``), which can be selected and configured by the following code:: - lteHelper->SetHandoverAlgorithmType ("ns3::A3RsrpHandoverAlgorithm"); - lteHelper->SetHandoverAlgorithmAttribute ("Hysteresis", - DoubleValue (3.0)); - lteHelper->SetHandoverAlgorithmAttribute ("TimeToTrigger", - TimeValue (MilliSeconds (256))); + lteHelper->SetHandoverAlgorithmType("ns3::A3RsrpHandoverAlgorithm"); + lteHelper->SetHandoverAlgorithmAttribute("Hysteresis", + DoubleValue(3.0)); + lteHelper->SetHandoverAlgorithmAttribute("TimeToTrigger", + TimeValue(MilliSeconds(256))); The last option is a special one, called the *no-op* handover algorithm, which basically disables automatic handover trigger. This is useful for example in @@ -1461,7 +1460,7 @@ cases where manual handover trigger need an exclusive control of all handover decision. It does not have any configurable attributes. The usage is as follows:: - lteHelper->SetHandoverAlgorithmType ("ns3::NoOpHandoverAlgorithm"); + lteHelper->SetHandoverAlgorithmType("ns3::NoOpHandoverAlgorithm"); For more information on each handover algorithm's decision policy and their attributes, please refer to their respective subsections in Section @@ -1472,7 +1471,7 @@ instance of the selected handover algorithm for each eNodeB device. In other words, make sure to select the right handover algorithm before finalizing it in the following line of code:: - NetDeviceContainer enbLteDevs = lteHelper->InstallEnbDevice (enbNodes); + NetDeviceContainer enbLteDevs = lteHelper->InstallEnbDevice(enbNodes); Example with full source code of using automatic handover trigger can be found in the ``lena-x2-handover-measures`` example program. @@ -1526,8 +1525,8 @@ successfully, regardless of distance and channel condition. However, it will also affect all other data or control packets not related to handover, which may be an unwanted side effect. Otherwise, it can be done as follows:: - Config::SetDefault ("ns3::LteSpectrumPhy::CtrlErrorModelEnabled", BooleanValue (false)); - Config::SetDefault ("ns3::LteSpectrumPhy::DataErrorModelEnabled", BooleanValue (false)); + Config::SetDefault("ns3::LteSpectrumPhy::CtrlErrorModelEnabled", BooleanValue(false)); + Config::SetDefault("ns3::LteSpectrumPhy::DataErrorModelEnabled", BooleanValue(false)); By using the above code, we disable the error model in both control and data channels and in both directions (downlink and uplink). This is necessary because @@ -1550,13 +1549,13 @@ handover execution phase at both the UE and eNB side. As an example, in your simulation program you can declare the following methods:: void - NotifyHandoverStartUe (std::string context, - uint64_t imsi, - uint16_t cellId, - uint16_t rnti, - uint16_t targetCellId) + NotifyHandoverStartUe(std::string context, + uint64_t imsi, + uint16_t cellId, + uint16_t rnti, + uint16_t targetCellId) { - std::cout << Simulator::Now ().GetSeconds () << " " << context + std::cout << Simulator::Now().GetSeconds() << " " << context << " UE IMSI " << imsi << ": previously connected to CellId " << cellId << " with RNTI " << rnti @@ -1565,12 +1564,12 @@ in your simulation program you can declare the following methods:: } void - NotifyHandoverEndOkUe (std::string context, - uint64_t imsi, - uint16_t cellId, - uint16_t rnti) + NotifyHandoverEndOkUe(std::string context, + uint64_t imsi, + uint16_t cellId, + uint16_t rnti) { - std::cout << Simulator::Now ().GetSeconds () << " " << context + std::cout << Simulator::Now().GetSeconds() << " " << context << " UE IMSI " << imsi << ": successful handover to CellId " << cellId << " with RNTI " << rnti @@ -1578,13 +1577,13 @@ in your simulation program you can declare the following methods:: } void - NotifyHandoverStartEnb (std::string context, - uint64_t imsi, - uint16_t cellId, - uint16_t rnti, - uint16_t targetCellId) + NotifyHandoverStartEnb(std::string context, + uint64_t imsi, + uint16_t cellId, + uint16_t rnti, + uint16_t targetCellId) { - std::cout << Simulator::Now ().GetSeconds () << " " << context + std::cout << Simulator::Now().GetSeconds() << " " << context << " eNB CellId " << cellId << ": start handover of UE with IMSI " << imsi << " RNTI " << rnti @@ -1593,12 +1592,12 @@ in your simulation program you can declare the following methods:: } void - NotifyHandoverEndOkEnb (std::string context, - uint64_t imsi, - uint16_t cellId, - uint16_t rnti) + NotifyHandoverEndOkEnb(std::string context, + uint64_t imsi, + uint16_t cellId, + uint16_t rnti) { - std::cout << Simulator::Now ().GetSeconds () << " " << context + std::cout << Simulator::Now().GetSeconds() << " " << context << " eNB CellId " << cellId << ": completed handover of UE with IMSI " << imsi << " RNTI " << rnti @@ -1608,17 +1607,17 @@ in your simulation program you can declare the following methods:: Then, you can hook up these methods to the corresponding trace sources like this:: - Config::Connect ("/NodeList/*/DeviceList/*/LteEnbRrc/HandoverStart", - MakeCallback (&NotifyHandoverStartEnb)); - Config::Connect ("/NodeList/*/DeviceList/*/LteUeRrc/HandoverStart", - MakeCallback (&NotifyHandoverStartUe)); - Config::Connect ("/NodeList/*/DeviceList/*/LteEnbRrc/HandoverEndOk", - MakeCallback (&NotifyHandoverEndOkEnb)); - Config::Connect ("/NodeList/*/DeviceList/*/LteUeRrc/HandoverEndOk", - MakeCallback (&NotifyHandoverEndOkUe)); + Config::Connect("/NodeList/*/DeviceList/*/LteEnbRrc/HandoverStart", + MakeCallback(&NotifyHandoverStartEnb)); + Config::Connect("/NodeList/*/DeviceList/*/LteUeRrc/HandoverStart", + MakeCallback(&NotifyHandoverStartUe)); + Config::Connect("/NodeList/*/DeviceList/*/LteEnbRrc/HandoverEndOk", + MakeCallback(&NotifyHandoverEndOkEnb)); + Config::Connect("/NodeList/*/DeviceList/*/LteUeRrc/HandoverEndOk", + MakeCallback(&NotifyHandoverEndOkUe)); Handover failure events can also be traced by trace sink functions with -a similar signature as above (including IMSI, cell ID, and RNTI). Four +a similar signature as above(including IMSI, cell ID, and RNTI). Four different failure events are traced: 1. HandoverFailureNoPreamble: Handover failure due to non allocation of @@ -1630,14 +1629,14 @@ different failure events are traced: Similarly, one can hook up methods to the corresponding trace sources like this:: - Config::Connect ("/NodeList/*/DeviceList/*/LteEnbRrc/HandoverFailureNoPreamble", - MakeCallback (&NotifyHandoverFailureNoPreamble)); - Config::Connect ("/NodeList/*/DeviceList/*/LteEnbRrc/HandoverFailureMaxRach", - MakeCallback (&NotifyHandoverFailureMaxRach)); - Config::Connect ("/NodeList/*/DeviceList/*/LteEnbRrc/HandoverFailureLeaving", - MakeCallback (&NotifyHandoverFailureLeaving)); - Config::Connect ("/NodeList/*/DeviceList/*/LteEnbRrc/HandoverFailureJoining", - MakeCallback (&NotifyHandoverFailureJoining)); + Config::Connect("/NodeList/*/DeviceList/*/LteEnbRrc/HandoverFailureNoPreamble", + MakeCallback(&NotifyHandoverFailureNoPreamble)); + Config::Connect("/NodeList/*/DeviceList/*/LteEnbRrc/HandoverFailureMaxRach", + MakeCallback(&NotifyHandoverFailureMaxRach)); + Config::Connect("/NodeList/*/DeviceList/*/LteEnbRrc/HandoverFailureLeaving", + MakeCallback(&NotifyHandoverFailureLeaving)); + Config::Connect("/NodeList/*/DeviceList/*/LteEnbRrc/HandoverFailureJoining", + MakeCallback(&NotifyHandoverFailureJoining)); The example program ``src/lte/examples/lena-x2-handover.cc`` illustrates how the above instructions can be integrated in a @@ -1695,8 +1694,8 @@ seven FR algorithms are implemented: Selecting a FR algorithm is done via the ``LteHelper`` object and its ``SetFfrAlgorithmType`` method as shown below:: - Ptr lteHelper = CreateObject (); - lteHelper->SetFfrAlgorithmType ("ns3::LteFrHardAlgorithm"); + Ptr lteHelper = CreateObject(); + lteHelper->SetFfrAlgorithmType("ns3::LteFrHardAlgorithm"); Each implemented FR algorithm provide several configurable attributes. Users do not have to care about UL and DL bandwidth configuration, because it is done @@ -1704,8 +1703,8 @@ automatically during cell configuration. To change bandwidth for FR algorithm, configure required values for ``LteEnbNetDevice``:: uint8_t bandwidth = 100; - lteHelper->SetEnbDeviceAttribute ("DlBandwidth", UintegerValue (bandwidth)); - lteHelper->SetEnbDeviceAttribute ("UlBandwidth", UintegerValue (bandwidth)); + lteHelper->SetEnbDeviceAttribute("DlBandwidth", UintegerValue(bandwidth)); + lteHelper->SetEnbDeviceAttribute("UlBandwidth", UintegerValue(bandwidth)); Now, each FR algorithms configuration will be described. @@ -1726,12 +1725,12 @@ Hard Frequency Reuse Algorithm provides following attributes: Example configuration of LteFrHardAlgorithm can be done in following way:: - lteHelper->SetFfrAlgorithmType ("ns3::LteFrHardAlgorithm"); - lteHelper->SetFfrAlgorithmAttribute ("DlSubBandOffset", UintegerValue (8)); - lteHelper->SetFfrAlgorithmAttribute ("DlSubBandwidth", UintegerValue (8)); - lteHelper->SetFfrAlgorithmAttribute ("UlSubBandOffset", UintegerValue (8)); - lteHelper->SetFfrAlgorithmAttribute ("UlSubBandwidth", UintegerValue (8)); - NetDeviceContainer enbDevs = lteHelper->InstallEnbDevice (enbNodes.Get(0)); + lteHelper->SetFfrAlgorithmType("ns3::LteFrHardAlgorithm"); + lteHelper->SetFfrAlgorithmAttribute("DlSubBandOffset", UintegerValue(8)); + lteHelper->SetFfrAlgorithmAttribute("DlSubBandwidth", UintegerValue(8)); + lteHelper->SetFfrAlgorithmAttribute("UlSubBandOffset", UintegerValue(8)); + lteHelper->SetFfrAlgorithmAttribute("UlSubBandwidth", UintegerValue(8)); + NetDeviceContainer enbDevs = lteHelper->InstallEnbDevice(enbNodes.Get(0)); Above example allow eNB to use only RBs from 8 to 16 in DL and UL, while entire cell bandwidth is 25. @@ -1765,21 +1764,21 @@ Example below allow eNB to use RBs from 0 to 6 as common sub-band and from 12 to private sub-band in DL and UL, RSRQ threshold is 20 dB, power in center area equals ``LteEnbPhy::TxPower - 3dB``, power in edge area equals ``LteEnbPhy::TxPower + 3dB``:: - lteHelper->SetFfrAlgorithmType ("ns3::LteFrStrictAlgorithm"); - lteHelper->SetFfrAlgorithmAttribute ("DlCommonSubBandwidth", UintegerValue (6)); - lteHelper->SetFfrAlgorithmAttribute ("UlCommonSubBandwidth", UintegerValue (6)); - lteHelper->SetFfrAlgorithmAttribute ("DlEdgeSubBandOffset", UintegerValue (6)); - lteHelper->SetFfrAlgorithmAttribute ("DlEdgeSubBandwidth", UintegerValue (6)); - lteHelper->SetFfrAlgorithmAttribute ("UlEdgeSubBandOffset", UintegerValue (6)); - lteHelper->SetFfrAlgorithmAttribute ("UlEdgeSubBandwidth", UintegerValue (6)); - lteHelper->SetFfrAlgorithmAttribute ("RsrqThreshold", UintegerValue (20)); - lteHelper->SetFfrAlgorithmAttribute ("CenterPowerOffset", - UintegerValue (LteRrcSap::PdschConfigDedicated::dB_3)); - lteHelper->SetFfrAlgorithmAttribute ("EdgePowerOffset", - UintegerValue (LteRrcSap::PdschConfigDedicated::dB3)); - lteHelper->SetFfrAlgorithmAttribute ("CenterAreaTpc", UintegerValue (1)); - lteHelper->SetFfrAlgorithmAttribute ("EdgeAreaTpc", UintegerValue (2)); - NetDeviceContainer enbDevs = lteHelper->InstallEnbDevice (enbNodes.Get(0)); + lteHelper->SetFfrAlgorithmType("ns3::LteFrStrictAlgorithm"); + lteHelper->SetFfrAlgorithmAttribute("DlCommonSubBandwidth", UintegerValue(6)); + lteHelper->SetFfrAlgorithmAttribute("UlCommonSubBandwidth", UintegerValue(6)); + lteHelper->SetFfrAlgorithmAttribute("DlEdgeSubBandOffset", UintegerValue(6)); + lteHelper->SetFfrAlgorithmAttribute("DlEdgeSubBandwidth", UintegerValue(6)); + lteHelper->SetFfrAlgorithmAttribute("UlEdgeSubBandOffset", UintegerValue(6)); + lteHelper->SetFfrAlgorithmAttribute("UlEdgeSubBandwidth", UintegerValue(6)); + lteHelper->SetFfrAlgorithmAttribute("RsrqThreshold", UintegerValue(20)); + lteHelper->SetFfrAlgorithmAttribute("CenterPowerOffset", + UintegerValue(LteRrcSap::PdschConfigDedicated::dB_3)); + lteHelper->SetFfrAlgorithmAttribute("EdgePowerOffset", + UintegerValue(LteRrcSap::PdschConfigDedicated::dB3)); + lteHelper->SetFfrAlgorithmAttribute("CenterAreaTpc", UintegerValue(1)); + lteHelper->SetFfrAlgorithmAttribute("EdgeAreaTpc", UintegerValue(2)); + NetDeviceContainer enbDevs = lteHelper->InstallEnbDevice(enbNodes.Get(0)); Soft Frequency Reuse Algorithm @@ -1808,18 +1807,18 @@ Example below configures RBs from 8 to 16 to be used by cell edge UEs and this s is not available for cell center users. RSRQ threshold is 20 dB, power in center area equals ``LteEnbPhy::TxPower``, power in edge area equals ``LteEnbPhy::TxPower + 3dB``:: - lteHelper->SetFfrAlgorithmType ("ns3::LteFrSoftAlgorithm"); - lteHelper->SetFfrAlgorithmAttribute ("DlEdgeSubBandOffset", UintegerValue (8)); - lteHelper->SetFfrAlgorithmAttribute ("DlEdgeSubBandwidth", UintegerValue (8)); - lteHelper->SetFfrAlgorithmAttribute ("UlEdgeSubBandOffset", UintegerValue (8)); - lteHelper->SetFfrAlgorithmAttribute ("UlEdgeSubBandwidth", UintegerValue (8)); - lteHelper->SetFfrAlgorithmAttribute ("AllowCenterUeUseEdgeSubBand", BooleanValue (false)); - lteHelper->SetFfrAlgorithmAttribute ("RsrqThreshold", UintegerValue (20)); - lteHelper->SetFfrAlgorithmAttribute ("CenterPowerOffset", - UintegerValue (LteRrcSap::PdschConfigDedicated::dB0)); - lteHelper->SetFfrAlgorithmAttribute ("EdgePowerOffset", - UintegerValue (LteRrcSap::PdschConfigDedicated::dB3)); - NetDeviceContainer enbDevs = lteHelper->InstallEnbDevice (enbNodes.Get(0)); + lteHelper->SetFfrAlgorithmType("ns3::LteFrSoftAlgorithm"); + lteHelper->SetFfrAlgorithmAttribute("DlEdgeSubBandOffset", UintegerValue(8)); + lteHelper->SetFfrAlgorithmAttribute("DlEdgeSubBandwidth", UintegerValue(8)); + lteHelper->SetFfrAlgorithmAttribute("UlEdgeSubBandOffset", UintegerValue(8)); + lteHelper->SetFfrAlgorithmAttribute("UlEdgeSubBandwidth", UintegerValue(8)); + lteHelper->SetFfrAlgorithmAttribute("AllowCenterUeUseEdgeSubBand", BooleanValue(false)); + lteHelper->SetFfrAlgorithmAttribute("RsrqThreshold", UintegerValue(20)); + lteHelper->SetFfrAlgorithmAttribute("CenterPowerOffset", + UintegerValue(LteRrcSap::PdschConfigDedicated::dB0)); + lteHelper->SetFfrAlgorithmAttribute("EdgePowerOffset", + UintegerValue(LteRrcSap::PdschConfigDedicated::dB3)); + NetDeviceContainer enbDevs = lteHelper->InstallEnbDevice(enbNodes.Get(0)); Soft Fractional Frequency Reuse Algorithm @@ -1860,22 +1859,22 @@ and medium area is 28 dB, RSRQ threshold between medium and edge area is 18 dB. Power in center area equals ``LteEnbPhy::TxPower - 3dB``, power in medium area equals ``LteEnbPhy::TxPower + 3dB``, power in edge area equals ``LteEnbPhy::TxPower + 3dB``:: - lteHelper->SetFfrAlgorithmType ("ns3::LteFfrSoftAlgorithm"); - lteHelper->SetFfrAlgorithmAttribute ("UlCommonSubBandwidth", UintegerValue (6)); - lteHelper->SetFfrAlgorithmAttribute ("DlCommonSubBandwidth", UintegerValue (6)); - lteHelper->SetFfrAlgorithmAttribute ("DlEdgeSubBandOffset", UintegerValue (0)); - lteHelper->SetFfrAlgorithmAttribute ("DlEdgeSubBandwidth", UintegerValue (6)); - lteHelper->SetFfrAlgorithmAttribute ("UlEdgeSubBandOffset", UintegerValue (0)); - lteHelper->SetFfrAlgorithmAttribute ("UlEdgeSubBandwidth", UintegerValue (6)); - lteHelper->SetFfrAlgorithmAttribute ("CenterRsrqThreshold", UintegerValue (28)); - lteHelper->SetFfrAlgorithmAttribute ("EdgeRsrqThreshold", UintegerValue (18)); - lteHelper->SetFfrAlgorithmAttribute ("CenterAreaPowerOffset", - UintegerValue (LteRrcSap::PdschConfigDedicated::dB_3)); - lteHelper->SetFfrAlgorithmAttribute ("MediumAreaPowerOffset", - UintegerValue (LteRrcSap::PdschConfigDedicated::dB0)); - lteHelper->SetFfrAlgorithmAttribute ("EdgeAreaPowerOffset", - UintegerValue (LteRrcSap::PdschConfigDedicated::dB3)); - NetDeviceContainer enbDevs = lteHelper->InstallEnbDevice (enbNodes.Get(0)); + lteHelper->SetFfrAlgorithmType("ns3::LteFfrSoftAlgorithm"); + lteHelper->SetFfrAlgorithmAttribute("UlCommonSubBandwidth", UintegerValue(6)); + lteHelper->SetFfrAlgorithmAttribute("DlCommonSubBandwidth", UintegerValue(6)); + lteHelper->SetFfrAlgorithmAttribute("DlEdgeSubBandOffset", UintegerValue(0)); + lteHelper->SetFfrAlgorithmAttribute("DlEdgeSubBandwidth", UintegerValue(6)); + lteHelper->SetFfrAlgorithmAttribute("UlEdgeSubBandOffset", UintegerValue(0)); + lteHelper->SetFfrAlgorithmAttribute("UlEdgeSubBandwidth", UintegerValue(6)); + lteHelper->SetFfrAlgorithmAttribute("CenterRsrqThreshold", UintegerValue(28)); + lteHelper->SetFfrAlgorithmAttribute("EdgeRsrqThreshold", UintegerValue(18)); + lteHelper->SetFfrAlgorithmAttribute("CenterAreaPowerOffset", + UintegerValue(LteRrcSap::PdschConfigDedicated::dB_3)); + lteHelper->SetFfrAlgorithmAttribute("MediumAreaPowerOffset", + UintegerValue(LteRrcSap::PdschConfigDedicated::dB0)); + lteHelper->SetFfrAlgorithmAttribute("EdgeAreaPowerOffset", + UintegerValue(LteRrcSap::PdschConfigDedicated::dB3)); + NetDeviceContainer enbDevs = lteHelper->InstallEnbDevice(enbNodes.Get(0)); Enhanced Fractional Frequency Reuse Algorithm @@ -1921,19 +1920,19 @@ thresholds are set to value of 10. Power in center area equals ``LteEnbPhy::TxPo power in edge area equals ``LteEnbPhy::TxPower + 0dB``:: lteHelper->SetFfrAlgorithmType("ns3::LteFfrEnhancedAlgorithm"); - lteHelper->SetFfrAlgorithmAttribute("RsrqThreshold", UintegerValue (25)); - lteHelper->SetFfrAlgorithmAttribute("DlCqiThreshold", UintegerValue (10)); - lteHelper->SetFfrAlgorithmAttribute("UlCqiThreshold", UintegerValue (10)); + lteHelper->SetFfrAlgorithmAttribute("RsrqThreshold", UintegerValue(25)); + lteHelper->SetFfrAlgorithmAttribute("DlCqiThreshold", UintegerValue(10)); + lteHelper->SetFfrAlgorithmAttribute("UlCqiThreshold", UintegerValue(10)); lteHelper->SetFfrAlgorithmAttribute("CenterAreaPowerOffset", - UintegerValue (LteRrcSap::PdschConfigDedicated::dB_6)); + UintegerValue(LteRrcSap::PdschConfigDedicated::dB_6)); lteHelper->SetFfrAlgorithmAttribute("EdgeAreaPowerOffset", - UintegerValue (LteRrcSap::PdschConfigDedicated::dB0)); - lteHelper->SetFfrAlgorithmAttribute("UlSubBandOffset", UintegerValue (0)); - lteHelper->SetFfrAlgorithmAttribute("UlReuse3SubBandwidth", UintegerValue (4)); - lteHelper->SetFfrAlgorithmAttribute("UlReuse1SubBandwidth", UintegerValue (4)); - lteHelper->SetFfrAlgorithmAttribute("DlSubBandOffset", UintegerValue (0)); - lteHelper->SetFfrAlgorithmAttribute("DlReuse3SubBandwidth", UintegerValue (4)); - lteHelper->SetFfrAlgorithmAttribute("DlReuse1SubBandwidth", UintegerValue (4)); + UintegerValue(LteRrcSap::PdschConfigDedicated::dB0)); + lteHelper->SetFfrAlgorithmAttribute("UlSubBandOffset", UintegerValue(0)); + lteHelper->SetFfrAlgorithmAttribute("UlReuse3SubBandwidth", UintegerValue(4)); + lteHelper->SetFfrAlgorithmAttribute("UlReuse1SubBandwidth", UintegerValue(4)); + lteHelper->SetFfrAlgorithmAttribute("DlSubBandOffset", UintegerValue(0)); + lteHelper->SetFfrAlgorithmAttribute("DlReuse3SubBandwidth", UintegerValue(4)); + lteHelper->SetFfrAlgorithmAttribute("DlReuse1SubBandwidth", UintegerValue(4)); Distributed Fractional Frequency Reuse Algorithm @@ -1971,13 +1970,13 @@ Power in center area equals ``LteEnbPhy::TxPower - 0dB``, power in edge area equ lteHelper->SetFfrAlgorithmType("ns3::LteFfrDistributedAlgorithm"); lteHelper->SetFfrAlgorithmAttribute("CalculationInterval", TimeValue(MilliSeconds(500))); - lteHelper->SetFfrAlgorithmAttribute ("RsrqThreshold", UintegerValue (25)); - lteHelper->SetFfrAlgorithmAttribute ("RsrpDifferenceThreshold", UintegerValue (5)); - lteHelper->SetFfrAlgorithmAttribute ("EdgeRbNum", UintegerValue (6)); - lteHelper->SetFfrAlgorithmAttribute ("CenterPowerOffset", - UintegerValue (LteRrcSap::PdschConfigDedicated::dB0)); - lteHelper->SetFfrAlgorithmAttribute ("EdgePowerOffset", - UintegerValue (LteRrcSap::PdschConfigDedicated::dB3)); + lteHelper->SetFfrAlgorithmAttribute("RsrqThreshold", UintegerValue(25)); + lteHelper->SetFfrAlgorithmAttribute("RsrpDifferenceThreshold", UintegerValue(5)); + lteHelper->SetFfrAlgorithmAttribute("EdgeRbNum", UintegerValue(6)); + lteHelper->SetFfrAlgorithmAttribute("CenterPowerOffset", + UintegerValue(LteRrcSap::PdschConfigDedicated::dB0)); + lteHelper->SetFfrAlgorithmAttribute("EdgePowerOffset", + UintegerValue(LteRrcSap::PdschConfigDedicated::dB3)); Automatic configuration @@ -1999,8 +1998,8 @@ configuration. Example below show automatic FR algorithm configuration:: lteHelper->SetFfrAlgorithmType("ns3::LteFfrSoftAlgorithm"); - lteHelper->SetFfrAlgorithmAttribute("FrCellTypeId", UintegerValue (1)); - NetDeviceContainer enbDevs = lteHelper->InstallEnbDevice (enbNodes.Get(0)); + lteHelper->SetFfrAlgorithmAttribute("FrCellTypeId", UintegerValue(1)); + NetDeviceContainer enbDevs = lteHelper->InstallEnbDevice(enbNodes.Get(0)); Uplink Power Control @@ -2044,10 +2043,10 @@ Traced values in Uplink Power Control: Example configuration is presented below:: - Config::SetDefault ("ns3::LteUePhy::EnableUplinkPowerControl", BooleanValue (true)); - Config::SetDefault ("ns3::LteEnbPhy::TxPower", DoubleValue (30)); - Config::SetDefault ("ns3::LteUePowerControl::ClosedLoop", BooleanValue (true)); - Config::SetDefault ("ns3::LteUePowerControl::AccumulationEnabled", BooleanValue (true)); + Config::SetDefault("ns3::LteUePhy::EnableUplinkPowerControl", BooleanValue(true)); + Config::SetDefault("ns3::LteEnbPhy::TxPower", DoubleValue(30)); + Config::SetDefault("ns3::LteUePowerControl::ClosedLoop", BooleanValue(true)); + Config::SetDefault("ns3::LteUePowerControl::AccumulationEnabled", BooleanValue(true)); As an example, user can take a look and run the lena-uplink-power-control program. @@ -2098,28 +2097,28 @@ Finally, SINR can be obtained by enabling the PHY simulation output. The following sample code snippet shows one possible way to obtain the above:: void - NotifyHandoverEndOkUe (std::string context, uint64_t imsi, - uint16_t cellId, uint16_t rnti) + NotifyHandoverEndOkUe(std::string context, uint64_t imsi, + uint16_t cellId, uint16_t rnti) { std::cout << "Handover IMSI " << imsi << std::endl; } int - main (int argc, char *argv[]) + main(int argc, char *argv[]) { /*** SNIP ***/ - Config::Connect ("/NodeList/*/DeviceList/*/LteUeRrc/HandoverEndOk", - MakeCallback (&NotifyHandoverEndOkUe)); + Config::Connect("/NodeList/*/DeviceList/*/LteUeRrc/HandoverEndOk", + MakeCallback(&NotifyHandoverEndOkUe)); - lteHelper->EnablePhyTraces (); - lteHelper->EnableRlcTraces (); - Ptr rlcStats = lteHelper->GetRlcStats (); - rlcStats->SetAttribute ("StartTime", TimeValue (Seconds (0))); - rlcStats->SetAttribute ("EpochDuration", TimeValue (Seconds (simTime))); + lteHelper->EnablePhyTraces(); + lteHelper->EnableRlcTraces(); + Ptr rlcStats = lteHelper->GetRlcStats(); + rlcStats->SetAttribute("StartTime", TimeValue(Seconds(0))); + rlcStats->SetAttribute("EpochDuration", TimeValue(Seconds(simTime))); - Simulator::Run (); - Simulator::Destroy (); + Simulator::Run(); + Simulator::Destroy(); return 0; } @@ -2500,9 +2499,9 @@ The CCM can be configured by using the attribute ``LteHelper::EnbComponentCarrie An example configuration is presented below:: - Config::SetDefault ("ns3::LteHelper::UseCa", BooleanValue (useCa)); - Config::SetDefault ("ns3::LteHelper::NumberOfComponentCarriers", UintegerValue (2)); - Config::SetDefault ("ns3::LteHelper::EnbComponentCarrierManager", StringValue ("ns3::RrComponentCarrierManager")); + Config::SetDefault("ns3::LteHelper::UseCa", BooleanValue(useCa)); + Config::SetDefault("ns3::LteHelper::NumberOfComponentCarriers", UintegerValue(2)); + Config::SetDefault("ns3::LteHelper::EnbComponentCarrierManager", StringValue("ns3::RrComponentCarrierManager")); As an example, the user can take a look and run the ``lena-simple`` and ``lena-simple-epc`` programs and enable LTE traces to check the performance. A new column is added to PHY and MAC traces to indicate the component carrier. @@ -2577,7 +2576,7 @@ scenarios shown in :ref:`lena-radio-link-failure-one-enb` and We note that, the RLF detection is enabled by default, which can be disabled by configuring the ``LteUePhy::EnableRlfDetection`` to false, e.g.,:: - Config::SetDefault ("ns3::LteUePhy::EnableRlfDetection", BooleanValue (false)); + Config::SetDefault("ns3::LteUePhy::EnableRlfDetection", BooleanValue(false)); In this example, to study the impact of a RLF on the user's quality of experience, we compute an instantaneous (i.e., every 200 ms) DL throughput of the UE, and @@ -2710,5 +2709,3 @@ output is as expected. In detail: EpcSgwApplication, EpcPgwApplication and EpcEnbApplication, then moving down the LTE radio stack (PDCP, RLC, MAC, and finally PHY). All this until you find where packets stop being processed / forwarded. - - diff --git a/src/mobility/doc/mobility.rst b/src/mobility/doc/mobility.rst index 57b8c9493..2830e5382 100644 --- a/src/mobility/doc/mobility.rst +++ b/src/mobility/doc/mobility.rst @@ -227,13 +227,13 @@ First, the user instantiates a ``MobilityHelper`` object and sets some MobilityHelper mobility; - mobility.SetPositionAllocator ("ns3::GridPositionAllocator", - "MinX", DoubleValue (0.0), - "MinY", DoubleValue (0.0), - "DeltaX", DoubleValue (5.0), - "DeltaY", DoubleValue (10.0), - "GridWidth", UintegerValue (3), - "LayoutType", StringValue ("RowFirst")); + mobility.SetPositionAllocator("ns3::GridPositionAllocator", + "MinX", DoubleValue(0.0), + "MinY", DoubleValue(0.0), + "DeltaX", DoubleValue(5.0), + "DeltaY", DoubleValue(10.0), + "GridWidth", UintegerValue(3), + "LayoutType", StringValue("RowFirst")); This code tells the mobility helper to use a two-dimensional grid to initially place the nodes. The first argument is an |ns3| TypeId specifying the @@ -244,14 +244,14 @@ Next, the user typically sets the MobilityModel subclass; e.g.: .. sourcecode:: cpp - mobility.SetMobilityModel ("ns3::RandomWalk2dMobilityModel", - "Bounds", RectangleValue (Rectangle (-50, 50, -50, 50))); + mobility.SetMobilityModel("ns3::RandomWalk2dMobilityModel", + "Bounds", RectangleValue(Rectangle(-50, 50, -50, 50))); Once the helper is configured, it is typically passed a container, such as: .. sourcecode:: cpp - mobility.Install (wifiStaNodes); + mobility.Install(wifiStaNodes); A MobilityHelper object may be reconfigured and reused for different NodeContainers during the configuration of an |ns3| scenario. @@ -391,7 +391,7 @@ API to assign streams to underlying random variables: * \param stream first stream index to use * \return the number of stream indices assigned by this model */ - int64_t AssignStreams (int64_t stream); + int64_t AssignStreams(int64_t stream); The class ``MobilityHelper`` also provides this API. The typical usage pattern when using the helper is: @@ -401,8 +401,8 @@ pattern when using the helper is: int64_t streamIndex = /*some positive integer */ MobilityHelper mobility; ... (configure mobility) - mobility.Install (wifiStaNodes); - int64_t streamsUsed = mobility.AssignStreams (wifiStaNodes, streamIndex); + mobility.Install(wifiStaNodes); + int64_t streamsUsed = mobility.AssignStreams(wifiStaNodes, streamIndex); If AssignStreams is called before Install, it will not have any effect. diff --git a/src/mpi/doc/distributed.rst b/src/mpi/doc/distributed.rst index 28302c753..140d81df7 100644 --- a/src/mpi/doc/distributed.rst +++ b/src/mpi/doc/distributed.rst @@ -243,20 +243,20 @@ DistributedSimulatorImpl is not used. Here is an example code snippet showing how to add a command line argument to control the synchronization algorithm choice::: - cmd.AddValue ("nullmsg", "Enable the use of null-message synchronization", nullmsg); - if(nullmsg) + cmd.AddValue("nullmsg", "Enable the use of null-message synchronization", nullmsg); + if (nullmsg) { - GlobalValue::Bind ("SimulatorImplementationType", - StringValue ("ns3::NullMessageSimulatorImpl")); + GlobalValue::Bind("SimulatorImplementationType", + StringValue("ns3::NullMessageSimulatorImpl")); } else { - GlobalValue::Bind ("SimulatorImplementationType", - StringValue ("ns3::DistributedSimulatorImpl")); + GlobalValue::Bind("SimulatorImplementationType", + StringValue("ns3::DistributedSimulatorImpl")); } // Enable parallel simulator with the command line arguments - MpiInterface::Enable (&argc, &argv); + MpiInterface::Enable(&argc, &argv); @@ -274,17 +274,17 @@ Assigning system ids to nodes is simple and can be handled two different ways. First, a NodeContainer can be used to create the nodes and assign system ids:: NodeContainer nodes; - nodes.Create (5, 1); // Creates 5 nodes with system id 1. + nodes.Create(5, 1); // Creates 5 nodes with system id 1. Alternatively, nodes can be created individually, assigned system ids, and added to a NodeContainer. This is useful if a NodeContainer holds nodes with different system ids:: NodeContainer nodes; - Ptr node1 = CreateObject (0); // Create node1 with system id 0 - Ptr node2 = CreateObject (1); // Create node2 with system id 1 - nodes.Add (node1); - nodes.Add (node2); + Ptr node1 = CreateObject(0); // Create node1 with system id 0 + Ptr node2 = CreateObject(1); // Create node2 with system id 1 + nodes.Add(node1); + nodes.Add(node2); Next, where the simulation is divided is determined by the placement of point-to-point links. If a point-to-point link is created between two @@ -308,15 +308,15 @@ differently, based on the system id of the simulator. For example, something like this should work well, assuming all of these local variables were previously defined:: - if (MpiInterface::GetSystemId () == 0) + if (MpiInterface::GetSystemId() == 0) { - pointToPoint.EnablePcapAll ("distributed-rank0"); - phy.EnablePcap ("distributed-rank0", apDevices.Get (0)); - csma.EnablePcap ("distributed-rank0", csmaDevices.Get (0), true); + pointToPoint.EnablePcapAll("distributed-rank0"); + phy.EnablePcap("distributed-rank0", apDevices.Get(0)); + csma.EnablePcap("distributed-rank0", csmaDevices.Get(0), true); } - else if (MpiInterface::GetSystemId () == 1) + else if (MpiInterface::GetSystemId() == 1) { - pointToPoint.EnablePcapAll ("distributed-rank1"); - phy.EnablePcap ("distributed-rank1", apDevices.Get (0)); - csma.EnablePcap ("distributed-rank1", csmaDevices.Get (0), true); + pointToPoint.EnablePcapAll("distributed-rank1"); + phy.EnablePcap("distributed-rank1", apDevices.Get(0)); + csma.EnablePcap("distributed-rank1", csmaDevices.Get(0), true); } diff --git a/src/netanim/doc/animation.rst b/src/netanim/doc/animation.rst index fbd505892..a89a3ef63 100644 --- a/src/netanim/doc/animation.rst +++ b/src/netanim/doc/animation.rst @@ -159,7 +159,7 @@ Mandatory .. sourcecode:: cpp - AnimationInterface anim ("animation.xml"); // where "animation.xml" is any arbitrary filename + AnimationInterface anim("animation.xml"); // where "animation.xml" is any arbitrary filename [for versions before ns-3.13 you also have to use the line "anim.SetXMLOutput() to set the XML mode and also use anim.StartAnimation();] @@ -172,7 +172,7 @@ Optional The following are optional but useful steps:: // Step 1 - anim.SetMobilityPollInterval (Seconds (1)); + anim.SetMobilityPollInterval(Seconds(1)); AnimationInterface records the position of all nodes every 250 ms by default. The statement above sets the periodic interval at which AnimationInterface records the position of all nodes. If the nodes are @@ -181,21 +181,21 @@ expected to move very little, it is useful to set a high mobility poll interval :: // Step 2 - anim.SetConstantPosition (Ptr< Node > n, double x, double y); + anim.SetConstantPosition(Ptr< Node > n, double x, double y); AnimationInterface requires that the position of all nodes be set. In |ns3| this is done by setting an associated MobilityModel. "SetConstantPosition" is a quick way to set the x-y coordinates of a node which is stationary. :: // Step 3 - anim.SetStartTime (Seconds(150)); and anim.SetStopTime (Seconds(150)); + anim.SetStartTime(Seconds(150)); and anim.SetStopTime(Seconds(150)); AnimationInterface can generate large XML files. The above statements restricts the window between which AnimationInterface does tracing. Restricting the window serves to focus only on relevant portions of the simulation and creating manageably small XML files :: // Step 4 - AnimationInterface anim ("animation.xml", 50000); + AnimationInterface anim("animation.xml", 50000); Using the above constructor ensures that each animation XML trace file has only 50000 packets. For example, if AnimationInterface captures 150000 packets, using the above constructor splits the capture into 3 files @@ -208,7 +208,7 @@ Using the above constructor ensures that each animation XML trace file has only :: // Step 5 - anim.EnablePacketMetadata (true); + anim.EnablePacketMetadata(true); With the above statement, AnimationInterface records the meta-data of each packet in the xml trace file. Metadata can be used by NetAnim to provide better statistics and filter, along with providing some brief information about the packet such as TCP sequence number or source & destination IP address during packet animation. @@ -218,21 +218,21 @@ Please do NOT enable this feature when using Wimax links. :: // Step 6 - anim.UpdateNodeDescription (5, "Access-point"); + anim.UpdateNodeDescription(5, "Access-point"); With the above statement, AnimationInterface assigns the text "Access-point" to node 5. :: // Step 7 - anim.UpdateNodeSize (6, 1.5, 1.5); + anim.UpdateNodeSize(6, 1.5, 1.5); With the above statement, AnimationInterface sets the node size to scale by 1.5. NetAnim automatically scales the graphics view to fit the oboundaries of the topology. This means that NetAnim, can abnormally scale a node's size too high or too low. Using AnimationInterface::UpdateNodeSize allows you to overwrite the default scaling in NetAnim and use your own custom scale. :: // Step 8 - anim.UpdateNodeCounter (89, 7, 3.4); + anim.UpdateNodeCounter(89, 7, 3.4); With the above statement, AnimationInterface sets the counter with Id == 89, associated with Node 7 with the value 3.4. The counter with Id 89 is obtained using AnimationInterface::AddNodeCounter. An example usage for this is in src/netanim/examples/resource-counters.cc. diff --git a/src/network/doc/packets.rst b/src/network/doc/packets.rst index 870c337af..a17edf9b5 100644 --- a/src/network/doc/packets.rst +++ b/src/network/doc/packets.rst @@ -159,12 +159,12 @@ Creating a new packet The following command will create a new packet with a new unique Id.:: - Ptr pkt = Create (); + Ptr pkt = Create(); What is the Uid (unique Id)? It is an internal id that the system uses to identify packets. It can be fetched via the following method:: - uint32_t uid = pkt->GetUid (); + uint32_t uid = pkt->GetUid(); But please note the following. This uid is an internal uid and cannot be counted on to provide an accurate counter of how many "simulated packets" of a @@ -182,7 +182,7 @@ to have a certain number of payload bytes, but the bytes will only be allocated on-demand when needed). The command to do this is, when the packet is created:: - Ptr pkt = Create (N); + Ptr pkt = Create(N); where N is a positive integer. @@ -193,17 +193,17 @@ method:: * \returns the size in bytes of the packet (including the zero-filled * initial payload) */ - uint32_t GetSize () const; + uint32_t GetSize() const; You can also initialize a packet with a character buffer. The input data is copied and the input buffer is untouched. The constructor applied is:: - Packet (uint8_t const *buffer, uint32_t size); + Packet(uint8_t const *buffer, uint32_t size); Here is an example:: - Ptr pkt1 = Create (reinterpret_cast ("hello"), 5); + Ptr pkt1 = Create(reinterpret_cast("hello"), 5); Packets are freed when there are no more references to them, as with all |ns3| objects referenced by the Ptr class. @@ -244,17 +244,17 @@ Packet API can be used to add or remove such headers.:: * * \param header a reference to the header to add to this packet. */ - void AddHeader (const Header & header); + void AddHeader(const Header & header); /** * Deserialize and remove the header from the internal buffer. * - * This method invokes Header::Deserialize (begin) and should be used for + * This method invokes Header::Deserialize(begin) and should be used for * fixed-length headers. * * \param header a reference to the header to remove from the internal buffer. * \returns the number of bytes removed from the packet. */ - uint32_t RemoveHeader (Header &header); + uint32_t RemoveHeader(Header &header); /** * Deserialize but does _not_ remove the header from the internal buffer. * This method invokes Header::Deserialize. @@ -262,20 +262,20 @@ Packet API can be used to add or remove such headers.:: * \param header a reference to the header to read from the internal buffer. * \returns the number of bytes read from the packet. */ - uint32_t PeekHeader (Header &header) const; + uint32_t PeekHeader(Header &header) const; For instance, here are the typical operations to add and remove a UDP header.:: - // add header - Ptr packet = Create (); - UdpHeader udpHeader; - // Fill out udpHeader fields appropriately - packet->AddHeader (udpHeader); - ... - // remove header - UdpHeader udpHeader; - packet->RemoveHeader (udpHeader); - // Read udpHeader fields as needed + // add header + Ptr packet = Create(); + UdpHeader udpHeader; + // Fill out udpHeader fields appropriately + packet->AddHeader(udpHeader); + ... + // remove header + UdpHeader udpHeader; + packet->RemoveHeader(udpHeader); + // Read udpHeader fields as needed If the header is variable-length, then another variant of RemoveHeader() is needed:: @@ -283,7 +283,7 @@ needed:: /** * \brief Deserialize and remove the header from the internal buffer. * - * This method invokes Header::Deserialize (begin, end) and should be + * This method invokes Header::Deserialize(begin, end) and should be * used for variable-length headers (where the size is determined somehow * by the caller). * @@ -291,7 +291,7 @@ needed:: * \param size number of bytes to deserialize * \returns the number of bytes removed from the packet. */ - uint32_t RemoveHeader (Header &header, uint32_t size); + uint32_t RemoveHeader(Header &header, uint32_t size); In this case, the caller must figure out and provide the right 'size' as an argument (the Deserialization routine may not know when to stop). An @@ -331,7 +331,7 @@ behavior of packet tags and byte tags. * **Finding and Printing:** Both classes allow you to iterate over all of the tags and print them. * **Removal:** Users can add and remove the same packet tag multiple times on a - single packet (AddPacketTag () and RemovePacketTag ()). The packet However, + single packet (AddPacketTag() and RemovePacketTag()). The packet However, once a byte tag is added, it can only be removed by stripping all byte tags from the packet. Removing one of possibly multiple byte tags is not supported by the current API. @@ -360,11 +360,11 @@ The Packet API for byte tags is given below.:: * totally evil to allow a trace sink to modify the content of a * packet). */ - void AddByteTag (const Tag &tag) const; + void AddByteTag(const Tag &tag) const; /** * \returns an iterator over the set of byte tags included in this packet. */ - ByteTagIterator GetByteTagIterator () const; + ByteTagIterator GetByteTagIterator() const; /** * \param tag the tag to search in this packet * \returns true if the requested tag type was found, false otherwise. @@ -372,12 +372,12 @@ The Packet API for byte tags is given below.:: * If the requested tag type is found, it is copied in the user's * provided tag instance. */ - bool FindFirstMatchingByteTag (Tag &tag) const; + bool FindFirstMatchingByteTag(Tag &tag) const; /** * Remove all the tags stored in this packet. */ - void RemoveAllByteTags (); + void RemoveAllByteTags(); /** * \param os output stream in which the data should be printed. @@ -385,7 +385,7 @@ The Packet API for byte tags is given below.:: * Iterate over the tags present in this packet, and * invoke the Print method of each tag stored in the packet. */ - void PrintByteTags (std::ostream &os) const; + void PrintByteTags(std::ostream &os) const; The Packet API for packet tags is given below.:: @@ -399,7 +399,7 @@ The Packet API for packet tags is given below.:: * modify the state of this packet, which is fairly * un-intuitive. */ - void AddPacketTag (const Tag &tag) const; + void AddPacketTag(const Tag &tag) const; /** * \param tag the tag to remove from this packet * \returns true if the requested tag is found, false @@ -408,7 +408,7 @@ The Packet API for packet tags is given below.:: * Remove a tag from this packet. This method calls * Tag::Deserialize if the tag is found. */ - bool RemovePacketTag (Tag &tag); + bool RemovePacketTag(Tag &tag); /** * \param tag the tag to search in this packet * \returns true if the requested tag is found, false @@ -416,11 +416,11 @@ The Packet API for packet tags is given below.:: * * Search a matching tag and call Tag::Deserialize if it is found. */ - bool PeekPacketTag (Tag &tag) const; + bool PeekPacketTag(Tag &tag) const; /** * Remove all packet tags. */ - void RemoveAllPacketTags (); + void RemoveAllPacketTags(); /** * \param os the stream in which we want to print data. @@ -430,30 +430,30 @@ The Packet API for packet tags is given below.:: * \sa Packet::AddPacketTag, Packet::RemovePacketTag, Packet::PeekPacketTag, * Packet::RemoveAllPacketTags */ - void PrintPacketTags (std::ostream &os) const; + void PrintPacketTags(std::ostream &os) const; /** * \returns an object which can be used to iterate over the list of * packet tags. */ - PacketTagIterator GetPacketTagIterator () const; + PacketTagIterator GetPacketTagIterator() const; Here is a simple example illustrating the use of tags from the code in ``src/internet/model/udp-socket-impl.cc``:: Ptr p; // pointer to a pre-existing packet SocketIpTtlTag tag - tag.SetTtl (m_ipMulticastTtl); // Convey the TTL from UDP layer to IP layer - p->AddPacketTag (tag); + tag.SetTtl(m_ipMulticastTtl); // Convey the TTL from UDP layer to IP layer + p->AddPacketTag(tag); This tag is read at the IP layer, then stripped (``src/internet/model/ipv4-l3-protocol.cc``):: uint8_t ttl = m_defaultTtl; SocketIpTtlTag tag; - bool found = packet->RemovePacketTag (tag); + bool found = packet->RemovePacketTag(tag); if (found) { - ttl = tag.GetTtl (); + ttl = tag.GetTtl(); } Fragmentation and concatenation @@ -463,15 +463,15 @@ Packets may be fragmented or merged together. For example, to fragment a packet ``p`` of 90 bytes into two packets, one containing the first 10 bytes and the other containing the remaining 80, one may call the following code:: - Ptr frag0 = p->CreateFragment (0, 10); - Ptr frag1 = p->CreateFragment (10, 90); + Ptr frag0 = p->CreateFragment(0, 10); + Ptr frag1 = p->CreateFragment(10, 90); As discussed above, the packet tags from ``p`` will follow to both packet fragments, and the byte tags will follow the byte ranges as needed. Now, to put them back together:: - frag0->AddAtEnd (frag1); + frag0->AddAtEnd(frag1); Now frag0 should be equivalent to the original packet ``p``. If, however, there were operations on the fragments before being reassembled (such as tag @@ -500,8 +500,8 @@ the program. To enable this operation, users will typically insert one or both of these statements at the beginning of their programs:: - Packet::EnablePrinting (); - Packet::EnableChecking (); + Packet::EnablePrinting(); + Packet::EnableChecking(); Sample programs *************** diff --git a/src/network/doc/queue-limits.rst b/src/network/doc/queue-limits.rst index 9b238a490..2e7e4e447 100644 --- a/src/network/doc/queue-limits.rst +++ b/src/network/doc/queue-limits.rst @@ -88,9 +88,9 @@ the queue limits type and attributes from the helper, such as this example: .. sourcecode:: cpp TrafficControlHelper tch; - uint32_t handle = tch.SetRootQueueDisc ("ns3::PfifoFastQueueDisc", "Limit", UintegerValue (1000)); + uint32_t handle = tch.SetRootQueueDisc("ns3::PfifoFastQueueDisc", "Limit", UintegerValue(1000)); - tch.SetQueueLimits ("ns3::DynamicQueueLimits", "HoldTime", StringValue ("4ms")); + tch.SetQueueLimits("ns3::DynamicQueueLimits", "HoldTime", StringValue("4ms")); then install the configuration on a NetDevices container diff --git a/src/network/doc/queue.rst b/src/network/doc/queue.rst index 99a5752e9..5cf6b2f1e 100644 --- a/src/network/doc/queue.rst +++ b/src/network/doc/queue.rst @@ -96,21 +96,21 @@ the queue type and attributes from the helper, such as this example: PointToPointHelper p2p; - p2p.SetQueue ("ns3::DropTailQueue"); - p2p.SetDeviceAttribute ("DataRate", StringValue ("10Mbps")); - p2p.SetChannelAttribute ("Delay", StringValue ("2ms")); - NetDeviceContainer devn0n2 = p2p.Install (n0n2); + p2p.SetQueue("ns3::DropTailQueue"); + p2p.SetDeviceAttribute("DataRate", StringValue("10Mbps")); + p2p.SetChannelAttribute("Delay", StringValue("2ms")); + NetDeviceContainer devn0n2 = p2p.Install(n0n2); - p2p.SetQueue ("ns3::DropTailQueue"); - p2p.SetDeviceAttribute ("DataRate", StringValue ("10Mbps")); - p2p.SetChannelAttribute ("Delay", StringValue ("3ms")); - NetDeviceContainer devn1n2 = p2p.Install (n1n2); + p2p.SetQueue("ns3::DropTailQueue"); + p2p.SetDeviceAttribute("DataRate", StringValue("10Mbps")); + p2p.SetChannelAttribute("Delay", StringValue("3ms")); + NetDeviceContainer devn1n2 = p2p.Install(n1n2); - p2p.SetQueue ("ns3::DropTailQueue", - "MaxSize", StringValue ("50p")); - p2p.SetDeviceAttribute ("DataRate", StringValue (linkDataRate)); - p2p.SetChannelAttribute ("Delay", StringValue (linkDelay)); - NetDeviceContainer devn2n3 = p2p.Install (n2n3); + p2p.SetQueue("ns3::DropTailQueue", + "MaxSize", StringValue("50p")); + p2p.SetDeviceAttribute("DataRate", StringValue(linkDataRate)); + p2p.SetChannelAttribute("Delay", StringValue(linkDelay)); + NetDeviceContainer devn2n3 = p2p.Install(n2n3); Please note that the SetQueue method of the PointToPointHelper class allows to specify "ns3::DropTailQueue" instead of "ns3::DropTailQueue". The diff --git a/src/network/doc/sockets-api.rst b/src/network/doc/sockets-api.rst index 408520326..274f2ef9c 100644 --- a/src/network/doc/sockets-api.rst +++ b/src/network/doc/sockets-api.rst @@ -82,7 +82,7 @@ one type of socket, and if sockets of a particular type are able to be created on a given node, then a factory that can create such sockets must be aggregated to the Node:: - static Ptr CreateSocket (Ptr node, TypeId tid); + static Ptr CreateSocket(Ptr node, TypeId tid); Examples of TypeIds to pass to this method are :cpp:class:`ns3::TcpSocketFactory`, :cpp:class:`ns3::PacketSocketFactory`, and :cpp:class:`ns3::UdpSocketFactory`. @@ -93,7 +93,7 @@ example:: Ptr n0; // Do some stuff to build up the Node's internet stack Ptr localSocket = - Socket::CreateSocket (n0, TcpSocketFactory::GetTypeId ()); + Socket::CreateSocket(n0, TcpSocketFactory::GetTypeId()); In some ns-3 code, sockets will not be explicitly created by user's main programs, if an ns-3 application does it. For instance, for @@ -130,14 +130,14 @@ An application can also ask the socket how much space is available by calling :cpp:func:`ns3::Socket::GetTxAvailable`. A typical sequence of events for sending data (ignoring connection setup) might be:: - SetSendCallback (MakeCallback(&HandleSendCallback)); - Send (); - Send (); + SetSendCallback(MakeCallback(&HandleSendCallback)); + Send(); + Send(); ... // Send fails because buffer is full // Wait until HandleSendCallback is called // HandleSendCallback is called by socket, since space now available - Send (); // Start sending again + Send(); // Start sending again Similarly, on the receive side, the socket user does not block on a call to ``recv()``. Instead, the application sets a callback @@ -152,11 +152,11 @@ Packet vs. buffer variants There are two basic variants of ``Send()`` and ``Recv()`` supported:: - virtual int Send (Ptr p) = 0; - int Send (const uint8_t* buf, uint32_t size); + virtual int Send(Ptr p) = 0; + int Send(const uint8_t* buf, uint32_t size); - Ptr Recv (); - int Recv (uint8_t* buf, uint32_t size); + Ptr Recv(); + int Recv(uint8_t* buf, uint32_t size); The non-Packet variants are provided for legacy API reasons. When calling the raw buffer variant of :cpp:func:`ns3::Socket::Send`, the buffer is immediately @@ -196,9 +196,9 @@ Use of Send() vs. SendTo() There are two variants of methods used to send data to the socket:: - virtual int Send (Ptr p, uint32_t flags) = 0; + virtual int Send(Ptr p, uint32_t flags) = 0; - virtual int SendTo (Ptr p, uint32_t flags, + virtual int SendTo(Ptr p, uint32_t flags, const Address &toAddress) = 0; The first method is used if the socket has already been connected @@ -222,8 +222,8 @@ ToS (Type of Service) The native sockets API for ns-3 provides two public methods (of the Socket base class):: - void SetIpTos (uint8_t ipTos); - uint8_t GetIpTos () const; + void SetIpTos(uint8_t ipTos); + uint8_t GetIpTos() const; to set and get, respectively, the type of service associated with the socket. These methods are equivalent to using the IP_TOS option of BSD sockets. @@ -234,9 +234,9 @@ by application helpers and users cannot get a pointer to the sockets. Instead, users can create an address of type :cpp:class:`ns3::InetSocketAddress` with the desired type of service value and pass it to the application helpers:: - InetSocketAddress destAddress (ipv4Address, udpPort); - destAddress.SetTos (tos); - OnOffHelper onoff ("ns3::UdpSocketFactory", destAddress); + InetSocketAddress destAddress(ipv4Address, udpPort); + destAddress.SetTos(tos); + OnOffHelper onoff("ns3::UdpSocketFactory", destAddress); For this to work, the application must eventually call the :cpp:func:`ns3::Socket::Connect()` method to connect to the provided @@ -277,8 +277,8 @@ Priority The native sockets API for ns-3 provides two public methods (of the Socket base class):: - void SetPriority (uint8_t priority); - uint8_t GetPriority () const; + void SetPriority(uint8_t priority); + uint8_t GetPriority() const; to set and get, respectively, the priority associated with the socket. These methods are equivalent to using the SO_PRIORITY option of BSD sockets. diff --git a/src/nix-vector-routing/doc/nix-vector-routing.rst b/src/nix-vector-routing/doc/nix-vector-routing.rst index e50d67d61..f13c20ad6 100644 --- a/src/nix-vector-routing/doc/nix-vector-routing.rst +++ b/src/nix-vector-routing/doc/nix-vector-routing.rst @@ -112,8 +112,8 @@ use IPv4 or IPv6 Nix-Vector routing. Ipv4NixVectorHelper nixRouting; InternetStackHelper stack; - stack.SetRoutingHelper (nixRouting); // has effect on the next Install () - stack.Install (allNodes); // allNodes is the NodeContainer + stack.SetRoutingHelper(nixRouting); // has effect on the next Install() + stack.Install(allNodes); // allNodes is the NodeContainer * Using IPv6 Nix-Vector Routing: @@ -121,8 +121,8 @@ use IPv4 or IPv6 Nix-Vector routing. Ipv6NixVectorHelper nixRouting; InternetStackHelper stack; - stack.SetRoutingHelper (nixRouting); // has effect on the next Install () - stack.Install (allNodes); // allNodes is the NodeContainer + stack.SetRoutingHelper(nixRouting); // has effect on the next Install() + stack.Install(allNodes); // allNodes is the NodeContainer .. note:: The NixVectorHelper helper class helps to use NixVectorRouting functionality. diff --git a/src/olsr/doc/olsr.rst b/src/olsr/doc/olsr.rst index fa33282c1..fede8a33c 100644 --- a/src/olsr/doc/olsr.rst +++ b/src/olsr/doc/olsr.rst @@ -57,18 +57,18 @@ before the node's static routing table.:: NodeContainer c: ... // Enable OLSR - NS_LOG_INFO ("Enabling OLSR Routing."); + NS_LOG_INFO("Enabling OLSR Routing."); OlsrHelper olsr; Ipv4StaticRoutingHelper staticRouting; Ipv4ListRoutingHelper list; - list.Add (staticRouting, 0); - list.Add (olsr, 10); + list.Add(staticRouting, 0); + list.Add(olsr, 10); InternetStackHelper internet; - internet.SetRoutingHelper (list); - internet.Install (c); + internet.SetRoutingHelper(list); + internet.Install(c); Once installed,the OLSR "main interface" can be set with the SetMainInterface() command. If the user does not specify a main address, the protocol will select diff --git a/src/point-to-point-layout/doc/point-to-point-dumbbell.rst b/src/point-to-point-layout/doc/point-to-point-dumbbell.rst index 2e10e5837..8549d5f00 100644 --- a/src/point-to-point-layout/doc/point-to-point-dumbbell.rst +++ b/src/point-to-point-layout/doc/point-to-point-dumbbell.rst @@ -67,18 +67,18 @@ A dumbbell topology with point-to-point links can be configured by using the router nodes as shown below:: PointToPointHelper p2pLeaf; - p2pLeaf.SetDeviceAttribute ("DataRate", StringValue ("10Mbps")); - p2pLeaf.SetChannelAttribute ("Delay", StringValue ("2ms")); + p2pLeaf.SetDeviceAttribute("DataRate", StringValue("10Mbps")); + p2pLeaf.SetChannelAttribute("Delay", StringValue("2ms")); PointToPointHelper p2pRouter; - p2pRouter.SetDeviceAttribute ("DataRate", StringValue ("5Mbps")); - p2pRouter.SetChannelAttribute ("Delay", StringValue ("10ms")); + p2pRouter.SetDeviceAttribute("DataRate", StringValue("5Mbps")); + p2pRouter.SetChannelAttribute("Delay", StringValue("10ms")); After creating the ``PointToPointHelper`` objects, we need to instantiate the ``PointToPointDumbbellHelper``:: - PointToPointDumbbellHelper dumbbell (nLeftLeaf, p2pLeaf, nRightLeaf, - p2pLeaf, p2pRouter); + PointToPointDumbbellHelper dumbbell(nLeftLeaf, p2pLeaf, nRightLeaf, + p2pLeaf, p2pRouter); It is also possible to create two separate ``PointToPointHelper`` objects for left leaf nodes and right leaf nodes. In this case, a total of three @@ -86,21 +86,21 @@ left leaf nodes and right leaf nodes. In this case, a total of three one for right leaf nodes and one for the router nodes as shown below:: PointToPointHelper p2pLeft; - p2pLeft.SetDeviceAttribute ("DataRate", StringValue ("10Mbps")); - p2pLeft.SetChannelAttribute ("Delay", StringValue ("2ms")); + p2pLeft.SetDeviceAttribute("DataRate", StringValue("10Mbps")); + p2pLeft.SetChannelAttribute("Delay", StringValue("2ms")); PointToPointHelper p2pRight; - p2pRight.SetDeviceAttribute ("DataRate", StringValue ("15Mbps")); - p2pRight.SetChannelAttribute ("Delay", StringValue ("5ms")); + p2pRight.SetDeviceAttribute("DataRate", StringValue("15Mbps")); + p2pRight.SetChannelAttribute("Delay", StringValue("5ms")); PointToPointHelper p2pRouter; - p2pRouter.SetDeviceAttribute ("DataRate", StringValue ("5Mbps")); - p2pRouter.SetChannelAttribute ("Delay", StringValue ("10ms")); + p2pRouter.SetDeviceAttribute("DataRate", StringValue("5Mbps")); + p2pRouter.SetChannelAttribute("Delay", StringValue("10ms")); In this case, we instantiate the ``PointToPointDumbbellHelper`` as shown below:: - PointToPointDumbbellHelper dumbbell (nLeftLeaf, p2pLeft, nRightLeaf, - p2pRight, p2pRouter); + PointToPointDumbbellHelper dumbbell(nLeftLeaf, p2pLeft, nRightLeaf, + p2pRight, p2pRouter); After this, we can tell the helper to position the nodes in a dumbbell layout. This is done to improve the visualization of the topology and can be achieved @@ -110,33 +110,33 @@ by calling the ``BoundingBox`` function:: // uly -> Minimum Upper Left Y coordinate // lrx -> Maximum Lower Right X coordinate // lry -> Maximum Lower Right Y coordinate - dumbbell.BoundingBox (ulx, uly, lrx, lry); + dumbbell.BoundingBox(ulx, uly, lrx, lry); Next, we need to install an Internet Stack on the nodes. We have to instantiate a ``InternetStackHelper`` object for this, and pass it as a parameter to ``InstallStack`` function:: InternetStackHelper stack; - dumbbell.InstallStack (stack); + dumbbell.InstallStack(stack); Subsequently, we have to assign a IPv4/IPv6 address to the nodes as shown below:: // IPv4 Ipv4AddressHelper leftIp, rightIp, routerIp; - leftIp.SetBase ("10.1.1.0", "255.255.255.0"); - rightIp.SetBase ("10.2.1.0", "255.255.255.0"); - routerIp.SetBase ("10.3.1.0", "255.255.255.0"); + leftIp.SetBase("10.1.1.0", "255.255.255.0"); + rightIp.SetBase("10.2.1.0", "255.255.255.0"); + routerIp.SetBase("10.3.1.0", "255.255.255.0"); - dumbbell.AssignIpv4Addresses (leftIp, rightIp, routerIp); + dumbbell.AssignIpv4Addresses(leftIp, rightIp, routerIp); For IPv6 address:: // IPv6 - Ipv6Address addrBase ("2001:1::"); - Ipv6Prefix prefix (64) + Ipv6Address addrBase("2001:1::"); + Ipv6Prefix prefix(64) - dumbbell.AssignIpv6Addresses (addrBase, prefix); + dumbbell.AssignIpv6Addresses(addrBase, prefix); Example ******* diff --git a/src/point-to-point/doc/point-to-point.rst b/src/point-to-point/doc/point-to-point.rst index e5f189242..f914970df 100644 --- a/src/point-to-point/doc/point-to-point.rst +++ b/src/point-to-point/doc/point-to-point.rst @@ -79,23 +79,23 @@ helper. You just ask this helper to create as many computers (we call them ``Nodes``) as you need on your network:: NodeContainer nodes; - nodes.Create (2); + nodes.Create(2); Once you have your nodes, you need to instantiate a ``PointToPointHelper`` and set any attributes you may want to change. Note that since this is a -point-to-point (as compared to a point-to-multipoint) there may only be two +point-to-point(as compared to a point-to-multipoint) there may only be two nodes with associated net devices connected by a PointToPointChannel.:: PointToPointHelper pointToPoint; - pointToPoint.SetDeviceAttribute ("DataRate", StringValue ("5Mbps")); - pointToPoint.SetChannelAttribute ("Delay", StringValue ("2ms")); + pointToPoint.SetDeviceAttribute("DataRate", StringValue("5Mbps")); + pointToPoint.SetChannelAttribute("Delay", StringValue("2ms")); Once the attributes are set, all that remains is to create the devices and install them on the required nodes, and to connect the devices together using a PointToPoint channel. When we create the net devices, we add them to a container to allow you to use them in the future. This all takes just one line of code.:: - NetDeviceContainer devices = pointToPoint.Install (nodes); + NetDeviceContainer devices = pointToPoint.Install(nodes); PointToPoint Tracing ******************** diff --git a/src/stats/doc/aggregator.rst b/src/stats/doc/aggregator.rst index e7d085989..cca991b8e 100644 --- a/src/stats/doc/aggregator.rst +++ b/src/stats/doc/aggregator.rst @@ -79,7 +79,7 @@ how to do this: // Create an aggregator. Ptr aggregator = - CreateObject (fileNameWithoutExtension); + CreateObject(fileNameWithoutExtension); The first argument for the constructor, fileNameWithoutExtension, is the name of the gnuplot related files to write with no extension. @@ -138,18 +138,18 @@ GnuplotAggregator as was discussed above. :: - void Create2dPlot () + void Create2dPlot() { std::string fileNameWithoutExtension = "gnuplot-aggregator"; std::string plotTitle = "Gnuplot Aggregator Plot"; - std::string plotXAxisHeading = "Time (seconds)"; + std::string plotXAxisHeading = "Time(seconds)"; std::string plotYAxisHeading = "Double Values"; std::string plotDatasetLabel = "Data Values"; std::string datasetContext = "Dataset/Context/String"; // Create an aggregator. Ptr aggregator = - CreateObject (fileNameWithoutExtension); + CreateObject(fileNameWithoutExtension); Various GnuplotAggregator attributes are set including the 2-D dataset that will be plotted. @@ -157,15 +157,15 @@ that will be plotted. :: // Set the aggregator's properties. - aggregator->SetTerminal ("png"); - aggregator->SetTitle (plotTitle); - aggregator->SetLegend (plotXAxisHeading, plotYAxisHeading); + aggregator->SetTerminal("png"); + aggregator->SetTitle(plotTitle); + aggregator->SetLegend(plotXAxisHeading, plotYAxisHeading); // Add a data set to the aggregator. - aggregator->Add2dDataset (datasetContext, plotDatasetLabel); + aggregator->Add2dDataset(datasetContext, plotDatasetLabel); // aggregator must be turned on - aggregator->Enable (); + aggregator->Enable(); Next, the 2-D values are calculated, and each one is individually written to the GnuplotAggregator using the ``Write2d()`` function. @@ -186,11 +186,11 @@ written to the GnuplotAggregator using the ``Write2d()`` function. value = time * time; // Add this point to the plot. - aggregator->Write2d (datasetContext, time, value); + aggregator->Write2d(datasetContext, time, value); } // Disable logging of data for the aggregator. - aggregator->Disable (); + aggregator->Disable(); } FileAggregator @@ -227,7 +227,7 @@ to do this: // Create an aggregator that will have formatted values. Ptr aggregator = - CreateObject (fileName, FileAggregator::FORMATTED); + CreateObject(fileName, FileAggregator::FORMATTED); The first argument for the constructor, filename, is the name of the file to write; the second argument, fileType, is type of file to @@ -281,21 +281,21 @@ FileAggregator as was discussed above. :: - void CreateCommaSeparatedFile () + void CreateCommaSeparatedFile() { std::string fileName = "file-aggregator-comma-separated.txt"; std::string datasetContext = "Dataset/Context/String"; // Create an aggregator. Ptr aggregator = - CreateObject (fileName, FileAggregator::COMMA_SEPARATED); + CreateObject(fileName, FileAggregator::COMMA_SEPARATED); FileAggregator attributes are set. :: // aggregator must be turned on - aggregator->Enable (); + aggregator->Enable(); Next, the 2-D values are calculated, and each one is individually written to the FileAggregator using the ``Write2d()`` function. @@ -316,11 +316,11 @@ written to the FileAggregator using the ``Write2d()`` function. value = time * time; // Add this point to the plot. - aggregator->Write2d (datasetContext, time, value); + aggregator->Write2d(datasetContext, time, value); } // Disable logging of data for the aggregator. - aggregator->Disable (); + aggregator->Disable(); } The following text file with 2 columns of formatted values was also @@ -345,14 +345,14 @@ FileAggregator as was discussed above. :: - void CreateFormattedFile () + void CreateFormattedFile() { std::string fileName = "file-aggregator-formatted-values.txt"; std::string datasetContext = "Dataset/Context/String"; // Create an aggregator that will have formatted values. Ptr aggregator = - CreateObject (fileName, FileAggregator::FORMATTED); + CreateObject(fileName, FileAggregator::FORMATTED); FileAggregator attributes are set, including the C-style format string to use. @@ -360,10 +360,10 @@ to use. :: // Set the format for the values. - aggregator->Set2dFormat ("Time = %.3e\tValue = %.0f"); + aggregator->Set2dFormat("Time = %.3e\tValue = %.0f"); // aggregator must be turned on - aggregator->Enable (); + aggregator->Enable(); Next, the 2-D values are calculated, and each one is individually written to the FileAggregator using the ``Write2d()`` function. @@ -384,10 +384,9 @@ written to the FileAggregator using the ``Write2d()`` function. value = time * time; // Add this point to the plot. - aggregator->Write2d (datasetContext, time, value); + aggregator->Write2d(datasetContext, time, value); } // Disable logging of data for the aggregator. - aggregator->Disable (); + aggregator->Disable(); } - diff --git a/src/stats/doc/data-collection-helpers.rst b/src/stats/doc/data-collection-helpers.rst index 736e34148..999954715 100644 --- a/src/stats/doc/data-collection-helpers.rst +++ b/src/stats/doc/data-collection-helpers.rst @@ -69,20 +69,20 @@ output type, where the output type defaults to PNG if unspecified): :: - void ConfigurePlot (const std::string &outputFileNameWithoutExtension, - const std::string &title, - const std::string &xLegend, - const std::string &yLegend, - const std::string &terminalType = ".png"); + void ConfigurePlot(const std::string &outputFileNameWithoutExtension, + const std::string &title, + const std::string &xLegend, + const std::string &yLegend, + const std::string &terminalType = ".png"); The second statement hooks the trace source of interest: :: - void PlotProbe (const std::string &typeId, - const std::string &path, - const std::string &probeTraceSource, - const std::string &title); + void PlotProbe(const std::string &typeId, + const std::string &path, + const std::string &probeTraceSource, + const std::string &title); The arguments are as follows: @@ -105,21 +105,21 @@ A fully worked example (from ``seventh.cc``) is shown below: // Configure the plot. The first argument is the file name prefix // for the output files generated. The second, third, and fourth // arguments are, respectively, the plot title, x-axis, and y-axis labels - plotHelper.ConfigurePlot ("seventh-packet-byte-count", - "Packet Byte Count vs. Time", - "Time (Seconds)", - "Packet Byte Count", - "png"); + plotHelper.ConfigurePlot("seventh-packet-byte-count", + "Packet Byte Count vs. Time", + "Time(Seconds)", + "Packet Byte Count", + "png"); // Specify the probe type, trace source path (in configuration namespace), and // probe output trace source ("OutputBytes") to plot. The fourth argument // specifies the name of the data series label on the plot. The last // argument formats the plot by specifying where the key should be placed. - plotHelper.PlotProbe (probeType, - tracePath, - "OutputBytes", - "Packet Byte Count", - GnuplotAggregator::KEY_BELOW); + plotHelper.PlotProbe(probeType, + tracePath, + "OutputBytes", + "Packet Byte Count", + GnuplotAggregator::KEY_BELOW); In this example, the ``probeType`` and ``tracePath`` are as follows (for IPv4): @@ -176,11 +176,11 @@ It has the following prototype: :: - void ConfigurePlot (const std::string &outputFileNameWithoutExtension, - const std::string &title, - const std::string &xLegend, - const std::string &yLegend, - const std::string &terminalType = ".png"); + void ConfigurePlot(const std::string &outputFileNameWithoutExtension, + const std::string &title, + const std::string &xLegend, + const std::string &yLegend, + const std::string &terminalType = ".png"); It has the following arguments: @@ -217,11 +217,11 @@ An example of how to use this function can be seen in the :: - plotHelper.ConfigurePlot ("seventh-packet-byte-count", - "Packet Byte Count vs. Time", - "Time (Seconds)", - "Packet Byte Count", - "png"); + plotHelper.ConfigurePlot("seventh-packet-byte-count", + "Packet Byte Count vs. Time", + "Time(Seconds)", + "Packet Byte Count", + "png"); GnuplotHelper PlotProbe ####################### @@ -233,11 +233,11 @@ It has the following prototype: :: - void PlotProbe (const std::string &typeId, - const std::string &path, - const std::string &probeTraceSource, - const std::string &title, - enum GnuplotAggregator::KeyLocation keyLocation = GnuplotAggregator::KEY_INSIDE); + void PlotProbe(const std::string &typeId, + const std::string &path, + const std::string &probeTraceSource, + const std::string &title, + enum GnuplotAggregator::KeyLocation keyLocation = GnuplotAggregator::KEY_INSIDE); It has the following arguments: @@ -283,11 +283,11 @@ variable substitution) as follows: :: - plotHelper.PlotProbe ("ns3::Ipv4PacketProbe", - "/NodeList/*/$ns3::Ipv4L3Protocol/Tx", - "OutputBytes", - "Packet Byte Count", - GnuplotAggregator::KEY_BELOW); + plotHelper.PlotProbe("ns3::Ipv4PacketProbe", + "/NodeList/*/$ns3::Ipv4L3Protocol/Tx", + "OutputBytes", + "Packet Byte Count", + GnuplotAggregator::KEY_BELOW); Other Examples ############## @@ -311,8 +311,8 @@ value as a trace source. :: - Ptr emitter = CreateObject (); - Names::Add ("/Names/Emitter", emitter); + Ptr emitter = CreateObject(); + Names::Add("/Names/Emitter", emitter); Note that because there are no wildcards in the path used below, only 1 datastream was drawn in the plot. @@ -326,19 +326,19 @@ see if there were wildcards in the path. GnuplotHelper plotHelper; // Configure the plot. - plotHelper.ConfigurePlot ("gnuplot-helper-example", - "Emitter Counts vs. Time", - "Time (Seconds)", - "Emitter Count", - "png"); + plotHelper.ConfigurePlot("gnuplot-helper-example", + "Emitter Counts vs. Time", + "Time(Seconds)", + "Emitter Count", + "png"); // Plot the values generated by the probe. The path that we provide // helps to disambiguate the source of the trace. - plotHelper.PlotProbe ("ns3::Uinteger32Probe", - "/Names/Emitter/Counter", - "Output", - "Emitter Count", - GnuplotAggregator::KEY_INSIDE); + plotHelper.PlotProbe("ns3::Uinteger32Probe", + "/Names/Emitter/Counter", + "Output", + "Emitter Count", + GnuplotAggregator::KEY_INSIDE); FileHelper ========== @@ -425,16 +425,16 @@ there are no matches for a path that contains wildcards. FileHelper fileHelper; // Configure the file to be written. - fileHelper.ConfigureFile ("seventh-packet-byte-count", - FileAggregator::FORMATTED); + fileHelper.ConfigureFile("seventh-packet-byte-count", + FileAggregator::FORMATTED); // Set the labels for this formatted output file. - fileHelper.Set2dFormat ("Time (Seconds) = %.3e\tPacket Byte Count = %.0f"); + fileHelper.Set2dFormat("Time (Seconds) = %.3e\tPacket Byte Count = %.0f"); // Write the values generated by the probe. - fileHelper.WriteProbe ("ns3::Ipv4PacketProbe", - "/NodeList/*/$ns3::Ipv4L3Protocol/Tx", - "OutputBytes"); + fileHelper.WriteProbe("ns3::Ipv4PacketProbe", + "/NodeList/*/$ns3::Ipv4L3Protocol/Tx", + "OutputBytes"); FileHelper ConfigureFile ######################## @@ -446,8 +446,8 @@ It has the following prototype: :: - void ConfigureFile (const std::string &outputFileNameWithoutExtension, - enum FileAggregator::FileType fileType = FileAggregator::SPACE_SEPARATED); + void ConfigureFile(const std::string &outputFileNameWithoutExtension, + enum FileAggregator::FileType fileType = FileAggregator::SPACE_SEPARATED); It has the following arguments: @@ -474,8 +474,8 @@ An example of how to use this function can be seen in the :: - fileHelper.ConfigureFile ("seventh-packet-byte-count", - FileAggregator::FORMATTED); + fileHelper.ConfigureFile("seventh-packet-byte-count", + FileAggregator::FORMATTED); FileHelper WriteProbe ##################### @@ -487,9 +487,9 @@ It has the following prototype: :: - void WriteProbe (const std::string &typeId, - const std::string &path, - const std::string &probeTraceSource); + void WriteProbe(const std::string &typeId, + const std::string &path, + const std::string &probeTraceSource); It has the following arguments: @@ -530,9 +530,9 @@ An example of how to use this function can be seen in the :: - fileHelper.WriteProbe ("ns3::Ipv4PacketProbe", - "/NodeList/*/$ns3::Ipv4L3Protocol/Tx", - "OutputBytes"); + fileHelper.WriteProbe("ns3::Ipv4PacketProbe", + "/NodeList/*/$ns3::Ipv4L3Protocol/Tx", + "OutputBytes"); Other Examples ############## @@ -567,8 +567,8 @@ value as a trace source. :: - Ptr emitter = CreateObject (); - Names::Add ("/Names/Emitter", emitter); + Ptr emitter = CreateObject(); + Names::Add("/Names/Emitter", emitter); Note that because there are no wildcards in the path used below, only 1 text file was created. @@ -582,17 +582,17 @@ you would see if there were wildcards in the path. FileHelper fileHelper; // Configure the file to be written. - fileHelper.ConfigureFile ("file-helper-example", - FileAggregator::FORMATTED); + fileHelper.ConfigureFile("file-helper-example", + FileAggregator::FORMATTED); // Set the labels for this formatted output file. - fileHelper.Set2dFormat ("Time (Seconds) = %.3e\tCount = %.0f"); + fileHelper.Set2dFormat("Time (Seconds) = %.3e\tCount = %.0f"); // Write the values generated by the probe. The path that we // provide helps to disambiguate the source of the trace. - fileHelper.WriteProbe ("ns3::Uinteger32Probe", - "/Names/Emitter/Counter", - "Output"); + fileHelper.WriteProbe("ns3::Uinteger32Probe", + "/Names/Emitter/Counter", + "Output"); Scope and Limitations ===================== diff --git a/src/stats/doc/probe.rst b/src/stats/doc/probe.rst index 684bac61e..b8148e4b6 100644 --- a/src/stats/doc/probe.rst +++ b/src/stats/doc/probe.rst @@ -45,19 +45,19 @@ trace source are as follows: complicated structures; for instance, outputting the packet size value from a received ns3::Packet. * Probes register a name in the ns3::Config namespace (using - ``Names::Add ()``) so that other objects may refer to them. + ``Names::Add()``) so that other objects may refer to them. * Probes provide a static method that allows one to manipulate a Probe by name, such as what is done in ns2measure [Cic06]_ :: - Stat::put ("my_metric", ID, sample); + Stat::put("my_metric", ID, sample); The ns-3 equivalent of the above ns2measure code is, e.g. :: - DoubleProbe::SetValueByPath ("/path/to/probe", sample); + DoubleProbe::SetValueByPath("/path/to/probe", sample); Creation ######## @@ -74,7 +74,7 @@ just needs to call the |ns3| method ``CreateObject()``: :: - Ptr myprobe = CreateObject (); + Ptr myprobe = CreateObject(); The declaration above creates DoubleProbes using the default values for its attributes. There are four attributes in the DoubleProbe class; two in the @@ -90,11 +90,11 @@ method: :: - Ptr myprobe = CreateObjectWithAttributes ( - "Name", StringValue ("myprobe"), - "Enabled", BooleanValue (false), - "Start", TimeValue (Seconds (100.0)), - "Stop", TimeValue (Seconds (1000.0))); + Ptr myprobe = CreateObjectWithAttributes( + "Name", StringValue("myprobe"), + "Enabled", BooleanValue(false), + "Start", TimeValue(Seconds(100.0)), + "Stop", TimeValue(Seconds(1000.0))); Start and Stop are Time variables which determine the interval of action of the Probe. The Probe will only output data if the current time of the @@ -128,14 +128,14 @@ probing a Counter exported by an emitter object (class Emitter). :: - Ptr emitter = CreateObject (); - Names::Add ("/Names/Emitter", emitter); + Ptr emitter = CreateObject(); + Names::Add("/Names/Emitter", emitter); ... - Ptr probe1 = CreateObject (); + Ptr probe1 = CreateObject(); // Connect the probe to the emitter's Counter - bool connected = probe1->ConnectByObject ("Counter", emitter); + bool connected = probe1->ConnectByObject("Counter", emitter); The following code is probing the same Counter exported by the same emitter object. This DoubleProbe, however, is using a path in the @@ -145,10 +145,10 @@ otherwise, the ConnectByPath would not work. :: - Ptr probe2 = CreateObject (); + Ptr probe2 = CreateObject(); // Note, no return value is checked here - probe2->ConnectByPath ("/Names/Emitter/Counter"); + probe2->ConnectByPath("/Names/Emitter/Counter"); The next DoubleProbe shown that is shown below will have its value set using its path in the configuration namespace. Note that this time the @@ -157,22 +157,22 @@ created. :: - Ptr probe3 = CreateObject (); - probe3->SetName ("StaticallyAccessedProbe"); + Ptr probe3 = CreateObject(); + probe3->SetName("StaticallyAccessedProbe"); // We must add it to the config database - Names::Add ("/Names/Probes", probe3->GetName (), probe3); + Names::Add("/Names/Probes", probe3->GetName(), probe3); The emitter's Count() function is now able to set the value for this DoubleProbe as follows: :: void - Emitter::Count () + Emitter::Count() { ... m_counter += 1.0; - DoubleProbe::SetValueByPath ("/Names/StaticallyAccessedProbe", m_counter); + DoubleProbe::SetValueByPath("/Names/StaticallyAccessedProbe", m_counter); ... } @@ -197,7 +197,7 @@ a downstream object can hook a trace sink (NotifyViaProbe) to this as follows: :: - connected = probe1->TraceConnect ("Output", probe1->GetName (), MakeCallback (&NotifyViaProbe)); + connected = probe1->TraceConnect("Output", probe1->GetName(), MakeCallback(&NotifyViaProbe)); Other probes @@ -259,13 +259,13 @@ particular, two ways of emitting data are shown: :: void - Emitter::Count () + Emitter::Count() { - NS_LOG_FUNCTION (this); - NS_LOG_DEBUG ("Counting at " << Simulator::Now ().GetSeconds ()); + NS_LOG_FUNCTION(this); + NS_LOG_DEBUG("Counting at " << Simulator::Now().GetSeconds()); m_counter += 1.0; - DoubleProbe::SetValueByPath ("/Names/StaticallyAccessedProbe", m_counter); - Simulator::Schedule (Seconds (m_var->GetValue ()), &Emitter::Count, this); + DoubleProbe::SetValueByPath("/Names/StaticallyAccessedProbe", m_counter); + Simulator::Schedule(Seconds(m_var->GetValue()), &Emitter::Count, this); } Let's look at the Probe more carefully. Probes can receive their values @@ -287,21 +287,21 @@ with a Probe object. We'll call this case 0) below. // This is a function to test hooking a raw function to the trace source void - NotifyViaTraceSource (std::string context, double oldVal, double newVal) + NotifyViaTraceSource(std::string context, double oldVal, double newVal) { - NS_LOG_DEBUG ("context: " << context << " old " << oldVal << " new " << newVal); + NS_LOG_DEBUG("context: " << context << " old " << oldVal << " new " << newVal); } First, the emitter needs to be setup: :: - Ptr emitter = CreateObject (); - Names::Add ("/Names/Emitter", emitter); + Ptr emitter = CreateObject(); + Names::Add("/Names/Emitter", emitter); // The Emitter object is not associated with an ns-3 node, so // it won't get started automatically, so we need to do this ourselves - Simulator::Schedule (Seconds (0.0), &Emitter::Start, emitter); + Simulator::Schedule(Seconds(0.0), &Emitter::Start, emitter); The various DoubleProbes interact with the emitter in the example as shown below. @@ -313,8 +313,8 @@ Case 0): // The below shows typical functionality without a probe // (connect a sink function to a trace source) // - connected = emitter->TraceConnect ("Counter", "sample context", MakeCallback (&NotifyViaTraceSource)); - NS_ASSERT_MSG (connected, "Trace source not connected"); + connected = emitter->TraceConnect("Counter", "sample context", MakeCallback(&NotifyViaTraceSource)); + NS_ASSERT_MSG(connected, "Trace source not connected"); case 1): @@ -326,13 +326,13 @@ case 1): // // probe1 will be hooked to the Emitter trace source - Ptr probe1 = CreateObject (); + Ptr probe1 = CreateObject(); // the probe's name can serve as its context in the tracing - probe1->SetName ("ObjectProbe"); + probe1->SetName("ObjectProbe"); // Connect the probe to the emitter's Counter - connected = probe1->ConnectByObject ("Counter", emitter); - NS_ASSERT_MSG (connected, "Trace source not connected to probe1"); + connected = probe1->ConnectByObject("Counter", emitter); + NS_ASSERT_MSG(connected, "Trace source not connected to probe1"); case 2): @@ -344,13 +344,13 @@ case 2): // // Create another similar probe; this will hook up via a Config path - Ptr probe2 = CreateObject (); - probe2->SetName ("PathProbe"); + Ptr probe2 = CreateObject(); + probe2->SetName("PathProbe"); // Note, no return value is checked here - probe2->ConnectByPath ("/Names/Emitter/Counter"); + probe2->ConnectByPath("/Names/Emitter/Counter"); -case 4) (case 3 is not shown in this example): +case 4)(case 3 is not shown in this example): :: @@ -358,10 +358,10 @@ case 4) (case 3 is not shown in this example): // Probe3 will be called by the emitter directly through the // static method SetValueByPath(). // - Ptr probe3 = CreateObject (); - probe3->SetName ("StaticallyAccessedProbe"); + Ptr probe3 = CreateObject(); + probe3->SetName("StaticallyAccessedProbe"); // We must add it to the config database - Names::Add ("/Names/Probes", probe3->GetName (), probe3); + Names::Add("/Names/Probes", probe3->GetName(), probe3); And finally, the example shows how the probes can be hooked to generate output: @@ -371,10 +371,10 @@ generate output: // The probe itself should generate output. The context that we provide // to this probe (in this case, the probe name) will help to disambiguate // the source of the trace - connected = probe3->TraceConnect ("Output", - "/Names/Probes/StaticallyAccessedProbe/Output", - MakeCallback (&NotifyViaProbe)); - NS_ASSERT_MSG (connected, "Trace source not .. connected to probe3 Output"); + connected = probe3->TraceConnect("Output", + "/Names/Probes/StaticallyAccessedProbe/Output", + MakeCallback(&NotifyViaProbe)); + NS_ASSERT_MSG(connected, "Trace source not .. connected to probe3 Output"); The following callback is hooked to the Probe in this example for illustrative purposes; normally, the Probe would be hooked to a @@ -384,9 +384,9 @@ Collector object. // This is a function to test hooking it to the probe output void - NotifyViaProbe (std::string context, double oldVal, double newVal) + NotifyViaProbe(std::string context, double oldVal, double newVal) { - NS_LOG_DEBUG ("context: " << context << " old " << oldVal << " new " << newVal); + NS_LOG_DEBUG("context: " << context << " old " << oldVal << " new " << newVal); } @@ -424,17 +424,17 @@ itself (`Output`) and a count of the number of bytes in the packet :: TypeId - Ipv4PacketProbe::GetTypeId () + Ipv4PacketProbe::GetTypeId() { - static TypeId tid = TypeId ("ns3::Ipv4PacketProbe") - .SetParent () - .AddConstructor () - .AddTraceSource ( "Output", - "The packet plus its IPv4 object and interface that serve as the output for this probe", - MakeTraceSourceAccessor (&Ipv4PacketProbe::m_output)) - .AddTraceSource ( "OutputBytes", - "The number of bytes in the packet", - MakeTraceSourceAccessor (&Ipv4PacketProbe::m_outputBytes)) + static TypeId tid = TypeId("ns3::Ipv4PacketProbe") + .SetParent() + .AddConstructor() + .AddTraceSource( "Output", + "The packet plus its IPv4 object and interface that serve as the output for this probe", + MakeTraceSourceAccessor(&Ipv4PacketProbe::m_output)) + .AddTraceSource( "OutputBytes", + "The number of bytes in the packet", + MakeTraceSourceAccessor(&Ipv4PacketProbe::m_outputBytes)) ; return tid; } @@ -447,18 +447,18 @@ output the number of bytes on the `OutputBytes` trace source. :: void - Ipv4PacketProbe::TraceSink (Ptr packet, Ptr ipv4, uint32_t interface) + Ipv4PacketProbe::TraceSink(Ptr packet, Ptr ipv4, uint32_t interface) { - NS_LOG_FUNCTION (this << packet << ipv4 << interface); - if (IsEnabled ()) + NS_LOG_FUNCTION(this << packet << ipv4 << interface); + if (IsEnabled()) { m_packet = packet; m_ipv4 = ipv4; m_interface = interface; - m_output (packet, ipv4, interface); + m_output(packet, ipv4, interface); - uint32_t packetSizeNew = packet->GetSize (); - m_outputBytes (m_packetSizeOld, packetSizeNew); + uint32_t packetSizeNew = packet->GetSize(); + m_outputBytes(m_packetSizeOld, packetSizeNew); m_packetSizeOld = packetSizeNew; } } diff --git a/src/stats/doc/statistics.rst b/src/stats/doc/statistics.rst index d23a4d663..eb1430797 100644 --- a/src/stats/doc/statistics.rst +++ b/src/stats/doc/statistics.rst @@ -103,18 +103,18 @@ The first thing to do in implementing this experiment is developing the simulati :: double distance = 50.0; - string format ("OMNet++"); - string experiment ("wifi-distance-test"); - string strategy ("wifi-default"); + string format("OMNet++"); + string experiment("wifi-distance-test"); + string strategy("wifi-default"); string runID; - CommandLine cmd (__FILE__); - cmd.AddValue("distance", "Distance apart to place nodes (in meters).", distance); + CommandLine cmd(__FILE__); + cmd.AddValue("distance", "Distance apart to place nodes(in meters).", distance); cmd.AddValue("format", "Format to use for data output.", format); cmd.AddValue("experiment", "Identifier for experiment.", experiment); cmd.AddValue("strategy", "Identifier for strategy.", strategy); cmd.AddValue("run", "Identifier for run.", runID); - cmd.Parse (argc, argv); + cmd.Parse(argc, argv); * Creating nodes and network stacks using ``ns3::NodeContainer``, ``ns3::WiFiHelper``, and ``ns3::InternetStackHelper``. @@ -357,5 +357,3 @@ End Result The resulting graph provides no evidence that the default WiFi model's performance is necessarily unreasonable and lends some confidence to an at least token faithfulness to reality. More importantly, this simple investigation has been carried all the way through using the statistical framework. Success! .. image:: figures/Wifi-default.png - - diff --git a/src/traffic-control/doc/cobalt.rst b/src/traffic-control/doc/cobalt.rst index 4c525fc47..ab6ae6a4a 100644 --- a/src/traffic-control/doc/cobalt.rst +++ b/src/traffic-control/doc/cobalt.rst @@ -51,7 +51,7 @@ Linux model of COBALT is provided in ([Cobalt19]_). parameters (Pdrop of BLUE and dropping state of CoDel). If either of them decide to drop the packet, the packet is dropped. * ``CobaltQueueDisc::DoDequeue ()``: This routine performs the actual packet - ``drop based on ``CobaltQueueDisc::ShouldDrop ()``'s return value and + ``drop based on ``CobaltQueueDisc::ShouldDrop()``'s return value and schedules the next drop. Cobalt will decrease BLUE's drop probability if the queue is empty. This will ensure that the queue does not underflow. Otherwise Cobalt will take the next packet from the queue and calculate @@ -138,4 +138,3 @@ or :: $ NS_LOG="CobaltQueueDisc" ./ns3 run "test-runner --suite=cobalt-queue-disc" - diff --git a/src/traffic-control/doc/codel.rst b/src/traffic-control/doc/codel.rst index 7e8238b67..8caa7a305 100644 --- a/src/traffic-control/doc/codel.rst +++ b/src/traffic-control/doc/codel.rst @@ -28,22 +28,22 @@ Andrew McGregor based on Linux kernel code implemented by Dave Täht and Eric Du * class :cpp:class:`CoDelQueueDisc`: This class implements the main CoDel algorithm: - * ``CoDelQueueDisc::DoEnqueue ()``: This routine tags a packet with the current time before pushing it into the queue. The timestamp tag is used by ``CoDelQueue::DoDequeue()`` to compute the packet's sojourn time. If the queue is full upon the packet arrival, this routine will drop the packet and record the number of drops due to queue overflow, which is stored in `m_dropOverLimit`. + * ``CoDelQueueDisc::DoEnqueue()``: This routine tags a packet with the current time before pushing it into the queue. The timestamp tag is used by ``CoDelQueue::DoDequeue()`` to compute the packet's sojourn time. If the queue is full upon the packet arrival, this routine will drop the packet and record the number of drops due to queue overflow, which is stored in `m_dropOverLimit`. - * ``CoDelQueueDisc::ShouldDrop ()``: This routine is ``CoDelQueueDisc::DoDequeue()``'s helper routine that determines whether a packet should be dropped or not based on its sojourn time. If the sojourn time goes above `m_target` and remains above continuously for at least `m_interval`, the routine returns ``true`` indicating that it is OK to drop the packet. Otherwise, it returns ``false``. + * ``CoDelQueueDisc::ShouldDrop()``: This routine is ``CoDelQueueDisc::DoDequeue()``'s helper routine that determines whether a packet should be dropped or not based on its sojourn time. If the sojourn time goes above `m_target` and remains above continuously for at least `m_interval`, the routine returns ``true`` indicating that it is OK to drop the packet. Otherwise, it returns ``false``. - * ``CoDelQueueDisc::DoDequeue ()``: This routine performs the actual packet drop based on ``CoDelQueueDisc::ShouldDrop ()``'s return value and schedules the next drop/mark. + * ``CoDelQueueDisc::DoDequeue()``: This routine performs the actual packet drop based on ``CoDelQueueDisc::ShouldDrop()``'s return value and schedules the next drop/mark. * class :cpp:class:`CoDelTimestampTag`: This class implements the timestamp tagging for a packet. This tag is used to compute the packet's sojourn time (the difference between the time the packet is dequeued and the time it is pushed into the queue). -There are 2 branches to ``CoDelQueueDisc::DoDequeue ()``: +There are 2 branches to ``CoDelQueueDisc::DoDequeue()``: -1. If the queue is currently in the dropping state, which means the sojourn time has remained above `m_target` for more than `m_interval`, the routine determines if it's OK to leave the dropping state or it's time for the next drop/mark. When ``CoDelQueueDisc::ShouldDrop ()`` returns ``false``, the queue can move out of the dropping state (set `m_dropping` to ``false``). Otherwise, the queue continuously drops/marks packets and updates the time for next drop (`m_dropNext`) until one of the following conditions is met: +1. If the queue is currently in the dropping state, which means the sojourn time has remained above `m_target` for more than `m_interval`, the routine determines if it's OK to leave the dropping state or it's time for the next drop/mark. When ``CoDelQueueDisc::ShouldDrop()`` returns ``false``, the queue can move out of the dropping state (set `m_dropping` to ``false``). Otherwise, the queue continuously drops/marks packets and updates the time for next drop (`m_dropNext`) until one of the following conditions is met: - 1. The queue is empty, upon which the queue leaves the dropping state and exits ``CoDelQueueDisc::ShouldDrop ()`` routine; - 2. ``CoDelQueueDisc::ShouldDrop ()`` returns ``false`` (meaning the sojourn time goes below `m_target`) upon which the queue leaves the dropping state; + 1. The queue is empty, upon which the queue leaves the dropping state and exits ``CoDelQueueDisc::ShouldDrop()`` routine; + 2. ``CoDelQueueDisc::ShouldDrop()`` returns ``false`` (meaning the sojourn time goes below `m_target`) upon which the queue leaves the dropping state; 3. It is not yet time for next drop/mark (`m_dropNext` is less than current time) upon which the queue waits for the next packet dequeue to check the condition again. -2. If the queue is not in the dropping state, the routine enters the dropping state and drop/mark the first packet if ``CoDelQueueDisc::ShouldDrop ()`` returns ``true`` (meaning the sojourn time has gone above `m_target` for at least `m_interval` for the first time or it has gone above again after the queue leaves the dropping state). +2. If the queue is not in the dropping state, the routine enters the dropping state and drop/mark the first packet if ``CoDelQueueDisc::ShouldDrop()`` returns ``true`` (meaning the sojourn time has gone above `m_target` for at least `m_interval` for the first time or it has gone above again after the queue leaves the dropping state). The CoDel queue disc does not require packet filters, does not admit child queue discs and uses a single internal queue. If not provided by @@ -146,4 +146,3 @@ or .. sourcecode:: bash $ NS_LOG="CoDelQueueDisc" ./ns3 run "test-runner --suite=codel-queue-disc" - diff --git a/src/traffic-control/doc/fq-cobalt.rst b/src/traffic-control/doc/fq-cobalt.rst index ad4c0e7f8..3422fef44 100644 --- a/src/traffic-control/doc/fq-cobalt.rst +++ b/src/traffic-control/doc/fq-cobalt.rst @@ -62,9 +62,10 @@ For example, `FqCobalt` can be configured as follows: .. sourcecode:: cpp TrafficControlHelper tch; - tch.SetRootQueueDisc ("ns3::FqCobaltQueueDisc", "DropBatchSize", UintegerValue (1) - "Perturbation", UintegerValue (256)); - QueueDiscContainer qdiscs = tch.Install (devices); + tch.SetRootQueueDisc("ns3::FqCobaltQueueDisc", + "DropBatchSize", UintegerValue(1), + "Perturbation", UintegerValue(256)); + QueueDiscContainer qdiscs = tch.Install(devices); Validation ********** diff --git a/src/traffic-control/doc/fq-codel.rst b/src/traffic-control/doc/fq-codel.rst index d1fe41e55..0f44e44c9 100644 --- a/src/traffic-control/doc/fq-codel.rst +++ b/src/traffic-control/doc/fq-codel.rst @@ -46,13 +46,13 @@ as described below. * class :cpp:class:`FqCoDelQueueDisc`: This class implements the main FqCoDel algorithm: - * ``FqCoDelQueueDisc::DoEnqueue ()``: If no packet filter has been configured, this routine calls the QueueDiscItem::Hash() method to classify the given packet into an appropriate queue. Otherwise, the configured filters are used to classify the packet. If the filters are unable to classify the packet, the packet is dropped. Otherwise, an option is provided if set associative hashing is to be used.The packet is now handed over to the CoDel algorithm for timestamping. Then, if the queue is not currently active (i.e., if it is not in either the list of new or the list of old queues), it is added to the end of the list of new queues, and its deficit is initiated to the configured quantum. Otherwise, the queue is left in its current queue list. Finally, the total number of enqueued packets is compared with the configured limit, and if it is above this value (which can happen since a packet was just enqueued), packets are dropped from the head of the queue with the largest current byte count until the number of dropped packets reaches the configured drop batch size or the backlog of the queue has been halved. Note that this in most cases means that the packet that was just enqueued is not among the packets that get dropped, which may even be from a different queue. + * ``FqCoDelQueueDisc::DoEnqueue()``: If no packet filter has been configured, this routine calls the QueueDiscItem::Hash() method to classify the given packet into an appropriate queue. Otherwise, the configured filters are used to classify the packet. If the filters are unable to classify the packet, the packet is dropped. Otherwise, an option is provided if set associative hashing is to be used.The packet is now handed over to the CoDel algorithm for timestamping. Then, if the queue is not currently active (i.e., if it is not in either the list of new or the list of old queues), it is added to the end of the list of new queues, and its deficit is initiated to the configured quantum. Otherwise, the queue is left in its current queue list. Finally, the total number of enqueued packets is compared with the configured limit, and if it is above this value (which can happen since a packet was just enqueued), packets are dropped from the head of the queue with the largest current byte count until the number of dropped packets reaches the configured drop batch size or the backlog of the queue has been halved. Note that this in most cases means that the packet that was just enqueued is not among the packets that get dropped, which may even be from a different queue. * ``FqCoDelQueueDisc::SetAssociativeHash()``: An outer hash is identified for the given packet. This corresponds to the set into which the packet is to be enqueued. A set consists of a group of queues. The set determined by outer hash is enumerated; if a queue corresponding to this packet's flow is found (we use per-queue tags to achieve this), or in case of an inactive queue, or if a new queue can be created for this set without exceeding the maximum limit, the index of this queue is returned. Otherwise, all queues of this full set are active and correspond to flows different from the current packet's flow. In such cases, the index of first queue of this set is returned. We don’t consider creating new queues for the packet in these cases, since this approach may waste resources in the long run. The situation highlighted is a guaranteed collision and cannot be avoided without increasing the overall number of queues. - * ``FqCoDelQueueDisc::DoDequeue ()``: The first task performed by this routine is selecting a queue from which to dequeue a packet. To this end, the scheduler first looks at the list of new queues; for the queue at the head of that list, if that queue has a negative deficit (i.e., it has already dequeued at least a quantum of bytes), it is given an additional amount of deficit, the queue is put onto the end of the list of old queues, and the routine selects the next queue and starts again. Otherwise, that queue is selected for dequeue. If the list of new queues is empty, the scheduler proceeds down the list of old queues in the same fashion (checking the deficit, and either selecting the queue for dequeuing, or increasing deficit and putting the queue back at the end of the list). After having selected a queue from which to dequeue a packet, the CoDel algorithm is invoked on that queue. As a result of this, one or more packets may be discarded from the head of the selected queue, before the packet that should be dequeued is returned (or nothing is returned if the queue is or becomes empty while being handled by the CoDel algorithm). Finally, if the CoDel algorithm does not return a packet, then the queue must be empty, and the scheduler does one of two things: if the queue selected for dequeue came from the list of new queues, it is moved to the end of the list of old queues. If instead it came from the list of old queues, that queue is removed from the list, to be added back (as a new queue) the next time a packet for that queue arrives. Then (since no packet was available for dequeue), the whole dequeue process is restarted from the beginning. If, instead, the scheduler did get a packet back from the CoDel algorithm, it subtracts the size of the packet from the byte deficit for the selected queue and returns the packet as the result of the dequeue operation. + * ``FqCoDelQueueDisc::DoDequeue()``: The first task performed by this routine is selecting a queue from which to dequeue a packet. To this end, the scheduler first looks at the list of new queues; for the queue at the head of that list, if that queue has a negative deficit (i.e., it has already dequeued at least a quantum of bytes), it is given an additional amount of deficit, the queue is put onto the end of the list of old queues, and the routine selects the next queue and starts again. Otherwise, that queue is selected for dequeue. If the list of new queues is empty, the scheduler proceeds down the list of old queues in the same fashion (checking the deficit, and either selecting the queue for dequeuing, or increasing deficit and putting the queue back at the end of the list). After having selected a queue from which to dequeue a packet, the CoDel algorithm is invoked on that queue. As a result of this, one or more packets may be discarded from the head of the selected queue, before the packet that should be dequeued is returned (or nothing is returned if the queue is or becomes empty while being handled by the CoDel algorithm). Finally, if the CoDel algorithm does not return a packet, then the queue must be empty, and the scheduler does one of two things: if the queue selected for dequeue came from the list of new queues, it is moved to the end of the list of old queues. If instead it came from the list of old queues, that queue is removed from the list, to be added back (as a new queue) the next time a packet for that queue arrives. Then (since no packet was available for dequeue), the whole dequeue process is restarted from the beginning. If, instead, the scheduler did get a packet back from the CoDel algorithm, it subtracts the size of the packet from the byte deficit for the selected queue and returns the packet as the result of the dequeue operation. - * ``FqCoDelQueueDisc::FqCoDelDrop ()``: This routine is invoked by ``FqCoDelQueueDisc::DoEnqueue()`` to drop packets from the head of the queue with the largest current byte count. This routine keeps dropping packets until the number of dropped packets reaches the configured drop batch size or the backlog of the queue has been halved. + * ``FqCoDelQueueDisc::FqCoDelDrop()``: This routine is invoked by ``FqCoDelQueueDisc::DoEnqueue()`` to drop packets from the head of the queue with the largest current byte count. This routine keeps dropping packets until the number of dropped packets reaches the configured drop batch size or the backlog of the queue has been halved. * class :cpp:class:`FqCoDelFlow`: This class implements a flow queue, by keeping its current status (whether it is in the list of new queues, in the list of old queues or inactive) and its current deficit. @@ -122,9 +122,9 @@ can be configured as follows: .. sourcecode:: cpp TrafficControlHelper tch; - tch.SetRootQueueDisc ("ns3::FqCoDelQueueDisc", "DropBatchSize", UintegerValue (1) - "Perturbation", UintegerValue (256)); - QueueDiscContainer qdiscs = tch.Install (devices); + tch.SetRootQueueDisc("ns3::FqCoDelQueueDisc", "DropBatchSize", UintegerValue(1) + "Perturbation", UintegerValue(256)); + QueueDiscContainer qdiscs = tch.Install(devices); The example for FqCoDel's L4S mode is `FqCoDel-L4S-example.cc` located in ``src/traffic-control/examples``. To run the file (the first invocation below shows the available command-line options): diff --git a/src/traffic-control/doc/fq-pie.rst b/src/traffic-control/doc/fq-pie.rst index cbbcbc47a..c92fbb6a1 100644 --- a/src/traffic-control/doc/fq-pie.rst +++ b/src/traffic-control/doc/fq-pie.rst @@ -77,9 +77,10 @@ can be configured as follows: .. sourcecode:: cpp TrafficControlHelper tch; - tch.SetRootQueueDisc ("ns3::FqPieQueueDisc", "DropBatchSize", UintegerValue (1) - "Perturbation", UintegerValue (256)); - QueueDiscContainer qdiscs = tch.Install (devices); + tch.SetRootQueueDisc("ns3::FqPieQueueDisc", + "DropBatchSize", UintegerValue(1) + "Perturbation", UintegerValue(256)); + QueueDiscContainer qdiscs = tch.Install(devices); Validation ********** diff --git a/src/traffic-control/doc/mq.rst b/src/traffic-control/doc/mq.rst index fdad38d8c..ddfb9ee3e 100644 --- a/src/traffic-control/doc/mq.rst +++ b/src/traffic-control/doc/mq.rst @@ -47,10 +47,10 @@ discs: .. sourcecode:: cpp TrafficControlHelper tch; - uint16_t handle = tch.SetRootQueueDisc ("ns3::MqQueueDisc"); - TrafficControlHelper::ClassIdList cls = tch.AddQueueDiscClasses (handle, numTxQueues, "ns3::QueueDiscClass"); - tch.AddChildQueueDiscs (handle, cls, "ns3::FqCoDelQueueDisc"); - QueueDiscContainer qdiscs = tch.Install (devices); + uint16_t handle = tch.SetRootQueueDisc("ns3::MqQueueDisc"); + TrafficControlHelper::ClassIdList cls = tch.AddQueueDiscClasses(handle, numTxQueues, "ns3::QueueDiscClass"); + tch.AddChildQueueDiscs(handle, cls, "ns3::FqCoDelQueueDisc"); + QueueDiscContainer qdiscs = tch.Install(devices); Note that the child queue discs attached to the classes do not necessarily have to be of the same type. @@ -79,4 +79,3 @@ or :: $ NS_LOG="WifiAcMappingTest" ./ns3 run "test-runner --suite=ns3-wifi-ac-mapping" - diff --git a/src/traffic-control/doc/pie.rst b/src/traffic-control/doc/pie.rst index 3c452f8f4..4de339e2d 100644 --- a/src/traffic-control/doc/pie.rst +++ b/src/traffic-control/doc/pie.rst @@ -24,13 +24,13 @@ P. Tahiliani for the ns-3.32 release, with additional unit test cases contribute * class :cpp:class:`PieQueueDisc`: This class implements the main PIE algorithm: - * ``PieQueueDisc::DoEnqueue ()``: This routine checks whether the queue is full, and if so, drops the packets and records the number of drops due to queue overflow. If queue is not full then if ActiveThreshold is set then it checks if queue delay is higher than ActiveThreshold and if it is then, this routine calls ``PieQueueDisc::DropEarly()``, and depending on the value returned, the incoming packet is either enqueued or dropped. + * ``PieQueueDisc::DoEnqueue()``: This routine checks whether the queue is full, and if so, drops the packets and records the number of drops due to queue overflow. If queue is not full then if ActiveThreshold is set then it checks if queue delay is higher than ActiveThreshold and if it is then, this routine calls ``PieQueueDisc::DropEarly()``, and depending on the value returned, the incoming packet is either enqueued or dropped. - * ``PieQueueDisc::DropEarly ()``: The decision to enqueue or drop the packet is taken by invoking this routine, which returns a boolean value; false indicates enqueue and true indicates drop. + * ``PieQueueDisc::DropEarly()``: The decision to enqueue or drop the packet is taken by invoking this routine, which returns a boolean value; false indicates enqueue and true indicates drop. - * ``PieQueueDisc::CalculateP ()``: This routine is called at a regular interval of `m_tUpdate` and updates the drop probability, which is required by ``PieQueueDisc::DropEarly()`` + * ``PieQueueDisc::CalculateP()``: This routine is called at a regular interval of `m_tUpdate` and updates the drop probability, which is required by ``PieQueueDisc::DropEarly()`` - * ``PieQueueDisc::DoDequeue ()``: This routine calculates queue delay using timestamps (by default) or, optionally with the `UseDequeRateEstimator` attribute enabled, calculates the average departure rate to estimate queue delay. A queue delay estimate required for updating the drop probability in ``PieQueueDisc::CalculateP ()``. Starting with the ns-3.32 release, the default approach to calculate queue delay has been changed to use timestamps. + * ``PieQueueDisc::DoDequeue()``: This routine calculates queue delay using timestamps (by default) or, optionally with the `UseDequeRateEstimator` attribute enabled, calculates the average departure rate to estimate queue delay. A queue delay estimate required for updating the drop probability in ``PieQueueDisc::CalculateP()``. Starting with the ns-3.32 release, the default approach to calculate queue delay has been changed to use timestamps. References ========== @@ -112,4 +112,3 @@ or alternatively (to see logging statements in a debug build): .. sourcecode:: bash $ NS_LOG="PieQueueDisc" ./ns3 run "test-runner --suite=pie-queue-disc" - diff --git a/src/traffic-control/doc/prio.rst b/src/traffic-control/doc/prio.rst index c961c2962..581fc04fb 100644 --- a/src/traffic-control/doc/prio.rst +++ b/src/traffic-control/doc/prio.rst @@ -40,10 +40,10 @@ An example of how to configure PrioQueueDisc with custom child queue discs and p is provided by `queue-discs-benchmark.cc` located in ``examples/traffic-control``:: TrafficControlHelper tch; - uint16_t handle = tch.SetRootQueueDisc ("ns3::PrioQueueDisc", "Priomap", StringValue ("0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1")); - TrafficControlHelper::ClassIdList cid = tch.AddQueueDiscClasses (handle, 2, "ns3::QueueDiscClass"); - tch.AddChildQueueDisc (handle, cid[0], "ns3::FifoQueueDisc"); - tch.AddChildQueueDisc (handle, cid[1], "ns3::RedQueueDisc"); + uint16_t handle = tch.SetRootQueueDisc("ns3::PrioQueueDisc", "Priomap", StringValue("0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1")); + TrafficControlHelper::ClassIdList cid = tch.AddQueueDiscClasses(handle, 2, "ns3::QueueDiscClass"); + tch.AddChildQueueDisc(handle, cid[0], "ns3::FifoQueueDisc"); + tch.AddChildQueueDisc(handle, cid[1], "ns3::RedQueueDisc"); The code above adds two classes (bands) to a PrioQueueDisc. The highest priority one is a FifoQueueDisc, the other one is a RedQueueDisc. The attribute Priomap is set to diff --git a/src/traffic-control/doc/queue-discs.rst b/src/traffic-control/doc/queue-discs.rst index ac21560ea..3480debd7 100644 --- a/src/traffic-control/doc/queue-discs.rst +++ b/src/traffic-control/doc/queue-discs.rst @@ -211,9 +211,9 @@ the pfifo_fast can be configured as follows: .. sourcecode:: cpp TrafficControlHelper tch; - uint16_t handle = tch.SetRootQueueDisc ("ns3::PfifoFastQueueDisc"); - tch.AddInternalQueues (handle, 3, "ns3::DropTailQueue", "MaxSize", StringValue ("1000p")); - QueueDiscContainer qdiscs = tch.Install (devices); + uint16_t handle = tch.SetRootQueueDisc("ns3::PfifoFastQueueDisc"); + tch.AddInternalQueues(handle, 3, "ns3::DropTailQueue", "MaxSize", StringValue("1000p")); + QueueDiscContainer qdiscs = tch.Install(devices); The above code adds three internal queues to the root queue disc of type PfifoFast. With the above configuration, the config path of the root queue disc installed on the j-th @@ -235,7 +235,7 @@ method of the TrafficControlHelper: .. sourcecode:: cpp TrafficControlHelper tch; - tch.Uninstall (device); + tch.Uninstall(device); Note that the Uninstall method must be called after ``InternetStackHelper::Install()`` is called and after that IP addresses are configured using ``Ipv{4,6}AddressHelper``. For an example program, diff --git a/src/traffic-control/doc/red.rst b/src/traffic-control/doc/red.rst index 3e2508c8d..ab02acd2e 100644 --- a/src/traffic-control/doc/red.rst +++ b/src/traffic-control/doc/red.rst @@ -138,7 +138,7 @@ as done in ``src/traffic-control/examples/adaptive-red-tests.cc``: .. sourcecode:: cpp - Config::SetDefault ("ns3::RedQueueDisc::ARED", BooleanValue (true)); + Config::SetDefault("ns3::RedQueueDisc::ARED", BooleanValue(true)); Setting ARED to true implicitly configures both: (i) automatic setting of Queue weight, MinTh and MaxTh and (ii) adapting m_curMaxP. @@ -151,16 +151,16 @@ as done in ``src/traffic-control/examples/adaptive-red-tests.cc``: .. sourcecode:: cpp - Config::SetDefault ("ns3::RedQueueDisc::QW", DoubleValue (0.0)); - Config::SetDefault ("ns3::RedQueueDisc::MinTh", DoubleValue (0)); - Config::SetDefault ("ns3::RedQueueDisc::MaxTh", DoubleValue (0)); + Config::SetDefault("ns3::RedQueueDisc::QW", DoubleValue(0.0)); + Config::SetDefault("ns3::RedQueueDisc::MinTh", DoubleValue(0)); + Config::SetDefault("ns3::RedQueueDisc::MaxTh", DoubleValue(0)); To configure (ii); AdaptMaxP must be set to true, as done in ``src/traffic-control/examples/adaptive-red-tests.cc``: .. sourcecode:: cpp - Config::SetDefault ("ns3::RedQueueDisc::AdaptMaxP", BooleanValue (true)); + Config::SetDefault("ns3::RedQueueDisc::AdaptMaxP", BooleanValue(true)); Simulating Feng's Adaptive RED ============================== @@ -170,7 +170,7 @@ set to true, as done in ``examples/traffic-control/red-vs-fengadaptive.cc``: .. sourcecode:: cpp - Config::SetDefault ("ns3::RedQueueDisc::FengAdaptive", BooleanValue (true)); + Config::SetDefault("ns3::RedQueueDisc::FengAdaptive", BooleanValue(true)); Simulating NLRED ================ @@ -180,7 +180,7 @@ as shown below: .. sourcecode:: cpp - Config::SetDefault ("ns3::RedQueueDisc::NLRED", BooleanValue (true)); + Config::SetDefault("ns3::RedQueueDisc::NLRED", BooleanValue(true)); Examples ======== diff --git a/src/traffic-control/doc/tbf.rst b/src/traffic-control/doc/tbf.rst index 2b36624c9..3cbdd2169 100644 --- a/src/traffic-control/doc/tbf.rst +++ b/src/traffic-control/doc/tbf.rst @@ -61,20 +61,20 @@ class. * class :cpp:class:`TbfQueueDisc`: This class implements the main TBF algorithm: - * ``TbfQueueDisc::DoEnqueue ()``: This routine enqueue's the incoming packet if the queue is not full and drops the packet otherwise. + * ``TbfQueueDisc::DoEnqueue()``: This routine enqueue's the incoming packet if the queue is not full and drops the packet otherwise. - * ``TbfQueueDisc::DoPeek ()``: This routine peeks for the top item in the queue and if the queue is not empty, it returns the topmost item. + * ``TbfQueueDisc::DoPeek()``: This routine peeks for the top item in the queue and if the queue is not empty, it returns the topmost item. - * ``TbfQueueDisc::DoDequeue ()``: This routine performs the dequeuing of packets according to the following logic: + * ``TbfQueueDisc::DoDequeue()``: This routine performs the dequeuing of packets according to the following logic: - * It calls ``TbfQueueDisc::Peek ()`` and calculates the size of the packet to be dequeued in bytes. + * It calls ``TbfQueueDisc::Peek()`` and calculates the size of the packet to be dequeued in bytes. * Then it calculates the time difference 'delta', which is the time elapsed since the last update of tokens in the buckets. * If the second bucket exists, the number of tokens are updated according to the 'PeakRate' and 'delta'. * From this second bucket a number of tokens equal to the size of the packet to be dequeued is subtracted. * Now the number of tokens in the first bucket are updated according to 'Rate' and 'delta'. * From this first bucket a number of tokens equal to the size of the packet to be dequeued is subtracted. * If after this, both the first and second buckets have tokens greater than zero, then the packet is dequeued. - * Else, an event to ``QueueDisc::Run ()`` is scheduled after a time period when enough tokens will be present for the dequeue operation. + * Else, an event to ``QueueDisc::Run()`` is scheduled after a time period when enough tokens will be present for the dequeue operation. References ========== diff --git a/src/wave/doc/wave.rst b/src/wave/doc/wave.rst index da8de4cfa..468258774 100644 --- a/src/wave/doc/wave.rst +++ b/src/wave/doc/wave.rst @@ -225,7 +225,7 @@ channel operation as follows: 10. RegisterTxProfile and DeleteTxProfile After channel access is assigned, we still cannot send IP-based - (or other protocol) packets by the Send () method. A tx profile should + (or other protocol) packets by the ``Send()`` method. A tx profile should be registered to specify tx parameters before transmission. 11. StartVsa, StopVsa and SetWaveVsaCallback @@ -237,7 +237,7 @@ channel operation as follows: 12. SendX After channel access is assigned, we can send WSMP (or other protocol) - packets via the SendX () method. We should specify the tx parameters for + packets via the ``SendX()`` method. We should specify the tx parameters for each packet, e.g. the channel number for transmit. 13. Send and SetReceiveCallback @@ -453,13 +453,13 @@ Usage is as follows: NodeContainer nodes; NetDeviceContainer devices; - nodes.Create (2); - YansWifiPhyHelper wifiPhy = YansWifiPhyHelper::Default (); - YansWifiChannelHelper wifiChannel = YansWifiChannelHelper::Default (); - wifiPhy.SetChannel (wifiChannel.Create ()); + nodes.Create(2); + YansWifiPhyHelper wifiPhy = YansWifiPhyHelper::Default(); + YansWifiChannelHelper wifiChannel = YansWifiChannelHelper::Default(); + wifiPhy.SetChannel(wifiChannel.Create()); NqosWave80211pMacHelper wifi80211pMac = NqosWaveMacHelper::Default(); - Wifi80211pHelper 80211pHelper = Wifi80211pHelper::Default (); - devices = 80211pHelper.Install (wifiPhy, wifi80211pMac, nodes); + Wifi80211pHelper 80211pHelper = Wifi80211pHelper::Default(); + devices = 80211pHelper.Install(wifiPhy, wifi80211pMac, nodes); The relation of ``ns3::YansWavePhyHelper``, ``ns3::QosWaveMacHelper`` and ``ns3::WaveHelper`` is described as below: @@ -482,13 +482,13 @@ Usage is as follows: NodeContainer nodes; NetDeviceContainer devices; - nodes.Create (2); - YansWifiChannelHelper wifiChannel = YansWifiChannelHelper::Default (); - YansWavePhyHelper wavePhy = YansWavePhyHelper::Default (); - wavePhy.SetChannel (wifiChannel.Create ()); - QosWaveMacHelper waveMac = QosWaveMacHelper::Default (); - WaveHelper waveHelper = WaveHelper::Default (); - devices = waveHelper.Install (wavePhy, waveMac, nodes); + nodes.Create(2); + YansWifiChannelHelper wifiChannel = YansWifiChannelHelper::Default(); + YansWavePhyHelper wavePhy = YansWavePhyHelper::Default(); + wavePhy.SetChannel(wifiChannel.Create()); + QosWaveMacHelper waveMac = QosWaveMacHelper::Default(); + WaveHelper waveHelper = WaveHelper::Default(); + devices = waveHelper.Install(wavePhy, waveMac, nodes); The higher-level helpers include ``ns3::WaveBsmStats`` and ``ns3::WaveBsmHelper``. @@ -531,39 +531,39 @@ From , usage is as follows: // used to get consistent random numbers across scenarios int64_t m_streamIndex; - m_waveBsmHelper.Install (m_adhocTxNodes, - m_adhocTxDevices, - m_adhocTxInterfaces, - Seconds(m_TotalSimTime), - m_wavePacketSize, - Seconds(m_waveInterval), - // convert GPS accuracy, in ns, to Time - Seconds(m_gpsAccuracyNs / 1000000.0), - m_txSafetyRanges); + m_waveBsmHelper.Install(m_adhocTxNodes, + m_adhocTxDevices, + m_adhocTxInterfaces, + Seconds(m_TotalSimTime), + m_wavePacketSize, + Seconds(m_waveInterval), + // convert GPS accuracy, in ns, to Time + Seconds(m_gpsAccuracyNs / 1000000.0), + m_txSafetyRanges); // fix random number streams - m_streamIndex += m_waveBsmHelper.AssignStreams (m_streamIndex); + m_streamIndex += m_waveBsmHelper.AssignStreams(m_streamIndex); Example usages of BSM statistics are as follows: // Get the cumulative PDR of the first safety Tx range (i.e, 50m in the // m_txSafetyRanges example above). - double bsm_pdr1 = m_waveBsmHelper.GetWaveBsmStats ()->GetBsmPdr (1); + double bsm_pdr1 = m_waveBsmHelper.GetWaveBsmStats()->GetBsmPdr(1); // total WAVE BSM bytes sent - uint32_t cumulativeWaveBsmBytes = m_waveBsmHelper.GetWaveBsmStats ()->GetTxByteCount (); + uint32_t cumulativeWaveBsmBytes = m_waveBsmHelper.GetWaveBsmStats()->GetTxByteCount(); // get number of WAVE BSM packets sent - int wavePktsSent = m_waveBsmHelper.GetWaveBsmStats ()->GetTxPktCount (); + int wavePktsSent = m_waveBsmHelper.GetWaveBsmStats()->GetTxPktCount(); // get number of WAVE BSM packets received - int wavePktsReceived = m_waveBsmHelper.GetWaveBsmStats ()->GetRxPktCount (); + int wavePktsReceived = m_waveBsmHelper.GetWaveBsmStats()->GetRxPktCount(); // reset count of WAVE BSM packets received - m_waveBsmHelper.GetWaveBsmStats ()->SetRxPktCount (0); + m_waveBsmHelper.GetWaveBsmStats()->SetRxPktCount(0); // reset count of WAVE BSM packets sent - m_waveBsmHelper.GetWaveBsmStats ()->SetTxPktCount (0); + m_waveBsmHelper.GetWaveBsmStats()->SetTxPktCount(0); // indicate that a node (nodeId) is moving. (set to 0 to "stop" node) WaveBsmHelper::GetNodesMoving()[nodeId] = 1; @@ -590,22 +590,22 @@ OrganizationIdentifier fields to identify differences. :: - VscCallback vsccall = MakeCallback (&VsaExample::GetWsaAndOi, this); + VscCallback vsccall = MakeCallback(&VsaExample::GetWsaAndOi, this); 4. receiver registers this identifier and function :: - Ptr device1 = DynamicCast(nodes.Get (i)->GetDevice (0)); - Ptr ocb1 = DynamicCast(device->GetMac ()); - ocb1->AddReceiveVscCallback (oi, vsccall); + Ptr device1 = DynamicCast(nodes.Get(i)->GetDevice(0)); + Ptr ocb1 = DynamicCast(device->GetMac()); + ocb1->AddReceiveVscCallback(oi, vsccall); 5. sender transmits management information over VSA frames :: - Ptr vsc = Create (); - ocb2->SendVsc (vsc, Mac48Address::GetBroadcast (), m_16093oi); + Ptr vsc = Create(); + ocb2->SendVsc(vsc, Mac48Address::GetBroadcast(), m_16093oi); 6. then registered callbacks in the receiver will be called. @@ -623,118 +623,118 @@ followed; otherwise, the packets may be discarded by devices. :: // the class ``ns3::WaveNetDeviceExample``here will has a receive method "Receive" to be registered. - receiver->SetReceiveCallback (MakeCallback (&WaveNetDeviceExample::Receive, this)); + receiver->SetReceiveCallback(MakeCallback(&WaveNetDeviceExample::Receive, this)); 3. receiver registers the receive callback if WSA frames are supposed to be received. :: // the class ``ns3::WaveNetDeviceExample``here will has a receive method "ReceiveVsa" to be registered. - receiver->SetWaveVsaCallback (MakeCallback (&WaveNetDeviceExample::ReceiveVsa, this)); + receiver->SetWaveVsaCallback(MakeCallback (&WaveNetDeviceExample::ReceiveVsa, this)); 4. sender and receiver assign channel access by StartSch method. :: // in this case that alternating access with non-immediate mode is assigned for sender and receiver devices. - const SchInfo schInfo = SchInfo (SCH1, false, EXTENDED_ALTERNATING); - Simulator::Schedule (Seconds (0.0), &WaveNetDevice::StartSch, sender, schInfo); - Simulator::Schedule (Seconds (0.0), &WaveNetDevice::StartSch, receiver, schInfo); + const SchInfo schInfo = SchInfo(SCH1, false, EXTENDED_ALTERNATING); + Simulator::Schedule(Seconds(0.0), &WaveNetDevice::StartSch, sender, schInfo); + Simulator::Schedule(Seconds(0.0), &WaveNetDevice::StartSch, receiver, schInfo); or :: // in this case that continuous access with immediate mode is assigned for sender and receiver devices. - const SchInfo schInfo = SchInfo (SCH1, true, EXTENDED_CONTINUOUS); - Simulator::Schedule (Seconds (0.0), &WaveNetDevice::StartSch, sender, schInfo); - Simulator::Schedule (Seconds (0.0), &WaveNetDevice::StartSch, receiver, schInfo) + const SchInfo schInfo = SchInfo(SCH1, true, EXTENDED_CONTINUOUS); + Simulator::Schedule(Seconds(0.0), &WaveNetDevice::StartSch, sender, schInfo); + Simulator::Schedule(Seconds(0.0), &WaveNetDevice::StartSch, receiver, schInfo) or :: // in this case that extended access with non-immediate mode is assigned for sender and receiver devices. - const SchInfo schInfo = SchInfo (SCH1, false, 100); - Simulator::Schedule (Seconds (0.0), &WaveNetDevice::StartSch, sender, schInfo); - Simulator::Schedule (Seconds (0.0), &WaveNetDevice::StartSch, receiver, schInfo) + const SchInfo schInfo = SchInfo(SCH1, false, 100); + Simulator::Schedule(Seconds(0.0), &WaveNetDevice::StartSch, sender, schInfo); + Simulator::Schedule(Seconds(0.0), &WaveNetDevice::StartSch, receiver, schInfo) 5. sender registers a tx profile if IP-based packets are planned to be transmitted :: // the IP-based packets will be transmitted in SCH1 with 6Mbps and 4 txPowerLevel with adaptable mode. - const TxProfile txProfile = TxProfile (SCH1, true, 4, WifiMode("OfdmRate6MbpsBW10MHz")); - Simulator::Schedule (Seconds (2.0), &WaveNetDevice::RegisterTxProfile, sender, txProfile); + const TxProfile txProfile = TxProfile(SCH1, true, 4, WifiMode("OfdmRate6MbpsBW10MHz")); + Simulator::Schedule(Seconds(2.0), &WaveNetDevice::RegisterTxProfile, sender, txProfile); 6. sender transmits WSMP packets by SendX method. :: // the data rate and txPowerLevel is controlled by the high layer which are 6Mbps and 0 level here. - const TxInfo txInfo = TxInfo (CCH, 7, WifiMode("OfdmRate6MbpsBW10MHz"), 0); + const TxInfo txInfo = TxInfo(CCH, 7, WifiMode("OfdmRate6MbpsBW10MHz"), 0); // this packet will contain WSMP header when IEEE 1609.3 model is implemented const static uint16_t WSMP_PROT_NUMBER = 0x88DC; - Ptr wsaPacket = Create (100); - const Address dest = receiver->GetAddress (); - Simulator::Schedule (Seconds (2.0), &WaveNetDevice::SendX, sender, wsaPacket, dest, WSMP_PROT_NUMBER, txInfo); + Ptr wsaPacket = Create(100); + const Address dest = receiver->GetAddress(); + Simulator::Schedule(Seconds(2.0), &WaveNetDevice::SendX, sender, wsaPacket, dest, WSMP_PROT_NUMBER, txInfo); or :: // the data rate and txPowerLevel is controlled by the MAC layer which are decided by WifiRemoteStationManager - const TxInfo txInfo = TxInfo (CCH, 7, WifiMode(), 8); + const TxInfo txInfo = TxInfo(CCH, 7, WifiMode(), 8); // this packet will contain WSMP header when IEEE 1609.3 model is implemented const static uint16_t WSMP_PROT_NUMBER = 0x88DC; - Ptr wsaPacket = Create (100); - const Address dest = receiver->GetAddress (); - Simulator::Schedule (Seconds (2.0), &WaveNetDevice::SendX, sender, wsaPacket, dest, WSMP_PROT_NUMBER, txInfo); + Ptr wsaPacket = Create(100); + const Address dest = receiver->GetAddress(); + Simulator::Schedule(Seconds(2.0), &WaveNetDevice::SendX, sender, wsaPacket, dest, WSMP_PROT_NUMBER, txInfo); 7. sender transmits IP-based packets by Send method. :: const static uint16_t IPv6_PROT_NUMBER = 0x86DD; - Ptr packet = Create (100); - const Address dest = receiver->GetAddress (); - Simulator::Schedule (Seconds (2.0), &WaveNetDevice::Send, sender, packet, dest, IPv6_PROT_NUMBER); + Ptr packet = Create(100); + const Address dest = receiver->GetAddress(); + Simulator::Schedule(Seconds(2.0), &WaveNetDevice::Send, sender, packet, dest, IPv6_PROT_NUMBER); 8. send transmits WSA frames repeatedly by StartVsa method. :: // this packet will contain WSA management information when IEEE 1609.3 model is implemented - Ptr wsaPacket = Create (100); - Mac48Address dest = Mac48Address::GetBroadcast (); - const VsaInfo vsaInfo = VsaInfo (dest, OrganizationIdentifier (), 0, wsaPacket, SCH1, 100, VSA_TRANSMIT_IN_BOTHI); - Simulator::Schedule (Seconds (2.0), &WaveNetDevice::StartVsa, sender, vsaInfo); + Ptr wsaPacket = Create(100); + Mac48Address dest = Mac48Address::GetBroadcast(); + const VsaInfo vsaInfo = VsaInfo(dest, OrganizationIdentifier(), 0, wsaPacket, SCH1, 100, VSA_TRANSMIT_IN_BOTHI); + Simulator::Schedule(Seconds(2.0), &WaveNetDevice::StartVsa, sender, vsaInfo); 9. sender stops WSA frames repeatedly transmit by StopVsa method. :: - Simulator::Schedule (Seconds (3.0), &WaveNetDevice::StopVsa, sender, SCH1); + Simulator::Schedule(Seconds(3.0), &WaveNetDevice::StopVsa, sender, SCH1); 10. sender and receiver release assigned channel access by StopSch method. :: - Simulator::Schedule (Seconds (4.0), &WaveNetDevice::StopSch, sender, SCH1); - Simulator::Schedule (Seconds (4.0), &WaveNetDevice::StopSch, receiver, SCH1); + Simulator::Schedule(Seconds(4.0), &WaveNetDevice::StopSch, sender, SCH1); + Simulator::Schedule(Seconds(4.0), &WaveNetDevice::StopSch, receiver, SCH1); 11. sender or receiver changes current MAC address by ChangeAddress method. :: - Address newAddress = Mac48Address::Allocate (); - Simulator::Schedule (Seconds (4.0), &WaveNetDevice::ChangeAddress, sender, newAddress); + Address newAddress = Mac48Address::Allocate(); + Simulator::Schedule(Seconds(4.0), &WaveNetDevice::ChangeAddress, sender, newAddress); 12. sender cancels all transmissions with the particular category and channel number by CancelTx method. :: - Simulator::Schedule (Seconds (4.0), &WaveNetDevice::CancelTx, sender, CCH, AC_BE); + Simulator::Schedule(Seconds(4.0), &WaveNetDevice::CancelTx, sender, CCH, AC_BE); For transmitting and receiving these packets successfully, the normal and appropriate invocation procedures should be performed. @@ -817,7 +817,7 @@ components can be enabled globally via the call to :: - Wifi80211pHelper::EnableLogComponents (); + Wifi80211pHelper::EnableLogComponents(); For the WAVE device, current classes provide output of the same type as WiFi devices; namely, ASCII and pcap traces, and logging output. The WAVE logging @@ -825,7 +825,7 @@ components can be enabled globally via the call to :: - WaveHelper::EnableLogComponents (); + WaveHelper::EnableLogComponents(); Advanced Usage @@ -841,10 +841,10 @@ Usage is as follows: :: // in this case, the MAC entities for SCH2 to SCH6 will not be created - WaveHelper helper = WaveHelper::Default (); + WaveHelper helper = WaveHelper::Default(); uint32_t channels[] = {CCH, SCH1}; - std::vector channelsVector (channels, channels + 2); - helper.CreateMacForChannel (channelsVector); + std::vector channelsVector(channels, channels + 2); + helper.CreateMacForChannel(channelsVector); If users can create other channel access assignment mechanism, e.g. in the context of more PHY entities, which may be called @@ -853,11 +853,11 @@ with new assignment mechanisms. Usage is as follows: :: - WaveHelper helper = WaveHelper::Default (); - helper.helper.CreateMacForChannel (ChannelManager::GetWaveChannels ()); // create all 7 MAC entities for WAVE - helper.CreatePhys (2); // or other number which should be less than 7 - helper.SetChannelScheduler ("ns3::AnotherScheduler"); // The AnotherScheduler should be implemented by users. - helper.SetRemoteStationManager ("ns3::ConstantRateWifiManager"); // or other rate control algorithms + WaveHelper helper = WaveHelper::Default(); + helper.helper.CreateMacForChannel(ChannelManager::GetWaveChannels()); // create all 7 MAC entities for WAVE + helper.CreatePhys(2); // or other number which should be less than 7 + helper.SetChannelScheduler("ns3::AnotherScheduler"); // The AnotherScheduler should be implemented by users. + helper.SetRemoteStationManager("ns3::ConstantRateWifiManager"); // or other rate control algorithms Examples ======== diff --git a/src/wifi/doc/source/wifi-changelog.rst b/src/wifi/doc/source/wifi-changelog.rst index 721a59e4e..ca54b1400 100644 --- a/src/wifi/doc/source/wifi-changelog.rst +++ b/src/wifi/doc/source/wifi-changelog.rst @@ -22,12 +22,12 @@ continue to set the Wi-Fi standard separately). For instance, where pre-ns-3.36 code may have said:: WifiPhyHelper phy; - phy.Set("ChannelNumber", UintegerValue (36)); + phy.Set("ChannelNumber", UintegerValue(36)); the equivalent new code is:: WifiPhyHelper phy; - phy.Set ("ChannelSettings", StringValue ("{36, 20, BAND_5GHZ, 0}")); + phy.Set("ChannelSettings", StringValue("{36, 20, BAND_5GHZ, 0}")); which denotes that channel 36 is used on a 20 MHz channel in the 5GHz band, and because a larger channel width greater than 20 MHz is not being used, there diff --git a/src/wifi/doc/source/wifi-user.rst b/src/wifi/doc/source/wifi-user.rst index 2e158969d..c3579bd35 100644 --- a/src/wifi/doc/source/wifi-user.rst +++ b/src/wifi/doc/source/wifi-user.rst @@ -58,14 +58,14 @@ The following sample code illustrates a typical configuration using mostly default values in the simulator, and infrastructure mode:: NodeContainer wifiStaNode; - wifiStaNode.Create (10); // Create 10 station node objects + wifiStaNode.Create(10); // Create 10 station node objects NodeContainer wifiApNode; - wifiApNode.Create (1); // Create 1 access point node object + wifiApNode.Create(1); // Create 1 access point node object // Create a channel helper and phy helper, and then create the channel - YansWifiChannelHelper channel = YansWifiChannelHelper::Default (); - YansWifiPhyHelper phy = YansWifiPhyHelper::Default (); - phy.SetChannel (channel.Create ()); + YansWifiChannelHelper channel = YansWifiChannelHelper::Default(); + YansWifiPhyHelper phy = YansWifiPhyHelper::Default(); + phy.SetChannel(channel.Create()); // Create a WifiMacHelper, which is reused across STA and AP configurations WifiMacHelper mac; @@ -74,16 +74,16 @@ default values in the simulator, and infrastructure mode:: // and install Wifi devices. Configure a Wifi standard to use, which // will align various parameters in the Phy and Mac to standard defaults. WifiHelper wifi; - wifi.SetStandard (WIFI_STANDARD_80211n); + wifi.SetStandard(WIFI_STANDARD_80211n); // Declare NetDeviceContainers to hold the container returned by the helper NetDeviceContainer wifiStaDevices; NetDeviceContainer wifiApDevice; // Perform the installation - mac.SetType ("ns3::StaWifiMac"); - wifiStaDevices = wifi.Install (phy, mac, wifiStaNodes); - mac.SetType ("ns3::ApWifiMac"); - wifiApDevice = wifi.Install (phy, mac, wifiApNode); + mac.SetType("ns3::StaWifiMac"); + wifiStaDevices = wifi.Install(phy, mac, wifiStaNodes); + mac.SetType("ns3::ApWifiMac"); + wifiApDevice = wifi.Install(phy, mac, wifiApNode); At this point, the 11 nodes have Wi-Fi devices configured, attached to a common channel. The rest of this section describes how additional @@ -100,8 +100,8 @@ PropagationDelay model. Users will typically type code such as:: - YansWifiChannelHelper wifiChannelHelper = YansWifiChannelHelper::Default (); - Ptr wifiChannel = wifiChannelHelper.Create (); + YansWifiChannelHelper wifiChannelHelper = YansWifiChannelHelper::Default(); + Ptr wifiChannel = wifiChannelHelper.Create(); to get the defaults. Specifically, the default is a channel model with a propagation delay equal to a constant, the speed of light (``ns3::ConstantSpeedPropagationDelayModel``), @@ -136,7 +136,7 @@ supplemental ErrorRateModel and a pointer to a MobilityModel. The user code is typically:: YansWifiPhyHelper wifiPhyHelper; - wifiPhyHelper.SetChannel (wifiChannel); + wifiPhyHelper.SetChannel(wifiChannel); The default YansWifiPhyHelper is configured with TableBasedErrorRateModel (``ns3::TableBasedErrorRateModel``). You can change the error rate model by @@ -145,7 +145,7 @@ calling the ``YansWifiPhyHelper::SetErrorRateModel`` method. Optionally, if pcap tracing is needed, a user may use the following command to enable pcap tracing:: - YansWifiPhyHelper::SetPcapDataLinkType (enum SupportedPcapDataLinkTypes dlt) + YansWifiPhyHelper::SetPcapDataLinkType(enum SupportedPcapDataLinkTypes dlt) |ns3| supports RadioTap and Prism tracing extensions for 802.11. @@ -156,43 +156,43 @@ The Phy objects are created in the next step. In order to enable 802.11n/ac/ax MIMO, the number of antennas as well as the number of supported spatial streams need to be configured. For example, this code enables MIMO with 2 antennas and 2 spatial streams:: - wifiPhyHelper.Set ("Antennas", UintegerValue (2)); - wifiPhyHelper.Set ("MaxSupportedTxSpatialStreams", UintegerValue (2)); - wifiPhyHelper.Set ("MaxSupportedRxSpatialStreams", UintegerValue (2)); + wifiPhyHelper.Set("Antennas", UintegerValue(2)); + wifiPhyHelper.Set("MaxSupportedTxSpatialStreams", UintegerValue(2)); + wifiPhyHelper.Set("MaxSupportedRxSpatialStreams", UintegerValue(2)); It is also possible to configure less streams than the number of antennas in order to benefit from diversity gain, and to define different MIMO capabilities for downlink and uplink. For example, this code configures a node with 3 antennas that supports 2 spatial streams in downstream and 1 spatial stream in upstream:: - wifiPhyHelper.Set ("Antennas", UintegerValue (3)); - wifiPhyHelper.Set ("MaxSupportedTxSpatialStreams", UintegerValue (2)); - wifiPhyHelper.Set ("MaxSupportedRxSpatialStreams", UintegerValue (1)); + wifiPhyHelper.Set("Antennas", UintegerValue(3)); + wifiPhyHelper.Set("MaxSupportedTxSpatialStreams", UintegerValue(2)); + wifiPhyHelper.Set("MaxSupportedRxSpatialStreams", UintegerValue(1)); 802.11n PHY layer can support both 20 (default) or 40 MHz channel width, and 802.11ac/ax PHY layer can use either 20, 40, 80 (default) or 160 MHz channel width. See below for further documentation on setting the frequency, channel width, and channel number. :: WifiHelper wifi; - wifi.SetStandard (WIFI_STANDARD_80211ac); - wifi.SetRemoteStationManager ("ns3::ConstantRateWifiManager", - "DataMode", StringValue ("VhtMcs9"), - "ControlMode", StringValue ("VhtMcs0")); + wifi.SetStandard(WIFI_STANDARD_80211ac); + wifi.SetRemoteStationManager("ns3::ConstantRateWifiManager", + "DataMode", StringValue("VhtMcs9"), + "ControlMode", StringValue("VhtMcs0")); //Install PHY and MAC - Ssid ssid = Ssid ("ns3-wifi"); + Ssid ssid = Ssid("ns3-wifi"); WifiMacHelper mac; - mac.SetType ("ns3::StaWifiMac", - "Ssid", SsidValue (ssid), - "ActiveProbing", BooleanValue (false)); + mac.SetType("ns3::StaWifiMac", + "Ssid", SsidValue(ssid), + "ActiveProbing", BooleanValue(false)); NetDeviceContainer staDevice; - staDevice = wifi.Install (phy, mac, wifiStaNode); + staDevice = wifi.Install(phy, mac, wifiStaNode); - mac.SetType ("ns3::ApWifiMac", - "Ssid", SsidValue (ssid)); + mac.SetType("ns3::ApWifiMac", + "Ssid", SsidValue(ssid)); NetDeviceContainer apDevice; - apDevice = wifi.Install (phy, mac, wifiApNode); + apDevice = wifi.Install(phy, mac, wifiApNode); .. _Channel-settings: @@ -209,14 +209,14 @@ providing either a StringValue object or a TupleValue object: :: - StringValue value ("{38, 40, BAND_5GHZ, 0}")); + StringValue value("{38, 40, BAND_5GHZ, 0}")); * Defining a TupleValue object to set the ``ChannelSettings`` attribute :: TupleValue value; - value.Set (WifiPhy::ChannelTuple {38, 40, WIFI_PHY_BAND_5GHZ, 0}); + value.Set(WifiPhy::ChannelTuple {38, 40, WIFI_PHY_BAND_5GHZ, 0}); In both cases, the operating channel will be channel 38 in the 5 GHz band, which has a width of 40 MHz, and the primary20 channel will be the 20 MHz subchannel @@ -228,26 +228,26 @@ The operating channel settings can then be configured in a number of ways: :: - Config::SetDefault ("ns3::WifiPhy::ChannelSettings", StringValue ("{38, 40, BAND_5GHZ, 0}")); + Config::SetDefault("ns3::WifiPhy::ChannelSettings", StringValue("{38, 40, BAND_5GHZ, 0}")); * by setting an attribute value in the helper; e.g. :: TupleValue value; - value.Set (WifiPhy::ChannelTuple {38, 40, WIFI_PHY_BAND_5GHZ, 0}); - YansWifiPhyHelper wifiPhyHelper = YansWifiPhyHelper::Default (); - wifiPhyHelper.Set ("ChannelSettings", value); + value.Set(WifiPhy::ChannelTuple {38, 40, WIFI_PHY_BAND_5GHZ, 0}); + YansWifiPhyHelper wifiPhyHelper = YansWifiPhyHelper::Default(); + wifiPhyHelper.Set("ChannelSettings", value); -* by setting the WifiHelper::SetStandard (enum WifiStandard) method; and +* by setting the WifiHelper::SetStandard(enum WifiStandard) method; and * by performing post-installation configuration of the option, either via a Ptr to the WifiPhy object, or through the Config namespace; e.g.: :: - Config::Set ("/NodeList/0/DeviceList/*/$ns3::WifiNetDevice/Phy/$ns3::WifiPhy/ChannelSettings", - StringValue ("{38, 40, BAND_5GHZ, 0}")); + Config::Set("/NodeList/0/DeviceList/*/$ns3::WifiNetDevice/Phy/$ns3::WifiPhy/ChannelSettings", + StringValue("{38, 40, BAND_5GHZ, 0}")); This section provides guidance on how to properly configure these settings. @@ -311,27 +311,27 @@ Following are a few examples to clarify these rules: :: WifiHelper wifi; - wifi.SetStandard (WIFI_STANDARD_80211ac); + wifi.SetStandard(WIFI_STANDARD_80211ac); YansWifiPhyHelper phyHelper; - phyHelper.Set ("ChannelSettings", StringValue ("{58, 0, BAND_5GHZ, 0}")); + phyHelper.Set("ChannelSettings", StringValue("{58, 0, BAND_5GHZ, 0}")); // channel width unspecified // -> it is set to 80 MHz (width of channel 58) :: WifiHelper wifi; - wifi.SetStandard (WIFI_STANDARD_80211n); + wifi.SetStandard(WIFI_STANDARD_80211n); YansWifiPhyHelper phyHelper; - phyHelper.Set ("ChannelSettings", StringValue ("{0, 40, BAND_5GHZ, 0}")); + phyHelper.Set("ChannelSettings", StringValue("{0, 40, BAND_5GHZ, 0}")); // channel number unspecified // -> it is set to channel 38 (first 40 MHz channel in the 5GHz band) :: WifiHelper wifi; - wifi.SetStandard (WIFI_STANDARD_80211ax); + wifi.SetStandard(WIFI_STANDARD_80211ax); YansWifiPhyHelper phyHelper; - phyHelper.Set ("ChannelSettings", StringValue ("{0, 0, BAND_2_4GHZ, 0}")); + phyHelper.Set("ChannelSettings", StringValue("{0, 0, BAND_2_4GHZ, 0}")); // both channel number and width unspecified // -> width set to 20 MHz (default width for 802.11ax in the 2.4 GHZ band) // -> channel number set to 1 (first 20 MHz channel in the 2.4 GHz band) @@ -339,9 +339,9 @@ Following are a few examples to clarify these rules: :: WifiHelper wifi; - wifi.SetStandard (WIFI_STANDARD_80211a); + wifi.SetStandard(WIFI_STANDARD_80211a); YansWifiPhyHelper phyHelper; - phyHelper.Set ("ChannelSettings", StringValue ("{0, 0, BAND_UNSPECIFIED, 0}")); + phyHelper.Set("ChannelSettings", StringValue("{0, 0, BAND_UNSPECIFIED, 0}")); // band, channel number and width unspecified // -> band is set to WIFI_PHY_BAND_5GHZ (default band for 802.11a) // -> width set to 20 MHz (default width for 802.11a in the 5 GHZ band) @@ -458,7 +458,7 @@ simulator will exit with an error; for instance, such as: :: Ptr wifiPhy = ...; - wifiPhy->SetAttribute ("ChannelSettings", StringValue ("{1321, 20, BAND_5GHZ, 0}")); + wifiPhy->SetAttribute("ChannelSettings", StringValue("{1321, 20, BAND_5GHZ, 0}")); The known channel numbers are defined in the implementation file ``src/wifi/model/wifi-phy-operating-channel.cc``. Of course, this file may be edited @@ -471,10 +471,10 @@ such as: :: WifiHelper wifi; - wifi.SetStandard (WIFI_STANDARD_80211n); + wifi.SetStandard(WIFI_STANDARD_80211n); ... Ptr wifiPhy = ...; - wifiPhy->SetAttribute ("ChannelSettings", StringValue ("{14, 20, BAND_5GHZ, 0}")); + wifiPhy->SetAttribute("ChannelSettings", StringValue("{14, 20, BAND_5GHZ, 0}")); In the above, while channel number 14 is well-defined in practice for 802.11b only, it is for 2.4 GHz band, not 5 GHz band. @@ -520,19 +520,19 @@ For example the following user code configures a non-QoS and non-HT/non-VHT/non- will be a non-AP STA in an infrastructure network where the AP has SSID ``ns-3-ssid``:: WifiMacHelper wifiMacHelper; - Ssid ssid = Ssid ("ns-3-ssid"); - wifiMacHelper.SetType ("ns3::StaWifiMac", - "Ssid", SsidValue (ssid), - "ActiveProbing", BooleanValue (false)); + Ssid ssid = Ssid("ns-3-ssid"); + wifiMacHelper.SetType("ns3::StaWifiMac", + "Ssid", SsidValue(ssid), + "ActiveProbing", BooleanValue(false)); The following code shows how to create an AP with QoS enabled:: WifiMacHelper wifiMacHelper; - wifiMacHelper.SetType ("ns3::ApWifiMac", - "Ssid", SsidValue (ssid), - "QosSupported", BooleanValue (true), - "BeaconGeneration", BooleanValue (true), - "BeaconInterval", TimeValue (Seconds (2.5))); + wifiMacHelper.SetType("ns3::ApWifiMac", + "Ssid", SsidValue(ssid), + "QosSupported", BooleanValue(true), + "BeaconGeneration", BooleanValue(true), + "BeaconInterval", TimeValue(Seconds(2.5))); To create ad-hoc MAC instances, simply use ``ns3::AdhocWifiMac`` instead of ``ns3::StaWifiMac`` or ``ns3::ApWifiMac``. @@ -555,12 +555,12 @@ For example the following user code configures a MAC that will be a non-AP STA w in an infrastructure network where the AP has SSID ``ns-3-ssid``:: WifiMacHelper wifiMacHelper; - Ssid ssid = Ssid ("ns-3-ssid"); - wifiMacHelper.SetType ("ns3::StaWifiMac", - "Ssid", SsidValue (ssid), - "QosSupported", BooleanValue (true), - "BE_BlockAckThreshold", UintegerValue (2), - "ActiveProbing", BooleanValue (false)); + Ssid ssid = Ssid("ns-3-ssid"); + wifiMacHelper.SetType("ns3::StaWifiMac", + "Ssid", SsidValue(ssid), + "QosSupported", BooleanValue(true), + "BE_BlockAckThreshold", UintegerValue(2), + "ActiveProbing", BooleanValue(false)); For MAC instances that have 802.11n-style High Throughput (HT) and/or 802.11ac-style Very High Throughput (VHT) and/or 802.11ax-style High Efficiency (HE) support enabled, the ``ns3::WifiMacHelper`` can be also used to set: @@ -574,31 +574,31 @@ For example the following user code configures a MAC that will be a non-AP STA w in an infrastructure network where the AP has SSID ``ns-3-ssid``:: WifiHelper wifi; - wifi.SetStandard (WIFI_STANDARD_80211n); + wifi.SetStandard(WIFI_STANDARD_80211n); WifiMacHelper wifiMacHelper; - Ssid ssid = Ssid ("ns-3-ssid"); - wifiMacHelper.SetType ("ns3::StaWifiMac", - "Ssid", SsidValue (ssid), - "VO_MaxAmpduSize", UintegerValue (65535), - "BE_MaxAmsduSize", UintegerValue (7935), - "ActiveProbing", BooleanValue (false)); + Ssid ssid = Ssid("ns-3-ssid"); + wifiMacHelper.SetType("ns3::StaWifiMac", + "Ssid", SsidValue(ssid), + "VO_MaxAmpduSize", UintegerValue(65535), + "BE_MaxAmsduSize", UintegerValue(7935), + "ActiveProbing", BooleanValue(false)); 802.11ax APs support sending multi-user frames via DL OFDMA and UL OFDMA if a Multi-User Scheduler is -aggregated to the wifi MAC (by default no scheduler is aggregated). WifiMacHelper enables to aggregate +aggregated to the wifi MAC(by default no scheduler is aggregated). WifiMacHelper enables to aggregate a Multi-User Scheduler to an AP and set its parameters:: WifiMacHelper wifiMacHelper; - wifiMacHelper.SetMultiUserScheduler ("ns3::RrMultiUserScheduler", - "EnableUlOfdma", BooleanValue (true), - "EnableBsrp", BooleanValue (false)); + wifiMacHelper.SetMultiUserScheduler("ns3::RrMultiUserScheduler", + "EnableUlOfdma", BooleanValue(true), + "EnableBsrp", BooleanValue(false)); The Ack Manager is in charge of selecting the acknowledgment method among the three -available methods (see section :ref:`wifi-mu-ack-sequences` ). The default ack manager +available methods(see section :ref:`wifi-mu-ack-sequences` ). The default ack manager enables to select the acknowledgment method, e.g.:: - Config::SetDefault ("ns3::WifiDefaultAckManager::DlMuAckSequenceType", - EnumValue (WifiAcknowledgment::DL_MU_AGGREGATE_TF)); + Config::SetDefault("ns3::WifiDefaultAckManager::DlMuAckSequenceType", + EnumValue(WifiAcknowledgment::DL_MU_AGGREGATE_TF)); Selection of the Access Category (AC) +++++++++++++++++++++++++++++++++++++ @@ -611,9 +611,9 @@ packets are given in the :ref:`Type-of-service` section of the documentation. In summary, users can create an address of type :cpp:class:`ns3::InetSocketAddress` with the desired type of service value and pass it to the application helpers:: - InetSocketAddress destAddress (ipv4Address, udpPort); - destAddress.SetTos (tos); - OnOffHelper onoff ("ns3::UdpSocketFactory", destAddress); + InetSocketAddress destAddress(ipv4Address, udpPort); + destAddress.SetTos(tos); + OnOffHelper onoff("ns3::UdpSocketFactory", destAddress); Mapping the values of the DS field onto user priorities is performed similarly to the Linux mac80211 subsystem. Basically, the :cpp:func:`ns3::WifiNetDevice::SelectQueue()` @@ -665,7 +665,7 @@ CS7 111000xx 7 AC_VO So, for example,:: - destAddress.SetTos (0xc0); + destAddress.SetTos(0xc0); will map to CS6, User Priority 6, and Access Category AC_VO. Also, the ns3-wifi-ac-mapping test suite (defined in @@ -697,7 +697,7 @@ What does this do? It sets the default wifi standard to **802.11a** and sets th Now, let's use the wifiPhyHelper and wifiMacHelper created above to install WifiNetDevices on a set of nodes in a NodeContainer "c":: - NetDeviceContainer wifiContainer = WifiHelper::Install (wifiPhyHelper, wifiMacHelper, c); + NetDeviceContainer wifiContainer = WifiHelper::Install(wifiPhyHelper, wifiMacHelper, c); This creates the WifiNetDevice which includes also a WifiRemoteStationManager, a WifiMac, and a WifiPhy (connected to the matching Channel). @@ -706,30 +706,30 @@ The ``WifiHelper::SetStandard`` method sets various default timing parameters as In order to change parameters that are overwritten by ``WifiHelper::SetStandard``, this should be done post-install using ``Config::Set``:: WifiHelper wifi; - wifi.SetStandard (WIFI_STANDARD_80211n); - wifi.SetRemoteStationManager ("ns3::ConstantRateWifiManager", "DataMode", StringValue("HtMcs7"), "ControlMode", StringValue("HtMcs0")); + wifi.SetStandard(WIFI_STANDARD_80211n); + wifi.SetRemoteStationManager("ns3::ConstantRateWifiManager", "DataMode", StringValue("HtMcs7"), "ControlMode", StringValue("HtMcs0")); //Install PHY and MAC - Ssid ssid = Ssid ("ns3-wifi"); + Ssid ssid = Ssid("ns3-wifi"); WifiMacHelper mac; - mac.SetType ("ns3::StaWifiMac", - "Ssid", SsidValue (ssid), - "ActiveProbing", BooleanValue (false)); + mac.SetType("ns3::StaWifiMac", + "Ssid", SsidValue(ssid), + "ActiveProbing", BooleanValue(false)); NetDeviceContainer staDevice; - staDevice = wifi.Install (phy, mac, wifiStaNode); + staDevice = wifi.Install(phy, mac, wifiStaNode); - mac.SetType ("ns3::ApWifiMac", - "Ssid", SsidValue (ssid)); + mac.SetType("ns3::ApWifiMac", + "Ssid", SsidValue(ssid)); NetDeviceContainer apDevice; - apDevice = wifi.Install (phy, mac, wifiApNode); + apDevice = wifi.Install(phy, mac, wifiApNode); //Once install is done, we overwrite the standard timing values - Config::Set ("/NodeList/*/DeviceList/*/$ns3::WifiNetDevice/Phy/Slot", TimeValue (MicroSeconds (slot))); - Config::Set ("/NodeList/*/DeviceList/*/$ns3::WifiNetDevice/Phy/Sifs", TimeValue (MicroSeconds (sifs))); - Config::Set ("/NodeList/*/DeviceList/*/$ns3::WifiNetDevice/Phy/Pifs", TimeValue (MicroSeconds (pifs))); + Config::Set("/NodeList/*/DeviceList/*/$ns3::WifiNetDevice/Phy/Slot", TimeValue(MicroSeconds(slot))); + Config::Set("/NodeList/*/DeviceList/*/$ns3::WifiNetDevice/Phy/Sifs", TimeValue(MicroSeconds(sifs))); + Config::Set("/NodeList/*/DeviceList/*/$ns3::WifiNetDevice/Phy/Pifs", TimeValue(MicroSeconds(pifs))); The WifiHelper can be used to set the attributes of the default ack policy selector (``ConstantWifiAckPolicySelector``) or to select a different (user provided) ack @@ -738,16 +738,16 @@ following code can be used to set the BaThreshold attribute of the default ack policy selector associated with BE AC to 0.5:: WifiHelper wifi; - wifi.SetAckPolicySelectorForAc (AC_BE, "ns3::ConstantWifiAckPolicySelector", - "BaThreshold", DoubleValue (0.5)); + wifi.SetAckPolicySelectorForAc(AC_BE, "ns3::ConstantWifiAckPolicySelector", + "BaThreshold", DoubleValue(0.5)); The WifiHelper is also used to configure OBSS PD spatial reuse for 802.11ax. The following lines configure a WifiHelper to support OBSS PD spatial reuse using the ``ConstantObssPdAlgorithm`` with a threshold set to -72 dBm:: WifiHelper wifi; - wifi.SetObssPdAlgorithm ("ns3::ConstantObssPdAlgorithm", - "ObssPdLevel", DoubleValue (-72.0)); + wifi.SetObssPdAlgorithm("ns3::ConstantObssPdAlgorithm", + "ObssPdLevel", DoubleValue(-72.0)); There are many other |ns3| attributes that can be set on the above helpers to deviate from the default behavior; the example scripts show how to do some of @@ -765,15 +765,15 @@ manage HT-specific attributes. 802.11n/ac PHY layer can use either long (800 ns) or short (400 ns) OFDM guard intervals. To configure this parameter for a given device, the following lines of code could be used (in this example, it enables the support of a short guard interval for the first station):: - Ptr nd = wifiStaDevices.Get (0); - Ptr wnd = nd->GetObject (); - Ptr htConfiguration = wnd->GetHtConfiguration (); - htConfiguration->SetShortGuardIntervalSupported (true); + Ptr nd = wifiStaDevices.Get(0); + Ptr wnd = nd->GetObject(); + Ptr htConfiguration = wnd->GetHtConfiguration(); + htConfiguration->SetShortGuardIntervalSupported(true); It is also possible to configure HT-specific attributes using ``Config::Set``. -The following line of code enables the support of a short guard interval for all stations: +The following line of code enables the support of a short guard interval for all stations:: - Config::Set ("/NodeList/*/DeviceList/*/$ns3::WifiNetDevice/HtConfiguration/ShortGuardIntervalSupported", BooleanValue (true)); + Config::Set("/NodeList/*/DeviceList/*/$ns3::WifiNetDevice/HtConfiguration/ShortGuardIntervalSupported", BooleanValue(true)); VHT configuration ================= @@ -794,17 +794,17 @@ attributes for 802.11ax devices. 802.11ax PHY layer can use either 3200 ns, 1600 ns or 800 ns OFDM guard intervals. To configure this parameter, the following lines of code could be used (in this example, it enables the support of 1600 ns guard interval), such as in this example code snippet:: - Ptr nd = wifiStaDevices.Get (0); - Ptr wnd = nd->GetObject (); - Ptr heConfiguration = wnd->GetHeConfiguration (); - heConfiguration->SetGuardInterval (NanoSeconds (1600)); + Ptr nd = wifiStaDevices.Get(0); + Ptr wnd = nd->GetObject(); + Ptr heConfiguration = wnd->GetHeConfiguration(); + heConfiguration->SetGuardInterval(NanoSeconds(1600)); 802.11ax allows extended compressed Block ACKs containing a 256-bits bitmap, making possible transmissions of A-MPDUs containing up to 256 MPDUs, depending on the negotiated buffer size. In order to configure the buffer size of an 802.11ax device, the following line of code could be used:: - heConfiguration->SetMpduBufferSize (256); + heConfiguration->SetMpduBufferSize(256); For transmitting large MPDUs, it might also be needed to increase the maximum aggregation size (see above). @@ -844,41 +844,41 @@ We use the ``ns3::ConstantSpeedPropagationDelayModel`` as the propagation delay Both devices are configured with ``ConstantRateWifiManager`` at the fixed rate of 12Mbps. Finally, we manually place them by using the ``ns3::ListPositionAllocator``:: - std::string phyMode ("OfdmRate12Mbps"); + std::string phyMode("OfdmRate12Mbps"); NodeContainer c; - c.Create (2); + c.Create(2); WifiHelper wifi; - wifi.SetStandard (WIFI_STANDARD_80211a); + wifi.SetStandard(WIFI_STANDARD_80211a); - YansWifiPhyHelper wifiPhy = YansWifiPhyHelper::Default (); + YansWifiPhyHelper wifiPhy = YansWifiPhyHelper::Default(); // ns-3 supports RadioTap and Prism tracing extensions for 802.11 - wifiPhy.SetPcapDataLinkType (WifiPhyHelper::DLT_IEEE802_11_RADIO); + wifiPhy.SetPcapDataLinkType(WifiPhyHelper::DLT_IEEE802_11_RADIO); YansWifiChannelHelper wifiChannel; - wifiChannel.SetPropagationDelay ("ns3::ConstantSpeedPropagationDelayModel"); - wifiChannel.AddPropagationLoss ("ns3::LogDistancePropagationLossModel", - "Exponent", DoubleValue (3.0)); - wifiPhy.SetChannel (wifiChannel.Create ()); + wifiChannel.SetPropagationDelay("ns3::ConstantSpeedPropagationDelayModel"); + wifiChannel.AddPropagationLoss("ns3::LogDistancePropagationLossModel", + "Exponent", DoubleValue(3.0)); + wifiPhy.SetChannel(wifiChannel.Create()); // Add a non-QoS upper mac, and disable rate control (i.e. ConstantRateWifiManager) WifiMacHelper wifiMac; - wifi.SetRemoteStationManager ("ns3::ConstantRateWifiManager", - "DataMode",StringValue (phyMode), - "ControlMode",StringValue (phyMode)); + wifi.SetRemoteStationManager("ns3::ConstantRateWifiManager", + "DataMode",StringValue(phyMode), + "ControlMode",StringValue(phyMode)); // Set it to adhoc mode - wifiMac.SetType ("ns3::AdhocWifiMac"); - NetDeviceContainer devices = wifi.Install (wifiPhy, wifiMac, c); + wifiMac.SetType("ns3::AdhocWifiMac"); + NetDeviceContainer devices = wifi.Install(wifiPhy, wifiMac, c); // Configure mobility MobilityHelper mobility; - Ptr positionAlloc = CreateObject (); - positionAlloc->Add (Vector (0.0, 0.0, 0.0)); - positionAlloc->Add (Vector (5.0, 0.0, 0.0)); - mobility.SetPositionAllocator (positionAlloc); - mobility.SetMobilityModel ("ns3::ConstantPositionMobilityModel"); - mobility.Install (c); + Ptr positionAlloc = CreateObject(); + positionAlloc->Add(Vector(0.0, 0.0, 0.0)); + positionAlloc->Add(Vector(5.0, 0.0, 0.0)); + mobility.SetPositionAllocator(positionAlloc); + mobility.SetMobilityModel("ns3::ConstantPositionMobilityModel"); + mobility.Install(c); // other set up (e.g. InternetStack, Application) @@ -889,58 +889,58 @@ This is a typical example of how a user might configure an access point and a se In this example, we create one access point and two clients. Each node is equipped with 802.11b Wi-Fi device:: - std::string phyMode ("DsssRate1Mbps"); + std::string phyMode("DsssRate1Mbps"); NodeContainer ap; - ap.Create (1); + ap.Create(1); NodeContainer sta; - sta.Create (2); + sta.Create(2); WifiHelper wifi; - wifi.SetStandard (WIFI_STANDARD_80211b); + wifi.SetStandard(WIFI_STANDARD_80211b); - YansWifiPhyHelper wifiPhy = YansWifiPhyHelper::Default (); + YansWifiPhyHelper wifiPhy = YansWifiPhyHelper::Default(); // ns-3 supports RadioTap and Prism tracing extensions for 802.11 - wifiPhy.SetPcapDataLinkType (WifiPhyHelper::DLT_IEEE802_11_RADIO); + wifiPhy.SetPcapDataLinkType(WifiPhyHelper::DLT_IEEE802_11_RADIO); YansWifiChannelHelper wifiChannel; // reference loss must be changed since 802.11b is operating at 2.4GHz - wifiChannel.SetPropagationDelay ("ns3::ConstantSpeedPropagationDelayModel"); - wifiChannel.AddPropagationLoss ("ns3::LogDistancePropagationLossModel", - "Exponent", DoubleValue (3.0), - "ReferenceLoss", DoubleValue (40.0459)); - wifiPhy.SetChannel (wifiChannel.Create ()); + wifiChannel.SetPropagationDelay("ns3::ConstantSpeedPropagationDelayModel"); + wifiChannel.AddPropagationLoss("ns3::LogDistancePropagationLossModel", + "Exponent", DoubleValue(3.0), + "ReferenceLoss", DoubleValue(40.0459)); + wifiPhy.SetChannel(wifiChannel.Create()); // Add a non-QoS upper mac, and disable rate control WifiMacHelper wifiMac; - wifi.SetRemoteStationManager ("ns3::ConstantRateWifiManager", - "DataMode",StringValue (phyMode), - "ControlMode",StringValue (phyMode)); + wifi.SetRemoteStationManager("ns3::ConstantRateWifiManager", + "DataMode",StringValue(phyMode), + "ControlMode",StringValue(phyMode)); // Setup the rest of the upper mac - Ssid ssid = Ssid ("wifi-default"); + Ssid ssid = Ssid("wifi-default"); // setup ap. - wifiMac.SetType ("ns3::ApWifiMac", - "Ssid", SsidValue (ssid)); - NetDeviceContainer apDevice = wifi.Install (wifiPhy, wifiMac, ap); + wifiMac.SetType("ns3::ApWifiMac", + "Ssid", SsidValue(ssid)); + NetDeviceContainer apDevice = wifi.Install(wifiPhy, wifiMac, ap); NetDeviceContainer devices = apDevice; // setup sta. - wifiMac.SetType ("ns3::StaWifiMac", - "Ssid", SsidValue (ssid), - "ActiveProbing", BooleanValue (false)); - NetDeviceContainer staDevice = wifi.Install (wifiPhy, wifiMac, sta); - devices.Add (staDevice); + wifiMac.SetType("ns3::StaWifiMac", + "Ssid", SsidValue(ssid), + "ActiveProbing", BooleanValue(false)); + NetDeviceContainer staDevice = wifi.Install(wifiPhy, wifiMac, sta); + devices.Add(staDevice); // Configure mobility MobilityHelper mobility; - Ptr positionAlloc = CreateObject (); - positionAlloc->Add (Vector (0.0, 0.0, 0.0)); - positionAlloc->Add (Vector (5.0, 0.0, 0.0)); - positionAlloc->Add (Vector (0.0, 5.0, 0.0)); - mobility.SetPositionAllocator (positionAlloc); - mobility.SetMobilityModel ("ns3::ConstantPositionMobilityModel"); - mobility.Install (ap); - mobility.Install (sta); + Ptr positionAlloc = CreateObject(); + positionAlloc->Add(Vector(0.0, 0.0, 0.0)); + positionAlloc->Add(Vector(5.0, 0.0, 0.0)); + positionAlloc->Add(Vector(0.0, 5.0, 0.0)); + mobility.SetPositionAllocator(positionAlloc); + mobility.SetMobilityModel("ns3::ConstantPositionMobilityModel"); + mobility.Install(ap); + mobility.Install(sta); // other set up (e.g. InternetStack, Application) diff --git a/src/wimax/doc/wimax.rst b/src/wimax/doc/wimax.rst index 7bba8988a..58116d6a3 100644 --- a/src/wimax/doc/wimax.rst +++ b/src/wimax/doc/wimax.rst @@ -99,18 +99,18 @@ shows how to set up the model:: NodeContainer ssNodes; NodeContainer bsNodes; - ssNodes.Create (2); - bsNodes.Create (1); + ssNodes.Create(2); + bsNodes.Create(1); WimaxHelper wimax; NetDeviceContainer ssDevs, bsDevs; - ssDevs = wimax.Install (ssNodes, - WimaxHelper::DEVICE_TYPE_SUBSCRIBER_STATION, - WimaxHelper::SIMPLE_PHY_TYPE_OFDM, - scheduler); - bsDevs = wimax.Install (bsNodes, WimaxHelper::DEVICE_TYPE_BASE_STATION, WimaxHelper::SIMPLE_PHY_TYPE_OFDM, scheduler); + ssDevs = wimax.Install(ssNodes, + WimaxHelper::DEVICE_TYPE_SUBSCRIBER_STATION, + WimaxHelper::SIMPLE_PHY_TYPE_OFDM, + scheduler); + bsDevs = wimax.Install(bsNodes, WimaxHelper::DEVICE_TYPE_BASE_STATION, WimaxHelper::SIMPLE_PHY_TYPE_OFDM, scheduler); This example shows that there are two subscriber stations and one base station created. The helper method ``Install`` allows the user to specify the scheduler @@ -120,18 +120,18 @@ Different variants of ``Install`` are available; for instance, the example ``src/wimax/examples/wimax-multicast.cc`` shows how to specify a non-default channel or propagation model:: - channel = CreateObject (); - channel->SetPropagationModel (SimpleOfdmWimaxChannel::COST231_PROPAGATION); - ssDevs = wimax.Install (ssNodes, - WimaxHelper::DEVICE_TYPE_SUBSCRIBER_STATION, - WimaxHelper::SIMPLE_PHY_TYPE_OFDM, - channel, - scheduler); - Ptr dev = wimax.Install (bsNodes.Get (0), - WimaxHelper::DEVICE_TYPE_BASE_STATION, - WimaxHelper::SIMPLE_PHY_TYPE_OFDM, - channel, - scheduler); + channel = CreateObject(); + channel->SetPropagationModel(SimpleOfdmWimaxChannel::COST231_PROPAGATION); + ssDevs = wimax.Install(ssNodes, + WimaxHelper::DEVICE_TYPE_SUBSCRIBER_STATION, + WimaxHelper::SIMPLE_PHY_TYPE_OFDM, + channel, + scheduler); + Ptr dev = wimax.Install(bsNodes.Get(0), + WimaxHelper::DEVICE_TYPE_BASE_STATION, + WimaxHelper::SIMPLE_PHY_TYPE_OFDM, + channel, + scheduler); Mobility is also supported in the same way as in Wifi models; see the ``src/wimax/examples/wimax-multicast.cc``. @@ -143,11 +143,11 @@ issuing service flow identifiers and mapping them to WiMAX connections. The following code from ``src/wimax/examples/wimax-multicast.cc`` shows how this is configured from a helper level:: - ServiceFlow MulticastServiceFlow = wimax.CreateServiceFlow (ServiceFlow::SF_DIRECTION_DOWN, - ServiceFlow::SF_TYPE_UGS, - MulticastClassifier); + ServiceFlow MulticastServiceFlow = wimax.CreateServiceFlow(ServiceFlow::SF_DIRECTION_DOWN, + ServiceFlow::SF_TYPE_UGS, + MulticastClassifier); - bs->GetServiceFlowManager ()->AddMulticastServiceFlow (MulticastServiceFlow, WimaxPhy::MODULATION_TYPE_QPSK_12); + bs->GetServiceFlowManager()->AddMulticastServiceFlow(MulticastServiceFlow, WimaxPhy::MODULATION_TYPE_QPSK_12); Wimax Attributes @@ -183,8 +183,8 @@ WimaxHelper has similar APIs:: AsciiTraceHelper ascii; WimaxHelper wimax; - wimax.EnablePcap ("wimax-program", false); - wimax.EnableAsciiAll (ascii.CreateFileStream ("wimax-program.tr"); + wimax.EnablePcap("wimax-program", false); + wimax.EnableAsciiAll(ascii.CreateFileStream("wimax-program.tr"); Unlike other helpers, there is also a special ``EnableAsciiForConnection()`` method that limits the ascii tracing to a specific device and connection.