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