NS-3 based Named Data Networking (NDN) simulator
ndnSIM 2.0: 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 
33 #include "model/ndn-app-face.hpp"
35 
36 #include <boost/lexical_cast.hpp>
37 #include <boost/ref.hpp>
38 
39 NS_LOG_COMPONENT_DEFINE("ndn.Consumer");
40 
41 namespace ns3 {
42 namespace ndn {
43 
45 
46 TypeId
48 {
49  static TypeId tid =
50  TypeId("ns3::ndn::Consumer")
51  .SetGroupName("Ndn")
52  .SetParent<App>()
53  .AddAttribute("StartSeq", "Initial sequence number", IntegerValue(0),
54  MakeIntegerAccessor(&Consumer::m_seq), MakeIntegerChecker<int32_t>())
55 
56  .AddAttribute("Prefix", "Name of the Interest", StringValue("/"),
58  .AddAttribute("LifeTime", "LifeTime for interest packet", StringValue("2s"),
59  MakeTimeAccessor(&Consumer::m_interestLifeTime), MakeTimeChecker())
60 
61  .AddAttribute("RetxTimer",
62  "Timeout defining how frequent retransmission timeouts should be checked",
63  StringValue("50ms"),
65  MakeTimeChecker())
66 
67  .AddTraceSource("LastRetransmittedInterestDataDelay",
68  "Delay between last retransmitted Interest and received Data",
69  MakeTraceSourceAccessor(&Consumer::m_lastRetransmittedInterestDataDelay),
70  "ns3::ndn::Consumer::LastRetransmittedInterestDataDelayCallback")
71 
72  .AddTraceSource("FirstInterestDataDelay",
73  "Delay between first transmitted Interest and received Data",
74  MakeTraceSourceAccessor(&Consumer::m_firstInterestDataDelay),
75  "ns3::ndn::Consumer::FirstInterestDataDelayCallback");
76 
77  return tid;
78 }
79 
81  : m_rand(CreateObject<UniformRandomVariable>())
82  , m_seq(0)
83  , m_seqMax(0) // don't request anything
84 {
85  NS_LOG_FUNCTION_NOARGS();
86 
87  m_rtt = CreateObject<RttMeanDeviation>();
88 }
89 
90 void
91 Consumer::SetRetxTimer(Time retxTimer)
92 {
93  m_retxTimer = retxTimer;
94  if (m_retxEvent.IsRunning()) {
95  // m_retxEvent.Cancel (); // cancel any scheduled cleanup events
96  Simulator::Remove(m_retxEvent); // slower, but better for memory
97  }
98 
99  // schedule even with new timeout
100  m_retxEvent = Simulator::Schedule(m_retxTimer, &Consumer::CheckRetxTimeout, this);
101 }
102 
103 Time
105 {
106  return m_retxTimer;
107 }
108 
109 void
111 {
112  Time now = Simulator::Now();
113 
114  Time rto = m_rtt->RetransmitTimeout();
115  // NS_LOG_DEBUG ("Current RTO: " << rto.ToDouble (Time::S) << "s");
116 
117  while (!m_seqTimeouts.empty()) {
119  m_seqTimeouts.get<i_timestamp>().begin();
120  if (entry->time + rto <= now) // timeout expired?
121  {
122  uint32_t seqNo = entry->seq;
123  m_seqTimeouts.get<i_timestamp>().erase(entry);
124  OnTimeout(seqNo);
125  }
126  else
127  break; // nothing else to do. All later packets need not be retransmitted
128  }
129 
130  m_retxEvent = Simulator::Schedule(m_retxTimer, &Consumer::CheckRetxTimeout, this);
131 }
132 
133 // Application Methods
134 void
135 Consumer::StartApplication() // Called at time specified by Start
136 {
137  NS_LOG_FUNCTION_NOARGS();
138 
139  // do base stuff
141 
143 }
144 
145 void
146 Consumer::StopApplication() // Called at time specified by Stop
147 {
148  NS_LOG_FUNCTION_NOARGS();
149 
150  // cancel periodic packet generation
151  Simulator::Cancel(m_sendEvent);
152 
153  // cleanup base stuff
155 }
156 
157 void
159 {
160  if (!m_active)
161  return;
162 
163  NS_LOG_FUNCTION_NOARGS();
164 
165  uint32_t seq = std::numeric_limits<uint32_t>::max(); // invalid
166 
167  while (m_retxSeqs.size()) {
168  seq = *m_retxSeqs.begin();
169  m_retxSeqs.erase(m_retxSeqs.begin());
170  break;
171  }
172 
173  if (seq == std::numeric_limits<uint32_t>::max()) {
174  if (m_seqMax != std::numeric_limits<uint32_t>::max()) {
175  if (m_seq >= m_seqMax) {
176  return; // we are totally done
177  }
178  }
179 
180  seq = m_seq++;
181  }
182 
183  //
184  shared_ptr<Name> nameWithSequence = make_shared<Name>(m_interestName);
185  nameWithSequence->appendSequenceNumber(seq);
186  //
187 
188  // shared_ptr<Interest> interest = make_shared<Interest> ();
189  shared_ptr<Interest> interest = make_shared<Interest>();
190  interest->setNonce(m_rand->GetValue(0, std::numeric_limits<uint32_t>::max()));
191  interest->setName(*nameWithSequence);
192  time::milliseconds interestLifeTime(m_interestLifeTime.GetMilliSeconds());
193  interest->setInterestLifetime(interestLifeTime);
194 
195  // NS_LOG_INFO ("Requesting Interest: \n" << *interest);
196  NS_LOG_INFO("> Interest for " << seq);
197 
198  WillSendOutInterest(seq);
199 
200  m_transmittedInterests(interest, this, m_face);
201  m_face->onReceiveInterest(*interest);
202 
204 }
205 
207 // Process incoming packets //
209 
210 void
211 Consumer::OnData(shared_ptr<const Data> data)
212 {
213  if (!m_active)
214  return;
215 
216  App::OnData(data); // tracing inside
217 
218  NS_LOG_FUNCTION(this << data);
219 
220  // NS_LOG_INFO ("Received content object: " << boost::cref(*data));
221 
222  // This could be a problem......
223  uint32_t seq = data->getName().at(-1).toSequenceNumber();
224  NS_LOG_INFO("< DATA for " << seq);
225 
226  int hopCount = 0;
227  auto ns3PacketTag = data->getTag<Ns3PacketTag>();
228  if (ns3PacketTag != nullptr) { // e.g., packet came from local node's cache
229  FwHopCountTag hopCountTag;
230  if (ns3PacketTag->getPacket()->PeekPacketTag(hopCountTag)) {
231  hopCount = hopCountTag.Get();
232  NS_LOG_DEBUG("Hop count: " << hopCount);
233  }
234  }
235 
236  SeqTimeoutsContainer::iterator entry = m_seqLastDelay.find(seq);
237  if (entry != m_seqLastDelay.end()) {
238  m_lastRetransmittedInterestDataDelay(this, seq, Simulator::Now() - entry->time, hopCount);
239  }
240 
241  entry = m_seqFullDelay.find(seq);
242  if (entry != m_seqFullDelay.end()) {
243  m_firstInterestDataDelay(this, seq, Simulator::Now() - entry->time, m_seqRetxCounts[seq], hopCount);
244  }
245 
246  m_seqRetxCounts.erase(seq);
247  m_seqFullDelay.erase(seq);
248  m_seqLastDelay.erase(seq);
249 
250  m_seqTimeouts.erase(seq);
251  m_retxSeqs.erase(seq);
252 
253  m_rtt->AckSeq(SequenceNumber32(seq));
254 }
255 
256 void
257 Consumer::OnTimeout(uint32_t sequenceNumber)
258 {
259  NS_LOG_FUNCTION(sequenceNumber);
260  // std::cout << Simulator::Now () << ", TO: " << sequenceNumber << ", current RTO: " <<
261  // m_rtt->RetransmitTimeout ().ToDouble (Time::S) << "s\n";
262 
263  m_rtt->IncreaseMultiplier(); // Double the next RTO
264  m_rtt->SentSeq(SequenceNumber32(sequenceNumber),
265  1); // make sure to disable RTT calculation for this sample
266  m_retxSeqs.insert(sequenceNumber);
268 }
269 
270 void
271 Consumer::WillSendOutInterest(uint32_t sequenceNumber)
272 {
273  NS_LOG_DEBUG("Trying to add " << sequenceNumber << " with " << Simulator::Now() << ". already "
274  << m_seqTimeouts.size() << " items");
275 
276  m_seqTimeouts.insert(SeqTimeout(sequenceNumber, Simulator::Now()));
277  m_seqFullDelay.insert(SeqTimeout(sequenceNumber, Simulator::Now()));
278 
279  m_seqLastDelay.erase(sequenceNumber);
280  m_seqLastDelay.insert(SeqTimeout(sequenceNumber, Simulator::Now()));
281 
282  m_seqRetxCounts[sequenceNumber]++;
283 
284  m_rtt->SentSeq(SequenceNumber32(sequenceNumber), 1);
285 }
286 
287 } // namespace ndn
288 } // 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.
Packet tag that is used to track hop count for Interest-Data pairs.
virtual void StopApplication()
Called at time specified by Stop.
Definition: ndn-app.cpp:138
void SetRetxTimer(Time retxTimer)
Modifies the frequency of checking the retransmission timeouts.
ndn Consumer
Copyright (c) 2011-2015 Regents of the University of California.
NS_OBJECT_ENSURE_REGISTERED(ContentStore)
uint32_t m_seq
currently requested sequence number
virtual void StartApplication()
Called at time specified by Start.
Definition: ndn-app.cpp:120
Time m_retxTimer
Currently estimated retransmission timer.
shared_ptr< AppFace > m_face
automatically created application face through which application communicates
Definition: ndn-app.hpp:103
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...
Table::const_iterator iterator
Definition: cs-internal.hpp:41
Copyright (c) 2011-2015 Regents of the University of California.
uint32_t Get() const
Get value of hop count.
TracedCallback< shared_ptr< const Interest >, Ptr< App >, shared_ptr< Face > > m_transmittedInterests
App-level trace of transmitted Interests.
Definition: ndn-app.hpp:113
Base class that all NDN applications should be derived from.
Definition: ndn-app.hpp:47
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:47
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:102
static TypeId GetTypeId()
Time GetRetxTimer() const
Returns the frequency of checking the retransmission timeouts.
virtual void OnData(shared_ptr< const Data > data)
Method that will be called every time new Data arrives.
Definition: ndn-app.cpp:112
virtual void StartApplication()
Called at time specified by Start.