blob: 8352212c23f0793f952107aa534856cd9461df8d [file] [log] [blame]
/* -*- Mode: C++; c-file-style: "gnu"; indent-tabs-mode:nil; -*- */
/*
* Copyright (c) 2011 University of California, Los Angeles
*
* 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: Ilya Moiseenko <iliamo@cs.ucla.edu>
*/
#include "ccnx-consumer.h"
#include "ns3/ptr.h"
#include "ns3/ccnx-local-face.h"
#include "ns3/ccnx.h"
#include "ns3/callback.h"
#include "ns3/ccnx-content-object-header.h"
NS_LOG_COMPONENT_DEFINE ("CcnxConsumer");
namespace ns3
{
NS_OBJECT_ENSURE_REGISTERED (CcnxConsumer);
TypeId
CcnxConsumer::GetTypeId (void)
{
static TypeId tid = TypeId ("ns3::CcnxConsumer")
.SetParent<Application> ()
.AddConstructor<CcnxConsumer> ()
.AddAttribute ("OffTime", "Time interval between packets",
TimeValue (Seconds (0.001)),
MakeTimeAccessor (&CcnxConsumer::m_offTime),
MakeTimeChecker ())
.AddAttribute ("InterestName","CcnxName of the Interest (use CcnxNameComponents)",
CcnxNameComponentsValue (),
MakeCcnxNameComponentsAccessor (&CcnxConsumer::m_interestName),
MakeCcnxNameComponentsChecker ())
.AddAttribute ("LifeTime", "LifeTime fo interest packet",
TimeValue (Seconds (0)),
MakeTimeAccessor (&CcnxConsumer::m_interestLifeTime),
MakeTimeChecker ())
.AddAttribute ("MinSuffixComponents", "MinSuffixComponents",
IntegerValue(-1),
MakeIntegerAccessor(&CcnxConsumer::m_minSuffixComponents),
MakeIntegerChecker<int32_t>())
.AddAttribute ("MaxSuffixComponents", "MaxSuffixComponents",
IntegerValue(-1),
MakeIntegerAccessor(&CcnxConsumer::m_maxSuffixComponents),
MakeIntegerChecker<int32_t>())
.AddAttribute ("ChildSelector", "ChildSelector",
BooleanValue(false),
MakeBooleanAccessor(&CcnxConsumer::m_childSelector),
MakeBooleanChecker())
.AddAttribute ("Exclude", "only simple name matching is supported (use CcnxNameComponents)",
CcnxNameComponentsValue (),
MakeCcnxNameComponentsAccessor (&CcnxConsumer::m_exclude),
MakeCcnxNameComponentsChecker ())
.AddAttribute ("Initial Nonce", "If 0 then nonce is not used",
UintegerValue(1),
MakeUintegerAccessor(&CcnxConsumer::m_initialNonce),
MakeUintegerChecker<uint32_t>())
.AddTraceSource ("InterestTrace", "Interests that were sent",
MakeTraceSourceAccessor (&CcnxConsumer::m_interestsTrace))
.AddTraceSource ("ContentObjectTrace", "ContentObjects that were received",
MakeTraceSourceAccessor (&CcnxConsumer::m_contentObjectsTrace))
;
return tid;
}
CcnxConsumer::CcnxConsumer ()
: m_seq (0)
{
NS_LOG_FUNCTION_NOARGS ();
}
CcnxConsumer::~CcnxConsumer()
{
NS_LOG_FUNCTION_NOARGS ();
}
void
CcnxConsumer::DoDispose (void)
{
NS_LOG_FUNCTION_NOARGS ();
Application::DoDispose ();
}
// Application Methods
void
CcnxConsumer::StartApplication () // Called at time specified by Start
{
NS_LOG_FUNCTION_NOARGS ();
NS_ASSERT_MSG (m_face == 0, "Face should not exist");
m_face = Create<CcnxLocalFace> ();
// step 1. Set up forwarding from face to application
m_face->SetNode (GetNode ());
m_face->SetContentObjectHandler (MakeCallback (&CcnxConsumer::OnContentObject, this));
// step 2. Set up forwarding to and from ccnx
NS_ASSERT_MSG (GetNode ()->GetObject<Ccnx> () !=0,
"Ccnx stack should be installed on the node " << GetNode ());
GetNode ()->GetObject<Ccnx> ()->AddFace (m_face);
// step 3. Enable face
m_face->SetUp ();
// Send first packet immediately
m_sendEvent = Simulator::Schedule (Seconds(0.0), &CcnxConsumer::SendPacket, this);
}
void
CcnxConsumer::StopApplication () // Called at time specified by Stop
{
NS_LOG_FUNCTION_NOARGS ();
CancelEvents ();
// step 1. Disable face
m_face->SetDown ();
// step 2. Remove face from ccnx stack
GetNode ()->GetObject<Ccnx> ()->RemoveFace (m_face);
// step 3. Disable callbacks
m_face->SetContentObjectHandler (MakeNullCallback<void,
const Ptr<const CcnxContentObjectHeader> &,
const Ptr<const Packet> &> ());
}
void
CcnxConsumer::CancelEvents ()
{
NS_LOG_FUNCTION_NOARGS ();
Simulator::Cancel (m_sendEvent);
}
void
CcnxConsumer::SendPacket ()
{
NS_LOG_FUNCTION_NOARGS ();
NS_LOG_INFO ("Sending Interest at " << Simulator::Now ());
UniformVariable rand(1, std::numeric_limits<uint32_t>::max ());
uint32_t randomNonce = rand.GetValue();
CcnxInterestHeader interestHeader;
interestHeader.SetNonce(randomNonce);
Ptr<CcnxNameComponents> name = Create<CcnxNameComponents> (m_interestName);
std::ostringstream os;
os << m_seq++;
(*name) (os.str ());
interestHeader.SetName (name);
interestHeader.SetInterestLifetime(m_interestLifeTime);
interestHeader.SetChildSelector(m_childSelector);
interestHeader.SetExclude(Create<CcnxNameComponents> (m_exclude));
interestHeader.SetMaxSuffixComponents(m_maxSuffixComponents);
interestHeader.SetMinSuffixComponents(m_minSuffixComponents);
NS_LOG_INFO ("Interest: \n" << interestHeader);
Ptr<Packet> packet = Create<Packet> ();
packet->AddHeader (interestHeader);
m_face->ReceiveFromApplication (packet);
m_interestsTrace (m_face,packet);
NS_LOG_INFO("time = " << m_offTime);
m_sendEvent = Simulator::Schedule (m_offTime, &CcnxConsumer::SendPacket, this);
}
// void
// CcnxConsumer::OnInterest (const Ptr<const CcnxInterestHeader> &interest)
// {
// }
void
CcnxConsumer::OnContentObject (const Ptr<const CcnxContentObjectHeader> &contentObject,
const Ptr<const Packet> &payload)
{
// do stuff
NS_LOG_FUNCTION ("Received contentObject " << contentObject );
NS_LOG_INFO ("Preved!");
m_contentObjectsTrace (m_face,payload);
}
}