[network simulation] ns-3 Basics

6 ns-3 other modules

6.1 network module

Grouping: messages delivered, simulator base objects. Each packet in ns-3 includes a byte buffer and a Tag list. The buffer data is added and deleted through Header class and tracker class.

6.1.1 grouping

6.1.3 packet interface

Public member functions for grouped objects

// 1. Constructor
Packet();//Create an empty group with the new uid and return getuid
Packet(uint32_t size);//Payload size populated with size 0
// 2. Add or delete buffer data
void Add (Header const &header);// To add a header for the packet, ns3::Header::serializeTo() is called to serialize the header in the data packet buffer itself.
void Peek (Header &header);
void Remove (Header const &header);
// 3. Add or delete Tags to the group
template <typename T> // Define a template. Template is the template keyword. < > Inside is a parameter list. Type parameters are used here and declared with typename. T can make the function decide what type it is when calling (avoid writing too many overloaded functions).
void AddTag (T const &tag);// Improve code efficiency and declare references as constants

template <typename T>
bool RemoveTag (T &tag); // Remove label from group

template <typename T>
bool PeekTag (T &tag) const; // Copy a label stored internally. If there is no instance of this label, the input label will not be changed. 

void RemoveAllTags (void);// Delete all tags stored in this data group. Faster than removeTag.

// 4. Grouping
Packet CreateFragment (uint32_t start, uint32_t length) const; // Create a new data group containing a segment of the original data group. The returned data packets share the same uid.
void addAtEnd (Packet packet); // Connect the input data packet to the tail of the current data packet.
void AddAtEnd (Packet packet, uint32_t offset, uint32_t size); // Enter offset and size parameters.
void RemoveAtEnd (uint32_t size);
void RemoveAtStart (uint32_t size);

// 5. Other Miscellaneous
uint32_t GetSize (void) const; // Returns bytes of data packet size
uint8_t const *PeekData (void) const; //Returns a pointer to the internal buffer of a data packet
uint32_t GetUid (void) const;

6.1.4 example program

  1. src/network/examples/main-packet-header.cc
# include "ns3/ptr.h"
# include "ns3/packet.h"
# include "ns3/header.h"
# include <iostream>
using namespace std;

// Header instance definition
class MyHeader : public Header
{
	public:
		MyHeader (); // Constructor declaration
		virtual ~MyHeader (); // Destructor declaration
		void SetData (uint16_t data);
		uint16_t GetData (void) const;

		static TypeId GetTypeId (void);
		
		virtual TypeId 
}

// Member function definition
 
  1. src/network/examples/main-packet-tag.cc

6.1.5 implementation details

6.2 Internet module

6.2.1 Internet protocol stack

Source code: src/Internet

// Add protocol stack for node (before assigning IP address)
InternetStackHelper stack;
stack.Install (nodes);

It includes two layers of protocol components:

  1. Layer-3 protocols
    IPv4L3Protocol class
  2. Layer-4 protocols

6.2.2 routing

6.2.3 TCP

6.3 network equipment module

6.3.1 PointToPoint point to point

6.3.2 CSMA wired LAN

6.3.3 Wi Fi WLAN

6.4 application layer module

Application class: the base class of all applications, in src/network/model/application.h and application.cc.

There are several applications:

  1. UdpClientServer application
  • UDP based applications. This module has four classes: SeqTsHeader class (set and get the header of UDP protocol packet), UdpClient class (configure client), UdpServer class (configure server) and UdpClient class (similar to UdpClient class, but UdpClient class uses the specified file as the data stream, and UdpClient class uses the data stream automatically given by the system).

  • The Helper class is directly used by the user. Its header files are udp-client-server-helper.h and udp-client-server-helper.cc. The source code is ns-3.xx/src/applications/helper

  • Example: ns-3.xx/examples/udp-client-server/udp-client-server.cc

// Network topology
//
//       n0    n1
//       |     |
//       =======
//         LAN (CSMA)
//
// -UDP flow from n0 to n1 of 1024 byte packets at intervals of 50 ms within 50 ms, node n0 sends 1024 byte packets to n1
//   - maximum of 320 packets sent (or limited by simulation duration)
//   - option to use IPv4 or IPv6 addressing
//   - option to disable logging statements

#include <fstream>
#include "ns3/core-module.h"
#include "ns3/csma-module.h"
#include "ns3/applications-module.h"
#include "ns3/internet-module.h"

using namespace ns3;

NS_LOG_COMPONENT_DEFINE ("UdpClientServerExample");

