/* -*- 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 * * Authors: Joe Kopena * * These applications are used in the WiFi Distance Test experiment, * described and implemented in test02.cc. That file should be in the * same place as this file. The applications have two very simple * jobs, they just generate and receive packets. We could use the * standard Application classes included in the NS-3 distribution. * These have been written just to change the behavior a little, and * provide more examples. * */ #include #include "ns3/core-module.h" #include "ns3/network-module.h" #include "ns3/internet-module.h" #include "ns3/stats-module.h" #include "wifi-example-apps.h" using namespace ns3; NS_LOG_COMPONENT_DEFINE ("WiFiDistanceApps"); TypeId Sender::GetTypeId (void) { static TypeId tid = TypeId ("Sender") .SetParent () .AddConstructor () .AddAttribute ("PacketSize", "The size of packets transmitted.", UintegerValue (64), MakeUintegerAccessor (&Sender::m_pktSize), MakeUintegerChecker(1)) .AddAttribute ("Destination", "Target host address.", Ipv4AddressValue ("255.255.255.255"), MakeIpv4AddressAccessor (&Sender::m_destAddr), MakeIpv4AddressChecker ()) .AddAttribute ("Port", "Destination app port.", UintegerValue (1603), MakeUintegerAccessor (&Sender::m_destPort), MakeUintegerChecker()) .AddAttribute ("NumPackets", "Total number of packets to send.", UintegerValue (30), MakeUintegerAccessor (&Sender::m_numPkts), MakeUintegerChecker(1)) .AddAttribute ("Interval", "Delay between transmissions.", StringValue ("ns3::ConstantRandomVariable[Constant=0.5]"), MakePointerAccessor (&Sender::m_interval), MakePointerChecker ()) .AddTraceSource ("Tx", "A new packet is created and is sent", MakeTraceSourceAccessor (&Sender::m_txTrace), "ns3::Packet::TracedCallback") ; return tid; } Sender::Sender() { NS_LOG_FUNCTION_NOARGS (); m_interval = CreateObject (); m_socket = 0; } Sender::~Sender() { NS_LOG_FUNCTION_NOARGS (); } void Sender::DoDispose (void) { NS_LOG_FUNCTION_NOARGS (); m_socket = 0; // chain up Application::DoDispose (); } void Sender::StartApplication () { NS_LOG_FUNCTION_NOARGS (); if (m_socket == 0) { Ptr socketFactory = GetNode ()->GetObject (UdpSocketFactory::GetTypeId ()); m_socket = socketFactory->CreateSocket (); m_socket->Bind (); } m_count = 0; Simulator::Cancel (m_sendEvent); m_sendEvent = Simulator::ScheduleNow (&Sender::SendPacket, this); // end Sender::StartApplication } void Sender::StopApplication () { NS_LOG_FUNCTION_NOARGS (); Simulator::Cancel (m_sendEvent); // end Sender::StopApplication } void Sender::SendPacket () { // NS_LOG_FUNCTION_NOARGS (); NS_LOG_INFO ("Sending packet at " << Simulator::Now () << " to " << m_destAddr); Ptr packet = Create(m_pktSize); TimestampTag timestamp; timestamp.SetTimestamp (Simulator::Now ()); packet->AddByteTag (timestamp); // Could connect the socket since the address never changes; using SendTo // here simply because all of the standard apps do not. m_socket->SendTo (packet, 0, InetSocketAddress (m_destAddr, m_destPort)); // Report the event to the trace. m_txTrace (packet); if (++m_count < m_numPkts) { m_sendEvent = Simulator::Schedule (Seconds (m_interval->GetValue ()), &Sender::SendPacket, this); } // end Sender::SendPacket } //---------------------------------------------------------------------- //-- Receiver //------------------------------------------------------ TypeId Receiver::GetTypeId (void) { static TypeId tid = TypeId ("Receiver") .SetParent () .AddConstructor () .AddAttribute ("Port", "Listening port.", UintegerValue (1603), MakeUintegerAccessor (&Receiver::m_port), MakeUintegerChecker()) ; return tid; } Receiver::Receiver() : m_calc (0), m_delay (0) { NS_LOG_FUNCTION_NOARGS (); m_socket = 0; } Receiver::~Receiver() { NS_LOG_FUNCTION_NOARGS (); } void Receiver::DoDispose (void) { NS_LOG_FUNCTION_NOARGS (); m_socket = 0; // chain up Application::DoDispose (); } void Receiver::StartApplication () { NS_LOG_FUNCTION_NOARGS (); if (m_socket == 0) { Ptr socketFactory = GetNode ()->GetObject (UdpSocketFactory::GetTypeId ()); m_socket = socketFactory->CreateSocket (); InetSocketAddress local = InetSocketAddress (Ipv4Address::GetAny (), m_port); m_socket->Bind (local); } m_socket->SetRecvCallback (MakeCallback (&Receiver::Receive, this)); // end Receiver::StartApplication } void Receiver::StopApplication () { NS_LOG_FUNCTION_NOARGS (); if (m_socket != 0) { m_socket->SetRecvCallback (MakeNullCallback > ()); } // end Receiver::StopApplication } void Receiver::SetCounter (Ptr > calc) { m_calc = calc; // end Receiver::SetCounter } void Receiver::SetDelayTracker (Ptr delay) { m_delay = delay; // end Receiver::SetDelayTracker } void Receiver::Receive (Ptr socket) { // NS_LOG_FUNCTION (this << socket << packet << from); Ptr packet; Address from; while ((packet = socket->RecvFrom (from))) { if (InetSocketAddress::IsMatchingType (from)) { NS_LOG_INFO ("Received " << packet->GetSize () << " bytes from " << InetSocketAddress::ConvertFrom (from).GetIpv4 ()); } TimestampTag timestamp; // Should never not be found since the sender is adding it, but // you never know. if (packet->FindFirstMatchingByteTag (timestamp)) { Time tx = timestamp.GetTimestamp (); if (m_delay != 0) { m_delay->Update (Simulator::Now () - tx); } } if (m_calc != 0) { m_calc->Update (); } // end receiving packets } // end Receiver::Receive } //---------------------------------------------------------------------- //-- TimestampTag //------------------------------------------------------ TypeId TimestampTag::GetTypeId (void) { static TypeId tid = TypeId ("TimestampTag") .SetParent () .AddConstructor () .AddAttribute ("Timestamp", "Some momentous point in time!", EmptyAttributeValue (), MakeTimeAccessor (&TimestampTag::GetTimestamp), MakeTimeChecker ()) ; return tid; } TypeId TimestampTag::GetInstanceTypeId (void) const { return GetTypeId (); } uint32_t TimestampTag::GetSerializedSize (void) const { return 8; } void TimestampTag::Serialize (TagBuffer i) const { int64_t t = m_timestamp.GetNanoSeconds (); i.Write ((const uint8_t *)&t, 8); } void TimestampTag::Deserialize (TagBuffer i) { int64_t t; i.Read ((uint8_t *)&t, 8); m_timestamp = NanoSeconds (t); } void TimestampTag::SetTimestamp (Time time) { m_timestamp = time; } Time TimestampTag::GetTimestamp (void) const { return m_timestamp; } void TimestampTag::Print (std::ostream &os) const { os << "t=" << m_timestamp; }