NS-3 based Named Data Networking (NDN) simulator
ndnSIM: NDN, CCN, CCNx, content centric networks
API Documentation
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Groups Pages
ndn-api-face.cc
1 /* -*- Mode: C++; c-file-style: "gnu"; indent-tabs-mode:nil -*- */
2 /*
3  * Copyright (c) 2012 University of California, Los Angeles
4  *
5  * This program is free software; you can redistribute it and/or modify
6  * it under the terms of the GNU General Public License version 2 as
7  * published by the Free Software Foundation;
8  *
9  * This program is distributed in the hope that it will be useful,
10  * but WITHOUT ANY WARRANTY; without even the implied warranty of
11  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12  * GNU General Public License for more details.
13  *
14  * You should have received a copy of the GNU General Public License
15  * along with this program; if not, write to the Free Software
16  * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
17  *
18  * Author: Alexander Afanasyev <alexander.afanasyev@ucla.edu>
19  */
20 
21 #include "ndn-api-face.h"
22 #include "detail/pending-interests-container.h"
23 #include "detail/registered-prefix-container.h"
24 
25 #include <ns3/random-variable.h>
26 
27 #include <ns3/ndn-l3-protocol.h>
28 #include <ns3/ndn-interest.h>
29 #include <ns3/ndn-data.h>
30 #include <ns3/ndn-face.h>
31 #include <ns3/ndn-fib.h>
32 
33 #include <ns3/packet.h>
34 #include <ns3/log.h>
35 
36 using namespace std;
37 using namespace boost;
38 using namespace ns3;
39 
40 NS_LOG_COMPONENT_DEFINE ("ndn.ApiFace");
41 
42 namespace ns3 {
43 namespace ndn {
44 
45 using namespace detail;
46 
48 {
49 public:
50  ApiFacePriv ()
51  : m_rand (0, std::numeric_limits<uint32_t>::max ())
52  {
53  }
54 
55  ns3::UniformVariable m_rand; // nonce generator
56 
57  PendingInterestContainer m_pendingInterests;
58  RegisteredPrefixContainer m_expectedInterests;
59 };
60 
61 
62 ApiFace::ApiFace (Ptr<Node> node)
63  : Face (node)
64  , m_this (new ApiFacePriv ())
65 {
66  NS_LOG_FUNCTION (this << boost::cref (*this));
67 
68  NS_ASSERT_MSG (GetNode ()->GetObject<L3Protocol> () != 0,
69  "NDN stack should be installed on the node " << GetNode ());
70 
71  GetNode ()->GetObject<L3Protocol> ()->AddFace (this);
72  this->SetUp (true);
73  this->SetFlags (APPLICATION);
74 }
75 
76 ApiFace::~ApiFace ()
77 {
78  NS_LOG_FUNCTION (this << boost::cref (*this));
79 
80  delete m_this;
81 }
82 
83 void
85 {
86  NS_LOG_FUNCTION (this << boost::cref (*this));
87 
88  if (!IsUp ())
89  {
90  return;
91  }
92 
93  this->SetUp (false);
94 
95  m_this->m_pendingInterests.clear ();
96  m_this->m_expectedInterests.clear ();
97 
98  GetNode ()->GetObject<L3Protocol> ()->RemoveFace (this);
99 }
100 
101 void
102 ApiFace::ExpressInterest (Ptr<Interest> interest,
103  DataCallback onData,
104  TimeoutCallback onTimeout/* = MakeNullCallback< void, Ptr<Interest> > ()*/)
105 {
106  NS_LOG_INFO (">> I " << interest->GetName ());
107 
108  if (interest->GetNonce () == 0)
109  {
110  interest->SetNonce (m_this->m_rand.GetValue ());
111  }
112 
113  // Record the callback
114  bool needToActuallyExpressInterest = false;
115  PendingInterestContainer::iterator entry = m_this->m_pendingInterests.find_exact (interest->GetName ());
116  if (entry == m_this->m_pendingInterests.end ())
117  {
118  pair<PendingInterestContainer::iterator, bool> status =
119  m_this->m_pendingInterests.insert (interest->GetName (), Create <PendingInterestEntry> (interest));
120 
121  entry = status.first;
122 
123  needToActuallyExpressInterest = true;
124  }
125  entry->payload ()->AddCallbacks (onData, onTimeout);
126 
127  if (needToActuallyExpressInterest)
128  {
129  Simulator::ScheduleNow (&Face::ReceiveInterest, this, interest);
130  }
131 }
132 
133 void
134 ApiFace::SetInterestFilter (Ptr<const Name> prefix, InterestCallback onInterest)
135 {
136  NS_LOG_DEBUG ("== setInterestFilter " << *prefix << " (" << GetNode ()->GetId () << ")");
137 
138  RegisteredPrefixContainer::iterator entry = m_this->m_expectedInterests.find_exact (*prefix);
139  if (entry == m_this->m_expectedInterests.end ())
140  {
141  pair<RegisteredPrefixContainer::iterator, bool> status =
142  m_this->m_expectedInterests.insert (*prefix, Create < RegisteredPrefixEntry > (prefix));
143 
144  entry = status.first;
145  }
146 
147  entry->payload ()->AddCallback (onInterest);
148 
149  // creating actual face
150  Ptr<ndn::Fib> fib = GetNode ()->GetObject<ndn::Fib> ();
151  Ptr<ndn::fib::Entry> fibEntry = fib->Add (prefix, this, 0);
152  fibEntry->UpdateStatus (this, ndn::fib::FaceMetric::NDN_FIB_GREEN);
153 }
154 
155 void
156 ApiFace::ClearInterestFilter (Ptr<const Name> prefix)
157 {
158  RegisteredPrefixContainer::iterator entry = m_this->m_expectedInterests.find_exact (*prefix);
159  if (entry == m_this->m_expectedInterests.end ())
160  return;
161 
162  entry->payload ()->ClearCallback ();
163  m_this->m_expectedInterests.erase (entry);
164 }
165 
166 void
167 ApiFace::Put (Ptr<Data> data)
168 {
169  NS_LOG_INFO (">> D " << data->GetName ());
170 
171  Simulator::ScheduleNow (&Face::ReceiveData, this, data);
172 }
173 
174 
176 // private stuff
177 
178 
179 bool
180 ApiFace::SendInterest (Ptr<const Interest> interest)
181 {
182  NS_LOG_FUNCTION (this << interest);
183 
184  NS_LOG_DEBUG ("<< I " << interest->GetName ());
185 
186  if (!IsUp ())
187  {
188  return false;
189  }
190 
191  // the app cannot set several filters for the same prefix
192  RegisteredPrefixContainer::iterator entry = m_this->m_expectedInterests.longest_prefix_match (interest->GetName ());
193  if (entry == m_this->m_expectedInterests.end ())
194  {
195  return false;
196  }
197 
198  if (!entry->payload ()->m_callback.IsNull ())
199  entry->payload ()->m_callback (entry->payload ()->GetPrefix (), interest);
200  return true;
201 }
202 
203 bool
204 ApiFace::SendData (Ptr<const Data> data)
205 {
206  // data has been send out from NDN stack towards the application
207  NS_LOG_DEBUG ("<< D " << data->GetName ());
208  // NS_LOG_FUNCTION (this << data);
209 
210  if (!IsUp ())
211  {
212  return false;
213  }
214 
215  PendingInterestContainer::iterator entry = m_this->m_pendingInterests.longest_prefix_match (data->GetName ());
216  if (entry == m_this->m_pendingInterests.end ())
217  {
218  return false;
219  }
220 
221  while (entry != m_this->m_pendingInterests.end ())
222  {
223  entry->payload ()->ProcessOnData (entry->payload ()->GetInterest (), data);
224  m_this->m_pendingInterests.erase (entry);
225 
226  entry = m_this->m_pendingInterests.longest_prefix_match (data->GetName ());
227  }
228  m_this->m_pendingInterests.erase (entry);
229 
230  return true;
231 }
232 
233 std::ostream&
234 ApiFace::Print (std::ostream &os) const
235 {
236  os << "dev=ApiFace(" << GetId () << ")";
237  return os;
238 }
239 
240 
241 }
242 }
void SetUp(bool up=true)
These are face states and may be distinct from actual lower-layer device states, such as found in rea...
Definition: ndn-face.h:290
void ExpressInterest(Ptr< Interest > interest, DataCallback onData, TimeoutCallback onTimeout)
Express Interest.
virtual Ptr< fib::Entry > Add(const Name &prefix, Ptr< Face > face, int32_t metric)=0
Add or update FIB entry.
virtual bool ReceiveInterest(Ptr< Interest > interest)
Receive interest from application or another node and forward it up to the NDN stack.
Definition: ndn-face.cc:204
uint32_t GetId() const
Get face Id.
Definition: ndn-face.h:314
Implementation network-layer of NDN stack.
Virtual class defining NDN face.
Definition: ndn-face.h:58
iterator longest_prefix_match(const FullKey &key)
Find a node that has the longest common prefix with key (FIB/PIT lookup)
virtual bool SendData(Ptr< const Data > data)
Send out Dat packet through the face.
void ClearInterestFilter(Ptr< const Name > prefix)
clear Interest filter
virtual bool SendInterest(Ptr< const Interest > interest)
Send out interest through the face.
An application face.
Definition: ndn-face.h:191
void SetFlags(uint32_t flags)
Set face flags.
Definition: ndn-face.cc:243
Class implementing FIB functionality.
Definition: ndn-fib.h:44
void Put(Ptr< Data > data)
Publish data.
Ptr< Node > GetNode() const
Get node to which this face is associated.
Definition: ndn-face.cc:98
virtual bool ReceiveData(Ptr< Data > data)
Receive Data packet from application or another node and forward it up to the NDN stack...
Definition: ndn-face.cc:217
bool IsUp() const
Returns true if this face is enabled, false otherwise.
Definition: ndn-face.h:284
virtual void Shutdown()
Shutdown the API face.
Definition: ndn-api-face.cc:84
void SetInterestFilter(Ptr< const Name > prefix, InterestCallback onInterest)
set Interest filter (specify what interest you want to receive)
virtual std::ostream & Print(std::ostream &os) const
Print information about the face into the stream.
iterator find_exact(const FullKey &key)
Find a node that has the exact match with the key.