int
main (int argc, char *argv[])
{
  // Declare variables used in command-line arguments
  bool useV6 = false;
  bool logging = true;
  Address serverAddress;

  CommandLine cmd (__FILE__);
  cmd.AddValue ("useIpv6", "Use Ipv6", useV6);
  cmd.AddValue ("logging", "Enable logging", logging);
  cmd.Parse (argc, argv);

  if (logging)
    {
      LogComponentEnable ("UdpClient", LOG_LEVEL_INFO);
      LogComponentEnable ("UdpServer", LOG_LEVEL_INFO);
    }

  NS_LOG_INFO ("Create nodes in above topology.");
  NodeContainer n;
  n.Create (2);

  InternetStackHelper internet;
  internet.Install (n);

  NS_LOG_INFO ("Create channel between the two nodes.");
  CsmaHelper csma;
  csma.SetChannelAttribute ("DataRate", DataRateValue (DataRate (5000000)));
  csma.SetChannelAttribute ("Delay", TimeValue (MilliSeconds (2)));
  csma.SetDeviceAttribute ("Mtu", UintegerValue (1400));
  NetDeviceContainer d = csma.Install (n);

  NS_LOG_INFO ("Assign IP Addresses.");
  if (useV6 == false)
    {
      Ipv4AddressHelper ipv4;
      ipv4.SetBase ("10.1.1.0", "255.255.255.0");
      Ipv4InterfaceContainer i = ipv4.Assign (d);
      serverAddress = Address (i.GetAddress (1));
    }
  else
    {
      Ipv6AddressHelper ipv6;
      ipv6.SetBase ("2001:0000:f00d:cafe::", Ipv6Prefix (64));
      Ipv6InterfaceContainer i6 = ipv6.Assign (d);
      serverAddress = Address(i6.GetAddress (1,1));
    }

  NS_LOG_INFO ("Create UdpServer application on node 1.");
  uint16_t port = 4000; // Define an unsigned 16bit variable, name it port number, and the value is 4000
  UdpServerHelper server (port); // Create the udpserverhapper object, name it server, and the parameter is port
  ApplicationContainer apps = server.Install (n.Get (1)); // ApplicationContainer install (nodecontainer C) function: create a UdpClientServer application from the node in the parameter and return an application container ApplicationContainer.
  apps.Start (Seconds (1.0)); 
  apps.Stop (Seconds (10.0));

  NS_LOG_INFO ("Create UdpClient application on node 0 to send to node 1.");
  uint32_t MaxPacketSize = 1024;
  Time interPacketInterval = Seconds (0.05);
  uint32_t maxPacketCount = 320;
  UdpClientHelper client (serverAddress, port); //Create the udpclienthhelper object.
  client.SetAttribute ("MaxPackets", UintegerValue (maxPacketCount));
  client.SetAttribute ("Interval", TimeValue (interPacketInterval));
  client.SetAttribute ("PacketSize", UintegerValue (MaxPacketSize));
  apps = client.Install (n.Get (0));
  apps.Start (Seconds (2.0));
  apps.Stop (Seconds (10.0));

  NS_LOG_INFO ("Run Simulation.");
  Simulator::Run ();
  Simulator::Destroy ();
  NS_LOG_INFO ("Done.");
}
  1. Udpeecho program
  • Echo response protocol is mainly used in debugging and detection, that is, what is received is sent back unopened. It can be based on TCP protocol or UDP protocol. The detected port is 7.
  • The UdpEcho application is UDP based and involves two classes: udpeconclient and UdpEchoServer.
  • Corresponding helper classes: UdpEchoServerHelper and UdpEchoClientHelper. Its header files: udp-echo-helper.h and udp-echo-helper.cc, source code: ns-3.xx/src/applications/helper
  1. Radvd
  2. Ping6 application
  • Ping: a command used to detect whether the network is unobstructed or the network connection speed.
  • The Ping6 application is IPv6 Based.
  • Ping6 class: class Ping6, class Ping6Helper
  • Example: ns-3.xx/examples/ipv6/ping6.cc
// Network topology
//
//       n0    n1
//       |     |
//       =================
//              LAN
//
// - ICMPv6 echo request flows from n0 to n1 and back with ICMPv6 echo reply
// - DropTail queues 
// - Tracing of queues and packet receptions to file "ping6.tr"

#include <fstream>
#include "ns3/core-module.h"
#include "ns3/internet-module.h"
#include "ns3/csma-module.h"
#include "ns3/internet-apps-module.h"

using namespace ns3;

NS_LOG_COMPONENT_DEFINE ("Ping6Example");

int main (int argc, char **argv)
{
  bool verbose = false;

  CommandLine cmd (__FILE__);
  cmd.AddValue ("verbose", "turn on log components", verbose);
  cmd.Parse (argc, argv);

  if (verbose)
    {
      LogComponentEnable ("Ping6Example", LOG_LEVEL_INFO);
      LogComponentEnable ("Ipv6EndPointDemux", LOG_LEVEL_ALL);
      LogComponentEnable ("Ipv6L3Protocol", LOG_LEVEL_ALL);
      LogComponentEnable ("Ipv6StaticRouting", LOG_LEVEL_ALL);
      LogComponentEnable ("Ipv6ListRouting", LOG_LEVEL_ALL);
      LogComponentEnable ("Ipv6Interface", LOG_LEVEL_ALL);
      LogComponentEnable ("Icmpv6L4Protocol", LOG_LEVEL_ALL);
      LogComponentEnable ("Ping6Application", LOG_LEVEL_ALL);
      LogComponentEnable ("NdiscCache", LOG_LEVEL_ALL);
    }

  NS_LOG_INFO ("Create nodes.");
  NodeContainer n;
  n.Create (4);

  /* Install IPv4/IPv6 stack */
  InternetStackHelper internetv6;
  internetv6.SetIpv4StackInstall (false);
  internetv6.Install (n);

  NS_LOG_INFO ("Create channels.");
  CsmaHelper csma;
  csma.SetChannelAttribute ("DataRate", DataRateValue (5000000));
  csma.SetChannelAttribute ("Delay", TimeValue (MilliSeconds (2)));
  NetDeviceContainer d = csma.Install (n);

  Ipv6AddressHelper ipv6;
  NS_LOG_INFO ("Assign IPv6 Addresses.");
  Ipv6InterfaceContainer i = ipv6.Assign (d);

  NS_LOG_INFO ("Create Applications.");

  /* Create a Ping6 application to send ICMPv6 echo request from node zero to
   * all-nodes (ff02::1).
   */
  uint32_t packetSize = 1024;
  uint32_t maxPacketCount = 5;
  Time interPacketInterval = Seconds (1.);
  Ping6Helper ping6;

  /*
     ping6.SetLocal (i.GetAddress (0, 1)); 
     ping6.SetRemote (i.GetAddress (1, 1));
     */
  ping6.SetIfIndex (i.GetInterfaceIndex (0)); // GetInterfaceIndex(0) get the address of node 0 in the IPv6 address as the running host of the ping program.
  ping6.SetRemote (Ipv6Address::GetAllNodesMulticast ()); // GetAllNodesMulticast() gets the IP addresses of all hosts. ping6.SetRemote() sets the parameters of the ping command, which are all PC s in the LAN.

  ping6.SetAttribute ("MaxPackets", UintegerValue (maxPacketCount));
  ping6.SetAttribute ("Interval", TimeValue (interPacketInterval));
  ping6.SetAttribute ("PacketSize", UintegerValue (packetSize));
  ApplicationContainer apps = ping6.Install (n.Get (0));
  apps.Start (Seconds (2.0));
  apps.Stop (Seconds (10.0));

  AsciiTraceHelper ascii;
  csma.EnableAsciiAll (ascii.CreateFileStream ("ping6.tr"));
  csma.EnablePcapAll (std::string ("ping6"), true);

  NS_LOG_INFO ("Run Simulation.");
  Simulator::Run ();
  Simulator::Destroy ();
  NS_LOG_INFO ("Done.");
}


  1. PacketSink module: receiving packets
  2. OnOffApplication
  3. BulkSendApplication
    Learning method: first look at the definition API of the class and its Helper (in ns-3.xx/src, just look at the. h file to understand the input and output of the class member function) - > then look at the examples to understand how to use it in the script program (in ns-3.xx/examples).

