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