NS-3 based Named Data Networking (NDN) simulator
ndnSIM 2.0: NDN, CCN, CCNx, content centric networks
API Documentation
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Groups Pages
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 
71  .AddTraceSource("FirstInterestDataDelay",
72  "Delay between first transmitted Interest and received Data",
73  MakeTraceSourceAccessor(&Consumer::m_firstInterestDataDelay));
74 
75  return tid;
76 }
77 
79  : m_rand(0, std::numeric_limits<uint32_t>::max())
80  , m_seq(0)
81  , m_seqMax(0) // don't request anything
82 {
83  NS_LOG_FUNCTION_NOARGS();
84 
85  m_rtt = CreateObject<RttMeanDeviation>();
86 }
87 
88 void
89 Consumer::SetRetxTimer(Time retxTimer)
90 {
91  m_retxTimer = retxTimer;
92  if (m_retxEvent.IsRunning()) {
93  // m_retxEvent.Cancel (); // cancel any scheduled cleanup events
94  Simulator::Remove(m_retxEvent); // slower, but better for memory
95  }
96 
97  // schedule even with new timeout
98  m_retxEvent = Simulator::Schedule(m_retxTimer, &Consumer::CheckRetxTimeout, this);
99 }
100 
101 Time
103 {
104  return m_retxTimer;
105 }
106 
107 void
109 {
110  Time now = Simulator::Now();
111 
112  Time rto = m_rtt->RetransmitTimeout();
113  // NS_LOG_DEBUG ("Current RTO: " << rto.ToDouble (Time::S) << "s");
114 
115  while (!m_seqTimeouts.empty()) {
116  SeqTimeoutsContainer::index<i_timestamp>::type::iterator entry =
117  m_seqTimeouts.get<i_timestamp>().begin();
118  if (entry->time + rto <= now) // timeout expired?
119  {
120  uint32_t seqNo = entry->seq;
121  m_seqTimeouts.get<i_timestamp>().erase(entry);
122  OnTimeout(seqNo);
123  }
124  else
125  break; // nothing else to do. All later packets need not be retransmitted
126  }
127 
128  m_retxEvent = Simulator::Schedule(m_retxTimer, &Consumer::CheckRetxTimeout, this);
129 }
130 
131 // Application Methods
132 void
133 Consumer::StartApplication() // Called at time specified by Start
134 {
135  NS_LOG_FUNCTION_NOARGS();
136 
137  // do base stuff
139 
141 }
142 
143 void
144 Consumer::StopApplication() // Called at time specified by Stop
145 {
146  NS_LOG_FUNCTION_NOARGS();
147 
148  // cancel periodic packet generation
149  Simulator::Cancel(m_sendEvent);
150 
151  // cleanup base stuff
153 }
154 
155 void
157 {
158  if (!m_active)
159  return;
160 
161  NS_LOG_FUNCTION_NOARGS();
162 
163  uint32_t seq = std::numeric_limits<uint32_t>::max(); // invalid
164 
165  while (m_retxSeqs.size()) {
166  seq = *m_retxSeqs.begin();
167  m_retxSeqs.erase(m_retxSeqs.begin());
168  break;
169  }
170 
171  if (seq == std::numeric_limits<uint32_t>::max()) {
172  if (m_seqMax != std::numeric_limits<uint32_t>::max()) {
173  if (m_seq >= m_seqMax) {
174  return; // we are totally done
175  }
176  }
177 
178  seq = m_seq++;
179  }
180 
181  //
182  shared_ptr<Name> nameWithSequence = make_shared<Name>(m_interestName);
183  nameWithSequence->appendSequenceNumber(seq);
184  //
185 
186  // shared_ptr<Interest> interest = make_shared<Interest> ();
187  shared_ptr<Interest> interest = make_shared<Interest>();
188  interest->setNonce(m_rand.GetValue());
189  interest->setName(*nameWithSequence);
190  time::milliseconds interestLifeTime(m_interestLifeTime.GetMilliSeconds());
191  interest->setInterestLifetime(interestLifeTime);
192 
193  // NS_LOG_INFO ("Requesting Interest: \n" << *interest);
194  NS_LOG_INFO("> Interest for " << seq);
195 
196  WillSendOutInterest(seq);
197 
198  m_transmittedInterests(interest, this, m_face);
199  m_face->onReceiveInterest(*interest);
200 
202 }
203 
205 // Process incoming packets //
207 
208 void
209 Consumer::OnData(shared_ptr<const Data> data)
210 {
211  if (!m_active)
212  return;
213 
214  App::OnData(data); // tracing inside
215 
216  NS_LOG_FUNCTION(this << data);
217 
218  // NS_LOG_INFO ("Received content object: " << boost::cref(*data));
219 
220  // This could be a problem......
221  uint32_t seq = data->getName().at(-1).toSequenceNumber();
222  NS_LOG_INFO("< DATA for " << seq);
223 
224  int hopCount = -1;
225  auto ns3PacketTag = data->getTag<Ns3PacketTag>();
226  if (ns3PacketTag != nullptr) {
227  FwHopCountTag hopCountTag;
228  if (ns3PacketTag->getPacket()->PeekPacketTag(hopCountTag)) {
229  hopCount = hopCountTag.Get();
230  NS_LOG_DEBUG("Hop count: " << hopCount);
231  }
232  }
233 
234  SeqTimeoutsContainer::iterator entry = m_seqLastDelay.find(seq);
235  if (entry != m_seqLastDelay.end()) {
236  m_lastRetransmittedInterestDataDelay(this, seq, Simulator::Now() - entry->time, hopCount);
237  }
238 
239  entry = m_seqFullDelay.find(seq);
240  if (entry != m_seqFullDelay.end()) {
241  m_firstInterestDataDelay(this, seq, Simulator::Now() - entry->time, m_seqRetxCounts[seq], hopCount);
242  }
243 
244  m_seqRetxCounts.erase(seq);
245  m_seqFullDelay.erase(seq);
246  m_seqLastDelay.erase(seq);
247 
248  m_seqTimeouts.erase(seq);
249  m_retxSeqs.erase(seq);
250 
251  m_rtt->AckSeq(SequenceNumber32(seq));
252 }
253 
254 void
255 Consumer::OnTimeout(uint32_t sequenceNumber)
256 {
257  NS_LOG_FUNCTION(sequenceNumber);
258  // std::cout << Simulator::Now () << ", TO: " << sequenceNumber << ", current RTO: " <<
259  // m_rtt->RetransmitTimeout ().ToDouble (Time::S) << "s\n";
260 
261  m_rtt->IncreaseMultiplier(); // Double the next RTO
262  m_rtt->SentSeq(SequenceNumber32(sequenceNumber),
263  1); // make sure to disable RTT calculation for this sample
264  m_retxSeqs.insert(sequenceNumber);
266 }
267 
268 void
269 Consumer::WillSendOutInterest(uint32_t sequenceNumber)
270 {
271  NS_LOG_DEBUG("Trying to add " << sequenceNumber << " with " << Simulator::Now() << ". already "
272  << m_seqTimeouts.size() << " items");
273 
274  m_seqTimeouts.insert(SeqTimeout(sequenceNumber, Simulator::Now()));
275  m_seqFullDelay.insert(SeqTimeout(sequenceNumber, Simulator::Now()));
276 
277  m_seqLastDelay.erase(sequenceNumber);
278  m_seqLastDelay.insert(SeqTimeout(sequenceNumber, Simulator::Now()));
279 
280  m_seqRetxCounts[sequenceNumber]++;
281 
282  m_rtt->SentSeq(SequenceNumber32(sequenceNumber), 1);
283 }
284 
285 } // namespace ndn
286 } // 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
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:121
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:103
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...
UniformVariable m_rand
nonce generator
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:111
shared_ptr< Face > m_face
and StopApplication)
Definition: ndn-app.hpp:101
Base class that all NDN applications should be derived from.
Definition: ndn-app.hpp:47
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.
Definition: ndn-app.hpp:98
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:95
virtual void StartApplication()
Called at time specified by Start.