Example 1: ns-3.xx/examples/tcp/tcp-star-sever.cc. PacketSink and OnOffApplication modules are used.

// Default Network topology, 9 nodes in a star
/*
          n2 n3 n4
           \ | /
            \|/
       n1---n0---n5
            /| \
           / | \
          n8 n7 n6
*/
// - CBR Traffic goes from the star "arms" to the "hub"
// - Tracing of queues and packet receptions to file
//   "tcp-star-server.tr"
// - pcap traces also generated in the following files
//   "tcp-star-server-$n-$i.pcap" where n and i represent node and interface numbers respectively
// Usage examples for things you might want to tweak:
//       ./waf --run="tcp-star-server"
//       ./waf --run="tcp-star-server --nNodes=25"
//       ./waf --run="tcp-star-server --ns3::OnOffApplication::DataRate=10000"
//       ./waf --run="tcp-star-server --ns3::OnOffApplication::PacketSize=500"
// See the ns-3 tutorial for more info on the command line: 
// http://www.nsnam.org/tutorials.html




#include <iostream>
#include <fstream>
#include <string>
#include <cassert>

#include "ns3/core-module.h"
#include "ns3/network-module.h"
#include "ns3/internet-module.h"
#include "ns3/point-to-point-module.h"
#include "ns3/applications-module.h"
#include "ns3/ipv4-global-routing-helper.h"

using namespace ns3;

NS_LOG_COMPONENT_DEFINE ("TcpServer");

int 
main (int argc, char *argv[])
{
  // Users may find it convenient to turn on explicit debugging
  // for selected modules; the below lines suggest how to do this

  //LogComponentEnable ("TcpServer", LOG_LEVEL_INFO);
  //LogComponentEnable ("TcpL4Protocol", LOG_LEVEL_ALL);
  //LogComponentEnable ("TcpSocketImpl", LOG_LEVEL_ALL);
  //LogComponentEnable ("PacketSink", LOG_LEVEL_ALL);

  // Set up some default values for the simulation.
  Config::SetDefault ("ns3::OnOffApplication::PacketSize", UintegerValue (250));
  Config::SetDefault ("ns3::OnOffApplication::DataRate", StringValue ("5kb/s"));
  uint32_t N = 9; //number of nodes in the star

  // Allow the user to override any of the defaults and the above
  // Config::SetDefault()s at run-time, via command-line arguments
  CommandLine cmd (__FILE__);
  cmd.AddValue ("nNodes", "Number of nodes to place in the star", N);
  cmd.Parse (argc, argv);

  // Here, we will create N nodes in a star.
  NS_LOG_INFO ("Create nodes.");
  NodeContainer serverNode;
  NodeContainer clientNodes;
  serverNode.Create (1);
  clientNodes.Create (N-1);
  NodeContainer allNodes = NodeContainer (serverNode, clientNodes);

  // Install network stacks on the nodes
  InternetStackHelper internet;
  internet.Install (allNodes);

  //Collect an adjacency list of nodes for the p2p topology
  std::vector<NodeContainer> nodeAdjacencyList (N-1);
  for(uint32_t i=0; i<nodeAdjacencyList.size (); ++i)
    {
      nodeAdjacencyList[i] = NodeContainer (serverNode, clientNodes.Get (i));
    }

  // We create the channels first without any IP addressing information
  NS_LOG_INFO ("Create channels.");
  PointToPointHelper p2p;
  p2p.SetDeviceAttribute ("DataRate", StringValue ("5Mbps"));
  p2p.SetChannelAttribute ("Delay", StringValue ("2ms"));
  std::vector<NetDeviceContainer> deviceAdjacencyList (N-1);
  for(uint32_t i=0; i<deviceAdjacencyList.size (); ++i)
    {
      deviceAdjacencyList[i] = p2p.Install (nodeAdjacencyList[i]);
    }

  // Later, we add IP addresses.
  NS_LOG_INFO ("Assign IP Addresses.");
  Ipv4AddressHelper ipv4;
  std::vector<Ipv4InterfaceContainer> interfaceAdjacencyList (N-1);
  for(uint32_t i=0; i<interfaceAdjacencyList.size (); ++i)
    {
      std::ostringstream subnet;
      subnet<<"10.1."<<i+1<<".0";
      ipv4.SetBase (subnet.str ().c_str (), "255.255.255.0");
      interfaceAdjacencyList[i] = ipv4.Assign (deviceAdjacencyList[i]);
    }

  //Turn on global static routing
  Ipv4GlobalRoutingHelper::PopulateRoutingTables ();

  // 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); // Use the constructor to create an application for the central node hub. The first parameter is the protocol and the second parameter is the IP address.
  ApplicationContainer sinkApp = sinkHelper.Install (serverNode);
  sinkApp.Start (Seconds (1.0));
  sinkApp.Stop (Seconds (10.0));

  // Create the OnOff applications to send TCP to the server
  OnOffHelper clientHelper ("ns3::TcpSocketFactory", Address ());
  clientHelper.SetAttribute ("OnTime", StringValue ("ns3::ConstantRandomVariable[Constant=1]"));
  clientHelper.SetAttribute ("OffTime", StringValue ("ns3::ConstantRandomVariable[Constant=0]"));

  //normally wouldn't need a loop here but the server IP address is different
  //on each p2p subnet
  ApplicationContainer clientApps;
  for(uint32_t i=0; i<clientNodes.GetN (); ++i)
    {
      AddressValue remoteAddress
        (InetSocketAddress (interfaceAdjacencyList[i].GetAddress (0), port));
      clientHelper.SetAttribute ("Remote", remoteAddress);
      clientApps.Add (clientHelper.Install (clientNodes.Get (i)));
    }
  clientApps.Start (Seconds (1.0));
  clientApps.Stop (Seconds (10.0));


  //configure tracing
  AsciiTraceHelper ascii;
  p2p.EnableAsciiAll (ascii.CreateFileStream ("tcp-star-server.tr"));
  p2p.EnablePcapAll ("tcp-star-server");

  NS_LOG_INFO ("Run Simulation.");
  Simulator::Run ();
  Simulator::Destroy ();
  NS_LOG_INFO ("Done.");

  return 0;
}

