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