blob: e66bda17e9e339b68b2edb8a0abfb64a77ece0bc [file] [log] [blame]
Alexander Afanasyev181d7e52012-04-09 13:54:11 -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: Zhenkai Zhu <zhenkai@cs.ucla.edu>
19 * Chaoyi Bian <bcy@pku.edu.cn>
20 * Alexander Afanasyev <alexander.afanasyev@ucla.edu>
21 */
22
23#include "sync-ccnx-wrapper.h"
24#include "sync-log.h"
25#include <boost/throw_exception.hpp>
26#include <boost/date_time/posix_time/posix_time.hpp>
27#include <boost/lambda/lambda.hpp>
28#include <boost/lambda/bind.hpp>
29
30namespace ll = boost::lambda;
31
32#include <ns3/ccnx-name-components.h>
33#include <ns3/ccnx-interest-header.h>
34#include <ns3/ccnx-content-object-header.h>
35#include <ns3/ccnx-face.h>
36#include <ns3/packet.h>
37#include <ns3/ccnx-fib.h>
38
39typedef boost::error_info<struct tag_errmsg, std::string> errmsg_info_str;
40typedef boost::error_info<struct tag_errmsg, int> errmsg_info_int;
41
42using namespace std;
43using namespace boost;
44using namespace ns3;
45
46INIT_LOGGER ("CcnxWrapper");
47
48namespace Sync {
49
50CcnxWrapper::CcnxWrapper()
51{
52}
53
54CcnxWrapper::~CcnxWrapper()
55{
56}
57
58void
59CcnxWrapper::StartApplication ()
60{
61 CcnxApp::StartApplication ();
62}
63
64void
65CcnxWrapper::StopApplication ()
66{
67 CcnxApp::StopApplication ();
68}
69
70int
71CcnxWrapper::publishData (const string &dataName, const string &dataBuffer, int freshness)
72{
73 // NS_LOG_INFO ("Requesting Interest: \n" << interestHeader);
74 _LOG_INFO ("> Data for " << dataName);
75
76 Ptr<CcnxNameComponents> name = Create<CcnxNameComponents> ();
77 istringstream is (dataName);
78 is >> *name;
79
80 static CcnxContentObjectTail trailer;
81
82 CcnxContentObjectHeader data;
83 data.SetName (name);
84 data.SetFreshness (Seconds (freshness));
85
86 Ptr<Packet> packet = Create<Packet> (reinterpret_cast<const uint8_t*> (dataBuffer.c_str ()), dataBuffer.size ());
87
88 packet->AddHeader (data);
89 packet->AddTrailer (trailer);
90
91 m_protocolHandler (packet);
92
93 m_transmittedContentObjects (&data, packet, this, m_face);
94
95 return 0;
96}
97
98int CcnxWrapper::sendInterest (const string &strInterest, const DataCallback &dataCallback)
99{
100 // NS_LOG_INFO ("Requesting Interest: \n" << interestHeader);
101 _LOG_INFO ("> Interest for " << strInterest);
102
103 Ptr<CcnxNameComponents> name = Create<CcnxNameComponents> ();
104 istringstream is (strInterest);
105 is >> *name;
106
107 CcnxInterestHeader interestHeader;
108 interestHeader.SetNonce (m_rand.GetValue ());
109 interestHeader.SetName (name);
110 interestHeader.SetInterestLifetime (Seconds (4.0));
111
112 Ptr<Packet> packet = Create<Packet> ();
113 packet->AddHeader (interestHeader);
114
115 m_protocolHandler (packet);
116
117 m_transmittedInterests (&interestHeader, this, m_face);
118
119 // Record the callback
120 CcnxFilterEntryContainer<DataCallback>::type::iterator entry = m_dataCallbacks.find (*name);
121 if (entry == m_dataCallbacks.end ())
122 {
123 pair<CcnxFilterEntryContainer<DataCallback>::type::iterator, bool> status =
124 m_dataCallbacks.insert (CcnxFilterEntry<DataCallback> (name));
125
126 entry = status.first;
127 }
128 m_dataCallbacks.modify (entry, ll::bind (&CcnxFilterEntry<DataCallback>::AddCallback, ll::_1, dataCallback));
129
130 return 0;
131}
132
133int CcnxWrapper::setInterestFilter (const string &prefix, const InterestCallback &interestCallback)
134{
135 Ptr<CcnxNameComponents> name = Create<CcnxNameComponents> ();
136 istringstream is (prefix);
137 is >> *name;
138
139 CcnxFilterEntryContainer<InterestCallback>::type::iterator entry = m_interestCallbacks.find (*name);
140 if (entry == m_interestCallbacks.end ())
141 {
142 pair<CcnxFilterEntryContainer<InterestCallback>::type::iterator, bool> status =
143 m_interestCallbacks.insert (CcnxFilterEntry<InterestCallback> (name));
144
145 entry = status.first;
146 }
147
148 m_interestCallbacks.modify (entry, ll::bind (&CcnxFilterEntry<InterestCallback>::AddCallback, ll::_1, interestCallback));
149
150 // creating actual face
151
152 Ptr<CcnxFib> fib = GetNode ()->GetObject<CcnxFib> ();
153 CcnxFibEntryContainer::type::iterator fibEntry = fib->Add (*name, m_face, 0);
154
155 // make face green, so it will be used primarily
156 fib->m_fib.modify (fibEntry,
157 ll::bind (&CcnxFibEntry::UpdateStatus,
158 ll::_1, m_face, CcnxFibFaceMetric::NDN_FIB_GREEN));
159
160 return 0;
161}
162
163void
164CcnxWrapper::clearInterestFilter (const std::string &prefix)
165{
166 Ptr<CcnxNameComponents> name = Create<CcnxNameComponents> ();
167 istringstream is (prefix);
168 is >> *name;
169
170 CcnxFilterEntryContainer<InterestCallback>::type::iterator entry = m_interestCallbacks.find (*name);
171 if (entry == m_interestCallbacks.end ())
172 return;
173
174 m_interestCallbacks.modify (entry, ll::bind (&CcnxFilterEntry<InterestCallback>::ClearCallback, ll::_1));
175}
176
177CcnxFilterEntryContainer<CcnxWrapper::InterestCallback>::type::iterator
178CcnxWrapper::InterestCallbackLookup (const ns3::CcnxNameComponents &name)
179{
180 CcnxFilterEntryContainer<InterestCallback>::type::iterator entry = m_interestCallbacks.end ();
181
182 // do the longest prefix match
183 for (size_t componentsCount = name.GetComponents ().size ()+1;
184 componentsCount > 0;
185 componentsCount--)
186 {
187 CcnxNameComponents subPrefix (name.GetSubComponents (componentsCount-1));
188
189 entry = m_interestCallbacks.find (subPrefix);
190 if (entry != m_interestCallbacks.end())
191 return entry;
192 }
193
194 return entry;
195}
196
197CcnxFilterEntryContainer<CcnxWrapper::DataCallback>::type::iterator
198CcnxWrapper::DataCallbackLookup (const ns3::CcnxNameComponents &name)
199{
200 CcnxFilterEntryContainer<DataCallback>::type::iterator entry = m_dataCallbacks.end ();
201
202 // do the longest prefix match
203 for (size_t componentsCount = name.GetComponents ().size ()+1;
204 componentsCount > 0;
205 componentsCount--)
206 {
207 CcnxNameComponents subPrefix (name.GetSubComponents (componentsCount-1));
208
209 entry = m_dataCallbacks.find (subPrefix);
210 if (entry != m_dataCallbacks.end())
211 return entry;
212 }
213
214 return entry;
215}
216
217void
218CcnxWrapper::OnInterest (const Ptr<const CcnxInterestHeader> &interest, Ptr<Packet> packet)
219{
220 CcnxApp::OnInterest (interest, packet);
221
222 CcnxFilterEntryContainer<InterestCallback>::type::iterator entry = InterestCallbackLookup (interest->GetName ());
223 if (entry == m_interestCallbacks.end ())
224 {
225 _LOG_DEBUG ("No Interest callback set");
226 return;
227 }
228
229 entry->m_callback (lexical_cast<string> (interest->GetName ()));
230}
231
232void
233CcnxWrapper::OnContentObject (const Ptr<const CcnxContentObjectHeader> &contentObject,
234 Ptr<Packet> payload)
235{
236 CcnxApp::OnContentObject (contentObject, payload);
237
238 CcnxFilterEntryContainer<DataCallback>::type::iterator entry = DataCallbackLookup (contentObject->GetName ());
239 if (entry == m_dataCallbacks.end ())
240 {
241 _LOG_DEBUG ("No Data callback set");
242 return;
243 }
244
245 ostringstream content;
246 payload->CopyData (&content, payload->GetSize ());
247
248 entry->m_callback (lexical_cast<string> (contentObject->GetName ()), content.str ());
249
250 // i guess it make sense to remove callback when interest is satisfied
251 m_dataCallbacks.erase (entry);
252}
253
254
255}