Example 2: ns-3.xx/examples/tcp/tcp-bukl-send.cc. PacketSink and BulkSendApplication modules are used.

/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
/*
 * This program is free software; you can redistribute it and/or modify
 * it under the terms of the GNU General Public License version 2 as
 * published by the Free Software Foundation;
 *
 * This program is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU General Public License for more details.
 *
 * You should have received a copy of the GNU General Public License
 * along with this program; if not, write to the Free Software
 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
 */

// Network topology
//
//       n0 ----------- n1
//            500 Kbps
//             5 ms
//
// - Flow from n0 to n1 using BulkSendApplication.
// - Tracing of queues and packet receptions to file "tcp-bulk-send.tr"
//   and pcap tracing available when tracing is turned on.

#include <string>
#include <fstream>
#include "ns3/core-module.h"
#include "ns3/point-to-point-module.h"
#include "ns3/internet-module.h"
#include "ns3/applications-module.h"
#include "ns3/network-module.h"
#include "ns3/packet-sink.h"

using namespace ns3;

NS_LOG_COMPONENT_DEFINE ("TcpBulkSendExample");

int
main (int argc, char *argv[])
{

  bool tracing = false;
  uint32_t maxBytes = 0;

//
// Allow the user to override any of the defaults at
// run-time, via command-line arguments
//
  CommandLine cmd (__FILE__);
  cmd.AddValue ("tracing", "Flag to enable/disable tracing", tracing);
  cmd.AddValue ("maxBytes",
                "Total number of bytes for application to send", maxBytes);
  cmd.Parse (argc, argv);

//
// Explicitly create the nodes required by the topology (shown above).
//
  NS_LOG_INFO ("Create nodes.");
  NodeContainer nodes;
  nodes.Create (2);

  NS_LOG_INFO ("Create channels.");

//
// Explicitly create the point-to-point link required by the topology (shown above).
//
  PointToPointHelper pointToPoint;
  pointToPoint.SetDeviceAttribute ("DataRate", StringValue ("500Kbps"));
  pointToPoint.SetChannelAttribute ("Delay", StringValue ("5ms"));

  NetDeviceContainer devices;
  devices = pointToPoint.Install (nodes);

//
// Install the internet stack on the nodes
//
  InternetStackHelper internet;
  internet.Install (nodes);

//
// We've got the "hardware" in place.  Now we need to add IP addresses.
//
  NS_LOG_INFO ("Assign IP Addresses.");
  Ipv4AddressHelper ipv4;
  ipv4.SetBase ("10.1.1.0", "255.255.255.0");
  Ipv4InterfaceContainer i = ipv4.Assign (devices);

  NS_LOG_INFO ("Create Applications.");

//
// Create a BulkSendApplication and install it on node 0
//
  uint16_t port = 9;  // well-known echo port number


  BulkSendHelper source ("ns3::TcpSocketFactory",
                         InetSocketAddress (i.GetAddress (1), port));
  // Set the amount of data to send in bytes.  Zero is unlimited.
  source.SetAttribute ("MaxBytes", UintegerValue (maxBytes));
  ApplicationContainer sourceApps = source.Install (nodes.Get (0));
  sourceApps.Start (Seconds (0.0));
  sourceApps.Stop (Seconds (10.0));

//
// Create a PacketSinkApplication and install it on node 1
//
  PacketSinkHelper sink ("ns3::TcpSocketFactory",
                         InetSocketAddress (Ipv4Address::GetAny (), port));
  ApplicationContainer sinkApps = sink.Install (nodes.Get (1));
  sinkApps.Start (Seconds (0.0));
  sinkApps.Stop (Seconds (10.0));

//
// Set up tracing if enabled
//
  if (tracing)
    {
      AsciiTraceHelper ascii;
      pointToPoint.EnableAsciiAll (ascii.CreateFileStream ("tcp-bulk-send.tr"));
      pointToPoint.EnablePcapAll ("tcp-bulk-send", false);
    }

//
// Now, do the actual simulation.
//
  NS_LOG_INFO ("Run Simulation.");
  Simulator::Stop (Seconds (10.0));
  Simulator::Run ();
  Simulator::Destroy ();
  NS_LOG_INFO ("Done.");

  Ptr<PacketSink> sink1 = DynamicCast<PacketSink> (sinkApps.Get (0));
  std::cout << "Total Bytes Received: " << sink1->GetTotalRx () << std::endl;
}

