Adding 3 new applications:udp-client, udp-server, udp-trace-client.
--- a/AUTHORS Thu Nov 26 14:53:53 2009 +0100
+++ b/AUTHORS Fri Nov 27 17:06:45 2009 +0100
@@ -12,6 +12,7 @@
Luis Cortes (cortes@gatech.edu)
Craig Dowell (craigdo@ee.washington.edu)
David Gross (gdavid.devel@gmail.com)
+Mohamed Amine Ismail (amine.ismail@sophia.inria.fr, iamine@udcast.com)
Tom Henderson (tomhend@u.washington.edu)
Sam Jansen (sam.jansen@gmail.com)
Liu Jian (liujatp@gmail.com)
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/examples/udp-client-server/udp-client-server.cc Fri Nov 27 17:06:45 2009 +0100
@@ -0,0 +1,104 @@
+/* -*- 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
+// | |
+// =======
+// LAN
+//
+// - UDP flows from n0 to n1
+
+#include <fstream>
+#include "ns3/core-module.h"
+#include "ns3/simulator-module.h"
+#include "ns3/helper-module.h"
+
+using namespace ns3;
+
+NS_LOG_COMPONENT_DEFINE ("UdpClientServerExample");
+
+int
+main (int argc, char *argv[])
+{
+//
+// Enable logging for UdpClient and
+//
+ LogComponentEnable ("UdpClient", LOG_LEVEL_INFO);
+ LogComponentEnable ("UdpServer", LOG_LEVEL_INFO);
+
+//
+// Explicitly create the nodes required by the topology (shown above).
+//
+ NS_LOG_INFO ("Create nodes.");
+ NodeContainer n;
+ n.Create (2);
+
+ InternetStackHelper internet;
+ internet.Install (n);
+
+ NS_LOG_INFO ("Create channels.");
+//
+// Explicitly create the channels required by the topology (shown above).
+//
+ CsmaHelper csma;
+ csma.SetChannelAttribute ("DataRate", DataRateValue (DataRate(5000000)));
+ csma.SetChannelAttribute ("Delay", TimeValue (MilliSeconds (2)));
+ csma.SetDeviceAttribute ("Mtu", UintegerValue (1400));
+ NetDeviceContainer d = csma.Install (n);
+
+ Ipv4AddressHelper ipv4;
+//
+// We've got the "hardware" in place. Now we need to add IP addresses.
+//
+ NS_LOG_INFO ("Assign IP Addresses.");
+ ipv4.SetBase ("10.1.1.0", "255.255.255.0");
+ Ipv4InterfaceContainer i = ipv4.Assign (d);
+
+ NS_LOG_INFO ("Create Applications.");
+//
+// Create one udpServer applications on node one.
+//
+ uint16_t port = 4000;
+ UdpServerHelper server (port);
+ ApplicationContainer apps = server.Install (n.Get(1));
+ apps.Start (Seconds (1.0));
+ apps.Stop (Seconds (10.0));
+
+//
+// Create one UdpClient application to send UDP datagrams from node zero to
+// node one.
+//
+ uint32_t MaxPacketSize = 1024;
+ Time interPacketInterval = Seconds (0.05);
+ uint32_t maxPacketCount = 320;
+ UdpClientHelper client (i.GetAddress (1), port);
+ 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));
+
+//
+// Now, do the actual simulation.
+//
+ NS_LOG_INFO ("Run Simulation.");
+ Simulator::Run ();
+ Simulator::Destroy ();
+ NS_LOG_INFO ("Done.");
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/examples/udp-client-server/udp-trace-client-server.cc Fri Nov 27 17:06:45 2009 +0100
@@ -0,0 +1,100 @@
+/* -*- 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
+// | |
+// =======
+// LAN
+//
+// - UDP flows from n0 to n1
+
+#include <fstream>
+#include "ns3/core-module.h"
+#include "ns3/simulator-module.h"
+#include "ns3/helper-module.h"
+
+using namespace ns3;
+
+NS_LOG_COMPONENT_DEFINE ("UdpTraceClientServerExample");
+
+int
+main (int argc, char *argv[])
+{
+//
+// Enable logging for UdpClient and
+//
+ LogComponentEnable ("UdpTraceClient", LOG_LEVEL_INFO);
+ LogComponentEnable ("UdpServer", LOG_LEVEL_INFO);
+
+//
+// Explicitly create the nodes required by the topology (shown above).
+//
+ NS_LOG_INFO ("Create nodes.");
+ NodeContainer n;
+ n.Create (2);
+
+ InternetStackHelper internet;
+ internet.Install (n);
+
+ NS_LOG_INFO ("Create channels.");
+//
+// Explicitly create the channels required by the topology (shown above).
+//
+ CsmaHelper csma;
+ csma.SetChannelAttribute ("DataRate", DataRateValue (DataRate(5000000)));
+ csma.SetChannelAttribute ("Delay", TimeValue (MilliSeconds (2)));
+ csma.SetDeviceAttribute ("Mtu", UintegerValue (1400));
+ NetDeviceContainer d = csma.Install (n);
+
+ Ipv4AddressHelper ipv4;
+//
+// We've got the "hardware" in place. Now we need to add IP addresses.
+//
+ NS_LOG_INFO ("Assign IP Addresses.");
+ ipv4.SetBase ("10.1.1.0", "255.255.255.0");
+ Ipv4InterfaceContainer i = ipv4.Assign (d);
+
+ NS_LOG_INFO ("Create Applications.");
+//
+// Create one udpServer applications on node one.
+//
+ uint16_t port = 4000;
+ UdpServerHelper server (port);
+ ApplicationContainer apps = server.Install (n.Get(1));
+ apps.Start (Seconds (1.0));
+ apps.Stop (Seconds (10.0));
+
+//
+// Create one UdpTraceClient application to send UDP datagrams from node zero to
+// node one.
+//
+ uint32_t MaxPacketSize = 1400;
+ UdpTraceClientHelper client (i.GetAddress (1), port,"");
+ client.SetAttribute ("MaxPacketSize", UintegerValue (MaxPacketSize));
+ apps = client.Install (n.Get (0));
+ apps.Start (Seconds (2.0));
+ apps.Stop (Seconds (10.0));
+
+//
+// Now, do the actual simulation.
+//
+ NS_LOG_INFO ("Run Simulation.");
+ Simulator::Run ();
+ Simulator::Destroy ();
+ NS_LOG_INFO ("Done.");
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/examples/udp-client-server/waf Fri Nov 27 17:06:45 2009 +0100
@@ -0,0 +1,1 @@
+exec "`dirname "$0"`"/../../waf "$@"
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/examples/udp-client-server/wscript Fri Nov 27 17:06:45 2009 +0100
@@ -0,0 +1,8 @@
+## -*- Mode: python; py-indent-offset: 4; indent-tabs-mode: nil; coding: utf-8; -*-
+
+def build(bld):
+ obj = bld.create_ns3_program('udp-client-server', ['csma', 'internet-stack'])
+ obj.source = 'udp-client-server.cc'
+
+ obj = bld.create_ns3_program('udp-trace-client-server', ['csma', 'internet-stack'])
+ obj.source = 'udp-trace-client-server.cc'
--- a/examples/wscript Thu Nov 26 14:53:53 2009 +0100
+++ b/examples/wscript Fri Nov 27 17:06:45 2009 +0100
@@ -20,3 +20,4 @@
bld.add_subdirs('tutorial')
bld.add_subdirs('udp')
bld.add_subdirs('wireless')
+ bld.add_subdirs('udp-client-server')
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/src/applications/udp-client-server/packet-loss-counter.cc Fri Nov 27 17:06:45 2009 +0100
@@ -0,0 +1,124 @@
+/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
+/*
+ * Copyright (c) 2009 INRIA, UDCAST
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation;
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ *
+ * Author: Amine Ismail <amine.ismail@sophia.inria.fr>
+ * <amine.ismail@udcast.com>
+ */
+
+#include "ns3/log.h"
+#include "ns3/simulator.h"
+#include "ns3/uinteger.h"
+#include "packet-loss-counter.h"
+
+namespace ns3 {
+
+NS_LOG_COMPONENT_DEFINE ("PacketLossCounter");
+
+
+PacketLossCounter::PacketLossCounter (uint8_t bitmapSize)
+ : m_lost (0),
+ m_bitMapSize (0),
+ m_lastMaxSeqNum (0),
+ m_receiveBitMap (0)
+{
+ SetBitMapSize (bitmapSize);
+}
+
+PacketLossCounter::~PacketLossCounter ()
+{
+ delete [] m_receiveBitMap;
+}
+
+uint16_t
+PacketLossCounter::GetBitMapSize () const
+{
+ return m_bitMapSize * 8;
+}
+
+void
+PacketLossCounter::SetBitMapSize (uint16_t winSize)
+{
+
+ NS_ASSERT_MSG(winSize%8==0,"The packet window size should be a multiple of 8");
+ m_bitMapSize = winSize/8;
+ if (m_receiveBitMap!=0)
+ {
+ delete [] m_receiveBitMap;
+ }
+ m_receiveBitMap = new uint8_t [m_bitMapSize] ();
+ memset (m_receiveBitMap,0,m_bitMapSize);
+}
+
+uint32_t
+PacketLossCounter::GetLost () const
+{
+ return m_lost;
+}
+
+bool
+PacketLossCounter::GetBit(uint32_t seqNum)
+{
+ return ((m_receiveBitMap[(seqNum%(m_bitMapSize*8))/8] >> (7-(seqNum%8)))&0x01);
+}
+
+void
+PacketLossCounter::SetBit(uint32_t seqNum, bool val)
+{
+ if (val)
+ {
+ m_receiveBitMap[(seqNum%(m_bitMapSize*8))/8] |= 0x80 >> (seqNum%8);
+ }
+ else
+ {
+ m_receiveBitMap[(seqNum%(m_bitMapSize*8))/8] &= ~(0x80 >> (seqNum%8));
+ }
+}
+
+/*
+ * This algo works as follows:
+ * When a packet is received:
+ * 1) From the last received packet to the current one:
+ * 1.1) check the corresponding bit in the bitMAP.
+ * This bit indicates if the packet with (SeqNum-bitMapSizeInBit) is
+ * received (1) or not (0)
+ * 1.2) Mark the packet as lost (0) in the bitMap
+ * 2) Mark the current packet as received (1) in the bitMap
+ * 3) Update the value of the last received packet
+ */
+
+void
+PacketLossCounter::NotifyReceived (uint32_t seqNum)
+{
+ if (seqNum>(uint32_t)(m_bitMapSize*8)-1)
+ {
+ for (uint32_t i=m_lastMaxSeqNum+1; i<=seqNum;i++)
+ {
+ if (GetBit(i)!=1)
+ {
+ NS_LOG_INFO ("Packet lost: " << i-(m_bitMapSize*8));
+ m_lost++;
+ }
+ SetBit(i, 0);
+ }
+ }
+ SetBit(seqNum, 1);
+ if (seqNum>m_lastMaxSeqNum)
+ {
+ m_lastMaxSeqNum = seqNum;
+ }
+}
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/src/applications/udp-client-server/packet-loss-counter.h Fri Nov 27 17:06:45 2009 +0100
@@ -0,0 +1,56 @@
+/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
+/*
+ * Copyright (c) 2007,2008,2009 INRIA, UDCAST
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation;
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ *
+ * Author: Amine Ismail <amine.ismail@sophia.inria.fr>
+ * <amine.ismail@udcast.com>
+ *
+ */
+#ifndef _PACKET_LOSS_COUNTER_H_
+#define _PACKET_LOSS_COUNTER_H_
+
+
+#include "ns3/application.h"
+#include "ns3/event-id.h"
+#include "ns3/ptr.h"
+#include "ns3/address.h"
+
+namespace ns3 {
+
+class Socket;
+class Packet;
+
+class PacketLossCounter
+{
+public:
+ PacketLossCounter (uint8_t bitmapSize);
+ ~PacketLossCounter ();
+ void NotifyReceived (uint32_t seq);
+ uint32_t GetLost (void) const;
+ uint16_t GetBitMapSize (void) const;
+ void SetBitMapSize (uint16_t size);
+private:
+ bool GetBit (uint32_t seqNum);
+ void SetBit (uint32_t seqNum, bool val);
+
+ uint32_t m_lost;
+ uint16_t m_bitMapSize;
+ uint32_t m_lastMaxSeqNum;
+ uint8_t * m_receiveBitMap;
+};
+}
+
+#endif /* PACKETLOSSCOUNTER_H_ */
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/src/applications/udp-client-server/seq-ts-header.cc Fri Nov 27 17:06:45 2009 +0100
@@ -0,0 +1,96 @@
+/* -*- Mode: C++; c-file-style: "gnu"; indent-tabs-mode:nil; -*- */
+/*
+ * Copyright (c) 2009 INRIA
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation;
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ *
+ * Author: Mathieu Lacage <mathieu.lacage@sophia.inria.fr>
+ */
+
+#include "ns3/assert.h"
+#include "ns3/log.h"
+#include "ns3/header.h"
+#include "ns3/simulator.h"
+#include "seq-ts-header.h"
+
+NS_LOG_COMPONENT_DEFINE ("SeqTsHeader");
+
+namespace ns3 {
+
+NS_OBJECT_ENSURE_REGISTERED (SeqTsHeader);
+
+SeqTsHeader::SeqTsHeader ()
+ : m_seq (0),
+ m_ts (Simulator::Now ().GetTimeStep ())
+{}
+
+void
+SeqTsHeader::SetSeq (uint32_t seq)
+{
+ m_seq = seq;
+}
+uint32_t
+SeqTsHeader::GetSeq (void) const
+{
+ return m_seq;
+}
+
+Time
+SeqTsHeader::GetTs (void) const
+{
+ return TimeStep (m_ts);
+}
+
+TypeId
+SeqTsHeader::GetTypeId (void)
+{
+ static TypeId tid = TypeId ("ns3::SeqTsHeader")
+ .SetParent<Header> ()
+ .AddConstructor<SeqTsHeader> ()
+ ;
+ return tid;
+}
+TypeId
+SeqTsHeader::GetInstanceTypeId (void) const
+{
+ return GetTypeId ();
+}
+void
+SeqTsHeader::Print (std::ostream &os) const
+{
+ os << "(seq=" << m_seq << " time=" << TimeStep (m_ts).GetSeconds () << ")";
+}
+uint32_t
+SeqTsHeader::GetSerializedSize (void) const
+{
+ return 4+8;
+}
+
+void
+SeqTsHeader::Serialize (Buffer::Iterator start) const
+{
+ Buffer::Iterator i = start;
+ i.WriteHtonU32 (m_seq);
+ i.WriteHtonU64 (m_ts);
+}
+uint32_t
+SeqTsHeader::Deserialize (Buffer::Iterator start)
+{
+ Buffer::Iterator i = start;
+ m_seq = i.ReadNtohU32 ();
+ m_ts = i.ReadNtohU64 ();
+ return GetSerializedSize ();
+}
+
+} // namespace ns3
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/src/applications/udp-client-server/seq-ts-header.h Fri Nov 27 17:06:45 2009 +0100
@@ -0,0 +1,61 @@
+/* -*- Mode: C++; c-file-style: "gnu"; indent-tabs-mode:nil; -*- */
+/*
+ * Copyright (c) 2009 INRIA
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation;
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ *
+ * Author: Mathieu Lacage <mathieu.lacage@sophia.inria.fr>
+ */
+
+#ifndef SEQ_TS_HEADER_H
+#define SEQ_TS_HEADER_H
+
+#include "ns3/header.h"
+#include "ns3/nstime.h"
+
+namespace ns3 {
+/**
+ * \ingroup udpclientserver
+ * \class SeqTsHeader
+ * \brief Packet header for Udp client/server application
+ * The header is made of a 32bits sequence number followed by
+ * a 64bits time stamp.
+ */
+class SeqTsHeader : public Header
+{
+public:
+ SeqTsHeader ();
+
+ /**
+ * \param seq the sequence number
+ */
+ void SetSeq (uint32_t seq);
+ uint32_t GetSeq (void) const;
+ Time GetTs (void) const;
+
+ static TypeId GetTypeId (void);
+ private:
+ virtual TypeId GetInstanceTypeId (void) const;
+ virtual void Print (std::ostream &os) const;
+ virtual uint32_t GetSerializedSize (void) const;
+ virtual void Serialize (Buffer::Iterator start) const;
+ virtual uint32_t Deserialize (Buffer::Iterator start);
+
+ uint32_t m_seq;
+ uint64_t m_ts;
+};
+
+} // namespace ns3
+
+#endif /* SEQ_TS_HEADER_H */
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/src/applications/udp-client-server/udp-client-server-test.cc Fri Nov 27 17:06:45 2009 +0100
@@ -0,0 +1,287 @@
+/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
+/*
+ * Copyright (c) 2007,2008, 2009 INRIA, UDcast
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation;
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ *
+ * Author: Mohamed Amine Ismail <amine.ismail@sophia.inria.fr>
+ * <amine.ismail@udcast.com>
+ */
+
+#include <fstream>
+#include "ns3/log.h"
+#include "ns3/abort.h"
+#include "ns3/config.h"
+#include "ns3/string.h"
+#include "ns3/uinteger.h"
+#include "ns3/inet-socket-address.h"
+#include "ns3/point-to-point-helper.h"
+#include "ns3/internet-stack-helper.h"
+#include "ns3/ipv4-address-helper.h"
+#include "ns3/udp-client-server-helper.h"
+#include "ns3/csma-helper.h"
+#include "ns3/test.h"
+#include "ns3/simulator.h"
+
+using namespace ns3;
+
+/**
+ * Test that all the udp packets generated by an udpClient application are
+ * correctly received by an udpServer application
+ */
+
+class UdpClientServerTestCase: public TestCase
+{
+public:
+ UdpClientServerTestCase ();
+ virtual ~UdpClientServerTestCase ();
+
+private:
+ virtual bool DoRun (void);
+
+};
+
+UdpClientServerTestCase::UdpClientServerTestCase () :
+ TestCase ("Test that all the udp packets generated by an udpClient application are correctly received by an udpServer application")
+{
+}
+
+UdpClientServerTestCase::~UdpClientServerTestCase ()
+{
+}
+
+bool UdpClientServerTestCase::DoRun (void)
+{
+ NodeContainer n;
+ n.Create (2);
+
+ InternetStackHelper internet;
+ internet.Install (n);
+
+ CsmaHelper csma;
+ csma.SetChannelAttribute ("DataRate", DataRateValue (DataRate(5000000)));
+ csma.SetChannelAttribute ("Delay", TimeValue (MilliSeconds (2)));
+ csma.SetDeviceAttribute ("Mtu", UintegerValue (1400));
+ NetDeviceContainer d = csma.Install (n);
+
+ Ipv4AddressHelper ipv4;
+
+ ipv4.SetBase ("10.1.1.0", "255.255.255.0");
+ Ipv4InterfaceContainer i = ipv4.Assign (d);
+
+ uint16_t port = 4000;
+ UdpServerHelper server (port);
+ ApplicationContainer apps = server.Install (n.Get(1));
+ apps.Start (Seconds (1.0));
+ apps.Stop (Seconds (10.0));
+
+ uint32_t MaxPacketSize = 1024;
+ Time interPacketInterval = Seconds (1.);
+ uint32_t maxPacketCount = 10;
+ UdpClientHelper client (i.GetAddress (1), port);
+ 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));
+
+ Simulator::Run ();
+ Simulator::Destroy ();
+
+ if ((server.GetServer ()->GetLost () != 0)
+ || (server.GetServer ()->GetReceived () != 8))
+ {
+ return true; // there was an error
+ }
+ return false;
+
+}
+
+/**
+ * Test that all the udp packets generated by an udpTraceClient application are
+ * correctly received by an udpServer application
+ */
+
+class UdpTraceClientServerTestCase: public TestCase
+{
+public:
+ UdpTraceClientServerTestCase ();
+ virtual ~UdpTraceClientServerTestCase ();
+
+private:
+ virtual bool DoRun (void);
+
+};
+
+UdpTraceClientServerTestCase::UdpTraceClientServerTestCase () :
+ TestCase ("Test that all the udp packets generated by an udpTraceClient application are correctly received by an udpServer application")
+{
+}
+
+UdpTraceClientServerTestCase::~UdpTraceClientServerTestCase ()
+{
+}
+
+bool UdpTraceClientServerTestCase::DoRun (void)
+{
+
+
+ NodeContainer n;
+ n.Create (2);
+
+ InternetStackHelper internet;
+ internet.Install (n);
+
+
+ CsmaHelper csma;
+ csma.SetChannelAttribute ("DataRate", DataRateValue (DataRate(5000000)));
+ csma.SetChannelAttribute ("Delay", TimeValue (MilliSeconds (2)));
+ csma.SetDeviceAttribute ("Mtu", UintegerValue (1400));
+ NetDeviceContainer d = csma.Install (n);
+
+ Ipv4AddressHelper ipv4;
+ ipv4.SetBase ("10.1.1.0", "255.255.255.0");
+ Ipv4InterfaceContainer i = ipv4.Assign (d);
+
+ uint16_t port = 4000;
+ UdpServerHelper server (port);
+ ApplicationContainer apps = server.Install (n.Get(1));
+ apps.Start (Seconds (1.0));
+ apps.Stop (Seconds (10.0));
+
+ uint32_t MaxPacketSize = 1400;
+ UdpTraceClientHelper client (i.GetAddress (1), port,"");
+ client.SetAttribute ("MaxPacketSize", UintegerValue (MaxPacketSize));
+ apps = client.Install (n.Get (0));
+ apps.Start (Seconds (2.0));
+ apps.Stop (Seconds (10.0));
+
+ Simulator::Run ();
+ Simulator::Destroy ();
+
+ if ((server.GetServer ()->GetLost () != 0)||
+ (server.GetServer ()->GetReceived () != 247))
+ {
+ return true; // there was an error
+ }
+
+ return false;
+}
+
+
+/**
+ * Test that all the PacketLossCounter class checks loss correctly in different cases
+ */
+
+class PacketLossCounterTestCase: public TestCase
+{
+public:
+ PacketLossCounterTestCase ();
+ virtual ~PacketLossCounterTestCase ();
+
+private:
+ virtual bool DoRun (void);
+
+};
+
+PacketLossCounterTestCase::PacketLossCounterTestCase () :
+ TestCase ("Test that all the PacketLossCounter class checks loss correctly in different cases")
+{
+}
+
+PacketLossCounterTestCase::~PacketLossCounterTestCase ()
+{
+}
+
+bool PacketLossCounterTestCase::DoRun (void)
+{
+ PacketLossCounter lossCounter(32);
+ for (uint32_t i=0;i<64;i++)
+ {
+ lossCounter.NotifyReceived(i);
+ }
+
+ if (lossCounter.GetLost()!=0) // Check that 0 packets are lost
+ {
+ return true;
+ }
+ for (uint32_t i=65;i<128;i++) // drop (1) seqNum 64
+ {
+ lossCounter.NotifyReceived(i);
+ }
+ if (lossCounter.GetLost()!=1) //chek that 1 packet is lost
+ {
+ return true;
+ }
+ for (uint32_t i=134;i<200;i++) // drop seqNum 128,129,130,131,132,133
+ {
+ lossCounter.NotifyReceived(i);
+ }
+ if (lossCounter.GetLost()!=7) //chek that 7 (6+1) packet are lost
+ {
+ return true;
+ }
+ // reordering without loss
+ lossCounter.NotifyReceived(205);
+ lossCounter.NotifyReceived(206);
+ lossCounter.NotifyReceived(207);
+ lossCounter.NotifyReceived(200);
+ lossCounter.NotifyReceived(201);
+ lossCounter.NotifyReceived(202);
+ lossCounter.NotifyReceived(203);
+ lossCounter.NotifyReceived(204);
+ for (uint32_t i=205;i<250;i++)
+ {
+ lossCounter.NotifyReceived(i);
+ }
+ if (lossCounter.GetLost()!=7)
+ {
+ return true;
+ }
+
+ // reordering with loss
+ lossCounter.NotifyReceived(255);
+ // drop (2) seqNum 250, 251
+ lossCounter.NotifyReceived(252);
+ lossCounter.NotifyReceived(253);
+ lossCounter.NotifyReceived(254);
+ for (uint32_t i=256;i<300;i++)
+ {
+ lossCounter.NotifyReceived(i);
+ }
+ if (lossCounter.GetLost()!=9) //chek that 7 (6+1+2) packet are lost
+ {
+ return true;
+ }
+
+
+ return false;
+
+}
+class UdpClientServerTestSuite: public TestSuite
+{
+public:
+ UdpClientServerTestSuite ();
+};
+
+UdpClientServerTestSuite::UdpClientServerTestSuite () :
+ TestSuite ("udp-client-server", UNIT)
+{
+ AddTestCase (new UdpTraceClientServerTestCase);
+ AddTestCase (new UdpClientServerTestCase);
+ AddTestCase (new PacketLossCounterTestCase);
+}
+
+UdpClientServerTestSuite udpClientServerTestSuite;
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/src/applications/udp-client-server/udp-client.cc Fri Nov 27 17:06:45 2009 +0100
@@ -0,0 +1,155 @@
+/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
+/*
+ * Copyright (c) 2007,2008,2009 INRIA, UDCAST
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation;
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ *
+ * Author: Amine Ismail <amine.ismail@sophia.inria.fr>
+ * <amine.ismail@udcast.com>
+ */
+#include "ns3/log.h"
+#include "ns3/ipv4-address.h"
+#include "ns3/nstime.h"
+#include "ns3/inet-socket-address.h"
+#include "ns3/socket.h"
+#include "ns3/simulator.h"
+#include "ns3/socket-factory.h"
+#include "ns3/packet.h"
+#include "ns3/uinteger.h"
+#include "udp-client.h"
+#include "seq-ts-header.h"
+#include <stdlib.h>
+#include <stdio.h>
+
+namespace ns3 {
+
+NS_LOG_COMPONENT_DEFINE ("UdpClient");
+NS_OBJECT_ENSURE_REGISTERED ( UdpClient);
+
+TypeId
+UdpClient::GetTypeId (void)
+{
+ static TypeId tid = TypeId ("ns3::UdpClient")
+ .SetParent<Application> ()
+ .AddConstructor<UdpClient> ()
+ .AddAttribute ("MaxPackets",
+ "The maximum number of packets the application will send",
+ UintegerValue (100),
+ MakeUintegerAccessor (&UdpClient::m_count),
+ MakeUintegerChecker<uint32_t> ())
+ .AddAttribute ("Interval",
+ "The time to wait between packets", TimeValue (Seconds (1.0)),
+ MakeTimeAccessor (&UdpClient::m_interval),
+ MakeTimeChecker ())
+ .AddAttribute (
+ "RemoteAddress",
+ "The destination Ipv4Address of the outbound packets",
+ Ipv4AddressValue (),
+ MakeIpv4AddressAccessor (&UdpClient::m_peerAddress),
+ MakeIpv4AddressChecker ())
+ .AddAttribute ("RemotePort", "The destination port of the outbound packets",
+ UintegerValue (100),
+ MakeUintegerAccessor (&UdpClient::m_peerPort),
+ MakeUintegerChecker<uint16_t> ())
+ .AddAttribute ("PacketSize",
+ "Size of packets generated. The minimum packet size is 12 bytes which is the size of the header carrying the sequence number and the time stamp.",
+ UintegerValue (1024),
+ MakeUintegerAccessor (&UdpClient::m_size),
+ MakeUintegerChecker<uint32_t> (12,1500))
+ ;
+ return tid;
+}
+
+UdpClient::UdpClient ()
+{
+ NS_LOG_FUNCTION_NOARGS ();
+ m_sent = 0;
+ m_socket = 0;
+ m_sendEvent = EventId ();
+}
+
+UdpClient::~UdpClient ()
+{
+ NS_LOG_FUNCTION_NOARGS ();
+}
+
+void
+UdpClient::SetRemote (Ipv4Address ip, uint16_t port)
+{
+ m_peerAddress = ip;
+ m_peerPort = port;
+}
+
+void
+UdpClient::DoDispose (void)
+{
+ NS_LOG_FUNCTION_NOARGS ();
+ Application::DoDispose ();
+}
+
+void
+UdpClient::StartApplication (void)
+{
+ NS_LOG_FUNCTION_NOARGS ();
+
+ if (m_socket == 0)
+ {
+ TypeId tid = TypeId::LookupByName ("ns3::UdpSocketFactory");
+ m_socket = Socket::CreateSocket (GetNode (), tid);
+ m_socket->Bind ();
+ m_socket->Connect (InetSocketAddress (m_peerAddress, m_peerPort));
+ }
+
+ m_socket->SetRecvCallback (MakeNullCallback<void, Ptr<Socket> > ());
+ m_sendEvent = Simulator::Schedule (Seconds (0.0), &UdpClient::Send, this);
+}
+
+void
+UdpClient::StopApplication ()
+{
+ NS_LOG_FUNCTION_NOARGS ();
+ Simulator::Cancel (m_sendEvent);
+}
+
+void
+UdpClient::Send (void)
+{
+ NS_LOG_FUNCTION_NOARGS ();
+ NS_ASSERT (m_sendEvent.IsExpired ());
+ SeqTsHeader seqTs;
+ seqTs.SetSeq (m_sent);
+ Ptr<Packet> p = Create<Packet> (m_size-(8+4)); // 8+4 : the size of the seqTs header
+ p->AddHeader (seqTs);
+
+ if ((m_socket->Send (p)) >= 0)
+ {
+ ++m_sent;
+ NS_LOG_INFO ("TraceDelay TX " << m_size << " bytes to "
+ << m_peerAddress << " Uid: " << p->GetUid ()
+ << " Time: " << (Simulator::Now ()).GetSeconds ());
+
+ }
+ else
+ {
+ NS_LOG_INFO ("Error while sending " << m_size << " bytes to "
+ << m_peerAddress);
+ }
+
+ if (m_sent < m_count)
+ {
+ m_sendEvent = Simulator::Schedule (m_interval, &UdpClient::Send, this);
+ }
+}
+
+} // Namespace ns3
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/src/applications/udp-client-server/udp-client.h Fri Nov 27 17:06:45 2009 +0100
@@ -0,0 +1,85 @@
+/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
+/*
+ * Copyright (c) 2007,2008,2009 INRIA, UDCAST
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation;
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ *
+ * Author: Amine Ismail <amine.ismail@sophia.inria.fr>
+ * <amine.ismail@udcast.com>
+ *
+ */
+
+#ifndef __UDP_CLIENT_H__
+#define __UDP_CLIENT_H__
+
+#include "ns3/application.h"
+#include "ns3/event-id.h"
+#include "ns3/ptr.h"
+#include "ns3/ipv4-address.h"
+
+namespace ns3 {
+
+class Socket;
+class Packet;
+
+/**
+ * \ingroup udpclientserver
+ * \class UdpClient
+ * \brief A Udp client. Sends UDP packet carrying sequence number and time stamp
+ * in their payloads
+ *
+ */
+class UdpClient : public Application
+{
+public:
+ static TypeId
+ GetTypeId (void);
+
+ UdpClient ();
+
+ virtual ~UdpClient ();
+
+ /**
+ * \brief set the remote address and port
+ * \param ip remote IP address
+ * \param port remote port
+ */
+ void SetRemote (Ipv4Address ip, uint16_t port);
+
+protected:
+ virtual void DoDispose (void);
+
+private:
+
+ virtual void StartApplication (void);
+ virtual void StopApplication (void);
+
+ void ScheduleTransmit (Time dt);
+ void Send (void);
+
+ uint32_t m_count;
+ Time m_interval;
+ uint32_t m_size;
+
+ uint32_t m_sent;
+ Ptr<Socket> m_socket;
+ Ipv4Address m_peerAddress;
+ uint16_t m_peerPort;
+ EventId m_sendEvent;
+
+};
+
+} // namespace ns3
+
+#endif // __UDP_CLIENT_H__
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/src/applications/udp-client-server/udp-server.cc Fri Nov 27 17:06:45 2009 +0100
@@ -0,0 +1,164 @@
+/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
+/*
+ * Copyright (c) 2007,2008,2009 INRIA, UDCAST
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation;
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ *
+ * Author: Amine Ismail <amine.ismail@sophia.inria.fr>
+ * <amine.ismail@udcast.com>
+ */
+
+#include "ns3/log.h"
+#include "ns3/ipv4-address.h"
+#include "ns3/nstime.h"
+#include "ns3/inet-socket-address.h"
+#include "ns3/socket.h"
+#include "ns3/simulator.h"
+#include "ns3/socket-factory.h"
+#include "ns3/packet.h"
+#include "ns3/uinteger.h"
+#include "packet-loss-counter.h"
+
+#include "seq-ts-header.h"
+#include "udp-server.h"
+
+namespace ns3 {
+
+NS_LOG_COMPONENT_DEFINE ("UdpServer");
+NS_OBJECT_ENSURE_REGISTERED ( UdpServer);
+
+
+TypeId
+UdpServer::GetTypeId (void)
+{
+ static TypeId tid = TypeId ("ns3::UdpServer")
+ .SetParent<Application> ()
+ .AddConstructor<UdpServer> ()
+ .AddAttribute ("Port",
+ "Port on which we listen for incoming packets.",
+ UintegerValue (100),
+ MakeUintegerAccessor (&UdpServer::m_port),
+ MakeUintegerChecker<uint16_t> ())
+ .AddAttribute ("PacketWindowSize",
+ "The size of the window used to compute the packet loss. This value should be a multiple of 8.",
+ UintegerValue (32),
+ MakeUintegerAccessor (&UdpServer::GetPacketWindowSize,
+ &UdpServer::SetPacketWindowSize),
+ MakeUintegerChecker<uint16_t> (8,256))
+ ;
+ return tid;
+}
+
+UdpServer::UdpServer ()
+ : m_lossCounter (0)
+{
+ NS_LOG_FUNCTION_NOARGS ();
+ m_received=0;
+}
+
+UdpServer::~UdpServer ()
+{
+ NS_LOG_FUNCTION_NOARGS ();
+}
+
+uint16_t
+UdpServer::GetPacketWindowSize () const
+{
+ return m_lossCounter.GetBitMapSize ();
+}
+
+void
+UdpServer::SetPacketWindowSize (uint16_t size)
+{
+ m_lossCounter.SetBitMapSize (size);
+}
+
+uint32_t
+UdpServer::GetLost (void) const
+{
+ return m_lossCounter.GetLost ();
+}
+
+uint32_t
+UdpServer::GetReceived (void) const
+{
+
+ return m_received;
+
+}
+
+void
+UdpServer::DoDispose (void)
+{
+ NS_LOG_FUNCTION_NOARGS ();
+ Application::DoDispose ();
+}
+
+void
+UdpServer::StartApplication (void)
+{
+ NS_LOG_FUNCTION_NOARGS ();
+
+ if (m_socket == 0)
+ {
+ TypeId tid = TypeId::LookupByName ("ns3::UdpSocketFactory");
+ m_socket = Socket::CreateSocket (GetNode (), tid);
+ InetSocketAddress local = InetSocketAddress (Ipv4Address::GetAny (),
+ m_port);
+ m_socket->Bind (local);
+ }
+
+ m_socket->SetRecvCallback (MakeCallback (&UdpServer::HandleRead, this));
+
+}
+
+void
+UdpServer::StopApplication ()
+{
+ NS_LOG_FUNCTION_NOARGS ();
+
+ if (m_socket != 0)
+ {
+ m_socket->SetRecvCallback (MakeNullCallback<void, Ptr<Socket> > ());
+ }
+}
+
+void
+UdpServer::HandleRead (Ptr<Socket> socket)
+{
+ Ptr<Packet> packet;
+ Address from;
+ while (packet = socket->RecvFrom (from))
+ {
+ if (packet->GetSize () > 0)
+ {
+ SeqTsHeader seqTs;
+ packet->RemoveHeader (seqTs);
+ Time delay = Simulator::Now () - seqTs.GetTs ();
+ uint32_t currentSequenceNumber = seqTs.GetSeq ();
+ NS_LOG_INFO ("TraceDelay: RX " << packet->GetSize () <<
+ " bytes from "<< InetSocketAddress::ConvertFrom(from).GetIpv4 () <<
+ " Sequence Number: " << currentSequenceNumber <<
+ " Uid: " << packet->GetUid () <<
+ " TXtime: " << seqTs.GetTs () <<
+ " RXtime: " << Simulator::Now () <<
+ " Delay: " << delay) ;
+
+ m_lossCounter.NotifyReceived (currentSequenceNumber);
+ m_received++;
+ }
+ }
+}
+
+} // Namespace ns3
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/src/applications/udp-client-server/udp-server.h Fri Nov 27 17:06:45 2009 +0100
@@ -0,0 +1,94 @@
+/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
+/*
+ * Copyright (c) 2007,2008,2009 INRIA, UDCAST
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation;
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ *
+ * Author: Amine Ismail <amine.ismail@sophia.inria.fr>
+ * <amine.ismail@udcast.com>
+ *
+ */
+
+#ifndef __UDP_SERVER_H__
+#define __UDP_SERVER_H__
+
+#include "ns3/application.h"
+#include "ns3/event-id.h"
+#include "ns3/ptr.h"
+#include "ns3/address.h"
+#include "packet-loss-counter.h"
+namespace ns3 {
+/**
+ * \ingroup applications
+ * \defgroup udpclientserver UdpClientServer
+ */
+
+/**
+ * \ingroup udpclientserver
+ * \class UdpServer
+ * \brief A Udp server. Receives UDP packets from a remote host. UDP packets
+ * carry a 32bits sequence number followed by a 64bits time stamp in their
+ * payloads. The application uses, the sequence number to determine if a packet
+ * is lost, and the time stamp to compute the delay
+ */
+class UdpServer : public Application
+{
+public:
+ static TypeId GetTypeId (void);
+ UdpServer ();
+ virtual ~UdpServer ();
+ /**
+ * returns the number of lost packets
+ * \return the number of lost packets
+ */
+ uint32_t GetLost (void) const;
+
+ /**
+ * \brief returns the number of received packets
+ * \return the number of received packets
+ */
+ uint32_t GetReceived (void) const;
+
+ /**
+ * \return the size of the window used for checking loss.
+ */
+ uint16_t GetPacketWindowSize () const;
+
+ /**
+ * \brief Set the size of the window used for checking loss. This value should
+ * be a multiple of 8
+ * \param size the size of the window used for checking loss. This value should
+ * be a multiple of 8
+ */
+ void SetPacketWindowSize (uint16_t size);
+protected:
+ virtual void DoDispose (void);
+
+private:
+
+ virtual void StartApplication (void);
+ virtual void StopApplication (void);
+
+ void HandleRead (Ptr<Socket> socket);
+
+ uint16_t m_port;
+ Ptr<Socket> m_socket;
+ Address m_local;
+ uint32_t m_received;
+ PacketLossCounter m_lossCounter;
+};
+
+} // namespace ns3
+
+#endif // __UDP_SERVER_H__
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/src/applications/udp-client-server/udp-trace-client.cc Fri Nov 27 17:06:45 2009 +0100
@@ -0,0 +1,292 @@
+/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
+/*
+ * Copyright (c) 2007,2008, 2009 INRIA, UDcast
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation;
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ *
+ * Author: Mohamed Amine Ismail <amine.ismail@sophia.inria.fr>
+ * <amine.ismail@udcast.com>
+ */
+#include "ns3/log.h"
+#include "ns3/ipv4-address.h"
+#include "ns3/nstime.h"
+#include "ns3/inet-socket-address.h"
+#include "ns3/socket.h"
+#include "ns3/simulator.h"
+#include "ns3/socket-factory.h"
+#include "ns3/packet.h"
+#include "ns3/uinteger.h"
+#include "ns3/string.h"
+#include "seq-ts-header.h"
+#include "udp-trace-client.h"
+#include <stdlib.h>
+#include <stdio.h>
+#include <fstream>
+
+namespace ns3 {
+
+NS_LOG_COMPONENT_DEFINE ("UdpTraceClient");
+NS_OBJECT_ENSURE_REGISTERED ( UdpTraceClient);
+
+struct UdpTraceClient::TraceEntry UdpTraceClient::g_defaultEntries[] = {
+ {0, 534, 'I'},
+ {40, 1542, 'P'},
+ {120, 134, 'B'},
+ {80, 390, 'B'},
+ {240, 765, 'P'},
+ {160, 407, 'B'},
+ {200, 504, 'B'},
+ {360, 903, 'P'},
+ {280, 421, 'B'},
+ {320, 587, 'B'}
+};
+
+TypeId
+UdpTraceClient::GetTypeId (void)
+{
+ static TypeId tid = TypeId ("ns3::UdpTraceClient")
+ .SetParent<Application> ()
+ .AddConstructor<UdpTraceClient> ()
+ .AddAttribute ("RemoteAddress",
+ "The destination Ipv4Address of the outbound packets",
+ Ipv4AddressValue (),
+ MakeIpv4AddressAccessor (&UdpTraceClient::m_peerAddress),
+ MakeIpv4AddressChecker ())
+ .AddAttribute ("RemotePort",
+ "The destination port of the outbound packets",
+ UintegerValue (100),
+ MakeUintegerAccessor (&UdpTraceClient::m_peerPort),
+ MakeUintegerChecker<uint16_t> ())
+ .AddAttribute ("MaxPacketSize",
+ "The maximum size of a packet.",
+ UintegerValue (1024),
+ MakeUintegerAccessor (&UdpTraceClient::m_maxPacketSize),
+ MakeUintegerChecker<uint32_t> ())
+ .AddAttribute ("TraceFilename",
+ "Name of file to load a trace from. By default, uses a hardcoded trace.",
+ StringValue (""),
+ MakeStringAccessor (&UdpTraceClient::SetTraceFile),
+ MakeStringChecker ())
+
+ ;
+ return tid;
+}
+
+UdpTraceClient::UdpTraceClient ()
+{
+ NS_LOG_FUNCTION_NOARGS ();
+ m_sent = 0;
+ m_socket = 0;
+ m_sendEvent = EventId ();
+ m_maxPacketSize = 1400;
+}
+
+UdpTraceClient::UdpTraceClient (Ipv4Address ip, uint16_t port,
+ char *traceFile)
+{
+ NS_LOG_FUNCTION_NOARGS ();
+ m_sent = 0;
+ m_socket = 0;
+ m_sendEvent = EventId ();
+ m_peerAddress = ip;
+ m_peerPort = port;
+ m_currentEntry = 0;
+ m_maxPacketSize = 1400;
+ if (traceFile != NULL)
+ {
+ SetTraceFile (traceFile);
+ }
+}
+
+UdpTraceClient::~UdpTraceClient ()
+{
+ m_entries.clear ();
+ NS_LOG_FUNCTION_NOARGS ();
+}
+
+void
+UdpTraceClient::SetRemote (Ipv4Address ip, uint16_t port)
+{
+ m_entries.clear ();
+ m_peerAddress = ip;
+ m_peerPort = port;
+}
+
+void
+UdpTraceClient::SetTraceFile (std::string traceFile)
+{
+ if (traceFile == "")
+ {
+ LoadDefaultTrace ();
+ }
+ else
+ {
+ LoadTrace (traceFile);
+ }
+}
+
+void
+UdpTraceClient::SetMaxPacketSize (uint16_t maxPacketSize){
+ m_maxPacketSize = maxPacketSize;
+}
+
+
+uint16_t UdpTraceClient::GetMaxPacketSize (void){
+ return m_maxPacketSize;
+}
+
+
+void
+UdpTraceClient::DoDispose (void)
+{
+ NS_LOG_FUNCTION_NOARGS ();
+ Application::DoDispose ();
+}
+
+void
+UdpTraceClient::LoadTrace (std::string filename)
+{
+ uint32_t time, index, prevTime = 0;
+ uint16_t size;
+ char frameType;
+ TraceEntry entry;
+ std::ifstream ifTraceFile;
+ ifTraceFile.open (filename.c_str (), std::ifstream::in);
+ m_entries.clear ();
+ if (!ifTraceFile.good ())
+ {
+ LoadDefaultTrace ();
+ }
+ while (ifTraceFile.good ())
+ {
+ ifTraceFile >> index >> frameType >> time >> size;
+ if (frameType == 'B')
+ {
+ entry.timeToSend = 0;
+ }
+ else
+ {
+ entry.timeToSend = time - prevTime;
+ prevTime = time;
+ }
+ entry.packetSize = size;
+ entry.frameType = frameType;
+ m_entries.push_back (entry);
+ }
+ ifTraceFile.close ();
+ m_currentEntry = 0;
+}
+
+void
+UdpTraceClient::LoadDefaultTrace (void)
+{
+ uint32_t prevTime = 0;
+ for (uint32_t i = 0; i < (sizeof (g_defaultEntries) / sizeof (struct TraceEntry)); i++)
+ {
+ struct TraceEntry entry = g_defaultEntries[i];
+ if (entry.frameType == 'B')
+ {
+ entry.timeToSend = 0;
+ }
+ else
+ {
+ uint32_t tmp = entry.timeToSend;
+ entry.timeToSend -= prevTime;
+ prevTime = tmp;
+ }
+ m_entries.push_back (entry);
+ }
+ m_currentEntry = 0;
+}
+
+void
+UdpTraceClient::StartApplication (void)
+{
+ NS_LOG_FUNCTION (this);
+
+ if (m_socket == 0)
+ {
+ TypeId tid = TypeId::LookupByName ("ns3::UdpSocketFactory");
+ m_socket = Socket::CreateSocket (GetNode (), tid);
+ m_socket->Bind ();
+ m_socket->Connect (InetSocketAddress (m_peerAddress, m_peerPort));
+ }
+ m_socket->SetRecvCallback (MakeNullCallback<void, Ptr<Socket> > ());
+ m_sendEvent = Simulator::Schedule (Seconds (0.0), &UdpTraceClient::Send, this);
+}
+
+void
+UdpTraceClient::StopApplication ()
+{
+ NS_LOG_FUNCTION (this);
+ Simulator::Cancel (m_sendEvent);
+}
+
+void
+UdpTraceClient::SendPacket (uint32_t size)
+{
+ Ptr<Packet> p;
+ uint32_t packetSize;
+ if (size>12)
+ {
+ packetSize = size - 12; // 12 is the size of the SeqTsHeader
+ }
+ else
+ {
+ packetSize = 0;
+ }
+ p = Create<Packet> (packetSize);
+ SeqTsHeader seqTs;
+ seqTs.SetSeq (m_sent);
+ p->AddHeader (seqTs);
+ if ((m_socket->Send (p)) >= 0)
+ {
+ ++m_sent;
+ NS_LOG_INFO ("Sent " << size << " bytes to "
+ << m_peerAddress);
+ }
+ else
+ {
+ NS_LOG_INFO ("Error while sending " << size << " bytes to "
+ << m_peerAddress);
+ }
+}
+
+void
+UdpTraceClient::Send (void)
+{
+ NS_LOG_FUNCTION_NOARGS ();
+
+ NS_ASSERT (m_sendEvent.IsExpired ());
+ Ptr<Packet> p;
+ struct TraceEntry *entry = &m_entries[m_currentEntry];
+ do
+ {
+ for (int i = 0; i < entry->packetSize / m_maxPacketSize; i++)
+ {
+ SendPacket (m_maxPacketSize);
+ }
+
+ uint16_t sizetosend = entry->packetSize % m_maxPacketSize;
+ SendPacket (sizetosend);
+
+ m_currentEntry++;
+ m_currentEntry %= m_entries.size ();
+ entry = &m_entries[m_currentEntry];
+ }
+ while (entry->timeToSend == 0);
+ m_sendEvent = Simulator::Schedule (MilliSeconds (entry->timeToSend), &UdpTraceClient::Send, this);
+}
+
+} // Namespace ns3
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/src/applications/udp-client-server/udp-trace-client.h Fri Nov 27 17:06:45 2009 +0100
@@ -0,0 +1,135 @@
+/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
+/*
+ * Copyright (c) 2007,2008, 2009 INRIA, UDcast
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation;
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ *
+ * Author: Mohamed Amine Ismail <amine.ismail@sophia.inria.fr>
+ * <amine.ismail@udcast.com>
+ */
+
+#ifndef __UDP_TRACE_CLIENT__
+#define __UDP_TRACE_CLIENT__
+
+#include "ns3/application.h"
+#include "ns3/event-id.h"
+#include "ns3/ptr.h"
+#include "ns3/ipv4-address.h"
+#include <vector>
+namespace ns3 {
+
+class Socket;
+class Packet;
+
+/**
+ * \ingroup udpclientserver
+ * \class UdpTraceClient
+ * \brief A trace based streamer
+ *
+ * sends udp packets based on a trace file of an MPEG4 stream
+ * trace files could be downloaded form :
+ * http://www.tkn.tu-berlin.de/research/trace/ltvt.html (the 2 first lines of
+ * the file should be removed)
+ * A valid trace file is a file with 4 columns:
+ * -1- the first one represents the frame index
+ * -2- the second one indicates the type of the frame: I, P or B
+ * -3- the third one indicates the time on which the frame was generated by the encoder
+ * -4- the fourth one indicates the frame size in byte
+ * if no valid MPEG4 trace file is provided to the application the trace from
+ * g_defaultEntries array will be loaded.
+ */
+class UdpTraceClient : public Application
+{
+public:
+ static TypeId
+ GetTypeId (void);
+ /**
+ * \brief creates a traceBasedStreamer application
+ */
+ UdpTraceClient ();
+
+ /**
+ * \brief creates a traceBasedStreamer application
+ * \param dataSize ip the destination ip address to which the stream will be sent
+ * \param port the destination udp port to which the stream will be sent
+ * \param traceFile a path to an MPEG4 trace file formatted as follows:
+ * FrameNo Frametype Time[ms] Length [byte]
+ * FrameNo Frametype Time[ms] Length [byte]
+ * ...
+ *
+ *
+ */
+
+ UdpTraceClient (Ipv4Address ip, uint16_t port, char *traceFile);
+ ~UdpTraceClient ();
+
+ /**
+ * \brief set the destination IP address and port
+ * \param ip the destination ip address to which the stream will be sent
+ * \param port the destination udp port to which the stream will be sent
+ */
+ void SetRemote (Ipv4Address ip, uint16_t port);
+
+ /**
+ * \brief set the trace file to be used by the application
+ * \param traceFile a path to an MPEG4 trace file formatted as follows:
+ * Frame No Frametype Time[ms] Length [byte]
+ * Frame No Frametype Time[ms] Length [byte]
+ * ...
+ */
+ void SetTraceFile (std::string filename);
+
+ /**
+ * \return the maximum packet size
+ */
+ uint16_t GetMaxPacketSize(void);
+
+ /**
+ * \param maxPacketSize The maximum packet size
+ */
+ void SetMaxPacketSize(uint16_t maxPacketSize);
+
+protected:
+ virtual void DoDispose (void);
+
+private:
+ void LoadTrace (std::string filename);
+ void LoadDefaultTrace (void);
+ virtual void StartApplication (void);
+ virtual void StopApplication (void);
+ void ScheduleTransmit (Time dt);
+ void Send (void);
+ void SendPacket (uint32_t size);
+
+
+ struct TraceEntry
+ {
+ uint32_t timeToSend;
+ uint16_t packetSize;
+ char frameType;
+ };
+ uint32_t m_sent;
+ Ptr<Socket> m_socket;
+ Ipv4Address m_peerAddress;
+ uint16_t m_peerPort;
+ EventId m_sendEvent;
+ std::vector<struct TraceEntry> m_entries;
+ uint32_t m_currentEntry;
+ static struct TraceEntry g_defaultEntries[];
+ uint16_t m_maxPacketSize;
+};
+
+} // namespace ns3
+
+#endif // __UDP_TRACE_CLIENT__
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/src/applications/udp-client-server/waf Fri Nov 27 17:06:45 2009 +0100
@@ -0,0 +1,1 @@
+exec "`dirname "$0"`"/../../../waf "$@"
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/src/applications/udp-client-server/wscript Fri Nov 27 17:06:45 2009 +0100
@@ -0,0 +1,21 @@
+## -*- Mode: python; py-indent-offset: 4; indent-tabs-mode: nil; coding: utf-8; -*-
+
+def build(bld):
+ module = bld.create_ns3_module('udp-client-server', ['internet-stack'])
+ module.source = [
+ 'udp-client.cc',
+ 'udp-server.cc',
+ 'seq-ts-header.cc',
+ 'udp-trace-client.cc',
+ 'udp-client-server-test.cc',
+ 'packet-loss-counter.cc',
+ ]
+ headers = bld.new_task_gen('ns3header')
+ headers.module = 'udp-client-server'
+ headers.source = [
+ 'udp-client.h',
+ 'udp-server.h',
+ 'udp-trace-client.h',
+ 'packet-loss-counter.h',
+ ]
+
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/src/helper/udp-client-server-helper.cc Fri Nov 27 17:06:45 2009 +0100
@@ -0,0 +1,127 @@
+/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
+/*
+ * Copyright (c) 2008 INRIA
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation;
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ *
+ * Author: Mohamed Amine Ismail <amine.ismail@sophia.inria.fr>
+ */
+#include "udp-client-server-helper.h"
+#include "ns3/udp-server.h"
+#include "ns3/udp-client.h"
+#include "ns3/udp-trace-client.h"
+#include "ns3/uinteger.h"
+#include "ns3/string.h"
+
+namespace ns3 {
+
+UdpServerHelper::UdpServerHelper ()
+{}
+
+UdpServerHelper::UdpServerHelper (uint16_t port)
+{
+ m_factory.SetTypeId (UdpServer::GetTypeId ());
+ SetAttribute ("Port", UintegerValue (port));
+}
+
+void
+UdpServerHelper::SetAttribute (std::string name, const AttributeValue &value)
+{
+ m_factory.Set (name, value);
+}
+
+ApplicationContainer
+UdpServerHelper::Install (NodeContainer c)
+{
+ ApplicationContainer apps;
+ for (NodeContainer::Iterator i = c.Begin (); i != c.End (); ++i)
+ {
+ Ptr<Node> node = *i;
+
+ m_server = m_factory.Create<UdpServer> ();
+ node->AddApplication (m_server);
+ apps.Add (m_server);
+
+ }
+ return apps;
+}
+
+Ptr<UdpServer>
+UdpServerHelper::GetServer (void)
+{
+ return m_server;
+}
+
+UdpClientHelper::UdpClientHelper ()
+{}
+
+UdpClientHelper::UdpClientHelper (Ipv4Address address, uint16_t port)
+{
+ m_factory.SetTypeId (UdpClient::GetTypeId ());
+ SetAttribute ("RemoteAddress", Ipv4AddressValue (address));
+ SetAttribute ("RemotePort", UintegerValue (port));
+}
+
+void
+UdpClientHelper::SetAttribute (std::string name, const AttributeValue &value)
+{
+ m_factory.Set (name, value);
+}
+
+ApplicationContainer
+UdpClientHelper::Install (NodeContainer c)
+{
+ ApplicationContainer apps;
+ for (NodeContainer::Iterator i = c.Begin (); i != c.End (); ++i)
+ {
+ Ptr<Node> node = *i;
+ Ptr<UdpClient> client = m_factory.Create<UdpClient> ();
+ node->AddApplication (client);
+ apps.Add (client);
+ }
+ return apps;
+}
+
+UdpTraceClientHelper::UdpTraceClientHelper ()
+{}
+
+UdpTraceClientHelper::UdpTraceClientHelper (Ipv4Address address, uint16_t port, std::string filename)
+{
+ m_factory.SetTypeId (UdpTraceClient::GetTypeId ());
+ SetAttribute ("RemoteAddress", Ipv4AddressValue (address));
+ SetAttribute ("RemotePort", UintegerValue (port));
+ SetAttribute ("TraceFilename", StringValue (filename));
+}
+
+void
+UdpTraceClientHelper::SetAttribute (std::string name, const AttributeValue &value)
+{
+ m_factory.Set (name, value);
+}
+
+ApplicationContainer
+UdpTraceClientHelper::Install (NodeContainer c)
+{
+ ApplicationContainer apps;
+ for (NodeContainer::Iterator i = c.Begin (); i != c.End (); ++i)
+ {
+ Ptr<Node> node = *i;
+ Ptr<UdpTraceClient> client = m_factory.Create<UdpTraceClient> ();
+ node->AddApplication (client);
+ apps.Add (client);
+ }
+ return apps;
+}
+
+} // namespace ns3
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/src/helper/udp-client-server-helper.h Fri Nov 27 17:06:45 2009 +0100
@@ -0,0 +1,178 @@
+/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
+/*
+ * Copyright (c) 2008 INRIA
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation;
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ *
+ * Author: Mohamed Amine Ismail <amine.ismail@sophia.inria.fr>
+ */
+#ifndef UDP_CLIENT_SERVER_HELPER_H
+#define UDP_CLIENT_SERVER_HELPER_H
+
+#include <stdint.h>
+#include "application-container.h"
+#include "node-container.h"
+#include "ns3/object-factory.h"
+#include "ns3/ipv4-address.h"
+#include "ns3/udp-server.h"
+#include "ns3/udp-client.h"
+namespace ns3 {
+ /**
+ * \brief Create a server application which waits for input udp packets
+ * and uses the information carried into their payload to compute
+ * delay and to determine if some packets are lost.
+ */
+class UdpServerHelper
+{
+public:
+ /**
+ * Create UdpServerHelper which will make life easier for people trying
+ * to set up simulations with udp-client-server application.
+ *
+ */
+ UdpServerHelper ();
+
+ /**
+ * Create UdpServerHelper which will make life easier for people trying
+ * to set up simulations with udp-client-server application.
+ *
+ * \param port The port the server will wait on for incoming packets
+ */
+ UdpServerHelper (uint16_t port);
+
+ /**
+ * Record an attribute to be set in each Application after it is is created.
+ *
+ * \param name the name of the attribute to set
+ * \param value the value of the attribute to set
+ */
+ void SetAttribute (std::string name, const AttributeValue &value);
+
+ /**
+ * Create one udp server application on each of the Nodes in the
+ * NodeContainer.
+ *
+ * \param c The nodes on which to create the Applications. The nodes
+ * are specified by a NodeContainer.
+ * \returns The applications created, one Application per Node in the
+ * NodeContainer.
+ */
+ ApplicationContainer Install (NodeContainer c);
+ Ptr<UdpServer> GetServer(void);
+private:
+ ObjectFactory m_factory;
+ Ptr<UdpServer> m_server;
+};
+
+/**
+ * \brief Create a client application which sends udp packets carrying
+ * a 32bit sequence numbre and a 64 bit time stamp.
+ *
+ */
+class UdpClientHelper
+{
+
+public:
+ /**
+ * Create UdpClientHelper which will make life easier for people trying
+ * to set up simulations with udp-client-server.
+ *
+ */
+ UdpClientHelper ();
+
+ /**
+ * Create UdpClientHelper which will make life easier for people trying
+ * to set up simulations with udp-client-server.
+ *
+ * \param ip The IP address of the remote udp server
+ * \param port The port number of the remote udp server
+ */
+
+ UdpClientHelper (Ipv4Address ip, uint16_t port);
+
+ /**
+ * Record an attribute to be set in each Application after it is is created.
+ *
+ * \param name the name of the attribute to set
+ * \param value the value of the attribute to set
+ */
+ void SetAttribute (std::string name, const AttributeValue &value);
+
+ /**
+ * \param c the nodes
+ *
+ * Create one udp client application on each of the input nodes
+ *
+ * \returns the applications created, one application per input node.
+ */
+ ApplicationContainer Install (NodeContainer c);
+
+private:
+ ObjectFactory m_factory;
+};
+ /**
+ * Create udpTraceClient application which sends udp packets based on a trace
+ * file of an MPEG4 stream. Trace files could be downloaded form :
+ * http://www.tkn.tu-berlin.de/research/trace/ltvt.html (the 2 first lines of
+ * the file should be removed)
+ * A valid trace file is a file with 4 columns:
+ * -1- the first one represents the frame index
+ * -2- the second one indicates the type of the frame: I, P or B
+ * -3- the third one indicates the time on which the frame was generated by the encoder
+ * -4- the fourth one indicates the frame size in byte
+*/
+class UdpTraceClientHelper
+{
+public:
+ /**
+ * Create UdpTraceClientHelper which will make life easier for people trying
+ * to set up simulations with udp-client-server.
+ *
+ */
+ UdpTraceClientHelper ();
+
+ /**
+ * Create UdpTraceClientHelper which will make life easier for people trying
+ * to set up simulations with udp-client-server.
+ *
+ * \param ip The IP address of the remote udp server
+ * \param port The port number of the remote udp server
+ * \param filename the file from which packet traces will be loaded
+ */
+ UdpTraceClientHelper (Ipv4Address ip, uint16_t port, std::string filename);
+
+ /**
+ * Record an attribute to be set in each Application after it is is created.
+ *
+ * \param name the name of the attribute to set
+ * \param value the value of the attribute to set
+ */
+ void SetAttribute (std::string name, const AttributeValue &value);
+
+ /**
+ * \param c the nodes
+ *
+ * Create one udp trace client application on each of the input nodes
+ *
+ * \returns the applications created, one application per input node.
+ */
+ ApplicationContainer Install (NodeContainer c);
+
+private:
+ ObjectFactory m_factory;
+};
+
+} // namespace ns3
+
+#endif /* UDP_CLIENT_SERVER_H */
--- a/src/helper/wscript Thu Nov 26 14:53:53 2009 +0100
+++ b/src/helper/wscript Fri Nov 27 17:06:45 2009 +0100
@@ -47,6 +47,7 @@
'point-to-point-grid-helper.cc',
'point-to-point-star-helper.cc',
'csma-star-helper.cc',
+ 'udp-client-server-helper.cc',
]
headers = bld.new_task_gen('ns3header')
@@ -97,6 +98,7 @@
'point-to-point-grid-helper.h',
'point-to-point-star-helper.h',
'csma-star-helper.h',
+ 'udp-client-server-helper.h',
]
env = bld.env_of_name('default')
--- a/src/wscript Thu Nov 26 14:53:53 2009 +0100
+++ b/src/wscript Fri Nov 27 17:06:45 2009 +0100
@@ -47,6 +47,7 @@
'test/ns3tcp',
'test/ns3wifi',
'contrib/flow-monitor',
+ 'applications/udp-client-server',
)
def set_options(opt):