NS-3 based Named Data Networking (NDN) simulator
ndnSIM 2.5: NDN, CCN, CCNx, content centric networks
API Documentation
ndn-consumer.cpp
Go to the documentation of this file.
1 /* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
20 #include "ndn-consumer.hpp"
21 #include "ns3/ptr.h"
22 #include "ns3/log.h"
23 #include "ns3/simulator.h"
24 #include "ns3/packet.h"
25 #include "ns3/callback.h"
26 #include "ns3/string.h"
27 #include "ns3/boolean.h"
28 #include "ns3/uinteger.h"
29 #include "ns3/integer.h"
30 #include "ns3/double.h"
31 
34 
35 #include <ndn-cxx/lp/tags.hpp>
36 
37 #include <boost/lexical_cast.hpp>
38 #include <boost/ref.hpp>
39 
40 NS_LOG_COMPONENT_DEFINE("ndn.Consumer");
41 
42 namespace ns3 {
43 namespace ndn {
44 
46 
47 TypeId
49 {
50  static TypeId tid =
51  TypeId("ns3::ndn::Consumer")
52  .SetGroupName("Ndn")
53  .SetParent<App>()
54  .AddAttribute("StartSeq", "Initial sequence number", IntegerValue(0),
55  MakeIntegerAccessor(&Consumer::m_seq), MakeIntegerChecker<int32_t>())
56 
57  .AddAttribute("Prefix", "Name of the Interest", StringValue("/"),
59  .AddAttribute("LifeTime", "LifeTime for interest packet", StringValue("2s"),
60  MakeTimeAccessor(&Consumer::m_interestLifeTime), MakeTimeChecker())
61 
62  .AddAttribute("RetxTimer",
63  "Timeout defining how frequent retransmission timeouts should be checked",
64  StringValue("50ms"),
66  MakeTimeChecker())
67 
68  .AddTraceSource("LastRetransmittedInterestDataDelay",
69  "Delay between last retransmitted Interest and received Data",
70  MakeTraceSourceAccessor(&Consumer::m_lastRetransmittedInterestDataDelay),
71  "ns3::ndn::Consumer::LastRetransmittedInterestDataDelayCallback")
72 
73  .AddTraceSource("FirstInterestDataDelay",
74  "Delay between first transmitted Interest and received Data",
75  MakeTraceSourceAccessor(&Consumer::m_firstInterestDataDelay),
76  "ns3::ndn::Consumer::FirstInterestDataDelayCallback");
77 
78  return tid;
79 }
80 
82  : m_rand(CreateObject<UniformRandomVariable>())
83  , m_seq(0)
84  , m_seqMax(0) // don't request anything
85 {
86  NS_LOG_FUNCTION_NOARGS();
87 
88  m_rtt = CreateObject<RttMeanDeviation>();
89 }
90 
91 void
92 Consumer::SetRetxTimer(Time retxTimer)
93 {
94  m_retxTimer = retxTimer;
95  if (m_retxEvent.IsRunning()) {
96  // m_retxEvent.Cancel (); // cancel any scheduled cleanup events
97  Simulator::Remove(m_retxEvent); // slower, but better for memory
98  }
99 
100  // schedule even with new timeout
101  m_retxEvent = Simulator::Schedule(m_retxTimer, &Consumer::CheckRetxTimeout, this);
102 }
103 
104 Time
106 {
107  return m_retxTimer;
108 }
109 
110 void
112 {
113  Time now = Simulator::Now();
114 
115  Time rto = m_rtt->RetransmitTimeout();
116  // NS_LOG_DEBUG ("Current RTO: " << rto.ToDouble (Time::S) << "s");
117 
118  while (!m_seqTimeouts.empty()) {
119  SeqTimeoutsContainer::index<i_timestamp>::type::iterator entry =
120  m_seqTimeouts.get<i_timestamp>().begin();
121  if (entry->time + rto <= now) // timeout expired?
122  {
123  uint32_t seqNo = entry->seq;
124  m_seqTimeouts.get<i_timestamp>().erase(entry);
125  OnTimeout(seqNo);
126  }
127  else
128  break; // nothing else to do. All later packets need not be retransmitted
129  }
130 
131  m_retxEvent = Simulator::Schedule(m_retxTimer, &Consumer::CheckRetxTimeout, this);
132 }
133 
134 // Application Methods
135 void
136 Consumer::StartApplication() // Called at time specified by Start
137 {
138  NS_LOG_FUNCTION_NOARGS();
139 
140  // do base stuff
142 
144 }
145 
146 void
147 Consumer::StopApplication() // Called at time specified by Stop
148 {
149  NS_LOG_FUNCTION_NOARGS();
150 
151  // cancel periodic packet generation
152  Simulator::Cancel(m_sendEvent);
153 
154  // cleanup base stuff
156 }
157 
158 void
160 {
161  if (!m_active)
162  return;
163 
164  NS_LOG_FUNCTION_NOARGS();
165 
166  uint32_t seq = std::numeric_limits<uint32_t>::max(); // invalid
167 
168  while (m_retxSeqs.size()) {
169  seq = *m_retxSeqs.begin();
170  m_retxSeqs.erase(m_retxSeqs.begin());
171  break;
172  }
173 
174  if (seq == std::numeric_limits<uint32_t>::max()) {
175  if (m_seqMax != std::numeric_limits<uint32_t>::max()) {
176  if (m_seq >= m_seqMax) {
177  return; // we are totally done
178  }
179  }
180 
181  seq = m_seq++;
182  }
183 
184  //
185  shared_ptr<Name> nameWithSequence = make_shared<Name>(m_interestName);
186  nameWithSequence->appendSequenceNumber(seq);
187  //
188 
189  // shared_ptr<Interest> interest = make_shared<Interest> ();
190  shared_ptr<Interest> interest = make_shared<Interest>();
191  interest->setNonce(m_rand->GetValue(0, std::numeric_limits<uint32_t>::max()));
192  interest->setName(*nameWithSequence);
193  interest->setCanBePrefix(false);
194  time::milliseconds interestLifeTime(m_interestLifeTime.GetMilliSeconds());
195  interest->setInterestLifetime(interestLifeTime);
196 
197  // NS_LOG_INFO ("Requesting Interest: \n" << *interest);
198  NS_LOG_INFO("> Interest for " << seq);
199 
200  WillSendOutInterest(seq);
201 
202  m_transmittedInterests(interest, this, m_face);
203  m_appLink->onReceiveInterest(*interest);
204 
206 }
207 
209 // Process incoming packets //
211 
212 void
213 Consumer::OnData(shared_ptr<const Data> data)
214 {
215  if (!m_active)
216  return;
217 
218  App::OnData(data); // tracing inside
219 
220  NS_LOG_FUNCTION(this << data);
221 
222  // NS_LOG_INFO ("Received content object: " << boost::cref(*data));
223 
224  // This could be a problem......
225  uint32_t seq = data->getName().at(-1).toSequenceNumber();
226  NS_LOG_INFO("< DATA for " << seq);
227 
228  int hopCount = 0;
229  auto hopCountTag = data->getTag<lp::HopCountTag>();
230  if (hopCountTag != nullptr) { // e.g., packet came from local node's cache
231  hopCount = *hopCountTag;
232  }
233  NS_LOG_DEBUG("Hop count: " << hopCount);
234 
235  SeqTimeoutsContainer::iterator entry = m_seqLastDelay.find(seq);
236  if (entry != m_seqLastDelay.end()) {
237  m_lastRetransmittedInterestDataDelay(this, seq, Simulator::Now() - entry->time, hopCount);
238  }
239 
240  entry = m_seqFullDelay.find(seq);
241  if (entry != m_seqFullDelay.end()) {
242  m_firstInterestDataDelay(this, seq, Simulator::Now() - entry->time, m_seqRetxCounts[seq], hopCount);
243  }
244 
245  m_seqRetxCounts.erase(seq);
246  m_seqFullDelay.erase(seq);
247  m_seqLastDelay.erase(seq);
248 
249  m_seqTimeouts.erase(seq);
250  m_retxSeqs.erase(seq);
251 
252  m_rtt->AckSeq(SequenceNumber32(seq));
253 }
254 
255 void
256 Consumer::OnNack(shared_ptr<const lp::Nack> nack)
257 {
259  App::OnNack(nack);
260 
261  NS_LOG_INFO("NACK received for: " << nack->getInterest().getName()
262  << ", reason: " << nack->getReason());
263 }
264 
265 void
266 Consumer::OnTimeout(uint32_t sequenceNumber)
267 {
268  NS_LOG_FUNCTION(sequenceNumber);
269  // std::cout << Simulator::Now () << ", TO: " << sequenceNumber << ", current RTO: " <<
270  // m_rtt->RetransmitTimeout ().ToDouble (Time::S) << "s\n";
271 
272  m_rtt->IncreaseMultiplier(); // Double the next RTO
273  m_rtt->SentSeq(SequenceNumber32(sequenceNumber),
274  1); // make sure to disable RTT calculation for this sample
275  m_retxSeqs.insert(sequenceNumber);
277 }
278 
279 void
280 Consumer::WillSendOutInterest(uint32_t sequenceNumber)
281 {
282  NS_LOG_DEBUG("Trying to add " << sequenceNumber << " with " << Simulator::Now() << ". already "
283  << m_seqTimeouts.size() << " items");
284 
285  m_seqTimeouts.insert(SeqTimeout(sequenceNumber, Simulator::Now()));
286  m_seqFullDelay.insert(SeqTimeout(sequenceNumber, Simulator::Now()));
287 
288  m_seqLastDelay.erase(sequenceNumber);
289  m_seqLastDelay.insert(SeqTimeout(sequenceNumber, Simulator::Now()));
290 
291  m_seqRetxCounts[sequenceNumber]++;
292 
293  m_rtt->SentSeq(SequenceNumber32(sequenceNumber), 1);
294 }
295 
296 } // namespace ndn
297 } // namespace ns3
Time m_interestLifeTime
LifeTime for interest packet.
virtual void OnTimeout(uint32_t sequenceNumber)
Timeout event.
uint32_t m_seqMax
maximum number of sequence number
Copyright (c) 2011-2015 Regents of the University of California.
virtual void StopApplication()
Called at time specified by Stop.
Definition: ndn-app.cpp:162
void SetRetxTimer(Time retxTimer)
Modifies the frequency of checking the retransmission timeouts.
ndn Consumer
Copyright (c) 2011-2015 Regents of the University of California.
uint32_t m_seq
currently requested sequence number
virtual void StartApplication()
Called at time specified by Start.
Definition: ndn-app.cpp:138
NS_OBJECT_ENSURE_REGISTERED(GlobalRouter)
void onReceiveInterest(const Interest &interest)
Time m_retxTimer
Currently estimated retransmission timer.
Ptr< RttEstimator > m_rtt
RTT estimator.
Name m_interestName
NDN Name of the Interest (use Name)
void CheckRetxTimeout()
Checks if the packet need to be retransmitted becuase of retransmission timer expiration.
virtual void OnData(shared_ptr< const Data > contentObject)
Method that will be called every time new Data arrives.
void SendPacket()
Actually send packet.
virtual void ScheduleNextPacket()=0
Constructs the Interest packet and sends it using a callback to the underlying NDN protocol...
provides a tag type for simple types
Definition: tag.hpp:58
Time GetRetxTimer() const
Returns the frequency of checking the retransmission timeouts.
virtual void OnNack(shared_ptr< const lp::Nack > nack)
Method that will be called every time new Nack arrives.
Definition: ndn-app.cpp:128
virtual void OnNack(shared_ptr< const lp::Nack > nack)
Method that will be called every time new Nack arrives.
Copyright (c) 2011-2015 Regents of the University of California.
TracedCallback< shared_ptr< const Interest >, Ptr< App >, shared_ptr< Face > > m_transmittedInterests
App-level trace of transmitted Interests.
Definition: ndn-app.hpp:119
shared_ptr< Face > m_face
Definition: ndn-app.hpp:104
AppLinkService * m_appLink
Definition: ndn-app.hpp:105
Base class that all NDN applications should be derived from.
Definition: ndn-app.hpp:48
Ptr< UniformRandomVariable > m_rand
nonce generator
Consumer()
Default constructor Sets up randomizer function and packet sequence number.
Ptr< const AttributeChecker > MakeNameChecker(void)
virtual void StopApplication()
Called at time specified by Stop.
EventId m_sendEvent
EventId of pending "send packet" event.
virtual void WillSendOutInterest(uint32_t sequenceNumber)
An event that is fired just before an Interest packet is actually send out (send is inevitable) ...
Ptr< const AttributeAccessor > MakeNameAccessor(T1 a1)
Definition: ndn-common.hpp:48
EventId m_retxEvent
Event to check whether or not retransmission should be performed.
bool m_active
Flag to indicate that application is active (set by StartApplication and StopApplication) ...
Definition: ndn-app.hpp:103
static TypeId GetTypeId()
virtual void OnData(shared_ptr< const Data > data)
Method that will be called every time new Data arrives.
Definition: ndn-app.cpp:121
virtual void StartApplication()
Called at time specified by Start.
boost::chrono::milliseconds milliseconds
Definition: time.hpp:48