6.5 mobile module

  • In ns-3, the mobile model is integrated in the mobile node. You can use GetObject < mobilitymodel > () to extract the mobile model from the node with the bound model.
  • All mobile models inherit the ns3::MobilityModel class.
  • The initial location distribution of mobile nodes is the responsibility of the PositionAllocator class.
  • The MobileHelper class integrates the mobile model and location allocation together to facilitate the installation of the mobile model for Node nodes.
  • ns3::Vector class is the base class of coordinate system.

ns3::MobilityModel class

  • Base class for all mobile models. Current position (m) and speed (m/s) of the tracking object
  • Defined in Src / mobility / model / mobility model. H
#ifndef MOBILITY_MODEL_H
#define MOBILITY_MODEL_H

#include "ns3/vector.h"
#include "ns3/object.h"
#include "ns3/traced-callback.h"

namespace ns3 {
class MobilityModel : public Object
{
public:
  /**
   * Register this type with the TypeId system.
   * \return the object TypeId
   */
  static TypeId GetTypeId (void);
  MobilityModel ();
  virtual ~MobilityModel () = 0;

  /**
   * \return the current position
   */
  Vector GetPosition (void) const;
  /**
   * \param position the position to set.
   */
  void SetPosition (const Vector &position);
  /**
   * \return the current velocity.
   */
  Vector GetVelocity (void) const;
  /**
   * \param position a reference to another mobility model
   * \return the distance between the two objects. Unit is meters.
   */
  double GetDistanceFrom (Ptr<const MobilityModel> position) const;
  /**
   * \param other reference to another object's mobility model
   * \return the relative speed between the two objects. Unit is meters/s.
   */
  double GetRelativeSpeed (Ptr<const MobilityModel> other) const;
  /**
   * Assign a fixed random variable stream number to the random variables
   * used by this model. Return the number of streams (possibly zero) that
   * have been assigned.
   *
   * \param stream first stream index to use
   * \return the number of stream indices assigned by this model
   */
  int64_t AssignStreams (int64_t stream);

  /**
   *  TracedCallback signature.
   *
   * \param [in] model Value of the MobilityModel.
   */
  typedef void (* TracedCallback)(Ptr<const MobilityModel> model);
  
protected:
  /**
   * Must be invoked by subclasses when the course of the
   * position changes to notify course change listeners.
   */
  void NotifyCourseChange (void) const;
private:
  /**
   * \return the current position.
   *
   * Concrete subclasses of this base class must 
   * implement this method.
   */
  virtual Vector DoGetPosition (void) const = 0;
  /**
   * \param position the position to set.
   *
   * Concrete subclasses of this base class must 
   * implement this method.
   */
  virtual void DoSetPosition (const Vector &position) = 0;
  /**
   * \return the current velocity.
   *
   * Concrete subclasses of this base class must 
   * implement this method.
   */
  virtual Vector DoGetVelocity (void) const = 0;
  /**
   * The default implementation does nothing but return the passed-in
   * parameter.  Subclasses using random variables are expected to
   * override this.
   * \param start  starting stream index
   * \return the number of streams used
   */
  virtual int64_t DoAssignStreams (int64_t start);

  /**
   * Used to alert subscribers that a change in direction, velocity,
   * or position has occurred.
   */
  ns3::TracedCallback<Ptr<const MobilityModel> > m_courseChangeTrace;

};

} // namespace ns3

#endif /* MOBILITY_MODEL_H */

Use of mobile models.
Example 1: third.cc

  MobilityHelper mobility; // Declare the object mobility with the MobilityHelper class
  mobility.SetPositionAllocator ("ns3::GridPositionAllocator", // Scheme for setting the initial position. It includes: listpositionallocator (initial location list of user-defined nodes), gridpositionallocator (initializing the location of nodes according to the table form), randomrectanglepositionallocator (giving the initialization node location of random matrix), randomboxpositionallocator (giving a random solid rectangle allocation scheme)
                                 "MinX", DoubleValue (0.0),
                                 "MinY", DoubleValue (0.0),
                                 "DeltaX", DoubleValue (5.0),
                                 "DeltaY", DoubleValue (10.0),
                                 "GridWidth", UintegerValue (3),
                                 "LayoutType", StringValue ("RowFirst")); // Call the SetPositionAllocator() function to initialize the initial position of the node

  mobility.SetMobilityModel ("ns3::RandomWalk2dMobilityModel",
                             "Bounds", RectangleValue (Rectangle (-50, 50, -50, 50))); // Call SetMobilityModel() to set the mobile model to use
  mobility.Install (wifiStaNodes); // Install the prepared mobile model on each node

  mobility.SetMobilityModel ("ns3::ConstantPositionMobilityModel");
  mobility.Install (wifiApNode);

Example 2: src/mobility/examples/main-random-walk.cc

6.6 energy module

In reality, wireless devices consume energy. In simulation, it is necessary to determine the energy consumption of nodes or networks, so it is necessary to ns-3 model the energy consumption.

6.6.1 model description

ns-3 energy module consists of two parts: energy resources (battery, gas) and equipment energy model (each equipment has multiple states, and each state has a power consumption value).

6.6.2 usage

Interaction with ns-3 energy module: through assistant API and exposed module properties.
Using the module, first install the energy resources for the nodes and install the corresponding equipment energy model for the network equipment.
Examples: src/examples/energy and examples/energy.

  1. assistant

  2. attribute

  3. track

  4. verification

6.6.3 example

  • ns-3.xx/src/energy/examples/li-ion-energy-source.cc
