Ltp long transmission example
authorRub?n Mart?nez
Tue, 12 Aug 2014 20:38:16 +0200
changeset 10848 81c59d7cb498
parent 10847 4f20a951cdf1
child 10849 7c61ad82de3c
Ltp long transmission example
src/ltp-protocol/examples/ltp-protocol-long-transmission-example.cc
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/ltp-protocol/examples/ltp-protocol-long-transmission-example.cc	Tue Aug 12 20:38:16 2014 +0200
@@ -0,0 +1,355 @@
+/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*-
+ * Copyright (c) 2014 Universitat Autònoma de Barcelona
+ *
+ * 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: Rubén Martínez <rmartinez@deic.uab.cat>
+ */
+
+//        Network topology
+//
+//       n0              n1
+//       |               |
+//       =================
+//          PointToPoint
+//
+// - Send a block of data from one service instance in node n0 to the other in node n1.
+// - Data is sent end-to-end through a LtpProtcol <-> UdpLayerAdapter <-> PointToPointLink <-> UdpLayerAdapter <-> LtpProtcol.
+// - Functions (ClientServiceInstanceNotificationsSnd and ClientServiceInstanceNotificationsRcv) are used for tracing
+//
+
+#include "ns3/core-module.h"
+#include "ns3/ltp-protocol-helper.h"
+#include "ns3/ltp-protocol.h"
+#include "ns3/point-to-point-module.h"
+#include "ns3/internet-module.h"
+#include "ns3/network-module.h"
+#include <sstream>
+
+using namespace ns3;
+using namespace ltp;
+
+NS_LOG_COMPONENT_DEFINE ("LtpProtocolSimpleExample");
+
+
+
+class ClientServiceInstance : public Application
+{
+public:
+	ClientServiceInstance();
+	ClientServiceInstance(
+			bool isSender,
+			uint64_t localClientId);
+	ClientServiceInstance(
+			bool isSender,
+			uint64_t localClientId,
+			uint64_t destinationClient,
+			uint64_t destinationLtpEngine,
+			uint32_t bytesToSend,
+			uint32_t blockSize,
+			uint32_t redPartSize
+			);
+
+	virtual ~ClientServiceInstance();
+
+
+	void SetProtocol(Ptr<LtpProtocol>);
+protected:
+  virtual void DoDispose (void);
+private:
+
+	 virtual void StartApplication (void);    // Called at time specified by Start
+	  virtual void StopApplication (void);     // Called at time specified by Stop
+		void Send();
+		void Receive(SessionId id,
+	            StatusNotificationCode code,
+	            std::vector<uint8_t> data,
+	            uint32_t dataLength,
+	            bool endFlag,
+	            uint64_t srcLtpEngine,
+	            uint32_t offset );
+
+	bool m_isSender;
+	uint64_t m_localClientServiceId;
+
+
+	uint64_t m_destinationClientServiceId;
+	uint64_t m_destinationLtpId;
+
+
+	// Used by sender
+	uint32_t m_bytesToSend;
+	uint32_t m_bytesSent;
+	uint32_t m_blockSize;
+	uint32_t m_blocksSent;
+	uint32_t m_redPartSize;
+
+
+	// User by receiver
+	uint32_t m_bytesReceived;
+	uint32_t m_lastBlockSize;
+	uint32_t m_numBlocks;
+
+	Ptr<LtpProtocol> m_protocol;
+
+};
+
+ClientServiceInstance::~ClientServiceInstance()
+{}
+
+ClientServiceInstance::ClientServiceInstance():
+							m_isSender(0),
+							m_localClientServiceId(0),
+							m_destinationClientServiceId(0),
+							m_destinationLtpId(0),
+							m_bytesToSend(0),
+							m_bytesSent(0),
+							m_blockSize(0),
+							m_blocksSent(0),
+							m_redPartSize(0),
+							m_bytesReceived(0),
+							m_lastBlockSize(0),
+							m_numBlocks(0),
+							m_protocol(0)
+{}
+
+
+ClientServiceInstance::ClientServiceInstance(
+		bool isSender,
+		uint64_t localClientId):
+					m_isSender(isSender),
+					m_localClientServiceId(localClientId),
+					m_destinationClientServiceId(0),
+					m_destinationLtpId(0),
+					m_bytesToSend(0),
+					m_bytesSent(0),
+					m_blockSize(0),
+					m_blocksSent(0),
+					m_redPartSize(0),
+					m_bytesReceived(0),
+					m_lastBlockSize(0),
+					m_numBlocks(0),
+					m_protocol(0)
+{
+
+}
+
+ClientServiceInstance::ClientServiceInstance(
+		bool isSender,
+		uint64_t localClientId,
+		uint64_t destinationClient,
+		uint64_t destinationLtpEngine,
+		uint32_t bytesToSend,
+		uint32_t blockSize,
+		uint32_t redPartSize
+		):
+			m_isSender(isSender),
+			m_localClientServiceId(localClientId),
+			m_destinationClientServiceId(destinationClient),
+			m_destinationLtpId(destinationLtpEngine),
+			m_bytesToSend(bytesToSend),
+			m_bytesSent(0),
+			m_blockSize(blockSize),
+			m_blocksSent(0),
+			m_redPartSize(redPartSize),
+			m_bytesReceived(0),
+			m_lastBlockSize(0),
+			m_numBlocks(0),
+			m_protocol(0)
+{
+
+}
+
+void ClientServiceInstance::DoDispose()
+{
+	NS_LOG_FUNCTION(this);
+}
+
+void ClientServiceInstance::StartApplication()
+{
+	NS_LOG_FUNCTION(this);
+ if (m_protocol)
+ {
+	if(m_isSender)
+	{
+		Send();
+
+	}
+ }
+}
+
+void ClientServiceInstance::StopApplication()
+{
+	NS_LOG_FUNCTION(this);
+}
+
+void
+ClientServiceInstance::SetProtocol(Ptr<LtpProtocol> prot)
+{
+	NS_LOG_FUNCTION(this);
+	m_protocol = prot;
+	CallbackBase cb = MakeCallback (&ClientServiceInstance::Receive, this);
+	m_protocol->RegisterClientService(m_localClientServiceId, cb);
+}
+
+void
+ClientServiceInstance::Send ()
+{
+	NS_LOG_FUNCTION(this);
+	// Create a block of dummy data
+	std::vector<uint8_t> data ( m_blockSize, 0);
+	uint32_t bytes = m_protocol->StartTransmission(
+							m_localClientServiceId,
+					m_destinationClientServiceId,
+					m_destinationLtpId,
+					data,
+					m_redPartSize);
+
+
+	m_bytesSent += bytes;
+
+}
+
+void
+ClientServiceInstance::Receive (SessionId id,
+                                       StatusNotificationCode code,
+                                       std::vector<uint8_t> data,
+                                       uint32_t dataLength,
+                                       bool endFlag,
+                                       uint64_t srcLtpEngine,
+                                       uint32_t offset )
+{
+	NS_LOG_FUNCTION(this);
+  std::cout << "ClientServiceNotification - Session ID: " << id.GetSessionNumber () << " Code : " << code << std::endl;
+
+  if(m_isSender)
+  {
+
+	  if (code == ns3::ltp::SESSION_END)
+	     {
+		  	  m_blocksSent++;
+	 		  std::cout << "ClientServiceNotification - Sender Session - Sent a full block of data with size: ( " << m_blockSize << ") - total data sent " <<  m_bytesSent << std::endl;
+	 		  Send();
+	     }
+  }
+  else {
+
+  m_bytesReceived += dataLength;
+  m_lastBlockSize += dataLength;
+
+  if (code == ns3::ltp::GP_SEGMENT_RCV)
+    {
+
+      std::cout << "ClientServiceNotification - Receiver Session - Received a Green Data Segment of Size: ( " << dataLength << ")" << std::endl;
+    }
+
+  if (code == ns3::ltp::RED_PART_RCV)
+    {
+      std::stringstream ss;
+
+      for ( std::vector<uint8_t>::const_iterator i = data.begin (); i != data.end (); ++i)
+        {
+          ss << *i;
+        }
+
+      NS_ASSERT (ss.str ().length () == dataLength);
+
+      std::cout << "ClientServiceNotification - Receiver Session - Received Full Red Part of Size: ( " << dataLength << ")" << std::endl;
+
+    }
+  if (code == ns3::ltp::SESSION_END)
+    {
+		  m_numBlocks++;
+		  std::cout << "ClientServiceNotification - Receiver Session - Received a full block of data with size: ( " << m_lastBlockSize << ") from LtpEngine: " << srcLtpEngine << std::endl;
+		  m_lastBlockSize = 0;
+    }
+  }
+}
+
+
+
+int
+main (int argc, char *argv[])
+{
+  bool verbose = true;
+
+  LogComponentEnable ("LtpProtocolSimpleExample", LOG_LEVEL_ALL);
+  LogComponentEnable ("LtpProtocol", LOG_LEVEL_ALL);
+  //LogComponentEnable ("LtpUdpConvergenceLayerAdapter", LOG_LEVEL_ALL);
+
+  CommandLine cmd;
+  cmd.AddValue ("verbose", "Tell application to log if true", verbose);
+  cmd.Parse (argc,argv);
+
+  // Create the nodes required by the topology (shown above).
+  NodeContainer nodes;
+  nodes.Create (2);
+
+  // Create point to point links and instell them on the nodes
+  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);
+
+  // Assign IPv4 addresses.
+  Ipv4AddressHelper ipv4;
+  ipv4.SetBase ("10.1.1.0", "255.255.255.0");
+  Ipv4InterfaceContainer i = ipv4.Assign (devices);
+
+  // Create a LtpIpResolution table to perform mappings between Ipv4 adresses and LtpEngineIDs
+  Ptr<LtpIpResolutionTable> routing =  CreateObjectWithAttributes<LtpIpResolutionTable> ("Addressing", StringValue ("Ipv4"));
+
+  // Use a helper to create and install Ltp Protocol instances in the nodes.
+  LtpProtocolHelper ltpHelper;
+  ltpHelper.SetAttributes("CheckPointRtxLimit",  UintegerValue(20),
+		  	  	  	  	  "ReportSegmentRtxLimit", UintegerValue(20),
+		  	  	  	  	  "RetransCyclelimit",  UintegerValue(20));
+  ltpHelper.SetLtpIpResolutionTable (routing);
+  ltpHelper.SetBaseLtpEngineId (0);
+  ltpHelper.SetStartTransmissionTime(Seconds(1));
+  ltpHelper.InstallAndLink (nodes);
+
+  // Define the ClientService ID Code of the Client Service Instance that will be using the Ltp protocol.
+  uint64_t ClientId = 0;  // Bundle
+
+  // Create a client service instance that will act as receiver
+  ClientServiceInstance receiver(false, ClientId);
+  receiver.SetProtocol(  nodes.Get (1)->GetObject<LtpProtocol> () );
+  receiver.SetStartTime(Seconds(0));
+
+  // Define parameters used for the sender
+  uint64_t receiverLtpId = nodes.Get (1)->GetObject<LtpProtocol> ()->GetLocalEngineId ();
+  uint32_t bytesToSend = 1024*1024*100; // 100 MB
+  uint32_t blockSize = 1024*1024; // 1 MB
+  uint32_t dataSentReliably = blockSize / 8;
+
+  // Create a client service instance that will act as a sender.
+  ClientServiceInstance sender (false, ClientId, ClientId, receiverLtpId, bytesToSend, blockSize, dataSentReliably );
+  sender.SetProtocol(  nodes.Get (0)->GetObject<LtpProtocol> () );
+  sender.SetStartTime(Seconds(0));
+
+
+  Simulator::Run ();
+  Simulator::Destroy ();
+  return 0;
+}
+
+
+