blob: 4be416246168f41b40631724f92d77ba90cc636c [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 Afanasyeva4e74282013-07-11 15:23:20 -0700110 PendingInterestContainer::iterator entry = m_this->m_pendingInterests.find_exact (interest->GetName ());
Alexander Afanasyev79606062013-07-11 00:57:28 -0700111 if (entry == m_this->m_pendingInterests.end ())
112 {
Alexander Afanasyeva4e74282013-07-11 15:23:20 -0700113 pair<PendingInterestContainer::iterator, bool> status =
114 m_this->m_pendingInterests.insert (interest->GetName (), Create <PendingInterestEntry> (interest));
Alexander Afanasyev5bee19e2013-07-10 14:33:57 -0700115
Alexander Afanasyev79606062013-07-11 00:57:28 -0700116 entry = status.first;
117 }
Alexander Afanasyeva4e74282013-07-11 15:23:20 -0700118 entry->payload ()->AddCallbacks (onData, onTimeout);
Alexander Afanasyev5bee19e2013-07-10 14:33:57 -0700119
Alexander Afanasyev79606062013-07-11 00:57:28 -0700120 ReceiveInterest (interest);
121}
122
123void
124ApiFace::SetInterestFilter (Ptr<const Name> prefix, InterestCallback onInterest)
125{
126 NS_LOG_DEBUG ("== setInterestFilter " << *prefix << " (" << GetNode ()->GetId () << ")");
127
Alexander Afanasyeva4e74282013-07-11 15:23:20 -0700128 RegisteredPrefixContainer::iterator entry = m_this->m_expectedInterests.find_exact (*prefix);
Alexander Afanasyev79606062013-07-11 00:57:28 -0700129 if (entry == m_this->m_expectedInterests.end ())
130 {
Alexander Afanasyeva4e74282013-07-11 15:23:20 -0700131 pair<RegisteredPrefixContainer::iterator, bool> status =
132 m_this->m_expectedInterests.insert (*prefix, Create < RegisteredPrefixEntry > (prefix));
Alexander Afanasyev79606062013-07-11 00:57:28 -0700133
134 entry = status.first;
135 }
136
137 entry->payload ()->AddCallback (onInterest);
138
139 // creating actual face
140 Ptr<ndn::Fib> fib = GetNode ()->GetObject<ndn::Fib> ();
141 Ptr<ndn::fib::Entry> fibEntry = fib->Add (prefix, this, 0);
142 fibEntry->UpdateStatus (this, ndn::fib::FaceMetric::NDN_FIB_GREEN);
143}
144
145void
146ApiFace::ClearInterestFilter (Ptr<const Name> prefix)
147{
Alexander Afanasyeva4e74282013-07-11 15:23:20 -0700148 RegisteredPrefixContainer::iterator entry = m_this->m_expectedInterests.find_exact (*prefix);
Alexander Afanasyev79606062013-07-11 00:57:28 -0700149 if (entry == m_this->m_expectedInterests.end ())
150 return;
151
152 entry->payload ()->ClearCallback ();
153 m_this->m_expectedInterests.erase (entry);
154}
155
156void
Alexander Afanasyev772f51b2013-08-01 18:53:25 -0700157ApiFace::Put (Ptr<Data> data)
Alexander Afanasyev79606062013-07-11 00:57:28 -0700158{
159 NS_LOG_INFO (">> D " << data->GetName ());
Alexander Afanasyev5bee19e2013-07-10 14:33:57 -0700160
Alexander Afanasyev79606062013-07-11 00:57:28 -0700161 ReceiveData (data);
162}
Alexander Afanasyev5bee19e2013-07-10 14:33:57 -0700163
Alexander Afanasyev5bee19e2013-07-10 14:33:57 -0700164
Alexander Afanasyev5bee19e2013-07-10 14:33:57 -0700165
Alexander Afanasyev5bee19e2013-07-10 14:33:57 -0700166
Alexander Afanasyev79606062013-07-11 00:57:28 -0700167///////////////////////////////////////////////
168// private stuff
Alexander Afanasyev5bee19e2013-07-10 14:33:57 -0700169
Alexander Afanasyev5bee19e2013-07-10 14:33:57 -0700170
Alexander Afanasyev79606062013-07-11 00:57:28 -0700171bool
172ApiFace::SendInterest (Ptr<const Interest> interest)
173{
174 NS_LOG_FUNCTION (this << interest);
Alexander Afanasyev5bee19e2013-07-10 14:33:57 -0700175
Alexander Afanasyev79606062013-07-11 00:57:28 -0700176 NS_LOG_DEBUG ("<< I " << interest->GetName ());
Alexander Afanasyev5bee19e2013-07-10 14:33:57 -0700177
Alexander Afanasyev79606062013-07-11 00:57:28 -0700178 if (!IsUp ())
179 {
180 return false;
181 }
Alexander Afanasyev5bee19e2013-07-10 14:33:57 -0700182
Alexander Afanasyev79606062013-07-11 00:57:28 -0700183 // the app cannot set several filters for the same prefix
Alexander Afanasyeva4e74282013-07-11 15:23:20 -0700184 RegisteredPrefixContainer::iterator entry = m_this->m_expectedInterests.longest_prefix_match (interest->GetName ());
Alexander Afanasyev79606062013-07-11 00:57:28 -0700185 if (entry == m_this->m_expectedInterests.end ())
186 {
187 return false;
188 }
Alexander Afanasyeve4795ae2013-07-11 20:01:31 -0700189
190 if (!entry->payload ()->m_callback.IsNull ())
191 entry->payload ()->m_callback (entry->payload ()->GetPrefix (), interest);
Alexander Afanasyev79606062013-07-11 00:57:28 -0700192 return true;
193}
Alexander Afanasyev5bee19e2013-07-10 14:33:57 -0700194
Alexander Afanasyev79606062013-07-11 00:57:28 -0700195bool
Alexander Afanasyev772f51b2013-08-01 18:53:25 -0700196ApiFace::SendData (Ptr<const Data> data)
Alexander Afanasyev79606062013-07-11 00:57:28 -0700197{
198 // data has been send out from NDN stack towards the application
199 NS_LOG_DEBUG ("<< D " << data->GetName ());
Alexander Afanasyev5bee19e2013-07-10 14:33:57 -0700200
Alexander Afanasyev79606062013-07-11 00:57:28 -0700201 NS_LOG_FUNCTION (this << data);
202
203 if (!IsUp ())
204 {
205 return false;
206 }
207
Alexander Afanasyeva4e74282013-07-11 15:23:20 -0700208 PendingInterestContainer::iterator entry = m_this->m_pendingInterests.longest_prefix_match (data->GetName ());
Alexander Afanasyev79606062013-07-11 00:57:28 -0700209 if (entry == m_this->m_pendingInterests.end ())
210 {
211 return false;
212 }
213
214 while (entry != m_this->m_pendingInterests.end ())
215 {
Alexander Afanasyeve4795ae2013-07-11 20:01:31 -0700216 if (!entry->payload ()->m_dataCallback.IsNull ())
217 entry->payload ()->m_dataCallback (entry->payload ()->GetInterest (), data);
Alexander Afanasyev79606062013-07-11 00:57:28 -0700218 m_this->m_pendingInterests.erase (entry);
219
220 entry = m_this->m_pendingInterests.longest_prefix_match (data->GetName ());
221 }
222 m_this->m_pendingInterests.erase (entry);
223
224 return true;
225}
226
227std::ostream&
228ApiFace::Print (std::ostream &os) const
229{
230 os << "dev=ApiFace(" << GetId () << ")";
231 return os;
232}
233
Alexander Afanasyev5bee19e2013-07-10 14:33:57 -0700234
235}
236}