/*
 * Author: Andrea Sacco <andrea.sacco85@gmail.com>
 */

#include "ns3/log.h"
#include "ns3/simulator.h"
#include "ns3/command-line.h"
#include "ns3/simple-device-energy-model.h"
#include "ns3/li-ion-energy-source.h"
#include "ns3/energy-source-container.h"

using namespace ns3;

/**
 * In this simple example, we show how to create and drain energy from a
 * LiIonEnergySource. Creation and consumption of lithium ion energy
 * We make a series of discharge calls to the energy source class with
 * different current drain and duration until all the energy is depleted
 * from the cell. We make a series of discharge calls on energy classes with different current consumption and duration until all energy is exhausted from the battery
 *
 * Every 20 seconds it is printed out the actual cell voltage to verify
 * that it follows the discharge curve of the datasheet [1]. Print the battery voltage every 20s to prove that it conforms to the discharge curve in data table 1
 *
 * At the end of the example it is verified that after the energy depletion
 * call, the cell voltage is below the threshold voltage. When the voltage is lower than the threshold, the energy stops calling
 *
 * References:
 * [1] Panasonic CGR18650DA Datasheet, http://www.panasonic.com/industrial/includes/pdf/Panasonic_LiIon_CGR18650DA.pdf
 */

static void
PrintCellInfo (Ptr<LiIonEnergySource> es)
{
  std::cout << "At " << Simulator::Now ().As (Time::S) << " Cell voltage: " << es->GetSupplyVoltage () << " V Remaining Capacity: " <<
  es->GetRemainingEnergy () / (3.6 * 3600) << " Ah" << std::endl;

  if (!Simulator::IsFinished ())
    {
      Simulator::Schedule (Seconds (20),
                           &PrintCellInfo,
                           es);
    }
}

int
main (int argc, char **argv)
{
  CommandLine cmd (__FILE__);
  cmd.Parse (argc, argv);
  
    // uncomment below to see the energy consumption details
  // LogComponentEnable ("LiIonEnergySource", LOG_LEVEL_DEBUG);

  Ptr<Node> node = CreateObject<Node> (); // Generation node

  Ptr<SimpleDeviceEnergyModel> sem = CreateObject<SimpleDeviceEnergyModel> ();
  Ptr<EnergySourceContainer> esCont = CreateObject<EnergySourceContainer> ();
  Ptr<LiIonEnergySource> es = CreateObject<LiIonEnergySource> ();
  esCont->Add (es);
  es->SetNode (node);
  sem->SetEnergySource (es);
  es->AppendDeviceEnergyModel (sem);
  sem->SetNode (node);
  node->AggregateObject (esCont);

  Time now = Simulator::Now ();

  // discharge at 2.33 A for 1700 seconds
  sem->SetCurrentA (2.33);
  now += Seconds (1701);


  // discharge at 4.66 A for 628 seconds
  Simulator::Schedule (now,
                       &SimpleDeviceEnergyModel::SetCurrentA,
                       sem,
                       4.66);
  now += Seconds (600);

  PrintCellInfo (es);

  Simulator::Stop (now);
  Simulator::Run ();
  Simulator::Destroy ();

  // the cell voltage should be under 3.3v
  DoubleValue v;
  es->GetAttribute ("ThresholdVoltage", v);
  NS_ASSERT (es->GetSupplyVoltage () <= v.Get ());
}

# function
./waf --run li-ion-energy-source
# result
At 0 Cell voltage : 4.05 V Remaining Capacity : 2.45 Ah
...

6.7 adding modules

6.7.1 generate new module

6.7.2 adding new modules

7 example

7.1 first.cc

Location: ns-3.xx/examples/tutorial/

//0. Emacs mode line, explaining the predetermined format of the code (GNU, General Public License license)
/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */ 
/*
 * This program is free software; you can redistribute it and/or modify
 * it under the terms of the GNU General Public License version 2 as
 * published by the Free Software Foundation;
 *
 * This program is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU General Public License for more details.
 *
 * You should have received a copy of the GNU General Public License
 * along with this program; if not, write to the Free Software
 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
 */
//1. Header file
#include "ns3/core-module.h" //all header file is at build/ns3
#include "ns3/network-module.h"
#include "ns3/internet-module.h"
#include "ns3/point-to-point-module.h"
#include "ns3/applications-module.h"
#include "ns3/netanim-module.h"
// Create a simple point-to-point communication between two nodes
// Default Network Topology
//
//       10.1.1.0
// n0 -------------- n1
//    point-to-point
//

//2. Namespace
using namespace ns3; //if is not at namespace ns3, add xx:: ,e.g. Time::NS, std::cout, std::min()

//3. Define log module (allow script to print auxiliary information using macro definition in log system)
NS_LOG_COMPONENT_DEFINE ("FirstScriptExample");

