blob: 4d522fa82f6dc07f3a2429955a261a42b202e797 [file] [log] [blame]
Alexander Afanasyev5bee19e2013-07-10 14:33:57 -07001/* -*- 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>
Alexander Afanasyev5bee19e2013-07-10 14:33:57 -070019 */
20
21#include "ndn-api-face.h"
Alexander Afanasyeva4e74282013-07-11 15:23:20 -070022#include "detail/pending-interests-container.h"
23#include "detail/registered-prefix-container.h"
Alexander Afanasyev5bee19e2013-07-10 14:33:57 -070024
Alexander Afanasyev79606062013-07-11 00:57:28 -070025#include <ns3/random-variable.h>
Alexander Afanasyev5bee19e2013-07-10 14:33:57 -070026
Alexander Afanasyev79606062013-07-11 00:57:28 -070027#include <ns3/ndn-l3-protocol.h>
Alexander Afanasyev5bee19e2013-07-10 14:33:57 -070028#include <ns3/ndn-interest.h>
Alexander Afanasyev6eba36f2013-08-07 17:42:54 -070029#include <ns3/ndn-data.h>
Alexander Afanasyev5bee19e2013-07-10 14:33:57 -070030#include <ns3/ndn-face.h>
31#include <ns3/ndn-fib.h>
Alexander Afanasyev5bee19e2013-07-10 14:33:57 -070032
Alexander Afanasyev79606062013-07-11 00:57:28 -070033#include <ns3/packet.h>
34#include <ns3/log.h>
Alexander Afanasyev5bee19e2013-07-10 14:33:57 -070035
36using namespace std;
37using namespace boost;
38using namespace ns3;
39
Alexander Afanasyev79606062013-07-11 00:57:28 -070040NS_LOG_COMPONENT_DEFINE ("ndn.ApiFace");
Alexander Afanasyev5bee19e2013-07-10 14:33:57 -070041
42namespace ns3 {
43namespace ndn {
44
Alexander Afanasyeva4e74282013-07-11 15:23:20 -070045using namespace detail;
46
Alexander Afanasyev79606062013-07-11 00:57:28 -070047class ApiFacePriv
48{
49public:
50 ApiFacePriv ()
51 : m_rand (0, std::numeric_limits<uint32_t>::max ())
52 {
53 }
Alexander Afanasyev5bee19e2013-07-10 14:33:57 -070054
Alexander Afanasyev79606062013-07-11 00:57:28 -070055 ns3::UniformVariable m_rand; // nonce generator
Alexander Afanasyev5bee19e2013-07-10 14:33:57 -070056
Alexander Afanasyeva4e74282013-07-11 15:23:20 -070057 PendingInterestContainer m_pendingInterests;
58 RegisteredPrefixContainer m_expectedInterests;
Alexander Afanasyev79606062013-07-11 00:57:28 -070059};
Alexander Afanasyev5bee19e2013-07-10 14:33:57 -070060
61
Alexander Afanasyev79606062013-07-11 00:57:28 -070062ApiFace::ApiFace (Ptr<Node> node)
63 : Face (node)
64 , m_this (new ApiFacePriv ())
65{
66 NS_ASSERT_MSG (GetNode ()->GetObject<L3Protocol> () != 0,
67 "NDN stack should be installed on the node " << GetNode ());
Alexander Afanasyev5bee19e2013-07-10 14:33:57 -070068
Alexander Afanasyev79606062013-07-11 00:57:28 -070069 GetNode ()->GetObject<L3Protocol> ()->AddFace (this);
70 this->SetUp (true);
71 this->SetFlags (APPLICATION);
72}
Alexander Afanasyev5bee19e2013-07-10 14:33:57 -070073
Alexander Afanasyev79606062013-07-11 00:57:28 -070074ApiFace::~ApiFace ()
75{
76 delete m_this;
77}
Alexander Afanasyev5bee19e2013-07-10 14:33:57 -070078
Alexander Afanasyev79606062013-07-11 00:57:28 -070079void
Alexander Afanasyeva4e74282013-07-11 15:23:20 -070080ApiFace::Shutdown ()
81{
82 NS_LOG_FUNCTION (this);
83
84 if (!IsUp ())
85 {
86 return;
87 }
88
89 this->SetUp (false);
90
91 m_this->m_pendingInterests.clear ();
92 m_this->m_expectedInterests.clear ();
93
94 GetNode ()->GetObject<L3Protocol> ()->RemoveFace (this);
95}
96
97void
Alexander Afanasyev79606062013-07-11 00:57:28 -070098ApiFace::ExpressInterest (Ptr<Interest> interest,
99 DataCallback onData,
100 TimeoutCallback onTimeout/* = MakeNullCallback< void, Ptr<Interest> > ()*/)
101{
102 NS_LOG_INFO (">> I " << interest->GetName ());
Alexander Afanasyev5bee19e2013-07-10 14:33:57 -0700103
Alexander Afanasyev79606062013-07-11 00:57:28 -0700104 if (interest->GetNonce () == 0)
105 {
106 interest->SetNonce (m_this->m_rand.GetValue ());
107 }
Alexander Afanasyev5bee19e2013-07-10 14:33:57 -0700108
Alexander Afanasyev79606062013-07-11 00:57:28 -0700109 // Record the callback
Alexander Afanasyevbaccf7d2013-08-09 12:38:44 -0700110 bool needToActuallyExpressInterest = false;
Alexander Afanasyeva4e74282013-07-11 15:23:20 -0700111 PendingInterestContainer::iterator entry = m_this->m_pendingInterests.find_exact (interest->GetName ());
Alexander Afanasyev79606062013-07-11 00:57:28 -0700112 if (entry == m_this->m_pendingInterests.end ())
113 {
Alexander Afanasyeva4e74282013-07-11 15:23:20 -0700114 pair<PendingInterestContainer::iterator, bool> status =
115 m_this->m_pendingInterests.insert (interest->GetName (), Create <PendingInterestEntry> (interest));
Alexander Afanasyev5bee19e2013-07-10 14:33:57 -0700116
Alexander Afanasyev79606062013-07-11 00:57:28 -0700117 entry = status.first;
Alexander Afanasyevbaccf7d2013-08-09 12:38:44 -0700118
119 needToActuallyExpressInterest = true;
Alexander Afanasyev79606062013-07-11 00:57:28 -0700120 }
Alexander Afanasyeva4e74282013-07-11 15:23:20 -0700121 entry->payload ()->AddCallbacks (onData, onTimeout);
Alexander Afanasyev5bee19e2013-07-10 14:33:57 -0700122
Alexander Afanasyevbaccf7d2013-08-09 12:38:44 -0700123 if (needToActuallyExpressInterest)
124 {
125 Simulator::ScheduleNow (&Face::ReceiveInterest, this, interest);
126 }
Alexander Afanasyev79606062013-07-11 00:57:28 -0700127}
128
129void
130ApiFace::SetInterestFilter (Ptr<const Name> prefix, InterestCallback onInterest)
131{
132 NS_LOG_DEBUG ("== setInterestFilter " << *prefix << " (" << GetNode ()->GetId () << ")");
133
Alexander Afanasyeva4e74282013-07-11 15:23:20 -0700134 RegisteredPrefixContainer::iterator entry = m_this->m_expectedInterests.find_exact (*prefix);
Alexander Afanasyev79606062013-07-11 00:57:28 -0700135 if (entry == m_this->m_expectedInterests.end ())
136 {
Alexander Afanasyeva4e74282013-07-11 15:23:20 -0700137 pair<RegisteredPrefixContainer::iterator, bool> status =
138 m_this->m_expectedInterests.insert (*prefix, Create < RegisteredPrefixEntry > (prefix));
Alexander Afanasyev79606062013-07-11 00:57:28 -0700139
140 entry = status.first;
141 }
142
143 entry->payload ()->AddCallback (onInterest);
144
145 // creating actual face
146 Ptr<ndn::Fib> fib = GetNode ()->GetObject<ndn::Fib> ();
147 Ptr<ndn::fib::Entry> fibEntry = fib->Add (prefix, this, 0);
148 fibEntry->UpdateStatus (this, ndn::fib::FaceMetric::NDN_FIB_GREEN);
149}
150
151void
152ApiFace::ClearInterestFilter (Ptr<const Name> prefix)
153{
Alexander Afanasyeva4e74282013-07-11 15:23:20 -0700154 RegisteredPrefixContainer::iterator entry = m_this->m_expectedInterests.find_exact (*prefix);
Alexander Afanasyev79606062013-07-11 00:57:28 -0700155 if (entry == m_this->m_expectedInterests.end ())
156 return;
157
158 entry->payload ()->ClearCallback ();
159 m_this->m_expectedInterests.erase (entry);
160}
161
162void
Alexander Afanasyev772f51b2013-08-01 18:53:25 -0700163ApiFace::Put (Ptr<Data> data)
Alexander Afanasyev79606062013-07-11 00:57:28 -0700164{
165 NS_LOG_INFO (">> D " << data->GetName ());
Alexander Afanasyev5bee19e2013-07-10 14:33:57 -0700166
Alexander Afanasyevbaccf7d2013-08-09 12:38:44 -0700167 Simulator::ScheduleNow (&Face::ReceiveData, this, data);
Alexander Afanasyev79606062013-07-11 00:57:28 -0700168}
Alexander Afanasyev5bee19e2013-07-10 14:33:57 -0700169
Alexander Afanasyev5bee19e2013-07-10 14:33:57 -0700170
Alexander Afanasyev79606062013-07-11 00:57:28 -0700171///////////////////////////////////////////////
172// private stuff
Alexander Afanasyev5bee19e2013-07-10 14:33:57 -0700173
Alexander Afanasyev5bee19e2013-07-10 14:33:57 -0700174
Alexander Afanasyev79606062013-07-11 00:57:28 -0700175bool
176ApiFace::SendInterest (Ptr<const Interest> interest)
177{
178 NS_LOG_FUNCTION (this << interest);
Alexander Afanasyev5bee19e2013-07-10 14:33:57 -0700179
Alexander Afanasyev79606062013-07-11 00:57:28 -0700180 NS_LOG_DEBUG ("<< I " << interest->GetName ());
Alexander Afanasyev5bee19e2013-07-10 14:33:57 -0700181
Alexander Afanasyev79606062013-07-11 00:57:28 -0700182 if (!IsUp ())
183 {
184 return false;
185 }
Alexander Afanasyev5bee19e2013-07-10 14:33:57 -0700186
Alexander Afanasyev79606062013-07-11 00:57:28 -0700187 // the app cannot set several filters for the same prefix
Alexander Afanasyeva4e74282013-07-11 15:23:20 -0700188 RegisteredPrefixContainer::iterator entry = m_this->m_expectedInterests.longest_prefix_match (interest->GetName ());
Alexander Afanasyev79606062013-07-11 00:57:28 -0700189 if (entry == m_this->m_expectedInterests.end ())
190 {
191 return false;
192 }
Alexander Afanasyeve4795ae2013-07-11 20:01:31 -0700193
194 if (!entry->payload ()->m_callback.IsNull ())
195 entry->payload ()->m_callback (entry->payload ()->GetPrefix (), interest);
Alexander Afanasyev79606062013-07-11 00:57:28 -0700196 return true;
197}
Alexander Afanasyev5bee19e2013-07-10 14:33:57 -0700198
Alexander Afanasyev79606062013-07-11 00:57:28 -0700199bool
Alexander Afanasyev772f51b2013-08-01 18:53:25 -0700200ApiFace::SendData (Ptr<const Data> data)
Alexander Afanasyev79606062013-07-11 00:57:28 -0700201{
202 // data has been send out from NDN stack towards the application
203 NS_LOG_DEBUG ("<< D " << data->GetName ());
Alexander Afanasyevbaccf7d2013-08-09 12:38:44 -0700204 // NS_LOG_FUNCTION (this << data);
Alexander Afanasyev79606062013-07-11 00:57:28 -0700205
206 if (!IsUp ())
207 {
208 return false;
209 }
210
Alexander Afanasyeva4e74282013-07-11 15:23:20 -0700211 PendingInterestContainer::iterator entry = m_this->m_pendingInterests.longest_prefix_match (data->GetName ());
Alexander Afanasyev79606062013-07-11 00:57:28 -0700212 if (entry == m_this->m_pendingInterests.end ())
213 {
214 return false;
215 }
216
217 while (entry != m_this->m_pendingInterests.end ())
218 {
Alexander Afanasyevbaccf7d2013-08-09 12:38:44 -0700219 entry->payload ()->ProcessOnData (entry->payload ()->GetInterest (), data);
Alexander Afanasyev79606062013-07-11 00:57:28 -0700220 m_this->m_pendingInterests.erase (entry);
221
222 entry = m_this->m_pendingInterests.longest_prefix_match (data->GetName ());
223 }
224 m_this->m_pendingInterests.erase (entry);
225
226 return true;
227}
228
229std::ostream&
230ApiFace::Print (std::ostream &os) const
231{
232 os << "dev=ApiFace(" << GetId () << ")";
233 return os;
234}
235
Alexander Afanasyev5bee19e2013-07-10 14:33:57 -0700236
237}
238}