blob: fd78763bb69947cccf66a8c37e500c17bee79f69 [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 Afanasyevf0bda2f2013-08-12 16:38:13 -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{
Alexander Afanasyevf0bda2f2013-08-12 16:38:13 -070066 NS_LOG_FUNCTION (this << boost::cref (*this));
67
Alexander Afanasyev79606062013-07-11 00:57:28 -070068 NS_ASSERT_MSG (GetNode ()->GetObject<L3Protocol> () != 0,
69 "NDN stack should be installed on the node " << GetNode ());
Alexander Afanasyev5bee19e2013-07-10 14:33:57 -070070
Alexander Afanasyev79606062013-07-11 00:57:28 -070071 GetNode ()->GetObject<L3Protocol> ()->AddFace (this);
72 this->SetUp (true);
73 this->SetFlags (APPLICATION);
74}
Alexander Afanasyev5bee19e2013-07-10 14:33:57 -070075
Alexander Afanasyev79606062013-07-11 00:57:28 -070076ApiFace::~ApiFace ()
77{
Alexander Afanasyevf0bda2f2013-08-12 16:38:13 -070078 NS_LOG_FUNCTION (this << boost::cref (*this));
79
Alexander Afanasyev79606062013-07-11 00:57:28 -070080 delete m_this;
81}
Alexander Afanasyev5bee19e2013-07-10 14:33:57 -070082
Alexander Afanasyev79606062013-07-11 00:57:28 -070083void
Alexander Afanasyeva4e74282013-07-11 15:23:20 -070084ApiFace::Shutdown ()
85{
Alexander Afanasyevf0bda2f2013-08-12 16:38:13 -070086 NS_LOG_FUNCTION (this << boost::cref (*this));
Alexander Afanasyeva4e74282013-07-11 15:23:20 -070087
88 if (!IsUp ())
89 {
90 return;
91 }
Alexander Afanasyevf0bda2f2013-08-12 16:38:13 -070092
Alexander Afanasyeva4e74282013-07-11 15:23:20 -070093 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
101void
Alexander Afanasyev79606062013-07-11 00:57:28 -0700102ApiFace::ExpressInterest (Ptr<Interest> interest,
103 DataCallback onData,
104 TimeoutCallback onTimeout/* = MakeNullCallback< void, Ptr<Interest> > ()*/)
105{
106 NS_LOG_INFO (">> I " << interest->GetName ());
Alexander Afanasyev5bee19e2013-07-10 14:33:57 -0700107
Alexander Afanasyev79606062013-07-11 00:57:28 -0700108 if (interest->GetNonce () == 0)
109 {
110 interest->SetNonce (m_this->m_rand.GetValue ());
111 }
Alexander Afanasyevf0bda2f2013-08-12 16:38:13 -0700112
Alexander Afanasyev79606062013-07-11 00:57:28 -0700113 // Record the callback
Alexander Afanasyevbaccf7d2013-08-09 12:38:44 -0700114 bool needToActuallyExpressInterest = false;
Alexander Afanasyeva4e74282013-07-11 15:23:20 -0700115 PendingInterestContainer::iterator entry = m_this->m_pendingInterests.find_exact (interest->GetName ());
Alexander Afanasyev79606062013-07-11 00:57:28 -0700116 if (entry == m_this->m_pendingInterests.end ())
117 {
Alexander Afanasyeva4e74282013-07-11 15:23:20 -0700118 pair<PendingInterestContainer::iterator, bool> status =
119 m_this->m_pendingInterests.insert (interest->GetName (), Create <PendingInterestEntry> (interest));
Alexander Afanasyev5bee19e2013-07-10 14:33:57 -0700120
Alexander Afanasyev79606062013-07-11 00:57:28 -0700121 entry = status.first;
Alexander Afanasyevbaccf7d2013-08-09 12:38:44 -0700122
123 needToActuallyExpressInterest = true;
Alexander Afanasyev79606062013-07-11 00:57:28 -0700124 }
Alexander Afanasyeva4e74282013-07-11 15:23:20 -0700125 entry->payload ()->AddCallbacks (onData, onTimeout);
Alexander Afanasyev5bee19e2013-07-10 14:33:57 -0700126
Alexander Afanasyevbaccf7d2013-08-09 12:38:44 -0700127 if (needToActuallyExpressInterest)
128 {
129 Simulator::ScheduleNow (&Face::ReceiveInterest, this, interest);
130 }
Alexander Afanasyev79606062013-07-11 00:57:28 -0700131}
132
133void
134ApiFace::SetInterestFilter (Ptr<const Name> prefix, InterestCallback onInterest)
135{
136 NS_LOG_DEBUG ("== setInterestFilter " << *prefix << " (" << GetNode ()->GetId () << ")");
137
Alexander Afanasyeva4e74282013-07-11 15:23:20 -0700138 RegisteredPrefixContainer::iterator entry = m_this->m_expectedInterests.find_exact (*prefix);
Alexander Afanasyev79606062013-07-11 00:57:28 -0700139 if (entry == m_this->m_expectedInterests.end ())
140 {
Alexander Afanasyeva4e74282013-07-11 15:23:20 -0700141 pair<RegisteredPrefixContainer::iterator, bool> status =
142 m_this->m_expectedInterests.insert (*prefix, Create < RegisteredPrefixEntry > (prefix));
Alexander Afanasyev79606062013-07-11 00:57:28 -0700143
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
155void
156ApiFace::ClearInterestFilter (Ptr<const Name> prefix)
157{
Alexander Afanasyeva4e74282013-07-11 15:23:20 -0700158 RegisteredPrefixContainer::iterator entry = m_this->m_expectedInterests.find_exact (*prefix);
Alexander Afanasyev79606062013-07-11 00:57:28 -0700159 if (entry == m_this->m_expectedInterests.end ())
160 return;
161
162 entry->payload ()->ClearCallback ();
163 m_this->m_expectedInterests.erase (entry);
164}
165
166void
Alexander Afanasyev772f51b2013-08-01 18:53:25 -0700167ApiFace::Put (Ptr<Data> data)
Alexander Afanasyev79606062013-07-11 00:57:28 -0700168{
169 NS_LOG_INFO (">> D " << data->GetName ());
Alexander Afanasyevf0bda2f2013-08-12 16:38:13 -0700170
Alexander Afanasyevbaccf7d2013-08-09 12:38:44 -0700171 Simulator::ScheduleNow (&Face::ReceiveData, this, data);
Alexander Afanasyev79606062013-07-11 00:57:28 -0700172}
Alexander Afanasyev5bee19e2013-07-10 14:33:57 -0700173
Alexander Afanasyev5bee19e2013-07-10 14:33:57 -0700174
Alexander Afanasyev79606062013-07-11 00:57:28 -0700175///////////////////////////////////////////////
176// private stuff
Alexander Afanasyev5bee19e2013-07-10 14:33:57 -0700177
Alexander Afanasyev5bee19e2013-07-10 14:33:57 -0700178
Alexander Afanasyev79606062013-07-11 00:57:28 -0700179bool
180ApiFace::SendInterest (Ptr<const Interest> interest)
181{
182 NS_LOG_FUNCTION (this << interest);
Alexander Afanasyev5bee19e2013-07-10 14:33:57 -0700183
Alexander Afanasyev79606062013-07-11 00:57:28 -0700184 NS_LOG_DEBUG ("<< I " << interest->GetName ());
Alexander Afanasyevf0bda2f2013-08-12 16:38:13 -0700185
Alexander Afanasyev79606062013-07-11 00:57:28 -0700186 if (!IsUp ())
187 {
188 return false;
189 }
Alexander Afanasyev5bee19e2013-07-10 14:33:57 -0700190
Alexander Afanasyev79606062013-07-11 00:57:28 -0700191 // the app cannot set several filters for the same prefix
Alexander Afanasyeva4e74282013-07-11 15:23:20 -0700192 RegisteredPrefixContainer::iterator entry = m_this->m_expectedInterests.longest_prefix_match (interest->GetName ());
Alexander Afanasyev79606062013-07-11 00:57:28 -0700193 if (entry == m_this->m_expectedInterests.end ())
194 {
195 return false;
196 }
Alexander Afanasyeve4795ae2013-07-11 20:01:31 -0700197
198 if (!entry->payload ()->m_callback.IsNull ())
199 entry->payload ()->m_callback (entry->payload ()->GetPrefix (), interest);
Alexander Afanasyev79606062013-07-11 00:57:28 -0700200 return true;
201}
Alexander Afanasyev5bee19e2013-07-10 14:33:57 -0700202
Alexander Afanasyev79606062013-07-11 00:57:28 -0700203bool
Alexander Afanasyev772f51b2013-08-01 18:53:25 -0700204ApiFace::SendData (Ptr<const Data> data)
Alexander Afanasyev79606062013-07-11 00:57:28 -0700205{
206 // data has been send out from NDN stack towards the application
207 NS_LOG_DEBUG ("<< D " << data->GetName ());
Alexander Afanasyevbaccf7d2013-08-09 12:38:44 -0700208 // NS_LOG_FUNCTION (this << data);
Alexander Afanasyev79606062013-07-11 00:57:28 -0700209
210 if (!IsUp ())
211 {
212 return false;
213 }
214
Alexander Afanasyeva4e74282013-07-11 15:23:20 -0700215 PendingInterestContainer::iterator entry = m_this->m_pendingInterests.longest_prefix_match (data->GetName ());
Alexander Afanasyev79606062013-07-11 00:57:28 -0700216 if (entry == m_this->m_pendingInterests.end ())
217 {
218 return false;
219 }
220
221 while (entry != m_this->m_pendingInterests.end ())
222 {
Alexander Afanasyevbaccf7d2013-08-09 12:38:44 -0700223 entry->payload ()->ProcessOnData (entry->payload ()->GetInterest (), data);
Alexander Afanasyev79606062013-07-11 00:57:28 -0700224 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);
Alexander Afanasyevf0bda2f2013-08-12 16:38:13 -0700229
Alexander Afanasyev79606062013-07-11 00:57:28 -0700230 return true;
231}
232
233std::ostream&
234ApiFace::Print (std::ostream &os) const
235{
236 os << "dev=ApiFace(" << GetId () << ")";
237 return os;
238}
239
Alexander Afanasyev5bee19e2013-07-10 14:33:57 -0700240
241}
242}