//4. Main function
int
main (int argc, char *argv[])
{
  CommandLine cmd;//You can enter parameters on the command line, such as sudo. / WAF -- run "Hello simulator -- numbers = 5"
  cmd.Parse (argc, argv);//Read command line parameters
  
  Time::SetResolution (Time::NS);//Minimum unit time, MS
  //Set the client-side and server-side log levels of the "UdpEcho" application to the "INFO" level. That is, when the simulation generates data packet sending and receiving, the corresponding application will output the corresponding log message to the relevant log module.
  LogComponentEnable ("UdpEchoClientApplication",LOG_LEVEL_INFO); 
  LogComponentEnable ("UdpEchoServerApplication", LOG_LEVEL_INFO);

  //5. Create network topology
  NodeContainer nodes; 
  nodes.Create (2); //Create two network nodes and access: nodes.Get (0) and nodes.Get (1)

  PointToPointHelper pointToPoint; //Create p2p helper class
  pointToPoint.SetDeviceAttribute ("DataRate", StringValue ("5Mbps"));//Set device properties - transfer rate of the device
  pointToPoint.SetChannelAttribute ("Delay", StringValue ("2ms"));
  NetDeviceContainer devices;//Create network device
  devices = pointToPoint.Install (nodes);// The pointToPoint.Install (nodes) function creates two p2p network device objects and one p2p channel object, and connects them together.

  //6. Install TCP/IP protocol stack
  InternetStackHelper stack;
  stack.Install (nodes);//Install the TCP/IP protocol stack for the nodes in the nodes container, mainly the IP layer

  Ipv4AddressHelper address;//Assign IP addresses to network devices, and the topology assistant manages the allocation of IP addresses
  address.SetBase ("10.1.1.0", "255.255.255.0");//Set start address, subnet mask

  Ipv4InterfaceContainer interfaces = address.Assign (devices);//Assign the generated ip address to each device (the address starts from 1 and increases monotonically, i.e. 10.1.1.1, 10.1.1.2)

  //7. Install the application
//Server side
  UdpEchoServerHelper echoServer (9);//The listening port of the server is 9

  ApplicationContainer serverApps = echoServer.Install (nodes.Get (1));// The echoServer.Install() method installs the echoServer application on node 1 and records it with the ApplicationContainer
  serverApps.Start (Seconds (1.0));//Set the application to start running in 1s
  serverApps.Stop (Seconds (10.0));//End of 10s
//client
  UdpEchoClientHelper echoClient (interfaces.GetAddress (1), 9);//The client assistant class UdpEchoClientHelper creates an application echoClient at node 0. Properties: connect to ip address and port 1
  echoClient.SetAttribute ("MaxPackets", UintegerValue (1));//The maximum number of packets that can be sent during simulation is 1
  echoClient.SetAttribute ("Interval", TimeValue (Seconds (1.0))); //Packet sending interval 1s
  echoClient.SetAttribute ("PacketSize", UintegerValue (1024));//Packet load byte size, 1024bit

  ApplicationContainer clientApps = echoClient.Install (nodes.Get (0));
  clientApps.Start (Seconds (2.0));
  clientApps.Stop (Seconds (10.0));//2s after the simulation is started, node 0 sends a 1024bit UDP packet to port 9 of node 1, and the 10s ends

  //this is set for visualization (NetAnim)
  AnimationInterface anim("first.xml");
  anim.SetConstantPosition(nodes.Get(0), 1.0, 2.0);
  anim.SetConstantPosition(nodes.Get(1), 2.0, 3.0);
  
  //8. Start and end
  Simulator::Run ();
  Simulator::Destroy ();
  return 0;
}

7.2 second.cc

/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
/*
 * This program is free software; you can redistribute it and/or modify
 * it under the terms of the GNU General Public License version 2 as
 * published by the Free Software Foundation;
 *
 * This program is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU General Public License for more details.
 *
 * You should have received a copy of the GNU General Public License
 * along with this program; if not, write to the Free Software
 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
 */
// Run command under ns-3.29
// cp examples/tutorial/second.cc scratch/second.cc
// ./waf --run second
// . / waf --run second --vis # visualization
// . / waf --run "second -- nCsma=100" -- vis # number of nodes in LAN 3 - > 101

//1. Header file
#include "ns3/core-module.h"
#include "ns3/network-module.h"
#include "ns3/csma-module.h"
#include "ns3/internet-module.h"
#include "ns3/point-to-point-module.h"
#include "ns3/applications-module.h"
#include "ns3/ipv4-global-routing-helper.h"
//Simulation topology, there are two kinds of networks: p2p network and CSMA network, with 2 and 4 nodes respectively. There are two netdevices installed on n1, i.e. p2p and CSMA. n0 communicates with n4 through n1.
// Default Network Topology
//
//       10.1.1.0
// n0 -------------- n1   n2   n3   n4
//    point-to-point  |    |    |    |
//                    ================
//                      LAN 10.1.2.0

//2. Namespace
using namespace ns3;

//3. Define LOG module
NS_LOG_COMPONENT_DEFINE ("SecondScriptExample");

//4. Main function
int 
main (int argc, char *argv[])
{
  bool verbose = true;//Define variables to decide whether to open the logging component of two applications; The default is true
  uint32_t nCsma = 3;//There are three additional node s in the LAN

  //Declaring nCsma variables using the command line
  CommandLine cmd;
  cmd.AddValue ("nCsma", "Number of \"extra\" CSMA nodes/devices", nCsma);//Add command line arguments. The nCsma variable indicates the number of CSMA nodes
  cmd.AddValue ("verbose", "Tell echo applications to log if true", verbose);

  cmd.Parse (argc,argv);//Read command line parameters

  if (verbose)
    {
      LogComponentEnable ("UdpEchoClientApplication", LOG_LEVEL_INFO);  //Print UdpEchoClientApplication component information
      LogComponentEnable ("UdpEchoServerApplication", LOG_LEVEL_INFO); //Print udpsechoserverapplication component information
    }

  nCsma = nCsma == 0 ? 1 : nCsma;
  //5. Create network topology
  NodeContainer p2pNodes;
  p2pNodes.Create (2);//Create two p2p nodes, N0 --- N1

  NodeContainer csmaNodes;
  csmaNodes.Add (p2pNodes.Get (1));//n1 node is both a p2p node and a csma node
  csmaNodes.Create (nCsma);//Create additional nCsma csma nodes, n2,n3,n4

  PointToPointHelper pointToPoint;//p2p assistant class to set device and channel properties
  pointToPoint.SetDeviceAttribute ("DataRate", StringValue ("5Mbps"));//Set the device transmission rate to 5Mbps
  pointToPoint.SetChannelAttribute ("Delay", StringValue ("2ms"));//Set the channel delay to 2ms

  NetDeviceContainer p2pDevices; //Create p2p network device
  p2pDevices = pointToPoint.Install (p2pNodes); //p2p network devices are installed on nodes n0 and n1 respectively, and then connected to the same channel object together

  CsmaHelper csma;//csma helper class to set csma channel properties
  csma.SetChannelAttribute ("DataRate", StringValue ("100Mbps"));//Set the transmission rate to 100Mbps
  csma.SetChannelAttribute ("Delay", TimeValue (NanoSeconds (6560)));//Set the channel delay to 6560ns

  NetDeviceContainer csmaDevices;//Create csma network device
  csmaDevices = csma.Install (csmaNodes);//Connecting nodes and channels

  //6. Install protocol stack and assign ip address
  
  InternetStackHelper stack;//Install the protocol stack for each node
  stack.Install (p2pNodes.Get (0));
  stack.Install (csmaNodes);

  Ipv4AddressHelper address; 
  address.SetBase ("10.1.1.0", "255.255.255.0");//Assign ip addresses to p2p network devices. The starting address is 10.1.1.0 and the ending address is 10.1.1.254
  Ipv4InterfaceContainer p2pInterfaces;
  p2pInterfaces = address.Assign (p2pDevices);

  address.SetBase ("10.1.2.0", "255.255.255.0");//Assign ip addresses to csma network devices. The start address is 10.1.2.0 and the end address is 10.1.2.254
  Ipv4InterfaceContainer csmaInterfaces;
  csmaInterfaces = address.Assign (csmaDevices);
  
  //7. Install the application
  UdpEchoServerHelper echoServer (9);//Monitor port 9
 //Configure server properties
  ApplicationContainer serverApps = echoServer.Install (csmaNodes.Get (nCsma));//Use the Install method to Install the echoServer on node n4(n3?). The application starts running in 1s and receives port 9 data, and ends in 10s.
  serverApps.Start (Seconds (1.0));
  serverApps.Stop (Seconds (10.0));
 //Configure client properties
  UdpEchoClientHelper echoClient (csmaInterfaces.GetAddress (nCsma), 9);
  echoClient.SetAttribute ("MaxPackets", UintegerValue (1));//Maximum number of transmitted packets, 1
  echoClient.SetAttribute ("Interval", TimeValue (Seconds (1.0)));//Packet sending interval 1s
  echoClient.SetAttribute ("PacketSize", UintegerValue (1024));//Packet size, 1024bit

  ApplicationContainer clientApps = echoClient.Install (p2pNodes.Get (0));//Use the install method to install the echoClient on node n0. The Application starts running in the second second second of the simulation, accepts the data from port 9, and stops in the tenth second.
  clientApps.Start (Seconds (2.0));
  clientApps.Stop (Seconds (10.0));

//8. Set global routing
  Ipv4GlobalRoutingHelper::PopulateRoutingTables ();
//9. Data tracking
//Open the pacp of the P2P helper class object, and second is the prefix name of the saved file.
  pointToPoint.EnablePcapAll ("second");//The EnablePcapAll ("second") function is used to collect the link layer packet transceiver records of all nodes on this channel. The record file format is pcap, "second" is the prefix of the file name.
//Open the pcap of csmaHelper class object, use the device with CSMA segment index 1 (the second) to sniff, and True open Promiscuous mode
  csma.EnablePcap ("second", csmaDevices.Get (1), true);//The packet sending and receiving information of CSMA network equipment in a wired node is recorded
//10. Start and end
  Simulator::Run ();
  Simulator::Destroy ();
  return 0;
}

After running, the upper level file generates three tracking files:

second-0-0.pcap represents the tracking file of node 0 and device 0 on the point-to-point network device. View its file contents:

# command
tcpdump -nn -tt -r second-0-0.pcap
# output
reading from file second-0-0.pcap, link-type PPP (PPP) # The link type is PPP
2.000000 IP 10.1.1.1.49153 > 10.1.2.4.9: UDP, length 1024 # Data packets are sent from node 0(IP:10.1.1.1, port:49153) to node 4(IP:10.1.2.4, port:9)
2.007607 IP 10.1.2.4.9 > 10.1.1.1.49153: UDP, length 1024 

# command
tcpdump -nn -tt -r second-2-0.pcap 
# output
reading from file second-2-0.pcap, link-type EN10MB (Ethernet) # The link type is Ethernet, and ARP address resolution protocol is required
2.003698 ARP, Request who-has 10.1.2.4 (ff:ff:ff:ff:ff:ff) tell 10.1.2.1, length 50 # First find the device with IP 10.1.2.4 in the CSMA network (ff:ff:ff:ff:ff:ff) (node 2 does not directly participate in communication, but sniffs the network and reports all traffic)
2.003710 ARP, Reply 10.1.2.4 is-at 00:00:00:00:00:06, length 50
2.003803 IP 10.1.1.1.49153 > 10.1.2.4.9: UDP, length 1024
2.003815 ARP, Request who-has 10.1.2.1 (ff:ff:ff:ff:ff:ff) tell 10.1.2.4, length 50 # The server calls back to the client and knows that its address is on another network (IP: 10.1.2.1), because the global route is initialized. However, the echo server node does not know the MAC address of the first CSMA node, so it sends ARP.
2.003710 ARP, Reply 10.1.2.1 is-at 00:00:00:00:00:03, length 50
2.007607 IP 10.1.2.4.9 > 10.1.1.1.49153: UDP, length 1024 

7.3 third.cc

7.4 forth.cc

7.5 fifth.cc

7.5.1 which variable is the Trace Source

7.5.2 how to construct a callback function as Trace Sink

7.5.3 overall grasp of fifth.cc

7.5.4 run fifth.cc

Added by praeses on Sun, 12 Sep 2021 22:26:17 +0300